Skip to content

Commit c99f5b5

Browse files
authored
Merge branch 'main' into feature-mesh_deformation
2 parents 53a09de + d57674d commit c99f5b5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+919
-600
lines changed

.github/workflows/check_doxygen.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,21 @@ jobs:
4242
repository: ${{ github.event.pull_request.head.repo.full_name }}
4343
ref: ${{ github.event.pull_request.head.ref }}
4444
fetch-depth: 0
45+
fetch-tags: true
4546
- name: disable ownership checks
4647
run: git config --global --add safe.directory '*'
4748
- name: init submodules
4849
run: git submodule init
4950
- name: update submodules
5051
run: git submodule update
52+
- name: Check whether a version tag is found and throw error message otherwise.
53+
run: |
54+
if ! [ -n "$(git tag --list 'v[0-9]*.[0-9]*.[0-9]*')" ]; then
55+
echo "ERROR: No version TAG found! A likely explanation is that the PR was created" \
56+
"from a git fork missing the associated tags. If so, here is how to fix it:" \
57+
"https://github.com/DLR-AMR/t8code/wiki/Contribution-workflow#failing-version-tags-in-pr-tests"
58+
exit 1
59+
fi
5160
- name: Install LaTeX dependencies
5261
run: |
5362
sudo apt-get update

mesh_handle/competence_pack.hxx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#pragma once
2828

