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>
26#include <control/domain/domain_control.hpp>
27#include <control/meshopt/meshopt_control.hpp>
54 template<
typename DT_,
typename IT_,
typename DomainControl_>
75 typedef typename DomainLevelType::TrafoType
TrafoType;
78 template<
typename DT2_,
typename IT2_>
85 typedef typename DomainControl_::MeshType
MeshType;
119 std::shared_ptr<Solver::SolverBase<GlobalSystemVectorR>>
solver;
154 DomainControl_& dom_ctrl,
155 const int meshopt_lvl_,
156 const std::deque<String>& dirichlet_list,
const std::deque<String>& slip_list,
158 bool fixed_reference_domain_):
159 BaseClass(dom_ctrl, dirichlet_list, slip_list),
179 for(
size_t i(0); i < dom_ctrl.size_physical(); ++i)
181 if(dom_ctrl.at(i)->get_level_index() ==
meshopt_lvl)
190 for(
size_t i(0); i < dom_ctrl.size_physical(); ++i)
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));
221 this->_create_solver();
247 return "DuDvFunctionalControl<>";
253 const Index pad_width(30);
299 _system_levels.front()->local_functional.compute_cell_size_defect_pre_sync(vol_min, vol_max, vol);
306 _system_levels.front()->local_functional.compute_cell_size_defect_post_sync(lambda_min, lambda_max, vol_min, vol_max, vol);
310 cell_size_defect =
_system_levels.front()->gate_sys.sum(cell_size_defect);
312 return cell_size_defect;
334 const auto& coords_buffer_loc =
_system_levels.front()->local_functional.get_coords();
348 vec_level(coords_buffer_loc, ndofs,
Index(0));
350 _system_levels.at(level)->local_functional.get_coords().copy(vec_level);
362 const auto& coords_buffer_loc =
_system_levels.front()->coords_buffer.local();
376 vec_level(coords_buffer_loc, ndofs,
Index(0));
378 _system_levels.at(level)->local_functional.get_coords().copy(vec_level);
389 if(this->_system_levels.at(pos)->get_level_index() == lvl_index)
391 const auto& sys_lvl = this->_system_levels.at(pos);
392 sys_lvl->local_functional.add_to_vtk_exporter(exporter);
394 for(
auto& it:sys_lvl->filter_sys.local().template at<0>())
396 const String field_name(
"nu_"+it.first);
418 _system_levels.at(lvl)->local_functional.assemble_system_matrix();
427 vec_buf.convert(vec_state.
local());
495 this->
apply(vec_sol, vec_rhs);
499 vec_buf.convert(vec_sol.
local());
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();
521 refinery.fill_vertex_set(fine_vtx);
524 typename GlobalSystemVectorL::LocalVectorType vec_sol_lvl;
525 vec_sol_lvl.convert(
_system_levels.at(pos)->coords_buffer.local());
527 auto& dirichlet_filters_lvl =
_system_levels.at(pos)->filter_sys.local().template at<1>();
528 dirichlet_filters_lvl.filter_sol(vec_sol_lvl);
532 auto* fine_mesh_node = this->
_dom_ctrl.at(pos)->get_mesh_node();
535 fine_mesh_node->adapt_by_name(it);
565 void _create_solver()
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");
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);
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);
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);
607 auto cg_pcg =
Solver::new_pcg(
"DuDvMGCoarseSolver", sec_mg_coarse, lvl.matrix_sys, lvl.filter_sys, jacobi);
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Control class for DuDvFunctionals.
DomainLevelType::TrafoType TrafoType
The transformation we solve for.
DT_ DataType
The floating point type.
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.
IT_ IndexType
The index type.
String solver_name
The name of the section from solver_config we want to use.
PropertyMap & solver_config
Solver configuration.
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.
virtual String info() const override
DomainControl_::LayerType DomainLayerType
Domain layers.
virtual void optimize() override
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.
virtual ~DuDvFunctionalControl()
Virtual destructor.
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.
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.
Standard Refinery class template.
Global vector wrapper class template.
LocalVector_ & local()
Returns a reference to the internal local LAFEM vector object.
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.
static String get_formatted_solver_tree(String target="default")
Returns a descriptive string of the complete solver tree.
static String expression_target
the current solver's descriptive string
String class implementation.
String pad_back(size_type len, char c=' ') const
Pads the back of the string up to a desired length.
String trim(const String &charset) const
Trims the string.
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.
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.
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.
Status
Solver status return codes enumeration.
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.
String stringify(const T_ &item)
Converts an item into a String.
std::uint64_t Index
Index data type.