LCOV - code coverage report
Current view: top level - ugbase/lib_grid/algorithms/extrusion - ArteExpandFracs3D.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 1335 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 42 0

            Line data    Source code
       1              : /*
       2              :  * ArteExpandFracs3D.cpp
       3              :  *
       4              :  *  Created on: 06.10.2024
       5              :  *      Author: Markus M. Knodel
       6              :  *
       7              :  *  * expand fractures using the Arte algorithm, 3D case
       8              :  *
       9              :  * Author: Markus Knodel, inspired by Arte from Fuchs and Sebastian Reiters code for fracture expansion without Arte
      10              :  *
      11              :  * implementing a class that gives the basic tools for Arte in 3D
      12              :  * might be templated at a later stage to fulfill 2D and 3D purposes, if suitable
      13              :  * ( so far 2D case one entire function, not so perfect, but running....)
      14              :  *
      15              :  *
      16              :  * This file is part of UG4.
      17              :  *
      18              :  * UG4 is free software: you can redistribute it and/or modify it under the
      19              :  * terms of the GNU Lesser General Public License version 3 (as published by the
      20              :  * Free Software Foundation) with the following additional attribution
      21              :  * requirements (according to LGPL/GPL v3 §7):
      22              :  *
      23              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      24              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      25              :  *
      26              :  * (2) The following notice must be displayed at a prominent place in the
      27              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      28              :  *
      29              :  * (3) The following bibliography is recommended for citation and must be
      30              :  * preserved in all covered files:
      31              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      32              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      33              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      34              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      35              :  *   flexible software system for simulating pde based models on high performance
      36              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      37              :  *
      38              :  * This program is distributed in the hope that it will be useful,
      39              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      40              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      41              :  * GNU Lesser General Public License for more details.
      42              :  */
      43              : 
      44              : #include <boost/function.hpp>
      45              : 
      46              : #include "lib_grid/algorithms/geom_obj_util/geom_obj_util.h"
      47              : #include "lib_grid/callbacks/callbacks.h"
      48              : #include "lib_grid/grid/grid_util.h"
      49              : 
      50              : #include <stack>
      51              : #include <utility>
      52              : #include <vector>
      53              : #include <type_traits>
      54              : #include <limits>
      55              : #include <atomic>
      56              : #include <cstddef>
      57              : #include <bitset>
      58              : #include <string>
      59              : #include <cmath>
      60              : 
      61              : #include "support.h"
      62              : #include "support3D.h"
      63              : 
      64              : 
      65              : #include <lib_grid/algorithms/extrusion/ArteExpandFracs3D.h>
      66              : 
      67              : #include "simpleMatrixOps.h"
      68              : 
      69              : 
      70              : 
      71              : namespace ug
      72              : {
      73              : 
      74            0 : ArteExpandFracs3D::ArteExpandFracs3D(
      75              :                 Grid & grid, SubsetHandler & sh,
      76              :             std::vector<FractureInfo> const & fracInfos,
      77            0 :                 bool useTrianglesInDiamonds, bool establishDiamonds )
      78            0 :         : m_grid(grid),
      79            0 :           m_sh(sh),
      80            0 :           m_fracInfos(fracInfos),
      81            0 :           m_useTrianglesInDiamonds(useTrianglesInDiamonds),
      82            0 :           m_establishDiamonds(establishDiamonds),
      83              :           m_aaPos(Grid::VertexAttachmentAccessor<APosition>()),
      84              : //        m_facDescr(FaceDescriptor()),
      85              : //        m_volDescr(VolumeDescriptor()),
      86              :           m_fracInfosBySubset(std::vector<FractureInfo>()),
      87              :           //m_sel(Selector()),
      88              :           m_aAdjMarkerVFP(AttVertFracProp()),
      89              :           m_aaMarkVrtVFP( Grid::VertexAttachmentAccessor<AttVertFracProp>()),
      90              : //        m_aAdjMarkerVFP(AttVertFracProp()),
      91              :           m_aaMarkEdgeVFP(Grid::EdgeAttachmentAccessor<AttVertFracProp>()),
      92              :           m_aAdjMarkerFaceIsFracB(ABool()),
      93              :           m_aaMarkFaceIsFracB(Grid::FaceAttachmentAccessor<ABool>()),
      94              : //        m_aaMarkFaceHasUnclosedFracSideB(Grid::FaceAttachmentAccessor<ABool>()),
      95              : //        m_aAdjMarkerVrtxHasUnclosedFracB(ABool()),
      96              : //        m_aaMarkVrtxHasUnclosedFracB(Grid::VertexAttachmentAccessor<ABool>()),
      97              :           m_aAdjMarkerFaceWithEndingCrossingCleft(ABool()),
      98              :           m_aaMarkFaceWithEndingCrossingCleft(Grid::FaceAttachmentAccessor<ABool>()),
      99              :           m_aAdjMarkerVrtxAtEndingCrossingCleft(ABool()),
     100              :           m_aaMarkVrtxAtEndingCrossingCleft(Grid::VertexAttachmentAccessor<ABool>()),
     101              : //        m_aAdjMarkerVrtx2AtInnerEndOfEndingCrossingFract(ABool()),
     102              : //        m_aaMarkVrtx2AtInnerEndOfEndingCrossingFract(Grid::VertexAttachmentAccessor<ABool>()),
     103            0 :           m_needToSplitEdgesConnectingNeighbrdEndingCrossCleftVrtx(false),
     104              :           m_originalFractureFaces(std::vector<Face*>()),
     105              : //        m_attVrtVec(AttVrtVec()),
     106              : //        m_aaVrtVecVol( Grid::VolumeAttachmentAccessor<AttVrtVec>() ),
     107              :           m_aAdjInfoEdges(AttVecEdge()),
     108              :           m_aAdjInfoFaces(AttVecFace()),
     109              : //        m_aAdjInfoVols(AttVecVol()),
     110              :           m_aaVrtInfoAssoEdges( Grid::VertexAttachmentAccessor<AttVecEdge>()),
     111              :           m_aaVrtInfoAssoFaces( Grid::VertexAttachmentAccessor<AttVecFace>()),
     112              : //        m_aaVrtInfoAssoVols( Grid::VertexAttachmentAccessor<AttVecVol>()),
     113              : //        m_aAdjInfoAVVFT( AttVecVertFracTrip() ),
     114              : //        m_aaVrtInfoFraTri(Grid::VertexAttachmentAccessor<AttVecVertFracTrip>()),
     115              : //        m_vrtxFractrQuadrplVec(VrtxFractrQuadrplArte3DVec())
     116              :           m_attVrtVec(AttVrtVec()),
     117              :           m_aaVrtVecVol( Grid::VolumeAttachmentAccessor<AttVrtVec>() ),
     118              :           m_vecCrossVrtInf(std::vector<CrossVertInf>()),
     119              : //        m_aAdjVolElmInfo(AttVecAttachedVolumeElemInfo()),
     120              : //        m_aaVolElmInfo(Grid::VertexAttachmentAccessor<AttVecAttachedVolumeElemInfo>()),
     121              :           m_attAdjVecSegVolElmInfo( AttVecSegmentVolElmInfo() ),
     122              :           m_accsAttVecSegVolElmInfo( Grid::VertexAttachmentAccessor<AttVecSegmentVolElmInfo>() ),
     123              :           m_attVecSegmLimSid(AttVecSegmLimSid()),
     124              :           m_vrtxAttAccsVecSegmLimSid(Grid::VertexAttachmentAccessor<AttVecSegmLimSid>()),
     125              :           m_vecEdgeDirectConnectingEndingCrossCleftVrtcs( std::vector<Edge* >() ),
     126              :           m_vecEndCrossFractSegmInfo( VecEndingCrossingFractureSegmentInfo() ),
     127              : //        m_vecEndCrossFractSegmInfo(VecEndingCrossingFractureSegmentInfo()),
     128              :           m_attAtVrtxVecEndingCrossFractSegmInfo(AttVecEndingCrossingFractureSegmentInfo()),
     129              :           m_vrtxAttAccsVecEndingCrossFractSegmInfo(Grid::VertexAttachmentAccessor<AttVecEndingCrossingFractureSegmentInfo>()),
     130              : //        m_attAtVrtxIfVrtxIsEndingCrossingCleftVrtx(ABool()),
     131              : //        m_vrtxAttAccsVrtxIsEndingCrossingCleftVrtx(Grid::VertexAttachmentAccessor<ABool>()),
     132              :           m_attAtFaceIfFaceIsSegmLimFaceEndingCrossingCleft(ABool()),
     133              :           m_facAttAccsIfFaceIsSegmLimFaceEndingCrossingCleft(Grid::FaceAttachmentAccessor<ABool>()),
     134              :           m_attAtVolIfVolTouchesEndingCrossingCleft(ABool()),
     135              :           m_volAttAccsVolTouchesEndingCrossingCleft(Grid::VolumeAttachmentAccessor<ABool>()),
     136              :           m_attAtVrtxIfVrtxArisesFromExpandedEndingCrossingCleft(ABool()),
     137              :           m_vrtxAttAccsVrtxArisesFromExpandedEndingCrossingCleft(Grid::VertexAttachmentAccessor<ABool>()),
     138              :           m_vrtxArisesFromExpandedEndingCrossingCleft(std::vector<Vertex*>()),
     139            0 :           m_allowedSqueeze(0.9),
     140              :           m_vrtcsViolatingExpansion(std::vector<Vertex*>()),
     141            0 :           m_volsViolatingExpansion(std::vector<Volume*>())
     142              : {
     143              : //      // Notloesung, nicht in die erste Initialisierung vor geschweifter Klammer, da copy constructor privat
     144            0 :         m_sel = Selector();
     145            0 : }
     146              : 
     147              : 
     148            0 : ArteExpandFracs3D::~ArteExpandFracs3D()
     149              : {
     150              :         //  Auto-generated destructor stub
     151            0 : }
     152              : 
     153            0 : bool ArteExpandFracs3D::run( bool & needToRestart )
     154              : {
     155            0 :         needToRestart = false;
     156              : 
     157            0 :         if( ! initialize() )
     158              :                 return false;
     159              : 
     160              :         UG_LOG("initialisiert" << std::endl);
     161              : 
     162            0 :         if( ! setSelector() )
     163              :                 return false;
     164              : 
     165              :         UG_LOG("selektiert" << std::endl);
     166              : 
     167            0 :         if( ! attachMarkers() )
     168              :                 return false;
     169              : 
     170              :         UG_LOG("attached" << std::endl);
     171              : 
     172            0 :         int splittedEdges = splitInnerFreeFracEdgs();
     173              : 
     174            0 :         UG_LOG("splitted edges " << splittedEdges << std::endl);
     175              : //
     176              : //      return false;
     177              : //
     178              : //      UG_LOG("Splitted inner free frac edges" << splittedEdges << std::endl);
     179              : 
     180            0 :         if( ! countAndSelectFracBaseNums() )
     181              :                 return false;
     182              : 
     183              :         UG_LOG("gezaehlt" << std::endl);
     184              : 
     185              : //      constexpr bool assignFracInfosFirst = true;
     186              : //
     187              : //      if( assignFracInfosFirst )
     188              : //      {
     189            0 :         if( ! assignOrigFracInfos() )
     190              :                 return false;
     191              : 
     192              :         UG_LOG("assigniert zuerst " << std::endl);
     193              : 
     194            0 :         if( ! enableVolOptAutoGenFac() )
     195              :         {
     196              :                 UG_LOG("autogen war schon eingestellt" << std::endl);
     197              :         }
     198              :         else
     199              :         {
     200              :                 UG_LOG("Autogen einstellen" << std::endl);
     201              :         }
     202              :         // TODO FIXME für was gebraucht????
     203              : 
     204              : //      }
     205              : 
     206              : //      constexpr bool generVrtInfoFirst = true;
     207              : //
     208              : //      if( generVrtInfoFirst )
     209              : //      {
     210              : //      if( ! generateVertexInfos() )
     211              : //              return false;
     212              : //
     213              : //      UG_LOG("generiert zuerst " << std::endl);
     214              : 
     215              : //      }
     216              : 
     217              : //      if( ! prepareStasi() )
     218              : //              return false;
     219              : //
     220              : //      UG_LOG("Stasi vorbereitet " << std::endl);
     221              : 
     222            0 :         if( ! distinguishSegments() )
     223              :                 return false;
     224              : 
     225              :         UG_LOG("Segmente erzeugt " << std::endl);
     226              : 
     227              : 
     228              :         UG_LOG("check unclosed frac faces" << std::endl);
     229              : 
     230            0 :         if( ! establishSegmentLimitingSidesInfo() )
     231              :                 return false;
     232              : 
     233              :         UG_LOG("established Segment limiting sides info" << std::endl);
     234              : 
     235            0 :         if( ! detectEndingCrossingCleftsSegmBased() )
     236              :         {
     237            0 :                 if( m_needToSplitEdgesConnectingNeighbrdEndingCrossCleftVrtx )
     238              :                 {
     239            0 :                         needToRestart = true;
     240              :                         UG_LOG("Restart due to splitted edges" << std::endl);
     241              :                 }
     242              :                 else
     243              :                 {
     244            0 :                         needToRestart = false;
     245              :                         UG_LOG("No need to restart due to splitted edges" << std::endl);
     246              :                 }
     247              : 
     248            0 :                 return false;
     249              :         }
     250              : 
     251              :         UG_LOG("Ending crossing clefts detected" << std::endl);
     252              : 
     253            0 :         if( ! seletForSegmented() )
     254              :                 return false;
     255              : 
     256              :         UG_LOG("Closed Open Vertex Fract untersucht " << std::endl);
     257              : 
     258              : //      if( ! assignFracInfosFirst )
     259              : //      {
     260              : //              if( ! assignOrigFracInfos() )
     261              : //                      return false;
     262              : //
     263              : //              UG_LOG("assigniert danach " << std::endl);
     264              : //
     265              : //      }
     266              : 
     267              : 
     268            0 :         if( ! establishNewVrtBase() )
     269              :                 return false;
     270              : 
     271              :         UG_LOG("etabliert" << std::endl);
     272              : 
     273              : //      if( ! generVrtInfoFirst )
     274              : //      {
     275              : //
     276              : //              if( ! generateVertexInfos() )
     277              : //                      return false;
     278              : //
     279              : //              UG_LOG("generiert danach " << std::endl);
     280              : //      }
     281              : 
     282            0 :         if( ! createConditionForNewVrtcs() )
     283              :                 return false;
     284              : 
     285              :         UG_LOG("kreiert" << std::endl);
     286              : 
     287            0 :         if( ! loop2EstablishNewVertices() )
     288              :                 return false;
     289              : 
     290              :         UG_LOG("loopiert" << std::endl);
     291              : 
     292              :         UG_LOG("under construction " << std::endl);
     293              : 
     294            0 :         if( ! createNewElements() )
     295              :                 return false;
     296              : 
     297              :         UG_LOG("new elements created " << std::endl);
     298              : 
     299            0 :         if( ! detachMarkers() )
     300              :                 return false;
     301              : 
     302              :         UG_LOG("detachiert" << std::endl);
     303              : 
     304              : //      assignDebugSubsets( false );
     305              : 
     306              :         UG_LOG("Debug subsets assigned" << std::endl );
     307              : 
     308            0 :         IndexType numDelEndCrossCleftFacs = deleteEndingCrossingCleftOrigFacs();
     309              : 
     310              :         UG_LOG("deleted ending crossing cleft changed faces and direction edges " << numDelEndCrossCleftFacs << std::endl);
     311              : 
     312            0 :         return true;
     313              : }
     314              : 
     315              : ////////////////////////////////////////////////
     316              : 
     317            0 : bool ArteExpandFracs3D::splitEdgesOfNeighboredEndingCrossingFracVrtcs()
     318              : {
     319              : //      IndexType numberSplittedEdges = 0;
     320              : 
     321              :         // TODO FIXME vergleichen, was bei den debug Ecken alles an Randvertizes ist, und was bei
     322              :         // den hochstehenden Edges für Randvertizes sind, ob da was verloren gegangen ist
     323              :         // oder ob bei den modernen SegmentEnding Infos was fehlt an Vertizes.....
     324              :         // angefangen mit dem simplen Beispiel!
     325              :         // wenn das klappt, können die debug m_d_ Variablen entfernt werden.....
     326              : 
     327              :         UG_LOG("NUMBER EDGES DIRECT " << m_vecEdgeDirectConnectingEndingCrossCleftVrtcs.size() << std::endl );
     328              : 
     329              :         UG_LOG("NUMBER VERTICES FRAC SEGMENTS " << m_vecEndCrossFractSegmInfo.size() << std::endl );
     330              : 
     331            0 :         for( Edge * edg : m_vecEdgeDirectConnectingEndingCrossCleftVrtcs )
     332              :         {
     333              : 
     334            0 :                 UG_LOG("trying to split edge " << CalculateCenter( edg, m_aaPos ) << std::endl);
     335              : 
     336            0 :                 UG_LOG("E VERTEX ONE " << m_aaPos[ edg->vertex(0) ] << std::endl);
     337            0 :                 UG_LOG("E VERTEX TWO " << m_aaPos[ edg->vertex(1) ] << std::endl);
     338              : 
     339            0 :                 for( EndingCrossingFractureSegmentInfo const & ecfsiOne : m_vecEndCrossFractSegmInfo )
     340              :                 {
     341              :                         Vertex * vrtOne = ecfsiOne.spuckUnclosedVrtx();
     342              : 
     343            0 :                         UG_LOG("V ONE " << m_aaPos[vrtOne] << std::endl);
     344              : 
     345            0 :                         for( EndingCrossingFractureSegmentInfo const & ecfsiTwo : m_vecEndCrossFractSegmInfo )
     346              :                         {
     347              :                                 Vertex * vrtTwo = ecfsiTwo.spuckUnclosedVrtx();
     348              : 
     349            0 :                                 UG_LOG("V TWO " << m_aaPos[vrtTwo] << std::endl);
     350              : 
     351            0 :                                 if( vrtOne != vrtTwo )
     352              :                                 {
     353            0 :                                         if( EdgeContains(edg, vrtOne) && EdgeContains( edg, vrtTwo) )
     354              :                                         {
     355              :                                                 UG_LOG("Edge needs to be splitted" << std::endl);
     356              : 
     357            0 :                                                 int suse = m_sh.num_subsets();
     358              : 
     359            0 :                                                 m_sh.assign_subset( edg, suse );
     360              : 
     361              :                                                 UG_LOG("need to detach markers" << std::endl);
     362            0 :                                                 detachMarkers();
     363              : 
     364            0 :                                                 vector3 center = CalculateCenter(edg, m_aaPos);
     365            0 :                                                 UG_LOG("splitting ECCV edge at " << center << std::endl);
     366            0 :                                                 RegularVertex* vrtSE = SplitEdge<RegularVertex>(m_grid, edg, false);
     367              :                                                 m_aaPos[vrtSE] = center;
     368              : 
     369              :                                                 UG_LOG("Edge splitted, please restart process with the thus changed geometry" << std::endl);
     370              : 
     371              :                                                 return true;
     372              : 
     373              :                                         }
     374              : 
     375              :                                 }
     376              : 
     377              :                         }
     378              : 
     379              : 
     380              :                 }
     381              :         }
     382              : 
     383              :         return false;
     384              : 
     385              : //      if( numberSplittedEdges > 0 )
     386              : //              UG_LOG("Edge splitted, please restart process with the thus changed geometry, new edges " << numberSplittedEdges << std::endl);
     387              : //
     388              : //      return numberSplittedEdges;
     389              : 
     390              :         // TODO FIXME das ganze nochmal mit dem Debug Zeug
     391              : 
     392              : //      UG_LOG("DEBUG" << std::endl);
     393              : //
     394              : //      int suse = m_sh.num_subsets();
     395              : //
     396              : //      for( Edge * edg : m_d_allContributingEdges )
     397              : //      {
     398              : //              UG_LOG("E VERTEX ONE " << m_aaPos[ edg->vertex(0) ] << std::endl);
     399              : //              UG_LOG("E VERTEX TWO " << m_aaPos[ edg->vertex(1) ] << std::endl);
     400              : //
     401              : //              for( Vertex * vrtOne : m_d_endingCrossingCleftVrtcs )
     402              : //              {
     403              : //                      UG_LOG("V ONE " << m_aaPos[vrtOne] << std::endl);
     404              : //
     405              : //                      for( Vertex * vrtTwo : m_d_endingCrossingCleftVrtcs )
     406              : //                      {
     407              : //
     408              : //                              UG_LOG("V Two " << m_aaPos[vrtTwo] << std::endl);
     409              : //
     410              : //                              if( vrtOne != vrtTwo )
     411              : //                              {
     412              : //                                      if( EdgeContains(edg, vrtOne) && EdgeContains( edg, vrtTwo) )
     413              : //                                      {
     414              : //                                              UG_LOG("Edge needs to be splitted" << std::endl);
     415              : //
     416              : //                                              m_sh.assign_subset( edg, suse );
     417              : //
     418              : //                                              vector3 center = CalculateCenter(edg, m_aaPos);
     419              : //                                              UG_LOG("splitting ECCV edge at " << center << std::endl);
     420              : //                                              RegularVertex* vrtSE = SplitEdge<RegularVertex>(m_grid, edg, false);
     421              : //                                              m_aaPos[vrtSE] = center;
     422              : //
     423              : //                                              UG_LOG("Edge splitted, please restart process with the thus changed geometry" << std::endl);
     424              : //
     425              : //                                              return 1;
     426              : //
     427              : //                                      }
     428              : //                              }
     429              : //                      }
     430              : //
     431              : //              }
     432              : //      }
     433              : //
     434              : //      return 0;
     435              : //
     436              : //      return false;
     437              : 
     438              : }
     439              : 
     440              : ////////////////////////////////////////////////
     441              : 
     442            0 : void ArteExpandFracs3D::assignDebugSubsets( bool intermediate )
     443              : {
     444              : //      return;
     445              : 
     446              :         std::vector<Face*> d_endingCrossingCleftFaces;
     447              :         std::vector<Face*> d_endingCrossingCleftFacesNoCut;
     448              :         std::vector<Vertex*> d_endingCrossingCleftVrtcs;
     449              :         std::vector<Edge*> d_cuttingEdges;
     450              :         std::vector<Edge*> d_shiftEdges;
     451              :         std::vector<Face*> d_crossingNeighboredNotEndingFaces;
     452              :         std::vector<Face*> d_crossingNeighboredNotEndingFacesCommEdg;
     453              :         std::vector<Face*> d_notEndingCrossingFacesNotNeighbour;
     454              :         std::vector<Volume*> d_vols;
     455              :         std::vector<Vertex*> d_shiftVrtcs;
     456              : 
     457              :         UG_LOG("Number ending crossing clefts " << m_vecEndCrossFractSegmInfo.size()  << std::endl);
     458              : 
     459            0 :         for( EndingCrossingFractureSegmentInfo const & ecfsi : m_vecEndCrossFractSegmInfo )
     460              :         {
     461            0 :                 Vertex * vrt = ecfsi.spuckUnclosedVrtx();
     462              : 
     463            0 :                 d_endingCrossingCleftVrtcs.push_back(vrt);
     464              : 
     465              :                 std::vector<Face*> vecClosFracFacNoNeig = ecfsi.spuckVecClosedFracManifElNoNeighbr();
     466              : 
     467            0 :                 for( Face * fac : vecClosFracFacNoNeig )
     468              :                 {
     469            0 :                         d_crossingNeighboredNotEndingFaces.push_back(fac);
     470              :                 }
     471              : 
     472            0 :                 Face * endingFacCut = ecfsi.spuckEndingFractManifCutting();
     473              : 
     474            0 :                 d_endingCrossingCleftFaces.push_back(endingFacCut);
     475              : 
     476            0 :                 for( Face * endingFacNoCut : ecfsi.spuckVecEndingFractManifNotCutting() )
     477              :                 {
     478            0 :                         if( endingFacNoCut != nullptr )
     479              :                         {
     480            0 :                                 d_endingCrossingCleftFacesNoCut.push_back(endingFacNoCut);
     481              :                         }
     482            0 :                 }
     483              : 
     484            0 :                 Edge * cutEdge = ecfsi.spuckOldLowDimElCut();
     485              : 
     486            0 :                 d_cuttingEdges.push_back(cutEdge);
     487              : 
     488            0 :                 std::pair<Face*,Face*> const & neighrdFacsClos = ecfsi.spuckPairNeighbouredFractClosedManifEl();
     489              : 
     490            0 :                 d_crossingNeighboredNotEndingFacesCommEdg.push_back(neighrdFacsClos.first);
     491            0 :                 d_crossingNeighboredNotEndingFacesCommEdg.push_back(neighrdFacsClos.second);
     492              : 
     493              :                 std::vector<Volume*> vols = ecfsi.spuckVecFulldimEl();
     494              : 
     495            0 :                 for( Volume * v : vols )
     496              :                 {
     497            0 :                         d_vols.push_back(v);
     498              :                 }
     499              : 
     500            0 :                 Edge * shiftEdge = ecfsi.spuckLowdimElmShiftDirection();
     501            0 :                 d_shiftEdges.push_back(shiftEdge);
     502              : 
     503              : 
     504            0 :                 if( ! intermediate )
     505              :                 {
     506            0 :                         Vertex * shiVe = ecfsi.spuckShiftVrtx();
     507              : 
     508            0 :                         if( shiVe == nullptr )
     509              :                         {
     510            0 :                                 m_sh.assign_subset(vrt, m_sh.num_subsets());
     511            0 :                                 m_sh.assign_subset(shiftEdge, m_sh.num_subsets());
     512              : 
     513              :                                 UG_LOG("no shift vertex for ending crossing cleft segment " << std::endl);
     514            0 :                                 UG_THROW("no shift vertex for ending crossing cleft segment " << std::endl);
     515              : 
     516              :                         }
     517            0 :                         d_shiftVrtcs.push_back(shiVe);
     518              :                 }
     519              : 
     520              : 
     521              : 
     522            0 :         }
     523              : 
     524            0 :         int suse = m_sh.num_subsets();
     525              : 
     526            0 :         if( ! intermediate )
     527              :         {
     528              : 
     529            0 :                 for( Face * fac : d_endingCrossingCleftFaces )
     530              :                 {
     531            0 :                         if( fac != nullptr )
     532            0 :                                 m_sh.assign_subset( fac, suse );
     533              : 
     534              :                 }
     535              : 
     536            0 :                 suse = m_sh.num_subsets();
     537              : 
     538            0 :                 for( Face * fac : d_endingCrossingCleftFacesNoCut )
     539              :                 {
     540            0 :                         if( fac != nullptr )
     541            0 :                                 m_sh.assign_subset( fac, suse );
     542              : 
     543              :                 }
     544              : 
     545            0 :                 suse = m_sh.num_subsets();
     546              : 
     547            0 :                 for( Vertex * vrt : d_endingCrossingCleftVrtcs )
     548              :                 {
     549            0 :                         if( vrt != nullptr )
     550            0 :                                 m_sh.assign_subset( vrt, suse );
     551              :                 }
     552              : 
     553            0 :                 suse = m_sh.num_subsets();
     554              : 
     555            0 :                 for( Edge * edg : d_cuttingEdges )
     556              :                 {
     557            0 :                         if( edg == nullptr )
     558              :                         {
     559              :                                 UG_LOG("NULL UNERLAUBT" << std::endl);
     560            0 :                                 UG_THROW("NULL UNERLAUBT" << std::endl);
     561              :                         }
     562              : 
     563            0 :                         m_sh.assign_subset( edg, suse );
     564              : 
     565              :                 }
     566              : 
     567            0 :                 suse = m_sh.num_subsets();
     568              : 
     569            0 :                 for( Edge * edg : d_shiftEdges )
     570              :                 {
     571            0 :                         if( edg == nullptr )
     572              :                         {
     573              :                                 UG_LOG("NULL UNERLAUBT" << std::endl);
     574            0 :                                 UG_THROW("NULL UNERLAUBT" << std::endl);
     575              :                         }
     576              : 
     577            0 :                         m_sh.assign_subset( edg, suse );
     578              : 
     579              :                 }
     580              : 
     581              : 
     582            0 :                 suse = m_sh.num_subsets();
     583              : 
     584            0 :                 for( Face * fac : d_crossingNeighboredNotEndingFaces )
     585              :                 {
     586            0 :                         if( fac != nullptr )
     587            0 :                                 m_sh.assign_subset( fac, suse );
     588              :                 }
     589              : 
     590            0 :                 suse = m_sh.num_subsets();
     591              : 
     592            0 :                 for( Face * fac : d_notEndingCrossingFacesNotNeighbour )
     593              :                 {
     594            0 :                         m_sh.assign_subset( fac, suse );
     595              :                 }
     596              : 
     597            0 :                 suse = m_sh.num_subsets();
     598              : 
     599            0 :                 for( Face * fac : d_crossingNeighboredNotEndingFacesCommEdg )
     600              :                 {
     601            0 :                         m_sh.assign_subset( fac, suse );
     602              :                 }
     603              : 
     604            0 :                 suse = m_sh.num_subsets();
     605              : 
     606            0 :                 for( Vertex * vrtx : d_shiftVrtcs )
     607              :                 {
     608            0 :                         if( vrtx != nullptr )
     609            0 :                                 m_sh.assign_subset( vrtx, suse );
     610              :                 }
     611              : 
     612              : //      suse = m_sh.num_subsets();
     613              :         }
     614              :         else
     615              :         {
     616              : 
     617            0 :                 for( Volume * v : d_vols )
     618              :                 {
     619            0 :                         if( v != nullptr )
     620            0 :                                 m_sh.assign_subset( v, suse );
     621              :                 }
     622              :         }
     623              : 
     624            0 :         return;
     625              : 
     626              : #if 0
     627              : //      if( numEndingCrossingClefts == 0 )
     628              : //              return true;
     629              : 
     630              :         // debug for ending crossing clefts
     631              : 
     632              :         suse = m_sh.num_subsets();
     633              : 
     634              :         for( Face * fac : m_d_endingCrossingCleftFaces )
     635              :         {
     636              : //              m_sh.assign_subset( fac, m_sh.num_subsets());
     637              :                 m_sh.assign_subset( fac, suse );
     638              : 
     639              :         }
     640              : 
     641              :         suse = m_sh.num_subsets();
     642              : 
     643              :         for( Vertex * vrt : m_d_endingCrossingCleftVrtcs )
     644              :         {
     645              : //              m_sh.assign_subset( vrt, m_sh.num_subsets());
     646              :                 m_sh.assign_subset( vrt, suse );
     647              :         }
     648              : 
     649              :         suse = m_sh.num_subsets();
     650              : 
     651              :         for( Edge * edg : m_d_cuttingEdges )
     652              :         {
     653              :                 if( edg == nullptr )
     654              :                 {
     655              :                         UG_LOG("NULL UNERLAUBT" << std::endl);
     656              :                         UG_THROW("NULL UNERLAUBT" << std::endl);
     657              :                 }
     658              : 
     659              : //              m_sh.assign_subset( edg, m_sh.num_subsets());
     660              :                 m_sh.assign_subset( edg, suse );
     661              : 
     662              :         }
     663              : 
     664              :         suse = m_sh.num_subsets();
     665              : 
     666              :         for( Face * fac : m_d_crossingNeighboredNotEndingFaces )
     667              :         {
     668              : //              m_sh.assign_subset( fac, m_sh.num_subsets());
     669              :                 m_sh.assign_subset( fac, suse );
     670              :         }
     671              : 
     672              : //      for( Edge * edg : otherEdgeOfCrossingNotEndingFace )
     673              : //      {
     674              : //              if( edg == nullptr )
     675              : //              {
     676              : //                      UG_LOG("NULL C UNERLAUBT" << std::endl);
     677              : //                      UG_THROW("NULL C UNERLAUBT" << std::endl);
     678              : //              }
     679              : //
     680              : //              m_sh.assign_subset( edg, m_sh.num_subsets());
     681              : //
     682              : //      }
     683              :         suse = m_sh.num_subsets();
     684              : 
     685              :         for( Face * fac : m_d_notEndingCrossingFacesNotNeighbour )
     686              :         {
     687              : //              m_sh.assign_subset( fac, m_sh.num_subsets());
     688              :                 m_sh.assign_subset( fac, suse );
     689              :         }
     690              : 
     691              :         suse = m_sh.num_subsets();
     692              : 
     693              :         for( Face * fac : m_d_crossingNeighboredNotEndingFacesCommEdg )
     694              :         {
     695              : //              m_sh.assign_subset( fac, m_sh.num_subsets());
     696              :                 m_sh.assign_subset( fac, suse );
     697              :         }
     698              : 
     699              : //      suse = m_sh.num_subsets();
     700              : //
     701              : //      for( Edge * edg : m_d_allContributingEdges )
     702              : //      {
     703              : //              for( Vertex * vrtOne : m_d_endingCrossingCleftVrtcs )
     704              : //              {
     705              : //                      for( Vertex * vrtTwo : m_d_endingCrossingCleftVrtcs )
     706              : //                      {
     707              : //                              if( vrtOne != vrtTwo )
     708              : //                              {
     709              : //                                      if( EdgeContains(edg, vrtOne) && EdgeContains( edg, vrtTwo) )
     710              : //                                      {
     711              : //                                              UG_LOG("Edge needs to be splitted" << std::endl);
     712              : //
     713              : //                                              m_sh.assign_subset( edg, suse );
     714              : //
     715              : //
     716              : ////                                            vector3 center = CalculateCenter(edg, m_aaPos);
     717              : ////                                            UG_LOG("splitting ECCV edge at " << center << std::endl);
     718              : ////                                            RegularVertex* vrtSE = SplitEdge<RegularVertex>(m_grid, edg, false);
     719              : ////                                            m_aaPos[vrtSE] = center;
     720              : //
     721              : //                                      }
     722              : //                              }
     723              : //                      }
     724              : //
     725              : //              }
     726              : //      }
     727              : 
     728              : 
     729              :         return;
     730              : #endif
     731              : 
     732              : //      return false;
     733            0 : }
     734              : 
     735              : ////////////////////////////////////////////////
     736              : 
     737            0 : bool ArteExpandFracs3D::initialize()
     738              : {
     739              :         UG_LOG("initialize " << std::endl);
     740              : 
     741              :         //      access position attachment
     742            0 :         if(!m_grid.has_vertex_attachment(aPosition) )
     743              :         {
     744              :                 UG_LOG("Error in ExpandFractures Arte 3D: Missing position attachment");
     745            0 :                 return false;
     746              :         }
     747              : 
     748            0 :         m_aaPos = Grid::VertexAttachmentAccessor<APosition>(m_grid, aPosition);
     749              : 
     750              :         //      make sure that the required options are enabled.
     751              : 
     752            0 :         if( ! m_grid.option_is_enabled(VOLOPT_AUTOGENERATE_FACES) )
     753              :         {
     754              :                 UG_LOG("WARNING in Arte 3D init : grid option VOLOPT_AUTOGENERATE_FACES autoenabled.\n");
     755            0 :                 m_grid.enable_options(VOLOPT_AUTOGENERATE_FACES);
     756              :         }
     757              : 
     758            0 :         if( ! m_grid.option_is_enabled(FACEOPT_AUTOGENERATE_EDGES) )
     759              :         {
     760              :                 UG_LOG("WARNING in Arte 3D init: grid option FACEOPT_AUTOGENERATE_EDGES autoenabled.\n");
     761            0 :                 m_grid.enable_options(FACEOPT_AUTOGENERATE_EDGES);
     762              :         }
     763              : 
     764              :         //      vectors that allow to access fracture properties by subset index
     765            0 :         m_fracInfosBySubset = std::vector<FractureInfo>( m_sh.num_subsets(), FractureInfo(-1, -1, 0) );
     766              : 
     767            0 :         for( size_t i = 0; i < m_fracInfos.size(); ++i)
     768              :         {
     769            0 :                 if( m_fracInfos[i].subsetIndex >= m_sh.num_subsets())
     770              :                 {
     771            0 :                         throw(UGError("Bad subsetIndex in given fracInfos."));
     772              :                 }
     773              : 
     774            0 :                 m_fracInfosBySubset[ m_fracInfos[i].subsetIndex] = m_fracInfos[i];
     775              : 
     776              :         }
     777              : 
     778              : 
     779              :         return true;
     780              : }
     781              : 
     782              : 
     783            0 : bool ArteExpandFracs3D::setSelector()
     784              : {
     785              :         //      Collect surrounding volumes, faces and edges of all fractures in a selector
     786              :         //      and select fracture faces, edges and vertices too.
     787              : 
     788              : //      m_sel = Selector(m_grid);
     789              : 
     790            0 :         m_sel.assign_grid(m_grid);
     791              : 
     792            0 :         m_sel.enable_autoselection(false);
     793            0 :         m_sel.enable_selection_inheritance(true);       //required for select and mark, disabled later
     794            0 :         m_sel.enable_strict_inheritance(false);
     795              : 
     796              : //      bool strictInherit = m_sel.strict_inheritance_enabled();
     797              : //
     798              : //      UG_LOG("strikte Inheritenz ist " << strictInherit << " und false ist " << false << std::endl);
     799              : 
     800            0 :         return true;
     801              : }
     802              : 
     803              : 
     804            0 : bool ArteExpandFracs3D::attachMarkers()
     805              : {
     806              :         // first part
     807              : 
     808              :         // attachment pair boundary is fracture, number fractures crossing
     809              : 
     810              :         m_aAdjMarkerVFP = AttVertFracProp();
     811              : 
     812              : //      support::VertexFracturePropertiesVol<IndexType> vfp0; // false, 0 );
     813              :         VertxFracPropts vfp0; // false, 0 );
     814              :         // default value: no boundary fracture, no fractures crossing
     815              : 
     816            0 :         m_grid.attach_to_vertices_dv( m_aAdjMarkerVFP, vfp0 );
     817            0 :         m_aaMarkVrtVFP = Grid::VertexAttachmentAccessor<AttVertFracProp> ( m_grid, m_aAdjMarkerVFP );
     818              : 
     819              :         //m_aAdjMarkerVFP = AttVertFracProp();
     820              :         m_grid.attach_to_edges_dv( m_aAdjMarkerVFP, vfp0 );
     821              : 
     822            0 :         m_aaMarkEdgeVFP = Grid::EdgeAttachmentAccessor<AttVertFracProp>( m_grid, m_aAdjMarkerVFP );
     823              : 
     824              :         m_aAdjMarkerFaceIsFracB = ABool(); // used to know if an face is frac face
     825              : 
     826            0 :         m_grid.attach_to_faces_dv( m_aAdjMarkerFaceIsFracB, false );
     827            0 :         m_aaMarkFaceIsFracB = Grid::FaceAttachmentAccessor<ABool>( m_grid, m_aAdjMarkerFaceIsFracB );
     828              : 
     829              : //      m_aAdjMarkerFaceHasUnclosedFracSideB = ABool();
     830              : //
     831              : //      m_grid.attach_to_faces_dv( m_aAdjMarkerFaceHasUnclosedFracSideB, false );
     832              : //      m_aaMarkFaceHasUnclosedFracSideB = Grid::FaceAttachmentAccessor<ABool>( m_grid, m_aAdjMarkerFaceHasUnclosedFracSideB );
     833              : //
     834              : //      m_aAdjMarkerVrtxHasUnclosedFracB = ABool();
     835              : //
     836              : //      m_grid.attach_to_vertices_dv( m_aAdjMarkerVrtxHasUnclosedFracB, false );
     837              : //      m_aaMarkVrtxHasUnclosedFracB = Grid::VertexAttachmentAccessor<ABool>( m_grid, m_aAdjMarkerVrtxHasUnclosedFracB );
     838              : //
     839              :         m_aAdjMarkerFaceWithEndingCrossingCleft = ABool();
     840              : 
     841            0 :         m_grid.attach_to_faces_dv( m_aAdjMarkerFaceWithEndingCrossingCleft, false );
     842              : 
     843            0 :         m_aaMarkFaceWithEndingCrossingCleft = Grid::FaceAttachmentAccessor<ABool>( m_grid, m_aAdjMarkerFaceWithEndingCrossingCleft );
     844              : 
     845              :         m_aAdjMarkerVrtxAtEndingCrossingCleft = ABool();
     846              : 
     847            0 :         m_grid.attach_to_vertices_dv( m_aAdjMarkerVrtxAtEndingCrossingCleft, false );
     848              : 
     849            0 :         m_aaMarkVrtxAtEndingCrossingCleft = Grid::VertexAttachmentAccessor<ABool>( m_grid, m_aAdjMarkerVrtxAtEndingCrossingCleft );
     850              : //
     851              : //      m_aAdjMarkerVrtx2AtInnerEndOfEndingCrossingFract = ABool();
     852              : //
     853              : //      m_grid.attach_to_vertices_dv( m_aAdjMarkerVrtx2AtInnerEndOfEndingCrossingFract, false );
     854              : //
     855              : //      m_aaMarkVrtx2AtInnerEndOfEndingCrossingFract = Grid::VertexAttachmentAccessor<ABool>( m_grid, m_aAdjMarkerVrtx2AtInnerEndOfEndingCrossingFract );
     856              : 
     857              :         // second part
     858              : 
     859              : //      m_grid.attach_to_volumes(m_attVrtVec);
     860              : //      m_aaVrtVecVol = Grid::VolumeAttachmentAccessor<AttVrtVec>( m_grid, m_attVrtVec);
     861              : 
     862              :         std::vector<Edge*> noEdge;
     863              :         std::vector<Face*> noFace;
     864              : //      std::vector<Volume*> noVol;
     865              : 
     866              :         m_aAdjInfoEdges = AttVecEdge();
     867              :         m_aAdjInfoFaces = AttVecFace();
     868              : //      m_aAdjInfoVols = AttVecVol();
     869              : 
     870            0 :         m_grid.attach_to_vertices_dv( m_aAdjInfoEdges, noEdge );
     871            0 :         m_aaVrtInfoAssoEdges = Grid::VertexAttachmentAccessor<AttVecEdge>( m_grid, m_aAdjInfoEdges );
     872              : 
     873            0 :         m_grid.attach_to_vertices_dv( m_aAdjInfoFaces, noFace );
     874            0 :         m_aaVrtInfoAssoFaces = Grid::VertexAttachmentAccessor<AttVecFace>( m_grid, m_aAdjInfoFaces );
     875              : 
     876              : //      m_grid.attach_to_vertices_dv( m_aAdjInfoVols, noVol );
     877              : //      m_aaVrtInfoAssoVols = Grid::VertexAttachmentAccessor<AttVecVol>( m_grid, m_aAdjInfoVols );
     878              : 
     879              : 
     880              :         //  TODO FIXME
     881              :         //  das fehlt hier , Analogon 2D Fall!!!!!!!!!!!!! der geht hier eigentlich weiter
     882              :         // die Vertizes, Faces und Edges, die mit einer Kluft zu tun haben
     883              :         //      using VertFracTrip = VertexFractureTriple<Edge*, Face*, vector3>;
     884              :         //      using VecVertFracTrip = std::vector<VertFracTrip>;
     885              :         //      VecVertFracTrip vertexNoInfo;
     886              : 
     887              :         // AttVecVertFracTrip m_aAdjInfoAVVFT;
     888              : 
     889              : //      VecVertFracTrip vertexNoInfo;
     890              : //
     891              : //      m_aAdjInfoAVVFT = AttVecVertFracTrip();
     892              : //
     893              : //      m_grid.attach_to_vertices_dv( m_aAdjInfoAVVFT, vertexNoInfo );
     894              : //
     895              : //      m_aaVrtInfoFraTri = Grid::VertexAttachmentAccessor<AttVecVertFracTrip>(m_grid,  m_aAdjInfoAVVFT );
     896              : 
     897              : 
     898              :         //      associate a vector of vertices for each volume adjacent to the frac.
     899              :         //      An entry later will contain the new vertex, if the
     900              :         //      corresponding vertex is an inner fracture vertex, and nullptr if not.
     901              : 
     902              :         m_attVrtVec = AttVrtVec();
     903              : 
     904            0 :         m_grid.attach_to_volumes(m_attVrtVec);
     905              : 
     906            0 :         m_aaVrtVecVol = Grid::VolumeAttachmentAccessor<AttVrtVec>(m_grid, m_attVrtVec);
     907              : 
     908              : 
     909              : //      VecAttachedVolumeElemInfo noVolInfo;
     910              : 
     911              : //      m_aAdjVolElmInfo = AttVecAttachedVolumeElemInfo();
     912              : //
     913              : //      m_grid.attach_to_vertices_dv(m_aAdjVolElmInfo,noVolInfo);
     914              : //
     915              : //      m_aaVolElmInfo = Grid::VertexAttachmentAccessor<AttVecAttachedVolumeElemInfo>(m_grid, m_aAdjVolElmInfo);
     916              : 
     917              : 
     918              :         VecSegmentVolElmInfo noSegmts;
     919              : 
     920              :         m_attAdjVecSegVolElmInfo = AttVecSegmentVolElmInfo();
     921              : 
     922            0 :         m_grid.attach_to_vertices_dv( m_attAdjVecSegVolElmInfo, noSegmts );
     923              : 
     924            0 :         m_accsAttVecSegVolElmInfo = Grid::VertexAttachmentAccessor<AttVecSegmentVolElmInfo>( m_grid, m_attAdjVecSegVolElmInfo );
     925              : 
     926              :         VecSegmentLimitingSides emptyVecSegmLimSid;
     927              : 
     928              :         AttVecSegmLimSid m_attVecSegmLimSid;
     929              : 
     930              :         m_grid.attach_to_vertices_dv( m_attVecSegmLimSid, emptyVecSegmLimSid );
     931              : 
     932            0 :         m_vrtxAttAccsVecSegmLimSid = Grid::VertexAttachmentAccessor<AttVecSegmLimSid>( m_grid, m_attVecSegmLimSid );
     933              : 
     934              :         VecEndingCrossingFractureSegmentInfo emptyVECFSI;
     935              : 
     936              :         m_attAtVrtxVecEndingCrossFractSegmInfo = AttVecEndingCrossingFractureSegmentInfo();
     937              : 
     938            0 :         m_grid.attach_to_vertices_dv( m_attAtVrtxVecEndingCrossFractSegmInfo, emptyVECFSI );
     939              : 
     940            0 :         m_vrtxAttAccsVecEndingCrossFractSegmInfo = Grid::VertexAttachmentAccessor<AttVecEndingCrossingFractureSegmentInfo>( m_grid, m_attAtVrtxVecEndingCrossFractSegmInfo );
     941              : 
     942              : //      m_attAtVrtxIfVrtxIsEndingCrossingCleftVrtx = ABool();
     943              : //
     944              : //      m_grid.attach_to_vertices_dv( m_attAtVrtxIfVrtxIsEndingCrossingCleftVrtx, false );
     945              : //
     946              : //      m_vrtxAttAccsVrtxIsEndingCrossingCleftVrtx = Grid::VertexAttachmentAccessor<ABool>( m_grid, m_attAtVrtxIfVrtxIsEndingCrossingCleftVrtx );
     947              : 
     948              :         m_attAtFaceIfFaceIsSegmLimFaceEndingCrossingCleft = ABool();
     949              : 
     950            0 :         m_grid.attach_to_faces_dv( m_attAtFaceIfFaceIsSegmLimFaceEndingCrossingCleft, false );
     951              : 
     952            0 :         m_facAttAccsIfFaceIsSegmLimFaceEndingCrossingCleft = Grid::FaceAttachmentAccessor<ABool>( m_grid, m_attAtFaceIfFaceIsSegmLimFaceEndingCrossingCleft );
     953              : 
     954              :         m_attAtVolIfVolTouchesEndingCrossingCleft = ABool();
     955              : 
     956            0 :         m_grid.attach_to_volumes_dv( m_attAtVolIfVolTouchesEndingCrossingCleft, false );
     957              : 
     958            0 :         m_volAttAccsVolTouchesEndingCrossingCleft = Grid::VolumeAttachmentAccessor<ABool>( m_grid, m_attAtVolIfVolTouchesEndingCrossingCleft );
     959              : 
     960              :         m_attAtVrtxIfVrtxArisesFromExpandedEndingCrossingCleft = ABool();
     961              : 
     962            0 :         m_grid.attach_to_vertices_dv( m_attAtVrtxIfVrtxArisesFromExpandedEndingCrossingCleft, false );
     963              : 
     964            0 :         m_vrtxAttAccsVrtxArisesFromExpandedEndingCrossingCleft = Grid::VertexAttachmentAccessor<ABool>( m_grid, m_attAtVrtxIfVrtxArisesFromExpandedEndingCrossingCleft );
     965              : 
     966            0 :         return true;
     967            0 : }
     968              : 
     969              : 
     970            0 : bool ArteExpandFracs3D::detachMarkers()
     971              : {
     972            0 :         m_grid.detach_from_vertices( m_aAdjMarkerVFP );
     973            0 :         m_grid.detach_from_edges( m_aAdjMarkerVFP );
     974            0 :         m_grid.detach_from_faces( m_aAdjMarkerFaceIsFracB );
     975              : //      m_grid.detach_from_faces( m_aAdjMarkerFaceHasUnclosedFracSideB );
     976              : //
     977              : //      m_grid.detach_from_vertices( m_aAdjMarkerVrtxHasUnclosedFracB );
     978              : //
     979            0 :         m_grid.detach_from_faces( m_aAdjMarkerFaceWithEndingCrossingCleft );
     980            0 :         m_grid.detach_from_vertices( m_aAdjMarkerVrtxAtEndingCrossingCleft );
     981              : //      m_grid.detach_from_vertices( m_aAdjMarkerVrtx2AtInnerEndOfEndingCrossingFract );
     982              : 
     983            0 :         m_grid.detach_from_vertices( m_aAdjInfoEdges );
     984            0 :         m_grid.detach_from_vertices( m_aAdjInfoFaces );
     985              : //      m_grid.detach_from_vertices( m_aAdjInfoVols );
     986              : 
     987              : //      m_grid.detach_from_vertices( m_aAdjInfoAVVFT  );
     988              : 
     989            0 :         m_grid.detach_from_volumes( m_attVrtVec );
     990              : 
     991              : //      m_grid.detach_from_vertices(m_aAdjVolElmInfo);
     992              : 
     993            0 :         m_grid.detach_from_vertices( m_attAdjVecSegVolElmInfo );
     994              : 
     995            0 :         m_grid.detach_from_vertices( m_attVecSegmLimSid );
     996              : 
     997            0 :         m_grid.detach_from_vertices( m_attAtVrtxVecEndingCrossFractSegmInfo );
     998              : 
     999              : //      m_grid.detach_from_vertices( m_attAtVrtxIfVrtxIsEndingCrossingCleftVrtx );
    1000              : 
    1001            0 :         m_grid.detach_from_faces( m_attAtFaceIfFaceIsSegmLimFaceEndingCrossingCleft );
    1002              : 
    1003            0 :         m_grid.detach_from_volumes( m_attAtVolIfVolTouchesEndingCrossingCleft );
    1004              : 
    1005            0 :         m_grid.detach_from_vertices( m_attAtVrtxIfVrtxArisesFromExpandedEndingCrossingCleft );
    1006              : 
    1007            0 :         return true;
    1008              : }
    1009              : 
    1010            0 : bool ArteExpandFracs3D::enableVolOptAutoGenFac()
    1011              : {
    1012              :         // brauchen wir das? für was? von SR irgendwie übernommen, wo dort was entfernt ähnliches gemacht wird....
    1013            0 :         if(! m_grid.option_is_enabled(VOLOPT_AUTOGENERATE_FACES) )
    1014              :         {
    1015              :                 UG_LOG("WARNING grid option VOLOPT_AUTOGENERATE_FACES autoenabled.\n");
    1016            0 :                 m_grid.enable_options(VOLOPT_AUTOGENERATE_FACES);
    1017            0 :                 return true;
    1018              :         }
    1019              : 
    1020              :         return false;
    1021              : 
    1022              : }
    1023              : 
    1024              : //////////////////////////////////////////////////////////////////
    1025              : 
    1026            0 : int ArteExpandFracs3D::splitInnerFreeFracEdgs()
    1027              : {
    1028              :         int splittedEdges = 0;
    1029              : 
    1030            0 :         for(size_t i_fi = 0; i_fi < m_fracInfos.size(); ++i_fi )
    1031              :         {
    1032            0 :                 int fracIndSudo = m_fracInfos[i_fi].subsetIndex;
    1033              : 
    1034            0 :                 UG_LOG("sudo ind " << fracIndSudo << std::endl);
    1035              : 
    1036              :                 AttVertFracProp func_aAdjMarkerVFP;
    1037              :                 VertxFracPropts vfp0;
    1038            0 :                 m_grid.attach_to_edges_dv( func_aAdjMarkerVFP, vfp0 );
    1039            0 :                 Grid::EdgeAttachmentAccessor<AttVertFracProp> func_aaMarkEdgeVFP( m_grid, func_aAdjMarkerVFP );
    1040              : 
    1041            0 :                 for( FaceIterator iter = m_sh.begin<Face>(fracIndSudo); iter != m_sh.end<Face>(fracIndSudo); ++iter )
    1042              :                 {
    1043              :                         Face* fac = *iter;
    1044              : 
    1045              :                         std::vector<Edge*> facEdges;
    1046              : 
    1047            0 :                         CollectEdges( facEdges, m_grid, fac );
    1048              : 
    1049            0 :                         for( auto const & edg : facEdges )
    1050              :                         {
    1051            0 :                                 if( func_aaMarkEdgeVFP[edg].getNumberFracEdgesInVertex() != 0 )
    1052            0 :                                         UG_THROW("Attachment nicht auf default " << std::endl);
    1053              : //                              func_aaMarkEdgeVFP[edg].setNumberCrossingFracsInVertex(0);
    1054              :                         }
    1055            0 :                 }
    1056              : 
    1057              : 
    1058            0 :                 for( FaceIterator iter = m_sh.begin<Face>(fracIndSudo); iter != m_sh.end<Face>(fracIndSudo); ++iter )
    1059              :                 {
    1060              :                         Face* fac = *iter;
    1061              : 
    1062              :                         std::vector<Edge*> facEdges;
    1063              : 
    1064            0 :                         CollectEdges( facEdges, m_grid, fac );
    1065              : 
    1066            0 :                         for( auto const & edg : facEdges )
    1067              :                         {
    1068            0 :                                 func_aaMarkEdgeVFP[edg]++;
    1069              :                         }
    1070            0 :                 }
    1071              : 
    1072              :                 std::vector<Edge *> edgesToBeSplitted;
    1073              : 
    1074            0 :                 for( FaceIterator iter = m_sh.begin<Face>(fracIndSudo); iter != m_sh.end<Face>(fracIndSudo); ++iter )
    1075              :                 {
    1076              :                         Face* fac = *iter;
    1077              : 
    1078              :                         std::vector<Edge*> facEdges;
    1079              : 
    1080            0 :                         CollectEdges( facEdges, m_grid, fac );
    1081              : 
    1082              :                         IndexType openEdges = 0;
    1083              : 
    1084            0 :                         for( auto const & edg : facEdges )
    1085              :                         {
    1086            0 :                                 VertxFracPropts & edgeFracPrps = func_aaMarkEdgeVFP[edg];
    1087              : 
    1088              :                                 IndexType fracEdgesOverlap = edgeFracPrps.getNumberFracEdgesInVertex();
    1089              : 
    1090            0 :                                 if( fracEdgesOverlap == 1 )
    1091              :                                 {
    1092            0 :                                         openEdges++;
    1093              :                                 }
    1094            0 :                                 else if( fracEdgesOverlap == 2 )
    1095              :                                 {
    1096              :                                         ; // fine, inner edge of fracture
    1097              :                                 }
    1098              :                                 else
    1099              :                                 {
    1100            0 :                                         m_sh.assign_subset(edg, m_sh.num_subsets());
    1101              : 
    1102              :                                         UG_LOG("how many fractures at this edge " << fracEdgesOverlap << std::endl);
    1103            0 :                                         UG_LOG("sudo " << fracIndSudo << std::endl);
    1104            0 :                                         UG_THROW("how many fractures at this edge " << fracEdgesOverlap << std::endl);
    1105              :                                         UG_THROW("sudo " << fracIndSudo << std::endl);
    1106              : //                                      return splittedEdges;
    1107              : //                                      UG_THROW("how many fractures at this edge " << fracEdgesOverlap << std::endl);
    1108              :                                 }
    1109              :                         }
    1110              : 
    1111            0 :                         if( openEdges == 2 )
    1112              :                         {
    1113              :                                 // figure out that edge that is not open, this must be splitted
    1114              : 
    1115              :                                 IndexType innerEdges = 0;
    1116              : 
    1117            0 :                                 for( auto const & edg : facEdges )
    1118              :                                 {
    1119            0 :                                         VertxFracPropts & edgeFracPrps = func_aaMarkEdgeVFP[edg];
    1120              : 
    1121              :                                         IndexType fracEdgesOverlap = edgeFracPrps.getNumberFracEdgesInVertex();
    1122              : 
    1123            0 :                                         if( fracEdgesOverlap == 2 )
    1124              :                                         {
    1125            0 :                                                 edgesToBeSplitted.push_back(edg);
    1126            0 :                                                 innerEdges++;
    1127              :                                         }
    1128              :                                 }
    1129              : 
    1130            0 :                                 if( innerEdges != 1 )
    1131              :                                 {
    1132              :                                         UG_LOG("inner edge number strange " << innerEdges << std::endl);
    1133            0 :                                         UG_THROW("inner edge number strange " << innerEdges << std::endl);
    1134              :                                 }
    1135              : 
    1136              : 
    1137              :                         }
    1138            0 :                 }
    1139              : 
    1140            0 :                 for( Edge * edg : edgesToBeSplitted )
    1141              :                 {
    1142            0 :                         vector3 center = CalculateCenter(edg, m_aaPos);
    1143            0 :                         UG_LOG("splitting edge at " << center << std::endl);
    1144            0 :                         RegularVertex* vrt = SplitEdge<RegularVertex>(m_grid, edg, false);
    1145              :                         m_aaPos[vrt] = center;
    1146            0 :                         splittedEdges++;
    1147              :                 }
    1148              : 
    1149            0 :                 m_grid.detach_from_edges( func_aAdjMarkerVFP );
    1150            0 :         }
    1151              : 
    1152            0 :         return splittedEdges;
    1153              : }
    1154              : 
    1155              : #if 0
    1156              : int ArteExpandFracs3D::splitInnerFreeFracEdgs()
    1157              : {
    1158              :         int splittedEdges = 0;
    1159              : 
    1160              :         UG_LOG("search inner frac edges with two inner boundary edges" << std::endl);
    1161              : 
    1162              :         // TODO FIXME
    1163              : 
    1164              : 
    1165              :         for(size_t i_fi = 0; i_fi < m_fracInfos.size(); ++i_fi )
    1166              :         {
    1167              :                 int fracIndSudo = m_fracInfos[i_fi].subsetIndex;
    1168              : 
    1169              :                 UG_LOG("sudo ind " << fracIndSudo << std::endl);
    1170              : 
    1171              : //              std::vector<Edge *> edgesToBeSplitted;
    1172              : 
    1173              :                 std::vector<Face*> facesAtInnerBoundary;
    1174              : 
    1175              :                 for( FaceIterator iter = m_sh.begin<Face>(fracIndSudo); iter != m_sh.end<Face>(fracIndSudo); ++iter )
    1176              :                 {
    1177              :                         Face* fac = *iter;
    1178              : 
    1179              : //                      std::vector<Vertex*> assoVrt;
    1180              : //
    1181              : //                      CollectVertices( assoVrt, m_grid, fac );
    1182              : //
    1183              : //                      // check number of edges which have only one fracture face around
    1184              : //
    1185              : //                      for( Vertex * vrt : assoVrt )
    1186              : //                      {
    1187              :                         std::vector<Edge*> assoEdg;
    1188              : 
    1189              :                         CollectEdges( assoEdg, m_grid, fac );
    1190              : 
    1191              :                         for( Edge * edg : assoEdg )
    1192              :                         {
    1193              :                                 // check if edge is inner boundary edge, i.e. if has at one side non-fracture face
    1194              :                                 // only check for those edges which have one fracture face on one side
    1195              : 
    1196              :                                 // split only inner edges at the moment in case of problems
    1197              :                                 if( IsBoundaryEdge3D(m_grid, edg) )
    1198              :                                 {
    1199              :                                         continue;
    1200              :                                 }
    1201              : 
    1202              :                                 std::vector<Face *> assoFac;
    1203              : 
    1204              :                                 CollectFaces( assoFac, m_grid, edg );
    1205              : 
    1206              :                                 IndexType numFacsFromFracSudo = 0;
    1207              : 
    1208              :                                 for( Face * testFac : assoFac )
    1209              :                                 {
    1210              :                                         IndexType testSudo = m_sh.get_subset_index(testFac);
    1211              : 
    1212              :                                         if( testSudo == fracIndSudo )
    1213              :                                                 numFacsFromFracSudo++;
    1214              :                                 }
    1215              : 
    1216              :                                 if( numFacsFromFracSudo == 0 )
    1217              :                                 {
    1218              : //                                      UG_LOG("no facs at edg " << std::endl );
    1219              :                                                 ; // nothing to do, belongs from an edge not relevant for the fracture
    1220              :                                 }
    1221              :                                 else if( numFacsFromFracSudo == 1 )
    1222              :                                 {
    1223              :                                         // relevant! edge needs to be split
    1224              : 
    1225              : //                                      UG_LOG("one fac at edg" << std::endl);
    1226              : 
    1227              :                                         addElem( facesAtInnerBoundary, fac );
    1228              :                                 }
    1229              :                                 else if( numFacsFromFracSudo == 2 )
    1230              :                                 {
    1231              : //                                              UG_LOG("two fac sides at edge " << std::endl);
    1232              :                                                 ; // nothing to do, edge at both sides surrounded by fracture face
    1233              :                                 }
    1234              :                                 else
    1235              :                                 {
    1236              :                                         UG_LOG("komische Ecke" << std::endl);
    1237              :                                         UG_THROW("komische Ecke" << std::endl);
    1238              :                                 }
    1239              :                         }
    1240              : 
    1241              :                 }
    1242              : 
    1243              :                 std::vector<Edge *> edgesToBeSplitted;
    1244              : 
    1245              :                 for( Face * fac : facesAtInnerBoundary )
    1246              :                 {
    1247              :                         std::vector<Vertex *> assoVrt;
    1248              : 
    1249              :                         CollectVertices(assoVrt, m_grid, fac);
    1250              : 
    1251              :                         // check if at a vertex of a frac face is associated with two inner boundary edges
    1252              : 
    1253              :                         for( Vertex * vrt : assoVrt )
    1254              :                         {
    1255              :                                 std::vector<Edge*> assoEdg;
    1256              : 
    1257              :                                 CollectEdges( assoEdg, m_grid, vrt );
    1258              : 
    1259              :                                 IndexType innerBoundaryEdges = 0;
    1260              : 
    1261              :                                 // count number of edges of the vertex which have one free side
    1262              : 
    1263              :                                 for( Edge * edg : assoEdg )
    1264              :                                 {
    1265              :                                         // check if edge is inner boundary edge, i.e. if has at one side non-fracture face
    1266              :                                         // only check for those edges which have one fracture face on one side
    1267              : 
    1268              :                                         // split only inner edges at the moment in case of problems
    1269              :                                         if( IsBoundaryEdge3D(m_grid, edg) )
    1270              :                                         {
    1271              :                                                 continue;
    1272              :                                         }
    1273              : 
    1274              :                                         std::vector<Face *> assoFac;
    1275              : 
    1276              :                                         CollectFaces( assoFac, m_grid, edg );
    1277              : 
    1278              :                                         IndexType numFacsFromFracSudo = 0;
    1279              : 
    1280              :                                         for( Face * testFac : assoFac )
    1281              :                                         {
    1282              :                                                 IndexType testSudo = m_sh.get_subset_index(testFac);
    1283              : 
    1284              :                                                 if( testSudo == fracIndSudo )
    1285              :                                                         numFacsFromFracSudo++;
    1286              :                                         }
    1287              : 
    1288              :                                         if( numFacsFromFracSudo == 0 )
    1289              :                                         {
    1290              : //                                              UG_LOG("no facs at edg " << std::endl );
    1291              :                                                 ; // nothing to do, belongs from an edge not relevant for the fracture
    1292              :                                         }
    1293              :                                         else if( numFacsFromFracSudo == 1 )
    1294              :                                         {
    1295              :                                                 // relevant! edge needs to be split
    1296              : 
    1297              : //                                              UG_LOG("one fac at edg" << std::endl);
    1298              : 
    1299              : //                                              addElemToSplit( edgesToBeSplitted, edg );
    1300              :                                                 innerBoundaryEdges++;
    1301              :                                         }
    1302              :                                         else if( numFacsFromFracSudo == 2 )
    1303              :                                         {
    1304              : //                                              UG_LOG("two fac sides at edge " << std::endl);
    1305              :                                                 ; // nothing to do, edge at both sides surrounded by fracture face
    1306              :                                         }
    1307              :                                         else
    1308              :                                         {
    1309              :                                                 UG_LOG("komische Ecke" << std::endl);
    1310              :                                                 UG_THROW("komische Ecke" << std::endl);
    1311              :                                         }
    1312              : 
    1313              :                                 }
    1314              : 
    1315              :                                 if( innerBoundaryEdges == 0  || 1 || 3 )
    1316              :                                 {
    1317              : //                                      UG_LOG("komische innere Grenze ohne Grenze " << std::endl);
    1318              : //                                      UG_THROW("komische innere Grenze ohne Grenze " << std::endl);
    1319              : //                                      ; // nothing to do
    1320              : //                              }
    1321              : //                              else if( innerBoundaryEdges == 1 )
    1322              : //                              {
    1323              :                                         ; // nothing to do, entire boundary edge with no problem, or external edge
    1324              :                                 }
    1325              :                                 else if( innerBoundaryEdges == 2 )
    1326              :                                 {
    1327              :                                         // figure out that edge that is NOT the boundary edge
    1328              : 
    1329              :                                         UG_LOG("we have two inner boundary edges" << std::endl);
    1330              : 
    1331              :                                         std::vector<Edge*> assoEdg;
    1332              : 
    1333              :                                         CollectEdges( assoEdg, m_grid, fac );
    1334              : 
    1335              :                                         for( Edge * edg : assoEdg )
    1336              :                                         {
    1337              :                                                 // check if edge is inner boundary edge, i.e. if has at one side non-fracture face
    1338              :                                                 // only check for those edges which have one fracture face on one side
    1339              : 
    1340              :                                                 // split only inner edges at the moment in case of problems
    1341              :                                                 if( IsBoundaryEdge3D(m_grid, edg) )
    1342              :                                                 {
    1343              :                                                         continue;
    1344              :                                                 }
    1345              : 
    1346              :                                                 std::vector<Face *> assoFac;
    1347              : 
    1348              :                                                 CollectFaces( assoFac, m_grid, edg );
    1349              : 
    1350              :                                                 IndexType numFacsFromFracSudo = 0;
    1351              : 
    1352              :                                                 for( Face * testFac : assoFac )
    1353              :                                                 {
    1354              :                                                         IndexType testSudo = m_sh.get_subset_index(testFac);
    1355              : 
    1356              :                                                         if( testSudo == fracIndSudo )
    1357              :                                                                 numFacsFromFracSudo++;
    1358              :                                                 }
    1359              : 
    1360              :                                                 if( numFacsFromFracSudo == 0 ||  numFacsFromFracSudo == 1 )
    1361              :                                                 {
    1362              :                                                         // relevant! edge needs to be split
    1363              : 
    1364              :                 //                                      UG_LOG("one fac at edg" << std::endl);
    1365              :                                                         ;
    1366              : //                                                      addElem( facesAtInnerBoundary, fac );
    1367              :                                                 }
    1368              :                                                 else if( numFacsFromFracSudo == 2 )
    1369              :                                                 {
    1370              :                 //                                              UG_LOG("two fac sides at edge " << std::endl);
    1371              :                                                                 ; // nothing to do, edge at both sides surrounded by fracture face
    1372              :                                                                 addElem(edgesToBeSplitted, edg);
    1373              :                                                 }
    1374              :                                                 else
    1375              :                                                 {
    1376              :                                                         UG_LOG("komische Ecke" << std::endl);
    1377              :                                                         UG_THROW("komische Ecke" << std::endl);
    1378              :                                                 }
    1379              :                                         }
    1380              : 
    1381              :                                 }
    1382              :                                 else
    1383              :                                 {
    1384              :                                         UG_LOG("how many inner boundary edges at a fracture face???" << std::endl) ;
    1385              :                                         UG_THROW("how many inner boundary edges at a fracture face???" << std::endl) ;
    1386              :                                 }
    1387              :                         }
    1388              : 
    1389              :                         // figure out that edge that needs to be splitted - it is that one which is in touch with the fracture on two sides
    1390              : 
    1391              : //                      for( Face * fac : facesAtInnerBoundary )
    1392              : 
    1393              : 
    1394              : 
    1395              :                 }
    1396              : 
    1397              :                 for( Edge * edg : edgesToBeSplitted )
    1398              :                 {
    1399              :                         vector3 center = CalculateCenter(edg, m_aaPos);
    1400              :                         UG_LOG("splitting edge at " << center << std::endl);
    1401              :                         RegularVertex* vrt = SplitEdge<RegularVertex>(m_grid, edg, false);
    1402              :                         m_aaPos[vrt] = center;
    1403              :                 }
    1404              : 
    1405              :         }
    1406              : 
    1407              : 
    1408              :         return splittedEdges;
    1409              : 
    1410              : }
    1411              : 
    1412              : #endif
    1413              : 
    1414              : //////////////////////////////////////////////////////////////////
    1415              : 
    1416              : template<typename ELEMTYP>
    1417              : bool ArteExpandFracs3D::addElem(std::vector<ELEMTYP> & knownElems, ELEMTYP elemToAdd )
    1418              : {
    1419            0 :         return support::addElem(knownElems, elemToAdd);
    1420              : 
    1421              : //      bool unknown = true;
    1422              : //
    1423              : //      for( ELEMTYP elmKnown : knownElems )
    1424              : //      {
    1425              : //              if( elemToAdd == elmKnown )
    1426              : //              {
    1427              : //                      unknown = false;
    1428              : //                      break;
    1429              : //              }
    1430              : //      }
    1431              : //
    1432              : //      if( unknown )
    1433              : //              knownElems.push_back(elemToAdd);
    1434              : //
    1435              : //      return unknown;
    1436              : 
    1437              : }
    1438              : 
    1439              : //////////////////////////////////////////////////////////////////
    1440              : 
    1441              : 
    1442            0 : bool ArteExpandFracs3D::countAndSelectFracBaseNums()
    1443              : {
    1444              :         UG_LOG("countandselect" << std::endl);
    1445              : 
    1446            0 :         for(size_t i_fi = 0; i_fi < m_fracInfos.size(); ++i_fi )
    1447              :         {
    1448            0 :                 int fracIndSudo = m_fracInfos[i_fi].subsetIndex;
    1449              : 
    1450            0 :                 UG_LOG("sudo ind " << fracIndSudo << std::endl);
    1451              : 
    1452            0 :                 for( FaceIterator iter = m_sh.begin<Face>(fracIndSudo); iter != m_sh.end<Face>(fracIndSudo); ++iter )
    1453              :                 {
    1454              :                         Face* fac = *iter;
    1455              : 
    1456              : //                      UG_LOG("Gesicht " << m_aaPos[fac] << std::endl);
    1457              : 
    1458            0 :                         vector3 facCenter = CalculateCenter( fac, m_aaPos );
    1459            0 :                         UG_LOG("fac center " << facCenter << std::endl);
    1460              : 
    1461            0 :                         for( IndexType i = 0; i < fac->num_vertices(); i++ )
    1462            0 :                                 UG_LOG("Vertex " << i << " -> " << m_aaPos[fac->vertex(i)] << std::endl);
    1463              : 
    1464              :                         UG_LOG("alle Vertizes" << std::endl);
    1465              : 
    1466            0 :                         m_sel.select(fac);
    1467              : 
    1468              :                         UG_LOG("selektiert msel " << fac << std::endl);
    1469              : 
    1470              :                         m_aaMarkFaceIsFracB[fac] = true;
    1471              : 
    1472              :                         UG_LOG("mark bool " << fac << std::endl);
    1473              : 
    1474              : //                      return true;
    1475              : 
    1476              :                         std::vector<Edge*> facEdges;
    1477              : 
    1478              :                         UG_LOG("kollektiere ecken" << std::endl);
    1479              : 
    1480            0 :                         CollectEdges( facEdges, m_grid, fac );
    1481              : 
    1482            0 :                         IndexType d_anzahlEcken = facEdges.size();
    1483              : 
    1484            0 :                         if( d_anzahlEcken == 0 )
    1485              :                         {
    1486              :                                 UG_LOG("keine Ecken " << std::endl);
    1487              :                                 return true;
    1488              :                         }
    1489              : 
    1490              :                         UG_LOG("Anzahl Ecken " << d_anzahlEcken << std::endl);
    1491              : 
    1492            0 :                         for( auto const & edg : facEdges )
    1493              :                         {
    1494            0 :                                 m_aaMarkEdgeVFP[edg]++;
    1495              : 
    1496            0 :                                 if( IsBoundaryEdge3D( m_grid, edg ) )
    1497            0 :                                         m_aaMarkEdgeVFP[edg].setIsBndFracVertex();
    1498              : 
    1499            0 :                                 m_sel.select(edg);
    1500              :                         }
    1501              : 
    1502              :                         UG_LOG("Ecken gesammelt " << std::endl);
    1503              : 
    1504            0 :                         for(size_t i = 0; i < fac->num_vertices(); ++i)
    1505              :                         {
    1506            0 :                                 Vertex* vrt = fac->vertex(i);
    1507              :                                 m_sel.select(vrt);
    1508              :                                 // TODO FIXME hier anpassen, herausfinden ob fracture geschlossen
    1509              :                                 // oder inneres Ende, und Anzahl der umgebenden fractures bestimmen!!!
    1510              : 
    1511              :                                 auto & vrtxFracPrps = m_aaMarkVrtVFP[ vrt ];
    1512              : 
    1513              : //                              m_aaMarkVrtVFP[vrt]++;
    1514              :                                 vrtxFracPrps++;
    1515              :                                 // vielleicht auch in nachfolgendem Loop über alle selektierten Vertizes,
    1516              :                                 // wo dann die attached faces abgelaufen und dabei die Subdomain Nummer ermittelt wird
    1517              :                                 // kann eventuell sogar im Hauptloop gemacht werden, dann könnte man praktisch
    1518              :                                 // das alte vertex fracture properties von 2D weiter verwenden, noch zu klären
    1519              : 
    1520              : //                              m_aaMarkVrtVFP[vrt].addFractSudo(fracIndSudo);
    1521            0 :                                 vrtxFracPrps.addFractSudo(fracIndSudo);
    1522              : 
    1523            0 :                                 if( IsBoundaryVertex3D(m_grid, vrt) )
    1524              :                                 {
    1525              : //                                      m_aaMarkVrtVFP[vrt].setIsBndFracVertex();
    1526              :                                         vrtxFracPrps.setIsBndFracVertex();
    1527              :                                 }
    1528              : 
    1529              :                                 // nicht mehr notwendig
    1530              : //                              // die Ecken heraus filtern, die mit diesem Vertex assoziert sind
    1531              : //                              std::vector<Edge*> attEdg;
    1532              : //
    1533              : //                              for( auto const & ae: facEdges )
    1534              : //                              {
    1535              : //                                      if( EdgeContains(ae,vrt) )
    1536              : //                                              attEdg.push_back(ae);
    1537              : //                              }
    1538              : //
    1539              : //                              if( attEdg.size() == 2 )
    1540              : //                              {
    1541              : //                                      EdgePair edgPr( attEdg[0], attEdg[1] );
    1542              : //
    1543              : //                                      AttachedFractFaceEdgeSudo afes( fac, edgPr, fracIndSudo );
    1544              : //
    1545              : //                                      vrtxFracPrps.addAttachedFractElem(afes);
    1546              : //                              }
    1547              : //                              else
    1548              : //                              {
    1549              : //                                      UG_THROW("number of attached edges wrong " << std::endl);
    1550              : //                              }
    1551              : 
    1552              :                         }
    1553            0 :                 }
    1554              :         }
    1555              : 
    1556              : 
    1557              :         //      now make sure that no inner edge is associated with two
    1558              :         //      boundary vertices (referring to the selection)
    1559              : 
    1560              :         constexpr bool splitEdgesTwoBdryVrt = false;
    1561              : 
    1562              :         if( splitEdgesTwoBdryVrt )
    1563              :         {
    1564              :                 std::vector<Edge*> tmpEdges;
    1565              : 
    1566              :                 for(EdgeIterator iterEdg = m_sel.begin<Edge>(); iterEdg != m_sel.end<Edge>(); iterEdg++ )
    1567              :                 {
    1568              :                         Edge* edg = *iterEdg;
    1569              : 
    1570              :                         Vertex * vrtZer = edg->vertex(0);
    1571              :                         Vertex * vrtOne = edg->vertex(1);
    1572              : 
    1573              :                         VertxFracPropts & vrtxFracPrpsVrtZer = m_aaMarkVrtVFP[ vrtZer ];
    1574              :                         VertxFracPropts & vrtxFracPrpsVrtOne = m_aaMarkVrtVFP[ vrtOne ];
    1575              :                         VertxFracPropts & edgeFracPrps = m_aaMarkEdgeVFP[ edg ];
    1576              : 
    1577              :                         if(      vrtxFracPrpsVrtZer.getIsBndFracVertex()
    1578              :                                 &&   vrtxFracPrpsVrtOne.getIsBndFracVertex()
    1579              :                                 && ! edgeFracPrps.getIsBndFracVertex()
    1580              :                         )
    1581              :                         {
    1582              :                                 tmpEdges.push_back(edg);
    1583              :                         }
    1584              : 
    1585              :                 }
    1586              : 
    1587              :                 for( Edge * edg : tmpEdges )
    1588              :                 {
    1589              :                         vector3 center = CalculateCenter(edg, m_aaPos);
    1590              :                         RegularVertex* vrt = SplitEdge<RegularVertex>(m_grid, edg, false);
    1591              :                         m_aaPos[vrt] = center;
    1592              :                         m_sel.select(vrt);
    1593              :                         auto & vrtxFracPrps = m_aaMarkVrtVFP[ vrt ];
    1594              :                         vrtxFracPrps++;
    1595              : 
    1596              :                         vrtxFracPrps.setIsBndFracVertex(false);
    1597              : 
    1598              :                         //      assign adjacency values for associated selected edges (2 to each)
    1599              :                         for(Grid::AssociatedEdgeIterator iterEdg  = m_grid.associated_edges_begin(vrt);
    1600              :                                                                                          iterEdg != m_grid.associated_edges_end(vrt);
    1601              :                                                                                          iterEdg++
    1602              :                         )
    1603              :                         {
    1604              :                                 Edge * assoEdg = *iterEdg;
    1605              : 
    1606              :                                 if( m_sel.is_selected(assoEdg) )
    1607              :                                 {
    1608              :                                         auto & edgFracPrps = m_aaMarkEdgeVFP[assoEdg];
    1609              :                                         edgFracPrps.setIsBndFracVertex(false);
    1610              :                                 }
    1611              :                         }
    1612              :                 }
    1613              : 
    1614              :                 // TODO FIXME unsicher, ob das hier richtig übertragen von Prof. Reiter......
    1615              :         }
    1616              : 
    1617              : #if 0
    1618              : 
    1619              :         // TODO FIXME das ist was komisches, was von Prof. Reiter da ist, es werden edges gesplittet, für was?
    1620              : 
    1621              :         edges.clear();
    1622              :         for(EdgeIterator iter = sel.begin<Edge>();
    1623              :                 iter != sel.end<Edge>(); ++iter)
    1624              :         {
    1625              :                 Edge* e = *iter;
    1626              :                 if(aaMarkVRT[e->vertex(0)] != 2 &&
    1627              :                         aaMarkVRT[e->vertex(1)] != 2 &&
    1628              :                         aaMarkEDGE[e] > 1)
    1629              :                 {
    1630              :                         edges.push_back(e);
    1631              :                 }
    1632              :         }
    1633              : 
    1634              :         for(size_t i = 0; i < edges.size(); ++i){
    1635              :                 vector3 center = CalculateCenter(edges[i], aaPos);
    1636              :                 RegularVertex* v =      SplitEdge<RegularVertex>(grid, edges[i], false);
    1637              :                 aaPos[v] = center;
    1638              :                 aaMarkVRT[v] = 2;
    1639              :                 sel.select(v);
    1640              :         //      assign adjacency values for associated selected edges (2 to each)
    1641              :                 for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(v);
    1642              :                         iter != grid.associated_edges_end(v); ++iter)
    1643              :                 {
    1644              :                         if(sel.is_selected(*iter))
    1645              :                                 aaMarkEDGE[*iter] = 2;
    1646              :                 }
    1647              :         }
    1648              : 
    1649              : 
    1650              : #endif
    1651              : 
    1652              :         return true;
    1653              : 
    1654              : }
    1655              : 
    1656            0 : int ArteExpandFracs3D::prepareStasi( Vertex * const & vrt, AttachedVolumeElemInfo & attVolElmInfo )
    1657              : {
    1658              :         // NOTE returns number of boundary faces
    1659              : 
    1660              :         // Voraussetzung  FÜR StammiBene Aufrufung
    1661              :         // Stammi-Bene-Vorbereitung
    1662              : //      for( VertexIterator iter = m_sel.begin<Vertex>(); iter != m_sel.end<Vertex>(); ++iter)
    1663              : //      {
    1664              : //              Vertex* vrt = *iter;
    1665              : 
    1666              : //              std::vector<Volume*> & attVol = m_aaVrtInfoAssoVols[vrt];
    1667              : 
    1668            0 :         auto & vrtxFracPrps = m_aaMarkVrtVFP[ vrt ];
    1669              : 
    1670              : //      bool isBndryVrtx = vrtxFracPrps.getIsBndFracVertex();
    1671              : 
    1672              :         IndexType numBndryFacs = 0;
    1673              : 
    1674              :                 // TODO FIXME das hier soll wegfallen, und an dieser Stelle direkt berechnet werden
    1675              :                 // damit es einheitlich für echte fracture faces und auch für boundary faces gilt,
    1676              :                 // die eine Art Fracture sind, an denen mit dem Durchmesser 0 der neue Vertex verschoben wird
    1677              : 
    1678              :                 // die erzeugen wir an Ort und Stelle neu und verteilen nicht alles auf hundert Plätze
    1679              : //              VecAttachedFractFaceEdgeSudo vecAttFacEdgSudo = vrtxFracPrps.getAllAttachedFractElems();
    1680              : 
    1681              : //              auto & vecVolElmInfo = m_aaVolElmInfo[vrt];
    1682              : 
    1683              :                 // TODO FIXME eigentlich eine Dummheit, das auf zu teilen in ein VolElemInfo und ein VrtInfoAssoVols
    1684              :                 // denn die InfoAssoVols haben als Info nur die Volumen, die VolElmInfos haben die Volumen
    1685              :                 // und noch viel mehr Infos zu den Faces und den Edges....
    1686              :                 // mittelfristig die m_aaVrtInfoAssoVols abschaffen und alles auf die AttachedFullDimElemInfo
    1687              :                 // übertragen, dann geht der folgende Loop gleich über den Vektor darüber, bzw. gleichbedeutend
    1688              :                 // über m_aaVolElmInfo
    1689              : //              for( auto & vol : attVol )
    1690              : //              for( AttachedVolumeElemInfo & attVolElmInfo : vecVolElmInfo )
    1691              : //              {
    1692              : //                      AttachedVolumeElemInfo attVolElmInfo( vol );
    1693            0 :         Volume * vol = attVolElmInfo.getFulldimElem();
    1694              : 
    1695              :                         // add those faces which are fracture faces
    1696              :                         // TODO FIXME hier müssen die fracture faces neu erzeugt und addiert werden, oder weiter unten.....
    1697              : //                      for( auto & afes : vecAttFacEdgSudo )
    1698              : //                      {
    1699              : //                              attVolElmInfo.addFractManifElem(afes, m_grid);
    1700              : //                      }
    1701              : 
    1702              :                         // add those faces which are NOT fracture faces, assign them arbitraryly subdomain  -1
    1703              :                         // to indicate that they are not from the manifold, independent of their subdomain
    1704              : 
    1705              :                         // collect all volume faces which incorporate the vertex
    1706              : 
    1707              :         std::vector<Face*> volFacesContainingVrtx;
    1708              : 
    1709            0 :         for( IndexType iFac = 0; iFac < vol->num_faces(); iFac++ )
    1710              :         {
    1711            0 :                 Face * fac = m_grid.get_face(vol,iFac);
    1712              : 
    1713            0 :                 if( FaceContains( fac, vrt ) )
    1714              :                 {
    1715            0 :                         volFacesContainingVrtx.push_back( fac );
    1716              :                 }
    1717              :         }
    1718              : 
    1719            0 :         for( auto const & fac : volFacesContainingVrtx )
    1720              :         {
    1721              :                                 // get the edges of the face connected to the vertex
    1722              : 
    1723              :                 std::vector<Edge*> vecEdgesFaceVrtx;
    1724              : 
    1725              :                                 // need to be two edges always, check
    1726              : 
    1727            0 :                 for( IndexType iEdge = 0; iEdge < fac->num_edges(); iEdge++ )
    1728              :                 {
    1729            0 :                         Edge * edg = m_grid.get_edge(fac,iEdge);
    1730              : 
    1731            0 :                         if( EdgeContains(edg,vrt) )
    1732              :                         {
    1733            0 :                                 vecEdgesFaceVrtx.push_back(edg);
    1734              :                         }
    1735              :                 }
    1736              : 
    1737            0 :                 if( vecEdgesFaceVrtx.size() != 2 )
    1738              :                 {
    1739              :                         UG_LOG("edge number Unsinn " << vecEdgesFaceVrtx.size() << std::endl);
    1740            0 :                         UG_THROW("edge number Unsinn " << vecEdgesFaceVrtx.size() << std::endl);
    1741              :                         return false;
    1742              :                 }
    1743              : 
    1744              :                 EdgePair edgesFaceVrtx( vecEdgesFaceVrtx[0], vecEdgesFaceVrtx[1] );
    1745              : 
    1746              :                                 // test the subdomain first, if from the subdomains of the cleft manifolds
    1747              : 
    1748            0 :                 IndexType sudoThisFace = m_sh.get_subset_index(fac);
    1749              : 
    1750              :                 std::vector<IndexType> const & sudoList = vrtxFracPrps.getSudoList();
    1751              : 
    1752              :                                 // test if sudo of face belongs to the fracture face subdom list
    1753              : 
    1754              :                 bool faceBelongsToFracSudo = false;
    1755              : 
    1756            0 :                 for( auto const & sudoFrac : sudoList )
    1757              :                 {
    1758            0 :                         if( sudoFrac == sudoThisFace )
    1759              :                         {
    1760              :                                 faceBelongsToFracSudo = true;
    1761              :                                 break;
    1762              :                         }
    1763              :                 }
    1764              : 
    1765              :                                 // TODO FIXME für Boundary faces und für Fracture faces soll die Normale berechnet werden ins VOlumen hinein
    1766              :                                 // hier die KuhVol-Prozedur
    1767              : 
    1768              :                 bool isBoundaryFace = false;
    1769              : 
    1770            0 :                 if( ! faceBelongsToFracSudo )
    1771              :                 {
    1772            0 :                         if( IsBoundaryFace3D( m_grid, fac ) )
    1773              :                         {
    1774              :                                 isBoundaryFace = true;
    1775              :                         }
    1776              :                 }
    1777              : 
    1778            0 :                 if( isBoundaryFace && faceBelongsToFracSudo )
    1779            0 :                         UG_THROW("not allowed to be fracture at boundary" << std::endl);
    1780              : 
    1781              :                 // will get a nonzero value in case that fracture face or boundary face
    1782              :                 NormalVectorFacIntoVol normalIntoVol(0,0,0);
    1783              : 
    1784            0 :                 if( isBoundaryFace || faceBelongsToFracSudo )
    1785              :                 {
    1786              :                                 // TODO FIXME compute normal into volume, needed to know!!!
    1787              :                                         // kuhVol Procedure
    1788            0 :                         if( ! computeNormalKuhVolProcedure(vol,fac,normalIntoVol) )
    1789              :                         {
    1790              :                                 UG_LOG("Kuh VOl schief gegangen " << std::endl);
    1791            0 :                                 UG_THROW("Kuh VOl schief gegangen " << std::endl);
    1792              :                                 return numBndryFacs;
    1793              :                         }
    1794              :                 }
    1795              : 
    1796            0 :                 if( faceBelongsToFracSudo )
    1797              :                 {
    1798              :                                         // if it belongs, construct it again and test if it already belongs to the fracture faces
    1799              :                                         // MUST be already part of the list, else major error appeared!
    1800              : 
    1801            0 :                         UG_LOG("Kuh Normale " << normalIntoVol << std::endl);
    1802              : 
    1803              :                         AttachedFractFaceEdgeSudo afesFract( fac, edgesFaceVrtx, sudoThisFace, normalIntoVol );
    1804              :                                         //  hier soll auch gleich die Normale relativ zum VOlumen dazu gespeichert werden!!
    1805              : 
    1806            0 :                         attVolElmInfo.addFractManifElem( afesFract, m_grid );
    1807              : 
    1808              :                                         // vorher soll es nicht mehr gespeichert werden, da die Infos vorher weg fallen sollen
    1809              : //                                      if( attVolElmInfo.addFractManifElem( afesFract, m_grid ) )
    1810              : //                                      {
    1811              : //                                              UG_LOG("manifold element already contained!" << std::endl);
    1812              : //                                              UG_THROW("manifold element already contained!" << std::endl);
    1813              : //                                              return false;
    1814              : //                                      }
    1815              : 
    1816              :                                         // nothing to do, already added before hoffentlich
    1817              : 
    1818              :                 }
    1819              :                 else
    1820              :                 {
    1821              :                                         // TODO FIXME hier muss entschieden werden, ob es eine boundary face ist
    1822              :                         // die kommt dann auch nochmal in ein anderes Konstrukt, was aber
    1823              :                                         // dem fracture face ähnelt
    1824              :                                         // am Ende müssen die Frac Faces, die nicht geschlossen sind, und doppelt in einem Segment
    1825              :                                         // in die general faces verschoben werden, da stören sie nicht, und sind egal
    1826              : 
    1827              :                                         // zeitweilig fehlten alle Faces, die keine fractures sind
    1828              :                                         // die müssen noch irgendwie als nicht-fracture-faces auch dazu gefügt werden
    1829              :                                         // die sind in den attached volumes schon enthalten,
    1830              :                                         // Frage: wie prüfen, dass die gar keine fractures sind, die Infos sollten bekannt sein.....
    1831              :                                         // wichtig auch, dass nur die faces dazu kommen, die den Vertex enthalten!!!
    1832              :                                         // irgendwas von der Art "nonFractureFaceInfos" oder sowas dazu hängen, mit Info
    1833              :                                         // ob schon getouched oder noch nicht.....
    1834              : 
    1835              : 
    1836              :                                         // we construct the attached manifold, given that it is NOT a fracture manifold
    1837              : 
    1838              :                                         // notwendig auch, dass es eine Markierungsmöglichkeit gibt dafür, ob
    1839              :                                         // ein face bei der nächsten weiter inneren Runde quasi äussere Begrenzung sein muss
    1840              :                                         // gilt sowohl für fracture faces, die können das in erster Runde auch sein am Ende
    1841              :                                         // der Runde, sowie danach nur noch für nicht-fracture-faces
    1842              : //                                      if( IsBoundaryFace3D( m_grid, fac ) )
    1843            0 :                         if( isBoundaryFace )
    1844              :                         {
    1845              :                                 AttachedBndryFaceEdgeSudo afesBndry( fac, edgesFaceVrtx, sudoThisFace, normalIntoVol );
    1846              : 
    1847            0 :                                 attVolElmInfo.addBndryManifElem( afesBndry, m_grid );
    1848              : 
    1849            0 :                                 UG_LOG("Boundary element added" << m_aaPos[vrt] << " -> " << normalIntoVol << std::endl);
    1850              : 
    1851            0 :                                 numBndryFacs++;
    1852              : 
    1853              : //                                                      UG_THROW("da ist es " << std::endl);
    1854              : 
    1855              :                                 // TODO FIXME sehr wichtig, die Boundary faces brauchen auch
    1856              :                                                 // noch ihre Normale in das Volumen hinein, analog zu den Fracture faces!!!
    1857              :                                                 // die haben die allerdings dummerweise in die boundary vertizes gesteckt
    1858              :                                                 // vielleicht boundaries wie fractures behandeln? keine gute Idee......
    1859              :                                                 // mithin steckt die Normale NICHT in diesen Informationen drin
    1860              :                                                 // sondern extra in den vertex fracture tripeln
    1861              :                                                 // vielleicht dort die boundaries irgendwie dazu würgen.....
    1862              : 
    1863              :                         }
    1864              :                         else // normal face, no fracture, no boundary
    1865              :                         {
    1866              :                                 AttachedGenerFaceEdgeSudo afesAdd( fac, edgesFaceVrtx );
    1867              : 
    1868            0 :                                 attVolElmInfo.addGenerManifElem( afesAdd, m_grid );
    1869              :                         }
    1870              : 
    1871              : 
    1872              :                 }
    1873              : 
    1874            0 :         }
    1875              : 
    1876              : //              }
    1877              : //      }
    1878              : 
    1879              : //      if( isBndryVrtx && numBndryFacs == 0 )
    1880              : //      {
    1881              : //              UG_LOG("boundary vertex but no boundary faces ")
    1882              : //      }
    1883              : 
    1884            0 :         return numBndryFacs;
    1885            0 : }
    1886              : 
    1887            0 : bool ArteExpandFracs3D::computeNormalKuhVolProcedure( Volume * const & kuhVol, Face * const & fac, NormalVectorFacIntoVol & normalIntoVol )
    1888              : {
    1889              :         IndexType numFd = 0;
    1890              : 
    1891            0 :         for( IndexType iSide = 0; iSide < kuhVol->num_sides(); iSide++ )
    1892              :         {
    1893            0 :                 Face * kuhFac = m_grid.get_side(kuhVol, iSide);
    1894              : 
    1895              : //                                      UG_LOG("Center Kuh Face " << CalculateCenter(kuhFac,m_aaPos) << std::endl);
    1896              : 
    1897              :                 //  eigentliches Ziel ist es, den face descriptor des Volumens zu finden,
    1898              :                 // das mit dem face übereinstimmt, alle anderen Seiten des Volumens sind egal
    1899              :                 // Funktion suchen, die ausgehend von einem Face, das ein Volumen begrenzt,
    1900              :                 // den zum Volumen passenden FaceDescriptor findet, also auch richtige Orientierung
    1901              :                 // der Vertices beinhaltet
    1902              :                 // FRAGE: ist ein face descriptor von der Orientierung zum Volumen abhängig
    1903              :                 // oder hängt der nur vom Face ab, das eine vorgegebene Oriertierung hat?
    1904              : 
    1905            0 :                 bool checkCoincide = checkIfFacesVerticesCoincide( kuhFac, fac );
    1906              : 
    1907            0 :                 if( checkCoincide )
    1908              :                 {
    1909            0 :                         numFd++;
    1910              : 
    1911            0 :                         if( kuhFac != fac )
    1912              :                                 UG_LOG("Kuh Fac ist nicht fac " << std::endl);
    1913              : 
    1914            0 :                         FaceDescriptor facDescr;
    1915              : 
    1916              :                         // testen, ob der Face Descriptor von der Orientierung abhängt
    1917              :                         // also testen, ob sich der face descriptor ändert, wenn das Volumen
    1918              :                         // auf der einen und auf der anderen Seite des faces hängt
    1919              :                         // deswegen auch die ganze Prozedur mit den kuhFacs, die hoffentlich
    1920              :                         // je nach Volumen anders orientiert sind als das eigentliche Face,
    1921              :                         // aber dieselben Vertices haben, also geometrisch gleich sind, aber anders orientiert!!!!
    1922              : 
    1923              :                         //  andere Hergehensweise vielleicht:
    1924              :                         // von m_aaVrtInfoAssoVols ausgehen, darüber loopen, oder die in einen Vektor stecken,
    1925              :                         // wo die Vertices dabei sind, dann kann man sich vielelicht ein paar Klimmzüge sparen,
    1926              :                         // vielleicht aber auch nicht.....
    1927              : 
    1928            0 :                         kuhVol->face_desc( iSide, facDescr );
    1929              : 
    1930              : //                      vector3 normal;
    1931              : 
    1932            0 :                         CalculateNormal( normalIntoVol, & facDescr, m_aaPos );
    1933              : 
    1934            0 :                         vector3 facCenter = CalculateCenter( kuhFac, m_aaPos );
    1935            0 :                         vector3 kuhCenter = CalculateCenter( fac, m_aaPos );
    1936            0 :                         vector3 kuhVolCenter = CalculateCenter( kuhVol, m_aaPos);
    1937              : 
    1938              : //                                              UG_LOG("Normale zum face descriptor " << normal << " , " << facCenter << std::endl);
    1939              : //                                              UG_LOG("Normale zum Kuhh descriptor " << normal << " , " << kuhCenter << std::endl);
    1940              : //                                              UG_LOG("Zentrum des Vol")
    1941              : 
    1942              : //                                              UG_LOG("fac " << fac << std::endl );
    1943              : //                                              UG_LOG("kuh " << kuhFac << std::endl );
    1944              : 
    1945            0 :                         UG_LOG("Normale ist " << normalIntoVol << " fac " << facCenter
    1946              :                                         << " vol " << kuhVolCenter << std::endl);
    1947              : 
    1948              : 
    1949              : //                                              VolNormPair normalsAwayVol( kuhVol, normal );
    1950              : //
    1951              : //                                              vecNormalsAwayVol.push_back( normalsAwayVol );
    1952              : 
    1953              :                 }
    1954              :         }
    1955              : 
    1956            0 :         if( numFd != 1 )
    1957              :         {
    1958            0 :                 UG_THROW("Kein Kuh Volumen gefunden" << std::endl);
    1959              :                 return false;
    1960              :         }
    1961              : 
    1962              : 
    1963              :         return true;
    1964              : }
    1965              : 
    1966              : //////////////////////////////////////////////////////////////////
    1967              : 
    1968            0 : bool ArteExpandFracs3D::distinguishSegments()
    1969              : {
    1970              : 
    1971              :         UG_LOG("neuer Beginn Segmente" << std::endl);
    1972              : //      return true;
    1973              : 
    1974              :         //      StammiBene Algorithmus erklärt und in Worten Plan erstellt
    1975              :         //      Search the adjacent merged manifold iteratively between each necessary element
    1976              :         // TODO FIXME hier Loop über alle selektierten Vertizes
    1977              :         // darin für jeden Vertex die adjungierten Volumen bestimmen ohne Vorbedingung
    1978              :         // dann den Loop zur Vorbereitung des StammiBene Algorithmus aufrufen
    1979              :         // für jeden Vertex wieder, der hat dann schon die Basisinfo von der
    1980              :         // VecAttachedVolumeElemInfo Klasse an jedem Vertex
    1981              :         // auf die aufbauend fügt er Fracture  Manifolds, general manifolds,
    1982              :         // und NEU auch boundary manifolds in einer eigenen Member dazu
    1983              :         // danach wird für jeden Vertex der StammiBene Algorithmus aufgerufen
    1984              :         // später werden Boundary Faces wie eine eigene Subdomain Ebene
    1985              :         // mit Expansion null behandelt
    1986              :         // was an Knicken aussen an boundary zu tun ist, noch zu überlegen
    1987              : 
    1988              :         UG_LOG("Stasi Algo alle Vrt Start << std::endl");
    1989              : 
    1990            0 :         for( VertexIterator iter = m_sel.begin<Vertex>(); iter != m_sel.end<Vertex>(); ++iter)
    1991              :         {
    1992            0 :                 Vertex* vrt = *iter;
    1993              : 
    1994            0 :                 if( ! stasiAlgo( vrt ) )
    1995              :                 {
    1996              :                         UG_LOG("Stasi schief gegangen " << std::endl);
    1997            0 :                         UG_THROW("Stasi schief gegangen" << std::endl);
    1998              :                         return false;
    1999              :                 }
    2000              :         }
    2001              : 
    2002              :         UG_LOG("Stasi Algo alle Vrt End << std::endl");
    2003              : 
    2004              :         // TODO FIXME
    2005              :         // es müssen in den Segmenten noch die fracture faces zu generellen faces verschoben werden,
    2006              :         // die nicht abgeschlossen sind, und umgangen werden können, und so in die Landschaft ragen
    2007              :         // also die fracture faces, die für die Segmenteigenschaft unerheblich sind
    2008              : 
    2009            0 :         for( VertexIterator iter = m_sel.begin<Vertex>(); iter != m_sel.end<Vertex>(); ++iter)
    2010              :         {
    2011            0 :                 Vertex* vrt = *iter;
    2012              : 
    2013            0 :                 IndexType shiFraFac = shiftUnclosedFracFacesToUnclosedFractFaces( vrt );
    2014              : 
    2015            0 :                 UG_LOG("shifted frac faces at " << m_aaPos[vrt] << shiFraFac << std::endl);
    2016              :         }
    2017              : 
    2018              : 
    2019              :         return true;
    2020              : 
    2021              : }
    2022              : 
    2023              : //////////////////////////////////////////////////////////////////
    2024              : 
    2025              : 
    2026            0 : bool ArteExpandFracs3D::detectEndingCrossingCleftsSegmBased()
    2027              : {
    2028              : 
    2029            0 :         m_vecEdgeDirectConnectingEndingCrossCleftVrtcs = std::vector<Edge*>();
    2030              : 
    2031              :         // TODO FIXME eigene Klasse erzeugen, die die ganzen Infos an endenden Klüften speichert, wo sich
    2032              :         // zwei Klüfte kreuzen
    2033              :         // Vertex, auslaufende faces, wo anders aufgeblasen werden muss,
    2034              :         // Edges der Kreuzung, die anhängenden faces der anderen Kluft, die
    2035              :         // die Basis sind für die Aufblasungen, die auch anders funktionieren
    2036              :         // von dieser Klasse dann ein attachment an die vertizes und vielleicht die faces,
    2037              :         // die problematisch sind
    2038              :         // (noch zu klären, ob vielleicht ein paar der auskommentierten attachments doch sinnvoll)
    2039              : 
    2040              :         IndexType numEndingCrossingClefts = 0;
    2041              : 
    2042              : //      std::vector<Face*> m_d_endingCrossingCleftFaces;
    2043              : //
    2044              : //      std::vector<Vertex*> m_d_endingCrossingCleftVrtcs;
    2045              : //
    2046              : //      std::vector<Edge*> m_d_cuttingEdges;
    2047              : //      std::vector<Face*> crossingNotEndingFaces;
    2048              : //
    2049              : //      std::vector<Edge*> otherEdgeOfCrossingNotEndingFace;
    2050              : //      std::vector<Face*> nextFaceOfCrossingNotEndingFaces;
    2051              : 
    2052            0 :         for( VertexIterator iter = m_sel.begin<Vertex>(); iter != m_sel.end<Vertex>(); ++iter)
    2053              :         {
    2054            0 :                 Vertex* vrt = *iter;
    2055              : 
    2056              :                 VecSegmentLimitingSides & vecSegmLimSid = m_vrtxAttAccsVecSegmLimSid[vrt];
    2057              : 
    2058            0 :                 if(  vecSegmLimSid.size() == 0 )
    2059              :                 {
    2060              :                         UG_LOG("keine verschiedenen Segmente ECCV" << std::endl);
    2061              : //                      return true;
    2062              :                 }
    2063              : 
    2064            0 :                 if( vecSegmLimSid.size() == 1 )
    2065              :                 {
    2066              :                         UG_LOG("sonderbarer Fall von nur einem Segment ECCV" << std::endl );
    2067            0 :                         UG_THROW("sonderbarer Fall von nur einem Segment ECCV" << std::endl );
    2068            0 :                         return false;
    2069              :                 }
    2070              : 
    2071            0 :                 for( SegmentLimitingSides & segLimSids : vecSegmLimSid )
    2072              :                 {
    2073            0 :                         if( segLimSids.hasUnclosedFaces() )
    2074              :                         {
    2075              :                                 UG_LOG("im distinguisch ungeschlossene Gesichter " << std::endl );
    2076              : 
    2077            0 :                                 numEndingCrossingClefts++;
    2078              : 
    2079              :                                 std::vector<Volume*> volsOfUnclosedSegm;
    2080              : 
    2081            0 :                                 if( ! segLimSids.spuckVecFulldimElem(volsOfUnclosedSegm) )
    2082              :                                 {
    2083              :                                         UG_LOG("No volumes at segment with ending cleft" << std::endl);
    2084            0 :                                         UG_THROW("No volumes at segment with ending cleft" << std::endl);
    2085              :                                         return false;
    2086              :                                 }
    2087              : 
    2088            0 :                                 for( Volume * vol : volsOfUnclosedSegm )
    2089              :                                 {
    2090              :                                         m_volAttAccsVolTouchesEndingCrossingCleft[vol] = true;
    2091              :                                 }
    2092              : 
    2093              :                                 Vertex * endingCrossingCleftVrtx = segLimSids.spuckVertex();
    2094              : 
    2095            0 :                                 if( endingCrossingCleftVrtx != vrt )
    2096              :                                 {
    2097            0 :                                         UG_THROW("System von attachments und vektoren durcheinander " << std::endl);
    2098              :                                 }
    2099              : 
    2100              :                                 //  commented out the debug members:  m_d_endingCrossingCleftVrtcs.push_back( endingCrossingCleftVrtx );
    2101              : 
    2102              :                                 UG_LOG("vertex gefunden an ending crossing cleft " << std::endl);
    2103              : 
    2104              :                                 m_aaMarkVrtxAtEndingCrossingCleft[vrt] = true;
    2105              : 
    2106              :                                 // the unclosed ending crossing faces
    2107              :                                 VecSegLimSidesFractFace vecSegmLimSiFFUnclosed;
    2108              : 
    2109              :                                 if( ! segLimSids.spuckVecAttUnclosedFractElm( vecSegmLimSiFFUnclosed ) )
    2110              :                                         return false;
    2111              : 
    2112              :                                 // figure out the faces that are in touch with the ending faces, and the corresponding edges
    2113              : 
    2114              :                                 VecSegLimSidesFractFace vecSegmLimSiFFClosed;
    2115              : 
    2116              :                                 if( ! segLimSids.spuckVecAttFractElm( vecSegmLimSiFFClosed ) )
    2117              :                                         return false;
    2118              : 
    2119              :                                 UG_LOG("Faces suchen an ending crossing cleft " << std::endl);
    2120              : 
    2121              : //                              Face * endingFractManifCutting = nullptr;
    2122              : //                              Face * endingFractManifNotCutting = nullptr;
    2123              : //                              Edge * oldLowDimElCut = nullptr;
    2124              : //                              std::pair<Face*,Face*> pairNeighbouredFractClosedManifEl(nullptr,nullptr);
    2125              : //                              IndexType sudoFractEnding = std::numeric_limits<IndexType>::max();
    2126              : //                              IndexType sudoFractNotEnding = std::numeric_limits<IndexType>::max();
    2127              : 
    2128              :                                 std::vector<Face*> vecEndingFractFaceCutting; // must have size two after been filled but both same content
    2129              :                                 std::vector<Face*> vecEndingFractFaceNotCutting; // can contain an arbitrary number from zero to .....
    2130              :                                 std::vector<Face*> vecNeighbouredFacesClosedFract; // must have size 2
    2131              : 
    2132              :                                 std::vector<IndexType> vecSudoFractFacsEnding; // must be filled with same number
    2133              :                                 std::vector<IndexType> vecSudoFractFacsNotEnding; // must be filled with same number
    2134              : 
    2135              :                                 std::vector<Edge*> vecCuttingEdges; // must contain only same element, twice
    2136              : 
    2137              :                                 std::vector<Edge*> vecUncuttingEdge; // must get same element twice
    2138              : 
    2139              :                                 UG_LOG("size of vec segm unclos " << vecSegmLimSiFFUnclosed.size() << std::endl);
    2140              : 
    2141            0 :                                 for( SegLimSidesFractFace const & slsffUncl : vecSegmLimSiFFUnclosed )
    2142              :                                 {
    2143              :                                         bool isCuttingTheClosed = false;
    2144              : 
    2145            0 :                                         Face * facUncl = slsffUncl.getManifElm();
    2146              :                                         //  commented out the debug members:  m_d_endingCrossingCleftFaces.push_back(facUncl);
    2147              :                                         m_aaMarkFaceWithEndingCrossingCleft[facUncl] = true;
    2148              : 
    2149            0 :                                         IndexType sudoUncl = slsffUncl.getSudo();
    2150            0 :                                         vecSudoFractFacsEnding.push_back(sudoUncl);
    2151              : 
    2152              :                                         EdgePair const & epU = slsffUncl.getPairLowElm();
    2153              : 
    2154              :                                         //  commented out the debug members:  m_d_allContributingEdges.push_back(epU.first);
    2155              :                                         //  commented out the debug members:  m_d_allContributingEdges.push_back(epU.second);
    2156              : 
    2157              :                                         addElem( m_vecEdgeDirectConnectingEndingCrossCleftVrtcs, epU.first );
    2158              :                                         addElem( m_vecEdgeDirectConnectingEndingCrossCleftVrtcs, epU.second );
    2159              : 
    2160            0 :                                         for( SegLimSidesFractFace const & slsffClos : vecSegmLimSiFFClosed )
    2161              :                                         {
    2162              :                                                 // we need different subdoms, as want to have the not ending crossing fracture neighbours
    2163              :                                                 // that have a common edge
    2164            0 :                                                 Edge * commonEdge = nullptr;
    2165              : 
    2166            0 :                                                 if( fractFacesAreNeighboured<false>( slsffClos, slsffUncl, commonEdge ) )
    2167              :                                                 {
    2168              :                                                         isCuttingTheClosed = true;
    2169              : 
    2170            0 :                                                         Face * facClos = slsffClos.getManifElm();
    2171              :                                                         //  commented out the debug members:  m_d_crossingNeighboredNotEndingFaces.push_back( facClos );
    2172              : 
    2173            0 :                                                         if( commonEdge == nullptr )
    2174              :                                                         {
    2175              :                                                                 UG_LOG("NULL COMMON" << std::endl);
    2176            0 :                                                                 UG_THROW("NULL COMMON" << std::endl);
    2177              :                                                         }
    2178              : 
    2179              :                                                         //  commented out the debug members:  m_d_cuttingEdges.push_back(commonEdge);
    2180              :                                                         //  commented out the debug members:  m_d_crossingNeighboredNotEndingFacesCommEdg.push_back(facUncl);
    2181              : //                                                      // search the durchgehende fracture face which is neighboured to the durchgehende one
    2182              : //                                                      // same vertex, other edge
    2183              : 
    2184            0 :                                                         vecNeighbouredFacesClosedFract.push_back(facClos);
    2185            0 :                                                         vecCuttingEdges.push_back(commonEdge);
    2186            0 :                                                         vecEndingFractFaceCutting.push_back(facUncl);
    2187              : 
    2188            0 :                                                         Edge * uncuttingEdgeUnclosedFac = nullptr;
    2189              : 
    2190            0 :                                                         if( ! assignNotCuttingEdgeUnclosedCrossingCleft( slsffUncl, commonEdge, uncuttingEdgeUnclosedFac ) )
    2191              :                                                         {
    2192              :                                                                 UG_LOG("NO shift edge" << std::endl);
    2193            0 :                                                                 UG_THROW("NO shift edge" << std::endl);
    2194              :                                                         }
    2195              : 
    2196            0 :                                                         if( uncuttingEdgeUnclosedFac == nullptr )
    2197              :                                                         {
    2198              :                                                                 UG_LOG("NO shift edge Z" << std::endl);
    2199            0 :                                                                 UG_THROW("NO shift edge Z" << std::endl);
    2200              :                                                         }
    2201              : 
    2202            0 :                                                         vecUncuttingEdge.push_back(uncuttingEdgeUnclosedFac);
    2203              : 
    2204              :                                                         //                                                      EdgePair const & edgesClosedFracFace = slsffClos.getPairLowElm();
    2205              : //
    2206              : //                                                      Edge * notCommonEdgeOfNotEndingCleft = nullptr;
    2207              : //
    2208              : //                                                      if(  edgesClosedFracFace.first == commonEdge )
    2209              : //                                                      {
    2210              : //                                                              notCommonEdgeOfNotEndingCleft = edgesClosedFracFace.second;
    2211              : //                                                      }
    2212              : //                                                      else if( edgesClosedFracFace.second == commonEdge )
    2213              : //                                                      {
    2214              : //                                                              notCommonEdgeOfNotEndingCleft = edgesClosedFracFace.first;
    2215              : //                                                      }
    2216              : //
    2217              : //                                                      if( notCommonEdgeOfNotEndingCleft == nullptr )
    2218              : //                                                      {
    2219              : //                                                              UG_LOG("no not common edge?" << std::endl);
    2220              : //                                                              UG_THROW("no not common edge?" << std::endl);
    2221              : //                                                      }
    2222              : //
    2223              : ////                                                    otherEdgeOfCrossingNotEndingFace.push_back( notCommonEdgeOfNotEndingCleft );
    2224              : //
    2225              : //                                                      Edge * closedCommonEdge = nullptr;
    2226              : //
    2227              : //                                                      for( SegLimSidesFractFace const & slsffClosOther : vecSegmLimSiFFClosed )
    2228              : //                                                      {
    2229              : //                                                              if( fractFacesAreNeighboured<true>( slsffClos, slsffClosOther, closedCommonEdge ) )
    2230              : //                                                              {
    2231              : //
    2232              : //                                                                      if( closedCommonEdge == nullptr )
    2233              : //                                                                      {
    2234              : //                                                                              UG_LOG("NULL NOT COMMON" << std::endl);
    2235              : //                                                                              UG_THROW("NULL NOT COMMON" << std::endl);
    2236              : //                                                                      }
    2237              : //
    2238              : //                                                                      if( closedCommonEdge != notCommonEdgeOfNotEndingCleft )
    2239              : //                                                                      {
    2240              : //                                                                              UG_LOG("Ecke passt nicht " << CalculateCenter(closedCommonEdge, m_aaPos) << " - " << CalculateCenter( notCommonEdgeOfNotEndingCleft, m_aaPos) << std::endl);
    2241              : ////                                                                            UG_THROW("Ecke verloren " << std::endl);
    2242              : //                                                                      }
    2243              : //                                                                      else
    2244              : //                                                                      {
    2245              : //                                                                              Face * facClosOther = slsffClosOther.getManifElm();
    2246              : //
    2247              : //                                                                              nextFaceOfCrossingNotEndingFaces.push_back( facClosOther );
    2248              : //                                                                              otherEdgeOfCrossingNotEndingFace.push_back(notCommonEdgeOfNotEndingCleft);
    2249              : //                                                                      }
    2250              : //
    2251              : //
    2252              : //                                                              }
    2253              : //                                                      }
    2254              : 
    2255              : 
    2256              :                                                 }
    2257              :                                         }
    2258              : 
    2259            0 :                                         if( ! isCuttingTheClosed )
    2260              :                                         {
    2261            0 :                                                 vecEndingFractFaceNotCutting.push_back(facUncl);
    2262              :                                         }
    2263              : 
    2264              :                                 }
    2265              : 
    2266              : 
    2267              :                                 std::vector<Face*> vecClosedFracFacNoNeighbr;
    2268              : 
    2269            0 :                                 for( SegLimSidesFractFace const & slsffClos : vecSegmLimSiFFClosed )
    2270              :                                 {
    2271            0 :                                         Face * facClos = slsffClos.getManifElm();
    2272              : 
    2273              :                                         EdgePair const & epC = slsffClos.getPairLowElm();
    2274              : 
    2275              :                                         //  commented out the debug members:  m_d_allContributingEdges.push_back(epC.first);
    2276              :                                         //  commented out the debug members:  m_d_allContributingEdges.push_back(epC.second);
    2277              : 
    2278              :                                         addElem( m_vecEdgeDirectConnectingEndingCrossCleftVrtcs, epC.first );
    2279              :                                         addElem( m_vecEdgeDirectConnectingEndingCrossCleftVrtcs, epC.second );
    2280              : 
    2281              : 
    2282            0 :                                         IndexType sudoClos = slsffClos.getSudo();
    2283              : 
    2284            0 :                                         vecSudoFractFacsNotEnding.push_back(sudoClos);
    2285              : 
    2286              :                                         // valid for all closed faces
    2287              :                                         m_facAttAccsIfFaceIsSegmLimFaceEndingCrossingCleft[facClos] = true;
    2288              : 
    2289              :                                         bool facGiven = false;
    2290              : 
    2291              :                                         // ATTENTION hier ausgetauscht erst später, Gefahr von Fehler
    2292              :                                         // m_d_ Variable war Teil von echtem Algorithmus, gefährlich
    2293              :                                         // hoffentlich richtig getauscht
    2294              :                                         // im Falle von bugs hier nochmal testen, ob die m_d Variable
    2295              :                                         // richtig getauscht wurde!!!
    2296              : //                                      for( Face * facClosNoNei : m_d_crossingNeighboredNotEndingFaces )
    2297            0 :                                         for( Face * facClosNoNei : vecNeighbouredFacesClosedFract )
    2298              :                                         {
    2299            0 :                                                 if( facClosNoNei == facClos )
    2300              :                                                 {
    2301              :                                                         facGiven = true;
    2302              :                                                         break;
    2303              :                                                 }
    2304              :                                         }
    2305              : 
    2306            0 :                                         if( ! facGiven )
    2307              :                                         {
    2308              :                                                 //  commented out the debug members:  m_d_notEndingCrossingFacesNotNeighbour.push_back( facClos );
    2309            0 :                                                 vecClosedFracFacNoNeighbr.push_back( facClos );
    2310              :                                         }
    2311              :                                 }
    2312              : 
    2313              : 
    2314              :                                 UG_LOG("Faces vielleicht gefunden an ending crossing cleft " << std::endl);
    2315              : 
    2316              :                                 //                              Face * endingFractManifCutting = nullptr;
    2317              :                                 //                              Face * endingFractManifNotCutting = nullptr;
    2318              :                                 //                              Edge * oldLowDimElCut = nullptr;
    2319              :                                 //                              std::pair<Face*,Face*> pairNeighbouredFractClosedManifEl(nullptr,nullptr);
    2320              :                                 //                              IndexType sudoFractEnding = std::numeric_limits<IndexType>::max();
    2321              :                                 //                              IndexType sudoFractNotEnding = std::numeric_limits<IndexType>::max();
    2322              : 
    2323              :                                 std::vector<Face*> vecContEndingFractFaceCutting; // must have size two after been filled but both same content
    2324              :                                 std::vector<Face*> vecContEndingFractFaceNotCutting; // must have size maximum two same content both, or zero
    2325              :                                 std::vector<Face*> vecContNeighbouredFacesClosedFract; // must have size 2
    2326              : 
    2327              : 
    2328              :                                 std::vector<IndexType> vecContSudoFractFacsEnding; // must be filled with same number
    2329              :                                 std::vector<IndexType> vecContSudoFractFacsNotEnding; // must be filled with same number
    2330              : 
    2331            0 :                                 if( vecEndingFractFaceCutting.size() == 2 )
    2332              :                                 {
    2333            0 :                                         if( ! checkIfContentUnique( vecEndingFractFaceCutting, vecContEndingFractFaceCutting, 1 ) )
    2334              :                                         {
    2335            0 :                                                 for( Face * fac : vecEndingFractFaceCutting  )
    2336              :                                                 {
    2337            0 :                                                         m_sh.assign_subset( fac, m_sh.num_subsets());
    2338              : 
    2339            0 :                                                         UG_LOG("fract face cutting strange behaviour at " << CalculateCenter( fac, m_aaPos ) << std::endl);
    2340              :                                                 }
    2341              : 
    2342              :                                                 UG_LOG("Problem with cutting fac " << std::endl);
    2343              :                                                 return false;
    2344              :                                                 UG_THROW("Problem with cutting fac " << std::endl);
    2345              :                                         }
    2346              :                                 }
    2347              :                                 else
    2348              :                                 {
    2349            0 :                                         UG_THROW("Problem with cutting fac size " << std::endl);
    2350              : 
    2351              :                                 }
    2352              : 
    2353            0 :                                 Face * endingFractManifCutting = vecContEndingFractFaceCutting[0];
    2354              : //
    2355              : //                              std::vector<Face> endingFractManifNotCutting; // = nullptr;
    2356              : //
    2357              : //                              if( vecEndingFractFaceNotCutting.size() != 0 )
    2358              : //                              {
    2359              : //                                      if( vecEndingFractFaceNotCutting.size() == 1 )
    2360              : //                                      {
    2361              : //                                              if( ! checkIfContentUnique( vecEndingFractFaceNotCutting, vecContEndingFractFaceNotCutting, 1 ) )
    2362              : //                                              {
    2363              : //                                                      UG_THROW("Problem with not cutting fac " << std::endl);
    2364              : //                                              }
    2365              : //
    2366              : //                                              endingFractManifNotCutting = vecContEndingFractFaceNotCutting[0];
    2367              : //
    2368              : //                                      }
    2369              : //                                      else
    2370              : //                                      {
    2371              : //                                              for( Face * fac : vecEndingFractFaceNotCutting )
    2372              : //                                              {
    2373              : //                                                      m_sh.assign_subset( fac, m_sh.num_subsets() );
    2374              : //                                              }
    2375              : //
    2376              : //                                              UG_LOG("schief gegangen " << std::endl);
    2377              : //                                              UG_LOG("Problem with not cutting fac size " << vecEndingFractFaceNotCutting.size() << std::endl);
    2378              : //
    2379              : //                                              return false;
    2380              : //                                              UG_THROW("Problem with not cutting fac size " << vecEndingFractFaceNotCutting.size() << std::endl);
    2381              : //
    2382              : //                                      }
    2383              : //
    2384              : //                              }
    2385              : 
    2386              : 
    2387            0 :                                 if( vecNeighbouredFacesClosedFract.size() == 2  )
    2388              :                                 {
    2389            0 :                                         if( ! checkIfContentUnique( vecNeighbouredFacesClosedFract, vecContNeighbouredFacesClosedFract, 2 ) )
    2390              :                                         {
    2391            0 :                                                 UG_THROW("Problem with neigh clos fac " << std::endl);
    2392              :                                         }
    2393              : 
    2394              :                                 }
    2395              :                                 else
    2396              :                                 {
    2397            0 :                                         UG_THROW("Problem with neigh clos fac size " << std::endl);
    2398              :                                 }
    2399              : 
    2400              :                                 std::pair<Face*,Face*> pairNeighbouredFractClosedManifEl( vecContNeighbouredFacesClosedFract[0],
    2401              :                                                                                                                                                   vecContNeighbouredFacesClosedFract[1]
    2402              :                                                                                                                                                  );
    2403              : 
    2404              : 
    2405            0 :                                 if(  ! checkIfContentUnique( vecSudoFractFacsEnding, vecContSudoFractFacsEnding, 1 ) )
    2406              :                                 {
    2407            0 :                                         UG_THROW("Problem with sudo ending " << std::endl);
    2408              :                                 }
    2409              : 
    2410            0 :                                 IndexType sudoFractEnding = vecContSudoFractFacsEnding[0];
    2411              : 
    2412            0 :                                 if(  ! checkIfContentUnique( vecSudoFractFacsNotEnding, vecContSudoFractFacsNotEnding, 1 ) )
    2413              :                                 {
    2414            0 :                                         UG_THROW("Problem with sudo not ending " << std::endl);
    2415              :                                 }
    2416              : 
    2417              : 
    2418            0 :                                 IndexType sudoFractNotEnding = vecContSudoFractFacsNotEnding[0];
    2419              : 
    2420              :                                 std::vector<Edge*> vecContCuttingEdges; // must contain only same element, twice
    2421              : 
    2422            0 :                                 if( vecCuttingEdges.size() == 2 )
    2423              :                                 {
    2424            0 :                                         if(  ! checkIfContentUnique( vecCuttingEdges, vecContCuttingEdges, 1 ) )
    2425              :                                         {
    2426            0 :                                                 UG_THROW("Problem with edges unique " << std::endl);
    2427              :                                         }
    2428              : 
    2429              :                                 }
    2430              :                                 else
    2431              :                                 {
    2432            0 :                                         UG_THROW("Problem with edges unique size " << std::endl);
    2433              : 
    2434              :                                 }
    2435              : 
    2436            0 :                                 Edge * oldLowDimElCut = vecContCuttingEdges[0];
    2437              : 
    2438              :                                 UG_LOG("Pushing back Edge" << std::endl);
    2439              : 
    2440              :                                 std::vector<Edge*> vecContUncuttingEdge; // must get same elemes twice
    2441              : 
    2442            0 :                                 if( vecUncuttingEdge.size() == 2 )
    2443              :                                 {
    2444            0 :                                         if(  ! checkIfContentUnique( vecUncuttingEdge, vecContUncuttingEdge, 1 ) )
    2445              :                                         {
    2446            0 :                                                 UG_THROW("Problem with edges shift unique " << std::endl);
    2447              :                                         }
    2448              : 
    2449              :                                 }
    2450              :                                 else
    2451              :                                 {
    2452            0 :                                         UG_THROW("Problem with edges shift unique size " << std::endl);
    2453              : 
    2454              :                                 }
    2455              : 
    2456            0 :                                 Edge * uncuttingLowDimEl = vecContUncuttingEdge[0];
    2457              : 
    2458            0 :                                 Edge * shiftLowDimEl = nullptr;
    2459              : 
    2460              :                                 std::vector<Edge*> vecEdgsNotCutFaces;
    2461              : 
    2462            0 :                                 if( ! findShiftEdgeUncuttingCrossingCleft( vecSegmLimSiFFUnclosed,
    2463              : //                                                                                                                 endingFractManifCutting,
    2464              :                                                                                                                vecEndingFractFaceNotCutting,
    2465              :                                                                                                                    uncuttingLowDimEl,
    2466              :                                                                                                                    shiftLowDimEl,
    2467              :                                                                                                                    vecEdgsNotCutFaces
    2468              :                                                                                                                   )
    2469              :                                         )
    2470              :                                 {
    2471              :                                         UG_LOG("Kein shift Element gefunden" << std::endl);
    2472            0 :                                         UG_THROW("Kein shift Element gefunden" << std::endl);
    2473              :                                 }
    2474              : 
    2475            0 :                                 if( shiftLowDimEl == nullptr )
    2476              :                                 {
    2477              :                                         UG_LOG("SHift El null " << std::endl);
    2478            0 :                                         UG_THROW("SHift El null " << std::endl);
    2479              :                                 }
    2480              : 
    2481            0 :                                 if(  vecClosedFracFacNoNeighbr.size() + vecNeighbouredFacesClosedFract.size()
    2482              :                                         !=  vecSegmLimSiFFClosed.size()
    2483              :                                 )
    2484              :                                 {
    2485            0 :                                         UG_THROW("size sum clos not fit " << std::endl);
    2486              :                                 }
    2487              : 
    2488              :                                 EndingCrossingFractureSegmentInfo ecfsi( vrt,
    2489              :                                                                                                              endingFractManifCutting,
    2490              :                                                                                                              vecEndingFractFaceNotCutting,
    2491              :                                                                                                                  oldLowDimElCut,
    2492              :                                                                                                                  pairNeighbouredFractClosedManifEl,
    2493              :                                                                                                                  shiftLowDimEl,
    2494              :                                                                                                                  vecEdgsNotCutFaces,
    2495              :                                                                                                                  sudoFractEnding,
    2496              :                                                                                                                  sudoFractNotEnding
    2497            0 :                                                                                                             );
    2498              : 
    2499              :                                 ecfsi.schluckVecClosedFracManifElNoNeighbr( vecClosedFracFacNoNeighbr );
    2500              : 
    2501              :                                 ecfsi.schluckVecFulldimElm( volsOfUnclosedSegm );
    2502              : 
    2503            0 :                                 m_vrtxAttAccsVecEndingCrossFractSegmInfo[vrt].push_back( ecfsi );
    2504              : 
    2505            0 :                                 m_vecEndCrossFractSegmInfo.push_back( ecfsi );
    2506              : 
    2507              : 
    2508            0 :                                 segLimSids.schluckLowdimElmShiftDirectionIfUnclosedFractPresent(shiftLowDimEl);
    2509              : 
    2510              :                                 // schlechte Idee: die segment limiting sides müssen die ganze EndingCrossingFractureSegmentInfo zu wissen bekommen
    2511              :                                 // klar alternativ sollte die shift direction reichen, um die ending crossing fracture segment info rekonstruieren zu können
    2512              :                                 // wäre aber ein Umweg!!!
    2513              :                                 // besser aber der Umweg, ansonsten entsteht das Henne Ei Problem:
    2514              :                                 // wer ist von was der Ursprung? wer schluckt was,
    2515              :                                 // die Segment Seite die Ending crossing fracture segment info, oder umgekehrt?
    2516              :                                 // und wenn es dann als Kopie geschluckt wird, was passiert wenn was verändert wird,
    2517              :                                 // es müssten also Pointer sein, und es entsteht eine unsinnige Kaskade.....
    2518              : 
    2519            0 :                         }
    2520              :                 }
    2521              : 
    2522              :         }
    2523              : 
    2524              :         UG_LOG("detected ending crossing cleft faces " << numEndingCrossingClefts << std::endl);
    2525              : 
    2526              :         UG_LOG("EDGES number " << m_vecEdgeDirectConnectingEndingCrossCleftVrtcs.size() << std::endl);
    2527              : 
    2528              : //      if( m_d_endingCrossingCleftVrtcs.size() == 0 )
    2529              : //              return true;
    2530              : 
    2531            0 :         if( splitEdgesOfNeighboredEndingCrossingFracVrtcs() )
    2532              :         {
    2533              :                 UG_LOG("needed to split, please restart with this geometry" << std::endl);
    2534            0 :                 m_needToSplitEdgesConnectingNeighbrdEndingCrossCleftVrtx = true;
    2535            0 :                 return false;
    2536              :         }
    2537              :         else
    2538              :         {
    2539            0 :                 m_needToSplitEdgesConnectingNeighbrdEndingCrossCleftVrtx = false;
    2540              :         }
    2541              : 
    2542              : //      return true;
    2543              : 
    2544              : 
    2545            0 :         for( VertexIterator iter = m_sel.begin<Vertex>(); iter != m_sel.end<Vertex>(); ++iter)
    2546              :         {
    2547              :                 Vertex* vrt = *iter;
    2548              : 
    2549              :                 VecSegmentLimitingSides & vecSegmLimSid = m_vrtxAttAccsVecSegmLimSid[vrt];
    2550              : 
    2551            0 :                 for( SegmentLimitingSides const & sls : vecSegmLimSid )
    2552              :                 {
    2553            0 :                         if( sls.hasUnclosedFaces())
    2554              :                                 UG_LOG("Hier nach detect hat das Gesicht noch ungeschlossene " << std::endl);
    2555              :                 }
    2556              : 
    2557              :         }
    2558              : 
    2559              :         if( numEndingCrossingClefts == 0 )
    2560              :                         return true;
    2561              : 
    2562              : //      assignDebugSubsets( true );
    2563              : //
    2564              : //      UG_LOG("problematic elements highlighted " << std::endl);
    2565              : 
    2566              :         return true;
    2567              : 
    2568              : 
    2569              : 
    2570              : //      if( numEndingCrossingClefts == 0 )
    2571              : //              return true;
    2572              : //
    2573              : //      // debug for ending crossing clefts
    2574              : //
    2575              : //      for( Face * fac : m_d_endingCrossingCleftFaces )
    2576              : //      {
    2577              : //              m_sh.assign_subset( fac, m_sh.num_subsets());
    2578              : //
    2579              : //      }
    2580              : //
    2581              : //      for( Vertex * vrt : m_d_endingCrossingCleftVrtcs )
    2582              : //      {
    2583              : //              m_sh.assign_subset( vrt, m_sh.num_subsets());
    2584              : //      }
    2585              : //
    2586              : //      for( Edge * edg : m_d_cuttingEdges )
    2587              : //      {
    2588              : //              if( edg == nullptr )
    2589              : //              {
    2590              : //                      UG_LOG("NULL UNERLAUBT" << std::endl);
    2591              : //                      UG_THROW("NULL UNERLAUBT" << std::endl);
    2592              : //              }
    2593              : //
    2594              : //              m_sh.assign_subset( edg, m_sh.num_subsets());
    2595              : //
    2596              : //      }
    2597              : //
    2598              : //      for( Face * fac : crossingNotEndingFaces )
    2599              : //      {
    2600              : //              m_sh.assign_subset( fac, m_sh.num_subsets());
    2601              : //      }
    2602              : //
    2603              : //      for( Edge * edg : otherEdgeOfCrossingNotEndingFace )
    2604              : //      {
    2605              : //              if( edg == nullptr )
    2606              : //              {
    2607              : //                      UG_LOG("NULL C UNERLAUBT" << std::endl);
    2608              : //                      UG_THROW("NULL C UNERLAUBT" << std::endl);
    2609              : //              }
    2610              : //
    2611              : //              m_sh.assign_subset( edg, m_sh.num_subsets());
    2612              : //
    2613              : //      }
    2614              : //
    2615              : //      for( Face * fac : nextFaceOfCrossingNotEndingFaces )
    2616              : //      {
    2617              : //              m_sh.assign_subset( fac, m_sh.num_subsets());
    2618              : //      }
    2619              : //
    2620              : //
    2621              : //      return false;
    2622              : }
    2623              : 
    2624              : //////////////////////////////////////////////////////////////////
    2625              : 
    2626            0 : bool ArteExpandFracs3D::assignNotCuttingEdgeUnclosedCrossingCleft( SegLimSidesFractFace const & slsffUncl, Edge * const & commonEdge, Edge * & shiftEdge )
    2627              : {
    2628              :         EdgePair const & edgesFac = slsffUncl.getPairLowElm();
    2629              : 
    2630              :         Edge * edgeFrst = edgesFac.first;
    2631              :         Edge * edgeScnd = edgesFac.second;
    2632              : 
    2633            0 :         if( edgeFrst == commonEdge )
    2634              :         {
    2635            0 :                 shiftEdge = edgeScnd;
    2636              :         }
    2637            0 :         else if( edgeScnd == commonEdge )
    2638              :         {
    2639            0 :                 shiftEdge = edgeFrst;
    2640              :         }
    2641              :         else
    2642              :         {
    2643              :                 UG_LOG("common and shift edge different face " << std::endl);
    2644            0 :                 UG_THROW("common and shift edge different face " << std::endl);
    2645              :         }
    2646              : 
    2647            0 :         if( shiftEdge != nullptr )
    2648              :                 return true;
    2649              : 
    2650              :         UG_LOG("shift edge null" << std::endl);
    2651              : 
    2652              :         return false;
    2653              : 
    2654              : }
    2655              : 
    2656              : //////////////////////////////////////////////////////////////////
    2657              : 
    2658            0 : bool ArteExpandFracs3D::findShiftEdgeUncuttingCrossingCleft( VecSegLimSidesFractFace const & vecSegmLimSiFFUnclosed,
    2659              : //                                                                                                                       Face * const & endingFractManifCutting,
    2660              :                                                                                                                      std::vector<Face*> const & vecEndingFractManifNotCutting,
    2661              :                                                                                                                          Edge * const & uncuttingLowDimEl,
    2662              :                                                                                                                          Edge * & shiftLowDimEl,
    2663              :                                                                                                                          std::vector<Edge*> & vecEdgsNotCutFaces
    2664              :                                                                                                                         )
    2665              : {
    2666              : 
    2667            0 :         if( uncuttingLowDimEl == nullptr )
    2668              :         {
    2669              :                 UG_LOG("null uncut" << std::endl );
    2670            0 :                 UG_THROW("null uncut" << std::endl );
    2671              :         }
    2672              : 
    2673            0 :         if( vecEndingFractManifNotCutting.size() == 0 )
    2674              :         {
    2675            0 :                 shiftLowDimEl = uncuttingLowDimEl;
    2676            0 :                 return true;
    2677              :         }
    2678              : 
    2679              :         std::vector<Edge*> vecEdgsCollectMulti;
    2680              : 
    2681              :         std::vector<Edge*> vecEdgsCollectSingle;
    2682              : 
    2683            0 :         for( SegLimSidesFractFace const & slsffUncl : vecSegmLimSiFFUnclosed )
    2684              :         {
    2685              : 
    2686              :                 Face * facUncl = slsffUncl.getManifElm();
    2687              : 
    2688            0 :                 for( Face * facNotCut : vecEndingFractManifNotCutting )
    2689              :                 {
    2690            0 :                         if( facNotCut == facUncl )
    2691              :                         {
    2692              :                                 EdgePair const & epU = slsffUncl.getPairLowElm();
    2693              : 
    2694            0 :                                 Edge * edgeOne = epU.first;
    2695            0 :                                 Edge * edgeTwo = epU.second;
    2696              : 
    2697            0 :                                 if( edgeOne != uncuttingLowDimEl )
    2698              :                                 {
    2699            0 :                                         vecEdgsCollectMulti.push_back(edgeOne);
    2700              : 
    2701              :                                         addElem(vecEdgsCollectSingle, edgeOne);
    2702              :                                 }
    2703              : 
    2704            0 :                                 if( edgeTwo != uncuttingLowDimEl )
    2705              :                                 {
    2706            0 :                                         vecEdgsCollectMulti.push_back(edgeTwo);
    2707              : 
    2708              :                                         addElem(vecEdgsCollectSingle,edgeTwo);
    2709              :                                 }
    2710              :                         }
    2711              :                 }
    2712              :         }
    2713              : 
    2714            0 :         if(    ( vecEdgsCollectMulti.size() != vecEdgsCollectSingle.size() * 2 - 1  )
    2715            0 :                 || ( vecEdgsCollectMulti.size() != ( ( vecSegmLimSiFFUnclosed.size() - 1 ) * 2 ) - 1  )
    2716            0 :                 || ( vecEdgsCollectSingle.size() != vecSegmLimSiFFUnclosed.size() - 1 )
    2717              :           )
    2718              :         {
    2719              :                 UG_LOG("Konzept der wilden Ecken schief gegangen " << std::endl);
    2720              : 
    2721              :                 UG_LOG("multi " << vecEdgsCollectMulti.size() << std::endl );
    2722              :                 UG_LOG("single " << vecEdgsCollectSingle.size() << std::endl );
    2723              :                 UG_LOG("segm uncl " << vecSegmLimSiFFUnclosed.size() << std::endl );
    2724              : 
    2725            0 :                 UG_THROW("Konzept der wilden Ecken schief gegangen " << std::endl);
    2726              :         }
    2727              : 
    2728              :         IndexType numShiftEdgFnd = 0;
    2729              : 
    2730            0 :         for( Edge * eS : vecEdgsCollectSingle )
    2731              :         {
    2732              :                 IndexType singleFoundInMulti = 0;
    2733              : 
    2734            0 :                 for( Edge * eM : vecEdgsCollectMulti )
    2735              :                 {
    2736            0 :                         if( eS == eM )
    2737            0 :                                 singleFoundInMulti++;
    2738              :                 }
    2739              : 
    2740            0 :                 if( singleFoundInMulti == 1 )
    2741              :                 {
    2742              :                         numShiftEdgFnd++;
    2743              : 
    2744            0 :                         shiftLowDimEl = eS;
    2745              :                 }
    2746            0 :                 else if( singleFoundInMulti == 2 )
    2747              :                 {
    2748            0 :                         vecEdgsNotCutFaces.push_back( eS );
    2749              :                 }
    2750              :                 else
    2751              :                 {
    2752              :                         UG_LOG("Edge not in useful number " << singleFoundInMulti << std::endl);
    2753            0 :                         UG_THROW("Edge not in useful number " << singleFoundInMulti << std::endl);
    2754              :                 }
    2755              : 
    2756              :         }
    2757              : 
    2758              :         return true;
    2759              : 
    2760              : //      IndexType edgeWasFound = 0;
    2761              : 
    2762              : //      for( SegLimSidesFractFace const & slsffUncl : vecSegmLimSiFFUnclosed )
    2763              : //      {
    2764              : //
    2765              : //              Face * facUncl = slsffUncl.getManifElm();
    2766              : //
    2767              : //              if( facUncl == endingFractManifNotCutting )
    2768              : //              {
    2769              : //                      EdgePair const & epU = slsffUncl.getPairLowElm();
    2770              : //
    2771              : //                      Edge * edgeOne = epU.first;
    2772              : //                      Edge * edgeTwo = epU.second;
    2773              : //
    2774              : //                      if( edgeOne == uncuttingLowDimEl )
    2775              : //                      {
    2776              : //                              shiftLowDimEl = edgeTwo;
    2777              : //                      }
    2778              : //                      else if( edgeTwo == uncuttingLowDimEl )
    2779              : //                      {
    2780              : //                              shiftLowDimEl = edgeOne;
    2781              : //                      }
    2782              : //                      else
    2783              : //                      {
    2784              : //                              UG_LOG("No edge found uncutting shift?" << std::endl);
    2785              : //                              UG_THROW("No edge found uncutting shift?" << std::endl);
    2786              : //                      }
    2787              : //
    2788              : //                      edgeWasFound++;
    2789              : //
    2790              : //              }
    2791              : //      }
    2792              : //
    2793              : //      if( edgeWasFound == 0 )
    2794              : //      {
    2795              : //              UG_LOG("NO shift edge " << std::endl);
    2796              : //              return false;
    2797              : //      }
    2798              : //      else if( edgeWasFound == 1 )
    2799              : //      {
    2800              : //              return true;
    2801              : //      }
    2802              : //      if( edgeWasFound > 1 )
    2803              : //      {
    2804              : //              UG_LOG("Many shift edges " << edgeWasFound << std::endl);
    2805              : //              return false;
    2806              : //      }
    2807              : 
    2808              :         UG_LOG("Cannot come here at this edge" << std::endl);
    2809              : 
    2810              :         return false;
    2811              : 
    2812            0 : }
    2813              : 
    2814              : //////////////////////////////////////////////////////////////////
    2815              : 
    2816              : template<typename ELMTYP>
    2817            0 : bool ArteExpandFracs3D::checkIfContentUnique( std::vector<ELMTYP> const & vecTest, std::vector<ELMTYP> & content, IndexType mandatoryDifferentElems )
    2818              : {
    2819            0 :         if( vecTest.size() == 0 )
    2820              :         {
    2821              :                 UG_LOG("zero vector testing nonsense" << std::endl);
    2822            0 :                 UG_THROW("zero vector testing nonsense" << std::endl);
    2823              :         }
    2824              : 
    2825            0 :         std::vector<ELMTYP> vecTestCop = vecTest; // copy
    2826              : 
    2827            0 :         while( vecTestCop.size() != 0 )
    2828              :         {
    2829            0 :                 ELMTYP elmCont = vecTestCop[0];
    2830              : 
    2831            0 :                 content.push_back(elmCont);
    2832              : 
    2833            0 :                 for( typename std::vector<ELMTYP>::iterator itEl = vecTestCop.begin(); itEl != vecTestCop.end(); )
    2834              :                 {
    2835            0 :                         ELMTYP elmTest = *itEl;
    2836              : 
    2837            0 :                         if( elmCont == elmTest )
    2838              :                         {
    2839              :                                 itEl = vecTestCop.erase(itEl);
    2840              :                         }
    2841              :                         else
    2842              :                                 ++itEl;
    2843              :                 }
    2844              : 
    2845              :         }
    2846              : 
    2847            0 :         return ( mandatoryDifferentElems == content.size() );
    2848            0 : }
    2849              : 
    2850              : //////////////////////////////////////////////////////////////////
    2851              : 
    2852              : template< bool FACES_HAVE_SAME_SUDO >
    2853            0 : bool ArteExpandFracs3D::fractFacesAreNeighboured( SegLimSidesFractFace const & fractFaceOne,
    2854              :                                                                                                   SegLimSidesFractFace const & fractFaceTwo,
    2855              :                                                                                                   Edge * & commonEdge
    2856              :                                                                                                 )
    2857              : {
    2858            0 :         commonEdge = nullptr; // general case
    2859              : 
    2860              :         bool facesHaveSameSudo = FACES_HAVE_SAME_SUDO;
    2861              : 
    2862              :         // exclude that the elements are the same
    2863              : 
    2864              :         Face * facOne = fractFaceOne.getManifElm();
    2865              :         Face * facTwo = fractFaceTwo.getManifElm();
    2866              : 
    2867            0 :         if( facOne == facTwo )
    2868              :         {
    2869              :                 UG_LOG("Faces coincide" << std::endl);
    2870            0 :                 return false;
    2871              :         }
    2872              : 
    2873              :         EdgePair const & edgesFacOne = fractFaceOne.getPairLowElm();
    2874              :         EdgePair const & edgesFacTwo = fractFaceTwo.getPairLowElm();
    2875              : 
    2876              :         Edge * edgeOneFrst = edgesFacOne.first;
    2877              :         Edge * edgeOneScnd = edgesFacOne.second;
    2878              : 
    2879              :         Edge * edgeTwoFrst = edgesFacTwo.first;
    2880              :         Edge * edgeTwoScnd = edgesFacTwo.second;
    2881              : 
    2882            0 :         bool edgeCondA = ( edgeOneFrst == edgeTwoFrst );
    2883            0 :         bool edgeCondB = ( edgeOneFrst == edgeTwoScnd );
    2884            0 :         bool edgeCondC = ( edgeOneScnd == edgeTwoFrst );
    2885            0 :         bool edgeCondD = ( edgeOneScnd == edgeTwoScnd );
    2886              : 
    2887              : 
    2888              :         bool fractFacsNeighbr = (    edgeCondA
    2889            0 :                                                           || edgeCondB
    2890              :                                                           || edgeCondC
    2891            0 :                                                           || edgeCondD
    2892              :                                                         );
    2893              : 
    2894              :         IndexType sudoOne = fractFaceOne.getSudo();
    2895              :         IndexType sudoTwo = fractFaceTwo.getSudo();
    2896              : 
    2897              :         bool sudosCoincide = ( sudoOne == sudoTwo );
    2898              : 
    2899            0 :         bool necessarySudoProperty = ( facesHaveSameSudo == sudosCoincide );
    2900              : 
    2901            0 :         bool neighbrsWithRequestedSudo = ( fractFacsNeighbr && necessarySudoProperty );
    2902              : 
    2903            0 :         if( neighbrsWithRequestedSudo )
    2904              :         {
    2905            0 :                 if( edgeCondA || edgeCondB )
    2906              :                 {
    2907            0 :                         commonEdge = edgeOneFrst;
    2908              :                 }
    2909            0 :                 else if( edgeCondC || edgeCondD )
    2910              :                 {
    2911            0 :                         commonEdge = edgeOneScnd;
    2912              :                 }
    2913              : 
    2914            0 :                 if( commonEdge == nullptr )
    2915              :                 {
    2916              :                         UG_LOG("COMMON NULL " << std::endl);
    2917            0 :                         UG_THROW("COMMON NULL " << std::endl);
    2918              :                 }
    2919              :                 else
    2920              :                 {
    2921            0 :                         UG_LOG("COORDINATES NOT NULL " << CalculateCenter( commonEdge, m_aaPos ) << std::endl );
    2922              :                 }
    2923              :         }
    2924              : 
    2925              :         return neighbrsWithRequestedSudo;
    2926              : }
    2927              : 
    2928              : 
    2929              : //////////////////////////////////////////////////////////////////
    2930              : 
    2931              : 
    2932              : #if 0
    2933              : bool ArteExpandFracs3D::detectEndingCrossingClefts()
    2934              : {
    2935              : //      bool unclosedFracFacesPresent = false;
    2936              : //
    2937              : //      for( VertexIterator iter = m_sel.begin<Vertex>(); iter != m_sel.end<Vertex>(); ++iter)
    2938              : //      {
    2939              : //              Vertex* vrt = *iter;
    2940              : //
    2941              : //              IndexType shiFraFac = shiftUnclosedFracFacesToUnclosedFractFaces( vrt );
    2942              : //
    2943              : //              UG_LOG("shifted frac faces at " << m_aaPos[vrt] << " -> " << shiFraFac << std::endl);
    2944              : //
    2945              : //              if( shiFraFac > 0 )
    2946              : //                      unclosedFracFacesPresent = true;
    2947              : //
    2948              : ////            constexpr bool d_highlightVrtcsWithShifts = false;
    2949              : ////
    2950              : ////            if( d_highlightVrtcsWithShifts )
    2951              : ////            {
    2952              : ////                    if( shiFraFac > 0 )
    2953              : ////                    {
    2954              : ////                            IndexType sudoNum = m_sh.num_subsets();
    2955              : ////
    2956              : ////                            m_sh.assign_subset(vrt, sudoNum );
    2957              : ////                    }
    2958              : ////            }
    2959              : //      }
    2960              : 
    2961              :         IndexType numEndingCrossingClefts = 0;
    2962              : 
    2963              :         std::vector<Face*> m_d_endingCrossingCleftFaces;
    2964              : 
    2965              :         std::vector<Vertex*> m_d_endingCrossingCleftVrtcs;
    2966              : 
    2967              : 
    2968              : //      for( VertexIterator iter = m_sel.begin<Vertex>(); iter != m_sel.end<Vertex>(); ++iter)
    2969              : //      {
    2970              : //              Vertex* vrt = *iter;
    2971              : //
    2972              : //
    2973              : //
    2974              : //      }
    2975              : 
    2976              : 
    2977              : 
    2978              :         // TODO FIXME unterscheide Faces entlang der expandierten Kreuzungskluft,
    2979              :         // mit 2 Knoten an Kreuzungspunkten, ein Knoten voll expandiert für beide subsets
    2980              :         // von solchen, die in der Luft hängen am Ende der Kluft, wo nur die durchgehende Kluft expandiert
    2981              : 
    2982              :         // TODO FIXME need to detect attached faces from the durchgehende cleft which gets expanded
    2983              :         // as specific structures needed also there
    2984              : 
    2985              :         // TODO FIXME auch die Kante, die an dem auslaufenden Face entlang geht im Schnitt mit dem ausgedehnten,
    2986              :         // per edge attachment markieren! bool
    2987              :         // und die anhängenden faces der kreuzenden durchgehenden Kluft ebenso markieren irgendwie per face attachment bool
    2988              : 
    2989              : 
    2990              : 
    2991              : 
    2992              : #if 1
    2993              : 
    2994              :         IndexType unclosedFracFacesFound = 0;
    2995              : 
    2996              :         for(size_t i_fi = 0; i_fi < m_fracInfos.size(); ++i_fi )
    2997              :         {
    2998              : 
    2999              :                 int fracIndSudo = m_fracInfos[i_fi].subsetIndex;
    3000              : 
    3001              :                 for( FaceIterator iter = m_sh.begin<Face>(fracIndSudo); iter != m_sh.end<Face>(fracIndSudo); ++iter )
    3002              :                 {
    3003              :                         Face* fac = *iter;
    3004              : 
    3005              :                         UG_LOG("Check for unclosed frac faces " << CalculateCenter(fac, m_aaPos) << std::endl);
    3006              : 
    3007              :                         if( m_aaMarkFaceHasUnclosedFracSideB[fac] )
    3008              :                         {
    3009              :                                 unclosedFracFacesFound++;
    3010              : 
    3011              : //                              m_sh.assign_subset( fac, m_sh.num_subsets());
    3012              :                         }
    3013              : 
    3014              :                 }
    3015              : 
    3016              :         }
    3017              : 
    3018              :         if( unclosedFracFacesFound > 0 ) // || unclosedFracFacesPresent )
    3019              :         {
    3020              :                 UG_LOG("unclosed Frac faces " << unclosedFracFacesFound << std::endl);
    3021              : //              return false;
    3022              :         }
    3023              : 
    3024              : //      return true;
    3025              : 
    3026              : 
    3027              :         //  wieso die ending crossing cleft faces nicht aus den Segmenten raus holen,
    3028              :         // und zwar aus den ungeschlossenen Faces, die im Segment liegen?
    3029              :         // müssen doch dieselben sein, dann sollte die komische Prozedur hier unnötig werden!!!
    3030              : 
    3031              : 
    3032              : //      UG_THROW("KÄSE" << std::endl);
    3033              : 
    3034              :         for(size_t i_fi = 0; i_fi < m_fracInfos.size(); ++i_fi )
    3035              :         {
    3036              :                 int fracIndSudo = m_fracInfos[i_fi].subsetIndex;
    3037              : 
    3038              :                 for( FaceIterator iter = m_sh.begin<Face>(fracIndSudo); iter != m_sh.end<Face>(fracIndSudo); iter++ )
    3039              :                 {
    3040              :                         Face* fac = *iter;
    3041              : 
    3042              :                         UG_LOG("Detect for unclosed ending cleft frac faces " << CalculateCenter(fac, m_aaPos) << std::endl);
    3043              : 
    3044              :                         if( m_aaMarkFaceHasUnclosedFracSideB[fac] )
    3045              :                         {
    3046              : 
    3047              :                                 // figure out the vertice(s) where the face is unclosed
    3048              :                                 // check if at one of these vertices, two fractures are crossing and one ending
    3049              :                                 // by checking if there are at least two segments as precondition, else no matter
    3050              : 
    3051              :                                 std::vector<Vertex *> assoVrt;
    3052              : 
    3053              :                                 CollectVertices(assoVrt, m_grid, fac);
    3054              : 
    3055              :                                 for( Vertex * vrt : assoVrt )
    3056              :                                 {
    3057              :                                         if( m_aaMarkVrtxHasUnclosedFracB[vrt] )
    3058              :                                         {
    3059              :                                                 VecSegmentVolElmInfo & vecSegVolElmInf = m_accsAttVecSegVolElmInfo[vrt];
    3060              : 
    3061              :                                                 if( vecSegVolElmInf.size() > 1 ) // expansion takes place here
    3062              :                                                 {
    3063              : //                                                      m_sh.assign_subset(fac,m_sh.num_subsets());
    3064              :                                                         numEndingCrossingClefts++;
    3065              :                                                         m_d_endingCrossingCleftFaces.push_back(fac);
    3066              :                                                         m_d_endingCrossingCleftVrtcs.push_back(vrt);
    3067              :                                                         // TODO FIXME vielleicht eine Klasse, wo die Faces und Vertices einer
    3068              :                                                         // jeweiligen ending Crossing Cleft Stelle zusammengefasst werden?
    3069              :                                                         // statt unabhängige Listen? gemeinsame Liste?
    3070              :                                                 }
    3071              : 
    3072              :                                         }
    3073              :                                 }
    3074              : 
    3075              : 
    3076              :                         }
    3077              : 
    3078              :                 }
    3079              : 
    3080              :         }
    3081              : 
    3082              : 
    3083              :         UG_LOG("detected ending crossing cleft faces " << numEndingCrossingClefts << std::endl);
    3084              : 
    3085              :         if( numEndingCrossingClefts == 0 )
    3086              :                 return true;
    3087              : 
    3088              :         // debug for ending crossing clefts
    3089              : 
    3090              :         for( Face * fac : m_d_endingCrossingCleftFaces )
    3091              :         {
    3092              :                 m_sh.assign_subset( fac, m_sh.num_subsets());
    3093              : 
    3094              :         }
    3095              : 
    3096              :         for( Vertex * vrt : m_d_endingCrossingCleftVrtcs )
    3097              :         {
    3098              :                 m_sh.assign_subset( vrt, m_sh.num_subsets());
    3099              :         }
    3100              : 
    3101              : #endif
    3102              : 
    3103              : 
    3104              :         return false;
    3105              : 
    3106              : 
    3107              : 
    3108              : }
    3109              : 
    3110              : #endif
    3111              : 
    3112              : ////////////////////////////////////////////////////////////////////
    3113              : 
    3114              : #if 0
    3115              : bool ArteExpandFracs3D::detectEndingCrossingClefts()
    3116              : {
    3117              : 
    3118              :         //  wieso die ending crossing cleft faces nicht aus den Segmenten raus holen,
    3119              :         // und zwar aus den ungeschlossenen Faces, die im Segment liegen?
    3120              :         // müssen doch dieselben sein, dann sollte die komische Prozedur hier unnötig werden!!!
    3121              : 
    3122              :         IndexType numEndingCrossingClefts = 0;
    3123              : 
    3124              :         std::vector<Face*> m_d_endingCrossingCleftFaces;
    3125              : 
    3126              :         std::vector<Vertex*> m_d_endingCrossingCleftVrtcs;
    3127              : 
    3128              : //      UG_THROW("KÄSE" << std::endl);
    3129              : 
    3130              :         for(size_t i_fi = 0; i_fi < m_fracInfos.size(); ++i_fi )
    3131              :         {
    3132              :                 int fracIndSudo = m_fracInfos[i_fi].subsetIndex;
    3133              : 
    3134              :                 for( FaceIterator iter = m_sh.begin<Face>(fracIndSudo); iter != m_sh.end<Face>(fracIndSudo); iter++ )
    3135              :                 {
    3136              :                         Face* fac = *iter;
    3137              : 
    3138              :                         UG_LOG("Detect for unclosed ending cleft frac faces " << CalculateCenter(fac, m_aaPos) << std::endl);
    3139              : 
    3140              :                         if( m_aaMarkFaceHasUnclosedFracSideB[fac] )
    3141              :                         {
    3142              : 
    3143              :                                 // figure out the vertice(s) where the face is unclosed
    3144              :                                 // check if at one of these vertices, two fractures are crossing and one ending
    3145              :                                 // by checking if there are at least two segments as precondition, else no matter
    3146              : 
    3147              :                                 std::vector<Vertex *> assoVrt;
    3148              : 
    3149              :                                 CollectVertices(assoVrt, m_grid, fac);
    3150              : 
    3151              :                                 for( Vertex * vrt : assoVrt )
    3152              :                                 {
    3153              :                                         if( m_aaMarkVrtxHasUnclosedFracB[vrt] )
    3154              :                                         {
    3155              :                                                 VecSegmentVolElmInfo & vecSegVolElmInf = m_accsAttVecSegVolElmInfo[vrt];
    3156              : 
    3157              :                                                 if( vecSegVolElmInf.size() > 1 ) // expansion takes place here
    3158              :                                                 {
    3159              : //                                                      m_sh.assign_subset(fac,m_sh.num_subsets());
    3160              :                                                         numEndingCrossingClefts++;
    3161              :                                                         m_d_endingCrossingCleftFaces.push_back(fac);
    3162              :                                                         m_d_endingCrossingCleftVrtcs.push_back(vrt);
    3163              :                                                         // TODO FIXME vielleicht eine Klasse, wo die Faces und Vertices einer
    3164              :                                                         // jeweiligen ending Crossing Cleft Stelle zusammengefasst werden?
    3165              :                                                         // statt unabhängige Listen? gemeinsame Liste?
    3166              :                                                 }
    3167              : 
    3168              :                                         }
    3169              :                                 }
    3170              : 
    3171              : 
    3172              :                         }
    3173              : 
    3174              :                 }
    3175              : 
    3176              :         }
    3177              : 
    3178              :         // TODO FIXME m_d_endingCrossingCleftVrtcs      m_d_endingCrossingCleftFaces globale member vielleicht?
    3179              : 
    3180              : #if 0
    3181              : //      for( VertexIterator iterV = m_sel.begin<Vertex>(); iterV != m_sel.end<Vertex>(); iterV++ )
    3182              :         for( Vertex * vrt : m_d_endingCrossingCleftVrtcs )
    3183              :         {
    3184              : //              Vertex * vrt = *iterV;
    3185              : 
    3186              :                 // search neigbours of ending crossing cleft faces
    3187              : 
    3188              :                 if( m_aaMarkVrtxHasUnclosedFracB[vrt] )
    3189              :                 {
    3190              :                         VecSegmentVolElmInfo const & vecSegVolElmInf = m_accsAttVecSegVolElmInfo[vrt];
    3191              : 
    3192              :                         for( SegmentVolElmInfo const & svei : vecSegVolElmInf )
    3193              :                         {
    3194              :                                 for( AttachedVolumeElemInfo const & attVolEI : svei )
    3195              :                                 {
    3196              :                                         VecAttachedFractFaceEdgeSudo vecAttFracFace = attVolEI.getVecFractManifElem();
    3197              :                                         // die sind alle von den echten das Segment begrenzenden Faces
    3198              : 
    3199              :                                         for( AttachedFractFaceEdgeSudo & afes : vecAttFracFace )
    3200              :                                         {
    3201              :                                                 Face * faceSegmLim = afes.getManifElm();
    3202              : 
    3203              :                                                 IndexType sudoSegmLim = afes.getSudo();
    3204              : 
    3205              :                                                 std::pair<Edge*,Edge*> const & edgePair = afes.getPairLowElm();
    3206              : 
    3207              :                                                 // figure out neighbours of ending crossing cleft faces at ending node
    3208              : 
    3209              :                                                 // rule out free edge
    3210              : 
    3211              :                                                 Edge * freeEdge = nullptr;
    3212              :                                                 Edge * boundedEdge = nullptr;
    3213              : 
    3214              :                                                 for( Face * eccf : m_d_endingCrossingCleftFaces )
    3215              :                                                 {
    3216              :                                                         if( FaceContains( eccf, vrt ) )
    3217              :                                                         {
    3218              :                                                                 if( eccf != fac )
    3219              :                                                                 {
    3220              :                                                                         if( FaceContains( eccf, edgePair.first ) || FaceContains( eccf, edgePair.second ) )
    3221              :                                                                         {
    3222              : 
    3223              :                                                                         }
    3224              :                                                                 }
    3225              :                                                         }
    3226              :                                                 }
    3227              : //                                              if( )
    3228              :                                         }
    3229              : 
    3230              :                                 }
    3231              : 
    3232              : 
    3233              :                         }
    3234              :                 }
    3235              :                 else
    3236              :                 {
    3237              :                         UG_LOG("only ending crossing cleft vertices allowed here" << std::endl);
    3238              :                         UG_THROW("only ending crossing cleft vertices allowed here" << std::endl);
    3239              :                         return false;
    3240              :                 }
    3241              : 
    3242              :         }
    3243              : 
    3244              : #endif
    3245              : 
    3246              : 
    3247              :         UG_LOG("detected ending crossing cleft faces " << numEndingCrossingClefts << std::endl);
    3248              : 
    3249              :         if( numEndingCrossingClefts == 0 )
    3250              :                 return true;
    3251              : 
    3252              :         // debug for ending crossing clefts
    3253              : 
    3254              :         for( Face * fac : m_d_endingCrossingCleftFaces )
    3255              :         {
    3256              :                 m_sh.assign_subset( fac, m_sh.num_subsets());
    3257              : 
    3258              :         }
    3259              : 
    3260              :         for( Vertex * vrt : m_d_endingCrossingCleftVrtcs )
    3261              :         {
    3262              :                 m_sh.assign_subset( vrt, m_sh.num_subsets());
    3263              :         }
    3264              : 
    3265              :         // TODO FIXME unterscheide Faces entlang der expandierten Kreuzungskluft,
    3266              :         // mit 2 Knoten an Kreuzungspunkten, ein Knoten voll expandiert für beide subsets
    3267              :         // von solchen, die in der Luft hängen am Ende der Kluft, wo nur die durchgehende Kluft expandiert
    3268              : 
    3269              :         // TODO FIXME need to detect attached faces from the durchgehende cleft which gets expanded
    3270              :         // as specific structures needed also there
    3271              : 
    3272              :         // TODO FIXME auch die Kante, die an dem auslaufenden Face entlang geht im Schnitt mit dem ausgedehnten,
    3273              :         // per edge attachment markieren! bool
    3274              :         // und die anhängenden faces der kreuzenden durchgehenden Kluft ebenso markieren irgendwie per face attachment bool
    3275              : 
    3276              :         return false;
    3277              : }
    3278              : 
    3279              : #endif
    3280              : 
    3281              : //////////////////////////////////////////////////////////////////
    3282              : 
    3283              : // TODO FIXME diese Funktion macht nur in Teilen das richtige
    3284              : // die ungeschlossenen Faces zeigen an, dass eine Kluft hier endet
    3285              : // wird bisher nicht berücksichtigt
    3286              : // irgendwie muss das markiert werden, damit die Kluft, die zu Ende geht.
    3287              : // im Durchstich trotzdem berücksichtigt wird
    3288            0 : ArteExpandFracs3D::IndexType ArteExpandFracs3D::shiftUnclosedFracFacesToUnclosedFractFaces( Vertex * const & vrt )
    3289              : {
    3290              :         IndexType shiftedFracFaces = 0;
    3291              : 
    3292              :         // TODO FIXME still to be implemented - shift those fracture faces which appear
    3293              :         // twice in the segment volumes, i.e. which are part of two volumes of the
    3294              :         // segment, i.e. which touch each other, but are not closed,
    3295              :         // shift them to the general faces, to avoid that they are taken into account
    3296              :         // for the creation of new vertices, they must not have any influence
    3297              : 
    3298              :         UG_LOG("SHIFT FRAC 2 GENER" << std::endl);
    3299              : 
    3300            0 :         VecSegmentVolElmInfo & vecSegVolElmInf = m_accsAttVecSegVolElmInfo[vrt];
    3301              : 
    3302              :         IndexType segmentNumber = 0;
    3303              : 
    3304              : 
    3305              : 
    3306            0 :         for( SegmentVolElmInfo & svei : vecSegVolElmInf )
    3307              :         {
    3308              : //              VecAttachedFractFaceEdgeSudo vecAttFractList;
    3309              : 
    3310            0 :                 for( AttachedVolumeElemInfo & attVolEIOne : svei )
    3311              :                 {
    3312              :                         VecAttachedFractFaceEdgeSudo vecAttFracFaceOne = attVolEIOne.getVecFractManifElem();
    3313              : 
    3314            0 :                         for( AttachedVolumeElemInfo & attVolEITwo : svei )
    3315              :                         {
    3316            0 :                                 if( ! attVolEIOne.hasSameFulldimElem( attVolEITwo ) )
    3317              :                                 {
    3318              :                                         VecAttachedFractFaceEdgeSudo vecAttFracFaceTwo = attVolEITwo.getVecFractManifElem();
    3319              : 
    3320            0 :                                         for( AttachedFractFaceEdgeSudo & afesOne : vecAttFracFaceOne )
    3321              :                                         {
    3322            0 :                                                 for( AttachedFractFaceEdgeSudo & afesTwo : vecAttFracFaceTwo )
    3323              :                                                 {
    3324              :                                                         if( afesOne.testIfEquals( afesTwo ) )
    3325              :                                                         {
    3326              :                                                                 // beide in die generellen Faces verschieben!
    3327              : 
    3328            0 :                                                                 if( ! attVolEIOne.searchFractManifElem( afesOne, true ) )
    3329              :                                                                 {
    3330            0 :                                                                         UG_THROW("im einen nicht gefunden "<< std::endl);
    3331              :                                                                 }
    3332              : 
    3333            0 :                                                                 if( ! attVolEITwo.searchFractManifElem( afesTwo, true ) )
    3334              :                                                                 {
    3335            0 :                                                                         UG_THROW("im anderen nicht gefunden "<< std::endl);
    3336              :                                                                 }
    3337              : 
    3338            0 :                                                                 shiftedFracFaces++;
    3339              : 
    3340              : //                                                              Face * unclosedFace = afesOne.getManifElm();
    3341              : //                                                              // tested if same as that one from afesTwo
    3342              : //
    3343              : ////                                                            m_aaMarkFaceHasUnclosedFracSideB[ unclosedFace ] = true;
    3344              : //
    3345              : //                                                              UG_LOG("unclosed face " << CalculateCenter( unclosedFace, m_aaPos ) << std::endl);
    3346              : 
    3347              : //                                                              m_sh.assign_subset( unclosedFace, m_sh.num_subsets());
    3348              : 
    3349              : //                                                              m_aaMarkVrtxHasUnclosedFracB[vrt] = true;
    3350              : 
    3351              :                                                                 //  added vertex attachment that knows if at vertex there is an unclosed fracture
    3352              : 
    3353              : 
    3354              :                                                         }
    3355              :                                                 }
    3356              :                                         }
    3357            0 :                                 }
    3358              :                         }
    3359              : 
    3360              : 
    3361              : //                      for( AttachedFractFaceEdgeSudo & affe : nextVolFacs )
    3362              : //                      {
    3363              : //                              vecAttFractList.push_back( affe );
    3364              : //                      }
    3365              :                         // create a full chain of all fracture faces, and if one appears twice, shift it for both
    3366              :                         // volumes where it is in to the general faces, i.e. count after establishing, and when twice,
    3367              :                         // then shift
    3368            0 :                 }
    3369              :         }
    3370              : 
    3371              :         UG_LOG("SHIFT FRAC 2 GENER" << std::endl);
    3372              : 
    3373              : 
    3374              : 
    3375            0 :         return shiftedFracFaces;
    3376              : }
    3377              : 
    3378              : //////////////////////////////////////////////////////////////////
    3379              : 
    3380              : 
    3381              : 
    3382            0 : bool ArteExpandFracs3D::seletForSegmented()
    3383              : {
    3384            0 :         for( VertexIterator iter = m_sel.begin<Vertex>(); iter != m_sel.end<Vertex>(); ++iter)
    3385              :         {
    3386              :                 Vertex* vrt = *iter;
    3387              : 
    3388              : #if 0
    3389              : 
    3390              :                 bool wahl = true;
    3391              : 
    3392              :                 // TODO FIXME
    3393              :                 // hier den Stammi-bene Algorithmus einfügen
    3394              :                 // Search the merged manifold interatively between each basic element
    3395              :                 // dazu noch für boundary faces ein eigenes member einführen,
    3396              :                 // das vom Typ General statt fracture manifold ist, aber sonst wie general
    3397              :                 // später wirken die boundary faces wie eine fracture, die aber
    3398              :                 // um den Wert null nur verschoben wird
    3399              :                 // die Anzahl der Segmente bestimmt, ob der Vertex gewählt wird
    3400              :                 // damit er gewählt wird, muss mehr als ein Segment vorhanden sein
    3401              : 
    3402              :                 auto & vrtxFracPrps = m_aaMarkVrtVFP[ vrt ];
    3403              : 
    3404              : //              bool isBnd = m_aaMarkVrtVFP[ vrt ].getIsBndFracVertex();
    3405              :                 bool isBnd = vrtxFracPrps.getIsBndFracVertex();
    3406              : //              auto numCrosFrac = m_aaMarkVrtVFP[ vrt ].getNumberFracEdgesInVertex();
    3407              : 
    3408              :                 VertxFracPropts::VrtxFracStatus vfpStatus =  vrtxFracPrps.getVrtxFracStatus();
    3409              : 
    3410              :                 if( vfpStatus == VertxFracPropts::noFracSuDoAtt )
    3411              :                         UG_THROW("vertex selected and no frac " << std::endl);
    3412              : 
    3413              :                 // TODO FIXME das ist richtig für den 2D Fall, aber passt das auch im 3D Fall???? nein, da SudoFrac Zahl nötig
    3414              : //              if( ! isBnd && numCrosFrac == 1 )
    3415              : //              if( ! isBnd && vfpStatus == VertxFracPropts::oneFracSuDoAtt && )
    3416              :                 // TODO FIXME was, wenn ein Teil geschlossen ist der fractures, und ein anderer nicht???
    3417              :                 //static_assert(false);
    3418              : 
    3419              : 
    3420              :                 // bestimmen, ob die vertizes der fracture vertizes von ihrer subdomain komplett umzingelt werden
    3421              :                 // muss vor  hier geklärt werden!!!
    3422              : 
    3423              : //              VecPairSudoBool sudoIsSourrounded;
    3424              : 
    3425              : 
    3426              : 
    3427              :                 bool allClosed = false;
    3428              : 
    3429              :                 allClosed = isVrtxSurroundedByFracFaces( vrt, vrtxFracPrps ); //, sudoIsSourrounded );
    3430              : //                      // case boundary: figure out if the vertex is surrounded by frac faces of which two end in
    3431              : //                      // boundary edges, similar the case when the boundary face has itself two
    3432              : //                      // boundary edges, where the vertex is connected to both of them, then it is easy
    3433              : 
    3434              : //              if( ! allClosed )
    3435              : //                      return false;
    3436              : 
    3437              : //              return true;
    3438              : 
    3439              : //              if( ! isBnd )
    3440              : //              {
    3441              : //                      UG_LOG("test if closed" << std::endl);
    3442              : //
    3443              : ////                    m_sh.assign_subset(vrt,m_sh.num_subsets());
    3444              : //
    3445              : ////                    UG_LOG("test if closed assign" << std::endl);
    3446              : //
    3447              : //
    3448              : //              }
    3449              : //              else
    3450              : //              {
    3451              : //
    3452              : //
    3453              : //
    3454              : ////                    allClosed =
    3455              : //              }
    3456              : //              // TODO FIXME auch bei einer boundary muss das gemacht werden!
    3457              : 
    3458              :                 UG_LOG("getestet if closed " << m_aaPos[vrt] << std::endl);
    3459              : 
    3460              : 
    3461              : //              return true;
    3462              : 
    3463              :                 if( allClosed == vrtxFracPrps.getInfoAllFracturesSameClosedState<false>() )
    3464              :                         UG_THROW("da ist was schief gegangen " << std::endl);
    3465              : 
    3466              :                 // TODO FIXME ist das so richtig? kann sein, dass das zu vereinfacht ist!!!!!
    3467              :                 // sudo is suourrounded muss übertragen werden TODO FIXME
    3468              : //              if( ! isBnd && vrtxFracPrps.getInfoAllFracturesSameClosedState<false>() )
    3469              :                 // das !isBnd im 2D Fall wichtig, hier bestimmt auch, wie verallgemeinern?
    3470              :                 // bei mehreren subdoms eventuell komplizierter, kommt aber hoffentlich am Rand nicht vor......
    3471              :                 if( vrtxFracPrps.getInfoAllFracturesSameClosedState<false>() )
    3472              :                 {
    3473              :                         wahl = false;
    3474              :                 }
    3475              : 
    3476              : #else
    3477              : 
    3478              :                 VecSegmentVolElmInfo & vecSegVolElmInf = m_accsAttVecSegVolElmInfo[vrt];
    3479              : 
    3480              :                 auto & vrtxFracPrps = m_aaMarkVrtVFP[ vrt ];
    3481              : 
    3482              : //              bool isBnd = m_aaMarkVrtVFP[ vrt ].getIsBndFracVertex();
    3483              :                 bool isBnd = vrtxFracPrps.getIsBndFracVertex();
    3484              : 
    3485              : //              bool wahl = ( vecSegVolElmInf.size() > 1 );
    3486              : //              bool wahl = ( vecSegVolElmInf.size() > 1 && ! isBnd );
    3487            0 :                 bool wahl = ( vecSegVolElmInf.size() > 1 );
    3488              :                 // TODO FIXME danach vielleicht auch fuer boundary wieder selektieren
    3489              :                 // sobald die Boundary Behandlung wie Pseudo Fracture mit Expansion null
    3490              :                 // aber solange die bounaries nicht behandelt werden, führt
    3491              :                 // die Selektion der Boundary Vertizes zu Problemen
    3492              : 
    3493              : #endif
    3494              : 
    3495              : 
    3496              : //              UG_LOG("SELEKTIERE " << m_aaPos[vrt] << " -> " << vrtxFracPrps.getInfoAllFracturesSameClosedState<false>() << std::endl);
    3497              : 
    3498            0 :                 UG_LOG("SELEKTIERE " << m_aaPos[vrt] << " -> " << wahl << std::endl);
    3499              : 
    3500              : 
    3501              :                 // was, wenn numCrossFrac == 0 ist?
    3502              :                 // wieso werden die boundary vrt ausgeschlossen, oder sollen die nicht ausgeschlossen werden?
    3503              :                 // schon im 2D Fall unklar, hier noch wirrer!!! TODO FIXME
    3504              : 
    3505            0 :                 if( wahl )
    3506              : //              if( m_aaMarkVrtVFP[vrt].getNumberFracEdgesInVertex() > 1 ) // TODO FIXME stimmt das so?
    3507              :                 {
    3508              :                         //      select all associated edges, faces and volumes
    3509            0 :                         m_sel.select( m_grid.associated_edges_begin(vrt), m_grid.associated_edges_end(vrt) );
    3510            0 :                         m_sel.select( m_grid.associated_faces_begin(vrt), m_grid.associated_faces_end(vrt) );
    3511            0 :                         m_sel.select( m_grid.associated_volumes_begin(vrt), m_grid.associated_volumes_end(vrt) );
    3512              : 
    3513              :                         std::vector<Edge*> assoEdg;
    3514              :                         std::vector<Face*> assoFac;
    3515              : //                      std::vector<Volume*> assoVol;
    3516              : //                      VecAttachedVolumeElemInfo assoVolElemInfo;
    3517              : 
    3518            0 :                         for( std::vector<Edge *>::iterator iterEdg = m_grid.associated_edges_begin(vrt);
    3519            0 :                                                                                            iterEdg != m_grid.associated_edges_end(vrt);
    3520              :                                                                                            iterEdg++ )
    3521              :                         {
    3522            0 :                                 assoEdg.push_back(*iterEdg);
    3523              :                         }
    3524              : 
    3525            0 :                         for( std::vector<Face *>::iterator iterFac = m_grid.associated_faces_begin(vrt);
    3526            0 :                                                                                            iterFac != m_grid.associated_faces_end(vrt);
    3527              :                                                                                            iterFac++ )
    3528              :                         {
    3529            0 :                                 assoFac.push_back(*iterFac);
    3530              :                         }
    3531              : 
    3532              :                         // TODO FIXME das nach oben verschieben, wo der Stammi Bene Algo sein soll
    3533              :                         // die asso edges und faces brauchen wir vielleicht gar nicht
    3534              :                         // bzw asso edges und asso faces können hier bleiben wo gewählt wird
    3535              :                         // die assoVolElemInfo wird schon oben erzeugt vor der Wahl
    3536              :                         // und dann wird die danach folgende Loop Info
    3537              : //                      for( std::vector<Volume *>::iterator iterVol = m_grid.associated_volumes_begin(vrt);
    3538              : //                                                                                               iterVol != m_grid.associated_volumes_end(vrt);
    3539              : //                                                                                               iterVol++ )
    3540              : //                      {
    3541              : //                              assoVol.push_back(*iterVol);
    3542              : //
    3543              : //                              AttachedVolumeElemInfo avei(*iterVol);
    3544              : //
    3545              : //                              assoVolElemInfo.push_back(avei);
    3546              : //                      }
    3547              : 
    3548            0 :                         m_aaVrtInfoAssoEdges[vrt] = assoEdg;
    3549            0 :                         m_aaVrtInfoAssoFaces[vrt] = assoFac;
    3550              : //                      m_aaVrtInfoAssoVols[vrt] = assoVol;
    3551              : //                      m_aaVolElmInfo[vrt] = assoVolElemInfo;
    3552              : 
    3553            0 :                 }
    3554              :         }
    3555              : 
    3556              :         UG_LOG("vertex Infos Runde eins fertig " << std::endl);
    3557              : 
    3558              : #if 0
    3559              :         // Voraussetzung  FÜR StammiBene Aufrufung
    3560              :         // Stammi-Bene-Vorbereitung
    3561              :         for( VertexIterator iter = m_sel.begin<Vertex>(); iter != m_sel.end<Vertex>(); ++iter)
    3562              :         {
    3563              :                 Vertex* vrt = *iter;
    3564              : 
    3565              : //              std::vector<Volume*> & attVol = m_aaVrtInfoAssoVols[vrt];
    3566              : 
    3567              :                 auto & vrtxFracPrps = m_aaMarkVrtVFP[ vrt ];
    3568              : 
    3569              :                 VecAttachedFractFaceEdgeSudo vecAttFacEdgSudo = vrtxFracPrps.getAllAttachedFractElems();
    3570              : 
    3571              :                 auto & vecVolElmInfo = m_aaVolElmInfo[vrt];
    3572              : 
    3573              :                 // TODO FIXME eigentlich eine Dummheit, das auf zu teilen in ein VolElemInfo und ein VrtInfoAssoVols
    3574              :                 // denn die InfoAssoVols haben als Info nur die Volumen, die VolElmInfos haben die Volumen
    3575              :                 // und noch viel mehr Infos zu den Faces und den Edges....
    3576              :                 // mittelfristig die m_aaVrtInfoAssoVols abschaffen und alles auf die AttachedFullDimElemInfo
    3577              :                 // übertragen, dann geht der folgende Loop gleich über den Vektor darüber, bzw. gleichbedeutend
    3578              :                 // über m_aaVolElmInfo
    3579              : //              for( auto & vol : attVol )
    3580              :                 for( AttachedVolumeElemInfo & attVolElmInfo : vecVolElmInfo )
    3581              :                 {
    3582              : //                      AttachedVolumeElemInfo attVolElmInfo( vol );
    3583              :                         Volume * vol = attVolElmInfo.getFulldimElem();
    3584              : 
    3585              :                         // add those faces which are fracture faces
    3586              :                         for( auto & afes : vecAttFacEdgSudo )
    3587              :                         {
    3588              :                                 attVolElmInfo.addFractManifElem(afes, m_grid);
    3589              :                         }
    3590              : 
    3591              :                         // add those faces which are NOT fracture faces, assign them arbitraryly subdomain  -1
    3592              :                         // to indicate that they are not from the manifold, independent of their subdomain
    3593              : 
    3594              :                         // collect all volume faces which incorporate the vertex
    3595              : 
    3596              :                         std::vector<Face*> volFacesContainingVrtx;
    3597              : 
    3598              :                         for( IndexType iFac = 0; iFac < vol->num_faces(); iFac++ )
    3599              :                         {
    3600              :                                 Face * fac = m_grid.get_face(vol,iFac);
    3601              : 
    3602              :                                 if( FaceContains( fac, vrt ) )
    3603              :                                 {
    3604              :                                         volFacesContainingVrtx.push_back( fac );
    3605              :                                 }
    3606              :                         }
    3607              : 
    3608              :                         for( auto const & fac : volFacesContainingVrtx )
    3609              :                         {
    3610              :                                 // get the edges of the face connected to the vertex
    3611              : 
    3612              :                                 std::vector<Edge*> vecEdgesFaceVrtx;
    3613              : 
    3614              :                                 // need to be two edges always, check
    3615              : 
    3616              :                                 for( IndexType iEdge = 0; iEdge < fac->num_edges(); iEdge++ )
    3617              :                                 {
    3618              :                                         Edge * edg = m_grid.get_edge(fac,iEdge);
    3619              : 
    3620              :                                         if( EdgeContains(edg,vrt) )
    3621              :                                         {
    3622              :                                                 vecEdgesFaceVrtx.push_back(edg);
    3623              :                                         }
    3624              :                                 }
    3625              : 
    3626              :                                 if( vecEdgesFaceVrtx.size() != 2 )
    3627              :                                 {
    3628              :                                         UG_LOG("edge number Unsinn " << vecEdgesFaceVrtx.size() << std::endl);
    3629              :                                         UG_THROW("edge number Unsinn " << vecEdgesFaceVrtx.size() << std::endl);
    3630              :                                         return false;
    3631              :                                 }
    3632              : 
    3633              :                                 EdgePair edgesFaceVrtx( vecEdgesFaceVrtx[0], vecEdgesFaceVrtx[1] );
    3634              : 
    3635              :                                 // test the subdomain first, if from the subdomains of the cleft manifolds
    3636              : 
    3637              :                                 IndexType sudoThisFace = m_sh.get_subset_index(fac);
    3638              : 
    3639              :                                 std::vector<IndexType> const & sudoList = vrtxFracPrps.getSudoList();
    3640              : 
    3641              :                                 // test if sudo of face belongs to the fracture face subdom list
    3642              : 
    3643              :                                 bool belongsToFracFaceSudo = false;
    3644              : 
    3645              :                                 for( auto const & sudoFrac : sudoList )
    3646              :                                 {
    3647              :                                         if( sudoFrac == sudoThisFace )
    3648              :                                         {
    3649              :                                                 belongsToFracFaceSudo = true;
    3650              :                                                 break;
    3651              :                                         }
    3652              :                                 }
    3653              : 
    3654              : 
    3655              :                                 if( belongsToFracFaceSudo )
    3656              :                                 {
    3657              :                                         // if it belongs, construct it again and test if it already belongs to the fracture faces
    3658              :                                         // MUST be already part of the list, else major error appeared!
    3659              : 
    3660              :                                         AttachedFractFaceEdgeSudo afesTest( fac, edgesFaceVrtx, sudoThisFace );
    3661              : 
    3662              :                                         if( attVolElmInfo.addFractManifElem( afesTest, m_grid ) )
    3663              :                                         {
    3664              :                                                 UG_LOG("manifold element already contained!" << std::endl);
    3665              :                                                 UG_THROW("manifold element already contained!" << std::endl);
    3666              :                                                 return false;
    3667              :                                         }
    3668              : 
    3669              :                                         // nothing to do, already added before hoffentlich
    3670              : 
    3671              :                                 }
    3672              :                                 else
    3673              :                                 {
    3674              :                                         // zeitweilig fehlten alle Faces, die keine fractures sind
    3675              :                                         // die müssen noch irgendwie als nicht-fracture-faces auch dazu gefügt werden
    3676              :                                         // die sind in den attached volumes schon enthalten,
    3677              :                                         // Frage: wie prüfen, dass die gar keine fractures sind, die Infos sollten bekannt sein.....
    3678              :                                         // wichtig auch, dass nur die faces dazu kommen, die den Vertex enthalten!!!
    3679              :                                         // irgendwas von der Art "nonFractureFaceInfos" oder sowas dazu hängen, mit Info
    3680              :                                         // ob schon getouched oder noch nicht.....
    3681              : 
    3682              : 
    3683              :                                         // we construct the attached manifold, given that it is NOT a fracture manifold
    3684              : 
    3685              :                                         // notwendig auch, dass es eine Markierungsmöglichkeit gibt dafür, ob
    3686              :                                         // ein face bei der nächsten weiter inneren Runde quasi äussere Begrenzung sein muss
    3687              :                                         // gilt sowohl für fracture faces, die können das in erster Runde auch sein am Ende
    3688              :                                         // der Runde, sowie danach nur noch für nicht-fracture-faces
    3689              : 
    3690              :                                         AttachedGenerFaceEdgeSudo afesAdd( fac, edgesFaceVrtx );
    3691              : 
    3692              :                                         attVolElmInfo.addGenerManifElem( afesAdd, m_grid );
    3693              : 
    3694              :                                 }
    3695              : 
    3696              :                         }
    3697              : 
    3698              :                 }
    3699              :         }
    3700              : #endif
    3701              : 
    3702              :         UG_LOG("vertex Infos Runde eins fertig Volumen auch" << std::endl);
    3703              : 
    3704            0 :         return true;
    3705              : }
    3706              : 
    3707            0 : bool ArteExpandFracs3D::stasiAlgo( Vertex * const & oldVrt )
    3708              : {
    3709              : 
    3710            0 :         UG_LOG("Stasi start " << m_aaPos[oldVrt] << std::endl);
    3711              :         // TODO FIXME übernehmen von loop2EstablishNewVertices und establishNewVertices
    3712              :         // plus Boundary faces ähnlich Fracture
    3713              :         // am Ende die in Segment verbundenen offenen Fracture Faces verschwinden lassen
    3714              :         // Segmente erstellen Ziel hier, aber auch raus finden, ob es mehr als eines gibt
    3715              :         // oder ob es offen ist, wegen wahl
    3716              : 
    3717            0 :         vector3 posOldVrt = m_aaPos[oldVrt];
    3718              : 
    3719            0 :         UG_LOG("vertex at " << posOldVrt << std::endl);
    3720              : 
    3721            0 :         VecSegmentVolElmInfo & vecSegVolElmInfo = m_accsAttVecSegVolElmInfo[oldVrt];
    3722              : 
    3723              :         auto & vrtxFracPrps = m_aaMarkVrtVFP[ oldVrt ];
    3724              : 
    3725              :         bool isBndryVrtx = vrtxFracPrps.getIsBndFracVertex();
    3726              : 
    3727              :         UG_LOG("under construction Tetrahedra limited Stasi Algo" << std::endl);
    3728              : 
    3729              : //      VecVertFracTrip const & vecVertFracTrip = m_aaVrtInfoFraTri[oldVrt];
    3730              : 
    3731              :         VecAttachedVolumeElemInfo assoVolElemInfo;
    3732              : 
    3733              :         int bndryFacsFnd = 0;
    3734              : 
    3735            0 :         for( std::vector<Volume *>::iterator iterVol = m_grid.associated_volumes_begin(oldVrt);
    3736            0 :                                                                                  iterVol != m_grid.associated_volumes_end(oldVrt);
    3737              :                                                                                  iterVol++ )
    3738              :         {
    3739            0 :                 Volume * vol = *iterVol;
    3740              : 
    3741              :                 AttachedVolumeElemInfo avei(vol);
    3742              : 
    3743            0 :                 bndryFacsFnd += prepareStasi(oldVrt, avei);
    3744              : 
    3745            0 :                 assoVolElemInfo.push_back(avei);
    3746            0 :         }
    3747              : 
    3748            0 :         if( isBndryVrtx && bndryFacsFnd == 0 )
    3749              :         {
    3750              :                 UG_LOG("Boundary vertex with no boundary faces adjoint" << std::endl);
    3751            0 :                 UG_THROW("Boundary vertex with no boundary faces adjoint" << std::endl);
    3752              :                 return false;
    3753              :         }
    3754              : 
    3755              : 
    3756              : //      if( vrtxFracPrps.getIsBndFracVertex() )
    3757              : //      {
    3758              : //              for( AttachedVolumeElemInfo ave : assoVolElemInfo )
    3759              : //              {
    3760              : //                      UG_LOG("BONDVERT " << m_aaPos[oldVrt] << " -> " << ave.getVecBndryManifElem().size()  << std::endl);
    3761              : //                      if(  ave.getVecBndryManifElem().size() == 0 )
    3762              : //                      {
    3763              : //                              UG_THROW("VERLUST" << std::endl);
    3764              : //                      }
    3765              : //              }
    3766              : //      }
    3767              : 
    3768              :         // von copy und paste angepasst, die unsinnige Verdopplung von vecAttVolElemInfo und assoVolElemInfo
    3769              :         // vielleicht noch entfernen
    3770              :         VecAttachedVolumeElemInfo const & vecAttVolElemInfo = assoVolElemInfo; // m_aaVolElmInfo[oldVrt];
    3771              : 
    3772            0 :         VecAttachedVolumeElemInfo vecAttVolElemInfoCop = vecAttVolElemInfo; // echte KOPIE
    3773              : 
    3774              :         VecAttachedVolumeElemInfo reconstructedVecAttVolElmInf;
    3775              : 
    3776              :                 /*
    3777              :                  * While Schleifen aufbauen für den
    3778              :                  * Search the adjacent surface interatively - Algorithmus
    3779              :                  * (Stasi Algorithmus)
    3780              :                  *
    3781              :                  */
    3782              : 
    3783              :         IndexType d_segmenteErledigt = 0;
    3784              : 
    3785            0 :         while( vecAttVolElemInfoCop.size() != 0 )
    3786              :         {
    3787              :                 SegmentVolElmInfo segmentAVEI;
    3788              : 
    3789              :                 AttachedVolumeElemInfo & startVolInfoThisSegment = vecAttVolElemInfoCop[0];
    3790              : 
    3791              :                 startVolInfoThisSegment.markIt();
    3792              : 
    3793              :                 Volume * volSta = startVolInfoThisSegment.getFulldimElem();
    3794              : 
    3795              :                 vector3 center;
    3796              : 
    3797            0 :                 if( volSta != nullptr )
    3798            0 :                         center = CalculateCenter(volSta,m_aaPos);
    3799              : 
    3800              : //              UG_LOG("volume center " << center << std::endl );
    3801              : 
    3802              :                 int d_loopsDone = 0;
    3803              : 
    3804            0 :                 while( vecAttVolElemInfoCop.size() != 0 )
    3805              :                 {
    3806              :                         // count number of marked elements
    3807              :                         IndexType numMarkedElems = 0;
    3808              :                         IndexType markPoint = 0;
    3809              : 
    3810              : //                      IndexType lastMarkPt = 0;
    3811              :                         IndexType startIndexInner = 0;
    3812              : 
    3813            0 :                         for( AttachedVolumeElemInfo const & volElInfCop : vecAttVolElemInfoCop )
    3814              :                         {
    3815            0 :                                 if( volElInfCop.isMarked() )
    3816              :                                 {
    3817              :                                         Volume * vol = volElInfCop.getFulldimElem();
    3818              : //                                      m_sh.assign_subset(vol, m_sh.num_subsets());
    3819              : 
    3820            0 :                                         vector3 center = CalculateCenter(vol,m_aaPos);
    3821              : 
    3822              : //                                      UG_LOG("DAS ZENTRUM " << numMarkedElems << " -> " << center << std::endl);
    3823              : 
    3824              :                                         startIndexInner = markPoint;
    3825            0 :                                         numMarkedElems++;
    3826              : 
    3827              :                                 }
    3828              : 
    3829            0 :                                 markPoint++;
    3830              :                         }
    3831              : 
    3832              :                         UG_LOG("LOOPS DONE " << numMarkedElems << std::endl);
    3833              : 
    3834            0 :                         if( numMarkedElems == 0 )
    3835              :                                 break;
    3836              : 
    3837              : //                      int startIndexInner = -1;
    3838              : //
    3839              : //                      for( int i = 0; i < vecAttVolElemInfoCop.size(); i++ )
    3840              : //                      {
    3841              : //                              AttachedVolumeElemInfo vi = vecAttVolElemInfoCop[i];
    3842              : //
    3843              : //                              Volume * vo = vi.getFulldimElem();
    3844              : //
    3845              : //                              vector3 center = CalculateCenter(vo,m_aaPos);
    3846              : //
    3847              : //                              UG_LOG("DAS ZENTRUM ZAHL VOR " << i << " -> " <<  center << std::endl);
    3848              : //
    3849              : //                              if( vi.isMarked() )
    3850              : //                                      startIndexInner = i;
    3851              : //                      }
    3852              : //
    3853              : //                      if( startIndexInner < 0 )
    3854              : //                      {
    3855              : //                              UG_THROW("kein Anfang gefunden " << std::endl);
    3856              : //                      }
    3857              : //
    3858              : //#if 0
    3859              : //                      IndexType startIndexInner = markPoint - 1;
    3860              : //#endif
    3861            0 :                         AttachedVolumeElemInfo startVolInfoMarkLoop = vecAttVolElemInfoCop[startIndexInner];
    3862              : 
    3863              :                         Volume * stattVoll = startVolInfoMarkLoop.getFulldimElem();
    3864              : 
    3865            0 :                         vector3 centerX = CalculateCenter(stattVoll,m_aaPos);
    3866              : 
    3867            0 :                         UG_LOG("DAS ZENTRUM DANACH STASI" << startIndexInner << " -> " <<  centerX << std::endl);
    3868              : 
    3869              : //                      m_sh.assign_subset(stattVoll, m_sh.num_subsets());
    3870              : #if 0
    3871              :                         for( int i = 0; i < vecAttVolElemInfoCop.size(); i++ )
    3872              :                         {
    3873              :                                 AttachedVolumeElemInfo vi = vecAttVolElemInfoCop[i];
    3874              : 
    3875              :                                 Volume * vo = vi.getFulldimElem();
    3876              : 
    3877              :                                 vector3 center = CalculateCenter(vo,m_aaPos);
    3878              : 
    3879              :                                 UG_LOG("DAS ZENTRUM ZAHL " << i << " -> " <<  center << std::endl);
    3880              : 
    3881              :                         }
    3882              : #endif
    3883            0 :                         for( AttachedVolumeElemInfo const & possibleOrigVolInfo : vecAttVolElemInfo )
    3884              :                         {
    3885            0 :                                 if( possibleOrigVolInfo.hasSameFulldimElem( startVolInfoMarkLoop ) )
    3886              :                                 {
    3887            0 :                                         segmentAVEI.push_back(possibleOrigVolInfo);
    3888            0 :                                         reconstructedVecAttVolElmInf.push_back(possibleOrigVolInfo);
    3889              :                                         break;
    3890              :                                 }
    3891              :                         }
    3892              : 
    3893              :                         vecAttVolElemInfoCop.erase( vecAttVolElemInfoCop.begin() + startIndexInner );
    3894              : 
    3895              : //                      if( d_loopsDone == 1 )
    3896              : //                              return false;
    3897              : 
    3898            0 :                         for( VecAttachedVolumeElemInfo::iterator aveiIt = vecAttVolElemInfoCop.begin();
    3899            0 :                                                                                                          aveiIt < vecAttVolElemInfoCop.end();
    3900              :                                                                                                          aveiIt++
    3901              :                         )
    3902              :                         {
    3903              :                                 AttachedVolumeElemInfo & possibleNeighbour = *aveiIt;
    3904              : 
    3905            0 :                                 if( possibleNeighbour.hasSameFulldimElem( startVolInfoMarkLoop ) )
    3906              :                                 {
    3907            0 :                                         continue;
    3908              :                                 }
    3909              :                                 else
    3910              :                                 {
    3911            0 :                                         bool neighbourFound = possibleNeighbour.testFullDimElmNeighbour( startVolInfoMarkLoop );
    3912              : 
    3913              :                                         if( neighbourFound )
    3914              :                                         {
    3915              :                                                 Volume * vol = possibleNeighbour.getFulldimElem();
    3916              : 
    3917              : //                                              m_sh.assign_subset(vol, m_sh.num_subsets());
    3918              : 
    3919              :                                         }
    3920              :                                 }
    3921              :                         }
    3922              : 
    3923              : 
    3924              :                         d_loopsDone++;
    3925              : 
    3926              : 
    3927            0 :                 }
    3928              : 
    3929            0 :                 vecSegVolElmInfo.push_back(segmentAVEI);
    3930              : 
    3931              : //              d_segmenteErledigt++;
    3932              : //
    3933              : //              if( d_segmenteErledigt == 1 )
    3934              : //              return false;
    3935            0 :         }
    3936              : 
    3937            0 :         if( reconstructedVecAttVolElmInf.size() != vecAttVolElemInfo.size() )
    3938              :         {
    3939              :                 UG_LOG("Rekonstruktion schief gegangen " << std::endl);
    3940            0 :                 UG_THROW("Rekonstruktion schief gegangen " << std::endl);
    3941              :                 return false;
    3942              :         }
    3943              : 
    3944              : // for debug purposes
    3945              : 
    3946              :         constexpr bool d_assignSudos2Segments = false;
    3947              : 
    3948              :         if( d_assignSudos2Segments )
    3949              :         {
    3950              :                 if( vecSegVolElmInfo.size() > 1 )
    3951              :                 {
    3952              :                         for( SegmentVolElmInfo const & svei : vecSegVolElmInfo )
    3953              :                         {
    3954              :                                 // TODO FIXME das hier wieder entfernen, die Subdomain Zuweisung, nur für debug Zwecke
    3955              :                                 IndexType sudoMax = m_sh.num_subsets();
    3956              : 
    3957              :                                 for( AttachedVolumeElemInfo const & vei : svei )
    3958              :                                 {
    3959              :                                         Volume * vol = vei.getFulldimElem();
    3960              : 
    3961              :                                         m_sh.assign_subset( vol, sudoMax );
    3962              :                                 }
    3963              :                         }
    3964              :                 }
    3965              :         }
    3966              : 
    3967            0 :         UG_LOG("Stasi END " << m_aaPos[oldVrt] << std::endl);
    3968              : 
    3969              :         return true;
    3970            0 : }
    3971              : 
    3972              : #if 0
    3973              : // Deprecated due to Stasi Algo
    3974              : // herausfinden für Sudo der frac, ob bezüglich dieser sudo die faces geschlossen sind, oder ob ein Fracture End vorliegt
    3975              : bool ArteExpandFracs3D::isVrtxSurroundedByFracFaces( Vertex * const & vrt, VertxFracPropts & vrtxFracPrps )
    3976              : //, VecPairSudoBool & sudoSurrounded )
    3977              : {
    3978              :         // TODO FIXME wenn an Boundary, dann auch auf closed open unterscheiden - sowohl wenn nur edge an
    3979              :         // boundary, aber auch wenn ein ganzes face dort, noch unklar, was das bedeutet
    3980              : 
    3981              :         // ganz ähnlich wie im 2D Fall, Loopen, im Kreis drehen, kucken, ob wir vom Anfang ans Ende kommen,
    3982              :         // und ob das Ende der edges wieder der Anfang der edges ist, da wir uns auf faces drehen
    3983              : 
    3984              :         // case boundary: figure out if the vertex is surrounded by frac faces of which two end in
    3985              :         // boundary edges, similar the case when the boundary face has itself two
    3986              :         // boundary edges, where the vertex is connected to both of them, then it is easy
    3987              : 
    3988              : 
    3989              :         VecAttachedFractFaceEdgeSudo vafes = vrtxFracPrps.getAllAttachedFractElems();
    3990              : 
    3991              :         std::vector<IndexType> sudoList = vrtxFracPrps.getSudoList();
    3992              : 
    3993              : //      for( auto const & sudo : sudoList )
    3994              : //      {
    3995              : //              std::vector<Face*> tmpFaces;
    3996              : //
    3997              : //              CollectFaces( tmpFace, m_grid, vrt );
    3998              : //
    3999              : //      }
    4000              : 
    4001              :         // first compare sudo list, if equal
    4002              : 
    4003              :         std::vector<IndexType> sudosTestList;
    4004              : 
    4005              :         std::vector<bool> sudoFound( sudoList.size(), false );
    4006              : 
    4007              :         UG_LOG("sudo list size " << sudoList.size() << std::endl );
    4008              : 
    4009              :         UG_LOG("vafes list size VA " << vafes.size() << std::endl );
    4010              : 
    4011              : 
    4012              :         for( auto const & af : vafes )
    4013              :         {
    4014              :                 bool found = false;
    4015              : 
    4016              :                 IndexType sudo = af.getSudo();
    4017              : 
    4018              :                 UG_LOG("sudo af " << sudo << std::endl);
    4019              : 
    4020              :                 for( IndexType i = 0; i < sudoList.size(); i++ )
    4021              :                 {
    4022              :                         UG_LOG("sudo list dusso is " << sudoList[i] << std::endl);
    4023              : 
    4024              :                         if( sudo == sudoList[i] )
    4025              :                         {
    4026              :                                 sudoFound[i] = true;
    4027              :                                 found = true;
    4028              :                         }
    4029              :                 }
    4030              : 
    4031              : 
    4032              :                 if( ! found )
    4033              :                         UG_THROW("sudo nicht gefunden muss aber da sein " << std::endl);
    4034              :         }
    4035              : 
    4036              :         UG_LOG("alles gefunden " << std::endl);
    4037              : 
    4038              : 
    4039              :         for( auto const & sf: sudoFound )
    4040              :         {
    4041              :                 if( sf == false )
    4042              :                 {
    4043              :                         UG_LOG("Falsch" << std::endl);
    4044              :                         UG_THROW("sudo not found but must be there " << std::endl);
    4045              :                 }
    4046              :         }
    4047              : 
    4048              :         UG_LOG("alles gefunden Test " << std::endl);
    4049              : 
    4050              : 
    4051              :         // sort faces with respect to subdomain - macht das wirklich Sinn, wie umständlich das gemacht wird jetzt?
    4052              : 
    4053              :         // if we arrive here, all sudos found, the entire circle closing can start
    4054              : 
    4055              :         VecPairSudoBool sudoSurrounded;
    4056              : 
    4057              :         for( auto const & sudo : sudoList )
    4058              :         {
    4059              :                 VecAttachedFractFaceEdgeSudo vecAttFacSudo;
    4060              : 
    4061              :                 for( auto const & attFac : vafes )
    4062              :                 {
    4063              :                         if( sudo == attFac.getSudo() )
    4064              :                         {
    4065              :                                 UG_LOG("die sudo gefunden " << sudo << std::endl);
    4066              :                                 vecAttFacSudo.push_back(attFac);
    4067              :                         }
    4068              :                 }
    4069              : 
    4070              :                 VecAttachedFractFaceEdgeSudo vecAttFacSudoSort;
    4071              : 
    4072              : 
    4073              : 
    4074              :                 bool isClosed = false;
    4075              : 
    4076              :                 bool isBndVrtx = IsBoundaryVertex3D(m_grid,vrt);
    4077              : 
    4078              :                 if( ! isBndVrtx )
    4079              :                 {
    4080              :                         UG_LOG("No boundary vertex test closed " << m_aaPos[vrt] << std::endl);
    4081              : 
    4082              :                         if( vecAttFacSudo.size() == 1 )
    4083              :                         {
    4084              :                                 // no need for further investigations for inner faces
    4085              :                                 isClosed = false;
    4086              :                                 vecAttFacSudoSort = vecAttFacSudo;
    4087              :                         }
    4088              :                         else
    4089              :                         {
    4090              :                                 isClosed = sortElemCircleIsClosed( vecAttFacSudo, vecAttFacSudoSort );
    4091              :                         }
    4092              : 
    4093              :                 }
    4094              :                 else // different treatment boundary vertex
    4095              :                 {
    4096              :                         // figure out start face with a boundary edge, and figure out an eventual additional boundary edge
    4097              :                         // if only one face, then check if two attached boundary edges, then true, else false
    4098              : 
    4099              :                         if( vecAttFacSudo.size() == 1 )
    4100              :                         {
    4101              :                                 AttachedFractFaceEdgeSudo & singleEntry = vecAttFacSudo[0];
    4102              : 
    4103              :                                 EdgePair faceEdgs = singleEntry.getPairLowElm();
    4104              : 
    4105              :                                 if( IsBoundaryEdge3D(m_grid, faceEdgs.first) && IsBoundaryEdge3D(m_grid, faceEdgs.second ) )
    4106              :                                         isClosed = true;
    4107              : 
    4108              :                                 // very simple
    4109              :                                 vecAttFacSudoSort = vecAttFacSudo;
    4110              : 
    4111              :                         }
    4112              :                         else
    4113              :                         {
    4114              :                                 // figure out a begin face with a boundary edge and figure out another face with a boundary edge
    4115              : 
    4116              :                                 Edge * beginEdge = nullptr;
    4117              :                                 Edge * endEdge = nullptr;
    4118              : 
    4119              :                                 IndexType startFaceIndx = 0;
    4120              :                                 IndexType endFaceIndx = 0;
    4121              : 
    4122              :                                 for( auto const & afs : vecAttFacSudo )
    4123              :                                 {
    4124              :                                         Face * fac = afs.getManifElm();
    4125              : 
    4126              :                                         EdgePair edgs = afs.getPairLowElm();
    4127              : 
    4128              :                                         Edge * edgOne = edgs.first;
    4129              :                                         Edge * edgTwo = edgs.second;
    4130              : 
    4131              :                                         if( beginEdge == nullptr )
    4132              :                                         {
    4133              :                                                 if( IsBoundaryEdge3D(m_grid, edgOne) )
    4134              :                                                 {
    4135              :                                                         beginEdge = edgTwo;
    4136              :                                                 }
    4137              :                                                 else if( IsBoundaryEdge3D(m_grid, edgTwo) )
    4138              :                                                 {
    4139              :                                                         beginEdge = edgOne;
    4140              :                                                 }
    4141              :                                                 else
    4142              :                                                 {
    4143              :                                                         startFaceIndx++;
    4144              :                                                 }
    4145              :                                         }
    4146              :                                         else
    4147              :                                         {
    4148              :                                                 if( IsBoundaryEdge3D(m_grid, edgOne) )
    4149              :                                                 {
    4150              :                                                         endEdge = edgOne;
    4151              :                                                 }
    4152              :                                                 else if( IsBoundaryEdge3D(m_grid, edgTwo) )
    4153              :                                                 {
    4154              :                                                         endEdge = edgTwo;
    4155              :                                                 }
    4156              :                                         }
    4157              : 
    4158              :                                         if( endEdge != nullptr )
    4159              :                                                 break;
    4160              : 
    4161              :                                         endFaceIndx++;
    4162              :                                 }
    4163              : 
    4164              :                                 if( beginEdge == nullptr && endFaceIndx == vecAttFacSudo.size() )
    4165              : //                                      || beginEdge == nullptr || endEdge == nullptr )
    4166              :                                 {
    4167              :                                         UG_LOG("keine boundary edges" << std::endl);
    4168              : 
    4169              :                                         startFaceIndx = -1;
    4170              : 
    4171              :                                         if( endEdge != nullptr )
    4172              :                                                 UG_THROW("Ende nicht null, Anfang null " << std::endl);
    4173              :                                 }
    4174              : 
    4175              :                                 UG_LOG("Boundary vertex test closed " << m_aaPos[vrt] << std::endl);
    4176              : 
    4177              : //                              int d_num = 0;
    4178              : //                              for( auto const & afs : vecAttFacSudo )
    4179              : //                              {
    4180              : //                                      d_num++;
    4181              : //                                      Face * fac = afs.getManifElm();
    4182              : //                                      m_sh.assign_subset(fac, m_sh.num_subsets());
    4183              : //                              }
    4184              : //                              UG_LOG("number of surr faces " << d_num << std::endl );
    4185              : 
    4186              : //                              m_sh.assign_subset(beginEdge,m_sh.num_subsets());
    4187              : //                              m_sh.assign_subset(endEdge,m_sh.num_subsets());
    4188              : //                              m_sh.assign_subset(vecAttFacSudo[startFaceIndx].getManifElm(),m_sh.num_subsets());
    4189              : 
    4190              :                                 isClosed = sortElemCircleIsClosed( vecAttFacSudo, vecAttFacSudoSort, startFaceIndx, beginEdge, endEdge );
    4191              : 
    4192              :                         }
    4193              :                 }
    4194              : 
    4195              :                 UG_LOG("-------------------------------" << std::endl);
    4196              :                 UG_LOG("is closed " << isClosed << " at " << m_aaPos[vrt] << std::endl);
    4197              :                 UG_LOG("-------------------------------" << std::endl);
    4198              : 
    4199              : //              if( isClosed )
    4200              : //              {
    4201              : //                      m_sh.assign_subset(vrt,3);
    4202              : //              }
    4203              : //              else
    4204              : //              {
    4205              : //                      m_sh.assign_subset(vrt,4);
    4206              : //              }
    4207              : 
    4208              :                 if( vecAttFacSudo.size() != vecAttFacSudoSort.size() )
    4209              :                 {
    4210              : //                      return false;
    4211              : 
    4212              :                         UG_THROW("Die Sortierung ist komplett schief gegangen " << std::endl);
    4213              :                 }
    4214              : 
    4215              :                 // DEBUG Zeug, später entfernen!!!!!!
    4216              : //              for( auto const & afss : vecAttFacSudoSort )
    4217              : //              {
    4218              : //                      Face * fac = afss.getManifElm();
    4219              : //
    4220              : //                      m_sh.assign_subset(fac, m_sh.num_subsets());
    4221              : //              }
    4222              : 
    4223              :                 PairSudoBool ic( sudo, isClosed );
    4224              : 
    4225              :                 sudoSurrounded.push_back( ic );
    4226              : 
    4227              :         }
    4228              : 
    4229              :         vrtxFracPrps.setInfoAllFractureSudosIfClosed(sudoSurrounded);
    4230              : 
    4231              :         bool allClosed = true;
    4232              : 
    4233              :         for( auto const & ic : sudoSurrounded )
    4234              :         {
    4235              :                 if( ! ic.second )
    4236              :                         allClosed = false;
    4237              :         }
    4238              : 
    4239              :         return allClosed;
    4240              : }
    4241              : 
    4242              : bool ArteExpandFracs3D::sortElemCircleIsClosed( VecAttachedFractFaceEdgeSudo const & vecAttFac,
    4243              :                                                                                                 VecAttachedFractFaceEdgeSudo & vecSortedFac,
    4244              :                                                                                                 int startFacIndexUser,
    4245              : //                                                                                              int endFacIndexUser,
    4246              : //                                                                                              IndexType startEdgeIndexUser,
    4247              : //                                                                                              IndexType endEdgeIndexUser
    4248              : //                                                                                              Face * const & startFacUser,
    4249              : //                                                                                              Face * const & endFacUser,
    4250              :                                                                                                 Edge * const & startEdgUser,
    4251              :                                                                                                 Edge * const & endEdgUser
    4252              :                                                                                                 )
    4253              : {
    4254              : 
    4255              :         UG_LOG("Schliesstest" << std::endl);
    4256              : 
    4257              :         IndexType originalSize = vecAttFac.size();
    4258              : 
    4259              :         if( originalSize == 0 )
    4260              :         {
    4261              :                 UG_THROW("zu klein zum sortieren " << std::endl);
    4262              :                 return false;
    4263              :         }
    4264              :         else if ( originalSize == 1 )
    4265              :         {
    4266              :                 UG_THROW("should not happen size 1, should have been mentioned before " << std::endl);
    4267              :         }
    4268              : 
    4269              :         UG_LOG("Kopieren zwecks sortieren " << std::endl);
    4270              : 
    4271              :         for( auto const & af : vecAttFac )
    4272              :         {
    4273              :                 UG_LOG("die sudos innen sind " << af.getSudo() << std::endl);
    4274              :         }
    4275              : 
    4276              :         VecAttachedFractFaceEdgeSudo copyVecAttFac = vecAttFac;
    4277              : 
    4278              :         for( auto const & af : copyVecAttFac )
    4279              :         {
    4280              :                 UG_LOG("die sudos kopiert sind " << af.getSudo() << std::endl);
    4281              :         }
    4282              : 
    4283              :         IndexType beginIndx = 0;
    4284              : 
    4285              :         UG_LOG("begin Index " << beginIndx << std::endl);
    4286              : 
    4287              :         bool simpleConnectionTest = false;
    4288              : 
    4289              :         Edge * startEdgeForced = nullptr;
    4290              : 
    4291              :         if( startFacIndexUser >= 0 )
    4292              :         {
    4293              :                 UG_LOG("Veränderung " << startFacIndexUser << std::endl);
    4294              :                 beginIndx = startFacIndexUser;
    4295              :                 simpleConnectionTest = true; // user hopefully did it
    4296              :         }
    4297              :         else
    4298              :         {
    4299              :                 // we need to ensure to start at a fracture which is not in between, in case that circle not closed
    4300              :                 // so ensure that all fracture faces have a fracture face at both edges as neighbour,
    4301              :                 // in principle this is already sufficient to answer the question which we want to know
    4302              :                 // all the rest here is useless playing in principle
    4303              : 
    4304              :                 bool broken = false;
    4305              : 
    4306              :                 for( IndexType i = 0; i < vecAttFac.size(); i++ )
    4307              :                 {
    4308              :                         IndexType firstSideConnected = 0;
    4309              :                         IndexType secondSideConnected = 0;
    4310              : 
    4311              :                         AttachedFractFaceEdgeSudo afBase = vecAttFac[i];
    4312              : 
    4313              :                         Face * faceBase = afBase.getManifElm();
    4314              :                         EdgePair edgPairBase = afBase.getPairLowElm();
    4315              : 
    4316              :                         Edge * edgeBaseOne = edgPairBase.first;
    4317              :                         Edge * edgeBaseTwo = edgPairBase.second;
    4318              : 
    4319              :                         for( IndexType j = 0; j < vecAttFac.size(); j++ )
    4320              :                         {
    4321              :                                 if( i != j )
    4322              :                                 {
    4323              :                                         AttachedFractFaceEdgeSudo afCompr = vecAttFac[j];
    4324              : 
    4325              :                                         Face * faceCompr = afCompr.getManifElm();
    4326              :                                         EdgePair edgPairCompr = afCompr.getPairLowElm();
    4327              : 
    4328              :                                         Edge * edgeComprOne = edgPairCompr.first;
    4329              :                                         Edge * edgeComprTwo = edgPairCompr.second;
    4330              : 
    4331              :                                         if( edgeComprOne == edgeBaseOne || edgeComprTwo == edgeBaseOne )
    4332              :                                                 firstSideConnected++;
    4333              : 
    4334              :                                         if( edgeComprOne == edgeBaseTwo || edgeComprTwo == edgeBaseTwo )
    4335              :                                                 secondSideConnected++;
    4336              :                                 }
    4337              : 
    4338              :                         }
    4339              : 
    4340              :                         if( vecAttFac.size() > 2 && ( firstSideConnected > 1 || secondSideConnected > 1 ) )
    4341              :                         {
    4342              :                                 UG_THROW("zu oft verbunden " << std::endl );
    4343              :                         }
    4344              :                         else if( vecAttFac.size() == 2 && ( firstSideConnected > 2 || secondSideConnected > 2 ) )
    4345              :                         {
    4346              :                                 UG_THROW("zu oft verbunden " << std::endl );
    4347              :                         }
    4348              :                         else if( firstSideConnected == 0 )
    4349              :                         {
    4350              :                                 // face is open into one direction, already clear that not closed!!
    4351              : 
    4352              :                                 beginIndx = i;
    4353              :                                 simpleConnectionTest = false;
    4354              :                                 startEdgeForced = edgeBaseTwo;
    4355              :                                 UG_LOG("forcieren 1 " << std::endl);
    4356              :                                 broken = true;
    4357              :                                 break;
    4358              :                         }
    4359              :                         else if( secondSideConnected == 0 )
    4360              :                         {
    4361              :                                 // face is open into one direction, already clear that not closed!!
    4362              : 
    4363              :                                 beginIndx = i;
    4364              :                                 simpleConnectionTest = false;
    4365              :                                 startEdgeForced = edgeBaseOne;
    4366              :                                 UG_LOG("forcieren 2 " << std::endl);
    4367              :                                 broken = true;
    4368              :                                 break;
    4369              :                         }
    4370              :                         else if( firstSideConnected == 1 && secondSideConnected == 1 )
    4371              :                         {
    4372              :                                 simpleConnectionTest = true; // as long as a look
    4373              :                         }
    4374              :                         else
    4375              :                         {
    4376              :                                 UG_THROW("komischer Verbindungsfall " << std::endl);
    4377              :                         }
    4378              : 
    4379              :                         if( broken )
    4380              :                                 break;
    4381              : 
    4382              :                 }
    4383              :         }
    4384              : 
    4385              :         UG_LOG("begin Index X " << beginIndx << std::endl);
    4386              : 
    4387              : 
    4388              : //      AttachedFractFaceEdgeSudo initialAFES = *(copyAttFac.begin());
    4389              :         AttachedFractFaceEdgeSudo initialAFES = copyVecAttFac[beginIndx];
    4390              : 
    4391              :         IndexType sudo = initialAFES.getSudo();
    4392              : 
    4393              :         UG_LOG("sudo " << beginIndx << " ist " << sudo << std::endl);
    4394              : 
    4395              :         Face * beginFacLoop = initialAFES.getManifElm();
    4396              : 
    4397              :         // TODO FIXME wird das irgendwo verwendet? wieso nicht?
    4398              : //      Face * endFacLoop = nullptr;
    4399              : 
    4400              : //      if( endFacIndexUser != -1 )
    4401              : //      {
    4402              : //              endFacLoop = copyVecAttFac[endFacIndexUser].getManifElm();
    4403              : //      }
    4404              : 
    4405              :         EdgePair beginEdges = initialAFES.getPairLowElm();
    4406              : 
    4407              :         Edge * beginEdgeLoop = beginEdges.second;
    4408              :         Edge * targetedEndEdgeLoop = beginEdges.first; // should be closed! should end at same edge as it begins!
    4409              : 
    4410              : //
    4411              : //      return true;
    4412              : 
    4413              : //      if( startEdgeIndexUser != -1 )
    4414              : //      {
    4415              : //              beginEdgeLoop =
    4416              : //      }
    4417              : 
    4418              : //      if( startFacUser != nullptr )
    4419              : //      {
    4420              : //              beginFacLoop = startFacUser;
    4421              : //
    4422              : //      }
    4423              : //
    4424              : 
    4425              : //      if( ! FaceContains(beginFacLoop,beginEdgeLoop->vertex(0)) )
    4426              : //              UG_THROW("Sortierung Gesicht hat nicht die gewünschte Ecke " << std::endl);
    4427              : //
    4428              : //      if( endFacUser != nullptr )
    4429              : //      {
    4430              : //              endFacLoop = endFacUser;
    4431              : //      }
    4432              : //
    4433              : 
    4434              :         if( startEdgUser != nullptr )
    4435              :         {
    4436              :                 beginEdgeLoop = startEdgUser;
    4437              : 
    4438              :                 // check if part of the begin face!
    4439              : 
    4440              :                 if( ! FaceContains( beginFacLoop, beginEdgeLoop ) )
    4441              :                         UG_THROW("Anfangsgesicht hat keine Anfangsecke " << std::endl);
    4442              : 
    4443              :         }
    4444              : 
    4445              :         if( startEdgeForced != nullptr )
    4446              :         {
    4447              :                 beginEdgeLoop = startEdgeForced;
    4448              : 
    4449              :                 // check if part of the begin face!
    4450              : 
    4451              :                 if( ! FaceContains( beginFacLoop, beginEdgeLoop ) )
    4452              :                         UG_THROW("Anfangsgesicht hat keine Anfangsecke forced " << std::endl);
    4453              : 
    4454              : //              m_sh.assign_subset(startEdgeForced, m_sh.num_subsets());
    4455              :                 UG_LOG("forciert " << std::endl);
    4456              : 
    4457              : //              return false;
    4458              : 
    4459              :         }
    4460              : 
    4461              : 
    4462              :         if( endEdgUser != nullptr )
    4463              :         {
    4464              :                 // check if part of end face at end of loop somehow
    4465              :                 targetedEndEdgeLoop = endEdgUser;
    4466              : 
    4467              :                 if( startEdgeForced != nullptr )
    4468              :                         UG_THROW("das muss schief gehen, Chaos " << std::endl);
    4469              : 
    4470              : //              if( endFacLoop != nullptr )
    4471              : //              {
    4472              : //                      if( ! FaceContains( endFacLoop, targetedEndEdgeLoop ) )
    4473              : //                              UG_THROW("Endgesicht hat keine Endecke " << std::endl);
    4474              : //              }
    4475              :         }
    4476              : //
    4477              : 
    4478              :         // DEBUG
    4479              : //      m_sh.assign_subset(beginFacLoop, m_sh.num_subsets());
    4480              : //      m_sh.assign_subset(beginEdgeLoop, m_sh.num_subsets());
    4481              : //      m_sh.assign_subset(targetedEndEdgeLoop, m_sh.num_subsets());
    4482              : 
    4483              : 
    4484              :         // Du musst sortieren. Du musst einen Zeitplan machen. Das kann man lernen. Du kannst das selber machen.
    4485              : 
    4486              :         IndexType countedCrossedFaces = 1;
    4487              : 
    4488              :         vecSortedFac.push_back( initialAFES );
    4489              : 
    4490              :         copyVecAttFac.erase( copyVecAttFac.begin() + beginIndx );
    4491              : 
    4492              : //      Face * face2Append = beginFacLoop;
    4493              :         Edge * startEdge2Append = beginEdgeLoop;
    4494              : 
    4495              : //      m_sh.assign_subset(startEdge2Append,m_sh.num_subsets());
    4496              : 
    4497              :         UG_LOG("while loop anfangen " << std::endl);
    4498              : 
    4499              :         IndexType d_whi = 0;
    4500              : 
    4501              :         while( copyVecAttFac.size() != 0 )
    4502              :         {
    4503              : 
    4504              :                 UG_LOG("in while loop " << d_whi << std::endl);
    4505              :                 d_whi++;
    4506              : 
    4507              :                 IndexType foundCommEdg = 0;
    4508              : 
    4509              :                 Edge * nextEdge = nullptr;
    4510              : 
    4511              : //              for( auto const & caf : copyVecAttFac )
    4512              :                 for( VecAttachedFractFaceEdgeSudo::iterator itAttFES  = copyVecAttFac.begin();
    4513              :                                                                                            itAttFES != copyVecAttFac.end();
    4514              :                                                                                            itAttFES++
    4515              :                 )
    4516              :                 {
    4517              :                         AttachedFractFaceEdgeSudo caf = *itAttFES;
    4518              : 
    4519              :                         Face * d_Fac = caf.getManifElm();
    4520              : 
    4521              : //                      m_sh.assign_subset(d_Fac,m_sh.num_subsets());
    4522              : 
    4523              :                         EdgePair edgPr = caf.getPairLowElm();
    4524              : 
    4525              :                         Edge * edgOne = edgPr.first;
    4526              :                         Edge * edgTwo = edgPr.second;
    4527              : 
    4528              : //                      m_sh.assign_subset(edgOne,m_sh.num_subsets());
    4529              : //                      m_sh.assign_subset(edgTwo,m_sh.num_subsets());
    4530              : 
    4531              : //                      return true;
    4532              : 
    4533              :                         IndexType hasEdge = 0;
    4534              : 
    4535              :                         Edge * overNextEdge = nullptr;
    4536              : 
    4537              :                         if( edgOne == startEdge2Append )
    4538              :                         {
    4539              :                                 nextEdge = edgOne;
    4540              :                                 overNextEdge = edgTwo;
    4541              :                                 hasEdge++;
    4542              :                         }
    4543              : 
    4544              :                         if( edgTwo == startEdge2Append )
    4545              :                         {
    4546              :                                 nextEdge = edgTwo;
    4547              :                                 overNextEdge = edgOne;
    4548              :                                 hasEdge++;
    4549              :                         }
    4550              : 
    4551              :                         if( hasEdge > 1 )
    4552              :                                 UG_THROW("zu viele Ecken und Kanten " << std::endl);
    4553              : 
    4554              :                         if( hasEdge == 1 )
    4555              :                         {
    4556              :                                 Face * fac2App = caf.getManifElm();
    4557              : //                              m_sh.assign_subset(fac2App,m_sh.num_subsets());
    4558              :                                 EdgePair edgesNextFace( edgOne, edgTwo );
    4559              :                                 AttachedFractFaceEdgeSudo nextAttFES( fac2App, edgesNextFace, sudo );
    4560              : 
    4561              :                                 vecSortedFac.push_back(nextAttFES);
    4562              : 
    4563              :                                 copyVecAttFac.erase(itAttFES);
    4564              :                                 foundCommEdg++;
    4565              :                                 startEdge2Append = overNextEdge;
    4566              : 
    4567              :                                 break;
    4568              :                         }
    4569              : 
    4570              : 
    4571              :                 }
    4572              : 
    4573              :                 if( foundCommEdg > 1 )
    4574              :                         UG_THROW("Kein Anschluss unter dieser Nummer " << std::endl);
    4575              : 
    4576              :                 if( foundCommEdg == 0 )
    4577              :                 {
    4578              :                         UG_LOG("Kreislauf nicht geschlossen " << std::endl);
    4579              : 
    4580              :                         if( nextEdge != nullptr )
    4581              :                                 UG_THROW("nicht konsistent, null und null " << std::endl);
    4582              : 
    4583              :                         break;
    4584              :                 }
    4585              : 
    4586              :                 if( nextEdge == nullptr )
    4587              :                 {
    4588              :                         if( foundCommEdg != 0 )
    4589              :                                 UG_THROW("nicht konsistent, null und null v2 " << foundCommEdg << " -> " << nextEdge << std::endl);
    4590              : 
    4591              :         //                      return false;
    4592              :                 }
    4593              : 
    4594              :         }
    4595              : 
    4596              :         if( originalSize != vecSortedFac.size() )
    4597              :         {
    4598              :                 UG_THROW("Sortierung hat nicht funktioniert " << std::endl);
    4599              :                 return false;
    4600              :         }
    4601              : 
    4602              :         if( startEdge2Append != targetedEndEdgeLoop )
    4603              :         {
    4604              :                 if( simpleConnectionTest )
    4605              :                         UG_THROW("obwohl offen oder vorgegeben trotzdem Ziel nicht erreicht?" << std::endl);
    4606              : 
    4607              :                 UG_LOG("Ende nicht erreicht, Kreis nicht geschlossen, innerer Rand vermutlich" << std::endl);
    4608              :                 return false;
    4609              :         }
    4610              : 
    4611              : 
    4612              :         UG_LOG("Kreislauf Faces 3D Test ob Knoten umrandet geschlossen " << std::endl);
    4613              : 
    4614              :         return true;
    4615              : }
    4616              : 
    4617              : #endif
    4618              : 
    4619            0 : bool ArteExpandFracs3D::assignOrigFracInfos()
    4620              : {
    4621              :         m_originalFractureFaces.clear();
    4622              : 
    4623            0 :         for( FaceIterator iter = m_sel.begin<Face>(); iter != m_sel.end<Face>(); ++iter)
    4624              :         {
    4625            0 :                 if( m_aaMarkFaceIsFracB[*iter] == true )
    4626            0 :                         m_originalFractureFaces.push_back(*iter);
    4627              :         }
    4628              : 
    4629            0 :         m_fracInfosBySubset = std::vector<FractureInfo>( m_sh.num_subsets(), FractureInfo(-1, -1, 0) );
    4630              : 
    4631            0 :         for(size_t i = 0; i < m_fracInfos.size(); ++i)
    4632              :         {
    4633            0 :                 if( m_fracInfos[i].subsetIndex >= m_sh.num_subsets())
    4634              :                 {
    4635            0 :                         throw(UGError("Bad subsetIndex in given fracInfos."));
    4636              :                 }
    4637              : 
    4638            0 :                 m_fracInfosBySubset[ m_fracInfos[i].subsetIndex ] = m_fracInfos[i];
    4639              :         }
    4640              : 
    4641              : //      disable selection inheritance to avoid infinite recursion.
    4642            0 :         m_sel.enable_selection_inheritance(false);
    4643              : 
    4644            0 :         return true;
    4645              : }
    4646              : 
    4647            0 : bool ArteExpandFracs3D::establishNewVrtBase()
    4648              : {
    4649              :         //      iterate over all surrounding volumes to enable shifted vertices, this loop taken from SR but shortened
    4650              : 
    4651            0 :         for( VolumeIterator iterSurrVol = m_sel.volumes_begin(); iterSurrVol != m_sel.volumes_end(); ++ iterSurrVol )
    4652              :         {
    4653              :                 Volume* sv = *iterSurrVol;
    4654              : 
    4655              :                 std::vector<Vertex*> & newVrts = m_aaVrtVecVol[sv];
    4656            0 :                 newVrts.resize(sv->num_vertices());
    4657              : 
    4658            0 :                 for(size_t iVrt = 0; iVrt < sv->num_vertices(); ++ iVrt )
    4659              :                 {
    4660            0 :                         newVrts[iVrt] = nullptr;
    4661              :                 }
    4662              : 
    4663              :                 // erstmal so tun, als ob keine neuen Vertizes erzeugt werden an den alten Vertizes
    4664              : 
    4665              :         }
    4666              : 
    4667            0 :         return true;
    4668              : }
    4669              : 
    4670              : #if 0
    4671              : // Analogon zu VertrexFractureInfo in 2D, wo jeder Vertex eine Liste bekommt, wo alle die ihm angehängten
    4672              : // Ecken, Faces und Volumen gespeichert werden; dazu die Normalen, und vielleicht noch weitere Infos
    4673              : bool ArteExpandFracs3D::generateVertexInfos()
    4674              : {
    4675              :         UG_LOG("Starte Generierung" << std::endl);
    4676              : 
    4677              :         // TODO FIXME das wird benötigt
    4678              : 
    4679              :         // sowas von der Art als attachement bei den attachments, und dann mit Leben füllen für jeden Vertex
    4680              :         // in dieser Funktion;
    4681              :         // vielleicht braucht es auch Edge Infos, oder nur Edge Infos?
    4682              : //      VecVertFracTrip vertexNoInfo;
    4683              : //      using AttVecVertFracTrip = Attachment<VecVertFracTrip>;
    4684              : //      AttVecVertFracTrip aAdjInfoAVVFT;
    4685              : //      grid.attach_to_vertices_dv( aAdjInfoAVVFT, vertexNoInfo );
    4686              : //      Grid::VertexAttachmentAccessor<AttVecVertFracTrip> aaVrtInfoFraTri(grid,  aAdjInfoAVVFT );
    4687              : 
    4688              :         // Lebendigmachung in:
    4689              :         //      for( auto & fsfpmv : fracSubdom_facePerpendMinVal ) .....
    4690              :         // von dort lernen!!!!!
    4691              : 
    4692              :         // notwendig: face, normal, volume, edge
    4693              : 
    4694              :         // TODO FIXME das wollen wir nicht, sondern das alte Vertex Fracture Triple
    4695              : //      m_vrtxFractrQuadrplVec = VrtxFractrQuadrplArte3DVec();
    4696              :         // TODO FIXME diese Einträge erzeugen
    4697              : 
    4698              :         // TODO FIXME kann vielleicht vereinfacht werden durch einen Loop über alle Vertizes,
    4699              :         // und das Abfragen der dort schon gespeicherten vertex property Geschichten, sonst
    4700              :         // wird manches doppelt gemoppelt
    4701              :         
    4702              :         for( auto const & fracInf : m_fracInfos )
    4703              :         {
    4704              :                 IndexType fracSudo = fracInf.subsetIndex;
    4705              : 
    4706              : 
    4707              : //              for(EdgeIterator iterEdg = m_sh.begin<Edge>(fracIndSudo); iterEdg != m_sh.end<Edge>(fracIndSudo); iterEdg++ )
    4708              : //
    4709              :                 for( FaceIterator iterFac = m_sh.begin<Face>(fracSudo); iterFac != m_sh.end<Face>(fracSudo); iterFac++ )
    4710              :                 {
    4711              : 
    4712              : //                      VrtxFractrQuadrplArte3D vrtxFractrQuadrpl;
    4713              :                         
    4714              :                         // TODO FIXME die Innereien dieses Loops irgendwie für boundary faces hinbiegen,
    4715              :                         // vermutlich nicht viel verändern, dafür eigene Routine, die dann für jeweils ein face den
    4716              :                         // Müll umsetzt
    4717              : 
    4718              :                         Face* fac = *iterFac;
    4719              :                         
    4720              :                         auto sudoFacInnerLoop = m_sh.get_subset_index(fac);
    4721              :                         
    4722              :                         if( sudoFacInnerLoop != fracSudo )
    4723              :                                 UG_THROW("Subdomain Index Fehler 3D " << std::endl);
    4724              : 
    4725              : //                      std::vector<Vertex*> verticesFac;
    4726              : //
    4727              : //                      for( IndexType i = 0; i < fac->num_vertices(); i++ )
    4728              : //                      {
    4729              : //                              verticesFac.push_back( fac->vertex(i) );
    4730              : //                      }
    4731              : 
    4732              : 
    4733              :                         std::vector<Volume*> assoVols;
    4734              : 
    4735              :                         // wo kam denn der Käse her?
    4736              : //                      if( ! m_grid.option_is_enabled(FACEOPT_STORE_ASSOCIATED_VOLUMES) )
    4737              : //                              UG_THROW("How to collect asso vols?" << std::endl);
    4738              : 
    4739              :                         // brauchen wir das? für was? von SR irgendwie übernommen, wo dort was entfernt ähnliches gemacht wird....
    4740              :                         if(! m_grid.option_is_enabled(VOLOPT_AUTOGENERATE_FACES) )
    4741              :                         {
    4742              :                                 UG_LOG("WARNING grid option VOLOPT_AUTOGENERATE_FACES autoenabled.\n");
    4743              :                                 m_grid.enable_options(VOLOPT_AUTOGENERATE_FACES);
    4744              :                         }
    4745              : 
    4746              : 
    4747              : //                      for( Grid::AssociatedVolumeIterator volIt  = m_grid.associated_volumes_begin(fac);
    4748              : //                                                                                              volIt != m_grid.associated_volumes_end(fac);
    4749              : //                                                                                              volIt++
    4750              : //                      )
    4751              : //                      {
    4752              : //                              assoVols.push_back(*volIt);
    4753              : //                      }
    4754              : 
    4755              :                         CollectVolumes(assoVols, m_grid, fac );
    4756              : //
    4757              : //                      for( auto const & av : assoVols )
    4758              : //                      {
    4759              : //                              m_sh.assign_subset(av, m_sh.num_subsets());
    4760              : //                      }
    4761              : //
    4762              : //                      return true;
    4763              : 
    4764              : //                      using VolNormPair = std::pair< Volume*, vector3 >;
    4765              : //
    4766              : //                      using VecVolNormPair = std::vector<VolNormPair>;
    4767              : //
    4768              : //                      VecVolNormPair vecNormalsAwayVol;
    4769              : 
    4770              : //                      UG_LOG("Center Face " << CalculateCenter(fac,m_aaPos) << std::endl);
    4771              : 
    4772              :                         for( auto const & kuhVol : assoVols )
    4773              :                         {
    4774              :                                 bool facFound = false;
    4775              :                                 IndexType numFd = 0;
    4776              : 
    4777              :                                 for( IndexType iSide = 0; iSide < kuhVol->num_sides(); iSide++ )
    4778              :                                 {
    4779              :                                         Face * kuhFac = m_grid.get_side(kuhVol, iSide);
    4780              : 
    4781              : //                                      UG_LOG("Center Kuh Face " << CalculateCenter(kuhFac,m_aaPos) << std::endl);
    4782              : 
    4783              :                                         // TODO FIXME eigentliches Ziel ist es, den face descriptor des Volumens zu finden,
    4784              :                                         // das mit dem face übereinstimmt, alle anderen Seiten des Volumens sind egal
    4785              :                                         // Funktion suchen, die ausgehend von einem Face, das ein Volumen begrenzt,
    4786              :                                         // den zum Volumen passenden FaceDescriptor findet, also auch richtige Orientierung
    4787              :                                         // der Vertices beinhaltet
    4788              :                                         // FRAGE TODO FIXME ist ein face descriptor von der Orientierung zum Volumen abhängig
    4789              :                                         // oder hängt der nur vom Face ab, das eine vorgegebene Oriertierung hat?
    4790              : 
    4791              :                                         bool checkCoincide = checkIfFacesVerticesCoincide( kuhFac, fac );
    4792              : 
    4793              :                                         if( checkCoincide )
    4794              :                                         {
    4795              :                                                 facFound = true;
    4796              :                                                 numFd++;
    4797              : 
    4798              :                                                 if( kuhFac != fac )
    4799              :                                                         UG_LOG("Kuh Fac ist nicht fac " << std::endl);
    4800              : 
    4801              :                                                 FaceDescriptor facDescr;
    4802              : 
    4803              :                                                 // TODO FIXME testen, ob der Face Descriptor von der Orientierung abhängt
    4804              :                                                 // also testen, ob sich der face descriptor ändert, wenn das Volumen
    4805              :                                                 // auf der einen und auf der anderen Seite des faces hängt
    4806              :                                                 // deswegen auch die ganze Prozedur mit den kuhFacs, die hoffentlich
    4807              :                                                 // je nach Volumen anders orientiert sind als das eigentliche Face,
    4808              :                                                 // aber dieselben Vertices haben, also geometrisch gleich sind, aber anders orientiert!!!!
    4809              : 
    4810              :                                                 // TODO FIXME andere Hergehensweise vielleicht:
    4811              :                                                 // von m_aaVrtInfoAssoVols ausgehen, darüber loopen, oder die in einen Vektor stecken,
    4812              :                                                 // wo die Vertices dabei sind, dann kann man sich vielelicht ein paar Klimmzüge sparen,
    4813              :                                                 // vielleicht aber auch nicht.....
    4814              : 
    4815              :                                                 kuhVol->face_desc( iSide, facDescr );
    4816              : 
    4817              :                                                 vector3 normal;
    4818              : 
    4819              :                                                 CalculateNormal( normal, & facDescr, m_aaPos );
    4820              : 
    4821              :                                                 vector3 facCenter = CalculateCenter( kuhFac, m_aaPos );
    4822              :                                                 vector3 kuhCenter = CalculateCenter( fac, m_aaPos );
    4823              :                                                 vector3 kuhVolCenter = CalculateCenter( kuhVol, m_aaPos);
    4824              : 
    4825              : //                                              UG_LOG("Normale zum face descriptor " << normal << " , " << facCenter << std::endl);
    4826              : //                                              UG_LOG("Normale zum Kuhh descriptor " << normal << " , " << kuhCenter << std::endl);
    4827              : //                                              UG_LOG("Zentrum des Vol")
    4828              : 
    4829              : //                                              UG_LOG("fac " << fac << std::endl );
    4830              : //                                              UG_LOG("kuh " << kuhFac << std::endl );
    4831              : 
    4832              :                                                 UG_LOG("Normale ist " << normal << " fac " << facCenter
    4833              :                                                                 << " vol " << kuhVolCenter << std::endl);
    4834              : 
    4835              : 
    4836              : //                                              VolNormPair normalsAwayVol( kuhVol, normal );
    4837              : //
    4838              : //                                              vecNormalsAwayVol.push_back( normalsAwayVol );
    4839              : 
    4840              :                                                 std::vector<Edge*> facEdgs;
    4841              : 
    4842              :                                                 CollectEdges( facEdgs, m_grid, fac);
    4843              : 
    4844              :                                                 for( IndexType iF = 0; iF < fac->num_vertices(); iF++ )
    4845              :                                                 {
    4846              :                                                         Vertex * vrt = fac->vertex(iF);
    4847              : 
    4848              :                         //                              verticesFac.push_back(vrt);
    4849              : 
    4850              :                                                         std::vector<Edge*> edgOfVrtx;
    4851              : 
    4852              :                                                         for( auto const & edg : facEdgs )
    4853              :                                                         {
    4854              :                                                                 if( EdgeContains(edg, vrt) )
    4855              :                                                                 {
    4856              :                                                                         edgOfVrtx.push_back(edg);
    4857              :                                                                 }
    4858              :                                                         }
    4859              : 
    4860              :                                                         if( edgOfVrtx.size() == 2 )
    4861              :                                                         {
    4862              :                                                                 EdgePair commonEdges(edgOfVrtx[0], edgOfVrtx[1]); //  fill values
    4863              :                                                                 // edges commun between face and volume, with the vertex included as well, i.e. two possibilities
    4864              : 
    4865              :                                                                 // TODO FIXME diese Info muss woanders hin, in der AttachedFractFaceEdgeSudo Klasse speichern!
    4866              :                                                                 VertFracTrip infoVerticesThisFace( fac, fracSudo, kuhVol, normal, commonEdges );
    4867              : 
    4868              :                                                                 // TODO FIXME hier irgendwie graphische Ausgabe von irgendwas
    4869              : 
    4870              :                                                                 m_aaVrtInfoFraTri[vrt].push_back( infoVerticesThisFace );
    4871              : 
    4872              :                                                                 // DEBUG OUTPUT; REMOVE LATER
    4873              : //                                                              m_sh.assign_subset(kuhVol,m_sh.num_subsets());
    4874              :                                                         }
    4875              :                                                         else
    4876              :                                                         {
    4877              :                                                                 UG_THROW("Mein Face das hat keine Ecken, keine Ecken hat mein Face" << std::endl);
    4878              :                                                         }
    4879              :                                                 }
    4880              : 
    4881              :                                         }
    4882              :                                 }
    4883              : 
    4884              :                                 if( ! facFound || numFd != 1 )
    4885              :                                 {
    4886              :                                         UG_THROW("Kein Kuh Volumen gefunden" << std::endl);
    4887              :                                         return false;
    4888              :                                 }
    4889              : 
    4890              :                         }
    4891              : 
    4892              :                 }
    4893              : 
    4894              : 
    4895              :         }
    4896              : 
    4897              :         UG_LOG("GEnerierung gelungen " << std::endl);
    4898              : 
    4899              :         return true;
    4900              : }
    4901              : #endif
    4902              : 
    4903            0 : bool ArteExpandFracs3D::checkIfFacesVerticesCoincide( Face * const & facOne, Face * const & facTwo )
    4904              : {
    4905              : 
    4906            0 :         if( facOne->size() != facTwo->size() )
    4907              :                 return false;
    4908              : 
    4909              :         std::vector<Vertex* > facOneVrtcs, facTwoVrtcs;
    4910              : 
    4911            0 :         collectFaceVertices( facOneVrtcs, facOne );
    4912            0 :         collectFaceVertices( facTwoVrtcs, facTwo );
    4913              : 
    4914            0 :         for( auto const & vrtOne : facOneVrtcs )
    4915              :         {
    4916              :                 bool found = false;
    4917              : 
    4918              :                 IndexType numFd = 0;
    4919              : 
    4920            0 :                 for( auto const & vrtTwo : facTwoVrtcs )
    4921              :                 {
    4922            0 :                         if( vrtOne == vrtTwo )
    4923              :                         {
    4924              :                                 found = true;
    4925            0 :                                 numFd++;
    4926              :                         }
    4927              :                 }
    4928              : 
    4929            0 :                 if( ! found || numFd != 1 )
    4930              :                         return false;
    4931              :         }
    4932              : 
    4933              :         return true;
    4934            0 : }
    4935              : 
    4936            0 : bool ArteExpandFracs3D::collectFaceVertices( std::vector<Vertex*> & facVrt, Face * const & fac )
    4937              : {
    4938            0 :         if( fac == nullptr )
    4939              :                 return false;
    4940              : 
    4941              :         facVrt.clear();
    4942              : 
    4943            0 :         for( IndexType iF = 0; iF < fac->num_vertices(); iF++ )
    4944              :         {
    4945            0 :                 Vertex * vrt = fac->vertex(iF);
    4946              : 
    4947            0 :                 facVrt.push_back( vrt );
    4948              :         }
    4949              : 
    4950              :         return true;
    4951              : }
    4952              : 
    4953              : 
    4954              : 
    4955              : 
    4956              : // major function of new grid generation, in Keil Style, but functional grid, only the diamonds have to be
    4957              : // established in additional functionalities independent of this function
    4958            0 : bool ArteExpandFracs3D::loop2EstablishNewVertices()
    4959              : {
    4960            0 :         m_vecCrossVrtInf = std::vector<CrossVertInf>();
    4961              : 
    4962              : 
    4963              :         // TODO FIXME sowas von der Art wird nötig sein als Vorbereitung für die Diamanten,
    4964              :         // Infos darin speichern, vielleicht auch noch notwendig, die Kanten zu speichern oder die faces,
    4965              :         // zu klären im Laufe der Implementation
    4966              :         // std::vector<CrossVertInf > vecCrossVrtInf;
    4967              : 
    4968              :         // zentraler Loop
    4969              : 
    4970              :         // TODO FIXME vorher noch den attVrtVec und den aaVrtVecFac analog implementieren, das fehlt noch!!!
    4971              :         // ebenso seine Befüllung, braucht noch eine Funktion dazwischen, die attachments selber in die
    4972              :         // attach Funktion natürlich
    4973              :         
    4974              :         int untilVrt = 0;
    4975              : 
    4976            0 :         for( VertexIterator iterV = m_sel.begin<Vertex>(); iterV != m_sel.end<Vertex>(); ++ iterV )
    4977              :         {
    4978            0 :                 Vertex * oldVrt = *iterV;
    4979              : 
    4980              :                 // Position dieses Vertex
    4981              :                 vector3 posOldVrt = m_aaPos[oldVrt];
    4982              : 
    4983              :                 // TODO FIXME diese Funktion mit Leben und Analytischer Geometrie 13. Klasse füllen
    4984              : 
    4985              : //              VecVertFracTrip & vecVertFracTrip = m_aaVrtInfoFraTri[oldVrt];
    4986              : //
    4987              : //              std::vector<Edge*> & allAssoEdges = m_aaVrtInfoAssoEdges[oldVrt];
    4988              : //              std::vector<Face*> & allAssoFaces = m_aaVrtInfoAssoFaces[oldVrt];
    4989              : //              std::vector<Volume*> & allAssoVolumes = m_aaVrtInfoAssoVols[oldVrt];
    4990              : 
    4991            0 :                 UG_LOG("vertex at " << posOldVrt << std::endl);
    4992              : 
    4993            0 :                 VecSegmentLimitingSides & vecSegmLimSid = m_vrtxAttAccsVecSegmLimSid[oldVrt];
    4994              : 
    4995            0 :                 for( SegmentLimitingSides const & sls : vecSegmLimSid )
    4996              :                 {
    4997            0 :                         if( sls.hasUnclosedFaces())
    4998              :                                 UG_LOG("Hier hat das Gesicht noch ungeschlossene " << std::endl);
    4999              :                 }
    5000              : 
    5001              : //              if( ! vrtxIsBndVrt )
    5002              : //              {
    5003            0 :                 if( ! establishNewVertizesStasiBased(oldVrt) )
    5004              :                 {
    5005              :                         UG_LOG("Vertex Erzeugung schief gegangen " << std::endl);
    5006            0 :                         return false;
    5007              :                 }
    5008              : 
    5009              : //              }
    5010              : 
    5011              : 
    5012              :                 
    5013              : 
    5014              :         }
    5015              : 
    5016              :         // for debugging
    5017              : //      return false;
    5018              : 
    5019            0 :         return true;
    5020              : }
    5021              : 
    5022              : ////////////////////////////////////////////////////////////////////
    5023              : 
    5024              : #if 0
    5025              : bool ArteExpandFracs3D::establishNewVertizesStasiBased( Vertex * const & oldVrt)
    5026              : {
    5027              :         // anfangs nur für innere Vertizes mit einer fracture
    5028              : 
    5029              :         VecSegmentVolElmInfo & vecSegVolElmInf = m_accsAttVecSegVolElmInfo[oldVrt];
    5030              : 
    5031              :         if( vecSegVolElmInf.size() < 2 )
    5032              :         {
    5033              :                 UG_LOG("nur ein Segment, aber will frische Vertizes?" << std::endl);
    5034              : //              UG_THROW("nur ein Segment, aber will frische Vertizes?" << std::endl);
    5035              : //              return false;
    5036              :                 return true;
    5037              :         }
    5038              : 
    5039              :         for( SegmentVolElmInfo const & svei : vecSegVolElmInf )
    5040              :         {
    5041              :                 // count the number of the fracture subdomains surrounding the segment
    5042              :                 // in case of boundary vertex, also count the number of boundary subdomains
    5043              : 
    5044              :                 std::vector<IndexType> sudosInSegment;
    5045              : 
    5046              :                 if( ! extracFractSudosOfSegment( svei, sudosInSegment ) )
    5047              :                 {
    5048              :                         UG_LOG("kann sudos nicht extrahieren " << std::endl);
    5049              :                         UG_THROW("kann sudos nicht extrahieren " << std::endl);
    5050              :                         return false;
    5051              :                 }
    5052              : 
    5053              :                 IndexType sudoNumInSeg = sudosInSegment.size();
    5054              : 
    5055              :                 // check if is boundary vertex
    5056              : 
    5057              :                 auto & vrtxFracPrps = m_aaMarkVrtVFP[ oldVrt ];
    5058              : 
    5059              :                 bool vrtxIsBndVrt = vrtxFracPrps.getIsBndFracVertex();
    5060              : 
    5061              :                 UG_LOG("is bndry " << vrtxIsBndVrt << std::endl);
    5062              : 
    5063              :                 if( ! vrtxIsBndVrt )
    5064              :                 {
    5065              :                         // count number of fracture subdomains in the Segment, should have been done before......
    5066              : 
    5067              :                         // TODO FIXME ersetze das altmodische VrtxFracProptsStatus durch ein Zählen
    5068              :                         // der subdomains, die pro Segment wirklich vorkommen, nachdem die
    5069              :                         // auslaufenden fracture faces den generellen Faces zugeschlagen worden sind
    5070              :                         // diese Zählweise ist die erste Folgeaufgabe, damit der komische vrtxFractureProperties Status
    5071              :                         // weg geworfen werden kann, der ist nämlich nutzlos inzwischen, da er auch auslaufende
    5072              :                         // fracture faces zählt, was Unsinn ist.......
    5073              :                         // später folgt auch die Verallgemeinerung auf boundary vertizes, dann muss deren Wahl
    5074              :                         // vielleicht wieder dazu genommen werden.....
    5075              : 
    5076              :                         //Vorbereitung Ersetzung VertexFractureProperties Status
    5077              :                         // durch Zählen der Fracture Subdomains von jedem Segment
    5078              :                         // die Zählerei kann dann gemacht werden, wenn die doppelten offenen fracture faces
    5079              :                         // in die allgemeinen faces verschoben werden, dann geht das in einem Abwasch,
    5080              :                         // gehe dazu in die entsprechende Funktion
    5081              : 
    5082              : //                      if( vrtxFracPrps.getVrtxFracStatus() == VrtxFracProptsStatus::oneFracSuDoAtt )
    5083              :                         if( sudoNumInSeg == 1 )
    5084              :                         {
    5085              :                                 // standard case, one fracture
    5086              :                                 if( ! expandWithinTheSegment<1,false>( oldVrt, svei ) )
    5087              :                                 {
    5088              :                                         UG_LOG("Expandierung einfachster Fall schief gegangen " << std::endl);
    5089              :                                         return false;
    5090              :                                 }
    5091              :                         }
    5092              :                         else // unterscheiden zwei und drei vermutlich..... aber wichtiger Segmentzahl..... und dann kommt es darauf an, wieviele subdoms im einzelnen Segment sind
    5093              :                         {
    5094              : 
    5095              :                         }
    5096              : 
    5097              :                 }
    5098              :                 else
    5099              :                 {
    5100              :                         // boundary faces counted as fracture faces, but no expansion
    5101              :                         // zuerst aber die inneren Schnittvertizes, weil bei denen die Nicht-Null Expansion
    5102              :                         // gelernt werden kann, dann anzuwenden auf Null-Expansion senkrecht zu den boundaries......
    5103              :                 }
    5104              : 
    5105              :         }
    5106              : 
    5107              :         return true;
    5108              : }
    5109              : #endif
    5110              : 
    5111              : ///////////////////////////////////////////////////////////////////
    5112              : 
    5113            0 : bool ArteExpandFracs3D::establishSegmentLimitingSidesInfo()
    5114              : {
    5115              : 
    5116              :         UG_LOG("ESTABLISH SGEMENT LIM SIDE INFO" << std::endl );
    5117              : 
    5118            0 :         for( VertexIterator iterV = m_sel.begin<Vertex>(); iterV != m_sel.end<Vertex>(); ++ iterV )
    5119              :         {
    5120              :                 Vertex * oldVrt = *iterV;
    5121              : 
    5122            0 :                 UG_LOG("establish segm lim sides for " << m_aaPos[oldVrt] << std::endl);
    5123              : 
    5124              :                 VecSegmentLimitingSides & vecSegmLimSid = m_vrtxAttAccsVecSegmLimSid[oldVrt];
    5125              : 
    5126              :                 UG_LOG("Segment limiting sides got " << std::endl);
    5127              : 
    5128              :                 auto & vrtxFracPrps = m_aaMarkVrtVFP[ oldVrt ];
    5129              : 
    5130              :                 bool vrtxIsBndVrt = vrtxFracPrps.getIsBndFracVertex();
    5131              : 
    5132              :                 UG_LOG("is bndry " << vrtxIsBndVrt << std::endl);
    5133              : 
    5134              :                 VecSegmentVolElmInfo & vecSegVolElmInf = m_accsAttVecSegVolElmInfo[oldVrt];
    5135              : 
    5136              :                 UG_LOG("CHECK SIZE" << std::endl);
    5137              : 
    5138            0 :                 if( vecSegVolElmInf.size() < 2 )
    5139              :                 {
    5140              :                         UG_LOG("nur ein Segment, aber will frische Vertizes?" << std::endl);
    5141              :         //              UG_THROW("nur ein Segment, aber will frische Vertizes?" << std::endl);
    5142              :         //              return false;
    5143              : //                      return true;
    5144              :                         continue;
    5145              :                 }
    5146              : 
    5147              :                 UG_LOG("CONTINUED" << std::endl);
    5148              : 
    5149            0 :                 for( SegmentVolElmInfo const & segVolsElInf : vecSegVolElmInf )
    5150              :                 {
    5151              :                         // count the number of the fracture subdomains surrounding the segment
    5152              :                         // in case of boundary vertex, also count the number of boundary subdomains
    5153              : 
    5154              :         //              std::vector<IndexType> sudosInSegment;
    5155              : 
    5156              :                         // hier die neue Klasse und ihr averaing einführen, oder im Hauptloop der neuen Elemente.....
    5157              :                         // SegmentSides<....> in .h file für die richtigen template parameter Kurznamen geben und hier
    5158              :                         // Objekt erstellen und je nach ob mit oder ohne Bndry entsprechend aufladen und averagen.....
    5159              :                         // und zwar für jedes Segment einzeln, und abhängig von boundary oder nicht die boundary Geschichten
    5160              :                         // dazu oder auch nicht...... also einen VecSegmentSides erstellen auch, das einzelne Objekt
    5161              :                         // weiss dann, ob es eine Boundary ist..... vielleicht noch den Vektor dazu als übergebener Parameter
    5162              :                         // damit man den da drin weiter reichen kann?
    5163              :                         // wenn jedes Objekt des Vektors von SegmentSIdes sowohl seinen Vertex kennt als auch weiss,
    5164              :                         // ob es boundary oder nicht ist, kann danach darüber geloopt werden, ohne nochmal
    5165              :                         // aussen den Vertex mit geben zu müssen, oder die Info, ob bndry oder nicht.....
    5166              :                         // danach gibts dann Funktionen, die alleine ein Objekt von der Sorte SegmentSides schlucken brauchen
    5167              :                         // und hier nur ein Loop über den ganzen Vektor davon, wo für jedes Element dann die Fkt aufgerufen wird....
    5168              : 
    5169              :                         SegmentLimitingSides segLimSids( oldVrt, vrtxIsBndVrt );
    5170              : 
    5171              :         //              std::vector<Volume*> vecVolsOfSegment;
    5172              : 
    5173              :                         IndexType boundarySites = 0;
    5174              : 
    5175            0 :                         for( AttachedVolumeElemInfo const & volElmInf : segVolsElInf )
    5176              :                         {
    5177            0 :                                 if( ! segLimSids.schluckVecAttFractElm( volElmInf.getVecFractManifElem() ) )
    5178              :                                 {
    5179              :                                         UG_LOG("schlucken schief gegangen " << std::endl);
    5180            0 :                                         UG_THROW("schlucken schief gegangen " << std::endl);
    5181              :                                         return false;
    5182              :                                 }
    5183              : 
    5184              : 
    5185            0 :                                 if( volElmInf.hasUnclosedFracture() )
    5186              :                                 {
    5187            0 :                                         if( ! segLimSids.schluckVecAttUnclosedFractElm( volElmInf.getVecUnclosedFractManifElem() ) )
    5188              :                                         {
    5189              :                                                 UG_LOG("Schlucken von unclosed schief gegangen " << std::endl);
    5190              : //                                              UG_THROW("Schlucken von unclosed schief gegangen " << std::endl);
    5191              : //                                              return false;
    5192              :                                         }
    5193              :                                         else
    5194              :                                         {
    5195              :                                                 UG_LOG("ungeschlossene fracture geschluckt " << std::endl);
    5196              :                                         }
    5197              : 
    5198            0 :                                         if( ! segLimSids.hasUnclosedFaces() )
    5199              :                                         {
    5200              :                                                 UG_LOG("keine ungeschlossenen Gesichter " << std::endl);
    5201            0 :                                                 UG_THROW("keine ungeschlossenen Gesichter " << std::endl);
    5202              :                                         }
    5203              :                                 }
    5204              : 
    5205            0 :                                 if( vrtxIsBndVrt )
    5206              :                                 {
    5207              :                                         auto vecBndryManifelm = volElmInf.getVecBndryManifElem();
    5208              : 
    5209            0 :                                         IndexType sizeVecBndryManifElm = volElmInf.getVecBndryManifElem().size();
    5210              : 
    5211            0 :                                         boundarySites += sizeVecBndryManifElm;
    5212              : 
    5213              :         //                              if( ! segLimSids.schluckVecAttBndryElm( volElmInf.getVecBndryManifElem() ) )
    5214            0 :                                         if( ! segLimSids.schluckVecAttBndryElm( vecBndryManifelm ) )
    5215              :                                         {
    5216              :                                                 UG_LOG("schlucken B schief gegangen " << std::endl);
    5217            0 :                                                 UG_THROW("schlucken B schief gegangen " << std::endl);
    5218              :                                                 return false;
    5219              :                                         }
    5220              : 
    5221              :                                         // TODO FIXME es muss abgefangen werden, wenn bei einem boundary vertex gar keine boundary Seiten da sind
    5222              :         //                              if( (volElmInf.getVecBndryManifElem()).size() == 0  )
    5223            0 :                                         if( sizeVecBndryManifElm == 0  )
    5224            0 :                                                 UG_LOG("Grenze verloren gegangen " << m_aaPos[oldVrt] << std::endl);
    5225            0 :                                 }
    5226              : 
    5227              :                                 Volume * vol2Add = volElmInf.getFulldimElem();
    5228              :                                 segLimSids.schluckFulldimElem(vol2Add);
    5229              :                         }
    5230              : 
    5231            0 :                         if( vrtxIsBndVrt && boundarySites == 0 )
    5232              :                         {
    5233            0 :                                 UG_LOG("No boundary sites at " << m_aaPos[oldVrt] << std::endl);
    5234            0 :                                 UG_THROW("No boundary sites at " << m_aaPos[oldVrt] << std::endl);
    5235              :                         }
    5236              : 
    5237            0 :                         if( ! segLimSids.averageAll() )
    5238              :                         {
    5239              :                                 UG_LOG("keine Mittelung " << std::endl);
    5240            0 :                                 UG_THROW("keine Mittelung " << std::endl);
    5241              :                                 return false;
    5242              :                         }
    5243              : 
    5244            0 :                         vecSegmLimSid.push_back(segLimSids);
    5245            0 :                 }
    5246              : 
    5247              : 
    5248              :         }
    5249              : 
    5250              :         UG_LOG("END ESTABLISH SGEMENT LIM SIDE INFO" << std::endl );
    5251              : 
    5252              : 
    5253              :         return true;
    5254              : }
    5255              : 
    5256              : ///////////////////////////////////////////////////////////////////////
    5257              : 
    5258            0 : bool ArteExpandFracs3D::establishNewVertizesStasiBased( Vertex * const & oldVrt)
    5259              : {
    5260              : 
    5261            0 :         auto & vrtxFracPrps = m_aaMarkVrtVFP[ oldVrt ];
    5262              : 
    5263              :         bool vrtxIsBndVrt = vrtxFracPrps.getIsBndFracVertex();
    5264              : 
    5265              :         UG_LOG("is bndry " << vrtxIsBndVrt << std::endl);
    5266              : 
    5267              : 
    5268              : //      VecSegmentVolElmInfo & vecSegVolElmInf = m_accsAttVecSegVolElmInfo[oldVrt];
    5269              : //
    5270              : //      if( vecSegVolElmInf.size() < 2 )
    5271              : //      {
    5272              : //              UG_LOG("nur ein Segment, aber will frische Vertizes?" << std::endl);
    5273              : ////            UG_THROW("nur ein Segment, aber will frische Vertizes?" << std::endl);
    5274              : ////            return false;
    5275              : //              return true;
    5276              : //      }
    5277              : 
    5278            0 :         VecSegmentLimitingSides & vecSegmLimSid = m_vrtxAttAccsVecSegmLimSid[oldVrt];
    5279              : 
    5280            0 :         if(  vecSegmLimSid.size() == 0 )
    5281              :         {
    5282              :                 UG_LOG("keine verschiedenen Segmente" << std::endl);
    5283            0 :                 return true;
    5284              :         }
    5285              : 
    5286            0 :         if( vecSegmLimSid.size() == 1 )
    5287              :         {
    5288              :                 UG_LOG("sonderbarer Fall von nur einem Segment " << std::endl );
    5289            0 :                 UG_THROW("sonderbarer Fall von nur einem Segment " << std::endl );
    5290              :                 return false;
    5291              :         }
    5292              : 
    5293            0 :         for( SegmentLimitingSides & segLimSids : vecSegmLimSid )
    5294              :         {
    5295              : 
    5296            0 :                 if( segLimSids.hasUnclosedFaces() )
    5297              :                 {
    5298              :                         UG_LOG("beim ausdehnen ungeschlossene Gesichter " << std::endl);
    5299              :                 }
    5300              : 
    5301            0 :                 if( ! expandWithinTheSegment(segLimSids) )
    5302              :                 {
    5303              :                         UG_LOG("schief gegangen Vertex Erzeugung " << std::endl);
    5304              :                         //UG_THROW("schief gegangen Vertex Erzeugung " << std::endl);
    5305              :                         return false;
    5306              :                 }
    5307              :         }
    5308              : 
    5309              :         UG_LOG("Vertex creation hat funktioniert " << std::endl);
    5310              :         //      UG_THROW("Vertex creation failed " << std::endl);
    5311              : 
    5312            0 :         return true;
    5313              : 
    5314              : }
    5315              : 
    5316              : /////////////////////////////////////////////////////////////////
    5317              : 
    5318              : #if 0
    5319              : 
    5320              : bool ArteExpandFracs3D::establishNewVertizesStasiBased( Vertex * const & oldVrt)
    5321              : {
    5322              :         // anfangs nur für innere Vertizes mit einer fracture
    5323              : 
    5324              :         // testweise, später verallgemeinert mit den Boundary faces
    5325              : 
    5326              :         auto & vrtxFracPrps = m_aaMarkVrtVFP[ oldVrt ];
    5327              : 
    5328              :         bool vrtxIsBndVrt = vrtxFracPrps.getIsBndFracVertex();
    5329              : 
    5330              :         UG_LOG("is bndry " << vrtxIsBndVrt << std::endl);
    5331              : 
    5332              : //      if( vrtxIsBndVrt )
    5333              : //      {
    5334              : //              UG_LOG("boundary noch zu lösen, bisher nix machen" << std::endl);
    5335              : //              return true;
    5336              : //      }
    5337              : 
    5338              :         VecSegmentVolElmInfo & vecSegVolElmInf = m_accsAttVecSegVolElmInfo[oldVrt];
    5339              : 
    5340              :         if( vecSegVolElmInf.size() < 2 )
    5341              :         {
    5342              :                 UG_LOG("nur ein Segment, aber will frische Vertizes?" << std::endl);
    5343              : //              UG_THROW("nur ein Segment, aber will frische Vertizes?" << std::endl);
    5344              : //              return false;
    5345              :                 return true;
    5346              :         }
    5347              : 
    5348              : 
    5349              :         for( SegmentVolElmInfo const & segVolsElInf : vecSegVolElmInf )
    5350              :         {
    5351              :                 // count the number of the fracture subdomains surrounding the segment
    5352              :                 // in case of boundary vertex, also count the number of boundary subdomains
    5353              : 
    5354              : //              std::vector<IndexType> sudosInSegment;
    5355              : 
    5356              :                 // hier die neue Klasse und ihr averaing einführen, oder im Hauptloop der neuen Elemente.....
    5357              :                 // SegmentSides<....> in .h file für die richtigen template parameter Kurznamen geben und hier
    5358              :                 // Objekt erstellen und je nach ob mit oder ohne Bndry entsprechend aufladen und averagen.....
    5359              :                 // und zwar für jedes Segment einzeln, und abhängig von boundary oder nicht die boundary Geschichten
    5360              :                 // dazu oder auch nicht...... also einen VecSegmentSides erstellen auch, das einzelne Objekt
    5361              :                 // weiss dann, ob es eine Boundary ist..... vielleicht noch den Vektor dazu als übergebener Parameter
    5362              :                 // damit man den da drin weiter reichen kann?
    5363              :                 // wenn jedes Objekt des Vektors von SegmentSIdes sowohl seinen Vertex kennt als auch weiss,
    5364              :                 // ob es boundary oder nicht ist, kann danach darüber geloopt werden, ohne nochmal
    5365              :                 // aussen den Vertex mit geben zu müssen, oder die Info, ob bndry oder nicht.....
    5366              :                 // danach gibts dann Funktionen, die alleine ein Objekt von der Sorte SegmentSides schlucken brauchen
    5367              :                 // und hier nur ein Loop über den ganzen Vektor davon, wo für jedes Element dann die Fkt aufgerufen wird....
    5368              : 
    5369              :                 SegmentLimitingSides segLimSids( oldVrt, vrtxIsBndVrt );
    5370              : 
    5371              : //              std::vector<Volume*> vecVolsOfSegment;
    5372              : 
    5373              :                 IndexType boundarySites = 0;
    5374              : 
    5375              :                 for( AttachedVolumeElemInfo const & volElmInf : segVolsElInf )
    5376              :                 {
    5377              :                         if( ! segLimSids.schluckVecAttFractElm( volElmInf.getVecFractManifElem() ) )
    5378              :                         {
    5379              :                                 UG_LOG("schlucken schief gegangen " << std::endl);
    5380              :                                 UG_THROW("schlucken schief gegangen " << std::endl);
    5381              :                                 return false;
    5382              :                         }
    5383              : 
    5384              :                         if( vrtxIsBndVrt )
    5385              :                         {
    5386              :                                 auto vecBndryManifelm = volElmInf.getVecBndryManifElem();
    5387              : 
    5388              :                                 IndexType sizeVecBndryManifElm = volElmInf.getVecBndryManifElem().size();
    5389              : 
    5390              :                                 boundarySites += sizeVecBndryManifElm;
    5391              : 
    5392              : //                              if( ! segLimSids.schluckVecAttBndryElm( volElmInf.getVecBndryManifElem() ) )
    5393              :                                 if( ! segLimSids.schluckVecAttBndryElm( vecBndryManifelm ) )
    5394              :                                 {
    5395              :                                         UG_LOG("schlucken B schief gegangen " << std::endl);
    5396              :                                         UG_THROW("schlucken B schief gegangen " << std::endl);
    5397              :                                         return false;
    5398              :                                 }
    5399              : 
    5400              :                                 // TODO FIXME es muss abgefangen werden, wenn bei einem boundary vertex gar keine boundary Seiten da sind
    5401              : //                              if( (volElmInf.getVecBndryManifElem()).size() == 0  )
    5402              :                                 if( sizeVecBndryManifElm == 0  )
    5403              :                                         UG_LOG("Grenze verloren gegangen " << m_aaPos[oldVrt] << std::endl);
    5404              :                         }
    5405              : 
    5406              :                         Volume * vol2Add = volElmInf.getFulldimElem();
    5407              :                         segLimSids.schluckFulldimElem(vol2Add);
    5408              :                 }
    5409              : 
    5410              :                 if( vrtxIsBndVrt && boundarySites == 0 )
    5411              :                 {
    5412              :                         UG_LOG("No boundary sites at " << m_aaPos[oldVrt] << std::endl);
    5413              :                         UG_THROW("No boundary sites at " << m_aaPos[oldVrt] << std::endl);
    5414              :                 }
    5415              : 
    5416              :                 if( ! segLimSids.averageAll() )
    5417              :                 {
    5418              :                         UG_LOG("keine Mittelung " << std::endl);
    5419              :                         UG_THROW("keine Mittelung " << std::endl);
    5420              :                         return false;
    5421              :                 }
    5422              : 
    5423              : //              if( vrtxIsBndVrt )
    5424              : //              {
    5425              : //                      if( segLimSids. )
    5426              : //              }
    5427              : 
    5428              : //              for( SegmentLimitSidesPairSudoNorml segLimSiPSN : vecSegmLimSidPrSudoNorml )
    5429              : //              {
    5430              : //
    5431              : //              }
    5432              : 
    5433              : //              expandWithinTheSegment<SegmentVrtxFracStatus::oneFracSuDoAtt>(segLimSids
    5434              : 
    5435              :                 if( ! expandWithinTheSegment(segLimSids) )
    5436              :                 {
    5437              :                         UG_LOG("schief gegangen Vertex Erzeugung " << std::endl);
    5438              :                         UG_THROW("schief gegangen Vertex Erzeugung " << std::endl);
    5439              :                         return false;
    5440              :                 }
    5441              : 
    5442              : //              SegmentVrtxFracStatus segStatFract = segLimSids.spuckCrossingTyp();
    5443              : //
    5444              : //              switch( segStatFract )
    5445              : //              {
    5446              : //                      case SegmentVrtxFracStatus::noFracSuDoAtt :
    5447              : //                      {
    5448              : //                              UG_LOG("is not a fracture, but a segment?" << std::endl);
    5449              : //                              UG_THROW("is not a fracture, but a segment?" << std::endl);
    5450              : //                              return false;
    5451              : //                      }
    5452              : //                      case SegmentVrtxFracStatus::oneFracSuDoAtt :
    5453              : //                      {
    5454              : //                              if( ! expandWithinTheSegment<SegmentVrtxFracStatus::oneFracSuDoAtt,false,false>(segLimSids, vecVolsOfSegment) )
    5455              : //                              {
    5456              : //                                      UG_LOG("Expandierung 1 schief gegangen " << std::endl);
    5457              : //                                      UG_THROW("Expandierung 1 schief gegangen " << std::endl);
    5458              : //                                      return false;
    5459              : //                              }
    5460              : //                              break;
    5461              : //                      }
    5462              : //                      case SegmentVrtxFracStatus::twoFracSuDoAtt :
    5463              : //                      {
    5464              : //                              break; // TODO FIXME implementieren
    5465              : //                      }
    5466              : //                      case SegmentVrtxFracStatus::threeFracSuDoAtt :
    5467              : //                      {
    5468              : //                              if( ! expandWithinTheSegment<SegmentVrtxFracStatus::threeFracSuDoAtt,false,false>(segLimSids, vecVolsOfSegment) )
    5469              : //                              {
    5470              : //                                      UG_LOG("Expandierung 3 schief gegangen " << std::endl);
    5471              : //                                      UG_THROW("Expandierung 3 schief gegangen " << std::endl);
    5472              : //                                      return false;
    5473              : //                              }
    5474              : //                              break;
    5475              : //                      }
    5476              : //                      default :
    5477              : //                      {
    5478              : //                              UG_LOG("strange fracture crossing" << std::endl);
    5479              : //                              UG_THROW("strange fracture crossing?" << std::endl);
    5480              : //                              return false;
    5481              : //                      }
    5482              : //              }
    5483              :         }
    5484              : 
    5485              :         UG_LOG("Vertex creation hat funktioniert " << std::endl);
    5486              :         //      UG_THROW("Vertex creation failed " << std::endl);
    5487              : 
    5488              :         return true;
    5489              : }
    5490              : 
    5491              : #endif
    5492              : 
    5493              : //              if( ! extracFractSudosOfSegment( svei, sudosInSegment ) )
    5494              : //              {
    5495              : //                      UG_LOG("kann sudos nicht extrahieren " << std::endl);
    5496              : //                      UG_THROW("kann sudos nicht extrahieren " << std::endl);
    5497              : //                      return false;
    5498              : //              }
    5499              : //
    5500              : //              IndexType sudoNumInSeg = sudosInSegment.size();
    5501              : //
    5502              : //              // check if is boundary vertex
    5503              : //
    5504              : //              auto & vrtxFracPrps = m_aaMarkVrtVFP[ oldVrt ];
    5505              : //
    5506              : //
    5507              : //              if( ! vrtxIsBndVrt )
    5508              : //              {
    5509              : //                      // count number of fracture subdomains in the Segment, should have been done before......
    5510              : //
    5511              : //                      // TODO FIXME ersetze das altmodische VrtxFracProptsStatus durch ein Zählen
    5512              : //                      // der subdomains, die pro Segment wirklich vorkommen, nachdem die
    5513              : //                      // auslaufenden fracture faces den generellen Faces zugeschlagen worden sind
    5514              : //                      // diese Zählweise ist die erste Folgeaufgabe, damit der komische vrtxFractureProperties Status
    5515              : //                      // weg geworfen werden kann, der ist nämlich nutzlos inzwischen, da er auch auslaufende
    5516              : //                      // fracture faces zählt, was Unsinn ist.......
    5517              : //                      // später folgt auch die Verallgemeinerung auf boundary vertizes, dann muss deren Wahl
    5518              : //                      // vielleicht wieder dazu genommen werden.....
    5519              : //
    5520              : //                      //Vorbereitung Ersetzung VertexFractureProperties Status
    5521              : //                      // durch Zählen der Fracture Subdomains von jedem Segment
    5522              : //                      // die Zählerei kann dann gemacht werden, wenn die doppelten offenen fracture faces
    5523              : //                      // in die allgemeinen faces verschoben werden, dann geht das in einem Abwasch,
    5524              : //                      // gehe dazu in die entsprechende Funktion
    5525              : //
    5526              : ////                    if( vrtxFracPrps.getVrtxFracStatus() == VrtxFracProptsStatus::oneFracSuDoAtt )
    5527              : //                      if( sudoNumInSeg == 1 )
    5528              : //                      {
    5529              : //                              // standard case, one fracture
    5530              : //                              if( ! expandWithinTheSegment<1,false>( oldVrt, svei ) )
    5531              : //                              {
    5532              : //                                      UG_LOG("Expandierung einfachster Fall schief gegangen " << std::endl);
    5533              : //                                      return false;
    5534              : //                              }
    5535              : //                      }
    5536              : //                      else // unterscheiden zwei und drei vermutlich..... aber wichtiger Segmentzahl..... und dann kommt es darauf an, wieviele subdoms im einzelnen Segment sind
    5537              : //                      {
    5538              : //
    5539              : //                      }
    5540              : //
    5541              : //              }
    5542              : //              else
    5543              : //              {
    5544              : //                      // boundary faces counted as fracture faces, but no expansion
    5545              : //                      // zuerst aber die inneren Schnittvertizes, weil bei denen die Nicht-Null Expansion
    5546              : //                      // gelernt werden kann, dann anzuwenden auf Null-Expansion senkrecht zu den boundaries......
    5547              : //              }
    5548              : //
    5549              : //      }
    5550              : 
    5551              : //      UG_LOG("Vertex creation failed " << std::endl);
    5552              : //      UG_THROW("Vertex creation failed " << std::endl);
    5553              : //
    5554              : //
    5555              : //      return false;
    5556              : //
    5557              : 
    5558              : 
    5559              : ////////////////////////////////////////////////////////////////////
    5560              : 
    5561              : #if 0
    5562              : bool ArteExpandFracs3D::extracFractSudosOfSegment( SegmentVolElmInfo const & segmVolElmInfo, std::vector<ArteExpandFracs3D::IndexType> & sudosInSegment )
    5563              : {
    5564              : 
    5565              : 
    5566              :         VecAttachedFractFaceEdgeSudo vecAttFractFaces;
    5567              : 
    5568              :         for( AttachedVolumeElemInfo const & avei : segmVolElmInfo )
    5569              :         {
    5570              :                 VecAttachedFractFaceEdgeSudo const & vecAttFractVol = avei.getVecFractManifElem();
    5571              : 
    5572              :                 for( AttachedFractFaceEdgeSudo const & affe : vecAttFractVol )
    5573              :                 {
    5574              :                         vecAttFractFaces.push_back(affe);
    5575              :                 }
    5576              :         }
    5577              : 
    5578              :         IndexType numbContrFracFaces = vecAttFractFaces.size();
    5579              : 
    5580              :         if( numbContrFracFaces < 1 )
    5581              :         {
    5582              :                 UG_LOG("Kein Affe da " << std::endl);
    5583              :                 UG_THROW("Kein Affe da " << std::endl);
    5584              :                 return false;
    5585              :         }
    5586              : 
    5587              :         IndexType sudoBase = vecAttFractFaces[0].getSudo();
    5588              : 
    5589              :         sudosInSegment.push_back(sudoBase);
    5590              : 
    5591              :         // add sudos different from the base one
    5592              :         for( AttachedFractFaceEdgeSudo const & affe : vecAttFractFaces )
    5593              :         {
    5594              :                 IndexType sudoNeeded = affe.getSudo();
    5595              : 
    5596              :                 bool sudoIsKnown = false;
    5597              : 
    5598              :                 for( IndexType sudoInList : sudosInSegment )
    5599              :                 {
    5600              :                         if( sudoNeeded == sudoInList )
    5601              :                         {
    5602              :                                 sudoIsKnown = true;
    5603              :                         }
    5604              :                 }
    5605              : 
    5606              :                 if( ! sudoIsKnown )
    5607              :                 {
    5608              :                         sudosInSegment.push_back(sudoNeeded);
    5609              :                 }
    5610              : 
    5611              :         }
    5612              : 
    5613              :         return true;
    5614              : }
    5615              : #endif
    5616              : 
    5617              : 
    5618              : ////////////////////////////////////////////////////////////////////
    5619              : // for only one surrounding subdom around the segment, for example only one fracture, or T End like ending side
    5620              : // TODO FIXME alles in eine einzige Funktion, die verschiedene Unterfunktionen aufruft für verschiedene Zahlen
    5621              : // von Seiten innen und aussen!!!!
    5622              : //template<>
    5623              : //bool ArteExpandFracs3D::expandWithinTheSegment<ArteExpandFracs3D::SegmentVrtxFracStatus::oneFracSuDoAtt>( SegmentLimitingSides const & segmLimSides )
    5624            0 : bool ArteExpandFracs3D::expandWithinTheSegment( ArteExpandFracs3D::SegmentLimitingSides & segmLimSides )
    5625              : {
    5626              :         // should not be called for boundary vertices
    5627              : 
    5628              :         bool isBndry = segmLimSides.isBoundary();
    5629              : 
    5630              : 
    5631              : //      if( isBndry )
    5632              : //              return true;
    5633              : 
    5634              : //      if( isBndry )
    5635              : //      {
    5636              : //              UG_LOG("boundary noch zu behandeln " << std::endl);
    5637              : //              UG_THROW("boundary noch zu behandeln " << std::endl);
    5638              : //              return false;
    5639              : //      }
    5640              : 
    5641              : //      VecSegmentLimitSidesPairSudoNorml vecSegmLimSidPrSudoNrml;
    5642              :         VecPlaneDescriptor vecPlaneFracDescr;
    5643              : 
    5644              :         //      if( ! segmLimSides.spuckFractSudoNormls( vecSegmLimSidPrSudoNrml ) )
    5645            0 :         if( ! segmLimSides.spuckFractManifDescr( vecPlaneFracDescr, m_aaPos ) )
    5646              :         {
    5647            0 :                 UG_LOG("Spucken schief gegangen  " << segmLimSides.spuckCrossingTyp() << std::endl);
    5648            0 :                 UG_THROW("Spucken schief gegangen  " << segmLimSides.spuckCrossingTyp() << std::endl);
    5649              :                 return false;
    5650              :         }
    5651              : 
    5652              :         // falls Boundary, hier noch spuckBndryManifDescr aufrufen
    5653              : 
    5654            0 :         Vertex * oldVrt = segmLimSides.spuckVertex();
    5655              :         vector3 posOldVrt = m_aaPos[oldVrt];
    5656              : 
    5657              :         VecPlaneDescriptor vecShiftedPlaneDescript;
    5658              : 
    5659              : //      for( SegmentLimitSidesPairSudoNorml const & segLimSidPrSN : vecSegmLimSidPrSudoNrml )
    5660            0 :         for( PlaneDescriptor & planeDescr : vecPlaneFracDescr )
    5661              :         {
    5662            0 :                 UG_LOG("GOT MANIF TYP " << planeDescr.spuckManifTyp() << std::endl );
    5663              : //              IndexType const & sudoSide = segLimSidPrSN.first;
    5664              : //              vector3 const & normlAvrg = segLimSidPrSN.second;
    5665              : //
    5666              : //              // normal computed standard mässig directs of of the volume, we need that one into the volume
    5667              : //              vector3 normalOutsideVol;
    5668              : 
    5669              :                 // hier testen, ob die Subdomain von der Liste der fracture subdomains ist,
    5670              :                 // damit für den Fall von sich zwei schneidenden Ebenen für die dritte,
    5671              :                 // die als senkrecht zu den beiden anderen gesetzt werden soll, mit Verschiebung null,
    5672              :                 // analog Boundary sides, die künstliche Weite null erhalten kann hier
    5673              : 
    5674            0 :                 if( planeDescr.spuckManifTyp() != PlaneDescriptorType::isFracture )
    5675            0 :                         UG_THROW("muss fracture sein " << std::endl);
    5676              : //
    5677              :                 int sudoSide = planeDescr.spuckSudo();
    5678            0 :                 number width = m_fracInfosBySubset[sudoSide].width;;
    5679              : 
    5680              :                 // ensure that the width is nonzero only for real fractures, not for pseudo vectors or such stuff
    5681              : //              if( ! isBndry )
    5682              : //              {
    5683              : //                      if( planeDescr.spuckManifTyp() == PlaneDescriptorType::isFracture )
    5684              : //                      {
    5685              : //                              width = m_fracInfosBySubset[sudoSide].width;
    5686              : //                      }
    5687              : //                      else
    5688              : //                      {
    5689              : //                              UG_LOG("Manif Typ is " << planeDescr.spuckManifTyp() << std::endl );
    5690              : //                              UG_LOG("Fract wäre " << PlaneDescriptorType::isFracture << std::endl );
    5691              : //                              UG_LOG("Bndry wäre " << PlaneDescriptorType:: << std::endl );
    5692              : //                              UG_LOG("Artif wäre " << PlaneDescriptorType::isArtificial << std::endl );
    5693              : //
    5694              : //                              UG_THROW("keine Boundary, aber will Boundary Manif" << std::endl);
    5695              : //                      }
    5696              : //              }
    5697              : //              else
    5698              : //              {
    5699              : //                      UG_THROW("hier nur keine boundary" << std::endl);
    5700              : //              }
    5701              : 
    5702              : 
    5703              : //              else
    5704              : //              {
    5705              : //      TODO FIXME              bei boundary auch noch für die entsprechenden boundaries
    5706              : //              }
    5707              : 
    5708            0 :                 number shiftScal = width / 2.;
    5709            0 :                 planeDescr.schluckScaleShiftNormal( - shiftScal );
    5710              : 
    5711              : //              vector3 shiftVec4Plane;
    5712              : //
    5713              : //              // as normal outside vol, but we need to go inside the volumes / segment side
    5714              : //              VecScale( shiftVec4Plane, normalOutsideVol, - shiftScal );
    5715              : 
    5716              : //              vecShiftVec4Plane.push_back( shiftVec4Plane );
    5717              : //              vecSudosSides.push_back( sudoSide );
    5718              : //              vecNormalsAveraged.push_back( normalIntoVol );
    5719              : 
    5720              : //              PlaneDescriptor planeDescr( normalOutsideVol, posOldVrt, shiftScal );
    5721              : 
    5722              :                 PlaneDescriptor shiftedPlaneDescr;
    5723            0 :                 planeDescr.spuckPlaneShifted( shiftedPlaneDescr );
    5724              : 
    5725              :                 //              planeDescr.spuckPlaneShiftedAlong( shiftVec4Plane, shiftedPlaneDescr );
    5726              : 
    5727            0 :                 vecShiftedPlaneDescript.push_back( shiftedPlaneDescr );
    5728              :         }
    5729              : 
    5730              :         // TODO FIXME test if the new points might squeeze the volumes
    5731              : 
    5732              : //      std::vector<Volume*> volsOfSegm;
    5733              : //
    5734              : //      if( ! segmLimSides.spuckListLowdimElmsOfVols( volsOfSegm, m_grid ) )
    5735              : //      {
    5736              : //              UG_LOG("which attached edges? " << std::endl);
    5737              : //              UG_LOG("which attached edges? " << std::endl);
    5738              : //      }
    5739              : 
    5740            0 :         bool testNewPoints = testIfNewPointsSqueezeVolumes( segmLimSides, vecShiftedPlaneDescript );
    5741              : 
    5742              :         UG_LOG("TESTING NEW POINTS IS " << testNewPoints << " of " << true << " or " << false << std::endl);
    5743              : 
    5744              : //      if( ! testIfNewPointsSqueezeVolumes( segmLimSides, vecShiftedPlaneDescript ) )
    5745            0 :         if( ! testNewPoints )
    5746              :         {
    5747              :                 UG_LOG("CAUTION: expansion probably violates the surrounding volumes!" << std::endl);
    5748              : //              return false;
    5749              :         }
    5750              : 
    5751              :         // will get the sudo of the shifted vertex
    5752              :         IndexType sudoExample = (vecPlaneFracDescr[0]).spuckSudo();
    5753              :         vector3 posNewVrt; // to be determined depending on the segment properties
    5754              : 
    5755              :         bool hasUnclosedFaces = segmLimSides.hasUnclosedFaces();
    5756              : 
    5757            0 :         if( hasUnclosedFaces )
    5758              :         {
    5759              :                 UG_LOG("hat ungeschlossene Seiten " << std::endl);
    5760              :         }
    5761              : 
    5762            0 :         if( ! isBndry && vecShiftedPlaneDescript.size() == 1 )
    5763              :         {
    5764              :                 // die unclosed crossing faces behandeln!!!
    5765              : 
    5766              :                 // muss wieder eingeschaltet werden hier
    5767              :                 // use the hasUnclosedFaces property, but for visual debugging, better set as false
    5768              :                 bool distinguishUnclosedFaces = segmLimSides.hasUnclosedFaces();
    5769              : //              constexpr bool distinguishUnclosedFaces = false; // segmLimSides.hasUnclosedFaces();
    5770              :                 UG_LOG("Please use switch unclosed faces in final version, please remove debugging set false" << std::endl);
    5771              : 
    5772            0 :                 if( ! distinguishUnclosedFaces ) // standard case, just shift perpendicular to the plane, no SLE to solve
    5773              :                 {
    5774              :                         //              // one single inner fracture, Testfall Anfang
    5775              :                         //              computeShiftVector( vecShiftedPlaneDescript[0] );
    5776            0 :                         posNewVrt = (vecPlaneFracDescr[0]).spuckShiftedBaseVect();
    5777              : 
    5778              :                 }
    5779              :                 else
    5780              :                 {
    5781              :                         // NOTE: TODO FIXME funktioniert vermutlich auch, wenn der Vertex ein Boundary Vertex ist
    5782              :                         // ob der Spezialfall aber auch praktisch vorkommt, fragwürdig
    5783              :                         // Test der Methode erstmal innen drin, später ggf. Ausweitung auf Grenzvertizes
    5784              :                         // dann würde das hier raus wandern aus dem Frage ob Boundary oder nicht, isBndry wäre egal
    5785              :                         // relevant wäre dass size des vecShiftPlaneDescr 1 ist und withUnclosedFaces true
    5786              : 
    5787              : 
    5788            0 :                         Edge * shiftDirectionEdg = nullptr;
    5789              : 
    5790              :                         if( ! segmLimSides.spuckLowdimElmShiftDirectionIfUnclosedFractPresent(shiftDirectionEdg) )
    5791              :                         {
    5792              :                                 UG_LOG("no shift direction " << std::endl);
    5793            0 :                                 UG_THROW("no shift direction " << std::endl);
    5794              : 
    5795              :                         }
    5796              : 
    5797              :                         if( shiftDirectionEdg == nullptr )
    5798              :                         {
    5799              :                                 UG_LOG("Null Shift cross end?" << std::endl);
    5800              :                                 UG_THROW("Null Shift cross end?" << std::endl);
    5801              :                         }
    5802              : 
    5803              :                         // jetzt sollte also die shift direction bekannt sein, muss normalisiert werden,
    5804              :                         // vielleicht kann man das im PlaneDescriptor drin auch machen
    5805              : 
    5806              :                         PlaneDescriptor const & shiftedPlane = vecShiftedPlaneDescript[0];
    5807              : 
    5808              : 
    5809            0 :                         if( ! computeCrossPointOfPlaneWithLine( shiftedPlane, shiftDirectionEdg, oldVrt, posNewVrt ) )
    5810              :                         {
    5811              :                                 UG_LOG("CAUTION: shifting cross point along ending crossing cleft edge might break volumes " << std::endl);
    5812              : 
    5813              : //                              UG_LOG("Not possible to compute crossing point plane with line" << std::endl);
    5814              : //                              UG_THROW("Not possible to compute crossing point plane with line" << std::endl);
    5815              :                         }
    5816              :                 }
    5817              :         }
    5818              :         else
    5819              :         {
    5820            0 :                 if( ! isBndry && vecShiftedPlaneDescript.size() > 1 )
    5821              :                 {
    5822              : 
    5823            0 :                         if( vecShiftedPlaneDescript.size() == 2 )
    5824              :                         {
    5825              :                                 // we need to add an artificial plane which gets extended with scale 0
    5826              : 
    5827              :                                 vector3 artificialNormal;
    5828            0 :                                 VecCross( artificialNormal, vecShiftedPlaneDescript[0].spuckNormalVector(), vecShiftedPlaneDescript[1].spuckNormalVector() );
    5829              : 
    5830            0 :                                 PlaneDescriptor artificialPlane( artificialNormal, posOldVrt );
    5831              : 
    5832            0 :                                 vecShiftedPlaneDescript.push_back(artificialPlane);
    5833              :                         }
    5834              : 
    5835            0 :                         if( vecShiftedPlaneDescript.size() > 3  )
    5836            0 :                                 UG_THROW("too much fractures" << std::endl);
    5837              : 
    5838              :                         // now we should have three planes to cross
    5839              : 
    5840              :                 }
    5841            0 :                 else if( isBndry )
    5842              :                 {
    5843              :                         VecPlaneDescriptor vecPlaneBndryDescr;
    5844              : 
    5845              :                         //      if( ! segmLimSides.spuckFractSudoNormls( vecSegmLimSidPrSudoNrml ) )
    5846            0 :                         if( ! segmLimSides.spuckBndryManifDescr( vecPlaneBndryDescr, m_aaPos ) )
    5847              :                         {
    5848            0 :                                 UG_LOG("Spucken schief gegangen bndry " << segmLimSides.spuckCrossingTyp() << std::endl);
    5849            0 :                                 UG_THROW("Spucken schief gegangen bndry " << segmLimSides.spuckCrossingTyp() << std::endl);
    5850              :                                 return false;
    5851              :                         }
    5852              : 
    5853            0 :                         if( vecPlaneBndryDescr.size() < 1 )
    5854              :                         {
    5855            0 :                                 UG_LOG("at point " << m_aaPos[oldVrt] << std::endl);
    5856              : 
    5857            0 :                                 UG_LOG("BOUNRARY PPPPP vertex BOUNDARY size problem " << m_aaPos[oldVrt] << std::endl);
    5858              : 
    5859              :                                 UG_LOG("Boundaries" << std::endl);
    5860            0 :                                 for( PlaneDescriptor pd : vecPlaneBndryDescr  )
    5861              :                                 {
    5862            0 :                                         UG_LOG("Subdom " << pd.spuckSudo() << std::endl);
    5863            0 :                                         UG_LOG("Base " << pd.spuckBaseVector() << std::endl);
    5864            0 :                                         UG_LOG("Normal " << pd.spuckNormalVector() <<std::endl);
    5865              :                                 }
    5866              : 
    5867              :                                 UG_LOG("Shifted" << std::endl);
    5868            0 :                                 for( PlaneDescriptor pd : vecShiftedPlaneDescript  )
    5869              :                                 {
    5870            0 :                                         UG_LOG("Subdom S " << pd.spuckSudo() << std::endl);
    5871            0 :                                         UG_LOG("Base S " << pd.spuckBaseVector() << std::endl);
    5872            0 :                                         UG_LOG("Normal S " << pd.spuckNormalVector() <<std::endl);
    5873              :                                 }
    5874              : 
    5875              :                                 UG_LOG("Fracs " << std::endl);
    5876            0 :                                 for( PlaneDescriptor pd : vecPlaneFracDescr  )
    5877              :                                 {
    5878            0 :                                         UG_LOG("Subdom F " << pd.spuckSudo() << std::endl);
    5879            0 :                                         UG_LOG("Base F " << pd.spuckBaseVector() << std::endl);
    5880            0 :                                         UG_LOG("Normal F " << pd.spuckNormalVector() <<std::endl);
    5881              :                                 }
    5882              : 
    5883              : 
    5884              :                                 // PROBLEM PPPPPPPPPPPPPPPPP
    5885            0 :                                 UG_THROW("NO boundary sudos " << std::endl);
    5886              :                         }
    5887              : 
    5888              :                         bool needToAverage = false;
    5889              : 
    5890            0 :                         if( vecPlaneBndryDescr.size() > 2 )
    5891              :                         {
    5892              : 
    5893              :                                 UG_LOG("dudos" << std::endl);
    5894            0 :                                 for( PlaneDescriptor pd : vecPlaneBndryDescr )
    5895              :                                 {
    5896              :                                         int sudo = pd.spuckSudo();
    5897            0 :                                         UG_LOG("sudos " << sudo << std::endl);
    5898              : 
    5899              :                                 }
    5900            0 :                                 UG_LOG("at point " << m_aaPos[oldVrt] << std::endl);
    5901              :                                 UG_LOG("too much boundary sudos - NEED TO AVERAGE OVER ALL - introduce pseudo boundary descriptor, size 1" << vecPlaneBndryDescr.size() << std::endl);
    5902              : 
    5903              :                                 needToAverage = true;
    5904              :                         }
    5905            0 :                         else if( vecPlaneBndryDescr.size() == 2 )
    5906              :                         {
    5907            0 :                                 if( vecPlaneFracDescr.size() == 2  )
    5908              :                                 {
    5909              :                                         UG_LOG("zwei Boundary subdoms plus zwei Kreuzungen " << std::endl);
    5910              :                                         needToAverage = true;
    5911              :                                 }
    5912              :                                 else
    5913              :                                 {
    5914              :                                         // depending on angle between the two boundary normals, an averaging also useful, if too similar
    5915              : 
    5916              :                                         vector3 const & normalOne = vecPlaneBndryDescr[0].spuckNormalVector();
    5917              :                                         vector3 const & normalTwo = vecPlaneBndryDescr[1].spuckNormalVector();
    5918              : 
    5919              :                                         number lengthOne = VecLength(normalOne);
    5920              :                                         number lengthTwo = VecLength(normalTwo);
    5921              : 
    5922              :                                         vector3 crossVec;
    5923              : 
    5924            0 :                                         VecCross(crossVec, normalOne, normalTwo);
    5925              : 
    5926              :                                         number crossProdBetween = VecLength(crossVec);
    5927              : 
    5928              :                                         number tol = 1e-1;
    5929              : 
    5930            0 :                                         number deviationOne = std::fabs( (lengthOne - 1.) / (lengthOne + 1 ) );
    5931            0 :                                         number deviationTwo = std::fabs( (lengthTwo - 1.) / (lengthTwo + 1 ) );
    5932              : 
    5933            0 :                                         if( deviationOne > tol || deviationTwo > tol )
    5934              :                                         {
    5935            0 :                                                 UG_LOG("Normals no length one " << normalOne << " " << normalTwo << std::endl);
    5936            0 :                                                 UG_THROW("Normals no length one " << normalOne << " " << normalTwo << std::endl);
    5937              :                                         }
    5938              : 
    5939            0 :                                         number sinBetween = std::fabs( crossProdBetween / lengthOne / lengthTwo );
    5940              : 
    5941              :                                         number decisionSin = 0.05;
    5942              : 
    5943            0 :                                         if( decisionSin > sinBetween )
    5944              :                                         {
    5945              :                                                 needToAverage = true;
    5946              : //                                              m_sh.assign_subset(oldVrt, m_sh.num_subsets());
    5947              : //                                              return false;
    5948              : 
    5949              :                                         }
    5950              : 
    5951              :                                         // very close, so better average, as they might be even parallel
    5952              :                                 }
    5953              :                         }
    5954              : 
    5955              : 
    5956              : 
    5957              :                         if( ! needToAverage  )
    5958              :                         {
    5959              : 
    5960            0 :                                 if( vecShiftedPlaneDescript.size() + vecPlaneBndryDescr.size() > 3 )
    5961            0 :                                         UG_THROW("too much crossing stuff at boundary"<<std::endl);
    5962              : 
    5963            0 :                                 for( PlaneDescriptor const & pbd : vecPlaneBndryDescr )
    5964              :                                 {
    5965            0 :                                         vecShiftedPlaneDescript.push_back( pbd );
    5966              :                                 }
    5967              : 
    5968            0 :                                 if( vecPlaneBndryDescr.size() == 2 )
    5969              :                                 {
    5970              :                                         // PROBLEM PPPPPPPPPPPPPPPP
    5971            0 :                                         if( vecShiftedPlaneDescript.size() != 3 ||  vecPlaneFracDescr.size() != 1 )
    5972              :                                         {
    5973            0 :                                                 UG_LOG("BOUNRARY PPPPP vertex TWO problem " << m_aaPos[oldVrt] << std::endl);
    5974              : 
    5975              :                                                 UG_LOG("Boundaries" << std::endl);
    5976            0 :                                                 for( PlaneDescriptor pd : vecPlaneBndryDescr  )
    5977              :                                                 {
    5978            0 :                                                         UG_LOG("Subdom " << pd.spuckSudo() << std::endl);
    5979            0 :                                                         UG_LOG("Base " << pd.spuckBaseVector() << std::endl);
    5980            0 :                                                         UG_LOG("Normal " << pd.spuckNormalVector() <<std::endl);
    5981              :                                                 }
    5982              : 
    5983              :                                                 UG_LOG("Shifted" << std::endl);
    5984            0 :                                                 for( PlaneDescriptor pd : vecShiftedPlaneDescript  )
    5985              :                                                 {
    5986            0 :                                                         UG_LOG("Subdom S " << pd.spuckSudo() << std::endl);
    5987            0 :                                                         UG_LOG("Base S " << pd.spuckBaseVector() << std::endl);
    5988            0 :                                                         UG_LOG("Normal S " << pd.spuckNormalVector() <<std::endl);
    5989              :                                                 }
    5990              : 
    5991              :                                                 UG_LOG("Fracs " << std::endl);
    5992            0 :                                                 for( PlaneDescriptor pd : vecPlaneFracDescr  )
    5993              :                                                 {
    5994            0 :                                                         UG_LOG("Subdom F " << pd.spuckSudo() << std::endl);
    5995            0 :                                                         UG_LOG("Base F " << pd.spuckBaseVector() << std::endl);
    5996            0 :                                                         UG_LOG("Normal F " << pd.spuckNormalVector() <<std::endl);
    5997              :                                                 }
    5998              : 
    5999            0 :                                                 UG_THROW("noch nicht genug Grenzen " << std::endl);
    6000              : 
    6001              :                                         }
    6002              :                                 }
    6003            0 :                                 else if( vecPlaneBndryDescr.size() == 1 )
    6004              :                                 {
    6005            0 :                                         if( vecShiftedPlaneDescript.size() < 3 )
    6006              :                                                 UG_LOG("noch nicht genug Grenzen " << std::endl);
    6007              : 
    6008            0 :                                         if( vecShiftedPlaneDescript.size() > 3 )
    6009              :                                                 UG_LOG("too much Grenzen " << std::endl);
    6010              : 
    6011            0 :                                         if( vecPlaneFracDescr.size() != 1 && vecPlaneFracDescr.size() != 2 )
    6012            0 :                                                 UG_THROW("Nicht passend Fract plus Bndry" << std::endl);
    6013              : 
    6014              :         //                              if( vecPlaneFracDescr.size() == 1 && vecPlaneFracDescr.size() == 2 )
    6015              :         //                                      if( vecShiftedPlaneDescript.size() != 3 )
    6016              :         //                                              UG_THROW"SO viele unsinnige Kombinationen " << std::endl );
    6017              : 
    6018            0 :                                         if( vecPlaneFracDescr.size() == 2 )
    6019              :                                         {
    6020            0 :                                                 if( vecShiftedPlaneDescript.size() != 3 )
    6021            0 :                                                         UG_THROW("da passt nicht zusammen was 3 sein sollte" << std::endl);
    6022              : 
    6023              :                                                 // sonst nix zu tun
    6024              :                                         }
    6025              :                                         else if( vecPlaneFracDescr.size() == 1 )
    6026              :                                         {
    6027            0 :                                                 if( vecShiftedPlaneDescript.size() != 2 )
    6028              :                                                         UG_LOG("1+2 nicht 3" << std::endl);
    6029              : 
    6030              :                                                 // add an artificial perpendicular plane with move vector zero
    6031              : 
    6032              :                                                 vector3 artificialNormal;
    6033            0 :                                                 VecCross( artificialNormal, vecShiftedPlaneDescript[0].spuckNormalVector(), vecShiftedPlaneDescript[1].spuckNormalVector() );
    6034              : 
    6035            0 :                                                 PlaneDescriptor artificialPlane( artificialNormal, posOldVrt );
    6036              : 
    6037            0 :                                                 vecShiftedPlaneDescript.push_back(artificialPlane);
    6038              : 
    6039              :                                         }
    6040              : 
    6041              : 
    6042              : 
    6043              :                                 }
    6044              : 
    6045              :                         }
    6046              :                         else
    6047              :                         {
    6048              :                                 // need to average boundaries
    6049              : 
    6050              :                                 // AVERAGE in this case and introduce an averaged pseudo boundary descriptor
    6051              :                                 // AAAAAAAAAAAAAAAA
    6052              : 
    6053              :                                 vector3 averagedNormal;
    6054              : 
    6055              : //                              if( ! averageBndryNormals( VecPlaneDescriptor const & vecPlaneBndryDescr, vector3 & averagedNormal ) )
    6056            0 :                                 if( ! averageBndryNormals( vecPlaneBndryDescr, averagedNormal ) )
    6057              :                                 {
    6058              :                                         UG_LOG("NORMAL NOT AVERAGABLE" << std::endl);
    6059            0 :                                         UG_THROW("NORMAL NOT AVERAGABLE" << std::endl);
    6060              :                                         return false;
    6061              :                                 }
    6062              : 
    6063            0 :                                 PlaneDescriptor averagedBoundaryPlane( averagedNormal, posOldVrt );
    6064            0 :                                 vecShiftedPlaneDescript.push_back(averagedBoundaryPlane);
    6065              : 
    6066            0 :                                 if( vecPlaneFracDescr.size() == 1 )
    6067              :                                 {
    6068              :                                         // behave as if we would have one boundary and thus need one additional artificial normal
    6069              : 
    6070              :                                         vector3 artificialNormal;
    6071            0 :                                         VecCross( artificialNormal, vecShiftedPlaneDescript[0].spuckNormalVector(), averagedNormal );
    6072              : 
    6073            0 :                                         PlaneDescriptor artificialPlane( artificialNormal, posOldVrt );
    6074              : 
    6075            0 :                                         vecShiftedPlaneDescript.push_back(artificialPlane);
    6076              :                                 }
    6077              : 
    6078              :                         }
    6079              : 
    6080              : 
    6081            0 :                 }
    6082              : 
    6083              :                 // vector shifted plane descriptor kriegt was dazu, wenn es keine drei sind ohne boundary
    6084              : 
    6085            0 :                 if( vecShiftedPlaneDescript.size() != 3 )
    6086            0 :                         UG_THROW("wie gross soll es denn sein" << std::endl);
    6087              : 
    6088            0 :                 computeCrossingPointOf3Planes( vecShiftedPlaneDescript, posNewVrt );
    6089              : 
    6090              :         }
    6091              : 
    6092              : 
    6093              : 
    6094              : //      if( vecSegmLimSidPrSudoNrml.size() != 1 )
    6095              : //      {
    6096              : //              UG_LOG("only one fracture, but not one normal and sudo?"  <<  std::endl);
    6097              : //              UG_THROW("only one fracture, but not one normal and sudo?" << std::endl);
    6098              : //              return false;
    6099              : //      }
    6100              : 
    6101              :         // FALL eins extra Funktion, unterscheiden nach Länge
    6102              : 
    6103              : //      if(  )
    6104              : 
    6105              : 
    6106              : //      SegmentLimitSidesPairSudoNorml & sudoAndNormal = vecSegmLimSidPrSudoNrml[0];
    6107              : //
    6108              : //      IndexType sudoBase = sudoAndNormal.first;
    6109              : //      vector3 normalsAveraged = sudoAndNormal.second;
    6110              : //
    6111              : //      Vertex * oldVrt = segmLimSides.spuckVertex();
    6112              : //
    6113              : //      number width = m_fracInfosBySubset[sudoBase].width;
    6114              : //
    6115              : //      number scal = width / 2.;
    6116              : //
    6117              : //      NormalVectorFacIntoVol scaledNormal;
    6118              : //
    6119              : //      VecScale( scaledNormal, normalsAveraged, - scal );
    6120              : //
    6121              : //      vector3 posOldVrt = m_aaPos[oldVrt];
    6122              : //
    6123              : //      UG_LOG("NORMAL OLD VRTX " << posOldVrt << " -> " << normalsAveraged << std::endl );
    6124              : 
    6125              : 
    6126              : //      VecAdd( posNewVrt, posOldVrt, scaledNormal );
    6127              : 
    6128            0 :         Vertex * newShiftVrtx = *m_grid.create<RegularVertex>();
    6129              : 
    6130            0 :         if( newShiftVrtx == nullptr )
    6131              :         {
    6132              :                 UG_LOG("Nullen erzeugt" << std::endl);
    6133            0 :                 UG_THROW("Nullen erzeugt" << std::endl);
    6134              :                 return false;
    6135              :         }
    6136              : 
    6137              :         m_aaPos[newShiftVrtx] = posNewVrt;
    6138              : 
    6139            0 :         UG_LOG("Created new vertex at " << m_aaPos[newShiftVrtx] << std::endl );
    6140              : 
    6141            0 :         m_sh.assign_subset(newShiftVrtx, sudoExample);
    6142              : //      m_sh.assign_subset(newShiftVrtx, m_sh.num_subsets());
    6143              : 
    6144              :         // wenn der neue Vertex mit einer ungeschlossenen endenden Kluft zu tun hat
    6145              :         // muss am Ende vom Kernvertex, old vertex, die edge, die nicht mit der
    6146              :         // kreuzenden nicht endenden KLuft geht, gelöscht werden
    6147              :         m_vrtxAttAccsVrtxArisesFromExpandedEndingCrossingCleft[newShiftVrtx] = hasUnclosedFaces;
    6148              : 
    6149              :         // TODO FIXME das auch verwenden
    6150              : 
    6151            0 :         if( hasUnclosedFaces )
    6152              :         {
    6153              :                 // TEST AUF ANZAHL der kreuzenden Klüfte, zusätzlich, ob es eine ist nur
    6154              :                 // zur Sicherheit
    6155            0 :                 if( isBndry || vecShiftedPlaneDescript.size() != 1 )
    6156              :                 {
    6157              :                         UG_LOG("Shift vertex but boundary or more than one shift direction " << std::endl);
    6158            0 :                         UG_THROW("Shift vertex but boundary or more than one shift direction " << std::endl);
    6159              :                 }
    6160              : 
    6161            0 :                 if( ! addElem( m_vrtxArisesFromExpandedEndingCrossingCleft, newShiftVrtx ) )
    6162              :                 {
    6163              :                         UG_LOG("Shifted ecf vertex schon bekannt " << std::endl);
    6164            0 :                         UG_THROW("Shifted ecf vertex schon bekannt " << std::endl);
    6165              :                 }
    6166              : 
    6167              :                 // TODO FIXME figure out segment limiting side of the member vector and add the shift vertex
    6168              : 
    6169              :                 Edge * shiftDirection = nullptr;
    6170              : 
    6171            0 :                 if( ! segmLimSides.spuckLowdimElmShiftDirectionIfUnclosedFractPresent( shiftDirection ) )
    6172              :                 {
    6173              :                         UG_LOG("No shift direction in ending crossing cleft segment " << std::endl);
    6174            0 :                         UG_THROW("No shift direction in ending crossing cleft segment " << std::endl);
    6175              :                 }
    6176              : 
    6177              :                 IndexType numFoundECFSI = 0;
    6178              : 
    6179              :                 // figure out the Ending crossing cleft segment info corresponding to this shift edge
    6180            0 :                 for( EndingCrossingFractureSegmentInfo const & ecfs : m_vecEndCrossFractSegmInfo )
    6181              :                 {
    6182            0 :                         if( ecfs.spuckLowdimElmShiftDirection() == shiftDirection )
    6183            0 :                                 numFoundECFSI++;
    6184              :                 }
    6185              : 
    6186            0 :                 if( numFoundECFSI != 1 )
    6187              :                 {
    6188              :                         UG_LOG("not one cefsi found " << numFoundECFSI << std::endl);
    6189            0 :                         UG_THROW("not one cefsi found " << numFoundECFSI << std::endl);
    6190              :                 }
    6191              : 
    6192            0 :                 for( EndingCrossingFractureSegmentInfo & ecfs : m_vecEndCrossFractSegmInfo )
    6193              :                 {
    6194            0 :                         if( ecfs.spuckLowdimElmShiftDirection() == shiftDirection )
    6195              :                         {
    6196            0 :                                 if( ! ecfs.schluckShiftVrtx( newShiftVrtx ) )
    6197              :                                 {
    6198            0 :                                         UG_LOG("Shift vertex wird nicht geschluckt" << m_aaPos[newShiftVrtx] << std::endl );
    6199            0 :                                         UG_THROW("Shift vertex wird nicht geschluckt" << m_aaPos[newShiftVrtx] << std::endl );
    6200              :                                         return false;
    6201              :                                 }
    6202              : 
    6203              :                                 break;
    6204              :                         }
    6205              :                 }
    6206              : 
    6207              :                 IndexType numFoundAssigned = 0;
    6208              : 
    6209            0 :                 for( EndingCrossingFractureSegmentInfo const & ecfs : m_vecEndCrossFractSegmInfo )
    6210              :                 {
    6211            0 :                         if( ecfs.spuckShiftVrtx() != nullptr && ecfs.spuckLowdimElmShiftDirection() == shiftDirection )
    6212            0 :                                 numFoundAssigned++;
    6213              :                 }
    6214              : 
    6215            0 :                 if( numFoundAssigned != 1 )
    6216              :                 {
    6217            0 :                         m_sh.assign_subset( oldVrt, m_sh.num_subsets());
    6218            0 :                         m_sh.assign_subset( shiftDirection, m_sh.num_subsets());
    6219              : 
    6220              : 
    6221              :                         UG_LOG( "num found assigend wrong " << numFoundAssigned );
    6222            0 :                         UG_THROW( "num found assigend wrong " << numFoundAssigned );
    6223              :                 }
    6224              : 
    6225              :                 UG_LOG("ending crossing cleft shift vertex generated " << std::endl);
    6226              : 
    6227              :         }
    6228              : 
    6229              :         std::vector<Volume*> volsInSegm;
    6230              : 
    6231              :         segmLimSides.spuckVecFulldimElem( volsInSegm );
    6232              : 
    6233            0 :         for( Volume * const & vol : volsInSegm )
    6234              :         {
    6235            0 :                 std::vector<Vertex*> & newVrts4Fac = m_aaVrtVecVol[ vol ];
    6236              : 
    6237            0 :                 for(size_t indVrt = 0; indVrt < (vol)->num_vertices();  indVrt++ )
    6238              :                 {
    6239            0 :                         Vertex* volVrt = (vol)->vertex(indVrt);
    6240              : 
    6241            0 :                         if(  volVrt == oldVrt )
    6242              :                         {
    6243            0 :                                 newVrts4Fac[ indVrt ] = newShiftVrtx;
    6244              :                         }
    6245              :                 }
    6246              :         }
    6247              : 
    6248              :         return true;
    6249              : 
    6250              : 
    6251            0 : }
    6252              : 
    6253              : //////////////////////////////////////////////////////////////////////////
    6254              : 
    6255              : 
    6256            0 : bool ArteExpandFracs3D::averageBndryNormals( VecPlaneDescriptor const & vecPlaneBndryDescr, vector3 & averagedNormal  )
    6257              : {
    6258            0 :         if( vecPlaneBndryDescr.size() == 0 )
    6259              :         {
    6260              :                 UG_LOG("no boundary" << std::endl);
    6261            0 :                 return false;
    6262              :         }
    6263              : 
    6264              :         vector3 normalsSum;
    6265              : 
    6266            0 :         for( PlaneDescriptor const & pd : vecPlaneBndryDescr )
    6267              :         {
    6268              :                 vector3 const & norml = pd.spuckNormalVector();
    6269              : 
    6270              :                 vector3 normalsSumBefore = normalsSum;
    6271              : 
    6272              :                 VecAdd(normalsSum, norml, normalsSumBefore );
    6273              :         }
    6274              : 
    6275            0 :         VecScale( averagedNormal, normalsSum, static_cast<number>(vecPlaneBndryDescr.size()) );
    6276              : 
    6277              :         return true;
    6278              : 
    6279              : }
    6280              : 
    6281              : 
    6282              : ///////////////////////////////////////////////////////////////////////////
    6283              : 
    6284            0 : bool ArteExpandFracs3D::testIfNewPointsSqueezeVolumes( ArteExpandFracs3D::SegmentLimitingSides & segmLimSides,
    6285              :                 ArteExpandFracs3D::VecPlaneDescriptor const & vecShiftedPlaneDescript )
    6286              : {
    6287              :         // TODO FIXME test if the new points might squeeze the volumes
    6288              : 
    6289              :         UG_LOG("TEST POINTS BEGIN " << std::endl);
    6290              : 
    6291              :         bool notViolated = true;
    6292              : 
    6293            0 :         IndexType debugSubs = m_sh.num_subsets();
    6294              : 
    6295            0 :         Vertex * oldVrt = segmLimSides.spuckVertex();
    6296              :         vector3 posOldVrt = m_aaPos[oldVrt];
    6297              : 
    6298              :         vector3 posTestVertex;
    6299              : 
    6300              :         std::vector<Edge*> vecEdgesOfSegVols;
    6301              : 
    6302            0 :         if( ! segmLimSides.spuckListLowdimElmsOfVols( vecEdgesOfSegVols, m_grid ) )
    6303              :         {
    6304              :                 UG_LOG("which attached edges? " << std::endl);
    6305              :                 UG_LOG("which attached edges? " << std::endl);
    6306              :         }
    6307              : 
    6308            0 :         if( vecEdgesOfSegVols.size() == 0 )
    6309              :         {
    6310              :                 UG_LOG("NO EDGES" << std::endl);
    6311              :         }
    6312              : 
    6313              :         std::vector<Volume*> attVols;
    6314              : 
    6315              :         segmLimSides.spuckVecFulldimElem(attVols);
    6316              : 
    6317            0 :         if( attVols.size() == 0 )
    6318              :         {
    6319              :                 UG_LOG("NO VOLS " << std::endl);
    6320              :         }
    6321              : 
    6322              :         UG_LOG("TEST POINTS MIDDLE " << notViolated << std::endl);
    6323              : 
    6324              : 
    6325            0 :         for( PlaneDescriptor const & shiftedPlane : vecShiftedPlaneDescript )
    6326              :         {
    6327              :                 std::vector<Edge *> manifoldEdges;
    6328              : 
    6329            0 :                 if( ! shiftedPlane.spuckLowDimElms(manifoldEdges) )
    6330              :                 {
    6331              :                         UG_LOG("NO MANIFOLD EDGED OF PLANE " << std::endl);
    6332            0 :                         UG_THROW("NO MANIFOLD EDGED OF PLANE " << std::endl);
    6333              :                 }
    6334              : 
    6335              :                 // TODO FIXME nur die Edges, die NICHT zur Basis-Ebene gehören, die, die zur Mannigfaltigkeit
    6336              :                 // gehören, die expandiert wird, müssen raus gefiltert werden!!!!!
    6337            0 :                 for( Edge * testEdge : vecEdgesOfSegVols )
    6338              :                 {
    6339              : //                      if( ! testEdge )
    6340              : //                              continue;
    6341              : 
    6342              :                         // test if testEdge belongs to the allowed Edges
    6343              : 
    6344              :                         bool isManifEdg = false;
    6345              : 
    6346            0 :                         for( Edge * me : manifoldEdges )
    6347              :                         {
    6348            0 :                                 if( me == testEdge )
    6349              :                                 {
    6350              :                                         isManifEdg = true;
    6351              :                                         UG_LOG("Test edge is manifold edge" << std::endl);
    6352            0 :                                         continue;
    6353              :                                 }
    6354              : 
    6355              :                                 // if edge belongs to manifold, it must not be considered!!!
    6356              :                         }
    6357              : 
    6358            0 :                         if( isManifEdg )
    6359            0 :                                 continue;
    6360              : 
    6361              :                         UG_LOG("TESTING CROSS POINT " << notViolated << std::endl);
    6362              : 
    6363              :                         // abuse of the compute cross point function originally developped for ending crossing cleft purposes
    6364            0 :                         if( ! computeCrossPointOfPlaneWithLine( shiftedPlane, testEdge, oldVrt, posTestVertex ) )
    6365              :                         {
    6366              :                                 UG_LOG("CAUTION: shifting cross point along test procedure cleft edge might break volumes " << std::endl);
    6367              : 
    6368              :                                 notViolated = false;
    6369              : 
    6370              :                                 UG_LOG("DEBUGGING WITH SUDO " << debugSubs << std::endl );
    6371              : 
    6372              : //                              return false;
    6373              : 
    6374            0 :                                 for( IndexType i = 0; i < 2; i++ )
    6375              :                                 {
    6376            0 :                                         Vertex * testVertex = testEdge->vertex(i);
    6377              : 
    6378            0 :                                         if( testVertex != oldVrt )
    6379              :                                         {
    6380            0 :                                                 addElem( m_vrtcsViolatingExpansion, testVertex );
    6381              :                                                 break;
    6382              :                                         }
    6383              :                                 }
    6384              : 
    6385            0 :                                 for( Volume * vol : attVols )
    6386              :                                 {
    6387            0 :                                         if( VolumeContains( vol, testEdge ))
    6388              :                                         {
    6389            0 :                                                 addElem(m_volsViolatingExpansion, vol);
    6390            0 :                                                 m_sh.assign_subset( vol, debugSubs );
    6391            0 :                                                 UG_LOG("CAUTION quenched volume, assigning debug subset " << debugSubs
    6392              :                                                                 << " for vol with center " << CalculateCenter( vol, m_aaPos )
    6393              :                                                                 << " for fracture subdomain " << shiftedPlane.spuckSudo() << std::endl);
    6394              :                                         }
    6395              :                                 }
    6396              : 
    6397              :                         }
    6398              : 
    6399              :                 }
    6400              : 
    6401            0 :         }
    6402              : 
    6403              :         UG_LOG("TEST POINTS END " << notViolated << " of " << true << " " << false << std::endl);
    6404              : 
    6405              : 
    6406            0 :         return true;
    6407              : 
    6408            0 : }
    6409              : 
    6410              : //////////////////////////////////////////////////////////////////////////
    6411              : 
    6412              : 
    6413            0 : bool ArteExpandFracs3D::computeCrossPointOfPlaneWithLine( PlaneDescriptor const & shiftedPlane, Edge * const & shiftDirectionEdg, Vertex * const & oldVrt, vector3 & posCrossingPt )
    6414              : {
    6415              :         UG_LOG("computing cross point start " << std::endl);
    6416              : 
    6417              :         vector3 const & normalShiftedPlane = shiftedPlane.spuckNormalVector();
    6418              :         vector3 const & baseShiftedPlane = shiftedPlane.spuckBaseVector();
    6419              :         number const & rhs = shiftedPlane.spuckRHS();
    6420              : 
    6421              :         // vector3 posOldVrt Aufpunkt der Edge, entland der verschoben werden soll
    6422              :         // establish
    6423              : 
    6424            0 :         if( ! ( EdgeContains(shiftDirectionEdg, oldVrt ) ) )
    6425              :         {
    6426              :                 UG_LOG("Shift edge ohne alten Vertex?" << std::endl);
    6427            0 :                 UG_THROW("Shift edge ohne alten Vertex?" << std::endl);
    6428              :         }
    6429              : 
    6430            0 :         vector3 posOldVrt = m_aaPos[oldVrt];
    6431              : 
    6432            0 :         UG_LOG("Pos old vertex CCP " << posOldVrt << std::endl);
    6433              : 
    6434              :         vector3 const & shiftVecBase = posOldVrt;
    6435              : 
    6436            0 :         Vertex * const & shiftEdgeVrtOne = shiftDirectionEdg->vertex(0);
    6437            0 :         Vertex * const & shiftEdgeVrtTwo = shiftDirectionEdg->vertex(1);
    6438              : 
    6439              :         vector3 shiftVecEnd = shiftVecBase; // needs to be changed still
    6440              : 
    6441            0 :         if( shiftEdgeVrtOne == oldVrt )
    6442              :         {
    6443              :                 shiftVecEnd = m_aaPos[shiftEdgeVrtTwo];
    6444              :         }
    6445            0 :         else if( shiftEdgeVrtTwo == oldVrt )
    6446              :         {
    6447              :                 shiftVecEnd = m_aaPos[shiftEdgeVrtOne];
    6448              :         }
    6449              :         else
    6450              :         {
    6451              :                 UG_LOG("no end vertex" << std::endl);
    6452            0 :                 UG_THROW("no end vertex" << std::endl);
    6453              :         }
    6454              : 
    6455              :         vector3 directionVec;
    6456              : 
    6457              :         VecSubtract(directionVec, shiftVecEnd, posOldVrt );
    6458              : 
    6459            0 :         UG_LOG("SHIVEEND " << shiftVecEnd << std::endl);
    6460            0 :         UG_LOG("POS OLD " << posOldVrt << std::endl);
    6461              : 
    6462              : 
    6463              :         // x = aufpunkt + s . r
    6464              :         // richtung einsetzen in ( x - x_0 ) * n = 0, auflösen nach s
    6465              :         // . gilt als Skalarprodukt, * als Kreuzprodukt hier in Notation
    6466              :         // x*n = rhs = x_0*n
    6467              :         // ( a + s . r -x0 ) * n = 0
    6468              :         // a * n + s . n * r - x0*n = 0
    6469              :         // s . ( n * r ) = x0 * n - a * n
    6470              :         // "Normallfall": n*r != 0
    6471              :         // dann gilt
    6472              :         // s = ( x0*n - a*n ) / ( n*r )
    6473              :         // Spezialfall: n*r = 0 dann, wenn Richtungsvektor Gerade und Normalenvektor Ebene übereinstimmen
    6474              :         // also wenn Verschiebung entlang der Normalen
    6475              :         // dann ist (x0-a) parallel zu n bzw r, dann ist die Frage, was für ein Vielfaches von r ist (x0-a)
    6476              :         // also a + s . r - x0 = 0 auflösen nach s
    6477              :         // s . r = x0 - a , muss auch für den Betrag gelten
    6478              :         // also s | r | = | x_0 - a |
    6479              :         // also s = | x_0 - a | / | r |
    6480              : 
    6481              :         number planeBaseMultNormal = VecDot(baseShiftedPlane,normalShiftedPlane);
    6482              :         number lineBaseMultNormal = VecDot(posOldVrt,normalShiftedPlane);
    6483              :         number lineDirMultNormal = VecDot( directionVec, normalShiftedPlane );
    6484              : 
    6485            0 :         UG_LOG("base shift plane " << baseShiftedPlane << std::endl);
    6486            0 :         UG_LOG("normal shift plane " << normalShiftedPlane << std::endl);
    6487            0 :         UG_LOG("pos Old " << posOldVrt << std::endl);
    6488            0 :         UG_LOG("direction " << directionVec << std::endl);
    6489              : 
    6490              : 
    6491            0 :         UG_LOG("COMPARE RHS AND LBMN " << rhs << " - " << planeBaseMultNormal << std::endl);
    6492              : 
    6493            0 :         number fbs = std::fabs( ( rhs - planeBaseMultNormal ) / ( rhs + planeBaseMultNormal) );
    6494              : 
    6495              :         UG_LOG("RELATIVE DIFF " << fbs << std::endl);
    6496              : 
    6497              :         number const d_toler = 1e-4;
    6498              : 
    6499            0 :         if( fbs > d_toler )
    6500              :         {
    6501              :                 UG_LOG("RELATIVE DIFF TOO BIG " << std::endl);
    6502            0 :                 UG_THROW("RELATIVE DIFF TOO BIG " << std::endl);
    6503              :         }
    6504              : 
    6505              :         number moveAlongLine = 0;
    6506              : 
    6507            0 :         if( lineDirMultNormal == 0. )
    6508              :         {
    6509              :                 UG_LOG("SHIFT denominator zero division " << std::endl);
    6510              : //              UG_THROW("denominator zero division " << std::endl);
    6511              : 
    6512              :                 vector3 connectNewAndOldBase;
    6513              :                 VecSubtract(connectNewAndOldBase, baseShiftedPlane, posOldVrt );
    6514              : 
    6515              :                 // Test also if the connection vector parallel to normalShiftedPlane and directionVec
    6516              : 
    6517              :                 number testParallShiftPlan = std::fabs( VecDot( connectNewAndOldBase, normalShiftedPlane ) );
    6518            0 :                 number testParallDirVec = std::fabs( VecDot( connectNewAndOldBase, directionVec ) );
    6519              : 
    6520            0 :                 if( testParallDirVec > d_toler || testParallDirVec > d_toler )
    6521              :                 {
    6522              :                         UG_LOG("VECTORS PARALLEL AND NOT " << std::endl);
    6523            0 :                         UG_THROW("VECTORS PARALLEL AND NOT " << std::endl);
    6524              :                 }
    6525              : 
    6526              :                 number lengthDirVec = VecLength(directionVec);
    6527              :                 number lengthConnVec = VecLength(connectNewAndOldBase);
    6528              : 
    6529            0 :                 moveAlongLine = lengthConnVec / lengthDirVec;
    6530              : 
    6531              :                 UG_LOG("MONULL " << lengthConnVec << " " << lengthDirVec << std::endl );
    6532              :         }
    6533              :         else
    6534              :         {
    6535            0 :                 moveAlongLine = ( planeBaseMultNormal - lineBaseMultNormal ) / lineDirMultNormal;
    6536              : 
    6537              :                 UG_LOG("MOAL  " << planeBaseMultNormal << " " <<  lineBaseMultNormal << " " <<  lineDirMultNormal << std::endl );
    6538              :         }
    6539              : 
    6540            0 :         if( moveAlongLine == 0. )
    6541              :         {
    6542              :                 UG_LOG("No Moving?" << std::endl);
    6543            0 :                 UG_THROW("No Moving?" << std::endl);
    6544              :         }
    6545              : 
    6546              :         vector3 shiftAlongLine;
    6547              : 
    6548              :         VecScale( shiftAlongLine, directionVec, moveAlongLine );
    6549              : 
    6550            0 :         UG_LOG("SHIFT " << shiftAlongLine << " Dir " << directionVec << " MOV " << moveAlongLine << std::endl );
    6551              : 
    6552              :         VecAdd( posCrossingPt, posOldVrt, shiftAlongLine );
    6553              : 
    6554              : //      m_allowedSqueeze = 0.8;
    6555              : 
    6556              : //      UG_LOG("MOVING " << moveAlongLine << std::endl);
    6557              : 
    6558              :         // falsch bei ending crossing cleft Verschiebung u.U. , zweiten Parameter dazu zur Unterscheidung?
    6559              :         // Vertex erzeugen wenn Problem an der Stelle? um zu sehen, wo es hin will?
    6560            0 :         if( moveAlongLine > m_allowedSqueeze )
    6561              :         {
    6562            0 :                 UG_LOG("MOVING ALONG LINE TOO BIG C " << posCrossingPt << " Old " << posOldVrt << " move " << shiftAlongLine << std::endl);
    6563              : 
    6564              :                 // create debug vertex at position of crossing point
    6565              : 
    6566            0 :                 Vertex * dbgVrtx = *m_grid.create<RegularVertex>();
    6567              : 
    6568              :                 m_aaPos[dbgVrtx] = posCrossingPt;
    6569              : 
    6570            0 :                 IndexType strangeSubs = m_sh.num_subsets();
    6571              : 
    6572            0 :                 m_sh.assign_subset(dbgVrtx, strangeSubs);
    6573              : 
    6574            0 :                 m_sh.assign_subset( shiftDirectionEdg, strangeSubs );
    6575              : //              m_sh.assign_subset( shiftDirectionEdg, m_sh.num_subsets() );
    6576              : 
    6577            0 :                 m_sh.assign_subset( shiftDirectionEdg->vertex(0), strangeSubs );
    6578            0 :                 m_sh.assign_subset( shiftDirectionEdg->vertex(1), strangeSubs );
    6579            0 :                 m_sh.assign_subset( oldVrt, strangeSubs );
    6580              : 
    6581              : 
    6582              :                 UG_LOG("computing cross point end false " << std::endl);
    6583              : 
    6584            0 :                 return false;
    6585              :         }
    6586              : 
    6587              :         UG_LOG("computing cross point end true " << std::endl);
    6588              : 
    6589              : 
    6590              :         return true;
    6591              : 
    6592              : }
    6593              : //////////////////////////////////////////////////////////////////////////
    6594              : 
    6595              : 
    6596              : #if 0
    6597              : template<>
    6598              : bool ArteExpandFracs3D::expandWithinTheSegment<1,false>( Vertex * const & oldVrt, SegmentVolElmInfo const & segmVolElmInfo )
    6599              : {
    6600              : 
    6601              :         // get all fracture faces, check if they belong to the same subdomain, must be the case here!
    6602              : 
    6603              :         VecAttachedFractFaceEdgeSudo vecAttFractFaces;
    6604              : 
    6605              :         for( AttachedVolumeElemInfo const & avei : segmVolElmInfo )
    6606              :         {
    6607              :                 VecAttachedFractFaceEdgeSudo const & vecAttFractVol = avei.getVecFractManifElem();
    6608              : 
    6609              :                 for( AttachedFractFaceEdgeSudo const & affe : vecAttFractVol )
    6610              :                 {
    6611              :                         vecAttFractFaces.push_back(affe);
    6612              :                 }
    6613              :         }
    6614              : 
    6615              :         IndexType numbContrFracFaces = vecAttFractFaces.size();
    6616              : 
    6617              :         if( numbContrFracFaces < 1 )
    6618              :         {
    6619              :                 UG_LOG("Kein Affe da " << std::endl);
    6620              :                 UG_THROW("Kein Affe da " << std::endl);
    6621              :                 return false;
    6622              :         }
    6623              : 
    6624              :         IndexType sudoBase = vecAttFractFaces[0].getSudo();
    6625              : 
    6626              :         // check if all sudos equal
    6627              :         for( AttachedFractFaceEdgeSudo const & affe : vecAttFractFaces )
    6628              :         {
    6629              :                 IndexType sudoTest = affe.getSudo();
    6630              : 
    6631              :                 if( sudoTest != sudoBase )
    6632              :                 {
    6633              :                         UG_LOG("unterschiedliche Sudos an einer einzelnen Fracture?" << std::endl);
    6634              :                         UG_THROW("unterschiedliche Sudos an einer einzelnen Fracture?" << std::endl);
    6635              :                         return false;
    6636              :                 }
    6637              :         }
    6638              : 
    6639              :         // now we are sure we have the same sudo, now we average the normals
    6640              : 
    6641              :         NormalVectorFacIntoVol normalsFacInVolSummed(0,0,0);
    6642              : 
    6643              :         for( AttachedFractFaceEdgeSudo const & affe : vecAttFractFaces )
    6644              :         {
    6645              :                 NormalVectorFacIntoVol tmpVec = normalsFacInVolSummed;
    6646              :                 UG_LOG("Normal Vec " << tmpVec << std::endl);
    6647              :                 VecAdd(normalsFacInVolSummed, tmpVec, affe.getNormalVec() );
    6648              :         }
    6649              : 
    6650              :         NormalVectorFacIntoVol normalsAveraged;
    6651              : 
    6652              :         VecScale( normalsAveraged, normalsFacInVolSummed, 1. / ( static_cast<number>(numbContrFracFaces) ) );
    6653              : 
    6654              :         number width = m_fracInfosBySubset[sudoBase].width;
    6655              : 
    6656              :         number scal = width / 2.;
    6657              : 
    6658              :         NormalVectorFacIntoVol scaledNormal;
    6659              : 
    6660              :         VecScale( scaledNormal, normalsAveraged, - scal );
    6661              : 
    6662              :         vector3 posOldVrt = m_aaPos[oldVrt];
    6663              : 
    6664              :         vector3 posNewVrt;
    6665              : 
    6666              :         VecAdd( posNewVrt, posOldVrt, scaledNormal );
    6667              : 
    6668              :         Vertex * newShiftVrtx = *m_grid.create<RegularVertex>();
    6669              : 
    6670              :         if( newShiftVrtx == nullptr )
    6671              :         {
    6672              :                 UG_LOG("Nullen erzeugt" << std::endl);
    6673              :                 UG_THROW("Nullen erzeugt" << std::endl);
    6674              :                 return false;
    6675              :         }
    6676              : 
    6677              :         m_aaPos[newShiftVrtx] = posNewVrt;
    6678              : 
    6679              :         UG_LOG("Created new vertex at " << m_aaPos[newShiftVrtx] << std::endl );
    6680              : 
    6681              :         m_sh.assign_subset(newShiftVrtx, sudoBase);
    6682              : 
    6683              :         for( AttachedVolumeElemInfo const & avei : segmVolElmInfo )
    6684              :         {
    6685              :                 Volume * vol = avei.getFulldimElem();
    6686              : 
    6687              :                 std::vector<Vertex*> & newVrts4Fac = m_aaVrtVecVol[ vol ];
    6688              : 
    6689              :                 for(size_t indVrt = 0; indVrt < (vol)->num_vertices();  indVrt++ )
    6690              :                 {
    6691              :                         Vertex* volVrt = (vol)->vertex(indVrt);
    6692              : 
    6693              :                         if(  volVrt == oldVrt )
    6694              :                         {
    6695              :                                 newVrts4Fac[ indVrt ] = newShiftVrtx;
    6696              :                         }
    6697              :                 }
    6698              :         }
    6699              : 
    6700              :         return true;
    6701              : }
    6702              : #endif
    6703              : 
    6704              : 
    6705              : ////////////////////////////////////////////////////////////////////
    6706              : 
    6707              : //template<ArteExpandFracs3D::SegmentVrtxFracStatus::oneFracSuDoAtt>
    6708              : //bool ArteExpandFracs3D::computeShiftVector( ArteExpandFracs3D::VecSegmentLimitSidesPairSudoNorml const & vecSegmLimSidPrSudoNrml )
    6709              : //{
    6710              : //      return {};
    6711              : //}
    6712              : 
    6713              : 
    6714              : ////////////////////////////////////////////////////////////////////
    6715              : 
    6716              : // TODO FIXME muss verschwinden!
    6717              : //template<>
    6718              : //bool ArteExpandFracs3D::computeShiftVector( VecSegmentLimitSidesPairSudoNorml const & vecSegmLimSidPrSudoNrml )
    6719              : ////bool ArteExpandFracs3D::expandWithinTheSegment<ArteExpandFracs3D::SegmentVrtxFracStatus::threeFracSuDoAtt>( SegmentLimitingSides const & segmLimSides )
    6720              : //{
    6721              : //      // wenn es nur zwei Segmentnormalen und sudos sind, dann wird die dritte auf Normale senkrecht zu
    6722              : //      // den beiden anderen gesetzt, und um Null verschoben, ihr
    6723              : //
    6724              : ////    if( segmLimSides.isBoundary() )
    6725              : ////    {
    6726              : ////            UG_LOG("three fracture at boundary need implementation " << std::endl);
    6727              : ////            UG_THROW("three fracture at boundary need implementation " << std::endl);
    6728              : ////            return false;
    6729              : ////    }
    6730              : //
    6731              : ////    VecSegmentLimitSidesPairSudoNorml vecSegmLimSidPrSudoNrml;
    6732              : //
    6733              : //      Vertex * oldVrt = segmLimSides.spuckVertex();
    6734              : //
    6735              : //      if( ! segmLimSides.spuckFractSudoNormls( vecSegmLimSidPrSudoNrml ) )
    6736              : //      {
    6737              : //              UG_LOG("Spucken schief gegangen three " << std::endl);
    6738              : //              UG_THROW("Spucken schief gegangen three " << std::endl);
    6739              : //              return false;
    6740              : //      }
    6741              : //
    6742              : //      if( vecSegmLimSidPrSudoNrml.size() != 3 )
    6743              : //      {
    6744              : //              UG_LOG("three fractures, but not three normals and sudo?"  <<  std::endl);
    6745              : //              UG_THROW("three fracture, but not three normal and sudo?" << std::endl);
    6746              : //              return false;
    6747              : //      }
    6748              : //
    6749              : //      // select one of the sudos of the sourrounding sudos of the segment, to which we want to assign the new vertex
    6750              : //      IndexType sudoExample = (vecSegmLimSidPrSudoNrml[0]).first;
    6751              : //
    6752              : ////    std::vector<IndexType> vecSudosSides;
    6753              : ////    std::vector<vector3> vecNormalsAveraged;
    6754              : ////    std::vector<vector3> vecShiftVec4Plane;
    6755              : //
    6756              : //      vector3 posOldVrt = m_aaPos[oldVrt];
    6757              : //
    6758              : //      VecPlaneDescriptor vecShiftedPlaneDescript;
    6759              : //
    6760              : ////    IndexType side = 0;
    6761              : //
    6762              : //      for( SegmentLimitSidesPairSudoNorml const & segLimSidPrSN : vecSegmLimSidPrSudoNrml )
    6763              : //      {
    6764              : //              IndexType const & sudoSide = segLimSidPrSN.first;
    6765              : //              vector3 const & normlAvrg = segLimSidPrSN.second;
    6766              : //
    6767              : //              // normal computed standard mässig directs of of the volume, we need that one into the volume
    6768              : //              vector3 normalOutsideVol;
    6769              : //
    6770              : //              // hier testen, ob die Subdomain von der Liste der fracture subdomains ist,
    6771              : //              // damit für den Fall von sich zwei schneidenden Ebenen für die dritte,
    6772              : //              // die als senkrecht zu den beiden anderen gesetzt werden soll, mit Verschiebung null,
    6773              : //              // analog Boundary sides, die künstliche Weite null erhalten kann hier
    6774              : //              number width = 0;
    6775              : //
    6776              : //              // ensure that the width is nonzero only for real fractures, not for pseudo vectors or such stuff
    6777              : //              if( ( side == 1 && ! artificialNormalTwo ) ||  ( side == 2 && ! artificialNormalThree ) )
    6778              : //                      width = m_fracInfosBySubset[sudoSide].width;
    6779              : //
    6780              : //              side++;
    6781              : //
    6782              : //              number shiftScal = width / 2.;
    6783              : //
    6784              : //              vector3 shiftVec4Plane;
    6785              : //
    6786              : //              // as normal outside vol, but we need to go inside the volumes / segment side
    6787              : //              VecScale( shiftVec4Plane, normalOutsideVol, - shiftScal );
    6788              : //
    6789              : ////            vecShiftVec4Plane.push_back( shiftVec4Plane );
    6790              : ////            vecSudosSides.push_back( sudoSide );
    6791              : ////            vecNormalsAveraged.push_back( normalIntoVol );
    6792              : //
    6793              : //              PlaneDescriptor planeDescr( normalOutsideVol, posOldVrt );
    6794              : //
    6795              : //              PlaneDescriptor shiftedPlaneDescr;
    6796              : //
    6797              : //              planeDescr.spuckPlaneShiftedAlong( shiftVec4Plane, shiftedPlaneDescr );
    6798              : //
    6799              : //              vecShiftedPlaneDescript.push_back( shiftedPlaneDescr );
    6800              : //      }
    6801              : //
    6802              : //      // KÄSE alles!!! wenn es eine boundary ist oder eine Kreuzung von zwei Ebenen innendrin,
    6803              : //      // dann muss hier DANACH noch was dazu kommen, das heisst, alles, was hier gemacht wird,
    6804              : //      // soll für den Fall sein, dass es keine einzelne Fracture innen drin ist,
    6805              : //      // und alle bool template Parameter sind MÜLL!!!!
    6806              : //      // das für zwei Fractures muss hier auch dazu
    6807              : //      // vielleicht am einfachsten, wenn man den template parameter auf true oder false stellt
    6808              : //      // für eine fracture innen oder allen anderen Rest......
    6809              : //
    6810              : //      // TODO FIXME compute crossing point of the three new planes!!!! need functions from lib_disc, cf FiniteStrainMechanics, solve LGS exact
    6811              : //
    6812              : //      vector3 shiftedCrossingPoint;
    6813              : //
    6814              : //      computeCrossingPointOf3Planes( vecShiftedPlaneDescript, shiftedCrossingPoint );
    6815              : //
    6816              : //      return true;
    6817              : //}
    6818              : 
    6819              : ////////////////////////////////////////////////////////////////////
    6820              : 
    6821            0 : bool ArteExpandFracs3D::computeCrossingPointOf3Planes(  VecPlaneDescriptor const & vecPlaneDescr, vector3 & crossingPoint )
    6822              : {
    6823              :         // n_i * vecX_i = a_i * n_i , i=1,2,3, ohne Summenkonvention, und n_i, vecX_i, a_i jeweils Vektoren Grösse 3
    6824              :         // es entsteht also ein LGS für drei Unbekannte und drei Gleichungen
    6825              : 
    6826              : //       vector<vector<double>> coefficients = {{2, 1}, {1, -3}};
    6827              : //       vector<double> constants = {5, -1};
    6828              : //       vector<double> solutions = cramer_rule(coefficients, constants);
    6829              : //       cout << "Solution for x: " << solutions[0] << endl;
    6830              : //       cout << "Solution for y: " << solutions[1] << endl;
    6831              : 
    6832              :         PlaneDescriptor const & planeDescrZero = vecPlaneDescr[0];
    6833              :         PlaneDescriptor const & planeDescrOne = vecPlaneDescr[1];
    6834              :         PlaneDescriptor const & planeDescrTwo = vecPlaneDescr[2];
    6835              : 
    6836              :         vector3 const & normalZero = planeDescrZero.spuckNormalVector();
    6837              :         vector3 const & normalOne = planeDescrOne.spuckNormalVector();
    6838              :         vector3 const & normalTwo = planeDescrTwo.spuckNormalVector();
    6839              : 
    6840              :         number const & rhsZero = planeDescrZero.spuckRHS();
    6841              :         number const & rhsOne = planeDescrOne.spuckRHS();
    6842              :         number const & rhsTwo = planeDescrTwo.spuckRHS();
    6843              : 
    6844              : 
    6845              : 
    6846              :         std::vector<std::vector<double>> coefficients = { {normalZero[0], normalZero[1], normalZero[2]},
    6847              :                                                                                                           {normalOne[0], normalOne[1], normalOne[2]},
    6848              :                                                                                                           {normalTwo[0], normalTwo[1], normalTwo[2]},
    6849            0 :                                                                                                         };
    6850              : 
    6851            0 :         std::vector<double> constants = { rhsZero, rhsOne, rhsTwo };
    6852              : 
    6853            0 :         std::vector<double> solutions = ug::simpleMatrOps::cramerRule(coefficients, constants);
    6854              : 
    6855            0 :         crossingPoint = vector3( solutions[0], solutions[1], solutions[2] );
    6856              : 
    6857            0 :         return true;
    6858            0 : }
    6859              : 
    6860              : ////////////////////////////////////////////////////////////////////
    6861              : 
    6862              : 
    6863              : 
    6864              : #if 0
    6865              : //template <>
    6866              : //bool ArteExpandFracs3D::establishNewVertices< Tetrahedron,
    6867              : //                                                                                        ArteExpandFracs3D::VrtxFracProptsStatus::oneFracSuDoAtt
    6868              : //                                                                                      >( Vertex * const & oldVrt )
    6869              : //template< bool APPLY_GENERAL_SEGMENT_ORDERING,
    6870              : //                ArteExpandFracs3D::VrtxFracProptsStatus vfp,
    6871              : //                typename std::enable_if< std::integral_constant<bool,APPLY_GENERAL_SEGMENT_ORDERING>>
    6872              : //              >
    6873              : template <>
    6874              : bool ArteExpandFracs3D::establishNewVertices< true,
    6875              :                                                                                           ArteExpandFracs3D::VrtxFracProptsStatus::oneFracSuDoAtt
    6876              :                                                                                         >( Vertex * const & oldVrt )
    6877              : {
    6878              :         UG_LOG("under construction Tetrahedra limited" << std::endl);
    6879              : 
    6880              :         VecVertFracTrip const & vecVertFracTrip = m_aaVrtInfoFraTri[oldVrt];
    6881              : 
    6882              :         VecAttachedVolumeElemInfo const & vecAttVolElemInfo = m_aaVolElmInfo[oldVrt];
    6883              : 
    6884              :         VecAttachedVolumeElemInfo vecAttVolElemInfoCop = vecAttVolElemInfo; // echte KOPIE
    6885              : 
    6886              :         VecAttachedVolumeElemInfo reconstructedVecAttVolElmInf;
    6887              : 
    6888              :         VecSegmentVolElmInfo vecSegVolElmInfo;
    6889              : 
    6890              :                 /*
    6891              :                  * While Schleifen aufbauen für den
    6892              :                  * Search the adjacent surface interatively - Algorithmus
    6893              :                  * (Stasi Algorithmus)
    6894              :                  *
    6895              :                  */
    6896              : 
    6897              :         IndexType d_segmenteErledigt = 0;
    6898              : 
    6899              :         while( vecAttVolElemInfoCop.size() != 0 )
    6900              :         {
    6901              :                 SegmentVolElmInfo segmentAVEI;
    6902              : 
    6903              :                 AttachedVolumeElemInfo & startVolInfoThisSegment = vecAttVolElemInfoCop[0];
    6904              : 
    6905              :                 startVolInfoThisSegment.markIt();
    6906              : 
    6907              :                 Volume * volSta = startVolInfoThisSegment.getFulldimElem();
    6908              : 
    6909              :                 vector3 center;
    6910              : 
    6911              :                 if( volSta != nullptr )
    6912              :                         center = CalculateCenter(volSta,m_aaPos);
    6913              : 
    6914              : //              UG_LOG("volume center " << center << std::endl );
    6915              : 
    6916              :                 int d_loopsDone = 0;
    6917              : 
    6918              :                 while( vecAttVolElemInfoCop.size() != 0 )
    6919              :                 {
    6920              :                         // count number of marked elements
    6921              :                         IndexType numMarkedElems = 0;
    6922              :                         IndexType markPoint = 0;
    6923              : 
    6924              : //                      IndexType lastMarkPt = 0;
    6925              :                         IndexType startIndexInner = 0;
    6926              : 
    6927              :                         for( AttachedVolumeElemInfo const & volElInfCop : vecAttVolElemInfoCop )
    6928              :                         {
    6929              :                                 if( volElInfCop.isMarked() )
    6930              :                                 {
    6931              :                                         Volume * vol = volElInfCop.getFulldimElem();
    6932              : //                                      m_sh.assign_subset(vol, m_sh.num_subsets());
    6933              : 
    6934              :                                         vector3 center = CalculateCenter(vol,m_aaPos);
    6935              : 
    6936              : //                                      UG_LOG("DAS ZENTRUM " << numMarkedElems << " -> " << center << std::endl);
    6937              : 
    6938              :                                         startIndexInner = markPoint;
    6939              :                                         numMarkedElems++;
    6940              : 
    6941              :                                 }
    6942              : 
    6943              :                                 markPoint++;
    6944              :                         }
    6945              : 
    6946              :                         UG_LOG("LOOPS DONE " << numMarkedElems << std::endl);
    6947              : 
    6948              :                         if( numMarkedElems == 0 )
    6949              :                                 break;
    6950              : 
    6951              : //                      int startIndexInner = -1;
    6952              : //
    6953              : //                      for( int i = 0; i < vecAttVolElemInfoCop.size(); i++ )
    6954              : //                      {
    6955              : //                              AttachedVolumeElemInfo vi = vecAttVolElemInfoCop[i];
    6956              : //
    6957              : //                              Volume * vo = vi.getFulldimElem();
    6958              : //
    6959              : //                              vector3 center = CalculateCenter(vo,m_aaPos);
    6960              : //
    6961              : //                              UG_LOG("DAS ZENTRUM ZAHL VOR " << i << " -> " <<  center << std::endl);
    6962              : //
    6963              : //                              if( vi.isMarked() )
    6964              : //                                      startIndexInner = i;
    6965              : //                      }
    6966              : //
    6967              : //                      if( startIndexInner < 0 )
    6968              : //                      {
    6969              : //                              UG_THROW("kein Anfang gefunden " << std::endl);
    6970              : //                      }
    6971              : //
    6972              : //#if 0
    6973              : //                      IndexType startIndexInner = markPoint - 1;
    6974              : //#endif
    6975              :                         AttachedVolumeElemInfo startVolInfoMarkLoop = vecAttVolElemInfoCop[startIndexInner];
    6976              : 
    6977              :                         Volume * stattVoll = startVolInfoMarkLoop.getFulldimElem();
    6978              : 
    6979              :                         vector3 centerX = CalculateCenter(stattVoll,m_aaPos);
    6980              : 
    6981              :                         UG_LOG("DAS ZENTRUM DANACH " << startIndexInner << " -> " <<  centerX << std::endl);
    6982              : 
    6983              : //                      m_sh.assign_subset(stattVoll, m_sh.num_subsets());
    6984              : #if 0
    6985              :                         for( int i = 0; i < vecAttVolElemInfoCop.size(); i++ )
    6986              :                         {
    6987              :                                 AttachedVolumeElemInfo vi = vecAttVolElemInfoCop[i];
    6988              : 
    6989              :                                 Volume * vo = vi.getFulldimElem();
    6990              : 
    6991              :                                 vector3 center = CalculateCenter(vo,m_aaPos);
    6992              : 
    6993              :                                 UG_LOG("DAS ZENTRUM ZAHL " << i << " -> " <<  center << std::endl);
    6994              : 
    6995              :                         }
    6996              : #endif
    6997              :                         for( AttachedVolumeElemInfo const & possibleOrigVolInfo : vecAttVolElemInfo )
    6998              :                         {
    6999              :                                 if( possibleOrigVolInfo.hasSameFulldimElem( startVolInfoMarkLoop ) )
    7000              :                                 {
    7001              :                                         segmentAVEI.push_back(possibleOrigVolInfo);
    7002              :                                         reconstructedVecAttVolElmInf.push_back(possibleOrigVolInfo);
    7003              :                                         break;
    7004              :                                 }
    7005              :                         }
    7006              : 
    7007              :                         vecAttVolElemInfoCop.erase( vecAttVolElemInfoCop.begin() + startIndexInner );
    7008              : 
    7009              : //                      if( d_loopsDone == 1 )
    7010              : //                              return false;
    7011              : 
    7012              :                         for( VecAttachedVolumeElemInfo::iterator aveiIt = vecAttVolElemInfoCop.begin();
    7013              :                                                                                                          aveiIt < vecAttVolElemInfoCop.end();
    7014              :                                                                                                          aveiIt++
    7015              :                         )
    7016              :                         {
    7017              :                                 AttachedVolumeElemInfo & possibleNeighbour = *aveiIt;
    7018              : 
    7019              :                                 if( possibleNeighbour.hasSameFulldimElem( startVolInfoMarkLoop ) )
    7020              :                                 {
    7021              :                                         continue;
    7022              :                                 }
    7023              :                                 else
    7024              :                                 {
    7025              :                                         bool neighbourFound = possibleNeighbour.testFullDimElmNeighbour( startVolInfoMarkLoop );
    7026              : 
    7027              :                                         if( neighbourFound )
    7028              :                                         {
    7029              :                                                 Volume * vol = possibleNeighbour.getFulldimElem();
    7030              : 
    7031              : //                                              m_sh.assign_subset(vol, m_sh.num_subsets());
    7032              : 
    7033              :                                         }
    7034              :                                 }
    7035              :                         }
    7036              : 
    7037              : 
    7038              :                         d_loopsDone++;
    7039              : 
    7040              : 
    7041              :                 }
    7042              : 
    7043              :                 vecSegVolElmInfo.push_back(segmentAVEI);
    7044              : 
    7045              : //              d_segmenteErledigt++;
    7046              : //
    7047              : //              if( d_segmenteErledigt == 1 )
    7048              : //              return false;
    7049              :         }
    7050              : 
    7051              :         if( reconstructedVecAttVolElmInf.size() != vecAttVolElemInfo.size() )
    7052              :         {
    7053              :                 UG_LOG("Rekonstruktion schief gegangen " << std::endl);
    7054              :                 UG_THROW("Rekonstruktion schief gegangen " << std::endl);
    7055              :                 return false;
    7056              :         }
    7057              : 
    7058              :         for( SegmentVolElmInfo const & svei : vecSegVolElmInfo )
    7059              :         {
    7060              :                 // TODO FIXME das hier wieder entfernen, die Subdomain Zuweisung, nur für debug Zwecke
    7061              :                 IndexType sudoMax = m_sh.num_subsets();
    7062              : 
    7063              :                 for( AttachedVolumeElemInfo const & vei : svei )
    7064              :                 {
    7065              :                         Volume * vol = vei.getFulldimElem();
    7066              : 
    7067              :                         m_sh.assign_subset( vol, sudoMax );
    7068              :                 }
    7069              :         }
    7070              : 
    7071              :         return true;
    7072              : }
    7073              : 
    7074              : 
    7075              : ////////////////////////////////////////////////////////////////////
    7076              : 
    7077              : 
    7078              : 
    7079              : //template <>
    7080              : //bool ArteExpandFracs3D::establishNewVertices< Hexahedron,
    7081              : //                                                                                        ArteExpandFracs3D::VrtxFracProptsStatus::oneFracSuDoAtt
    7082              : //                                                                                      >( Vertex * const & oldVrt )
    7083              : //template< bool APPLY_GENERAL_SEGMENT_ORDERING,
    7084              : //                ArteExpandFracs3D::VrtxFracProptsStatus vfp,
    7085              : //                typename std::enable_if< std::integral_constant<bool,!APPLY_GENERAL_SEGMENT_ORDERING>>
    7086              : //              >
    7087              : template <>
    7088              : bool ArteExpandFracs3D::establishNewVertices< false,
    7089              :                                                                                           ArteExpandFracs3D::VrtxFracProptsStatus::oneFracSuDoAtt
    7090              :                                                                                         >( Vertex * const & oldVrt )
    7091              : {
    7092              :         VecVertFracTrip & vecVertFracTrip = m_aaVrtInfoFraTri[oldVrt];
    7093              : 
    7094              : //      std::vector<Edge*> & allAssoEdges = m_aaVrtInfoAssoEdges[oldVrt];
    7095              : //      std::vector<Face*> & allAssoFaces = m_aaVrtInfoAssoFaces[oldVrt];
    7096              : //      std::vector<Volume*> & allAssoVolumes = m_aaVrtInfoAssoVols[oldVrt];
    7097              : 
    7098              :         // TODO FIXME works if at all only for very simple geometries
    7099              :         // and works only in particular if all asso volumes are part of the triple, i.e. have all a common face with the fracture
    7100              :         // this is not selbstverständlich at all!!!!
    7101              : 
    7102              :         VecVertFracTrip  vecVertFracTripCopy = m_aaVrtInfoFraTri[oldVrt]; // copy, not reference!
    7103              : 
    7104              : 
    7105              :         VecVertFracTrip firstSegment;
    7106              :         VecVertFracTrip secondSegment;
    7107              : 
    7108              :         IndexType beginIndex = 0;
    7109              : 
    7110              :         VertFracTrip startTrip = vecVertFracTripCopy[beginIndex];
    7111              : 
    7112              :         firstSegment.push_back( startTrip );
    7113              : 
    7114              :         vector3 normalOne = startTrip.getNormal();
    7115              :         vector3 normalTwo;
    7116              :         // vermute einfach umgekehrte Normale, ein Trick, der im einfachsten Fall geht......
    7117              :         VecScale(normalTwo,normalOne,-1);
    7118              : 
    7119              :         vecVertFracTripCopy.erase( vecVertFracTripCopy.begin() + beginIndex );
    7120              : 
    7121              : //      for( VecVertFracTrip::iterator itVFT  = vecVertFracTripCopy.begin();
    7122              : //                                                                         itVFT != vecVertFracTripCopy.end();
    7123              : //                                                                         itVFT++
    7124              : //              )
    7125              : //              {
    7126              : //                      VertFracTrip actualVFT = *itVFT;
    7127              : //
    7128              : //                      vector3 volCenter = CalculateCenter(actualVFT.getFullElm(),m_aaPos);
    7129              : //                      UG_LOG("Vol center" << volCenter << std::endl);
    7130              : //                      vecVertFracTripCopy.erase(itVFT);
    7131              : //              }
    7132              : //
    7133              : //      return true;
    7134              : 
    7135              : //      while( vecVertFracTripCopy.size() != 0 )
    7136              : //      {
    7137              : //              for( VecVertFracTrip::iterator itVFT  = vecVertFracTripCopy.begin();
    7138              : //                                                                         itVFT != vecVertFracTripCopy.end();
    7139              : //                                                                         itVFT++
    7140              : //              )
    7141              :         for( auto const & actualVFT : vecVertFracTripCopy )
    7142              :         {
    7143              : //                      VertFracTrip actualVFT = *itVFT;
    7144              : 
    7145              :                 vector3 normalActual = actualVFT.getNormal();
    7146              : 
    7147              :                 vector3 volCenter = CalculateCenter(actualVFT.getFullElm(),m_aaPos);
    7148              :                 UG_LOG("Vol center" << volCenter << std::endl);
    7149              : 
    7150              :                 // test direction
    7151              : 
    7152              :                 number cosinus2One = VecDot(normalOne,normalActual);
    7153              :                 number cosinus2Two = VecDot(normalTwo,normalActual);
    7154              : 
    7155              :                 UG_LOG("normal eins " << normalOne << std::endl);
    7156              :                 UG_LOG("normal zwei " << normalTwo << std::endl);
    7157              :                 UG_LOG("normal actu " << normalActual << std::endl);
    7158              : 
    7159              :                 UG_LOG("cosi one " << cosinus2One << std::endl );
    7160              :                 UG_LOG("cosi two " << cosinus2Two << std::endl );
    7161              : 
    7162              : 
    7163              :                 // if cosinus > 0, assume same side
    7164              : 
    7165              :                 if( ( cosinus2One >= 0 && cosinus2Two >= 0 ) || ( cosinus2One <= 0 && cosinus2Two <= 0 ) )
    7166              :                         UG_THROW("kann nicht auf zwei Seiten hinken" << std::endl);
    7167              : 
    7168              :                 if( cosinus2One >= 0 )
    7169              :                 {
    7170              :                         firstSegment.push_back( actualVFT );
    7171              :                 }
    7172              :                 else if( cosinus2Two >= 0 )
    7173              :                 {
    7174              :                         secondSegment.push_back( actualVFT );
    7175              :                 }
    7176              :                 else
    7177              :                 {
    7178              :                         UG_THROW("muss wo dazu gehoeren wohl" << std::endl);
    7179              :                 }
    7180              :         }
    7181              : //                      vecVertFracTripCopy.erase(itVFT);
    7182              : //              }
    7183              : //      }
    7184              : 
    7185              :         // computer averaged normal
    7186              : 
    7187              :         vector3 normalsOneSummed(0,0,0);
    7188              :         vector3 normalsTwoSummed(0,0,0);
    7189              : 
    7190              : 
    7191              :         for( auto const & seg: firstSegment )
    7192              :         {
    7193              :                 vector3 tmpVec = normalsOneSummed;
    7194              :                 VecAdd(normalsOneSummed,tmpVec,seg.getNormal());
    7195              :         }
    7196              : 
    7197              :         for( auto const & seg: secondSegment )
    7198              :         {
    7199              :                 vector3 tmpVec = normalsTwoSummed;
    7200              :                 VecAdd(normalsTwoSummed,tmpVec,seg.getNormal());
    7201              :         }
    7202              : 
    7203              :         vector3 normalsOneAveraged;
    7204              :         vector3 normalsTwoAveraged;
    7205              : 
    7206              :         if( firstSegment.size() != 0 )
    7207              :         {
    7208              :                 VecScale(normalsOneAveraged, normalsOneSummed, 1./firstSegment.size());
    7209              :         }
    7210              : 
    7211              :         if( secondSegment.size() != 0 )
    7212              :         {
    7213              :                 VecScale(normalsTwoAveraged, normalsTwoSummed, 1./secondSegment.size());
    7214              :         }
    7215              : 
    7216              :         // get to know width of fracture
    7217              : 
    7218              :         IndexType suse = startTrip.getSudoElm();
    7219              : 
    7220              :         number width = m_fracInfosBySubset[suse].width;
    7221              : 
    7222              :         number scal = width / 2.;
    7223              : 
    7224              :         vector3 scaledNormalOne, scaledNormalTwo;
    7225              :         VecScale( scaledNormalOne, normalOne, - scal );
    7226              :         VecScale( scaledNormalTwo, normalTwo, - scal );
    7227              :         // Minuszeichen wichtig, sonst wird in die falsche Richtung gedrückt, und die Volumen gehen über die fracture
    7228              :         // raus und werden grösser, anstatt kleiner zu werden.....
    7229              : 
    7230              :         vector3 posOldVrt = m_aaPos[oldVrt];
    7231              : 
    7232              :         vector3 posNewVrtOne, posNewVrtTwo;
    7233              : 
    7234              :         VecAdd( posNewVrtOne, posOldVrt, scaledNormalOne);
    7235              :         VecAdd( posNewVrtTwo, posOldVrt, scaledNormalTwo);
    7236              : 
    7237              :         Vertex * newShiftVrtxOne = *m_grid.create<RegularVertex>();
    7238              :         Vertex * newShiftVrtxTwo = *m_grid.create<RegularVertex>();
    7239              : 
    7240              :         m_aaPos[newShiftVrtxOne] = posNewVrtOne;
    7241              :         m_aaPos[newShiftVrtxTwo] = posNewVrtTwo;
    7242              : 
    7243              :         UG_LOG("Created new vertex 1 at " <<m_aaPos[newShiftVrtxOne] << std::endl );
    7244              :         UG_LOG("Created new vertex 2 at " <<m_aaPos[newShiftVrtxTwo] << std::endl );
    7245              : 
    7246              :         m_sh.assign_subset(newShiftVrtxOne, suse);
    7247              :         m_sh.assign_subset(newShiftVrtxTwo, suse);
    7248              : 
    7249              : //      m_sh.assign_subset(newShiftVrtxOne, 3);
    7250              : //      m_sh.assign_subset(newShiftVrtxTwo, 3);
    7251              : 
    7252              :         for( auto const & fs : firstSegment )
    7253              :         {
    7254              :                 Volume * vol = fs.getFullElm();
    7255              : 
    7256              :                 std::vector<Vertex*>& newVrts4Fac = m_aaVrtVecVol[ vol ];
    7257              : 
    7258              :                 for(size_t indVrt = 0; indVrt < (vol)->num_vertices();  indVrt++ )
    7259              :                 {
    7260              :                         Vertex* volVrt = (vol)->vertex(indVrt);
    7261              : 
    7262              :                         if(  volVrt == oldVrt )
    7263              :                         {
    7264              :                                 newVrts4Fac[ indVrt ] = newShiftVrtxOne;
    7265              :                         }
    7266              :                 }
    7267              :         }
    7268              : 
    7269              :         for( auto const & ses : secondSegment )
    7270              :         {
    7271              :                 Volume * vol = ses.getFullElm();
    7272              : 
    7273              :                 std::vector<Vertex*>& newVrts4Fac = m_aaVrtVecVol[ vol ];
    7274              : 
    7275              :                 for(size_t indVrt = 0; indVrt < (vol)->num_vertices();  indVrt++ )
    7276              :                 {
    7277              :                         Vertex* volVrt = (vol)->vertex(indVrt);
    7278              : 
    7279              :                         if(  volVrt == oldVrt )
    7280              :                         {
    7281              :                                 newVrts4Fac[ indVrt ] = newShiftVrtxTwo;
    7282              :                         }
    7283              :                 }
    7284              :         }
    7285              : 
    7286              : 
    7287              :         return true;
    7288              : }
    7289              : 
    7290              : #endif
    7291              : 
    7292              : ////////////////////////////////////////////////////////////////////
    7293              : 
    7294              : 
    7295            0 : bool ArteExpandFracs3D::createConditionForNewVrtcs()
    7296              : {
    7297              : 
    7298              :         //      iterate over all surrounding volumes to enable volume changes, this loop taken from SR but shortened
    7299            0 :         for(VolumeIterator iterSurrVol = m_sel.volumes_begin(); iterSurrVol != m_sel.volumes_end(); iterSurrVol++ )
    7300              :         {
    7301              :                 Volume * sv = *iterSurrVol;
    7302              : 
    7303              :                 std::vector<Vertex*>& newVrts = m_aaVrtVecVol[sv];
    7304            0 :                 newVrts.resize(sv->num_vertices());
    7305              : 
    7306            0 :                 for(size_t iVrt = 0; iVrt < sv->num_vertices(); iVrt++ )
    7307              :                 {
    7308            0 :                         newVrts[iVrt] = nullptr;
    7309              :                 }
    7310              :                         // erstmal so tun, als ob keine neuen Vertizes erzeugt werden an den alten Vertizes
    7311              :         }
    7312              : 
    7313              : 
    7314            0 :         return true;
    7315              : }
    7316              : 
    7317              : /////////////////////////////////////////////////////////////
    7318              : 
    7319            0 : bool ArteExpandFracs3D::createNewElements()
    7320              : {
    7321              :         // originally practically copied from Sebastian, as this concept was fine for 2D, but adapted in 3D
    7322              : 
    7323              :         //      create new elements
    7324              : 
    7325              :         UG_LOG("want to create new elems" << std::endl );
    7326              : 
    7327              :         //      holds local side vertex indices
    7328              :         std::vector<size_t>       locVrtInds;
    7329              : 
    7330              :         //      first we create new edges from selected ones which are connected to
    7331              :         //      inner vertices. This allows to preserve old subsets.
    7332              :         //      Since we have to make sure that we use the right vertices,
    7333              :         //      we have to iterate over the selected volumes and perform all actions on the edges
    7334              :         //      of those volumes.
    7335            0 :         for(VolumeIterator iter_sv = m_sel.volumes_begin(); iter_sv != m_sel.volumes_end(); ++iter_sv)
    7336              :         {
    7337              :                 Volume* sv = *iter_sv;
    7338              : 
    7339            0 :                 UG_LOG("entering volume to create new elems " << CalculateCenter(sv, m_aaPos) << std::endl);
    7340              : 
    7341              :                 //      check for each edge whether it has to be copied.
    7342            0 :                 for(size_t i_edge = 0; i_edge < sv->num_edges(); ++i_edge)
    7343              :                 {
    7344            0 :                         Edge* e = m_grid.get_edge(sv, i_edge);
    7345              : 
    7346            0 :                         if(m_sel.is_selected(e))
    7347              :                         {
    7348              :                                 //      check the associated vertices through the volumes aaVrtVecVol attachment.
    7349              :                                 //      If at least one has an associated new vertex and if no edge between the
    7350              :                                 //      new vertices already exists, we'll create the new edge.
    7351              :                                 size_t ind0, ind1;
    7352            0 :                                 sv->get_vertex_indices_of_edge(ind0, ind1, i_edge);
    7353            0 :                                 Vertex* nv0 = (m_aaVrtVecVol[sv])[ind0];
    7354            0 :                                 Vertex* nv1 = (m_aaVrtVecVol[sv])[ind1];
    7355              : 
    7356            0 :                                 if(nv0 || nv1)
    7357              :                                 {
    7358              :                                         //      if one vertex has no associated new one, then we use the vertex itself
    7359            0 :                                         if(!nv0)
    7360            0 :                                                 nv0 = sv->vertex(ind0);
    7361            0 :                                         if(!nv1)
    7362            0 :                                                 nv1 = sv->vertex(ind1);
    7363              : 
    7364              : #if 1
    7365              :                                         //      create the new edge if it not already exists.
    7366            0 :                                         if( ! m_grid.get_edge(nv0, nv1))
    7367            0 :                                                 m_grid.create_by_cloning(e, EdgeDescriptor(nv0, nv1), e);
    7368              : #else // only for debugging purposes
    7369              : 
    7370              :                                         //                                      if( ! ( m_vrtxAttAccsVrtxArisesFromExpandedEndingCrossingCleft[nv0] || m_vrtxAttAccsVrtxArisesFromExpandedEndingCrossingCleft[nv0] ) )
    7371              :                                         {
    7372              :                                                 //      create the new edge if it not already exists.
    7373              :                                                 if( ! m_grid.get_edge(nv0, nv1))
    7374              :                                                 {
    7375              :                                                         Edge * cloneEdge = * ( m_grid.create_by_cloning(e, EdgeDescriptor(nv0, nv1), e) );
    7376              : 
    7377              :                                                         if( ( m_vrtxAttAccsVrtxArisesFromExpandedEndingCrossingCleft[nv0] || m_vrtxAttAccsVrtxArisesFromExpandedEndingCrossingCleft[nv1] ) )
    7378              :                                                         {
    7379              :                                                                 m_sh.assign_subset(cloneEdge, m_sh.num_subsets());
    7380              :                                                                 UG_LOG("Edge clone from ending crossing cleft new shift vertex" << std::endl);
    7381              : 
    7382              :                                                         }
    7383              :                                                 }
    7384              :                                         }
    7385              :                                         //                                      else
    7386              :                                         //                                      {
    7387              :                                         //                                              UG_LOG("Edge clone from ending crossing cleft new shift vertex" << std::endl);
    7388              :                                         //                                      }
    7389              : 
    7390              :                                         // Ergebnis dieses debug Teils: alle edges, die geclont werden, sind notwendig
    7391              :                                         // auch bei ending crossing clefts
    7392              : #endif
    7393              :                                 }
    7394              :                         }
    7395              :                 }
    7396              :         }
    7397              : 
    7398              :         UG_LOG("Vol enter clone finished " << std::endl);
    7399              : 
    7400              :         //      now we create new faces from selected ones which are connected to
    7401              :         //      inner vertices. This allows to preserve old subsets.
    7402              :         //      Since we have to make sure that we use the right vertices,
    7403              :         //      we have to iterate over the selected volumes and perform all actions on the side-faces
    7404              :         //      of those volumes.
    7405              : 
    7406            0 :         FaceDescriptor fd;
    7407              : 
    7408              : 
    7409            0 :         for(VolumeIterator iter_sv = m_sel.volumes_begin(); iter_sv != m_sel.volumes_end(); ++iter_sv)
    7410              :         {
    7411              :                 Volume* sv = *iter_sv;
    7412              :                 //      check for each face whether it has to be copied.
    7413              : 
    7414            0 :                 UG_LOG("Face descriptor for vol " << CalculateCenter(sv, m_aaPos) << std::endl);
    7415              : 
    7416            0 :                 for(size_t i_face = 0; i_face < sv->num_faces(); ++i_face)
    7417              :                 {
    7418            0 :                         Face* sf = m_grid.get_face(sv, i_face);
    7419              : 
    7420            0 :                         if( m_sel.is_selected(sf))
    7421              :                         {
    7422              :                                 //      check the associated vertices through the volumes aaVrtVecVol attachment.
    7423              :                                 //      If no face between the new vertices already exists, we'll create the new face.
    7424            0 :                                 sv->get_vertex_indices_of_face(locVrtInds, i_face);
    7425            0 :                                 fd.set_num_vertices(sf->num_vertices());
    7426              : 
    7427              :                                 bool containsEndingCrossingCleftVrtx = false;
    7428              : 
    7429            0 :                                 for(size_t i = 0; i < sf->num_vertices(); ++i)
    7430              :                                 {
    7431            0 :                                         Vertex* nVrt = (m_aaVrtVecVol[sv])[locVrtInds[i]];
    7432              : 
    7433            0 :                                         if(nVrt)
    7434            0 :                                                 fd.set_vertex(i, nVrt);
    7435              :                                         else
    7436            0 :                                                 fd.set_vertex(i, sv->vertex(locVrtInds[i]));
    7437              :                                 }
    7438              : 
    7439              : #if 1
    7440              :                                 //      if the new face does not already exist, we'll create it
    7441            0 :                                 if(!m_grid.get_face(fd))
    7442            0 :                                         m_grid.create_by_cloning(sf, fd, sf);
    7443              : #else
    7444              :                                 //      if the new face does not already exist, we'll create it
    7445              :                                 if( ! m_grid.get_face(fd) )
    7446              :                                 {
    7447              :                                         Face * fac = *( m_grid.create_by_cloning(sf, fd, sf) );
    7448              : 
    7449              :                                         bool faceAtEndingCrossingCleft = m_aaMarkFaceWithEndingCrossingCleft[sf];
    7450              : 
    7451              :                                         bool faceTouchingEndingCrossingCleft = m_facAttAccsIfFaceIsSegmLimFaceEndingCrossingCleft[sf];
    7452              : 
    7453              :                                         if( faceAtEndingCrossingCleft || faceTouchingEndingCrossingCleft )
    7454              :                                         {
    7455              :                                                 m_sh.assign_subset( fac, m_sh.num_subsets() );
    7456              :                                                 UG_LOG("Face at ending crossing cleft" << std::endl);
    7457              :                                         }
    7458              :                                 }
    7459              : 
    7460              :                                 // Ergebnis dieses debug Teils: alle faces, die geclont werden, sind notwendig
    7461              :                                 // auch bei ending crossing clefts
    7462              : #endif
    7463              : 
    7464              :                         }
    7465              :                 }
    7466              :         }
    7467              : 
    7468              :         UG_LOG("Face descriptor left" << std::endl);
    7469              : 
    7470              :         //      Expand all faces.
    7471              :         //      Since volumes are replaced on the fly, we have to take care with the iterator.
    7472              :         //      record all new volumes in a vector. This will help to adjust positions later on.
    7473              : 
    7474              :         std::vector<Volume*> newFractureVolumes;
    7475              :         std::vector<IndexType> subsOfNewVolumes;
    7476              : 
    7477              :         // create alternative volumes where there are ending crossing clefts
    7478              : 
    7479              : //      etablishVolumesAtEndingCrossingClefts( std::vector<Volume*> & newFractureVolumes, std::vector<IndexType> & subsOfNewVolumes );
    7480            0 :         if( ! etablishVolumesAtEndingCrossingClefts( newFractureVolumes, subsOfNewVolumes ) )
    7481              :         {
    7482              :                 UG_LOG("unable to establish volumes at ending crossing clefts" << std::endl);
    7483              :                 return false;
    7484              :         }
    7485              : 
    7486              : //      return false;
    7487              : 
    7488            0 :         VolumeDescriptor vd;
    7489              : 
    7490              :         // beim Volumen fängt das Abfangen an, es muss abgefragt werden, ob das Volumen aus
    7491              :         // einem Segment ist, wo bisher falsch expandiert wird
    7492              :         // erst beim Face ab zu fangen ist viel zu spät TODO FIXME
    7493              :         // nicht zu vergessen, die Edges ordentlich sortiert zu sammeln, die zwei endende Vertizes enthalten,
    7494              :         // und dann zu splitten, wenn alle Attachements entfernt sind, dann Neustart anfordern mit neuer Geometrie
    7495              : 
    7496            0 :         for(VolumeIterator iter_sv = m_sel.volumes_begin(); iter_sv != m_sel.volumes_end();)
    7497              :         {
    7498              :                 Volume* sv = *iter_sv;
    7499              :                 ++iter_sv;
    7500              : 
    7501            0 :                 UG_LOG("Volume new creation try at " << CalculateCenter(sv, m_aaPos) << std::endl);
    7502              : 
    7503              :                 bool volHasEndingCrossingCleftFace = m_volAttAccsVolTouchesEndingCrossingCleft[sv];
    7504              : 
    7505              :                 //      now expand the fracture faces of sv to volumes.
    7506            0 :                 for(size_t i_side = 0; i_side < sv->num_sides(); ++i_side)
    7507              :                 {
    7508              :                         //      get the local vertex indices of the side of the volume
    7509            0 :                         sv->get_vertex_indices_of_face(locVrtInds, i_side);
    7510              : 
    7511            0 :                         Face* tFace = m_grid.get_side(sv, i_side);
    7512              : 
    7513            0 :                         if(tFace)
    7514              :                         {
    7515            0 :                                 if( m_aaMarkFaceIsFracB[tFace] ) // && ! m_aaMarkFaceHasUnclosedFracSideB[tFace] )
    7516              :                                 {
    7517              :                                         bool faceIsSegmLimEndCrossCleft = m_facAttAccsIfFaceIsSegmLimFaceEndingCrossingCleft[tFace];
    7518              :                                         bool faceIsEndingCleftCrossFace = m_aaMarkFaceWithEndingCrossingCleft[tFace];
    7519              : 
    7520            0 :                                         bool avoidFace = ( volHasEndingCrossingCleftFace && ( faceIsSegmLimEndCrossCleft || faceIsEndingCleftCrossFace ) );
    7521              : 
    7522              : //                                      for( Face * testFac :  m_d_endingCrossingCleftFaces )
    7523              : //                                      {
    7524              : //                                              if( testFac == tFace )
    7525              : //                                              {
    7526              : //                                                      avoidFace = true;
    7527              : //                                              }
    7528              : //                                      }
    7529              : //
    7530              : //                                      for( Face * testFac :  m_d_crossingNeighboredNotEndingFaces )
    7531              : //                                      {
    7532              : //                                              if( testFac == tFace )
    7533              : //                                              {
    7534              : //                                                      avoidFace = true;
    7535              : //                                              }
    7536              : //                                      }
    7537              : //
    7538              : //                                      for( Face * testFac :  m_d_crossingNeighboredNotEndingFacesCommEdg )
    7539              : //                                      {
    7540              : //                                              if( testFac == tFace )
    7541              : //                                              {
    7542              : //                                                      avoidFace = true;
    7543              : //                                              }
    7544              : //                                      }
    7545              : //
    7546              : //                                      for( Face * testFac :  m_d_notEndingCrossingFacesNotNeighbour )
    7547              : //                                      {
    7548              : //                                              if( testFac == tFace )
    7549              : //                                              {
    7550              : //                                                      avoidFace = true;
    7551              : //                                              }
    7552              : //                                      }
    7553              : 
    7554              : 
    7555              :                                         constexpr bool debugTest = true;
    7556              : 
    7557            0 :                                         if( avoidFace && debugTest )
    7558            0 :                                                 continue;
    7559              : 
    7560            0 :                                         Volume* expVol = nullptr;
    7561              : 
    7562            0 :                                         if(locVrtInds.size() == 3)
    7563              :                                         {
    7564            0 :                                                 size_t iv0 = locVrtInds[0];
    7565            0 :                                                 size_t iv1 = locVrtInds[1];
    7566            0 :                                                 size_t iv2 = locVrtInds[2];
    7567              : 
    7568              :                                                 if(    ( m_aaVrtVecVol[sv] )[iv0]
    7569            0 :                                                         && ( m_aaVrtVecVol[sv] )[iv1]
    7570            0 :                                                         && ( m_aaVrtVecVol[sv] )[iv2]
    7571              :                                                 )
    7572              :                                                 {
    7573              :                                                         //      create a new prism
    7574            0 :                                                         expVol = *m_grid.create<Prism>(
    7575            0 :                                                                                         PrismDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    7576              :                                                                                                                         (m_aaVrtVecVol[sv])[iv2],
    7577              :                                                                                                                         (m_aaVrtVecVol[sv])[iv1],
    7578              :                                                                                                                         (m_aaVrtVecVol[sv])[iv0]));
    7579              :                                                 }
    7580              :                                                 else if(    ( m_aaVrtVecVol[sv] )[iv0]
    7581            0 :                                                                  && ( m_aaVrtVecVol[sv] )[iv1]
    7582              :                                                 )
    7583              :                                                 {
    7584              :                                                         //      create a new Pyramid
    7585            0 :                                                         expVol = *m_grid.create<Pyramid>(
    7586            0 :                                                                                         PyramidDescriptor(sv->vertex(iv0), sv->vertex(iv1),
    7587              :                                                                                                 (m_aaVrtVecVol[sv])[iv1],
    7588              :                                                                                                 (m_aaVrtVecVol[sv])[iv0],
    7589            0 :                                                                                                 sv->vertex(iv2)));
    7590              :                                                 }
    7591              :                                                 else if(    ( m_aaVrtVecVol[sv] )[iv1]
    7592            0 :                                                                  && ( m_aaVrtVecVol[sv] )[iv2]
    7593              :                                                 )
    7594              :                                                 {
    7595              :                                                         //      create a new Pyramid
    7596            0 :                                                         expVol = *m_grid.create<Pyramid>(
    7597            0 :                                                                                         PyramidDescriptor(sv->vertex(iv1), sv->vertex(iv2),
    7598              :                                                                                                 (m_aaVrtVecVol[sv])[iv2],
    7599              :                                                                                                 (m_aaVrtVecVol[sv])[iv1],
    7600            0 :                                                                                                 sv->vertex(iv0)));
    7601              :                                                 }
    7602              :                                                 else if(    (m_aaVrtVecVol[sv])[iv0]
    7603            0 :                                                                  && (m_aaVrtVecVol[sv])[iv2]
    7604              :                                                 )
    7605              :                                                 {
    7606              :                                                         //      create a new Pyramid
    7607            0 :                                                         expVol = *m_grid.create<Pyramid>(
    7608            0 :                                                                                         PyramidDescriptor(sv->vertex(iv2), sv->vertex(iv0),
    7609              :                                                                                                 (m_aaVrtVecVol[sv])[iv0],
    7610              :                                                                                                 (m_aaVrtVecVol[sv])[iv2],
    7611            0 :                                                                                                 sv->vertex(iv1)));
    7612              :                                                 }
    7613            0 :                                                 else if( ( m_aaVrtVecVol[sv])[iv0] )
    7614              :                                                 {
    7615              :                                                         //      create a new Tetrahedron
    7616            0 :                                                         expVol = *m_grid.create<Tetrahedron>(
    7617            0 :                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    7618              :                                                                                                                                  (m_aaVrtVecVol[sv])[iv0]));
    7619              :                                                 }
    7620            0 :                                                 else if( ( m_aaVrtVecVol[sv])[iv1] )
    7621              :                                                 {
    7622              :                                                         //      create a new Tetrahedron
    7623            0 :                                                         expVol = *m_grid.create<Tetrahedron>(
    7624            0 :                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    7625              :                                                                                                                                  (m_aaVrtVecVol[sv])[iv1]));
    7626              :                                                 }
    7627            0 :                                                 else if( ( m_aaVrtVecVol[sv])[iv2] )
    7628              :                                                 {
    7629              :                                                         //      create a new Tetrahedron
    7630            0 :                                                         expVol = *m_grid.create<Tetrahedron>(
    7631            0 :                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    7632              :                                                                                                                                  (m_aaVrtVecVol[sv])[iv2]));
    7633              :                                                 }
    7634              :                                                 else
    7635              :                                                 {
    7636              :                                                         //      Text from SR, still similar:
    7637              :                                                         //  this code-block should never be entered. If it is entered then
    7638              :                                                         //      we either selected the wrong faces (this shouldn't happen), or there
    7639              :                                                         //      are selected faces, which have fracture-boundary-vertices only.
    7640              :                                                         //      This is the same is if inner fracture edges exists, which are
    7641              :                                                         //      connected to two boundary vertices.
    7642              :                                                         //      Since we tried to remove those edges above, something went wrong.
    7643              :                                                         //      remove the temporary attachments and throw an error
    7644              : 
    7645              :                                                         UG_LOG("Tetraeder Fehlt eine Loesung " << std::endl);
    7646              : #if 1
    7647            0 :                                                         detachMarkers();
    7648            0 :                                                         throw(UGError("Error in ExpandFractures3d Arte Stasi. Implementation Error."));
    7649              :                                                         return false;
    7650              : #endif
    7651              :                                                 }
    7652              :                                         }
    7653            0 :                                         else if ( locVrtInds.size() == 4 )
    7654              :                                         {
    7655              :                                                 // newly implemented by Markus to test with Hexahedrons
    7656              : 
    7657            0 :                                                 size_t iv0 = locVrtInds[0];
    7658            0 :                                                 size_t iv1 = locVrtInds[1];
    7659            0 :                                                 size_t iv2 = locVrtInds[2];
    7660            0 :                                                 size_t iv3 = locVrtInds[3];
    7661              : 
    7662              :                                                 if(    ( m_aaVrtVecVol[sv] )[iv0]
    7663            0 :                                                         && ( m_aaVrtVecVol[sv] )[iv1]
    7664            0 :                                                         && ( m_aaVrtVecVol[sv] )[iv2]
    7665            0 :                                                         && ( m_aaVrtVecVol[sv] )[iv3]
    7666              :                                                 )
    7667              :                                                 {
    7668              :                                                         //      create a new prism
    7669            0 :                                                         expVol = *m_grid.create<Hexahedron>(
    7670            0 :                                                                                                 HexahedronDescriptor(
    7671            0 :                                                                                                                         sv->vertex(iv3), sv->vertex(iv2),
    7672            0 :                                                                                                                         sv->vertex(iv1), sv->vertex(iv0),
    7673              :                                                                                                                         (m_aaVrtVecVol[sv])[iv3],
    7674              :                                                                                                                         (m_aaVrtVecVol[sv])[iv2],
    7675              :                                                                                                                         (m_aaVrtVecVol[sv])[iv1],
    7676              :                                                                                                                         (m_aaVrtVecVol[sv])[iv0]
    7677              :                                                                                                                         )
    7678              :                                                                                                                 );
    7679              : 
    7680              : //                                                      m_sh.assign_subset(expVol, m_fracInfosBySubset.at(m_sh.get_subset_index(tFace)).newSubsetIndex);
    7681              : //
    7682              : //                                                      return true;
    7683              :                                                 }
    7684              :                                                 else if(    ( m_aaVrtVecVol[sv] )[iv0]
    7685            0 :                                                                  && ( m_aaVrtVecVol[sv] )[iv1]
    7686              : 
    7687              :                                                 )
    7688              :                                                 {
    7689              :                                                         //      create a new prism
    7690              :                                                         //      create a new prism
    7691              : //                                                      expVol = *m_grid.create<Prism>(
    7692              : //                                                                                      PrismDescriptor(sv->vertex(iv3),sv->vertex(iv2), sv->vertex(iv1),
    7693              : //                                                                                                                      sv->vertex(iv0),
    7694              : //                                                                                                                      (m_aaVrtVecVol[sv])[iv1],
    7695              : //                                                                                                                      (m_aaVrtVecVol[sv])[iv0])
    7696              : //                                                                                                                      );
    7697              :                                                         //      create a new Prism
    7698              :                                                         ///     only used to initialize a prism. for all other tasks you should use VolumeDescripor.
    7699              :                                                         /**
    7700              :                                                          * please be sure to pass the vertices in the correct order:
    7701              :                                                          * v1, v2, v3: bottom-vertices in counterclockwise order (if viewed from the top).
    7702              :                                                          * v4, v5, v6: top-vertices in counterclockwise order (if viewed from the top).
    7703              :                                                          *              PrismDescriptor(Vertex* v1, Vertex* v2, Vertex* v3,
    7704              :                                                 Vertex* v4, Vertex* v5, Vertex* v6);
    7705              :                                                          *
    7706              :                                                          */
    7707            0 :                                                         expVol = *m_grid.create<Prism>(
    7708            0 :                                                                                         PrismDescriptor( (m_aaVrtVecVol[sv])[iv0],
    7709            0 :                                                                                                         sv->vertex(iv0), sv->vertex(iv3),
    7710            0 :                                                                                                         (m_aaVrtVecVol[sv])[iv1], sv->vertex(iv1), sv->vertex(iv2)
    7711              :                                                                                                 )
    7712              :                                                                                                 );
    7713              : 
    7714              :                                                         UG_LOG("PRISM 0 1 " << std::endl);
    7715              :                                                 }
    7716              :                                                 else if(    ( m_aaVrtVecVol[sv] )[iv0]
    7717            0 :                                                                  && ( m_aaVrtVecVol[sv] )[iv2]
    7718              :                                                 )
    7719              :                                                 {
    7720              :                                                         UG_LOG("PRISM 0 2 " << std::endl);
    7721            0 :                                                         expVol = *m_grid.create<Prism>(
    7722            0 :                                                                                         PrismDescriptor( (m_aaVrtVecVol[sv])[iv0],
    7723            0 :                                                                                                         sv->vertex(iv0), sv->vertex(iv3),
    7724            0 :                                                                                                         sv->vertex(iv2), (m_aaVrtVecVol[sv])[iv2], sv->vertex(iv1)
    7725              :                                                                                                 )
    7726              :                                                                                                 );
    7727              : 
    7728              : //                                                      m_sh.assign_subset(expVol, m_sh.num_subsets());
    7729              : //                                                      m_sh.assign_subset( sv->vertex(iv0), m_sh.num_subsets());
    7730              : //                                                      m_sh.assign_subset( sv->vertex(iv1), m_sh.num_subsets());
    7731              : //                                                      m_sh.assign_subset( sv->vertex(iv2), m_sh.num_subsets());
    7732              : //                                                      m_sh.assign_subset( sv->vertex(iv3), m_sh.num_subsets());
    7733              : //                                                      m_sh.assign_subset( (m_aaVrtVecVol[sv])[iv0], m_sh.num_subsets());
    7734              : //                                                      m_sh.assign_subset( (m_aaVrtVecVol[sv])[iv2], m_sh.num_subsets());
    7735              : 
    7736              : 
    7737              :                                                 }
    7738              :                                                 else if(    ( m_aaVrtVecVol[sv] )[iv0]
    7739            0 :                                                                  && ( m_aaVrtVecVol[sv] )[iv3]
    7740              :                                                 )
    7741              :                                                 {
    7742              :                                                         UG_LOG("PRISM 0 3 " << std::endl);
    7743              : 
    7744              :                                                 }
    7745              :                                                 else if(    ( m_aaVrtVecVol[sv] )[iv1]
    7746            0 :                                                                  && ( m_aaVrtVecVol[sv] )[iv2]
    7747              :                                                 )
    7748              :                                                 {
    7749              : 
    7750              :                                                         UG_LOG("PRISM 1 2 " << std::endl);
    7751              : 
    7752              :                                                 }
    7753              :                                                 else if(    ( m_aaVrtVecVol[sv] )[iv2]
    7754            0 :                                                                  && ( m_aaVrtVecVol[sv] )[iv3]
    7755              :                                                 )
    7756              :                                                 {
    7757              :                                                         UG_LOG("PRISM 2 3 " << std::endl);
    7758              : 
    7759              :                                                 }
    7760              : 
    7761              : 
    7762              : 
    7763              :                                         }
    7764              :                                         else
    7765              :                                         {
    7766              :                                                 //      traditionally only tetrahedrons are supported. This section thus raises an error
    7767              :                                                 // Markus tries to implement also Hexahedra
    7768              : //                                                      grid.detach_from_vertices(aVrtVec);
    7769              : //                                                      grid.detach_from_volumes(aVrtVec);
    7770              : //                                                      grid.detach_from_vertices(aAdjMarker);
    7771              : //                                                      grid.detach_from_edges(aAdjMarker);
    7772            0 :                                                 detachMarkers();
    7773            0 :                                                 throw(UGError("Incomplete implementation error in ExpandFractures3d Arte: Only tetrahedrons are supported in the current implementation, and hexahedra are in development."));
    7774              :                                                 return false;
    7775              :                                         }
    7776              : 
    7777            0 :                                         if(expVol)
    7778              :                                         {
    7779              : 
    7780            0 :                                                 IndexType newSubs = m_fracInfosBySubset.at(m_sh.get_subset_index(tFace)).newSubsetIndex;
    7781              : 
    7782            0 :                                                 subsOfNewVolumes.push_back( newSubs );
    7783              : 
    7784              : //                                              m_sh.assign_subset(expVol, m_fracInfosBySubset.at(m_sh.get_subset_index(tFace)).newSubsetIndex);
    7785            0 :                                                 m_sh.assign_subset(expVol, newSubs);
    7786              : 
    7787            0 :                                                 newFractureVolumes.push_back(expVol);
    7788              :                                         }
    7789              :                                 }
    7790              :                         }
    7791              :                 }
    7792              : 
    7793              :                 //      now set up a new volume descriptor and replace the volume.
    7794            0 :                 if(vd.num_vertices() != sv->num_vertices())
    7795            0 :                         vd.set_num_vertices(sv->num_vertices());
    7796              : 
    7797            0 :                 for(size_t i_vrt = 0; i_vrt < sv->num_vertices(); ++i_vrt)
    7798              :                 {
    7799            0 :                         if( (m_aaVrtVecVol[sv])[i_vrt] )
    7800            0 :                                 vd.set_vertex(i_vrt, (m_aaVrtVecVol[sv])[i_vrt]);
    7801              :                         else
    7802            0 :                                 vd.set_vertex(i_vrt, sv->vertex(i_vrt));
    7803              :                 }
    7804              : 
    7805            0 :                 m_grid.create_by_cloning(sv, vd, sv);
    7806            0 :                 m_grid.erase(sv);
    7807              :         }
    7808              : 
    7809              :         UG_LOG("Volumes erzeugt " << std::endl);
    7810              : 
    7811              : //      return false;
    7812              : 
    7813              : 
    7814              : 
    7815              : 
    7816              :         //      we have to clean up unused faces and edges.
    7817              :         //      note that all selected edges with mark 0 may safley be deleted. - warum?
    7818            0 :         for(EdgeIterator iter = m_sel.begin<Edge>(); iter!= m_sel.end<Edge>();)
    7819              :         {
    7820              :                 //      take care of the iterator
    7821              :                 Edge* e = *iter;
    7822              :                 ++iter;
    7823              : 
    7824            0 :                 if( m_aaMarkEdgeVFP[e].getNumberFracEdgesInVertex() == 0 )
    7825            0 :                         m_grid.erase(e);
    7826              :         }
    7827              : 
    7828              :         //      make sure that no unused faces linger around (This should never happen!)
    7829              :         bool foundUnusedFaces = false;
    7830              : 
    7831            0 :         for(FaceIterator iter = m_sel.begin<Face>(); iter != m_sel.end<Face>();)
    7832              :         {
    7833              :                 Face* f = *iter;
    7834              :                 ++iter;
    7835              : 
    7836              : //              if( m_aaMarkFaceHasUnclosedFracSideB[f] )
    7837              : //              {
    7838              : //                      UG_LOG("want to delete unclosed frac face " << std::endl);
    7839              : //                      // todo fixme XXXXXXXXXXXXXXXXXX
    7840              : //                      //return false;
    7841              : //              }
    7842              : 
    7843            0 :                 if( ! m_aaMarkFaceIsFracB[f] )
    7844              :                 {
    7845              :                         foundUnusedFaces = true;
    7846            0 :                         m_grid.erase(f);
    7847              :                 }
    7848              :         }
    7849              : 
    7850            0 :         if(foundUnusedFaces)
    7851              :         {
    7852              :                 UG_LOG("WARNING in ExpandFractures3D Arte: Unused faces encountered during cleanup. Removing them...\n");
    7853              :         }
    7854              : 
    7855            0 :         if( subsOfNewVolumes.size() != newFractureVolumes.size() )
    7856              :         {
    7857            0 :                 UG_THROW("andere zahl neue volumes als subdoms " << std::endl);
    7858              :         }
    7859              : 
    7860              : 
    7861              : //      return true;
    7862              : 
    7863              : 
    7864              :         IndexType nfn = 0;
    7865              : 
    7866            0 :         for( auto const & nf : newFractureVolumes )
    7867              :         {
    7868            0 :                 for(size_t iFace = 0; iFace < nf->num_faces(); ++iFace)
    7869              :                 {
    7870            0 :                         Face * fac = m_grid.get_face(nf, iFace);
    7871              : 
    7872            0 :                         m_sh.assign_subset( fac, subsOfNewVolumes[nfn] );
    7873              : 
    7874              :                 }
    7875              : 
    7876            0 :                 for(size_t iEdge = 0; iEdge < nf->num_edges(); ++iEdge)
    7877              :                 {
    7878            0 :                         Edge* edg = m_grid.get_edge(nf, iEdge);
    7879              : 
    7880            0 :                         m_sh.assign_subset( edg, subsOfNewVolumes[nfn] );
    7881              : 
    7882              :                 }
    7883              : 
    7884            0 :                 for( size_t iVrt = 0; iVrt < nf->num_vertices(); iVrt++ )
    7885              :                 {
    7886            0 :                         Vertex * vrt = nf->vertex(iVrt);
    7887              : 
    7888            0 :                         m_sh.assign_subset( vrt, subsOfNewVolumes[nfn] );
    7889              :                 }
    7890              : 
    7891            0 :                 nfn++;
    7892              :         }
    7893              : 
    7894            0 :         for( EndingCrossingFractureSegmentInfo const & ecfsi : m_vecEndCrossFractSegmInfo )
    7895              :         {
    7896              :                 Face * hiddenCutFracFace = ecfsi.spuckHiddenCutFractManifEl();
    7897              : 
    7898              :                 IndexType subsECC = ecfsi.spuckSudoFractEnding();
    7899              : 
    7900            0 :                 m_sh.assign_subset( hiddenCutFracFace, subsECC );
    7901              : 
    7902            0 :                 for(size_t iEdge = 0; iEdge < hiddenCutFracFace->num_edges(); ++iEdge)
    7903              :                 {
    7904            0 :                         Edge* edg = m_grid.get_edge(hiddenCutFracFace, iEdge);
    7905              : 
    7906            0 :                         m_sh.assign_subset( edg, subsECC );
    7907              : 
    7908              :                 }
    7909              : 
    7910            0 :                 for( size_t iVrt = 0; iVrt < hiddenCutFracFace->num_vertices(); iVrt++ )
    7911              :                 {
    7912            0 :                         Vertex * vrt = hiddenCutFracFace->vertex(iVrt);
    7913              : 
    7914            0 :                         m_sh.assign_subset( vrt, subsECC );
    7915              :                 }
    7916              : 
    7917              :         }
    7918              : 
    7919              : 
    7920              :         return true;
    7921            0 : }
    7922              : 
    7923            0 : ArteExpandFracs3D::IndexType ArteExpandFracs3D::deleteEndingCrossingCleftOrigFacs()
    7924              : {
    7925              : 
    7926              :         IndexType numOfDelSegs = 0;
    7927              : 
    7928            0 :         for( EndingCrossingFractureSegmentInfo const & ecfsi : m_vecEndCrossFractSegmInfo )
    7929              :         {
    7930              :                 Vertex * vrt = ecfsi.spuckUnclosedVrtx();
    7931              : 
    7932              :                 Edge * directionEdge = ecfsi.spuckLowdimElmShiftDirection();
    7933              : 
    7934              :                 Face * oldFractFacCut = ecfsi.spuckEndingFractManifCutting();
    7935              : 
    7936              :                 std::vector<Face*> vecOldFractFacNotCut = ecfsi.spuckVecEndingFractManifNotCutting();
    7937              : 
    7938              : //              Edge * commonEdge = nullptr;
    7939              : 
    7940              :                 std::vector<Edge*> innerEdges;
    7941              : 
    7942            0 :                 for( Face * oldFractFacNotCut : vecOldFractFacNotCut )
    7943              :                 {
    7944              : //                      for(size_t iEdge = 0; iEdge < oldFractFacCut->num_edges(); ++iEdge)
    7945              : //                      {
    7946              : //                              Edge* edgC = m_grid.get_edge(oldFractFacCut, iEdge);
    7947              : 
    7948            0 :                         for(size_t iEdge = 0; iEdge < oldFractFacNotCut->num_edges(); ++iEdge)
    7949              :                         {
    7950            0 :                                 Edge* edgN = m_grid.get_edge(oldFractFacNotCut, iEdge);
    7951              : 
    7952            0 :                                 if( edgN != directionEdge && EdgeContains(edgN, vrt) )
    7953              :                                         addElem(innerEdges, edgN);
    7954              : //                                      if( edgC == edgN )
    7955              : //                                      {
    7956              : //                                              commonEdge = edgC;
    7957              : //                                              break;
    7958              : //                                      }
    7959              : 
    7960              :                         }
    7961              : //                              if( commonEdge )
    7962              : //                                      break;
    7963              : //
    7964              : //                      }
    7965              :                 }
    7966              : 
    7967            0 :                 if( oldFractFacCut )
    7968            0 :                         m_grid.erase(oldFractFacCut);
    7969              : 
    7970            0 :                 for( Face * oldFractFacNotCut : vecOldFractFacNotCut )
    7971              :                 {
    7972            0 :                         if( oldFractFacNotCut )
    7973            0 :                                 m_grid.erase(oldFractFacNotCut);
    7974              :                 }
    7975              : 
    7976            0 :                 if( directionEdge )
    7977            0 :                         m_grid.erase(directionEdge);
    7978              : 
    7979            0 :                 for( Edge * iE : innerEdges )
    7980              :                 {
    7981            0 :                         if( iE )
    7982              :                         {
    7983            0 :                                 m_grid.erase(iE);
    7984              : //                              m_sh.assign_subset( iE, m_sh.num_subsets());
    7985              :                         }
    7986              :                 }
    7987              : 
    7988            0 :                 numOfDelSegs++;
    7989            0 :         }
    7990              : 
    7991            0 :         return numOfDelSegs;
    7992              : }
    7993              : 
    7994              : ////////////////////////////////////////////////////////////
    7995              : 
    7996            0 : bool ArteExpandFracs3D::etablishVolumesAtEndingCrossingClefts( std::vector<Volume*> & newFractureVolumes, std::vector<IndexType> & subsOfNewVolumes )
    7997              : {
    7998              : 
    7999            0 :         for( EndingCrossingFractureSegmentInfo & ecfsi : m_vecEndCrossFractSegmInfo )
    8000              :         {
    8001              :                 Vertex * baseVrtx = ecfsi.spuckUnclosedVrtx();
    8002              : 
    8003              :                 Vertex * shiftVrtx = ecfsi.spuckShiftVrtx();
    8004              : 
    8005              :                 Edge * cutEdge = ecfsi.spuckOldLowDimElCut();
    8006              : 
    8007              :                 Vertex * secondVrtxCutEdge = nullptr;
    8008              : 
    8009            0 :                 if( cutEdge->vertex(0) == baseVrtx )
    8010              :                 {
    8011            0 :                         secondVrtxCutEdge = cutEdge->vertex(1);
    8012              :                 }
    8013            0 :                 else if( cutEdge->vertex(1) == baseVrtx )
    8014              :                 {
    8015            0 :                         secondVrtxCutEdge = cutEdge->vertex(0);
    8016              :                 }
    8017              :                 else
    8018              :                 {
    8019              :                         UG_LOG("no second vertex of cut edge " << std::endl);
    8020            0 :                         UG_THROW("no second vertex of cut edge " << std::endl);
    8021              :                         return false;
    8022              :                 }
    8023              : 
    8024            0 :                 Edge * divisionEdge = *m_grid.create<RegularEdge>( EdgeDescriptor( secondVrtxCutEdge, shiftVrtx ) );
    8025              : 
    8026              :                 IndexType subsetECC = ecfsi.spuckSudoFractEnding();
    8027              : 
    8028              : //              m_sh.assign_subset(divisionEdge, m_sh.num_subsets());
    8029            0 :                 m_sh.assign_subset(divisionEdge, subsetECC);
    8030              : 
    8031            0 :                 Face * hiddenCutFracFace = *m_grid.create<Triangle>(TriangleDescriptor( baseVrtx, shiftVrtx, secondVrtxCutEdge ));
    8032              : 
    8033              : //              m_sh.assign_subset(hiddenCutFracFace, m_sh.num_subsets());
    8034            0 :                 m_sh.assign_subset(hiddenCutFracFace, subsetECC);
    8035              : 
    8036            0 :                 IndexType subsNewFacesEdges = m_sh.get_subset_index(hiddenCutFracFace);
    8037              : 
    8038            0 :                 for(size_t iEdge = 0; iEdge < hiddenCutFracFace->num_edges(); ++iEdge)
    8039              :                 {
    8040            0 :                         Edge* edg = m_grid.get_edge(hiddenCutFracFace, iEdge);
    8041              : 
    8042            0 :                         m_sh.assign_subset( edg, subsNewFacesEdges );
    8043            0 :                         UG_LOG("HEDGE CENTER " << CalculateCenter( edg, m_aaPos ) << std::endl );
    8044              : 
    8045            0 :                         UG_LOG("HEdge subdom " << m_sh.get_subset_index(edg) << std::endl );
    8046              : 
    8047              :                 }
    8048              : 
    8049              :                 if( ! ecfsi.schluckHiddenCutFractManifEl( hiddenCutFracFace ))
    8050              :                 {
    8051              :                         UG_LOG("hidden cut face Problem" << std::endl);
    8052            0 :                         UG_THROW("hidden cut face Problem" << std::endl);
    8053              :                 }
    8054              : 
    8055              :                 Face * endingFractFacCutting = ecfsi.spuckEndingFractManifCutting();
    8056              : 
    8057              :                 IndexType const triangVrtxNum = 3;
    8058              : 
    8059            0 :                 if( endingFractFacCutting->num_vertices() != triangVrtxNum )
    8060              :                 {
    8061              :                         UG_LOG("only triangles allowed " << std::endl);
    8062            0 :                         UG_THROW("only triangles allowed " << std::endl);
    8063              :                 }
    8064              : 
    8065              : 
    8066              :                 IndexType foundNotTouchVrtx = 0;
    8067              : 
    8068              :                 Vertex * notTouchingVrtx = nullptr;
    8069              : 
    8070              : 
    8071              :                 // figure out that vertex of the ending fracture faces that is not touching the crossing not ending cleft
    8072            0 :                 for( IndexType vrtIndx = 0; vrtIndx < triangVrtxNum; vrtIndx++ )
    8073              :                 {
    8074            0 :                         Vertex * testVrt = endingFractFacCutting->vertex(vrtIndx);
    8075              : 
    8076            0 :                         if( ! EdgeContains( cutEdge, testVrt ) )
    8077              :                         {
    8078            0 :                                 foundNotTouchVrtx++;
    8079              :                                 notTouchingVrtx = testVrt;
    8080              :                         }
    8081              :                 }
    8082              : 
    8083            0 :                 if( foundNotTouchVrtx != 1 || ! notTouchingVrtx  )
    8084              :                 {
    8085              :                         UG_LOG("not touching vertex not found " << std::endl);
    8086            0 :                         UG_THROW("not touching vertex not found " << std::endl);
    8087              :                 }
    8088              : 
    8089              :                 // replace the face that touches with an edge
    8090            0 :                 Face * replaceEndingFractCutFac = *m_grid.create<Triangle>(TriangleDescriptor( shiftVrtx, secondVrtxCutEdge, notTouchingVrtx ));
    8091              : 
    8092              : //              m_sh.assign_subset( replaceEndingFractCutFac, m_sh.num_subsets() );
    8093            0 :                 m_sh.assign_subset( replaceEndingFractCutFac, subsetECC );
    8094              : 
    8095            0 :                 IndexType subsNewFacesEdgesC = m_sh.get_subset_index(replaceEndingFractCutFac);
    8096              : 
    8097              :                 UG_LOG("EDGE NUMBER CCS CC " << replaceEndingFractCutFac->num_edges() << std::endl);
    8098              : 
    8099            0 :                 for(size_t iEdge = 0; iEdge < replaceEndingFractCutFac->num_edges(); ++iEdge)
    8100              :                 {
    8101            0 :                         Edge* edg = m_grid.get_edge(replaceEndingFractCutFac, iEdge);
    8102              : 
    8103            0 :                         m_sh.assign_subset( edg, subsNewFacesEdgesC );
    8104            0 :                         UG_LOG("EDGE CENTER " << CalculateCenter( edg, m_aaPos ) << std::endl );
    8105              : 
    8106            0 :                         UG_LOG("Edge subdom " << m_sh.get_subset_index(edg) << std::endl );
    8107              : 
    8108              :                 }
    8109              : 
    8110              : //              // replace the face that has only the base vertex common, if existing
    8111              : //              Face * endingFractFacNotCutting = ecfsi.spuckEndingFractManifNotCutting();
    8112              : //
    8113            0 :                 for( Face * const & endingFractFacNotCutting : ecfsi.spuckVecEndingFractManifNotCutting() )
    8114              :                 {
    8115            0 :                         if( endingFractFacNotCutting )
    8116              :                         {
    8117              : 
    8118            0 :                                 if( endingFractFacNotCutting->num_vertices() != triangVrtxNum )
    8119              :                                 {
    8120              :                                         UG_LOG("only triangles allowed NC" << std::endl);
    8121            0 :                                         UG_THROW("only triangles allowed NC" << std::endl);
    8122              :                                 }
    8123              : 
    8124              :                                 std::vector<Vertex*> vrtcsNotBase;
    8125              : 
    8126              :                                 // figure out those vertices which are not the basis vertex
    8127            0 :                                 for( IndexType vrtIndx = 0; vrtIndx < triangVrtxNum; vrtIndx++ )
    8128              :                                 {
    8129            0 :                                         Vertex * testVrt = endingFractFacNotCutting->vertex(vrtIndx);
    8130              : 
    8131            0 :                                         if( testVrt != baseVrtx )
    8132            0 :                                                 vrtcsNotBase.push_back(testVrt);
    8133              :                                 }
    8134              : 
    8135            0 :                                 if( vrtcsNotBase.size() != 2 )
    8136              :                                 {
    8137              :                                         UG_LOG("strange number vertices " << vrtcsNotBase.size() << std::endl);
    8138            0 :                                         UG_THROW("strange number vertices " << vrtcsNotBase.size() << std::endl);
    8139              :                                 }
    8140              : 
    8141            0 :                                 Face * replaceEndingFractNotCutFac = *m_grid.create<Triangle>(TriangleDescriptor( shiftVrtx, vrtcsNotBase[0], vrtcsNotBase[1] ));
    8142              : 
    8143              :         //                      m_sh.assign_subset( replaceEndingFractNotCutFac, m_sh.num_subsets() );
    8144            0 :                                 m_sh.assign_subset( replaceEndingFractNotCutFac, subsetECC );
    8145              : 
    8146            0 :                                 IndexType subsNewFacesEdges = m_sh.get_subset_index(replaceEndingFractNotCutFac);
    8147              : 
    8148              :                                 UG_LOG("EDGE NUMBER CCS " << replaceEndingFractNotCutFac->num_edges() << std::endl);
    8149              : 
    8150            0 :                                 for(size_t iEdge = 0; iEdge < replaceEndingFractNotCutFac->num_edges(); ++iEdge)
    8151              :                                 {
    8152            0 :                                         Edge* edg = m_grid.get_edge(replaceEndingFractNotCutFac, iEdge);
    8153              : 
    8154            0 :                                         m_sh.assign_subset( edg, subsNewFacesEdges );
    8155              : 
    8156            0 :                                         UG_LOG("EDGE CENTER " << CalculateCenter( edg, m_aaPos ) << std::endl );
    8157              : 
    8158            0 :                                         UG_LOG("Edge subdom " << m_sh.get_subset_index(edg) << std::endl );
    8159              : 
    8160              :                                 }
    8161              : 
    8162            0 :                         }
    8163              : 
    8164            0 :                 }
    8165              : 
    8166              : //              for(VolumeIterator iter_sv = m_sel.volumes_begin(); iter_sv != m_sel.volumes_end();)
    8167            0 :                 for( Volume * const & sv : ecfsi.spuckVecFulldimEl() )
    8168              :                 {
    8169              : 
    8170            0 :                         UG_LOG("CEC Volume new creation try at " << CalculateCenter(sv, m_aaPos) << std::endl);
    8171              : 
    8172            0 :                         bool volHasEndingCrossingCleftFace = m_volAttAccsVolTouchesEndingCrossingCleft[sv];
    8173              : 
    8174              :                         // should be true!
    8175              : 
    8176            0 :                         if( ! volHasEndingCrossingCleftFace )
    8177              :                         {
    8178              :                                 UG_LOG("Was ist da los, ending cleft und doch nicht " << std::endl);
    8179            0 :                                 UG_THROW("Was ist da los, ending cleft und doch nicht " << std::endl);
    8180              :                         }
    8181              : 
    8182              :                         // check if volume contains the base vertex
    8183              : 
    8184            0 :                         if( ! VolumeContains(sv, baseVrtx))
    8185              :                         {
    8186              :                                 UG_LOG("VOlume ausdehenen ECC ohne base vertex " << std::endl);
    8187            0 :                                 UG_THROW("VOlume ausdehenen ECC ohne base vertex " << std::endl);
    8188              :                         }
    8189              : 
    8190              :                         //      now expand the fracture faces of sv to volumes.
    8191            0 :                         for(size_t i_side = 0; i_side < sv->num_sides(); ++i_side)
    8192              :                         {
    8193              :                                 //      holds local side vertex indices
    8194              :                                 std::vector<size_t>       locVrtInds;
    8195              : 
    8196              :                                 //      get the local vertex indices of the side of the volume
    8197            0 :                                 sv->get_vertex_indices_of_face(locVrtInds, i_side);
    8198              : 
    8199            0 :                                 Face* tFace = m_grid.get_side(sv, i_side);
    8200              : 
    8201            0 :                                 if(tFace)
    8202              :                                 {
    8203            0 :                                         if( m_aaMarkFaceIsFracB[tFace] )
    8204              :                                         {
    8205              :                                                 bool faceIsSegmLimEndCrossCleft = m_facAttAccsIfFaceIsSegmLimFaceEndingCrossingCleft[tFace];
    8206              :                                                 bool faceIsEndingCleftCrossFace = m_aaMarkFaceWithEndingCrossingCleft[tFace];
    8207              : 
    8208              :                                                 UG_LOG("Volumenerzeugung Versuch ECC Anfang" << std::endl);
    8209              : 
    8210            0 :                                                 Volume* expVol = nullptr;
    8211              : 
    8212            0 :                                                 Volume* expVolTwo = nullptr;
    8213              : 
    8214              : 
    8215            0 :                                                 if(locVrtInds.size() == 3)
    8216              :                                                 {
    8217            0 :                                                         size_t iv0 = locVrtInds[0];
    8218            0 :                                                         size_t iv1 = locVrtInds[1];
    8219            0 :                                                         size_t iv2 = locVrtInds[2];
    8220              : 
    8221              : //                                                      Vertex * vrtxOne = ( m_aaVrtVecVol[sv] )[iv0];
    8222              : //                                                      Vertex * vrtxTwo = ( m_aaVrtVecVol[sv] )[iv1];
    8223              : //                                                      Vertex * vrtxThree = ( m_aaVrtVecVol[sv] )[iv2];
    8224              : 
    8225              :                                                         // figure out which vertex is the base vertex
    8226              : 
    8227              :                                                         int indBasVrtx = -1;
    8228              : 
    8229              :                                                         // wie kann das nur stimmen, das Volumen hat doch mehr als 3 Vertizes....
    8230              :                                                         // zufällig für das Testbeispiel vielleicht richtig?
    8231              : //                                                      for( IndexType vrtxInd = 0; vrtxInd < triangVrtxNum; vrtxInd++ )
    8232            0 :                                                         for( IndexType vrtxInd = 0; vrtxInd < sv->num_vertices(); vrtxInd++ )
    8233              :                                                         {
    8234            0 :                                                                 if( sv->vertex(vrtxInd) == baseVrtx )
    8235            0 :                                                                         indBasVrtx = vrtxInd;
    8236              :                                                         }
    8237              :                                                         // muss der Loop nicht über die Vertizes des volumens gehen?????
    8238              : 
    8239              :                                                         // der Index des Basisvertex ist tabu für die Ausehnung der endenden fracture
    8240              : 
    8241            0 :                                                         bool belongsToEndingCleftFaces = (endingFractFacCutting == tFace);
    8242              : 
    8243              :                                                         bool belongstToEndingNotCuttingFacs = false;
    8244              : 
    8245            0 :                                                         for( Face * const & endingFractFacNotCutting : ecfsi.spuckVecEndingFractManifNotCutting() )
    8246              :                                                         {
    8247            0 :                                                                 if( tFace == endingFractFacNotCutting )
    8248              :                                                                 {
    8249              :                                                                         belongsToEndingCleftFaces = true;
    8250              :                                                                         belongstToEndingNotCuttingFacs = true;
    8251              :                                                                         UG_LOG("Want to create for not cutting ending fract face vol " << std::endl);
    8252              :                                                                 }
    8253            0 :                                                         }
    8254              : 
    8255            0 :                                                         if( belongsToEndingCleftFaces != faceIsEndingCleftCrossFace )
    8256              :                                                         {
    8257              :                                                                 UG_LOG("Widerspruch ending but not ending ECC" << std::endl);
    8258            0 :                                                                 UG_THROW("Widerspruch ending but not ending ECC" << std::endl);
    8259              : 
    8260              :                                                         }
    8261              : 
    8262            0 :                                                         if( belongsToEndingCleftFaces )
    8263              :                                                         {
    8264            0 :                                                                 if( ! faceIsEndingCleftCrossFace )
    8265              :                                                                 {
    8266              :                                                                         UG_LOG("Widerspruch ending but not ending ECC" << std::endl);
    8267              :                                                                 }
    8268              : 
    8269            0 :                                                                 if( iv0 == indBasVrtx )
    8270              :                                                                 {
    8271            0 :                                                                         if(    ( m_aaVrtVecVol[sv] )[iv0]
    8272            0 :                                                                                 && ( m_aaVrtVecVol[sv] )[iv1]
    8273            0 :                                                                                 && ( m_aaVrtVecVol[sv] )[iv2]
    8274              :                                                                         )
    8275              :                                                                         {
    8276              :                                                                                 //      create a new pyramid
    8277              : //                                                                              expVol = *m_grid.create<Pyramid>(
    8278              : //                                                                                                              PyramidDescriptor(sv->vertex(iv2), sv->vertex(iv1),
    8279              : //                                                                                                                                              (m_aaVrtVecVol[sv])[iv2],
    8280              : //                                                                                                                                              (m_aaVrtVecVol[sv])[iv1],
    8281              : //                                                                                                                                              (m_aaVrtVecVol[sv])[iv0]));
    8282              : 
    8283            0 :                                                                                 expVol = *m_grid.create<Pyramid>(
    8284            0 :                                                                                                                 PyramidDescriptor(sv->vertex(iv1), sv->vertex(iv2),
    8285              :                                                                                                                         (m_aaVrtVecVol[sv])[iv2],
    8286              :                                                                                                                         (m_aaVrtVecVol[sv])[iv1],
    8287              :                                                                                                                         (m_aaVrtVecVol[sv])[iv0]));
    8288              : 
    8289              :                                                                         }
    8290              :                                                                         else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8291            0 :                                                                                          && ( m_aaVrtVecVol[sv] )[iv1]
    8292              :                                                                         )
    8293              :                                                                         {
    8294              :                                                                                 //      create a new tetrahedron
    8295            0 :                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8296            0 :                                                                                                                 TetrahedronDescriptor(sv->vertex(iv1),
    8297              :                                                                                                                         (m_aaVrtVecVol[sv])[iv1],
    8298            0 :                                                                                                                         (m_aaVrtVecVol[sv])[iv0],
    8299            0 :                                                                                                                         sv->vertex(iv2)));
    8300              :                                                                         }
    8301              : //                                                                      else if(    ( m_aaVrtVecVol[sv] )[iv1]
    8302              : //                                                                                       && ( m_aaVrtVecVol[sv] )[iv2]
    8303              : //                                                                      )
    8304              : //                                                                      {
    8305              : //                                                                              //      create a new Pyramid
    8306              : //                                                                              expVol = *m_grid.create<Pyramid>(
    8307              : //                                                                                                              PyramidDescriptor(sv->vertex(iv1), sv->vertex(iv2),
    8308              : //                                                                                                                      (m_aaVrtVecVol[sv])[iv2],
    8309              : //                                                                                                                      (m_aaVrtVecVol[sv])[iv1],
    8310              : //                                                                                                                      sv->vertex(iv0)));
    8311              : //                                                                      }
    8312              :                                                                         else if(    (m_aaVrtVecVol[sv])[iv0]
    8313            0 :                                                                                          && (m_aaVrtVecVol[sv])[iv2]
    8314              :                                                                         )
    8315              :                                                                         {
    8316              :                                                                                 //      create a new tetrahedron
    8317            0 :                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8318            0 :                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2),
    8319              :                                                                                                                         (m_aaVrtVecVol[sv])[iv0],
    8320            0 :                                                                                                                         (m_aaVrtVecVol[sv])[iv2],
    8321            0 :                                                                                                                         sv->vertex(iv1)));
    8322              :                                                                         }
    8323              : //                                                                      else if( ( m_aaVrtVecVol[sv])[iv0] )
    8324              : //                                                                      {
    8325              : //                                                                              //      create a new Tetrahedron
    8326              : //                                                                              expVol = *m_grid.create<Tetrahedron>(
    8327              : //                                                                                                              TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8328              : //                                                                                                                                                       (m_aaVrtVecVol[sv])[iv0]));
    8329              : //                                                                      }
    8330              : //                                                                      else if( ( m_aaVrtVecVol[sv])[iv1] )
    8331              : //                                                                      {
    8332              : //                                                                              //      create a new Tetrahedron
    8333              : //                                                                              expVol = *m_grid.create<Tetrahedron>(
    8334              : //                                                                                                              TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8335              : //                                                                                                                                                       (m_aaVrtVecVol[sv])[iv1]));
    8336              : //                                                                      }
    8337              : //                                                                      else if( ( m_aaVrtVecVol[sv])[iv2] )
    8338              : //                                                                      {
    8339              : //                                                                              //      create a new Tetrahedron
    8340              : //                                                                              expVol = *m_grid.create<Tetrahedron>(
    8341              : //                                                                                                              TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8342              : //                                                                                                                                                       (m_aaVrtVecVol[sv])[iv2]));
    8343              : //                                                                      }
    8344              :                                                                         else
    8345              :                                                                         {
    8346              :                                                                                 //      Text from SR, still similar:
    8347              :                                                                                 //  this code-block should never be entered. If it is entered then
    8348              :                                                                                 //      we either selected the wrong faces (this shouldn't happen), or there
    8349              :                                                                                 //      are selected faces, which have fracture-boundary-vertices only.
    8350              :                                                                                 //      This is the same is if inner fracture edges exists, which are
    8351              :                                                                                 //      connected to two boundary vertices.
    8352              :                                                                                 //      Since we tried to remove those edges above, something went wrong.
    8353              :                                                                                 //      remove the temporary attachments and throw an error
    8354              : 
    8355              :                                                                                 UG_LOG("Tetraeder ECC Fehlt eine Loesung " << std::endl);
    8356            0 :                                                                                 detachMarkers();
    8357            0 :                                                                                 throw(UGError("Error in ExpandFractures3d Arte Stasi. Implementation Error."));
    8358              :                                                                                 return false;
    8359              :                                                                         }
    8360              : 
    8361              :                                                                 }
    8362            0 :                                                                 else if( iv1 == indBasVrtx )
    8363              :                                                                 {
    8364            0 :                                                                         if(    ( m_aaVrtVecVol[sv] )[iv0]
    8365            0 :                                                                                 && ( m_aaVrtVecVol[sv] )[iv1]
    8366            0 :                                                                                 && ( m_aaVrtVecVol[sv] )[iv2]
    8367              :                                                                         )
    8368              :                                                                         {
    8369              :                                                                                 //      create a new prism
    8370              : //                                                                              expVol = *m_grid.create<Pyramid>(
    8371              : //                                                                                                              PyramidDescriptor( sv->vertex(iv2), sv->vertex(iv0),
    8372              : //                                                                                                                                                              (m_aaVrtVecVol[sv])[iv2],
    8373              : //                                                                                                                                                              (m_aaVrtVecVol[sv])[iv1],
    8374              : //                                                                                                                                                              (m_aaVrtVecVol[sv])[iv0]));
    8375              : 
    8376              : 
    8377            0 :                                                                                 expVol = *m_grid.create<Pyramid>(
    8378            0 :                                                                                                                 PyramidDescriptor(sv->vertex(iv2), sv->vertex(iv0),
    8379              :                                                                                                                         (m_aaVrtVecVol[sv])[iv0],
    8380              :                                                                                                                         (m_aaVrtVecVol[sv])[iv2],
    8381              :                                                                                                                         (m_aaVrtVecVol[sv])[iv1]));
    8382              : 
    8383              :                                                                         }
    8384              :                                                                         else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8385            0 :                                                                                          && ( m_aaVrtVecVol[sv] )[iv1]
    8386              :                                                                         )
    8387              :                                                                         {
    8388              :                                                                                 //      create a new Pyramid
    8389            0 :                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8390            0 :                                                                                                                 TetrahedronDescriptor(sv->vertex(iv0),
    8391              :                                                                                                                         (m_aaVrtVecVol[sv])[iv1],
    8392            0 :                                                                                                                         (m_aaVrtVecVol[sv])[iv0],
    8393            0 :                                                                                                                         sv->vertex(iv2)));
    8394              :                                                                         }
    8395              :                                                                         else if(    ( m_aaVrtVecVol[sv] )[iv1]
    8396            0 :                                                                                          && ( m_aaVrtVecVol[sv] )[iv2]
    8397              :                                                                         )
    8398              :                                                                         {
    8399              :                                                                                 //      create a new Pyramid
    8400            0 :                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8401            0 :                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2),
    8402              :                                                                                                                         (m_aaVrtVecVol[sv])[iv2],
    8403            0 :                                                                                                                         (m_aaVrtVecVol[sv])[iv1],
    8404            0 :                                                                                                                         sv->vertex(iv0)));
    8405              :                                                                         }
    8406              : //                                                                      else if(    (m_aaVrtVecVol[sv])[iv0]
    8407              : //                                                                                       && (m_aaVrtVecVol[sv])[iv2]
    8408              : //                                                                      )
    8409              : //                                                                      {
    8410              : //                                                                              //      create a new Pyramid
    8411              : //                                                                              expVol = *m_grid.create<Pyramid>(
    8412              : //                                                                                                              PyramidDescriptor(sv->vertex(iv2), sv->vertex(iv0),
    8413              : //                                                                                                                      (m_aaVrtVecVol[sv])[iv0],
    8414              : //                                                                                                                      (m_aaVrtVecVol[sv])[iv2],
    8415              : //                                                                                                                      sv->vertex(iv1)));
    8416              : //                                                                      }
    8417              : //                                                                      else if( ( m_aaVrtVecVol[sv])[iv0] )
    8418              : //                                                                      {
    8419              : //                                                                              //      create a new Tetrahedron
    8420              : //                                                                              expVol = *m_grid.create<Tetrahedron>(
    8421              : //                                                                                                              TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8422              : //                                                                                                                                                       (m_aaVrtVecVol[sv])[iv0]));
    8423              : //                                                                      }
    8424              : //                                                                      else if( ( m_aaVrtVecVol[sv])[iv1] )
    8425              : //                                                                      {
    8426              : //                                                                              //      create a new Tetrahedron
    8427              : //                                                                              expVol = *m_grid.create<Tetrahedron>(
    8428              : //                                                                                                              TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8429              : //                                                                                                                                                       (m_aaVrtVecVol[sv])[iv1]));
    8430              : //                                                                      }
    8431              : //                                                                      else if( ( m_aaVrtVecVol[sv])[iv2] )
    8432              : //                                                                      {
    8433              : //                                                                              //      create a new Tetrahedron
    8434              : //                                                                              expVol = *m_grid.create<Tetrahedron>(
    8435              : //                                                                                                              TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8436              : //                                                                                                                                                       (m_aaVrtVecVol[sv])[iv2]));
    8437              : //                                                                      }
    8438              :                                                                         else
    8439              :                                                                         {
    8440              :                                                                                 //      Text from SR, still similar:
    8441              :                                                                                 //  this code-block should never be entered. If it is entered then
    8442              :                                                                                 //      we either selected the wrong faces (this shouldn't happen), or there
    8443              :                                                                                 //      are selected faces, which have fracture-boundary-vertices only.
    8444              :                                                                                 //      This is the same is if inner fracture edges exists, which are
    8445              :                                                                                 //      connected to two boundary vertices.
    8446              :                                                                                 //      Since we tried to remove those edges above, something went wrong.
    8447              :                                                                                 //      remove the temporary attachments and throw an error
    8448              : 
    8449              :                                                                                 UG_LOG("Tetraeder ECC Fehlt eine Loesung " << std::endl);
    8450            0 :                                                                                 detachMarkers();
    8451            0 :                                                                                 throw(UGError("Error in ExpandFractures3d Arte Stasi. Implementation Error."));
    8452              :                                                                                 return false;
    8453              :                                                                         }
    8454              :                                                                 }
    8455            0 :                                                                 else if( iv2 == indBasVrtx )
    8456              :                                                                 {
    8457            0 :                                                                         if(    ( m_aaVrtVecVol[sv] )[iv0]
    8458            0 :                                                                                 && ( m_aaVrtVecVol[sv] )[iv1]
    8459            0 :                                                                                 && ( m_aaVrtVecVol[sv] )[iv2]
    8460              :                                                                         )
    8461              :                                                                         {
    8462              :                                                                                 //      create a new prism
    8463              : //                                                                              expVol = *m_grid.create<Pyramid>(
    8464              : //                                                                                                              PyramidDescriptor(sv->vertex(iv1), sv->vertex(iv0),
    8465              : //                                                                                                                                              (m_aaVrtVecVol[sv])[iv2],
    8466              : //                                                                                                                                              (m_aaVrtVecVol[sv])[iv1],
    8467              : //                                                                                                                                              (m_aaVrtVecVol[sv])[iv0]));
    8468              : 
    8469            0 :                                                                                 expVol = *m_grid.create<Pyramid>(
    8470            0 :                                                                                                                 PyramidDescriptor(sv->vertex(iv0), sv->vertex(iv1),
    8471              :                                                                                                                         (m_aaVrtVecVol[sv])[iv1],
    8472              :                                                                                                                         (m_aaVrtVecVol[sv])[iv0],
    8473              :                                                                                                                         (m_aaVrtVecVol[sv])[iv2]));
    8474              : 
    8475              :                                                                         }
    8476              : //                                                                      else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8477              : //                                                                                       && ( m_aaVrtVecVol[sv] )[iv1]
    8478              : //                                                                      )
    8479              : //                                                                      {
    8480              : //                                                                              //      create a new Pyramid
    8481              : //                                                                              expVol = *m_grid.create<Pyramid>(
    8482              : //                                                                                                              PyramidDescriptor(sv->vertex(iv0), sv->vertex(iv1),
    8483              : //                                                                                                                      (m_aaVrtVecVol[sv])[iv1],
    8484              : //                                                                                                                      (m_aaVrtVecVol[sv])[iv0],
    8485              : //                                                                                                                      sv->vertex(iv2)));
    8486              : //                                                                      }
    8487              :                                                                         else if(    ( m_aaVrtVecVol[sv] )[iv1]
    8488            0 :                                                                                          && ( m_aaVrtVecVol[sv] )[iv2]
    8489              :                                                                         )
    8490              :                                                                         {
    8491              :                                                                                 //      create a new Pyramid
    8492            0 :                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8493            0 :                                                                                                                 TetrahedronDescriptor(sv->vertex(iv1),
    8494              :                                                                                                                         (m_aaVrtVecVol[sv])[iv2],
    8495            0 :                                                                                                                         (m_aaVrtVecVol[sv])[iv1],
    8496            0 :                                                                                                                         sv->vertex(iv0)));
    8497              :                                                                         }
    8498              :                                                                         else if(    (m_aaVrtVecVol[sv])[iv0]
    8499            0 :                                                                                          && (m_aaVrtVecVol[sv])[iv2]
    8500              :                                                                         )
    8501              :                                                                         {
    8502              :                                                                                 //      create a new Pyramid
    8503            0 :                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8504            0 :                                                                                                                 TetrahedronDescriptor(sv->vertex(iv0),
    8505              :                                                                                                                         (m_aaVrtVecVol[sv])[iv0],
    8506            0 :                                                                                                                         (m_aaVrtVecVol[sv])[iv2],
    8507            0 :                                                                                                                         sv->vertex(iv1)));
    8508              :                                                                         }
    8509              : //                                                                      else if( ( m_aaVrtVecVol[sv])[iv0] )
    8510              : //                                                                      {
    8511              : //                                                                              //      create a new Tetrahedron
    8512              : //                                                                              expVol = *m_grid.create<Tetrahedron>(
    8513              : //                                                                                                              TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8514              : //                                                                                                                                                       (m_aaVrtVecVol[sv])[iv0]));
    8515              : //                                                                      }
    8516              : //                                                                      else if( ( m_aaVrtVecVol[sv])[iv1] )
    8517              : //                                                                      {
    8518              : //                                                                              //      create a new Tetrahedron
    8519              : //                                                                              expVol = *m_grid.create<Tetrahedron>(
    8520              : //                                                                                                              TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8521              : //                                                                                                                                                       (m_aaVrtVecVol[sv])[iv1]));
    8522              : //                                                                      }
    8523              : //                                                                      else if( ( m_aaVrtVecVol[sv])[iv2] )
    8524              : //                                                                      {
    8525              : //                                                                              //      create a new Tetrahedron
    8526              : //                                                                              expVol = *m_grid.create<Tetrahedron>(
    8527              : //                                                                                                              TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8528              : //                                                                                                                                                       (m_aaVrtVecVol[sv])[iv2]));
    8529              : //                                                                      }
    8530              :                                                                         else
    8531              :                                                                         {
    8532              :                                                                                 //      Text from SR, still similar:
    8533              :                                                                                 //  this code-block should never be entered. If it is entered then
    8534              :                                                                                 //      we either selected the wrong faces (this shouldn't happen), or there
    8535              :                                                                                 //      are selected faces, which have fracture-boundary-vertices only.
    8536              :                                                                                 //      This is the same is if inner fracture edges exists, which are
    8537              :                                                                                 //      connected to two boundary vertices.
    8538              :                                                                                 //      Since we tried to remove those edges above, something went wrong.
    8539              :                                                                                 //      remove the temporary attachments and throw an error
    8540              : 
    8541              :                                                                                 UG_LOG("Tetraeder ECC Fehlt eine Loesung " << std::endl);
    8542            0 :                                                                                 detachMarkers();
    8543            0 :                                                                                 throw(UGError("Error in ExpandFractures3d Arte Stasi. Implementation Error."));
    8544              :                                                                                 return false;
    8545              :                                                                         }
    8546              : 
    8547              :                                                                 }
    8548              : 
    8549            0 :                                                                 if( belongstToEndingNotCuttingFacs )
    8550              :                                                                 {
    8551            0 :                                                                         if( expVol )
    8552              :                                                                         {
    8553            0 :                                                                                 UG_LOG("not cutting vol created at " << CalculateCenter(expVol, m_aaPos ) << std::endl );
    8554              : //                                                                              m_sh.assign_subset(expVol, m_sh.num_subsets());
    8555              :                                                                         }
    8556              :                                                                         else
    8557              :                                                                         {
    8558              :                                                                                 UG_LOG("was not able to create vol for not cutting " << std::endl);
    8559              :                                                                         }
    8560              :                                                                 }
    8561              :                                                         }
    8562              :                                                         else
    8563              :                                                         {
    8564              :                                                                 // test if face belongs to the closed faces
    8565              : 
    8566              :                                                                 std::pair<Face*,Face*> const & closedNeighbrs = ecfsi.spuckPairNeighbouredFractClosedManifEl();
    8567              : 
    8568              : 
    8569            0 :                                                                 if( closedNeighbrs.first == tFace || closedNeighbrs.second == tFace )
    8570              :                                                                 {
    8571              : 
    8572              :                                                                         // figure out the vertex that is not from the cut edge
    8573              : 
    8574              :                                                                         Vertex * freeVrtx = nullptr;
    8575              : 
    8576              :                                                                         // wasn das für ein Käse.....
    8577            0 :                                                                         for( IndexType vrtxInd = 0; vrtxInd < triangVrtxNum; vrtxInd++ )
    8578              : //                                                                      for( IndexType vrtxInd = 0; vrtxInd < sv->num_vertices(); vrtxInd++ )
    8579              :                                                                         {
    8580            0 :                                                                                 if( ! EdgeContains(cutEdge, tFace->vertex(vrtxInd)))
    8581            0 :                                                                                         freeVrtx = tFace->vertex(vrtxInd);
    8582              :                                                                         }
    8583              : 
    8584            0 :                                                                         if( freeVrtx == nullptr )
    8585              :                                                                         {
    8586              :                                                                                 UG_LOG("Immer noch null " << std::endl);
    8587            0 :                                                                                 UG_THROW("Immer noch null " << std::endl);
    8588              :                                                                         }
    8589              : 
    8590              : //                                                                      int freeVrtxInd = -1;
    8591              : //                                                                      int secondCutEdgVrtxInd = -1;
    8592              : //
    8593              : //                                                                      for( IndexType vrtxInd = 0; vrtxInd < sv->num_vertices(); vrtxInd++ )
    8594              : //                                                                      {
    8595              : //                                                                              if( ! EdgeContains(cutEdge, freeVrtx))
    8596              : //                                                                                      freeVrtxInd = vrtxInd;
    8597              : //
    8598              : //                                                                              if( secondVrtxCutEdge == secondVrtxCutEdge)
    8599              : //                                                                                      secondCutEdgVrtxInd = vrtxInd;
    8600              : //                                                                      }
    8601              : 
    8602              : 
    8603              :                                                                         // for the "pyramid", exclude the base Vertex
    8604              :                                                                         // for the other tetrahedron, exclude the shifted of the non-base of the cut edge
    8605              :                                                                         // i.e. of secondVrtxCutEdge
    8606              : 
    8607              : //                                                                      Vertex * vrtxNotFromCutEdge = tFace->vertex(freeVrtxInd);
    8608              : 
    8609              :                                                                         // relate iv0, iv1, iv2 to vrtxNotFromCutEdge, base
    8610              : 
    8611            0 :                                                                         if( iv0 == indBasVrtx )
    8612              :                                                                         {
    8613              : 
    8614            0 :                                                                                 if(    ( m_aaVrtVecVol[sv] )[iv0]
    8615            0 :                                                                                         && ( m_aaVrtVecVol[sv] )[iv1]
    8616            0 :                                                                                         && ( m_aaVrtVecVol[sv] )[iv2]
    8617              :                                                                                 )
    8618              :                                                                                 {
    8619            0 :                                                                                         expVol = *m_grid.create<Pyramid>(
    8620            0 :                                                                                                                         PyramidDescriptor(sv->vertex(iv1), sv->vertex(iv2),
    8621              :                                                                                                                                 (m_aaVrtVecVol[sv])[iv2],
    8622              :                                                                                                                                 (m_aaVrtVecVol[sv])[iv1],
    8623              :                                                                                                                                 ( m_aaVrtVecVol[sv] )[iv0]));
    8624              : 
    8625            0 :                                                                                         expVolTwo = *m_grid.create<Tetrahedron>(
    8626            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8627            0 :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv0]));
    8628              : 
    8629              :                                                                                 }
    8630              :                                                                                 else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8631            0 :                                                                                                  && ( m_aaVrtVecVol[sv] )[iv1]
    8632              :                                                                                 )
    8633              :                                                                                 {
    8634            0 :                                                                                         expVol = *m_grid.create<Tetrahedron>(
    8635            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), ( m_aaVrtVecVol[sv] )[iv0],
    8636              :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv1]));
    8637              : 
    8638              : 
    8639            0 :                                                                                         expVolTwo = *m_grid.create<Tetrahedron>(
    8640            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8641            0 :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv0]));
    8642              :                                                                                 }
    8643              : //                                                                              else if(    ( m_aaVrtVecVol[sv] )[iv1]
    8644              : //                                                                                      && ( m_aaVrtVecVol[sv] )[iv2]
    8645              : //                                                                              )
    8646              : //                                                                              {
    8647              : //
    8648              : //                                                                              }
    8649              :                                                                                 else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8650            0 :                                                                                         && ( m_aaVrtVecVol[sv] )[iv2]
    8651              :                                                                                 )
    8652              :                                                                                 {
    8653              : 
    8654            0 :                                                                                         expVol = *m_grid.create<Tetrahedron>(
    8655            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1),  ( m_aaVrtVecVol[sv] )[iv0],
    8656              :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv2]));
    8657              : 
    8658            0 :                                                                                         expVolTwo = *m_grid.create<Tetrahedron>(
    8659            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8660            0 :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv0]));
    8661              :                                                                                 } //
    8662            0 :                                                                                 else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8663              :                                                                                 )
    8664              :                                                                                 {
    8665              : 
    8666            0 :                                                                                         expVolTwo = *m_grid.create<Tetrahedron>(
    8667            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8668              :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv0]));
    8669              :                                                                                 } //
    8670              : 
    8671              : 
    8672              : 
    8673              :                                                                         }
    8674              : 
    8675            0 :                                                                         if( iv1 == indBasVrtx )
    8676              :                                                                         {
    8677              : 
    8678            0 :                                                                                 if(    ( m_aaVrtVecVol[sv] )[iv0]
    8679            0 :                                                                                         && ( m_aaVrtVecVol[sv] )[iv1]
    8680            0 :                                                                                         && ( m_aaVrtVecVol[sv] )[iv2]
    8681              :                                                                                 )
    8682              :                                                                                 {
    8683            0 :                                                                                         expVol = *m_grid.create<Pyramid>(
    8684            0 :                                                                                                                         PyramidDescriptor(sv->vertex(iv2), sv->vertex(iv0),
    8685              :                                                                                                                                 (m_aaVrtVecVol[sv])[iv0],
    8686              :                                                                                                                                 (m_aaVrtVecVol[sv])[iv2],
    8687              :                                                                                                                                 ( m_aaVrtVecVol[sv] )[iv1]));
    8688              : 
    8689            0 :                                                                                         expVolTwo = *m_grid.create<Tetrahedron>(
    8690            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8691            0 :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv1]));
    8692              : 
    8693              :                                                                                 }
    8694              :                                                                                 else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8695            0 :                                                                                         && ( m_aaVrtVecVol[sv] )[iv1]
    8696              :                                                                                 )
    8697              :                                                                                 {
    8698            0 :                                                                                         expVol = *m_grid.create<Tetrahedron>(
    8699            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), ( m_aaVrtVecVol[sv] )[iv1], sv->vertex(iv0),
    8700              :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv0]));
    8701              : 
    8702              : 
    8703            0 :                                                                                         expVolTwo = *m_grid.create<Tetrahedron>(
    8704            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8705            0 :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv1]));
    8706              : 
    8707              :                                                                                 }
    8708              :                                                                                 else if(    ( m_aaVrtVecVol[sv] )[iv1]
    8709            0 :                                                                                         && ( m_aaVrtVecVol[sv] )[iv2]
    8710              :                                                                                 )
    8711              :                                                                                 {
    8712            0 :                                                                                         expVol = *m_grid.create<Tetrahedron>(
    8713            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), ( m_aaVrtVecVol[sv] )[iv1], sv->vertex(iv0),
    8714              :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv2]));
    8715              : 
    8716            0 :                                                                                         expVolTwo = *m_grid.create<Tetrahedron>(
    8717            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8718            0 :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv1]));
    8719              : 
    8720              :                                                                                 }
    8721              : //                                                                              else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8722              : //                                                                                      && ( m_aaVrtVecVol[sv] )[iv2]
    8723              : //                                                                              )
    8724              : //                                                                              {
    8725              : //
    8726              : //                                                                              }
    8727            0 :                                                                                 else if(    ( m_aaVrtVecVol[sv] )[iv1]
    8728              :                                                                                 )
    8729              :                                                                                 {
    8730              : 
    8731            0 :                                                                                         expVolTwo = *m_grid.create<Tetrahedron>(
    8732            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8733              :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv1]));
    8734              : 
    8735              :                                                                                 }
    8736              : 
    8737              : 
    8738              :                                                                         }
    8739              : 
    8740            0 :                                                                         if( iv2 == indBasVrtx )
    8741              :                                                                         {
    8742              : 
    8743            0 :                                                                                 if(    ( m_aaVrtVecVol[sv] )[iv0]
    8744            0 :                                                                                         && ( m_aaVrtVecVol[sv] )[iv1]
    8745            0 :                                                                                         && ( m_aaVrtVecVol[sv] )[iv2]
    8746              :                                                                                 )
    8747              :                                                                                 {
    8748              : 
    8749            0 :                                                                                         expVol = *m_grid.create<Pyramid>(
    8750            0 :                                                                                                                         PyramidDescriptor(sv->vertex(iv0), sv->vertex(iv1),
    8751              :                                                                                                                                 (m_aaVrtVecVol[sv])[iv1],
    8752              :                                                                                                                                 (m_aaVrtVecVol[sv])[iv0],
    8753              :                                                                                                                                 ( m_aaVrtVecVol[sv] )[iv2]));
    8754              : 
    8755            0 :                                                                                         expVolTwo = *m_grid.create<Tetrahedron>(
    8756            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8757            0 :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv2]));
    8758              :                                                                                 }
    8759              : 
    8760              :         //                                                                      else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8761              :         //                                                                              && ( m_aaVrtVecVol[sv] )[iv1]
    8762              :         //                                                                      )
    8763              :         //                                                                      {
    8764              :         //
    8765              :         //                                                                      }
    8766              :                                                                                 else if(    ( m_aaVrtVecVol[sv] )[iv1]
    8767            0 :                                                                                         && ( m_aaVrtVecVol[sv] )[iv2]
    8768              :                                                                                 )
    8769              :                                                                                 {
    8770              : 
    8771            0 :                                                                                         expVol = *m_grid.create<Tetrahedron>(
    8772            0 :                                                                                                                         TetrahedronDescriptor(( m_aaVrtVecVol[sv] )[iv2], sv->vertex(iv1), sv->vertex(iv0),
    8773              :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv1]));
    8774              : 
    8775            0 :                                                                                         expVolTwo = *m_grid.create<Tetrahedron>(
    8776            0 :                                                                                                                         TetrahedronDescriptor( sv->vertex(iv1) , sv->vertex(iv1), sv->vertex(iv0),
    8777            0 :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv2]));
    8778              : 
    8779              :                                                                                 }
    8780              :                                                                                 else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8781            0 :                                                                                         && ( m_aaVrtVecVol[sv] )[iv2]
    8782              :                                                                                 )
    8783              :                                                                                 {
    8784            0 :                                                                                         expVol = *m_grid.create<Tetrahedron>(
    8785            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), ( m_aaVrtVecVol[sv] )[iv0],
    8786              :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv2]));
    8787              : 
    8788            0 :                                                                                         expVolTwo = *m_grid.create<Tetrahedron>(
    8789            0 :                                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8790            0 :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv2]));
    8791              :                                                                                 } //
    8792            0 :                                                                                 else if( ( m_aaVrtVecVol[sv] )[iv2]
    8793            0 :                                                                                 )
    8794              :                                                                                 {
    8795            0 :                                                                                         expVolTwo = *m_grid.create<Tetrahedron>(
    8796            0 :                                                                                                                         TetrahedronDescriptor( sv->vertex(iv1) , sv->vertex(iv1), sv->vertex(iv0),
    8797              :                                                                                                                                                                  (m_aaVrtVecVol[sv])[iv2]));
    8798              :                                                                                 }
    8799              : 
    8800              : 
    8801              : 
    8802              :                                                                         }
    8803              : 
    8804              :                                                                 }
    8805              : 
    8806              : 
    8807              :                                                                 std::vector<Face*> const & closedNotNeighbr = ecfsi.spuckVecClosedFracManifElNoNeighbr();
    8808              : 
    8809            0 :                                                                 for( Face * fac : closedNotNeighbr )
    8810              :                                                                 {
    8811            0 :                                                                         if( fac == tFace )
    8812              :                                                                         {
    8813            0 :                                                                                 if( iv0 == indBasVrtx )
    8814              :                                                                                 {
    8815              : 
    8816            0 :                                                                                         if(    ( m_aaVrtVecVol[sv] )[iv0]
    8817            0 :                                                                                                 && ( m_aaVrtVecVol[sv] )[iv1]
    8818            0 :                                                                                                 && ( m_aaVrtVecVol[sv] )[iv2]
    8819              :                                                                                         )
    8820              :                                                                                         {
    8821              : 
    8822            0 :                                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8823            0 :                                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8824              :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv0]));
    8825              : 
    8826            0 :                                                                                                 expVolTwo = *m_grid.create<Pyramid>(
    8827            0 :                                                                                                                                 PyramidDescriptor(sv->vertex(iv1), sv->vertex(iv2),
    8828              :                                                                                                                                         (m_aaVrtVecVol[sv])[iv2],
    8829              :                                                                                                                                         (m_aaVrtVecVol[sv])[iv1],
    8830            0 :                                                                                                                                         ( m_aaVrtVecVol[sv] )[iv0]));
    8831              : 
    8832              :                                                                                         }
    8833              :                                                                                         else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8834            0 :                                                                                                 && ( m_aaVrtVecVol[sv] )[iv1]
    8835              :                                                                                         )
    8836              :                                                                                         {
    8837            0 :                                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8838            0 :                                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8839              :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv0]));
    8840              : 
    8841            0 :                                                                                                 expVolTwo = *m_grid.create<Tetrahedron>(
    8842            0 :                                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), ( m_aaVrtVecVol[sv] )[iv0],
    8843            0 :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv1]));
    8844              : 
    8845              :                                                                                         }
    8846              : //                                                                                      else if(    ( m_aaVrtVecVol[sv] )[iv1]
    8847              : //                                                                                              && ( m_aaVrtVecVol[sv] )[iv2]
    8848              : //                                                                                      )
    8849              : //                                                                                      {
    8850              : //
    8851              : //                                                                                      }
    8852              : //                                                                                              && ( m_aaVrtVecVol[sv] )[iv2]
    8853              : //                                                                                      )
    8854              : //                                                                                      {
    8855              : //
    8856              : //                                                                                      }
    8857            0 :                                                                                         else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8858              :                                                                                         )
    8859              :                                                                                         {
    8860            0 :                                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8861            0 :                                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8862              :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv0]));
    8863              : 
    8864              : 
    8865              :                                                                                         }
    8866              : 
    8867              : 
    8868              : 
    8869              : 
    8870              :                                                                                 }
    8871              : 
    8872            0 :                                                                                 if( iv1 == indBasVrtx )
    8873              :                                                                                 {
    8874              : 
    8875            0 :                                                                                         if(    ( m_aaVrtVecVol[sv] )[iv0]
    8876            0 :                                                                                                 && ( m_aaVrtVecVol[sv] )[iv1]
    8877            0 :                                                                                                 && ( m_aaVrtVecVol[sv] )[iv2]
    8878              :                                                                                         )
    8879              :                                                                                         {
    8880            0 :                                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8881            0 :                                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8882              :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv1]));
    8883              : 
    8884            0 :                                                                                                 expVolTwo = *m_grid.create<Pyramid>(
    8885            0 :                                                                                                                                 PyramidDescriptor(sv->vertex(iv2), sv->vertex(iv0),
    8886              :                                                                                                                                         (m_aaVrtVecVol[sv])[iv0],
    8887              :                                                                                                                                         (m_aaVrtVecVol[sv])[iv2],
    8888            0 :                                                                                                                                         ( m_aaVrtVecVol[sv] )[iv1]));
    8889              : 
    8890              :                                                                                         }
    8891              :                                                                                         else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8892            0 :                                                                                                 && ( m_aaVrtVecVol[sv] )[iv1]
    8893              :                                                                                         )
    8894              :                                                                                         {
    8895            0 :                                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8896            0 :                                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8897              :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv1]));
    8898              : 
    8899            0 :                                                                                                 expVolTwo = *m_grid.create<Tetrahedron>(
    8900            0 :                                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2), ( m_aaVrtVecVol[sv] )[iv1], sv->vertex(iv0),
    8901            0 :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv0]));
    8902              : 
    8903              :                                                                                         }
    8904              :                                                                                         else if(    ( m_aaVrtVecVol[sv] )[iv1]
    8905            0 :                                                                                                 && ( m_aaVrtVecVol[sv] )[iv2]
    8906              :                                                                                         )
    8907              :                                                                                         {
    8908            0 :                                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8909            0 :                                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8910              :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv1]));
    8911              : 
    8912            0 :                                                                                                 expVolTwo = *m_grid.create<Tetrahedron>(
    8913            0 :                                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2), ( m_aaVrtVecVol[sv] )[iv1], sv->vertex(iv0),
    8914            0 :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv2]));
    8915              : 
    8916              :                                                                                         }
    8917              : //                                                                                      else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8918              : //                                                                                              && ( m_aaVrtVecVol[sv] )[iv2]
    8919              : //                                                                                      )
    8920              : //                                                                                      {
    8921              : //
    8922              : //                                                                                      }
    8923            0 :                                                                                         else if(    ( m_aaVrtVecVol[sv] )[iv1]
    8924              :                                                                                         )
    8925              :                                                                                         {
    8926            0 :                                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8927            0 :                                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8928              :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv1]));
    8929              : 
    8930              :                                                                                         }
    8931              : 
    8932              : 
    8933              :                                                                                 }
    8934              : 
    8935            0 :                                                                                 if( iv2 == indBasVrtx )
    8936              :                                                                                 {
    8937            0 :                                                                                         if(    ( m_aaVrtVecVol[sv] )[iv0]
    8938            0 :                                                                                                 && ( m_aaVrtVecVol[sv] )[iv1]
    8939            0 :                                                                                                 && ( m_aaVrtVecVol[sv] )[iv2]
    8940              :                                                                                         )
    8941              :                                                                                         {
    8942              : 
    8943            0 :                                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8944            0 :                                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8945              :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv2]));
    8946              : 
    8947            0 :                                                                                                 expVolTwo = *m_grid.create<Pyramid>(
    8948            0 :                                                                                                                                 PyramidDescriptor(sv->vertex(iv0), sv->vertex(iv1),
    8949              :                                                                                                                                         (m_aaVrtVecVol[sv])[iv1],
    8950              :                                                                                                                                         (m_aaVrtVecVol[sv])[iv0],
    8951            0 :                                                                                                                                         ( m_aaVrtVecVol[sv] )[iv2]));
    8952              : 
    8953              :                                                                                         }
    8954              :         //                                                                              else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8955              :         //                                                                                      && ( m_aaVrtVecVol[sv] )[iv1]
    8956              :         //                                                                              )
    8957              :         //                                                                              {
    8958              :         //
    8959              :         //                                                                              }
    8960              :                                                                                         else if(    ( m_aaVrtVecVol[sv] )[iv1]
    8961            0 :                                                                                                 && ( m_aaVrtVecVol[sv] )[iv2]
    8962              :                                                                                         )
    8963              :                                                                                         {
    8964            0 :                                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8965            0 :                                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8966              :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv2]));
    8967              : 
    8968            0 :                                                                                                 expVolTwo = *m_grid.create<Tetrahedron>(
    8969            0 :                                                                                                                                 TetrahedronDescriptor( ( m_aaVrtVecVol[sv] )[iv2], sv->vertex(iv1), sv->vertex(iv0),
    8970            0 :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv1]));
    8971              : 
    8972              :                                                                                         }
    8973              :                                                                                         else if(    ( m_aaVrtVecVol[sv] )[iv0]
    8974            0 :                                                                                                 && ( m_aaVrtVecVol[sv] )[iv2]
    8975              :                                                                                         )
    8976              :                                                                                         {
    8977            0 :                                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8978            0 :                                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8979              :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv2]));
    8980              : 
    8981            0 :                                                                                                 expVolTwo = *m_grid.create<Tetrahedron>(
    8982            0 :                                                                                                                                 TetrahedronDescriptor( ( m_aaVrtVecVol[sv] )[iv2], sv->vertex(iv1), sv->vertex(iv0),
    8983            0 :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv0]));
    8984              : 
    8985              :                                                                                         }       //
    8986            0 :                                                                                         else if(   ( m_aaVrtVecVol[sv] )[iv2]
    8987            0 :                                                                                         )
    8988              :                                                                                         {
    8989            0 :                                                                                                 expVol = *m_grid.create<Tetrahedron>(
    8990            0 :                                                                                                                                 TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    8991              :                                                                                                                                                                          (m_aaVrtVecVol[sv])[iv2]));
    8992              : 
    8993              : 
    8994              :                                                                                         }
    8995              : 
    8996              :                                                                                 }
    8997              : 
    8998              :                                                                         }
    8999              :                                                                 }
    9000              : 
    9001              : #if 0
    9002              : 
    9003              :                                                                 if(    ( m_aaVrtVecVol[sv] )[iv0]
    9004              :                                                                         && ( m_aaVrtVecVol[sv] )[iv1]
    9005              :                                                                         && ( m_aaVrtVecVol[sv] )[iv2]
    9006              :                                                                 )
    9007              :                                                                 {
    9008              :                                                                         //      create a new prism
    9009              :                                                                         expVol = *m_grid.create<Prism>(
    9010              :                                                                                                         PrismDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    9011              :                                                                                                                                         (m_aaVrtVecVol[sv])[iv2],
    9012              :                                                                                                                                         (m_aaVrtVecVol[sv])[iv1],
    9013              :                                                                                                                                         (m_aaVrtVecVol[sv])[iv0]));
    9014              :                                                                 }
    9015              :                                                                 else if(    ( m_aaVrtVecVol[sv] )[iv0]
    9016              :                                                                                  && ( m_aaVrtVecVol[sv] )[iv1]
    9017              :                                                                 )
    9018              :                                                                 {
    9019              :                                                                         //      create a new Pyramid
    9020              :                                                                         expVol = *m_grid.create<Pyramid>(
    9021              :                                                                                                         PyramidDescriptor(sv->vertex(iv0), sv->vertex(iv1),
    9022              :                                                                                                                 (m_aaVrtVecVol[sv])[iv1],
    9023              :                                                                                                                 (m_aaVrtVecVol[sv])[iv0],
    9024              :                                                                                                                 sv->vertex(iv2)));
    9025              :                                                                 }
    9026              :                                                                 else if(    ( m_aaVrtVecVol[sv] )[iv1]
    9027              :                                                                                  && ( m_aaVrtVecVol[sv] )[iv2]
    9028              :                                                                 )
    9029              :                                                                 {
    9030              :                                                                         //      create a new Pyramid
    9031              :                                                                         expVol = *m_grid.create<Pyramid>(
    9032              :                                                                                                         PyramidDescriptor(sv->vertex(iv1), sv->vertex(iv2),
    9033              :                                                                                                                 (m_aaVrtVecVol[sv])[iv2],
    9034              :                                                                                                                 (m_aaVrtVecVol[sv])[iv1],
    9035              :                                                                                                                 sv->vertex(iv0)));
    9036              :                                                                 }
    9037              :                                                                 else if(    (m_aaVrtVecVol[sv])[iv0]
    9038              :                                                                                  && (m_aaVrtVecVol[sv])[iv2]
    9039              :                                                                 )
    9040              :                                                                 {
    9041              :                                                                         //      create a new Pyramid
    9042              :                                                                         expVol = *m_grid.create<Pyramid>(
    9043              :                                                                                                         PyramidDescriptor(sv->vertex(iv2), sv->vertex(iv0),
    9044              :                                                                                                                 (m_aaVrtVecVol[sv])[iv0],
    9045              :                                                                                                                 (m_aaVrtVecVol[sv])[iv2],
    9046              :                                                                                                                 sv->vertex(iv1)));
    9047              :                                                                 }
    9048              :                                                                 else if( ( m_aaVrtVecVol[sv])[iv0] )
    9049              :                                                                 {
    9050              :                                                                         //      create a new Tetrahedron
    9051              :                                                                         expVol = *m_grid.create<Tetrahedron>(
    9052              :                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    9053              :                                                                                                                                                  (m_aaVrtVecVol[sv])[iv0]));
    9054              :                                                                 }
    9055              :                                                                 else if( ( m_aaVrtVecVol[sv])[iv1] )
    9056              :                                                                 {
    9057              :                                                                         //      create a new Tetrahedron
    9058              :                                                                         expVol = *m_grid.create<Tetrahedron>(
    9059              :                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    9060              :                                                                                                                                                  (m_aaVrtVecVol[sv])[iv1]));
    9061              :                                                                 }
    9062              :                                                                 else if( ( m_aaVrtVecVol[sv])[iv2] )
    9063              :                                                                 {
    9064              :                                                                         //      create a new Tetrahedron
    9065              :                                                                         expVol = *m_grid.create<Tetrahedron>(
    9066              :                                                                                                         TetrahedronDescriptor(sv->vertex(iv2), sv->vertex(iv1), sv->vertex(iv0),
    9067              :                                                                                                                                                  (m_aaVrtVecVol[sv])[iv2]));
    9068              :                                                                 }
    9069              :                                                                 else
    9070              :                                                                 {
    9071              :                                                                         //      Text from SR, still similar:
    9072              :                                                                         //  this code-block should never be entered. If it is entered then
    9073              :                                                                         //      we either selected the wrong faces (this shouldn't happen), or there
    9074              :                                                                         //      are selected faces, which have fracture-boundary-vertices only.
    9075              :                                                                         //      This is the same is if inner fracture edges exists, which are
    9076              :                                                                         //      connected to two boundary vertices.
    9077              :                                                                         //      Since we tried to remove those edges above, something went wrong.
    9078              :                                                                         //      remove the temporary attachments and throw an error
    9079              : 
    9080              :                                                                         UG_LOG("Tetraeder Fehlt eine Loesung " << std::endl);
    9081              :                                                                         detachMarkers();
    9082              :                                                                         throw(UGError("Error in ExpandFractures3d Arte Stasi. Implementation Error."));
    9083              :                                                                         return false;
    9084              :                                                                 }
    9085              : 
    9086              : 
    9087              : #endif
    9088              : 
    9089            0 :                                                         }
    9090              : 
    9091              : 
    9092              :                                                 }
    9093              :                                                 else
    9094              :                                                 {
    9095              :                                                         //      traditionally only tetrahedrons are supported. This section thus raises an error
    9096              :                                                         // Markus tries to implement also Hexahedra
    9097              :                 //                                                                      grid.detach_from_vertices(aVrtVec);
    9098              :                 //                                                              grid.detach_from_volumes(aVrtVec);
    9099              :                 //                                                      grid.detach_from_vertices(aAdjMarker);
    9100              :                 //                                                      grid.detach_from_edges(aAdjMarker);
    9101            0 :                                                         detachMarkers();
    9102            0 :                                                         throw(UGError("Incomplete implementation error in ExpandFractures3d Arte ending crossing clefts."));
    9103              :                                                         return false;
    9104              :                                                 }
    9105              : 
    9106            0 :                                                 if(expVol)
    9107              :                                                 {
    9108              : 
    9109            0 :                                                         IndexType newSubs = m_fracInfosBySubset.at(m_sh.get_subset_index(tFace)).newSubsetIndex;
    9110              : 
    9111            0 :                                                         subsOfNewVolumes.push_back( newSubs );
    9112              : 
    9113            0 :                                                         m_sh.assign_subset(expVol, newSubs);
    9114              : 
    9115            0 :                                                         newFractureVolumes.push_back(expVol);
    9116              :                                                 }
    9117              : 
    9118            0 :                                                 if(expVolTwo)
    9119              :                                                 {
    9120              : 
    9121            0 :                                                         IndexType newSubs = m_fracInfosBySubset.at(m_sh.get_subset_index(tFace)).newSubsetIndex;
    9122              : 
    9123            0 :                                                         subsOfNewVolumes.push_back( newSubs );
    9124              : 
    9125            0 :                                                         m_sh.assign_subset(expVolTwo, newSubs);
    9126              : 
    9127            0 :                                                         newFractureVolumes.push_back(expVolTwo);
    9128              :                                                 }
    9129              : 
    9130              :                                         }
    9131              :                                 }
    9132            0 :                         }
    9133            0 :                 }
    9134              :         }
    9135              : 
    9136              : 
    9137              :         return true;
    9138              : }
    9139              : 
    9140              : 
    9141              : } /* namespace ug */
        

Generated by: LCOV version 2.0-1