From 79b025728c613c5d1e2885a7a2d3cf99a3317236 Mon Sep 17 00:00:00 2001 From: Amaury Johnen <amaury.johnen@uclouvain.be> Date: Fri, 11 Aug 2017 09:21:28 +0200 Subject: [PATCH] allows to visualize pointwise Jacobian for a certain element --- Mesh/qualityMeasuresJacobian.cpp | 38 ++++++++---- Mesh/qualityMeasuresJacobian.h | 4 ++ Plugin/AnalyseCurvedMesh.cpp | 99 +++++++++++++++++++++++++++++++- Plugin/AnalyseCurvedMesh.h | 7 +++ 4 files changed, 136 insertions(+), 12 deletions(-) diff --git a/Mesh/qualityMeasuresJacobian.cpp b/Mesh/qualityMeasuresJacobian.cpp index 97eb1da16e..b882e54b5c 100644 --- a/Mesh/qualityMeasuresJacobian.cpp +++ b/Mesh/qualityMeasuresJacobian.cpp @@ -405,6 +405,32 @@ double minICNMeasure(MElement *el, } void sampleIGEMeasure(MElement *el, int deg, double &min, double &max) +{ + fullVector<double> ige; + sampleIGEMeasure(el, deg, ige); + + min = std::numeric_limits<double>::infinity(); + max = -min; + for (int i = 0; i < ige.size(); ++i) { + min = std::min(min, ige(i)); + max = std::max(max, ige(i)); + } +} + +void sampleJacobian(MElement *el, int deg, fullVector<double> &jac, + const fullMatrix<double> *normals) +{ + FuncSpaceData sampleSpace = FuncSpaceData(el, deg); + const JacobianBasis *jacBasis = BasisFactory::getJacobianBasis(sampleSpace); + + fullMatrix<double> nodesXYZ(el->getNumVertices(), 3); + el->getNodesCoord(nodesXYZ); + + jac.resize(jacBasis->getNumJacNodes()); + jacBasis->getSignedJacobian(nodesXYZ, jac, normals); +} + +void sampleIGEMeasure(MElement *el, int deg, fullVector<double> &ige) { fullMatrix<double> nodesXYZ(el->getNumVertices(), 3); el->getNodesCoord(nodesXYZ); @@ -427,7 +453,7 @@ void sampleIGEMeasure(MElement *el, int deg, double &min, double &max) jacDetSpace = FuncSpaceData(el, true, deg-1, 1, &serendipFalse); break; default: - Msg::Error("ICN not implemented for type of element %d", el->getType()); + Msg::Error("IGE not implemented for type of element %d", el->getType()); return; } @@ -443,17 +469,7 @@ void sampleIGEMeasure(MElement *el, int deg, double &min, double &max) fullMatrix<double> v; computeCoeffLengthVectors_(coeffMatLag, v, type); - fullVector<double> ige; computeIGE_(coeffDeterminant, v, ige, type); - - min = std::numeric_limits<double>::infinity(); - max = -min; - for (int i = 0; i < ige.size(); ++i) { - min = std::min(min, ige(i)); - max = std::max(max, ige(i)); - } - - return; } double minSampledICNMeasure(MElement *el, int deg)//fordebug diff --git a/Mesh/qualityMeasuresJacobian.h b/Mesh/qualityMeasuresJacobian.h index 6c3b62992a..1bb4fc2a35 100644 --- a/Mesh/qualityMeasuresJacobian.h +++ b/Mesh/qualityMeasuresJacobian.h @@ -24,6 +24,10 @@ double minICNMeasure(MElement *el, bool knownValid = false, bool reversedOk = false); void sampleIGEMeasure(MElement *el, int order, double &min, double &max); +void sampleJacobian(MElement *el, int order, fullVector<double> &jac, + const fullMatrix<double> *normals = NULL); +void sampleIGEMeasure(MElement *el, int order, fullVector<double> &ige); +void sampleICNMeasure(MElement *el, int order, fullVector<double> &icn); double minSampledICNMeasure(MElement *el, int order);//fordebug double minSampledIGEMeasure(MElement *el, int order);//fordebug diff --git a/Plugin/AnalyseCurvedMesh.cpp b/Plugin/AnalyseCurvedMesh.cpp index c798ab731f..8343055c84 100644 --- a/Plugin/AnalyseCurvedMesh.cpp +++ b/Plugin/AnalyseCurvedMesh.cpp @@ -19,6 +19,12 @@ #include <sstream> #include <fstream> #include "qualityMeasuresJacobian.h" +#include "MLine.h" +#include "MTriangle.h" +#include "MQuadrangle.h" +#include "MHexahedron.h" +#include "MTetrahedron.h" +#include "MPrism.h" class bezierBasis; @@ -29,7 +35,9 @@ StringXNumber CurvedMeshOptions_Number[] = { {GMSH_FULLRC, "Hiding threshold", NULL, 9}, {GMSH_FULLRC, "Draw PView", NULL, 0}, {GMSH_FULLRC, "Recompute", NULL, 0}, - {GMSH_FULLRC, "Dimension of elements", NULL, -1} + {GMSH_FULLRC, "Dimension of elements", NULL, -1}, + //{GMSH_FULLRC, "Element to print quality", NULL, 2485} + {GMSH_FULLRC, "Element to print quality", NULL, 2555} }; extern "C" @@ -104,6 +112,11 @@ PView* GMSH_AnalyseCurvedMeshPlugin::execute(PView *v) bool drawPView = static_cast<int>(CurvedMeshOptions_Number[4].def); bool recompute = static_cast<bool>(CurvedMeshOptions_Number[5].def); int askedDim = static_cast<int>(CurvedMeshOptions_Number[6].def); + _numElementToScan = static_cast<int>(CurvedMeshOptions_Number[7].def); + + _viewOrder = 10; + _elementToScan = NULL; + _hoElement = NULL; if (askedDim < 0 || askedDim > 4) askedDim = _m->getDim(); @@ -163,6 +176,14 @@ PView* GMSH_AnalyseCurvedMeshPlugin::execute(PView *v) if (printStatS) _printStatIGE(); if (printStatI) _printStatICN(); + if (_hoElement) { + std::map<int, std::vector<double>> dataPVelement; + dataPVelement[_hoElement->getNum()] = _jacElementToScan; + std::stringstream name; + name << "Jacobian elem " << _numElementToScan; + new PView(name.str().c_str(), "ElementNodeData", _m, dataPVelement, 0, 1); + } + // Create PView if (drawPView) for (int dim = 1; dim <= 3; ++dim) { @@ -342,6 +363,33 @@ void GMSH_AnalyseCurvedMeshPlugin::_computeMinMaxJandValidity(int dim) _data.push_back(data_elementMinMax(el, min, max)); if (min < 0 && max < 0) ++cntInverted; progress.next(); + + if (el->getNum() == _numElementToScan) { + _elementToScan = el; + fullMatrix<double> points = + _elementToScan->getFunctionSpace(_viewOrder)->points; + int tag = ElementType::getTag(_elementToScan->getType(), _viewOrder); + std::vector<MVertex *> v; + for (int k = 0; k < points.size1(); k++) { + double t1 = points(k, 0); + double t2 = points(k, 1); + double t3 = points(k, 2); + SPoint3 pos; + _elementToScan->pnt(t1, t2, t3, pos); + v.push_back(new MVertex(pos.x(), pos.y(), pos.z())); + } + MElementFactory factory; + _hoElement = factory.create(tag, v); + + _addElementInEntity(_hoElement, entity); + + fullVector<double> jac; + jacobianBasedQuality::sampleJacobian(_elementToScan, _viewOrder, + jac, normals); + for (int j = 0; j < jac.size(); ++j) { + _jacElementToScan.push_back(jac(j)); + } + } } delete normals; } @@ -515,4 +563,53 @@ void GMSH_AnalyseCurvedMeshPlugin::_printStatICN() infminI, avgminI, supminI); } +void GMSH_AnalyseCurvedMeshPlugin::_addElementInEntity(MElement *element, + GEntity *entity) +{ + int dim = entity->dim(); + switch (dim) { + case 1: + { + GEdge *gedge = dynamic_cast<GEdge*>(entity); + int type = element->getType(); + switch (type) { + case TYPE_LIN: + gedge->lines.push_back(dynamic_cast<MLine*>(element)); + } + } + break; + case 2: + { + GFace *gface = dynamic_cast<GFace*>(entity); + int type = element->getType(); + switch (type) { + case TYPE_TRI: + gface->triangles.push_back(dynamic_cast<MTriangle*>(element)); + break; + case TYPE_QUA: + gface->quadrangles.push_back(dynamic_cast<MQuadrangle*>(element)); + break; + } + } + break; + case 3: + { + GRegion *gregion = dynamic_cast<GRegion*>(entity); + int type = element->getType(); + switch (type) { + case TYPE_TET: + gregion->tetrahedra.push_back(dynamic_cast<MTetrahedron*>(element)); + break; + case TYPE_HEX: + gregion->hexahedra.push_back(dynamic_cast<MHexahedron*>(element)); + break; + case TYPE_PRI: + gregion->prisms.push_back(dynamic_cast<MPrism*>(element)); + break; + } + } + break; + } +} + #endif diff --git a/Plugin/AnalyseCurvedMesh.h b/Plugin/AnalyseCurvedMesh.h index d1aac032a5..7722695b87 100644 --- a/Plugin/AnalyseCurvedMesh.h +++ b/Plugin/AnalyseCurvedMesh.h @@ -42,6 +42,12 @@ private : GModel *_m; double _threshold; + // Element to scan + int _numElementToScan; + MElement *_elementToScan, *_hoElement; + int _viewOrder; + std::vector<double> _jacElementToScan; + // for 1d, 2d, 3d bool _computedJac[3], _computedIGE[3], _computedICN[3]; bool _PViewJac[3], _PViewIGE[3], _PViewICN[3]; @@ -81,6 +87,7 @@ private : void _printStatJacobian(); void _printStatIGE(); void _printStatICN(); + void _addElementInEntity(MElement*, GEntity*); }; #endif -- GitLab