FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
hyperelasticity_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/global/matrix.hpp>
10#include <kernel/global/nonlinear_functional.hpp>
11#include <kernel/global/vector.hpp>
12
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>
17
18#include <kernel/lafem/sparse_matrix_bwrappedcsr.hpp>
19
20#include <control/domain/domain_control.hpp>
21#include <control/meshopt/meshopt_control.hpp>
22#include <control/meshopt/meshopt_precond_factory.hpp>
23
24namespace FEAT
25{
26 namespace Control
27 {
28 namespace Meshopt
29 {
54 template
55 <
56 typename DT_, typename IT_, typename DomainControl_,
57 template<typename, typename, typename> class Hyperelasticity_
58 >
60 : public MeshoptControlBase<DomainControl_>
61 {
62 public:
64 typedef DT_ DataType;
66 typedef IT_ IndexType;
67
70
72 typedef DomainControl_ DomainControlType;
74 typedef typename DomainControl_::LayerType DomainLayerType;
76 typedef typename DomainControl_::LevelType DomainLevelType;
77
79 typedef typename DomainLevelType::TrafoType TrafoType;
80
82 template<typename DT2_, typename IT2_>
83 using LocalQualityFunctionalType = Hyperelasticity_<DT2_, IT2_, TrafoType>;
84
87
89 typedef typename DomainControl_::MeshType MeshType;
91 typedef typename MeshType::CoordType CoordType;
92
95
98 <
99 DT_, IT_,
102
104 //typedef MeshoptAssemblerLevel<DomainLevelType> AssemblerLevelType;
105
109 <
113
115 std::deque<SystemLevelType*> _system_levels;
116
117 public:
123 std::shared_ptr<Solver::Linesearch<typename SystemLevelType::GlobalFunctional, typename SystemLevelType::GlobalSystemFilter>> linesearch;
125 //std::shared_ptr<Solver::NLOptLS
126 //<
127 // typename SystemLevelType::GlobalFunctional,
128 // typename SystemLevelType::GlobalSystemFilter>
129 //> solver;
130 std::shared_ptr<Solver::IterativeSolver<typename SystemLevelType::GlobalSystemVectorR>> solver;
132 std::shared_ptr<PrecondType> precond;
137
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_,
170 PropertyMap& solver_config_,
171 Args_&&... args):
172 BaseClass(dom_ctrl, dirichlet_list, slip_list),
174 solver_config(solver_config_),
175 solver_name(solver_name_),
176 precond(nullptr),
177 meshopt_lvl(meshopt_lvl_),
178 meshopt_lvl_pos(~size_t(1))
179 {
180 XASSERT(meshopt_lvl >= -1);
181
182 // If the input level was set to -1, take the max level of the domain control
183 if(meshopt_lvl == -1)
184 {
185 meshopt_lvl = dom_ctrl.max_level_index();
186 }
187
188 XASSERT(meshopt_lvl <= dom_ctrl.max_level_index());
189
190 // Now find the position of the mesh optimization level in the domain levels
191 for(size_t i(0); i < dom_ctrl.size_physical(); ++i)
192 {
193 if(dom_ctrl.at(i)->get_level_index() == meshopt_lvl)
194 {
195 meshopt_lvl_pos = i;
196 }
197 }
198
199 XASSERT(meshopt_lvl_pos < dom_ctrl.size_physical());
200
201 for(size_t i(0); i < dom_ctrl.size_physical(); ++i)
202 {
203 _system_levels.push_back( new SystemLevelType(
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)...));
209 }
210
211 for(Index i(0); i < get_num_levels(); ++i)
212 {
213 _system_levels.at(i)->assemble_gates(dom_ctrl.at(i).layer());
214 // Call the operator's init() on the current level. This needs the gates, so it cannot be called
215 // earlier
216 _system_levels.at(i)->global_functional.init();
217 }
218
219 for(Index i(0); (i+1) < get_num_levels(); ++i)
220 {
221 _system_levels.at(i)->assemble_system_transfer(*_system_levels.at(i+1));
222 }
223
224 auto* solver_section = solver_config.query_section(solver_name);
225 if(solver_section == nullptr)
226 {
227 XABORTM("Could not find section for solver "+solver_name);
228 }
229
230 // create our preconditioner
231 precond = MeshoptPrecondFactory::create_nlopt_precond(*this, dom_ctrl, solver_section);
232
233 // create the actual nonlinear optimizer
234 _create_nonlinear_optimizer();
235 }
236
239
242 {
243 while(!_system_levels.empty())
244 {
245 delete _system_levels.back();
246 _system_levels.pop_back();
247 }
248
249 // Finish the solver
250 solver->done();
251
252 // Finish the preconditioner
253 if(precond != nullptr)
254 {
255 precond->done();
256 }
257 }
258
260 virtual CoordType compute_cell_size_defect(CoordType& lambda_min, CoordType& lambda_max,
261 CoordType& vol_min, CoordType& vol_max, CoordType& vol) const override
262 {
263
264 _system_levels.front()->global_functional.local().compute_cell_size_defect_pre_sync(vol_min, vol_max, vol);
265
266 vol_min = _system_levels.front()->gate_sys.min(vol_min);
267 vol_max = _system_levels.front()->gate_sys.max(vol_max);
268 vol = _system_levels.front()->gate_sys.sum(vol);
269
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);
272
273 lambda_min = _system_levels.front()->gate_sys.min(lambda_min);
274 lambda_max = _system_levels.front()->gate_sys.max(lambda_max);
275 cell_size_defect = _system_levels.front()->gate_sys.sum(cell_size_defect);
276
277 return cell_size_defect;
278 }
279
281 virtual String name() const override
282 {
283 return "HyperelasticityFunctionalControl<>";
284 }
285
287 virtual size_t get_num_levels() const override
288 {
289 return _system_levels.size();
290 }
291
293 virtual String info() const override
294 {
295 const Index pad_width(30);
296
297 String msg;
298
299 msg += name().pad_back(pad_width, '.') + String(":") + String("\n");
300
301 msg += String("level max/min").pad_back(pad_width, '.') + String(": ")
302 + stringify(this->_dom_ctrl.max_level_index()) + String(" / ")
303 + stringify(this->_dom_ctrl.min_level_index()) + String("\n");
304
305 msg += String("optimization on level").pad_back(pad_width, '.') + String(": ")
306 + stringify(meshopt_lvl) + String("\n");
307
308 for(const auto& it : this->get_dirichlet_boundaries())
309 {
310 msg += String("Displacement BC on").pad_back(pad_width, '.') + String(": ") + it + String("\n");
311 }
312
313 for(const auto& it : this->get_slip_boundaries())
314 {
315 msg += String("Unilateral BC of place on").pad_back(pad_width, '.') + String(": ") + it + String("\n");
316 }
317
318 msg += String("DoF").pad_back(pad_width, '.') + String(": ")
319 + stringify(_system_levels.front()->global_functional.columns()) + String("\n");
320
321 try
322 {
323 msg += String("Solver") .pad_back(pad_width, '.') + String(": ")
325 }
326 catch(...)
327 {
328 }
329
330 if(precond != nullptr)
331 {
332 msg += String("Nonlinear preconditioner:\n");
333 msg += precond->info() + String("\n");
334 }
335
336 msg += _system_levels.front()->global_functional.local().info();
337
338 return msg;
339 }
340
343 {
344 return _system_levels.front()->coords_buffer;
345 }
346
348 virtual void buffer_to_mesh() override
349 {
350 // Write finest level
351 _system_levels.front()->global_functional.local().buffer_to_mesh();
352
353 // Get the coords buffer on the finest level
354 const auto& coords_buffer_loc = _system_levels.front()->coords_buffer.local();
355
356 // Transfer fine coords buffer to coarser levels and perform buffer_to_mesh
357 for(size_t level(0); level < get_num_levels(); ++level )
358 {
359 Index ndofs(_system_levels.at(level)->local_functional.trafo_space.get_num_dofs());
360
361 // At this point, what we really need is a primal restriction operator that restricts the FE function
362 // representing the coordinate distribution to the coarser level. This is very simple for continuous
363 // Lagrange elements (just discard the additional information from the fine level), but not clear in
364 // the generic case. So we use an evil hack here:
365 // Because of the underlying two level ordering, we just need to copy the first ndofs entries from
366 // the fine level vector.
368 vec_level(coords_buffer_loc, ndofs, Index(0));
369
370 _system_levels.at(level)->global_functional.local().get_coords().copy(vec_level);
371 _system_levels.at(level)->global_functional.local().buffer_to_mesh();
372 }
373 }
374
376 virtual void mesh_to_buffer() override
377 {
378 // Write finest level
379 _system_levels.front()->global_functional.local().mesh_to_buffer();
380
381 // Get the coords buffer on the finest level
382 const auto& coords_buffer_loc = _system_levels.front()->coords_buffer.local();
383
384 // Transfer fine coords buffer to coarser levels and perform buffer_to_mesh
385 for(size_t level(0); level < get_num_levels(); ++level )
386 {
387 Index ndofs(_system_levels.at(level)->local_functional.trafo_space.get_num_dofs());
388
389 // At this point, what we really need is a primal restriction operator that restricts the FE function
390 // representing the coordinate distribution to the coarser level. This is very simple for continuous
391 // Lagrange elements (just discard the additional information from the fine level), but not clear in
392 // the generic case. So we use an evil hack here:
393 // Because of the underlying two level ordering, we just need to copy the first ndofs entries from
394 // the fine level vector.
395 typename SystemLevelType::LocalCoordsBuffer vec_level(coords_buffer_loc, ndofs, Index(0));
396
397 _system_levels.at(level)->global_functional.local().get_coords().copy(vec_level);
398 }
399 }
400
403 Geometry::ExportVTK<MeshType>& exporter, const int lvl_index) const override
404 {
405
406 for(size_t pos(0); pos < get_num_levels(); ++pos)
407 {
408 if(this->_system_levels.at(pos)->get_level_index() == lvl_index)
409 {
410
411 const auto& sys_lvl = this->_system_levels.at(pos);
412 sys_lvl->global_functional.local().add_to_vtk_exporter(exporter);
413
414 DataType fval(0);
415 auto grad = sys_lvl->global_functional.create_vector_r();
416
417 sys_lvl->global_functional.eval_fval_grad(fval, grad);
418 sys_lvl->filter_sys.filter_def(grad);
419 exporter.add_vertex_vector("grad", grad.local());
420
421 for(auto& it:sys_lvl->filter_sys.local().template at<0>())
422 {
423 const String field_name("nu_"+it.first);
424 // WARNING: This explicitly assumes that the filter vector belong to a P1/Q1 space and thus "lives"
425 // in the mesh's vertices
426 exporter.add_vertex_vector(field_name, it.second.get_filter_vector());
427 }
428 }
429 }
430 }
431
433 virtual void prepare(const typename SystemLevelType::GlobalSystemVectorR& vec_state) override
434 {
435 // Prepare the preconditioner before updating the status
436 if(precond != nullptr)
437 precond->init_numeric();
438
439 typename SystemLevelType::LocalCoordsBuffer vec_buf;
440 vec_buf.convert(vec_state.local());
441
442 for(size_t level(get_num_levels()); level > 0; )
443 {
444 --level;
445 Index ndofs(_system_levels.at(level)->local_functional.trafo_space.get_num_dofs());
446
447 // At this point, what we really need is a primal restriction operator that restricts the FE function
448 // representing the coordinate distribution to the coarser level. This is very simple for continuous
449 // Lagrange elements (just discard the additional information from the fine level), but not clear in
450 // the generic case. So we use an evil hack here:
451 // Because of the underlying two level ordering, we just need to copy the first ndofs entries from
452 // the fine level vector.
454 global_vec_level( &(_system_levels.at(level)->gate_sys), vec_buf, ndofs, Index(0));
455
456 _system_levels.at(level)->global_functional.prepare
457 (global_vec_level, _system_levels.at(level)->filter_sys);
458
459 // Call init() here to recompute all scales with current_** ScaleComputation
460 _system_levels.at(level)->global_functional.init();
461 }
462
463 }
464
466 virtual void optimize() override
467 {
468 // fetch our finest levels
469 SystemLevelType& the_system_level = *_system_levels.at(meshopt_lvl_pos);
470
471 // create our RHS and SOL vectors
472 typename SystemLevelType::GlobalSystemVectorR vec_rhs(the_system_level.assemble_rhs_vector());
473 typename SystemLevelType::GlobalSystemVectorL vec_sol(the_system_level.assemble_sol_vector());
474
475 // solve
476 //Solver::solve(*solver, vec_sol, vec_rhs, the_system_level.global_functional, the_system_level.filter_sys);
477
478 // Let it be knownst to Statistics that it was Us who called the solver
480
481 the_system_level.global_functional.reset_num_evals();
482 solver->correct(vec_sol, vec_rhs);
483
484 //If the mesh was not optimized on the finest domain level, we now need to prolongate the solution by:
485 // - refine the coarse vertex set using the StandardRefinery
486 // - copy the results to the CoordsBuffer
487 // - convert the CoordsBuffer to a vector type that we can filter with the system's Dirichlet filter
488 // - copy the filtered vector's contents back to the buffer and write the buffer to the mesh
489 // - apply the nonlinear filter representing unilateral BCs of place by calling adapt() for the
490 // corresponding meshparts
491 for(size_t pos(meshopt_lvl_pos); pos > size_t(0);)
492 {
493 --pos;
494
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();
498
499 // Refine coarse vertex set and write the result to the CoordsBuffer
500 Geometry::StandardRefinery<MeshType> refinery(coarse_mesh);
501 refinery.fill_vertex_set(fine_vtx);
502 _system_levels.at(pos)->global_functional.local().mesh_to_buffer();
503 // Convert the buffer to a filterable vector
504 typename SystemLevelType::GlobalSystemVectorL::LocalVectorType vec_sol_lvl;
505 vec_sol_lvl.convert(_system_levels.at(pos)->coords_buffer.local());
506 // Filter this vector, copy back the contents and write the changes to the mesh
507 auto& dirichlet_filters_lvl = (_system_levels.at(pos)->filter_sys).local().template at<1>();
508 dirichlet_filters_lvl.filter_sol(vec_sol_lvl);
509 _system_levels.at(pos)->coords_buffer.local().copy(vec_sol_lvl);
510 _system_levels.at(pos)->global_functional.local().buffer_to_mesh();
511 // Now call adapt() on the slip boundaries
512 auto* fine_mesh_node = this->_dom_ctrl.at(pos)->get_mesh_node();
513 for(const auto& it:this->get_slip_boundaries())
514 {
515 fine_mesh_node->adapt_by_name(it);
516 }
517 }
518
519 // Now we need to update all coarser levels
520 for(size_t pos(meshopt_lvl_pos+1); pos < get_num_levels(); ++pos)
521 {
522 Index ndofs(_system_levels.at(pos)->local_functional.trafo_space.get_num_dofs());
523
524 // At this point, what we really need is a primal restriction operator that restricts the FE function
525 // representing the coordinate distribution to the coarser level. This is very simple for continuous
526 // Lagrange elements (just discard the additional information from the fine level), but not clear in
527 // the generic case. So we use an evil hack here:
528 // Because of the underlying two level ordering, we just need to copy the first ndofs entries from
529 // the fine level vector.
531 global_sol_level( &(_system_levels.at(pos)->gate_sys), vec_sol.local(), ndofs, Index(0));
532
533 _system_levels.at(pos)->global_functional.prepare(
534 global_sol_level, _system_levels.at(pos)->filter_sys);
535
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();
538 }
539
540 }
541 protected:
542 void _create_linesearch(const String& section_name)
543 {
544 // Get the section where our solver is configured
545 auto section = solver_config.query_section(section_name);
546 if(section == nullptr)
547 {
548 XABORTM("could not find section "+section_name+" in PropertyMap!");
549 }
550
551 // Get the required type String
552 auto solver_p = section->query("type");
553 if (!solver_p.second)
554 {
555 XABORTM("No type key found in PropertyMap section with name " + section_name + "!");
556 }
557 String solver_type(solver_p.first);
558
559 // \todo: NewtonRaphsonLinesearch requires the operator to compute hessians, which has to be caught at
560 // runtime
561 /*if(solver_type == "NewtonRaphsonLinesearch")
562 {
563 result = Solver::new_newton_raphson_linesearch(
564 derefer<VectorTypeR>(system_levels.at(back_level)->op_sys, nullptr),
565 derefer<VectorTypeR>(system_levels.at(back_level)->filter_sys, nullptr));
566 }
567 else */
568 if(solver_type == "SecantLinesearch")
569 {
570 linesearch = Solver::new_secant_linesearch(section_name, section,
571 _system_levels.at(meshopt_lvl_pos)->global_functional,
572 _system_levels.at(meshopt_lvl_pos)->filter_sys);
573 }
574 else if(solver_type == "MQCLinesearch")
575 {
576 linesearch = Solver::new_mqc_linesearch(section_name, section,
577 _system_levels.at(meshopt_lvl_pos)->global_functional,
578 _system_levels.at(meshopt_lvl_pos)->filter_sys);
579 }
580 else
581 {
582 XABORTM("Unknown linesearch type " + section_name + "!");
583 }
584 }
585
586 void _create_nonlinear_optimizer()
587 {
588 // query our solver section
589 PropertyMap* solver_section = solver_config.query_section(solver_name);
590 String solver_type = "none";
591 String nlcg_section_name = solver_name;
592
593 // Get the String identifying the solver type
594 auto solver_p = solver_section->query("type");
595 if (!solver_p.second)
596 {
597 XABORTM("no type key found in property map: " + solver_name + "!");
598 }
599 solver_type = solver_p.first;
600
601 // there are only 2 allowed solver types: 'QPenalty' or 'NLCG'
602 // QPenalty might be used as an outer solver around NLCG, so let's check for this
603
604 const bool is_qpenalty = (solver_type == "QPenalty");
605 PropertyMap* qpenalty_section = nullptr;
606 if(is_qpenalty)
607 {
608 // ok, use QPenalty on the outside, so get its inner solver
609 qpenalty_section = solver_section;
610
611 // Create inner solver first
612 auto inner_solver_p = solver_section->query("inner_solver");
613 // Safety catches for recursions
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.");
616
617 // now replace our solver_section pointer by the inner solver, which must be NLCG now
618 nlcg_section_name = inner_solver_p.first;
619 solver_section = solver_config.query_section(inner_solver_p.first);
620 auto solver_type_p = solver_section->query("type");
621 if (!solver_type_p.second)
622 {
623 XABORTM("no type key found in property map: " + inner_solver_p.first + "!");
624 }
625 solver_type = solver_type_p.first;
626 }
627
628 // now the solver type must be 'NLCG'
629 if(solver_type != "NLCG")
630 {
631 XABORTM("Solver type key "+stringify(solver_type)+" unknown.");
632 }
633
634 // okay, let's create an NLCG
635 String linesearch_name("");
636 auto linesearch_p = solver_section->query("linesearch");
637 if(linesearch_p.second)
638 {
639 linesearch_name = linesearch_p.first;
640 }
641 else
642 {
643 XABORTM("NLCG config section is missing the mandatory linesearch key!");
644 }
645
646 // create the linesearch
647 _create_linesearch(linesearch_name);
648
649 // create the actual NLCG solver
650 solver = Solver::new_nlcg(nlcg_section_name, solver_section,
651 _system_levels.at(meshopt_lvl_pos)->global_functional,
652 _system_levels.at(meshopt_lvl_pos)->filter_sys,
654
655 // if we wanted a QPenalty in the first place, create it around the NLCG now
656 if(is_qpenalty)
657 {
659 solver_name, qpenalty_section, _system_levels.at(meshopt_lvl_pos)->global_functional, solver);
660 }
661
662 // finally, initialize it
663 solver->init();
664 solver->set_plot_name(solver->name() + " (meshopt-Hyper)");
665 }
666 }; // class HyperelasticityFunctionalControl
667 } // namespace Meshopt
668 } // namespace Control
669} // namespace FEAT
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
#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.
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.
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.
virtual SystemLevelType::GlobalCoordsBuffer & get_coords() override
Gets the coordinates buffer vector.
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.
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.
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 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.
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.
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
void reset_num_evals()
Resets the evaluation counters.
LocalVector_ & local()
Returns a reference to the internal local LAFEM vector object.
Definition: vector.hpp:121
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.
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< 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.
Definition: qpenalty.hpp:392
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.
Definition: nlcg.hpp:911
FEAT namespace.
Definition: adjactor.hpp:12
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:944
@ 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.