1 // Gmsh - Copyright (C) 1997-2021 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5
6 #include "BGMBase.h"
7
8 #include <iostream>
9 #include "OS.h"
10 #include "GPoint.h"
11 #include "GFace.h"
12 #include "GmshDefines.h"
13 #include "MElementOctree.h"
14
export_scalar(const std::string & filename,const DoubleStorageType & _whatToPrint) const15 void BGMBase::export_scalar(const std::string &filename,
16 const DoubleStorageType &_whatToPrint) const
17 {
18 FILE *f = Fopen(filename.c_str(), "w");
19 if(!f) {
20 Msg::Error("Could not open file '%s'", filename.c_str());
21 return;
22 }
23
24 fprintf(f, "View \"Background Mesh\"{\n");
25
26 const MElement *elem;
27 int nvertex;
28 int type;
29
30 for(unsigned int i = 0; i < getNumMeshElements(); i++) {
31 elem = getElement(i);
32 nvertex = elem->getNumVertices();
33 type = elem->getType();
34 const char *s = 0;
35 switch(type) {
36 case TYPE_PNT: s = "SP"; break;
37 case TYPE_LIN: s = "SL"; break;
38 case TYPE_TRI: s = "ST"; break;
39 case TYPE_QUA: s = "SQ"; break;
40 case TYPE_TET: s = "SS"; break;
41 case TYPE_HEX: s = "SH"; break;
42 case TYPE_PRI: s = "SI"; break;
43 case TYPE_PYR: s = "SY"; break;
44 default: throw;
45 }
46
47 fprintf(f, "%s(", s);
48 const MVertex *v;
49 std::vector<double> values(nvertex);
50 for(int iv = 0; iv < nvertex; iv++) {
51 v = elem->getVertex(iv);
52 values[iv] = get_nodal_value(v, _whatToPrint);
53 // GPoint p = gf->point(SPoint2(v->x(),v->y()));
54 GPoint p = get_GPoint_from_MVertex(v);
55 fprintf(f, "%g,%g,%g", p.x(), p.y(), p.z());
56 if(iv != nvertex - 1)
57 fprintf(f, ",");
58 else
59 fprintf(f, "){");
60 }
61 for(int iv = 0; iv < nvertex; iv++) {
62 fprintf(f, "%g", values[iv]);
63 if(iv != nvertex - 1)
64 fprintf(f, ",");
65 else
66 fprintf(f, "};\n");
67 }
68 }
69 fprintf(f, "};\n");
70 fclose(f);
71 }
72
export_vector(const std::string & filename,const VectorStorageType & _whatToPrint) const73 void BGMBase::export_vector(const std::string &filename,
74 const VectorStorageType &_whatToPrint) const
75 {
76 FILE *f = Fopen(filename.c_str(), "w");
77 if(!f) {
78 Msg::Error("Could not open file '%s'", filename.c_str());
79 return;
80 }
81
82 fprintf(f, "View \"Background Mesh\"{\n");
83
84 const MElement *elem;
85 int nvertex;
86 int type;
87
88 for(unsigned int i = 0; i < getNumMeshElements(); i++) {
89 elem = getElement(i);
90 nvertex = elem->getNumVertices();
91 type = elem->getType();
92 const char *s = 0;
93 switch(type) {
94 case TYPE_PNT: s = "VP"; break;
95 case TYPE_LIN: s = "VL"; break;
96 case TYPE_TRI: s = "VT"; break;
97 case TYPE_QUA: s = "VQ"; break;
98 case TYPE_TET: s = "VS"; break;
99 case TYPE_HEX: s = "VH"; break;
100 case TYPE_PRI: s = "VI"; break;
101 case TYPE_PYR: s = "VY"; break;
102 default: throw;
103 }
104
105 fprintf(f, "%s(", s);
106 const MVertex *v;
107 std::vector<double> values(nvertex * 3);
108 for(int iv = 0; iv < nvertex; iv++) {
109 v = elem->getVertex(iv);
110 std::vector<double> temp = get_nodal_value(v, _whatToPrint);
111 for(int j = 0; j < 3; j++) values[iv * 3 + j] = temp[j];
112 GPoint p = get_GPoint_from_MVertex(v);
113 fprintf(f, "%g,%g,%g", p.x(), p.y(), p.z());
114 if(iv != nvertex - 1)
115 fprintf(f, ",");
116 else
117 fprintf(f, "){");
118 }
119 for(int iv = 0; iv < nvertex; iv++) {
120 for(int j = 0; j < 3; j++) {
121 fprintf(f, "%g", values[iv * 3 + j]);
122 if(!((iv == nvertex - 1) && (j == 2)))
123 fprintf(f, ",");
124 else
125 fprintf(f, "};\n");
126 }
127 }
128 }
129 fprintf(f, "};\n");
130 fclose(f);
131 }
132
export_tensor_as_vectors(const std::string & filename,const TensorStorageType & _whatToPrint) const133 void BGMBase::export_tensor_as_vectors(
134 const std::string &filename, const TensorStorageType &_whatToPrint) const
135 {
136 FILE *f = Fopen(filename.c_str(), "w");
137 if(!f) {
138 Msg::Error("Could not open file '%s'", filename.c_str());
139 return;
140 }
141
142 fprintf(f, "View \"Background Mesh\"{\n");
143
144 TensorStorageType::const_iterator it = _whatToPrint.begin();
145 const char *s = "VP";
146
147 for(; it != _whatToPrint.end(); it++) { // for all vertices
148 GPoint p = get_GPoint_from_MVertex(it->first);
149 for(int i = 0; i < 3; i++) {
150 fprintf(f, "%s(%g,%g,%g){%g,%g,%g};\n", s, p.x(), p.y(), p.z(),
151 (it->second)(0, i), (it->second)(1, i), (it->second)(2, i));
152 fprintf(f, "%s(%g,%g,%g){%g,%g,%g};\n", s, p.x(), p.y(), p.z(),
153 -(it->second)(0, i), -(it->second)(1, i), -(it->second)(2, i));
154 }
155 }
156 fprintf(f, "};\n");
157 fclose(f);
158 }
159
BGMBase(int dim,GEntity * _gf)160 BGMBase::BGMBase(int dim, GEntity *_gf)
161 : octree(NULL), gf(_gf), DIM(dim), order(1)
162 {
163 }
164
~BGMBase()165 BGMBase::~BGMBase() {}
166
inDomain(double u,double v,double w)167 bool BGMBase::inDomain(double u, double v, double w)
168 {
169 return (findElement(u, v, w) != NULL);
170 }
171
findElement(double u,double v,double w,bool strict)172 const MElement *BGMBase::findElement(double u, double v, double w, bool strict)
173 {
174 return (getOctree()->find(u, v, w, DIM, strict));
175 }
176
get_field_value(double u,double v,double w,const VectorStorageType & data)177 std::vector<double> BGMBase::get_field_value(double u, double v, double w,
178 const VectorStorageType &data)
179 {
180 // TODO C++11 remove const_cast and enforce const-correctness otherwise
181 MElement *e = const_cast<MElement *>(findElement(u, v, w));
182
183 if(!e) return std::vector<double>(3, -1000.);
184
185 std::vector<std::vector<double> > val = get_nodal_values(e, data);
186 std::vector<double> element_uvw = get_element_uvw_from_xyz(e, u, v, w);
187
188 std::vector<double> res(3);
189
190 for(int j = 0; j < 3; j++) {
191 std::vector<double> values(e->getNumVertices());
192
193 for(std::size_t i = 0; i < e->getNumVertices(); i++) {
194 values[i] = val[i][j];
195 }
196 res[j] = e->interpolate(&values[0], element_uvw[0], element_uvw[1],
197 element_uvw[2], 1, order);
198 }
199 return res;
200 }
201
get_field_value(double u,double v,double w,const DoubleStorageType & data)202 double BGMBase::get_field_value(double u, double v, double w,
203 const DoubleStorageType &data)
204 {
205 // TODO C++11 Remove const_cast
206 MElement *e = const_cast<MElement *>(findElement(u, v, w));
207 if(!e) return -1000.;
208 std::vector<double> val = get_nodal_values(e, data);
209 std::vector<double> element_uvw = get_element_uvw_from_xyz(e, u, v, w);
210 std::vector<double> values(e->getNumVertices());
211 for(std::size_t i = 0; i < e->getNumVertices(); i++) values[i] = val[i];
212
213 return e->interpolate(&values[0], element_uvw[0], element_uvw[1],
214 element_uvw[2], 1, order);
215 }
216
size(double u,double v,double w)217 double BGMBase::size(double u, double v, double w)
218 {
219 return get_field_value(u, v, w, sizeField);
220 }
221
size(const MVertex * v)222 double BGMBase::size(const MVertex *v) { return get_nodal_value(v, sizeField); }
223
224 std::vector<double>
get_nodal_value(const MVertex * v,const VectorStorageType & data) const225 BGMBase::get_nodal_value(const MVertex *v, const VectorStorageType &data) const
226 {
227 VectorStorageType::const_iterator itfind = data.find(v);
228 if(itfind == data.end()) {
229 Msg::Error("Unknown vertex %d in BGMBase::get_nodal_value", v->getNum());
230 return std::vector<double>(3, 0.);
231 }
232 return itfind->second;
233 }
234
get_nodal_value(const MVertex * v,const DoubleStorageType & data) const235 double BGMBase::get_nodal_value(const MVertex *v,
236 const DoubleStorageType &data) const
237 {
238 DoubleStorageType::const_iterator itfind = data.find(v);
239 if(itfind == data.end()) {
240 Msg::Error("Unknown vertex %d in BGMBase::get_nodal_value", v->getNum());
241 return 0.;
242 }
243 return itfind->second;
244 }
245
246 std::vector<std::vector<double> >
get_nodal_values(const MElement * e,const VectorStorageType & data) const247 BGMBase::get_nodal_values(const MElement *e,
248 const VectorStorageType &data) const
249 {
250 std::vector<std::vector<double> > res(e->getNumVertices());
251
252 for(std::size_t i = 0; i < e->getNumVertices(); i++) {
253 VectorStorageType::const_iterator itfind =
254 data.find(const_cast<MVertex *>(e->getVertex(i)));
255 for(int j = 0; j < 3; j++) res[i].push_back((itfind->second)[j]);
256 }
257 return res;
258 }
259
260 std::vector<double>
get_nodal_values(const MElement * element,const DoubleStorageType & data) const261 BGMBase::get_nodal_values(const MElement *element,
262 const DoubleStorageType &data) const
263 {
264 std::vector<double> res(element->getNumVertices(), 0.);
265
266 for(std::size_t i = 0; i < element->getNumVertices(); i++)
267 // res[i] = (data.find(const_cast<MVertex*>(e->getVertex(i))))->second;
268 res[i] = data.find(element->getVertex(i))->second;
269 return res;
270 }
271
get_element_uvw_from_xyz(const MElement * e,double x,double y,double z) const272 std::vector<double> BGMBase::get_element_uvw_from_xyz(const MElement *e,
273 double x, double y,
274 double z) const
275 {
276 std::vector<double> res(3);
277
278 double xyz[3] = {x, y, z};
279 e->xyz2uvw(xyz, &res[0]);
280
281 return res;
282 }
283
get_vertices_of_maximum_dim(int dim)284 std::set<MVertex *> BGMBase::get_vertices_of_maximum_dim(int dim)
285 {
286 std::set<MVertex *> bnd_vertices;
287 for(unsigned int i = 0; i < gf->getNumMeshElements(); i++) {
288 MElement *element = gf->getMeshElement(i);
289 for(std::size_t j = 0; j < element->getNumVertices(); j++) {
290 MVertex *vertex = element->getVertex(j);
291 if(vertex->onWhat()->dim() <= dim) bnd_vertices.insert(vertex);
292 }
293 }
294 return bnd_vertices;
295 }
296
getBackgroundGEntity()297 GEntity *BGMBase::getBackgroundGEntity() { return gf; }
298