Skip to content
Snippets Groups Projects
Commit 0e49772a authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

*** empty log message ***

parent afb84fa5
No related branches found
No related tags found
No related merge requests found
// $Id: meshGRegionDelaunayInsertion.cpp,v 1.33 2008-01-20 10:10:42 geuzaine Exp $ // $Id: meshGRegionDelaunayInsertion.cpp,v 1.34 2008-01-21 21:25:29 geuzaine Exp $
// //
// Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
// //
...@@ -32,82 +32,82 @@ ...@@ -32,82 +32,82 @@
#include <map> #include <map>
#include <algorithm> #include <algorithm>
int MTet4::inCircumSphere ( const double *p ) const int MTet4::inCircumSphere(const double *p) const
{ {
double pa[3] = {base->getVertex(0)->x(),base->getVertex(0)->y(),base->getVertex(0)->z()}; double pa[3] = {base->getVertex(0)->x(),
double pb[3] = {base->getVertex(1)->x(),base->getVertex(1)->y(),base->getVertex(1)->z()}; base->getVertex(0)->y(),
double pc[3] = {base->getVertex(2)->x(),base->getVertex(2)->y(),base->getVertex(2)->z()}; base->getVertex(0)->z()};
double pd[3] = {base->getVertex(3)->x(),base->getVertex(3)->y(),base->getVertex(3)->z()}; double pb[3] = {base->getVertex(1)->x(),
double result = gmsh::insphere(pa, pb, pc, pd, (double*)p) * gmsh::orient3d(pa, pb, pc, pd); base->getVertex(1)->y(),
base->getVertex(1)->z()};
double pc[3] = {base->getVertex(2)->x(),
base->getVertex(2)->y(),
base->getVertex(2)->z()};
double pd[3] = {base->getVertex(3)->x(),
base->getVertex(3)->y(),
base->getVertex(3)->z()};
double result =
gmsh::insphere(pa, pb, pc, pd, (double*)p) * gmsh::orient3d(pa, pb, pc, pd);
return (result > 0) ? 1 : 0; return (result > 0) ? 1 : 0;
} }
static int faces[4][3] = {{0,1,2},{0,2,3},{0,1,3},{1,2,3}}; static int faces[4][3] = {{0,1,2}, {0,2,3}, {0,1,3}, {1,2,3}};
struct faceXtet struct faceXtet{
{
MVertex *v[3]; MVertex *v[3];
MTet4 * t1; MTet4 *t1;
int i1; int i1;
faceXtet ( MTet4 *_t, int iFac) faceXtet(MTet4 *_t, int iFac) : t1(_t), i1(iFac)
: t1(_t),i1(iFac)
{ {
v[0] = t1->tet()->getVertex ( faces [iFac][0] ); v[0] = t1->tet()->getVertex(faces[iFac][0]);
v[1] = t1->tet()->getVertex ( faces [iFac][1] ); v[1] = t1->tet()->getVertex(faces[iFac][1]);
v[2] = t1->tet()->getVertex ( faces [iFac][2] ); v[2] = t1->tet()->getVertex(faces[iFac][2]);
std::sort ( v, v+3 ); std::sort(v, v + 3);
} }
inline bool operator < ( const faceXtet & other) const inline bool operator < (const faceXtet & other) const
{ {
if (v[0] < other.v[0])return true; if (v[0] < other.v[0]) return true;
if (v[0] > other.v[0])return false; if (v[0] > other.v[0]) return false;
if (v[1] < other.v[1])return true; if (v[1] < other.v[1]) return true;
if (v[1] > other.v[1])return false; if (v[1] > other.v[1]) return false;
if (v[2] < other.v[2])return true; if (v[2] < other.v[2]) return true;
return false; return false;
} }
}; };
template <class ITER> template <class ITER>
void connectTets ( ITER beg, ITER end) void connectTets ( ITER beg, ITER end)
{ {
std::set<faceXtet> conn; std::set<faceXtet> conn;
{ while (beg != end){
while (beg != end) if (!(*beg)->isDeleted()){
{ for (int i = 0; i < 4; i++){
if (!(*beg)->isDeleted()) faceXtet fxt(*beg, i);
{ std::set<faceXtet>::iterator found = conn.find(fxt);
for (int i=0;i<4;i++) if (found == conn.end())
{ conn.insert(fxt);
faceXtet fxt ( *beg , i ); else if (found->t1 != *beg){
std::set<faceXtet>::iterator found = conn.find (fxt); found->t1->setNeigh(found->i1, *beg);
if (found == conn.end()) (*beg)->setNeigh(i, found->t1);
conn.insert ( fxt ); }
else if (found->t1 != *beg)
{
found->t1->setNeigh(found->i1,*beg);
(*beg)->setNeigh ( i, found->t1);
}
}
}
++beg;
} }
}
++beg;
} }
} }
void connectTets ( std::list<MTet4*> & l) {connectTets(l.begin(),l.end());}
void connectTets ( std::vector<MTet4*> &l ) {connectTets(l.begin(),l.end());}
void connectTets(std::list<MTet4*> &l) { connectTets(l.begin(), l.end()); }
void connectTets(std::vector<MTet4*> &l) { connectTets(l.begin(), l.end()); }
void recurFindCavity ( std::list<faceXtet> & shell, void recurFindCavity(std::list<faceXtet> & shell,
std::list<MTet4*> & cavity, std::list<MTet4*> & cavity,
MVertex *v , MVertex *v ,
MTet4 *t) MTet4 *t)
{ {
// Msg(INFO,"tet %d %d %d %d",t->tet()->getVertex(0)->getNum(), // Msg(INFO,"tet %d %d %d %d",t->tet()->getVertex(0)->getNum(),
// t->tet()->getVertex(1)->getNum(), // t->tet()->getVertex(1)->getNum(),
// t->tet()->getVertex(2)->getNum(), // t->tet()->getVertex(2)->getNum(),
// t->tet()->getVertex(3)->getNum()); // t->tet()->getVertex(3)->getNum());
// invariant : this one has to be inserted in the cavity // invariant : this one has to be inserted in the cavity
// consider this tet deleted // consider this tet deleted
...@@ -117,36 +117,34 @@ void recurFindCavity ( std::list<faceXtet> & shell, ...@@ -117,36 +117,34 @@ void recurFindCavity ( std::list<faceXtet> & shell,
// because it violates delaunay criterion // because it violates delaunay criterion
cavity.push_back(t); cavity.push_back(t);
for (int i=0;i<4;i++) for (int i = 0; i < 4; i++){
{ MTet4 *neigh = t->getNeigh(i) ;
MTet4 *neigh = t->getNeigh(i) ; if (!neigh)
if (!neigh) shell.push_back(faceXtet(t, i));
shell.push_back ( faceXtet ( t, i ) ); else if (!neigh->isDeleted()){
else if (!neigh->isDeleted() ) int circ = neigh->inCircumSphere(v);
{ if (circ && (neigh->onWhat() == t->onWhat()))
int circ = neigh->inCircumSphere ( v ); recurFindCavity(shell, cavity, v, neigh);
if (circ && (neigh->onWhat() == t->onWhat())) else
recurFindCavity ( shell, cavity,v , neigh); shell.push_back(faceXtet(t, i));
else
shell.push_back ( faceXtet ( t, i ) );
}
} }
}
} }
bool insertVertex (MVertex *v , bool insertVertex(MVertex *v,
MTet4 *t , MTet4 *t,
MTet4Factory &myFactory, MTet4Factory &myFactory,
std::set<MTet4*,compareTet4Ptr> &allTets, std::set<MTet4*,compareTet4Ptr> &allTets,
std::vector<double> & vSizes) std::vector<double> & vSizes)
{ {
std::list<faceXtet> shell; std::list<faceXtet> shell;
std::list<MTet4*> cavity; std::list<MTet4*> cavity;
std::list<MTet4*> new_cavity; std::list<MTet4*> new_cavity;
recurFindCavity ( shell, cavity, v , t); recurFindCavity(shell, cavity, v, t);
// Msg(INFO,"%d %d",cavity.size(),NC); // Msg(INFO,"%d %d",cavity.size(),NC);
// if (NC != cavity.size())throw; // if (NC != cavity.size())throw;
// check that volume is conserved // check that volume is conserved
double newVolume = 0; double newVolume = 0;
...@@ -156,12 +154,10 @@ bool insertVertex (MVertex *v , ...@@ -156,12 +154,10 @@ bool insertVertex (MVertex *v ,
// FILE *ff2 = fopen (name2,"w"); // FILE *ff2 = fopen (name2,"w");
// fprintf(ff2,"View\"test\"{\n"); // fprintf(ff2,"View\"test\"{\n");
std::list<MTet4*>::iterator ittet = cavity.begin(); std::list<MTet4*>::iterator ittet = cavity.begin();
std::list<MTet4*>::iterator ittete = cavity.end(); std::list<MTet4*>::iterator ittete = cavity.end();
while ( ittet != ittete ) while (ittet != ittete){
{ oldVolume += fabs((*ittet)->getVolume());
oldVolume += fabs((*ittet)->getVolume());
// fprintf(ff2,"SS(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g) {0,0,0,0};\n", // fprintf(ff2,"SS(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g) {0,0,0,0};\n",
// (*ittet)->tet()->getVertex(0)->x(), // (*ittet)->tet()->getVertex(0)->x(),
// (*ittet)->tet()->getVertex(0)->y(), // (*ittet)->tet()->getVertex(0)->y(),
...@@ -196,16 +192,11 @@ bool insertVertex (MVertex *v , ...@@ -196,16 +192,11 @@ bool insertVertex (MVertex *v ,
MTet4** newTets = new MTet4*[shell.size()];; MTet4** newTets = new MTet4*[shell.size()];;
int k = 0; int k = 0;
std::list<faceXtet>::iterator it = shell.begin(); std::list<faceXtet>::iterator it = shell.begin();
while (it != shell.end()) while (it != shell.end()){
{ MTetrahedron *tr = new MTetrahedron (it->v[0], it->v[1], it->v[2], v);
MTetrahedron *tr = new MTetrahedron ( it->v[0], // Msg(INFO,"shell %d %d %d",it->v[0]->getNum(),it->v[1]->getNum(),it->v[2]->getNum());
it->v[1],
it->v[2],
v);
// Msg(INFO,"shell %d %d %d",it->v[0]->getNum(),it->v[1]->getNum(),it->v[2]->getNum());
// fprintf(ff,"ST(%g,%g,%g,%g,%g,%g,%g,%g,%g) {0,0,0};\n", // fprintf(ff,"ST(%g,%g,%g,%g,%g,%g,%g,%g,%g) {0,0,0};\n",
// it->v[0]->x(), // it->v[0]->x(),
// it->v[0]->y(), // it->v[0]->y(),
...@@ -217,20 +208,18 @@ bool insertVertex (MVertex *v , ...@@ -217,20 +208,18 @@ bool insertVertex (MVertex *v ,
// it->v[2]->y(), // it->v[2]->y(),
// it->v[2]->z()); // it->v[2]->z());
MTet4 *t4 = myFactory.Create ( tr , vSizes); MTet4 *t4 = myFactory.Create(tr, vSizes);
t4->setOnWhat(t->onWhat()); t4->setOnWhat(t->onWhat());
newTets[k++]=t4; newTets[k++] = t4;
// all new tets are pushed front in order to // all new tets are pushed front in order to ba able to destroy
// ba able to destroy them if the cavity is not // them if the cavity is not star shaped around the new vertex.
// star shaped around the new vertex. // here, we better use robust perdicates that implies to orient
// here, we better use robust perdicates // all faces and ensure that the tets are all oriented the same.
// that implies to orient all faces and new_cavity.push_back(t4);
// ensure that the tets are all oriented the same.
new_cavity.push_back (t4);
MTet4 *otherSide = it->t1->getNeigh(it->i1); MTet4 *otherSide = it->t1->getNeigh(it->i1);
if (otherSide) if (otherSide)
new_cavity.push_back (otherSide); new_cavity.push_back(otherSide);
// if (!it->t1->isDeleted())throw; // if (!it->t1->isDeleted())throw;
newVolume += fabs(t4->getVolume()); newVolume += fabs(t4->getVolume());
++it; ++it;
...@@ -239,162 +228,138 @@ bool insertVertex (MVertex *v , ...@@ -239,162 +228,138 @@ bool insertVertex (MVertex *v ,
// fclose (ff); // fclose (ff);
// Msg(INFO,"new cavity of vol %g (%d boundaries)",newVolume,shell.size()); // Msg(INFO,"new cavity of vol %g (%d boundaries)",newVolume,shell.size());
// OK, the cavity is star shaped // OK, the cavity is star shaped
if (fabs(oldVolume - newVolume) < 1.e-10 * oldVolume ) if (fabs(oldVolume - newVolume) < 1.e-10 * oldVolume){
{ connectTets ( new_cavity.begin(),new_cavity.end());
connectTets ( new_cavity.begin(),new_cavity.end() ); allTets.insert(newTets,newTets+shell.size());
allTets.insert(newTets,newTets+shell.size());
// ittet = cavity.begin();
// ittet = cavity.begin(); // ittete = cavity.end();
// ittete = cavity.end(); // while ( ittet != ittete ){
// while ( ittet != ittete ) // myFactory.Free (*ittet);
// { // ++ittet;
// myFactory.Free (*ittet); // }
// ++ittet; delete [] newTets;
// } return true;
delete [] newTets; }
return true; else { // The cavity is NOT star shaped
} for (unsigned int i = 0; i <shell.size(); i++) myFactory.Free(newTets[i]);
// The cavity is NOT star shaped delete [] newTets;
else ittet = cavity.begin();
{ ittete = cavity.end();
for (unsigned int i=0;i<shell.size();i++)myFactory.Free(newTets[i]); while(ittet != ittete){
delete [] newTets; (*ittet)->setDeleted(false);
ittet = cavity.begin(); ++ittet;
ittete = cavity.end();
while ( ittet != ittete )
{
(*ittet)->setDeleted(false);
++ittet;
}
return false;
} }
return false;
}
} }
static void setLcs ( MTetrahedron *t, std::map<MVertex*,double> &vSizes) static void setLcs(MTetrahedron *t, std::map<MVertex*,double> &vSizes)
{ {
for (int i=0;i<4;i++) for (int i = 0; i < 4; i++){
{ for (int j = i + 1; j < 4; j++){
for (int j=i+1;j<4;j++) MVertex *vi = t->getVertex(i);
{ MVertex *vj = t->getVertex(j);
MVertex *vi = t->getVertex(i); double dx = vi->x()-vj->x();
MVertex *vj = t->getVertex(j); double dy = vi->y()-vj->y();
double dx = vi->x()-vj->x(); double dz = vi->z()-vj->z();
double dy = vi->y()-vj->y(); double l = sqrt(dx * dx + dy * dy + dz * dz);
double dz = vi->z()-vj->z(); std::map<MVertex*,double>::iterator iti = vSizes.find(vi);
double l = sqrt(dx*dx+dy*dy+dz*dz); std::map<MVertex*,double>::iterator itj = vSizes.find(vj);
std::map<MVertex*,double>::iterator iti = vSizes.find(vi); if (iti == vSizes.end() || iti->second > l) vSizes[vi] = l;
std::map<MVertex*,double>::iterator itj = vSizes.find(vj); if (itj == vSizes.end() || itj->second > l) vSizes[vj] = l;
if (iti==vSizes.end() || iti->second > l)vSizes[vi] = l;
if (itj==vSizes.end() || itj->second > l)vSizes[vj] = l;
}
} }
}
} }
// void recover_volumes( GRegion *gr , std::set<MTet4*,compareTet4Ptr> & allTets ) // void recover_volumes( GRegion *gr , std::set<MTet4*,compareTet4Ptr> & allTets )
// { // {
// std::set<MTet4*,compareTet4Ptr>::iterator it = allTets.begin(); // std::set<MTet4*,compareTet4Ptr>::iterator it = allTets.begin();
// for ( ; it != allTets.end() ; ++it ) // for (; it != allTets.end(); ++it){
// { // MTet4 *t = *allTets.begin();
// MTet4 *t = *allTets.begin(); // if (!t->isDeleted()){
// if (!t->isDeleted())
// {
// }
// } // }
// }
// } // }
// 4th argument will disappear when the reclassification of vertices will be done // 4th argument will disappear when the reclassification of vertices will be done
bool find_triangle_in_model ( GModel *model , MTriangle *tri, GFace **gfound, bool force) bool find_triangle_in_model(GModel *model, MTriangle *tri, GFace **gfound, bool force)
{ {
static compareMTriangleLexicographic cmp;
static compareMTriangleLexicographic cmp;
GModel::fiter fit = model->firstFace() ;
GModel::fiter fit = model->firstFace() ; while (fit != model->lastFace()){
while (fit != model->lastFace()){ bool found = std::binary_search((*fit)->triangles.begin(),
bool found = std::binary_search((*fit)->triangles.begin(),
(*fit)->triangles.end(), (*fit)->triangles.end(),
tri,cmp); tri, cmp);
if (found ) if(found){
{ *gfound = *fit;
*gfound = *fit; return true;
return true; }
} ++fit;
++fit; }
} return false;
return false; }
}
GRegion *getRegionFromBoundingFaces (GModel *model, GRegion *getRegionFromBoundingFaces(GModel *model,
std::set<GFace *> &faces_bound) std::set<GFace *> &faces_bound)
{ {
GModel::riter git = model->firstRegion() ; GModel::riter git = model->firstRegion();
while (git != model->lastRegion()){ while (git != model->lastRegion()){
std::list <GFace *> _faces = (*git)->faces(); std::list <GFace *> _faces = (*git)->faces();
if (_faces.size() == faces_bound.size()) if(_faces.size() == faces_bound.size()){
{ bool ok = true;
bool ok = true; for (std::list<GFace *>::iterator it = _faces.begin(); it != _faces.end(); ++it){
for (std::list <GFace *>::iterator it = _faces.begin();it != _faces.end();++it) if(faces_bound.find (*it) == faces_bound.end()) ok = false;
{ }
if (faces_bound.find (*it) == faces_bound.end())ok = false; if (ok) return *git;
} }
if (ok)return *git;
}
++git; ++git;
} }
return 0; return 0;
} }
void recur_classify ( MTet4 *t , void recur_classify(MTet4 *t ,
std::list<MTet4*> &theRegion, std::list<MTet4*> &theRegion,
std::set<GFace *> &faces_bound, std::set<GFace *> &faces_bound,
GRegion *bidon , GRegion *bidon ,
GModel *model, GModel *model,
const fs_cont &search) const fs_cont &search)
{ {
if (!t) Msg (GERROR,"a tet is not connected by a boundary face"); if (!t) Msg (GERROR,"a tet is not connected by a boundary face");
if (t->onWhat())return; // should never return here... if (t->onWhat()) return; // should never return here...
theRegion.push_back(t); theRegion.push_back(t);
t->setOnWhat(bidon); t->setOnWhat(bidon);
bool FF[4] = {0,0,0,0}; bool FF[4] = {0,0,0,0};
for (int i=0;i<4;i++) for (int i = 0; i < 4; i++){
{ // if (!t->getNeigh(i) || !t->getNeigh(i)->onWhat())
// if (!t->getNeigh(i) || !t->getNeigh(i)->onWhat())
{
GFace* gfound = findInFaceSearchStructure ( t->tet()->getVertex ( faces[i][0] ),
t->tet()->getVertex ( faces[i][1] ),
t->tet()->getVertex ( faces[i][2] ), search );
if (gfound)
{
FF[i]=true;
if (faces_bound.find(gfound) == faces_bound.end())
faces_bound.insert(gfound);
}
// MTriangle tri ( t->tet()->getVertex ( faces[i][0] ),
// t->tet()->getVertex ( faces[i][1] ),
// t->tet()->getVertex ( faces[i][2] ) );
// GFace *gfound;
// if (FF[i] = find_triangle_in_model ( model , &tri, &gfound, false))
// {
// if (faces_bound.find(gfound) == faces_bound.end())
// faces_bound.insert(gfound);
// }
}
}
for (int i=0;i<4;i++)
{ {
if (!FF[i]) recur_classify ( t->getNeigh(i) , theRegion, faces_bound, bidon, model,search ); GFace* gfound = findInFaceSearchStructure (t->tet()->getVertex(faces[i][0]),
t->tet()->getVertex(faces[i][1]),
t->tet()->getVertex(faces[i][2]),
search);
if (gfound){
FF[i] = true;
if (faces_bound.find(gfound) == faces_bound.end())
faces_bound.insert(gfound);
}
// MTriangle tri (t->tet()->getVertex (faces[i][0]),
// t->tet()->getVertex (faces[i][1]),
// t->tet()->getVertex (faces[i][2]));
// GFace *gfound;
// if (FF[i] = find_triangle_in_model(model, &tri, &gfound, false)){
// if (faces_bound.find(gfound) == faces_bound.end())
// faces_bound.insert(gfound);
// }
} }
}
for (int i = 0; i < 4; i++){
if (!FF[i])
recur_classify(t->getNeigh(i), theRegion, faces_bound, bidon, model, search );
}
} }
void adaptMeshGRegion::operator () (GRegion *gr) void adaptMeshGRegion::operator () (GRegion *gr)
...@@ -419,85 +384,92 @@ void adaptMeshGRegion::operator () (GRegion *gr) ...@@ -419,85 +384,92 @@ void adaptMeshGRegion::operator () (GRegion *gr)
double worst = 1.0; double worst = 1.0;
double avg = 0; double avg = 0;
int count=0; int count=0;
for (int i=0;i<nbRanges;i++)quality_ranges[i] = 0; for (int i = 0; i < nbRanges; i++) quality_ranges[i] = 0;
for (CONTAINER::iterator it = allTets.begin();it!=allTets.end();++it) for (CONTAINER::iterator it = allTets.begin();it!=allTets.end(); ++it){
{ if (!(*it)->isDeleted()){
if (!(*it)->isDeleted()){ double vol = fabs((*it)->tet()->getVolume());
double vol = fabs((*it)->tet()->getVolume()); double qual = (*it)->getQuality();
double qual = (*it)->getQuality(); worst = std::min(qual, worst);
worst = std::min(qual,worst); avg += qual;
avg+=qual; count++;
count++; totalVolumeb += vol;
totalVolumeb+=vol; for (int i = 0; i < nbRanges; i++){
for (int i=0;i<nbRanges;i++){ double low = (double)i / nbRanges;
double low = (double)i/(nbRanges); double high = (double)(i + 1) / nbRanges;
double high = (double)(i+1)/(nbRanges); if (qual >= low && qual < high) quality_ranges[i]++;
if (qual >= low && qual < high)quality_ranges[i]++; }
}
}
} }
Msg(INFO,"Adaptation : START with %12.5E QBAD %12.5E QAVG %12.5E",totalVolumeb,worst,avg/count); }
for (int i=0;i<nbRanges;i++){ Msg(INFO,"Adaptation : START with %12.5E QBAD %12.5E QAVG %12.5E",
double low = (double)i/(nbRanges); totalVolumeb, worst, avg / count);
double high = (double)(i+1)/(nbRanges); for (int i = 0; i < nbRanges; i++){
Msg(INFO,"Opti : %3.2f < QUAL < %3.2f : %9d elements ",low,high,quality_ranges[i]); double low = (double)i / nbRanges;
double high = (double)(i + 1) / nbRanges;
Msg(INFO,"Opti : %3.2f < QUAL < %3.2f : %9d elements ",
low, high, quality_ranges[i]);
} }
} }
double qMin = 0.5; double qMin = 0.5;
double sliverLimit = 0.2; double sliverLimit = 0.2;
int nbESwap=0, nbFSwap=0, nbReloc=0, nbCollapse = 0; int nbESwap = 0, nbFSwap = 0, nbReloc = 0, nbCollapse = 0;
while (1){ while (1){
std::vector<MTet4*> newTets; std::vector<MTet4*> newTets;
for (CONTAINER::iterator it = allTets.begin(); it!=allTets.end(); ++it){
for (CONTAINER::iterator it = allTets.begin();it!=allTets.end();++it){
if (!(*it)->isDeleted()){ if (!(*it)->isDeleted()){
for (int i=0;i<4;i++){ for (int i = 0; i < 4; i++){
for (int j=0;j<4;j++){ for (int j = 0; j < 4; j++){
if (gmshCollapseVertex(newTets,*it,i,j,QMTET_2)){nbCollapse++;i=j=10;} if (gmshCollapseVertex(newTets, *it, i, j, QMTET_2)){
nbCollapse++; i = j = 10;
}
} }
} }
} }
} }
printf("nbCollapses = %d\n", nbCollapse);
printf("nbCollapses = %d\n",nbCollapse); for (CONTAINER::iterator it = allTets.begin(); it!=allTets.end(); ++it){
for (CONTAINER::iterator it = allTets.begin();it!=allTets.end();++it){
if (!(*it)->isDeleted()){ if (!(*it)->isDeleted()){
double qq = (*it)->getQuality(); double qq = (*it)->getQuality();
if (qq < qMin){ if (qq < qMin){
for (int i=0;i<4;i++){ for (int i = 0; i < 4; i++){
if (gmshFaceSwap(newTets,*it,i,qm)){nbFSwap++;break;} if (gmshFaceSwap(newTets, *it, i, qm)){
nbFSwap++;
break;
}
} }
} }
} }
} }
illegals.clear(); illegals.clear();
for (int i=0;i<nbRanges;i++)quality_ranges[i] = 0; for (int i = 0; i < nbRanges; i++) quality_ranges[i] = 0;
for (CONTAINER::iterator it = allTets.begin();it!=allTets.end();++it) for (CONTAINER::iterator it = allTets.begin(); it != allTets.end(); ++it){
{ if (!(*it)->isDeleted()){
if (!(*it)->isDeleted()){ double qq = (*it)->getQuality();
double qq = (*it)->getQuality(); if (qq < qMin)
if (qq < qMin) for (int i = 0; i < 6; i++){
for (int i=0;i<6;i++){ if (gmshEdgeSwap(newTets, *it, i, qm)) {
if (gmshEdgeSwap(newTets,*it,i,qm)) {nbESwap++;break;} nbESwap++;
break;
} }
}
if (!(*it)->isDeleted()){ if (!(*it)->isDeleted()){
if (qq < sliverLimit)illegals.push_back(*it); if (qq < sliverLimit) illegals.push_back(*it);
for (int i=0;i<nbRanges;i++){ for (int i = 0; i < nbRanges; i++){
double low = (double)i/(nbRanges); double low = (double)i / nbRanges;
double high = (double)(i+1)/(nbRanges); double high = (double)(i + 1)/ nbRanges;
if (qq >= low && qq < high)quality_ranges[i]++; if (qq >= low && qq < high) quality_ranges[i]++;
} }
} }
}
} }
}
if (!newTets.size())break;
if (!newTets.size()) break;
// add all the new tets in the container // add all the new tets in the container
for(unsigned int i = 0; i < newTets.size(); i++){ for(unsigned int i = 0; i < newTets.size(); i++){
...@@ -511,65 +483,65 @@ void adaptMeshGRegion::operator () (GRegion *gr) ...@@ -511,65 +483,65 @@ void adaptMeshGRegion::operator () (GRegion *gr)
} }
// relocate vertices // relocate vertices
for (CONTAINER::iterator it = allTets.begin();it!=allTets.end();++it) for (CONTAINER::iterator it = allTets.begin(); it != allTets.end(); ++it){
{ if (!(*it)->isDeleted()){
if (!(*it)->isDeleted()){ double qq = (*it)->getQuality();
double qq = (*it)->getQuality(); if (qq < qMin)
if (qq < qMin) for (int i = 0; i < 4; i++){
for (int i=0;i<4;i++){ if (gmshSmoothVertex(*it, i, qm)) nbReloc++;
if (gmshSmoothVertex(*it,i,qm))nbReloc++; }
}
}
} }
}
double totalVolumeb = 0.0; double totalVolumeb = 0.0;
double worst = 1.0; double worst = 1.0;
double avg = 0; double avg = 0;
int count=0; int count = 0;
for (CONTAINER::iterator it = allTets.begin();it!=allTets.end();++it) for (CONTAINER::iterator it = allTets.begin(); it != allTets.end(); ++it){
{ if (!(*it)->isDeleted()){
if (!(*it)->isDeleted()){ double vol = fabs((*it)->tet()->getVolume());
double vol = fabs((*it)->tet()->getVolume()); double qual = (*it)->getQuality();
double qual = (*it)->getQuality(); worst = std::min(qual, worst);
worst = std::min(qual,worst); avg += qual;
avg+=qual; count++;
count++; totalVolumeb += vol;
totalVolumeb+=vol;
}
} }
}
double t2 = Cpu(); double t2 = Cpu();
Msg(INFO,"Opti : (%d,%d,%d) = %12.5E QBAD %12.5E QAVG %12.5E (%8.3f sec)",nbESwap,nbFSwap,nbReloc,totalVolumeb,worst,avg/count,t2-t1); Msg(INFO,"Opti : (%d,%d,%d) = %12.5E QBAD %12.5E QAVG %12.5E (%8.3f sec)",
nbESwap, nbFSwap, nbReloc, totalVolumeb, worst, avg / count, t2 - t1);
break; break;
} }
int nbSlivers = 0; int nbSlivers = 0;
for(unsigned int i = 0; i < illegals.size(); i++) for(unsigned int i = 0; i < illegals.size(); i++)
if(!(illegals[i]->isDeleted())) nbSlivers ++; if(!(illegals[i]->isDeleted())) nbSlivers++;
if (nbSlivers){ if (nbSlivers){
Msg(INFO,"Opti : %d illegal tets are still in the mesh, trying to remove them",nbSlivers); Msg(INFO,"Opti : %d illegal tets are still in the mesh, trying to remove them",
nbSlivers);
} }
else{ else{
Msg(INFO,"Opti : no illegal tets in the mesh ;-)",nbSlivers); Msg(INFO,"Opti : no illegal tets in the mesh ;-)", nbSlivers);
} }
for (int i=0;i<nbRanges;i++){ for (int i = 0; i < nbRanges ;i++){
double low = (double)i/(nbRanges); double low = (double)i / nbRanges;
double high = (double)(i+1)/(nbRanges); double high = (double)(i + 1) / nbRanges;
Msg(INFO,"Opti : %3.2f < QUAL < %3.2f : %9d elements ",low,high,quality_ranges[i]); Msg(INFO,"Opti : %3.2f < QUAL < %3.2f : %9d elements",
low, high, quality_ranges[i]);
} }
for (CONTAINER::iterator it = allTets.begin();it!=allTets.end();++it) for (CONTAINER::iterator it = allTets.begin(); it != allTets.end(); ++it){
{ if (!(*it)->isDeleted()){
if (!(*it)->isDeleted()){ gr->tetrahedra.push_back((*it)->tet());
gr->tetrahedra.push_back((*it)->tet()); delete *it;
delete *it; }
} else{
else{ delete (*it)->tet();
delete (*it)->tet(); delete *it;
delete *it;
}
} }
}
} }
//template <class CONTAINER, class DATA> //template <class CONTAINER, class DATA>
...@@ -577,88 +549,94 @@ void gmshOptimizeMesh (GRegion *gr, const gmshQualityMeasure4Tet &qm) ...@@ -577,88 +549,94 @@ void gmshOptimizeMesh (GRegion *gr, const gmshQualityMeasure4Tet &qm)
{ {
typedef std::list<MTet4 *> CONTAINER ; typedef std::list<MTet4 *> CONTAINER ;
CONTAINER allTets; CONTAINER allTets;
for(unsigned int i=0;i<gr->tetrahedra.size();i++){ for(unsigned int i = 0; i < gr->tetrahedra.size(); i++){
MTet4 * t = new MTet4(gr->tetrahedra[i],qm); MTet4 * t = new MTet4(gr->tetrahedra[i], qm);
t->setOnWhat(gr); t->setOnWhat(gr);
allTets.push_back(t); allTets.push_back(t);
} }
gr->tetrahedra.clear(); gr->tetrahedra.clear();
connectTets(allTets.begin(),allTets.end()); connectTets(allTets.begin(), allTets.end());
double t1 = Cpu(); double t1 = Cpu();
std::vector<MTet4*> illegals; std::vector<MTet4*> illegals;
const int nbRanges=10; const int nbRanges = 10;
int quality_ranges [nbRanges]; int quality_ranges [nbRanges];
{ {
double totalVolumeb = 0.0; double totalVolumeb = 0.0;
double worst = 1.0; double worst = 1.0;
double avg = 0; double avg = 0;
int count=0; int count = 0;
for (int i=0;i<nbRanges;i++)quality_ranges[i] = 0; for (int i = 0; i < nbRanges; i++) quality_ranges[i] = 0;
for (CONTAINER::iterator it = allTets.begin();it!=allTets.end();++it) for (CONTAINER::iterator it = allTets.begin(); it != allTets.end(); ++it){
{ if (!(*it)->isDeleted()){
if (!(*it)->isDeleted()){ double vol = fabs((*it)->tet()->getVolume());
double vol = fabs((*it)->tet()->getVolume()); double qual = (*it)->getQuality();
double qual = (*it)->getQuality(); worst = std::min(qual, worst);
worst = std::min(qual,worst); avg += qual;
avg+=qual; count++;
count++; totalVolumeb += vol;
totalVolumeb+=vol; for (int i = 0; i < nbRanges; i++){
for (int i=0;i<nbRanges;i++){ double low = (double)i / nbRanges;
double low = (double)i/(nbRanges); double high = (double)(i + 1) / nbRanges;
double high = (double)(i+1)/(nbRanges); if (qual >= low && qual < high) quality_ranges[i]++;
if (qual >= low && qual < high)quality_ranges[i]++; }
}
}
} }
Msg(INFO,"Opti : START with %12.5E QBAD %12.5E QAVG %12.5E",totalVolumeb,worst,avg/count); }
for (int i=0;i<nbRanges;i++){ Msg(INFO,"Opti : START with %12.5E QBAD %12.5E QAVG %12.5E",
double low = (double)i/(nbRanges); totalVolumeb, worst, avg / count);
double high = (double)(i+1)/(nbRanges); for (int i = 0; i < nbRanges; i++){
Msg(INFO,"Opti : %3.2f < QUAL < %3.2f : %9d elements ",low,high,quality_ranges[i]); double low = (double)i / nbRanges;
double high = (double)(i + 1) / nbRanges;
Msg(INFO,"Opti : %3.2f < QUAL < %3.2f : %9d elements",
low, high, quality_ranges[i]);
} }
} }
double qMin = 0.5; double qMin = 0.5;
double sliverLimit = 0.1; double sliverLimit = 0.1;
int nbESwap=0, nbFSwap=0, nbReloc=0; int nbESwap = 0, nbFSwap = 0, nbReloc = 0;
while (1){ while (1){
std::vector<MTet4*> newTets; std::vector<MTet4*> newTets;
for (CONTAINER::iterator it = allTets.begin();it!=allTets.end();++it){ for (CONTAINER::iterator it = allTets.begin(); it != allTets.end(); ++it){
if (!(*it)->isDeleted()){ if (!(*it)->isDeleted()){
double qq = (*it)->getQuality(); double qq = (*it)->getQuality();
if (qq < qMin){ if (qq < qMin){
for (int i=0;i<4;i++){ for (int i = 0; i < 4; i++){
if (gmshFaceSwap(newTets,*it,i,qm)){nbFSwap++;break;} if (gmshFaceSwap(newTets, *it, i, qm)){
nbFSwap++;
break;
}
} }
} }
} }
} }
illegals.clear(); illegals.clear();
for (int i=0;i<nbRanges;i++)quality_ranges[i] = 0; for (int i = 0; i < nbRanges; i++) quality_ranges[i] = 0;
for (CONTAINER::iterator it = allTets.begin();it!=allTets.end();++it) for (CONTAINER::iterator it = allTets.begin(); it != allTets.end(); ++it){
{ if (!(*it)->isDeleted()){
if (!(*it)->isDeleted()){ double qq = (*it)->getQuality();
double qq = (*it)->getQuality(); if (qq < qMin)
if (qq < qMin) for (int i = 0; i < 6; i++){
for (int i=0;i<6;i++){ if (gmshEdgeSwap(newTets, *it, i, qm)) {
if (gmshEdgeSwap(newTets,*it,i,qm)) {nbESwap++;break;} nbESwap++;
break;
} }
if (!(*it)->isDeleted()){
if (qq < sliverLimit)illegals.push_back(*it);
for (int i=0;i<nbRanges;i++){
double low = (double)i/(nbRanges);
double high = (double)(i+1)/(nbRanges);
if (qq >= low && qq < high)quality_ranges[i]++;
}
} }
if (!(*it)->isDeleted()){
if (qq < sliverLimit) illegals.push_back(*it);
for (int i = 0; i < nbRanges; i++){
double low = (double)i / nbRanges;
double high = (double)(i + 1) / nbRanges;
if (qq >= low && qq < high) quality_ranges[i]++;
}
} }
} }
}
if (0 && !newTets.size()){ if (0 && !newTets.size()){
int nbSlivers = 0; int nbSlivers = 0;
...@@ -667,9 +645,9 @@ void gmshOptimizeMesh (GRegion *gr, const gmshQualityMeasure4Tet &qm) ...@@ -667,9 +645,9 @@ void gmshOptimizeMesh (GRegion *gr, const gmshQualityMeasure4Tet &qm)
if(!(illegals[i]->isDeleted())){ if(!(illegals[i]->isDeleted())){
if(gmshSliverRemoval(newTets, illegals[i], qm)) if(gmshSliverRemoval(newTets, illegals[i], qm))
nbSliversWeCanDoSomething++; nbSliversWeCanDoSomething++;
nbSlivers ++; nbSlivers++;
} }
Msg(INFO,"Opti : %d Sliver Removals",nbSliversWeCanDoSomething); Msg(INFO, "Opti : %d Sliver Removals", nbSliversWeCanDoSomething);
} }
if (!newTets.size()){ if (!newTets.size()){
...@@ -688,65 +666,61 @@ void gmshOptimizeMesh (GRegion *gr, const gmshQualityMeasure4Tet &qm) ...@@ -688,65 +666,61 @@ void gmshOptimizeMesh (GRegion *gr, const gmshQualityMeasure4Tet &qm)
} }
// relocate vertices // relocate vertices
for (CONTAINER::iterator it = allTets.begin();it!=allTets.end();++it) for (CONTAINER::iterator it = allTets.begin();it!=allTets.end();++it){
{ if (!(*it)->isDeleted()){
if (!(*it)->isDeleted()){ double qq = (*it)->getQuality();
double qq = (*it)->getQuality(); if (qq < qMin)
if (qq < qMin) for (int i = 0; i < 4; i++){
for (int i=0;i<4;i++){ if (gmshSmoothVertex(*it, i, qm)) nbReloc++;
if (gmshSmoothVertex(*it,i,qm))nbReloc++; }
}
}
} }
}
double totalVolumeb = 0.0; double totalVolumeb = 0.0;
double worst = 1.0; double worst = 1.0;
double avg = 0; double avg = 0;
int count=0; int count = 0;
for (CONTAINER::iterator it = allTets.begin();it!=allTets.end();++it) for (CONTAINER::iterator it = allTets.begin(); it != allTets.end(); ++it){
{ if (!(*it)->isDeleted()){
if (!(*it)->isDeleted()){ double vol = fabs((*it)->tet()->getVolume());
double vol = fabs((*it)->tet()->getVolume()); double qual = (*it)->getQuality();
double qual = (*it)->getQuality(); worst = std::min(qual, worst);
worst = std::min(qual,worst); avg += qual;
avg+=qual; count++;
count++; totalVolumeb += vol;
totalVolumeb+=vol;
}
} }
}
double t2 = Cpu(); double t2 = Cpu();
Msg(INFO,"Opti : (%d,%d,%d) = %12.5E QBAD %12.5E QAVG %12.5E (%8.3f sec)",nbESwap,nbFSwap,nbReloc,totalVolumeb,worst,avg/count,t2-t1); Msg(INFO, "Opti : (%d,%d,%d) = %12.5E QBAD %12.5E QAVG %12.5E (%8.3f sec)",
nbESwap, nbFSwap, nbReloc, totalVolumeb, worst, avg / count, t2 - t1);
} }
if (illegals.size()){ if (illegals.size()){
Msg(INFO,"Opti : %d illegal tets are still in the mesh",illegals.size()); Msg(INFO, "Opti : %d illegal tets are still in the mesh", illegals.size());
} }
else{ else{
Msg(INFO,"Opti : no illegal tets in the mesh ;-)"); Msg(INFO, "Opti : no illegal tets in the mesh ;-)");
} }
for (int i=0;i<nbRanges;i++){ for (int i = 0; i < nbRanges; i++){
double low = (double)i/(nbRanges); double low = (double)i / nbRanges;
double high = (double)(i+1)/(nbRanges); double high = (double)(i + 1) / nbRanges;
Msg(INFO,"Opti : %3.2f < QUAL < %3.2f : %9d elements ",low,high,quality_ranges[i]); Msg(INFO,"Opti : %3.2f < QUAL < %3.2f : %9d elements",
low, high, quality_ranges[i]);
} }
for (CONTAINER::iterator it = allTets.begin();it!=allTets.end();++it) for (CONTAINER::iterator it = allTets.begin(); it != allTets.end(); ++it){
{ if (!(*it)->isDeleted()){
if (!(*it)->isDeleted()){ gr->tetrahedra.push_back((*it)->tet());
gr->tetrahedra.push_back((*it)->tet()); delete *it;
delete *it;
}
else{
delete (*it)->tet();
delete *it;
}
} }
else{
delete (*it)->tet();
delete *it;
}
}
} }
void insertVerticesInRegion (GRegion *gr) void insertVerticesInRegion (GRegion *gr)
{ {
//printf("sizeof MTet4 = %d sizeof MTetrahedron %d sizeof(MVertex) %d\n", //printf("sizeof MTet4 = %d sizeof MTetrahedron %d sizeof(MVertex) %d\n",
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment