diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp index cbd150631e3c0902108d43bba3996fe34660187c..c4bd9be8692f416807d1c29074c28d08eaffa5c7 100644 --- a/Fltk/graphicWindow.cpp +++ b/Fltk/graphicWindow.cpp @@ -2098,6 +2098,14 @@ static std::vector<std::string> getInfoStrings(MElement *ele) sstream << " SICN range: " << sICNMin << " " << sICNMax; info.push_back(sstream.str()); } + { + std::ostringstream sstream; + sstream.precision(12); + double sIGEMin, sIGEMax; + ele->signedInvGradErrorRange(sIGEMin, sIGEMax); + sstream << " SIGE range: " << sIGEMin << " " << sIGEMax; + info.push_back(sstream.str()); + } { std::ostringstream sstream; sstream.precision(12); diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp index 5f30aa793af0bef8549ecc26b5243e33bacfb214..efa878f7530b20ca034470f7124c38f521b61a49 100644 --- a/Fltk/optionWindow.cpp +++ b/Fltk/optionWindow.cpp @@ -2518,6 +2518,7 @@ optionWindow::optionWindow(int deltaFontSize) static Fl_Menu_Item menu_quality_type[] = { {"SICN", 0, 0, 0}, + {"SIGE", 0, 0, 0}, {"Gamma", 0, 0, 0}, {"Rho", 0, 0, 0}, {"Disto", 0, 0, 0}, diff --git a/Fltk/statisticsWindow.cpp b/Fltk/statisticsWindow.cpp index 7f5e88acd600976d58dc231997b23040a1749989..ed6919a4f6ea7ecf17648450436ab62d2d4064f9 100644 --- a/Fltk/statisticsWindow.cpp +++ b/Fltk/statisticsWindow.cpp @@ -18,7 +18,10 @@ #include "OS.h" #include "Field.h" -enum QM_HISTO {QMH_SICN_XY, QMH_SICN_3D, QMH_GAMMA_XY, QMH_GAMMA_3D, QMH_RHO_XY, QMH_RHO_3D}; +enum QM_HISTO {QMH_SICN_XY, QMH_SICN_3D, + QMH_GAMMA_XY, QMH_GAMMA_3D, + QMH_RHO_XY, QMH_RHO_3D, + QMH_SIGE_XY, QMH_SIGE_3D}; void statistics_cb(Fl_Widget *w, void *data) { @@ -57,6 +60,13 @@ static void statistics_histogram_cb(Fl_Widget *w, void *data) } new PView("Rho", "# Elements", x, y); } + else if (qmh == QMH_SIGE_XY) { + for(int i = 0; i < 100; i++){ + x.push_back((double)(2*i-99) / 99); + y.push_back(FlGui::instance()->stats->quality[3][i]); + } + new PView("SIGE", "# Elements", x, y); + } else { std::vector<GEntity*> entities_; GModel::current()->getEntities(entities_); @@ -71,11 +81,14 @@ static void statistics_histogram_cb(Fl_Widget *w, void *data) d[e->getNum()].push_back(e->gammaShapeMeasure()); else if (qmh == QMH_RHO_3D) d[e->getNum()].push_back(e->rhoShapeMeasure()); + else if (qmh == QMH_SIGE_3D) + d[e->getNum()].push_back(e->minSIGEShapeMeasure()); } } std::string name = (qmh == QMH_SICN_3D) ? "SICN" : (qmh == QMH_GAMMA_3D) ? "Gamma" : - (qmh == QMH_RHO_3D) ? "Rho" : ""; + (qmh == QMH_RHO_3D) ? "Rho" : + (qmh == QMH_SIGE_3D) ? "SIGE" : ""; new PView(name, "ElementData", GModel::current(), d); } @@ -89,7 +102,7 @@ statisticsWindow::statisticsWindow(int deltaFontSize) int num = 0; int width = 26 * FL_NORMAL_SIZE; - int height = 5 * WB + 18 * BH; + int height = 5 * WB + 19 * BH; win = new paletteWindow (width, height, CTX::instance()->nonModalWindows ? true : false, "Statistics"); @@ -126,12 +139,14 @@ statisticsWindow::statisticsWindow(int deltaFontSize) value[num] = new Fl_Output(2 * WB, 2 * WB + 14 * BH, IW, BH, "SICN"); value[num]->tooltip("~ signed inverse condition number"); num++; - value[num] = new Fl_Output(2 * WB, 2 * WB + 15 * BH, IW, BH, "Gamma"); + value[num] = new Fl_Output(2 * WB, 2 * WB + 15 * BH, IW, BH, "SIGE"); + value[num]->tooltip("~ signed inverse error on gradient FE solution"); num++; + value[num] = new Fl_Output(2 * WB, 2 * WB + 16 * BH, IW, BH, "Gamma"); value[num]->tooltip("~ inscribed_radius / circumscribed_radius (simplices)"); num++; - value[num] = new Fl_Output(2 * WB, 2 * WB + 16 * BH, IW, BH, "Rho"); + value[num] = new Fl_Output(2 * WB, 2 * WB + 17 * BH, IW, BH, "Rho"); value[num]->tooltip("~ min_edge_length / max_edge_length"); num++; - for(int i = 0; i < 3; i++){ + for(int i = 0; i < 4; i++){ int ww = 3 * FL_NORMAL_SIZE; new Fl_Box (FL_NO_BOX, width - 3 * ww - 2 * WB, 2 * WB + (14 + i) * BH, ww, BH, "Plot"); @@ -141,13 +156,16 @@ statisticsWindow::statisticsWindow(int deltaFontSize) (width - ww - 2 * WB, 2 * WB + (14 + i) * BH, ww, BH, "3D"); } static const QM_HISTO qmh0 = QMH_SICN_XY, qmh1 = QMH_SICN_3D, qmh2 = QMH_GAMMA_XY, - qmh3 = QMH_GAMMA_3D, qmh4 = QMH_RHO_XY, qmh5 = QMH_RHO_3D; + qmh3 = QMH_GAMMA_3D, qmh4 = QMH_RHO_XY, qmh5 = QMH_RHO_3D, + qmh6 = QMH_SIGE_XY, qmh7 = QMH_SIGE_3D; butt[0]->callback(statistics_histogram_cb, (void*) &qmh0); butt[1]->callback(statistics_histogram_cb, (void*) &qmh1); butt[2]->callback(statistics_histogram_cb, (void*) &qmh2); butt[3]->callback(statistics_histogram_cb, (void*) &qmh3); butt[4]->callback(statistics_histogram_cb, (void*) &qmh4); butt[5]->callback(statistics_histogram_cb, (void*) &qmh5); + butt[6]->callback(statistics_histogram_cb, (void*) &qmh6); + butt[7]->callback(statistics_histogram_cb, (void*) &qmh7); group[1]->end(); } @@ -225,7 +243,10 @@ void statisticsWindow::compute(bool elementQuality) sprintf(label[num], "%g", s[16]); value[num]->value(label[num]); num++; if(!elementQuality){ - for(int i = 0; i < 6; i += 2) butt[i]->deactivate(); + for(int i = 0; i < 8; i += 2) butt[i]->deactivate(); + sprintf(label[num], "Press Update"); + value[num]->deactivate(); + value[num]->value(label[num]); num++; sprintf(label[num], "Press Update"); value[num]->deactivate(); value[num]->value(label[num]); num++; @@ -237,7 +258,7 @@ void statisticsWindow::compute(bool elementQuality) value[num]->value(label[num]); num++; } else{ - for(int i = 0; i < 6; i += 2) butt[i]->activate(); + for(int i = 0; i < 8; i += 2) butt[i]->activate(); sprintf(label[num], "%.4g (%.4g->%.4g)", s[18], s[19], s[20]); value[num]->activate(); value[num]->value(label[num]); num++; diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp index 880936ba498ff6a16f22b51edfdb74270f59419e..f863409c310229baed5b517f2ec23c8290efebe0 100644 --- a/Geo/MElement.cpp +++ b/Geo/MElement.cpp @@ -334,6 +334,14 @@ void MElement::signedInvCondNumRange(double &iCNMin, double &iCNMax, GEntity *ge #endif } +void MElement::signedInvGradErrorRange(double &minSIGE, double &maxSIGE, + GEntity *ge) +{ + minSIGE = jacobianBasedQuality::minSampledICNMeasure(this, getPolynomialOrder()); + maxSIGE = 1; + return; +} + void MElement::getNode(int num, double &u, double &v, double &w) const { // only for MElements that don't have a lookup table for this diff --git a/Geo/MElement.h b/Geo/MElement.h index 7fa7470a99a63229ff20e7c51b50bf684b5f1cab..9c1318fed98deb755d3a9d8f595800ee24411bcb 100644 --- a/Geo/MElement.h +++ b/Geo/MElement.h @@ -202,18 +202,24 @@ class MElement virtual double rhoShapeMeasure(); virtual double gammaShapeMeasure(){ return 0.; } virtual double etaShapeMeasure(){ return 0.; } - double distoShapeMeasure() - { - double jmin, jmax; - scaledJacRange(jmin, jmax); - return jmin; - } double minSICNShapeMeasure() { double sICNMin, sICNMax; signedInvCondNumRange(sICNMin, sICNMax); return sICNMin; } + double minSIGEShapeMeasure() + { + double minSIGE, maxSIGE; + signedInvGradErrorRange(minSIGE, maxSIGE); + return minSIGE; + } + double distoShapeMeasure() + { + double jmin, jmax; + scaledJacRange(jmin, jmax); + return jmin; + } double minIsotropyMeasure(bool knownValid = false, bool reversedOk = false); double minScaledJacobian(bool knownValid = false, bool reversedOk = false); double specialQuality(); @@ -222,6 +228,7 @@ class MElement virtual void scaledJacRange(double &jmin, double &jmax, GEntity *ge = 0) const; virtual void idealJacRange(double &jmin, double &jmax, GEntity *ge = 0); virtual void signedInvCondNumRange(double &iCNMin, double &iCNMax, GEntity *ge = 0); + virtual void signedInvGradErrorRange(double &minSIGE, double &maxSIGE, GEntity *ge = 0); // get the radius of the inscribed circle/sphere if it exists, // otherwise get the minimum radius of all the circles/spheres