9#include <kernel/assembly/base.hpp>
10#include <kernel/assembly/unit_filter_assembler.hpp>
11#include <kernel/lafem/slip_filter.hpp>
12#include <kernel/lafem/sparse_vector_blocked.hpp>
13#include <kernel/geometry/mesh_node.hpp>
14#include <kernel/geometry/intern/face_index_mapping.hpp>
15#include <kernel/space/lagrange1/element.hpp>
16#include <kernel/space/lagrange2/element.hpp>
29 template<
typename Space_,
int shape_dim_ = Space_::shape_dim>
30 class Lagrange2InterpolatorWrapper;
59 template<
typename Trafo_>
74 static constexpr int facet_dim = ShapeType::dimension-1;
76 static constexpr int world_dim = MeshType::world_dim;
109 const auto& idx_vert_at_facet(mesh.template get_index_set<facet_dim, 0>());
110 const auto& idx_vert_at_shape(mesh.template get_index_set<ShapeType::dimension, 0>());
111 const auto& idx_facet_at_shape(mesh.template get_index_set<ShapeType::dimension, facet_dim>());
114 typename MeshType::template IndexSet<facet_dim, 0>::Type::IndexTupleType reference_numbering;
116 typename MeshType::template IndexSet<facet_dim, 0>::Type::IndexTupleType my_numbering;
117 Index num_elements = mesh.get_num_elements();
120 FEAT_PRAGMA_OMP(parallel
for)
121 for(
Index k = 0; k < num_elements; ++k)
124 for(
int l(0); l < Shape::FaceTraits<ShapeType, facet_dim>::count; ++l)
127 Index parent_l(idx_facet_at_shape[k][l]);
130 if(facets[parent_l] != ~
Index(0))
133 for(
int i(0); i <
nvt_loc; ++i)
136 int j(Geometry::Intern::FaceIndexMapping<ShapeType, facet_dim, 0>::map(l,i));
137 reference_numbering[i] = idx_vert_at_shape[k][j];
140 my_numbering[i] = idx_vert_at_facet[parent_l][i];
145 int orientation_code = Geometry::Intern::CongruencySampler<FacetType>::compare(reference_numbering, my_numbering);
150 Geometry::Intern::CongruencySampler<FacetType>::orientation(orientation_code)
186 template<
typename VectorType_,
typename TrafoType_>
191 const TrafoType_& trafo)
193 typedef typename VectorType_::DataType DataType;
195 nu.format(DataType(0));
197 auto& idx(trafo.get_mesh().template get_index_set<facet_dim,0>());
202 typename TrafoType_::template Evaluator<FacetType, CoordType>::Type facet_evaluator(trafo);
206 for(
Index k(0); k < trafo.get_mesh().get_num_entities(
facet_dim); ++k)
208 if(facets[k] != ~
Index(0) )
210 facet_evaluator.prepare(k);
211 CoordType vol = facet_evaluator.volume();
212 facet_evaluator.finish();
219 for(
int l(0); l <
nvt_loc; ++l)
221 tmp = nu(idx[k][l]) + nu_loc[l]*DataType(orientation[k]*vol);
248 template<
typename TrafoType_>
252 typedef typename TrafoType_::template Evaluator<FacetType, CoordType>::Type FaceEvaluator;
254 typedef typename FaceEvaluator::JacobianMatrixType JacobianMatrixType;
257 FaceEvaluator trafo_eval(trafo);
258 trafo_eval.prepare(k);
262 for(
int i(0); i <
nvt_loc; ++i)
264 for(
int d(0); d < ShapeType::dimension - 1 ; ++d)
275 for(
int i(0); i <
nvt_loc; ++i)
281 trafo_eval.calc_jac_mat(
jac_mat, xloc[i]);
308 template<
typename Trafo_>
356 for(
int i(0); i < MeshType::shape_dim+1; ++i)
386 this->_recompute =
true;
387 const auto& facet_target(meshpart.template get_target_set<facet_dim>());
389 for(
Index l(0); l < facet_target.get_num_entities(); l++)
422 Geometry::Intern::template TargetSetComputer<facet_dim, 0>::top_to_bottom(
448 template<
typename DataType_,
typename IndexType_>
452 if(filter.get_nu().size() ==
Index(0))
469 filter.get_filter_vector().clone(filter.get_nu());
497 template<
typename DataType_,
typename IndexType_>
503 const auto& mesh = space.
get_trafo().get_mesh();
506 if(filter.get_nu().size() ==
Index(0))
524 if(filter.get_nu().used_elements() >
Index(0))
526 Intern::Lagrange2InterpolatorWrapper<SpaceType>::project(
530 auto* nu = filter.get_values();
531 for(
Index i(0); i < filter.used_elements(); ++i)
547 template<
typename Vector_,
typename Space_,
int shape_dim_>
548 struct Lagrange2InterpolatorCore
551 template<
typename TSH_>
552 static void project(Vector_& lagrange_2_vector,
const Vector_& lagrange_1_vector,
const Space_& space,
const TSH_* tsh)
554 typedef typename Vector_::DataType DataType;
555 typedef typename Vector_::ValueType ValueType;
558 typedef typename Space_::template DofAssignment<shape_dim_, DataType>::Type DofAssignType;
559 DofAssignType dof_assign(space);
562 if(dof_assign.get_max_assigned_dofs() < 1)
566 auto& idx(space.get_trafo().get_mesh().template get_index_set<shape_dim_, 0>());
571 const Index num_shapes = space.get_mesh().get_num_entities(shape_dim_);
572 for(
Index shape(0); shape < num_shapes; ++shape)
574 ValueType tmp(DataType(0));
577 for(
int j(0); j < idx.get_num_indices(); ++j)
578 tmp += lagrange_1_vector(idx(shape, j));
580 tmp *= DataType(1)/DataType(idx.get_num_indices());
584 dof_assign.prepare(shape);
587 Index dof_index(dof_assign.get_index(0));
588 lagrange_2_vector(dof_index, tmp);
596 auto& ts = tsh->template get_target_set<shape_dim_>();
599 const Index num_shapes = ts.get_num_entities();
601 for(Index shape(0); shape < num_shapes; ++shape)
603 ValueType tmp(DataType(0));
606 for(
int j(0); j < idx.get_num_indices(); ++j)
607 tmp += lagrange_1_vector(idx(ts[shape], j));
609 tmp *= DataType(1)/DataType(idx.get_num_indices());
613 dof_assign.prepare(ts[shape]);
616 Index dof_index(dof_assign.get_index(0));
617 lagrange_2_vector(dof_index, tmp);
626 template<
typename Vector_,
typename Space_>
627 struct Lagrange2InterpolatorCore<Vector_, Space_, 0>
630 template<
typename TSH_>
631 static void project(Vector_& lagrange_2_vector,
const Vector_& lagrange_1_vector,
const Space_& space,
const TSH_* tsh)
633 typedef typename Vector_::DataType DataType;
634 typedef typename Vector_::ValueType ValueType;
637 typedef typename Space_::template DofAssignment<0, DataType>::Type DofAssignType;
638 DofAssignType dof_assign(space);
643 const Index num_verts = space.get_mesh().get_num_entities(0);
644 for(Index vert(0); vert < num_verts; ++vert)
647 dof_assign.prepare(vert);
650 Index dof_index(dof_assign.get_index(0));
653 ValueType tmp(lagrange_1_vector(vert));
654 lagrange_2_vector(dof_index, tmp);
662 auto& ts = tsh->template get_target_set<0>();
664 const Index num_verts = ts.get_num_entities();
665 for(Index vert(0); vert < num_verts; ++vert)
668 dof_assign.prepare(ts[vert]);
671 Index dof_index(dof_assign.get_index(0));
674 ValueType tmp(lagrange_1_vector(ts[vert]));
675 lagrange_2_vector(dof_index, tmp);
684 template<
typename Space_,
int shape_dim_>
685 class Lagrange2InterpolatorWrapper
688 template<
typename Vector_,
typename TSH_>
689 static void project(Vector_& lagrange_2_vector,
const Vector_& lagrange_1_vector,
const Space_& space,
const TSH_* tsh)
692 Lagrange2InterpolatorWrapper<Space_, shape_dim_ - 1>::project(lagrange_2_vector, lagrange_1_vector, space, tsh);
695 Lagrange2InterpolatorCore<Vector_, Space_, shape_dim_>::project(lagrange_2_vector, lagrange_1_vector, space, tsh);
699 template<
typename Space_>
700 class Lagrange2InterpolatorWrapper<Space_, 0>
703 template<
typename Vector_,
typename TSH_>
704 static void project(Vector_& lagrange_2_vector,
const Vector_& lagrange_1_vector,
const Space_& space,
const TSH_* tsh)
707 Lagrange2InterpolatorCore<Vector_, Space_, 0>::project(lagrange_2_vector, lagrange_1_vector, space, tsh);
Helper class that computes a weighted outer unit normal field.
MeshType::CoordType CoordType
Floating point type.
static void compute_orientations(CoordType *orientation, const Index *facets, const MeshType &mesh)
Computes facet orientations.
TrafoType::MeshType MeshType
The underlying mesh type.
static constexpr int facet_dim
The shape dimension of the boundary faces.
static constexpr int world_dim
The number of coordinates for each vertex.
Shape::FaceTraits< ShapeType, ShapeType::dimension-1 >::ShapeType FacetType
Shape of the facets that make up the boundary we want to compute the normals for,.
static Tiny::Matrix< CoordType, nvt_loc, MeshType::world_dim > compute_oriented_normals(const TrafoType_ &trafo, Index k)
Computes all oriented normals on one face.
Trafo_ TrafoType
Type for the transformation.
static constexpr int nvt_loc
The number of vertices that make up a Facet, i.e. 4 for a Hypercube<2>
MeshType::ShapeType ShapeType
Shape of the mesh's cells.
static void compute_outer_unit_normal(VectorType_ &nu, const Index *facets, const CoordType *orientation, const TrafoType_ &trafo)
Computes an outer unit normal field.
Contains routines to assemble slip filters.
virtual ~SlipFilterAssembler()
Virtual destructor.
SlipFilterAssembler(const TrafoType &trafo)
Constructor from mesh.
SlipFilterAssembler & operator=(SlipFilterAssembler &&)=delete
Explicitly delete the move assignment operator.
static constexpr int world_dim
The number of coordinates for each vertex.
bool _recompute
Flag when to recompute _facets and _orientation (i.e. if MeshParts get added)
void assemble(LAFEM::SlipFilter< DataType_, IndexType_, world_dim > &filter, const Space::Lagrange2::Element< Trafo_ > &space)
Assembles a homogeneous SlipFilter for a Lagrange 2 FE space.
void add_mesh_part(const Geometry::MeshPart< MeshType > &meshpart)
Adds a MeshPart to the assembler.
Trafo_ TrafoType
the trafo type
SlipFilterAssembler(SlipFilterAssembler &&)=delete
Explicitly delete the move constructor.
MeshType::CoordType CoordType
Floating point type.
Geometry::TargetSetHolder< typename MeshType::ShapeType > TargetSetHolderType
Type for the mapping of slip boundary entities to mesh entities.
std::vector< CoordType > _orientation
For every facet in the mesh, this is its orientation in the mesh.
TrafoType::MeshType MeshType
The mesh type.
static constexpr int facet_dim
shape dimension
void recompute_target_set_holder(const MeshType &mesh)
Recomputes the target mapping for geometric entities.
const TrafoType & _trafo
a reference to the trafo that we want to assemble on
std::vector< Index > _facets
Facets for the slip condition get marked by this.
Index _num_entities[MeshType::shape_dim+1]
Number of entities of various shape dimensions in the slip boundary represented by this filter.
void assemble(LAFEM::SlipFilter< DataType_, IndexType_, world_dim > &filter, const Space::Lagrange1::Element< Trafo_ > &space)
Assembles a homogeneous SlipFilter for a Lagrange 1 FE space.
SlipFilterAssembler(const SlipFilterAssembler &)=delete
Explicitly delete the copy constructor.
TargetSetHolderType _target_set_holder
Mapping of boundary entities to mesh entities (i.e. vertices, edges, facets)
Class template for partial meshes.
Slip Filter class template.
TrafoType & get_trafo()
Returns a reference to the trafo.
Standard Lagrange-1 Finite-Element space class template.
Index get_num_dofs() const
Returns the number of dofs.
Standard Lagrange-2 Finite-Element space class template.
Index get_num_dofs() const
Returns the number of dofs.
Tiny Matrix class template.
Tiny Vector class template.
Vector< T_, m_ > orthogonal(const Matrix< T_, m_, m_-1, sm_, sn_ > &tau)
Computes the positively oriented orthogonal vector to the columns of a m_ x (m_-1) Matrix.
std::uint64_t Index
Index data type.
@ jac_mat
specifies whether the trafo should supply jacobian matrices
Face traits tag struct template.
Reference cell traits structure.