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 #ifndef FIELD_H 7 #define FIELD_H 8 9 #include <string> 10 #include <map> 11 #include <vector> 12 #include <list> 13 #include "GmshConfig.h" 14 #include "Context.h" 15 #include "STensor3.h" 16 #include <fstream> 17 #include <string> 18 #include <string.h> 19 #include <sstream> 20 #include <algorithm> 21 22 #if defined(HAVE_POST) 23 class PView; 24 #endif 25 26 class Field; 27 class GEntity; 28 29 typedef enum { 30 FIELD_OPTION_DOUBLE = 0, 31 FIELD_OPTION_INT, 32 FIELD_OPTION_STRING, 33 FIELD_OPTION_PATH, 34 FIELD_OPTION_BOOL, 35 FIELD_OPTION_LIST, 36 FIELD_OPTION_LIST_DOUBLE 37 } FieldOptionType; 38 39 class FieldCallback { 40 private: 41 std::string _help; 42 43 public: 44 virtual void run() = 0; FieldCallback(const std::string & help)45 FieldCallback(const std::string &help) { _help = help; } ~FieldCallback()46 virtual ~FieldCallback(){}; getDescription()47 virtual std::string getDescription() { return _help; } 48 }; 49 50 class FieldOption { 51 private: 52 std::string _help; 53 bool _deprecated; 54 55 protected: 56 bool *status; modified()57 inline void modified() 58 { 59 if(status) *status = true; 60 } 61 62 public: FieldOption(const std::string & help,bool * _status,bool deprecated)63 FieldOption(const std::string &help, bool *_status, bool deprecated) 64 : _help(help), _deprecated(deprecated), status(_status) 65 { 66 } ~FieldOption()67 virtual ~FieldOption() {} 68 virtual FieldOptionType getType() = 0; 69 virtual void getTextRepresentation(std::string &v_str) = 0; getDescription()70 virtual std::string getDescription() { return _help; } getTypeName()71 std::string getTypeName() 72 { 73 switch(getType()) { 74 case FIELD_OPTION_INT: return "integer"; 75 case FIELD_OPTION_DOUBLE: return "float"; 76 case FIELD_OPTION_BOOL: return "boolean"; 77 case FIELD_OPTION_PATH: return "path"; 78 case FIELD_OPTION_STRING: return "string"; 79 case FIELD_OPTION_LIST: return "list"; 80 case FIELD_OPTION_LIST_DOUBLE: return "list_double"; 81 default: return "unknown"; 82 } 83 } numericalValue(double val)84 virtual void numericalValue(double val) {} numericalValue()85 virtual double numericalValue() const { return 0.; } list()86 virtual const std::list<int> &list() const 87 { 88 static std::list<int> l; 89 return l; 90 } listdouble()91 virtual const std::list<double> &listdouble() const 92 { 93 static std::list<double> l; 94 return l; 95 } list(std::list<int> value)96 virtual void list(std::list<int> value) {} listdouble(std::list<double> value)97 virtual void listdouble(std::list<double> value) {} string()98 virtual std::string string() const { return ""; } string(const std::string value)99 virtual void string(const std::string value) {} isDeprecated()100 bool isDeprecated() { return _deprecated; } 101 }; 102 103 class Field { 104 protected: 105 bool _deprecated; 106 public: Field()107 Field() : _deprecated(false), updateNeeded(false) {} 108 virtual ~Field(); isDeprecated()109 bool isDeprecated() { return _deprecated; } update()110 virtual void update() {} 111 int id; 112 std::map<std::string, FieldOption *> options; 113 std::map<std::string, FieldCallback *> callbacks; numComponents()114 virtual int numComponents() const { return 1; } isotropic()115 virtual bool isotropic() const { return true; } 116 // isotropic 117 virtual double operator()(double x, double y, double z, 118 GEntity *ge = nullptr) = 0; 119 // vector value operator()120 virtual void operator()(double x, double y, double z, SVector3 &, 121 GEntity *ge = 0) 122 { 123 } 124 // anisotropic operator()125 virtual void operator()(double x, double y, double z, SMetric3 &, 126 GEntity *ge = nullptr) 127 { 128 } 129 bool updateNeeded; 130 virtual const char *getName() = 0; 131 #if defined(HAVE_POST) 132 void putOnView(PView *view, int comp = -1); 133 #endif 134 void putOnNewView(int viewTag = -1); getDescription()135 virtual std::string getDescription() { return ""; } 136 FieldOption *getOption(const std::string &optionName); 137 }; 138 139 class FieldFactory { 140 public: ~FieldFactory()141 virtual ~FieldFactory() {} 142 virtual Field *operator()() = 0; 143 }; 144 145 class FieldManager : public std::map<int, Field *> { 146 private: 147 int _backgroundField; 148 std::vector<int> _boundaryLayerFields; 149 150 public: 151 std::map<std::string, FieldFactory *> mapTypeName; 152 void initialize(); 153 void reset(); 154 Field *get(int id); 155 Field *newField(int id, const std::string &type_name); 156 void deleteField(int id); 157 int newId(); 158 int maxId(); 159 FieldManager(); 160 ~FieldManager(); 161 // compatibility with -bgm 162 void setBackgroundMesh(int iView); 163 // set and get background field 164 void setBackgroundField(Field *BGF); setBackgroundFieldId(int id)165 inline void setBackgroundFieldId(int id) { _backgroundField = id; }; addBoundaryLayerFieldId(int id)166 inline void addBoundaryLayerFieldId(int id) 167 { 168 for(std::size_t i = 0; i < _boundaryLayerFields.size(); ++i) { 169 if(_boundaryLayerFields[i] == id) return; 170 } 171 _boundaryLayerFields.push_back(id); 172 } addBoundaryLayerFieldId(std::vector<int> & tags)173 inline void addBoundaryLayerFieldId(std::vector<int> &tags) 174 { 175 for(std::size_t i = 0; i < tags.size(); ++i) 176 addBoundaryLayerFieldId(tags[i]); 177 } getBackgroundField()178 inline int getBackgroundField() { return _backgroundField; } getNumBoundaryLayerFields()179 inline int getNumBoundaryLayerFields() 180 { 181 return (int)_boundaryLayerFields.size(); 182 } getBoundaryLayerField(int i)183 inline int getBoundaryLayerField(int i) { return _boundaryLayerFields[i]; } 184 }; 185 186 // Boundary Layer Field (used both for anisotropic meshing and BL 187 // extrusion) 188 189 class DistanceField; 190 191 class BoundaryLayerField : public Field { 192 private: 193 std::list<DistanceField *> _attFields; 194 std::list<double> _hWallNNodes; 195 std::list<int> _pointTags, _curveTags; 196 std::list<int> _pointTagsSaved, _curveTagsSaved, _fanPointTags; 197 std::list<int> _excludedSurfaceTags; 198 std::list<int> _fanSizes; 199 SPoint3 _closestPoint; 200 void operator()(DistanceField *cc, double dist, double x, double y, double z, 201 SMetric3 &metr, GEntity *ge); 202 203 public: 204 double hWallN, ratio, hFar, thickness; 205 double currentDistance, tgtAnisoRatio, beta; 206 int iRecombine, iIntersect, betaLaw, nb_divisions; 207 DistanceField *currentClosest; isotropic()208 virtual bool isotropic() const { return false; } 209 virtual const char *getName(); 210 virtual std::string getDescription(); 211 BoundaryLayerField(); ~BoundaryLayerField()212 ~BoundaryLayerField() { removeAttractors(); } 213 virtual double operator()(double x, double y, double z, 214 GEntity *ge = nullptr); 215 virtual void operator()(double x, double y, double z, SMetric3 &metr, 216 GEntity *ge = nullptr); isEdgeBL(int iE)217 bool isEdgeBL(int iE) const 218 { 219 return std::find(_curveTags.begin(), _curveTags.end(), iE) != 220 _curveTags.end(); 221 } isEdgeBLSaved(int iE)222 bool isEdgeBLSaved(int iE) const 223 { 224 return std::find(_curveTagsSaved.begin(), _curveTagsSaved.end(), iE) != 225 _curveTagsSaved.end(); 226 } isFanNode(int iV)227 bool isFanNode(int iV) const 228 { 229 return std::find(_fanPointTags.begin(), _fanPointTags.end(), iV) != 230 _fanPointTags.end(); 231 } fanSize(int iV)232 int fanSize(int iV) 233 { 234 if(_fanPointTags.size() != _fanSizes.size()) 235 return CTX::instance()->mesh.boundaryLayerFanElements; 236 auto it1 = _fanPointTags.begin(); 237 auto it2 = _fanSizes.begin(); 238 for(; it1 != _fanPointTags.end(); ++it1, ++it2) { 239 if(*it1 == iV) return *it2; 240 } 241 return 0; 242 } 243 isEndNode(int iV)244 bool isEndNode(int iV) const 245 { 246 return std::find(_pointTags.begin(), _pointTags.end(), iV) != 247 _pointTags.end(); 248 } hWall(int iV)249 double hWall(int iV) 250 { 251 for(auto it = _hWallNNodes.begin(); it != _hWallNNodes.end(); ++it) { 252 int i = (int)*it; 253 ++it; 254 double h = *it; 255 if(i == iV) return h; 256 } 257 return hWallN; 258 } 259 void computeFor1dMesh(double x, double y, double z, SMetric3 &metr); 260 void setupFor1d(int iE); 261 bool setupFor2d(int iF); 262 void removeAttractors(); 263 }; 264 265 class FieldOptionString : public FieldOption { 266 public: 267 std::string &val; getType()268 virtual FieldOptionType getType() { return FIELD_OPTION_STRING; } 269 FieldOptionString(std::string &_val, const std::string &help, 270 bool *status = nullptr, bool deprecated = false) FieldOption(help,status,deprecated)271 : FieldOption(help, status, deprecated), val(_val) 272 { 273 } string(const std::string value)274 void string(const std::string value) 275 { 276 modified(); 277 val = value; 278 } string()279 std::string string() const { return val; } getTextRepresentation(std::string & v_str)280 void getTextRepresentation(std::string &v_str) 281 { 282 std::ostringstream sstream; 283 sstream << "\"" << val << "\""; 284 v_str = sstream.str(); 285 } 286 }; 287 288 class FieldOptionDouble : public FieldOption { 289 public: 290 double &val; getType()291 FieldOptionType getType() { return FIELD_OPTION_DOUBLE; } 292 FieldOptionDouble(double &_val, const std::string &help, 293 bool *status = nullptr, bool deprecated = false) FieldOption(help,status,deprecated)294 : FieldOption(help, status, deprecated), val(_val) 295 { 296 } numericalValue()297 double numericalValue() const { return val; } numericalValue(double v)298 void numericalValue(double v) 299 { 300 modified(); 301 val = v; 302 } getTextRepresentation(std::string & v_str)303 void getTextRepresentation(std::string &v_str) 304 { 305 std::ostringstream sstream; 306 sstream.precision(16); 307 sstream << val; 308 v_str = sstream.str(); 309 } 310 }; 311 312 class FieldOptionInt : public FieldOption { 313 public: 314 int &val; getType()315 FieldOptionType getType() { return FIELD_OPTION_INT; } 316 FieldOptionInt(int &_val, const std::string &help, bool *status = nullptr, 317 bool deprecated = false) FieldOption(help,status,deprecated)318 : FieldOption(help, status, deprecated), val(_val) 319 { 320 } numericalValue()321 double numericalValue() const { return val; } numericalValue(double v)322 void numericalValue(double v) 323 { 324 modified(); 325 val = (int)v; 326 } getTextRepresentation(std::string & v_str)327 void getTextRepresentation(std::string &v_str) 328 { 329 std::ostringstream sstream; 330 sstream << val; 331 v_str = sstream.str(); 332 } 333 }; 334 335 class FieldOptionList : public FieldOption { 336 public: 337 std::list<int> &val; getType()338 FieldOptionType getType() { return FIELD_OPTION_LIST; } 339 FieldOptionList(std::list<int> &_val, const std::string &help, 340 bool *status = nullptr, bool deprecated = false) FieldOption(help,status,deprecated)341 : FieldOption(help, status, deprecated), val(_val) 342 { 343 } list(std::list<int> value)344 void list(std::list<int> value) 345 { 346 modified(); 347 val = value; 348 } list()349 const std::list<int> &list() const { return val; } getTextRepresentation(std::string & v_str)350 void getTextRepresentation(std::string &v_str) 351 { 352 std::ostringstream sstream; 353 sstream << "{"; 354 for(auto it = val.begin(); it != val.end(); it++) { 355 if(it != val.begin()) sstream << ", "; 356 sstream << *it; 357 } 358 sstream << "}"; 359 v_str = sstream.str(); 360 } 361 }; 362 363 class FieldOptionListDouble : public FieldOption { 364 public: 365 std::list<double> &val; getType()366 FieldOptionType getType() { return FIELD_OPTION_LIST_DOUBLE; } 367 FieldOptionListDouble(std::list<double> &_val, const std::string &help, 368 bool *status = nullptr, bool deprecated = false) FieldOption(help,status,deprecated)369 : FieldOption(help, status, deprecated), val(_val) 370 { 371 } listdouble(std::list<double> value)372 void listdouble(std::list<double> value) 373 { 374 modified(); 375 val = value; 376 } listdouble()377 const std::list<double> &listdouble() const { return val; } getTextRepresentation(std::string & v_str)378 void getTextRepresentation(std::string &v_str) 379 { 380 std::ostringstream sstream; 381 sstream.precision(16); 382 sstream << "{"; 383 for(auto it = val.begin(); it != val.end(); it++) { 384 if(it != val.begin()) sstream << ", "; 385 sstream << *it; 386 } 387 sstream << "}"; 388 v_str = sstream.str(); 389 } 390 }; 391 392 class FieldOptionPath : public FieldOptionString { 393 public: getType()394 virtual FieldOptionType getType() { return FIELD_OPTION_PATH; } 395 FieldOptionPath(std::string &val, const std::string &help, 396 bool *status = nullptr, bool deprecated = false) FieldOptionString(val,help,status,deprecated)397 : FieldOptionString(val, help, status, deprecated) 398 { 399 } 400 }; 401 402 class FieldOptionBool : public FieldOption { 403 public: 404 bool &val; getType()405 FieldOptionType getType() { return FIELD_OPTION_BOOL; } 406 FieldOptionBool(bool &_val, const std::string &help, bool *status = nullptr, 407 bool deprecated = false) FieldOption(help,status,deprecated)408 : FieldOption(help, status, deprecated), val(_val) 409 { 410 } numericalValue()411 double numericalValue() const { return val; } numericalValue(double v)412 void numericalValue(double v) 413 { 414 modified(); 415 val = v; 416 } getTextRepresentation(std::string & v_str)417 void getTextRepresentation(std::string &v_str) 418 { 419 std::ostringstream sstream; 420 sstream << val; 421 v_str = sstream.str(); 422 } 423 }; 424 425 template <class t> class FieldCallbackGeneric : public FieldCallback { 426 t *_field; 427 void (t::*_callback)(); 428 429 public: run()430 void run() { (_field->*_callback)(); } FieldCallbackGeneric(t * field,void (t::* callback)(),const std::string description)431 FieldCallbackGeneric(t *field, void (t::*callback)(), 432 const std::string description) 433 : FieldCallback(description) 434 { 435 _field = field; 436 _callback = callback; 437 } 438 }; 439 440 template <class F> class FieldFactoryT : public FieldFactory { 441 public: operator()442 Field *operator()() { return new F; } 443 }; 444 445 // the class GenericField contains a set of void* functions, which give a mesh 446 // size All these functions are called when calling operator() ; then, the 447 // minimum size is returned. 448 class GenericField : public Field { 449 public: 450 // callback prototypes: 451 // this callback is called with a void* previously given to the GenericField ! 452 typedef bool (*ptrfunction)(double, double, double, void *, double &); 453 // this callback also takes the GEntity object into account 454 typedef bool (*ptrfunctionextended)(double, double, double, void *, void *, 455 double &); 456 457 GenericField(); 458 ~GenericField(); 459 using Field::operator(); 460 virtual double operator()(double x, double y, double z, 461 GEntity *ge = nullptr); getName()462 virtual const char *getName() { return "GenericField"; }; 463 464 // sets the callbacks 465 void setCallbackWithData(ptrfunction fct, void *data); 466 void setCallbackWithData(ptrfunctionextended fct, void *data); 467 468 private: 469 std::vector<std::pair<ptrfunction, void *> > 470 cbs_with_data; // the callbacks with the data to be sent to them 471 std::vector<std::pair<ptrfunctionextended, void *> > 472 cbs_extended_with_data; // the extended callbacks with the data to be sent 473 // to them 474 }; 475 476 #endif 477