Skip to content
Snippets Groups Projects
Generator.cpp 33.6 KiB
Newer Older
// Gmsh - Copyright (C) 1997-2016 C. Geuzaine, J.-F. Remacle
Christophe Geuzaine's avatar
Christophe Geuzaine committed
//
Christophe Geuzaine's avatar
Christophe Geuzaine committed
// See the LICENSE.txt file for license information. Please report all
Christophe Geuzaine's avatar
Christophe Geuzaine committed
// bugs and problems to the public mailing list <gmsh@onelab.info>.
Claudine Bon's avatar
Claudine Bon committed
#include <stdlib.h>
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#include "OS.h"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#include "GModel.h"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#include "MPoint.h"
#include "MLine.h"
#include "MTriangle.h"
#include "MQuadrangle.h"
#include "MTetrahedron.h"
#include "MHexahedron.h"
#include "MPrism.h"
#include "MPyramid.h"
#include "meshGEdge.h"
#include "meshGFace.h"
#include "meshGFaceOptimize.h"
#include "meshGFaceBDS.h"
#include "meshGRegion.h"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#include "BackgroundMesh.h"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
#include "HighOrder.h"
#include "Generator.h"
Christophe Geuzaine's avatar
Christophe Geuzaine committed
#include "meshGFaceLloyd.h"
#include "GFaceCompound.h"
#include "Options.h"
#include "simple3D.h"
#include "meshGRegionRelocateVertex.h"
#if defined(HAVE_OPTHOM)
#include "OptHomRun.h"
#include "OptHomElastic.h"
#endif

