void meshOptimizer(GModel *gm, MeshOptParameters &par) { #if defined(HAVE_BFGS) if (par.nCurses) mvinit(); redirectMessage _logWriter(par.logFileName, !par.nCurses); if (par.logFileName.compare("") != 0 || par.nCurses) Msg::SetCallback(&_logWriter); double startTime = Cpu(); if (par.nCurses) { mvbold(true); mvprintCenter(0, "OPTIMIZING MESH"); mvfillRow(1,'-'); mvfillRow(10,'-'); mvfillRow(20,'-'); mvfillRow(27,'-'); mvbold(false); } if (par.verbose > 0) Msg::StatusBar(true, "Optimizing mesh..."); std::vector<GEntity*> entities; gm->getEntities(entities); vertElVecMap vertex2elements; elEntMap element2entity, bndEl2Ent; elElMap el2BndEl; elSet badElts; for (int iEnt = 0; iEnt < entities.size(); ++iEnt) { GEntity* &entity = entities[iEnt]; if (entity->dim() != par.dim || (par.onlyVisible && !entity->getVisibility())) continue; if (par.nCurses) { mvprintCenter(15, "Computing connectivity and bad elements for entity %3d...", entity->tag()); } Msg::Info("Computing connectivity and bad elements for entity %d...", entity->tag()); calcVertex2Elements(par.dim, entity, vertex2elements); if ((par.useGeomForPatches) || (par.useGeomForOpt)) calcElement2Entity(entity, element2entity); if (par.useBoundaries) calcBndInfo(entity, el2BndEl, bndEl2Ent); for (int iEl = 0; iEl < entity->getNumMeshElements(); iEl++) { // Detect bad elements MElement *el = entity->getMeshElement(iEl); if (el->getDim() == par.dim) { if (par.patchDef->elBadness(el, entity) < 0.) badElts.insert(el); else if (par.useBoundaries) { elElMap::iterator bndElIt = el2BndEl.find(el); if (bndElIt != el2BndEl.end()) { MElement* &bndEl = bndElIt->second; if (par.patchDef->bndElBadness(bndEl, bndEl2Ent[bndEl]) < 0.) badElts.insert(el); } } } } } if (par.patchDef->strategy == MeshOptPatchDef::STRAT_DISJOINT) optimizeDisjointPatches(vertex2elements, element2entity, el2BndEl, bndEl2Ent, badElts, par); else if (par.patchDef->strategy == MeshOptPatchDef::STRAT_ONEBYONE) optimizeOneByOne(vertex2elements, element2entity, el2BndEl, bndEl2Ent, badElts, par); else { if (par.nCurses){ mvcolor(2,true); mvbold(true); mvprintCenter(-2, " ERROR: Unknown strategy %d for mesh optimization ", par.patchDef->strategy); mvcolor(2,false); mvbold(false); } else Msg::Error("Unknown strategy %d for mesh optimization", par.patchDef->strategy); } if (par.verbose > 0) { if (par.success == 1){ if (par.nCurses){ mvcolor(4,true); mvbold(true); mvprintCenter(-2, " Optimization succeeded "); mvcolor(4,false); mvbold(false); } else Msg::Info("Optimization succeeded"); } else if (par.success == 0){ if (par.nCurses){ mvcolor(5,true); mvbold(true); mvprintCenter(-2, " Optimization partially failed (all measures above critical value, but some below target) "); mvcolor(5,false); mvbold(false); } else Msg::Warning("Optimization partially failed (all measures above critical " "value, but some below target)"); } else if (par.success == -1){ if (par.nCurses){ mvcolor(3,true); mvbold(true); mvprintCenter(-2, "Optimization Failed"); mvcolor(3,false); mvbold(false); } else Msg::Error("Optimization failed (some measures below critical value)"); } par.CPU = Cpu()-startTime; Msg::StatusBar(true, "Done optimizing mesh (%g s)", par.CPU); } if (par.nCurses){ mvpause(); mvterminate(); } if (par.logFileName.compare("") != 0 || par.nCurses) Msg::SetCallback(NULL); #else Msg::Error("Mesh optimizer requires BFGS"); #endif }
void HighOrderMeshOptimizer(GModel *gm, OptHomParameters &p) { #if defined(HAVE_BFGS) double t1 = Cpu(); int samples = 30; double tf1 = Cpu(); Msg::StatusBar(true, "Optimizing high order mesh..."); std::vector<GEntity*> entities; gm->getEntities(entities); std::map<MVertex*, std::vector<MElement *> > vertex2elements; std::map<MElement*,GEntity*> element2entity; elSet badasses; double maxdist = 0.; // TODO: To be cleaned? std::map<MElement*,double> distances; distanceFromElementsToGeometry(gm, p.dim,distances); for (int iEnt = 0; iEnt < entities.size(); ++iEnt) { GEntity* &entity = entities[iEnt]; if (entity->dim() != p.dim || (p.onlyVisible && !entity->getVisibility())) continue; Msg::Info("Computing connectivity and bad elements for entity %d...", entity->tag()); calcVertex2Elements(p.dim,entity,vertex2elements); if (p.optPrimSurfMesh) calcElement2Entity(entity,element2entity); for (int iEl = 0; iEl < entity->getNumMeshElements();iEl++) { // Detect bad elements double jmin, jmax; MElement *el = entity->getMeshElement(iEl); if (el->getDim() == p.dim) { // FIXME TEST // badasses.insert(el); if (p.optCAD) { // const double DISTE =computeBndDist(el,2,fabs(p.discrTolerance)); const double DISTE =distances[el]; // if (DISTE > 0)printf("El %d dist %12.5E vs %12.5E\n",iEl,DISTE,p.optCADDistMax); maxdist = std::max(DISTE, maxdist); if (DISTE > p.optCADDistMax) badasses.insert(el); } el->scaledJacRange(jmin, jmax, p.optPrimSurfMesh ? entity : 0); if (p.BARRIER_MIN_METRIC > 0) jmax = jmin; if (jmin < p.BARRIER_MIN || jmax > p.BARRIER_MAX) badasses.insert(el); } } } printf("maxdist = %g badasses size = %lu\n", maxdist, badasses.size()); if (p.strategy == 0) optimizeConnectedBlobs(vertex2elements, element2entity, badasses, p, samples, false); else if (p.strategy == 2) optimizeConnectedBlobs(vertex2elements, element2entity, badasses, p, samples, true); else optimizeOneByOne(vertex2elements, element2entity, badasses, p, samples); if (p.SUCCESS == 1) Msg::Info("Optimization succeeded"); else if (p.SUCCESS == 0) Msg::Warning("All jacobians positive but not all in the range"); else if (p.SUCCESS == -1) Msg::Error("Still negative jacobians"); double t2 = Cpu(); p.CPU = t2-t1; Msg::StatusBar(true, "Done optimizing high order mesh (%g s)", p.CPU); #else Msg::Error("High-order mesh optimizer requires BFGS"); #endif }
void meshOptimizer(GModel *gm, MeshOptParameters &par) { #if defined(HAVE_BFGS) double startTime = Cpu(); if (par.verbose > 0) Msg::StatusBar(true, "Optimizing mesh..."); std::vector<GEntity*> entities; gm->getEntities(entities); vertElVecMap vertex2elements; elEntMap element2entity, bndEl2Ent; elElMap el2BndEl; elSet badElts; for (int iEnt = 0; iEnt < entities.size(); ++iEnt) { GEntity* &entity = entities[iEnt]; if (entity->dim() != par.dim || (par.onlyVisible && !entity->getVisibility())) continue; Msg::Info("Computing connectivity and bad elements for entity %d...", entity->tag()); calcVertex2Elements(par.dim, entity, vertex2elements); if ((par.useGeomForPatches) || (par.useGeomForOpt)) calcElement2Entity(entity, element2entity); if (par.useBoundaries) calcBndInfo(entity, el2BndEl, bndEl2Ent); for (int iEl = 0; iEl < entity->getNumMeshElements(); iEl++) { // Detect bad elements MElement *el = entity->getMeshElement(iEl); if (el->getDim() == par.dim) { if (par.patchDef->elBadness(el, entity) < 0.) badElts.insert(el); else if (par.useBoundaries) { elElMap::iterator bndElIt = el2BndEl.find(el); if (bndElIt != el2BndEl.end()) { MElement* &bndEl = bndElIt->second; if (par.patchDef->bndElBadness(bndEl, bndEl2Ent[bndEl]) < 0.) badElts.insert(el); } } } } } if (par.patchDef->strategy == MeshOptPatchDef::STRAT_DISJOINT) optimizeDisjointPatches(vertex2elements, element2entity, el2BndEl, bndEl2Ent, badElts, par); else if (par.patchDef->strategy == MeshOptPatchDef::STRAT_ONEBYONE) optimizeOneByOne(vertex2elements, element2entity, el2BndEl, bndEl2Ent, badElts, par); else Msg::Error("Unknown strategy %d for mesh optimization", par.patchDef->strategy); if (par.verbose > 0) { if (par.success == 1) Msg::Info("Optimization succeeded"); else if (par.success == 0) Msg::Warning("Optimization partially failed (all measures above critical " "value, but some below target)"); else if (par.success == -1) Msg::Error("Optimization failed (some measures below critical value)"); par.CPU = Cpu()-startTime; Msg::StatusBar(true, "Done optimizing mesh (%g s)", par.CPU); } #else Msg::Error("Mesh optimizer requires BFGS"); #endif }