OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
nlisomoisturemat.C
Go to the documentation of this file.
1 /*
2  *
3  * ##### ##### ###### ###### ### ###
4  * ## ## ## ## ## ## ## ### ##
5  * ## ## ## ## #### #### ## # ##
6  * ## ## ## ## ## ## ## ##
7  * ## ## ## ## ## ## ## ##
8  * ##### ##### ## ###### ## ##
9  *
10  *
11  * OOFEM : Object Oriented Finite Element Code
12  *
13  * Copyright (C) 1993 - 2013 Borek Patzak
14  *
15  *
16  *
17  * Czech Technical University, Faculty of Civil Engineering,
18  * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19  *
20  * This library is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU Lesser General Public
22  * License as published by the Free Software Foundation; either
23  * version 2.1 of the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28  * Lesser General Public License for more details.
29  *
30  * You should have received a copy of the GNU Lesser General Public
31  * License along with this library; if not, write to the Free Software
32  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33  */
34 
35 #include "nlisomoisturemat.h"
36 #include "gausspoint.h"
37 #include "mathfem.h"
38 #include "classfactory.h"
39 
40 namespace oofem {
41 REGISTER_Material(NlIsoMoistureMaterial);
42 
45 {
46  IRResultType result; // Required by IR_GIVE_FIELD macro
47 
48  int type = 0;
50 
51  if ( type >= 7 ) {
52  OOFEM_WARNING("isothermType must be equal to 0, 1, 2 ... 6");
53  return IRRT_BAD_FORMAT;
54  }
55 
56  this->Isotherm = ( isothermType ) type;
57 
59 
60  if ( type >= 4 ) {
61  OOFEM_ERROR ( "permeabilityType must be equal to 0, 1, 2, 3" );
62  }
63 
64  this->Permeability = ( permeabilityType ) type;
65 
66  if (Permeability == KunzelPerm) {
69  if ( type >= 3 ) {
70  OOFEM_ERROR ( "capillaryTransportType must be equal to 0, 1, 2" );
71  }
72  }
73 
74  if ( this->Isotherm == linear ) { // linear isotherm = type 0
76  } else if ( this->Isotherm == multilinear ) { // multilinear isotherm = type 1
79 
80  if ( iso_h.giveSize() != iso_wh.giveSize() ) {
81  OOFEM_WARNING("the size of 'iso_h' and 'iso_w(h)' must be the same");
82  return IRRT_BAD_FORMAT;
83  }
84 
85  for ( int i = 1; i < iso_h.giveSize(); i++ ) {
86  if ( ( iso_h.at(i) < 0. ) || ( iso_h.at(i) > 1. ) ) {
87  OOFEM_WARNING("iso_h must be in the range <0; 1>");
88  return IRRT_BAD_FORMAT;
89  }
90  }
91  } else if ( this->Isotherm == Ricken ) { // reference mentioned in Kuenzel isotherm = type 2
93  } else if ( this->Isotherm == Kuenzel ) { // isotherm = type 3
96  } else if ( this->Isotherm == Hansen ) { // isotherm = type 4
101  } else if ( this->Isotherm == BSB ) { // isotherm = type 5
106  } else if ( this->Isotherm == bilinear ) { // bilinear isotherm = type 6
111 
112  this->iso_offset = 0.;
114 
115  this->capa2 = (wf-hx*moistureCapacity-iso_offset)/(1-hx);
116  double wa = (hx-dx)*moistureCapacity + iso_offset;
117  double wb = hx*moistureCapacity + dx*capa2 + iso_offset;
118 
119  this->c1 = (moistureCapacity*(2*dx)+capa2*(2*dx)+2*wa-2*wb)/(8*dx*dx*dx);
120  this->c2 = (-3*c1*(2*dx)*(2*dx)-moistureCapacity+capa2)/(2*(2*dx));
121  } else {
122  OOFEM_ERROR("unknown isotherm type");
123  }
124 
125  if ( this->Permeability == multilin ) {
128 
129  if ( perm_h.giveSize() != perm_ch.giveSize() ) {
130  OOFEM_WARNING("the size of 'perm_h' and 'perm_c(h)' must be the same");
131  return IRRT_BAD_FORMAT;
132  }
133 
134  for ( int i = 1; i < perm_h.giveSize(); i++ ) {
135  if ( ( perm_h.at(i) < 0. ) || ( perm_h.at(i) > 1. ) ) {
136  OOFEM_WARNING("perm_h must be in the range <0; 1>");
137  return IRRT_BAD_FORMAT;
138  }
139  }
140  } else if ( this->Permeability == Bazant ) {
145  } else if ( this->Permeability == Xi ) {
149  } else if ( this->Permeability == KunzelPerm ) {
150 
151  // compute vapor diffusion coefficient in air [kg m^-1 s^-1 Pa^-1]
152  double delta;
153  double PL; // ambient atmospheric pressure [Pa]
154  double mu; // water vapor diffusion resistance [-]
155  double T; // temperature [K]
156 
157  PL = 101325.;
161 
162  double timeScale = 1.; // = 1 for analysis in seconds, = 86400 for analysis in days, etc.
164  delta = timeScale * 2.0 * 1.e-7 * pow(T,0.81) / PL;
165 
166  this->deltap = delta / mu;
167 
168  // compute saturation water vapor pressure
169  double T0, a;
170  double T_C = T - 273.15;
171 
172  if (T_C < 0.) {
173  a = 22.44;
174  T0 = 272.44;
175  } else {
176  a = 17.08;
177  T0 = 234.18;
178  }
179  this->p_sat = 611. * exp( a * T_C / (T0 + T_C) );
180 
181 
185 
186  if ( ! ( capPerm_h.giveSize() == capPerm_Dwh.giveSize() ) )
187  OOFEM_ERROR ( "size of 'capPerm_h' and 'capPerm_dw(h)' must be the same" );
188 
189  for ( int i = 1; i < capPerm_h.giveSize(); i++ ) {
190  if ( ( capPerm_h.at ( i ) < 0. ) || ( capPerm_h.at ( i ) > 1. ) )
191  OOFEM_ERROR ( "capPerm_h must be in the range <0; 1>" );
192  }
193 
194  } else if (this->CapillaryTransport == Multilin_wV) {
195 
196  rhoH2O = 1000.;
198 
201 
202  if ( ! ( capPerm_wV.giveSize() == capPerm_DwwV.giveSize() ) )
203  OOFEM_ERROR ( "size of 'capPerm_wV' and 'capPerm_Dw(wV)' must be the same" );
204 
205  for ( int i = 1; i < capPerm_wV.giveSize(); i++ ) {
206  if ( ( capPerm_wV.at ( i ) < 0. ) || ( capPerm_wV.at ( i ) > 1. ) )
207  OOFEM_ERROR ( "capPerm_wv must be in the range <0; 1>" );
208  }
209 
210  } else { // according to Kunzel
211 
212  if ( this->Isotherm == Hansen ) {
213  this->wf = rhodry*uh;
214  } else {
216  }
218  }
219 
220  } else {
221  OOFEM_ERROR("unknown permeability type");
222  }
223 
225 }
226 
227 double
229 {
230  double humidity = this->giveHumidity(gp, VM_Total);
231 
232  if ( this->Isotherm == linear ) {
233  return moistureCapacity;
234  } else if ( this->Isotherm == multilinear ) {
235  double tol = 1.e-10;
236  for ( int i = 2; i <= iso_h.giveSize(); i++ ) {
237  if ( ( humidity - iso_h.at(i) ) < tol ) {
238  return ( iso_wh.at(i) - iso_wh.at(i - 1) ) / ( iso_h.at(i) - iso_h.at(i - 1) );
239  }
240  }
241  } else if ( this->Isotherm == Ricken ) {
242  return 1. / ( dd * ( 1. - humidity ) );
243  } else if ( this->Isotherm == Kuenzel ) {
244  return wf * ( b - 1. ) * b / ( ( b - humidity ) * ( b - humidity ) );
245  } else if ( this->Isotherm == Hansen ) {
246  return rhodry * uh / ( A * nn * humidity * pow( ( 1 - log(humidity) / A ), ( 1 / nn + 1 ) ) );
247  } else if ( this->Isotherm == BSB ) {
248  double nominator, denominator;
249  nominator = c * k * Vm * rhodry * ( 1. + k * k * humidity * humidity * c - k * k * humidity * humidity );
250  denominator = ( 1. - k * humidity ) * ( 1. - k * humidity ) * ( 1. + ( c - 1. ) * k * humidity ) * ( 1. + ( c - 1. ) * k * humidity );
251  return nominator / denominator;
252  } else if ( this->Isotherm == bilinear ) {
253  if( humidity <= (hx-dx) ) {
254  return moistureCapacity;
255  } else if (humidity >= (hx + dx) ) {
256  return capa2;
257  } else {
258  return moistureCapacity + 2*c2*(humidity-hx+dx) + 3*c1*pow(humidity-hx+dx,2);
259  }
260  } else {
261  OOFEM_ERROR("unknown isotherm type");
262  }
263 
264  return 0.;
265 }
266 
267 double
269 {
270  if ( this->Isotherm == linear ) {
271  return moistureCapacity*humidity;
272 
273  } else if ( this->Isotherm == multilinear ) {
274  double tol = 1.e-10;
275  for (int i = 1; i <= iso_h.giveSize(); i++) {
276  if ( ( humidity - iso_h.at(i) ) < tol ) {
277  return iso_wh.at(i-1) + (iso_wh.at(i)-iso_wh.at(i-1))/(iso_h.at(i)-iso_h.at(i-1)) * (humidity-iso_h.at(i-1)) ;
278  }
279  }
280 
281  } else if ( this->Isotherm == Ricken ) {
282  return wf - log(1.-humidity)/dd ;
283 
284  } else if ( this->Isotherm == Kuenzel ) {
285  return wf * (b-1.) * humidity / (b-humidity);
286 
287  } else if ( this->Isotherm == Hansen ) {
288  return rhodry*uh * pow( (1.-log(humidity)/A), (-1./nn) ) ;
289 
290  } else if ( this->Isotherm == BSB ) {
291  return rhodry*c*k*Vm*humidity/( (1.-k*humidity) * (c-1.)*k*humidity );
292 
293  } else if ( this->Isotherm == bilinear ) {
294 
295  if( humidity <= (hx-dx) ) {
296  return moistureCapacity*humidity + iso_offset;
297 
298  } else if (humidity >= (hx + dx) ) {
299  return hx*moistureCapacity + (humidity-hx)*capa2 + iso_offset;
300 
301  } else {
302  return (hx-dx)*moistureCapacity + moistureCapacity*(humidity-hx+dx) + c2 * pow(humidity-hx+dx,2) + c1 * pow(humidity-hx+dx,3) + iso_offset;
303  }
304 
305  } else {
306  OOFEM_ERROR("unknown isotherm type");
307  }
308 
309  return 0.;
310 }
311 
312 double
314 {
315  double permeability = 0.;
316  double humidity = this->giveHumidity(gp, VM_Total);
317 
318  if ( this->Permeability == multilin ) {
319  double tol = 1.e-10;
320  for ( int i = 1; i <= perm_h.giveSize(); i++ ) {
321  if ( ( humidity - perm_h.at(i) ) < tol ) {
322  permeability = perm_ch.at(i - 1) + ( perm_ch.at(i) - perm_ch.at(i - 1) ) * ( humidity - perm_h.at(i - 1) ) / ( perm_h.at(i) - perm_h.at(i - 1) );
323  break;
324  }
325  }
326  } else if ( this->Permeability == Bazant ) {
327  permeability = C1 * ( alpha0 + ( 1. - alpha0 ) / ( 1. + pow( ( 1. - humidity ) / ( 1. - hC ), n ) ) );
328  } else if ( this->Permeability == Xi ) {
329  double power = pow( 10., gammah * ( humidity - 1. ) );
330  permeability = alphah + betah * ( 1. - pow(2., -power) );
331  } else if (this->Permeability == KunzelPerm) {
332 
333  double dw_dh; //[kg/m^3]
334  double Dw; // capillary transport coefficient [m^2/s]
335 
336  dw_dh = this->giveMoistureCapacity(gp, tStep);
337  Dw = this->computeCapTranspCoeff(humidity);
338 
339  permeability = Dw * dw_dh + deltap * p_sat;
340 
341  } else {
342  OOFEM_ERROR("unknown permeability type");
343  }
344 
345  return permeability;
346 }
347 
348 
349 double
351 {
352  double Dw = 0.;
353 
354  if ( this->CapillaryTransport == Multilin_h ) {
355  double tol = 1.e-10;
356  for (int i = 1; i <= capPerm_h.giveSize(); i++) {
357  if ((humidity - capPerm_h.at(i))<tol) {
358  Dw = capPerm_Dwh.at(i-1) + (capPerm_Dwh.at(i)-capPerm_Dwh.at(i-1))*(humidity-capPerm_h.at(i-1))/(capPerm_h.at(i)-capPerm_h.at(i-1));
359  break;
360  }
361  }
362 
363  } else if ( this->CapillaryTransport == Multilin_wV ) {
364  double wV = this->sorptionIsotherm(humidity) / rhoH2O;
365  double tol = 1.e-10;
366  for (int i = 1; i <= capPerm_wV.giveSize(); i++) {
367  if ((wV - capPerm_wV.at(i))<tol) {
368  Dw = capPerm_DwwV.at(i-1) + (capPerm_DwwV.at(i)-capPerm_DwwV.at(i-1))*(wV-capPerm_wV.at(i-1))/(capPerm_wV.at(i)-capPerm_wV.at(i-1));
369  break;
370  }
371  }
372 
373  } else if ( this->CapillaryTransport == KunzelCT ){
374  double w;
375  w = this->sorptionIsotherm(humidity);
376  Dw = 3.8 * (Abs/wf)*(Abs/wf) * pow(1000., w/wf -1.);
377 
378  } else {
379  OOFEM_ERROR("unknown capillary transport type");
380  }
381 
382  return Dw;
383 }
384 
385 
386 double
388 {
389  const FloatArray &tempState = static_cast< TransportMaterialStatus * >( this->giveStatus(gp) )->giveTempField();
390  if ( ( tempState.at(1) > 1.0 ) || ( tempState.at(1) < 0.0 ) ) {
391  OOFEM_ERROR("Relative humidity %.3f is out of range", tempState.at(1) );
392  return 0.0;
393  } else {
394  return tempState.at(1);
395  }
396 }
397 } // end namespace oofem
#define _IFT_NlIsoMoistureMaterial_n
#define _IFT_NlIsoMoistureMaterial_capperm_wv
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Returns material status of receiver in given integration point.
Definition: material.C:244
#define _IFT_NlIsoMoistureMaterial_t
double c
parameters of the BSB isotherm
FloatArray capPerm_h
values of the multilinear capillary transport function
#define _IFT_NlIsoMoistureMaterial_c
#define _IFT_NlIsoMoistureMaterial_c1
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
FloatArray perm_h
values of the multilinear permeability
enum oofem::NlIsoMoistureMaterial::isothermType Isotherm
ValueModeType
Type representing the mode of UnknownType or CharType, or similar types.
Definition: valuemodetype.h:78
#define _IFT_NlIsoMoistureMaterial_vm
double deltap
permeability parameters according to Kunzel
double wf
parameters of the Kuenzel isotherm
#define _IFT_NlIsoMoistureMaterial_perm_h
#define _IFT_NlIsoMoistureMaterial_betah
#define _IFT_NlIsoMoistureMaterial_nn
#define _IFT_NlIsoMoistureMaterial_iso_wh
virtual double giveHumidity(GaussPoint *gp, ValueModeType mode)
Returns positive value of humidity if implemented and enabled in derived material, -1 otherwise.
double alphah
permeability parameters according to Xi, Bazant & Jennings
#define _IFT_NlIsoMoistureMaterial_timescale
This class implements a transport material status information.
enum oofem::NlIsoMoistureMaterial::permeabilityType Permeability
#define _IFT_NlIsoMoistureMaterial_alphah
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
#define _IFT_NlIsoMoistureMaterial_rhoh2o
double dd
parameters of the Ricken isotherm
double hx
values of the bilinear isotherm
#define _IFT_NlIsoMoistureMaterial_perm_ch
#define _IFT_NlIsoMoistureMaterial_iso_h
#define _IFT_NlIsoMoistureMaterial_rhodry
#define _IFT_NlIsoMoistureMaterial_b
#define OOFEM_ERROR(...)
Definition: error.h:61
#define _IFT_NlIsoMoistureMaterial_gammah
#define _IFT_NlIsoMoistureMaterial_alpha0
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
double C1
"permeability" according to Bazant
#define _IFT_NlIsoMoistureMaterial_capa
enum oofem::NlIsoMoistureMaterial::capillaryTransportType CapillaryTransport
double Abs
water absorption coefficient [kg m^-2 s^-0.5]
#define _IFT_NlIsoMoistureMaterial_a
#define _IFT_NlIsoMoistureMaterial_hx
#define _IFT_NlIsoMoistureMaterial_dx
#define _IFT_NlIsoMoistureMaterial_pl
Class representing vector of real numbers.
Definition: floatarray.h:82
#define _IFT_NlIsoMoistureMaterial_hc
double moistureCapacity
values of the linear isotherm
#define _IFT_NlIsoMoistureMaterial_abs
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
#define _IFT_NlIsoMoistureMaterial_capperm_h
#define _IFT_NlIsoMoistureMaterial_dd
#define _IFT_NlIsoMoistureMaterial_mu
Class representing the general Input Record.
Definition: inputrecord.h:101
FloatArray iso_h
values of the multilinear isotherm
double rhodry
density of the dry solid phase
#define _IFT_NlIsoMoistureMaterial_wf
virtual double givePermeability(GaussPoint *gp, TimeStep *tStep)
#define _IFT_NlIsoMoistureMaterial_iso_offset
#define _IFT_NlIsoMoistureMaterial_capperm_dwh
double uh
parameters of the isotherm proposed by P. Freiesleben Hansen (Coupled moisture/heat transport in cros...
#define _IFT_NlIsoMoistureMaterial_capillarytransporttype
#define _IFT_NlIsoMoistureMaterial_uh
#define _IFT_NlIsoMoistureMaterial_isothermtype
REGISTER_Material(DummyMaterial)
virtual double sorptionIsotherm(double humidity)
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
#define _IFT_NlIsoMoistureMaterial_capperm_dwwv
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
the oofem namespace is to define a context or scope in which all oofem names are defined.
#define IR_GIVE_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:69
virtual double giveMoistureCapacity(GaussPoint *gp, TimeStep *tStep)
evaluates slope of the sorption isotherm
#define _IFT_NlIsoMoistureMaterial_k
virtual double computeCapTranspCoeff(double humidity)
Class representing integration point in finite element program.
Definition: gausspoint.h:93
#define OOFEM_WARNING(...)
Definition: error.h:62
Class representing solution step.
Definition: timestep.h:80
#define _IFT_NlIsoMoistureMaterial_permeabilitytype

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:30 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011