1#ifndef DUNE_COPASI_MODEL_LOCAL_EQUATIONS_LOCAL_EQUATIONS_HH
2#define DUNE_COPASI_MODEL_LOCAL_EQUATIONS_LOCAL_EQUATIONS_HH
13#include <dune/pdelab/concepts/basis.hh>
14#include <dune/pdelab/common/container_entry.hh>
16#include <dune/geometry/dimension.hh>
18#include <dune/common/fvector.hh>
19#include <dune/common/indices.hh>
20#include <dune/common/overloadset.hh>
21#include <dune/common/parametertree.hh>
22#include <dune/common/tuplevector.hh>
24#include <function2/function2.hpp>
25#include <spdlog/spdlog.h>
37template<std::
size_t dim>
44 using CompartmentPath = TypeTree::HybridTreePath<index_constant<0>, std::size_t, std::size_t>;
45 using MembranePath = TypeTree::HybridTreePath<index_constant<1>, std::size_t, std::size_t>;
62 assert(path[Indices::_1] == 0);
63 return lbasis.child(path[Indices::_2]);
70 return lbasis.child(path[Indices::_1]).child(path[Indices::_2]);
77 assert(path[Indices::_1] == 0);
78 return lbasis.child(path[Indices::_2]);
81 static const Concept::MembraneSubEntitiesLocalBasisNode
auto& path_to_local_basis_node(
83 const Concept::MultiCompartmentLocalBasisNode
auto&
lbasis)
85 return lbasis.child(path[Indices::_1]).child(path[Indices::_2]);
88 enum class FactoryFalgs
98 struct CompartmentNode;
101 template<
class Signature>
113 template<
class Signature>
125 template<
class Signature>
131 template<
class Signature>
163 fu2::unique_function<Vector(Vector)
const noexcept>&&
callable,
190 const PDELab::Concept::LocalBasis
auto&
lbasis)
const
192 return path_to_local_basis_node(
path,
lbasis.tree());
197 std::cout << fmt::format(
"Name: {}\n",
name);
198 std::cout <<
"\tPath: " <<
path << std::endl;
199 std::cout << fmt::format(
"\tValue: {}\n",
value[0]);
200 std::cout <<
"\tGradient: " <<
gradient << std::endl;
202 std::cout << fmt::format(
"\tReaction: {}\n",
reaction()[0]);
204 std::cout << fmt::format(
"\t\tJacobian wrt '{}': {}\n",
jac.wrt.name,
jac()[0]);
207 std::cout << fmt::format(
"\tStorage: {}\n",
storage()[0]);
209 std::cout << fmt::format(
"\tCross Diffusion wrt '{}': ",
diffusion.wrt.name)
212 std::cout << fmt::format(
"\t\tJacobian wrt '{}': ",
jac.wrt.name) <<
jac(
jac.wrt.gradient)
235 const PDELab::Concept::LocalBasis
auto&
lbasis)
const
237 return path_to_local_basis_node(
path,
lbasis.tree());
242 std::cout << fmt::format(
"Name: {}\n",
name);
243 std::cout <<
"\tPath: " <<
path << std::endl;
244 std::cout << fmt::format(
"\tValue: {}\n",
value[0]);
245 std::cout <<
"\tGradient: " <<
gradient << std::endl;
247 std::cout << fmt::format(
"\tReaction: {}\n",
reaction()[0]);
249 std::cout << fmt::format(
"\t\tJacobian wrt '{}': {}\n",
jac.wrt.name,
jac()[0]);
252 std::cout << fmt::format(
"\tStorage: {}\n",
storage()[0]);
254 std::cout << fmt::format(
"\tCross Diffusion wrt '{}': ",
diffusion.wrt.name)
257 std::cout << fmt::format(
"\t\tJacobian wrt '{}': ",
jac.wrt.name) <<
jac(
jac.wrt.gradient)
263 template<PDELab::Concept::LocalBasis LocalBasis,
class CellDataGr
idView =
typename LocalBasis::GlobalBasis::EntitySet,
class CellDataType =
double>
268 std::shared_ptr<const CellData<CellDataGridView, CellDataType>>
grid_cell_data =
nullptr,
277 PDELab::forEachLeafNode(
280 [&](
const Concept::MembraneScalarLocalBasisNode
auto&) { ++
membrane_count; }));
285 lbasis.tree(), [&](
auto path) { return lbasis.globalBasis().subSpace(path).name(); });
288 std::set<std::string_view>
names;
290 for (const auto& compartment_fncs : compartments_fncs)
291 for (const auto& component_fncs : compartment_fncs)
292 if (auto [it, inserted] = names.insert(component_fncs.name); not inserted)
293 throw format_exception(
294 InvalidStateException{},
"\tVariable with name '{}' is repeated", *
it);
306 template<
class CellDataGr
idView,
class CellDataType =
double>
308 const PDELab::Concept::LocalBasis
auto&
lbasis,
318 FactoryFalgs::Reaction | FactoryFalgs::Diffusion | FactoryFalgs::Velocity |
319 FactoryFalgs::Outflow);
322 template<
class CellDataGr
idView,
class CellDataType =
double>
324 const PDELab::Concept::LocalBasis
auto&
lbasis,
334 FactoryFalgs::Storage);
342 return PDELab::containerEntry(_nodes, make_path(
tree));
350 return PDELab::containerEntry(_nodes, make_path(
tree)).value;
358 return PDELab::containerEntry(_nodes, make_path(
tree)).gradient;
362 const std::function<
void(std::string_view,
374 const std::function<
void(std::string_view,
383 std::fill(
begin(_values),
end(_values), 0.);
384 std::fill(
begin(_gradients),
end(_gradients), 0.);
396 const auto&
nodes()
const {
return _nodes; }
402 auto make_path(
const Tree&
tree)
const
420 return tree.orderingViewPath();
436 std::array<std::vector<std::string>, 2> _compartment_names;
438 std::vector<Scalar> _values;
439 std::vector<Vector> _gradients;
441 auto compartment_index(
const Concept::CompartmentLocalBasisTree
auto&)
const
446 auto compartment_index(
const Concept::MembraneLocalBasisTree
auto&)
const {
return Indices::_1; }
449 requires Concept::CompartmentLocalBasisNode<Tree> || Concept::MembraneLocalBasisNode<Tree>
450 void initialize_nodes(
const Tree&
tree,
auto fname, std::size_t
c = 0)
452 auto ct = compartment_index(
tree);
453 _nodes[
ct].resize(
c + 1);
454 _nodes[
ct][
c].clear();
455 _compartment_names[
ct].resize(
c + 1);
456 for (std::size_t
i = 0;
i !=
tree.degree(); ++
i) {
457 _nodes[
ct][
c].emplace_back(_values.emplace_back(),
458 _gradients.emplace_back(),
459 TypeTree::treePath(
ct,
c,
i),
466 requires Concept::MultiCompartmentLocalBasisNode<Tree> ||
467 Concept::MultiMembraneLocalBasisNode<Tree>
470 for (std::size_t
c = 0;
c !=
tree.degree(); ++
c)
474 void initialize_nodes(
const Concept::MultiCompartmentMembraneLocalBasisNode
auto&
tree,
482 void initialize_nodes(
const Concept::CompartmentMembraneLocalBasisNode
auto&
tree,
auto fname)
489 template<
class CellDataGr
idView,
class CellDataType>
510 -> fu2::unique_function<Scalar()
const noexcept> {
515 -> fu2::unique_function<Vector()
const noexcept> {
519 [&](std::string_view
prefix,
523 -> fu2::unique_function<Vector(Vector)
const noexcept> {
549 spdlog::warn(
"Some sub-sections in \"jacobian\" section are being ignored");
594 auto& cross_diffusion =
component_fncs.cross_diffusion.emplace_back(
601 if (
not cross_diffusion)
606 "Some sub-sections in \"{}.cross_diffusion\" section are being ignored",
631 "Outflow for membranes is not implemented");
633 for (std::size_t
i = 0;
i != _compartment_names[
l].size(); ++
i) {
638 fmt::format(
"{}.storage.{}",
component_fncs.name, _compartment_names[
l][
i]),
Bit flags for enumerators.
Definition bit_flags.hh:47
static constexpr BitFlags< Enum > no_flags()
Bitflag with all flags turned off.
Definition bit_flags.hh:70
Container for cell data of a grid view.
Definition cell_data.hh:25
Definition local_equations.hh:39
void forEachValue(Codim< 1 >, const std::function< void(std::string_view, const FieldVector< double, 1 > &, const FieldVector< double, dim - 1 > &)> &) const override
Definition local_equations.hh:373
LocalEquations & operator=(LocalEquations &&)=delete
void clear()
Definition local_equations.hh:381
static std::unique_ptr< LocalEquations > make(const LocalBasis &lbasis, const ParameterTree &config={}, std::shared_ptr< const FunctorFactory< dim > > functor_factory=nullptr, std::shared_ptr< const CellData< CellDataGridView, CellDataType > > grid_cell_data=nullptr, BitFlags< FactoryFalgs > opts=BitFlags< FactoryFalgs >::no_flags())
Definition local_equations.hh:264
auto & get_gradient(const Tree &tree)
Definition local_equations.hh:356
const auto & nodes() const
Definition local_equations.hh:396
static std::unique_ptr< LocalEquations > make_stiffness(const PDELab::Concept::LocalBasis auto &lbasis, const ParameterTree &config, std::shared_ptr< const FunctorFactory< dim > > functor_factory, std::shared_ptr< const CellData< CellDataGridView, CellDataType > > grid_cell_data)
Definition local_equations.hh:307
LocalEquations(const LocalEquations &)=delete
LocalEquations(LocalEquations &&)=delete
LocalEquations & operator=(const LocalEquations &)=delete
void forEachValue(Codim< 0 >, const std::function< void(std::string_view, const FieldVector< double, 1 > &, const FieldVector< double, dim > &)> &apply) const override
Definition local_equations.hh:361
virtual ~LocalEquations() override=default
void debug() const
Definition local_equations.hh:387
auto & get_value(const Tree &tree)
Definition local_equations.hh:348
static std::unique_ptr< LocalEquations > make_mass(const PDELab::Concept::LocalBasis auto &lbasis, const ParameterTree &config, std::shared_ptr< const FunctorFactory< dim > > functor_factory, std::shared_ptr< const CellData< CellDataGridView, CellDataType > > grid_cell_data)
Definition local_equations.hh:323
const auto & get_equation(const Tree &tree) const
Definition local_equations.hh:340
Definition functor_factory.hh:24
Definition compartment_tree.hh:30
Definition compartment_tree.hh:20
Definition compartment_tree.hh:36
Definition compartment_tree.hh:25
Definition compartment_tree.hh:42
Definition compartment_tree.hh:61
auto format_exception(Exception &&e, fmt::format_string< Args... > format, Args &&... args)
Definition exceptions.hh:23
constexpr bool is_bitflags_v
Alias for Bitflag indicator.
Definition bit_flags.hh:24
Definition local_equations.hh:127
std::vector< CompartmentPartialDerivative< Signature > > compartment_jacobian
Definition local_equations.hh:128
Definition local_equations.hh:150
const CompartmentNode & wrt
Definition local_equations.hh:156
CompartmentDiffusionApply(fu2::unique_function< Vector(Vector) const noexcept > &&callable, const CompartmentNode &_wrt)
Definition local_equations.hh:151
Definition local_equations.hh:173
CompartmentScalarFunction storage
Definition local_equations.hh:181
std::vector< MembraneScalarFunction > outflow
Definition local_equations.hh:185
std::vector< CompartmentDiffusionApply > cross_diffusion
Definition local_equations.hh:184
std::string name
Definition local_equations.hh:178
void debug() const
Definition local_equations.hh:195
CompartmentScalarFunction reaction
Definition local_equations.hh:180
CompartmentNode(Scalar &value, Vector &gradient, CompartmentPath path, const std::string &name)
Definition local_equations.hh:187
Vector & gradient
Definition local_equations.hh:175
const Concept::CompartmentScalarLocalBasisNode auto & to_local_basis_node(const PDELab::Concept::LocalBasis auto &lbasis) const
Definition local_equations.hh:189
CompartmentPath path
Definition local_equations.hh:177
Scalar & value
Definition local_equations.hh:174
CompartmentVectorFunction velocity
Definition local_equations.hh:182
Definition local_equations.hh:103
const CompartmentNode & wrt
Definition local_equations.hh:110
CompartmentPartialDerivative(fu2::unique_function< Signature > &&callable, const CompartmentNode &_wrt)
Definition local_equations.hh:104
Definition local_equations.hh:133
std::vector< MembranePartialDerivative< Signature > > membrane_jacobian
Definition local_equations.hh:135
std::vector< CompartmentPartialDerivative< Signature > > compartment_jacobian
Definition local_equations.hh:134
Definition local_equations.hh:161
const MembraneNode & wrt
Definition local_equations.hh:169
MembraneDiffusionApply(fu2::unique_function< Vector(Vector) const noexcept > &&callable, const MembraneNode &_wrt)
Definition local_equations.hh:162
Definition local_equations.hh:219
void debug() const
Definition local_equations.hh:240
MembranePath path
Definition local_equations.hh:223
Scalar & value
Definition local_equations.hh:220
std::vector< MembraneDiffusionApply > cross_diffusion
Definition local_equations.hh:231
bool is_linear
Definition local_equations.hh:225
MembraneScalarFunction storage
Definition local_equations.hh:228
std::string name
Definition local_equations.hh:224
Vector & gradient
Definition local_equations.hh:221
const Concept::MembraneSubEntitiesLocalBasisNode auto & to_local_basis_node(const PDELab::Concept::LocalBasis auto &lbasis) const
Definition local_equations.hh:234
MembraneScalarFunction reaction
Definition local_equations.hh:227
std::vector< MembraneScalarFunction > outflow
Definition local_equations.hh:232
MembraneVectorFunction velocity
Definition local_equations.hh:229
Definition local_equations.hh:115
const MembraneNode & wrt
Definition local_equations.hh:122
MembranePartialDerivative(fu2::unique_function< Signature > &&callable, const MembraneNode &_wrt)
Definition local_equations.hh:116
Definition local_domain.hh:15