6#include <apfDynamicVector.h>
7#include <apfCavityOp.h>
12#include <samElementCount.h>
16static void SmoothField(apf::Field *
f);
17void gradeAnisoMesh(apf::Mesh* m,
double gradingFactor,PCU_t PCUObj);
18void gradeAspectRatio(apf::Mesh* m,
int idx,
double gradingFactor,PCU_t PCUObj);
22static double isotropicFormula(
double phi,
double dphi,
double verr,
double hmin,
double hmax,
double phi_s = 0,
double epsFact = 0)
25 double dphi_size_factor;
27 if (fabs(phi_s) < (epsFact*7.5) * hmin)
33static void setSizeField(apf::Mesh2 *m,apf::MeshEntity *vertex,
double h,apf::MeshTag *marker,apf::Field* sizeField,PCU_t PCUObj)
37 if(m->hasTag(vertex,marker))
41 h_new = std::min(h,apf::getScalar(sizeField,vertex,0));
46 m->setIntTag(vertex,marker,&newMark);
48 apf::setScalar(sizeField,vertex,0,h_new);
51 if(!m->isOwned(vertex))
54 m->getRemotes(vertex,remotes);
55 int owningPart=m->getOwner(vertex);
56 PCU_COMM_PACK(PCUObj, owningPart, remotes[owningPart]);
57 PCU_COMM_PACK(PCUObj, owningPart, h_new);
64 size_iso = apf::createLagrangeField(m,
"proteus_size", apf::SCALAR, 1);
66 apf::MeshIterator *it = m->begin(0);
68 while ((ent = m->iterate(it)))
70 int modelTag = m->getModelTag(m->toModel(ent));
77 apf::setScalar(size_iso,ent,0,sizeDesired);
88 if(m->findField(
"interfaceBand"))
89 apf::destroyField(m->findField(
"interfaceBand"));
91 apf::Field* interfaceBand = apf::createLagrangeField(m,
"interfaceBand", apf::SCALAR, 1);
92 apf::Field *phif = m->findField(
"phi");
95 apf::MeshTag* vertexMarker = m->createIntTag(
"vertexMarker",1);
96 apf::MeshIterator *it = m->begin(1);
97 apf::MeshEntity *edge;
101 PCU_Comm_Begin(PCUObj);
102 while ((edge = m->iterate(it)))
104 apf::Adjacent edge_adjVerts;
105 m->getAdjacent(edge,0,edge_adjVerts);
106 apf::MeshEntity *vertex1 = edge_adjVerts[0];
107 apf::MeshEntity *vertex2 = edge_adjVerts[1];
108 double phi1 = apf::getScalar(phif,vertex1,0);
109 double phi2 = apf::getScalar(phif,vertex2,0);
111 if(std::fabs(phi1)>L_band)
113 if(std::fabs(phi2)>L_band)
116 if(caseNumber==1 || caseNumber == 2)
118 setSizeField(m,vertex1,
hPhi,vertexMarker,interfaceBand,PCUObj);
119 setSizeField(m,vertex2,
hPhi,vertexMarker,interfaceBand,PCUObj);
125 setSizeField(m,vertex1,
hPhi,vertexMarker,interfaceBand,PCUObj);
126 setSizeField(m,vertex2,
hPhi,vertexMarker,interfaceBand,PCUObj);
130 setSizeField(m,vertex1,
hmax,vertexMarker,interfaceBand,PCUObj);
131 setSizeField(m,vertex2,
hmax,vertexMarker,interfaceBand,PCUObj);
137 PCU_Comm_Send(PCUObj);
140 apf::MeshEntity *ent;
142 while(PCU_Comm_Receive(PCUObj))
145 PCU_COMM_UNPACK(PCUObj, ent);
146 PCU_COMM_UNPACK(PCUObj, h_received);
148 double h_current = apf::getScalar(interfaceBand,ent,0);
149 double h_final = std::min(h_current,h_received);
150 apf::setScalar(interfaceBand,ent,0,h_final);
154 apf::synchronize(interfaceBand);
157 m->destroyTag(vertexMarker);
160 sizeFieldList.push(interfaceBand);
166 apf::Mesh* m = apf::getMesh(levelSet);
167 apf::Adjacent edge_adjVerts;
168 m->getAdjacent(edge,0,edge_adjVerts);
169 apf::MeshEntity *vertex1 = edge_adjVerts[0];
170 apf::MeshEntity *vertex2 = edge_adjVerts[1];
171 double phi1 = apf::getScalar(levelSet,vertex1,0);
172 double phi2 = apf::getScalar(levelSet,vertex2,0);
173 int doesIntersect = 0;
176 return doesIntersect;
193 apf::MeshEntity* vert = inputObject.
vertex;
195 double L_local = inputObject.
L_local;
196 double direction = inputObject.
direction;
198 apf::MeshTag* vertexMaxTraverse = m->findTag(
"maximumTraversal");
199 apf::Field* predictInterfaceBand = m->findField(
"predictInterfaceBand");
200 apf::Field* levelSet = m->findField(
"phi");
202 apf::Vector3 pt_vert;
203 m->getPoint(vert,0,pt_vert);
204 apf::Vector3 difference_vect = pt_vert-actualPosition;
207 int dontContinue = 0;
208 if(m->hasTag(vert,vertexMaxTraverse))
210 double traversalDistance;
211 m->getDoubleTag(vert,vertexMaxTraverse,&traversalDistance);
212 if((L_local-difference_vect.getLength()) < traversalDistance*1.01)
217 double phiCurrent = apf::getScalar(levelSet,vert,0);
218 if((difference_vect.getLength() > L_local) || dontContinue || (phiCurrent*direction<=0))
224int BFS_propagation(apf::Mesh* m, std::queue<edgeWalkerInfo> &markedVertices, PCU_t PCUObj)
232 markedVertices.pop();
235 apf::MeshEntity* vert = inputObject.
vertex;
237 double L_local = inputObject.
L_local;
238 double direction = inputObject.
direction;
241 apf::MeshTag* vertexMaxTraverse = m->findTag(
"maximumTraversal");
242 apf::Field* predictInterfaceBand = m->findField(
"predictInterfaceBand");
243 apf::Field* levelSet = m->findField(
"phi");
247 apf::Adjacent vertex_adjVerts;
248 apf::getBridgeAdjacent(m,vert,1,0,vertex_adjVerts);
249 for(
int i=0;i<vertex_adjVerts.getSize();i++)
252 apf::MeshEntity* newVert = vertex_adjVerts[i];
253 inputObject.
vertex=newVert;
259 apf::Vector3 pt_vert;
260 m->getPoint(newVert,0,pt_vert);
261 apf::Vector3 difference_vect = pt_vert-actualPosition;
263 double traversalDistance = L_local-difference_vect.getLength();
264 m->setDoubleTag(newVert,vertexMaxTraverse,&traversalDistance);
267 apf::setScalar(predictInterfaceBand,newVert,0,apf::getScalar(predictInterfaceBand,vert,0));
269 inputObject.
vertex = newVert;
270 markedVertices.push(inputObject);
272 if(m->isShared(newVert))
274 int initialRank = PCU_Comm_Self(PCUObj);
275 double desiredSize = apf::getScalar(predictInterfaceBand,vert,0);
277 m->getRemotes(newVert,remotes);
278 for(apf::Copies::iterator iter=remotes.begin(); iter!=remotes.end();++iter)
280 PCU_COMM_PACK(PCUObj, iter->first, iter->second);
281 PCU_COMM_PACK(PCUObj, iter->first, L_local);
282 PCU_COMM_PACK(PCUObj, iter->first, actualPosition);
283 PCU_COMM_PACK(PCUObj, iter->first, direction);
284 PCU_COMM_PACK(PCUObj, iter->first, initialRank);
285 PCU_COMM_PACK(PCUObj, iter->first, inputObject.
edgeID);
286 PCU_COMM_PACK(PCUObj, iter->first, desiredSize);
293 return needsParallel;
301 apf::Field* interfaceBand = m->findField(
"interfaceBand");
302 apf::Field* velocity = m->findField(
"velocity");
303 apf::Field* levelSet = m->findField(
"phi");
306 apf::Field *gradphi = apf::recoverGradientByVolume(levelSet);
308 apf::Field* predictInterfaceBand = apf::createLagrangeField(m,
"predictInterfaceBand",apf::SCALAR,1);
309 apf::copyData(predictInterfaceBand,interfaceBand);
312 apf::MeshTag* vertexMaxTraverse = m->createDoubleTag(
"maximumTraversal",1);
314 apf::MeshEntity* edge;
315 apf::MeshIterator* it = m->begin(1);
317 std::queue <edgeWalkerInfo> markedVertices;
319 PCU_Comm_Begin(PCUObj);
320 while( (edge = m->iterate(it)) )
325 apf::Adjacent edge_adjVerts;
326 m->getAdjacent(edge,0,edge_adjVerts);
327 apf::MeshEntity *vertex1 = edge_adjVerts[0];
328 apf::MeshEntity *vertex2 = edge_adjVerts[1];
329 double phi1 = apf::getScalar(levelSet,vertex1,0);
330 double phi2 = apf::getScalar(levelSet,vertex2,0);
331 apf::Vector3 pt_1, pt_2;
332 m->getPoint(vertex1,0,pt_1);
333 m->getPoint(vertex2,0,pt_2);
334 apf::Vector3 edgeVector = pt_2-pt_1;
336 double zeroPosition = 2*(-phi1/(phi2-phi1))-1.0;
337 double relativePosition = -phi1/(phi2-phi1);
338 apf::Vector3 actualPosition = (pt_2-pt_1)*relativePosition + pt_1;
340 apf::Vector3 edgePoint(zeroPosition,0.0,0.0);
341 apf::Element* phiElem = apf::createElement(levelSet,edge);
342 apf::Element* gradPhiElem = apf::createElement(gradphi,edge);
343 apf::Element* velocityElem = apf::createElement(velocity,edge);
344 apf::Vector3 localVelocity;
345 apf::getVector(velocityElem,edgePoint,localVelocity);
346 apf::Vector3 localInterfaceNormal;
347 apf::getVector(gradPhiElem,edgePoint,localInterfaceNormal);
348 apf::destroyElement(phiElem);
349 apf::destroyElement(velocityElem);
350 apf::destroyElement(gradPhiElem);
353 double L_local = localVelocity.getLength()*
numAdaptSteps*delta_T;
358 double signValue = localVelocity*localInterfaceNormal;
361 for(
int i=0; i<edge_adjVerts.getSize();i++)
364 inputObject.
vertex = edge_adjVerts[i];
372 markedVertices.push(inputObject);
375 if(m->isShared(inputObject.
vertex))
377 int initialRank = PCU_Comm_Self(PCUObj);
378 double desiredSize = apf::getScalar(predictInterfaceBand,inputObject.
vertex,0);
380 m->getRemotes(inputObject.
vertex,remotes);
381 for(apf::Copies::iterator iter=remotes.begin(); iter!=remotes.end();++iter)
383 PCU_COMM_PACK(PCUObj, iter->first, iter->second);
384 PCU_COMM_PACK(PCUObj, iter->first, L_local);
385 PCU_COMM_PACK(PCUObj, iter->first, actualPosition);
386 PCU_COMM_PACK(PCUObj, iter->first, inputObject.
direction);
387 PCU_COMM_PACK(PCUObj, iter->first, initialRank);
388 PCU_COMM_PACK(PCUObj, iter->first, inputObject.
edgeID);
389 PCU_COMM_PACK(PCUObj, iter->first, desiredSize);
401 PCU_Comm_Send(PCUObj);
402 while(PCU_Comm_Receive(PCUObj))
404 apf::MeshEntity* vertex;
406 apf::Vector3 actualPosition;
411 PCU_COMM_UNPACK(PCUObj, vertex);
412 PCU_COMM_UNPACK(PCUObj, L_local);
413 PCU_COMM_UNPACK(PCUObj, actualPosition);
414 PCU_COMM_UNPACK(PCUObj, direction);
415 PCU_COMM_UNPACK(PCUObj, initialRank);
416 PCU_COMM_UNPACK(PCUObj, edgeID);
417 PCU_COMM_UNPACK(PCUObj, desiredSize);
420 inputObject.
vertex = vertex;
424 inputObject.
edgeID = edgeID;
428 if(desiredSize < apf::getScalar(predictInterfaceBand,vertex,0))
429 apf::setScalar(predictInterfaceBand,vertex,0,desiredSize);
433 apf::Vector3 pt_vert;
434 m->getPoint(vertex,0,pt_vert);
435 apf::Vector3 difference_vect = pt_vert-actualPosition;
437 double traversalDistance = L_local-difference_vect.getLength();
438 m->setDoubleTag(vertex,vertexMaxTraverse,&traversalDistance);
440 markedVertices.push(inputObject);
447 while(needsParallel>0)
451 PCU_Comm_Begin(PCUObj);
454 while(!markedVertices.empty())
458 PCU_Add_Ints(PCUObj, &needsParallel,1);
460 PCU_Comm_Send(PCUObj);
461 while( PCU_Comm_Receive(PCUObj) )
463 apf::MeshEntity* vertex;
465 apf::Vector3 actualPosition;
470 PCU_COMM_UNPACK(PCUObj, vertex);
471 PCU_COMM_UNPACK(PCUObj, L_local);
472 PCU_COMM_UNPACK(PCUObj, actualPosition);
473 PCU_COMM_UNPACK(PCUObj, direction);
474 PCU_COMM_UNPACK(PCUObj, initialRank);
475 PCU_COMM_UNPACK(PCUObj, edgeID);
476 PCU_COMM_UNPACK(PCUObj, desiredSize);
480 inputObject.
vertex = vertex;
484 inputObject.
edgeID = edgeID;
488 if(desiredSize < apf::getScalar(predictInterfaceBand,vertex,0))
489 apf::setScalar(predictInterfaceBand,vertex,0,desiredSize);
493 apf::Vector3 pt_vert;
494 m->getPoint(vertex,0,pt_vert);
495 apf::Vector3 difference_vect = pt_vert-actualPosition;
497 double traversalDistance = L_local-difference_vect.getLength();
498 m->setDoubleTag(vertex,vertexMaxTraverse,&traversalDistance);
500 markedVertices.push(inputObject);
505 apf::copyData(interfaceBand,predictInterfaceBand);
506 apf::destroyField(predictInterfaceBand);
507 apf::destroyField(gradphi);
510 apf::MeshIterator* tagIt = m->begin(0);
511 apf::MeshEntity* taggedVertex;
512 while( taggedVertex = m->iterate(tagIt) )
514 if(m->hasTag(taggedVertex,vertexMaxTraverse))
515 m->removeTag(taggedVertex,vertexMaxTraverse);
518 m->destroyTag(vertexMaxTraverse);
522void MeshAdaptPUMIDrvr::isotropicIntersect()
525 if(m->findField(
"proteus_size"))
526 apf::destroyField(m->findField(
"proteus_size"));
528 size_iso = apf::createFieldOn(m,
"proteus_size", apf::SCALAR);
530 apf::MeshEntity *vert;
531 apf::MeshIterator *it = m->begin(0);
533 apf::Field *field = sizeFieldList.front();
534 apf::copyData(size_iso,field);
537 while(!sizeFieldList.empty())
539 field = sizeFieldList.front();
540 while(vert = m->iterate(it))
542 double value1 = apf::getScalar(size_iso,vert,0);
543 double value2 = apf::getScalar(field,vert,0);
544 double minValue = std::min(value1,value2);
545 apf::setScalar(size_iso,vert,0,minValue);
557void MeshAdaptPUMIDrvr::averageToEntity(apf::Field *ef, apf::Field *vf,
558 apf::MeshEntity *ent)
567 apf::Mesh *m = apf::getMesh(ef);
568 apf::Adjacent elements;
569 m->getAdjacent(ent, m->getDimension(), elements);
571 for (std::size_t i = 0; i < elements.getSize(); ++i)
572 s += apf::getScalar(ef, elements[i], 0);
573 s /= elements.getSize();
574 apf::setScalar(vf, ent, 0,
s);
578void MeshAdaptPUMIDrvr::minToEntity(apf::Field* ef, apf::Field* vf,
579 apf::MeshEntity* ent)
581 apf::Mesh* m = apf::getMesh(ef);
582 apf::Adjacent elements;
583 m->getAdjacent(ent, m->getDimension(), elements);
585 for (std::size_t i=0; i < elements.getSize(); ++i){
587 s = apf::getScalar(ef, elements[i], 0);
588 else if(apf::getScalar(ef,elements[i],0) <
s)
589 s= apf::getScalar(ef,elements[i],0);
591 apf::setScalar(vf, ent, 0,
s);
596void MeshAdaptPUMIDrvr::volumeAverageToEntity(apf::Field *ef, apf::Field *vf,
597 apf::MeshEntity *ent)
600 apf::Mesh *m = apf::getMesh(ef);
601 apf::Adjacent elements;
602 apf::MeshElement *testElement;
603 m->getAdjacent(ent, m->getDimension(), elements);
605 double VolumeTotal = 0;
606 for (std::size_t i = 0; i < elements.getSize(); ++i)
608 testElement = apf::createMeshElement(m, elements[i]);
609 s += apf::getScalar(ef, elements[i], 0)*apf::measure(testElement);
610 VolumeTotal += apf::measure(testElement);
611 apf::destroyMeshElement(testElement);
614 apf::setScalar(vf, ent, 0,
s);
621 apf::Mesh *m = apf::getMesh(ef);
622 apf::Adjacent elements;
623 m->getAdjacent(ent, m->getDimension(), elements);
625 double errorTotal = 0;
626 for (std::size_t i = 0; i < elements.getSize(); ++i)
628 s += apf::getScalar(ef, elements[i], 0)*apf::getScalar(err,elements[i],0);
629 errorTotal += apf::getScalar(err,elements[i],0);
638 apf::setScalar(vf, ent, 0,
s);
643static apf::Field *extractSpeed(apf::Field *velocity)
646 apf::Mesh *m = apf::getMesh(velocity);
647 apf::Field *speedF = apf::createLagrangeField(m,
"proteus_speed", apf::SCALAR, 1);
648 apf::MeshIterator *it = m->begin(0);
650 apf::Vector3 vel_vect;
651 while ((
v = m->iterate(it)))
653 apf::getVector(velocity,
v, 0, vel_vect);
654 double speed = vel_vect.getLength();
655 apf::setScalar(speedF,
v, 0, speed);
661static apf::Matrix3x3 hessianFormula(apf::Matrix3x3
const &g2phi)
664 apf::Matrix3x3 g2phit = apf::transpose(g2phi);
665 return (g2phi + g2phit) / 2;
668static apf::Field *computeHessianField(apf::Field *grad2phi)
671 apf::Mesh *m = apf::getMesh(grad2phi);
672 apf::Field *hessf = createLagrangeField(m,
"proteus_hess", apf::MATRIX, 1);
673 apf::MeshIterator *it = m->begin(0);
675 while ((
v = m->iterate(it)))
677 apf::Matrix3x3 g2phi;
678 apf::getMatrix(grad2phi,
v, 0, g2phi);
679 apf::Matrix3x3 hess = hessianFormula(g2phi);
680 apf::setMatrix(hessf,
v, 0, hess);
686static apf::Field *computeMetricField(apf::Field *gradphi, apf::Field *grad2phi, apf::Field *size_iso,
double eps_u)
690 apf::Mesh *m = apf::getMesh(grad2phi);
691 apf::Field *metricf = createLagrangeField(m,
"proteus_metric", apf::MATRIX, 1);
692 apf::MeshIterator *it = m->begin(0);
694 while ((
v = m->iterate(it)))
696 apf::Matrix3x3 g2phi;
697 apf::getMatrix(grad2phi,
v, 0, g2phi);
705 apf::Matrix3x3 hess = hessianFormula(g2phi);
706 apf::Matrix3x3 metric = hess;
709 apf::setMatrix(metricf,
v, 0, metric);
716static void curveFormula(apf::Matrix3x3
const &h, apf::Vector3
const &g,
719 double a = (h[1][1] + h[2][2]) * g[0] * g[0] + (h[0][0] + h[2][2]) * g[1] * g[1] + (h[0][0] + h[1][1]) * g[2] * g[2];
721 double b = g[0] * g[1] * h[0][1] + g[0] * g[2] * h[0][2] + g[1] * g[2] * h[1][2];
723 double Km = (a - 2 * b) / pow(g * g, 1.5);
725 double c = g[0] * g[0] * (h[1][1] * h[2][2] - h[1][2] * h[1][2]) + g[1] * g[1] * (h[0][0] * h[2][2] - h[0][2] * h[0][2]) + g[2] * g[2] * (h[0][0] * h[1][1] - h[0][1] * h[0][1]);
727 double d = g[0] * g[1] * (h[0][2] * h[1][2] - h[0][1] * h[2][2]) + g[1] * g[2] * (h[0][1] * h[0][2] - h[1][2] * h[0][0]) + g[0] * g[2] * (h[0][1] * h[1][2] - h[0][2] * h[1][1]);
729 double Kg = (
c + 2 * d) / pow(g * g, 2);
732 curve[1] = Km + sqrt(Km * Km - Kg);
733 curve[2] = Km - sqrt(Km * Km - Kg);
736static apf::Field *getCurves(apf::Field *hessians, apf::Field *gradphi)
738 apf::Mesh *m = apf::getMesh(hessians);
740 curves = apf::createLagrangeField(m,
"proteus_curves", apf::VECTOR, 1);
741 apf::MeshIterator *it = m->begin(0);
743 while ((
v = m->iterate(it)))
745 apf::Matrix3x3 hessian;
746 apf::getMatrix(hessians,
v, 0, hessian);
748 apf::getVector(gradphi,
v, 0, gphi);
750 curveFormula(hessian, gphi, curve);
751 apf::setVector(curves,
v, 0, curve);
757static void clamp(
double &
v,
double min,
double max)
760 v = std::min(
max,
v);
761 v = std::max(
min,
v);
764static void clampField(apf::Field *field,
double min,
double max)
767 apf::Mesh *m = apf::getMesh(field);
768 int numcomps = apf::countComponents(field);
769 double components[numcomps];
771 apf::MeshIterator *it = m->begin(0);
772 while ((
v = m->iterate(it)))
775 apf::getComponents(field,
v, 0, &components[0]);
776 for (
int i = 0; i < numcomps; i++)
777 clamp(components[i],
min,
max);
779 apf::setComponents(field,
v, 0, &components[0]);
784static void scaleFormula(
double phi,
double hmin,
double hmax,
786 apf::Vector3
const &curves,
790 double epsilon = 7.0 * hmin;
791 if (fabs(
phi) < epsilon)
794 scale[1] = sqrt(0.002 / fabs(curves[1]));
795 scale[2] = sqrt(0.002 / fabs(curves[2]));
797 else if (fabs(
phi) < 4 * epsilon)
800 scale[1] = 2 * sqrt(0.002 / fabs(curves[1]));
801 scale[2] = 2 * sqrt(0.002 / fabs(curves[2]));
805 scale = apf::Vector3(1, 1, 1) * hmax;
812static void scaleFormulaERM(
double phi,
double hmin,
double hmax,
double h_dest,
813 apf::Vector3
const &curves,
814 double lambda[3],
double eps_u, apf::Vector3 &scale,
int nsd,
double maxAspect)
868 scale[0] = h_dest * pow((lambda[1] ) / (lambda[0]), 1.0 / 4.0);
869 scale[1] = sqrt(lambda[0] / lambda[1]) * scale[0];
879 scale[1] = sqrt(lambda[0] / lambda[1]) * scale[0];
880 scale[2] = sqrt(lambda[0] / lambda[2]) * scale[0];
881 if(scale[1]/scale[0] > maxAspect)
882 scale[1] = maxAspect*scale[0];
883 if(scale[2]/scale[0] > maxAspect)
884 scale[2] = maxAspect*scale[0];
885 if(scale[1]/scale[0] > maxAspect || scale[2]/scale[0] > maxAspect){
886 logEvent(
"Scales reached maximum aspect ratio",4);
901static apf::Field *getSizeScales(apf::Field *phif, apf::Field *curves,
902 double hmin,
double hmax,
int adapt_step)
905 apf::Mesh *m = apf::getMesh(phif);
907 scales = apf::createLagrangeField(m,
"proteus_size_scale", apf::VECTOR, 1);
908 apf::MeshIterator *it = m->begin(0);
910 while ((
v = m->iterate(it)))
912 double phi = apf::getScalar(phif,
v, 0);
914 apf::getVector(curves,
v, 0, curve);
916 scaleFormula(
phi, hmin, hmax, adapt_step, curve, scale);
917 apf::setVector(scales,
v, 0, scale);
929 return wm < other.
wm;
933static apf::Field *getSizeFrames(apf::Field *hessians, apf::Field *gradphi)
936 apf::Mesh *m = apf::getMesh(gradphi);
938 frames = apf::createLagrangeField(m,
"proteus_size_frame", apf::MATRIX, 1);
939 apf::MeshIterator *it = m->begin(0);
941 while ((
v = m->iterate(it)))
944 apf::getVector(gradphi,
v, 0, gphi);
946 if (gphi.getLength() > 1e-16)
947 dir = gphi.normalize();
949 dir = apf::Vector3(1, 0, 0);
950 apf::Matrix3x3 hessian;
951 apf::getMatrix(hessians,
v, 0, hessian);
952 apf::Vector3 eigenVectors[3];
953 double eigenValues[3];
954 apf::eigen(hessian, eigenVectors, eigenValues);
956 for (
int i = 0; i < 3; ++i)
958 ssa[i].
v = eigenVectors[i];
959 ssa[i].
wm = std::fabs(eigenValues[i]);
961 std::sort(ssa, ssa + 3);
962 assert(ssa[2].wm >= ssa[1].wm);
963 assert(ssa[1].wm >= ssa[0].wm);
964 double firstEigenvalue = ssa[2].
wm;
965 apf::Matrix3x3 frame;
967 if (firstEigenvalue > 1e-16)
969 apf::Vector3 firstEigenvector = ssa[2].
v;
970 frame[1] = apf::reject(firstEigenvector, dir);
971 frame[2] = apf::cross(frame[0], frame[1]);
972 if (frame[2].getLength() < 1e-16)
973 frame = apf::getFrame(dir);
976 frame = apf::getFrame(dir);
977 for (
int i = 0; i < 3; ++i)
978 frame[i] = frame[i].normalize();
979 frame = apf::transpose(frame);
980 apf::setMatrix(frames,
v, 0, frame);
986static apf::Field *getERMSizeFrames(apf::Field *hessians, apf::Field *gradphi, apf::Field *frame_comps[3])
989 apf::Mesh *m = apf::getMesh(gradphi);
991 frames = m->findField(
"proteus_size_frame");
992 apf::MeshIterator *it = m->begin(0);
994 while ((
v = m->iterate(it)))
996 apf::Matrix3x3 frame(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
998 apf::getVector(gradphi,
v, 0, gphi);
1008 apf::Matrix3x3 hessian;
1009 apf::getMatrix(hessians,
v, 0, hessian);
1010 apf::Vector3 eigenVectors[3];
1011 double eigenValues[3];
1012 apf::eigen(hessian, eigenVectors, eigenValues);
1014 for (
int i = 0; i < 3; ++i)
1016 ssa[i].
v = eigenVectors[i];
1017 ssa[i].
wm = std::fabs(eigenValues[i]);
1021 std::sort(ssa, ssa + 3);
1022 assert(ssa[2].wm >= ssa[1].wm);
1023 assert(ssa[1].wm >= ssa[0].wm);
1024 double firstEigenvalue = ssa[2].
wm;
1025 assert(firstEigenvalue > 1e-12);
1029 frame[0] = ssa[2].
v;
1030 frame[1] = ssa[1].
v;
1031 frame[2] = ssa[0].
v;
1043 for (
int i = 0; i < 3; ++i)
1044 frame[i] = frame[i].normalize();
1045 frame = apf::transpose(frame);
1046 apf::setMatrix(frames,
v, 0, frame);
1047 apf::setVector(frame_comps[0],
v, 0, frame[0]);
1048 apf::setVector(frame_comps[1],
v, 0, frame[1]);
1049 apf::setVector(frame_comps[2],
v, 0, frame[2]);
1058 apf::Field *phif = m->findField(
"phi");
1060 apf::Field *gradphi = apf::recoverGradientByVolume(phif);
1061 apf::Field *grad2phi = apf::recoverGradientByVolume(gradphi);
1062 apf::Field *hess = computeHessianField(grad2phi);
1063 apf::destroyField(grad2phi);
1064 apf::Field *curves = getCurves(hess, gradphi);
1065 freeField(size_scale);
1068 apf::destroyField(curves);
1069 freeField(size_frame);
1070 size_frame = getSizeFrames(hess, gradphi);
1071 apf::destroyField(hess);
1073 apf::destroyField(gradphi);
1074 for (
int i = 0; i < 2; ++i)
1075 SmoothField(size_scale);
1085 int nc = apf::countComponents(
f);
1086 newField = apf::createPackedField(mesh,
"proteus_smooth_new", nc);
1100 if (!this->requestLocality(&e, 1))
1111 mesh->getUp(
vertex, edges);
1113 for (
int i = 0; i < edges.n; ++i)
1115 apf::MeshEntity *ov = apf::getEdgeVertOppositeVert(
1116 mesh, edges.e[i],
vertex);
1133static void SmoothField(apf::Field *
f)
1136 op.applyToDimension(0);
1139void getTargetError(apf::Mesh* m, apf::Field* errField,
double &target_error,
double totalError, PCU_t PCUObj){
1142 logEvent(
"WARNING/ERROR:Parallel implementation is not completed yet",4);
1143 if(m->getDimension()==2){
1144 target_error = totalError/sqrt(m->count(m->getDimension()));
1145 if(PCU_Comm_Self(PCUObj)==0)
1146 std::cout<<
"The estimated target error is "<<target_error<<std::endl;
1149 apf::Field* interfaceField = m->findField(
"vof");
1150 apf::Field* targetField = apf::createField(m,
"targetError",apf::SCALAR,apf::getVoronoiShape(m->getDimension(),1));
1151 apf::MeshEntity* ent;
1152 apf::MeshIterator* it = m->begin(m->getDimension());
1153 apf::MeshElement* element;
1154 apf::Element* vofElem;
1155 std::vector <double> errVect;
1156 while( (ent = m->iterate(it))){
1157 element = apf::createMeshElement(m, ent);
1158 vofElem = apf::createElement(interfaceField,element);
1159 double vofVal = apf::getScalar(vofElem,apf::Vector3(1./3.,1./3.,1./3.));
1161 if(vofVal < 0.9 && vofVal > 0.1){
1162 double errorValue = apf::getScalar(errField,ent,0);
1163 errVect.push_back(errorValue);
1164 apf::setScalar(targetField,ent,0,errorValue);
1167 apf::setScalar(targetField,ent,0,0.0);
1171 if(errVect.size()==0){
1172 target_error = totalError/sqrt(m->count(m->getDimension()));
1175 std::ofstream myfile;
1176 myfile.open(
"interfaceErrors.txt", std::ios::app );
1177 for(
int i=0;i<errVect.size();i++){
1178 myfile << errVect[i]<<std::endl;
1181 std::sort(errVect.begin(),errVect.end());
1182 int vectorSize = errVect.size();
1183 if(vectorSize %2 ==0){
1184 int idx1 = vectorSize/2-1;
1185 target_error = (errVect[idx1]+errVect[idx1+1])/2;
1188 target_error = errVect[(vectorSize-1)/2];
1190 if(PCU_Comm_Self(PCUObj)==0)
1191 std::cout<<
"The estimated target error is "<<target_error<<std::endl;
1199 freeField(size_frame);
1200 freeField(size_scale);
1201 freeField(size_iso);
1204 apf::Field* errField;
1207 errField = m->findField(
"ErrorRegion");
1209 errField = m->findField(
"VMSH1");
1213 apf::MeshIterator *it;
1215 apf::MeshElement *element;
1216 apf::MeshEntity *reg;
1218 if(m->findField(
"errorSize"))
1219 apf::destroyField(m->findField(
"errorSize"));
1220 apf::Field *errorSize = apf::createLagrangeField(m,
"errorSize", apf::SCALAR, 1);
1223 size_scale = apf::createLagrangeField(m,
"proteus_size_scale", apf::VECTOR, 1);
1224 size_frame = apf::createLagrangeField(m,
"proteus_size_frame", apf::MATRIX, 1);
1226 apf::Field *errorSize_reg = apf::createField(m,
"iso_size", apf::SCALAR, apf::getConstant(
nsd));
1227 apf::Field *clipped_vtx = apf::createLagrangeField(m,
"iso_clipped", apf::SCALAR, 1);
1231 int nsd = m->getDimension();
1232 numel = m->count(
nsd);
1233 PCU_Add_Ints(PCUObj, &numel, 1);
1236 if(target_error==0){
1237 if(m->findField(
"vof")!=NULL)
1240 target_error = err_total/sqrt(m->count(
nsd));
1245 if (domainVolume == 0)
1247 double volTotal = 0.0;
1249 while (reg = m->iterate(it))
1251 volTotal += apf::measure(m, reg);
1253 PCU_Add_Doubles(PCUObj, &volTotal, 1);
1254 domainVolume = volTotal;
1255 assert(domainVolume > 0);
1259 double err_curr = 0.0;
1260 double errRho_curr = 0.0;
1261 double errRho_target = target_error / sqrt(domainVolume);
1262 apf::Vector3 err_vect;
1263 while (reg = m->iterate(it))
1267 element = apf::createMeshElement(m, reg);
1269 if (m->getDimension() == 2)
1271 h_old = apf::computeLargestHeightInTri(m,reg);
1274 h_old = apf::computeLargestHeightInTet(m,reg);
1276 err_curr = apf::getScalar(errField, reg, 0);
1285 if(target_error/err_curr <= 1)
1286 h_new = h_old * pow((target_error / err_curr),2.0/(2.0*(1.0)+1.0));
1288 h_new = h_old * pow((target_error / err_curr),2.0/(2.0*(1.0)+3.0));
1291 if(target_error/err_curr <= 1)
1292 h_new = h_old * pow((target_error / err_curr),2.0/(2.0*(1.0)+
nsd));
1294 h_new = h_old * pow((target_error / err_curr),2.0/(2.0*(1.0)+
nsd));
1298 apf::setScalar(errorSize_reg, reg, 0, h_new);
1299 apf::destroyMeshElement(element);
1304 PCU_Comm_Begin(PCUObj);
1306 while ((
v = m->iterate(it)))
1311 minToEntity(errorSize_reg, errorSize,
v);
1314 apf::Copies remotes;
1315 m->getRemotes(
v,remotes);
1316 int owningPart=m->getOwner(
v);
1317 PCU_COMM_PACK(PCUObj, owningPart, remotes[owningPart]);
1318 double currentSize = apf::getScalar(errorSize,
v,0);
1319 PCU_COMM_PACK(PCUObj, owningPart,currentSize);
1324 PCU_Comm_Send(PCUObj);
1325 while(PCU_Comm_Receive(PCUObj))
1327 apf::MeshEntity* receivedEnt;
1328 double receivedSize;
1329 PCU_COMM_UNPACK(PCUObj, receivedEnt);
1330 PCU_COMM_UNPACK(PCUObj, receivedSize);
1332 double currentSize = apf::getScalar(errorSize,receivedEnt,0);
1334 if(receivedSize<currentSize)
1336 apf::setScalar(errorSize,receivedEnt,0,receivedSize);
1347 std::cout<<
"Entering anisotropic loop to compute size scales and frames\n";
1348 double eps_u = 0.002;
1354 apf::Field *speedF = extractSpeed(m->findField(
"velocity"));
1355 apf::Field *gradSpeed = apf::recoverGradientByVolume(speedF);
1356 apf::Field *grad2Speed = apf::recoverGradientByVolume(gradSpeed);
1360 apf::Field *metricf = computeMetricField(gradSpeed, grad2Speed, errorSize, eps_u);
1361 apf::Field *frame_comps[3] = {apf::createLagrangeField(m,
"frame_0", apf::VECTOR, 1), apf::createLagrangeField(m,
"frame_1", apf::VECTOR, 1), apf::createLagrangeField(m,
"frame_2", apf::VECTOR, 1)};
1367 while ((
v = m->iterate(it)))
1369 double tempScale = apf::getScalar(errorSize,
v, 0);
1370 if (tempScale <
hmin)
1371 apf::setScalar(clipped_vtx,
v, 0, -1);
1372 else if (tempScale >
hmax)
1373 apf::setScalar(clipped_vtx,
v, 0, 1);
1375 apf::setScalar(clipped_vtx,
v, 0, 0);
1377 apf::setScalar(errorSize,
v,0,tempScale);
1380 while( (
v = m->iterate(it)) ){
1386 apf::Matrix3x3 metric;
1387 apf::getMatrix(metricf,
v, 0, metric);
1389 apf::Vector3 eigenVectors[3];
1390 double eigenValues[3];
1391 apf::eigen(metric, eigenVectors, eigenValues);
1395 for (
int i = 0; i < 3; ++i)
1397 ssa[i].
v = eigenVectors[i];
1398 ssa[i].
wm = std::fabs(eigenValues[i]);
1400 std::sort(ssa, ssa + 3);
1402 assert(ssa[2].wm >= ssa[1].wm);
1403 assert(ssa[1].wm >= ssa[0].wm);
1405 double lambda[3] = {ssa[2].
wm, ssa[1].
wm, ssa[0].
wm};
1407 scaleFormulaERM(
phi,
hmin,
hmax, apf::getScalar(errorSize,
v, 0), curve, lambda, eps_u, scale,
nsd,
maxAspect);
1408 apf::setVector(size_scale,
v, 0, scale);
1411 apf::Matrix3x3 frame(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
1414 double firstEigenvalue = ssa[2].
wm;
1415 assert(firstEigenvalue > 1e-12);
1416 frame[0] = ssa[2].
v;
1417 frame[1] = ssa[1].
v;
1418 frame[2] = ssa[0].
v;
1421 for (
int i = 0; i < 3; ++i)
1422 frame[i] = frame[i].normalize();
1423 frame = apf::transpose(frame);
1424 apf::setMatrix(size_frame,
v, 0, frame);
1432 std::cout<<
"Finished grading size 0\n";
1435 std::cout<<
"Finished grading size 1\n";
1438 std::cout<<
"Finished grading size 2\n";
1440 apf::synchronize(size_scale);
1448 char namebuffer[20];
1449 sprintf(namebuffer,
"pumi_preadapt_aniso_%i",
nAdapt);
1450 apf::writeVtkFiles(namebuffer, m);
1453 apf::destroyField(metricf);
1454 apf::destroyField(frame_comps[0]);
1455 apf::destroyField(frame_comps[1]);
1456 apf::destroyField(frame_comps[2]);
1457 apf::destroyField(speedF);
1458 apf::destroyField(gradSpeed);
1459 apf::destroyField(grad2Speed);
1464 while ((
v = m->iterate(it)))
1466 double tempScale = apf::getScalar(errorSize,
v, 0);
1467 if (tempScale <
hmin)
1468 apf::setScalar(clipped_vtx,
v, 0, -1);
1469 else if (tempScale >
hmax)
1470 apf::setScalar(clipped_vtx,
v, 0, 1);
1472 apf::setScalar(clipped_vtx,
v, 0, 0);
1474 apf::setScalar(errorSize,
v, 0, tempScale);
1477 apf::synchronize(errorSize);
1479 if (target_element_count != 0)
1481 sam::scaleIsoSizeField(errorSize, target_element_count);
1486 sizeFieldList.push(errorSize);
1490 apf::destroyField(errorSize_reg);
1491 apf::destroyField(clipped_vtx);
1493 std::cout<<
"Finished Size Field\n";
1500 freeField(size_iso);
1501 size_iso = apf::createLagrangeField(m,
"proteus_size",apf::SCALAR,1);
1502 apf::MeshIterator* it = m->begin(0);
1504 while(
v = m->iterate(it)){
1507 apf::setScalar(size_iso,
v,0,
phi);
1513 double size[2], apf::Adjacent edgAdjVert,
1514 apf::Adjacent vertAdjEdg,
1515 std::queue<apf::MeshEntity*> &markedEdges,
1516 apf::MeshTag* isMarked,
1535 int marker[3] = {0,1,0};
1536 double marginVal = 0.01;
1537 int needsParallel=0;
1539 if(fieldType == apf::SCALAR){
1540 apf::Field* size_iso = m->findField(
"proteus_size");
1542 if(size[idx1]>(gradingFactor*size[idx2])*(1+marginVal))
1544 if(m->isOwned(edgAdjVert[idx1]))
1546 size[idx1] = gradingFactor*size[idx2];
1547 apf::setScalar(size_iso,edgAdjVert[idx1],0,size[idx1]);
1548 m->getAdjacent(edgAdjVert[idx1], 1, vertAdjEdg);
1549 for (std::size_t i=0; i<vertAdjEdg.getSize();++i){
1550 m->getIntTag(vertAdjEdg[i],isMarked,&marker[2]);
1553 m->setIntTag(vertAdjEdg[i],isMarked,&marker[1]);
1554 markedEdges.push(vertAdjEdg[i]);
1561 apf::Copies remotes;
1562 m->getRemotes(edgAdjVert[idx1],remotes);
1563 double newSize = gradingFactor*size[idx2];
1564 int owningPart=m->getOwner(edgAdjVert[idx1]);
1565 PCU_COMM_PACK(PCUObj, owningPart, remotes[owningPart]);
1566 PCU_COMM_PACK(PCUObj, owningPart,newSize);
1572 apf::Field* size_scale = m->findField(
"proteus_size_scale");
1573 apf::Vector3 sizeVec;
1574 if(size[idx1]>(gradingFactor*size[idx2])*(1+marginVal)){
1575 size[idx1] = gradingFactor*size[idx2];
1576 apf::getVector(size_scale,edgAdjVert[idx1],0,sizeVec);
1578 sizeVec[vecPos] = size[idx1]*sizeVec[0];
1581 sizeVec[0] = size[idx1];
1583 apf::setVector(size_scale,edgAdjVert[idx1],0,sizeVec);
1584 m->getAdjacent(edgAdjVert[idx1], 1, vertAdjEdg);
1585 for (std::size_t i=0; i<vertAdjEdg.getSize();++i){
1586 m->getIntTag(vertAdjEdg[i],isMarked,&marker[2]);
1589 m->setIntTag(vertAdjEdg[i],isMarked,&marker[1]);
1590 markedEdges.push(vertAdjEdg[i]);
1595 return needsParallel;
1598void markEdgesInitial(apf::Mesh* m, std::queue<apf::MeshEntity*> &markedEdges,
double gradingFactor)
1602 int marker[3] = {0,1,0};
1605 apf::MeshTag* isMarked = m->findTag(
"isMarked");
1606 apf::Field* size_iso = m->findField(
"proteus_size");
1607 apf::Adjacent edgAdjVert;
1608 apf::MeshEntity* edge;
1609 apf::MeshIterator* it = m->begin(1);
1610 while((edge=m->iterate(it))){
1611 m->getAdjacent(edge, 0, edgAdjVert);
1612 for (std::size_t i=0; i < edgAdjVert.getSize(); ++i){
1613 size[i]=apf::getScalar(size_iso,edgAdjVert[i],0);
1615 if( (size[0] > gradingFactor*size[1]) || (size[1] > gradingFactor*size[0]) ){
1617 markedEdges.push(edge);
1619 m->setIntTag(edge,isMarked,&marker[1]);
1622 m->setIntTag(edge,isMarked,&marker[0]);
1628int serialGradation(apf::Mesh* m, std::queue<apf::MeshEntity*> &markedEdges,
double gradingFactor, PCU_t PCUObj)
1633 int marker[3] = {0,1,0};
1634 apf::MeshTag* isMarked = m->findTag(
"isMarked");
1635 apf::Field* size_iso = m->findField(
"proteus_size");
1636 apf::Adjacent edgAdjVert;
1637 apf::Adjacent vertAdjEdg;
1638 apf::MeshEntity* edge;
1639 apf::MeshIterator* it = m->begin(1);
1640 int needsParallel=0;
1643 while(!markedEdges.empty()){
1644 edge = markedEdges.front();
1645 m->getAdjacent(edge, 0, edgAdjVert);
1646 for (std::size_t i=0; i < edgAdjVert.getSize(); ++i){
1647 size[i] = apf::getScalar(size_iso,edgAdjVert[i],0);
1651 vertAdjEdg, markedEdges, isMarked, apf::SCALAR,0, 0, PCUObj);
1653 vertAdjEdg, markedEdges, isMarked, apf::SCALAR,0, 1, PCUObj);
1655 m->setIntTag(edge,isMarked,&marker[0]);
1658 return needsParallel;
1671 logEvent(
"Starting grading",4);
1672 apf::MeshEntity* edge;
1673 apf::Adjacent edgAdjVert;
1674 apf::Adjacent vertAdjEdg;
1676 std::queue<apf::MeshEntity*> markedEdges;
1677 apf::MeshTag* isMarked = m->createIntTag(
"isMarked",1);
1680 int marker[3] = {0,1,0};
1682 apf::MeshIterator* it;
1685 int needsParallel=1;
1687 while(needsParallel)
1689 PCU_Comm_Begin(PCUObj);
1692 PCU_Add_Ints(PCUObj, &needsParallel,1);
1694 std::cerr<<
"Sending size info for gradation"<<std::endl;
1695 PCU_Comm_Send(PCUObj);
1697 apf::MeshEntity* ent;
1698 double receivedSize;
1703 std::queue<apf::MeshEntity*> updateRemoteVertices;
1705 apf::Copies remotes;
1707 while(PCU_Comm_Receive(PCUObj))
1709 PCU_COMM_UNPACK(PCUObj, ent);
1710 PCU_COMM_UNPACK(PCUObj, receivedSize);
1712 if(!m->isOwned(ent)){
1713 logEvent(
"THERE WAS AN ERROR",4);
1717 currentSize = apf::getScalar(size_iso,ent,0);
1718 newSize = std::min(receivedSize,currentSize);
1719 apf::setScalar(size_iso,ent,0,newSize);
1722 m->getAdjacent(ent, 1, vertAdjEdg);
1723 for (std::size_t i=0; i<vertAdjEdg.getSize();++i)
1725 edge = vertAdjEdg[i];
1726 m->getIntTag(vertAdjEdg[i],isMarked,&marker[2]);
1729 markedEdges.push(edge);
1731 m->setIntTag(edge,isMarked,&marker[1]);
1734 updateRemoteVertices.push(ent);
1737 PCU_Comm_Begin(PCUObj);
1739 while(!updateRemoteVertices.empty())
1741 ent = updateRemoteVertices.front();
1743 m->getRemotes(ent,remotes);
1744 currentSize = apf::getScalar(size_iso,ent,0);
1745 for(apf::Copies::iterator iter=remotes.begin(); iter!=remotes.end();++iter)
1747 PCU_COMM_PACK(PCUObj, iter->first, iter->second);
1749 updateRemoteVertices.pop();
1752 PCU_Comm_Send(PCUObj);
1754 while(PCU_Comm_Receive(PCUObj))
1757 PCU_COMM_UNPACK(PCUObj, ent);
1759 assert(!m->isOwned(ent));
1761 if(m->isOwned(ent)){
1762 logEvent(
"Problem occurred",4);
1767 m->getAdjacent(ent, 1, vertAdjEdg);
1768 for (std::size_t i=0; i<vertAdjEdg.getSize();++i)
1770 edge = vertAdjEdg[i];
1771 m->getIntTag(vertAdjEdg[i],isMarked,&marker[2]);
1774 markedEdges.push(edge);
1776 m->setIntTag(edge,isMarked,&marker[1]);
1780 apf::synchronize(size_iso);
1786 while((edge=m->iterate(it))){
1787 m->removeTag(edge,isMarked);
1790 m->destroyTag(isMarked);
1793 logEvent(
"Completed grading",4);
1794 return needsParallel;
1804 apf::MeshIterator* it = m->begin(1);
1805 apf::MeshEntity* edge;
1806 apf::Adjacent edgAdjVert;
1807 apf::Adjacent vertAdjEdg;
1808 double gradingFactor = 1.3;
1810 apf::Vector3 sizeVec;
1811 std::queue<apf::MeshEntity*> markedEdges;
1812 apf::MeshTag* isMarked = m->createIntTag(
"isMarked",1);
1813 apf::Field* size_scale = m->findField(
"proteus_size_scale");
1816 int marker[3] = {0,1,0};
1818 while((edge=m->iterate(it))){
1819 m->getAdjacent(edge, 0, edgAdjVert);
1820 for (std::size_t i=0; i < edgAdjVert.getSize(); ++i){
1821 apf::getVector(size_scale,edgAdjVert[i],0,sizeVec);
1824 if( (size[0] > gradingFactor*size[1]) || (size[1] > gradingFactor*size[0]) ){
1826 markedEdges.push(edge);
1828 m->setIntTag(edge,isMarked,&marker[1]);
1832 m->setIntTag(edge,isMarked,&marker[0]);
1836 while(!markedEdges.empty()){
1837 edge = markedEdges.front();
1838 m->getAdjacent(edge, 0, edgAdjVert);
1839 for (std::size_t i=0; i < edgAdjVert.getSize(); ++i){
1840 apf::getVector(size_scale,edgAdjVert[i],0,sizeVec);
1844 vertAdjEdg, markedEdges, isMarked, apf::VECTOR,0, 0, PCUObj);
1846 vertAdjEdg, markedEdges, isMarked, apf::VECTOR,0, 1, PCUObj);
1880 m->setIntTag(edge,isMarked,&marker[0]);
1884 while((edge=m->iterate(it))){
1885 m->removeTag(edge,isMarked);
1888 m->destroyTag(isMarked);
1889 apf::synchronize(size_scale);
1898 std::cout<<
"Entered function\n";
1899 apf::MeshIterator* it = m->begin(1);
1900 apf::MeshEntity* edge;
1901 apf::Adjacent edgAdjVert;
1902 apf::Adjacent vertAdjEdg;
1903 double gradingFactor = 1.3;
1905 apf::Vector3 sizeVec;
1906 std::queue<apf::MeshEntity*> markedEdges;
1907 apf::MeshTag* isMarked = m->createIntTag(
"isMarked",1);
1908 apf::Field* size_scale = m->findField(
"proteus_size_scale");
1911 int marker[3] = {0,1,0};
1913 while((edge=m->iterate(it))){
1914 m->getAdjacent(edge, 0, edgAdjVert);
1915 for (std::size_t i=0; i < edgAdjVert.getSize(); ++i){
1916 apf::getVector(size_scale,edgAdjVert[i],0,sizeVec);
1917 size[i]=sizeVec[idx]/sizeVec[0];
1919 if( (size[0] > gradingFactor*size[1]) || (size[1] > gradingFactor*size[0]) ){
1921 markedEdges.push(edge);
1923 m->setIntTag(edge,isMarked,&marker[1]);
1927 m->setIntTag(edge,isMarked,&marker[0]);
1932 std::cout<<
"Got queue of size "<<markedEdges.size()<<std::endl;
1933 while(!markedEdges.empty()){
1934 edge = markedEdges.front();
1935 m->getAdjacent(edge, 0, edgAdjVert);
1936 for (std::size_t i=0; i < edgAdjVert.getSize(); ++i){
1937 apf::getVector(size_scale,edgAdjVert[i],0,sizeVec);
1938 size[i]=sizeVec[idx]/sizeVec[0];
1941 vertAdjEdg, markedEdges, isMarked, apf::VECTOR, idx, 0, PCUObj);
1943 vertAdjEdg, markedEdges, isMarked, apf::VECTOR, idx, 1, PCUObj);
1945 m->setIntTag(edge,isMarked,&marker[0]);
1949 while((edge=m->iterate(it))){
1950 m->removeTag(edge,isMarked);
1953 m->destroyTag(isMarked);
1954 apf::synchronize(size_scale);
1964 apf::MeshIterator* it = m->begin(1);
1965 apf::MeshEntity* edge;
1966 apf::Adjacent edgAdjVert;
1967 apf::Adjacent vertAdjEdg;
1970 apf::Vector3 sizeVec;
1971 std::queue<apf::MeshEntity*> markedEdges;
1972 apf::MeshTag* isMarked = m->createIntTag(
"isMarked",1);
1973 apf::Field* size_scale = m->findField(
"proteus_size_scale");
1976 int marker[3] = {0,1,0};
1978 while((edge=m->iterate(it))){
1979 m->getAdjacent(edge, 0, edgAdjVert);
1980 for (std::size_t i=0; i < edgAdjVert.getSize(); ++i){
1981 apf::getVector(size_scale,edgAdjVert[i],0,sizeVec);
1984 if( (size[0] > gradingFactor*size[1]) || (size[1] > gradingFactor*size[0]) ){
1986 markedEdges.push(edge);
1988 m->setIntTag(edge,isMarked,&marker[1]);
1992 m->setIntTag(edge,isMarked,&marker[0]);
1996 while(!markedEdges.empty()){
1997 edge = markedEdges.front();
1998 m->getAdjacent(edge, 0, edgAdjVert);
1999 for (std::size_t i=0; i < edgAdjVert.getSize(); ++i){
2000 apf::getVector(size_scale,edgAdjVert[i],0,sizeVec);
2004 vertAdjEdg, markedEdges, isMarked, apf::VECTOR,0, 0, PCUObj);
2006 vertAdjEdg, markedEdges, isMarked, apf::VECTOR,0, 1, PCUObj);
2040 m->setIntTag(edge,isMarked,&marker[0]);
2044 while((edge=m->iterate(it))){
2045 m->removeTag(edge,isMarked);
2048 m->destroyTag(isMarked);
2049 apf::synchronize(size_scale);
2058 if(PCU_Comm_Self(PCUObj)==0)
2059 std::cout<<
"Entered function\n";
2060 apf::MeshIterator* it = m->begin(1);
2061 apf::MeshEntity* edge;
2062 apf::Adjacent edgAdjVert;
2063 apf::Adjacent vertAdjEdg;
2066 apf::Vector3 sizeVec;
2067 std::queue<apf::MeshEntity*> markedEdges;
2068 apf::MeshTag* isMarked = m->createIntTag(
"isMarked",1);
2069 apf::Field* size_scale = m->findField(
"proteus_size_scale");
2072 int marker[3] = {0,1,0};
2074 while((edge=m->iterate(it))){
2075 m->getAdjacent(edge, 0, edgAdjVert);
2076 for (std::size_t i=0; i < edgAdjVert.getSize(); ++i){
2077 apf::getVector(size_scale,edgAdjVert[i],0,sizeVec);
2078 size[i]=sizeVec[idx]/sizeVec[0];
2080 if( (size[0] > gradingFactor*size[1]) || (size[1] > gradingFactor*size[0]) ){
2082 markedEdges.push(edge);
2084 m->setIntTag(edge,isMarked,&marker[1]);
2088 m->setIntTag(edge,isMarked,&marker[0]);
2093 if(PCU_Comm_Self(PCUObj)==0)
2094 std::cout<<
"Got queue of size "<<markedEdges.size()<<std::endl;
2095 while(!markedEdges.empty()){
2096 edge = markedEdges.front();
2097 m->getAdjacent(edge, 0, edgAdjVert);
2098 for (std::size_t i=0; i < edgAdjVert.getSize(); ++i){
2099 apf::getVector(size_scale,edgAdjVert[i],0,sizeVec);
2100 size[i]=sizeVec[idx]/sizeVec[0];
2103 vertAdjEdg, markedEdges, isMarked, apf::VECTOR, idx, 0, PCUObj);
2105 vertAdjEdg, markedEdges, isMarked, apf::VECTOR, idx, 1, PCUObj);
2107 m->setIntTag(edge,isMarked,&marker[0]);
2111 while((edge=m->iterate(it))){
2112 m->removeTag(edge,isMarked);
2115 m->destroyTag(isMarked);
2116 apf::synchronize(size_scale);
int BFS_propagation(apf::Mesh *m, std::queue< edgeWalkerInfo > &markedVertices, PCU_t PCUObj)
int gradeSizeModify(apf::Mesh *m, double gradingFactor, double size[2], apf::Adjacent edgAdjVert, apf::Adjacent vertAdjEdg, std::queue< apf::MeshEntity * > &markedEdges, apf::MeshTag *isMarked, int fieldType, int vecPos, int idxFlag, PCU_t PCUObj)
int checkForPropagation(apf::Mesh *m, edgeWalkerInfo inputObject)
void getTargetError(apf::Mesh *m, apf::Field *errField, double &target_error, double totalError, PCU_t PCUObj)
void markEdgesInitial(apf::Mesh *m, std::queue< apf::MeshEntity * > &markedEdges, double gradingFactor)
void gradeAspectRatio(apf::Mesh *m, int idx, double gradingFactor, PCU_t PCUObj)
void errorAverageToEntity(apf::Field *ef, apf::Field *vf, apf::Field *err, apf::MeshEntity *ent)
int intersectsInterface(apf::MeshEntity *edge, apf::Field *levelSet)
void gradeAnisoMesh(apf::Mesh *m, double gradingFactor, PCU_t PCUObj)
int serialGradation(apf::Mesh *m, std::queue< apf::MeshEntity * > &markedEdges, double gradingFactor, PCU_t PCUObj)
int getERMSizeField(double err_total)
int localNumber(apf::MeshEntity *e)
int gradeMesh(double gradationFactor)
int calculateAnisoSizeField()
void predictiveInterfacePropagation()
int testIsotropicSizeField()
std::string logging_config
int calculateSizeField(double L_band)
std::string adapt_type_config
double edgeLength(int nL, int nR, const double *nodeArray)
virtual Outcome setEntity(apf::MeshEntity *e)
bool operator<(const SortingStruct &other) const
apf::MeshTag * trackerTag
apf::Vector3 actualPosition