void RefineMesh(GModel *m, bool linear, bool splitIntoQuads, bool splitIntoHexas) { Msg::StatusBar(true, "Refining mesh..."); double t1 = Cpu(); // Create 2nd order mesh (using "2nd order complete" elements) to // generate vertex positions SetOrderN(m, 2, linear, false); // only used when splitting tets into hexes faceContainer faceVertices; // Subdivide the second order elements to create the refined linear // mesh for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); ++it) Subdivide(*it); for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it){ Subdivide(*it, splitIntoQuads, splitIntoHexas, faceVertices); if (splitIntoQuads){ recombineIntoQuads(*it,true,true); } } for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it) Subdivide(*it, splitIntoHexas, faceVertices); double t2 = Cpu(); Msg::StatusBar(true, "Done refining mesh (%g s)", t2 - t1); }
void Centerline::run() { double t1 = Cpu(); if (update_needed){ std::ifstream input; //std::string pattern = FixRelativePath(fileName, "./"); //Msg::StatusBar(true, "Reading TEST '%s'...", pattern.c_str()); //input.open(pattern.c_str()); input.open(fileName.c_str()); if(StatFile(fileName)) Msg::Fatal("Centerline file '%s' does not exist ", fileName.c_str()); importFile(fileName); buildKdTree(); update_needed = false; } if (is_cut) cutMesh(); else{ GFace *gf = current->getFaceByTag(1); gf->addPhysicalEntity(1); current->setPhysicalName("wall", 2, 1);//tag 1 current->createTopologyFromMesh(); NV = current->getMaxElementaryNumber(0); NE = current->getMaxElementaryNumber(1); NF = current->getMaxElementaryNumber(2); NR = current->getMaxElementaryNumber(3); } //identify the boundary edges by looping over all discreteFaces std::vector<GEdge*> boundEdges; double dist_inlet = 1.e6; GEdge *gin = NULL; for (int i= 0; i< NF; i++){ GFace *gf = current->getFaceByTag(i+1); std::list<GEdge*> l_edges = gf->edges(); for(std::list<GEdge*>::iterator it = l_edges.begin(); it != l_edges.end(); it++){ std::vector<GEdge*>::iterator ite = std::find(boundEdges.begin(), boundEdges.end(), *it); if (ite != boundEdges.end()) boundEdges.erase(ite); else boundEdges.push_back(*it); GVertex *gv = (*it)->getBeginVertex(); SPoint3 pt(gv->x(), gv->y(), gv->z()); double dist = pt.distance(ptin); if(dist < dist_inlet){ dist_inlet = dist; gin = *it; } } } if (is_closed) createClosedVolume(gin, boundEdges); if (is_extruded) extrudeBoundaryLayerWall(gin, boundEdges); double t2 = Cpu(); Msg::Info("Centerline operators computed in %g (s) ",t2-t1); }
void Homology::findBettiNumbers() { if(!isBettiComputed()) { if(_cellComplex == NULL) _createCellComplex(); if(_cellComplex->isReduced()) _cellComplex->restoreComplex(); Msg::StatusBar(true, "Reducing cell complex..."); double t1 = Cpu(); double size1 = _cellComplex->getSize(-1); _cellComplex->bettiReduceComplex(); double t2 = Cpu(); double size2 = _cellComplex->getSize(-1); Msg::StatusBar(true, "Done reducing cell complex (%g s, %g %%)", t2 - t1, (1.-size2/size1)*100.); Msg::Info("%d volumes, %d faces, %d edges, and %d vertices", _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0)); Msg::StatusBar(true, "Computing betti numbers..."); t1 = Cpu(); ChainComplex chainComplex = ChainComplex(_cellComplex); chainComplex.computeHomology(); for(int i = 0; i < 4; i++) _betti[i] = chainComplex.getBasisSize(i, 3); t2 = Cpu(); Msg::StatusBar(true, "Betti numbers computed (%g s)", t2 - t1); } std::string domain = _getDomainString(_domain, _subdomain); Msg::Info("Domain %s Betti numbers:", domain.c_str()); Msg::Info("b0 = %d", _betti[0]); Msg::Info("b1 = %d", _betti[1]); Msg::Info("b2 = %d", _betti[2]); Msg::Info("b3 = %d", _betti[3]); Msg::StatusBar(false, "b0: %d, b1: %d, b2: %d, b3: %d", _betti[0], _betti[1], _betti[2], _betti[3]); }
/** Simulate a context switch that places a user program in execution. <b> Algorithm: </b> \verbatim Copy the given state into the CPU's state Resume execution of the program at the new PC--just call Cpu() \endverbatim @param[in] state -- program state to load into CPU */ void Exec_Program( struct state_type* state ) { //Copy the given state into the CPU's state CPU.state = *state; //~ printf("mode = %x\nseg = %d\noff = %d\n", CPU.state.mode, CPU.state.pc.segment, CPU.state.pc.offset); //Resume execution of the program at the new PC--just call Cpu() Cpu(); }
Cpu& Sched::getCpu(unsigned int cpu) { QMutableVectorIterator<Cpu> iter(cpus); while (iter.hasNext()) { Cpu &tmp = iter.next(); if (tmp.id == cpu) { return tmp; } } cpus.append(Cpu(cpu)); return cpus.last(); }
void Homology::_createCellComplex() { Msg::StatusBar(true, "Creating cell complex..."); double t1 = Cpu(); if(_domainEntities.empty()) Msg::Error("Domain is empty"); if(_subdomainEntities.empty()) Msg::Info("Subdomain is empty"); std::vector<MElement*> domainElements; std::vector<MElement*> subdomainElements; std::vector<MElement*> nondomainElements; std::vector<MElement*> nonsubdomainElements; std::vector<MElement*> immuneElements; _getElements(_domainEntities, domainElements); _getElements(_subdomainEntities, subdomainElements); _getElements(_nondomainEntities, nondomainElements); _getElements(_nonsubdomainEntities, nonsubdomainElements); _getElements(_immuneEntities, immuneElements); if(_cellComplex != NULL) delete _cellComplex; _cellComplex = new CellComplex(_model, domainElements, subdomainElements, nondomainElements, nonsubdomainElements, immuneElements, _saveOrig); if(_cellComplex->getSize(0) == 0) { Msg::Error("Cell Complex is empty: check the domain and the mesh"); } double t2 = Cpu(); Msg::StatusBar(true, "Done creating cell complex (%g s)", t2 - t1); Msg::Info("%d volumes, %d faces, %d edges, and %d vertices", _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0)); }
CpuView::CpuList CpuView::createList() { config()->setGroup("CpuPlugin"); CpuList list; int number = 0; TQStringList cpus = config()->readListEntry("Cpus"); TQStringList::ConstIterator it; for (it = cpus.begin(); it != cpus.end(); ++it) { list.append(Cpu((*it), config()->readEntry(CPU_NAME(number), "%T"), number)); ++number; } return list; }
void refineMeshBDS(GFace *gf, BDS_Mesh &m, const int NIT, const bool computeNodalSizeField, std::map<MVertex*, BDS_Point*> *recoverMapInv) { int IT = 0; int MAXNP = m.MAXPOINTNUMBER; // classify correctly the embedded vertices use a negative model // face number to avoid mesh motion if(recoverMapInv){ std::list<GVertex*> emb_vertx = gf->embeddedVertices(); std::list<GVertex*>::iterator itvx = emb_vertx.begin(); while(itvx != emb_vertx.end()){ MVertex *v = *((*itvx)->mesh_vertices.begin()); std::map<MVertex*, BDS_Point*>::iterator itp = recoverMapInv->find(v); if(itp != recoverMapInv->end()){ BDS_Point *p = itp->second; m.add_geom(-1, 2); p->g = m.get_geom(-1, 2); p->lc() = (*itvx)->prescribedMeshSizeAtVertex(); p->lcBGM() = (*itvx)->prescribedMeshSizeAtVertex(); ++itvx; } } } // If asked, compute nodal size field using 1D Mesh if (computeNodalSizeField){ std::set<BDS_Point*,PointLessThan>::iterator itp = m.points.begin(); while (itp != m.points.end()){ std::list<BDS_Edge*>::iterator it = (*itp)->edges.begin(); std::list<BDS_Edge*>::iterator ite = (*itp)->edges.end(); double L = 0; int ne = 0; while(it != ite){ double l = (*it)->length(); if ((*it)->g && (*it)->g->classif_degree == 1){ L = ne ? std::max(L, l) : l; ne++; } ++it; } if ((*itp)->g && (*itp)->g->classif_tag > 0){ if (!ne) L = MAX_LC; if(CTX::instance()->mesh.lcFromPoints) (*itp)->lc() = L; (*itp)->lcBGM() = L; } ++itp; } } double t_spl = 0, t_sw = 0,t_col = 0,t_sm = 0; const double MINE_ = 0.6666, MAXE_ = 1.4; while (1){ // we count the number of local mesh modifs. int nb_split = 0; int nb_smooth = 0; int nb_collaps = 0; int nb_swap = 0; // split long edges double minL = 1.e22, maxL = 0; int NN1 = m.edges.size(); int NN2 = 0; std::list<BDS_Edge*>::iterator it = m.edges.begin(); while (1){ if (NN2++ >= NN1)break; if (!(*it)->deleted){ (*it)->p1->config_modified = false; (*it)->p2->config_modified = false; double lone = NewGetLc(*it, gf, m.scalingU, m.scalingV); maxL = std::max(maxL, lone); minL = std::min(minL, lone); } ++it; } if ((minL > MINE_ && maxL < MAXE_) || IT > (abs(NIT))) break; double maxE = MAXE_; double minE = MINE_; double t1 = Cpu(); splitEdgePass(gf, m, maxE, nb_split); double t2 = Cpu(); swapEdgePass(gf, m, nb_swap); swapEdgePass(gf, m, nb_swap); swapEdgePass(gf, m, nb_swap); // if (computeNodalSizeField){ // char name[256]; sprintf(name,"iter%d_SPLIT.pos",IT); // outputScalarField(m.triangles, name, 0); // } double t3 = Cpu(); collapseEdgePass(gf, m, minE, MAXNP, nb_collaps); double t4 = Cpu(); double t5 = Cpu(); smoothVertexPass(gf, m, nb_smooth, false); double t6 = Cpu(); swapEdgePass ( gf, m, nb_swap); double t7 = Cpu(); // if (computeNodalSizeField){ // char name[256]; sprintf(name,"iter%d_COLLAPSE.pos",IT); // outputScalarField(m.triangles, name, 0); // } // clean up the mesh t_spl += t2 - t1; t_sw += t3 - t2; t_sw += t5 - t4; t_sw += t7 - t6; t_col += t4 - t3; t_sm += t6 - t5; m.cleanup(); IT++; Msg::Debug(" iter %3d minL %8.3f/%8.3f maxL %8.3f/%8.3f : " "%6d splits, %6d swaps, %6d collapses, %6d moves", IT, minL, minE, maxL, maxE, nb_split, nb_swap, nb_collaps, nb_smooth); if (nb_split == 0 && nb_collaps == 0) break; } double t_total = t_spl + t_sw + t_col + t_sm; if(!t_total) t_total = 1.e-6; Msg::Debug(" ---------------------------------------"); Msg::Debug(" CPU Report "); Msg::Debug(" ---------------------------------------"); Msg::Debug(" CPU SWAP %12.5E sec (%3.0f %%)", t_sw,100 * t_sw / t_total); Msg::Debug(" CPU SPLIT %12.5E sec (%3.0f %%) ", t_spl,100 * t_spl / t_total); Msg::Debug(" CPU COLLAPS %12.5E sec (%3.0f %%) ", t_col,100 * t_col / t_total); Msg::Debug(" CPU SMOOTH %12.5E sec (%3.0f %%) ", t_sm,100 * t_sm / t_total); Msg::Debug(" ---------------------------------------"); Msg::Debug(" CPU TOTAL %12.5E sec ",t_total); Msg::Debug(" ---------------------------------------"); }
bool eigenSolver::solve(int numEigenValues, std::string which) { if(!_A) return false; Mat A = _A->getMatrix(); Mat B = _B ? _B->getMatrix() : PETSC_NULL; PetscInt N, M; _try(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); _try(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); _try(MatGetSize(A, &N, &M)); PetscInt N2, M2; if (_B) { _try(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); _try(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); _try(MatGetSize(B, &N2, &M2)); } // generalized eigenvalue problem A x - \lambda B x = 0 EPS eps; _try(EPSCreate(PETSC_COMM_WORLD, &eps)); _try(EPSSetOperators(eps, A, B)); if(_hermitian) _try(EPSSetProblemType(eps, _B ? EPS_GHEP : EPS_HEP)); else _try(EPSSetProblemType(eps, _B ? EPS_GNHEP : EPS_NHEP)); // set some default options _try(EPSSetDimensions(eps, numEigenValues, PETSC_DECIDE, PETSC_DECIDE)); _try(EPSSetTolerances(eps, 1.e-7, 20));//1.e-7 20 _try(EPSSetType(eps, EPSKRYLOVSCHUR)); //default //_try(EPSSetType(eps, EPSARNOLDI)); //_try(EPSSetType(eps, EPSARPACK)); //_try(EPSSetType(eps, EPSPOWER)); // override these options at runtime, petsc-style _try(EPSSetFromOptions(eps)); // force options specified directly as arguments if(numEigenValues) _try(EPSSetDimensions(eps, numEigenValues, PETSC_DECIDE, PETSC_DECIDE)); if(which == "smallest") _try(EPSSetWhichEigenpairs(eps, EPS_SMALLEST_MAGNITUDE)); else if(which == "smallestReal") _try(EPSSetWhichEigenpairs(eps, EPS_SMALLEST_REAL)); else if(which == "largest") _try(EPSSetWhichEigenpairs(eps, EPS_LARGEST_MAGNITUDE)); // print info #if (SLEPC_VERSION_RELEASE == 0 || (SLEPC_VERSION_MAJOR > 3 || (SLEPC_VERSION_MAJOR == 3 && SLEPC_VERSION_MINOR >= 4))) EPSType type; #else const EPSType type; #endif _try(EPSGetType(eps, &type)); Msg::Debug("SLEPc solution method: %s", type); PetscInt nev; _try(EPSGetDimensions(eps, &nev, PETSC_NULL, PETSC_NULL)); Msg::Debug("SLEPc number of requested eigenvalues: %d", nev); PetscReal tol; PetscInt maxit; _try(EPSGetTolerances(eps, &tol, &maxit)); Msg::Debug("SLEPc stopping condition: tol=%g, maxit=%d", tol, maxit); // solve Msg::Info("SLEPc solving..."); double t1 = Cpu(); _try(EPSSolve(eps)); // check convergence int its; _try(EPSGetIterationNumber(eps, &its)); EPSConvergedReason reason; _try(EPSGetConvergedReason(eps, &reason)); if(reason == EPS_CONVERGED_TOL){ double t2 = Cpu(); Msg::Debug("SLEPc converged in %d iterations (%g s)", its, t2-t1); } else if(reason == EPS_DIVERGED_ITS) Msg::Error("SLEPc diverged after %d iterations", its); else if(reason == EPS_DIVERGED_BREAKDOWN) Msg::Error("SLEPc generic breakdown in method"); #if (SLEPC_VERSION_MAJOR < 3 || (SLEPC_VERSION_MAJOR == 3 && SLEPC_VERSION_MINOR < 2)) else if(reason == EPS_DIVERGED_NONSYMMETRIC) Msg::Error("The operator is nonsymmetric"); #endif // get number of converged approximate eigenpairs PetscInt nconv; _try(EPSGetConverged(eps, &nconv)); Msg::Debug("SLEPc number of converged eigenpairs: %d", nconv); // ignore additional eigenvalues if we get more than what we asked if(nconv > nev) nconv = nev; if (nconv > 0) { Vec xr, xi; _try(MatGetVecs(A, PETSC_NULL, &xr)); _try(MatGetVecs(A, PETSC_NULL, &xi)); Msg::Debug(" Re[EigenValue] Im[EigenValue]" " Relative error"); for (int i = 0; i < nconv; i++){ PetscScalar kr, ki; _try(EPSGetEigenpair(eps, i, &kr, &ki, xr, xi)); PetscReal error; _try(EPSComputeRelativeError(eps, i, &error)); #if defined(PETSC_USE_COMPLEX) PetscReal re = PetscRealPart(kr); PetscReal im = PetscImaginaryPart(kr); #else PetscReal re = kr; PetscReal im = ki; #endif Msg::Debug("EIG %03d %s%.16e %s%.16e %3.6e", i, (re < 0) ? "" : " ", re, (im < 0) ? "" : " ", im, error); // store eigenvalues and eigenvectors _eigenValues.push_back(std::complex<double>(re, im)); PetscScalar *tmpr, *tmpi; _try(VecGetArray(xr, &tmpr)); _try(VecGetArray(xi, &tmpi)); std::vector<std::complex<double> > ev(N); for(int i = 0; i < N; i++){ #if defined(PETSC_USE_COMPLEX) ev[i] = tmpr[i]; #else ev[i] = std::complex<double>(tmpr[i], tmpi[i]); #endif } _eigenVectors.push_back(ev); } _try(VecDestroy(&xr)); _try(VecDestroy(&xi)); } _try(EPSDestroy(&eps)); if(reason == EPS_CONVERGED_TOL){ Msg::Debug("SLEPc done"); return true; } else{ Msg::Warning("SLEPc failed"); return false; } }
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 CShutdownDevice::Interrupt() { Cpu().Stop(); }
void Homology::findCohomologyBasis(std::vector<int> dim) { double t0 = Cpu(); std::string domain = _getDomainString(_domain, _subdomain); Msg::Info(""); Msg::Info("To compute domain (%s) cohomology spaces", domain.c_str()); if(dim.empty()) { findBettiNumbers(); return; } if(_cellComplex == NULL) _createCellComplex(); if(_cellComplex->isReduced()) _cellComplex->restoreComplex(); Msg::StatusBar(true, "Reducing cell complex..."); double t1 = Cpu(); double size1 = _cellComplex->getSize(-1); _cellComplex->coreduceComplex(_combine, _omit, _heuristic); std::sort(dim.begin(), dim.end()); if(_combine > 1) { for(int i = 2; i >= 0; i--) { if(!std::binary_search(dim.begin(), dim.end(), i)) { _cellComplex->combine(i+1); } } } double t2 = Cpu(); double size2 = _cellComplex->getSize(-1); Msg::StatusBar(true, "Done reducing cell complex (%g s, %g %%)", t2 - t1, (1.-size2/size1)*100.); Msg::Info("%d volumes, %d faces, %d edges, and %d vertices", _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0)); Msg::StatusBar(true, "Computing cohomology space bases ..."); t1 = Cpu(); ChainComplex chainComplex = ChainComplex(_cellComplex); chainComplex.computeHomology(true); t2 = Cpu(); Msg::StatusBar(true, "Done computing cohomology space bases (%g s)", t2- t1); _deleteCochains(dim); for(int i = 0; i < 4; i++) _betti[i] = 0; for(int j = 3; j > -1; j--){ std::string dimension = convertInt(j); for(int i = 1; i <= chainComplex.getBasisSize(j, 3); i++){ std::string generator = convertInt(i); std::string name = "H^" + dimension + domain + generator; std::map<Cell*, int, Less_Cell> chain; chainComplex.getBasisChain(chain, i, j, 3, false); int torsion = chainComplex.getTorsion(j,i); if(!chain.empty()) { _createChain(chain, name, true); _betti[j] = _betti[j] + 1; if(torsion != 1){ Msg::Warning("H^%d %d has torsion coefficient %d!", j, i, torsion); } } } } if(_fileName != "") writeBasisMSH(); Msg::Info("Ranks of domain (%s) cohomology spaces:", domain.c_str()); Msg::Info("H^0 = %d", _betti[0]); Msg::Info("H^1 = %d", _betti[1]); Msg::Info("H^2 = %d", _betti[2]); Msg::Info("H^3 = %d", _betti[3]); double t3 = Cpu(); Msg::Info("Done computing (%s) cohomology spaces (%g s)", domain.c_str(), t3 - t0); Msg::StatusBar(false, "H^0: %d, H^1: %d, H^2: %d, H^3: %d", _betti[0], _betti[1], _betti[2], _betti[3]); for(unsigned int i = 0; i < dim.size(); i++) { int d = dim.at(i); if(d >= 0 && d < 4) _cohomologyComputed[d] = true; } }
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 }
bool Filler3D::treat_region(GRegion *gr) { BGMManager::set_use_cross_field(true); bool use_vectorial_smoothness; bool use_fifo; std::string algo; // readValue("param.dat","SMOOTHNESSALGO",algo); algo.assign("SCALAR"); if(!algo.compare("SCALAR")) { use_vectorial_smoothness = false; use_fifo = false; } else if(!algo.compare("FIFO")) { use_vectorial_smoothness = false; use_fifo = true; } else { std::cout << "unknown SMOOTHNESSALGO !" << std::endl; throw; } const bool debug = false; const bool export_stuff = true; double a; std::cout << "ENTERING POINTINSERTION3D" << std::endl; // acquire background mesh std::cout << "pointInsertion3D: recover BGM" << std::endl; a = Cpu(); frameFieldBackgroundMesh3D *bgm = dynamic_cast<frameFieldBackgroundMesh3D *>(BGMManager::get(gr)); time_smoothing += (Cpu() - a); if(!bgm) { std::cout << "pointInsertion3D:: BGM dynamic cast failed ! " << std::endl; throw; } // export BGM fields if(export_stuff) { std::cout << "pointInsertion3D: export size field " << std::endl; std::stringstream ss; ss << "bg3D_sizefield_" << gr->tag() << ".pos"; bgm->exportSizeField(ss.str()); std::cout << "pointInsertion3D : export crossfield " << std::endl; std::stringstream sscf; sscf << "bg3D_crossfield_" << gr->tag() << ".pos"; bgm->exportCrossField(sscf.str()); std::cout << "pointInsertion3D : export smoothness " << std::endl; std::stringstream sss; sss << "bg3D_smoothness_" << gr->tag() << ".pos"; bgm->exportSmoothness(sss.str()); if(use_vectorial_smoothness) { std::cout << "pointInsertion3D : export vectorial smoothness " << std::endl; std::stringstream ssvs; ssvs << "bg3D_vectorial_smoothness_" << gr->tag() << ".pos"; bgm->exportVectorialSmoothness(ssvs.str()); } } // ---------------- START FILLING NEW POINTS ---------------- std::cout << "pointInsertion3D : inserting points in region " << gr->tag() << std::endl; // ProfilerStart("/home/bernard/profile"); a = Cpu(); // ----- initialize fifo list ----- RTree<MVertex *, double, 3, double> rtree; listOfPoints *fifo; if(use_fifo) fifo = new listOfPointsFifo(); else if(use_vectorial_smoothness) fifo = new listOfPointsVectorialSmoothness(); else fifo = new listOfPointsScalarSmoothness(); std::set<MVertex *> temp; std::vector<MVertex *> boundary_vertices; std::map<MVertex *, int> vert_priority; std::map<MVertex *, double> smoothness_forplot; MElement *element; MVertex *vertex; std::vector<GFace *> faces = gr->faces(); for(std::vector<GFace *>::iterator it = faces.begin(); it != faces.end(); it++) { GFace *gf = *it; // int limit = code_kesskessai(gf->tag()); for(unsigned int i = 0; i < gf->getNumMeshElements(); i++) { element = gf->getMeshElement(i); for(std::size_t j = 0; j < element->getNumVertices(); j++) { // for all vertices vertex = element->getVertex(j); temp.insert(vertex); // limits.insert(make_pair(vertex,limit)); } } } int geodim; for(std::set<MVertex *>::iterator it = temp.begin(); it != temp.end(); it++) { geodim = (*it)->onWhat()->dim(); if((geodim == 0) || (geodim == 1) || (geodim == 2)) boundary_vertices.push_back(*it); } double min[3], max[3], x, y, z, h; for(unsigned int i = 0; i < boundary_vertices.size(); i++) { x = boundary_vertices[i]->x(); y = boundary_vertices[i]->y(); z = boundary_vertices[i]->z(); // "on boundary since working on boundary_vertices ... MVertex *closest = bgm->get_nearest_neighbor_on_boundary(boundary_vertices[i]); h = bgm->size(closest); // get approximate size, closest vertex, faster ?! fill_min_max(x, y, z, h, min, max); rtree.Insert(min, max, boundary_vertices[i]); if(!use_vectorial_smoothness) { smoothness_vertex_pair *svp = new smoothness_vertex_pair(); svp->v = boundary_vertices[i]; svp->rank = bgm->get_smoothness(x, y, z); svp->dir = 0; svp->layer = 0; svp->size = h; bgm->eval_approximate_crossfield(closest, svp->cf); fifo->insert(svp); if(debug) { smoothness_forplot[svp->v] = svp->rank; } } else { STensor3 temp; bgm->eval_approximate_crossfield(closest, temp); for(int idir = 0; idir < 3; idir++) { smoothness_vertex_pair *svp = new smoothness_vertex_pair(); svp->v = boundary_vertices[i]; svp->rank = bgm->get_vectorial_smoothness(idir, x, y, z); svp->dir = idir; svp->layer = 0; svp->size = h; svp->cf = temp; for(int k = 0; k < 3; k++) svp->direction(k) = temp(k, idir); // std::cout << "fifo size=" << fifo->size() << " inserting " ; fifo->insert(svp); // std::cout << " -> fifo size=" << fifo->size() << std::endl; } } } // TODO: si fifo était list of *PTR -> pas de copies, gain temps ? Wrapper3D wrapper; wrapper.set_bgm(bgm); MVertex *parent, *individual; new_vertices.clear(); bool spawn_created; int priority_counter = 0; STensor3 crossfield; int parent_layer; while(!fifo->empty()) { parent = fifo->get_first_vertex(); // parent_limit = fifo->get_first_limit(); parent_layer = fifo->get_first_layer(); // if(parent_limit!=-1 && parent_layer>=parent_limit()){ // continue; // } std::vector<MVertex *> spawns; if(!use_vectorial_smoothness) { spawns.resize(6); computeSixNeighbors(bgm, parent, spawns, fifo->get_first_crossfield(), fifo->get_first_size()); } else { spawns.resize(2); computeTwoNeighbors(bgm, parent, spawns, fifo->get_first_direction(), fifo->get_first_size()); } fifo->erase_first(); // std::cout << "while, fifo->size()=" << fifo->size() << " parent=(" << // parent->x() << "," << parent->y() << "," << parent->z() << ")" << // std::endl; for(unsigned int i = 0; i < spawns.size(); i++) { spawn_created = false; individual = spawns[i]; x = individual->x(); y = individual->y(); z = individual->z(); // std::cout << " working on candidate " << "(" << individual->x() << // "," // << individual->y() << "," << individual->z() << ")" << std::endl; if(bgm->inDomain(x, y, z)) { // std::cout << " spawn " << i << " in domain" << std::endl; MVertex *closest = bgm->get_nearest_neighbor(individual); h = bgm->size(closest); // get approximate size, closest vertex, faster ?! if(far_from_boundary_3D(bgm, individual, h)) { // std::cout << " spawn " << i << " far from bnd" << // std::endl; bgm->eval_approximate_crossfield(closest, crossfield); wrapper.set_ok(true); wrapper.set_individual(individual); wrapper.set_parent(parent); wrapper.set_size(&h); wrapper.set_crossfield(&crossfield); fill_min_max(x, y, z, h, min, max); rtree.Search(min, max, rtree_callback_3D, &wrapper); if(wrapper.get_ok()) { // std::cout << " spawn " << i << " wrapper OK" << // std::endl; if(!use_vectorial_smoothness) { smoothness_vertex_pair *svp = new smoothness_vertex_pair(); svp->v = individual; svp->rank = bgm->get_smoothness(individual->x(), individual->y(), individual->z()); svp->dir = 0; svp->layer = parent_layer + 1; svp->size = h; svp->cf = crossfield; fifo->insert(svp); if(debug) { smoothness_forplot[svp->v] = svp->rank; vert_priority[individual] = priority_counter++; } } else { if(debug) vert_priority[individual] = priority_counter++; for(int idir = 0; idir < 3; idir++) { smoothness_vertex_pair *svp = new smoothness_vertex_pair(); svp->v = individual; svp->rank = bgm->get_vectorial_smoothness(idir, x, y, z); svp->dir = idir; svp->layer = parent_layer + 1; svp->size = h; for(int k = 0; k < 3; k++) svp->direction(k) = crossfield(k, idir); svp->cf = crossfield; fifo->insert(svp); } } rtree.Insert(min, max, individual); new_vertices.push_back(individual); spawn_created = true; } } } if(!spawn_created) { delete individual; } } // end loop on spawns } // ProfilerStop(); time_insert_points += (Cpu() - a); // --- output --- if(debug) { std::stringstream ss; ss << "priority_3D_" << gr->tag() << ".pos"; print_nodal_info(ss.str().c_str(), vert_priority); ss.clear(); std::stringstream sss; sss << "smoothness_3D_" << gr->tag() << ".pos"; print_nodal_info(sss.str().c_str(), smoothness_forplot); sss.clear(); } // ------- meshing using new points std::cout << "tets in gr before= " << gr->tetrahedra.size() << std::endl; std::cout << "nb new vertices= " << new_vertices.size() << std::endl; a = Cpu(); int option = CTX::instance()->mesh.algo3d; CTX::instance()->mesh.algo3d = ALGO_3D_DELAUNAY; deMeshGRegion deleter; deleter(gr); std::vector<GRegion *> regions; regions.push_back(gr); meshGRegion mesher(regions); //? mesher(gr); //? MeshDelaunayVolume(regions); time_meshing += (Cpu() - a); std::cout << "tets in gr after= " << gr->tetrahedra.size() << std::endl; std::cout << "gr tag=" << gr->tag() << std::endl; CTX::instance()->mesh.algo3d = option; delete fifo; for(unsigned int i = 0; i < new_vertices.size(); i++) delete new_vertices[i]; new_vertices.clear(); rtree.RemoveAll(); return true; }
void Filler2D::pointInsertion2D(GFace *gf, std::vector<MVertex *> &packed, std::vector<SMetric3> &metrics) { // NB/ do not use the mesh in GFace, use the one in backgroundMesh2D! // if(debug) std::cout << " ------------------ OLD -------------------" << // std::endl; stringstream ssa; //// ssa << "oldbgm_angles_" << gf->tag() << ".pos"; //// backgroundMesh::current()->print(ssa.str(),gf,1); // ssa << "oldbgm_sizes_" << gf->tag() << ".pos"; // backgroundMesh::current()->print(ssa.str(),gf,0); // // // // // if(debug) std::cout << " ------------------ NEW -------------------" << // std::endl; backgroundMesh2D *bgm2 = // dynamic_cast<backgroundMesh2D*>(BGMManager::get(gf)); stringstream ss2; // ss2 << "basebg_sizefield_" << gf->tag() << ".pos"; // bgm2->exportSizeField(ss2.str()); // // // // return; // BGMManager::set_use_cross_field(true); const bool goNonLinear = true; const bool debug = false; const bool export_stuff = true; if(debug) std::cout << "ENTERING POINTINSERTION2D" << std::endl; double a; // acquire background mesh if(debug) std::cout << "pointInsertion2D: recover BGM" << std::endl; a = Cpu(); frameFieldBackgroundMesh2D *bgm = dynamic_cast<frameFieldBackgroundMesh2D *>(BGMManager::get(gf)); time_bgm_and_smoothing += (Cpu() - a); if(!bgm) { Msg::Error("BGM dynamic cast failed in filler2D::pointInsertion2D"); return; } // export BGM size field if(export_stuff) { std::cout << "pointInsertion2D: export size field " << std::endl; std::stringstream ss; ss << "bg2D_sizefield_" << gf->tag() << ".pos"; bgm->exportSizeField(ss.str()); std::cout << "pointInsertion2D : export crossfield " << std::endl; std::stringstream sscf; sscf << "bg2D_crossfield_" << gf->tag() << ".pos"; bgm->exportCrossField(sscf.str()); std::cout << "pointInsertion2D : export smoothness " << std::endl; std::stringstream sss; sss << "bg2D_smoothness_" << gf->tag() << ".pos"; bgm->exportSmoothness(sss.str()); } // point insertion algorithm: a = Cpu(); // for debug check... int priority_counter = 0; std::map<MVertex *, int> vert_priority; // get all the boundary vertices if(debug) std::cout << "pointInsertion2D : get bnd vertices " << std::endl; std::set<MVertex *> bnd_vertices = bgm->get_vertices_of_maximum_dim(1); // put boundary vertices in a fifo queue std::set<smoothness_point_pair, compareSurfacePointWithExclusionRegionPtr_Smoothness> fifo; std::vector<surfacePointWithExclusionRegion *> vertices; // initiate the rtree if(debug) std::cout << "pointInsertion2D : initiate RTree " << std::endl; RTree<surfacePointWithExclusionRegion *, double, 2, double> rtree; SMetric3 metricField(1.0); SPoint2 newp[4][NUMDIR]; std::set<MVertex *>::iterator it = bnd_vertices.begin(); for(; it != bnd_vertices.end(); ++it) { SPoint2 midpoint; computeFourNeighbors(bgm, *it, midpoint, goNonLinear, newp, metricField); surfacePointWithExclusionRegion *sp = new surfacePointWithExclusionRegion(*it, newp, midpoint, metricField); smoothness_point_pair mp; mp.ptr = sp; mp.rank = (1. - bgm->get_smoothness(midpoint[0], midpoint[1])); fifo.insert(mp); vertices.push_back(sp); double _min[2], _max[2]; sp->minmax(_min, _max); rtree.Insert(_min, _max, sp); } // ---------- main loop ----------------- while(!fifo.empty()) { if(debug) std::cout << " -------- fifo.size() = " << fifo.size() << std::endl; int count_nbaddedpt = 0; surfacePointWithExclusionRegion *parent = (*fifo.begin()).ptr; fifo.erase(fifo.begin()); for(int dir = 0; dir < NUMDIR; dir++) { for(int i = 0; i < 4; i++) { if(!inExclusionZone(parent->_p[i][dir], rtree, vertices)) { GPoint gp = gf->point(parent->_p[i][dir]); MFaceVertex *v = new MFaceVertex(gp.x(), gp.y(), gp.z(), gf, gp.u(), gp.v()); SPoint2 midpoint; computeFourNeighbors(bgm, v, midpoint, goNonLinear, newp, metricField); surfacePointWithExclusionRegion *sp = new surfacePointWithExclusionRegion(v, newp, midpoint, metricField, parent); smoothness_point_pair mp; mp.ptr = sp; mp.rank = (1. - bgm->get_smoothness(gp.u(), gp.v())); if(debug) vert_priority[v] = priority_counter++; fifo.insert(mp); vertices.push_back(sp); double _min[2], _max[2]; sp->minmax(_min, _max); rtree.Insert(_min, _max, sp); if(debug) { std::cout << " adding node (" << sp->_v->x() << "," << sp->_v->y() << "," << sp->_v->z() << ")" << std::endl; std::cout << " ----------------------------- sub --- fifo.size() = " << fifo.size() << std::endl; } count_nbaddedpt++; } } } if(debug) std::cout << "////////// nbre of added point: " << count_nbaddedpt << std::endl; } time_insertion += (Cpu() - a); if(debug) { std::stringstream ss; ss << "priority_" << gf->tag() << ".pos"; print_nodal_info(ss.str().c_str(), vert_priority); ss.clear(); } // add the vertices as additional vertices in the // surface mesh char ccc[256]; sprintf(ccc, "points%d.pos", gf->tag()); FILE *f = Fopen(ccc, "w"); if(f) { fprintf(f, "View \"\"{\n"); for(unsigned int i = 0; i < vertices.size(); i++) { vertices[i]->print(f, i); if(vertices[i]->_v->onWhat() == gf) { packed.push_back(vertices[i]->_v); metrics.push_back(vertices[i]->_meshMetric); SPoint2 midpoint; reparamMeshVertexOnFace(vertices[i]->_v, gf, midpoint); } delete vertices[i]; } fprintf(f, "};"); fclose(f); } }
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 }
// Main function for fast curving void HighOrderMeshFastCurving(GModel *gm, FastCurvingParameters &p) { double t1 = Cpu(); Msg::StatusBar(true, "Optimizing high order mesh..."); std::vector<GEntity*> allEntities; gm->getEntities(allEntities); // Compute vert. -> elt. connectivity Msg::Info("Computing connectivity..."); std::map<MVertex*, std::vector<MElement *> > vertex2elements; for (int iEnt = 0; iEnt < allEntities.size(); ++iEnt) calcVertex2Elements(p.dim, allEntities[iEnt], vertex2elements); // Get BL field (if any) BoundaryLayerField *blf = getBLField(gm); // Build multimap of each geometric entity to its boundaries std::multimap<GEntity*,GEntity*> entities; if (blf) { // BF field? for (int iEnt = 0; iEnt < allEntities.size(); ++iEnt) { GEntity* &entity = allEntities[iEnt]; if (entity->dim() == p.dim && (!p.onlyVisible || entity->getVisibility())) // Consider only "domain" entities if (p.dim == 2) { // "Domain" face? std::list<GEdge*> edges = entity->edges(); for (std::list<GEdge*>::iterator itEd = edges.begin(); itEd != edges.end(); itEd++) // Loop over model boundary edges if (blf->isEdgeBL((*itEd)->tag())) // Already skip model edge if no BL there entities.insert(std::pair<GEntity*,GEntity*>(entity, *itEd)); } else if (p.dim == 3) { // "Domain" region? std::list<GFace*> faces = entity->faces(); for (std::list<GFace*>::iterator itF = faces.begin(); itF != faces.end(); itF++) // Loop over model boundary faces if (blf->isFaceBL((*itF)->tag())) // Already skip model face if no BL there entities.insert(std::pair<GEntity*,GEntity*>(entity, *itF)); } } } else { // No BL field for (int iEnt = 0; iEnt < allEntities.size(); ++iEnt) { GEntity* &entity = allEntities[iEnt]; if (entity->dim() == p.dim-1 && (!p.onlyVisible || entity->getVisibility())) // Consider boundary entities entities.insert(std::pair<GEntity*,GEntity*>(0, entity)); } } // Build normals if necessary std::map<GEntity*, std::map<MVertex*, SVector3> > normVertEnt; // Normal to each vertex for each geom. entity if (!blf) { Msg::Warning("Boundary layer data not found, trying to detect columns"); buildNormals(vertex2elements, entities, p, normVertEnt); } // Loop over geometric entities for (std::multimap<GEntity*,GEntity*>::iterator itBE = entities.begin(); itBE != entities.end(); itBE++) { GEntity *domEnt = itBE->first, *bndEnt = itBE->second; BoundaryLayerColumns *blc = 0; if (blf) { Msg::Info("Curving elements for entity %d bounding entity %d...", bndEnt->tag(), domEnt->tag()); if (p.dim == 2) blc = domEnt->cast2Face()->getColumns(); else if (p.dim == 3) blc = domEnt->cast2Region()->getColumns(); else Msg::Error("Fast curving implemented only in dim. 2 and 3"); } else Msg::Info("Curving elements for boundary entity %d...", bndEnt->tag()); std::map<MVertex*, SVector3> &normVert = normVertEnt[bndEnt]; curveMeshFromBnd(vertex2elements, normVert, blc, bndEnt, p); } double t2 = Cpu(); Msg::StatusBar(true, "Done curving high order mesh (%g s)", t2-t1); }