FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
dudv_functional_control.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
8
9#include <kernel/assembly/bilinear_operator_assembler.hpp>
10#include <kernel/assembly/common_operators.hpp>
11#include <kernel/lafem/sparse_matrix_csr.hpp>
12#include <kernel/lafem/sparse_matrix_bcsr.hpp>
13#include <kernel/lafem/sparse_matrix_bwrappedcsr.hpp>
14#include <kernel/lafem/vector_mirror.hpp>
15#include <kernel/geometry/export_vtk.hpp>
16#include <kernel/global/gate.hpp>
17#include <kernel/global/matrix.hpp>
18#include <kernel/global/nonlinear_functional.hpp>
19#include <kernel/global/vector.hpp>
20#include <kernel/meshopt/dudv_functional.hpp>
21#include <kernel/solver/multigrid.hpp>
22#include <kernel/solver/pcg.hpp>
23#include <kernel/solver/richardson.hpp>
24#include <kernel/solver/jacobi_precond.hpp>
25
26#include <control/domain/domain_control.hpp>
27#include <control/meshopt/meshopt_control.hpp>
28
29namespace FEAT
30{
31 namespace Control
32 {
33 namespace Meshopt
34 {
35 template<typename>
37
54 template<typename DT_, typename IT_, typename DomainControl_>
56 : public MeshoptControlBase<DomainControl_>
57 {
58 public:
60 typedef DT_ DataType;
62 typedef IT_ IndexType;
63
66
68 typedef DomainControl_ DomainControlType;
70 typedef typename DomainControl_::LayerType DomainLayerType;
72 typedef typename DomainControl_::LevelType DomainLevelType;
73
75 typedef typename DomainLevelType::TrafoType TrafoType;
76
78 template<typename DT2_, typename IT2_>
80
83
85 typedef typename DomainControl_::MeshType MeshType;
87 typedef typename MeshType::CoordType CoordType;
88
91
102
104 std::deque<SystemLevelType*> _system_levels;
105
107 std::shared_ptr<Solver::MultiGridHierarchy<
112
113 public:
119 std::shared_ptr<Solver::SolverBase<GlobalSystemVectorR>> solver;
126
154 DomainControl_& dom_ctrl,
155 const int meshopt_lvl_,
156 const std::deque<String>& dirichlet_list, const std::deque<String>& slip_list,
157 const String& solver_name_, PropertyMap& solver_config_,
158 bool fixed_reference_domain_):
159 BaseClass(dom_ctrl, dirichlet_list, slip_list),
161 solver_config(solver_config_),
162 solver_name(solver_name_),
163 solver(nullptr),
164 fixed_reference_domain(fixed_reference_domain_),
165 meshopt_lvl(meshopt_lvl_),
166 meshopt_lvl_pos(~size_t(0))
167 {
168 XASSERT(meshopt_lvl >= -1);
169
170 // If the input level was set to -1, take the max level of the domain control
171 if(meshopt_lvl == -1)
172 {
173 meshopt_lvl = dom_ctrl.max_level_index();
174 }
175
176 XASSERT(meshopt_lvl<= dom_ctrl.max_level_index());
177
178 // Now find the position of the coarsest mesh optimization level in the domain levels
179 for(size_t i(0); i < dom_ctrl.size_physical(); ++i)
180 {
181 if(dom_ctrl.at(i)->get_level_index() == meshopt_lvl)
182 {
183 meshopt_lvl_pos = i;
184 break;
185 }
186 }
187
188 XASSERT(meshopt_lvl_pos < dom_ctrl.size_physical());
189
190 for(size_t i(0); i < dom_ctrl.size_physical(); ++i)
191 {
192 _system_levels.push_back( new SystemLevelType(
193 dom_ctrl.at(i)->get_level_index(),
194 dom_ctrl.at(i)->get_mesh_node(),
195 dom_ctrl.at(i)->trafo,
196 dirichlet_list, slip_list));
197
198 // This assembles the system matrix numerically
199 _system_levels.at(i)->local_functional.init();
200 }
201
202 // Now that _system_levels has the correct size, we can use get_num_levels()
203 for(Index i(0); i < get_num_levels(); ++i)
204 {
205 _system_levels.at(i)->assemble_gates(dom_ctrl.at(i).layer());
206 }
207
208 // Assemble the transfer matrices on all levels except for the coarsest
209 for(Index i(0); i+1 < get_num_levels(); ++i)
210 {
211 _system_levels.at(i)->assemble_system_transfer(*_system_levels.at(i+1));
212 }
213
214 // Now we need to assemble the filters on all levels before any shallow copies are made. This is done
215 // by calling prepare()
217 vec_buf.local().convert(_system_levels.front()->coords_buffer.local());
218 prepare(vec_buf);
219
220 // create the solver
221 this->_create_solver();
222 }
223
228
233 {
234 while(!_system_levels.empty())
235 {
236 delete _system_levels.back();
237 _system_levels.pop_back();
238 }
239
240 solver->done();
241 _multigrid_hierarchy->done();
242 }
243
245 virtual String name() const override
246 {
247 return "DuDvFunctionalControl<>";
248 }
249
251 virtual String info() const override
252 {
253 const Index pad_width(30);
254
255 String msg;
256
257 msg += name().pad_back(pad_width, '.') + String(":") + String("\n");
258
259 msg += String("level max/min").pad_back(pad_width, '.') + String(": ")
260 + stringify(this->_dom_ctrl.max_level_index()) + String(" / ")
261 + stringify(this->_dom_ctrl.min_level_index()) + String("\n");
262
263 msg += String("optimization on level").pad_back(pad_width, '.') + String(": ")
264 + stringify(meshopt_lvl) + String("\n");
265
266 msg += String("Fixed reference domain").pad_back(pad_width, '.') + String(": ")
268
269 for(const auto& it : this->get_dirichlet_boundaries())
270 {
271 msg += String("Displacement BC on").pad_back(pad_width, '.') + String(": ") + it + String("\n");
272 }
273
274 for(const auto& it : this->get_slip_boundaries())
275 {
276 msg += String("Unilateral BC of place on").pad_back(pad_width, '.') + String(": ") + it + String("\n");
277 }
278
279 msg += String("DoF").pad_back(pad_width, '.') + String(": ")
280 + stringify(_system_levels.front()->matrix_sys.columns()) + String("\n");
281
282 try
283 {
284 msg += String("Solver") .pad_back(pad_width, '.') + String(": ")
286 }
287 catch(...)
288 {
289 }
290
291 return msg;
292 }
293
295 virtual CoordType compute_cell_size_defect(CoordType& lambda_min, CoordType& lambda_max,
296 CoordType& vol_min, CoordType& vol_max, CoordType& vol) const override
297 {
298
299 _system_levels.front()->local_functional.compute_cell_size_defect_pre_sync(vol_min, vol_max, vol);
300
301 vol_min = _system_levels.front()->gate_sys.min(vol_min);
302 vol_max = _system_levels.front()->gate_sys.max(vol_max);
303 vol = _system_levels.front()->gate_sys.sum(vol);
304
305 CoordType cell_size_defect =
306 _system_levels.front()->local_functional.compute_cell_size_defect_post_sync(lambda_min, lambda_max, vol_min, vol_max, vol);
307
308 lambda_min = _system_levels.front()->gate_sys.min(lambda_min);
309 lambda_max = _system_levels.front()->gate_sys.max(lambda_max);
310 cell_size_defect = _system_levels.front()->gate_sys.sum(cell_size_defect);
311
312 return cell_size_defect;
313 }
314
317 {
318 return _system_levels.front()->coords_buffer;
319 }
320
322 virtual size_t get_num_levels() const override
323 {
324 return _system_levels.size();
325 }
326
328 virtual void buffer_to_mesh() override
329 {
330 // Write finest level
331 _system_levels.front()->local_functional.buffer_to_mesh();
332
333 // Get the coords buffer on the finest level
334 const auto& coords_buffer_loc = _system_levels.front()->local_functional.get_coords();
335
336 // Transfer fine coords buffer to coarser levels and perform buffer_to_mesh
337 for(size_t level(0); level < get_num_levels(); ++level)
338 {
339 Index ndofs(_system_levels.at(level)->local_functional.trafo_space.get_num_dofs());
340
341 // At this point, what we really need is a primal restriction operator that restricts the FE function
342 // representing the coordinate distribution to the coarser level. This is very simple for continuous
343 // Lagrange elements (just discard the additional information from the fine level), but not clear in
344 // the generic case. So we use an evil hack here:
345 // Because of the underlying two level ordering, we just need to copy the first ndofs entries from
346 // the fine level vector.
348 vec_level(coords_buffer_loc, ndofs, Index(0));
349
350 _system_levels.at(level)->local_functional.get_coords().copy(vec_level);
351 _system_levels.at(level)->local_functional.buffer_to_mesh();
352 }
353 }
354
356 virtual void mesh_to_buffer() override
357 {
358 // Write finest level
359 _system_levels.front()->local_functional.mesh_to_buffer();
360
361 // Get the coords buffer on the finest level
362 const auto& coords_buffer_loc = _system_levels.front()->coords_buffer.local();
363
364 // Transfer fine coords buffer to coarser levels and perform buffer_to_mesh
365 for(size_t level(0); level < get_num_levels(); ++level )
366 {
367 Index ndofs(_system_levels.at(level)->local_functional.trafo_space.get_num_dofs());
368
369 // At this point, what we really need is a primal restriction operator that restricts the FE function
370 // representing the coordinate distribution to the coarser level. This is very simple for continuous
371 // Lagrange elements (just discard the additional information from the fine level), but not clear in
372 // the generic case. So we use an evil hack here:
373 // Because of the underlying two level ordering, we just need to copy the first ndofs entries from
374 // the fine level vector.
376 vec_level(coords_buffer_loc, ndofs, Index(0));
377
378 _system_levels.at(level)->local_functional.get_coords().copy(vec_level);
379 }
380
381 }
382
385 Geometry::ExportVTK<MeshType>& exporter, const int lvl_index) const override
386 {
387 for(size_t pos(0); pos < get_num_levels(); ++pos)
388 {
389 if(this->_system_levels.at(pos)->get_level_index() == lvl_index)
390 {
391 const auto& sys_lvl = this->_system_levels.at(pos);
392 sys_lvl->local_functional.add_to_vtk_exporter(exporter);
393
394 for(auto& it:sys_lvl->filter_sys.local().template at<0>())
395 {
396 const String field_name("nu_"+it.first);
397 // WARNING: This explicitly assumes that the filter vector belong to a P1/Q1 space and thus "lives"
398 // in the mesh's vertices
399 exporter.add_vertex_vector(field_name, it.second.get_filter_vector());
400 }
401 }
402 }
403 }
404
412 virtual void init_numeric()
413 {
415 {
416 for(size_t lvl(0); lvl < size_t(get_num_levels()); ++lvl)
417 {
418 _system_levels.at(lvl)->local_functional.assemble_system_matrix();
419 }
420 }
421 }
422
424 virtual void prepare(const GlobalSystemVectorR& vec_state) override
425 {
426 typename SystemLevelType::LocalCoordsBuffer vec_buf;
427 vec_buf.convert(vec_state.local());
428
429 for(size_t level(0); level < get_num_levels(); ++level)
430 {
431 Index ndofs(_system_levels.at(level)->local_functional.trafo_space.get_num_dofs());
432
433 // At this point, what we really need is a primal restriction operator that restricts the FE function
434 // representing the coordinate distribution to the coarser level. This is very simple for continuous
435 // Lagrange elements (just discard the additional information from the fine level), but not clear in
436 // the generic case. So we use an evil hack here:
437 // Because of the underlying two level ordering, we just need to copy the first ndofs entries from
438 // the fine level vector.
440 global_vec_level( &(_system_levels.at(level)->gate_sys), vec_buf, ndofs, Index(0));
441
442 _system_levels.at(level)->local_functional.prepare(
443 vec_buf, _system_levels.at(level)->filter_sys.local());
444
445 _system_levels.at(level)->sync_system_filter();
446
447 }
448
449 }
450
466 {
467 // Get our global system matrix and filter
468 GlobalSystemMatrix& mat_sys = _system_levels.at(meshopt_lvl_pos)->matrix_sys;
469 GlobalSystemFilter& filter_sys = _system_levels.at(meshopt_lvl_pos)->filter_sys;
470
471 // Update the containers in the MatrixStock
472 _multigrid_hierarchy->done_numeric();
473 _multigrid_hierarchy->init_numeric();
474
475 return Solver::solve(*solver, vec_sol, vec_rhs, mat_sys, filter_sys);
476 }
477
479 virtual void optimize() override
480 {
481 // Reassemble the system matrix
482 init_numeric();
483
484 // fetch our finest levels
485 SystemLevelType& the_system_level = *_system_levels.at(meshopt_lvl_pos);
486
487 // Create our RHS and SOL vectors
488 GlobalSystemVectorR vec_rhs = the_system_level.assemble_rhs_vector();
489 GlobalSystemVectorL vec_sol = the_system_level.assemble_sol_vector();
490
491 // Let it be known to Statistics that it was Us who called the solver
493
494 // solve
495 this->apply(vec_sol, vec_rhs);
496
497 // Write the solution to the control object's buffer and the buffer to mesh
498 typename SystemLevelType::LocalCoordsBuffer vec_buf;
499 vec_buf.convert(vec_sol.local());
500 the_system_level.coords_buffer.local().copy(vec_buf);
501
502 the_system_level.local_functional.buffer_to_mesh();
503
504 //If the mesh was not optimized on the finest domain level, we now need to prolongate the solution by:
505 // - refine the coarse vertex set using the StandardRefinery
506 // - copy the results to the CoordsBuffer
507 // - convert the CoordsBuffer to a vector type that we can filter with the system's Dirichlet filter
508 // - copy the filtered vector's contents back to the buffer and write the buffer to the mesh
509 // - apply the nonlinear filter representing unilateral BCs of place by calling adapt() for the
510 // corresponding meshparts
511 for(size_t pos(meshopt_lvl_pos); pos > size_t(0);)
512 {
513 --pos;
514
515 auto& coarse_mesh = this->_dom_ctrl.at(pos+1)->get_mesh();
516 auto& fine_mesh = this->_dom_ctrl.at(pos)->get_mesh();
517 auto& fine_vtx = fine_mesh.get_vertex_set();
518
519 // Refine coarse vertex set and write the result to the CoordsBuffer
520 Geometry::StandardRefinery<MeshType> refinery(coarse_mesh);
521 refinery.fill_vertex_set(fine_vtx);
522 _system_levels.at(pos)->local_functional.mesh_to_buffer();
523 // Convert the buffer to a filterable vector
524 typename GlobalSystemVectorL::LocalVectorType vec_sol_lvl;
525 vec_sol_lvl.convert(_system_levels.at(pos)->coords_buffer.local());
526 // Filter this vector, copy back the contents and write the changes to the mesh
527 auto& dirichlet_filters_lvl = _system_levels.at(pos)->filter_sys.local().template at<1>();
528 dirichlet_filters_lvl.filter_sol(vec_sol_lvl);
529 _system_levels.at(pos)->coords_buffer.local().copy(vec_sol_lvl);
530 _system_levels.at(pos)->local_functional.buffer_to_mesh();
531 // Now call adapt() on the slip boundaries
532 auto* fine_mesh_node = this->_dom_ctrl.at(pos)->get_mesh_node();
533 for(const auto& it:this->get_slip_boundaries())
534 {
535 fine_mesh_node->adapt_by_name(it);
536 }
537 }
538
539 // Now we need to update all coarser levels
540 for(size_t pos(meshopt_lvl_pos+1); pos < get_num_levels(); ++pos)
541 {
542 Index ndofs(_system_levels.at(pos)->local_functional.trafo_space.get_num_dofs());
543
544 // At this point, what we really need is a primal restriction operator that restricts the FE function
545 // representing the coordinate distribution to the coarser level. This is very simple for continuous
546 // Lagrange elements (just discard the additional information from the fine level), but not clear in
547 // the generic case. So we use an evil hack here:
548 // Because of the underlying two level ordering, we just need to copy the first ndofs entries from
549 // the fine level vector.
551 global_sol_level( &(_system_levels.at(pos)->gate_sys), vec_sol.local(), ndofs, Index(0));
552
553 // prepare() needs to be called of the local object, because there is a Global::Matrix around it
554 // which knows nothing of prepare()
555 _system_levels.at(pos)->local_functional.prepare(
556 global_sol_level.local(), _system_levels.at(pos)->filter_sys.local());
557
558 _system_levels.at(pos)->local_functional.get_coords().copy(global_sol_level.local());
559 _system_levels.at(pos)->local_functional.buffer_to_mesh();
560 }
561
562 } // void optimize()
563
564 protected:
565 void _create_solver()
566 {
567 // first of all, let's fetch all the subsections for the DuDv solver
568 auto* sec_linsol = solver_config.query_section(this->solver_name);
569 auto* sec_mg_coarse = solver_config.query_section("DuDvMGCoarseSolver");
570 auto* sec_mg_smooth = solver_config.query_section("DuDvMGSmoother");
571 XASSERTM(sec_linsol != nullptr, "mandatory DuDv solver config section is missing");
572 XASSERTM(sec_mg_coarse != nullptr, "mandatory solver section [DuDvMGCoarseSolver] is missing");
573 XASSERTM(sec_mg_smooth != nullptr, "mandatory solver section [DuDvMGSmoother] is missing");
574
575 // our multigrid smoother is a simple Jacobi-smoother, so parse the damping parameter
576 // as well as the number of smoothing steps
577 Index smooth_steps = 4;
578 auto smooth_steps_p = sec_mg_smooth->get_entry("steps");
579 XASSERTM(smooth_steps_p.second, "DuDvMGSmoother.steps parameter is missing");
580 smooth_steps_p.first.parse(smooth_steps);
581
582 DT_ smooth_omega = DT_(0.5);
583 auto smooth_damp_p = sec_mg_smooth->get_entry("omega");
584 XASSERTM(smooth_damp_p.second, "DuDvMGSmoother.omega parameter is missing");
585 smooth_damp_p.first.parse(smooth_omega);
586
587 // now let's build the multigrid hierarchy
590
591 // create smoothers for all levels except the coarsest one
592 for(Index i(0); (i+1) < get_num_levels(); ++i)
593 {
594 const auto& lvl = *(_system_levels.at(i));
595 auto jacobi = Solver::new_jacobi_precond(lvl.matrix_sys, lvl.filter_sys);
596 auto smooth = Solver::new_richardson(lvl.matrix_sys, lvl.filter_sys, smooth_omega, jacobi);
597 smooth->set_min_iter(smooth_steps);
598 smooth->set_max_iter(smooth_steps);
599 _multigrid_hierarchy->push_level(lvl.matrix_sys, lvl.filter_sys, lvl.transfer_sys, smooth, smooth, smooth);
600 }
601
602 // now let's create the coarse grid solver; this is always a PCG-Jacobi, which is configured
603 // by the [DuDvMGCoarseSolver] section
604 {
605 const auto& lvl = *_system_levels.back();
606 auto jacobi = Solver::new_jacobi_precond(lvl.matrix_sys, lvl.filter_sys);
607 auto cg_pcg = Solver::new_pcg("DuDvMGCoarseSolver", sec_mg_coarse, lvl.matrix_sys, lvl.filter_sys, jacobi);
608 _multigrid_hierarchy->push_level(lvl.matrix_sys, lvl.filter_sys, cg_pcg);
609 }
610
611 // now, let's create the actual multigrid solver object
613
614 // get the finest level
615 const auto& lvl = *_system_levels.front();
616
617 // finally, create the outer solver, which is always a PCG solver
618 solver = Solver::new_pcg("DuDvLinearSolver", sec_linsol, lvl.matrix_sys, lvl.filter_sys, multigrid);
619
620 // initialize the hierarchy and the solver
621 _multigrid_hierarchy->init();
622 solver->init();
623 }
624 };
625 } // namespace Meshopt
626 } // namespace Control
627} // namespace FEAT
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
FEAT Kernel base header.
DomainLevelType::TrafoType TrafoType
The transformation we solve for.
MeshoptControlBase< DomainControl_ > BaseClass
Our base class.
virtual void add_to_vtk_exporter(Geometry::ExportVTK< MeshType > &exporter, const int lvl_index) const override
Adds quantities of the underlying mesh quality functional to a given exporter object.
virtual void prepare(const GlobalSystemVectorR &vec_state) override
Sets the internal state variable.
SystemLevelType::GlobalSystemVectorR GlobalSystemVectorR
Global right vector type.
LocalFunctionalType< DT_, IT_ >::SpaceType TrafoSpace
The FE space the transformation lives in.
QuadraticSystemLevel< DT_, IT_, LocalFunctionalType > SystemLevelType
Linear system of equations on one refinement level.
virtual size_t get_num_levels() const override
Get the number of levels in this object.
const bool fixed_reference_domain
Whether to reassemble the system matrix in every call of optimize.
SystemLevelType::GlobalSystemFilter GlobalSystemFilter
Global system filter.
virtual void buffer_to_mesh() override
Copies the contents of the buffer vector to the mesh's vertex coordinates.
int meshopt_lvl
The level index (= number of refinements since the mesh file) to optimize the mesh on.
virtual void init_numeric()
Numerically assembles the functional for evaluation.
String solver_name
The name of the section from solver_config we want to use.
virtual void mesh_to_buffer() override
Copies the mesh's vertex coordinates to the buffer vector.
std::shared_ptr< Solver::SolverBase< GlobalSystemVectorR > > solver
The solver.
virtual Solver::Status apply(GlobalSystemVectorR &vec_sol, const GlobalSystemVectorL &vec_rhs)
Applies the inverse of this functional's gradient to a right hand side.
DomainControl_::MeshType MeshType
The underlying mesh type.
virtual String name() const override
Returns a descriptive String.
DuDvFunctionalControl()=delete
Explicitly delete empty default constructor.
DuDvFunctionalControl(DuDvFunctionalControl &&)=delete
Explicitly delete move constructor.
SystemLevelType::GlobalSystemMatrix GlobalSystemMatrix
Global system matrix.
DomainControl_::LevelType DomainLevelType
Domain levels.
virtual SystemLevelType::GlobalCoordsBuffer & get_coords() override
Gets the coordinates buffer vector.
std::shared_ptr< Solver::MultiGridHierarchy< GlobalSystemMatrix, GlobalSystemFilter, typename SystemLevelType::GlobalSystemTransfer > > _multigrid_hierarchy
The multigrid hierarchy for our solver.
DomainControl_::LayerType DomainLayerType
Domain layers.
virtual CoordType compute_cell_size_defect(CoordType &lambda_min, CoordType &lambda_max, CoordType &vol_min, CoordType &vol_max, CoordType &vol) const override
‍**
std::deque< SystemLevelType * > _system_levels
For every level of refinement, we have one system level.
SystemLevelType::GlobalSystemVectorL GlobalSystemVectorL
Global left vector type.
LAFEM::SparseMatrixBWrappedCSR< DT_, IT_, MeshType::world_dim > TransferMatrixType
Inter-level transfer matrix.
DuDvFunctionalControl(DomainControl_ &dom_ctrl, const int meshopt_lvl_, const std::deque< String > &dirichlet_list, const std::deque< String > &slip_list, const String &solver_name_, PropertyMap &solver_config_, bool fixed_reference_domain_)
Constructor.
size_t meshopt_lvl_pos
The position of this level in the deque of system levels.
DomainControl_ DomainControlType
The type of the domain control.
MeshType::CoordType CoordType
The floating point type the mesh's coordinates use.
Base class for Meshopt control objects.
DomainControl & _dom_ctrl
The domain control whose mesh objects can be modified.
const std::deque< String > & get_dirichlet_boundaries() const
Gets the names of all Dirichlet boundaries.
const std::deque< String > & get_slip_boundaries() const
Gets the names of all slip boundaries.
GlobalCoordsBuffer coords_buffer
This contains a shallow copy of the operator's coords_buffer.
GlobalSystemVectorR assemble_sol_vector() const
Assembles an intial guess vector.
LocalFunctional local_functional
The (patch-)local mesh quality functional.
GlobalSystemVectorL assemble_rhs_vector() const
Assembles a right hand side vector.
SystemLevel for a quadratic mesh quality functional leading to a linear system.
BaseClass::LocalCoordsBuffer LocalCoordsBuffer
Local coordinates buffer type for passing information to or from the mesh.
Global::Transfer< LocalSystemTransfer, SystemMirror > GlobalSystemTransfer
Global system transfer operator.
VTK exporter class template.
Definition: export_vtk.hpp:119
void add_vertex_vector(const String &name, const T_ *x, const T_ *y=nullptr, const T_ *z=nullptr, double scaling_factor=1.0)
Adds a vector-field vertex variable to the exporter.
Definition: export_vtk.hpp:313
Standard Refinery class template.
Definition: factory.hpp:58
Global vector wrapper class template.
Definition: vector.hpp:68
LocalVector_ & local()
Returns a reference to the internal local LAFEM vector object.
Definition: vector.hpp:121
Wraps a SparseMatrixCSR to SparseMatrixBCSR.
Mesh optimizer based on minimization of harmonic energy.
Intern::TrafoFE< TrafoType >::Space SpaceType
Finite Element space for the transformation.
A class organizing a tree of key-value pairs.
PropertyMap * query_section(String sec_path)
Queries a section by its section path.
Multigrid hierarchy management class template.
Definition: multigrid.hpp:418
static String get_formatted_solver_tree(String target="default")
Returns a descriptive string of the complete solver tree.
Definition: statistics.hpp:361
static String expression_target
the current solver's descriptive string
Definition: statistics.hpp:173
String class implementation.
Definition: string.hpp:46
String pad_back(size_type len, char c=' ') const
Pads the back of the string up to a desired length.
Definition: string.hpp:415
String trim(const String &charset) const
Trims the string.
Definition: string.hpp:327
std::shared_ptr< MultiGrid< SystemMatrix_, SystemFilter_, TransferOperator_ > > new_multigrid(std::shared_ptr< MultiGridHierarchy< SystemMatrix_, SystemFilter_, TransferOperator_ > > hierarchy, MultiGridCycle cycle=MultiGridCycle::V, int top_level=0, int crs_level=-1)
Creates a new Multigrid preconditioner object.
Definition: multigrid.hpp:2027
@ V
Multigrid V-Cycle.
std::shared_ptr< PCG< Matrix_, Filter_ > > new_pcg(const Matrix_ &matrix, const Filter_ &filter, std::shared_ptr< SolverBase< typename Matrix_::VectorTypeL > > precond=nullptr)
Creates a new PCG solver object.
Definition: pcg.hpp:306
std::shared_ptr< Richardson< Matrix_, Filter_ > > new_richardson(const Matrix_ &matrix, const Filter_ &filter, typename Matrix_::DataType omega=typename Matrix_::DataType(1), std::shared_ptr< SolverBase< typename Matrix_::VectorTypeL > > precond=nullptr)
Creates a new Richardson solver object.
Definition: richardson.hpp:249
Status
Solver status return codes enumeration.
Definition: base.hpp:47
std::shared_ptr< JacobiPrecond< Matrix_, Filter_ > > new_jacobi_precond(const Matrix_ &matrix, const Filter_ &filter, const typename Matrix_::DataType omega=typename Matrix_::DataType(1))
Creates a new JacobiPrecond solver object.
Status solve(SolverBase< Vector_ > &solver, Vector_ &vec_sol, const Vector_ &vec_rhs, const Matrix_ &matrix, const Filter_ &filter)
Solve linear system with initial solution guess.
Definition: base.hpp:347
FEAT namespace.
Definition: adjactor.hpp:12
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:944
std::uint64_t Index
Index data type.