Dune::Copasi
Loading...
Searching...
No Matches
constraints.hh
Go to the documentation of this file.
1#ifndef DUNE_COPASI_MODEL_CONSTRAINTS_HH
2#define DUNE_COPASI_MODEL_CONSTRAINTS_HH
3
7
8#include <dune/pdelab/basis/constraints/container_affine.hh>
9#include <dune/pdelab/common/concurrency/shared_stash.hh>
10#include <dune/pdelab/concepts/multiindex.hh>
11
12#include <dune/typetree/leafnode.hh>
13
14#include <dune/common/parametertree.hh>
15
16#include <function2/function2.hpp>
17
18namespace Dune::Copasi {
19
27template<Dune::Concept::GridView GridView>
28class Constraints : public TypeTree::LeafNode
29{
30 constexpr static auto dim = GridView::dimension;
31 struct Data
32 {
33 std::unique_ptr<LocalDomain<dim>> local_domain;
34 fu2::unique_function<FieldVector<double, 1>() const noexcept> constrain_fnc;
35 Data(std::unique_ptr<LocalDomain<dim>> local_domain,
36 fu2::unique_function<FieldVector<double, 1>() const noexcept> constrain_fnc)
37 : local_domain{ std::move(local_domain) }
38 , constrain_fnc{ std::move(constrain_fnc) }
39 {
40 }
41 };
42
43public:
44 bool doConstrainBoundary() const { return _data_boundary and _data_boundary->constrain_fnc; }
45 bool doConstrainSkeleton() const { return _data_skeleton and _data_skeleton->constrain_fnc; }
46 bool doConstrainVolume() const { return _data_volume and _data_volume->constrain_fnc; }
47
48 template<PDELab::Concept::MultiIndex MultiIndex, Dune::Concept::GridView EntitySet>
49 using Container = PDELab::AffineConstraintsContainer<double, MultiIndex, EntitySet>;
50
52 const ParameterTree& config = {},
53 std::shared_ptr<const FunctorFactory<dim>> functor_factory = nullptr)
54 : TypeTree::LeafNode()
55 , _mapper{ mapper }
56 , _data_volume([_config = config.sub("volume"),
57 _functor_factory = functor_factory]() -> std::unique_ptr<Data> {
58 if (not _functor_factory)
59 return nullptr;
60 auto local_domain = std::make_unique<LocalDomain<dim>>();
61 local_domain->in_volume = 1;
62 // currently, time-dependent constraints are not possible in a generic way...
63 local_domain->time = std::numeric_limits<double>::quiet_NaN();
64 auto constraints =
65 _functor_factory->make_scalar("constrain.volume", _config, *local_domain, 0);
66 return std::make_unique<Data>(std::move(local_domain), std::move(constraints));
67 })
68 , _data_skeleton([_config = config.sub("skeleton"),
69 _functor_factory = functor_factory]() -> std::unique_ptr<Data> {
70 if (not _functor_factory)
71 return nullptr;
72 auto local_domain = std::make_unique<LocalDomain<dim>>();
73 // currently, time-dependent constraints are not possible in a generic way...
74 local_domain->time = std::numeric_limits<double>::quiet_NaN();
75 auto constraints =
76 _functor_factory->make_scalar("constrain.skeleton", _config, *local_domain, 1);
77 return std::make_unique<Data>(std::move(local_domain), std::move(constraints));
78 })
79 , _data_boundary([_config = config.sub("boundary"),
80 _functor_factory = functor_factory]() -> std::unique_ptr<Data> {
81 if (not _functor_factory)
82 return nullptr;
83 auto local_domain = std::make_unique<LocalDomain<dim>>();
84 // currently, time-dependent constraints are not possible in a generic way...
85 local_domain->time = std::numeric_limits<double>::quiet_NaN();
86 auto constraints =
87 _functor_factory->make_scalar("constrain.boundary", _config, *local_domain, 1);
88 return std::make_unique<Data>(std::move(local_domain), std::move(constraints));
89 })
90 {
91 }
92
93 void constrainVolume(const PDELab::Concept::LocalBasisLeaf auto& lbasis, auto& container)
94 {
95 if (lbasis.size() == 0)
96 return;
97
98 const auto& entity = lbasis.element();
99 _data_volume->local_domain->entity_volume = entity.geometry().volume();
100
101 const auto& lkeys = lbasis.finiteElement().localCoefficients();
102 for (std::size_t dof = 0; dof != lbasis.size(); ++dof) {
103 // the codim to which this dof is attached to
104 unsigned int codim = lkeys.localKey(dof).codim();
105 if (codim != 0)
106 continue;
107 _data_volume->local_domain->position = entity.geometry().center();
108 double constraint = _data_volume->constrain_fnc();
109 if (constraint != std::numeric_limits<double>::max())
110 container.addTranslationConstraint(lbasis.index(dof), constraint);
111 }
112 }
113
114 void constrainBoundary(const Dune::Concept::Intersection auto& intersection,
115 const PDELab::Concept::LocalBasisLeaf auto& lbasis_in,
116 auto& container)
117 {
118 if (lbasis_in.size() == 0)
119 return;
120
121 add_intersection_constraints(1,
122 _data_boundary,
123 lbasis_in,
125 intersection.geometryInInside(),
126 intersection.indexInInside(),
127 container);
128 }
129
130 void constrainSkeleton(const Dune::Concept::Intersection auto& intersection,
131 const PDELab::Concept::LocalBasisLeaf auto& lbasis_in,
132 const PDELab::Concept::LocalBasisLeaf auto& lbasis_out,
133 auto& container)
134 {
135 if (lbasis_in.size() == 0 and lbasis_out.size() == 0)
136 return;
137
138 if (lbasis_in.size() != 0)
139 add_intersection_constraints(1,
140 _data_skeleton,
141 lbasis_in,
143 intersection.geometryInInside(),
144 intersection.indexInInside(),
145 container);
146
147 if (intersection.neighbor() and lbasis_out.size() != 0)
148 add_intersection_constraints(-1,
149 _data_skeleton,
152 intersection.geometryInOutside(),
153 intersection.indexInOutside(),
154 container);
155 }
156
157private:
158 auto add_intersection_constraints(char dir_sign,
159 const auto& data,
160 const auto& lbasis,
161 const auto& intersection,
162 const auto& ig_geometry,
163 auto face,
164 auto& container) const
165 {
166 const auto& entity = lbasis.element();
167 // find dof indices that belong to the intersection
168 const auto& refelem = referenceElement(entity.geometry());
169 data->local_domain->entity_volume = intersection.geometry().volume();
170 data->local_domain->in_boundary = static_cast<double>(not intersection.neighbor());
171 data->local_domain->in_skeleton = static_cast<double>(intersection.neighbor());
172
173 const auto& lkeys = lbasis.finiteElement().localCoefficients();
174 for (std::size_t dof = 0; dof != lbasis.size(); ++dof) {
175 // the codim to which this dof is attached to
176 unsigned int codim = lkeys.localKey(dof).codim();
177 if (codim == 0)
178 continue;
179 // find the reference sub_entity index for this degree of freedom
180 int sub_entity = lkeys.localKey(dof).subEntity();
181
182 for (int j = 0; j != refelem.size(face, 1, codim); ++j) {
183 if (sub_entity == refelem.subEntity(face, 1, j, codim)) {
184 if (data->local_domain->in_boundary == _mapper->isBoundary(entity, sub_entity, codim)) {
185 auto inside_pos = refelem.position(sub_entity, codim);
186 data->local_domain->normal = dir_sign * intersection.unitOuterNormal(ig_geometry.local(inside_pos));
187 data->local_domain->position = entity.geometry().global(inside_pos);
188 double constraint = data->constrain_fnc();
189 if (constraint != std::numeric_limits<double>::max())
190 container.addTranslationConstraint(lbasis.index(dof), constraint);
191 }
192 }
193 }
194 }
195 };
196
197 std::shared_ptr<BoundaryEntityMapper<GridView>> _mapper;
198 PDELab::SharedStash<Data> _data_volume, _data_skeleton, _data_boundary;
199};
200
201} // namespace Dune::Copasi
202
203#endif // DUNE_COPASI_MODEL_CONSTRAINTS_HH
Mapper of boundary entities.
Definition boundary_entity_mapper.hh:26
Constraints parser and operator for a leaf basis.
Definition constraints.hh:29
PDELab::AffineConstraintsContainer< double, MultiIndex, EntitySet > Container
Definition constraints.hh:49
bool doConstrainBoundary() const
Definition constraints.hh:44
void constrainBoundary(const Dune::Concept::Intersection auto &intersection, const PDELab::Concept::LocalBasisLeaf auto &lbasis_in, auto &container)
Definition constraints.hh:114
Constraints(std::shared_ptr< BoundaryEntityMapper< GridView > > mapper, const ParameterTree &config={}, std::shared_ptr< const FunctorFactory< dim > > functor_factory=nullptr)
Definition constraints.hh:51
bool doConstrainVolume() const
Definition constraints.hh:46
void constrainSkeleton(const Dune::Concept::Intersection auto &intersection, const PDELab::Concept::LocalBasisLeaf auto &lbasis_in, const PDELab::Concept::LocalBasisLeaf auto &lbasis_out, auto &container)
Definition constraints.hh:130
void constrainVolume(const PDELab::Concept::LocalBasisLeaf auto &lbasis, auto &container)
Definition constraints.hh:93
bool doConstrainSkeleton() const
Definition constraints.hh:45
Definition axis_names.hh:7
constexpr bool is_bitflags_v
Alias for Bitflag indicator.
Definition bit_flags.hh:24
Definition local_domain.hh:15