Line data Source code
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 arte
37 : {
38 :
39 : namespace support
40 : {
41 :
42 : template<typename ELEMTYP>
43 0 : bool addElem(std::vector<ELEMTYP> & knownElems, ELEMTYP elemToAdd )
44 : {
45 : bool unknown = true;
46 :
47 0 : for( ELEMTYP elmKnown : knownElems )
48 : {
49 0 : if( elemToAdd == elmKnown )
50 : {
51 : unknown = false;
52 : break;
53 : }
54 : }
55 :
56 0 : if( unknown )
57 0 : knownElems.push_back(elemToAdd);
58 :
59 0 : return unknown;
60 :
61 : }
62 :
63 :
64 : #if 0
65 :
66 : template<typename ELEMTYP, typename INDEX_TYP>
67 : class ElemInfo
68 : {
69 : public:
70 :
71 : ElemInfo( ELEMTYP const & elem, INDEX_TYP sudo )
72 : : m_elem(elem), m_sudo(sudo)
73 : {
74 : }
75 :
76 :
77 :
78 : private:
79 :
80 : ELEMTYP m_elem;
81 : INDEX_TYP m_sudo;
82 :
83 : ElemInfo() {};
84 :
85 :
86 : };
87 :
88 : template<
89 : typename FACETYP,
90 : typename NORMALTYP,
91 : typename VOLUMETYP,
92 : typename EDGETYP,
93 : typename INDEX_TYP
94 : >
95 : class VertexFractureQuadrupel
96 : {
97 : public:
98 :
99 : using ElemInfoFac = ElemInfo<FACETYP,INDEX_TYP>;
100 :
101 : //face, normal, volume, edge
102 :
103 : // VertexFractureQuadrupel()
104 : // {};
105 :
106 :
107 : VertexFractureQuadrupel( ElemInfoFac const & fracFaceInfo,
108 : VOLUMETYP const & attVolume,
109 : NORMALTYP const & normal,
110 : std::pair<EDGETYP,EDGETYP> const & volCutEdges,
111 : std::pair<ElemInfoFac,ElemInfoFac> const & volCutEdgeFaces )
112 : : m_fracFaceInfo(fracFaceInfo),
113 : m_attVolume(attVolume),
114 : m_normal(normal),
115 : m_volCutEdges(volCutEdges),
116 : m_volCutEdgeFaces(volCutEdgeFaces)
117 : {
118 : }
119 :
120 : // todo fixme getter und ggf auch setter, aber vermutlich nur getter implementieren!!!
121 :
122 : private:
123 :
124 : // FACETYP const getFace() const { return m_full; }
125 : // NORMALTYP const getNormal() const { return m_normal; }
126 : // VOLUMETYP const getVolume() const { return m_volume; }
127 : // EDGETYP const getEdge() const { return m_edge; }
128 :
129 : ElemInfo<FACETYP,INDEX_TYP> m_fracFaceInfo;
130 : VOLUMETYP m_attVolume;
131 : NORMALTYP m_normal;
132 : std::pair<EDGETYP,EDGETYP> m_volCutEdges;
133 : std::pair<ElemInfoFac,ElemInfoFac> m_volCutEdgeFaces;
134 :
135 : //private:
136 : //
137 : // FACETYP m_face;
138 : // NORMALTYP m_normal;
139 : // VOLUMETYP m_volume;
140 : // EDGETYP m_edge;
141 :
142 : VertexFractureQuadrupel()
143 : {};
144 : };
145 : #endif
146 :
147 :
148 : template <
149 : typename MANIFELM,
150 : typename LOWDIMELM,
151 : typename INDEX_TXP
152 : >
153 0 : class AttachedGeneralElem
154 : {
155 : public:
156 : using PairLowEl = std::pair<LOWDIMELM,LOWDIMELM>;
157 :
158 : using AttGenElm = AttachedGeneralElem<MANIFELM,LOWDIMELM,INDEX_TXP>;
159 :
160 : // for fracture elements
161 0 : AttachedGeneralElem( MANIFELM const & manifElm,
162 : PairLowEl const & lowElm
163 : )
164 : :
165 0 : m_manifElm(manifElm), m_pairLowElm(lowElm)
166 : {
167 : };
168 :
169 0 : MANIFELM const getManifElm() const { return m_manifElm;}
170 : // PairLowEl const getLowElm() const { return m_lowElm; }
171 0 : PairLowEl const getPairLowElm() const { return m_pairLowElm; }
172 :
173 : bool const isNeighboured( AttGenElm const & attElm )
174 : const
175 : {
176 : // MANIFELM manifElmOther = attElm.getManifElm();
177 : PairLowEl lowElmOther = attElm.getPairLowElm();
178 : // INDEX_TXP sudoOther = attElm.getSudo();
179 :
180 : PairLowEl lowElmThis = this->m_pairLowElm;
181 :
182 : std::vector<bool> test;
183 :
184 : test.push_back( lowElmOther.first == lowElmThis.first );
185 : test.push_back( lowElmOther.second == lowElmThis.first );
186 : test.push_back( lowElmOther.first == lowElmThis.second );
187 : test.push_back( lowElmOther.second == lowElmThis.second );
188 :
189 : INDEX_TXP countCorr = 0;
190 :
191 : for( auto const t : test )
192 : {
193 : if( t )
194 : countCorr++;
195 : }
196 :
197 : if( countCorr == 1 )
198 : return true;
199 :
200 : if( countCorr > 1 )
201 : UG_THROW("zu viele gleiche Ecken " << std::endl);
202 :
203 : return false;
204 : }
205 :
206 : bool const isNeighbouredAtSpecificSide( AttGenElm const & attElm,
207 : LOWDIMELM const & specificLDE )
208 : const
209 : {
210 : PairLowEl lowElmOther = attElm.getPairLowElm();
211 :
212 : PairLowEl lowElmThis = this->m_pairLowElm;
213 :
214 : // test if the specific element is part of at least
215 : // one of the faces
216 :
217 : bool otherFirst = ( lowElmOther.first == specificLDE );
218 : bool otherSecond = ( lowElmOther.second == specificLDE );
219 :
220 : bool thisFirst = ( lowElmThis.first == specificLDE );
221 : bool thisSecond = ( lowElmThis.second == specificLDE );
222 :
223 : bool isPartOfThisFace = ( thisFirst || thisSecond );
224 : bool isPartOfOtherFace = ( otherFirst || otherSecond );
225 :
226 : if( ! isPartOfOtherFace || ! isPartOfThisFace )
227 : {
228 : UG_LOG("not part of one of the faces " << std::endl);
229 : return false;
230 : }
231 :
232 : if( otherFirst && thisFirst )
233 : {
234 : if( lowElmOther.first == lowElmThis.first )
235 : return true;
236 : }
237 : else if( otherFirst && thisSecond )
238 : {
239 : if( lowElmOther.first == lowElmThis.second )
240 : return true;
241 : }
242 : else if( otherSecond && thisFirst )
243 : {
244 : if( lowElmOther.second == lowElmThis.first )
245 : return true;
246 : }
247 : else if( otherSecond && thisSecond )
248 : {
249 : if( lowElmOther.second == lowElmThis.second )
250 : return true;
251 : }
252 :
253 : return false;
254 : }
255 :
256 0 : bool const testIfEquals( AttGenElm const & attElm )
257 : const
258 : {
259 : MANIFELM manifElmOther = attElm.getManifElm();
260 : PairLowEl lowElmOther = attElm.getPairLowElm();
261 :
262 0 : if( manifElmOther == this->m_manifElm
263 0 : && hasSameEdgePair( lowElmOther )
264 : // && lowElmOther == this->m_pairLowElm
265 : )
266 : {
267 : return true;
268 : }
269 :
270 0 : if( manifElmOther == this->m_manifElm && ! hasSameEdgePair( lowElmOther ) )
271 : {
272 : UG_LOG("gleiches face aber andere Ecken???" << std::endl);
273 0 : UG_THROW("gleiches face aber andere Ecken???" << std::endl);
274 : }
275 :
276 : return false;
277 : }
278 :
279 :
280 : protected:
281 :
282 : MANIFELM m_manifElm;
283 : PairLowEl m_pairLowElm;
284 :
285 : bool const hasSameEdgePair( PairLowEl const & epTwo ) const
286 : {
287 : PairLowEl const & epOne = this->m_pairLowElm;
288 :
289 0 : if( ( epOne.first == epTwo.first && epOne.second == epTwo.second )
290 0 : || ( epOne.first == epTwo.second && epOne.second == epTwo.first )
291 : )
292 : {
293 : return true;
294 : }
295 :
296 : return false;
297 : }
298 :
299 : };
300 :
301 :
302 :
303 : ///////////////////////////////////////////////////////////////////////////////
304 :
305 :
306 : // TODO FIXME vertex fracture triplett
307 : // vereinigen mit AttachedGeneralElem !!! davon ableiten!!!
308 : // doppelte Strukturen!!!
309 :
310 : #if 0
311 : // [[DEPRECATED]]
312 : // wird abgelöst durch fortschrittlichere Klassen, bald nicht mehr nötig
313 : template <
314 : typename MANIFOLDTYP, // 3D: Face
315 : typename INDEXTYP, // int oder unsinged int oder short oder unsigned short etc
316 : typename FULLDIMTYP, // 3D: Volume
317 : typename SENKRECHTENTYP, // 3D und 2D: ug::vector3
318 : typename LOWDIMTYP // 3D: Edge (2D nicht benötigt)
319 : >
320 : class VertexFractureTripleMF
321 : : public AttachedGeneralElem<MANIFOLDTYP,LOWDIMTYP,INDEXTYP>
322 : {
323 :
324 : private:
325 : using AttGenEl = AttachedGeneralElem<MANIFOLDTYP,LOWDIMTYP,INDEXTYP>;
326 :
327 : public:
328 :
329 : using PairLowEl = std::pair<LOWDIMTYP,LOWDIMTYP>;
330 :
331 : VertexFractureTripleMF( MANIFOLDTYP const & manifElm, INDEXTYP sudo,
332 : FULLDIMTYP const & fullElm,
333 : SENKRECHTENTYP const & normal,
334 : PairLowEl const & pairLowElm )
335 : : //m_manifElm(manifElm),
336 : AttGenEl(manifElm,pairLowElm),
337 : m_sudo(sudo), m_fullElm(fullElm),
338 : m_normal(normal), m_newNormal(normal)
339 : // ,
340 : // m_pairLowElm(pairLowElm)
341 : {
342 : };
343 :
344 : // MANIFOLDTYP const getManifElm() const { return m_manifElm; }
345 :
346 : INDEXTYP const getSudoElm() const { return m_sudo; }
347 :
348 : FULLDIMTYP const getFullElm() const { return m_fullElm; }
349 :
350 : SENKRECHTENTYP const getNormal() const { return m_normal; }
351 :
352 : // TODO FIXME unklar, ob neue Normale irgendwo gebraucht wird
353 : // falls notwendig in die Fracture Klasse einführen,
354 : // die diese Klasse hier mittelfristig ablösen soll vollständig
355 : void setNewNormal( SENKRECHTENTYP const & chNorml ) { m_newNormal = chNorml; }
356 :
357 : SENKRECHTENTYP const getNewNormal() const { return m_newNormal; }
358 :
359 : // PairLowEl const getPairLowElm() const { return m_pairLowElm; }
360 :
361 : private:
362 :
363 : // MANIFOLDTYP m_manifElm;
364 : INDEXTYP m_sudo;
365 : FULLDIMTYP m_fullElm;
366 : SENKRECHTENTYP m_normal;
367 : SENKRECHTENTYP m_newNormal;
368 : // PairLowEl m_pairLowElm;
369 :
370 : VertexFractureTripleMF()
371 : {};
372 :
373 : };
374 : #endif
375 :
376 : //////////////////////////////////////////////////////////////////
377 :
378 : // TODO FIXME das muss angepasst werden, ist noch wie für 2D Fall bisher
379 : enum FracTypVol { SingleFrac = 2, TEnd = 3, XCross = 4 };
380 :
381 : template < typename VRT, typename IndTyp >
382 0 : class CrossingVertexInfoVol
383 : {
384 :
385 : public:
386 :
387 : CrossingVertexInfoVol( VRT const & crossVrt, FracTypVol fracTyp )
388 : : m_crossVrt(crossVrt), m_fracTyp( fracTyp ),
389 : m_vecShiftedVrts(std::vector<VRT>())
390 : , m_vecShiftedVrtsWithTypInf(std::vector<std::pair<VRT,bool>>())
391 : , m_numberAtFreeSide(0)
392 : {
393 : }
394 :
395 : VRT getCrossVertex() const { return m_crossVrt; }
396 :
397 : FracTypVol getFracTyp() const { return m_fracTyp; }
398 :
399 : void addShiftVrtx( VRT const & vrt, bool isAtFreeSide = false )
400 : {
401 : m_vecShiftedVrts.push_back(vrt);
402 :
403 : // if( m_fracTyp == TEnd )
404 : // {
405 : // std::pair<VRT, bool > addSVI( vrt, isAtFreeSide );
406 : // m_vecShiftedVrtsWithTypInf.push_back(addSVI);
407 : //
408 : // if( isAtFreeSide )
409 : // m_numberAtFreeSide++;
410 : //
411 : // if( m_numberAtFreeSide > 1 )
412 : // UG_THROW("was ist das fuer ein T Ende" << std::endl);
413 : // }
414 :
415 : }
416 :
417 : void setShiftVrtx( std::vector<VRT> const & vecVrt ) { m_vecShiftedVrts = vecVrt; }
418 :
419 : std::vector<VRT> getVecShiftedVrts() const
420 : {
421 : return m_vecShiftedVrts;
422 : }
423 :
424 : std::vector<std::pair<VRT,bool>> getVecShiftedVrtsWithTypInfo() const
425 : {
426 : // if( m_fracTyp != TEnd )
427 : // UG_THROW("fuer Kreuz nicht erlaubt " << std::endl);
428 :
429 : return m_vecShiftedVrtsWithTypInf;
430 : }
431 :
432 :
433 : private:
434 :
435 : VRT m_crossVrt;
436 : std::vector<VRT> m_vecShiftedVrts;
437 : std::vector<std::pair<VRT,bool>> m_vecShiftedVrtsWithTypInf;
438 : FracTypVol m_fracTyp;
439 : IndTyp m_numberAtFreeSide;
440 : };
441 :
442 : ///////////////////////////////////////////////////////////////////////////////
443 :
444 :
445 :
446 : // info for a vertex: face and attached edges, for fractures only
447 : // derived from the similar class without fracture property!
448 : template <
449 : typename MANIFELM,
450 : typename LOWDIMELM,
451 : typename INDEX_TXP,
452 : typename NORMAL_VEC
453 : >
454 0 : class AttachedFractElem
455 : : public AttachedGeneralElem<MANIFELM,LOWDIMELM,INDEX_TXP>
456 : // TODO FIXME derive from AttachedGeneralElem
457 : {
458 : public:
459 : using PairLowEl = std::pair<LOWDIMELM,LOWDIMELM>;
460 :
461 : using AttFractElm = AttachedFractElem<MANIFELM,LOWDIMELM,INDEX_TXP,NORMAL_VEC>;
462 :
463 : using AttGenElm = AttachedGeneralElem<MANIFELM,LOWDIMELM,INDEX_TXP>;
464 :
465 : // for fracture elements
466 0 : AttachedFractElem( MANIFELM const & manifElm,
467 : PairLowEl & lowElm,
468 : INDEX_TXP sudo,
469 : NORMAL_VEC const & normalVec )
470 : :
471 : AttGenElm(manifElm,lowElm),
472 : //m_manifElm(manifElm), m_lowElm(lowElm),
473 0 : m_sudo(sudo),
474 : m_normalVec(normalVec)
475 : {
476 : };
477 :
478 :
479 : // MANIFELM const getManifElm() const { return m_manifElm;}
480 : // PairLowEl const getLowElm() const { return m_lowElm; }
481 0 : INDEX_TXP const getSudo() const { return m_sudo; };
482 :
483 : NORMAL_VEC const getNormalVec() const { return m_normalVec; }
484 :
485 : bool const testIfEquals( AttFractElm const & attElm )
486 : const
487 : {
488 0 : bool geomEqu = AttGenElm::testIfEquals(attElm);
489 :
490 : // MANIFELM manifElmOther = attElm.getManifElm();
491 : // PairLowEl lowElmOther = attElm.getLowElm();
492 : INDEX_TXP sudoOther = attElm.getSudo();
493 :
494 : // if( manifElmOther == this->m_manifElm
495 : // && lowElmOther == this->m_lowElm
496 : // && sudoOther == this->m_sudo
497 : // )
498 : // {
499 : // return true;
500 : // }
501 :
502 0 : if( geomEqu && sudoOther == this->m_sudo )
503 : {
504 : return true;
505 : }
506 :
507 : return false;
508 : }
509 :
510 :
511 : // bool const testIfEquals( AttachedFractElem<MANIFELM,LOWDIMELM,INDEX_TXP> const & attElm )
512 : // const
513 : // {
514 : // MANIFELM manifElmOther = attElm.getManifElm();
515 : // PairLowEl lowElmOther = attElm.getLowElm();
516 : // INDEX_TXP sudoOther = attElm.getSudo();
517 : //
518 : // if( manifElmOther == this->m_manifElm
519 : // && lowElmOther == this->m_lowElm
520 : // && sudoOther == this->m_sudo
521 : // )
522 : // {
523 : // return true;
524 : // }
525 : //
526 : // return false;
527 : // }
528 :
529 : // bool const isNeighboured( AttachedFractElem<MANIFELM,LOWDIMELM,INDEX_TXP> const & attElm )
530 : // const
531 : // {
532 : //// MANIFELM manifElmOther = attElm.getManifElm();
533 : // PairLowEl lowElmOther = attElm.getLowElm();
534 : //// INDEX_TXP sudoOther = attElm.getSudo();
535 : //
536 : // PairLowEl lowElmThis = this->m_lowElm;
537 : //
538 : // std::vector<bool> test;
539 : //
540 : // test.push_back( lowElmOther.first == lowElmThis.first );
541 : // test.push_back( lowElmOther.second == lowElmThis.first );
542 : // test.push_back( lowElmOther.first == lowElmThis.second );
543 : // test.push_back( lowElmOther.second == lowElmThis.second );
544 : //
545 : // INDEX_TXP countCorr = 0;
546 : //
547 : // for( auto const t : test )
548 : // {
549 : // if( t )
550 : // countCorr++;
551 : // }
552 : //
553 : // if( countCorr == 1 )
554 : // return true;
555 : //
556 : // if( countCorr > 1 )
557 : // UG_THROW("zu viele gleiche Ecken " << std::endl);
558 : //
559 : // return false;
560 : // }
561 : //
562 : // bool const isNeighbouredAtSpecificSide( AttachedFractElem<MANIFELM,LOWDIMELM,INDEX_TXP> const & attElm,
563 : // LOWDIMELM const & specificLDE )
564 : // const
565 : // {
566 : // PairLowEl lowElmOther = attElm.getLowElm();
567 : //
568 : // PairLowEl lowElmThis = this->m_lowElm;
569 : //
570 : // // test if the specific element is part of at least
571 : // // one of the faces
572 : //
573 : // bool otherFirst = ( lowElmOther.first == specificLDE );
574 : // bool otherSecond = ( lowElmOther.second == specificLDE );
575 : //
576 : // bool thisFirst = ( lowElmThis.first == specificLDE );
577 : // bool thisSecond = ( lowElmThis.second == specificLDE );
578 : //
579 : // bool isPartOfThisFace = ( thisFirst || thisSecond );
580 : // bool isPartOfOtherFace = ( otherFirst || otherSecond );
581 : //
582 : // if( ! isPartOfOtherFace || ! isPartOfThisFace )
583 : // {
584 : // UG_LOG("not part of one of the faces " << std::endl);
585 : // return false;
586 : // }
587 : //
588 : // if( otherFirst && thisFirst )
589 : // {
590 : // if( lowElmOther.first == lowElmThis.first )
591 : // return true;
592 : // }
593 : // else if( otherFirst && thisSecond )
594 : // {
595 : // if( lowElmOther.first == lowElmThis.second )
596 : // return true;
597 : // }
598 : // else if( otherSecond && thisFirst )
599 : // {
600 : // if( lowElmOther.second == lowElmThis.first )
601 : // return true;
602 : // }
603 : // else if( otherSecond && thisSecond )
604 : // {
605 : // if( lowElmOther.second == lowElmThis.second )
606 : // return true;
607 : // }
608 : //
609 : // return false;
610 : // }
611 :
612 : private:
613 : // MANIFELM m_manifElm;
614 : // PairLowEl m_lowElm;
615 : INDEX_TXP m_sudo;
616 : NORMAL_VEC m_normalVec;
617 :
618 :
619 : };
620 :
621 : //////////////////////////////////////////////////////////////////////////////
622 :
623 : // a quasi exact double, but only used for boundary faces, to avoid mismatch with frac faces
624 : template <
625 : typename MANIFELM,
626 : typename LOWDIMELM,
627 : typename INDEX_TXP,
628 : typename NORMAL_VEC
629 : >
630 : class AttachedBoundryElem
631 : : public AttachedFractElem<MANIFELM,LOWDIMELM,INDEX_TXP,NORMAL_VEC>
632 : {
633 : public:
634 : using PairLowEl = std::pair<LOWDIMELM,LOWDIMELM>;
635 :
636 : using AttBndryElm = AttachedBoundryElem<MANIFELM,LOWDIMELM,INDEX_TXP,NORMAL_VEC>;
637 :
638 : using AttFractElm = AttachedFractElem<MANIFELM,LOWDIMELM,INDEX_TXP,NORMAL_VEC>;
639 :
640 :
641 : // for boundary elements
642 : AttachedBoundryElem( MANIFELM const & manifElm,
643 : PairLowEl & lowElm,
644 : INDEX_TXP sudo,
645 : NORMAL_VEC const & normalVec )
646 : :
647 : AttFractElm( manifElm, lowElm, sudo, normalVec)
648 : {
649 : };
650 : };
651 :
652 : ////////////////////////////////////////////////////////////////////////////
653 :
654 : // class to help count and store a bool and a number of templete type
655 : // comparable to std::pair<bool,int> but more dedicated to the specific aim
656 : // TODO FIXME adapt for 3D case, figure out if inner end, and number of fracs sourrounding
657 : // CAUTION is also used for edges, but still uses
658 : // vertex as indicator - name should be made more flexible
659 :
660 : // die meisten Funktionen in dieser Klasse:
661 : // DEPRECATED, to be replaced in near future everywhere, not really useful any more
662 : // due to the Stasi algorithm
663 : // [[deprecated]] ab C++14, leider nicht passend zur Konvention C++11
664 : // die Sudo-Liste wollen wir aber lassen
665 : template<
666 : typename T,
667 : typename ATT_ELEM
668 : >
669 0 : class VertexFracturePropertiesVol
670 : {
671 : public:
672 :
673 : using pairTB = std::pair<T,bool>;
674 : using VecPairTB = std::vector<pairTB>;
675 :
676 :
677 : // VertexFracturePropertiesVol( bool isBndFracVertex, T numberCrossingFracsInVertex )
678 : // : m_isBndFracVertex(isBndFracVertex), m_numberCountedFracsInVertex(numberCrossingFracsInVertex)
679 : // {
680 : // };
681 :
682 : // DEPRECATED, kann entfernt werden vermutlich, CHECK, TODO FIXME
683 : enum VrtxFracStatus { noFracSuDoAtt = 0,
684 : oneFracSuDoAtt = 1,
685 : twoFracSuDoAtt = 2,
686 : threeFracSuDoAtt = 3 };
687 :
688 0 : VertexFracturePropertiesVol()
689 0 : : m_isBndFracVertex(false), m_numberCountedFracsInVertex(0),
690 0 : m_status( noFracSuDoAtt ),
691 : m_sudoList( std::vector<T>() ) //,
692 : // m_sudosClosed(VecPairTB()),
693 : // m_vecAttElem(std::vector<ATT_ELEM>())
694 : // VertexFracturePropertiesVol( false, 0 )
695 : {
696 : };
697 :
698 : void setIsBndFracVertex( bool iBDV = true )
699 : {
700 0 : m_isBndFracVertex = iBDV;
701 0 : }
702 :
703 : void setNumberCrossingFracsInVertex( T const & nCFIV )
704 : {
705 : m_numberCountedFracsInVertex = nCFIV;
706 : }
707 :
708 : bool getIsBndFracVertex()
709 : {
710 0 : return m_isBndFracVertex;
711 : }
712 :
713 : // T getCountedNumberFracsInVertex()
714 : // {
715 : // return m_numberCountedFracsInVertex;
716 : // }
717 :
718 :
719 : T getNumberFracEdgesInVertex()
720 : {
721 0 : return m_numberCountedFracsInVertex;
722 : }
723 :
724 : // T getNumberCrossingFracsInVertex()
725 : // {
726 : // if( m_isBndFracVertex )
727 : // return m_numberCountedFracsInVertex;
728 : //
729 : // // for inner vertices, each edge passed when
730 : // // fractures are counted along their edges
731 : // // that the vertizes get hit twice for each fracture run
732 : // // only for boundary vertices, this happens only once per fracture
733 : // T multipeInnerHits = 2;
734 : //
735 : // T rest = m_numberCountedFracsInVertex % multipeInnerHits;
736 : //
737 : // if( rest != 0 )
738 : // {
739 : //// UG_THROW("Expand layers: rest division frac counting not zero " << m_numberCountedFracsInVertex << std::endl);
740 : //
741 : // throw std::runtime_error("error");
742 : //
743 : // return 0;
744 : // }
745 : //
746 : // return m_numberCountedFracsInVertex / multipeInnerHits;
747 : // }
748 :
749 : VertexFracturePropertiesVol & operator++( int a )
750 : {
751 0 : m_numberCountedFracsInVertex++;
752 : return *this;
753 : }
754 :
755 :
756 : VrtxFracStatus getVrtxFracStatus()
757 : {
758 : return m_status;
759 : }
760 :
761 : // caution: returns false if sudo already known, but no problem, feature, not bug
762 : // so never stop the program if false returned here, this is good news
763 0 : bool addFractSudo( T const & sudo )
764 : {
765 : bool alreadyInList = false;
766 :
767 0 : for( auto const & availSudo : m_sudoList )
768 : {
769 0 : if( sudo == availSudo )
770 : alreadyInList = true;
771 : }
772 :
773 0 : if( ! alreadyInList )
774 : {
775 0 : m_sudoList.push_back( sudo );
776 : }
777 :
778 0 : return adaptVrtxFracStatus();
779 : }
780 :
781 : // setter private to avoid abusive use
782 : std::vector<T> const getSudoList() const
783 : {
784 0 : return m_sudoList;
785 : }
786 :
787 : // bool setIsAClosedFracture( T sudoNow, bool isClosedNow )
788 : // {
789 : //
790 : // T alreadyKnownMult = 0;
791 : //
792 : // for( auto & suSu : m_sudosClosed )
793 : // {
794 : // T & sudoVal = suSu.first;
795 : // bool & isClosedVal = suSu.second;
796 : //
797 : // if( sudoVal == sudoNow )
798 : // {
799 : // alreadyKnownMult++;
800 : //
801 : // UG_LOG("Reassign sudo surround " << std::endl);
802 : //
803 : // if( isClosedVal != isClosedNow )
804 : // UG_THROW("change property sudo surrounded, why?" << std::endl);
805 : //
806 : // isClosedVal = isClosedNow;
807 : // }
808 : // }
809 : //
810 : // if( alreadyKnownMult == 0 )
811 : // {
812 : // pairTB infoSudoSurr( sudoNow, isClosedNow );
813 : //
814 : // m_sudosClosed.push_back( infoSudoSurr );
815 : //
816 : // }
817 : // else if( alreadyKnownMult > 1 )
818 : // {
819 : // UG_THROW("zu oft bekannt " << std::endl);
820 : // return false;
821 : // }
822 : //
823 : // // check if now correct
824 : //
825 : // T testKnownFine = 0;
826 : //
827 : // for( auto const & suSu : m_sudosClosed )
828 : // {
829 : // T & sudoVal = suSu.first;
830 : // bool & isClosedVal = suSu.second;
831 : //
832 : // if( sudoVal == sudoNow )
833 : // {
834 : // testKnownFine++;
835 : //
836 : // if( isClosedVal != isClosedNow )
837 : // {
838 : // UG_THROW("NOT set property sudo surrounded, why?" << std::endl);
839 : // return false;
840 : // }
841 : //
842 : // }
843 : // }
844 : //
845 : // if( testKnownFine == 0 || testKnownFine > 1 )
846 : // {
847 : // UG_THROW("immer noch nicht bekannt?" << std::endl);
848 : // return false;
849 : //
850 : // }
851 : //
852 : // return true;
853 : // }
854 : //
855 : // bool getIsAClosedFracture( T sudoNow )
856 : // {
857 : // T foundMultpl = 0;
858 : //
859 : // bool isClosedReturn = false;
860 : //
861 : // for( auto const & suSu : m_sudosClosed )
862 : // {
863 : // T const & sudoVal = suSu.first;
864 : // bool const & isClosedVal = suSu.second;
865 : //
866 : // if( sudoVal == sudoNow )
867 : // {
868 : // foundMultpl++;
869 : // isClosedReturn = isClosedVal;
870 : // }
871 : // }
872 : //
873 : // if( foundMultpl != 1 )
874 : // {
875 : // UG_THROW("not known status closed or not sudo" << std::endl);
876 : // return false;
877 : // }
878 : //
879 : // return isClosedReturn;
880 : // }
881 : //
882 : // bool setInfoAllFractureSudosIfClosed( VecPairTB const & sudosClosed )
883 : // {
884 : // m_sudosClosed = sudosClosed;
885 : //
886 : // return true;
887 : // }
888 : //
889 : // VecPairTB const getInfoAllFracSudosIfClosed() const
890 : // {
891 : // return m_sudosClosed;
892 : // }
893 : //
894 : // // if all open or closed
895 : // template<bool B>
896 : // bool const getInfoAllFracturesSameClosedState() const
897 : // {
898 : // bool allFracsSame = true;
899 : //
900 : // for( auto const & suSu : m_sudosClosed )
901 : // {
902 : // //T const & sudoVal = suSu.first;
903 : // bool const & isClosedVal = suSu.second;
904 : //
905 : // if( isClosedVal != B )
906 : // allFracsSame = false;
907 : // }
908 : //
909 : // return allFracsSame;
910 : // }
911 :
912 : // DEPRECATED; REMOVE
913 : // bool addAttachedFractElem( ATT_ELEM const & attElem )
914 : // {
915 : // bool alreadyKnown = false;
916 : //
917 : // for( auto const & aE : m_vecAttElem )
918 : // {
919 : // if( aE.testIfEquals(attElem) )
920 : // alreadyKnown = true;
921 : // }
922 : //
923 : // if( ! alreadyKnown )
924 : // m_vecAttElem.push_back(attElem);
925 : //
926 : // // returns true if ads it, false if no need as known
927 : // return ! alreadyKnown;
928 : // }
929 :
930 : // std::vector<ATT_ELEM> const & getAllAttachedFractElems()
931 : // const
932 : // {
933 : // return m_vecAttElem;
934 : // }
935 :
936 : private:
937 : bool m_isBndFracVertex;
938 : T m_numberCountedFracsInVertex;
939 :
940 : VrtxFracStatus m_status;
941 :
942 : static VrtxFracStatus constexpr m_maxStatus = VrtxFracStatus::threeFracSuDoAtt;
943 :
944 : std::vector<T> m_sudoList;
945 :
946 : // better private, to avoid confusion
947 : bool setVrtxFracStatus( VrtxFracStatus status )
948 : {
949 : m_status = status;
950 :
951 : if( status < noFracSuDoAtt || status > threeFracSuDoAtt )
952 : return false;
953 :
954 : return true;
955 : }
956 :
957 0 : bool adaptVrtxFracStatus()
958 : {
959 : auto sudosNum = m_sudoList.size();
960 0 : if( sudosNum > static_cast<T>( m_maxStatus ) )
961 : {
962 0 : UG_THROW("zu viele subdomains crossing in one Punkt" << std::endl);
963 : return false;
964 : }
965 :
966 0 : m_status = static_cast<VrtxFracStatus>(sudosNum);
967 :
968 : return true;
969 : }
970 :
971 : // VecPairTB m_sudosClosed;
972 :
973 : bool setSudoList( std::vector<T> const & sudoList )
974 : {
975 : m_sudoList = sudoList;
976 :
977 : return true;
978 : }
979 :
980 : // std::vector<ATT_ELEM> m_vecAttElem;
981 :
982 : };
983 :
984 :
985 : // intention, explained for volume:
986 : template<
987 : typename FULLDIM_ELEM,
988 : typename MANIFELM,
989 : typename LOWDIMELM,
990 : typename INDEX_TXP,
991 : typename NORMAL_VEC
992 : >
993 : class AttachedFullDimElemInfo
994 : {
995 :
996 : public:
997 :
998 : using AttachedFractManifElemInfo = AttachedFractElem<MANIFELM,LOWDIMELM,INDEX_TXP,NORMAL_VEC>;
999 : using AttachedGenerManifElemInfo = AttachedGeneralElem<MANIFELM,LOWDIMELM,INDEX_TXP>;
1000 : using AttachedBndryManifElemInfo = AttachedBoundryElem<MANIFELM,LOWDIMELM,INDEX_TXP,NORMAL_VEC>;
1001 :
1002 : using VecAttachedFractManifElemInfo = std::vector<AttachedFractManifElemInfo>;
1003 : using VecAttachedGenerManifElemInfo = std::vector<AttachedGenerManifElemInfo>;
1004 : using VecAttachedBndryManifElemInfo = std::vector<AttachedBndryManifElemInfo>;
1005 :
1006 : using AttFullDimElmInfo = AttachedFullDimElemInfo<FULLDIM_ELEM,MANIFELM,LOWDIMELM,INDEX_TXP,NORMAL_VEC>;
1007 :
1008 0 : AttachedFullDimElemInfo( FULLDIM_ELEM const & fullDimElm )
1009 0 : : m_fullDimElm(fullDimElm),
1010 0 : m_elementMarked(false),
1011 : m_vecFractManifElm(VecAttachedFractManifElemInfo()),
1012 : m_vecUnclosedFractManifElm(VecAttachedFractManifElemInfo()),
1013 : // m_vecFractManifElmTouchInfo(VecAttFractManifElmTouchInf()),
1014 : // m_allSidesTouched(false),
1015 : m_vecGenerManifElm(VecAttachedGenerManifElemInfo()),
1016 : m_vecBndryManifElm(VecAttachedBndryManifElemInfo())
1017 : // m_vecGenerManifElmTouchInfo(VecAttFractManifElmTouchInf())
1018 : // m_vecInnerSegmentManifElm(VecAttachedGenerManifElemInfo())
1019 : {
1020 : }
1021 :
1022 : FULLDIM_ELEM const getFulldimElem() const
1023 : {
1024 0 : return m_fullDimElm;
1025 : }
1026 :
1027 : bool const hasSameFulldimElem( AttFullDimElmInfo const & otherFullDimElmInf )
1028 : const
1029 : {
1030 : FULLDIM_ELEM otherFullDimElm = otherFullDimElmInf.getFulldimElem();
1031 :
1032 0 : return ( otherFullDimElm == m_fullDimElm );
1033 : }
1034 :
1035 0 : bool const isMarked() const { return m_elementMarked; }
1036 :
1037 0 : void markIt() { m_elementMarked = true; } // to allow in loop to be start element
1038 :
1039 : bool const hasFracture() const { return ( m_vecFractManifElm.size() > 0 ); }
1040 :
1041 : bool const hasUnclosedFracture() const { return ( m_vecUnclosedFractManifElm.size() > 0 ); }
1042 :
1043 : bool addFractManifElem( AttachedFractManifElemInfo const & manifFractElm, Grid & grid )
1044 : {
1045 0 : return addManifElem( manifFractElm, m_vecFractManifElm, grid );
1046 : }
1047 :
1048 : bool addGenerManifElem( AttachedGenerManifElemInfo const & manifGenerElm, Grid & grid )
1049 : {
1050 : // static_assert(std::is_same<AttachedGenerManifElemInfo, decltype( manifGenerElm ) >::value);
1051 :
1052 0 : return addManifElem( manifGenerElm, m_vecGenerManifElm, grid );
1053 : }
1054 :
1055 : bool addBndryManifElem( AttachedBndryManifElemInfo const & manifBndryElm, Grid & grid )
1056 : {
1057 0 : return addManifElem( manifBndryElm, m_vecBndryManifElm, grid );
1058 : }
1059 :
1060 : // necessary to avoid stupid casting from derived class AttachedFractManifElemInfo
1061 : // else, addGenerManifElem would also eat objects of derived class
1062 : // however not it only accepts explicit base class objects
1063 : template <typename NOGEN>
1064 : bool addGenerManifElem( NOGEN const & noGener, Grid & grid )
1065 : = delete;
1066 :
1067 : template <typename NOGEN>
1068 : bool addBndryManifElem( NOGEN const & noGener, Grid & grid )
1069 : = delete;
1070 :
1071 :
1072 : // // will form new "surface" of next inner round in a segment
1073 : // bool addInnerSegmentManifElem( AttachedGenerManifElemInfo const & manifInnerSegmentElm, Grid & grid )
1074 : // {
1075 : // return addManifElem( manifInnerSegmentElm, m_vecInnerSegmentManifElm, grid );
1076 : // }
1077 : //
1078 : // template <typename NOGEN>
1079 : // bool addInnerSegmentElem( NOGEN const & noGener, Grid & grid )
1080 : // = delete;
1081 :
1082 :
1083 :
1084 : // bool addFractureManifElem( AttachedFractManifElemInfo const & manifElm, Grid & grid )
1085 : // {
1086 : // // Caution: first test if manifold elem is at all part of the fulldim elem manifols
1087 : // // if not, return false directly
1088 : //
1089 : // if( ! fullDimElmContainsManif( manifElm.getManifElm(), grid ) )
1090 : // return false;
1091 : //
1092 : // // if manif elem is in principle part of the fulldim elem manifolds,
1093 : // // then we need to check if it is already integrated
1094 : //
1095 : // bool hasElemAlready = false;
1096 : //
1097 : //
1098 : // for( auto const & me : m_vecFractManifElm )
1099 : // {
1100 : // if( manifElm.testIfEquals(me) )
1101 : // {
1102 : // hasElemAlready = true;
1103 : // break;
1104 : // }
1105 : // }
1106 : //
1107 : // if( ! hasElemAlready )
1108 : // {
1109 : // m_vecFractManifElm.push_back( manifElm );
1110 : //
1111 : //// AttFractManifElmTouchInf pamei( manifElm, false );
1112 : ////
1113 : //// m_vecFractManifElmTouchInfo.push_back(pamei);
1114 : // }
1115 : //
1116 : // return ! hasElemAlready;
1117 : // }
1118 :
1119 : VecAttachedFractManifElemInfo const getVecFractManifElem() const
1120 : {
1121 0 : return m_vecFractManifElm;
1122 : }
1123 :
1124 : VecAttachedFractManifElemInfo const getVecUnclosedFractManifElem() const
1125 : {
1126 0 : return m_vecUnclosedFractManifElm;
1127 : }
1128 :
1129 :
1130 : VecAttachedGenerManifElemInfo const getVecGenerManifElem() const
1131 : {
1132 0 : return m_vecGenerManifElm;
1133 : }
1134 :
1135 : VecAttachedBndryManifElemInfo const getVecBndryManifElem() const
1136 : {
1137 0 : return m_vecBndryManifElm;
1138 : }
1139 :
1140 :
1141 : bool const searchGenerManifElem( AttachedGenerManifElemInfo const & manifGenerElemOther, bool eraseFound = true )
1142 : {
1143 : bool found = searchManifElem( manifGenerElemOther, m_vecGenerManifElm, eraseFound );
1144 :
1145 : if( found && eraseFound )
1146 : {
1147 : m_elementMarked = true;
1148 : }
1149 :
1150 : return found;
1151 : }
1152 :
1153 0 : bool const testFullDimElmNeighbour( AttFullDimElmInfo const & attFullDimElmInfOther, bool eraseFoundManif = true )
1154 : {
1155 : VecAttachedGenerManifElemInfo const & vecGenerManifElmOther = attFullDimElmInfOther.getVecGenerManifElem();
1156 :
1157 : bool manifNeighbored = false;
1158 :
1159 0 : for( AttachedGenerManifElemInfo const & generManifElemOther : vecGenerManifElmOther )
1160 : {
1161 0 : if( searchManifElem( generManifElemOther, m_vecGenerManifElm, eraseFoundManif ) )
1162 : manifNeighbored = true;
1163 :
1164 : }
1165 :
1166 0 : if( manifNeighbored && eraseFoundManif )
1167 : {
1168 0 : m_elementMarked = true;
1169 : }
1170 :
1171 0 : return manifNeighbored;
1172 0 : }
1173 :
1174 :
1175 : template <typename NOGEN>
1176 : bool searchGenerManifElem( NOGEN const & manifGenerElemOther, bool eraseFound ) = delete;
1177 :
1178 : // bool const searchFractManifElem( AttachedFractManifElemInfo const & manifFractElemOther, bool eraseFound = true )
1179 0 : bool const searchFractManifElem( AttachedFractManifElemInfo const & manifFractElemOther, bool shiftToUnclosedFracts = true )
1180 : {
1181 0 : bool found = searchManifElem( manifFractElemOther, m_vecFractManifElm, shiftToUnclosedFracts );
1182 :
1183 0 : if( found && shiftToUnclosedFracts )
1184 : {
1185 : // for the case that a fracture is not closed at a vertex, shift the in principle
1186 : // fracture vertex to the gerneral vertices, as useless for segmente construction
1187 : // and useless for expansion
1188 :
1189 0 : m_vecUnclosedFractManifElm.push_back(manifFractElemOther);
1190 :
1191 :
1192 : // MANIFELM const & manifel = manifFractElemOther.getManifElm();
1193 : // typename AttachedGenerManifElemInfo::PairLowEl const & pairLowEl = manifFractElemOther.getPairLowElm();
1194 : //
1195 : // AttachedGenerManifElemInfo agmei( manifel, pairLowEl );
1196 :
1197 : // m_vecUnclosedFractManifElm.push_back(agmei);
1198 : }
1199 :
1200 0 : return found;
1201 :
1202 : }
1203 :
1204 : template <typename NOGEN>
1205 : bool const searchFractManifElem( NOGEN const & manifFractElemOther, bool shiftToGeneral ) = delete;
1206 :
1207 : bool const searchBndryManifElem( AttachedBndryManifElemInfo const & manifBndryElemOther )
1208 : {
1209 : return searchManifElem( manifBndryElemOther, m_vecBndryManifElm, false );
1210 : }
1211 :
1212 : // bool const searchInnerSegmentManifElem( AttachedGenerManifElemInfo const & manifInnerSegmElemOther, bool eraseFound = true )
1213 : // {
1214 : // return searchManifElem( manifInnerSegmElemOther, m_vecInnerSegmentManifElm, eraseFound );
1215 : // }
1216 :
1217 : // bool const tryToTouchManifElem( AttachedFractManifElemInfo const & manifElemOther ) const
1218 : // {
1219 : //// bool managed2Touch = false;
1220 : //
1221 : // for( typename VecAttachedFractManifElemInfo::iterator afeiIter = m_vecFractManifElm.begin();
1222 : // afeiIter != m_vecFractManifElm.end();
1223 : // afeiIter++
1224 : // )
1225 : // {
1226 : // AttachedFractManifElemInfo & manifElmTest = *afeiIter;
1227 : //
1228 : // if( manifElemOther.testIfEquals(manifElmTest) )
1229 : // {
1230 : // managed2Touch = true;
1231 : //
1232 : // m_vecFractManifElm.erase(afeiIter);
1233 : //
1234 : // return true;
1235 : // }
1236 : // }
1237 : //
1238 : // return false;
1239 : //
1240 : //// return managed2Touch;
1241 : //
1242 : //// for( auto & ameti : m_vecFractManifElmTouchInfo )
1243 : //// {
1244 : //// AttachedFractManifElemInfo & manifElmTest = ameti.first;
1245 : //// bool & alreadyTouched = ameti.second;
1246 : ////
1247 : //// if( ! alreadyTouched )
1248 : //// {
1249 : //// if( manifElemOther.testIfEquals( manifElmTest ) )
1250 : //// {
1251 : //// alreadyTouched = true;
1252 : //// }
1253 : //// }
1254 : ////
1255 : //// if( alreadyTouched )
1256 : //// {
1257 : //// managed2Touch = true;
1258 : //// break;
1259 : //// }
1260 : //// }
1261 : //
1262 : // return managed2Touch;
1263 : // }
1264 :
1265 : // VecAttachedFractManifElemInfo const getAlreadyTouchedManifElems() const
1266 : // {
1267 : // VecAttachedFractManifElemInfo alreadyTouchedManifElms;
1268 : //
1269 : // for( const auto & ameti : m_vecFractManifElmTouchInfo )
1270 : // {
1271 : // if( ameti.second )
1272 : // alreadyTouchedManifElms.push_back( ameti );
1273 : // }
1274 : //
1275 : // return alreadyTouchedManifElms;
1276 : // }
1277 :
1278 : // VecAttachedFractManifElemInfo const getSoFarUnTouchedManifElems() const
1279 : // {
1280 : // VecAttachedFractManifElemInfo unTouchedManifElms;
1281 : //
1282 : // for( const auto & ameti : m_vecFractManifElmTouchInfo )
1283 : // {
1284 : // if( ! ameti.second )
1285 : // unTouchedManifElms.push_back( ameti );
1286 : // }
1287 : //
1288 : // return unTouchedManifElms;
1289 : // }
1290 :
1291 : // bool const testIfAllSidesTouched() const
1292 : // {
1293 : // if( m_allSidesTouched )
1294 : // return true;
1295 : //
1296 : // bool allSidesTouched = true;
1297 : //
1298 : // for( const auto & ameti : m_vecFractManifElmTouchInfo )
1299 : // {
1300 : // if( ! ameti.second )
1301 : // {
1302 : // allSidesTouched = false;
1303 : // }
1304 : // }
1305 : //
1306 : // m_allSidesTouched = allSidesTouched;
1307 : //
1308 : // return m_allSidesTouched;
1309 : // }
1310 :
1311 : private:
1312 :
1313 : // bool m_allSidesTouched;
1314 :
1315 : FULLDIM_ELEM m_fullDimElm;
1316 :
1317 : bool m_elementMarked;
1318 :
1319 : VecAttachedFractManifElemInfo m_vecFractManifElm;
1320 :
1321 : VecAttachedFractManifElemInfo m_vecUnclosedFractManifElm;
1322 :
1323 :
1324 : // using AttFractManifElmTouchInf = std::pair<AttachedFractManifElemInfo,bool>;
1325 : // using VecAttFractManifElmTouchInf = std::vector<AttFractManifElmTouchInf>;
1326 : //
1327 : // VecAttFractManifElmTouchInf m_vecFractManifElmTouchInfo;
1328 :
1329 : VecAttachedGenerManifElemInfo m_vecGenerManifElm;
1330 :
1331 : VecAttachedBndryManifElemInfo m_vecBndryManifElm;
1332 :
1333 : // VecAttachedGenerManifElemInfo m_vecInnerSegmentManifElm;
1334 :
1335 : // using AttGenerManifElmTouchInf = std::pair<AttachedGenerManifElemInfo,bool>;
1336 : // using VecAttGenerManifElmTouchInf = std::vector<AttGenerManifElmTouchInf>;
1337 : //
1338 : // VecAttFractManifElmTouchInf m_vecGenerManifElmTouchInfo;
1339 :
1340 :
1341 : // template<
1342 : //// typename std::enable_if<std::is_same<FULLDIM_ELEM,Volume* const &>::value, true>,
1343 : //// typename std::enable_if<std::is_same<MANIFELM,Face* const &>::value, true>
1344 : //// typename std::enable_if<std::is_same<FULLDIM_ELEM,Volume* const &>::value, true>,
1345 : // typename std::enable_if<std::is_same<MANIFELM,Face* const &>::value,bool>
1346 : // >
1347 : //std::enable_if<std::is_same<MANIFELM,Face* const &>::value>
1348 : template
1349 : <
1350 : typename = std::enable_if<std::is_same<Volume*,FULLDIM_ELEM>::value>,
1351 : typename = std::enable_if<std::is_same<Face*,MANIFELM>::value>
1352 : // typename = std::enable_if<std::is_same<Volume* const &,FULLDIM_ELEM>::value>,
1353 : // typename = std::enable_if<std::is_same<Face* const &,MANIFELM>::value>
1354 : >
1355 0 : bool fullDimElmContainsManif( MANIFELM const & manifEl, Grid & grid )
1356 : {
1357 : // bool contained = false;
1358 :
1359 0 : for( INDEX_TXP iFac = 0; iFac < m_fullDimElm->num_faces(); iFac++ )
1360 : {
1361 :
1362 : // static_assert(std::is_same<decltype(m_fullDimElm), Volume *>::value);
1363 :
1364 0 : Face * fac = grid.get_face(m_fullDimElm,iFac);
1365 :
1366 0 : if( fac == manifEl )
1367 : {
1368 : return true;
1369 : // contained = true;
1370 : // break;
1371 : }
1372 : }
1373 :
1374 : // return contained;
1375 : return false;
1376 : }
1377 :
1378 :
1379 : template <typename ATT_MANIF_ELM_INF >
1380 0 : bool const searchManifElem( ATT_MANIF_ELM_INF const & manifElemOther,
1381 : std::vector<ATT_MANIF_ELM_INF> & memVecManifElem,
1382 : bool eraseFound = true )
1383 : const
1384 : {
1385 :
1386 0 : for( typename std::vector<ATT_MANIF_ELM_INF>::iterator afeiIter = memVecManifElem.begin();
1387 0 : afeiIter != memVecManifElem.end();
1388 : afeiIter++
1389 : )
1390 : {
1391 : ATT_MANIF_ELM_INF & manifElmTest = *afeiIter;
1392 :
1393 0 : if( manifElemOther.testIfEquals(manifElmTest) )
1394 : {
1395 :
1396 0 : if( eraseFound )
1397 : memVecManifElem.erase(afeiIter);
1398 :
1399 : return true;
1400 : }
1401 : }
1402 :
1403 : return false;
1404 : }
1405 :
1406 :
1407 :
1408 : template <typename ATT_MANIF_ELM_INFO >
1409 0 : bool addManifElem( ATT_MANIF_ELM_INFO const & manifElm,
1410 : std::vector<ATT_MANIF_ELM_INFO> & memVecManifElm,
1411 : Grid & grid )
1412 : {
1413 : // Caution: first test if manifold elem is at all part of the fulldim elem manifols
1414 : // if not, return false directly
1415 :
1416 0 : if( ! fullDimElmContainsManif( manifElm.getManifElm(), grid ) )
1417 : return false;
1418 :
1419 : // if manif elem is in principle part of the fulldim elem manifolds,
1420 : // then we need to check if it is already integrated
1421 :
1422 0 : for( auto const & me : memVecManifElm )
1423 : {
1424 0 : if( manifElm.testIfEquals(me) )
1425 : {
1426 : return false;
1427 : }
1428 : }
1429 :
1430 : // not contained so far, but part of the manifolds of the fulldim elem
1431 0 : memVecManifElm.push_back(manifElm);
1432 :
1433 0 : return true;
1434 :
1435 : }
1436 :
1437 :
1438 : };
1439 :
1440 : //////////////////////////////////////////////////////////////////
1441 :
1442 :
1443 : // Ebenentyp: a x1 + b x2 + c x3 = rhs, normal * ( vecX - baseVect ) = 0
1444 : template<typename VECTOR_TYP,
1445 : typename LOWDIMELM
1446 : >
1447 0 : class ManifoldDescriptor
1448 : {
1449 : public:
1450 :
1451 : enum ManifoldType { isFracture, isBoundary, isArtificial };
1452 :
1453 : template<typename = std::enable_if<std::is_same<VECTOR_TYP,vector3>::value>>
1454 : // ManifoldDescriptor( int sudo = -1, number scaleShiftNormal = 0 )
1455 0 : ManifoldDescriptor()
1456 : : m_normalVect(vector3()),
1457 : m_baseVect(vector3()),
1458 0 : m_rhs(0),
1459 0 : m_scaleShiftNormal(0),
1460 0 : m_dim(3),
1461 0 : m_sudo(-1),
1462 0 : m_manifTyp( isArtificial )
1463 : {
1464 : }
1465 :
1466 :
1467 : template<typename = std::enable_if<std::is_same<VECTOR_TYP,vector3>::value>>
1468 0 : ManifoldDescriptor( VECTOR_TYP const & normalVect,
1469 : VECTOR_TYP const & baseVect,
1470 : int sudo = -1,
1471 : ManifoldType manifTyp = isArtificial,
1472 : number scaleShiftNormal = 0
1473 : )
1474 : : m_normalVect(normalVect),
1475 : m_baseVect(baseVect),
1476 0 : m_scaleShiftNormal(scaleShiftNormal),
1477 0 : m_dim(3),
1478 0 : m_sudo(sudo),
1479 0 : m_manifTyp( manifTyp ),
1480 : m_lowDimElms(std::vector<LOWDIMELM>())
1481 : {
1482 0 : m_rhs = 0;
1483 :
1484 : UG_LOG("Ebenenkoordinatenform ");
1485 :
1486 0 : for( int i = 0; i < m_dim; i++ )
1487 : {
1488 0 : m_rhs += normalVect[i]*baseVect[i];
1489 :
1490 0 : UG_LOG( " + " << normalVect[i] << " x_" << i << " " );
1491 : }
1492 :
1493 0 : UG_LOG(" = " << m_rhs << std::endl);
1494 :
1495 0 : }
1496 :
1497 0 : VECTOR_TYP const & spuckNormalVector() const { return m_normalVect; }
1498 0 : VECTOR_TYP const & spuckBaseVector() const { return m_baseVect; }
1499 :
1500 0 : int const spuckSudo() const { return m_sudo; }
1501 :
1502 0 : ManifoldType const spuckManifTyp() const { return m_manifTyp; }
1503 :
1504 : number const spuckScaleShiftNormal() const { return m_scaleShiftNormal; }
1505 :
1506 : void schluckSudo( int sudo ) { m_sudo = sudo; }
1507 :
1508 : void schluckManifTyp( ManifoldType manifTyp ) { m_manifTyp = manifTyp; }
1509 :
1510 : void schluckScaleShiftNormal( number scaleShiftNormal )
1511 : {
1512 0 : m_scaleShiftNormal = scaleShiftNormal;
1513 : }
1514 :
1515 : number const & spuckRHS() const { return m_rhs; }
1516 :
1517 : template<typename = std::enable_if< std::is_same<VECTOR_TYP,vector3>::value
1518 : // || std::is_same<VECTOR_TYP,vector2>::value>
1519 : >
1520 : >
1521 : bool spuckPlaneShiftedAlong( VECTOR_TYP const & shiftVec, ManifoldDescriptor & manifoldDescr )
1522 : {
1523 : VECTOR_TYP shiftedBaseVect;
1524 : // number rhsShiftedPlane = 0;
1525 :
1526 : VecAdd( shiftedBaseVect, m_baseVect, shiftVec );
1527 :
1528 : UG_LOG("Ebenenkoordinatenform Shifted Plane " << std::endl);
1529 :
1530 : // ManifoldDescriptor( VECTOR_TYP const & normalVect,
1531 : // VECTOR_TYP const & baseVect,
1532 : // int sudo = -1,
1533 : // ManifoldType = isArtificial,
1534 : // number scaleShiftNormal = 0
1535 : // )
1536 :
1537 : manifoldDescr = ManifoldDescriptor( m_normalVect, shiftedBaseVect, m_sudo, m_manifTyp, 0 );
1538 :
1539 : return true;
1540 :
1541 : }
1542 :
1543 : template<typename = std::enable_if<std::is_same<VECTOR_TYP,vector3>::value >>
1544 0 : bool spuckPlaneShifted( ManifoldDescriptor & manifoldDescr )
1545 : {
1546 :
1547 : UG_LOG("Ebenenkoordinatenform Shifted Plane " << std::endl);
1548 :
1549 0 : manifoldDescr = ManifoldDescriptor( m_normalVect, spuckShiftedBaseVect(), m_sudo, m_manifTyp, 0 );
1550 :
1551 0 : if( ! manifoldDescr.schluckLowDimElms(m_lowDimElms) )
1552 : {
1553 : UG_LOG("Neuer Manifold Descripter verschoben ohne Ecken" << std::endl);
1554 : }
1555 :
1556 0 : return true;
1557 :
1558 : }
1559 :
1560 :
1561 : template<typename = std::enable_if< std::is_same<VECTOR_TYP,vector3>::value>>
1562 0 : VECTOR_TYP spuckShiftedBaseVect()
1563 : {
1564 : VECTOR_TYP shiftVec;
1565 :
1566 0 : VecScale(shiftVec, m_normalVect, m_scaleShiftNormal );
1567 :
1568 : VECTOR_TYP shiftedBaseVec;
1569 :
1570 : VecAdd( shiftedBaseVec, m_baseVect, shiftVec );
1571 :
1572 0 : return shiftedBaseVec;
1573 : }
1574 :
1575 : bool schluckLowDimElms( std::vector<LOWDIMELM> const & lowDimElms )
1576 : {
1577 0 : m_lowDimElms = lowDimElms;
1578 : return ( m_lowDimElms.size() > 0 );
1579 : }
1580 :
1581 : bool const spuckLowDimElms( std::vector<LOWDIMELM> & lowDimElms ) const
1582 : {
1583 0 : lowDimElms = m_lowDimElms;
1584 : return ( m_lowDimElms.size() > 0 );
1585 : }
1586 :
1587 : private:
1588 :
1589 : VECTOR_TYP m_normalVect;
1590 : VECTOR_TYP m_baseVect;
1591 : number m_rhs;
1592 : number m_scaleShiftNormal;
1593 :
1594 : // could be defined as static const variable, but then depending on the template parameter
1595 : // might be an idea for future, but no real use, but would be "nice" from the meta programmig point of view
1596 : int m_dim;
1597 : int m_sudo;
1598 : ManifoldType m_manifTyp;
1599 :
1600 : std::vector<LOWDIMELM> m_lowDimElms;
1601 : };
1602 :
1603 :
1604 : //////////////////////////////////////////////////////////////////
1605 :
1606 : //// needs to be declared as members used in following class
1607 : //template
1608 : //<
1609 : //typename FULLDIMEL,
1610 : //typename MANIFEL,
1611 : //typename LOWDIMEL,
1612 : //typename VRTXTYP,
1613 : //typename INDEXTYP
1614 : //>
1615 : //class EndingCrossingFractSegmentInfo;
1616 :
1617 : //////////////////////////////////////////////////////////////
1618 :
1619 :
1620 : template <
1621 : typename FULLDIM_ELEM,
1622 : typename MANIFELM,
1623 : typename LOWDIMELM,
1624 : typename INDEX_TXP,
1625 : typename VECTOR_TYP,
1626 : typename VRTXTYP
1627 : >
1628 : class SegmentSides
1629 : {
1630 : public:
1631 :
1632 : enum VrtxFracStatus { noFracSuDoAtt = 0,
1633 : oneFracSuDoAtt = 1,
1634 : twoFracSuDoAtt = 2,
1635 : threeFracSuDoAtt = 3 };
1636 :
1637 : using AttFractElm = AttachedFractElem<MANIFELM, LOWDIMELM, INDEX_TXP, VECTOR_TYP>;
1638 : using AttBndryElm = AttachedBoundryElem<MANIFELM, LOWDIMELM, INDEX_TXP, VECTOR_TYP>;
1639 :
1640 : using VecAttFractElm = std::vector<AttFractElm>;
1641 : using VecAttBndryElm = std::vector<AttBndryElm>;
1642 :
1643 : using PairSudoNormlV = std::pair<INDEX_TXP,VECTOR_TYP>;
1644 : using VecPairSudoNormlV = std::vector<PairSudoNormlV>;
1645 :
1646 : using PairSudoVecLowDiEl = std::pair<INDEX_TXP, std::vector<LOWDIMELM> >;
1647 : using VecPairSudoVecLowDiEl = std::vector<PairSudoVecLowDiEl>;
1648 :
1649 : using ManifDescr = ManifoldDescriptor<VECTOR_TYP, LOWDIMELM>;
1650 : using VecManifDescr = std::vector<ManifDescr>;
1651 :
1652 : // TODO FIXME das soll gleich durch den Manifold Descriptor ersetzt werden
1653 : // oder eine Basisklasse von ihm, die nicht so viele Infos enthält
1654 : // aber mindestens NormalenVektor, Sudo, und ob Boundary oder Fracture
1655 : // kann auch vielleicht einfach eine Klasse sein, die noch einen Parameter enthält
1656 : // der sich abfragen lässt, auch als Template vielleicht, true false, fracture or not
1657 : // also was wie template < index, normal, bool > pairsudonormlbla, oder sowas.....
1658 : // oder man kann einen Parameter setzen für diese Klasse, die extern definiert wird......
1659 : // bool isFracture true false.....
1660 :
1661 : template< typename = std::enable_if< std::is_pointer<LOWDIMELM>::value>
1662 : >
1663 0 : SegmentSides( VRTXTYP const & vrt, bool isBndry = false )
1664 0 : : m_vrt(vrt),
1665 0 : m_shiftDirectionIfUnclosedFractPresent(nullptr),
1666 : m_vecAttFractElms(VecAttFractElm()),
1667 : m_vecAttUnclosedFractElms(VecAttFractElm()),
1668 : m_vecAttBndryElms(VecAttBndryElm()),
1669 : m_vecFractSudosNormlV(VecPairSudoNormlV()),
1670 : m_vecBndrySudosNormlV(VecPairSudoNormlV()),
1671 : m_vecFractSudoLowDiEl(VecPairSudoVecLowDiEl()),
1672 : m_vecBndrySudoLowDiEl(VecPairSudoVecLowDiEl()),
1673 0 : m_isBoundary(isBndry),
1674 0 : m_averaged(false),
1675 : m_contribFulldimElm(std::vector<FULLDIM_ELEM>()),
1676 0 : m_volEdgesDetermined(false),
1677 : m_vecVolEdges(std::vector<LOWDIMELM>())
1678 : {};
1679 :
1680 : // template<typename = std::enable_if< std::is_pointer<VRTXTYP>::value>>
1681 : // SegmentSides()
1682 : // : m_vrt(nullptr),
1683 : // m_vecAttFractElms(VecAttFractElm()),
1684 : // m_vecAttUnclosedFractElms(VecAttFractElm()),
1685 : // m_vecAttBndryElms(VecAttBndryElm()),
1686 : // m_vecFractSudosNormlV(VecPairSudoNormlV()),
1687 : // m_vecBndrySudosNormlV(VecPairSudoNormlV()),
1688 : // m_isBoundary(false),
1689 : // m_averaged(false),
1690 : // m_contribFulldimElm(std::vector<FULLDIM_ELEM>())
1691 : // {};
1692 :
1693 :
1694 0 : bool const isBoundary() const { return m_isBoundary; }
1695 :
1696 : VRTXTYP const spuckVertex() const
1697 : {
1698 0 : return m_vrt;
1699 : }
1700 :
1701 : bool schluckFulldimElem( FULLDIM_ELEM const & fudielm )
1702 : {
1703 0 : m_volEdgesDetermined = false;
1704 0 : return addElem(m_contribFulldimElm, fudielm);
1705 : // m_contribFulldimElm.push_back(fudielm);
1706 : }
1707 :
1708 : bool const spuckVecFulldimElem( std::vector<FULLDIM_ELEM> & fudielm ) const
1709 : {
1710 0 : fudielm = m_contribFulldimElm;
1711 :
1712 : return ( m_contribFulldimElm.size() != 0 );
1713 : }
1714 :
1715 : template< //typename GRID,
1716 : //typename = std::enable_if< std::is_same<GRID, Grid >::value>,
1717 : typename = std::enable_if< std::is_same<FULLDIM_ELEM,Volume*>::value>,
1718 : typename = std::enable_if< std::is_same<FULLDIM_ELEM,Volume*>::value>
1719 : >
1720 : bool spuckListLowdimElmsOfVols( std::vector<LOWDIMELM> & listLowdimElms, Grid & grid )
1721 : {
1722 0 : if( ! m_volEdgesDetermined )
1723 : {
1724 0 : determineListLowdimElms( grid );
1725 : }
1726 :
1727 0 : listLowdimElms = m_vecVolEdges;
1728 :
1729 0 : return m_volEdgesDetermined;
1730 : }
1731 :
1732 :
1733 : VrtxFracStatus const spuckCrossingTyp() const
1734 : {
1735 0 : VrtxFracStatus vfsFract = static_cast<VrtxFracStatus>(m_vecFractSudosNormlV.size());
1736 :
1737 0 : if( m_isBoundary )
1738 : {
1739 : VrtxFracStatus vfsBndry = static_cast<VrtxFracStatus>(m_vecBndrySudosNormlV.size());
1740 :
1741 0 : return static_cast<VrtxFracStatus>( static_cast<INDEX_TXP>(vfsFract) + static_cast<INDEX_TXP>(vfsBndry) );
1742 : }
1743 :
1744 : return vfsFract;
1745 : }
1746 :
1747 : bool schluckVecAttFractElm( std::vector<AttFractElm> const & vecAtFracEl )
1748 : {
1749 0 : return schluckVecAttElm( vecAtFracEl, m_vecAttFractElms );
1750 : }
1751 :
1752 : template< typename NOFRACT >
1753 : bool schluckVecAttFractElm( std::vector<NOFRACT> const & vecAtFracEl ) = delete;
1754 :
1755 : bool schluckAttFractElm( AttFractElm const & afeNew )
1756 : {
1757 : return schluckAttElm( afeNew, m_vecAttFractElms );
1758 :
1759 : // if( ! isStillUnknown( afeNew, m_vecAttFractElms ) )
1760 : // {
1761 : // return false;
1762 : // }
1763 : //
1764 : // m_vecAttFractElms.push_back(afeNew);
1765 : //
1766 : // return true;
1767 : }
1768 :
1769 : template< typename NOFRACT >
1770 : bool schluckAttFractElm( NOFRACT const & afeNew ) = delete;
1771 :
1772 : // soll auch in der Lage sein, die einzenlen Fracture faces wieder aus zu spucken als Liste
1773 : // analog auch dan ach die boundary Geschichten
1774 : bool const spuckVecAttFractElm( std::vector<AttFractElm> & vecAttFracEl ) const
1775 : {
1776 0 : vecAttFracEl = m_vecAttFractElms;
1777 : return true;
1778 : }
1779 :
1780 : bool schluckVecAttBndryElm( std::vector<AttBndryElm> const & vecAtBndryEl )
1781 : {
1782 : // if( ! checkIfIsAtBndry() )
1783 : // return false;
1784 :
1785 0 : return schluckVecAttElm( vecAtBndryEl, m_vecAttBndryElms );
1786 : }
1787 :
1788 : bool schluckAttBndryElm( AttBndryElm const & afeNew )
1789 : {
1790 : // if( ! checkIfIsAtBndry() )
1791 : // return false;
1792 :
1793 : return schluckAttElm( afeNew, m_vecAttBndryElms );
1794 :
1795 : // if( ! isStillUnknown( afeNew, m_vecAttBndryElms ) )
1796 : // {
1797 : // return false;
1798 : // }
1799 : //
1800 : // m_vecAttBndryElms.push_back(afeNew);
1801 : //
1802 : // return true;
1803 : }
1804 :
1805 : bool spuckVecAttBndryElm( std::vector<AttBndryElm> & vecAtBndryEl )
1806 : {
1807 : vecAtBndryEl = m_vecAttBndryElms;
1808 : return true;
1809 : }
1810 :
1811 :
1812 : bool schluckVecAttUnclosedFractElm( std::vector<AttFractElm> const & vecAtFracEl )
1813 : {
1814 0 : return schluckVecAttElm( vecAtFracEl, m_vecAttUnclosedFractElms, true );
1815 : }
1816 :
1817 : template< typename NOFRACT >
1818 : bool schluckVecAttUnclosedFractElm( std::vector<NOFRACT> const & vecAtFracEl ) = delete;
1819 :
1820 : bool schluckAttUnclosedFractElm( AttFractElm const & afeNew )
1821 : {
1822 : return schluckAttElm( afeNew, m_vecAttUnclosedFractElms, true );
1823 : }
1824 :
1825 : template< typename NOFRACT >
1826 : bool schluckAttUnclosedFractElm( NOFRACT const & afeNew ) = delete;
1827 :
1828 : bool const spuckVecAttUnclosedFractElm( std::vector<AttFractElm> & vecAttFracEl ) const
1829 : {
1830 0 : vecAttFracEl = m_vecAttUnclosedFractElms;
1831 : return true;
1832 : }
1833 :
1834 : bool const hasUnclosedFaces() const
1835 : {
1836 : return ( m_vecAttUnclosedFractElms.size() > 0 );
1837 : }
1838 :
1839 : template< typename = std::enable_if< std::is_pointer<LOWDIMELM>::value>
1840 : >
1841 0 : bool schluckLowdimElmShiftDirectionIfUnclosedFractPresent( LOWDIMELM const & shiftDirectionElm )
1842 : {
1843 0 : if( m_shiftDirectionIfUnclosedFractPresent != nullptr
1844 0 : && shiftDirectionElm != m_shiftDirectionIfUnclosedFractPresent
1845 : )
1846 : {
1847 : UG_LOG("Shift direction already set different " << std::endl);
1848 0 : UG_THROW("Shift direction already set different " << std::endl);
1849 : }
1850 :
1851 0 : if( shiftDirectionElm != nullptr )
1852 : {
1853 0 : m_shiftDirectionIfUnclosedFractPresent = shiftDirectionElm;
1854 0 : return true;
1855 : }
1856 :
1857 : return false;
1858 : }
1859 :
1860 : template< typename = std::enable_if< std::is_pointer<LOWDIMELM>::value>
1861 : >
1862 : bool const spuckLowdimElmShiftDirectionIfUnclosedFractPresent( LOWDIMELM & shiftDirectionElm ) const
1863 : {
1864 0 : if( m_shiftDirectionIfUnclosedFractPresent != nullptr )
1865 : {
1866 0 : shiftDirectionElm = m_shiftDirectionIfUnclosedFractPresent;
1867 0 : return true;
1868 : }
1869 :
1870 : return false;
1871 : }
1872 :
1873 0 : bool averageAll()
1874 : {
1875 0 : if( m_isBoundary )
1876 : {
1877 0 : if( ! averageBndryNormals() )
1878 : return false;
1879 : }
1880 :
1881 0 : if( ! averageFractNormals() )
1882 : return false;
1883 :
1884 0 : m_averaged = true;
1885 :
1886 0 : return m_averaged;
1887 : }
1888 :
1889 : bool const spuckFractSudoNormls( VecPairSudoNormlV & vecFractSudosNormlV ) const
1890 : {
1891 : if( ! m_averaged )
1892 : {
1893 : UG_LOG("please average " << std::endl);
1894 : UG_THROW("please average " << std::endl);
1895 : return false;
1896 : }
1897 :
1898 : vecFractSudosNormlV = m_vecFractSudosNormlV;
1899 :
1900 : return true;
1901 : }
1902 :
1903 : template<typename = std::enable_if< std::is_same<VECTOR_TYP,vector3>::value>>
1904 : bool const spuckFractManifDescr( VecManifDescr & vecManifDesc,
1905 : Grid::VertexAttachmentAccessor<APosition> const & aaPos,
1906 : bool clearDescVec = true
1907 : ) const
1908 : {
1909 0 : return spuckManifDescr<ManifDescr::ManifoldType::isFracture>( vecManifDesc, aaPos, m_vecFractSudosNormlV, m_vecFractSudoLowDiEl, clearDescVec );
1910 : // return spuckManifDescr<0>( vecManifDesc, aaPos, m_vecFractSudosNormlV );
1911 : }
1912 :
1913 :
1914 :
1915 :
1916 : // bool spuckFractManifDescr( VecManifDescr & vecManifDesc, Grid::VertexAttachmentAccessor<APosition> const & aaPos )
1917 : // {
1918 : // if( ! m_averaged )
1919 : // {
1920 : // UG_LOG("please average " << std::endl);
1921 : // UG_THROW("please average " << std::endl);
1922 : // return false;
1923 : // }
1924 : //
1925 : // VecPairSudoNormlV const & vecFractSudosNormlV = m_vecFractSudosNormlV;
1926 : //
1927 : // vecManifDesc.clear();
1928 : //
1929 : // for( PairSudoNormlV const & psn : vecFractSudosNormlV )
1930 : // {
1931 : // VECTOR_TYP posVrt = aaPos[m_vrt];
1932 : //
1933 : // int sudo = psn.first;
1934 : // VECTOR_TYP normlVec = psn.second;
1935 : //
1936 : //// ManifoldDescriptor( VECTOR_TYP const & normalVect,
1937 : //// VECTOR_TYP const & baseVect,
1938 : //// int sudo = -1,
1939 : //// ManifoldType = isArtificial,
1940 : //// number scaleShiftNormal = 0
1941 : //// )
1942 : ////
1943 : //
1944 : // ManifDescr manifDesc( normlVec, posVrt, sudo, ManifDescr::ManifoldType::isFracture );
1945 : //
1946 : // vecManifDesc.push_back( manifDesc );
1947 : // }
1948 : //
1949 : // return true;
1950 : // }
1951 :
1952 : bool spuckBndrySudoNormls( VecPairSudoNormlV & vecBndrySudosNormlV )
1953 : {
1954 : // if( ! checkIfIsAtBndry() )
1955 : // return false;
1956 :
1957 : if( ! m_averaged )
1958 : {
1959 : UG_LOG("please average " << std::endl);
1960 : UG_THROW("please average " << std::endl);
1961 : return false;
1962 : }
1963 :
1964 : vecBndrySudosNormlV = m_vecBndrySudosNormlV;
1965 :
1966 : return true;
1967 : }
1968 :
1969 : template<typename = std::enable_if< std::is_same<VECTOR_TYP,vector3>::value>>
1970 : bool const spuckBndryManifDescr( VecManifDescr & vecManifDesc,
1971 : Grid::VertexAttachmentAccessor<APosition> const & aaPos,
1972 : bool clearDescVec = true
1973 : ) const
1974 : {
1975 0 : return spuckManifDescr<ManifDescr::ManifoldType::isBoundary>( vecManifDesc, aaPos, m_vecBndrySudosNormlV, m_vecBndrySudoLowDiEl, clearDescVec );
1976 : // return spuckManifDescr<2>( vecManifDesc, aaPos, m_vecFractSudosNormlV );
1977 : }
1978 :
1979 :
1980 : private:
1981 :
1982 : VRTXTYP m_vrt;
1983 :
1984 : LOWDIMELM m_shiftDirectionIfUnclosedFractPresent;
1985 :
1986 : VecAttFractElm m_vecAttFractElms;
1987 : VecAttFractElm m_vecAttUnclosedFractElms;
1988 :
1989 : VecAttBndryElm m_vecAttBndryElms;
1990 :
1991 :
1992 :
1993 : VecPairSudoNormlV m_vecFractSudosNormlV;
1994 : VecPairSudoNormlV m_vecBndrySudosNormlV;
1995 :
1996 : VecPairSudoVecLowDiEl m_vecFractSudoLowDiEl;
1997 : VecPairSudoVecLowDiEl m_vecBndrySudoLowDiEl;
1998 :
1999 :
2000 : bool m_isBoundary;
2001 : bool m_averaged;
2002 :
2003 : std::vector<FULLDIM_ELEM> m_contribFulldimElm;
2004 :
2005 : bool m_volEdgesDetermined;
2006 : std::vector<LOWDIMELM> m_vecVolEdges;
2007 :
2008 : // zu heikel, weil dabei Änderungen nicht übernommen würden, es sei denn, es wäre pointer, aber die
2009 : // wollen wir auch vermeiden
2010 : // EndingCrossingFractSegmentInfo<FULLDIM_ELEM, MANIFELM, LOWDIMELM, VRTXTYP, INDEX_TXP> m_endingCrossFractSegmInf;
2011 :
2012 : template <typename ATT_ELM, typename VEC_ATT_ELM,
2013 : typename = std::enable_if<std::is_same<std::vector<ATT_ELM>,VEC_ATT_ELM>::value>,
2014 : typename = std::enable_if<std::is_base_of<AttFractElm,ATT_ELM>::value>
2015 : >
2016 0 : bool isStillUnknown( ATT_ELM const & afeNew, VEC_ATT_ELM const & vecAttELm, bool acceptUnknowns = false )
2017 : {
2018 0 : for( ATT_ELM const & afeAlt : vecAttELm )
2019 : {
2020 : if( afeAlt.testIfEquals(afeNew) )
2021 : {
2022 : UG_LOG("Strange, already known?" << std::endl);
2023 0 : if( ! acceptUnknowns )
2024 0 : UG_THROW("Strange, already known?" << std::endl);
2025 : return false;
2026 : }
2027 : }
2028 :
2029 : return true;
2030 :
2031 : }
2032 :
2033 : template <typename ATT_ELM,
2034 : typename = std::enable_if<std::is_base_of<AttFractElm,ATT_ELM>::value>
2035 : >
2036 0 : bool extractSudoList( std::vector<INDEX_TXP> & sudoListSegment, std::vector<ATT_ELM> const & vecAttELm )
2037 : {
2038 0 : for( AttFractElm const & me : vecAttELm )
2039 : {
2040 0 : INDEX_TXP sudoNeeded = me.getSudo();
2041 :
2042 : bool sudoIsKnown = false;
2043 :
2044 0 : for( INDEX_TXP sudoInList : sudoListSegment )
2045 : {
2046 0 : if( sudoInList == sudoNeeded )
2047 : {
2048 : sudoIsKnown = true;
2049 : break;
2050 : }
2051 : }
2052 :
2053 0 : if( ! sudoIsKnown )
2054 0 : sudoListSegment.push_back(sudoNeeded);
2055 : }
2056 :
2057 0 : return true;
2058 : }
2059 :
2060 : template <typename ATT_ELM,
2061 : typename = std::enable_if<std::is_base_of<AttFractElm,ATT_ELM>::value>
2062 : >
2063 0 : bool averageNormlForEachSudo( std::vector<ATT_ELM> const & vecAttElm, VecPairSudoNormlV & vecPSudoNrml, VecPairSudoVecLowDiEl & vecPSudoVecLowDiElm )
2064 : {
2065 : // first determine appearing sudos
2066 :
2067 : std::vector<INDEX_TXP> sudoListSegment;
2068 :
2069 0 : extractSudoList(sudoListSegment,vecAttElm);
2070 :
2071 0 : for( INDEX_TXP sudo : sudoListSegment )
2072 : {
2073 : VECTOR_TYP normlAvrg;
2074 :
2075 0 : if( ! averageNormalForSpecificSudo( sudo, vecAttElm, normlAvrg ) )
2076 0 : return false;
2077 :
2078 : std::pair<INDEX_TXP, VECTOR_TYP> sudoNorml( sudo, normlAvrg );
2079 :
2080 0 : vecPSudoNrml.push_back(sudoNorml);
2081 :
2082 : // TODO FIXME auch Liste mit Sudo plus Ecken, die auf der Mannigfaltigkeit liegen!!!!
2083 :
2084 : std::vector<LOWDIMELM> vecLowDimElmsSudo;
2085 :
2086 0 : if( ! extractLowDimElemsForSpecificSudo( sudo, vecAttElm, vecLowDimElmsSudo ) )
2087 : return false;
2088 :
2089 : PairSudoVecLowDiEl sudoLDE( sudo, vecLowDimElmsSudo );
2090 :
2091 0 : vecPSudoVecLowDiElm.push_back( sudoLDE );
2092 :
2093 : }
2094 :
2095 : return true;
2096 0 : }
2097 :
2098 : template <typename ATT_ELM,
2099 : typename = std::enable_if<std::is_base_of<AttFractElm,ATT_ELM>::value>
2100 : >
2101 0 : bool averageNormalForSpecificSudo( INDEX_TXP specfcSudo, std::vector<ATT_ELM> const & vecAttElm, VECTOR_TYP & normlAvrg )
2102 : {
2103 : VECTOR_TYP normsSum(0,0,0);
2104 : INDEX_TXP numContrNrmls = 0;
2105 :
2106 0 : for( ATT_ELM const & ae : vecAttElm )
2107 : {
2108 : INDEX_TXP sudoElm = ae.getSudo();
2109 :
2110 0 : if( specfcSudo == sudoElm )
2111 : {
2112 : VECTOR_TYP normElm = ae.getNormalVec();
2113 :
2114 : VECTOR_TYP tmpSum = normsSum;
2115 :
2116 : VecAdd( normsSum, normElm, tmpSum );
2117 :
2118 0 : numContrNrmls++;
2119 : }
2120 : }
2121 :
2122 0 : if( numContrNrmls == 0 )
2123 : {
2124 : UG_LOG("Kein Beitrag in SUdo? " << std::endl);
2125 0 : UG_THROW("Kein Beitrag in SUdo? " << std::endl);
2126 : return false;
2127 : }
2128 :
2129 0 : VecScale( normlAvrg, normsSum, 1. / static_cast<number>(numContrNrmls) );
2130 :
2131 : return true;
2132 :
2133 : }
2134 :
2135 : template <typename ATT_ELM,
2136 : typename = std::enable_if<std::is_base_of<AttFractElm,ATT_ELM>::value>
2137 : >
2138 0 : bool extractLowDimElemsForSpecificSudo( INDEX_TXP specfcSudo, std::vector<ATT_ELM> const & vecAttElm, std::vector<LOWDIMELM> & vecLowDimElms )
2139 : {
2140 0 : for( ATT_ELM const & ae : vecAttElm )
2141 : {
2142 : INDEX_TXP sudoElm = ae.getSudo();
2143 :
2144 0 : if( specfcSudo == sudoElm )
2145 : {
2146 : std::pair<LOWDIMELM,LOWDIMELM> paLoDiEl = ae.getPairLowElm();
2147 :
2148 0 : addElem(vecLowDimElms, paLoDiEl.first);
2149 0 : addElem(vecLowDimElms, paLoDiEl.second);
2150 : }
2151 :
2152 : }
2153 :
2154 0 : return true;
2155 : }
2156 :
2157 :
2158 : bool averageFractNormals()
2159 : {
2160 0 : return averageNormlForEachSudo( m_vecAttFractElms, m_vecFractSudosNormlV, m_vecFractSudoLowDiEl );
2161 : }
2162 :
2163 0 : bool averageBndryNormals()
2164 : {
2165 0 : if( m_isBoundary )
2166 : {
2167 0 : return averageNormlForEachSudo( m_vecAttBndryElms, m_vecBndrySudosNormlV, m_vecBndrySudoLowDiEl );
2168 : }
2169 : else
2170 : {
2171 : UG_LOG("no boundary, no averaging");
2172 0 : return false;
2173 : }
2174 : }
2175 :
2176 : template
2177 : < typename ATT_ELM,
2178 : typename = std::enable_if<std::is_base_of<AttFractElm,ATT_ELM>::value>
2179 : >
2180 0 : bool schluckVecAttElm( std::vector<ATT_ELM> const & vecAttElNew, std::vector<ATT_ELM> & vecAttElmKnown, bool acceptUnknowns = false )
2181 : {
2182 : bool allUnknown = true;
2183 :
2184 0 : for( ATT_ELM const & aeN : vecAttElNew )
2185 : {
2186 0 : if( ! schluckAttElm( aeN, vecAttElmKnown, acceptUnknowns ) )
2187 : {
2188 : allUnknown = false;
2189 : UG_LOG("ist schon bekannt" << std::endl);
2190 0 : if( ! acceptUnknowns)
2191 0 : UG_THROW("ist schon bekannt" << std::endl);
2192 : //return false;
2193 : }
2194 : }
2195 :
2196 0 : return allUnknown;
2197 : }
2198 :
2199 : template
2200 : < typename ATT_ELM,
2201 : typename = std::enable_if<std::is_base_of<AttFractElm,ATT_ELM>::value>
2202 : >
2203 0 : bool schluckAttElm( ATT_ELM const & attElNew, std::vector<ATT_ELM> & vecAttElmKnown, bool acceptUnknowns = false )
2204 : {
2205 0 : m_averaged = false;
2206 :
2207 0 : if( ! isStillUnknown( attElNew, vecAttElmKnown, acceptUnknowns ) )
2208 : {
2209 : UG_LOG("ist schon bekannt" << std::endl);
2210 0 : if( ! acceptUnknowns )
2211 0 : UG_THROW("ist schon bekannt" << std::endl);
2212 : return false;
2213 : }
2214 :
2215 0 : vecAttElmKnown.push_back(attElNew);
2216 :
2217 0 : return true;
2218 : }
2219 :
2220 : bool checkIfIsAtBndry()
2221 : {
2222 : if( ! m_isBoundary )
2223 : {
2224 : UG_LOG("gibts keine Bndry " << std::endl);
2225 : UG_THROW("gibts keine Bndry " << std::endl);
2226 : return false;
2227 : }
2228 :
2229 : return m_isBoundary;
2230 : }
2231 :
2232 : // template<ManifDescr::ManifoldType manifTyp,
2233 : // template<typename ManifDescr::ManifoldType manifTyp,
2234 : template<typename ManifDescr::ManifoldType manifTyp,
2235 : typename = std::enable_if< std::is_same<VECTOR_TYP,vector3>::value>
2236 : >
2237 0 : bool const spuckManifDescr( VecManifDescr & vecManifDesc,
2238 : Grid::VertexAttachmentAccessor<APosition> const & aaPos,
2239 : VecPairSudoNormlV const & vecFractSudosNormlV,
2240 : VecPairSudoVecLowDiEl const & vecFractSudosLDE,
2241 : bool clearDescVec = true
2242 : ) const
2243 : {
2244 0 : if( ! m_averaged )
2245 : {
2246 : UG_LOG("please average " << std::endl);
2247 0 : UG_THROW("please average " << std::endl);
2248 : return false;
2249 : }
2250 :
2251 0 : if( clearDescVec )
2252 : vecManifDesc.clear();
2253 :
2254 0 : for( PairSudoNormlV const & psn : vecFractSudosNormlV )
2255 : {
2256 0 : VECTOR_TYP posVrt = aaPos[m_vrt];
2257 :
2258 0 : int sudo = psn.first;
2259 : VECTOR_TYP normlVec = psn.second;
2260 :
2261 : // ManifoldDescriptor( VECTOR_TYP const & normalVect,
2262 : // VECTOR_TYP const & baseVect,
2263 : // int sudo = -1,
2264 : // ManifoldType = isArtificial,
2265 : // number scaleShiftNormal = 0
2266 : // )
2267 : //
2268 :
2269 0 : UG_LOG("ASSIGN MANIF TYP " << manifTyp << std::endl);
2270 0 : ManifDescr manifDesc( normlVec, posVrt, sudo, manifTyp );
2271 : // TODO FIXME der Manifold Descriptor muss noch die Vertizes wissen, die ihn aufspannen
2272 : // abgesehen vom Zentrums-Vertex
2273 :
2274 0 : if( ! addLowDimElmListForSudo( manifDesc, sudo, vecFractSudosLDE ) )
2275 : {
2276 : UG_LOG("No low dim elems " << std::endl);
2277 0 : UG_THROW("No low dim elems " << std::endl);
2278 : return false;
2279 : }
2280 :
2281 0 : vecManifDesc.push_back( manifDesc );
2282 : }
2283 :
2284 : return true;
2285 : }
2286 :
2287 0 : bool const addLowDimElmListForSudo( ManifDescr & md, INDEX_TXP sudo, VecPairSudoVecLowDiEl const & vecFractSudosLDE ) const
2288 : {
2289 : INDEX_TXP foundSudo = 0;
2290 :
2291 0 : for( PairSudoVecLowDiEl const & psvlde : vecFractSudosLDE )
2292 : {
2293 0 : INDEX_TXP sudoFract = psvlde.first;
2294 :
2295 0 : if( sudoFract == sudo )
2296 : {
2297 0 : foundSudo++;
2298 :
2299 0 : std::vector<LOWDIMELM> const & vecLoDiEl = psvlde.second;
2300 :
2301 0 : if( ! md.schluckLowDimElms( vecLoDiEl ) )
2302 : {
2303 : UG_LOG("NO LOWDIM ELEMS" << std::endl);
2304 : return false;
2305 : }
2306 : }
2307 : }
2308 :
2309 0 : if( foundSudo != 1 )
2310 : {
2311 : UG_LOG("NO SUDO FOUND LDE" << std::endl);
2312 : }
2313 :
2314 0 : return ( foundSudo == 1 );
2315 : }
2316 :
2317 : template< //typename GRID,
2318 : //typename = std::enable_if< std::is_same<GRID, Grid >::value>,
2319 : typename = std::enable_if< std::is_same<FULLDIM_ELEM,Volume*>::value>,
2320 : typename = std::enable_if< std::is_same<FULLDIM_ELEM,Volume*>::value>
2321 : >
2322 0 : void determineListLowdimElms( Grid & grid )
2323 : {
2324 0 : for( FULLDIM_ELEM const & fe : m_contribFulldimElm )
2325 : {
2326 0 : for(size_t i_edge = 0; i_edge < fe->num_edges(); ++i_edge)
2327 : {
2328 0 : LOWDIMELM lowDimElm = grid.get_edge( fe, i_edge );
2329 :
2330 0 : if( EdgeContains(lowDimElm, m_vrt))
2331 : {
2332 0 : addElem(m_vecVolEdges, lowDimElm);
2333 : }
2334 : }
2335 :
2336 : }
2337 :
2338 0 : m_volEdgesDetermined = true;
2339 0 : }
2340 :
2341 :
2342 : };
2343 :
2344 : //////////////////////////////////////////////////////////////////
2345 :
2346 :
2347 :
2348 : #if 0
2349 : template <typename VEC_AVEI, typename OPERATION, typename INDX_TYP >
2350 : bool switchFulldimInfo( VEC_AVEI & vecAttVolElemInfoCop,
2351 : VEC_AVEI const & vecAttVolElemInfo,
2352 : VEC_AVEI & segmentAVEI,
2353 : OPERATION opera,
2354 : INDX_TYP switchInd = 0
2355 : )
2356 : {
2357 : auto & startVolInfoThisSegment = vecAttVolElemInfoCop[switchInd];
2358 :
2359 : auto const & startVol = startVolInfoThisSegment.opera();
2360 :
2361 : for( auto & possibleOrigVolInfo : vecAttVolElemInfo )
2362 : {
2363 : auto const & possVol = possibleOrigVolInfo.opera();
2364 :
2365 : if( possVol == startVol )
2366 : {
2367 : segmentAVEI().push_back(possibleOrigVolInfo);
2368 : break;
2369 : }
2370 : }
2371 :
2372 : if( segmentAVEI().size() != 1 )
2373 : {
2374 : UG_LOG("No start volume reconstructible " << std::endl);
2375 : UG_THROW("No start volume reconstructible " << std::endl);
2376 : return false;
2377 : }
2378 :
2379 : if( ! vecAttVolElemInfoCop.erase( vecAttVolElemInfoCop.begin() + switchInd ) )
2380 : return false;
2381 :
2382 : return true;
2383 :
2384 : }
2385 : #endif
2386 :
2387 :
2388 : //////////////////////////////////////////////////////////////////////////
2389 :
2390 : template
2391 : <
2392 : typename FULLDIMEL,
2393 : typename MANIFEL,
2394 : typename LOWDIMEL,
2395 : typename VRTXTYP,
2396 : typename INDEXTYP
2397 : >
2398 : class EndingCrossingFractSegmentInfo
2399 : {
2400 : public:
2401 :
2402 : // TODO FIXME
2403 : // wenn zwei an Kreuzungen endende Klüfte nur eine edge voneinander entfernt sind
2404 : // dann ist ein edge split an allen Ecken notwendig, die die beiden Problemzonen
2405 : // miteinander verbinden
2406 : // eventuell muss man danach die ganze Prozedur nochmal von vorne anfangen
2407 : // alternativ überlegen, ob man solche Punkte schon vor allen Segmentbildungen
2408 : // heraus filtern kann, etwa mit der altmodischen Art und Weise, wie anfangs,
2409 : // mit Loops über die Fracture faces...... um mindestens diese Stellen zu finden.....
2410 : // und gleich ein split edge an allen notwendigen Verbindungen durch zu führen.....
2411 : // hätte man die alte Methode vielleicht behalten sollen.......
2412 :
2413 : using ManifelPair = std::pair<MANIFEL,MANIFEL>;
2414 :
2415 : template< typename = std::enable_if< std::is_pointer<MANIFEL>::value>,
2416 : typename = std::enable_if< std::is_pointer<VRTXTYP>::value>
2417 : >
2418 0 : EndingCrossingFractSegmentInfo( VRTXTYP const & vrt,
2419 : MANIFEL const & endingFractManifCutting,
2420 : std::vector<MANIFEL> const & vecEndingFractManifNotCutting,
2421 : LOWDIMEL const & oldLowDimElCut,
2422 : ManifelPair const & pairNeighbouredFractClosedManifEl,
2423 : LOWDIMEL const & shiftDirectionElm,
2424 : std::vector<LOWDIMEL> const & vecLowDimElmsOfNotCuttingManifs,
2425 : INDEXTYP sudoFractEnding,
2426 : INDEXTYP sudoFractNotEnding
2427 : )
2428 : :
2429 0 : m_isEndingCleft(true),
2430 0 : m_unclosedVrtx(vrt),
2431 0 : m_endingFractManifCutting(endingFractManifCutting),
2432 0 : m_vecEndingFractManifNotCutting(vecEndingFractManifNotCutting),
2433 0 : m_pairNeighbouredFractClosedManifEl(pairNeighbouredFractClosedManifEl),
2434 : m_vecClosedFracManifElNoNeighbr(std::vector<MANIFEL>()),
2435 0 : m_oldLowDimElCut( oldLowDimElCut ),
2436 0 : m_vecLowDimElmsOfNotCuttingManifs(vecLowDimElmsOfNotCuttingManifs),
2437 0 : m_shiftDirectionElm(shiftDirectionElm),
2438 0 : m_sudoFractEnding(sudoFractEnding),
2439 0 : m_sudoFractNotEnding(sudoFractNotEnding),
2440 : m_vecFulldimEl(std::vector<FULLDIMEL>()),
2441 0 : m_shiftVrtx(nullptr),
2442 0 : m_hiddenCutManifEl(nullptr)
2443 : {
2444 0 : };
2445 :
2446 : template< typename = std::enable_if< std::is_pointer<MANIFEL>::value>,
2447 : typename = std::enable_if< std::is_pointer<VRTXTYP>::value>
2448 : >
2449 : // if there is no ending fract manif no cutting available
2450 : EndingCrossingFractSegmentInfo( VRTXTYP const & vrt,
2451 : MANIFEL const & endingFractManifCutting,
2452 : LOWDIMEL const & oldLowDimElCut,
2453 : ManifelPair const & pairNeighbouredFractClosedManifEl,
2454 : LOWDIMEL const & shiftDirectionElm,
2455 : int sudoFractEnding,
2456 : int sudoFractNotEnding
2457 : )
2458 : :
2459 : m_isEndingCleft(true),
2460 : m_unclosedVrtx(vrt),
2461 : m_endingFractManifCutting(endingFractManifCutting),
2462 : m_vecEndingFractManifNotCutting(std::vector<MANIFEL>()),
2463 : m_pairNeighbouredFractClosedManifEl(pairNeighbouredFractClosedManifEl),
2464 : m_vecClosedFracManifElNoNeighbr(std::vector<MANIFEL>()),
2465 : m_oldLowDimElCut( oldLowDimElCut ),
2466 : m_vecLowDimElmsOfNotCuttingManifs(std::vector<LOWDIMEL>()),
2467 : m_shiftDirectionElm(shiftDirectionElm),
2468 : m_sudoFractEnding(sudoFractEnding),
2469 : m_sudoFractNotEnding(sudoFractNotEnding),
2470 : m_vecFulldimEl(std::vector<FULLDIMEL>()),
2471 : m_shiftVrtx(nullptr),
2472 : m_hiddenCutManifEl(nullptr)
2473 : {
2474 : };
2475 :
2476 : template< typename = std::enable_if< std::is_pointer<MANIFEL>::value>,
2477 : typename = std::enable_if< std::is_pointer<LOWDIMEL>::value>,
2478 : typename = std::enable_if< std::is_pointer<VRTXTYP>::value>,
2479 : typename = std::enable_if< std::is_integral<INDEXTYP>::value>
2480 : >
2481 : // if there is no ending fract manif no cutting available
2482 : EndingCrossingFractSegmentInfo()
2483 : :
2484 : m_isEndingCleft(false),
2485 : m_unclosedVrtx(nullptr),
2486 : m_endingFractManifCutting(nullptr),
2487 : m_vecEndingFractManifNotCutting(std::vector<MANIFEL>()),
2488 : m_pairNeighbouredFractClosedManifEl(ManifelPair(nullptr,nullptr)),
2489 : m_vecClosedFracManifElNoNeighbr(std::vector<MANIFEL>()),
2490 : m_oldLowDimElCut( nullptr ),
2491 : m_vecLowDimElmsOfNotCuttingManifs(std::vector<LOWDIMEL>()),
2492 : m_shiftDirectionElm(nullptr),
2493 : m_sudoFractEnding(std::numeric_limits<INDEXTYP>::max()),
2494 : m_sudoFractNotEnding(std::numeric_limits<INDEXTYP>::max()),
2495 : m_vecFulldimEl(std::vector<FULLDIMEL>()),
2496 : m_shiftVrtx(nullptr),
2497 : m_hiddenCutManifEl(nullptr)
2498 : {
2499 : };
2500 :
2501 0 : bool schluckShiftVrtx( VRTXTYP const & shiftVrtx )
2502 : {
2503 :
2504 0 : if( m_shiftVrtx != nullptr
2505 0 : && shiftVrtx != m_shiftVrtx
2506 : )
2507 : {
2508 : UG_LOG("Shift Vertex already set different " << std::endl);
2509 0 : UG_THROW("Shift Vertex already set different " << std::endl);
2510 : return false;
2511 : }
2512 :
2513 0 : if( shiftVrtx != nullptr )
2514 : {
2515 0 : m_shiftVrtx = shiftVrtx;
2516 0 : return true;
2517 : }
2518 :
2519 : // else
2520 :
2521 : // UG_LOG("SHift vertex already set " << std::endl);
2522 : // UG_THROW("SHift vertex already set " << std::endl);
2523 :
2524 : return false;
2525 : }
2526 :
2527 : VRTXTYP const spuckShiftVrtx() const
2528 : {
2529 0 : return m_shiftVrtx;
2530 : // if( m_shiftVrtx != nullptr )
2531 : // {
2532 : // shiftVrtx = m_shiftVrtx;
2533 : // return true;
2534 : // }
2535 : //
2536 : // return false;
2537 : }
2538 :
2539 : bool isEndingCleft() { return m_isEndingCleft; }
2540 :
2541 : // schluck
2542 :
2543 : bool schluckClosedFracManifElNoNeighbr( MANIFEL const & closFracME )
2544 : {
2545 : return schluckElem( closFracME, m_vecClosedFracManifElNoNeighbr );
2546 :
2547 : }
2548 :
2549 : bool schluckVecClosedFracManifElNoNeighbr( std::vector<MANIFEL> const & vecClosFracME )
2550 : {
2551 0 : return schluckVecElem( vecClosFracME, m_vecClosedFracManifElNoNeighbr );
2552 : }
2553 :
2554 : bool schluckFulldimElm( FULLDIMEL const & fuDiEl )
2555 : {
2556 : return schluckElem( fuDiEl, m_vecFulldimEl );
2557 : }
2558 :
2559 : bool schluckVecFulldimElm( std::vector<FULLDIMEL> const & vecFuDiEl )
2560 : {
2561 0 : return schluckVecElem( vecFuDiEl, m_vecFulldimEl );
2562 : }
2563 :
2564 : // spuck
2565 :
2566 : // bool spuckUnclosedVrtx( VRTXTYP & vrt )
2567 : // {
2568 : // vrt = m_unclosedVrtx;
2569 : // return true;
2570 : // }
2571 : //
2572 : // bool spuckVecClosedFracManifElNoNeighbr( std::vector<MANIFEL> & vecClosFracManifEl )
2573 : // {
2574 : // vecClosFracManifEl = m_vecClosedFracManifElNoNeighbr;
2575 : //
2576 : // return (m_vecClosedFracManifElNoNeighbr.size() != 0 );
2577 : // }
2578 : //
2579 : // bool spuckEndingFractManifCutting( MANIFEL & endingFractManifCutting )
2580 : // {
2581 : // endingFractManifCutting = m_endingFractManifCutting;
2582 : // return true;
2583 : // }
2584 : //
2585 : // bool spuckEndingFractManifNotCutting( MANIFEL & efmnc )
2586 : // {
2587 : // efmnc = m_endingFractManifNotCutting;
2588 : // return true;
2589 : // }
2590 : //
2591 : // bool spuckOldLowDimElCut( LOWDIMEL & ldec )
2592 : // {
2593 : // ldec = m_oldLowDimElCut;
2594 : // return true;
2595 : // }
2596 : //
2597 : // bool spuckPairNeighbouredFractClosedManifEl( ManifelPair & neighFracClosME )
2598 : // {
2599 : // neighFracClosME = m_pairNeighbouredFractClosedManifEl;
2600 : // return true;
2601 : // }
2602 :
2603 : VRTXTYP const spuckUnclosedVrtx() const
2604 : {
2605 0 : return m_unclosedVrtx;
2606 : }
2607 :
2608 : std::vector<MANIFEL> const spuckVecClosedFracManifElNoNeighbr() const
2609 : {
2610 0 : return m_vecClosedFracManifElNoNeighbr;
2611 : }
2612 :
2613 : MANIFEL const spuckEndingFractManifCutting() const
2614 : {
2615 0 : return m_endingFractManifCutting;
2616 : }
2617 :
2618 : std::vector<MANIFEL> const spuckVecEndingFractManifNotCutting() const
2619 : {
2620 0 : return m_vecEndingFractManifNotCutting;
2621 : }
2622 :
2623 : LOWDIMEL const spuckOldLowDimElCut() const
2624 : {
2625 0 : return m_oldLowDimElCut;
2626 : }
2627 :
2628 : std::vector<LOWDIMEL> const spuckVecLowDimElmsOfNotCuttingManifs()
2629 : {
2630 : return m_vecLowDimElmsOfNotCuttingManifs;
2631 : }
2632 :
2633 : ManifelPair const spuckPairNeighbouredFractClosedManifEl() const
2634 : {
2635 0 : return m_pairNeighbouredFractClosedManifEl;
2636 : }
2637 :
2638 0 : INDEXTYP const spuckSudoFractEnding() const { return m_sudoFractEnding; }
2639 : INDEXTYP const spuckSudoFractNotEnding() const { return m_sudoFractNotEnding; }
2640 :
2641 : std::vector<FULLDIMEL> const spuckVecFulldimEl() const
2642 : {
2643 0 : return m_vecFulldimEl;
2644 : }
2645 :
2646 : // shift element edge
2647 :
2648 :
2649 : template< typename = std::enable_if< std::is_pointer<LOWDIMEL>::value>
2650 : >
2651 : LOWDIMEL const spuckLowdimElmShiftDirection() const
2652 : {
2653 0 : return m_shiftDirectionElm;
2654 : }
2655 :
2656 : bool schluckHiddenCutFractManifEl( MANIFEL const & manifel )
2657 : {
2658 0 : if( m_hiddenCutManifEl == nullptr && manifel != m_hiddenCutManifEl )
2659 : {
2660 0 : m_hiddenCutManifEl = manifel;
2661 : return true;
2662 : }
2663 :
2664 : return false;
2665 : }
2666 :
2667 : MANIFEL const spuckHiddenCutFractManifEl() const
2668 : {
2669 0 : return m_hiddenCutManifEl;
2670 : }
2671 :
2672 : private:
2673 :
2674 : bool m_isEndingCleft;
2675 :
2676 : // TODO FIXME vielleicht statt Manifel die Klasse, Attached Fracture Objekte? mit richtig geordneten Edges?
2677 :
2678 : VRTXTYP m_unclosedVrtx;
2679 : MANIFEL m_endingFractManifCutting;
2680 : // MANIFEL m_endingFractManifNotCutting;
2681 : std::vector<MANIFEL> m_vecEndingFractManifNotCutting;
2682 :
2683 : ManifelPair m_pairNeighbouredFractClosedManifEl;
2684 :
2685 : // NOTE here only those which do not have a common edge with the ending cleft!
2686 : std::vector<MANIFEL> m_vecClosedFracManifElNoNeighbr;
2687 :
2688 : LOWDIMEL m_oldLowDimElCut; // common edge between ending frac face with one sudo and durchgehende frac faces with another sudo
2689 : // LOWDIMEL m_newLowDimElCut;
2690 :
2691 : std::vector<LOWDIMEL> m_vecLowDimElmsOfNotCuttingManifs;
2692 :
2693 : LOWDIMEL m_shiftDirectionElm;
2694 :
2695 : INDEXTYP m_sudoFractEnding;
2696 : INDEXTYP m_sudoFractNotEnding;
2697 :
2698 : std::vector<FULLDIMEL> m_vecFulldimEl;
2699 :
2700 : VRTXTYP m_shiftVrtx;
2701 :
2702 : MANIFEL m_hiddenCutManifEl;
2703 :
2704 : template <typename ELEMTYP>
2705 0 : bool schluckElem( ELEMTYP const & anotherEl, std::vector<ELEMTYP> & vecElmKnown )
2706 : {
2707 : bool elemNotKnown = true;
2708 :
2709 0 : for( ELEMTYP me : vecElmKnown )
2710 : {
2711 0 : if( me == anotherEl )
2712 : {
2713 : elemNotKnown = false;
2714 : break;
2715 : }
2716 : }
2717 :
2718 0 : if( elemNotKnown )
2719 0 : vecElmKnown.push_back(anotherEl);
2720 :
2721 0 : return elemNotKnown;
2722 : }
2723 :
2724 : template <typename ELEMTYP>
2725 0 : bool schluckVecElem( std::vector<ELEMTYP> const & anotherVecEl, std::vector<ELEMTYP> & vecElmKnown )
2726 : {
2727 : bool someElemsUnknown = false;
2728 :
2729 0 : for( ELEMTYP me : anotherVecEl )
2730 : {
2731 0 : if( schluckElem( me, vecElmKnown ) )
2732 : {
2733 : someElemsUnknown = true;
2734 : }
2735 : }
2736 :
2737 0 : return someElemsUnknown;
2738 : }
2739 : };
2740 :
2741 : //////////////////////////////////////////////////////////////////////////
2742 :
2743 : }
2744 :
2745 : }
2746 :
2747 : }
2748 :
2749 : #endif /* UGCORE_UGBASE_LIB_GRID_ALGORITHMS_EXTRUSION_SUPPORT3D_H_ */
|