Dune::Copasi 2.1.0-git79717215+dune.gitlab.629933
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages Concepts
move_geometry.hh
Go to the documentation of this file.
1#ifndef DUNE_COPASI_GRID_MOVE_HH
2#define DUNE_COPASI_GRID_MOVE_HH
3
6
7#include <dune/pdelab/common/local_container.hh>
8
9#include <dune/grid/concepts/geometry.hh>
10
11#include <dune/geometry/multilineargeometry.hh>
12#include <dune/geometry/quadraturerules.hh>
13
14#include <dune/common/fvector.hh>
15
16namespace Dune::Copasi {
17
18
19namespace Impl {
20template< class ct >
21struct MultiLinearGeometrySimplexTraits : MultiLinearGeometryTraits<ct>
22{
23 template< int mydim, int cdim >
24 struct CornerStorage
25 {
26 typedef std::array< FieldVector< ct, cdim > , mydim + 1> Type;
27 };
28};
29}
30
35template<Dune::Concept::Geometry Geometry>
36Dune::Concept::Geometry auto
37move_geometry(auto time,
38 const PDELab::Concept::LocalBasis auto& lbasis,
39 const PDELab::Concept::LocalConstContainer auto& lcoeff,
40 auto& local_eqs,
41 auto& fe_cache,
42 const Geometry& geo,
43 auto quad_proj)
44{
45 constexpr int mdim = Geometry::mydimension;
46 constexpr int cdim = Geometry::coorddimension;
47
48 assert(geo.type().isSimplex());
49 assert(geo.corners() == mdim+1);
50
51 local_eqs->time = time;
52 local_eqs->in_volume = 1;
53 local_eqs->entity_volume = geo.volume();
54
55 std::array<typename Geometry::GlobalCoordinate, mdim+1> corner_storage;
56 if (local_eqs->domain_deformation) {
57 // get a quadrature rule with only corner points where we want to evaluate the deformation
58 thread_local auto quad_rule = [](){
59 QuadratureRule<typename Geometry::ctype, mdim> quad_rule;
60 quad_rule.reserve(mdim+1);
61 const auto& ref_el = ReferenceElements<typename Geometry::ctype, mdim>::general(GeometryTypes::simplex(mdim));
62 for (int i = 0; i != ref_el.size(mdim); ++i)
63 quad_rule.emplace_back(ref_el.position(i, mdim), std::numeric_limits<double>::quiet_NaN());
64 return quad_rule;
65 }();
66 assert(quad_rule.size() == mdim+1);
67 // evaluate deformation equations on each corner of the current geometry
68 for (int i = 0; i != mdim+1; ++i) {
69 // load trial functions into the equations cache
70 forEachLeafNode(lbasis.tree(), [&](const auto& node) {
71 if (node.size() == 0)
72 return;
73 auto& value = local_eqs->get_value(node);
74 auto& gradient = local_eqs->get_gradient(node);
75 value = 0.;
76 // we have not created the geometry yet so we cannot evaluate the geometry jacobian
77 // -> using the gradient would require a non-linear dependency on the geometry jacobian
78 gradient = std::numeric_limits<std::decay_t<decltype(gradient)>>::quiet_NaN();
79 fe_cache.bind(node.finiteElement(), quad_rule, quad_proj, true);
80 const auto& phi = fe_cache.evaluateFunction(i);
81 for (std::size_t dof = 0; dof != node.size(); ++dof)
82 value += lcoeff(node, dof) * phi[dof];
83 });
84
85 // [[pre: numbering of reference element corners is the same as for the global geometry]]
86 local_eqs->position = geo.corner(i);
87 // evaluate deformation
88 corner_storage[i] = local_eqs->position + local_eqs->domain_deformation();
89 }
90 } else {
91 // copy corners of old geometry to new geometry
92 for (int i = 0; i != mdim+1; ++i)
93 corner_storage[i] = geo.corner(i);
94 }
95
96 using Traits = Impl::MultiLinearGeometrySimplexTraits<typename Geometry::ctype>;
97 auto new_geo = MultiLinearGeometry<typename Geometry::ctype, mdim, cdim, Traits>(geo.type(), std::move(corner_storage));
98 local_eqs->entity_volume = new_geo.volume();
99 return new_geo;
100}
101
102} // namespace Dune::Copasi
103
104#endif // DUNE_COPASI_GRID_MOVE_HH
Definition: axis_names.hh:7
Dune::Concept::Geometry auto move_geometry(auto time, const PDELab::Concept::LocalBasis auto &lbasis, const PDELab::Concept::LocalConstContainer auto &lcoeff, auto &local_eqs, auto &fe_cache, const Geometry &geo, auto quad_proj)
Moves a geometry based on the local deformation equations.
Definition: move_geometry.hh:37