Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
SimplexFactory.h
Go to the documentation of this file.
1/* This file is part of MoDELib, distributed under GNU GPL v2. */
2#ifndef model_SimplexFactory_H_
3#define model_SimplexFactory_H_
4#include <WeakPtrFactories.h>
5#include <SimplexTraits.h>
6#include <tuple>
7#include <stdexcept>
8namespace model
9{
10 template <int dim> class SimplicialMesh;
11 template <short int dim, short int order> class Simplex;
12
13 template <short int dim, short int order>
14 struct SimplexFactory : WeakPtrFactory<SimplexFactory<dim, order>, Simplex<dim, order>>
15 {
18 using Pointer = std::shared_ptr<Simplex<dim, order>>;
20
21 SimplexFactory() = default;
22 SimplexFactory(const SimplexFactory &) = delete;
24
25 private:
26 using Base::create;
27
28 public:
29 template <typename... Args> Pointer getOrCreate(const KeyType &input, const Args &...args)
30 {
31 const auto key = SimplexTraits<dim, order>::sortID(input);
32 if (const auto existing = Base::get(key))
33 {
34 if constexpr (order == dim)
35 {
36 static_assert(sizeof...(Args) == 1);
37 if (existing->region->regionID != size_t(std::get<0>(std::tie(args...))))
38 {
39 throw std::runtime_error("A volume simplex cannot belong to two regions");
40 }
41 }
42 return existing;
43 }
44 const auto simplex = Base::create(key, args...);
45 if constexpr (order > 0)
46 {
47 // Construction is complete: weak parents can now reference its control block.
48 for (const auto &child : simplex->children())
49 {
50 child->addParent(simplex);
51 }
52 }
53 return simplex;
54 }
55 auto liveSimplices() const
56 {
57 std::map<KeyType, Pointer> result;
58 for (const auto &entry : *this)
59 {
60 if (const auto simplex = entry.second.lock())
61 {
62 result.emplace(entry.first, simplex);
63 }
64 }
65 return result;
66 }
68 {
69 for (auto entry = this->begin(); entry != this->end();)
70 {
71 if (entry->second.expired())
72 {
73 entry = this->erase(entry);
74 }
75 else
76 {
77 ++entry;
78 }
79 }
80 }
81 auto faces(const KeyType &id)
82 requires(order > 0)
83 {
85 for (size_t k = 0; k < result.size(); ++k)
86 {
87 result[k] =
88 mesh->template simplexFactory<order - 1>().getOrCreate(SimplexTraits<dim, order>::faceID(id, k));
89 }
90 return result;
91 }
92 };
93 template <int dim, typename Sequence> struct SimplexFactoryTuple;
94 template <int dim, size_t... orders> struct SimplexFactoryTuple<dim, std::index_sequence<orders...>>
95 {
96 using Type = std::tuple<SimplexFactory<dim, short(orders)>...>;
97 };
98 template <int dim> class SimplexFactories
99 {
101
102 public:
104 {
105 std::apply([owner](auto &...factory) { ((factory.mesh = owner), ...); }, factories);
106 }
107 template <short int order> auto &factory()
108 {
109 return std::get<order>(factories);
110 }
111 template <short int order> const auto &factory() const
112 {
113 return std::get<order>(factories);
114 }
115 void clear()
116 {
117 std::apply([](auto &...factory) { (factory.clear(), ...); }, factories);
118 }
119 };
120} // namespace model
121#endif
const auto & factory() const
SimplexFactories(SimplicialMesh< dim > *owner)
SimplexFactory & operator=(const SimplexFactory &)=delete
auto liveSimplices() const
SimplicialMesh< dim > * mesh
SimplexFactory(const SimplexFactory &)=delete
auto faces(const KeyType &id)
WeakPtrFactory< SimplexFactory< dim, order >, Simplex< dim, order > > Base
std::shared_ptr< Simplex< dim, order > > Pointer
typename SimplexTraits< dim, order >::SimplexIDType KeyType
Pointer getOrCreate(const KeyType &input, const Args &...args)
std::tuple< SimplexFactory< dim, short(orders)>... > Type
static SimplexTraits< dim, order-1 >::SimplexIDType faceID(const SimplexIDType &xID, const size_t &j)
static SimplexIDType sortID(const SimplexIDType &vIN)
std::array< std::shared_ptr< Simplex< dim, order-1 > >, nFaces > BaseArrayType
SimplexID< nVertices > SimplexIDType
int end[2]
b order
int k
newbad key
result