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