Alpine3D  Alpine3D-3.2.0
SnowDrift.h
Go to the documentation of this file.
1 /***********************************************************************************/
2 /* Copyright 2009-2015 WSL Institute for Snow and Avalanche Research SLF-DAVOS */
3 /***********************************************************************************/
4 /* This file is part of Alpine3D.
5  Alpine3D is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  Alpine3D is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with Alpine3D. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #ifndef SNOWDRIFTA3D_H
19 #define SNOWDRIFTA3D_H
20 
21 #define WS0 0.5
22 #define TKE 0
23 #define SALTATION 1 // switch for saltation simulation
24 #define SUBLIMATION 0 // switch for drifting snow sublimation
25 #define FIELD3D_OUTPUT 0 // output with all three-dimensional fields (only possible for sublimation)
26 #define SUBLIMATION_OUTPUT 0 // debug output of drifting snow sublimation
27 #define T_FB 1 //switch for feedback between sublimation and air temperature
28 #define Q_FB 1 //switch for feedback between sublimation and humidity
29 #define C_FB 1 //switch for feedback between sublimation and snow concentration
30 #define READK 0 //define as 1 if you have K from ARPS wind fields INCLUDING turbulence
31 #define WRITE_DRIFT_FLUXES 0 //set to 1 in order to write snow drift fluxes
32 #define dt_diff 0.5 /* Small calculation step length for snow diffusion */
33 
34 #include <stdio.h>
35 #include <math.h>
36 #include <stdlib.h>
37 #include <iostream>
38 #include <meteoio/MeteoIO.h>
39 #include <meteoio/plugins/ARPSIO.h>
40 
41 typedef mio::Array2D<int> CElementArray;
42 typedef mio::Array1D<double> CDoubleArray;
43 typedef mio::Array1D<int> CIntArray;
44 
48 
49 #pragma GCC diagnostic push
50 #pragma GCC diagnostic ignored "-Weffc++"
51 
52 class SnowpackInterface;
53 class EnergyBalance;
54 
55 typedef enum DRIFT_OUTPUT_ENUM {OUT_CONC, OUT_SUBL} DRIFT_OUTPUT;
56 typedef enum PARAM_TYPES {CON,HUM,SUB,TEM,SUB2} param_type;
57 typedef enum ASPECT_TYPES {OTHER,BOTTOM} aspect_type;
58 
59 struct WIND_FIELD {unsigned int start_step;std::string wind;};
60 
78 class SnowDriftA3D {
79  public:
80  SnowDriftA3D(const mio::DEMObject& dem, const mio::Config& cfg);
81 
82  virtual ~SnowDriftA3D();
83 
84  virtual void setSnowSurfaceData(const mio::Grid2DObject& cH_in, const mio::Grid2DObject& sp_in, const mio::Grid2DObject& rg_in,
85  const mio::Grid2DObject& N3_in, const mio::Grid2DObject& rb_in);
86 
87  void setSnowPack(SnowpackInterface &mysnowpack);
88  void setEnergyBalance(EnergyBalance &myeb);
89 
90  virtual void Compute(const mio::Date& calcDate);
91  bool isNewWindField(const unsigned int current_step) /*const*/;
92  void setMeteo (const unsigned int& steps, const mio::Grid2DObject& new_psum, const mio::Grid2DObject& new_psum_ph, const mio::Grid2DObject& new_p, const mio::Grid2DObject& new_vw,
93  const mio::Grid2DObject& new_rh, const mio::Grid2DObject& new_ta, const mio::Grid2DObject& new_ilwr, const mio::Date& calcDate,
94  const std::vector<mio::MeteoData>& vecMeteo);
95 
96  void GetTResults(double outtime_v[15], double outtime_tau[15], double outtime_salt[15], double outtime_diff[15]);
97 
98  double getTiming() const;
99 
100  void Destroy();
101 
102  std::string getGridsRequirements() const;
103 
104  protected:
105  void Initialize();
106  void ConstructElements();
107  void InitializeNodes(const mio::Grid3DObject& z_readMatr);
108  void CompleteNodes();
109 
110  virtual void compSaltation(bool setbound);
111  virtual void SnowMassChange(bool setbound, const mio::Date& calcDate);
112  virtual void Suspension();
113  virtual void Diffusion(double deltaT, double &diff_max, double t);
114 
115 
116  //sublimation functions begin
117  virtual void Sublimation();
118  double terminalFallVelocity(const double Radius, const double Temperature, const double RH, const double altitude);
119  double calcS(const double concentration, const double sublradius, const double dmdt);
120  double calcSubldM(const double Radius, const double AirTemperature, const double RH,const double WindSpeed, const double altitude);
121  double reynoldsNumberforFallingParticles(const double Radius, const double Windspeed, const double AirTemperature, const double RH, const double altitude);
122  double ventilationVelocity(const double Radius, const double Windspeed,const double AirTemperature, const double RH, const double altitude);
123  double waterVaporDensity(const double Temperature,const double VaporPressure);
124  double RH_from_q(const double AirTemp, const double q, const double altitude);
125  void initializeTRH();
126  //sublimation functions end
127 
128  //---------------------------------------------------------------------
129  //functions which are required for the fe numerics
130  //defined in SnowDriftFENumerics.cc
131  //---------------------------------------------------------------------
132  //bare numerics for element computations, i.e. integrations, jacobian and auxiliary stuff
133  virtual void Jacobian(double *DETERMINANTJ,double J[][3],const int element, const double *P, int k, const int ix, const int iy, const int iz);
134  virtual void J0fun(double J0[3][3], const double J[3][3]);
135  virtual double GQIntB(double *DETERMINANTJ,const int i, const int j);
136  virtual double GQIntC(double * DETERMINANTJ, const double J0M[3][3][8], const int i, const int j, const double b[3],const double K[3][3]);
137  virtual double GQIntApdx(double DETERMINANTJ[],const double J0M[3][3][8],const int i, const int j, double b[],const double deltak);
138  virtual double GQIntAdxdx(double *DETERMINANTJ, double J0M[3][3][8],const int i, const int j, double *b,const double deltak);
139  virtual void TTfun(double TT[3][8],const double P[]); // P is a pointer pointing at an adress containing a double
140  virtual void phi(double*PHI, double*P);
141  virtual void setQuadraturePoints();
142 
143  //functions required for solving the linear system
144  virtual void matmult(CDoubleArray& res, const CDoubleArray& x, double* sm, int* ijm);
145  virtual void matmult(CDoubleArray& res, const CDoubleArray& x, const CDoubleArray& sA, const CIntArray& colA, CIntArray& rowA);
146  virtual void transmult(CDoubleArray& res, const CDoubleArray& x,double* sm, int* ijm);
147  virtual void SolveEquation(int timeStep, int maxTimeStep, const param_type param );
148  virtual void bicgStab(CDoubleArray& result, CDoubleArray& rhs, const CDoubleArray& sA, const CIntArray& colA, CIntArray& rowA, const int nmax, const double tol, double& testres);
149 
150 
151  //---------------------------------------------------------------------
152  // finite Element functions, basically wrappers for the bare
153  // numerics. Basically two different "classes" of functions, the
154  // first (assembleSystem, applyBoundaryValues, computeDepositionFlux)
155  // contain loops over all or a particular subset of elements and then
156  // invoke the other class of functions which wrap the numerics for
157  // each element (computeDiffusionTensor, computeDriftVector,
158  // computeElementParameter,
159  // computeElementSystem,computeDirichletBoundaryValues,
160  // addElementMatrix
161  //
162  // all these functions are defined in SnowDriftFEControl.cc
163  //---------------------------------------------------------------------
164  virtual void assembleSystem( CIntArray& colA, CIntArray& rowA, CDoubleArray& sA, CDoubleArray& sB, CDoubleArray& Psi, CDoubleArray& f, const double dt);
165  virtual void applyBoundaryValues(CDoubleArray& c00, CDoubleArray& Psi);
166  virtual void prepareSolve();
167 
168 
169  //functions which are required for building the element matrices,
170  virtual void computeDiffusionTensor(double K[3][3], const unsigned int ix, const unsigned int iy, const unsigned int iz);
171  virtual void computeDriftVector(double b[3], const unsigned int ix, const unsigned int iy, const unsigned int iz );
172  virtual void computeElementParameters(const int& element, double DETERMINANTJ[8], double J0M[3][3][8], double J0[3][3], double J[3][3], double b[3], double K[3][3], double& deltak, double& qualla, const int ix, const int iy, const int iz);
173 
174  virtual void computeElementSystem(int &element, int &nDofNodes, int* dofNode, double Ael[9][9], double Del[9][9], bool stationary, double DETERMINANTJ[8], double J0M[3][3][8], double b[3], double K[3][3], double &deltak, const double &dt, CDoubleArray& f, CDoubleArray& Psi);
175 
176  virtual void computeDirichletBoundaryValues(int element,double DETERMINANTJ[8],double J0M[3][3][8], double J0[3][3], double b[3], double K[3][3], double deltak, int spec[8], int length_spec, int length_complSpec, CDoubleArray& c00, CDoubleArray& Psi);
177 
178  virtual void addElementMatrix( CDoubleArray& sA, const CIntArray& colInd, const CIntArray& rowPtr,const double Bel[9][9], const int element, const int* spec,const int length_spec);
179 
180  virtual void computeDepositionFlux(const CDoubleArray& c, const double theta);
181  virtual void computeDepositionFluxSublimation(const CDoubleArray& c, const double theta);
182 
183 
184  //---------------------------------------------------------------------
185  // Functions for initializing the finite element procedure
186  // defined in SnowDriftFEInit.cc
187  //---------------------------------------------------------------------
188  void setBC_BottomLayer(CDoubleArray& var00, const param_type param);
189  void values_nodes_to_elements(const mio::Grid3DObject& nodesGrid, CDoubleArray& elementsArray );
190  void values_elements_to_nodes(mio::Grid3DObject& nodesGrid, const CDoubleArray& elementsArray );
191  void setRobinBoundaryCondition(const aspect_type aspect, const double gamma_val, const int ix, const int iy, const int iz, CDoubleArray& var00, const param_type param);
192  virtual void InitializeFEData();
193  virtual void prepareSparseMatrix( CIntArray& colA, CIntArray& rowA, CDoubleArray& adjA);
194  virtual void initializeSystem( CIntArray& colA,CIntArray& rowA,CDoubleArray& sA,CDoubleArray& sB, CDoubleArray& rhs,CDoubleArray& f, CDoubleArray& Psi,CDoubleArray& var,CDoubleArray& var00, const param_type param);
195  virtual void resetArray(CDoubleArray& sA);
196  virtual void resetArray(CIntArray& sA);
197  virtual void classifySubdomain();
198  virtual int numberOfNonzeros();
199  void iterativeSublimationCalculation(int timeStep, int maxTimeStep);
200 
201  protected:
202  Saltation saltation_obj;
203 
204  //Time dependent data output after each computation step (SnowDrift::Compute)
205  double time_v[15], time_tau[15], time_salt[15], time_diff[15];
209 
210  mio::IOManager io;
213  mio::Timer timer;
214 
215  mio::Grid2DObject cH;
216  mio::Grid2DObject sp;
217  mio::Grid2DObject rg;
218  mio::Grid2DObject N3;
219  mio::Grid2DObject rb;
220 
221  //the dimensions of the rectangular domain
222  unsigned int nx, ny, nz;
223 
224  // Variables for the finite element solution
225  unsigned int nDOF; //the total number of degrees of freedom
226  unsigned int nNodes; //the total number of nodes
227  unsigned int nElements; //the total number of elements
228  unsigned int nNZ; //the total number of nonzero elements of the system matrix
229 
230  //create system matrix in compressed sparse row (CSR) storage format
235 
236  //auxiliary vector for incorporating inhomogeneous Dirichlet
237  //boundary conditions
239 
240  //vector of nodal concentrations, solution of the linear system
241  CDoubleArray c; //snow concentration in suspension
242  CDoubleArray q; //specific humidity
243  CDoubleArray T; //potential temperature
244 
245  //vector which contains the right hand side of the linear system
247 
248  //vector of sink/source terms
250 
251  //vector which contains boundary and initial conditions
255 
256  //vector which contains boundary and initial conditions
258  //mio::Grid3DObject newElements_precond;
259  //LH_BC
263  void zeroRow(int node);
264 
265  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
266  //LH_DEBUG: Algorithm test BEGIN
269  //LH_DEBUG: Algorithm test END
270  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271 
272 
273  double qualla;// paramater to vary the deltak coefficient of the SUPG approach
274 
275  double theta; // here you can vary the heigth above the point used in
276 
277  //the face,bar,corner interior arrays are used for the loops over
278  //all elements and are set in classifySubdomain, see there for details
279  mio::Array2D<int> nz_face;
280  mio::Array2D<int> ny_face;
281  mio::Array2D<int> nx_face;
282 
283  mio::Array2D<int> nz_bar;
284  mio::Array2D<int> ny_bar;
285  mio::Array2D<int> nx_bar;
286 
287  mio::Array2D<int> nz_interior;
288  mio::Array2D<int> ny_interior;
289  mio::Array2D<int> nx_interior;
290 
292 
293  //for the quadrature points of the numerical integration scheme
294  mio::Array2D<double> qPoint;
295 
296  //array for mapping the local node indices onto the global nodes
297  //indices (actually this is the analog of the array elems of the old code)
299 
300  //array for mapping the local node indices onto the global
301  //degree-of-freedom (dof) indices
303 
304  CDoubleArray flux_x, flux_y, flux_z, flux_x_subl, flux_y_subl, flux_z_subl;
305 
307 
309  mio::Array2D<double> saltation, c_salt, mns_subl, mns_nosubl,dif_mns_subl;
310 
311  //Meteo 2D data
312  mio::Grid2DObject mns, vw, rh, ta, p, psum, psum_ph/*, iswr, ea*/; // TODO ISWR activate, TODO EA activate
313 
314  //Meteo 1D data
315  double ta_1D;
316 
317  mio::Date skip_date; //time step to skip because there would be no drift
318 
319  //3D
320  mio::Grid3DObject nodes_x, nodes_y, nodes_z, nodes_sy, nodes_sx, nodes_slope, nodes_wstar;
321  mio::Grid3DObject nodes_u, nodes_v, nodes_w, nodes_K;
322  mio::Grid3DObject nodes_e, nodes_c;
323  mio::Grid3DObject nodes_Tair,nodes_Tair_ini, nodes_q, nodes_q_ini, nodes_RH, nodes_Subl, nodes_Subl_ini, nodes_WindVel, nodes_tmp_c;
325 
326  protected:
327  void buildWindFieldsTable(const std::string& wind_field_string);
328  std::vector<struct WIND_FIELD> wind_fields;
330 
331  void debugOutputs(const mio::Date& calcDate, const std::string& fname, const DRIFT_OUTPUT& filetype);
332  void writeOutput(const std::string& fname); //HACK: this should be done by MeteoIO
333 
334  //sublimation constants
335  static const double kinematicViscosityAir, USTAR, molecularWeightofWater, thermalConductivityofAtm;
336 
337  // constants originally from Snowpack
338  static const double c_red, grain_size, tau_thresh, z0;
339  static const bool thresh_snow;
340 };
341 
342 #pragma GCC diagnostic pop
343 
344 #endif
345 
346 
347 
348 
349 
mio::Grid2DObject vw
Definition: SnowDrift.h:312
double ta_1D
Definition: SnowDrift.h:315
mio::Grid3DObject nodes_z
Definition: SnowDrift.h:320
DRIFT_OUTPUT
Definition: SnowDrift.h:55
mio::Grid2DObject sp
Definition: SnowDrift.h:216
Definition: SnowDrift.h:55
mio::Grid3DObject nodes_e
Definition: SnowDrift.h:322
CDoubleArray T00
Definition: SnowDrift.h:254
Definition: SnowDrift.h:56
double station_altitude
Definition: SnowDrift.h:208
CElementArray elems
Definition: SnowDrift.h:308
Definition: SnowDrift.h:57
mio::Array2D< double > qPoint
Definition: SnowDrift.h:294
unsigned int nNZ
Definition: SnowDrift.h:228
std::string wind
Definition: SnowDrift.h:59
CElementArray nodeMap
Definition: SnowDrift.h:298
CIntArray colA
Definition: SnowDrift.h:233
Definition: SnowDrift.h:59
Definition: SnowDrift.h:56
mio::Array2D< int > nz_face
Definition: SnowDrift.h:279
CDoubleArray c
Definition: SnowDrift.h:241
CDoubleArray gamma
Definition: SnowDrift.h:262
CDoubleArray sB
Definition: SnowDrift.h:232
mio::Grid2DObject cH
Definition: SnowDrift.h:215
Definition: SnowDrift.h:56
param_type
Definition: SnowDrift.h:56
Saltation saltation_obj
Definition: SnowDrift.h:202
CDoubleArray flux_z_subl
Definition: SnowDrift.h:304
double theta
Definition: SnowDrift.h:275
mio::Array2D< int > nx_face
Definition: SnowDrift.h:281
mio::Grid2DObject rg
Definition: SnowDrift.h:217
mio::Array2D< int > nz_bar
Definition: SnowDrift.h:283
Definition: SnowDrift.h:78
CIntArray n_corner
Definition: SnowDrift.h:291
static const bool thresh_snow
Definition: SnowDrift.h:339
Definition: EnergyBalance.h:68
mio::Grid3DObject nodes_w
Definition: SnowDrift.h:321
std::vector< struct WIND_FIELD > wind_fields
Definition: SnowDrift.h:328
int DOITERATION
Definition: SnowDrift.h:206
double auxLayerHeight
Definition: SnowDrift.h:207
Definition: SnowDrift.h:56
Definition: SnowpackInterface.h:127
CIntArray nnzA
Definition: SnowDrift.h:267
CDoubleArray gNeumann
Definition: SnowDrift.h:260
int wind_field_index
Definition: SnowDrift.h:329
unsigned int nElements
Definition: SnowDrift.h:227
mio::Array1D< int > CIntArray
Definition: SnowDrift.h:43
bool new_wind_status
Definition: SnowDrift.h:306
mio::IOManager io
Definition: SnowDrift.h:210
mio::Timer timer
Definition: SnowDrift.h:213
mio::Grid3DObject nodes_WindVel
Definition: SnowDrift.h:323
Definition: SnowDrift.h:56
CDoubleArray adjA
Definition: SnowDrift.h:268
mio::Array2D< int > nz_interior
Definition: SnowDrift.h:287
CDoubleArray q
Definition: SnowDrift.h:242
mio::Array2D< int > ny_face
Definition: SnowDrift.h:280
mio::Array2D< int > ny_interior
Definition: SnowDrift.h:288
CDoubleArray precond
Definition: SnowDrift.h:257
mio::Array2D< double > saltation
Definition: SnowDrift.h:309
mio::Array2D< int > nx_bar
Definition: SnowDrift.h:285
mio::Array1D< double > CDoubleArray
Definition: SnowDrift.h:42
double qualla
Definition: SnowDrift.h:273
Definition: SnowDrift.h:55
unsigned int nNodes
Definition: SnowDrift.h:226
Definition: SnowDrift.h:57
aspect_type
Definition: SnowDrift.h:57
static int steps
Definition: AlpineMain.cc:48
CDoubleArray Psi
Definition: SnowDrift.h:238
CElementArray dofMap
Definition: SnowDrift.h:302
bool STATIONARY
Definition: SnowDrift.h:324
CDoubleArray T
Definition: SnowDrift.h:243
SnowpackInterface * snowpack
Definition: SnowDrift.h:211
static const double z0
Definition: SnowDrift.h:338
CDoubleArray c00
Definition: SnowDrift.h:252
CDoubleArray sA
Definition: SnowDrift.h:231
unsigned int nz
Definition: SnowDrift.h:222
CDoubleArray gDirichlet
Definition: SnowDrift.h:261
CDoubleArray rhs
Definition: SnowDrift.h:246
CDoubleArray f
Definition: SnowDrift.h:249
unsigned int start_step
Definition: SnowDrift.h:59
mio::Array2D< int > CElementArray
Definition: SnowDrift.h:41
EnergyBalance * eb
Definition: SnowDrift.h:212
CDoubleArray q00
Definition: SnowDrift.h:253
mio::Array2D< int > ny_bar
Definition: SnowDrift.h:284
mio::Array2D< int > nx_interior
Definition: SnowDrift.h:289
mio::Grid2DObject N3
Definition: SnowDrift.h:218
static const double USTAR
Definition: SnowDrift.h:335
CIntArray rowA
Definition: SnowDrift.h:234
mio::Grid2DObject rb
Definition: SnowDrift.h:219
unsigned int nDOF
Definition: SnowDrift.h:225
mio::Date skip_date
Definition: SnowDrift.h:317