1#ifndef DUNE_COPASI_GRID_MOVE_HH
2#define DUNE_COPASI_GRID_MOVE_HH
7#include <dune/pdelab/common/local_container.hh>
9#include <dune/grid/concepts/geometry.hh>
11#include <dune/geometry/multilineargeometry.hh>
12#include <dune/geometry/quadraturerules.hh>
14#include <dune/common/fvector.hh>
21struct MultiLinearGeometrySimplexTraits : MultiLinearGeometryTraits<ct>
23 template<
int mydim,
int cdim >
26 typedef std::array< FieldVector< ct, cdim > , mydim + 1> Type;
35template<Dune::Concept::Geometry Geometry>
36Dune::Concept::Geometry
auto
38 const PDELab::Concept::LocalBasis
auto& lbasis,
39 const PDELab::Concept::LocalConstContainer
auto& lcoeff,
45 constexpr int mdim = Geometry::mydimension;
46 constexpr int cdim = Geometry::coorddimension;
48 assert(geo.type().isSimplex());
49 assert(geo.corners() == mdim+1);
51 local_eqs->time = time;
52 local_eqs->in_volume = 1;
53 local_eqs->entity_volume = geo.volume();
55 std::array<typename Geometry::GlobalCoordinate, mdim+1> corner_storage;
56 if (local_eqs->domain_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());
66 assert(quad_rule.size() == mdim+1);
68 for (
int i = 0; i != mdim+1; ++i) {
70 forEachLeafNode(lbasis.tree(), [&](
const auto& node) {
73 auto& value = local_eqs->get_value(node);
74 auto& gradient = local_eqs->get_gradient(node);
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];
86 local_eqs->position = geo.corner(i);
88 corner_storage[i] = local_eqs->position + local_eqs->domain_deformation();
92 for (
int i = 0; i != mdim+1; ++i)
93 corner_storage[i] = geo.corner(i);
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();
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