diff --git a/contrib/HighOrderMeshOptimizer/CADDistances.cpp b/contrib/HighOrderMeshOptimizer/CADDistances.cpp index 96b517c97d291f2a5a55bd4ce434f5a29f3507e2..980c5d196e358f3f55669be158cafd2a417a0a8f 100644 --- a/contrib/HighOrderMeshOptimizer/CADDistances.cpp +++ b/contrib/HighOrderMeshOptimizer/CADDistances.cpp @@ -353,6 +353,7 @@ double discreteDistance(MLine *l, GEdge *ed, double tol, int meshDiscr, int geom double t0, t1; reparamMeshVertexOnEdge(l->getVertex(0), ed, t0); reparamMeshVertexOnEdge(l->getVertex(1), ed, t1); +// if (t1 == 0.) t1 = 1.; // DBG: Workaround bug closed curves parametricLineGEdge l1(ed, t0, t1); l1.discretize(dpts1, ts1, tol, 5, 45); } @@ -370,7 +371,6 @@ double discreteDistance(MLine *l, GEdge *ed, double tol, int meshDiscr, int geom l2.discretize(dpts2, ts2, tol, minDepth, 10*minDepth); } oversample(dpts2, tol); -// std::cout << "DBGTT: " << dpts1.size() << " points on model, " << dpts2.size() << " points on mesh\n"; switch (distDef) { case 1: return discreteHausdorffDistanceBrute(dpts1, dpts2); @@ -432,7 +432,7 @@ double taylorDistanceSq2D(const GradientBasis *gb, const fullMatrix<double> &nod const std::vector<SVector3> &normCAD) { const int nV = nodesXYZ.size1(); - fullMatrix<double> dxyzdX(nV, 3),dxyzdY(nV, 3); + fullMatrix<double> dxyzdX(nV, 3), dxyzdY(nV, 3); gb->getGradientsFromNodes(nodesXYZ, &dxyzdX, &dxyzdY, 0); double distSq = 0.; for (int i=0; i<nV; i++) { @@ -512,8 +512,8 @@ void distanceFromElementsToGeometry(GModel *gm, int dim, std::map<MElement*,doub std::map<MFace,double,Less_Face> dist2Face; for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it){ - if ((*it)->geomType() == GEntity::Plane)continue; - for (unsigned int i = 0; i < (*it)->triangles.size(); i++){ + if ((*it)->geomType() == GEntity::Plane) continue; + for (unsigned int i = 0; i < (*it)->triangles.size(); i++) { double d = taylorDistanceFace((*it)->triangles[i], *it); MFace f = (*it)->triangles[i]->getFace(0); dist2Face[f] = d; @@ -575,7 +575,6 @@ double distanceToGeometry(GModel *gm, int distType, double tol, int meshDiscr, i maxDist = std::max(dist, maxDist); } } -// printf("DISTANCE TO GEOMETRY : 1D PART %22.15E\n",Obj); if (distType == CADDIST_TAYLOR) { for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it) { @@ -585,7 +584,6 @@ double distanceToGeometry(GModel *gm, int distType, double tol, int meshDiscr, i } } } -// printf("DISTANCE TO GEOMETRY : 1D AND 2D PART %22.15E\n",Obj); return maxDist; } diff --git a/contrib/HighOrderMeshOptimizer/OptHomObjContribCADDist.h b/contrib/HighOrderMeshOptimizer/OptHomObjContribCADDist.h index fa4aed8d80368f28c5f60eccaa5b8fcf4f9f0d97..23a9f7b52e6b532d0a64cf43459c77d4002ea9d2 100644 --- a/contrib/HighOrderMeshOptimizer/OptHomObjContribCADDist.h +++ b/contrib/HighOrderMeshOptimizer/OptHomObjContribCADDist.h @@ -30,7 +30,7 @@ protected: template<class FuncType> ObjContribCADDistSq<FuncType>::ObjContribCADDistSq(double weight, double refDist) : - ObjContrib("CADDist", FuncType::getNamePrefix()+"CADDist"), + ObjContrib("ScaledCADDistSq", FuncType::getNamePrefix()+"ScaledCADDistSq"), _mesh(0), _weight(weight), _refDist(refDist) { } @@ -72,11 +72,11 @@ bool ObjContribCADDistSq<FuncType>::addContrib(double &Obj, alglib::real_1d_arra const double dFact = _weight * FuncType::computeDiff(f); for (int i=0; i<nVEl; i++) { const int iFVi = _mesh->bndEl2FV(iBndEl, i); - if (iFVi >= 0) { // Skip if not free vertex - if (bndDim == 1) gradObj[_mesh->indPCFV(iFVi, 0)] += gradF[i] * dFact; // 2D - else { // 3D - gradObj[_mesh->indPCFV(iFVi, 0)] += gradF[2*i] * dFact; - gradObj[_mesh->indPCFV(iFVi, 1)] += gradF[2*i+1] * dFact; + if (iFVi >= 0) { // Skip if not free vertex + if (bndDim == 1) gradObj[_mesh->indPCFV(iFVi, 0)] += gradF[i] * dFact; // 2D + else { // 3D + gradObj[_mesh->indPCFV(iFVi, 0)] += gradF[2*i] * dFact; // Deriv. w.r.t. 1st param.coord (edge or face vertex) + if (_mesh->nPCFV(iFVi) > 1) gradObj[_mesh->indPCFV(iFVi, 1)] += gradF[2*i+1] * dFact; // Deriv. w.r.t. 2nd param. coord. (only if face vertex) } } } diff --git a/contrib/HighOrderMeshOptimizer/OptHomRun.cpp b/contrib/HighOrderMeshOptimizer/OptHomRun.cpp index 9f6feb58ec450bc0a016ebc5e1af748f668fc035..51a05488bdd52b8034ac437e7040c75a1c04ce06 100644 --- a/contrib/HighOrderMeshOptimizer/OptHomRun.cpp +++ b/contrib/HighOrderMeshOptimizer/OptHomRun.cpp @@ -806,10 +806,10 @@ void HighOrderMeshOptimizerNew(GModel *gm, OptHomParameters &p) minJacBarFunc.setTarget(p.BARRIER_MIN, 1.); ObjContribScaledJac<ObjContribFuncBarrierFixMinMovMax> minMaxJacBarFunc(1.); minMaxJacBarFunc.setTarget(p.BARRIER_MAX, 1.); - ObjContribCADDistSq<ObjContribFuncSimpleTargetMax> CADDistFunc(p.optCADWeight, p.optCADDistMax); - CADDistFunc.setTarget(0.); -// ObjContribCADDistSq<ObjContribFuncBarrierMovMax> CADDistFunc(p.optCADWeight, p.optCADDistMax); -// CADDistFunc.setTarget(1., 0.); +// ObjContribCADDistSq<ObjContribFuncSimpleTargetMax> CADDistFunc(p.optCADWeight, p.optCADDistMax); +// CADDistFunc.setTarget(0.); + ObjContribCADDistSq<ObjContribFuncBarrierMovMax> CADDistFunc(p.optCADWeight, p.optCADDistMax); + CADDistFunc.setTarget(1., 0.); ObjContribScaledJac<ObjContribFuncBarrierFixMin> minJacFixBarFunc(1.); minJacFixBarFunc.setTarget(p.BARRIER_MIN, 1.); diff --git a/contrib/MeshOptimizer/MeshOptCommon.cpp b/contrib/MeshOptimizer/MeshOptCommon.cpp index d0a1cbfde62ee05f59ad7ebdb1eb273029cc8cf6..4f82cba30d9451363b69f2f1474c2e13b1b9c87c 100644 --- a/contrib/MeshOptimizer/MeshOptCommon.cpp +++ b/contrib/MeshOptimizer/MeshOptCommon.cpp @@ -121,8 +121,9 @@ bool MeshOptPatchDef::testElInDist(const SPoint3 &P, double limDist, const SPoint3 A = faceVert[0]->point(); const SPoint3 B = faceVert[1]->point(); const SPoint3 C = faceVert[2]->point(); - if (faceVert.size() == 3) + if (faceVert.size() == 3) { if (testTriSphereIntersect(A, B, C, P, limDistSq)) return true; + } else { const SPoint3 D = faceVert[3]->point(); if (testTriSphereIntersect(A, B, C, P, limDistSq) || diff --git a/contrib/MeshOptimizer/MeshOptPatch.cpp b/contrib/MeshOptimizer/MeshOptPatch.cpp index 32a8dfb09fb2195b477b3f38c1c1eb7e479cebd7..1aff778db46a6bbb3f214f178489ddc71aeadd80 100644 --- a/contrib/MeshOptimizer/MeshOptPatch.cpp +++ b/contrib/MeshOptimizer/MeshOptPatch.cpp @@ -633,37 +633,62 @@ void Patch::scaledCADDistSqAndGradients(int iBndEl, double &scaledDist, const int &iVi = iV[i], &iFVi = iFV[i]; MVertex* &vert = _vert[iVi]; SPoint2 pCAD; - if ((iFVi >= 0) && (vert->onWhat() == gf)) // If free vertex and on surface, ... - pCAD = SPoint2(_uvw[iFVi].x(), _uvw[iFVi].y()); // ... get stored param. coord. + if (iFVi >= 0) { // If free vertex... + if (vert->onWhat() == gf) // If on surface, ... + pCAD = SPoint2(_uvw[iFVi].x(), _uvw[iFVi].y()); // ... get stored param. coord. + else { // Otherwise, reparametrize on surface + const GEdge *ge = vert->onWhat()->cast2Edge(); + pCAD = ge->reparamOnFace(gf, _uvw[iFVi].x(), 1); + } + } else - reparamMeshVertexOnFace(vert, gf, pCAD); // Otherwise, get param. coord. from CAD. + reparamMeshVertexOnFace(vert, gf, pCAD); // If not free vertex, reparametrize on surface normCAD[i] = gf->normal(pCAD); // Compute normal at vertex normCAD[i].normalize(); // Normalize normal } scaledDist = _invRefCADDistSq * taylorDistanceSq2D(gb, nodesXYZ, normCAD); +// std::cout << "DBGTT: bnd el. " << _bndEl[iBndEl]->getNum() << ": scaledDist = " << scaledDist << "\n"; for (int i=0; i<nV; i++) { - const int &iFVi = iFV[i]; + const int &iVi = iV[i], &iFVi = iFV[i]; if (iFVi < 0) continue; // Skip if not free vertex const double xS = nodesXYZ(i, 0), yS = nodesXYZ(i, 1), zS = nodesXYZ(i, 2); // Save coord. of perturbed node for FD - const SVector3 tanCADS = normCAD[i]; // Save normal to CAD at perturbed node - const SPoint2 pCAD0 = SPoint2(_uvw[iFVi].x()+eps0, _uvw[iFVi].y()); // New param. coord. of perturbed node in 1st dir. - GPoint gp0 = gf->point(pCAD0); // New coord. of perturbed node in 1st dir. - nodesXYZ(i, 0) = gp0.x(); nodesXYZ(i, 1) = gp0.y(); nodesXYZ(i, 2) = gp0.z(); - normCAD[i] = gf->normal(pCAD0); // New normal to CAD at perturbed node in 1st dir. - normCAD[i].normalize(); // Normalize new normal - const double sDistDiff0 = _invRefCADDistSq * - taylorDistanceSq2D(gb, nodesXYZ, normCAD); // Compute distance with perturbed node in 1st dir. - gradScaledDist[2*i] = (sDistDiff0-scaledDist) / eps0; // Compute gradient in 1st dir. - const SPoint2 pCAD1 = SPoint2(_uvw[iFVi].x(), _uvw[iFVi].y()+eps1); // New param. coord. of perturbed node in 2nd dir. - GPoint gp1 = gf->point(pCAD1); // New coord. of perturbed node in 2nd dir. - nodesXYZ(i, 0) = gp1.x(); nodesXYZ(i, 1) = gp1.y(); nodesXYZ(i, 2) = gp1.z(); - normCAD[i] = gf->normal(pCAD1); // New normal to CAD at perturbed node in 2nd dir. - normCAD[i].normalize(); // Normalize new normal - double sDistDiff1 = _invRefCADDistSq * - taylorDistanceSq2D(gb, nodesXYZ, normCAD); // Compute distance with perturbed node in 2nd dir. - gradScaledDist[2*i+1] = (sDistDiff1-scaledDist) / eps0; // Compute gradient in 2nd dir. + const SVector3 normCADS = normCAD[i]; // Save normal to CAD at perturbed node + if (_nPCFV[iFVi] == 2) { // Vertex classified on surface, 2D gradient + const SPoint2 pCAD0 = SPoint2(_uvw[iFVi].x()+eps0, _uvw[iFVi].y()); // New param. coord. of perturbed node in 1st dir. + GPoint gp0 = gf->point(pCAD0); // New coord. of perturbed node in 1st dir. + nodesXYZ(i, 0) = gp0.x(); nodesXYZ(i, 1) = gp0.y(); nodesXYZ(i, 2) = gp0.z(); + normCAD[i] = gf->normal(pCAD0); // New normal to CAD at perturbed node in 1st dir. + normCAD[i].normalize(); // Normalize new normal + const double sDistDiff0 = _invRefCADDistSq * + taylorDistanceSq2D(gb, nodesXYZ, normCAD); // Compute distance with perturbed node in 1st dir. + gradScaledDist[2*i] = (sDistDiff0-scaledDist) / eps0; // Compute gradient in 1st dir. + const SPoint2 pCAD1 = SPoint2(_uvw[iFVi].x(), _uvw[iFVi].y()+eps1); // New param. coord. of perturbed node in 2nd dir. + GPoint gp1 = gf->point(pCAD1); // New coord. of perturbed node in 2nd dir. + nodesXYZ(i, 0) = gp1.x(); nodesXYZ(i, 1) = gp1.y(); nodesXYZ(i, 2) = gp1.z(); + normCAD[i] = gf->normal(pCAD1); // New normal to CAD at perturbed node in 2nd dir. + normCAD[i].normalize(); // Normalize new normal + double sDistDiff1 = _invRefCADDistSq * + taylorDistanceSq2D(gb, nodesXYZ, normCAD); // Compute distance with perturbed node in 2nd dir. + gradScaledDist[2*i+1] = (sDistDiff1-scaledDist) / eps1; // Compute gradient in 2nd dir. + } + else if (_nPCFV[iFVi] == 1) { // Vertex classified on edge, 1D gradient + MVertex* &vert = _vert[iVi]; + const GEdge *ge = vert->onWhat()->cast2Edge(); + const Range<double> parBounds = ge->parBounds(0); + const double eps = 1.e-6 * (parBounds.high()-parBounds.low()); + const double tCAD = _uvw[iFVi].x() + eps; // New param. coord. of perturbed node + GPoint gp = ge->point(tCAD); // New coord. of perturbed node + nodesXYZ(i, 0) = gp.x(); nodesXYZ(i, 1) = gp.y(); nodesXYZ(i, 2) = gp.z(); + SPoint2 pCAD = gf->parFromPoint(SPoint3(gp.x(), gp.y(), gp.z()), true); // Get param. coord. of perturbed node in face from CAD + normCAD[i] = gf->normal(pCAD); // New normal to CAD at perturbed node + normCAD[i].normalize(); // Normalize new normal + const double sDistDiff = _invRefCADDistSq * + taylorDistanceSq2D(gb, nodesXYZ, normCAD); // Compute distance with perturbed node + gradScaledDist[2*i] = (sDistDiff-scaledDist) / eps; // Compute gradient + } + else std::cout << "DBGTT: Inconsistent _nPCFV(iFVi), vert. " << _vert[iVi]->getNum() << "\n"; nodesXYZ(i, 0) = xS; nodesXYZ(i, 1) = yS; nodesXYZ(i, 2) = zS; // Restore coord. of perturbed node - normCAD[i] = tanCADS; // Restore tan. to CAD at perturbed node + normCAD[i] = normCADS; // Restore tan. to CAD at perturbed node } } } diff --git a/contrib/MeshOptimizer/MeshOptimizer.cpp b/contrib/MeshOptimizer/MeshOptimizer.cpp index 3365908d13e72f816483ce3abf214adc2ab6b0ae..b8445e941ed76643bc42aec86adffef158f8d2fb 100644 --- a/contrib/MeshOptimizer/MeshOptimizer.cpp +++ b/contrib/MeshOptimizer/MeshOptimizer.cpp @@ -590,7 +590,7 @@ void meshOptimizer(GModel *gm, MeshOptParameters &par) elElMap::iterator bndElIt = el2BndEl.find(el); if (bndElIt != el2BndEl.end()) { MElement* &bndEl = bndElIt->second; - if (par.patchDef->bndElBadness(bndEl, bndEl2Ent[bndEl])) badElts.insert(el); + if (par.patchDef->bndElBadness(bndEl, bndEl2Ent[bndEl]) < 0.) badElts.insert(el); } } }