OOFEM 3.0
Loading...
Searching...
No Matches
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 - 2025 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
36#include "gausspoint.h"
37#include "mathfem.h"
38#include "classfactory.h"
39
40namespace oofem {
42
43void
45{
47
48 int type = 0;
50
51 if ( type > 7 ) {
52 throw ValueInputException(ir, _IFT_NlIsoMoistureMaterial_isothermtype, "must be equal to 0, 1, 2 ... 7");
53 }
54
55 this->Isotherm = ( isothermType ) type;
56
58
59 if ( type >= 4 ) {
60 throw ValueInputException(ir, _IFT_NlIsoMoistureMaterial_permeabilitytype, "must be equal to 0, 1, 2, 3");
61 }
62
63 this->Permeability = ( permeabilityType ) type;
64
65 if ( Permeability == KunzelPerm ) {
68 if ( type >= 3 ) {
70 }
71 }
72
73 if ( this->Isotherm == linear ) { // linear isotherm = type 0
75 this->iso_offset = 0.;
77 } else if ( this->Isotherm == multilinear ) { // multilinear isotherm = type 1
80
81 if ( iso_h.giveSize() != iso_wh.giveSize() ) {
82 throw ValueInputException(ir, _IFT_NlIsoMoistureMaterial_iso_h, "the size of 'iso_h' and 'iso_w(h)' must be the same");
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 throw ValueInputException(ir, _IFT_NlIsoMoistureMaterial_iso_h, "iso_h must be in the range <0; 1>");
88 }
89 }
90 } else if ( this->Isotherm == Ricken ) { // reference mentioned in Kuenzel isotherm = type 2
92 } else if ( this->Isotherm == Kuenzel ) { // isotherm = type 3
95 } else if ( this->Isotherm == Hansen ) { // isotherm = type 4
100 } else if ( this->Isotherm == BSB ) { // isotherm = type 5
105 } else if ( this->Isotherm == bilinear ) { // bilinear isotherm = type 6
110
111 this->iso_offset = 0.;
113
114 this->capa2 = ( wf - hx * moistureCapacity - iso_offset ) / ( 1 - hx );
115 double wa = ( hx - dx ) * moistureCapacity + iso_offset;
116 double wb = hx * moistureCapacity + dx * capa2 + iso_offset;
117
118 this->c1 = ( moistureCapacity * ( 2 * dx ) + capa2 * ( 2 * dx ) + 2 * wa - 2 * wb ) / ( 8 * dx * dx * dx );
119 this->c2 = ( -3 * c1 * ( 2 * dx ) * ( 2 * dx ) - moistureCapacity + capa2 ) / ( 2 * ( 2 * dx ) );
120 } else if ( this->Isotherm == vanGenuchten ) { // isotherm = type 7
124 } else {
125 throw ValueInputException(ir, _IFT_NlIsoMoistureMaterial_isothermtype, "unknown isotherm type");
126 }
127
128 if ( this->Permeability == multilin ) {
131
132 if ( perm_h.giveSize() != perm_ch.giveSize() ) {
133 throw ValueInputException(ir, _IFT_NlIsoMoistureMaterial_perm_ch, "the size of 'perm_h' and 'perm_c(h)' must be the same");
134 }
135
136 for ( int i = 1; i < perm_h.giveSize(); i++ ) {
137 if ( ( perm_h.at(i) < 0. ) || ( perm_h.at(i) > 1. ) ) {
138 throw ValueInputException(ir, _IFT_NlIsoMoistureMaterial_perm_h, "must be in the range <0; 1>");
139 }
140 }
141 } else if ( this->Permeability == Bazant ) {
146 } else if ( this->Permeability == Xi ) {
150 } else if ( this->Permeability == KunzelPerm ) {
152
153 // read temperature - either constant or time-dependent
156 } else {
158 }
159
161
163
165
166
170
171 if ( !( capPerm_h.giveSize() == capPerm_Dwh.giveSize() ) ) {
172 throw ValueInputException(ir, _IFT_NlIsoMoistureMaterial_capperm_dwh, "size of 'capPerm_h' and 'capPerm_dw(h)' must be the same");
173 }
174
175 for ( int i = 1; i < capPerm_h.giveSize(); i++ ) {
176 if ( ( capPerm_h.at(i) < 0. ) || ( capPerm_h.at(i) > 1. ) ) {
177 throw ValueInputException(ir, _IFT_NlIsoMoistureMaterial_capperm_h, "must be in the range <0; 1>");
178 }
179 }
180 } else if ( this->CapillaryTransport == Multilin_wV ) {
181 rhoH2O = 1000.;
183
186
187 if ( !( capPerm_wV.giveSize() == capPerm_DwwV.giveSize() ) ) {
188 throw ValueInputException(ir, _IFT_NlIsoMoistureMaterial_capperm_dwwv, "size of 'capPerm_wV' and 'capPerm_Dw(wV)' must be the same");
189 }
190
191 for ( int i = 1; i < capPerm_wV.giveSize(); i++ ) {
192 if ( ( capPerm_wV.at(i) < 0. ) || ( capPerm_wV.at(i) > 1. ) ) {
193 throw ValueInputException(ir, _IFT_NlIsoMoistureMaterial_capperm_wv, "must be in the range <0; 1>");
194 }
195 }
196 } else { // according to Kunzel
197 if ( this->Isotherm == Hansen ) {
198 this->wf = rhodry * uh;
199 } else {
201 }
203 }
204 } else {
205 throw ValueInputException(ir, _IFT_NlIsoMoistureMaterial_permeabilitytype, "unknown permeability type");
206 }
207
208 wn = 0.;
211}
212
213double
215{
216 double humidity = this->giveHumidity(gp, VM_Total);
217
218 if ( this->Isotherm == linear ) {
219 return moistureCapacity;
220 } else if ( this->Isotherm == multilinear ) {
221 double tol = 1.e-10;
222 for ( int i = 2; i <= iso_h.giveSize(); i++ ) {
223 if ( ( humidity - iso_h.at(i) ) < tol ) {
224 return ( iso_wh.at(i) - iso_wh.at(i - 1) ) / ( iso_h.at(i) - iso_h.at(i - 1) );
225 }
226 }
227 } else if ( this->Isotherm == Ricken ) {
228 return 1. / ( dd * ( 1. - humidity ) );
229 } else if ( this->Isotherm == Kuenzel ) {
230 return wf * ( b - 1. ) * b / ( ( b - humidity ) * ( b - humidity ) );
231 } else if ( this->Isotherm == Hansen ) {
232 return rhodry * uh / ( A * nn * humidity * pow( ( 1 - log(humidity) / A ), ( 1 / nn + 1 ) ) );
233 } else if ( this->Isotherm == BSB ) {
234 double nominator, denominator;
235 nominator = c * k * Vm * rhodry * ( 1. + k * k * humidity * humidity * c - k * k * humidity * humidity );
236 denominator = ( 1. - k * humidity ) * ( 1. - k * humidity ) * ( 1. + ( c - 1. ) * k * humidity ) * ( 1. + ( c - 1. ) * k * humidity );
237 return nominator / denominator;
238 } else if ( this->Isotherm == bilinear ) {
239 if ( humidity <= ( hx - dx ) ) {
240 return moistureCapacity;
241 } else if ( humidity >= ( hx + dx ) ) {
242 return capa2;
243 } else {
244 return moistureCapacity + 2 * c2 * ( humidity - hx + dx ) + 3 * c1 * pow(humidity - hx + dx, 2);
245 }
246 } else if ( this->Isotherm == vanGenuchten ) {
247 return wf * vG_m * vG_b / humidity * pow( ( pow( ( -vG_b * log(humidity) ), ( 1. / ( 1. - vG_m ) ) ) + 1. ), ( -vG_m - 1 ) ) * ( 1. / ( 1. - vG_m ) * pow( ( -vG_b * log(humidity) ), ( vG_m / ( 1. - vG_m ) ) ) );
248 } else {
249 OOFEM_ERROR("unknown isotherm type");
250 }
251
252 return 0.;
253}
254
255double
257{
258 if ( this->Isotherm == linear ) {
259 return max(moistureCapacity * humidity + iso_offset, 0.);
260 } else if ( this->Isotherm == multilinear ) {
261 double tol = 1.e-10;
262 for ( int i = 1; i <= iso_h.giveSize(); i++ ) {
263 if ( ( humidity - iso_h.at(i) ) < tol ) {
264 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) );
265 }
266 }
267 } else if ( this->Isotherm == Ricken ) {
268 return wf - log(1. - humidity) / dd;
269 } else if ( this->Isotherm == Kuenzel ) {
270 return wf * ( b - 1. ) * humidity / ( b - humidity );
271 } else if ( this->Isotherm == Hansen ) {
272 return rhodry * uh * pow( ( 1. - log(humidity) / A ), ( -1. / nn ) );
273 } else if ( this->Isotherm == BSB ) {
274 return rhodry * c * k * Vm * humidity / ( ( 1. - k * humidity ) * ( c - 1. ) * k * humidity );
275 } else if ( this->Isotherm == bilinear ) {
276 if ( humidity <= ( hx - dx ) ) {
277 return max(moistureCapacity * humidity + iso_offset, 0.);
278 } else if ( humidity >= ( hx + dx ) ) {
279 return hx * moistureCapacity + ( humidity - hx ) * capa2 + iso_offset;
280 } else {
281 return ( hx - dx ) * moistureCapacity + moistureCapacity * ( humidity - hx + dx ) + c2 * pow(humidity - hx + dx, 2) + c1 * pow(humidity - hx + dx, 3) + iso_offset;
282 }
283 } else if ( this->Isotherm == vanGenuchten ) {
284 return wf * pow( ( pow( ( -vG_b * log(humidity) ), ( 1. / ( 1. - vG_m ) ) ) + 1. ), -vG_m);
285 } else {
286 OOFEM_ERROR("unknown isotherm type");
287 }
288
289 return 0.;
290}
291
292double
294{
295 double humidity = this->giveHumidity(gp, VM_Total);
296
297 if ( this->Permeability == multilin ) {
298 double tol = 1.e-10;
299 for ( int i = 1; i <= perm_h.giveSize(); i++ ) {
300 if ( ( humidity - perm_h.at(i) ) < tol ) {
301 return 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) );
302 }
303 }
304 } else if ( this->Permeability == Bazant ) {
305 return C1 * ( alpha0 + ( 1. - alpha0 ) / ( 1. + pow( ( 1. - humidity ) / ( 1. - hC ), n ) ) );
306 } else if ( this->Permeability == Xi ) {
307 double power = pow( 10., gammah * ( humidity - 1. ) );
308 return alphah + betah * ( 1. - pow(2., -power) );
309 } else if ( this->Permeability == KunzelPerm ) {
310 // [kg/m^3]
311 double dw_dh = this->giveMoistureCapacity(gp, tStep);
312 // capillary transport coefficient [m^2/s]
313 double Dw = this->computeCapTranspCoeff(humidity);
314
315 double temper_factor = this->computeTemperatureEffectOnViscosity(gp, tStep);
316 double p_sat = this->computeSaturationWaterVaporPressure(gp, tStep);
317 double deltap = this->computeVaporDiffusionCoeff(gp, tStep);
318
319 return temper_factor * Dw * dw_dh + deltap * p_sat;
320 } else {
321 OOFEM_ERROR("unknown permeability type");
322 }
323
324 return 0.;
325}
326
327
328double
330{
331 double Dw = 0.;
332
333 if ( this->CapillaryTransport == Multilin_h ) {
334 double tol = 1.e-10;
335 for ( int i = 1; i <= capPerm_h.giveSize(); i++ ) {
336 if ( ( humidity - capPerm_h.at(i) ) < tol ) {
337 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) );
338 break;
339 }
340 }
341 } else if ( this->CapillaryTransport == Multilin_wV ) {
342 double wV = this->giveMoistureContent(humidity) / rhoH2O;
343 double tol = 1.e-10;
344 for ( int i = 1; i <= capPerm_wV.giveSize(); i++ ) {
345 if ( ( wV - capPerm_wV.at(i) ) < tol ) {
346 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) );
347 break;
348 }
349 }
350 } else if ( this->CapillaryTransport == KunzelCT ) {
351 double w = this->giveMoistureContent(humidity);
352 Dw = 3.8 * ( Abs / wf ) * ( Abs / wf ) * pow(this->capillary_transport_coef, w / wf - 1.);
353 } else {
354 OOFEM_ERROR("unknown capillary transport type");
355 }
356
357
358
359
360 return Dw;
361}
362
363
364double
366{
367 double temperature = this->giveTemperature(gp, tStep);
368
369 double delta = this->timeScale * 2.0 * 1.e-7 * pow(temperature, 0.81) / this->PL;
370 return delta / this->mu;
371}
372
373
374double
376{
377 double temperature = this->giveTemperature(gp, tStep);
378
379 temperature -= 273.15;
380 double T0, a;
381
382 if ( temperature < 0. ) {
383 a = 22.44;
384 T0 = 272.44;
385 } else {
386 a = 17.08;
387 T0 = 234.18;
388 }
389
390 return 611. * exp( a * temperature / ( T0 + temperature ) );
391}
392
393
394double
396{
397 double temperature = this->giveTemperature(gp, tStep);
398
399 // ratio of water viscosity at given temperature and reference temperature, taken as 20 C
400 // viscosity is comptued according to Gawin
401 // eta(T) = 0.6612 * (T-229)**-1.532
402 return pow(64. / ( temperature - 229. ), -1.532);
403}
404
405
406double
408{
409 double temperature;
410
411 if ( this->T_TF != 0 ) {
412 temperature = domain->giveFunction(this->T_TF)->evaluateAtTime(tStep->giveTargetTime() );
413 } else {
414 temperature = this->T;
415 }
416
417 return temperature;
418}
419
420
421
422
423
424double
426{
427 auto tempState = static_cast< TransportMaterialStatus * >( this->giveStatus(gp) )->giveTempField();
428 if ( tempState > 1.0 || tempState < 0.0 ) {
429 OOFEM_ERROR("Relative humidity %.3f is out of range", tempState);
430 } else {
431 return tempState;
432 }
433}
434
435bool
437{
438 return this->wn != 0.;
439}
440
441void
443{
444 val.resize(1);
445 if ( mode == VM_Total || mode == VM_TotalIntrinsic ) {
446 val.at(1) = -wn * ( this->alpha.eval( { { "t", tStep->giveTargetTime() } }, this->giveDomain() ) - this->alpha.eval( { { "t", tStep->giveTargetTime() - tStep->giveTimeIncrement() } }, this->giveDomain() ) ) / tStep->giveTimeIncrement();
447 } else {
448 OOFEM_ERROR("Undefined mode %s\n", __ValueModeTypeToString(mode) );
449 }
450}
451} // end namespace oofem
#define REGISTER_Material(class)
Domain * giveDomain() const
Definition femcmpnn.h:97
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition femcmpnn.h:79
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
void initializeFrom(InputRecord &ir) override
virtual MaterialStatus * giveStatus(GaussPoint *gp) const
Definition material.C:206
double computeTemperatureEffectOnViscosity(GaussPoint *gp, TimeStep *tStep) const
evaluate temperature effect on water viscosity - liquid water capillary conduction
double vG_b
parameters of vanGenuchten isotherm
double T
constant temperature [K]
double rhodry
density of the dry solid phase
ScalarFunction alpha
Function of degree of hydration.
double giveHumidity(GaussPoint *gp, ValueModeType mode) const override
FloatArray perm_h
values of the multilinear permeability
enum oofem::NlIsoMoistureMaterial::isothermType Isotherm
double alphah
permeability parameters according to Xi, Bazant & Jennings
double capillary_transport_coef
parameter in liquid conduction
FloatArray capPerm_h
values of the multilinear capillary transport function
FloatArray iso_h
values of the multilinear isotherm
double Abs
water absorption coefficient [kg m^-2 s^-0.5]
double hx
values of the bilinear isotherm
double uh
parameters of the isotherm proposed by P. Freiesleben Hansen (Coupled moisture/heat transport in cros...
double c
parameters of the BSB isotherm
double wn
Nonevaporable water content per m3 of concrete at complete hydration.
double giveMoistureCapacity(GaussPoint *gp, TimeStep *tStep) const override
evaluates slope of the sorption isotherm
double timeScale
= 1 for analysis in seconds, = 86400 for analysis in days, etc.
int T_TF
explicitly prescribed evolution of temperature by a time function (e.g. piecewise-linear dfined exter...
bool hasInternalSource() const override
double PL
ambient atmospheric pressure [Pa]
double computeCapTranspCoeff(double humidity) const
double dd
parameters of the Ricken isotherm
double moistureCapacity
values of the linear isotherm
void initializeFrom(InputRecord &ir) override
double computeVaporDiffusionCoeff(GaussPoint *gp, TimeStep *tStep) const
compute vapor diffusion coefficient in air [kg m^-1 s^-1 Pa^-1]
double giveTemperature(GaussPoint *gp, TimeStep *tStep) const
returns temperature in [K]
double wf
parameters of the Kuenzel isotherm
void computeInternalSourceVector(FloatArray &val, GaussPoint *gp, TimeStep *tStep, ValueModeType mode) const override
enum oofem::NlIsoMoistureMaterial::permeabilityType Permeability
double mu
water vapor diffusion resistance [-]
enum oofem::NlIsoMoistureMaterial::capillaryTransportType CapillaryTransport
double givePermeability(GaussPoint *gp, TimeStep *tStep) const override
double giveMoistureContent(double humidity) const override
double computeSaturationWaterVaporPressure(GaussPoint *gp, TimeStep *tStep) const
compute saturation water vapor pressure
double C1
"permeability" according to Bazant
double giveTimeIncrement()
Returns solution step associated time increment.
Definition timestep.h:168
double giveTargetTime()
Returns target time.
Definition timestep.h:164
#define OOFEM_ERROR(...)
Definition error.h:79
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
#define _IFT_NlIsoMoistureMaterial_iso_h
#define _IFT_NlIsoMoistureMaterial_capa
#define _IFT_NlIsoMoistureMaterial_iso_offset
#define _IFT_NlIsoMoistureMaterial_vg_m
#define _IFT_NlIsoMoistureMaterial_rhoh2o
#define _IFT_NlIsoMoistureMaterial_capperm_h
#define _IFT_NlIsoMoistureMaterial_timescale
#define _IFT_NlIsoMoistureMaterial_gammah
#define _IFT_NlIsoMoistureMaterial_alpha
#define _IFT_NlIsoMoistureMaterial_alphah
#define _IFT_NlIsoMoistureMaterial_capperm_wv
#define _IFT_NlIsoMoistureMaterial_vm
#define _IFT_NlIsoMoistureMaterial_hc
#define _IFT_NlIsoMoistureMaterial_nn
#define _IFT_NlIsoMoistureMaterial_k
#define _IFT_NlIsoMoistureMaterial_t
#define _IFT_NlIsoMoistureMaterial_capillarytransporttype
#define _IFT_NlIsoMoistureMaterial_iso_wh
#define _IFT_NlIsoMoistureMaterial_c1
#define _IFT_NlIsoMoistureMaterial_permeabilitytype
#define _IFT_NlIsoMoistureMaterial_a
#define _IFT_NlIsoMoistureMaterial_perm_h
#define _IFT_NlIsoMoistureMaterial_wn
#define _IFT_NlIsoMoistureMaterial_vg_b
#define _IFT_NlIsoMoistureMaterial_capil_coef
#define _IFT_NlIsoMoistureMaterial_alpha0
#define _IFT_NlIsoMoistureMaterial_c
#define _IFT_NlIsoMoistureMaterial_hx
#define _IFT_NlIsoMoistureMaterial_capperm_dwh
#define _IFT_NlIsoMoistureMaterial_ttf
#define _IFT_NlIsoMoistureMaterial_isothermtype
#define _IFT_NlIsoMoistureMaterial_pl
#define _IFT_NlIsoMoistureMaterial_perm_ch
#define _IFT_NlIsoMoistureMaterial_b
#define _IFT_NlIsoMoistureMaterial_mu
#define _IFT_NlIsoMoistureMaterial_wf
#define _IFT_NlIsoMoistureMaterial_rhodry
#define _IFT_NlIsoMoistureMaterial_dx
#define _IFT_NlIsoMoistureMaterial_capperm_dwwv
#define _IFT_NlIsoMoistureMaterial_betah
#define _IFT_NlIsoMoistureMaterial_n
#define _IFT_NlIsoMoistureMaterial_uh
#define _IFT_NlIsoMoistureMaterial_dd
#define _IFT_NlIsoMoistureMaterial_abs

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011