Skip to content
Snippets Groups Projects
Commit 8ed03598 authored by Amaury Johnen's avatar Amaury Johnen
Browse files

(1) improved stats for analyseCurvedMesh plugin. (2) add function that sample...

(1) improved stats for analyseCurvedMesh plugin. (2) add function that sample quality measures for testing
parent 82a38fd6
No related branches found
No related tags found
No related merge requests found
...@@ -391,6 +391,129 @@ double minIsotropyMeasure(MElement *el, ...@@ -391,6 +391,129 @@ double minIsotropyMeasure(MElement *el,
// return min; // return min;
//} //}
double minSampledIsotropyMeasure(MElement *el, int deg, bool writeInFile)//fordebug
{
fullMatrix<double> nodesXYZ(el->getNumVertices(), 3);
el->getNodesCoord(nodesXYZ);
const JacobianBasis *jacBasis;
const GradientBasis *gradBasis;
const int type = el->getType();
// const int order = el->getPolynomialOrder();
// const int jacOrder = order * el->getDim();
const bool serendipFalse = false;
FuncSpaceData jacMatSpace, jacDetSpace;
switch(type) {
case TYPE_TRI:
case TYPE_TET:
case TYPE_QUA:
case TYPE_HEX:
case TYPE_PRI:
jacMatSpace = FuncSpaceData(el, deg, &serendipFalse);
jacDetSpace = FuncSpaceData(el, deg, &serendipFalse);
break;
case TYPE_PYR:
// jacMatSpace = FuncSpaceData(el, false, order, order-1, &serendipFalse);
// jacDetSpace = FuncSpaceData(el, false, jacOrder, jacOrder-3, &serendipFalse);
break;
default:
Msg::Error("Isotropy not implemented for type of element %d", el->getType());
return -1;
}
gradBasis = BasisFactory::getGradientBasis(jacMatSpace);
jacBasis = BasisFactory::getJacobianBasis(jacDetSpace);
fullVector<double> coeffDetLag(jacBasis->getNumJacNodes());
jacBasis->getSignedIdealJacobian(nodesXYZ, coeffDetLag);
fullMatrix<double> coeffMatLag(gradBasis->getNumSamplingPoints(), 9);
gradBasis->getAllIdealGradientsFromNodes(nodesXYZ, coeffMatLag);
double min = std::numeric_limits<double>::infinity();
for (int i = 0; i < coeffDetLag.size(); ++i) {
double frobNorm = 0;
if (el->getDim() == 2) {
for (int k = 0; k < 6; ++k)
frobNorm += coeffMatLag(i, k) * coeffMatLag(i, k);
min = std::min(min, 2*coeffDetLag(i)/frobNorm);
}
else if (el->getDim() == 3) {
for (int k = 0; k < 9; ++k)
frobNorm += coeffMatLag(i, k) * coeffMatLag(i, k);
min = std::min(min, 3*std::pow(coeffDetLag(i), 2/3.)/frobNorm);
}
}
return min;
}
double minSampledScaledJacobian(MElement *el, int deg, bool writeInFile)//fordebug
{
fullMatrix<double> nodesXYZ(el->getNumVertices(), 3);
el->getNodesCoord(nodesXYZ);
const JacobianBasis *jacBasis;
const GradientBasis *gradBasis;
const int type = el->getType();
// const int order = el->getPolynomialOrder();
// const int jacOrder = order * el->getDim();
const bool serendipFalse = false;
FuncSpaceData jacMatSpace, jacDetSpace;
switch(type) {
case TYPE_TRI:
case TYPE_TET:
case TYPE_QUA:
case TYPE_HEX:
case TYPE_PRI:
jacMatSpace = FuncSpaceData(el, deg, &serendipFalse);
jacDetSpace = FuncSpaceData(el, deg, &serendipFalse);
break;
case TYPE_PYR:
// jacMatSpace = FuncSpaceData(el, false, order, order-1, &serendipFalse);
// jacDetSpace = FuncSpaceData(el, false, jacOrder, jacOrder-3, &serendipFalse);
break;
default:
Msg::Error("Isotropy not implemented for type of element %d", el->getType());
return -1;
}
gradBasis = BasisFactory::getGradientBasis(jacMatSpace);
jacBasis = BasisFactory::getJacobianBasis(jacDetSpace);
fullVector<double> coeffDetLag(jacBasis->getNumJacNodes());
jacBasis->getSignedIdealJacobian(nodesXYZ, coeffDetLag);
fullMatrix<double> coeffMatLag(gradBasis->getNumSamplingPoints(), 9);
gradBasis->getAllIdealGradientsFromNodes(nodesXYZ, coeffMatLag);
double min = std::numeric_limits<double>::infinity();
for (int i = 0; i < coeffDetLag.size(); ++i) {
if (el->getDim() == 2) {
double v[2] = {0, 0};
for (int k = 0; k < 2; ++k) {
for (int l = k*3; l < k*3+3; ++l)
v[k] += coeffMatLag(i, l) * coeffMatLag(i, l);
}
min = std::min(min, coeffDetLag(i)/v[0]/v[1]);
}
else if (el->getDim() == 3) {
double v[3] = {0, 0, 0};
for (int k = 0; k < 3; ++k) {
for (int l = k*3; l < k*3+3; ++l)
v[k] += coeffMatLag(i, l) * coeffMatLag(i, l);
}
min = std::min(min, coeffDetLag(i)/std::sqrt(v[0]*v[1]*v[2]));
}
}
return min;
}
// Virtual class _CoeffData // Virtual class _CoeffData
bool _lessMinB::operator()(_CoeffData *cd1, _CoeffData *cd2) const bool _lessMinB::operator()(_CoeffData *cd1, _CoeffData *cd2) const
{ {
......
...@@ -28,6 +28,10 @@ double minIsotropyMeasure(MElement *el, ...@@ -28,6 +28,10 @@ double minIsotropyMeasure(MElement *el,
bool reversedOk = false); bool reversedOk = false);
//double minSampledAnisotropyMeasure(MElement *el, int order,//fordebug //double minSampledAnisotropyMeasure(MElement *el, int order,//fordebug
// bool writeInFile = false); // bool writeInFile = false);
double minSampledIsotropyMeasure(MElement *el, int order,//fordebug
bool writeInFile = false);
double minSampledScaledJacobian(MElement *el, int order,//fordebug
bool writeInFile = false);
class _CoeffData class _CoeffData
{ {
...@@ -45,6 +49,7 @@ public: ...@@ -45,6 +49,7 @@ public:
inline double maxL() const {return _maxL;} inline double maxL() const {return _maxL;}
inline double minB() const {return _minB;} inline double minB() const {return _minB;}
inline double maxB() const {return _maxB;} inline double maxB() const {return _maxB;}
inline int depth() const {return _depth;}
virtual bool boundsOk(double minL, double maxL) const = 0; virtual bool boundsOk(double minL, double maxL) const = 0;
virtual void getSubCoeff(std::vector<_CoeffData*>&) const = 0; virtual void getSubCoeff(std::vector<_CoeffData*>&) const = 0;
......
...@@ -27,7 +27,7 @@ StringXNumber CurvedMeshOptions_Number[] = { ...@@ -27,7 +27,7 @@ StringXNumber CurvedMeshOptions_Number[] = {
{GMSH_FULLRC, "Jacobian determinant", NULL, 1}, {GMSH_FULLRC, "Jacobian determinant", NULL, 1},
{GMSH_FULLRC, "Scaled Jacobian", NULL, 0}, {GMSH_FULLRC, "Scaled Jacobian", NULL, 0},
{GMSH_FULLRC, "Isotropy", NULL, 1}, {GMSH_FULLRC, "Isotropy", NULL, 1},
{GMSH_FULLRC, "Hidding threshold", NULL, 10}, {GMSH_FULLRC, "Hidding threshold", NULL, 9},
{GMSH_FULLRC, "Draw PView", NULL, 0}, {GMSH_FULLRC, "Draw PView", NULL, 0},
{GMSH_FULLRC, "Recompute", NULL, 0}, {GMSH_FULLRC, "Recompute", NULL, 0},
{GMSH_FULLRC, "Dimension of elements", NULL, -1} {GMSH_FULLRC, "Dimension of elements", NULL, -1}
...@@ -133,21 +133,24 @@ PView* GMSH_AnalyseCurvedMeshPlugin::execute(PView *v) ...@@ -133,21 +133,24 @@ PView* GMSH_AnalyseCurvedMeshPlugin::execute(PView *v)
double time = Cpu(); double time = Cpu();
Msg::StatusBar(true, "Computing Jacobian for %dD elements...", dim); Msg::StatusBar(true, "Computing Jacobian for %dD elements...", dim);
_computeMinMaxJandValidity(dim); _computeMinMaxJandValidity(dim);
Msg::StatusBar(true, "Done in %g seconds", Cpu()-time); Msg::StatusBar(true, "Done computing Jacobian for %dD elements (%g s)",
dim, Cpu()-time);
printStatJ = true; printStatJ = true;
} }
if (computeScaledJac && !_computedS[dim-1]) { if (computeScaledJac && !_computedS[dim-1]) {
double time = Cpu(); double time = Cpu();
Msg::StatusBar(true, "Computing scaled Jacobian for %dD elements...", dim); Msg::StatusBar(true, "Computing scaled Jacobian for %dD elements...", dim);
_computeMinScaledJac(dim); _computeMinScaledJac(dim);
Msg::StatusBar(true, "Done in %g seconds", Cpu()-time); Msg::StatusBar(true, "Done computing scaled Jacobian for %dD elements (%g s)",
dim, Cpu()-time);
printStatS = true; printStatS = true;
} }
if (computeIsotropy && !_computedI[dim-1]) { if (computeIsotropy && !_computedI[dim-1]) {
double time = Cpu(); double time = Cpu();
Msg::StatusBar(true, "Computing isotropy for %dD elements...", dim); Msg::StatusBar(true, "Computing isotropy for %dD elements...", dim);
_computeMinIsotropy(dim); _computeMinIsotropy(dim);
Msg::StatusBar(true, "Done in %g seconds", Cpu()-time); Msg::StatusBar(true, "Done computing isotropy for %dD elements (%g s)",
dim, Cpu()-time);
printStatI = true; printStatI = true;
} }
} }
...@@ -222,47 +225,79 @@ void GMSH_AnalyseCurvedMeshPlugin::_computeMinMaxJandValidity(int dim) ...@@ -222,47 +225,79 @@ void GMSH_AnalyseCurvedMeshPlugin::_computeMinMaxJandValidity(int dim)
{ {
if (_computedJ[dim-1]) return; if (_computedJ[dim-1]) return;
std::set<GEntity*, GEntityLessThan> entities;
switch (dim) { switch (dim) {
case 3: case 3:
for (GModel::riter it = _m->firstRegion(); it != _m->lastRegion(); it++) { for (GModel::riter it = _m->firstRegion(); it != _m->lastRegion(); it++)
GRegion *r = *it; entities.insert(*it);
unsigned int numType[6] = {0, 0, 0, 0, 0, 0};
r->getNumMeshElements(numType);
for(int type = 0; type < 5; type++) {
MElement *const *el = r->getStartElementType(type);
_computeMinMaxJandValidity(el, numType[type]);
}
}
break; break;
case 2: case 2:
for (GModel::fiter it = _m->firstFace(); it != _m->lastFace(); it++) { for (GModel::fiter it = _m->firstFace(); it != _m->lastFace(); it++)
GFace *f = *it; entities.insert(*it);
unsigned int numType[3] = {0, 0, 0};
f->getNumMeshElements(numType);
for (int type = 0; type < 3; type++) {
MElement *const *el = f->getStartElementType(type);
_computeMinMaxJandValidity(el, numType[type]);
}
}
break; break;
case 1: case 1:
for (GModel::eiter it = _m->firstEdge(); it != _m->lastEdge(); it++) { for (GModel::eiter it = _m->firstEdge(); it != _m->lastEdge(); it++)
GEdge *e = *it; entities.insert(*it);
unsigned int numElement = e->getNumMeshElements();
MElement *const *el = e->getStartElementType(0);
_computeMinMaxJandValidity(el, numElement);
}
break; break;
default: default:
Msg::Fatal("This should not happen."); Msg::Fatal("This should not happen.");
return; return;
} }
std::set<GEntity*, GEntityLessThan>::iterator it;
for (it = entities.begin(); it != entities.end(); ++it) {
GEntity *entity = *it;
unsigned num = entity->getNumMeshElements();
switch (dim) {
case 3:
Msg::StatusBar(true, "Volume %d: checking the Jacobian of %d elements",
entity->tag(), num);
break;
case 2:
Msg::StatusBar(true, "Surface %d: checking the Jacobian of %d elements",
entity->tag(), num);
break;
case 1:
Msg::StatusBar(true, "Line %d: checking the Jacobian of %d elements",
entity->tag(), num);
break;
default: break;
}
double initial, time = initial = Cpu();
unsigned int percentage = 0, nextCheck = 0;
for (unsigned i = 0; i < num; ++i) {
MElement *el = entity->getMeshElement(i);
double min, max;
jacobianBasedQuality::minMaxJacobianDeterminant(el, min, max);
_data.push_back(data_elementMinMax(el, min, max));
if (min < 0 && max < 0) {
Msg::Warning("Element %d is completely inverted", el->getNum());
}
if (i >= nextCheck) {
nextCheck += _data.size() / 100;
double curTime = Cpu();
unsigned int curPercentage = i*100/_data.size();
if ((curTime - time > 10. && curPercentage > percentage + 4) ||
(curTime - time > 15. && curPercentage < 5)) {
percentage = curPercentage;
time = curTime;
const double remaining = (time-initial) / (i+1) * (_data.size() - i-1);
if (remaining < 60*2)
Msg::StatusBar(true, "%d%% (remaining time ~%g seconds)",
percentage, remaining);
else if (remaining < 60*60*2)
Msg::StatusBar(true, "%d%% (remaining time ~%g minutes)",
percentage, remaining/60);
else
Msg::StatusBar(true, "%d%% (remaining time ~%g hours)",
percentage, remaining/3600);
}
}
}
}
_computedJ[dim-1] = true; _computedJ[dim-1] = true;
} }
...@@ -294,6 +329,12 @@ void GMSH_AnalyseCurvedMeshPlugin::_computeMinScaledJac(int dim) ...@@ -294,6 +329,12 @@ void GMSH_AnalyseCurvedMeshPlugin::_computeMinScaledJac(int dim)
else { else {
_data[i].setMinS(jacobianBasedQuality::minScaledJacobian(el, true)); _data[i].setMinS(jacobianBasedQuality::minScaledJacobian(el, true));
} }
// Msg::Info("Scaled Jac");
// Msg::Info("==========");
// for (int k = 1; k < 30; ++k) {
// Msg::Info("%.10g", jacobianBasedQuality::minSampledScaledJacobian(el, k));
// }
// Msg::Info(" ");
if (i >= nextCheck) { if (i >= nextCheck) {
nextCheck += _data.size() / 100; nextCheck += _data.size() / 100;
double curTime = Cpu(); double curTime = Cpu();
...@@ -335,6 +376,12 @@ void GMSH_AnalyseCurvedMeshPlugin::_computeMinIsotropy(int dim) ...@@ -335,6 +376,12 @@ void GMSH_AnalyseCurvedMeshPlugin::_computeMinIsotropy(int dim)
else { else {
_data[i].setMinI(jacobianBasedQuality::minIsotropyMeasure(el, true)); _data[i].setMinI(jacobianBasedQuality::minIsotropyMeasure(el, true));
} }
// Msg::Info("Isotropy");
// Msg::Info("========");
// for (int k = 1; k < 30; ++k) {
// Msg::Info("%.10g", jacobianBasedQuality::minSampledIsotropyMeasure(el, k));
// }
// Msg::Info(" ");
if (i >= nextCheck) { if (i >= nextCheck) {
nextCheck += _data.size() / 100; nextCheck += _data.size() / 100;
double curTime = Cpu(); double curTime = Cpu();
...@@ -362,7 +409,7 @@ void GMSH_AnalyseCurvedMeshPlugin::_computeMinIsotropy(int dim) ...@@ -362,7 +409,7 @@ void GMSH_AnalyseCurvedMeshPlugin::_computeMinIsotropy(int dim)
int GMSH_AnalyseCurvedMeshPlugin::_hideWithThreshold(int askedDim, int whichMeasure) int GMSH_AnalyseCurvedMeshPlugin::_hideWithThreshold(int askedDim, int whichMeasure)
{ {
// only hide for wuality measures // only hide for quality measures
if (_threshold > 1 || whichMeasure == 0) return 0; if (_threshold > 1 || whichMeasure == 0) return 0;
int nHidden = 0; int nHidden = 0;
...@@ -429,12 +476,12 @@ void GMSH_AnalyseCurvedMeshPlugin::_printStatJacobian() ...@@ -429,12 +476,12 @@ void GMSH_AnalyseCurvedMeshPlugin::_printStatJacobian()
avgratJ /= count; avgratJ /= count;
avgratJc /= countc; avgratJc /= countc;
Msg::Info("Jacobian determinant: in [%.3g, %.3g] (avg=%.3g)", Msg::Info("Min Jac. det. (minJ): %.3g, %.3g, %.3g (= min, avg, max)",
infminJ, supminJ, avgminJ); infminJ, avgminJ, supminJ);
Msg::Info("Ratio minJ/maxJ : in [%.3g, %.3g] (avg=%.3g)", Msg::Info("Ratio minJ/maxJ : %.3f, %.3f, %.3f (= worst, avg, best)",
infratJ, supratJ, avgratJ); infratJ, avgratJ, supratJ);
if (countc < count) if (countc && countc < count)
Msg::Info(" (avg=%.3g" Msg::Info(" (avg=%3.3g"
" on the %d non-constant elements)", " on the %d non-constant elements)",
avgratJc, countc); avgratJc, countc);
} }
...@@ -455,8 +502,8 @@ void GMSH_AnalyseCurvedMeshPlugin::_printStatScaledJac() ...@@ -455,8 +502,8 @@ void GMSH_AnalyseCurvedMeshPlugin::_printStatScaledJac()
} }
avgminS /= _data.size(); avgminS /= _data.size();
Msg::Info("Scaled Jacobian : in [%.3g, %.3g] (avg=%.3g)", Msg::Info("Scaled Jacobian : %.3f, %.3f, %.3f (= worst, avg, best)",
infminS, supminS, avgminS); infminS, avgminS, supminS);
} }
void GMSH_AnalyseCurvedMeshPlugin::_printStatIsotropy() void GMSH_AnalyseCurvedMeshPlugin::_printStatIsotropy()
...@@ -475,8 +522,8 @@ void GMSH_AnalyseCurvedMeshPlugin::_printStatIsotropy() ...@@ -475,8 +522,8 @@ void GMSH_AnalyseCurvedMeshPlugin::_printStatIsotropy()
} }
avgminI /= _data.size(); avgminI /= _data.size();
Msg::Info("Isotropy : in [%.3g, %.3g] (avg=%.3g)", Msg::Info("Isotropy : %.3f, %.3f, %.3f (= worst, avg, best)",
infminI, supminI, avgminI); infminI, avgminI, supminI);
} }
// For testing // For testing
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment