FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
meshopt_control_factory.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/meshopt/rumpf_functionals/p1.hpp>
10#include <kernel/meshopt/rumpf_functionals/q1.hpp>
11
12//#include <kernel/meshopt/rumpf_functionals/2d_q1_unrolled.hpp>
13//#include <kernel/meshopt/rumpf_functionals/2d_p1_unrolled.hpp>
14//#include <kernel/meshopt/rumpf_functionals/3d_p1_unrolled.hpp>
15
16#include <kernel/meshopt/hyperelasticity_functional.hpp>
17#include <kernel/meshopt/mesh_concentration_function.hpp>
18
19#include <control/meshopt/meshopt_control.hpp>
20#include <control/meshopt/dudv_functional_control.hpp>
21#include <control/meshopt/hyperelasticity_functional_control.hpp>
22
23namespace FEAT
24{
25 namespace Control
26 {
27 namespace Meshopt
28 {
30
36 template
37 <
38 template<typename, typename, typename, typename, typename> class Functional_,
39 typename CellFunctional_
40 >
41 class SetCellFunctional
42 {
43 public:
44 template<typename DT_, typename IT_, typename Trafo_>
45 using Functional = Functional_<DT_, IT_, Trafo_, CellFunctional_, FEAT::Meshopt::RumpfTrafo<Trafo_, typename Trafo_::CoordType>>;
46 };
48
64 template<typename DT_, typename IT_>
66 {
88 template<typename DomCtrl_>
89 static std::shared_ptr <Control::Meshopt::MeshoptControlBase<DomCtrl_>>
90 create_dudv_control(DomCtrl_& dom_ctrl, const String& section_key, PropertyMap* meshopt_config, PropertyMap* solver_config)
91 {
92 std::shared_ptr<Control::Meshopt::MeshoptControlBase<DomCtrl_>> result(nullptr);
93
94 // -1 causes the DuDvFunctionalControl to use max level of the underlying domain control
95 int meshopt_lvl(-1);
96
97 // Get Meshopt configuration section
98 auto meshopt_section = meshopt_config->query_section(section_key);
99 XASSERTM(meshopt_section != nullptr, "Application config is missing the mandatory MeshOptimizer section!");
100
101 // Verify the type
102 auto type_p = meshopt_section->query("type");
103 XASSERTM(type_p.second, "MeshOptimizer section is missing the mandatory type!");
104 XASSERTM(type_p.first == "DuDv", "Invalid type string!");
105
106 // Get list of boundary conditions
107 auto dirichlet_list_p = meshopt_section->query("dirichlet_boundaries");
108 std::deque<String> dirichlet_list = dirichlet_list_p.first.split_by_whitespaces();
109
110 // Get list of boundary conditions
111 auto slip_list_p = meshopt_section->query("slip_boundaries");
112 std::deque<String> slip_list = slip_list_p.first.split_by_whitespaces();
113
114 // Get meshopt level (if any)
115 auto meshopt_lvl_p = meshopt_section->query("meshopt_lvl");
116 if(meshopt_lvl_p.second)
117 {
118 meshopt_lvl = std::stoi(meshopt_lvl_p.first);
119 }
120
121 auto config_section_p = meshopt_section->query("config_section");
122 XASSERTM(config_section_p.second, "MeshOptimizer config section is missing config_section entry!");
123
124 auto dudv_config_section = meshopt_config->query_section(config_section_p.first);
125 if(dudv_config_section == nullptr)
126 {
127 XABORTM("config_section "+config_section_p.first+" not found!");
128 }
129
130 auto solver_p = dudv_config_section->query("solver_config");
131 XASSERTM(solver_p.second, "DuDv config section is missing solver_config entry!");
132
133 bool fixed_reference_domain(false);
134 auto fixed_reference_domain_p = dudv_config_section->query("fixed_reference_domain");
135 if(fixed_reference_domain_p.second)
136 {
137 fixed_reference_domain = (std::stoi(fixed_reference_domain_p.first) == 1);
138 }
139
141 result = std::make_shared<DuDvCtrl>(
142 dom_ctrl, meshopt_lvl,
143 dirichlet_list, slip_list, solver_p.first, *solver_config, fixed_reference_domain);
144
145 return result;
146 } // create_dudv_control
147
172 template<typename DomCtrl_>
173 static std::shared_ptr <Control::Meshopt::MeshoptControlBase<DomCtrl_>>
174 create_hyperelasticity_control(DomCtrl_& dom_ctrl, const String& section_key, PropertyMap* meshopt_config,
175 PropertyMap* solver_config)
176 {
177 typedef typename DomCtrl_::LevelType::TrafoType TrafoType;
178
179 std::shared_ptr<Control::Meshopt::MeshoptControlBase<DomCtrl_>> result(nullptr);
180
181 DT_ fac_norm(0);
182 DT_ fac_det(0);
183 DT_ fac_cof(0);
184 DT_ fac_reg(0);
185
186 // -1 causes the HyperelasticityFunctionalControl to use max level of the underlying domain control
187 int meshopt_lvl(-1);
188
189 //bool split_hypercubes(false);
190
191 // Get Meshopt configuration section
192 auto meshopt_section = meshopt_config->query_section(section_key);
193 XASSERTM(meshopt_section != nullptr, "Application config is missing the mandatory MeshOptimizer section!");
194
195 // Verify the type
196 auto type_p = meshopt_section->query("type");
197 XASSERTM(type_p.second, "MeshOptimizer section is missing the mandatory type!");
198 XASSERTM(type_p.first == "Hyperelasticity", "Invalid type!");
199
200 // Get list of boundary conditions
201 auto dirichlet_list_p = meshopt_section->query("dirichlet_boundaries");
202 std::deque<String> dirichlet_list = dirichlet_list_p.first.split_by_whitespaces();
203
204 // Get list of boundary conditions
205 auto slip_list_p = meshopt_section->query("slip_boundaries");
206 std::deque<String> slip_list = slip_list_p.first.split_by_whitespaces();
207
208 // Get meshopt level (if any)
209 auto meshopt_lvl_p = meshopt_section->query("meshopt_lvl");
210 if(meshopt_lvl_p.second)
211 {
212 meshopt_lvl = std::stoi(meshopt_lvl_p.first);
213 }
214
215 // Get the name of the MeshOptimizer configuration section
216 auto config_section_p = meshopt_section->query("config_section");
217 if(!config_section_p.second)
218 {
219 XABORTM("config_section "+config_section_p.first+" not found");
220 }
221
222 // Get the MeshOptimizer configuration section
223 auto hyperelasticity_config_section = meshopt_config->query_section(config_section_p.first);
224
225 // Get fac_norm
226 auto fac_norm_p = hyperelasticity_config_section->query("fac_norm");
227 if(!fac_norm_p.second)
228 {
229 XABORTM("config_section "+config_section_p.first+" is missing fac_norm entry!");
230 }
231 fac_norm = DT_(std::stod(fac_norm_p.first));
232
233 // Get fac_det
234 auto fac_det_p = hyperelasticity_config_section->query("fac_det");
235 if(!fac_det_p.second)
236 {
237 XABORTM("config_section "+config_section_p.first+" is missing fac_det entry!");
238 }
239 fac_det = DT_(std::stod(fac_det_p.first));
240
241 // Get fac_cof
242 auto fac_cof_p = hyperelasticity_config_section->query("fac_cof");
243 if(!fac_cof_p.second)
244 {
245 XABORTM("config_section "+config_section_p.first+" is missing fac_cof entry!");
246 }
247 fac_cof = DT_(std::stod(fac_cof_p.first));
248
249 // Get fac_reg
250 auto fac_reg_p = hyperelasticity_config_section->query("fac_reg");
251 if(!fac_reg_p.second)
252 {
253 XABORTM("config_section "+config_section_p.first+" is missing fac_reg entry!");
254 }
255 fac_reg = DT_(std::stod(fac_reg_p.first));
256
257 // Get the local functional
258 auto cell_functional_p = hyperelasticity_config_section->query("cell_functional");
259 if(!cell_functional_p.second)
260 {
261 XABORTM("config_section "+config_section_p.first+" is missing cell_functional entry!");
262 }
263
264 // Get the handling of the 1/det term
265 int exponent_det(0);
266 auto exponent_det_p = hyperelasticity_config_section->query("exponent_det");
267 if(!exponent_det_p.second)
268 {
269 XABORTM("config_section "+config_section_p.first+" is missing exponent_det entry!");
270 }
271 exponent_det = std::stoi(exponent_det_p.first);
272
273 // Get the local functional
274 if(cell_functional_p.first == "RumpfFunctional")
275 {
276 typedef FEAT::Meshopt::RumpfFunctional<DT_, TrafoType> CellFunctionalType;
277 std::shared_ptr<CellFunctionalType> my_functional = std::make_shared<CellFunctionalType>
278 (fac_norm, fac_det, fac_cof, fac_reg, exponent_det);
279
281 (dom_ctrl, meshopt_lvl, hyperelasticity_config_section, meshopt_config, solver_config, my_functional,
282 dirichlet_list, slip_list);
283 }
284 // This is disabled because the ***Unrolled classes produce huge object files, slow code and are a pain to compile.
285 // If you need them for debugging purposes, use the code below
286 //else if(cell_functional_p.first == "RumpfFunctionalUnrolled")
287 //{
288 // typedef FEAT::Meshopt::RumpfFunctionalUnrolled<DT_, TrafoType> CellFunctionalType;
289 // std::shared_ptr<CellFunctionalType> my_functional = std::make_shared<CellFunctionalType>
290 // (fac_norm, fac_det, fac_cof, fac_reg, exponent_det);
291 // result = create_hyperelasticity_control_with_cell_functional(dom_ctrl, hyperelasticity_config_section,
292 // meshopt_config, solver_config, my_functional, dirichlet_list, slip_list);
293 //}
294 else
295 {
296 XABORTM("Unhandled cell_functional "+cell_functional_p.first);
297 }
298
299 return result;
300 } // create_hyperelasticity_control
301
342 template<typename DomCtrl_, typename CellFunctional_>
343 static std::shared_ptr <Control::Meshopt::MeshoptControlBase<DomCtrl_>>
345 const int meshopt_lvl,
346 PropertyMap* hyperelasticity_config_section,
347 PropertyMap* meshopt_config,
348 PropertyMap* solver_config,
349 std::shared_ptr<CellFunctional_> my_functional,
350 const std::deque<String>& dirichlet_list, const std::deque<String>& slip_list)
351 {
352 typedef typename DomCtrl_::LevelType::TrafoType TrafoType;
353
354 std::shared_ptr<Control::Meshopt::MeshoptControlBase<DomCtrl_>> result(nullptr);
355
356 // Get the global mesh quality functional
357 auto global_functional_p = hyperelasticity_config_section->query("global_functional");
358 if(!global_functional_p.second)
359 {
360 XABORTM("Hyperelasticity config section is missing global_functional entry!");
361 }
362
363 // Get scale computation type, default is once_uniform
364 FEAT::Meshopt::ScaleComputation scale_computation(FEAT::Meshopt::ScaleComputation::once_uniform);
365
366 auto scale_computation_p = hyperelasticity_config_section->query("scale_computation");
367 if(scale_computation_p.second)
368 {
369 scale_computation << scale_computation_p.first;
370 }
371
372 int align_mesh(0);
373 auto align_mesh_p = hyperelasticity_config_section->query("align_mesh");
374 if(align_mesh_p.second)
375 {
376 align_mesh = std::stoi(align_mesh_p.first);
377 }
378
379 // Get the solver config section
380 auto solver_p = hyperelasticity_config_section->query("solver_config");
381 if(!solver_p.second)
382 {
383 XABORTM("Hyperelasticity config section is missing solver entry!");
384 }
385
386 if(global_functional_p.first == "HyperelasticityFunctional")
387 {
388 typedef typename FEAT::Meshopt::
389 HyperelasticityFunctional<DT_, IT_, TrafoType, CellFunctional_>::RefCellTrafo RefCellTrafo;
390
391 std::shared_ptr<FEAT::Meshopt::MeshConcentrationFunctionBase<TrafoType, RefCellTrafo>>
392 mesh_conc_func(nullptr);
393
394 if( scale_computation == FEAT::Meshopt::ScaleComputation::current_concentration ||
395 scale_computation == FEAT::Meshopt::ScaleComputation::iter_concentration ||
396 align_mesh == 1)
397 {
398 auto conc_func_section_p = hyperelasticity_config_section->query("conc_function");
399 XASSERTM(conc_func_section_p.second, "conc_function missing!");
401 create(conc_func_section_p.first, meshopt_config);
402 }
403
405 <DT_, IT_, DomCtrl_,
406 SetCellFunctional<FEAT::Meshopt::HyperelasticityFunctional, CellFunctional_>::template Functional>>
407 (dom_ctrl, meshopt_lvl, dirichlet_list, slip_list, solver_p.first,
408 *solver_config, my_functional, scale_computation, mesh_conc_func, DT_(align_mesh));
409 }
410 else
411 {
412 XABORTM("Unknown global_functional "+global_functional_p.first);
413 }
414
415 return result;
416 } // create_hyperelasticity_control_with_functional
417
438 template<typename DomCtrl_>
439 static std::shared_ptr<Control::Meshopt::MeshoptControlBase<DomCtrl_>>
440 create_meshopt_control(DomCtrl_& dom_ctrl, const String& section_key,
441 PropertyMap* meshopt_config, PropertyMap* solver_config)
442 {
443 std::shared_ptr<Control::Meshopt::MeshoptControlBase<DomCtrl_>> result(nullptr);
444
445 String type("");
446
447 auto meshopt_section = meshopt_config->query_section(section_key);
448 if(meshopt_section == nullptr)
449 {
450 XABORTM("Meshopt config is missing the ["+section_key+"] section!");
451 }
452 else
453 {
454 // Get mandatory quality functional entry
455 auto type_p = meshopt_section->query("type");
456 if(!type_p.second)
457 {
458 XABORTM("MeshOptimizer section is missing the mandatory type!");
459 }
460 else
461 {
462 type = type_p.first;
463 }
464 }
465
466 if(type == "DuDv")
467 {
468 result = create_dudv_control(dom_ctrl, section_key, meshopt_config, solver_config);
469 }
470 if(type == "Hyperelasticity")
471 {
472 result = create_hyperelasticity_control(dom_ctrl, section_key, meshopt_config, solver_config);
473 }
474
475 if(result == nullptr)
476 {
477 XABORTM("MeshOptimizer section has unhandled type "+type);
478 }
479
480 return result;
481 }
482 }; // struct ControlFactory
483
484 } // namespace Meshopt
485 } // namespace Control
486} // namespace FEAT
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
FEAT Kernel base header.
Functionals for measuring and optimising mesh quality.
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.
String class implementation.
Definition: string.hpp:46
ScaleComputation
Enum class for different types of scale computations.
FEAT namespace.
Definition: adjactor.hpp:12
Factory for MeshoptControl objects.
static std::shared_ptr< Control::Meshopt::MeshoptControlBase< DomCtrl_ > > create_hyperelasticity_control(DomCtrl_ &dom_ctrl, const String &section_key, PropertyMap *meshopt_config, PropertyMap *solver_config)
Creates a HyperelasticityFunctionalControl object.
static std::shared_ptr< Control::Meshopt::MeshoptControlBase< DomCtrl_ > > create_dudv_control(DomCtrl_ &dom_ctrl, const String &section_key, PropertyMap *meshopt_config, PropertyMap *solver_config)
Creates a DuDvFunctionalControl object.
static std::shared_ptr< Control::Meshopt::MeshoptControlBase< DomCtrl_ > > create_meshopt_control(DomCtrl_ &dom_ctrl, const String &section_key, PropertyMap *meshopt_config, PropertyMap *solver_config)
Creates a MeshoptControlBase object according to a PropertyMap.
static std::shared_ptr< Control::Meshopt::MeshoptControlBase< DomCtrl_ > > create_hyperelasticity_control_with_cell_functional(DomCtrl_ &dom_ctrl, const int meshopt_lvl, PropertyMap *hyperelasticity_config_section, PropertyMap *meshopt_config, PropertyMap *solver_config, std::shared_ptr< CellFunctional_ > my_functional, const std::deque< String > &dirichlet_list, const std::deque< String > &slip_list)
Creates a HyperelasticityFunctionalControl object.
static std::shared_ptr< MeshConcentrationFunctionBase< Trafo_, RefCellTrafo_ > > create(const String &section_key, PropertyMap *config)
Creates a MeshConcentrationFunction according to a PropertyMap.