// Gmsh - Copyright (C) 1997-2016 C. Geuzaine, J.-F. Remacle // // See the LICENSE.txt file for license information. Please report all // bugs and problems to the public mailing list <gmsh@onelab.info>. #ifndef _FIELD_H_ #define _FIELD_H_ #include <string> #include <map> #include <vector> #include <list> #include "GmshConfig.h" #include "STensor3.h" #include <fstream> #include <string> #include <string.h> #include <sstream> #include <algorithm> #if defined(HAVE_POST) class PView; #endif class Field; class GEntity; typedef enum { FIELD_OPTION_DOUBLE = 0, FIELD_OPTION_INT, FIELD_OPTION_STRING, FIELD_OPTION_PATH, FIELD_OPTION_BOOL, FIELD_OPTION_LIST } FieldOptionType; class FieldCallback { private: std::string _help; public: virtual void run() = 0; FieldCallback(const std::string help){ _help = help;} virtual ~FieldCallback(){}; virtual std::string getDescription(){ return _help; } }; class FieldOption { private: std::string _help; protected: bool *status; inline void modified(){ if(status) *status = true; } public: FieldOption(std::string help, bool *_status) : _help(help), status(_status) {} virtual ~FieldOption() {} virtual FieldOptionType getType() = 0; virtual void getTextRepresentation(std::string & v_str) = 0; virtual std::string getDescription(){ return _help; } std::string getTypeName(){ switch(getType()){ case FIELD_OPTION_INT: return "integer"; break; case FIELD_OPTION_DOUBLE: return "float"; break; case FIELD_OPTION_BOOL: return "boolean"; break; case FIELD_OPTION_PATH: return "path"; break; case FIELD_OPTION_STRING: return "string"; break; case FIELD_OPTION_LIST: return "list"; break; default: return "unknown"; } } virtual void numericalValue(double val) { throw(1); } virtual double numericalValue() const { throw(1); } virtual const std::list<int> &list() const { throw(1); } virtual void list(std::list<int> value) { throw(1); } virtual std::string string() const { throw(1); } virtual void string(const std::string value) { throw(1); } }; class Field { public: Field() : update_needed(false) {} virtual ~Field(); int id; std::map<std::string, FieldOption *> options; std::map<std::string, FieldCallback*> callbacks; virtual bool isotropic () const { return true; } // isotropic virtual double operator() (double x, double y, double z, GEntity *ge=0) = 0; // anisotropic virtual void operator() (double x, double y, double z, SMetric3 &, GEntity *ge=0){} // temporary virtual void operator()(double x, double y, double z, SVector3& v1, SVector3& v2, SVector3& v3,GEntity* ge=0){} bool update_needed; virtual const char *getName() = 0; #if defined(HAVE_POST) void putOnView(PView * view, int comp = -1); #endif void putOnNewView(); virtual std::string getDescription(){ return ""; } FieldOption * getOption(const std::string optionName); }; class FieldFactory { public: virtual ~FieldFactory() {} virtual Field * operator() () = 0; }; class FieldManager : public std::map<int, Field*> { private: int _background_field; int _boundaryLayer_field; public: std::map<std::string, FieldFactory*> map_type_name; void reset(); Field *get(int id); Field *newField(int id, std::string type_name); void deleteField(int id); int newId(); int maxId(); FieldManager(); ~FieldManager(); // compatibility with -bgm void setBackgroundMesh(int iView); // set and get background field void setBackgroundField(Field* BGF); inline void setBackgroundFieldId(int id){_background_field = id;}; inline void setBoundaryLayerFieldId(int id){_boundaryLayer_field = id;}; inline int getBackgroundField(){return _background_field;} inline int getBoundaryLayerField(){return _boundaryLayer_field;} }; // Boundary Layer Field (used both for anisotropic meshing and BL // extrusion) #if defined(HAVE_ANN) class AttractorField; class BoundaryLayerField : public Field { private: std::list<AttractorField *> _att_fields; std::list<int> nodes_id, edges_id, faces_id; std::list<int> faces_id_saved, edges_id_saved, nodes_id_saved, fans_id, fan_nodes_id; void operator() (AttractorField *cc, double dist, double x, double y, double z, SMetric3 &metr, GEntity *ge); public: double hwall_n,hwall_t,ratio,hfar,thickness,fan_angle; double current_distance, tgt_aniso_ratio; SPoint3 _closest_point; int iRecombine, iIntersect; AttractorField *current_closest; virtual bool isotropic () const {return false;} virtual const char *getName(); virtual std::string getDescription(); BoundaryLayerField(); ~BoundaryLayerField() {removeAttractors();} virtual double operator() (double x, double y, double z, GEntity *ge=0); virtual void operator() (double x, double y, double z, SMetric3 &metr, GEntity *ge=0); bool isFaceBL (int iF) const { return std::find(faces_id.begin(),faces_id.end(),iF) != faces_id.end(); } bool isEdgeBL (int iE) const { return std::find(edges_id.begin(),edges_id.end(),iE) != edges_id.end(); } bool isEdgeBLSaved (int iE) const { return std::find(edges_id_saved.begin(),edges_id_saved.end(),iE) != edges_id_saved.end(); } bool isFan (int iE) const { return std::find(fans_id.begin(),fans_id.end(),iE) != fans_id.end(); } bool isFanNode (int iV) const { return std::find(fan_nodes_id.begin(),fan_nodes_id.end(),iV) != fan_nodes_id.end(); } bool isVertexBL (int iV) const { return std::find(nodes_id.begin(),nodes_id.end(),iV) != nodes_id.end(); } void computeFor1dMesh(double x, double y, double z, SMetric3 &metr); void setupFor2d(int iF); void setupFor3d(); void removeAttractors(); }; #else class BoundaryLayerField : public Field { public: virtual bool isotropic() const { return false; } virtual const char *getName(){ return ""; } virtual std::string getDescription(){ return ""; } BoundaryLayerField() { Msg::Error("You must compile with ANN to use BoundaryLayerField"); } ~BoundaryLayerField() {} virtual double operator() (double x, double y, double z, GEntity *ge=0){ return 0.; } virtual void operator() (double x, double y, double z, SMetric3 &metr, GEntity *ge=0){} bool isFaceBL (int iF) const {return false;} bool isEdgeBL (int iE) const {return false;} bool isFan (int iE) const {return false;} bool isVertexBL (int iV) const {return false;} void computeFor1dMesh(double x, double y, double z, SMetric3 &metr){} void setupFor2d(int iF){} void setupFor3d(){} void removeAttractors(){} }; #endif class FieldOptionString : public FieldOption { public: std::string & val; virtual FieldOptionType getType(){ return FIELD_OPTION_STRING; } FieldOptionString(std::string &_val, std::string _help, bool *_status=0) : FieldOption(_help, _status), val(_val) {} void string(const std::string value) { modified(); val = value;} std::string string() const { return val; } void getTextRepresentation(std::string &v_str) { std::ostringstream sstream; sstream << "\"" << val << "\""; v_str = sstream.str(); } }; class FieldOptionDouble : public FieldOption { public: double &val; FieldOptionType getType(){ return FIELD_OPTION_DOUBLE; } FieldOptionDouble(double &_val, std::string _help, bool *_status=0) : FieldOption(_help, _status), val(_val){} double numericalValue() const { return val; } void numericalValue(double v){ modified(); val = v; } void getTextRepresentation(std::string &v_str) { std::ostringstream sstream; sstream.precision(16); sstream << val; v_str = sstream.str(); } }; class FieldOptionInt : public FieldOption { public: int &val; FieldOptionType getType(){ return FIELD_OPTION_INT; } FieldOptionInt(int &_val, std::string _help, bool *_status=0) : FieldOption(_help, _status), val(_val){} double numericalValue() const { return val; } void numericalValue(double v){ modified(); val = (int)v; } void getTextRepresentation(std::string & v_str) { std::ostringstream sstream; sstream << val; v_str = sstream.str(); } }; class FieldOptionList : public FieldOption { public: std::list<int> &val; FieldOptionType getType(){ return FIELD_OPTION_LIST; } FieldOptionList(std::list<int> &_val, std::string _help, bool *_status=0) : FieldOption(_help, _status), val(_val) {} void list(std::list<int> value){ modified(); val = value; } const std::list<int>& list() const { return val; } void getTextRepresentation(std::string & v_str) { std::ostringstream sstream; sstream << "{"; for(std::list<int>::iterator it = val.begin(); it != val.end(); it++) { if(it != val.begin()) sstream << ", "; sstream << *it; } sstream << "}"; v_str = sstream.str(); } }; class FieldOptionPath : public FieldOptionString { public: virtual FieldOptionType getType(){ return FIELD_OPTION_PATH; } FieldOptionPath(std::string &_val, std::string _help, bool *_status=0) : FieldOptionString(_val, _help, _status) {} }; class FieldOptionBool : public FieldOption { public: bool & val; FieldOptionType getType(){ return FIELD_OPTION_BOOL; } FieldOptionBool(bool & _val, std::string _help, bool *_status=0) : FieldOption(_help, _status), val(_val) {} double numericalValue() const { return val; } void numericalValue(double v){ modified(); val = v; } void getTextRepresentation(std::string & v_str) { std::ostringstream sstream; sstream << val; v_str = sstream.str(); } }; template<class t> class FieldCallbackGeneric : public FieldCallback { t * _field; void (t::*_callback)(); public : void run() { (_field->*_callback)(); } FieldCallbackGeneric( t *field, void (t::*callback)(), const std::string description) : FieldCallback(description) { _field = field; _callback = callback; } }; template<class F> class FieldFactoryT : public FieldFactory { public: Field * operator()() { return new F; } }; // the class GenericField contains a set of void* functions, which give a mesh size // All these functions are called when calling operator() ; then, the minimum size is returned. class GenericField : public Field{ public: // callback prototypes: // this callback is called with a void* previously given to the GenericField ! typedef bool (*ptrfunction)(double, double, double, void*, double&); GenericField(); ~GenericField(); virtual double operator() (double x, double y, double z, GEntity *ge=0); virtual const char *getName(){return "GenericField";}; // sets the callbacks void setCallbackWithData(ptrfunction fct, void *data); private: std::vector<ptrfunction> cbs;// the callbacks std::vector<void*> user_data;// the data to be sent to the callbacks }; #endif