Dune::Copasi
Loading...
Searching...
No Matches
local_equations.hh
Go to the documentation of this file.
1#ifndef DUNE_COPASI_MODEL_LOCAL_EQUATIONS_LOCAL_EQUATIONS_HH
2#define DUNE_COPASI_MODEL_LOCAL_EQUATIONS_LOCAL_EQUATIONS_HH
3
12
13#include <dune/pdelab/concepts/basis.hh>
14#include <dune/pdelab/common/container_entry.hh>
15
16#include <dune/geometry/dimension.hh>
17
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>
23
24#include <function2/function2.hpp>
25#include <spdlog/spdlog.h>
26
27#include <functional>
28#include <utility>
29#include <variant>
30#include <set>
31
33
34// this class holds a data-structure for each equation that contains functors to be evaluated.
35// Additionally, it contains the values with respect these functors may be evaluated if they are
36// non-linear All the functors are require to be thread-safe!
37template<std::size_t dim>
38class LocalEquations : public LocalDomain<dim>
39{
40 using Scalar = FieldVector<double, 1>;
41 using Vector = FieldVector<double, dim>;
42 using Tensor = FieldMatrix<double, dim, dim>;
43
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>;
46
47 LocalEquations() = default;
48public:
51
52 virtual ~LocalEquations() override = default;
53
56
57private:
58 static const Concept::CompartmentScalarLocalBasisNode auto& path_to_local_basis_node(
59 CompartmentPath path,
61 {
62 assert(path[Indices::_1] == 0);
63 return lbasis.child(path[Indices::_2]);
64 }
65
66 static const Concept::CompartmentScalarLocalBasisNode auto& path_to_local_basis_node(
67 CompartmentPath path,
69 {
70 return lbasis.child(path[Indices::_1]).child(path[Indices::_2]);
71 }
72
73 static const Concept::MembraneSubEntitiesLocalBasisNode auto& path_to_local_basis_node(
74 MembranePath path,
76 {
77 assert(path[Indices::_1] == 0);
78 return lbasis.child(path[Indices::_2]);
79 }
80
81 static const Concept::MembraneSubEntitiesLocalBasisNode auto& path_to_local_basis_node(
82 MembranePath path,
83 const Concept::MultiCompartmentLocalBasisNode auto& lbasis)
84 {
85 return lbasis.child(path[Indices::_1]).child(path[Indices::_2]);
86 }
87
88 enum class FactoryFalgs
89 {
90 Reaction = 1 << 0,
91 Diffusion = 1 << 1,
92 Velocity = 1 << 2,
93 Outflow = 1 << 3,
94 Storage = 1 << 4
95 };
96
97public:
98 struct CompartmentNode;
99 struct MembraneNode;
100
101 template<class Signature>
102 struct CompartmentPartialDerivative : public fu2::unique_function<Signature>
103 {
104 CompartmentPartialDerivative(fu2::unique_function<Signature>&& callable,
105 const CompartmentNode& _wrt)
106 : fu2::unique_function<Signature>{ std::move(callable) }
107 , wrt{ _wrt }
108 {
109 }
111 };
112
113 template<class Signature>
114 struct MembranePartialDerivative : public fu2::unique_function<Signature>
115 {
116 MembranePartialDerivative(fu2::unique_function<Signature>&& callable,
117 const MembraneNode& _wrt)
118 : fu2::unique_function<Signature>{ std::move(callable) }
119 , wrt{ _wrt }
120 {
121 }
123 };
124
125 template<class Signature>
126 struct CompartmentDifferentiableFunction : public fu2::unique_function<Signature>
127 {
128 std::vector<CompartmentPartialDerivative<Signature>> compartment_jacobian = {};
129 };
130
131 template<class Signature>
132 struct MembraneDifferentiableFunction : public fu2::unique_function<Signature>
133 {
134 std::vector<CompartmentPartialDerivative<Signature>> compartment_jacobian = {};
135 std::vector<MembranePartialDerivative<Signature>> membrane_jacobian = {};
136 };
137
142
147
150 {
151 CompartmentDiffusionApply(fu2::unique_function<Vector(Vector) const noexcept>&& callable,const CompartmentNode& _wrt)
152 : CompartmentDifferentiableFunction<Vector(Vector) const noexcept>{ std::move(callable) }
153 , wrt{ _wrt }
154 {
155 }
157 };
158
160 : public MembraneDifferentiableFunction<Vector(Vector) const noexcept>
161 {
163 fu2::unique_function<Vector(Vector) const noexcept>&& callable,
164 const MembraneNode& _wrt)
165 : MembraneDifferentiableFunction<Vector(Vector) const noexcept>{ std::move(callable) }
166 , wrt{ _wrt }
167 {
168 }
170 };
171
173 {
174 Scalar& value;
175 Vector& gradient;
176
177 CompartmentPath path;
178 std::string name;
179
183
184 std::vector<CompartmentDiffusionApply> cross_diffusion;
185 std::vector<MembraneScalarFunction> outflow;
186
187 CompartmentNode(Scalar& value, Vector& gradient, CompartmentPath path, const std::string& name) : value{value}, gradient{gradient}, path{path}, name{name} {}
188
190 const PDELab::Concept::LocalBasis auto& lbasis) const
191 {
192 return path_to_local_basis_node(path, lbasis.tree());
193 }
194
195 void debug() const
196 {
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;
201 if (reaction) {
202 std::cout << fmt::format("\tReaction: {}\n", reaction()[0]);
203 for (const auto& jac : reaction.compartment_jacobian)
204 std::cout << fmt::format("\t\tJacobian wrt '{}': {}\n", jac.wrt.name, jac()[0]);
205 }
206 if (storage)
207 std::cout << fmt::format("\tStorage: {}\n", storage()[0]);
208 for (const auto& diffusion : cross_diffusion) {
209 std::cout << fmt::format("\tCross Diffusion wrt '{}': ", diffusion.wrt.name)
210 << diffusion(diffusion.wrt.gradient) << std::endl;
211 for (const auto& jac : diffusion.compartment_jacobian)
212 std::cout << fmt::format("\t\tJacobian wrt '{}': ", jac.wrt.name) << jac(jac.wrt.gradient)
213 << std::endl;
214 }
215 }
216 };
217
219 {
220 Scalar& value;
221 Vector& gradient;
222
223 MembranePath path;
224 std::string name;
225 bool is_linear = false;
226
230
231 std::vector<MembraneDiffusionApply> cross_diffusion;
232 std::vector<MembraneScalarFunction> outflow;
233
235 const PDELab::Concept::LocalBasis auto& lbasis) const
236 {
237 return path_to_local_basis_node(path, lbasis.tree());
238 }
239
240 void debug() const
241 {
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;
246 if (reaction) {
247 std::cout << fmt::format("\tReaction: {}\n", reaction()[0]);
248 for (const auto& jac : reaction.compartment_jacobian)
249 std::cout << fmt::format("\t\tJacobian wrt '{}': {}\n", jac.wrt.name, jac()[0]);
250 }
251 if (storage)
252 std::cout << fmt::format("\tStorage: {}\n", storage()[0]);
253 for (const auto& diffusion : cross_diffusion) {
254 std::cout << fmt::format("\tCross Diffusion wrt '{}': ", diffusion.wrt.name)
255 << diffusion(diffusion.wrt.gradient) << std::endl;
256 for (const auto& jac : diffusion.compartment_jacobian)
257 std::cout << fmt::format("\t\tJacobian wrt '{}': ", jac.wrt.name) << jac(jac.wrt.gradient)
258 << std::endl;
259 }
260 }
261 };
262
263 template<PDELab::Concept::LocalBasis LocalBasis, class CellDataGridView = typename LocalBasis::GlobalBasis::EntitySet, class CellDataType = double>
264 [[nodiscard]] static std::unique_ptr<LocalEquations> make(
265 const LocalBasis& lbasis,
266 const ParameterTree& config = {},
267 std::shared_ptr<const FunctorFactory<dim>> functor_factory = nullptr,
268 std::shared_ptr<const CellData<CellDataGridView, CellDataType>> grid_cell_data = nullptr,
270 {
271 TRACE_EVENT("dune", "LocalEquations::make");
272 auto local_values = std::unique_ptr<LocalEquations>(new LocalEquations{});
273
274 // calculate how many nodes there are
275 std::size_t compartment_count = 0;
276 std::size_t membrane_count = 0;
277 PDELab::forEachLeafNode(
278 lbasis.tree(),
280 [&](const Concept::MembraneScalarLocalBasisNode auto&) { ++membrane_count; }));
282 local_values->_gradients.reserve(compartment_count + membrane_count);
283
284 local_values->initialize_nodes(
285 lbasis.tree(), [&](auto path) { return lbasis.globalBasis().subSpace(path).name(); });
286
287 // check that names are not repeated
288 std::set<std::string_view> names;
289 PDELab::forEach(local_values->_nodes, [&](auto& compartments_fncs) {
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);
295 });
296
297 if (opts.any()) {
298 if (not functor_factory) {
299 throw format_exception(InvalidStateException{}, "Equations cannot be configured without a functor factory");
300 }
302 }
303 return local_values;
304 }
305
306 template<class CellDataGridView, class CellDataType = double>
307 static std::unique_ptr<LocalEquations> make_stiffness(
308 const PDELab::Concept::LocalBasis auto& lbasis,
309 const ParameterTree& config,
310 std::shared_ptr<const FunctorFactory<dim>> functor_factory,
312 )
313 {
314 return make(lbasis,
315 config,
318 FactoryFalgs::Reaction | FactoryFalgs::Diffusion | FactoryFalgs::Velocity |
319 FactoryFalgs::Outflow);
320 }
321
322 template<class CellDataGridView, class CellDataType = double>
323 static std::unique_ptr<LocalEquations> make_mass(
324 const PDELab::Concept::LocalBasis auto& lbasis,
325 const ParameterTree& config,
326 std::shared_ptr<const FunctorFactory<dim>> functor_factory,
328 )
329 {
330 return make(lbasis,
331 config,
334 FactoryFalgs::Storage);
335 }
336
337 template<class Tree>
340 const auto& get_equation(const Tree& tree) const
341 {
342 return PDELab::containerEntry(_nodes, make_path(tree));
343 }
344
345 template<class Tree>
348 auto& get_value(const Tree& tree)
349 {
350 return PDELab::containerEntry(_nodes, make_path(tree)).value;
351 }
352
353 template<class Tree>
356 auto& get_gradient(const Tree& tree)
357 {
358 return PDELab::containerEntry(_nodes, make_path(tree)).gradient;
359 }
360
362 const std::function<void(std::string_view,
364 const FieldVector<double, dim>&)>& apply) const override
365 {
366 PDELab::forEach(nodes(), [&](auto& compartments) {
367 for (auto& compartment_fncs : compartments)
368 for (auto& component_fncs : compartment_fncs)
369 apply(component_fncs.name, component_fncs.value, component_fncs.gradient);
370 });
371 }
372
374 const std::function<void(std::string_view,
376 const FieldVector<double, dim - 1>&)>&) const override
377 {
378 throw format_exception(NotImplemented{}, "...");
379 }
380
381 void clear()
382 {
383 std::fill(begin(_values), end(_values), 0.);
384 std::fill(begin(_gradients), end(_gradients), 0.);
385 }
386
387 void debug() const
388 {
389 PDELab::forEach(_nodes, [&](auto& compartments) {
390 for (auto& compartment_fncs : compartments)
391 for (auto& func : compartment_fncs)
392 func.debug();
393 });
394 }
395
396 const auto& nodes() const { return _nodes; }
397
398private:
399 template<class Tree>
402 auto make_path(const Tree& tree) const
403 {
404 // the tree may be one of many kind of trees
405
406 // membrane/compartment is distinsuihed because the first index is a template parameter
407 // and because they have a different concept requirements
408 auto compartment_type = compartment_index(tree);
409
410 // remove compartment/membrane index (always comes from a tuple and is compile time constant)
411 auto mi = [&]() {
412 auto front_index = front(tree.orderingViewPath());
413 // in some cases, the tree has both comartment types in the tree, then the first index of its
414 // path is an integral constant
415 if constexpr (IsCompileTimeConstant<decltype(front_index)>{}) {
417 return pop_front(tree.orderingViewPath());
418 } else {
419 // otherwise, the tree has only one type of compartments
420 return tree.orderingViewPath();
421 }
422 }();
423 assert(mi.size() <= 2);
424 // all the compartment trees have their field id as their last path in the ordering view path
425 // (different from tree path if membrane)
426 auto field_id = back(mi);
427 // in case of different compartments, the first index (after stripping its compartment type) is
428 // the compartment id
429 auto compartment_id = (mi.size() == 2) ? front(mi) : 0;
430 return TypeTree::treePath(compartment_type, compartment_id, field_id);
431 }
432
433 // (bulk|membrane, compartment, component)
434 TupleVector<std::vector<std::vector<CompartmentNode>>, std::vector<std::vector<MembraneNode>>>
435 _nodes;
436 std::array<std::vector<std::string>, 2> _compartment_names;
437
438 std::vector<Scalar> _values;
439 std::vector<Vector> _gradients;
440
441 auto compartment_index(const Concept::CompartmentLocalBasisTree auto&) const
442 {
443 return Indices::_0;
444 }
445
446 auto compartment_index(const Concept::MembraneLocalBasisTree auto&) const { return Indices::_1; }
447
448 template<class Tree>
449 requires Concept::CompartmentLocalBasisNode<Tree> || Concept::MembraneLocalBasisNode<Tree>
450 void initialize_nodes(const Tree& tree, auto fname, std::size_t c = 0)
451 {
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),
460 fname(tree.child(i).orderingViewPath()));
461 _compartment_names[ct][c] = fname(pop_back(tree.child(i).orderingViewPath()));
462 }
463 }
464
465 template<class Tree>
466 requires Concept::MultiCompartmentLocalBasisNode<Tree> ||
467 Concept::MultiMembraneLocalBasisNode<Tree>
468 void initialize_nodes(const Tree& tree, auto fname)
469 {
470 for (std::size_t c = 0; c != tree.degree(); ++c)
471 initialize_nodes(tree.child(c), fname, c);
472 }
473
474 void initialize_nodes(const Concept::MultiCompartmentMembraneLocalBasisNode auto& tree,
475 auto fname)
476 {
477 using namespace Indices;
478 initialize_nodes(tree.child(_0), fname);
479 initialize_nodes(tree.child(_1), fname);
480 }
481
482 void initialize_nodes(const Concept::CompartmentMembraneLocalBasisNode auto& tree, auto fname)
483 {
484 using namespace Indices;
485 initialize_nodes(tree.child(_0), fname, 0);
486 initialize_nodes(tree.child(_1), fname, 0);
487 }
488
489 template<class CellDataGridView, class CellDataType>
490 void configure(const ParameterTree& config,
491 std::shared_ptr<const FunctorFactory<dim>> functor_factory,
494 {
495
499
500 // configure grid context data
501 if (grid_cell_data) {
502 this->cell_values.resize( grid_cell_data->size() );
503 this->cell_mask.resize( grid_cell_data->size() );
504 this->cell_keys = grid_cell_data->keys();
505 }
506
507 // configure functors
508 auto make_functor = overload(
509 [&](std::string_view prefix, const ParameterTree& config, int codim, ScalarTag)
510 -> fu2::unique_function<Scalar() const noexcept> {
511 return functor_factory->make_scalar(
512 prefix, config, std::as_const(*this), codim);
513 },
514 [&](std::string_view prefix, const ParameterTree& config, int codim, VectorTag)
515 -> fu2::unique_function<Vector() const noexcept> {
516 return functor_factory->make_vector(
517 prefix, config, std::as_const(*this), codim);
518 },
519 [&](std::string_view prefix,
520 const ParameterTree& config,
521 int codim,
523 -> fu2::unique_function<Vector(Vector) const noexcept> {
524 return functor_factory->make_tensor_apply(
525 prefix, config, std::as_const(*this), codim);
526 });
527
530 std::string_view prefix,
532 auto range_tag) {
535 std::set<std::string_view> debug_set;
536 const auto& jac_config = function_config.sub("jacobian");
537 for (const auto& compartment_fncs_jac : _nodes[Indices::_0])
540 if (auto jac =
541 make_functor(fmt::format("{}.jacobian.{}", prefix, component_fncs_jac.name),
543 0,
544 range_tag)) {
545 function.compartment_jacobian.emplace_back(std::move(jac), component_fncs_jac);
546 debug_set.insert(component_fncs_jac.name);
547 }
548 if (jac_config.getSubKeys().size() != debug_set.size())
549 spdlog::warn("Some sub-sections in \"jacobian\" section are being ignored");
550 },
551 [&]<class Signature>(MembraneDifferentiableFunction<Signature>& function,
552 std::string_view prefix,
554 auto range_tag) {
557 const auto& jac_config = function_config.sub("jacobian");
558 for (const auto& compartment_fncs_jac : _nodes[Indices::_0])
561 if (auto jac =
562 make_functor(fmt::format("{}.jacobian.{}", prefix, component_fncs_jac.name),
564 1,
565 range_tag))
566 function.compartment_jacobian.emplace_back(std::move(jac), component_fncs_jac);
567 for (const auto& membrane_fncs_jac : _nodes[Indices::_1])
570 if (auto jac =
571 make_functor(fmt::format("{}.jacobian.{}", prefix, component_fncs_jac.name),
573 1,
574 range_tag))
575 function.membrane_jacobian.emplace_back(std::move(jac), component_fncs_jac);
576 });
577
578 PDELab::forEach(
579 _nodes, [&]<class Node>(std::vector<std::vector<Node>>& compartments_fncs, auto l) {
580 for (auto& compartment_fncs : compartments_fncs) {
582
583 const auto& component_config = config.sub(component_fncs.name, true);
584
585 if (opts.test(FactoryFalgs::Diffusion) and component_config.hasSub("cross_diffusion")) {
586 const auto& cross_diffusion_config = component_config.sub("cross_diffusion");
587 std::set<std::string_view> debug_set;
591 const auto& diffusion_config =
594 auto& cross_diffusion = component_fncs.cross_diffusion.emplace_back(
597 cross_diffusion,
598 fmt::format("{}.cross_diffusion", component_fncs.name),
601 if (not cross_diffusion)
602 component_fncs.cross_diffusion.pop_back();
603 }
604 if (cross_diffusion_config.getSubKeys().size() != debug_set.size())
605 spdlog::warn(
606 "Some sub-sections in \"{}.cross_diffusion\" section are being ignored",
607 component_fncs.name);
608 }
609
610 if (opts.test(FactoryFalgs::Reaction) and component_config.hasSub("reaction"))
612 fmt::format("{}.reaction", component_fncs.name),
613 component_config.sub("reaction"),
614 ScalarTag{});
615
616 if (opts.test(FactoryFalgs::Velocity) and component_config.hasSub("velocity"))
618 fmt::format("{}.velocity", component_fncs.name),
619 component_config.sub("velocity"),
620 VectorTag{});
621
622 if (opts.test(FactoryFalgs::Storage) and component_config.hasSub("storage"))
624 fmt::format("{}.storage", component_fncs.name),
625 component_config.sub("storage"),
626 ScalarTag{});
627
628 if (opts.test(FactoryFalgs::Outflow) and component_config.hasSub("outflow")) {
629 if (l == 1)
631 "Outflow for membranes is not implemented");
632 const auto& boundaries_config = component_config.sub("outflow");
633 for (std::size_t i = 0; i != _compartment_names[l].size(); ++i) {
634 if (boundaries_config.hasSub(_compartment_names[l][i])) {
635 component_fncs.outflow.resize(_compartment_names[l].size());
637 component_fncs.outflow[i],
638 fmt::format("{}.storage.{}", component_fncs.name, _compartment_names[l][i]),
639 boundaries_config.sub(_compartment_names[l][i]),
640 ScalarTag{});
641 }
642 }
643 }
644 }
645 }
646 });
647 }
648};
649
650} // namespace Dune::Copasi::DiffusionReaction
651
652#endif // DUNE_COPASI_MODEL_LOCAL_EQUATIONS_LOCAL_EQUATIONS_HH
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 & 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
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:36
Definition factory.hh:28
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
std::vector< CompartmentPartialDerivative< Signature > > compartment_jacobian
Definition local_equations.hh:128
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
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
CompartmentVectorFunction velocity
Definition local_equations.hh:182
const CompartmentNode & wrt
Definition local_equations.hh:110
CompartmentPartialDerivative(fu2::unique_function< Signature > &&callable, const CompartmentNode &_wrt)
Definition local_equations.hh:104
std::vector< MembranePartialDerivative< Signature > > membrane_jacobian
Definition local_equations.hh:135
std::vector< CompartmentPartialDerivative< Signature > > compartment_jacobian
Definition local_equations.hh:134
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
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
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
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