2929
#include "competences.hxx"
30+
#include "internal/competence_pack_union.hxx"
3031
namespace t8_mesh_handle
3132
{
3233
/** Class to pack different competences into one template parameter for the \ref mesh class.
@@ -53,4 +54,13 @@ using all_cache_competences
5354
using cache_face_competences
5455
= competence_pack<cache_face_areas, cache_face_centroids, cache_face_normals, cache_neighbors>;
5556

57+
/** Compute the unique union of the competences of several \ref t8_mesh_handle::competence_pack 's.
58+
* This produces a new \ref t8_mesh_handle::competence_pack containing all competences of the competence packs
59+
* with duplicates removed.
60+
* \tparam TPacks The competence pack for which we should compute the unique union of the competences.
61+
* Each competence pack is expected to be of type \ref t8_mesh_handle::competence_pack.
62+
*/
63+
template <typename... TPacks>
64+
using union_competence_packs_type = typename detail::union_competence_packs<TPacks...>::type;
65+
5666
} // namespace t8_mesh_handle
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
This file is part of t8code.
3+
t8code is a C library to manage a collection (a forest) of multiple
4+
connected adaptive space-trees of general element classes in parallel.
5+
6+
Copyright (C) 2026 the developers
7+
8+
t8code is free software; you can redistribute it and/or modify
9+
it under the terms of the GNU General Public License as published by
10+
the Free Software Foundation; either version 2 of the License, or
11+
(at your option) any later version.
12+
13+
t8code is distributed in the hope that it will be useful,
14+
but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
GNU General Public License for more details.
17+
18+
You should have received a copy of the GNU General Public License
19+
along with t8code; if not, write to the Free Software Foundation, Inc.,
20+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21+
*/
22+
23+
/** \file competence_pack_union.hxx
24+
* Define the implementation of the unique union of competences of several \ref t8_mesh_handle::competence_pack 's.
25+
* Users should use \ref t8_mesh_handle::union_competence_packs_type in \ref competence_pack.hxx.
26+
*/
27+
28+
#pragma once
29+
30+
#include <type_traits>
31+
32+
namespace t8_mesh_handle
33+
{
34+
35+
/** Forward declaration of the competence pack class.
36+
* \tparam TCompetence The competences to be packed.
37+
*/
38+
template <template <typename> class... TCompetence>
39+
struct competence_pack;
40+
41+
/** Namespace to hide detail from user. */
42+
namespace detail
43+
{
44+
45+
// --- Unique insertion of one competence into a competence pack. ---
46+
/** Helper: Wraps a template-template parameter into a type for comparison.
47+
* Necessary because our competences are templated on the underlying type.
48+
* This allows safe comparison of template templates using std::is_same_v.
49+
* \tparam TType Template-template parameter to wrap.
50+
*/
51+
template <template <class> class TType>
52+
struct tag
53+
{
54+
};
55+
56+
/** Insert competence TCompetence into a pack with competences TUnionCompetences if not already present.
57+
* A new competence_pack is produced.
58+
* \tparam TCompetence Competence to insert.
59+
* \tparam TUnionCompetences Existing competences in the pack.
60+
*/
61+
template <template <class> class TCompetence, template <class> class... TUnionCompetences>
62+
using insert_unique
63+
= std::conditional_t<(std::is_same_v<tag<TCompetence>, tag<TUnionCompetences>> || ...),
64+
competence_pack<TUnionCompetences...>, competence_pack<TUnionCompetences..., TCompetence>>;
65+
66+
//--- Unique fold operation to fold competences into one competence pack without duplication. ---
67+
/** Fold operation to accumulate unique competences.
68+
* Recursively inserts all TCompetences into the competence pack.
69+
* \tparam TCompetencePack Current accumulated competence_pack.
70+
* \tparam TCompetences Competences to process.
71+
*/
72+
template <typename TCompetencePack, template <class> class... TCompetences>
73+
struct fold_unique;
74+
75+
/** Termination case: no more competences to process.
76+
* Specialization for the case when the competence pack is already fully processed and
77+
* no more competences are left to insert.
78+
* \tparam TUnionCompetences Existing competences in the pack.
79+
*/
80+
template <template <class> class... TUnionCompetences>
81+
struct fold_unique<competence_pack<TUnionCompetences...>>
82+
{
83+
/** Final competence pack with all competences inserted. */
84+
using type = competence_pack<TUnionCompetences...>;
85+
};
86+
87+
/** Recursive case: insert the first competence uniquely, then process the rest recursively until
88+
* termination (no competences left).
89+
* Specialization for the case when there is still at least one competence left to process.
90+
* \tparam TUnionCompetences Existing competences in the pack.
91+
* \tparam TCompetence Competence to insert in this recursion cycle.
92+
* \tparam TOtherCompetences Remaining competences to process in the next recursion cycles.
93+
*/
94+
template <template <class> class... TUnionCompetences, template <class> class TCompetence,
95+
template <class> class... TOtherCompetences>
96+
struct fold_unique<competence_pack<TUnionCompetences...>, TCompetence, TOtherCompetences...>
97+
{
98+
/** Competence pack after inserting the first competence TCompetence uniquely. */
99+
using type = typename fold_unique<insert_unique<TCompetence, TUnionCompetences...>, TOtherCompetences...>::type;
100+
};
101+
102+
//--- Unique union of two competence packs. ---
103+
/** Compute the unique union of the competences of two \ref competence_pack 's.
104+
* This produces a new \ref competence_pack containing all competences with duplicates removed.
105+
* \tparam TPack1 First competence pack.
106+
* \tparam TPack2 Second competence pack.
107+
*/
108+
template <typename TPack1, typename TPack2>
109+
struct union_two_competence_packs;
110+
111+
/** Specialization for two \ref competence_pack types.
112+
* This is necessary because this way, we can access the competences directly.
113+
* This specialization of the class above is used if both template parameters are of type \ref competence_pack.
114+
* \tparam TCompetences1 Competences of the first competence pack.
115+
* \tparam TCompetences2 Competences of the second competence pack.
116+
*/
117+
template <template <class> class... TCompetences1, template <class> class... TCompetences2>
118+
struct union_two_competence_packs<competence_pack<TCompetences1...>, competence_pack<TCompetences2...>>
119+
{
120+
/** The resulting competence_pack type with all competences from both packs, but without duplicates.
121+
* The type is computed by folding the unique insertion of all competences from both packs into an
122+
* initially empty pack.
123+
*/
124+
using type = typename fold_unique<competence_pack<>, TCompetences1..., TCompetences2...>::type;
125+
};
126+
127+
//--- Recursive union of multiple competence packs using the implementation for two packs. ---
128+
/** Recursive case: Compute the unique union of the competences of more than one \ref competence_pack 's.
129+
* Specialization for the case when there are still at least two competence packs left to process.
130+
* Uses \ref union_two_competence_packs recursively for pairwise combination.
131+
* \tparam TPack First competence pack to combine with the union of the rest of the competence packs
132+
* in this recursion cycle.
133+
* \tparam TPacks The competence pack for which we should compute the unique union of the competences.
134+
* Each competence pack is expected to be of type \ref competence_pack.
135+
*/
136+
template <typename TPack, typename... TPacks>
137+
struct union_competence_packs
138+
{
139+
/** This is the type of a new \ref competence_pack containing all competences of the competence packs
140+
* with duplicates removed.
141+
*/
142+
using type = typename union_two_competence_packs<TPack, typename union_competence_packs<TPacks...>::type>::type;
143+
};
144+
145+
/** Termination case: Only one pack left.
146+
* Specialization for the case when there is only one competence pack left to process.
147+
* \tparam TPack The only competence pack left.
148+
*/
149+
template <typename TPack>
150+
struct union_competence_packs<TPack>
151+
{
152+
/** Type of the last remaining competence pack. */
153+
using type = TPack;
154+
};
155+
156+
} // namespace detail
157+
} // namespace t8_mesh_handle

0 commit comments

Comments
 (0)