Skip to content
Snippets Groups Projects
Commit dfd86002 authored by Thomas Toulorge's avatar Thomas Toulorge
Browse files

Simplified fast curving (only 2D at the moment)

parent d2aea603
Branches
Tags
No related merge requests found
...@@ -55,304 +55,54 @@ namespace { ...@@ -55,304 +55,54 @@ namespace {
// Compute vertex -> element connectivity typedef std::map<MEdge, std::vector<MElement*>, Less_Edge> MEdgeVecMEltMap;
void calcVertex2Elements(int dim, GEntity *entity, typedef std::map<MFace, std::vector<MElement*>, Less_Face> MFaceVecMEltMap;
std::map<MVertex*, std::vector<MElement *> > &vertex2elements)
{
for (size_t i = 0; i < entity->getNumMeshElements(); ++i) {
MElement *element = entity->getMeshElement(i);
if (element->getDim() == dim)
for (int j = 0; j < element->getNumPrimaryVertices(); ++j)
vertex2elements[element->getVertex(j)].push_back(element);
}
}
// Given a starting vertex and a direction, find the next vertex in a column
MVertex *findVertFromDir(const std::map<MVertex*, std::vector<MElement*> > &vertex2elements,
MVertex *v0, MVertex *vExclude, const SVector3 &dir, double spLimit)
{
const std::vector<MElement*> &elts = (*vertex2elements.find(v0)).second; // All elements connected to vertex
MVertex *vFound = 0;
double spMax = 0.;
for (std::vector<MElement*>::const_iterator itEl = elts.begin(); itEl != elts.end(); ++itEl) // Loop over all elements
for (int i=0; i<(*itEl)->getNumEdges(); i++) { // Loop over all edges of each element
MEdge edge = (*itEl)->getEdge(i);
MVertex *vA = edge.getVertex(0), *vB = edge.getVertex(1), *vTmp;
if (v0 == vA) // Skip if edge unconnected to vertex...
if (vB == vExclude) continue; // ... or if connecting to preceding vertex
else vTmp = vB;
else if (v0 == vB)
if (vA == vExclude) continue;
else vTmp = vA;
else continue;
SVector3 tanVec = edge.tangent();
double sp = fabs(dot(tanVec, dir));
if ((sp > spMax) && (sp > spLimit)){ // Retain the edge giving max. dot product with normal
spMax = sp;
vFound = vTmp;
}
}
return vFound;
}
// Find a column of vertices starting with a given vertex
template<class bndType>
bool findColumn(const std::map<MVertex*, std::vector<MElement*> > &vertex2elements,
MVertex *baseVert, const SVector3 &norm,
const bndType &baseEd, std::vector<MVertex*> &col, int maxNumLayers)
{
static const double spMin = 0.866025404; // Threshold in cosine between 1st edge and normal
static const double spTol = 0.999; // Threshold in cosine between an edge and 1st edge
MVertex *vert = findVertFromDir(vertex2elements, baseVert, 0, norm, spMin);
if (!vert) { // If 1st normal edge not found...
vert = findVertFromDir(vertex2elements, baseVert, 0, baseEd.normal(), spMin); // ... tries normal to base edge/face
if (!vert) {
Msg::Warning("Could not find normal edge for vertex %i ", baseVert->getNum());
return false;
}
}
SVector3 firstEdgeDir(baseVert->point(), vert->point());
firstEdgeDir.normalize();
SVector3 dir(baseVert->point(), vert->point());
col.push_back(vert);
MVertex *oldVert = baseVert, *newVert;
for (int iLayer = 0; iLayer < maxNumLayers; iLayer++) {
newVert = findVertFromDir(vertex2elements, vert, oldVert, firstEdgeDir, spTol);
col.push_back(newVert); // Will add null pointer at the end, which is OK
if (!newVert) break;
oldVert = vert;
vert = newVert;
}
return (col.size() > 1);
}
// Add normal to edge/face to data structure for vertices
void addNormVertEl(MElement *el, const SVector3 &norm,
std::map<MVertex*, SVector3> &normVert)
{
for(unsigned int iV = 0; iV<el->getNumVertices(); iV++) {
MVertex *vert = el->getVertex(iV);
std::pair<std::map<MVertex*, SVector3>::iterator, bool> insNorm = // If nothing for vert...
normVert.insert(std::pair<MVertex*, SVector3>(vert, SVector3(0.))); // ... create zero normal
insNorm.first->second += norm; // Cumulate normals
}
}
// Compute normals to boundary edges/faces and store them per vertex // Compute edge -> element connectivity (for 2D elements)
void buildNormals(const std::map<MVertex*, std::vector<MElement*> > &vertex2elements, void calcEdge2Elements(GEntity *entity, MEdgeVecMEltMap &ed2el)
const std::multimap<GEntity*,GEntity*> &entities, const FastCurvingParameters &p,
std::map<GEntity*, std::map<MVertex*, SVector3> > &normVertEnt)
{ {
normVertEnt.clear(); for (size_t iEl = 0; iEl < entity->getNumMeshElements(); iEl++) {
for (std::multimap<GEntity*,GEntity*>::const_iterator itBE = entities.begin(); MElement *elt = entity->getMeshElement(iEl);
itBE != entities.end(); itBE++) { // Loop over model entities if (elt->getDim() == 2)
GEntity* const &bndEnt = itBE->second; for (int iEdge = 0; iEdge < elt->getNumEdges(); iEdge++) {
std::map<MVertex*, SVector3> &normVert = normVertEnt[bndEnt]; ed2el[elt->getEdge(iEdge)].push_back(elt);
if (bndEnt->dim() == 1) {
GEdge *ge = bndEnt->cast2Edge();
for(unsigned int iEl = 0; iEl<ge->lines.size(); iEl++) {
MLine* const &line = ge->lines[iEl];
SVector3 norm = line->getEdge(0).normal();
addNormVertEl(line, norm, normVert);
}
}
else if (bndEnt->dim() == 2) {
GFace *gf = bndEnt->cast2Face();
for(unsigned int iEl = 0; iEl<gf->triangles.size(); iEl++) {
MTriangle* const &tri = gf->triangles[iEl];
SVector3 norm = tri->getFace(0).normal();
addNormVertEl(tri, norm, normVert);
}
for(unsigned int iEl = 0; iEl<gf->quadrangles.size(); iEl++) {
MQuadrangle* const &quad = gf->quadrangles[iEl];
SVector3 norm = quad->getFace(0).normal();
addNormVertEl(quad, norm, normVert);
} }
} }
for (std::map<MVertex*, SVector3> ::iterator itNV = // Re-normalize for each geom. entity
normVert.begin(); itNV != normVert.end(); itNV++)
itNV->second.normalize();
}
} }
// Get first domain element for a given boundary edge // Compute face -> element connectivity (for 3D elements)
MElement *getFirstEl(const std::map<MVertex*, std::vector<MElement*> > &vertex2elements, void calcFace2Elements(GEntity *entity, MFaceVecMEltMap &face2el)
const MEdge &baseEd)
{ {
MVertex *vb0 = baseEd.getVertex(0), *vb1 = baseEd.getVertex(1); for (size_t iEl = 0; iEl < entity->getNumMeshElements(); iEl++) {
MElement *elt = entity->getMeshElement(iEl);
const std::vector<MElement*> &nb0 = vertex2elements.find(vb0)->second; if (elt->getDim() == 3)
const std::vector<MElement*> &nb1 = vertex2elements.find(vb1)->second; for (int iFace = 0; iFace < elt->getNumFaces(); iFace++)
MElement *firstEl = 0; face2el[elt->getFace(iFace)].push_back(elt);
for (int iEl=0; iEl<nb0.size(); iEl++) {
if (find(nb1.begin(), nb1.end(), nb0[iEl]) != nb1.end()) {
firstEl = nb0[iEl];
break;
} }
} }
return firstEl;
}
// Get intersection of two vectors of MElement*
void intersect(const std::vector<MElement*> &vi1, const std::vector<MElement*> &vi2,
std::vector<MElement*> &vo)
{
vo.clear();
for (std::vector<MElement*>::const_iterator it = vi1.begin(); it != vi1.end(); it++)
if (std::find(vi2.begin(), vi2.end(), *it) != vi2.end())
vo.push_back(*it);
}
// Get first domain element for a given boundary face // Get the face index of an element given a MFace
MElement *getFirstEl(const std::map<MVertex*, std::vector<MElement*> > &vertex2elements, inline int getElementFace(const MFace &face, MElement *el)
const MFace &baseFace)
{ {
MVertex *vb0 = baseFace.getVertex(0), *vb1 = baseFace.getVertex(1); for (int iFace = 0; iFace < el->getNumFaces(); iFace++)
if (el->getFace(iFace) == face) return iFace;
// Get elements common to vertices 0 and 1 return -1;
const std::vector<MElement*> &nb0 = vertex2elements.find(vb0)->second;
const std::vector<MElement*> &nb1 = vertex2elements.find(vb1)->second;
std::vector<MElement*> nb01;
intersect(nb0, nb1, nb01);
if (nb01.empty()) return 0;
if (nb01.size() == 1) return nb01.front();
// Get elements common to vertices 0, 1 and 2
MVertex *vb2 = baseFace.getVertex(2);
const std::vector<MElement*> &nb2 = vertex2elements.find(vb2)->second;
std::vector<MElement*> nb012;
intersect(nb01, nb2, nb012);
if (nb012.empty()) return 0;
if (nb012.size() == 1) return nb012.front();
// If quad, get elements common to all 4 vertices
if (baseFace.getNumVertices() == 4) {
MVertex *vb3 = baseFace.getVertex(3);
const std::vector<MElement*> &nb3 = vertex2elements.find(vb3)->second;
std::vector<MElement*> nb0123;
intersect(nb012, nb3, nb0123);
if (nb0123.empty()) return 0;
if (nb0123.size() == 1) return nb0123.front();
}
// Too many elements, return error
return 0;
} }
// Get base vertices (in order of first element) for an edge // Get the edge index of an element given a MEdge
bool getBaseVertices(const MEdge &baseEd, MElement *firstEl, std::vector<MVertex*> &baseVert) inline int getElementEdge(const MEdge &edge, MElement *el)
{ {
baseVert.clear(); for (int iEdge = 0; iEdge < el->getNumEdges(); iEdge++)
for (int iEd = 0; iEd < firstEl->getNumEdges(); iEd++) if (el->getEdge(iEdge) == edge) return iEdge;
if (firstEl->getEdge(iEd) == baseEd) return -1;
firstEl->getEdgeVertices(iEd, baseVert);
if (baseVert.empty()) {
Msg::Error("Base edge vertices not found in getBaseVertices");
return false;
}
else
return true;
}
// Get base vertices (in order of first element) for a face
bool getBaseVertices(const MFace &baseFace, MElement *firstEl, std::vector<MVertex*> &baseVert)
{
baseVert.clear();
for (int iFace = 0; iFace < firstEl->getNumFaces(); iFace++)
if (firstEl->getFace(iFace) == baseFace)
firstEl->getFaceVertices(iFace, baseVert);
if (baseVert.empty()) {
Msg::Error("Base face vertices not found in getBaseVertices");
return false;
}
else
return true;
}
// Top primary vertices (in order corresponding to the primary base vertices)
template<class bndType>
bool getTopPrimVertices(std::map<MVertex*, std::vector<MElement *> > &vertex2elements,
const std::map<MVertex*, SVector3> &normVert,
const bndType &baseBnd, int maxNumLayers,
const std::vector<MVertex*> &baseVert,
std::vector<MVertex*> &topPrimVert)
{
int nbVert = baseBnd.getNumVertices();
topPrimVert = std::vector<MVertex*>(nbVert);
for(int i = 0; i < nbVert; i++) {
std::map<MVertex*, SVector3>::const_iterator itNorm = normVert.find(baseVert[i]);
if (itNorm == normVert.end()) {
Msg::Error("Normal to vertex not found in getTopPrimVertices");
itNorm = normVert.begin();
}
std::vector<MVertex*> col;
bool colFound = findColumn(vertex2elements, baseVert[i], itNorm->second,
baseBnd, col, maxNumLayers);
if (!colFound) return false; // Give up element if column not found
topPrimVert[i] = *(col.end()-2);
}
return true;
}
// Get blob of elements encompassed by a given meta-element
// FIXME: Implement 3D
void get2DBLBlob(const std::map<MVertex*, std::vector<MElement*> > &vertex2elements,
MElement *firstEl, const MetaEl *supEl, std::set<MElement*> &blob)
{
static const int maxDepth = 100;
typedef std::list<MElement*> elLType;
typedef std::vector<MElement*> elVType;
// Build blob by looping over layers of elements (assuming that if an el is too far, its neighbours are too far as well)
blob.clear();
elLType currentLayer, lastLayer;
blob.insert(firstEl);
lastLayer.push_back(firstEl);
for (int d = 0; d < maxDepth; ++d) { // Loop over layers
currentLayer.clear();
for (elLType::iterator it = lastLayer.begin(); it != lastLayer.end(); ++it) { // Loop over elements of last layer
for (int i = 0; i < (*it)->getNumPrimaryVertices(); ++i) {
const elVType &neighbours = vertex2elements.find((*it)->getVertex(i))->second;
for (elVType::const_iterator itN = neighbours.begin(); itN != neighbours.end(); ++itN) { // Loop over neighbours of last layer
SPoint3 p = (*itN)->barycenter(true);
if (supEl->isPointIn(p)) // Add neighbour to blob if inside test element
if (blob.insert(*itN).second) currentLayer.push_back(*itN); // Add to current layer if new in blob
}
}
}
if (currentLayer.empty()) break; // Finished if no new element in blob
lastLayer = currentLayer;
}
} }
...@@ -383,7 +133,8 @@ inline void insertIfCurved(MElement *el, std::list<MElement*> &bndEl) ...@@ -383,7 +133,8 @@ inline void insertIfCurved(MElement *el, std::list<MElement*> &bndEl)
const int dim = el->getDim(); const int dim = el->getDim();
// Compute unit normal to straight edge/face // Compute unit normal to straight edge/face
SVector3 normal = (dim == 1) ? el->getEdge(0).normal() : el->getFace(0).normal(); SVector3 normal = (dim == 1) ? el->getEdge(0).normal() :
el->getFace(0).normal();
// Get functional spaces // Get functional spaces
const nodalBasis *lagBasis = el->getFunctionSpace(); const nodalBasis *lagBasis = el->getFunctionSpace();
...@@ -412,6 +163,102 @@ inline void insertIfCurved(MElement *el, std::list<MElement*> &bndEl) ...@@ -412,6 +163,102 @@ inline void insertIfCurved(MElement *el, std::list<MElement*> &bndEl)
} }
void getOppositeEdge(MElement *el, const MEdge &elBaseEd, MEdge &elTopEd,
double &edLenMin, double &edLenMax)
{
static const double BIG = 1e300;
const int iElBaseEd = getElementEdge(elBaseEd, el);
edLenMin = BIG;
edLenMax = -BIG;
MEdge elMaxEd;
// Look for largest edge except base one
for (int iElEd = 0; iElEd < el->getNumEdges(); iElEd++) {
if (iElEd != iElBaseEd) {
MEdge edTest = el->getEdge(iElEd);
double edLenTest = edTest.length();
if (edLenTest < edLenMin) edLenMin = edLenTest;
if (edLenTest > edLenMax) {
edLenMax = edLenTest;
elMaxEd = edTest;
}
}
}
// Build top edge from max edge (with right orientation)
bool sameOrient = false;
if (el->getType() == TYPE_TRI) { // Triangle: look for common vertex
sameOrient = (elBaseEd.getVertex(0) == elMaxEd.getVertex(0));
}
else { // Quad: look for edge between base and top vert.
MEdge sideEdTest(elBaseEd.getVertex(0), elMaxEd.getVertex(0));
for (int iElEd = 0; iElEd < el->getNumEdges(); iElEd++)
if (el->getEdge(iElEd) == sideEdTest) {
sameOrient = true;
break;
}
}
if (sameOrient) elTopEd = elMaxEd;
else elTopEd = MEdge(elMaxEd.getVertex(1), elMaxEd.getVertex(0));
}
bool getColumn2D(MEdgeVecMEltMap &ed2el,
int maxNumLayers, const MEdge &baseEd,
std::vector<MVertex*> &baseVert,
std::vector<MVertex*> &topPrimVert,
std::vector<MElement*> &blob)
{
static const double tol = 2.;
// Get first element and base vertices
std::vector<MElement*> firstElts = ed2el[baseEd];
if (firstElts.size() != 1) {
Msg::Error("%i edge(s) found for edge (%i, %i)", firstElts.size(),
baseEd.getVertex(0)->getNum(), baseEd.getVertex(1)->getNum());
return false;
}
MElement *el = firstElts[0];
const int iFirstElEd = getElementEdge(baseEd, el);
el->getEdgeVertices(iFirstElEd, baseVert);
MEdge elBaseEd(baseVert[0], baseVert[1]);
MEdge elTopEd;
// Sweep column upwards by choosing largest edges in each element
for (int iLayer = 0; iLayer < maxNumLayers; iLayer++) {
double edLenMin, edLenMax;
getOppositeEdge(el, elBaseEd, elTopEd, edLenMin, edLenMax);
if (edLenMax < edLenMin*tol) break;
blob.push_back(el);
std::vector<MElement*> newElts = ed2el[elTopEd];
el = (newElts[0] == el) ? newElts[1] : newElts[0];
elBaseEd = elTopEd;
}
// TODO: improve by taking all vertices?
topPrimVert.resize(2);
topPrimVert[0] = elBaseEd.getVertex(0);
topPrimVert[1] = elBaseEd.getVertex(1);
return true;
}
// TODO: Implement 3D
bool getColumn3D(MFaceVecMEltMap &face2el,
int maxNumLayers, const MFace &baseFace,
std::vector<MVertex*> &baseVert,
std::vector<MVertex*> &topPrimVert,
std::vector<MElement*> &blob)
{
return true;
}
class DbgOutput { class DbgOutput {
public: public:
void addMetaEl(MetaEl &mEl) { void addMetaEl(MetaEl &mEl) {
...@@ -455,9 +302,7 @@ private: ...@@ -455,9 +302,7 @@ private:
// Curve elements adjacent to a boundary model entity void curveMeshFromBnd(MEdgeVecMEltMap &ed2el, MFaceVecMEltMap &face2el,
void curveMeshFromBnd(std::map<MVertex*, std::vector<MElement *> > &vertex2elements,
const std::map<MVertex*, SVector3> &normVert,
GEntity *bndEnt, FastCurvingParameters &p) GEntity *bndEnt, FastCurvingParameters &p)
{ {
// Build list of bnd. elements to consider // Build list of bnd. elements to consider
...@@ -475,7 +320,8 @@ void curveMeshFromBnd(std::map<MVertex*, std::vector<MElement *> > &vertex2eleme ...@@ -475,7 +320,8 @@ void curveMeshFromBnd(std::map<MVertex*, std::vector<MElement *> > &vertex2eleme
insertIfCurved(gFace->quadrangles[i], bndEl); insertIfCurved(gFace->quadrangles[i], bndEl);
} }
else else
Msg::Error("Cannot treat model entity %i of dim %i", bndEnt->tag(), bndEnt->dim()); Msg::Error("Cannot treat model entity %i of dim %i", bndEnt->tag(),
bndEnt->dim());
DbgOutput dbgOut; DbgOutput dbgOut;
...@@ -484,19 +330,16 @@ void curveMeshFromBnd(std::map<MVertex*, std::vector<MElement *> > &vertex2eleme ...@@ -484,19 +330,16 @@ void curveMeshFromBnd(std::map<MVertex*, std::vector<MElement *> > &vertex2eleme
itBE != bndEl.end(); itBE++) { // Loop over bnd. elements itBE != bndEl.end(); itBE++) { // Loop over bnd. elements
const int bndType = (*itBE)->getType(); const int bndType = (*itBE)->getType();
int metaElType; int metaElType;
bool foundVert; bool foundCol;
MElement *firstEl = 0;
std::vector<MVertex*> baseVert, topPrimVert; std::vector<MVertex*> baseVert, topPrimVert;
std::vector<MElement*> blob;
if (bndType == TYPE_LIN) { // 1D boundary? if (bndType == TYPE_LIN) { // 1D boundary?
MVertex *vb0 = (*itBE)->getVertex(0); MVertex *vb0 = (*itBE)->getVertex(0);
MVertex *vb1 = (*itBE)->getVertex(1); MVertex *vb1 = (*itBE)->getVertex(1);
metaElType = TYPE_QUA; metaElType = TYPE_QUA;
MEdge baseEd(vb0, vb1); MEdge baseEd(vb0, vb1);
firstEl = getFirstEl(vertex2elements, baseEd); foundCol = getColumn2D(ed2el, p.maxNumLayers, baseEd, baseVert,
foundVert = getBaseVertices(baseEd, firstEl, baseVert); topPrimVert, blob);
if (!foundVert) continue; // Skip bnd. el. if base vertices not found
foundVert = getTopPrimVertices(vertex2elements, normVert, baseEd,
p.maxNumLayers, baseVert, topPrimVert);
} }
else { // 2D boundary else { // 2D boundary
MVertex *vb0 = (*itBE)->getVertex(0); MVertex *vb0 = (*itBE)->getVertex(0);
...@@ -512,28 +355,19 @@ void curveMeshFromBnd(std::map<MVertex*, std::vector<MElement *> > &vertex2eleme ...@@ -512,28 +355,19 @@ void curveMeshFromBnd(std::map<MVertex*, std::vector<MElement *> > &vertex2eleme
metaElType = TYPE_PRI; metaElType = TYPE_PRI;
} }
MFace baseFace(vb0, vb1, vb2, vb3); MFace baseFace(vb0, vb1, vb2, vb3);
firstEl = getFirstEl(vertex2elements, baseFace); foundCol = getColumn3D(face2el, p.maxNumLayers, baseFace, baseVert,
if (!firstEl) { topPrimVert, blob);
Msg::Error("Did not find first domain element for boundary element %i", }
(*itBE)->getNum()); if (!foundCol) continue; // Skip bnd. el. if top vertices not found
continue; int order = blob[0]->getPolynomialOrder();
}
foundVert = getBaseVertices(baseFace, firstEl, baseVert);
if (!foundVert) continue; // Skip bnd. el. if base vertices not found
foundVert = getTopPrimVertices(vertex2elements, normVert,
baseFace, p.maxNumLayers,
baseVert, topPrimVert);
}
if (!foundVert) continue; // Skip bnd. el. if top vertices not found
int order = firstEl->getPolynomialOrder();
MetaEl metaEl(metaElType, order, baseVert, topPrimVert); MetaEl metaEl(metaElType, order, baseVert, topPrimVert);
dbgOut.addMetaEl(metaEl); dbgOut.addMetaEl(metaEl);
std::set<MElement*> blob; for (int iEl = 0; iEl < blob.size(); iEl++) {
get2DBLBlob(vertex2elements, firstEl, &metaEl, blob); // TODO: Implement for 3D MElement *&elt = blob[iEl];
for (std::set<MElement*>::iterator itE = blob.begin(); itE != blob.end(); ++itE) { makeStraight(elt, movedVert);
makeStraight(*itE, movedVert); for (int iV = elt->getNumPrimaryVertices();
for (int i = (*itE)->getNumPrimaryVertices(); i < (*itE)->getNumVertices(); ++i) { // Loop over HO vert. of each el. in blob iV < elt->getNumVertices(); ++iV) { // Loop over HO vert. of each el. in blob
MVertex* vert = (*itE)->getVertex(i); MVertex* vert = elt->getVertex(iV);
if (movedVert.find(vert) == movedVert.end()) { // Try to move vert. not already moved if (movedVert.find(vert) == movedVert.end()) { // Try to move vert. not already moved
double xyzS[3] = {vert->x(), vert->y(), vert->z()}, xyzC[3]; double xyzS[3] = {vert->x(), vert->y(), vert->z()}, xyzC[3];
if (metaEl.straightToCurved(xyzS,xyzC)) { if (metaEl.straightToCurved(xyzS,xyzC)) {
...@@ -565,9 +399,11 @@ void HighOrderMeshFastCurving(GModel *gm, FastCurvingParameters &p) ...@@ -565,9 +399,11 @@ void HighOrderMeshFastCurving(GModel *gm, FastCurvingParameters &p)
// Compute vert. -> elt. connectivity // Compute vert. -> elt. connectivity
Msg::Info("Computing connectivity..."); Msg::Info("Computing connectivity...");
std::map<MVertex*, std::vector<MElement *> > vertex2elements; MEdgeVecMEltMap ed2el;
MFaceVecMEltMap face2el;
for (int iEnt = 0; iEnt < allEntities.size(); ++iEnt) for (int iEnt = 0; iEnt < allEntities.size(); ++iEnt)
calcVertex2Elements(p.dim, allEntities[iEnt], vertex2elements); if (p.dim == 2) calcEdge2Elements(allEntities[iEnt], ed2el);
else calcFace2Elements(allEntities[iEnt], face2el);
// Build multimap of each geometric entity to its boundaries // Build multimap of each geometric entity to its boundaries
std::multimap<GEntity*,GEntity*> entities; std::multimap<GEntity*,GEntity*> entities;
...@@ -578,17 +414,12 @@ void HighOrderMeshFastCurving(GModel *gm, FastCurvingParameters &p) ...@@ -578,17 +414,12 @@ void HighOrderMeshFastCurving(GModel *gm, FastCurvingParameters &p)
entities.insert(std::pair<GEntity*,GEntity*>(dummy, entity)); entities.insert(std::pair<GEntity*,GEntity*>(dummy, entity));
} }
// Build normals to base vertices
std::map<GEntity*, std::map<MVertex*, SVector3> > normVertEnt; // Normal to each vertex for each geom. entity
buildNormals(vertex2elements, entities, p, normVertEnt);
// Loop over geometric entities // Loop over geometric entities
for (std::multimap<GEntity*,GEntity*>::iterator itBE = entities.begin(); for (std::multimap<GEntity*,GEntity*>::iterator itBE = entities.begin();
itBE != entities.end(); itBE++) { itBE != entities.end(); itBE++) {
GEntity *domEnt = itBE->first, *bndEnt = itBE->second; GEntity *domEnt = itBE->first, *bndEnt = itBE->second;
Msg::Info("Curving elements for boundary entity %d...", bndEnt->tag()); Msg::Info("Curving elements for boundary entity %d...", bndEnt->tag());
std::map<MVertex*, SVector3> &normVert = normVertEnt[bndEnt]; curveMeshFromBnd(ed2el, face2el, bndEnt, p);
curveMeshFromBnd(vertex2elements, normVert, bndEnt, p);
} }
double t2 = Cpu(); double t2 = Cpu();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment