8 #include "GmshConfig.h"
15 #if defined(HAVE_SOLVER)
45 return "Plugin(Distance) computes distances to entities in a mesh.\n\n"
46 "If `PhysicalPoint', `PhysicalLine' and `PhysicalSurface' are 0, the "
47 "distance is computed to all the boundaries. Otherwise the distance "
48 "is computed to the given physical group.\n\n"
49 "If `DistanceType' is 0, the plugin computes the geometrical "
51 "distance using the naive O(N^2) algorithm. If `DistanceType' > 0, "
52 "the plugin computes an approximate distance by solving a PDE with "
53 "a diffusion constant equal to `DistanceType' time the maximum size "
54 "of the bounding box of the mesh as in [Legrand et al. 2006].\n\n"
55 "Positive `MinScale' and `MaxScale' scale the distance function.\n\n"
56 "Plugin(Distance) creates one new list-based view.";
70 std::map<MVertex *, double> &distanceMap)
75 double minDist = 1.e22;
77 for(
auto itv = distanceMap.begin(); itv != distanceMap.end(); ++itv) {
78 double dist = itv->second;
79 if(dist > maxDist) maxDist = dist;
80 if(dist < minDist) minDist = dist;
84 for(std::size_t ii = 0; ii < entities.size(); ii++) {
85 if(entities[ii]->dim() ==
_maxDim) {
86 for(std::size_t i = 0; i < entities[ii]->getNumMeshElements(); i++) {
87 MElement *e = entities[ii]->getMeshElement(i);
91 std::vector<double> x(numNodes), y(numNodes),
z(numNodes);
92 std::vector<double> *out =
94 std::vector<MVertex *> nods;
97 for(std::size_t i = 0; i < numNodes; i++)
104 for(std::size_t nod = 0; nod < numNodes; nod++)
105 out->push_back((nods[nod])->x());
106 for(std::size_t nod = 0; nod < numNodes; nod++)
107 out->push_back((nods[nod])->y());
108 for(std::size_t nod = 0; nod < numNodes; nod++)
109 out->push_back((nods[nod])->z());
111 std::vector<double> dist;
112 for(std::size_t j = 0; j < numNodes; j++) {
114 auto it = distanceMap.find(v);
115 dist.push_back(it->second);
118 for(std::size_t i = 0; i < dist.size(); i++) {
119 if(minScale > 0 && maxScale > 0 && maxDist != minDist)
120 dist[i] = minScale + ((dist[i] - minDist) / (maxDist - minDist)) *
121 (maxScale - minScale);
122 else if(minScale > 0)
123 dist[i] = minScale + dist[i];
124 out->push_back(dist[i]);
150 std::vector<GEntity *> entities;
153 std::vector<SPoint3> pts(totNumNodes);
154 std::vector<double> distances(totNumNodes, 1.e22);
155 std::vector<MVertex *> pt2Vertex(totNumNodes);
156 std::map<MVertex *, double> distanceMap;
159 for(std::size_t i = 0; i < entities.size(); i++) {
165 distanceMap.insert(std::make_pair(v, 0.0));
171 bool existEntity =
false;
172 for(std::size_t i = 0; i < entities.size(); i++) {
174 int gDim = g2->
dim();
175 bool computeForEntity =
false;
176 if(!id_point && !id_line && !id_face && gDim ==
_maxDim - 1) {
177 computeForEntity =
true;
181 for(std::size_t k = 0; k < phys.size(); k++) {
182 if((phys[k] == id_point && gDim == 0) ||
183 (phys[k] == id_line && gDim == 1) ||
184 (phys[k] == id_face && gDim == 2)) {
185 computeForEntity =
true;
190 if(computeForEntity) {
193 std::vector<double> iDistances;
194 std::vector<SPoint3> iClosePts;
195 std::vector<double> iDistancesE;
210 for(std::size_t kk = 0; kk < pts.size(); kk++) {
211 if(std::abs(iDistances[kk]) < distances[kk]) {
212 distances[kk] = std::abs(iDistances[kk]);
214 distanceMap[v] = distances[kk];
221 if(id_point)
Msg::Warning(
"Physical Point %d does not exist", id_point);
222 if(id_line)
Msg::Warning(
"Physical Curve %d does not exist", id_line);
223 if(id_face)
Msg::Warning(
"Physical Surface %d does not exist", id_face);
230 #if defined(HAVE_SOLVER)
231 #if defined(HAVE_PETSC)
233 #elif defined(HAVE_GMM)
240 bool existEntity =
false;
242 for(std::size_t i = 0; i < entities.size(); i++) {
244 int gDim = ge->
dim();
245 bool fixForEntity =
false;
246 if(!id_point && !id_line && !id_face && gDim ==
_maxDim - 1) {
251 for(std::size_t k = 0; k < phys.size(); k++) {
252 if((phys[k] == id_point && gDim == 0) ||
253 (phys[k] == id_line && gDim == 1) ||
254 (phys[k] == id_face && gDim == 2)) {
273 if(id_point)
Msg::Warning(
"Physical Point %d does not exist", id_point);
274 if(id_line)
Msg::Warning(
"Physical Curve %d does not exist", id_line);
275 if(id_face)
Msg::Warning(
"Physical Surface %d does not exist", id_face);
278 std::vector<MElement *> allElems;
279 for(std::size_t ii = 0; ii < entities.size(); ii++) {
280 if(entities[ii]->dim() ==
_maxDim) {
284 allElems.push_back(t);
291 double mu = type * L;
294 for(
auto it = allElems.begin(); it != allElems.end(); it++) {
296 distance.addToMatrix(*dofView, &se);
299 distance.addToRightHandSide(*dofView, gr);
301 for(
auto itv = distanceMap.begin(); itv != distanceMap.end(); ++itv) {
305 value = std::min(0.9999, value);
306 double dist = -mu * log(1. - value);