FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
dudv_functional.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
9#include <kernel/assembly/bilinear_operator_assembler.hpp> // for BilinearOperatorAssembler
10#include <kernel/assembly/common_operators.hpp> // for DuDvOperator
11#include <kernel/assembly/symbolic_assembler.hpp> // for SymbolicMatrixAssembler
12#include <kernel/assembly/slip_filter_assembler.hpp>
13#include <kernel/assembly/unit_filter_assembler.hpp>
14#include <kernel/cubature/dynamic_factory.hpp> // for DynamicFactory
15#include <kernel/geometry/conformal_mesh.hpp>
16#include <kernel/lafem/dense_vector_blocked.hpp>
17#include <kernel/lafem/filter_chain.hpp>
18#include <kernel/lafem/filter_sequence.hpp>
19#include <kernel/lafem/sparse_matrix_bcsr.hpp>
20#include <kernel/lafem/slip_filter.hpp>
21#include <kernel/lafem/unit_filter_blocked.hpp>
22#include <kernel/meshopt/mesh_quality_functional.hpp>
23#include <kernel/space/lagrange1/element.hpp>
24
25namespace FEAT
26{
27 namespace Meshopt
28 {
44 template
45 <
46 typename DT_, typename IT_, typename TrafoType_,
47 template<typename, typename, int, int> class MatrixType_ = LAFEM::SparseMatrixBCSR
48 >
50 public MeshQualityFunctional<typename TrafoType_::MeshType>
51 {
52 public:
54 typedef DT_ DataType;
56 typedef IT_ IndexType;
58 typedef TrafoType_ TrafoType;
60 typedef typename TrafoType::MeshType MeshType;
62 typedef typename MeshType::ShapeType ShapeType;
63
65 typedef MatrixType_<DT_, IT_, MeshType::world_dim, MeshType::world_dim> MatrixType;
67 static constexpr int BlockHeight = MatrixType::BlockHeight;
69 static constexpr int BlockWidth = MatrixType::BlockWidth;
70
72 template <typename DT2_ = DT_, typename IT2_ = IT_>
74
76 template <typename DataType2_, typename IndexType2_>
78
83
85 typedef typename MeshType::CoordType CoordType;
86
87 //template<typename A, typename B, typename C>
88 //using MatrixTemplate = MatrixType_<A, B, C, MeshType::world_dim, MeshType::world_dim>;
89
91 typedef typename MatrixType::VectorTypeL VectorTypeL;
93 typedef typename MatrixType::VectorTypeR VectorTypeR;
96
107
109 typedef typename Intern::TrafoFE<TrafoType>::Space SpaceType;
111 // 2 * (degree of trafo) for both trial and test spaces, +1 for safety reasons
112 // This could be decreased by the degree of the operator, i.e. 2 for Du:Dv
113 static constexpr int _local_degree = 4*SpaceType::local_degree + 1;
114
117
118 protected:
124 std::map<String, std::shared_ptr<Assembly::UnitFilterAssembler<MeshType>>> _dirichlet_asm;
126 std::map<String, std::shared_ptr<Assembly::SlipFilterAssembler<TrafoType>>> _slip_asm;
129
130 public:
133
134 public:
153 TrafoType& trafo,
154 const std::deque<String>& dirichlet_list, const std::deque<String>& slip_list):
155 BaseClass(rmn_),
156 matrix_sys(),
157 _trafo(trafo),
158 _lambda(rmn_->get_mesh()->get_num_entities(MeshType::shape_dim)),
160 _slip_asm(),
161 _cubature_factory("auto-degree:"+stringify(int(_local_degree))),
162 trafo_space(trafo)
163 {
164 // The symbolic assembly has to happen in the constructor because the matrix is shallow copied immediately
165 // after construction in the Control::QuadraticSystemLevel
167
168 // For every MeshPart specified in the list of Dirichlet boundaries, create a UnitFilterAssembler and
169 // insert it into the std::map
170 for(auto& it : dirichlet_list)
171 {
172 // Create empty assembler
173 auto new_asm = std::make_shared<Assembly::UnitFilterAssembler<MeshType>>();
174
175 // Add the MeshPart to the assembler if it is there. There are legimate reasons for it NOT to be
176 // there, i.e. we are in parallel and our patch is not adjacent to that MeshPart
177 auto* mpp = rmn_->find_mesh_part(it);
178 if(mpp != nullptr)
179 {
180 new_asm->add_mesh_part(*mpp);
181 }
182
183 // Insert into the map
184 String identifier(it);
185 _dirichlet_asm.emplace(identifier, new_asm);
186 }
187
188 // For every MeshPart specified in the list of slip boundaries, create a SlipFilterAssembler and
189 // insert it into the std::map
190 for(auto& it : slip_list)
191 {
192 // Create empty assembler
193 auto new_asm = std::make_shared<Assembly::SlipFilterAssembler<TrafoType>>(this->_trafo);
194
195 // Add the MeshPart to the assembler if it is there. There are legimate reasons for it NOT to be
196 // there, i.e. we are in parallel and our patch is not adjacent to that MeshPart
197 auto* mpp = rmn_->find_mesh_part(it);
198 if(mpp != nullptr)
199 {
200 new_asm->add_mesh_part(*mpp);
201 }
202
203 // Insert into the map
204 String identifier(it);
205 _slip_asm.emplace(identifier, new_asm);
206 }
207
208 }
209
212
215 {
216 }
217
224 virtual void init() override
225 {
226 //Assembly::SymbolicAssembler::assemble_matrix_std1(matrix_sys, trafo_space);
228 }
229
231 static String name()
232 {
233 return "DuDvFunctional<"+MeshType::name()+">";
234 }
235
243 virtual void add_to_vtk_exporter(Geometry::ExportVTK<MeshType>& exporter) const override
244 {
245 exporter.add_cell_scalar("lambda", this->_lambda.elements());
246 }
247
252 {
253 matrix_sys.format();
254
256
258 matrix_sys, // the matrix that receives the assembled operator
259 my_operator, // the operator that is to be assembled
260 trafo_space, // the finite element space in use
261 _cubature_factory // the cubature factory to be used for integration
262 );
263
264 }
265
278 virtual void prepare(VectorTypeR& vec_state, FilterType& filter)
279 {
280 for(Index cell(0); cell < this->get_mesh()->get_num_entities(MeshType::shape_dim); ++cell)
281 {
282 _lambda(cell, DataType(_trafo.template compute_vol<typename MeshType::ShapeType>(cell)));
283 }
284
285 auto& dirichlet_filters = filter.template at<1>();
286
287 for(auto& it : dirichlet_filters)
288 {
289 const auto& assembler = _dirichlet_asm.find(it.first);
290 if(assembler == _dirichlet_asm.end())
291 {
292 XABORTM("Could not find dirichlet assembler for filter with key "+it.first);
293 }
294
295 assembler->second->assemble(it.second, trafo_space, vec_state);
296 }
297
298 // The slip filter contains the outer unit normal, so reassemble it
299 auto& slip_filters = filter.template at<0>();
300
301 for(auto& it : slip_filters)
302 {
303 const auto& assembler = _slip_asm.find(it.first);
304 if(assembler == _slip_asm.end())
305 {
306 XABORTM("Could not find slip filter assembler for filter with key "+it.first);
307 }
308
309 assembler->second->assemble(it.second, trafo_space);
310 }
311
312 for(const auto& it:slip_filters)
313 {
314 this->_mesh_node->adapt_by_name(it.first);
315 }
316
317 }
318
355 virtual CoordType compute_cell_size_defect(CoordType& lambda_min, CoordType& lambda_max, CoordType& vol_min, CoordType& vol_max, CoordType& vol) const override
356 {
357
358 compute_cell_size_defect_pre_sync(vol_min, vol_max, vol);
359 return compute_cell_size_defect_post_sync(lambda_min, lambda_max, vol_min, vol_max, vol);
360
361 }
362
385 {
386 vol = CoordType(0);
387
388 vol_min = Math::huge<CoordType>();
389 vol_max = CoordType(0);
390
391 for(Index cell(0); cell < this->get_mesh()->get_num_entities(ShapeType::dimension); ++cell)
392 {
393 CoordType my_vol = this->_trafo.template compute_vol<ShapeType, CoordType>(cell);
394 vol_min = Math::min(vol_min, my_vol);
395 vol_max = Math::max(vol_min, my_vol);
396 vol += my_vol;
397 }
398 }
399
427 virtual CoordType compute_cell_size_defect_post_sync(CoordType& lambda_min, CoordType& lambda_max, CoordType& vol_min, CoordType& vol_max, const CoordType& vol) const
428 {
429 CoordType size_defect(0);
430 lambda_min = Math::huge<CoordType>();
431 lambda_max = CoordType(0);
432
433 for(Index cell(0); cell < this->get_mesh()->get_num_entities(ShapeType::dimension); ++cell)
434 {
435 size_defect += Math::abs(this->_trafo.template compute_vol<ShapeType, CoordType>(cell)/vol - this->_lambda(cell));
436 lambda_min = Math::min(lambda_min, CoordType(this->_lambda(cell)));
437 lambda_max = Math::max(lambda_max, CoordType(this->_lambda(cell)));
438 }
439
440 vol_min /= vol;
441 vol_max/= vol;
442
443 return size_defect;
444 }
445
451 bool empty() const
452 {
453 return matrix_sys.empty();
454 }
455
460 {
461 return VectorTypeL(trafo_space.get_num_dofs());
462 }
463
468 {
469 return VectorTypeR(trafo_space.get_num_dofs());
470 }
471
472
473 }; // class DuDvFunctional
474
475#ifdef FEAT_EICKT
476 extern template class DuDvFunctional
477 <
478 double, Index,
481 >;
482
483 extern template class DuDvFunctional
484 <
485 double, Index,
488 >;
489#endif // FEAT_EICKT
490 } // namespace Meshopt
491} // namespace FEAT
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
FEAT Kernel base header.
static void assemble_matrix1(Matrix_ &matrix, Operator_ &operat, const Space_ &space, const CubatureFactory_ &cubature_factory, typename Matrix_::DataType alpha=typename Matrix_::DataType(1))
Assembles a bilinear operator into a matrix.
static void assemble_matrix_std1(MatrixType_ &matrix, const Space_ &space)
Assembles a standard matrix structure from a single space.
VTK exporter class template.
Definition: export_vtk.hpp:195
void add_cell_scalar(const String &name, const T_ *data, double scaling_factor=1.0)
Adds a scalar cell variable to the exporter.
Definition: export_vtk.hpp:629
bool adapt_by_name(const String &part_name, bool recursive=false)
Adapts this mesh node.
Definition: mesh_node.hpp:523
MeshPartType * find_mesh_part(const String &part_name)
Searches this container for a MeshPart.
Definition: mesh_node.hpp:398
Root mesh node class template.
Definition: mesh_node.hpp:748
Dense data vector class template.
DT_ * elements()
Get a pointer to the data array.
Filter Chainclass template.
Sequence of filters of the same type.
Slip Filter class template.
Definition: slip_filter.hpp:67
CSR based blocked sparse matrix.
Unit Filter Blocked class template.
Mesh optimizer based on minimization of harmonic energy.
TrafoType_ TrafoType
Type for the transformation.
DuDvFunctional(Geometry::RootMeshNode< MeshType > *rmn_, TrafoType &trafo, const std::deque< String > &dirichlet_list, const std::deque< String > &slip_list)
Constructor.
virtual void add_to_vtk_exporter(Geometry::ExportVTK< MeshType > &exporter) const override
Adds relevant quantities of this object to a VTK exporter.
virtual CoordType compute_cell_size_defect_post_sync(CoordType &lambda_min, CoordType &lambda_max, CoordType &vol_min, CoordType &vol_max, const CoordType &vol) const
Computes a quality indicator concerning the cell sizes, pre synchronization phase.
LAFEM::FilterChain< SlipFilterSequence, DirichletFilterSequence > FilterType
Combined filter.
virtual void prepare(VectorTypeR &vec_state, FilterType &filter)
Prepares the functional for evaluation.
bool empty() const
Checks if the functional is empty (= the null functional.
virtual ~DuDvFunctional()
Virtual destructor.
MatrixType_< DT_, IT_, MeshType::world_dim, MeshType::world_dim > MatrixType
Type for the system matrix.
DuDvFunctional(const DuDvFunctional &)=delete
Explicitly delete copy constructor.
LAFEM::DenseVector< DT_, IT_ > ScalarVectorType
Type for i.e. cell vectors.
LAFEM::FilterSequence< SlipFilterType > SlipFilterSequence
Sequence of Slip filters for several different boundary parts.
MeshType::CoordType CoordType
The precision of the mesh coordinates.
LAFEM::FilterSequence< DirichletFilterType > DirichletFilterSequence
Sequence of Dirichlet filters for several different boundary parts.
ScalarVectorType _lambda
Vector saving the cell sizes on the reference mesh.
Cubature::DynamicFactory _cubature_factory
Cubature factory, for P1/Q1 transformations in 2d degree 5 is enough.
static constexpr int BlockHeight
Blockheight of the system matrix.
MeshQualityFunctional< MeshType > BaseClass
Our base class.
TrafoType::MeshType MeshType
The mesh the transformation is defined on.
void compute_cell_size_defect_pre_sync(CoordType &vol_min, CoordType &vol_max, CoordType &vol) const
Computes a quality indicator concerning the cell sizes, pre synchronization phase.
virtual CoordType compute_cell_size_defect(CoordType &lambda_min, CoordType &lambda_max, CoordType &vol_min, CoordType &vol_max, CoordType &vol) const override
Computes a quality indicator concerning the cell sizes.
LAFEM::UnitFilterBlocked< DT_, IT_, MeshType::world_dim > DirichletFilterType
Filter for Dirichlet boundary conditions.
VectorTypeR create_vector_r() const
Creates an R-vector for the functional and its gradient.
MatrixType matrix_sys
The system matrix.
SpaceType trafo_space
The FE space for the transformation, needed for filtering.
virtual void init() override
Performs one-time initializations.
static constexpr int BlockWidth
Blockwidth of the system matrix.
MeshType::ShapeType ShapeType
The shape type of the mesh.
std::map< String, std::shared_ptr< Assembly::UnitFilterAssembler< MeshType > > > _dirichlet_asm
Assembler for Dirichlet boundary conditions.
LAFEM::SlipFilter< DT_, IT_, MeshType::world_dim > SlipFilterType
Filter for slip boundary conditions.
std::map< String, std::shared_ptr< Assembly::SlipFilterAssembler< TrafoType > > > _slip_asm
Assembler for slip boundary conditions.
MatrixType::VectorTypeR VectorTypeR
Type for vectors from the primal space.
MatrixType::VectorTypeL VectorTypeL
Type for vectors from the dual space.
Intern::TrafoFE< TrafoType >::Space SpaceType
Finite Element space for the transformation.
static String name()
The class name.
TrafoType & _trafo
The transformation defining the physical mesh.
static constexpr int _local_degree
Maximum polynomial degree.
VectorTypeL create_vector_l() const
Creates an L-vector for the functional's gradient.
BaseClass::CoordsBufferType CoordsBufferType
Type for exchanging information between state variable and mesh.
virtual void assemble_system_matrix()
Assembles the system matrix.
Baseclass for mesh optimization algorithms.
Geometry::RootMeshNode< MeshType > * _mesh_node
The mesh for the underlying transformation.
String class implementation.
Definition: string.hpp:47
Standard transformation mapping class template.
Definition: mapping.hpp:39
T_ abs(T_ x)
Returns the absolute value.
Definition: math.hpp:275
T_ min(T_ a, T_ b)
Returns the minimum of two values.
Definition: math.hpp:123
T_ max(T_ a, T_ b)
Returns the maximum of two values.
Definition: math.hpp:137
FEAT namespace.
Definition: adjactor.hpp:12
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:993
std::uint64_t Index
Index data type.