From 0f4ba7ea0553344f994549d7714f735ae2330057 Mon Sep 17 00:00:00 2001
From: Emilie Marchandise <emilie.marchandise@uclouvain.be>
Date: Thu, 10 Nov 2011 14:40:31 +0000
Subject: [PATCH] SplitMesh add elementary tag for split lines (2d) and
 faces(3d)

---
 Geo/GModel.cpp                                |   2 +
 Geo/MElementCut.cpp                           | 118 +++++++++++++-----
 contrib/DiscreteIntegration/Integration3D.cpp |   7 +-
 3 files changed, 93 insertions(+), 34 deletions(-)

diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index 14243e6d6c..c189f2e47d 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -1821,6 +1821,7 @@ GModel *GModel::buildCutGModel(gLevelset *ls, bool cutElem, bool saveTri)
 
   GModel *cutGM = buildCutMesh(this, ls, elements, vertexMap, physicals, cutElem);
 
+
   for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
     cutGM->_storeElementsInEntities(elements[i]);
   cutGM->_associateEntityWithMeshVertices();
@@ -1837,6 +1838,7 @@ GModel *GModel::buildCutGModel(gLevelset *ls, bool cutElem, bool saveTri)
     }
   }
 
+
   Msg::Info("Mesh cutting completed (%g s)", Cpu() - t1);
 
   return cutGM;
