ug4
support3D.h
Go to the documentation of this file.
1 /*
2  * support3D.h
3  *
4  * Created on: 31.10.2024
5  * Author: Markus Knodel
6  */
7 
8 #ifndef UGCORE_UGBASE_LIB_GRID_ALGORITHMS_EXTRUSION_SUPPORT3D_H_
9 #define UGCORE_UGBASE_LIB_GRID_ALGORITHMS_EXTRUSION_SUPPORT3D_H_
10 
11 #include <iostream>
12 #include <stdexcept>
13 #include <cmath>
14 #include <iostream>
15 #include <stdlib.h>
16 #include <vector>
17 #include <assert.h>
18 #include <string>
19 #include <sstream>
20 #include <utility>
21 #include <vector>
22 #include <type_traits>
23 
24 #include "support.h"
25 
26 // TODO FIXME
27 // verschlanken,
28 // Verdoppelungen weg,
29 // Namen generalisieren
30 // nicht vertex spezifisch zB
31 // sondern lowest dim oder so
32 
33 namespace ug
34 {
35 
36 namespace support
37 {
38 
39 #if 0
40 
41 template<typename ELEMTYP, typename INDEX_TYP>
42 class ElemInfo
43 {
44 public:
45 
46  ElemInfo( ELEMTYP const & elem, INDEX_TYP sudo )
47  : m_elem(elem), m_sudo(sudo)
48  {
49  }
50 
51 
52 
53 private:
54 
55  ELEMTYP m_elem;
56  INDEX_TYP m_sudo;
57 
58  ElemInfo() {};
59 
60 
61 };
62 
63 template<
64 typename FACETYP,
65 typename NORMALTYP,
66 typename VOLUMETYP,
67 typename EDGETYP,
68 typename INDEX_TYP
69 >
70 class VertexFractureQuadrupel
71 {
72 public:
73 
74  using ElemInfoFac = ElemInfo<FACETYP,INDEX_TYP>;
75 
76  //face, normal, volume, edge
77 
78 // VertexFractureQuadrupel()
79 // {};
80 
81 
82  VertexFractureQuadrupel( ElemInfoFac const & fracFaceInfo,
83  VOLUMETYP const & attVolume,
84  NORMALTYP const & normal,
85  std::pair<EDGETYP,EDGETYP> const & volCutEdges,
86  std::pair<ElemInfoFac,ElemInfoFac> const & volCutEdgeFaces )
87  : m_fracFaceInfo(fracFaceInfo),
88  m_attVolume(attVolume),
89  m_normal(normal),
90  m_volCutEdges(volCutEdges),
91  m_volCutEdgeFaces(volCutEdgeFaces)
92  {
93  }
94 
95  // todo fixme getter und ggf auch setter, aber vermutlich nur getter implementieren!!!
96 
97 private:
98 
99 // FACETYP const getFace() const { return m_full; }
100 // NORMALTYP const getNormal() const { return m_normal; }
101 // VOLUMETYP const getVolume() const { return m_volume; }
102 // EDGETYP const getEdge() const { return m_edge; }
103 
104  ElemInfo<FACETYP,INDEX_TYP> m_fracFaceInfo;
105  VOLUMETYP m_attVolume;
106  NORMALTYP m_normal;
107  std::pair<EDGETYP,EDGETYP> m_volCutEdges;
108  std::pair<ElemInfoFac,ElemInfoFac> m_volCutEdgeFaces;
109 
110 //private:
111 //
112 // FACETYP m_face;
113 // NORMALTYP m_normal;
114 // VOLUMETYP m_volume;
115 // EDGETYP m_edge;
116 
117  VertexFractureQuadrupel()
118  {};
119 };
120 #endif
121 
122 
123 template <
124 typename MANIFELM,
125 typename LOWDIMELM,
126 typename INDEX_TXP
127 >
129 {
130 public:
131  using PairLowEl = std::pair<LOWDIMELM,LOWDIMELM>;
132 
134 
135  // for fracture elements
136  AttachedGeneralElem( MANIFELM const & manifElm,
137  PairLowEl const & lowElm
138  )
139  :
140  m_manifElm(manifElm), m_pairLowElm(lowElm)
141  {
142  };
143 
144  MANIFELM const getManifElm() const { return m_manifElm;}
145 // PairLowEl const getLowElm() const { return m_lowElm; }
146  PairLowEl const getPairLowElm() const { return m_pairLowElm; }
147 
148  bool const isNeighboured( AttGenElm const & attElm )
149  const
150  {
151 // MANIFELM manifElmOther = attElm.getManifElm();
152  PairLowEl lowElmOther = attElm.getPairLowElm();
153 // INDEX_TXP sudoOther = attElm.getSudo();
154 
155  PairLowEl lowElmThis = this->m_pairLowElm;
156 
157  std::vector<bool> test;
158 
159  test.push_back( lowElmOther.first == lowElmThis.first );
160  test.push_back( lowElmOther.second == lowElmThis.first );
161  test.push_back( lowElmOther.first == lowElmThis.second );
162  test.push_back( lowElmOther.second == lowElmThis.second );
163 
164  INDEX_TXP countCorr = 0;
165 
166  for( auto const t : test )
167  {
168  if( t )
169  countCorr++;
170  }
171 
172  if( countCorr == 1 )
173  return true;
174 
175  if( countCorr > 1 )
176  UG_THROW("zu viele gleiche Ecken " << std::endl);
177 
178  return false;
179  }
180 
181  bool const isNeighbouredAtSpecificSide( AttGenElm const & attElm,
182  LOWDIMELM const & specificLDE )
183  const
184  {
185  PairLowEl lowElmOther = attElm.getPairLowElm();
186 
187  PairLowEl lowElmThis = this->m_pairLowElm;
188 
189  // test if the specific element is part of at least
190  // one of the faces
191 
192  bool otherFirst = ( lowElmOther.first == specificLDE );
193  bool otherSecond = ( lowElmOther.second == specificLDE );
194 
195  bool thisFirst = ( lowElmThis.first == specificLDE );
196  bool thisSecond = ( lowElmThis.second == specificLDE );
197 
198  bool isPartOfThisFace = ( thisFirst || thisSecond );
199  bool isPartOfOtherFace = ( otherFirst || otherSecond );
200 
201  if( ! isPartOfOtherFace || ! isPartOfThisFace )
202  {
203  UG_LOG("not part of one of the faces " << std::endl);
204  return false;
205  }
206 
207  if( otherFirst && thisFirst )
208  {
209  if( lowElmOther.first == lowElmThis.first )
210  return true;
211  }
212  else if( otherFirst && thisSecond )
213  {
214  if( lowElmOther.first == lowElmThis.second )
215  return true;
216  }
217  else if( otherSecond && thisFirst )
218  {
219  if( lowElmOther.second == lowElmThis.first )
220  return true;
221  }
222  else if( otherSecond && thisSecond )
223  {
224  if( lowElmOther.second == lowElmThis.second )
225  return true;
226  }
227 
228  return false;
229  }
230 
231  bool const testIfEquals( AttGenElm const & attElm )
232  const
233  {
234  MANIFELM manifElmOther = attElm.getManifElm();
235  PairLowEl lowElmOther = attElm.getPairLowElm();
236 
237  if( manifElmOther == this->m_manifElm
238  && lowElmOther == this->m_pairLowElm
239  )
240  {
241  return true;
242  }
243 
244  return false;
245  }
246 
247 
248 protected:
249 
250  MANIFELM m_manifElm;
252 
253 };
254 
255 
256 
258 
259 
260 // TODO FIXME vertex fracture triplett
261 // vereinigen mit AttachedGeneralElem !!! davon ableiten!!!
262 // doppelte Strukturen!!!
263 
264 
265 template <
266 typename MANIFOLDTYP, // 3D: Face
267 typename INDEXTYP, // int oder unsinged int oder short oder unsigned short etc
268 typename FULLDIMTYP, // 3D: Volume
269 typename SENKRECHTENTYP, // 3D und 2D: ug::vector3
270 typename LOWDIMTYP // 3D: Edge (2D nicht benötigt)
271 >
273 : public AttachedGeneralElem<MANIFOLDTYP,LOWDIMTYP,INDEXTYP>
274 {
275 
276 private:
278 
279 public:
280 
281  using PairLowEl = std::pair<LOWDIMTYP,LOWDIMTYP>;
282 
283  VertexFractureTripleMF( MANIFOLDTYP const & manifElm, INDEXTYP sudo,
284  FULLDIMTYP const & fullElm,
285  SENKRECHTENTYP const & normal,
286  PairLowEl const & pairLowElm )
287  : //m_manifElm(manifElm),
288  AttGenEl(manifElm,pairLowElm),
289  m_sudo(sudo), m_fullElm(fullElm),
290  m_normal(normal), m_newNormal(normal)
291 // ,
292 // m_pairLowElm(pairLowElm)
293  {
294  };
295 
296 // MANIFOLDTYP const getManifElm() const { return m_manifElm; }
297 
298  INDEXTYP const getSudoElm() const { return m_sudo; }
299 
300  FULLDIMTYP const getFullElm() const { return m_fullElm; }
301 
302  SENKRECHTENTYP const getNormal() const { return m_normal; }
303 
304  void setNewNormal( SENKRECHTENTYP const & chNorml ) { m_newNormal = chNorml; }
305 
306  SENKRECHTENTYP const getNewNormal() const { return m_newNormal; }
307 
308 // PairLowEl const getPairLowElm() const { return m_pairLowElm; }
309 
310 private:
311 
312 // MANIFOLDTYP m_manifElm;
313  INDEXTYP m_sudo;
314  FULLDIMTYP m_fullElm;
315  SENKRECHTENTYP m_normal;
316  SENKRECHTENTYP m_newNormal;
317 // PairLowEl m_pairLowElm;
318 
320  {};
321 
322 };
323 
324 
326 
327 // TODO FIXME das muss angepasst werden, ist noch wie für 2D Fall bisher
328 enum FracTypVol { SingleFrac = 2, TEnd = 3, XCross = 4 };
329 
330 template < typename VRT, typename IndTyp >
332 {
333 
334 public:
335 
336  CrossingVertexInfoVol( VRT const & crossVrt, FracTypVol fracTyp )
337  : m_crossVrt(crossVrt), m_fracTyp( fracTyp ),
338  m_vecShiftedVrts(std::vector<VRT>())
339  , m_vecShiftedVrtsWithTypInf(std::vector<std::pair<VRT,bool>>())
340  , m_numberAtFreeSide(0)
341  {
342  }
343 
344  VRT getCrossVertex() const { return m_crossVrt; }
345 
346  FracTypVol getFracTyp() const { return m_fracTyp; }
347 
348  void addShiftVrtx( VRT const & vrt, bool isAtFreeSide = false )
349  {
350  m_vecShiftedVrts.push_back(vrt);
351 
352 // if( m_fracTyp == TEnd )
353 // {
354 // std::pair<VRT, bool > addSVI( vrt, isAtFreeSide );
355 // m_vecShiftedVrtsWithTypInf.push_back(addSVI);
356 //
357 // if( isAtFreeSide )
358 // m_numberAtFreeSide++;
359 //
360 // if( m_numberAtFreeSide > 1 )
361 // UG_THROW("was ist das fuer ein T Ende" << std::endl);
362 // }
363 
364  }
365 
366  void setShiftVrtx( std::vector<VRT> const & vecVrt ) { m_vecShiftedVrts = vecVrt; }
367 
368  std::vector<VRT> getVecShiftedVrts() const
369  {
370  return m_vecShiftedVrts;
371  }
372 
373  std::vector<std::pair<VRT,bool>> getVecShiftedVrtsWithTypInfo() const
374  {
375 // if( m_fracTyp != TEnd )
376 // UG_THROW("fuer Kreuz nicht erlaubt " << std::endl);
377 
379  }
380 
381 
382 private:
383 
385  std::vector<VRT> m_vecShiftedVrts;
386  std::vector<std::pair<VRT,bool>> m_vecShiftedVrtsWithTypInf;
389 };
390 
392 
393 
394 
395 // info for a vertex: face and attached edges, for fractures only
396 // derived from the similar class without fracture property!
397 template <
398 typename MANIFELM,
399 typename LOWDIMELM,
400 typename INDEX_TXP
401 >
403 : public AttachedGeneralElem<MANIFELM,LOWDIMELM,INDEX_TXP>
404 // TODO FIXME derive from AttachedGeneralElem
405 {
406 public:
407  using PairLowEl = std::pair<LOWDIMELM,LOWDIMELM>;
408 
410 
412 
413  // for fracture elements
414  AttachedFractElem( MANIFELM const & manifElm,
415  PairLowEl & lowElm,
416  INDEX_TXP sudo )
417  :
418  AttGenElm(manifElm,lowElm),
419  //m_manifElm(manifElm), m_lowElm(lowElm),
420  m_sudo(sudo)
421  {
422  };
423 
424 
425 // MANIFELM const getManifElm() const { return m_manifElm;}
426 // PairLowEl const getLowElm() const { return m_lowElm; }
427  INDEX_TXP const getSudo() const { return m_sudo; };
428 
429  bool const testIfEquals( AttFractElm const & attElm )
430  const
431  {
432  bool geomEqu = AttGenElm::testIfEquals(attElm);
433 
434 // MANIFELM manifElmOther = attElm.getManifElm();
435 // PairLowEl lowElmOther = attElm.getLowElm();
436  INDEX_TXP sudoOther = attElm.getSudo();
437 
438 // if( manifElmOther == this->m_manifElm
439 // && lowElmOther == this->m_lowElm
440 // && sudoOther == this->m_sudo
441 // )
442 // {
443 // return true;
444 // }
445 
446  if( geomEqu && sudoOther == this->m_sudo )
447  {
448  return true;
449  }
450 
451  return false;
452  }
453 
454 
455 // bool const testIfEquals( AttachedFractElem<MANIFELM,LOWDIMELM,INDEX_TXP> const & attElm )
456 // const
457 // {
458 // MANIFELM manifElmOther = attElm.getManifElm();
459 // PairLowEl lowElmOther = attElm.getLowElm();
460 // INDEX_TXP sudoOther = attElm.getSudo();
461 //
462 // if( manifElmOther == this->m_manifElm
463 // && lowElmOther == this->m_lowElm
464 // && sudoOther == this->m_sudo
465 // )
466 // {
467 // return true;
468 // }
469 //
470 // return false;
471 // }
472 
473 // bool const isNeighboured( AttachedFractElem<MANIFELM,LOWDIMELM,INDEX_TXP> const & attElm )
474 // const
475 // {
477 // PairLowEl lowElmOther = attElm.getLowElm();
479 //
480 // PairLowEl lowElmThis = this->m_lowElm;
481 //
482 // std::vector<bool> test;
483 //
484 // test.push_back( lowElmOther.first == lowElmThis.first );
485 // test.push_back( lowElmOther.second == lowElmThis.first );
486 // test.push_back( lowElmOther.first == lowElmThis.second );
487 // test.push_back( lowElmOther.second == lowElmThis.second );
488 //
489 // INDEX_TXP countCorr = 0;
490 //
491 // for( auto const t : test )
492 // {
493 // if( t )
494 // countCorr++;
495 // }
496 //
497 // if( countCorr == 1 )
498 // return true;
499 //
500 // if( countCorr > 1 )
501 // UG_THROW("zu viele gleiche Ecken " << std::endl);
502 //
503 // return false;
504 // }
505 //
506 // bool const isNeighbouredAtSpecificSide( AttachedFractElem<MANIFELM,LOWDIMELM,INDEX_TXP> const & attElm,
507 // LOWDIMELM const & specificLDE )
508 // const
509 // {
510 // PairLowEl lowElmOther = attElm.getLowElm();
511 //
512 // PairLowEl lowElmThis = this->m_lowElm;
513 //
514 // // test if the specific element is part of at least
515 // // one of the faces
516 //
517 // bool otherFirst = ( lowElmOther.first == specificLDE );
518 // bool otherSecond = ( lowElmOther.second == specificLDE );
519 //
520 // bool thisFirst = ( lowElmThis.first == specificLDE );
521 // bool thisSecond = ( lowElmThis.second == specificLDE );
522 //
523 // bool isPartOfThisFace = ( thisFirst || thisSecond );
524 // bool isPartOfOtherFace = ( otherFirst || otherSecond );
525 //
526 // if( ! isPartOfOtherFace || ! isPartOfThisFace )
527 // {
528 // UG_LOG("not part of one of the faces " << std::endl);
529 // return false;
530 // }
531 //
532 // if( otherFirst && thisFirst )
533 // {
534 // if( lowElmOther.first == lowElmThis.first )
535 // return true;
536 // }
537 // else if( otherFirst && thisSecond )
538 // {
539 // if( lowElmOther.first == lowElmThis.second )
540 // return true;
541 // }
542 // else if( otherSecond && thisFirst )
543 // {
544 // if( lowElmOther.second == lowElmThis.first )
545 // return true;
546 // }
547 // else if( otherSecond && thisSecond )
548 // {
549 // if( lowElmOther.second == lowElmThis.second )
550 // return true;
551 // }
552 //
553 // return false;
554 // }
555 
556 private:
557 // MANIFELM m_manifElm;
558 // PairLowEl m_lowElm;
559  INDEX_TXP m_sudo;
560 
561 
562 };
563 
565 
566 // class to help count and store a bool and a number of templete type
567 // comparable to std::pair<bool,int> but more dedicated to the specific aim
568 // TODO FIXME adapt for 3D case, figure out if inner end, and number of fracs sourrounding
569 // CAUTION is also used for edges, but still uses
570 // vertex as indicator - name should be made more flexible
571 
572 template<
573 typename T,
574 typename ATT_ELEM
575 >
577 {
578 public:
579 
580  using pairTB = std::pair<T,bool>;
581  using VecPairTB = std::vector<pairTB>;
582 
583 
584 // VertexFracturePropertiesVol( bool isBndFracVertex, T numberCrossingFracsInVertex )
585 // : m_isBndFracVertex(isBndFracVertex), m_numberCountedFracsInVertex(numberCrossingFracsInVertex)
586 // {
587 // };
588 
593 
597  m_sudoList( std::vector<T>() ),
599  m_vecAttElem(std::vector<ATT_ELEM>())
600 // VertexFracturePropertiesVol( false, 0 )
601  {
602  };
603 
604  void setIsBndFracVertex( bool iBDV = true )
605  {
606  m_isBndFracVertex = iBDV;
607  }
608 
609  void setNumberCrossingFracsInVertex( T const & nCFIV )
610  {
612  }
613 
615  {
616  return m_isBndFracVertex;
617  }
618 
619 // T getCountedNumberFracsInVertex()
620 // {
621 // return m_numberCountedFracsInVertex;
622 // }
623 
624 
626  {
628  }
629 
630 // T getNumberCrossingFracsInVertex()
631 // {
632 // if( m_isBndFracVertex )
633 // return m_numberCountedFracsInVertex;
634 //
635 // // for inner vertices, each edge passed when
636 // // fractures are counted along their edges
637 // // that the vertizes get hit twice for each fracture run
638 // // only for boundary vertices, this happens only once per fracture
639 // T multipeInnerHits = 2;
640 //
641 // T rest = m_numberCountedFracsInVertex % multipeInnerHits;
642 //
643 // if( rest != 0 )
644 // {
646 //
647 // throw std::runtime_error("error");
648 //
649 // return 0;
650 // }
651 //
652 // return m_numberCountedFracsInVertex / multipeInnerHits;
653 // }
654 
656  {
658  return *this;
659  }
660 
661 
663  {
664  return m_status;
665  }
666 
667  // caution: returns false if sudo already known, but no problem, feature, not bug
668  // so never stop the program if false returned here, this is good news
669  bool addFractSudo( T const & sudo )
670  {
671  bool alreadyInList = false;
672 
673  for( auto const & availSudo : m_sudoList )
674  {
675  if( sudo == availSudo )
676  alreadyInList = true;
677  }
678 
679  if( ! alreadyInList )
680  {
681  m_sudoList.push_back( sudo );
682  }
683 
684  return adaptVrtxFracStatus();
685  }
686 
687  // setter private to avoid abusive use
688  std::vector<T> const getSudoList() const
689  {
690  return m_sudoList;
691  }
692 
693  bool setIsAClosedFracture( T sudoNow, bool isClosedNow )
694  {
695 
696  T alreadyKnownMult = 0;
697 
698  for( auto & suSu : m_sudosClosed )
699  {
700  T & sudoVal = suSu.first;
701  bool & isClosedVal = suSu.second;
702 
703  if( sudoVal == sudoNow )
704  {
705  alreadyKnownMult++;
706 
707  UG_LOG("Reassign sudo surround " << std::endl);
708 
709  if( isClosedVal != isClosedNow )
710  UG_THROW("change property sudo surrounded, why?" << std::endl);
711 
712  isClosedVal = isClosedNow;
713  }
714  }
715 
716  if( alreadyKnownMult == 0 )
717  {
718  pairTB infoSudoSurr( sudoNow, isClosedNow );
719 
720  m_sudosClosed.push_back( infoSudoSurr );
721 
722  }
723  else if( alreadyKnownMult > 1 )
724  {
725  UG_THROW("zu oft bekannt " << std::endl);
726  return false;
727  }
728 
729  // check if now correct
730 
731  T testKnownFine = 0;
732 
733  for( auto const & suSu : m_sudosClosed )
734  {
735  T & sudoVal = suSu.first;
736  bool & isClosedVal = suSu.second;
737 
738  if( sudoVal == sudoNow )
739  {
740  testKnownFine++;
741 
742  if( isClosedVal != isClosedNow )
743  {
744  UG_THROW("NOT set property sudo surrounded, why?" << std::endl);
745  return false;
746  }
747 
748  }
749  }
750 
751  if( testKnownFine == 0 || testKnownFine > 1 )
752  {
753  UG_THROW("immer noch nicht bekannt?" << std::endl);
754  return false;
755 
756  }
757 
758  return true;
759  }
760 
761  bool getIsAClosedFracture( T sudoNow )
762  {
763  T foundMultpl = 0;
764 
765  bool isClosedReturn = false;
766 
767  for( auto const & suSu : m_sudosClosed )
768  {
769  T const & sudoVal = suSu.first;
770  bool const & isClosedVal = suSu.second;
771 
772  if( sudoVal == sudoNow )
773  {
774  foundMultpl++;
775  isClosedReturn = isClosedVal;
776  }
777  }
778 
779  if( foundMultpl != 1 )
780  {
781  UG_THROW("not known status closed or not sudo" << std::endl);
782  return false;
783  }
784 
785  return isClosedReturn;
786  }
787 
788  bool setInfoAllFractureSudosIfClosed( VecPairTB const & sudosClosed )
789  {
790  m_sudosClosed = sudosClosed;
791 
792  return true;
793  }
794 
796  {
797  return m_sudosClosed;
798  }
799 
800  // if all open or closed
801  template<bool B>
803  {
804  bool allFracsSame = true;
805 
806  for( auto const & suSu : m_sudosClosed )
807  {
808  //T const & sudoVal = suSu.first;
809  bool const & isClosedVal = suSu.second;
810 
811  if( isClosedVal != B )
812  allFracsSame = false;
813  }
814 
815  return allFracsSame;
816  }
817 
818  bool addAttachedFractElem( ATT_ELEM const & attElem )
819  {
820  bool alreadyKnown = false;
821 
822  for( auto const & aE : m_vecAttElem )
823  {
824  if( aE.testIfEquals(attElem) )
825  alreadyKnown = true;
826  }
827 
828  if( ! alreadyKnown )
829  m_vecAttElem.push_back(attElem);
830 
831  // returns true if ads it, false if no need as known
832  return ! alreadyKnown;
833  }
834 
835  std::vector<ATT_ELEM> const & getAllAttachedFractElems()
836  const
837  {
838  return m_vecAttElem;
839  }
840 
841 private:
844 
846 
847  static VrtxFracStatus constexpr m_maxStatus = VrtxFracStatus::threeFracSuDoAtt;
848 
849  std::vector<T> m_sudoList;
850 
851  // better private, to avoid confusion
853  {
854  m_status = status;
855 
856  if( status < noFracSuDoAtt || status > threeFracSuDoAtt )
857  return false;
858 
859  return true;
860  }
861 
863  {
864  auto sudosNum = m_sudoList.size();
865  if( sudosNum > static_cast<T>( m_maxStatus ) )
866  {
867  UG_THROW("zu viele subdomains crossing in one Punkt" << std::endl);
868  return false;
869  }
870 
871  m_status = static_cast<VrtxFracStatus>(sudosNum);
872 
873  return true;
874  }
875 
877 
878  bool setSudoList( std::vector<T> const & sudoList )
879  {
880  m_sudoList = sudoList;
881 
882  return true;
883  }
884 
885  std::vector<ATT_ELEM> m_vecAttElem;
886 
887 };
888 
889 
890 // intention, explained for volume:
891 template<typename FULLDIM_ELEM,
892 typename MANIFELM,
893 typename LOWDIMELM,
894 typename INDEX_TXP
895 >
897 {
898 
899 public:
900 
903 
904  using VecAttachedFractManifElemInfo = std::vector<AttachedFractManifElemInfo>;
905  using VecAttachedGenerManifElemInfo = std::vector<AttachedGenerManifElemInfo>;
906 
908 
909  AttachedFullDimElemInfo( FULLDIM_ELEM const & fullDimElm )
910  : m_fullDimElm(fullDimElm),
911  m_elementMarked(false),
913 // m_vecFractManifElmTouchInfo(VecAttFractManifElmTouchInf()),
914 // m_allSidesTouched(false),
916 // m_vecGenerManifElmTouchInfo(VecAttFractManifElmTouchInf())
917 // m_vecInnerSegmentManifElm(VecAttachedGenerManifElemInfo())
918  {
919  }
920 
921  FULLDIM_ELEM const getFulldimElem() const
922  {
923  return m_fullDimElm;
924  }
925 
926  bool const hasSameFulldimElem( AttFullDimElmInfo const & otherFullDimElmInf )
927  const
928  {
929  FULLDIM_ELEM otherFullDimElm = otherFullDimElmInf.getFulldimElem();
930 
931  return ( otherFullDimElm == m_fullDimElm );
932  }
933 
934  bool const isMarked() const { return m_elementMarked; }
935 
936  void markIt() { m_elementMarked = true; } // to allow in loop to be start element
937 
938  bool const hasFracture() const { return ( m_vecFractManifElm.size() > 0 ); }
939 
940  bool addFractManifElem( AttachedFractManifElemInfo const & manifFractElm, Grid & grid )
941  {
942  return addManifElem( manifFractElm, m_vecFractManifElm, grid );
943  }
944 
945  bool addGenerManifElem( AttachedGenerManifElemInfo const & manifGenerElm, Grid & grid )
946  {
947 // static_assert(std::is_same<AttachedGenerManifElemInfo, decltype( manifGenerElm ) >::value);
948 
949  return addManifElem( manifGenerElm, m_vecGenerManifElm, grid );
950  }
951 
952  // necessary to avoid stupid casting from derived class AttachedFractManifElemInfo
953  // else, addGenerManifElem would also eat objects of derived class
954  // however not it only accepts explicit base class objects
955  template <typename NOGEN>
956  bool addGenerManifElem( NOGEN const & noGener, Grid & grid )
957  = delete;
958 
959 
960 // // will form new "surface" of next inner round in a segment
961 // bool addInnerSegmentManifElem( AttachedGenerManifElemInfo const & manifInnerSegmentElm, Grid & grid )
962 // {
963 // return addManifElem( manifInnerSegmentElm, m_vecInnerSegmentManifElm, grid );
964 // }
965 //
966 // template <typename NOGEN>
967 // bool addInnerSegmentElem( NOGEN const & noGener, Grid & grid )
968 // = delete;
969 
970 
971 
972 // bool addFractureManifElem( AttachedFractManifElemInfo const & manifElm, Grid & grid )
973 // {
974 // // Caution: first test if manifold elem is at all part of the fulldim elem manifols
975 // // if not, return false directly
976 //
977 // if( ! fullDimElmContainsManif( manifElm.getManifElm(), grid ) )
978 // return false;
979 //
980 // // if manif elem is in principle part of the fulldim elem manifolds,
981 // // then we need to check if it is already integrated
982 //
983 // bool hasElemAlready = false;
984 //
985 //
986 // for( auto const & me : m_vecFractManifElm )
987 // {
988 // if( manifElm.testIfEquals(me) )
989 // {
990 // hasElemAlready = true;
991 // break;
992 // }
993 // }
994 //
995 // if( ! hasElemAlready )
996 // {
997 // m_vecFractManifElm.push_back( manifElm );
998 //
1002 // }
1003 //
1004 // return ! hasElemAlready;
1005 // }
1006 
1008  {
1009  return m_vecFractManifElm;
1010  }
1011 
1013  {
1014  return m_vecGenerManifElm;
1015  }
1016 
1017  bool const searchGenerManifElem( AttachedGenerManifElemInfo const & manifGenerElemOther, bool eraseFound = true )
1018  {
1019  bool found = searchManifElem( manifGenerElemOther, m_vecGenerManifElm, eraseFound );
1020 
1021  if( found && eraseFound )
1022  {
1023  m_elementMarked = true;
1024  }
1025 
1026  return found;
1027  }
1028 
1029  bool const testFullDimElmNeighbour( AttFullDimElmInfo const & attFullDimElmInfOther, bool eraseFoundManif = true )
1030  {
1031  VecAttachedGenerManifElemInfo const & vecGenerManifElmOther = attFullDimElmInfOther.getVecGenerManifElem();
1032 
1033  bool manifNeighbored = false;
1034 
1035  for( AttachedGenerManifElemInfo const & generManifElemOther : vecGenerManifElmOther )
1036  {
1037  if( searchManifElem( generManifElemOther, m_vecGenerManifElm, eraseFoundManif ) )
1038  manifNeighbored = true;
1039 
1040  }
1041 
1042  if( manifNeighbored && eraseFoundManif )
1043  {
1044  m_elementMarked = true;
1045  }
1046 
1047  return manifNeighbored;
1048  }
1049 
1050 
1051  template <typename NOGEN>
1052  bool searchGenerManifElem( NOGEN const & manifGenerElemOther, bool eraseFound ) = delete;
1053 
1054 // bool const searchFractManifElem( AttachedFractManifElemInfo const & manifFractElemOther, bool eraseFound = true )
1055  bool const searchFractManifElem( AttachedFractManifElemInfo const & manifFractElemOther, bool shiftToGeneral = true )
1056  {
1057  bool found = searchManifElem( manifFractElemOther, m_vecFractManifElm, shiftToGeneral );
1058 
1059  if( found && shiftToGeneral )
1060  {
1061  // for the case that a fracture is not closed at a vertex, shift the in principle
1062  // fracture vertex to the gerneral vertices, as useless for segmente construction
1063  // and useless for expansion
1064 
1065  MANIFELM const & manifel = manifFractElemOther.getManifElm();
1066  typename AttachedGenerManifElemInfo::PairLowEl const & pairLowEl = manifFractElemOther.getPairLowElm();
1067 
1068  AttachedGenerManifElemInfo agmei( manifel, pairLowEl );
1069 
1070  m_vecGenerManifElm.push_back(agmei);
1071  }
1072 
1073  return found;
1074 
1075  }
1076 
1077 // bool const searchInnerSegmentManifElem( AttachedGenerManifElemInfo const & manifInnerSegmElemOther, bool eraseFound = true )
1078 // {
1079 // return searchManifElem( manifInnerSegmElemOther, m_vecInnerSegmentManifElm, eraseFound );
1080 // }
1081 
1082 // bool const tryToTouchManifElem( AttachedFractManifElemInfo const & manifElemOther ) const
1083 // {
1085 //
1086 // for( typename VecAttachedFractManifElemInfo::iterator afeiIter = m_vecFractManifElm.begin();
1087 // afeiIter != m_vecFractManifElm.end();
1088 // afeiIter++
1089 // )
1090 // {
1091 // AttachedFractManifElemInfo & manifElmTest = *afeiIter;
1092 //
1093 // if( manifElemOther.testIfEquals(manifElmTest) )
1094 // {
1095 // managed2Touch = true;
1096 //
1097 // m_vecFractManifElm.erase(afeiIter);
1098 //
1099 // return true;
1100 // }
1101 // }
1102 //
1103 // return false;
1104 //
1106 //
1126 //
1127 // return managed2Touch;
1128 // }
1129 
1130 // VecAttachedFractManifElemInfo const getAlreadyTouchedManifElems() const
1131 // {
1132 // VecAttachedFractManifElemInfo alreadyTouchedManifElms;
1133 //
1134 // for( const auto & ameti : m_vecFractManifElmTouchInfo )
1135 // {
1136 // if( ameti.second )
1137 // alreadyTouchedManifElms.push_back( ameti );
1138 // }
1139 //
1140 // return alreadyTouchedManifElms;
1141 // }
1142 
1143 // VecAttachedFractManifElemInfo const getSoFarUnTouchedManifElems() const
1144 // {
1145 // VecAttachedFractManifElemInfo unTouchedManifElms;
1146 //
1147 // for( const auto & ameti : m_vecFractManifElmTouchInfo )
1148 // {
1149 // if( ! ameti.second )
1150 // unTouchedManifElms.push_back( ameti );
1151 // }
1152 //
1153 // return unTouchedManifElms;
1154 // }
1155 
1156 // bool const testIfAllSidesTouched() const
1157 // {
1158 // if( m_allSidesTouched )
1159 // return true;
1160 //
1161 // bool allSidesTouched = true;
1162 //
1163 // for( const auto & ameti : m_vecFractManifElmTouchInfo )
1164 // {
1165 // if( ! ameti.second )
1166 // {
1167 // allSidesTouched = false;
1168 // }
1169 // }
1170 //
1171 // m_allSidesTouched = allSidesTouched;
1172 //
1173 // return m_allSidesTouched;
1174 // }
1175 
1176 private:
1177 
1178 // bool m_allSidesTouched;
1179 
1180  FULLDIM_ELEM m_fullDimElm;
1181 
1183 
1185 
1186 // using AttFractManifElmTouchInf = std::pair<AttachedFractManifElemInfo,bool>;
1187 // using VecAttFractManifElmTouchInf = std::vector<AttFractManifElmTouchInf>;
1188 //
1189 // VecAttFractManifElmTouchInf m_vecFractManifElmTouchInfo;
1190 
1192 
1193 // VecAttachedGenerManifElemInfo m_vecInnerSegmentManifElm;
1194 
1195 // using AttGenerManifElmTouchInf = std::pair<AttachedGenerManifElemInfo,bool>;
1196 // using VecAttGenerManifElmTouchInf = std::vector<AttGenerManifElmTouchInf>;
1197 //
1198 // VecAttFractManifElmTouchInf m_vecGenerManifElmTouchInfo;
1199 
1200 
1201 // template<
1205 // typename std::enable_if<std::is_same<MANIFELM,Face* const &>::value,bool>
1206 // >
1207  //std::enable_if<std::is_same<MANIFELM,Face* const &>::value>
1208  template
1209  <
1210  typename = std::enable_if<std::is_same<Volume*,FULLDIM_ELEM>::value>,
1211  typename = std::enable_if<std::is_same<Face*,MANIFELM>::value>
1212 // typename = std::enable_if<std::is_same<Volume* const &,FULLDIM_ELEM>::value>,
1213 // typename = std::enable_if<std::is_same<Face* const &,MANIFELM>::value>
1214  >
1215  bool fullDimElmContainsManif( MANIFELM const & manifEl, Grid & grid )
1216  {
1217 // bool contained = false;
1218 
1219  for( INDEX_TXP iFac = 0; iFac < m_fullDimElm->num_faces(); iFac++ )
1220  {
1221 
1222 // static_assert(std::is_same<decltype(m_fullDimElm), Volume *>::value);
1223 
1224  Face * fac = grid.get_face(m_fullDimElm,iFac);
1225 
1226  if( fac == manifEl )
1227  {
1228  return true;
1229 // contained = true;
1230 // break;
1231  }
1232  }
1233 
1234 // return contained;
1235  return false;
1236  }
1237 
1238 
1239  template <typename ATT_MANIF_ELM_INF >
1240  bool const searchManifElem( ATT_MANIF_ELM_INF const & manifElemOther,
1241  std::vector<ATT_MANIF_ELM_INF> & memVecManifElem,
1242  bool eraseFound = true )
1243  const
1244  {
1245 
1246  for( typename std::vector<ATT_MANIF_ELM_INF>::iterator afeiIter = memVecManifElem.begin();
1247  afeiIter != memVecManifElem.end();
1248  afeiIter++
1249  )
1250  {
1251  ATT_MANIF_ELM_INF & manifElmTest = *afeiIter;
1252 
1253  if( manifElemOther.testIfEquals(manifElmTest) )
1254  {
1255 
1256  if( eraseFound )
1257  memVecManifElem.erase(afeiIter);
1258 
1259  return true;
1260  }
1261  }
1262 
1263  return false;
1264  }
1265 
1266 
1267 
1268  template <typename ATT_MANIF_ELM_INFO >
1269  bool addManifElem( ATT_MANIF_ELM_INFO const & manifElm,
1270  std::vector<ATT_MANIF_ELM_INFO> & memVecManifElm,
1271  Grid & grid )
1272  {
1273  // Caution: first test if manifold elem is at all part of the fulldim elem manifols
1274  // if not, return false directly
1275 
1276  if( ! fullDimElmContainsManif( manifElm.getManifElm(), grid ) )
1277  return false;
1278 
1279  // if manif elem is in principle part of the fulldim elem manifolds,
1280  // then we need to check if it is already integrated
1281 
1282  for( auto const & me : memVecManifElm )
1283  {
1284  if( manifElm.testIfEquals(me) )
1285  {
1286  return false;
1287  }
1288  }
1289 
1290  // not contained so far, but part of the manifolds of the fulldim elem
1291  memVecManifElm.push_back(manifElm);
1292 
1293  return true;
1294 
1295  }
1296 
1297 
1298 };
1299 
1300 #if 0
1301 template <typename VEC_AVEI, typename OPERATION, typename INDX_TYP >
1302 bool switchFulldimInfo( VEC_AVEI & vecAttVolElemInfoCop,
1303  VEC_AVEI const & vecAttVolElemInfo,
1304  VEC_AVEI & segmentAVEI,
1305  OPERATION opera,
1306  INDX_TYP switchInd = 0
1307  )
1308 {
1309  auto & startVolInfoThisSegment = vecAttVolElemInfoCop[switchInd];
1310 
1311  auto const & startVol = startVolInfoThisSegment.opera();
1312 
1313  for( auto & possibleOrigVolInfo : vecAttVolElemInfo )
1314  {
1315  auto const & possVol = possibleOrigVolInfo.opera();
1316 
1317  if( possVol == startVol )
1318  {
1319  segmentAVEI().push_back(possibleOrigVolInfo);
1320  break;
1321  }
1322  }
1323 
1324  if( segmentAVEI().size() != 1 )
1325  {
1326  UG_LOG("No start volume reconstructible " << std::endl);
1327  UG_THROW("No start volume reconstructible " << std::endl);
1328  return false;
1329  }
1330 
1331  if( ! vecAttVolElemInfoCop.erase( vecAttVolElemInfoCop.begin() + switchInd ) )
1332  return false;
1333 
1334  return true;
1335 
1336 }
1337 #endif
1338 
1339 }
1340 
1341 }
1342 
1343 #endif /* UGCORE_UGBASE_LIB_GRID_ALGORITHMS_EXTRUSION_SUPPORT3D_H_ */
Faces are 2-dimensional objects.
Definition: grid_base_objects.h:510
Manages the elements of a grid and their interconnection.
Definition: grid.h:132
Face * get_face(const FaceVertices &fv)
returns the face that is described by fv.
Definition: grid.cpp:1135
Definition: support3D.h:405
INDEX_TXP const getSudo() const
Definition: support3D.h:427
AttachedFractElem(MANIFELM const &manifElm, PairLowEl &lowElm, INDEX_TXP sudo)
Definition: support3D.h:414
INDEX_TXP m_sudo
Definition: support3D.h:559
bool const testIfEquals(AttFractElm const &attElm) const
Definition: support3D.h:429
Definition: support3D.h:897
bool addGenerManifElem(AttachedGenerManifElemInfo const &manifGenerElm, Grid &grid)
Definition: support3D.h:945
std::vector< AttachedFractManifElemInfo > VecAttachedFractManifElemInfo
Definition: support3D.h:904
VecAttachedGenerManifElemInfo m_vecGenerManifElm
Definition: support3D.h:1191
bool const testFullDimElmNeighbour(AttFullDimElmInfo const &attFullDimElmInfOther, bool eraseFoundManif=true)
Definition: support3D.h:1029
VecAttachedGenerManifElemInfo const getVecGenerManifElem() const
Definition: support3D.h:1012
bool const searchGenerManifElem(AttachedGenerManifElemInfo const &manifGenerElemOther, bool eraseFound=true)
Definition: support3D.h:1017
bool addGenerManifElem(NOGEN const &noGener, Grid &grid)=delete
AttachedFullDimElemInfo(FULLDIM_ELEM const &fullDimElm)
Definition: support3D.h:909
void markIt()
Definition: support3D.h:936
bool m_elementMarked
Definition: support3D.h:1182
VecAttachedFractManifElemInfo m_vecFractManifElm
Definition: support3D.h:1184
bool const isMarked() const
Definition: support3D.h:934
bool const searchManifElem(ATT_MANIF_ELM_INF const &manifElemOther, std::vector< ATT_MANIF_ELM_INF > &memVecManifElem, bool eraseFound=true) const
Definition: support3D.h:1240
bool addManifElem(ATT_MANIF_ELM_INFO const &manifElm, std::vector< ATT_MANIF_ELM_INFO > &memVecManifElm, Grid &grid)
Definition: support3D.h:1269
VecAttachedFractManifElemInfo const getVecFractManifElem() const
Definition: support3D.h:1007
bool const hasSameFulldimElem(AttFullDimElmInfo const &otherFullDimElmInf) const
Definition: support3D.h:926
bool addFractManifElem(AttachedFractManifElemInfo const &manifFractElm, Grid &grid)
Definition: support3D.h:940
FULLDIM_ELEM const getFulldimElem() const
Definition: support3D.h:921
bool searchGenerManifElem(NOGEN const &manifGenerElemOther, bool eraseFound)=delete
FULLDIM_ELEM m_fullDimElm
Definition: support3D.h:1180
bool fullDimElmContainsManif(MANIFELM const &manifEl, Grid &grid)
Definition: support3D.h:1215
bool const hasFracture() const
Definition: support3D.h:938
bool const searchFractManifElem(AttachedFractManifElemInfo const &manifFractElemOther, bool shiftToGeneral=true)
Definition: support3D.h:1055
std::vector< AttachedGenerManifElemInfo > VecAttachedGenerManifElemInfo
Definition: support3D.h:905
Definition: support3D.h:129
AttachedGeneralElem(MANIFELM const &manifElm, PairLowEl const &lowElm)
Definition: support3D.h:136
MANIFELM m_manifElm
Definition: support3D.h:250
MANIFELM const getManifElm() const
Definition: support3D.h:144
PairLowEl m_pairLowElm
Definition: support3D.h:251
std::pair< LOWDIMELM, LOWDIMELM > PairLowEl
Definition: support3D.h:131
bool const isNeighbouredAtSpecificSide(AttGenElm const &attElm, LOWDIMELM const &specificLDE) const
Definition: support3D.h:181
PairLowEl const getPairLowElm() const
Definition: support3D.h:146
bool const isNeighboured(AttGenElm const &attElm) const
Definition: support3D.h:148
bool const testIfEquals(AttGenElm const &attElm) const
Definition: support3D.h:231
Definition: support3D.h:332
void setShiftVrtx(std::vector< VRT > const &vecVrt)
Definition: support3D.h:366
std::vector< std::pair< VRT, bool > > m_vecShiftedVrtsWithTypInf
Definition: support3D.h:386
std::vector< VRT > m_vecShiftedVrts
Definition: support3D.h:385
std::vector< std::pair< VRT, bool > > getVecShiftedVrtsWithTypInfo() const
Definition: support3D.h:373
void addShiftVrtx(VRT const &vrt, bool isAtFreeSide=false)
Definition: support3D.h:348
FracTypVol getFracTyp() const
Definition: support3D.h:346
std::vector< VRT > getVecShiftedVrts() const
Definition: support3D.h:368
IndTyp m_numberAtFreeSide
Definition: support3D.h:388
VRT getCrossVertex() const
Definition: support3D.h:344
VRT m_crossVrt
Definition: support3D.h:384
FracTypVol m_fracTyp
Definition: support3D.h:387
CrossingVertexInfoVol(VRT const &crossVrt, FracTypVol fracTyp)
Definition: support3D.h:336
Definition: support3D.h:577
VecPairTB m_sudosClosed
Definition: support3D.h:876
std::vector< ATT_ELEM > const & getAllAttachedFractElems() const
Definition: support3D.h:835
bool getIsAClosedFracture(T sudoNow)
Definition: support3D.h:761
std::pair< T, bool > pairTB
Definition: support3D.h:580
VrtxFracStatus getVrtxFracStatus()
Definition: support3D.h:662
VrtxFracStatus m_status
Definition: support3D.h:845
bool m_isBndFracVertex
Definition: support3D.h:842
std::vector< ATT_ELEM > m_vecAttElem
Definition: support3D.h:885
std::vector< T > const getSudoList() const
Definition: support3D.h:688
VertexFracturePropertiesVol & operator++(int a)
Definition: support3D.h:655
bool addAttachedFractElem(ATT_ELEM const &attElem)
Definition: support3D.h:818
bool setSudoList(std::vector< T > const &sudoList)
Definition: support3D.h:878
bool adaptVrtxFracStatus()
Definition: support3D.h:862
void setNumberCrossingFracsInVertex(T const &nCFIV)
Definition: support3D.h:609
VecPairTB const getInfoAllFracSudosIfClosed() const
Definition: support3D.h:795
bool getIsBndFracVertex()
Definition: support3D.h:614
void setIsBndFracVertex(bool iBDV=true)
Definition: support3D.h:604
bool setVrtxFracStatus(VrtxFracStatus status)
Definition: support3D.h:852
bool setIsAClosedFracture(T sudoNow, bool isClosedNow)
Definition: support3D.h:693
std::vector< T > m_sudoList
Definition: support3D.h:849
static constexpr VrtxFracStatus m_maxStatus
Definition: support3D.h:847
bool setInfoAllFractureSudosIfClosed(VecPairTB const &sudosClosed)
Definition: support3D.h:788
VertexFracturePropertiesVol()
Definition: support3D.h:594
VrtxFracStatus
Definition: support3D.h:589
@ threeFracSuDoAtt
Definition: support3D.h:592
@ oneFracSuDoAtt
Definition: support3D.h:590
@ twoFracSuDoAtt
Definition: support3D.h:591
@ noFracSuDoAtt
Definition: support3D.h:589
std::vector< pairTB > VecPairTB
Definition: support3D.h:581
T getNumberFracEdgesInVertex()
Definition: support3D.h:625
T m_numberCountedFracsInVertex
Definition: support3D.h:843
bool const getInfoAllFracturesSameClosedState() const
Definition: support3D.h:802
bool addFractSudo(T const &sudo)
Definition: support3D.h:669
Definition: support3D.h:274
SENKRECHTENTYP m_newNormal
Definition: support3D.h:316
SENKRECHTENTYP const getNewNormal() const
Definition: support3D.h:306
VertexFractureTripleMF(MANIFOLDTYP const &manifElm, INDEXTYP sudo, FULLDIMTYP const &fullElm, SENKRECHTENTYP const &normal, PairLowEl const &pairLowElm)
Definition: support3D.h:283
std::pair< LOWDIMTYP, LOWDIMTYP > PairLowEl
Definition: support3D.h:281
INDEXTYP m_sudo
Definition: support3D.h:313
INDEXTYP const getSudoElm() const
Definition: support3D.h:298
FULLDIMTYP m_fullElm
Definition: support3D.h:314
SENKRECHTENTYP const getNormal() const
Definition: support3D.h:302
void setNewNormal(SENKRECHTENTYP const &chNorml)
Definition: support3D.h:304
VertexFractureTripleMF()
Definition: support3D.h:319
FULLDIMTYP const getFullElm() const
Definition: support3D.h:300
SENKRECHTENTYP m_normal
Definition: support3D.h:315
#define VRT(locInd)
Definition: file_io_vtu.cpp:713
#define UG_THROW(msg)
Definition: error.h:57
#define UG_LOG(msg)
Definition: log.h:367
Definition: smart_pointer.h:814
FracTypVol
Definition: support3D.h:328
@ XCross
Definition: support3D.h:328
@ TEnd
Definition: support3D.h:328
@ SingleFrac
Definition: support3D.h:328
the ug namespace