9#include <kernel/global/matrix.hpp>
10#include <kernel/global/nonlinear_functional.hpp>
11#include <kernel/global/vector.hpp>
13#include <kernel/solver/qpenalty.hpp>
14#include <kernel/solver/nlcg.hpp>
15#include <kernel/solver/mqc_linesearch.hpp>
16#include <kernel/solver/secant_linesearch.hpp>
18#include <kernel/lafem/sparse_matrix_bwrappedcsr.hpp>
20#include <control/domain/domain_control.hpp>
21#include <control/meshopt/meshopt_control.hpp>
22#include <control/meshopt/meshopt_precond_factory.hpp>
56 typename DT_,
typename IT_,
typename DomainControl_,
57 template<
typename,
typename,
typename>
class Hyperelasticity_
79 typedef typename DomainLevelType::TrafoType
TrafoType;
82 template<
typename DT2_,
typename IT2_>
89 typedef typename DomainControl_::MeshType
MeshType;
123 std::shared_ptr<Solver::Linesearch<typename SystemLevelType::GlobalFunctional, typename SystemLevelType::GlobalSystemFilter>>
linesearch;
130 std::shared_ptr<Solver::IterativeSolver<typename SystemLevelType::GlobalSystemVectorR>>
solver;
163 template<
typename... Args_>
165 DomainControl_& dom_ctrl,
166 const int meshopt_lvl_,
167 const std::deque<String>& dirichlet_list,
168 const std::deque<String>& slip_list,
169 const String& solver_name_,
172 BaseClass(dom_ctrl, dirichlet_list, slip_list),
191 for(
size_t i(0); i < dom_ctrl.size_physical(); ++i)
193 if(dom_ctrl.at(i)->get_level_index() ==
meshopt_lvl)
201 for(
size_t i(0); i < dom_ctrl.size_physical(); ++i)
204 dom_ctrl.at(i)->get_level_index(),
205 dom_ctrl.at(i)->get_mesh_node(),
206 dom_ctrl.at(i)->trafo,
207 dirichlet_list, slip_list,
208 std::forward<Args_>(args)...));
225 if(solver_section ==
nullptr)
234 _create_nonlinear_optimizer();
264 _system_levels.front()->global_functional.local().compute_cell_size_defect_pre_sync(vol_min, vol_max, vol);
270 CoordType cell_size_defect =
_system_levels.front()->global_functional.local().compute_cell_size_defect_post_sync(
271 lambda_min, lambda_max, vol_min, vol_max, vol);
275 cell_size_defect =
_system_levels.front()->gate_sys.sum(cell_size_defect);
277 return cell_size_defect;
283 return "HyperelasticityFunctionalControl<>";
295 const Index pad_width(30);
332 msg +=
String(
"Nonlinear preconditioner:\n");
351 _system_levels.front()->global_functional.local().buffer_to_mesh();
354 const auto& coords_buffer_loc =
_system_levels.front()->coords_buffer.local();
368 vec_level(coords_buffer_loc, ndofs,
Index(0));
370 _system_levels.at(level)->global_functional.local().get_coords().copy(vec_level);
371 _system_levels.at(level)->global_functional.local().buffer_to_mesh();
379 _system_levels.front()->global_functional.local().mesh_to_buffer();
382 const auto& coords_buffer_loc =
_system_levels.front()->coords_buffer.local();
397 _system_levels.at(level)->global_functional.local().get_coords().copy(vec_level);
408 if(this->_system_levels.at(pos)->get_level_index() == lvl_index)
411 const auto& sys_lvl = this->_system_levels.at(pos);
412 sys_lvl->global_functional.local().add_to_vtk_exporter(exporter);
415 auto grad = sys_lvl->global_functional.create_vector_r();
417 sys_lvl->global_functional.eval_fval_grad(fval,
grad);
418 sys_lvl->filter_sys.filter_def(
grad);
421 for(
auto& it:sys_lvl->filter_sys.local().template at<0>())
423 const String field_name(
"nu_"+it.first);
440 vec_buf.convert(vec_state.
local());
482 solver->correct(vec_sol, vec_rhs);
495 auto& coarse_mesh = this->
_dom_ctrl.at(pos+1)->get_mesh();
496 auto& fine_mesh = this->
_dom_ctrl.at(pos)->get_mesh();
497 auto& fine_vtx = fine_mesh.get_vertex_set();
501 refinery.fill_vertex_set(fine_vtx);
502 _system_levels.at(pos)->global_functional.local().mesh_to_buffer();
504 typename SystemLevelType::GlobalSystemVectorL::LocalVectorType vec_sol_lvl;
505 vec_sol_lvl.convert(
_system_levels.at(pos)->coords_buffer.local());
507 auto& dirichlet_filters_lvl = (
_system_levels.at(pos)->filter_sys).local().template at<1>();
508 dirichlet_filters_lvl.filter_sol(vec_sol_lvl);
510 _system_levels.at(pos)->global_functional.local().buffer_to_mesh();
512 auto* fine_mesh_node = this->
_dom_ctrl.at(pos)->get_mesh_node();
515 fine_mesh_node->adapt_by_name(it);
536 _system_levels.at(pos)->global_functional.local().get_coords().copy(global_sol_level.
local());
537 _system_levels.at(pos)->global_functional.local().buffer_to_mesh();
542 void _create_linesearch(
const String& section_name)
546 if(section ==
nullptr)
548 XABORTM(
"could not find section "+section_name+
" in PropertyMap!");
552 auto solver_p = section->query(
"type");
553 if (!solver_p.second)
555 XABORTM(
"No type key found in PropertyMap section with name " + section_name +
"!");
557 String solver_type(solver_p.first);
568 if(solver_type ==
"SecantLinesearch")
574 else if(solver_type ==
"MQCLinesearch")
582 XABORTM(
"Unknown linesearch type " + section_name +
"!");
586 void _create_nonlinear_optimizer()
590 String solver_type =
"none";
594 auto solver_p = solver_section->query(
"type");
595 if (!solver_p.second)
599 solver_type = solver_p.first;
604 const bool is_qpenalty = (solver_type ==
"QPenalty");
605 PropertyMap* qpenalty_section =
nullptr;
609 qpenalty_section = solver_section;
612 auto inner_solver_p = solver_section->query(
"inner_solver");
614 XASSERTM(inner_solver_p.second,
"QPenalty solver section is missing mandatory inner_solver key.");
615 XASSERTM(inner_solver_p.first !=
"QPenalty",
"QPenalty cannot be the inner solver for QPenalty.");
618 nlcg_section_name = inner_solver_p.first;
620 auto solver_type_p = solver_section->
query(
"type");
621 if (!solver_type_p.second)
623 XABORTM(
"no type key found in property map: " + inner_solver_p.first +
"!");
625 solver_type = solver_type_p.first;
629 if(solver_type !=
"NLCG")
635 String linesearch_name(
"");
636 auto linesearch_p = solver_section->query(
"linesearch");
637 if(linesearch_p.second)
639 linesearch_name = linesearch_p.first;
643 XABORTM(
"NLCG config section is missing the mandatory linesearch key!");
647 _create_linesearch(linesearch_name);
664 solver->set_plot_name(
solver->name() +
" (meshopt-Hyper)");
#define XABORTM(msg)
Abortion macro definition with custom message.
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Control class for HyperelasticityFunctionals.
NonlinearSystemLevel< DT_, IT_, LocalQualityFunctionalType > SystemLevelType
The system level type, holding all information about the nonlinear system of equations.
HyperelasticityFunctionalControl(const HyperelasticityFunctionalControl &)=delete
Explicitly delete the default constructor.
Hyperelasticity_< DT2_, IT2_, TrafoType > LocalQualityFunctionalType
Type of the "system matrix" for the solver.
DomainControl_ DomainControlType
The type of the domain control.
virtual void prepare(const typename SystemLevelType::GlobalSystemVectorR &vec_state) override
Sets the internal state variable.
HyperelasticityFunctionalControl(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_, Args_ &&... args)
Variadic template constructor.
LocalQualityFunctionalType< DT_, IT_ >::SpaceType TrafoSpace
The FE space the transformation lives in.
std::shared_ptr< Solver::Linesearch< typename SystemLevelType::GlobalFunctional, typename SystemLevelType::GlobalSystemFilter > > linesearch
The linesearch method for NLCG.
std::deque< SystemLevelType * > _system_levels
These hold the system information for each level.
size_t meshopt_lvl_pos
The position of this level in the deque of system levels.
IT_ IndexType
The index type.
virtual SystemLevelType::GlobalCoordsBuffer & get_coords() override
Gets the coordinates buffer vector.
PropertyMap & solver_config
Solver configuration.
DT_ DataType
The floating point type.
DomainControl_::LayerType DomainLayerType
Domain layers.
Solver::NLOptPrecond< typename SystemLevelType::GlobalSystemVectorR, typename SystemLevelType::GlobalSystemFilter > PrecondType
Type for assembling FE space based quantities like filters, gates etc.
MeshType::CoordType CoordType
The floating point type the mesh's coordinates use.
virtual ~HyperelasticityFunctionalControl()
Virtual destructor.
LAFEM::SparseMatrixBWrappedCSR< DT_, IT_, MeshType::world_dim > TransferMatrixType
Inter level transfer matrix.
int meshopt_lvl
The level index (= number of refinements since the mesh file) to optimize the mesh on.
DomainLevelType::TrafoType TrafoType
The transformation we solve for.
virtual size_t get_num_levels() const override
Get the number of levels in this object.
DomainControl_::MeshType MeshType
The underlying mesh type.
virtual String info() const override
const String solver_name
Name of the solver configuration from solver_config we want.
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 optimize() override
Optimizes the current mesh.
virtual void mesh_to_buffer() override
Copies the mesh's vertex coordinates to the buffer vector.
virtual CoordType compute_cell_size_defect(CoordType &lambda_min, CoordType &lambda_max, CoordType &vol_min, CoordType &vol_max, CoordType &vol) const override
**
MeshoptControlBase< DomainControl_ > BaseClass
Our base class.
std::shared_ptr< PrecondType > precond
The preconditioner. As this might involve a matrix to be assembled, we keep it between solves.
DomainControl_::LevelType DomainLevelType
Domain levels.
virtual String name() const override
Returns a descriptive String.
std::shared_ptr< Solver::IterativeSolver< typename SystemLevelType::GlobalSystemVectorR > > solver
The solver.
virtual void buffer_to_mesh() override
Copies the contents of the buffer vector to the mesh's vertex coordinates.
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.
GlobalSystemVectorR assemble_sol_vector() const
Assembles an intial guess vector.
GlobalSystemVectorL assemble_rhs_vector() const
Assembles a right hand side vector.
(Non)linear system of equations on one mesh refinement level
LocalFunctional::CoordsBufferType LocalCoordsBuffer
Local coordinates buffer type for passing information to or from the mesh.
Global::Vector< LocalSystemVectorR, SystemMirror > GlobalSystemVectorR
Global right-vectors.
GlobalFunctional global_functional
The global nonlinear functional.
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.
void reset_num_evals()
Resets the evaluation counters.
LocalVector_ & local()
Returns a reference to the internal local LAFEM vector object.
Wraps a SparseMatrixCSR to SparseMatrixBCSR.
A class organizing a tree of key-value pairs.
PropertyMap * query_section(String sec_path)
Queries a section by its section path.
std::pair< String, bool > query(String key_path) const
Queries a value by its key path.
Abstract base class for preconditioners for nonlinear optimization.
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< SecantLinesearch< Functional_, Filter_ > > new_secant_linesearch(Functional_ &functional, Filter_ &filter, typename Functional_::DataType secant_step=SecantLinesearch< Functional_, Filter_ >::secant_step_default, bool keep_iterates=false)
Creates a new SecantLinesearch object.
std::shared_ptr< QPenalty< Functional_ > > new_qpenalty(Functional_ &functional, std::shared_ptr< IterativeSolver< typename Functional_::VectorTypeR > > inner_solver, typename Functional_::VectorTypeR::DataType initial_penalty_param=typename Functional_::VectorTypeR::DataType(1))
Creates a new QPenalty object.
std::shared_ptr< MQCLinesearch< Functional_, Filter_ > > new_mqc_linesearch(Functional_ &functional, Filter_ &filter, bool keep_iterates=false)
Creates a new MQCLinesearch object.
std::shared_ptr< NLCG< Functional_, Filter_ > > new_nlcg(Functional_ &functional, Filter_ &filter, Linesearch_ &linesearch, NLCGDirectionUpdate direction_update=NLCG< Functional_, Filter_ >::direction_update_default, bool keep_iterates=false, std::shared_ptr< NLOptPrecond< typename Functional_::VectorTypeL, Filter_ > > precond=nullptr)
Creates a new NLCG solver object.
String stringify(const T_ &item)
Converts an item into a String.
@ grad
specifies whether the space should supply basis function gradients
std::uint64_t Index
Index data type.
static std::shared_ptr< Solver::NLOptPrecond< SolverVectorType_, FilterType_ > > create_nlopt_precond(MeshoptCtrl_ &my_ctrl, DomCtrl_ &dom_ctrl, PropertyMap *current_section)
Creates a preconditioner for nonlinear mesh optimization problems.