diff --git a/Plugin/Distance.cpp b/Plugin/Distance.cpp index 51a4108dd9f53e40e185fb328fedd67b6d1ebda6..8b0f5fec164d2146122b32e83bb7425b168f0319 100644 --- a/Plugin/Distance.cpp +++ b/Plugin/Distance.cpp @@ -18,16 +18,16 @@ #include "linearSystemGMM.h" #include "linearSystemCSR.h" #include "linearSystemFull.h" +#include "orthogonalTerm.h" +#include "laplaceTerm.h" +#include "crossConfTerm.h" -#if defined(HAVE_ANN) -#include "ANN/ANN.h" -#endif StringXNumber DistanceOptions_Number[] = { {GMSH_FULLRC, "Point", NULL, 0.}, {GMSH_FULLRC, "Line", NULL, 0.}, {GMSH_FULLRC, "Surface", NULL, 0.}, - {GMSH_FULLRC, "Computation", NULL, -1.0}, + {GMSH_FULLRC, "Computation", NULL, 1.0}, //{GMSH_FULLRC, "Scale", NULL, 0.}, //{GMSH_FULLRC, "Min Scale", NULL, 1.e-3}, //{GMSH_FULLRC, "Max Scale", NULL, 1} @@ -46,6 +46,7 @@ extern "C" } } + std::string GMSH_DistancePlugin::getHelp() const { return "Plugin(Distance) computes distances to elementary entities in " @@ -53,9 +54,9 @@ std::string GMSH_DistancePlugin::getHelp() const "Define the elementary entities to which the distance is computed. If Point=0, Line=0, and Surface=0, then the distance is computed to all the boundaries of the mesh (edges in 2D and faces in 3D)\n\n" - "Computation<0. computes the geometrical euclidian distance (warning: different than the geodesic distance), and Computation=a>0.0 solves a PDE on the mesh with the diffusion constant mu = a*bbox, with bbox being the max size of the bounding box of the mesh (see paper Legrand 2006) \n\n" + "Computation<0. computes the geometrical euclidian distance (warning: different than the geodesic distance), and Computation=a>0.0 solves a PDE on the mesh with the diffusion constant mu = a*bbox, with bbox being the max size of the bounding box of the mesh (see paper Legrand 2006) \n\n" - "Plugin(Distance) creates a new distance view and also saves the view in the fileName.pos file."; + "Plugin(Distance) creates a new distance view and also saves the view in the fileName.pos file."; } int GMSH_DistancePlugin::getNbOptions() const @@ -87,26 +88,36 @@ PView *GMSH_DistancePlugin::execute(PView *v) int id_face = (int) DistanceOptions_Number[2].def; double type = (double) DistanceOptions_Number[3].def; - PView *view = new PView(); PViewDataList *data = getDataList(view); - +#ifdef HAVE_TAUCS + linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>; +#else + linearSystemCSRGmm<double> *lsys = new linearSystemCSRGmm<double>; + lsys->setNoisy(1); + lsys->setGmres(1); + lsys->setPrec(5.e-8); +#endif + dofManager<double> * dofView = new dofManager<double>(lsys); + std::vector<GEntity*> entities; GModel::current()->getEntities(entities); - int numnodes = 0; - for(unsigned int i = 0; i < entities.size() - 1; i++) - numnodes += entities[i]->mesh_vertices.size(); - int totNumNodes = numnodes + entities[entities.size() - 1]->mesh_vertices.size(); + int totNumNodes = 0; + for(unsigned int i = 0; i < entities.size() ; i++) + totNumNodes += entities[i]->mesh_vertices.size(); - std::map<MVertex*,double* > distance_map_GEOM; - std::map<MVertex*,double > distance_map_PDE; + std::map<MVertex*,double > distance_map; std::vector<SPoint3> pts; std::vector<double> distances; + std::vector<MVertex* > pt2Vertex; pts.clear(); distances.clear(); - distances.reserve(totNumNodes); + pt2Vertex.clear(); pts.reserve(totNumNodes); + distances.reserve(totNumNodes); + pt2Vertex.reserve(totNumNodes); + for (int i = 0; i < totNumNodes; i++) distances.push_back(1.e22); int k = 0; @@ -117,8 +128,8 @@ PView *GMSH_DistancePlugin::execute(PView *v) for(unsigned int j = 0; j < ge->mesh_vertices.size(); j++){ MVertex *v = ge->mesh_vertices[j]; pts.push_back(SPoint3(v->x(), v->y(),v->z())); - distance_map_GEOM.insert(std::make_pair(v, &(distances[k]))); - distance_map_PDE.insert(std::make_pair(v, 0.0)); + distance_map.insert(std::make_pair(v, 0.0)); + pt2Vertex[k] = v; k++; } } @@ -154,8 +165,11 @@ PView *GMSH_DistancePlugin::execute(PView *v) signedDistancesPointsTriangle(iDistances, iClosePts, pts, p1, p2, p3); } for (unsigned int kk = 0; kk< pts.size(); kk++) { - if (std::abs(iDistances[kk]) < distances[kk]) + if (std::abs(iDistances[kk]) < distances[kk]){ distances[kk] = std::abs(iDistances[kk]); + MVertex *v = pt2Vertex[kk]; + distance_map[v] = distances[kk]; + } } } } @@ -170,7 +184,7 @@ PView *GMSH_DistancePlugin::execute(PView *v) // for(unsigned int i = 0; i < g2->getNumMeshElements(); i++) data->setName("distance GEOM"); - Msg::Info("Writing %g", fileName.c_str()); + Msg::Info("Writing %s", fileName.c_str()); FILE * f3 = fopen( fileName.c_str(),"w"); fprintf(f3,"View \"distance GEOM\"{\n"); for(unsigned int ii = 0; ii < entities.size(); ii++){ @@ -192,8 +206,8 @@ PView *GMSH_DistancePlugin::execute(PView *v) MVertex *v = e->getVertex(j); if(j) fprintf(f3,",%g,%g,%g",v->x(),v->y(), v->z()); else fprintf(f3,"%g,%g,%g", v->x(),v->y(), v->z()); - std::map<MVertex*, double*>::iterator it = distance_map_GEOM.find(v); - dist.push_back(*(it->second)); + std::map<MVertex*, double>::iterator it = distance_map.find(v); + dist.push_back(it->second); } fprintf(f3,"){"); for (unsigned int i = 0; i < dist.size(); i++){ @@ -215,17 +229,6 @@ PView *GMSH_DistancePlugin::execute(PView *v) #if defined(HAVE_SOLVER) -#ifdef HAVE_TAUCS - linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>; -#else - linearSystemCSRGmm<double> *lsys = new linearSystemCSRGmm<double>; - lsys->setNoisy(1); - lsys->setGmres(1); - lsys->setPrec(5.e-8); -#endif - - dofManager<double> myAssembler(lsys); - SBoundingBox3d bbox; for(unsigned int i = 0; i < entities.size(); i++){ GEntity* ge = entities[i]; @@ -237,21 +240,25 @@ PView *GMSH_DistancePlugin::execute(PView *v) else if ( (tag==id_pt && gDim==0)|| (tag==id_line && gDim==1) || (tag==id_face && gDim==2) ) fixForEntity = true; if (fixForEntity){ - for(unsigned int j = 0; j < ge->mesh_vertices.size(); j++){ - MVertex *v = ge->mesh_vertices[j]; - myAssembler.fixVertex(v, 0, 1, 0.0); - bbox += SPoint3(v->x(),v->y(),v->z()); + for(unsigned int i = 0; i < ge->getNumMeshElements(); ++i){ + MElement *t = ge->getMeshElement(i); + for(int k = 0; k < t->getNumVertices(); k++){ + MVertex *v = t->getVertex(k); + dofView->fixVertex(v, 0, 1, 0.0); + bbox += SPoint3(v->x(),v->y(),v->z()); + } } } } - + std::vector<MElement *> allElems; for(unsigned int ii = 0; ii < entities.size(); ii++){ if(entities[ii]->dim() == maxDim) { GEntity *ge = entities[ii]; for(unsigned int i = 0; i < ge->getNumMeshElements(); ++i){ MElement *t = ge->getMeshElement(i); + allElems.push_back(t); for(int k = 0; k < t->getNumVertices(); k++){ - myAssembler.numberVertex(t->getVertex(k), 0, 1); + dofView->numberVertex(t->getVertex(k), 0, 1); } } } @@ -263,126 +270,181 @@ PView *GMSH_DistancePlugin::execute(PView *v) simpleFunction<double> DIFF(mu*mu), ONE(1.0); distanceTerm distance(GModel::current(), 1, &DIFF, &ONE); - for(unsigned int ii = 0; ii < entities.size(); ii++){ - if(entities[ii]->dim() == maxDim) { - GEntity *ge = entities[ii]; - for(unsigned int i = 0; i < ge->getNumMeshElements(); ++i){ - SElement se(ge->getMeshElement(i)); - distance.addToMatrix(myAssembler, &se); - } - groupOfElements g((GFace*)ge); - distance.addToRightHandSide(myAssembler, g); - } + for (std::vector<MElement* >::iterator it = allElems.begin(); it != allElems.end(); it++){ + SElement se((*it)); + distance.addToMatrix(*dofView, &se); } + groupOfElements gr(allElems); + distance.addToRightHandSide(*dofView, gr); Msg::Info("Distance Computation: Assembly done"); lsys->systemSolve(); Msg::Info("Distance Computation: System solved"); - for(std::map<MVertex*,double >::iterator itv = distance_map_PDE.begin(); - itv !=distance_map_PDE.end() ; ++itv){ + for(std::map<MVertex*,double >::iterator itv = distance_map.begin(); + itv !=distance_map.end() ; ++itv){ MVertex *v = itv->first; double value; - myAssembler.getDofValue(v, 0, 1, value); + dofView->getDofValue(v, 0, 1, value); value = std::min(0.9999, value); double dist = -mu * log(1. - value); itv->second = dist; } - lsys->clear(); data->setName("distance PDE"); - Msg::Info("Writing %d", fileName.c_str()); + Msg::Info("Writing %s", fileName.c_str()); FILE * f4 = fopen(fileName.c_str(),"w"); fprintf(f4,"View \"distance PDE\"{\n"); - for(unsigned int ii = 0; ii < entities.size(); ii++){ - if(entities[ii]->dim() == maxDim) { - for(unsigned int i = 0; i < entities[ii]->getNumMeshElements(); i++){ - MElement *e = entities[ii]->getMeshElement(i); - - int numNodes = e->getNumVertices(); - std::vector<double> x(numNodes), y(numNodes), z(numNodes); - std::vector<double> *out = data->incrementList(1, e->getType()); - for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->x()); - for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->y()); - for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->z()); - - if (maxDim == 3) fprintf(f4,"SS("); - else if (maxDim == 2) fprintf(f4,"ST("); - std::vector<double> dist; - for(int j = 0; j < numNodes; j++) { - MVertex *v = e->getVertex(j); - if(j) fprintf(f4,",%g,%g,%g",v->x(),v->y(), v->z()); - else fprintf(f4,"%g,%g,%g", v->x(),v->y(), v->z()); - std::map<MVertex*, double>::iterator it = distance_map_PDE.find(v); - dist.push_back(it->second); - } - fprintf(f4,"){"); - for (unsigned int i = 0; i < dist.size(); i++){ - out->push_back(dist[i]); - if (i) fprintf(f4,",%g", dist[i]); - else fprintf(f4,"%g", dist[i]); - } - fprintf(f4,"};\n"); - } + for (std::vector<MElement* >::iterator it = allElems.begin(); it != allElems.end(); it++){ + MElement *e = *it; + int numNodes = e->getNumVertices(); + std::vector<double> x(numNodes), y(numNodes), z(numNodes); + std::vector<double> *out = data->incrementList(1, e->getType()); + for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->x()); + for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->y()); + for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->z()); + + if (maxDim == 3) fprintf(f4,"SS("); + else if (maxDim == 2) fprintf(f4,"ST("); + std::vector<double> dist; + for(int j = 0; j < numNodes; j++) { + MVertex *v = e->getVertex(j); + if(j) fprintf(f4,",%g,%g,%g",v->x(),v->y(), v->z()); + else fprintf(f4,"%g,%g,%g", v->x(),v->y(), v->z()); + std::map<MVertex*, double>::iterator it = distance_map.find(v); + dist.push_back(it->second); } + fprintf(f4,"){"); + for (unsigned int i = 0; i < dist.size(); i++){ + out->push_back(dist[i]); + if (i) fprintf(f4,",%g", dist[i]); + else fprintf(f4,"%g", dist[i]); + } + fprintf(f4,"};\n"); } fprintf(f4,"};\n"); fclose(f4); #endif } + data->Time.push_back(0); + data->setFileName(fileName.c_str()); + data->finalize(); + + //compute also orthogonal vector to distance field + // A Uortho = -C DIST //------------------------------------------------ -// #if defined(HAVE_SOLVER) +#if defined(HAVE_SOLVER) -// #ifdef HAVE_TAUCS -// linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>; -// #else -// linearSystemCSRGmm<double> *lsys = new linearSystemCSRGmm<double>; -// lsys->setNoisy(1); -// lsys->setGmres(1); -// lsys->setPrec(5.e-8); -// #endif - -// dofManager<double> myAssembler(lsys); - -// for(unsigned int ii = 0; ii < entities.size(); ii++){ -// if(entities[ii]->dim() == maxDim) { -// GEntity *ge = entities[ii]; -// for(unsigned int i = 0; i < ge->getNumMeshElements(); ++i){ -// MElement *t = ge->getMeshElement(i); -// for(int k = 0; k < t->getNumVertices(); k++){ -// myAssembler.numberVertex(t->getVertex(k), 0, 1); -// } -// } -// } -// } - -// simpleFunction<double> ONE(1.0); -// simpleFunction<double> MONE(-1.0 ); -// laplaceTerm laplace(model(), 1, &ONE); -// crossConfTerm cross12(model(), 1, 1, &ONE); - -// for(unsigned int ii = 0; ii < entities.size(); ii++){ -// if(entities[ii]->dim() == maxDim) { -// GEntity *ge = entities[ii]; -// for(unsigned int i = 0; i < ge->getNumMeshElements(); ++i){ -// SElement se(ge->getMeshElement(i)); -// laplace.addToMatrix(myAssembler, &se); -// } -// //groupOfElements g((GFace*)ge); //WARNING GFACE HE -// //distance.addToRightHandSide(myAssembler, g); -// } -// } - -// #endif - - //------------------------------------------------- +#ifdef HAVE_TAUCS + linearSystemCSRTaucs<double> *lsys2 = new linearSystemCSRTaucs<double>; +#else + linearSystemCSRGmm<double> *lsys2 = new linearSystemCSRGmm<double>; + lsys->setNoisy(1); + lsys->setGmres(1); + lsys->setPrec(5.e-8); +#endif + dofManager<double> myAssembler(lsys2); + simpleFunction<double> ONE(1.0); + + double dMax = 0.03; + + std::vector<MElement *> allElems; + for(unsigned int ii = 0; ii < entities.size(); ii++){ + if(entities[ii]->dim() == maxDim) { + GEntity *ge = entities[ii]; + for(unsigned int i = 0; i < ge->getNumMeshElements(); ++i){ + MElement *t = ge->getMeshElement(i); + double vMean = 0.0; + for(int k = 0; k < t->getNumVertices(); k++){ + std::map<MVertex*, double>::iterator it = distance_map.find(t->getVertex(k)); + vMean += it->second; + } + vMean/=t->getNumVertices(); + if (vMean < dMax) + allElems.push_back(ge->getMeshElement(i)); + } + } + } + int mid = (int)floor(allElems.size()/2); + MElement *e = allElems[mid]; + MVertex *vFIX = e->getVertex(0); + myAssembler.fixVertex(vFIX, 0, 1, 0.0); + + for (std::vector<MElement* >::iterator it = allElems.begin(); it != allElems.end(); it++){ + MElement *t = *it; + for(int k = 0; k < t->getNumVertices(); k++) + myAssembler.numberVertex(t->getVertex(k), 0, 1); + } + + orthogonalTerm *ortho; + ortho = new orthogonalTerm(GModel::current(), 1, &ONE, &distance_map); + // if (type < 0) + // ortho = new orthogonalTerm(GModel::current(), 1, &ONE, view); + // else + // ortho = new orthogonalTerm(GModel::current(), 1, &ONE, dofView); + + for (std::vector<MElement* >::iterator it = allElems.begin(); it != allElems.end(); it++){ + SElement se((*it)); + ortho->addToMatrix(myAssembler, &se); + } + groupOfElements gr(allElems); + ortho->addToRightHandSide(myAssembler, gr); + Msg::Info("Orthogonal Computation: Assembly done"); + lsys2->systemSolve(); + Msg::Info("Orthogonal Computation: System solved"); - data->Time.push_back(0); - data->setFileName(fileName.c_str()); - data->finalize(); + PView *view2 = new PView(); + PViewDataList *data2 = getDataList(view2); + data2->setName("ortogonal field"); + + Msg::Info("Writing orthogonal.pos"); + FILE * f5 = fopen("orthogonal.pos","w"); + fprintf(f5,"View \"orthogonal\"{\n"); + for (std::vector<MElement* >::iterator it = allElems.begin(); it != allElems.end(); it++){ + MElement *e = *it; + + int numNodes = e->getNumVertices(); + std::vector<double> x(numNodes), y(numNodes), z(numNodes); + std::vector<double> *out2 = data2->incrementList(1, e->getType()); + for(int nod = 0; nod < numNodes; nod++) out2->push_back((e->getVertex(nod))->x()); + for(int nod = 0; nod < numNodes; nod++) out2->push_back((e->getVertex(nod))->y()); + for(int nod = 0; nod < numNodes; nod++) out2->push_back((e->getVertex(nod))->z()); + + if (maxDim == 3) fprintf(f5,"SS("); + else if (maxDim == 2) fprintf(f5,"ST("); + std::vector<double> orth; + for(int j = 0; j < numNodes; j++) { + MVertex *v = e->getVertex(j); + if(j) fprintf(f5,",%g,%g,%g",v->x(),v->y(), v->z()); + else fprintf(f5,"%g,%g,%g", v->x(),v->y(), v->z()); + double value; + myAssembler.getDofValue(v, 0, 1, value ); + orth.push_back(value); + } + fprintf(f5,"){"); + for (unsigned int i = 0; i < orth.size(); i++){ + out2->push_back(orth[i]); + if (i) fprintf(f5,",%g", orth[i]); + else fprintf(f5,"%g", orth[i]); + } + fprintf(f5,"};\n"); + } + fprintf(f5,"};\n"); + fclose(f5); + lsys->clear(); + lsys2->clear(); + + data2->Time.push_back(0); + data2->setFileName("orthogonal.pos"); + data2->finalize(); + +#endif + + + //------------------------------------------------- return view; } diff --git a/Plugin/PluginManager.cpp b/Plugin/PluginManager.cpp index b21b41d993752ed3360bccc8429a017986310715..d567ac00739e1c25741d53ef3b6111311ae5f9b9 100644 --- a/Plugin/PluginManager.cpp +++ b/Plugin/PluginManager.cpp @@ -29,6 +29,7 @@ #include "Curl.h" #include "Divergence.h" #include "Annotate.h" +#include "Distance.h" #include "Remove.h" #include "MakeSimplex.h" #include "Smooth.h" @@ -198,6 +199,8 @@ void PluginManager::registerDefaultPlugins() ("Curl", GMSH_RegisterCurlPlugin())); allPlugins.insert(std::pair<std::string, GMSH_Plugin*> ("Divergence", GMSH_RegisterDivergencePlugin())); + allPlugins.insert(std::pair<std::string, GMSH_Plugin*> + ("Distance", GMSH_RegisterDistancePlugin())); allPlugins.insert(std::pair<std::string, GMSH_Plugin*> ("Annotate", GMSH_RegisterAnnotatePlugin())); allPlugins.insert(std::pair<std::string, GMSH_Plugin*> diff --git a/Solver/femTerm.h b/Solver/femTerm.h index 849c949fe3dbd8e6300d9f1870b6cc52bf284567..20cd31efb732844fa8874ab4a968eef651a73710 100644 --- a/Solver/femTerm.h +++ b/Solver/femTerm.h @@ -157,7 +157,7 @@ class femTerm { void addToRightHandSide(dofManager<dataVec> &dm, groupOfElements &C) const { - groupOfElements::elementContainer::const_iterator it = C.begin(); + groupOfElements::elementContainer::const_iterator it = C.begin(); for ( ; it != C.end(); ++it){ MElement *eL = *it; SElement se(eL); diff --git a/Solver/groupOfElements.cpp b/Solver/groupOfElements.cpp index 2ca9fe4c3994d4f62784b269339ff6be99b70824..5da5342ab5ee6f980c352c6f68d4c8c5c9510f5d 100644 --- a/Solver/groupOfElements.cpp +++ b/Solver/groupOfElements.cpp @@ -8,6 +8,24 @@ groupOfElements::groupOfElements(GFace*gf) addElementary(gf, filter); } +groupOfElements::groupOfElements(GRegion*gr) +{ + elementFilterTrivial filter; + addElementary(gr, filter); +} + +groupOfElements::groupOfElements(std::vector<MElement*> &elems) +{ + elementFilterTrivial filter; + for (std::vector<MElement*>::iterator it = elems.begin(); it != elems.end(); it++){ + MElement *e = *it; + if (filter(e)){ + insert(e); + } + } +} + + void groupOfElements::addElementary(GEntity *ge, const elementFilter &filter){ for (unsigned int j = 0; j < ge->getNumMeshElements(); j++){ MElement *e = ge->getMeshElement(j); diff --git a/Solver/groupOfElements.h b/Solver/groupOfElements.h index 8af0d6e0e9811e4c8a512bd629ed74c05d47f8eb..db8f6e0421fdc64d600509a173310897ab768594 100644 --- a/Solver/groupOfElements.h +++ b/Solver/groupOfElements.h @@ -37,6 +37,8 @@ class groupOfElements { } groupOfElements (GFace*); + groupOfElements (GRegion*); + groupOfElements(std::vector<MElement*> &elems); virtual void addPhysical(int dim, int physical) { elementFilterTrivial filter; diff --git a/Solver/helmholtzTerm.h b/Solver/helmholtzTerm.h index 64b6d1890b7764dc9402d7c7b17f9b741f1f0e6a..5946d62e6895ddf24dc427d47ce26ffbe0c76031 100644 --- a/Solver/helmholtzTerm.h +++ b/Solver/helmholtzTerm.h @@ -47,6 +47,7 @@ class helmholtzTerm : public femTerm<scalar> { } virtual void elementMatrix(SElement *se, fullMatrix<scalar> &m) const { + MElement *e = se->getMeshElement(); // compute integration rule const int integrationOrder = (_a) ? 2 * e->getPolynomialOrder() : @@ -98,6 +99,7 @@ class helmholtzTerm : public femTerm<scalar> { for (int j = 0; j < nbNodes; j++) for (int k = 0; k < j; k++) m(k, j) = m(j, k); + } }; diff --git a/Solver/orthogonalTerm.h b/Solver/orthogonalTerm.h index cf1d3c32749c8aff69635e18ff4c679de0516670..6a5bd80ac95bd8125fea1a404b982db2914a50b6 100644 --- a/Solver/orthogonalTerm.h +++ b/Solver/orthogonalTerm.h @@ -7,21 +7,29 @@ #define _ORTHOGONAL_TERM_H_ #include "helmholtzTerm.h" +#include "dofManager.h" class orthogonalTerm : public helmholtzTerm<double> { protected: - fullVector<double> *_value; + PView *_pview; + dofManager<double> *_dofView; + bool withDof; + std::map<MVertex*,double > *_distance_map; public: - orthogonalTerm(GModel *gm, int iField, fullVector<double> &value) - : helmholtzTerm<double>(gm, iField, iField, 1.0, 0), _value(value) {} + orthogonalTerm(GModel *gm, int iField, simpleFunction<double> *k, std::map<MVertex*,double > *distance_map) + : helmholtzTerm<double>(gm, iField, iField, k, 0), _distance_map(distance_map), withDof(false) {} + orthogonalTerm(GModel *gm, int iField, simpleFunction<double> *k, PView *pview) + : helmholtzTerm<double>(gm, iField, iField, k, 0), _pview(pview), withDof(false) {} + orthogonalTerm(GModel *gm, int iField, simpleFunction<double> *k, dofManager<double> *dofView) + : helmholtzTerm<double>(gm, iField, iField, k, 0), _dofView(dofView), withDof(true) {} void elementVector(SElement *se, fullVector<double> &m) const { MElement *e = se->getMeshElement(); + int nbNodes = e->getNumVertices(); //fill elementary matrix mat(i,j) - int nbNodes = e->getNumVertices(); - int integrationOrder = 2 * (e->getPolynomialOrder() - 1); + int integrationOrder = 2* (e->getPolynomialOrder() - 1); int npts; IntPt *GP; double jac[3][3]; @@ -29,9 +37,9 @@ class orthogonalTerm : public helmholtzTerm<double> { SVector3 Grads [256]; double grads[256][3]; e->getIntegrationPoints(integrationOrder, &npts, &GP); - fullMatrix<double> mat; + fullMatrix<double> mat(nbNodes,nbNodes); mat.setAll(0.); - + for (int i = 0; i < npts; i++){ const double u = GP[i].pt[0]; const double v = GP[i].pt[1]; @@ -39,7 +47,6 @@ class orthogonalTerm : public helmholtzTerm<double> { const double weight = GP[i].weight; const double detJ = e->getJacobian(u, v, w, jac); SPoint3 p; e->pnt(u, v, w, p); - const double _diff = (*_diffusivity)(p.x(), p.y(), p.z()); inv3x3(jac, invjac); e->getGradShapeFunctions(u, v, w, grads); for (int j = 0; j < nbNodes; j++){ @@ -51,25 +58,45 @@ class orthogonalTerm : public helmholtzTerm<double> { invjac[2][2] * grads[j][2]); } SVector3 N (jac[2][0], jac[2][1], jac[2][2]); - for (int j = 0; j < nbNodes; j++){ - for (int k = 0; k <= j; k++){ - mat(j, k) += dot(crossprod(Grads[j], Grads[k]), N) * weight * detJ * _diff; - } - } + for (int j = 0; j < nbNodes; j++) + for (int k = 0; k <= j; k++) + mat(j, k) += dot(crossprod(Grads[j], Grads[k]), N) * weight * detJ; } for (int j = 0; j < nbNodes; j++) for (int k = 0; k < j; k++) - mat(k, j) = -1.* m(j, k); - + mat(k, j) = -1.* mat(j, k); + //2) compute vector m(i) = mat(i,j)*val(j) fullVector<double> val(nbNodes); + val.scale(0.); + + for (int i = 0; i < nbNodes; i++){ + std::map<MVertex*, double>::iterator it = _distance_map->find(e->getVertex(i)); + val(i) = it->second; + } + + /* if( withDof){ */ + /* for (int i = 0; i < nbNodes; i++){ */ + /* _dofView->getDofValue( e->getVertex(i), 0, 1, val(i)); */ + /* printf("val=%g \n", val(i)); */ + /* } */ + /* } */ + /* else{ */ + /* printf("with no dof \n"); */ + /* exit(1); */ + /* /\* PViewData *data = view->getData(); *\/ */ + /* /\* for (int i = 0; i < nbNodes; i++){ *\/ */ + /* /\* data->getValue(0, e->, e->getNum(), e->getVertex(i)->getNum(), nod, 0, val(i)); *\/ */ + /* /\* } *\/ */ + /* } */ m.scale(0.); for (int i = 0; i < nbNodes; i++) for (int j = 0; j < nbNodes; j++) - m(i) += mat(i,j)*val(j); - + m(i) += -mat(i,j)*val(j); + } + }; #endif