Salome HOME
Check mesh equivalence when setting input fields
[tools/solverlab.git] / CoreFlows / Models / inc / StationaryDiffusionEquation.hxx
1 //============================================================================
2 /**
3  * \file StationaryDiffusionEquation.hxx
4  * \author Michael NDJINGA
5  * \version 1.0
6  * \date June 2019
7  * \brief Stationary heat diffusion equation solved with either finite elements or finite volume method. 
8  * -\lambda\Delta T=\Phi + \lambda_{sf} (T_{fluid}-T)
9  * Dirichlet (imposed temperature) or Neumann (imposed normal flux) boundary conditions.
10  * */
11 //============================================================================
12
13 /*! \class StationaryDiffusionEquation StationaryDiffusionEquation.hxx "StationaryDiffusionEquation.hxx"
14  *  \brief Scalar stationary heat equation solved with either finite elements or finite volume method. 
15  *  \details see \ref StationaryDiffusionEqPage for more details
16  * -\lambda\Delta T=\Phi(T) + \lambda_{sf} (T_{fluid}-T)
17  */
18  
19 #ifndef StationaryDiffusionEquation_HXX_
20 #define StationaryDiffusionEquation_HXX_
21
22 #include "ProblemCoreFlows.hxx"
23
24 using namespace std;
25
26 /*! Boundary condition type  */
27 enum BoundaryTypeStationaryDiffusion    { NeumannStationaryDiffusion, DirichletStationaryDiffusion, NoneBCStationaryDiffusion};
28
29 /** \struct LimitField
30  * \brief value of some fields on the boundary  */
31 struct LimitFieldStationaryDiffusion{
32         LimitFieldStationaryDiffusion(){bcType=NoneBCStationaryDiffusion; T=0; normalFlux=0;}
33         LimitFieldStationaryDiffusion(BoundaryTypeStationaryDiffusion _bcType, double _T,       double _normalFlux){
34                 bcType=_bcType; T=_T; normalFlux=_normalFlux;
35         }
36
37         BoundaryTypeStationaryDiffusion bcType;
38         double T; //for Dirichlet
39         double normalFlux; //for Neumann
40 };
41
42 class StationaryDiffusionEquation
43 {
44
45 public :
46         /** \fn StationaryDiffusionEquation
47                          * \brief Constructor for the temperature diffusion in a solid
48                          * \param [in] int : space dimension
49                          * \param [in] bool : numerical method
50                          * \param [in] double : solid conductivity
51                          *  */
52
53         StationaryDiffusionEquation( int dim,bool FECalculation=true,double lambda=1,MPI_Comm comm = MPI_COMM_WORLD);
54
55     void setMesh(const Mesh &M);
56     void setFileName(string fileName){
57         _fileName = fileName;
58     }
59     bool solveStationaryProblem();
60     
61     //Linear system and spectrum
62     void setLinearSolver(linearSolver kspType, preconditioner pcType);
63     double getConditionNumber(bool isSingular=false, double tol=1e-6) const;
64     std::vector< double > getEigenvalues (int nev, EPSWhich which=EPS_SMALLEST_MAGNITUDE, double tol=1e-6) const;
65     std::vector< Vector > getEigenvectors(int nev, EPSWhich which=EPS_SMALLEST_MAGNITUDE, double tol=1e-6) const;
66     Field getEigenvectorsField(int nev, EPSWhich which=EPS_SMALLEST_MAGNITUDE, double tol=1e-6) const;
67
68         //Gestion du calcul
69         void initialize();
70         void terminate();//vide la mémoire et enregistre le résultat final
71         double computeDiffusionMatrix(bool & stop);
72     double computeTimeStep(bool & stop);//For coupling calculations
73         bool iterateNewtonStep(bool &ok);
74         void save();
75
76     /* Boundary conditions */
77         void setBoundaryFields(map<string, LimitFieldStationaryDiffusion> boundaryFields){
78                 _limitField = boundaryFields;
79     };
80         /** \fn setDirichletBoundaryCondition
81                          * \brief adds a new boundary condition of type Dirichlet
82                          * \details
83                          * \param [in] string : the name of the boundary
84                          * \param [in] double : the value of the temperature at the boundary
85                          * \param [out] void
86                          *  */
87         void setDirichletBoundaryCondition(string groupName,double Temperature){
88                 _limitField[groupName]=LimitFieldStationaryDiffusion(DirichletStationaryDiffusion,Temperature,-1);
89         };
90
91         /** \fn setNeumannBoundaryCondition
92                          * \brief adds a new boundary condition of type Neumann
93                          * \details
94                          * \param [in] string : the name of the boundary
95                          * \param [in] double : outward normal flux
96                          * \param [out] void
97                          *  */
98         void setNeumannBoundaryCondition(string groupName, double normalFlux=0){
99                 _limitField[groupName]=LimitFieldStationaryDiffusion(NeumannStationaryDiffusion,-1, normalFlux);
100         };
101
102         void setDirichletValues(map< int, double> dirichletBoundaryValues);
103         void setNeumannValues  (map< int, double>   neumannBoundaryValues);
104         
105         void setConductivity(double conductivite){
106                 _conductivity=conductivite;
107         };
108         void setDiffusiontensor(Matrix DiffusionTensor){
109                 _DiffusionTensor=DiffusionTensor;
110         };
111
112
113         //get input fields to prepare the simulation or coupling
114         vector<string> getInputFieldsNames();
115         void setInputField(const string& nameField, Field& inputField );//supply of a required input field
116         
117         void setFluidTemperatureField(Field coupledTemperatureField){
118                 _fluidTemperatureField=coupledTemperatureField;
119                 _fluidTemperatureFieldSet=true;
120         };
121         void setFluidTemperature(double fluidTemperature){
122         _fluidTemperature=fluidTemperature;
123         }
124         Field& getFluidTemperatureField(){
125                 return _fluidTemperatureField;
126         }
127         /** \fn setHeatPowerField
128          * \brief set the heat power field (variable in space)
129          * \details
130          * \param [in] Field
131          * \param [out] void
132          *  */
133         void setHeatPowerField(Field heatPower){
134                 heatPower.getMesh().checkFastEquivalWith(_mesh);
135                 _heatPowerField=heatPower;
136                 _heatPowerFieldSet=true;
137         }
138
139         /** \fn setHeatPowerField
140          * \brief set the heat power field (variable in space)
141          * \details
142          * \param [in] string fileName (including file path)
143          * \param [in] string fieldName
144          * \param [out] void
145          *  */
146         void setHeatPowerField(string fileName, string fieldName, int iteration = 0, int order = 0, int meshLevel=0){
147                 _heatPowerField=Field(fileName, CELLS,fieldName, iteration, order, meshLevel);
148                 _heatPowerField.getMesh().checkFastEquivalWith(_mesh);
149                 _heatPowerFieldSet=true;
150         }
151
152         /** \fn getHeatPowerField
153          * \brief returns the heat power field
154          * \details
155          * \param [in] void
156          * \param [out] Field
157          *  */
158         Field getHeatPowerField(){
159                 return _heatPowerField;
160         }
161         //get output fields names for postprocessing or coupling
162         vector<string> getOutputFieldsNames() ;//liste tous les champs que peut fournir le code pour le postraitement
163         Field&         getOutputField(const string& nameField );//Renvoie un champs pour le postraitement
164
165     Field& getOutputTemperatureField();
166         Field& getRodTemperatureField();
167
168         /** \fn setVerbose
169          * \brief Updates display options
170          * \details
171          * \param [in] bool
172          * \param [in] bool
173          * \param [out] void
174          *  */
175         void setVerbose(bool verbose,  bool system=false)
176         {
177                 _verbose = verbose;
178                 _system = system;
179         };
180
181 protected :
182         //Main unknown field
183         Field _VV;
184
185         int _Ndim;//space dimension
186         int _nVar;//Number of equations to solve=1
187
188     //Mesh data
189         Mesh _mesh;
190     bool _meshSet;
191         bool _initializedMemory;
192         int _Nmailles;//number of cells for FV calculation
193         int _neibMaxNbCells;//maximum number of cells around a cell
194     
195         double _precision;
196         double _precision_Newton;
197         double _erreur_rel;//norme(Uk+1-Uk)
198     bool _computationCompletedSuccessfully;
199     
200         //Linear solver and petsc
201         KSP _ksp;
202         KSPType _ksptype;
203         PC _pc;
204         PCType _pctype;
205         string _pc_hypre;
206         int _maxPetscIts;//nombre maximum d'iteration gmres autorisé au cours d'une resolution de système lineaire
207         int _maxNewtonIts;//nombre maximum d'iteration de Newton autorise au cours de la resolution d'un pas de temps
208         int _PetscIts;//the number of iterations of the linear solver
209         int _NEWTON_its;
210         Mat  _A;//Linear system matrix
211         Vec _b;//Linear system right hand side
212         double _MaxIterLinearSolver;//nombre maximum d'iteration gmres obtenu au cours par les resolution de systemes lineaires au cours d'un pas de tmeps
213         bool _conditionNumber;//computes an estimate of the condition number
214
215         map<string, LimitFieldStationaryDiffusion> _limitField;
216     bool _onlyNeumannBC;//if true then the linear system is singular and should be solved up to a constant vector
217     
218         bool _diffusionMatrixSet;
219         Vector _normale;
220         Matrix _DiffusionTensor;
221         Vec _deltaT, _Tk, _Tkm1, _b0;
222         Vec _Tk_seq; // Local sequential copy of the parallel vector _Tk, used for saving result files
223
224         double _dt_src;
225     
226         //Heat transfert variables
227         double _conductivity, _fluidTemperature;
228         Field _heatPowerField, _fluidTemperatureField;
229         bool _heatPowerFieldSet, _fluidTemperatureFieldSet;
230         double _heatTransfertCoeff, _heatSource;
231
232         //Display variables
233         bool _verbose, _system;
234         ofstream * _runLogFile;//for creation of a log file to save the history of the simulation
235     //saving parameters
236         string _fileName;//name of the calculation
237         string _path;//path to execution directory used for saving results
238         saveFormat _saveFormat;//file saving format : MED, VTK or CSV
239
240         double computeRHS(bool & stop);
241         double computeDiffusionMatrixFV(bool & stop);
242         double computeDiffusionMatrixFE(bool & stop);
243
244     /************ Data for FE calculation *************/
245     bool _FECalculation;
246         int _Nnodes;/* number of nodes for FE calculation */
247         int _neibMaxNbNodes;/* maximum number of nodes around a node */
248         int _NunknownNodes;/* number of unknown nodes for FE calculation */
249         int _NboundaryNodes;/* total number of boundary nodes */
250         int _NdirichletNodes;/* number of boundary nodes with Dirichlet BC for FE calculation */
251     std::vector< int > _boundaryNodeIds;/* List of boundary nodes */
252     std::vector< int > _dirichletNodeIds;/* List of boundary nodes with Dirichlet BC */
253
254     /********* Possibility to set a boundary field as DirichletNeumann boundary condition *********/
255     bool _dirichletValuesSet;
256     bool _neumannValuesSet;
257     std::map< int, double> _dirichletBoundaryValues;
258     std::map< int, double> _neumannBoundaryValues;
259
260         /**** MPI related variables ***/
261         PetscMPIInt    _mpi_size;        /* size of communicator */
262         PetscMPIInt    _mpi_rank;        /* processor rank */
263         VecScatter _scat;                       /* For the distribution of a local vector */
264         int _globalNbUnknowns, _localNbUnknowns;
265         int _d_nnz, _o_nnz;                     /* local and "non local" numbers of non zeros corfficients */
266 };
267
268 #endif /* StationaryDiffusionEquation_HXX_ */