FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
mesh_concentration_function.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
7
9#include <kernel/shape.hpp>
10
11#include <kernel/analytic/common.hpp>
12#include <kernel/geometry/mesh_node.hpp>
13#include <kernel/geometry/intern/face_index_mapping.hpp>
14#include <kernel/meshopt/rumpf_trafo.hpp>
16#include <kernel/util/property_map.hpp>
17#include <kernel/util/dist.hpp>
18
19#include <deque>
20
21namespace FEAT
22{
23 namespace Meshopt
24 {
25
27
28 // Forward declarations
29 template<typename DT_>
30 class ConcentrationFunctionDefault;
31
32 template<typename DT_>
33 class ConcentrationFunctionPowOfDist;
35
52 template<typename DT_, typename ShapeType_>
53#ifndef DOXYGEN
54 struct AlignmentPenalty;
55#else
56 // Note: The following block is only visible for Doxygen. The implementation has to be provided by specializations
57 // in ShapeType_
59 {
61 typedef DT_ DataType;
64
89 template<typename Mesh_, typename Dist_, typename EdgeFreqs_>
90 static DataType compute_constraint(const Mesh_& DOXY(mesh), const Dist_& DOXY(dist),
91 const EdgeFreqs_& DOXY(edge_freqs))
92 {
93 }
94
118 template<typename Mesh_, typename Dist_>
119 static DataType compute_constraint(DataType* constraint_vec, const Mesh_& mesh, const Dist_& dist)
120 {
121 }
122
163 template<typename Vector_, typename Mesh_, typename Dist_, typename GradDist_, typename EdgeFreqs_>
165 Vector_& DOXY(grad), const DataType DOXY(alignment_fval), const DataType DOXY(fac),
166 const Mesh_& DOXY(mesh), const Dist_& DOXY(dist), const GradDist_& DOXY(grad_dist),
167 const EdgeFreqs_& DOXY(edge_freqs))
168 {
169 }
170
171 };
172#endif
173
175 template<typename DT_, int shape_dim>
176 struct AlignmentPenalty<DT_, Shape::Simplex<shape_dim>>
177 {
178 typedef DT_ DataType;
180
181 template<typename Mesh_, typename Dist_, typename EdgeFreqs_>
182 static DataType compute_constraint(const Mesh_& mesh, const Dist_& dist, const EdgeFreqs_& edge_freqs)
183 {
184 DataType constraint(0);
185 const auto& edge_idx = mesh.template get_index_set<1,0>();
186 for(Index edge(0); edge < mesh.get_num_entities(1); ++edge)
187 {
188 constraint += edge_freqs(edge)*FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
189 eval( - dist(edge_idx(edge,0)) * dist(edge_idx(edge,1)));
190 }
191
192 return constraint;
193 }
194
195 template<typename Mesh_, typename Dist_>
196 static DataType compute_constraint(DataType* constraint_vec, const Mesh_& mesh, const Dist_& dist)
197 {
198 XASSERT(constraint_vec != nullptr);
199 typedef Geometry::Intern::FaceIndexMapping<ShapeType, 1, 0> FimType;
200
201 DataType constraint(0);
202 const auto& idx = mesh.template get_index_set<ShapeType::dimension,0>();
203 for(Index cell(0); cell < mesh.get_num_entities(ShapeType::dimension); ++cell)
204 {
205 constraint_vec[cell] = DataType(0);
206 for(int edge(0); edge < Shape::FaceTraits<ShapeType,1>::count; ++edge)
207 {
208 //These are the indices of the vertices on edge
209 int i(FimType::map(edge,0));
210 int j(FimType::map(edge,1));
211 DataType my_constraint(FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
212 eval(- DataType(1)*dist(idx(cell, i)) * dist(idx(cell, j))) );
213
214 constraint_vec[cell] += my_constraint;
215
216 constraint += my_constraint;
217 }
218
219 }
220
221 return constraint;
222 }
223
224 template<typename Vector_, typename Mesh_, typename Dist_, typename GradDist_, typename EdgeFreqs_>
225 static void add_constraint_grad(
226 Vector_& grad, const DataType alignment_fval, const DataType fac, const Mesh_& mesh, const Dist_& dist, const GradDist_& grad_dist, const EdgeFreqs_& edge_freqs)
227 {
228 const auto& edge_idx = mesh.template get_index_set<1,0>();
230 typedef Tiny::Vector<DataType, Mesh_::world_dim> WorldPoint;
231
232 WorldPoint grad_loc(DataType(0));
233
234 for(Index edge(0); edge < mesh.get_num_entities(1); ++edge)
235 {
236 Index i(edge_idx(edge,0));
237 Index j(edge_idx(edge,1));
238
239 auto dist_prod = dist(i) * dist(j);
240 // Derivative of the heaviside function
241 auto heaviside_der = FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::der_x(-dist_prod);
242
243 grad_loc = (-fac * alignment_fval * heaviside_der * dist(j)) * grad_dist(i);
244 grad(i, grad(i) + edge_freqs(edge)*grad_loc);
245
246 grad_loc = (-fac * alignment_fval * heaviside_der * dist(i)) * grad_dist(j);
247 grad(j, grad(j) + edge_freqs(edge)*grad_loc);
248 }
249 }
250
251 };
252
253 template<typename DT_>
254 struct AlignmentPenalty<DT_, Shape::Hypercube<2>>
255 {
256
257 typedef DT_ DataType;
258 typedef Shape::Hypercube<2> ShapeType;
259
260 template<typename Mesh_, typename Dist_, typename EdgeFreqs_>
261 static DataType compute_constraint(const Mesh_& mesh, const Dist_& dist, const EdgeFreqs_& edge_freqs)
262 {
263 DataType constraint(0);
264 const auto& edge_idx = mesh.template get_index_set<1,0>();
265 for(Index edge(0); edge < mesh.get_num_entities(1); ++edge)
266 {
267 constraint += edge_freqs(edge)*FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
268 eval( - dist(edge_idx(edge,0)) * dist(edge_idx(edge,1)));
269 }
270
271 const auto& cell_idx = mesh.template get_index_set<ShapeType::dimension,0>();
272 for(Index cell(0); cell < mesh.get_num_entities(ShapeType::dimension); ++cell)
273 {
274 constraint += FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
275 eval( - dist(cell_idx(cell,0)) * dist(cell_idx(cell,3)));
276 constraint += FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
277 eval( - dist(cell_idx(cell,1)) * dist(cell_idx(cell,2)));
278 }
279
280 return constraint;
281 }
282
283 template<typename Mesh_, typename Dist_>
284 static DataType compute_constraint(DataType* constraint_vec, const Mesh_& mesh, const Dist_& dist)
285 {
286 XASSERT(constraint_vec != nullptr);
287 typedef Geometry::Intern::FaceIndexMapping<ShapeType, 1, 0> FimType;
288
289 DataType constraint(0);
290 const auto& idx = mesh.template get_index_set<ShapeType::dimension,0>();
291 for(Index cell(0); cell < mesh.get_num_entities(ShapeType::dimension); ++cell)
292 {
293 constraint_vec[cell] = DataType(0);
294 for(int edge(0); edge < Shape::FaceTraits<ShapeType,1>::count; ++edge)
295 {
296 //These are the indices of the vertices on edge
297 int i(FimType::map(edge,0));
298 int j(FimType::map(edge,1));
299 DataType my_constraint(FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
300 eval(- DataType(1)*dist(idx(cell, i)) * dist(idx(cell, j))) );
301
302 constraint_vec[cell] += my_constraint;
303
304 constraint += my_constraint;
305 }
306
307 DataType my_constraint(FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
308 eval( - dist(idx(cell,0)) * dist(idx(cell,3))));
309 my_constraint = FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
310 eval( - dist(idx(cell,1)) * dist(idx(cell,2)));
311
312 constraint_vec[cell] += my_constraint;
313
314 constraint += my_constraint;
315
316 }
317
318 return constraint;
319 }
320
321 template<typename Vector_, typename Mesh_, typename Dist_, typename GradDist_, typename EdgeFreqs_>
322 static void add_constraint_grad(
323 Vector_& grad, const DataType alignment_fval, const DataType fac, const Mesh_& mesh, const Dist_& dist,
324 const GradDist_& grad_dist, const EdgeFreqs_& edge_freqs)
325 {
326 const auto& edge_idx = mesh.template get_index_set<1,0>();
328 typedef Tiny::Vector<DataType, Mesh_::world_dim> WorldPoint;
329
330 WorldPoint grad_loc(DataType(0));
331
332 for(Index edge(0); edge < mesh.get_num_entities(1); ++edge)
333 {
334 Index i(edge_idx(edge,0));
335 Index j(edge_idx(edge,1));
336
337 auto dist_prod = dist(i) * dist(j);
338 // Derivative of the heaviside function
339 auto heaviside_der = FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::der_x(-dist_prod);
340
341 grad_loc = (-fac * alignment_fval * heaviside_der * dist(j)) * grad_dist(i);
342 grad(i, grad(i) + edge_freqs(edge)*grad_loc);
343
344 grad_loc = (-fac * alignment_fval * heaviside_der * dist(i)) * grad_dist(j);
345 grad(j, grad(j) + edge_freqs(edge)*grad_loc);
346 }
347
348 const auto& cell_idx = mesh.template get_index_set<ShapeType::dimension,0>();
349 for(Index cell(0); cell < mesh.get_num_entities(ShapeType::dimension); ++cell)
350 {
351 Index i(cell_idx(cell,Index(0)));
352 Index j(cell_idx(cell,Index(3)));
353
354 auto dist_prod = dist(i) * dist(j);
355 // Derivative of the heaviside function
356 auto heaviside_der = FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::der_x(-dist_prod);
357
358 grad_loc = (-fac * alignment_fval * heaviside_der * dist(j)) * grad_dist(i);
359 grad(i, grad(i)+grad_loc);
360
361 grad_loc = (-fac * alignment_fval * heaviside_der * dist(i)) * grad_dist(j);
362 grad(j, grad(j)+grad_loc);
363
364 i = cell_idx(cell,Index(1));
365 j = cell_idx(cell,Index(2));
366
367 dist_prod = dist(i) * dist(j);
368 // Derivative of the heaviside function
369 heaviside_der = FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::der_x(-dist_prod);
370
371 grad_loc = (-fac * alignment_fval * heaviside_der * dist(j)) * grad_dist(i);
372 grad(i, grad(i)+grad_loc);
373
374 grad_loc = (-fac * alignment_fval * heaviside_der * dist(i)) * grad_dist(j);
375 grad(j, grad(j)+grad_loc);
376 }
377 }
378 };
379
380 template<typename DT_>
381 struct AlignmentPenalty<DT_, Shape::Hypercube<3>>
382 {
383
384 typedef DT_ DataType;
385 typedef Shape::Hypercube<3> ShapeType;
386
387 template<typename Mesh_, typename Dist_, typename EdgeFreqs_>
388 static DataType compute_constraint(const Mesh_& mesh, const Dist_& dist, const EdgeFreqs_& edge_freqs)
389 {
390 DataType constraint(0);
391 const auto& edge_idx = mesh.template get_index_set<1,0>();
392 for(Index edge(0); edge < mesh.get_num_entities(1); ++edge)
393 {
394 constraint += edge_freqs(edge)*FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
395 eval( - dist(edge_idx(edge,0)) * dist(edge_idx(edge,1)));
396 }
397
398 const auto& face_idx = mesh.template get_index_set<2,0>();
399 for(Index face(0); face < mesh.get_num_entities(2); ++face)
400 {
401 constraint += FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
402 eval( - dist(face_idx(face,0)) * dist(face_idx(face,3)));
403 constraint += FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
404 eval( - dist(face_idx(face,1)) * dist(face_idx(face,2)));
405 }
406
407 const auto& cell_idx = mesh.template get_index_set<3,0>();
408 for(Index cell(0); cell < mesh.get_num_entities(3); ++cell)
409 {
410 constraint += FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
411 eval( - dist(cell_idx(cell,0)) * dist(cell_idx(cell,7)));
412 constraint += FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
413 eval( - dist(cell_idx(cell,1)) * dist(cell_idx(cell,6)));
414 constraint += FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
415 eval( - dist(cell_idx(cell,2)) * dist(cell_idx(cell,5)));
416 constraint += FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
417 eval( - dist(cell_idx(cell,3)) * dist(cell_idx(cell,4)));
418 }
419
420 return constraint;
421 }
422
423 template<typename Mesh_, typename Dist_>
424 static DataType compute_constraint(DataType* constraint_vec, const Mesh_& mesh, const Dist_& dist)
425 {
426 XASSERT(constraint_vec != nullptr);
427 typedef Geometry::Intern::FaceIndexMapping<ShapeType, 1, 0> VertAtEdge;
428 typedef Geometry::Intern::FaceIndexMapping<ShapeType, 2, 0> VertAtFace;
429
430 DataType constraint(0);
431 const auto& idx = mesh.template get_index_set<ShapeType::dimension,0>();
432 for(Index cell(0); cell < mesh.get_num_entities(ShapeType::dimension); ++cell)
433 {
434 constraint_vec[cell] = DataType(0);
435
436 for(int edge(0); edge < Shape::FaceTraits<ShapeType,1>::count; ++edge)
437 {
438 //These are the indices of the vertices on edge
439 int i(VertAtEdge::map(edge,0));
440 int j(VertAtEdge::map(edge,1));
441 DataType my_constraint(FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
442 eval(- DataType(1)*dist(idx(cell, Index(i))) * dist(idx(cell, Index(j)))) );
443
444 constraint_vec[cell] += my_constraint;
445
446 constraint += my_constraint;
447 }
448
449 for(int face(0); face < Shape::FaceTraits<ShapeType,2>::count; ++face)
450 {
451 // These are the indices of the vertices on edge
452 int i0(VertAtFace::map(face,0));
453 int i1(VertAtFace::map(face,1));
454 int i2(VertAtFace::map(face,2));
455 int i3(VertAtFace::map(face,3));
456
457 DataType my_constraint(0);
458 my_constraint += FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
459 eval(- DataType(1)*dist(idx(cell, Index(i0))) * dist(idx(cell, Index(i3))));
460 my_constraint += FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
461 eval(- DataType(1)*dist(idx(cell, Index(i1))) * dist(idx(cell, Index(i2))));
462
463 constraint_vec[cell] += my_constraint;
464
465 constraint += my_constraint;
466 }
467
468 DataType my_constraint(0);
469 my_constraint += FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
470 eval( - dist(idx(cell,0)) * dist(idx(cell,7)));
471 my_constraint += FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
472 eval( - dist(idx(cell,1)) * dist(idx(cell,6)));
473 my_constraint += FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
474 eval( - dist(idx(cell,2)) * dist(idx(cell,5)));
475 my_constraint += FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::
476 eval( - dist(idx(cell,3)) * dist(idx(cell,4)));
477
478 constraint_vec[cell] += my_constraint;
479
480 constraint += my_constraint;
481
482 }
483
484 return constraint;
485 }
486
487 template<typename Vector_, typename Mesh_, typename Dist_, typename GradDist_, typename EdgeFreqs_>
488 static void add_constraint_grad(
489 Vector_& grad, const DataType alignment_fval, const DataType fac, const Mesh_& mesh, const Dist_& dist,
490 const GradDist_& grad_dist, const EdgeFreqs_& edge_freqs)
491 {
492 const auto& edge_idx = mesh.template get_index_set<1,0>();
494 typedef Tiny::Vector<DataType, Mesh_::world_dim> WorldPoint;
495
496 WorldPoint grad_loc(DataType(0));
497
498 for(Index edge(0); edge < mesh.get_num_entities(1); ++edge)
499 {
500 Index i(edge_idx(edge,0));
501 Index j(edge_idx(edge,1));
502
503 auto dist_prod = dist(i) * dist(j);
504 // Derivative of the heaviside function
505 auto heaviside_der = FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::der_x(-dist_prod);
506
507 grad_loc = (-fac * alignment_fval * heaviside_der * dist(j)) * grad_dist(i);
508 grad(i, grad(i) + edge_freqs(edge)*grad_loc);
509
510 grad_loc = (-fac * alignment_fval * heaviside_der * dist(i)) * grad_dist(j);
511 grad(j, grad(j) + edge_freqs(edge)*grad_loc);
512 }
513
514 const auto& face_idx = mesh.template get_index_set<2,0>();
515 for(Index face(0); face < mesh.get_num_entities(2); ++face)
516 {
517 Index i(face_idx(face,Index(0)));
518 Index j(face_idx(face,Index(3)));
519
520 auto dist_prod = dist(i) * dist(j);
521 // Derivative of the heaviside function
522 auto heaviside_der = FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::der_x(-dist_prod);
523
524 grad_loc = (-fac * alignment_fval * heaviside_der * dist(j)) * grad_dist(i);
525 grad(i, grad(i)+grad_loc);
526
527 grad_loc = (-fac * alignment_fval * heaviside_der * dist(i)) * grad_dist(j);
528 grad(j, grad(j)+grad_loc);
529
530 i = face_idx(face,Index(1));
531 j = face_idx(face,Index(2));
532
533 dist_prod = dist(i) * dist(j);
534 // Derivative of the heaviside function
535 heaviside_der = FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::der_x(-dist_prod);
536
537 grad_loc = (-fac * alignment_fval * heaviside_der * dist(j)) * grad_dist(i);
538 grad(i, grad(i)+grad_loc);
539
540 grad_loc = (-fac * alignment_fval * heaviside_der * dist(i)) * grad_dist(j);
541 grad(j, grad(j)+grad_loc);
542 }
543
544 const auto& cell_idx = mesh.template get_index_set<3,0>();
545 for(Index cell(0); cell < mesh.get_num_entities(2); ++cell)
546 {
547 Index i[4]{cell_idx(cell,Index(0)), cell_idx(cell,Index(1)),cell_idx(cell,Index(2)),cell_idx(cell,Index(3))};
548 Index j[4]{cell_idx(cell,Index(7)), cell_idx(cell,Index(6)),cell_idx(cell,Index(5)),cell_idx(cell,Index(2))};
549
550 for(int k(0); k < 4; ++k)
551 {
552
553 auto dist_prod = dist(i[k]) * dist(j[k]);
554 // Derivative of the heaviside function
555 auto heaviside_der = FEAT::Analytic::Common::template HeavisideRegStatic<DataType>::der_x(-dist_prod);
556
557 grad_loc = (-fac * alignment_fval * heaviside_der * dist(j[k])) * grad_dist(i[k]);
558 grad(i[k], grad(i[k]) +grad_loc);
559
560 grad_loc = (-fac * alignment_fval * heaviside_der * dist(i[k])) * grad_dist(j[k]);
561 grad(j[k], grad(j[k]) + grad_loc);
562 }
563
564 }
565 }
566 };
568
590 template
591 <
592 typename Trafo_,
593 typename RefCellTrafo_ = RumpfTrafo<Trafo_, typename Trafo_::CoordType>
594 >
596 {
597 public:
599 typedef Trafo_ TrafoType;
600
602 typedef typename TrafoType::MeshType MeshType;
604 typedef typename MeshType::ShapeType ShapeType;
606 typedef typename MeshType::CoordType CoordType;
607
610
620 public:
623 {
624 }
625
629 virtual String info() const = 0;
630
640 virtual std::shared_ptr<MeshConcentrationFunctionBase> create_empty_clone() const = 0;
641
645 virtual void compute_dist() = 0;
646
650 virtual void compute_conc() = 0;
651
655 virtual void compute_grad_conc() = 0;
656
685 virtual void compute_grad_h(const CoordType& DOXY(sum_det)) = 0;
686
692 virtual const ScalarVectorType& get_conc() const = 0;
693
699 virtual const ScalarVectorType& get_dist() const = 0;
700
706 virtual const VectorType& get_grad_dist() const = 0;
707
713 virtual GradHType& get_grad_h() = 0;
714
720 virtual const GradHType& get_grad_h() const = 0;
721
731 virtual void set_mesh_node(const Geometry::RootMeshNode<MeshType>* DOXY(mesh_node_)) = 0;
732
738 virtual bool use_derivative() const = 0;
739
746 virtual CoordType compute_constraint() const = 0;
747
759 virtual CoordType compute_constraint(CoordType* DOXY(constraint_at_vtx)) const = 0;
760
774 virtual void add_constraint_grad(VectorType& DOXY(grad), const CoordType DOXY(constraint), const CoordType DOXY(fac)) const = 0;
775
783 virtual void compute_grad_sum_det(const VectorType& DOXY(coords)) = 0;
784
792 virtual void add_sync_vecs(std::set<VectorType*>& DOXY(sync_vecs)) = 0;
793
799 virtual CoordType& get_sum_conc() = 0;
800
801 };
802
820 template
821 <
822 typename ElementalFunction_,
823 typename Trafo_,
825 >
826 class MeshConcentrationFunction : public MeshConcentrationFunctionBase<Trafo_, RefCellTrafo_>
827 {
828 public:
831
833 typedef ElementalFunction_ ElementalFunction;
835 typedef Trafo_ TrafoType;
836
838 typedef typename TrafoType::MeshType MeshType;
840 typedef typename MeshType::CoordType CoordType;
841
844
846 typedef typename MeshType::ShapeType ShapeType;
858
859 protected:
864
880 // Each entry in the DenseVectorBlocked represents one cell. Each cell's block contains
881 // world_dim*(number of local vertices) entries. Has to be serialized like this because there is no
882 // DenseVector that saves a Tiny::Matrix
884
894 _mesh_node(nullptr),
895 _func(func_),
896 _edge_freqs(),
897 _dist(),
898 _grad_dist(),
900 _conc(),
901 _grad_conc(),
903 _grad_h()
904 {
905 }
906
908 // *
909 // */
910 //explicit MeshConcentrationFunction(const MeshConcentrationFunction& other) :
911 // _mesh_node(other._mesh_node),
912 // _func(other._func),
913 // _sum_conc(other._sum_conc)
914 // {
915 // _dist.clone(other._dist, LAFEM::CloneMode::Deep);
916 // _grad_dist.clone(other._grad_dist, LAFEM::CloneMode::Deep);
917 // _grad_conc.clone(other._grad_conc, LAFEM::CloneMode::Deep);
918 // _grad_sum_det.clone(other._grad_sum_det, LAFEM::CloneMode::Deep);
919 // _grad_h.clone(other._grad_h, LAFEM::CloneMode::Deep);
920 // }
921
922 public:
925 {
926 }
927
929 virtual void add_sync_vecs(std::set<VectorType*>& sync_vecs) override
930 {
931 if(_func.use_derivative)
932 {
933 sync_vecs.insert(&_grad_sum_det);
934 sync_vecs.insert(&_grad_conc);
935 }
936 }
937
939 virtual const ScalarVectorType& get_conc() const override
940 {
941 return _conc;
942 }
943
945 virtual const ScalarVectorType& get_dist() const override
946 {
947 return _dist;
948 }
949
951 virtual const VectorType& get_grad_dist() const override
952 {
953 return _grad_dist;
954 }
955
957 virtual GradHType& get_grad_h() override
958 {
959 return _grad_h;
960 }
961
963 virtual const GradHType& get_grad_h() const override
964 {
965 return _grad_h;
966 }
967
969 virtual CoordType& get_sum_conc() override
970 {
971 return _sum_conc;
972 }
973
975 virtual String info() const override
976 {
977 return _func.info();
978 }
979
981 virtual void set_mesh_node(const Geometry::RootMeshNode<MeshType>* mesh_node_) override
982 {
983 XASSERT(_mesh_node == nullptr);
984
985 _mesh_node = mesh_node_;
986
987 _sum_conc = CoordType(0);
988
989 Index ndofs(_mesh_node->get_mesh()->get_num_entities(0));
990 Index nedges(_mesh_node->get_mesh()->get_num_entities(1));
991 Index ncells(_mesh_node->get_mesh()->get_num_entities(ShapeType::dimension));
992
994 _dist = ScalarVectorType(ndofs, CoordType(0));
995 _grad_dist = VectorType(ndofs,CoordType(0));
996 _conc = ScalarVectorType(ncells);
997 _grad_conc = VectorType(ndofs, CoordType(0));
998 _grad_h = GradHType(ncells,CoordType(0));
1000
1001 for(const auto& it: _mesh_node->get_mesh_part_names())
1002 {
1003 if(it.starts_with("_halo"))
1004 {
1005 const auto& edge_ts = _mesh_node->find_mesh_part(it)->template get_target_set<1>();
1006 for(Index edge(0); edge < edge_ts.get_num_entities(); ++edge)
1007 _edge_freqs(edge_ts[edge], _edge_freqs(edge_ts[edge])+CoordType(1));
1008 }
1009 }
1011 }
1012
1014 virtual bool use_derivative() const override
1015 {
1016 return _func.use_derivative;
1017 }
1018
1027 virtual void compute_conc() override
1028 {
1029 // Total number of cells in the mesh
1030 const Index ncells(_mesh_node->get_mesh()->get_num_entities(ShapeType::dimension));
1031 // Index set for local/global numbering
1032 const auto& idx = _mesh_node->get_mesh()->template get_index_set<ShapeType::dimension,0>();
1033
1034 this->_conc.format(CoordType(0));
1035
1036 _sum_conc = CoordType(0);
1037
1038 for(Index cell(0); cell < ncells; ++cell)
1039 {
1040 CoordType avg_dist(0);
1041
1042 for(int j(0); j < Shape::FaceTraits<ShapeType,0>::count; ++j)
1043 {
1044 avg_dist += this->_dist(idx(cell,j));
1045 }
1046
1048
1049 this->_conc(cell, _func.conc_val(avg_dist));
1050 _sum_conc += this->_conc(cell);
1051 }
1052 }
1053
1061 virtual void compute_grad_sum_det(const VectorType& coords) override
1062 {
1063 if(_func.use_derivative)
1064 {
1065 RefCellTrafo_::compute_grad_sum_det(_grad_sum_det, coords, *(_mesh_node->get_mesh()));
1066 }
1067 }
1068
1091 template<typename Tgrad_, typename Tl_, typename Tgradl_>
1092 void compute_grad_conc_local(Tgrad_& grad_loc_, const Tl_& dist_loc_, const Tgradl_& grad_dist_loc_)
1093 {
1094 grad_loc_.format(CoordType(0));
1095
1096 // This will be the average of the levelset values at the vertices
1097 CoordType val(0);
1098 for(int i(0); i < Shape::FaceTraits<ShapeType,0>::count; ++i)
1099 {
1100 val += dist_loc_(i);
1101 }
1102
1104
1105 for(int i(0); i < Shape::FaceTraits<ShapeType,0>::count; ++i)
1106 {
1107 grad_loc_[i] = _func.conc_der(val)/CoordType(Shape::FaceTraits<ShapeType,0>::count) * grad_dist_loc_[i];
1108 }
1109 }
1110
1112 virtual void compute_grad_h(const CoordType& sum_det) override
1113 {
1114 XASSERT(_mesh_node != nullptr);
1115
1116 _grad_h.format();
1117
1118 if(_func.use_derivative)
1119 {
1120
1121 // Index set for local/global numbering
1122 auto& idx = _mesh_node->get_mesh()->template get_index_set<ShapeType::dimension,0>();
1123 // This will hold the levelset values at the mesh vertices for one element
1125 // This will hold the levelset gradient values for one element for passing to other routines
1127 // This will hold the local gradient values for one element for passing to other routines
1129 // This will hold the computed local gradient values for one element for copy assigning to the blocked
1130 // datatype
1132
1133 CoordType exponent(CoordType(1)/CoordType(MeshType::world_dim) - CoordType(1));
1134
1135 for(Index cell(0); cell < _mesh_node->get_mesh()->get_num_entities(ShapeType::dimension); ++cell)
1136 {
1137 grad_loc.format();
1138 for(int j(0); j < Shape::FaceTraits<ShapeType,0>::count; ++j)
1139 {
1140 Index i(idx(cell, j));
1141 // Get levelset
1142 dist_loc(j) = _dist(i);
1143 // Get levelset gradient
1144 grad_dist_loc[j] = _grad_dist(i);
1145 }
1146
1147 compute_grad_conc_local(grad_loc, dist_loc, grad_dist_loc);
1148
1149 for(int d(0); d < MeshType::world_dim; ++d)
1150 {
1151 for(int j(0); j < Shape::FaceTraits<ShapeType,0>::count; ++j)
1152 {
1153 Index i(idx(cell, j));
1154
1155 tmp(j*MeshType::world_dim +d) =
1156 CoordType(1)/CoordType(MeshType::world_dim)*Math::pow(_conc(cell)/_sum_conc*sum_det,exponent)
1157 *( _conc(cell)*(_grad_sum_det(i)(d)*_sum_conc + sum_det*_grad_conc(i)(d) )
1158 + grad_loc(j,d) * sum_det *_sum_conc)
1160 }
1161 }
1162 _grad_h(cell, tmp + _grad_h(cell));
1163
1164 }
1165 } // _func.use_derivative
1166
1167 } // compute_grad_h
1168
1178 virtual void compute_grad_conc() override
1179 {
1180 // Clear the old gradient
1182
1183 // Index set for local/global numbering
1184 auto& idx = _mesh_node->get_mesh()->template get_index_set<ShapeType::dimension,0>();
1185
1186 // This will hold the coordinates for one element for passing to other routines
1187 FEAT::Tiny::Matrix <CoordType, Shape::FaceTraits<ShapeType,0>::count, MeshType::world_dim> x;
1188 // Local cell dimensions for passing to other routines
1189 FEAT::Tiny::Vector <CoordType,MeshType::world_dim> h;
1190 // This will hold the local gradient for one element for passing to other routines
1191 FEAT::Tiny::Matrix <CoordType, Shape::FaceTraits<ShapeType,0>::count, MeshType::world_dim> grad_loc;
1192 // This will hold the levelset values at the mesh vertices for one element
1193 FEAT::Tiny::Vector <CoordType, Shape::FaceTraits<ShapeType,0>::count> grad_dist_loc;
1194 // This will hold the levelset gradient values for one element for passing to other routines
1195 FEAT::Tiny::Matrix <CoordType, Shape::FaceTraits<ShapeType,0>::count, MeshType::world_dim> dist_loc;
1196
1197 // Compute the functional value for each cell
1198 for(Index cell(0); cell < _mesh_node->get_mesh()->get_num_entities(ShapeType::dimension); ++cell)
1199 {
1200 // Collect levelset and levelset grad values
1201 for(int j(0); j < Shape::FaceTraits<ShapeType,0>::count; ++j)
1202 {
1203 // Global vertex/dof index
1204 Index i(idx(cell, j));
1205 // Get levelset
1206 grad_dist_loc(j) = _dist(i);
1207 // Get levelset gradient
1208 dist_loc[j] = _grad_dist(i);
1209 }
1210
1211 // Compute gradient of the concentration on this cell
1212 compute_grad_conc_local(grad_loc, grad_dist_loc, dist_loc);
1213
1214 // Add local contributions to global gradient vector
1215 for(int j(0); j < Shape::FaceTraits<ShapeType,0>::count; ++j)
1216 {
1217 Index i(idx(cell, j));
1218 this->_grad_conc(i, _grad_conc(i) + grad_loc[j]);
1219 }
1220 }
1221
1222 } // compute_grad_conc()
1223
1225 virtual CoordType compute_constraint() const override
1226 {
1227 return PenaltyFunction::compute_constraint(*(_mesh_node->get_mesh()), this->_dist, this->_edge_freqs);
1228 }
1229
1241 virtual CoordType compute_constraint(CoordType* constraint_at_vtx) const override
1242 {
1243 XASSERT(constraint_at_vtx != nullptr);
1244 return PenaltyFunction::compute_constraint(constraint_at_vtx, *(_mesh_node->get_mesh()), this->_dist);
1245 }
1246
1249 VectorType& grad, const CoordType constraint, const CoordType fac) const override
1250 {
1252 grad, constraint, fac, *(_mesh_node->get_mesh()), _dist, _grad_dist, this->_edge_freqs);
1253 }
1254
1255 }; // class MeshConcentrationFunction
1256
1276 template
1277 <
1278 typename ElementalFunction_,
1279 typename Trafo_,
1280 typename RefCellTrafo_ = RumpfTrafo<Trafo_, typename Trafo_::CoordType>
1281 >
1282 class ChartDistanceFunction : public MeshConcentrationFunction<ElementalFunction_, Trafo_, RefCellTrafo_>
1283 {
1284 public:
1286 typedef ElementalFunction_ ElementalFunction;
1288 typedef Trafo_ TrafoType;
1290 typedef typename TrafoType::MeshType MeshType;
1292 typedef typename MeshType::CoordType CoordType;
1295
1302
1304 typedef typename MeshType::ShapeType ShapeType;
1309
1310 protected:
1312 std::deque<String> _chart_list;
1315
1316 public:
1319
1333 ChartDistanceFunction(const ElementalFunction& func_, const std::deque<String>& chart_list_, const String& operation_):
1334 DirectBaseClass(func_),
1335 _chart_list(),
1336 _operation(operation_)
1337 {
1338 XASSERTM(chart_list_.size() > size_t(0), "Empty chart list.");
1339
1340 for(const auto& it:chart_list_)
1341 _chart_list.push_back(it);
1342 }
1343
1344 //explicit ChartDistanceFunction(const ChartDistanceFunction& other) :
1345 // BaseClass(other.BaseClass),
1346 // _chart_list(other._chart_list)
1347 // {
1348 // }
1349
1352 {
1353 }
1354
1356 virtual std::shared_ptr<BaseClass> create_empty_clone() const override
1357 {
1358 std::shared_ptr<BaseClass> result(nullptr);
1359 result = std::make_shared<ChartDistanceFunction>(this->_func, _chart_list, _operation);
1360 return result;
1361 }
1362
1364 virtual void compute_dist() override
1365 {
1366 if(_operation == "add")
1368 else if(_operation == "max")
1370 else if(_operation == "min")
1372 else
1373 XABORTM("Unknown operation "+_operation);
1374 }
1375
1378 {
1379 XASSERT(this->_mesh_node != nullptr);
1380
1381 const auto& vtx = this->_mesh_node->get_mesh()->get_vertex_set();
1382
1383 WorldPoint my_dist_vec(CoordType(0));
1384 WorldPoint tmp(CoordType(0));
1385
1386 for(Index i(0); i < this->_mesh_node->get_mesh()->get_num_entities(0); ++i)
1387 {
1388 CoordType my_dist(0);
1389 my_dist_vec.format(CoordType(0));
1390
1391 for(const auto& it:_chart_list)
1392 {
1393 auto* chart = this->_mesh_node->get_atlas()->find_mesh_chart(it);
1394 if(chart == nullptr)
1395 XABORTM("Could not find chart "+it);
1396
1397 my_dist += Math::abs(chart->signed_dist(vtx[i], tmp));
1398 my_dist_vec += tmp;
1399
1400 }
1401 this->_dist(i, my_dist);
1402
1403 // Because we added distance function gradient vectors, we have to normalize again if possible
1404 CoordType my_norm(my_dist_vec.norm_euclid());
1405 if(my_norm > Math::eps<CoordType>())
1406 my_dist_vec *= (CoordType(1)/my_norm);
1407
1408 this->_grad_dist(i, my_dist_vec);
1409 }
1410 }
1411
1414 {
1415 XASSERT(this->_mesh_node != nullptr);
1416
1417 const auto& vtx = this->_mesh_node->get_mesh()->get_vertex_set();
1418
1419 WorldPoint my_dist_vec(CoordType(0));
1420 WorldPoint tmp(CoordType(0));
1421
1422 for(Index i(0); i < this->_mesh_node->get_mesh()->get_num_entities(0); ++i)
1423 {
1424 CoordType my_dist(-Math::huge<CoordType>());
1425 my_dist_vec.format(CoordType(0));
1426
1427 for(const auto& it:_chart_list)
1428 {
1429 auto* chart = this->_mesh_node->get_atlas()->find_mesh_chart(it);
1430 if(chart == nullptr)
1431 XABORTM("Could not find chart "+it);
1432
1433 CoordType this_dist = chart->signed_dist(vtx[i], tmp);
1434 if(this_dist > my_dist)
1435 {
1436 my_dist = this_dist;
1437 my_dist_vec = tmp;
1438 }
1439
1440 }
1441
1442 this->_dist(i, my_dist);
1443 this->_grad_dist(i, my_dist_vec);
1444 }
1445 }
1448 {
1449 XASSERT(this->_mesh_node != nullptr);
1450
1451 const auto& vtx = this->_mesh_node->get_mesh()->get_vertex_set();
1452
1453 WorldPoint my_dist_vec(CoordType(0));
1454 WorldPoint tmp(CoordType(0));
1455
1456 for(Index i(0); i < this->_mesh_node->get_mesh()->get_num_entities(0); ++i)
1457 {
1458 CoordType my_dist(Math::huge<CoordType>());
1459 my_dist_vec.format(CoordType(0));
1460
1461 for(const auto& it:_chart_list)
1462 {
1463 auto* chart = this->_mesh_node->get_atlas()->find_mesh_chart(it);
1464 if(chart == nullptr)
1465 XABORTM("Could not find chart "+it);
1466
1467 CoordType this_dist = chart->signed_dist(vtx[i], tmp);
1468 if(Math::abs(this_dist) < Math::abs(my_dist))
1469 {
1470 my_dist = this_dist;
1471 my_dist_vec = tmp;
1472 }
1473
1474 }
1475
1476 this->_dist(i, my_dist);
1477 this->_grad_dist(i, my_dist_vec);
1478 }
1479 }
1480
1486 static String name()
1487 {
1488 return "ChartDistanceFunction<"+ElementalFunction::name()+">";
1489 }
1490
1492 virtual String info() const override
1493 {
1494 const Index width(30);
1495
1496 String msg = name() + ":\n";
1497
1498 msg += DirectBaseClass::info() + "\n";
1499 msg += String("Operation").pad_back(width, '.') + String(": ") + _operation;
1500
1501 for(const auto& it:_chart_list)
1502 {
1503 msg += String("\nDistance chart").pad_back(width, '.') + String(": ") + it;
1504 }
1505
1506 return msg;
1507 }
1508
1509 }; // class ChartDistanceFunction
1510
1521 template<typename Trafo_, typename RefCellTrafo_>
1523 {
1525 typedef typename Trafo_::MeshType MeshType;
1527 typedef typename MeshType::CoordType CoordType;
1528
1540 static std::shared_ptr<MeshConcentrationFunctionBase<Trafo_, RefCellTrafo_>>
1541 create(const String& section_key, PropertyMap* config)
1542 {
1543 XASSERT(config != nullptr);
1544
1545 std::shared_ptr<MeshConcentrationFunctionBase<Trafo_, RefCellTrafo_>> result(nullptr);
1546
1547 // Get the configuration section
1548 auto my_section = config->query_section(section_key);
1549 XASSERTM(my_section != nullptr, "Config is missing the referenced "+section_key+" section.");
1550
1551 auto type_p = my_section->query("type");
1552 XASSERTM(type_p.second, "Section "+section_key+" is missing the mandatory type key.");
1553
1554 if(type_p.first== "ChartDistance")
1555 {
1556 auto chart_list_p = my_section->query("chart_list");
1557 XASSERTM(chart_list_p.second, "Section "+section_key+" is missing the mandatory chart_list key.");
1558
1559 String operation("min");
1560 auto operation_p = my_section->query("operation");
1561 if(operation_p.second)
1562 operation = operation_p.first;
1563
1564 std::deque<String> chart_list = chart_list_p.first.split_by_whitespaces();
1565
1566 auto function_type_p = my_section->query("function_type");
1567 if(function_type_p.second)
1568 {
1569 // At the moment, there are only default and PowOfDist
1570 if(function_type_p.first == "PowOfDist")
1571 {
1572 CoordType minval(0);
1573 CoordType exponent(1);
1574 bool use_derivative(true);
1575
1576 auto minval_p = my_section->query("minval");
1577 if(minval_p.second)
1578 minval = std::stod(minval_p.first);
1579
1580 auto exponent_p = my_section->query("exponent");
1581 if(exponent_p.second)
1582 exponent = std::stod(exponent_p.first);
1583
1584 auto use_derivative_p = my_section->query("use_derivative");
1585 if(use_derivative_p.second)
1586 use_derivative = (std::stoi(use_derivative_p.first) == 1);
1587
1588 typedef ConcentrationFunctionPowOfDist<CoordType> ElementalFunction;
1589 ElementalFunction my_func(minval, exponent, use_derivative);
1590
1591 auto real_result = std::make_shared<ChartDistanceFunction<ElementalFunction, Trafo_, RefCellTrafo_>>
1592 (my_func, chart_list, operation);
1593
1594 result = real_result;
1595 }
1596 // Default case
1597 else
1598 {
1599 typedef ConcentrationFunctionDefault<CoordType> ElementalFunction;
1600 ElementalFunction my_func;
1601
1602 auto real_result = std::make_shared<ChartDistanceFunction<ElementalFunction, Trafo_, RefCellTrafo_>>
1603 (my_func, chart_list, operation);
1604
1605 result = real_result;
1606 }
1607 }
1608
1609 }
1610
1611 XASSERTM(result != nullptr, "Unknown conc_function type!");
1612
1613 return result;
1614 }
1615 };
1616
1624 template<typename DT_>
1626 {
1627 public:
1629 typedef DT_ DataType;
1630
1632 const bool use_derivative;
1633
1640 use_derivative(false)
1641 {
1642 }
1643
1653 {
1654 }
1655
1660 {
1661 }
1662
1668 static String name()
1669 {
1670 return "ConcentrationFunctionDefault";
1671 }
1672
1676 virtual String info() const
1677 {
1678 const Index pad_width(30);
1679
1680 String msg = name() + String(":\n");
1681
1682 msg += String("Function").pad_back(pad_width, '.') + String(": c(d) = |d|\n");
1683 msg += String("use_derivative").pad_back(pad_width, '.') + String(": ") += stringify(use_derivative);
1684
1685 return msg;
1686 }
1687
1696 DataType conc_val(DT_ dist) const
1697 {
1698 return Math::abs(dist);
1699 }
1700
1709 DataType conc_der(DT_ DOXY(dist)) const
1710 {
1711 return DataType(0);
1712 }
1713 };
1714
1725 template<typename DT_>
1727 {
1728 public:
1730 typedef DT_ DataType;
1732 const bool use_derivative;
1733
1734 private:
1739
1740 public:
1754 explicit ConcentrationFunctionPowOfDist(DataType minval_, DataType exponent_, bool use_derivative_ = true):
1755 use_derivative(use_derivative_),
1756 _minval(minval_),
1757 _exponent(exponent_)
1758 {
1759 }
1760
1761 //ConcentrationFunctionPowOfDist(const ConcentrationFunctionPowOfDist& other) :
1762 // use_derivative(other.use_derivative),
1763 // _minval(other._minval),
1764 // _exponent(other._exponent)
1765 // {
1766 // }
1767
1770
1776 {
1777 }
1778
1784 static String name()
1785 {
1786 return "ConcentrationFunctionPowOfDist";
1787 }
1788
1792 virtual String info() const
1793 {
1794 const Index pad_width(30);
1795
1796 String msg = name() + String(":\n");
1797
1798 msg += String("Function").pad_back(pad_width, '.') + String(": c(d) = (alpha + |d|^beta)\n");
1799 msg += String("alpha").pad_back(pad_width, '.') + String(": ") + stringify_fp_sci(_minval) + "\n";
1800 msg += String("beta").pad_back(pad_width, '.') + String(": ") + stringify_fp_sci(_exponent) + "\n";
1801 msg += String("use_derivative").pad_back(pad_width, '.') + String(": ") + stringify(use_derivative);
1802
1803 return msg;
1804 }
1805
1815 {
1816 return Math::pow(_minval + Math::abs(dist), _exponent);
1817 }
1818
1828 {
1830 }
1831 };
1832 } // namespace Meshopt
1833} // namespace FEAST
#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.
MeshChartType * find_mesh_chart(const String &name)
Searches for a mesh chart.
Definition: mesh_atlas.hpp:162
MeshPartType * find_mesh_part(const String &part_name)
Searches this container for a MeshPart.
Definition: mesh_node.hpp:398
std::deque< String > get_mesh_part_names(bool no_internals=false) const
Returns the names of all mesh parts of this node.
Definition: mesh_node.hpp:251
MeshType * get_mesh()
Returns the mesh of this node.
Definition: mesh_node.hpp:225
Root mesh node class template.
Definition: mesh_node.hpp:748
const MeshAtlasType * get_atlas() const
Definition: mesh_node.hpp:820
void format(DT_ value=DT_(0))
Reset all elements of the container to a given value or zero if missing.
Definition: container.hpp:851
Blocked Dense data vector class template.
Dense data vector class template.
void component_invert(const DenseVector &x, const DT_ alpha=DT_(1))
Performs .
Class to compute a desired concentration for the mesh cell distribution base on distance to Charts.
MeshConcentrationFunctionBase< Trafo_, RefCellTrafo_ > BaseClass
Our base class.
Tiny::Vector< CoordType, MeshType::world_dim > WorldPoint
Type for one mesh vertex.
MeshType::ShapeType ShapeType
ShapeType of said mesh.
ElementalFunction_ ElementalFunction
Type for the function mapping distance to concentration.
virtual String info() const override
Prints relevant information.
LAFEM::DenseVector< CoordType, IndexType > ScalarVectorType
Vector type for element sizes etc.
void compute_dist_max()
Computes the distance information.
ChartDistanceFunction(const ElementalFunction &func_, const std::deque< String > &chart_list_, const String &operation_)
Constructor setting the ElementalFunction_ and the list of charts.
MeshConcentrationFunction< ElementalFunction_, Trafo_, RefCellTrafo_ > DirectBaseClass
Our direct base class.
static String name()
Returns the class name as String.
Trafo_ TrafoType
Type for the transformation.
ChartDistanceFunction()=delete
Explicitly delete the empty default constructor.
void compute_dist_add()
Computes the distance information.
MeshType::CoordType CoordType
The precision of the mesh coordinates.
virtual std::shared_ptr< BaseClass > create_empty_clone() const override
Creates an empty clone of itself.
void compute_dist_min()
Computes the distance information.
TrafoType::MeshType MeshType
The mesh the transformation is defined on.
std::deque< String > _chart_list
List of charts to compute the distance to.
LAFEM::DenseVectorBlocked< CoordType, IndexType, MeshType::world_dim > VectorType
Vector type for element scales etc.
virtual void compute_dist() override
Computes the distance information.
const String _operation
How to mangle more than one distance (add, max, min)
Default elemental distance concentration function.
ConcentrationFunctionDefault(const ConcentrationFunctionDefault &other)
Copy constructor.
static String name()
Returns a descriptive String.
virtual String info() const
Prints relevant information.
DataType conc_val(DT_ dist) const
Computes the concentration according to a distance.
const bool use_derivative
Does this utilize the derivative of the input wrt. some other DoF?
DataType conc_der(DT_ dist) const
Computes the derivative of the concentration according to a distance.
Default elemental distance concentration function.
const bool use_derivative
Does this utilize the derivative of the input wrt. some other DoF?
static String name()
Returns a descriptive String.
DataType conc_der(DataType dist) const
Computes the concentration according to a distance.
virtual String info() const
Prints relevant information.
ConcentrationFunctionPowOfDist(DataType minval_, DataType exponent_, bool use_derivative_=true)
Constructor setting alpha, beta and use_derivative.
DataType conc_val(DataType dist) const
Computes the concentration according to a distance.
Base class for mesh concentration functions.
virtual bool use_derivative() const =0
Returns whether this function make use of the derivative of h wrt. the vertex coordinates.
virtual void add_sync_vecs(std::set< VectorType * > &sync_vecs)=0
Adds pointers to vectors that need synchronising (type-0 to type-1 vectors)
virtual std::shared_ptr< MeshConcentrationFunctionBase > create_empty_clone() const =0
Creates an empty clone of itself.
virtual void compute_conc()=0
Computes the concentration for each cell according to the distance information.
virtual const VectorType & get_grad_dist() const =0
Returns a const reference to the gradient of the distance function.
MeshType::CoordType CoordType
The precision of the mesh coordinates.
virtual void add_constraint_grad(VectorType &grad, const CoordType constraint, const CoordType fac) const =0
Adds the scaled gradient of the constraint wrt. the vertex coordinates.
LAFEM::DenseVectorBlocked< CoordType, IndexType, MeshType::world_dim > VectorType
Vector type for element scales etc.
virtual GradHType & get_grad_h()=0
Returns a reference to gradient of the optimal scales wrt. the vertex coordinates.
LAFEM::DenseVector< CoordType, IndexType > ScalarVectorType
Vector type for element sizes etc.
virtual CoordType & get_sum_conc()=0
Returns the sum of the mesh concentration over all cells.
Tiny::Vector< CoordType, MeshType::world_dim > WorldPoint
Type of a mesh vertex.
LAFEM::DenseVectorBlocked< CoordType, IndexType, MeshType::world_dim *Shape::FaceTraits< ShapeType, 0 >::count > GradHType
Vector type for the gradient of h wrt. the DoF.
virtual void compute_grad_h(const CoordType &sum_det)=0
Computes the local gradient of the optimal scales.
virtual const GradHType & get_grad_h() const =0
Returns a const reference to gradient of the optimal scales wrt. the vertex coordinates.
virtual const ScalarVectorType & get_conc() const =0
Returns a const reference to the concentration.
virtual void compute_grad_sum_det(const VectorType &coords)=0
Computes the gradient of the sum of all determinants of the trafo.
virtual void compute_grad_conc()=0
Computes the gradient of the mesh concentration for each cell according to the distance information.
virtual CoordType compute_constraint() const =0
Computes the surface alignment constraint.
virtual void compute_dist()=0
Computes the distance information.
virtual String info() const =0
Prints relevant information.
MeshType::ShapeType ShapeType
ShapeType of said mesh.
TrafoType::MeshType MeshType
The mesh the transformation is defined on.
virtual CoordType compute_constraint(CoordType *constraint_at_vtx) const =0
Computes the surface alignment constraint at every vertex.
virtual const ScalarVectorType & get_dist() const =0
Returns a const reference to the distance information.
virtual void set_mesh_node(const Geometry::RootMeshNode< MeshType > *mesh_node_)=0
Sets this object's mesh node.
Class to compute a desired concentration for the mesh cell distribution.
ElementalFunction _func
The scalar function mapping distance to concentration.
VectorType _grad_dist
For all vertices, this holds the gradient of the distance function.
MeshType::CoordType CoordType
The precision of the mesh coordinates.
MeshConcentrationFunction(const ElementalFunction &func_)
Constructor setting the elemantal function.
virtual void add_sync_vecs(std::set< VectorType * > &sync_vecs) override
Adds pointers to vectors that need synchronising (type-0 to type-1 vectors)
virtual const ScalarVectorType & get_conc() const override
Returns a const reference to the concentration.
VectorType _grad_sum_det
Gradient of _sum_det wrt. the mesh vertices.
virtual const ScalarVectorType & get_dist() const override
Returns a const reference to the distance information.
virtual void compute_grad_conc() override
Computes the gradient of the sum of all mesh concentrations.
MeshType::ShapeType ShapeType
ShapeType of said mesh.
virtual void compute_grad_h(const CoordType &sum_det) override
Computes the local gradient of the optimal scales.
ElementalFunction_ ElementalFunction
The scalar function that computes the concentration from something.
LAFEM::DenseVectorBlocked< CoordType, Index, MeshType::world_dim *Shape::FaceTraits< ShapeType, 0 >::count > GradHType
Vector type for the gradient of h wrt. the DoF.
virtual void add_constraint_grad(VectorType &grad, const CoordType constraint, const CoordType fac) const override
Adds the scaled gradient of the constraint wrt. the vertex coordinates.
ScalarVectorType _conc
Vector for saving the mesh concentration, one entry per cell.
const Geometry::RootMeshNode< MeshType > * _mesh_node
The mesh node this function works with.
LAFEM::DenseVector< CoordType, IndexType > ScalarVectorType
Vector type for element sizes etc.
virtual void compute_conc() override
Computes the mesh concentration function for each cell.
TrafoType::MeshType MeshType
The mesh the transformation is defined on.
VectorType _grad_conc
Gradient of the mesh concentration wrt. the world coordinates.
virtual void set_mesh_node(const Geometry::RootMeshNode< MeshType > *mesh_node_) override
Sets this object's mesh node.
virtual bool use_derivative() const override
Returns whether this function make use of the derivative of h wrt. the vertex coordinates.
GradHType _grad_h
Gradient of the local optimal scales h wrt. the vertex coordinates.
virtual const GradHType & get_grad_h() const override
Returns a reference to gradient of the optimal scales wrt. the vertex coordinates.
ScalarVectorType _dist
For all vertices, this holds their scalar "distance" to whatever.
void compute_grad_conc_local(Tgrad_ &grad_loc_, const Tl_ &dist_loc_, const Tgradl_ &grad_dist_loc_)
Computes the local gradient of the concentration function wrt. the vertices.
virtual CoordType & get_sum_conc() override
Returns the sum of the mesh concentration over all cells.
MeshConcentrationFunctionBase< Trafo_, RefCellTrafo_ > BaseClass
Our base class.
Tiny::Vector< CoordType, MeshType::world_dim > WorldPoint
Type for one mesh vertex.
LAFEM::DenseVectorBlocked< CoordType, IndexType, MeshType::world_dim > VectorType
Vector type for element scales etc.
virtual CoordType compute_constraint(CoordType *constraint_at_vtx) const override
Computes the surface alignment constraint at every vertex.
virtual const VectorType & get_grad_dist() const override
Returns a const reference to the gradient of the distance function.
AlignmentPenalty< CoordType, ShapeType > PenaltyFunction
Surface alignment penalty function.
virtual CoordType compute_constraint() const override
Computes the surface alignment constraint.
virtual GradHType & get_grad_h() override
Returns a reference to gradient of the optimal scales wrt. the vertex coordinates.
virtual String info() const override
copydoc BaseClass::info()
virtual void compute_grad_sum_det(const VectorType &coords) override
Computes the gradient of the sum of all determinants of the trafo.
CoordType _sum_conc
The sum of all entries in _conc.
ScalarVectorType _edge_freqs
For each edge, this contains 1/(# halos it is present in)
A class organizing a tree of key-value pairs.
PropertyMap * query_section(String sec_path)
Queries a section by its section path.
String class implementation.
Definition: string.hpp:46
std::deque< String > split_by_whitespaces() const
Splits the string by white-spaces.
Definition: string.hpp:518
String pad_back(size_type len, char c=' ') const
Pads the back of the string up to a desired length.
Definition: string.hpp:415
Tiny Matrix class template.
CUDA_HOST_DEVICE void format(DataType alpha=DataType(0))
Formats the matrix.
Tiny Vector class template.
CUDA_HOST_DEVICE void format(DataType alpha=DataType(0))
Formats the vector.
CUDA_HOST_DEVICE DataType norm_euclid() const
Computes the euclid norm of this vector.
T_ abs(T_ x)
Returns the absolute value.
Definition: math.hpp:275
T_ pow(T_ x, T_ y)
Returns x raised to the power of y.
Definition: math.hpp:643
T_ sqr(T_ x)
Returns the square of a value.
Definition: math.hpp:95
T_ signum(T_ x)
Returns the sign of a value.
Definition: math.hpp:250
FEAT namespace.
Definition: adjactor.hpp:12
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:944
String stringify_fp_sci(DataType_ value, int precision=0, int width=0, bool sign=false)
Prints a floating point value to a string in scientific notation.
Definition: string.hpp:1088
@ grad
specifies whether the space should supply basis function gradients
std::uint64_t Index
Index data type.
Wrapper class for functionality around aligning meshes to (implicit) surfaces.
static void add_constraint_grad(Vector_ &grad, const DataType alignment_fval, const DataType fac, const Mesh_ &mesh, const Dist_ &dist, const GradDist_ &grad_dist, const EdgeFreqs_ &edge_freqs)
Adds the gradient of the constraint violation term.
static DataType compute_constraint(const Mesh_ &mesh, const Dist_ &dist, const EdgeFreqs_ &edge_freqs)
Computes the constraint (violation) for a given mesh.
Shape::Simplex< shape_dim > ShapeType
The mesh's shape type.
static DataType compute_constraint(DataType *constraint_vec, const Mesh_ &mesh, const Dist_ &dist)
Computes the constraint (violation) on every cell of a given mesh.
MeshType::CoordType CoordType
Floating point precision of the mesh vertex coordinates.
static std::shared_ptr< MeshConcentrationFunctionBase< Trafo_, RefCellTrafo_ > > create(const String &section_key, PropertyMap *config)
Creates a MeshConcentrationFunction according to a PropertyMap.
Computes quantities associated with the transformation to Rumpf reference cells.
Definition: rumpf_trafo.hpp:44
Face traits tag struct template.
Definition: shape.hpp:106
Simplex shape tag struct template.
Definition: shape.hpp:44
static constexpr int dimension
Simplex dimension.
Definition: shape.hpp:48