#if defined(HAVE_POST)
static void GetQualityMeasure(std::vector<T*> &ele,
                              double &gamma, double &gammaMin, double &gammaMax,
                              double &minSICN, double &minSICNMin, double &minSICNMax,
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
                              double &rho, double &rhoMin, double &rhoMax,
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
{
  for(unsigned int i = 0; i < ele.size(); i++){
    double g = ele[i]->gammaShapeMeasure();
    gamma += g;
    gammaMin = std::min(gammaMin, g);
    gammaMax = std::max(gammaMax, g);
    double s = ele[i]->minSICNShapeMeasure();
    minSICN += s;
    minSICNMin = std::min(minSICNMin, s);
    minSICNMax = std::max(minSICNMax, s);
    double r = ele[i]->rhoShapeMeasure();
    rho += r;
    rhoMin = std::min(rhoMin, r);
    rhoMax = std::max(rhoMax, r);
    for(int j = 0; j < 100; j++){
      if(s > (2*j-100) / 100. && s <= (2*j-98) / 100.) quality[0][j]++;
      if(g > j / 100. && g <= (j + 1) / 100.) quality[1][j]++;
      if(r > j / 100. && r <= (j + 1) / 100.) quality[2][j]++;
    }
  }
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
}

void GetStatistics(double stat[50], double quality[3][100])
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
{
  for(int i = 0; i < 50; i++) stat[i] = 0.;

Christophe Geuzaine's avatar
Christophe Geuzaine committed
  GModel *m = GModel::current();

Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  if(!m) return;

  stat[0] = m->getNumVertices();
  stat[1] = m->getNumEdges();
  stat[2] = m->getNumFaces();
  stat[3] = m->getNumRegions();
  std::map<int, std::vector<GEntity*> > physicals[4];
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  m->getPhysicalGroups(physicals);
  stat[45] = physicals[0].size() + physicals[1].size() +
    physicals[2].size() + physicals[3].size();
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); ++it)
    stat[4] += (*it)->mesh_vertices.size();
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it){
    // TODO: make this an option! if((*it)->getVisibility()){
    stat[5] += (*it)->mesh_vertices.size();
    stat[7] += (*it)->triangles.size();
    stat[8] += (*it)->quadrangles.size();
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it){
    stat[6] += (*it)->mesh_vertices.size();
    stat[9] += (*it)->tetrahedra.size();
    stat[10] += (*it)->hexahedra.size();
    stat[11] += (*it)->prisms.size();
    stat[12] += (*it)->pyramids.size();
    stat[13] += (*it)->trihedra.size();
  stat[14] = CTX::instance()->meshTimer[0];
  stat[15] = CTX::instance()->meshTimer[1];
  stat[16] = CTX::instance()->meshTimer[2];
  if(quality){
    for(int i = 0; i < 3; i++)
      for(int j = 0; j < 100; j++)
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
        quality[i][j] = 0.;
    double minSICN = 0., minSICNMin = 1., minSICNMax = -1.;
Christophe Geuzaine's avatar
Christophe Geuzaine committed
    double gamma = 0., gammaMin = 1., gammaMax = 0.;
    double rho = 0., rhoMin = 1., rhoMax = 0.;

    double N = stat[9] + stat[10] + stat[11] + stat[12] + stat[13];
Christophe Geuzaine's avatar
Christophe Geuzaine committed
    if(N){ // if we have 3D elements
      for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it){
        GetQualityMeasure((*it)->tetrahedra, gamma, gammaMin, gammaMax,
                          minSICN, minSICNMin, minSICNMax, rho, rhoMin, rhoMax, quality);
        GetQualityMeasure((*it)->hexahedra, gamma, gammaMin, gammaMax,
                          minSICN, minSICNMin, minSICNMax, rho, rhoMin, rhoMax, quality);
        GetQualityMeasure((*it)->prisms, gamma, gammaMin, gammaMax,
                          minSICN, minSICNMin, minSICNMax, rho, rhoMin, rhoMax, quality);
        GetQualityMeasure((*it)->pyramids, gamma, gammaMin, gammaMax,
                          minSICN, minSICNMin, minSICNMax, rho, rhoMin, rhoMax, quality);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    }
Christophe Geuzaine's avatar
Christophe Geuzaine committed
    else{ // 2D elements
      N = stat[7] + stat[8];
      for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it){
        GetQualityMeasure((*it)->quadrangles, gamma, gammaMin, gammaMax,
                          minSICN, minSICNMin, minSICNMax, rho, rhoMin, rhoMax, quality);
Christophe Geuzaine's avatar
Christophe Geuzaine committed
        GetQualityMeasure((*it)->triangles, gamma, gammaMin, gammaMax,
                          minSICN, minSICNMin, minSICNMax, rho, rhoMin, rhoMax, quality);
Christophe Geuzaine's avatar
Christophe Geuzaine committed
      }
    }
    if(N){
      stat[18] = minSICN / N; stat[19] = minSICNMin; stat[20] = minSICNMax;
      stat[21] = gamma / N;   stat[22] = gammaMin;   stat[23] = gammaMax;
      stat[25] = rho / N;     stat[25] = rhoMin;     stat[26] = rhoMax;
Christophe Geuzaine's avatar
Christophe Geuzaine committed
    }
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed

#if defined(HAVE_POST)
  stat[27] = PView::list.size();
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  for(unsigned int i = 0; i < PView::list.size(); i++) {
Christophe Geuzaine's avatar
Christophe Geuzaine committed
    PViewData *data = PView::list[i]->getData(true);
    stat[28] += data->getNumPoints();
    stat[29] += data->getNumLines();
    stat[30] += data->getNumTriangles();
    stat[31] += data->getNumQuadrangles();
    stat[32] += data->getNumTetrahedra();
    stat[33] += data->getNumHexahedra();
    stat[34] += data->getNumPrisms();
    stat[35] += data->getNumPyramids();
    stat[36] += data->getNumStrings2D() + data->getNumStrings3D();
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  }
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
static bool TooManyElements(GModel *m, int dim)
  if(CTX::instance()->expertMode || !m->getNumVertices()) return false;

  // try to detect obvious mistakes in characteristic lenghts (one of
  // the most common cause for erroneous bug reports on the mailing
  // list)
  double sumAllLc = 0.;
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  for(GModel::viter it = m->firstVertex(); it != m->lastVertex(); ++it)
    sumAllLc += (*it)->prescribedMeshSizeAtVertex() * CTX::instance()->mesh.lcFactor;
  sumAllLc /= (double)m->getNumVertices();
  if(!sumAllLc || pow(CTX::instance()->lc / sumAllLc, dim) > 1.e10)
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    return !Msg::GetAnswer
      ("Your choice of mesh element sizes will likely produce a very\n"
       "large mesh. Do you really want to continue?\n\n"
       "(To disable this warning in the future, select `Enable expert mode'\n"
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
       "in the option dialog.)", 1, "Cancel", "Continue");
  return false;
}

static bool CancelDelaunayHybrid(GModel *m)
{
  if(CTX::instance()->expertMode) return false;
  int n = 0;
  for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it)
Loading
Loading full blame...