1#ifndef DUNE_COPASI_MODEL_CONSTRAINTS_HH
2#define DUNE_COPASI_MODEL_CONSTRAINTS_HH
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>
12#include <dune/typetree/leafnode.hh>
14#include <dune/common/parametertree.hh>
16#include <function2/function2.hpp>
27template<Dune::Concept::Gr
idView Gr
idView>
30 constexpr static auto dim = GridView::dimension;
33 std::unique_ptr<LocalDomain<dim>> local_domain;
34 fu2::unique_function<FieldVector<double, 1>()
const noexcept> constrain_fnc;
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) }
48 template<PDELab::Concept::MultiIndex MultiIndex, Dune::Concept::Gr
idView EntitySet>
49 using Container = PDELab::AffineConstraintsContainer<double, MultiIndex, EntitySet>;
52 const ParameterTree& config = {},
53 std::shared_ptr<const FunctorFactory<dim>> functor_factory =
nullptr)
54 : TypeTree::LeafNode()
56 , _data_volume([_config = config.sub(
"volume"),
57 _functor_factory = functor_factory]() -> std::unique_ptr<Data> {
58 if (not _functor_factory)
60 auto local_domain = std::make_unique<LocalDomain<dim>>();
61 local_domain->in_volume = 1;
63 local_domain->time = std::numeric_limits<double>::quiet_NaN();
65 _functor_factory->make_scalar(
"constrain.volume", _config, *local_domain, 0);
66 return std::make_unique<Data>(std::move(local_domain), std::move(constraints));
68 , _data_skeleton([_config = config.sub(
"skeleton"),
69 _functor_factory = functor_factory]() -> std::unique_ptr<Data> {
70 if (not _functor_factory)
72 auto local_domain = std::make_unique<LocalDomain<dim>>();
74 local_domain->time = std::numeric_limits<double>::quiet_NaN();
76 _functor_factory->make_scalar(
"constrain.skeleton", _config, *local_domain, 1);
77 return std::make_unique<Data>(std::move(local_domain), std::move(constraints));
79 , _data_boundary([_config = config.sub(
"boundary"),
80 _functor_factory = functor_factory]() -> std::unique_ptr<Data> {
81 if (not _functor_factory)
83 auto local_domain = std::make_unique<LocalDomain<dim>>();
85 local_domain->time = std::numeric_limits<double>::quiet_NaN();
87 _functor_factory->make_scalar(
"constrain.boundary", _config, *local_domain, 1);
88 return std::make_unique<Data>(std::move(local_domain), std::move(constraints));
93 void constrainVolume(
const PDELab::Concept::LocalBasisLeaf
auto& lbasis,
auto& container)
95 if (lbasis.size() == 0)
98 const auto& entity = lbasis.element();
99 _data_volume->local_domain->entity_volume = entity.geometry().volume();
101 const auto& lkeys = lbasis.finiteElement().localCoefficients();
102 for (std::size_t dof = 0; dof != lbasis.size(); ++dof) {
104 unsigned int codim = lkeys.localKey(dof).codim();
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);
115 const PDELab::Concept::LocalBasisLeaf
auto& lbasis_in,
118 if (lbasis_in.size() == 0)
121 add_intersection_constraints(1,
125 intersection.geometryInInside(),
126 intersection.indexInInside(),
131 const PDELab::Concept::LocalBasisLeaf
auto& lbasis_in,
132 const PDELab::Concept::LocalBasisLeaf
auto& lbasis_out,
135 if (lbasis_in.size() == 0 and lbasis_out.size() == 0)
138 if (lbasis_in.size() != 0)
139 add_intersection_constraints(1,
143 intersection.geometryInInside(),
144 intersection.indexInInside(),
147 if (intersection.neighbor() and lbasis_out.size() != 0)
148 add_intersection_constraints(-1,
152 intersection.geometryInOutside(),
153 intersection.indexInOutside(),
158 auto add_intersection_constraints(
char dir_sign,
161 const auto& intersection,
162 const auto& ig_geometry,
164 auto& container)
const
166 const auto& entity = lbasis.element();
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());
173 const auto& lkeys = lbasis.finiteElement().localCoefficients();
174 for (std::size_t dof = 0; dof != lbasis.size(); ++dof) {
176 unsigned int codim = lkeys.localKey(dof).codim();
180 int sub_entity = lkeys.localKey(dof).subEntity();
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);
197 std::shared_ptr<BoundaryEntityMapper<GridView>> _mapper;
198 PDELab::SharedStash<Data> _data_volume, _data_skeleton, _data_boundary;
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
Definition: local_domain.hh:15