Example #1
0
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);
}
Example #2
0
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);
}
Example #3
0
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]);
}
Example #4
0
/**
	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();
}
Example #5
0
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();
}
Example #6
0
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));
}
Example #7
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;
}
Example #8
0
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(" ---------------------------------------");
}
Example #9
0
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;
  }

}
Example #10
0
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
}
Example #11
0
void CShutdownDevice::Interrupt()
{
    Cpu().Stop();
}
Example #12
0
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;
  }
}
Example #13
0
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
}
Example #14
0
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;
}
Example #15
0
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);
  }
}
Example #16
0
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
}
Example #17
0
// 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);
}