diff --git a/Geo/MElementCut.cpp b/Geo/MElementCut.cpp
index ab10028bd8..285642b492 100644
--- a/Geo/MElementCut.cpp
+++ b/Geo/MElementCut.cpp
@@ -558,10 +558,13 @@ static void elementSplitMesh(MElement *e, fullMatrix<double> &verticesLs,
                              std::map<int, std::vector<MElement*> > elements[10],
                              std::map<int, std::map<int, std::string> > physicals[4],
                              std::map<int, int> newElemTags[4],
-                             std::map<int, int> newPhysTags[4])
+                             std::map<int, int> newPhysTags[4],
+			     std::map<int, int> borderElemTags[2],
+			     std::map<int, int> borderPhysTags[2], 
+			     int gLsTag)
 {
   int elementary = ge->tag();
-  int eType = e->getTypeForMSH();
+  int eType = e->getType();
   std::vector<int> gePhysicals = ge->physicals;
 
   MElement *copy = e->copy(vertexMap, newParents, newDomains);
@@ -574,52 +577,60 @@ static void elementSplitMesh(MElement *e, fullMatrix<double> &verticesLs,
 
   //EMI : better for embedded dirichlet with smoothed properties
   //split according to values of vertices (keep +)
-  int lsTag = 1; //negative ls
-  for(int k = 0; k < e->getNumVertices(); k++){
-   double val = verticesLs(0, e->getVertex(k)->getIndex());
-   if (val > 0.0) { lsTag = -1; break; }
+  bool splitElem = false;
+  int lsTag =  (verticesLs(0, e->getVertex(0)->getIndex()) > 0.0) ? -1 : 1;
+  for(int k = 1; k < e->getNumVertices(); k++){
+    int lsTag2 = (verticesLs(0, e->getVertex(k)->getIndex()) > 0.0) ? -1: 1;
+    if (lsTag*lsTag2 < 0.0) {
+      lsTag = -1;
+      splitElem = true;
+      break;
+    } 
   }
+  // int lsTag = 1; //negative ls
+  // for(int k = 0; k < e->getNumVertices(); k++){
+  //  double val = verticesLs(0, e->getVertex(k)->getIndex());
+  //  if (val > 0.0) { lsTag = -1; break; }
+  // }
 
   switch (eType) {
-  case MSH_TET_4 :
-  case MSH_HEX_8 :
-  case MSH_PYR_5 :
-  case MSH_PRI_6 :
-  case MSH_POLYH_ :
+  case TYPE_TET :
+  case TYPE_HEX :
+  case TYPE_PYR :
+  case TYPE_PRI :
+  case TYPE_POLYH :
     {
       int reg = getElementaryTag(lsTag, elementary, newElemTags[3]);
       getPhysicalTag(lsTag, gePhysicals, newPhysTags[3]);
-      if(eType == MSH_TET_4)
+      if(eType == TYPE_TET)
         elements[4][reg].push_back(copy);
-      else if(eType == MSH_HEX_8)
+      else if(eType == TYPE_HEX)
         elements[5][reg].push_back(copy);
-      else if(eType == MSH_PRI_6)
+      else if(eType == TYPE_PRI)
         elements[6][reg].push_back(copy);
-      else if(eType == MSH_PYR_5)
+      else if(eType == TYPE_PYR)
         elements[7][reg].push_back(copy);
-      else if(eType == MSH_POLYH_)
+      else if(eType == TYPE_POLYH)
         elements[9][reg].push_back(copy);
       assignPhysicals(GM, gePhysicals, reg, 3, physicals, newPhysTags[3], lsTag);
     }
     break;
-  case MSH_TRI_3 :
-  case MSH_QUA_4 :
-  case MSH_POLYG_ :
-  case MSH_POLYG_B :
+  case TYPE_TRI :
+  case TYPE_QUA :
+  case TYPE_POLYG :
     {
       int reg = getElementaryTag(lsTag, elementary, newElemTags[2]);
       getPhysicalTag(lsTag, gePhysicals, newPhysTags[2]);
-      if(eType == MSH_TRI_3)
+      if(eType == TYPE_TRI)
         elements[2][reg].push_back(copy);
-      else if(eType == MSH_QUA_4)
+      else if(eType == TYPE_QUA)
         elements[3][reg].push_back(copy);
-      else if(eType == MSH_POLYG_ || eType == MSH_POLYG_B)
+      else if(eType == TYPE_POLYG)
         elements[8][reg].push_back(copy);
       assignPhysicals(GM, gePhysicals, reg, 2, physicals, newPhysTags[2], lsTag);
     }
     break;
-  case MSH_LIN_2 :
-  case MSH_LIN_B :
+  case TYPE_LIN :
     {
       int reg = getElementaryTag(lsTag, elementary, newElemTags[1]);
       getPhysicalTag(lsTag, gePhysicals, newPhysTags[1]);
@@ -627,7 +638,7 @@ static void elementSplitMesh(MElement *e, fullMatrix<double> &verticesLs,
       assignPhysicals(GM, gePhysicals, reg, 1, physicals, newPhysTags[1], lsTag);
     }
     break;
-  case MSH_PNT :
+  case TYPE_PNT :
     {
       int reg = getElementaryTag(lsTag, elementary, newElemTags[0]);
       getPhysicalTag(lsTag, gePhysicals, newPhysTags[0]);
@@ -639,6 +650,53 @@ static void elementSplitMesh(MElement *e, fullMatrix<double> &verticesLs,
     Msg::Error("This type of element cannot be split.");
     return;
   }
+
+  //create level set interface (pt in 1D, line in 2D or face in 3D)
+  if (splitElem && copy->getDim()==2){
+     for(int k = 0; k < copy->getNumEdges(); k++){
+      MEdge me  = copy->getEdge(k);
+      MVertex *v0 = me.getVertex(0);
+      MVertex *v1 = me.getVertex(1);
+      double val0 = verticesLs(0, v0->getIndex());
+      double val1 = verticesLs(0, v1->getIndex());
+      if (val0*val1 > 0.0 && val0 < 0.0) { 
+  	MLine *lin = new MLine(v0, v1); 
+   	getPhysicalTag(-1, gePhysicals, newPhysTags[1]);
+	int c = elements[1].count(gLsTag);
+        int reg = getBorderTag(gLsTag, c, newElemTags[1][0], borderElemTags[0]);
+        int physTag = (!gePhysicals.size()) ? 0 : getBorderTag(gLsTag, c, newPhysTags[1][0], borderPhysTags[0]);
+  	elements[1][reg].push_back(lin);
+	if(physTag) assignLsPhysical(GM, reg, 1, physicals, physTag, gLsTag);
+      }    
+    }
+  }
+  else if (splitElem && copy->getDim()==3){
+    for(int k = 0; k < copy->getNumFaces(); k++){
+      MFace mf  = copy->getFace(k);
+      bool sameSign = true;
+      double val0 = verticesLs(0,  mf.getVertex(0)->getIndex());
+      for (int j= 1; j< mf.getNumVertices(); j++){
+	double valj = verticesLs(0,  mf.getVertex(j)->getIndex());
+	if (val0*valj < 0.0){ sameSign = false; break;}
+      }
+      if (sameSign && val0 < 0.0) {
+	getPhysicalTag(-1, gePhysicals, newPhysTags[2]);
+	int c = elements[2].count(gLsTag) + elements[3].count(gLsTag) + elements[8].count(gLsTag);
+        int reg = getBorderTag(gLsTag, c, newElemTags[2][0], borderElemTags[1]);
+        int physTag = (!gePhysicals.size()) ? 0 : getBorderTag(gLsTag, c, newPhysTags[2][0], borderPhysTags[1]);
+	if(mf.getNumVertices() == 3){
+	  MTriangle *tri = new MTriangle(mf.getVertex(0), mf.getVertex(1), mf.getVertex(2));
+          elements[2][reg].push_back(tri);
+	}
+        else if(mf.getNumVertices() == 4){
+	  MQuadrangle *quad = new MQuadrangle(mf.getVertex(0), mf.getVertex(1), mf.getVertex(2), mf.getVertex(3));
+          elements[3][reg].push_back(quad);
+	}
+        if(physTag)  assignLsPhysical(GM, reg, 2, physicals, physTag, gLsTag);
+      }    
+     }
+  }
+
 }
 
 #if defined(HAVE_DINTEGRATION)
@@ -800,7 +858,6 @@ static void elementCutMesh(MElement *e, std::vector<gLevelset *> &RPN,
           isCut = (isCut || iC);
         }
       }
-
       MPolyhedron *p1 = NULL, *p2 = NULL;
       if(isCut) {
         std::vector<MTetrahedron*> poly[2];
@@ -1295,6 +1352,8 @@ GModel *buildCutMesh(GModel *gm, gLevelset *ls,
 
   std::map<MElement*, MElement*> newParents; //map<oldParent, newParent>
   std::map<MElement*, MElement*> newDomains; //map<oldDomain, newDomain>
+  std::map<int, int> borderElemTags[2]; //map<lsTag,elementary>[line=0,surface=1]
+  std::map<int, int> borderPhysTags[2]; //map<lstag,physical>[line=0,surface=1]
 
   //SplitMesh
   if(!cutElem) {
@@ -1303,7 +1362,8 @@ GModel *buildCutMesh(GModel *gm, gLevelset *ls,
         MElement *e = gmEntities[i]->getMeshElement(j);
         e->setVolumePositive();
         elementSplitMesh(e, verticesLs, gmEntities[i], gm, numEle, vertexMap, newParents,
-                         newDomains, elements, physicals, newElemTags, newPhysTags);
+                         newDomains, elements, physicals, newElemTags, newPhysTags, 
+			 borderElemTags, borderPhysTags, ls->getTag());
         cutGM->getMeshPartitions().insert(e->getPartition());
       }
     }
@@ -1312,8 +1372,6 @@ GModel *buildCutMesh(GModel *gm, gLevelset *ls,
 
   //CutMesh
   newVerticesContainer newVertices;
-  std::map<int, int> borderElemTags[2]; //map<lsTag,elementary>[line=0,surface=1]
-  std::map<int, int> borderPhysTags[2]; //map<lstag,physical>[line=0,surface=1]
   std::multimap<MElement*, MElement*> borders[2]; //multimap<domain,border>[polyg=0,polyh=1]
   DI_Point::Container cp;
   std::vector<DI_Line *> lines;
diff --git a/contrib/DiscreteIntegration/Integration3D.cpp b/contrib/DiscreteIntegration/Integration3D.cpp
index 4a31c0254b..a281fd0f27 100644
--- a/contrib/DiscreteIntegration/Integration3D.cpp
+++ b/contrib/DiscreteIntegration/Integration3D.cpp
@@ -873,11 +873,10 @@ void DI_Element::evalC (const double u, const double v, const double w, double *
   int nbV = nbVert() + nbMid();
   std::vector<double> s(nbV);
   ev[0] = 0; ev[1] = 0; ev[2] = 0;
-  getShapeFunctions (u, v, w, &s[0], order);
   for(int i = 0; i < nbV; i++){
-    ev[0] += x(i) * s[i];
-    ev[1] += y(i) * s[i];
-    ev[2] += z(i) * s[i];
+      ev[0] += x(i) * s[i];
+      ev[1] += y(i) * s[i];
+      ev[2] += z(i) * s[i];
   }
 }
 double DI_Element::evalLs (const double u, const double v, const double w, int iLs, int order) const{
-- 
GitLab