https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PorousFlowVanGenuchtenTest.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#include "gtest/gtest.h"
11
12#include "DataIO.h"
14
15const double eps = 1.0E-8;
16
19const Real low_ext_Pc = 1.5;
21const Real low_ext_dPc =
40const Real high_ext_S = 0.9 * (1.0 - 0.3); // here 0.9 is the so-called ratio
41const Real high_ext_Pc =
43const Real high_ext_dPc =
57
58TEST(PorousFlowVanGenuchtenTest, extensionsDataIO)
59{
60 std::array<PorousFlowVanGenuchten::LowCapillaryPressureExtension, 1> stored_low = {low_ext_exp};
61 std::array<PorousFlowVanGenuchten::HighCapillaryPressureExtension, 1> stored_high = {
63 std::stringstream stream;
64 dataStore(stream, stored_low, nullptr);
65 dataStore(stream, stored_high, nullptr);
66
67 stream.seekg(0, std::ios::beg);
68 std::array<PorousFlowVanGenuchten::LowCapillaryPressureExtension, 1> loaded_low;
69 std::array<PorousFlowVanGenuchten::HighCapillaryPressureExtension, 1> loaded_high;
70 dataLoad(stream, loaded_low, nullptr);
71 dataLoad(stream, loaded_high, nullptr);
72
73 EXPECT_EQ(stored_low[0].strategy, loaded_low[0].strategy);
74 EXPECT_EQ(stored_low[0].S, loaded_low[0].S);
75 EXPECT_EQ(stored_low[0].Pc, loaded_low[0].Pc);
76 EXPECT_EQ(stored_low[0].dPc, loaded_low[0].dPc);
77 EXPECT_EQ(stored_high[0].strategy, loaded_high[0].strategy);
78 EXPECT_EQ(stored_high[0].S, loaded_high[0].S);
79 EXPECT_EQ(stored_high[0].Pc, loaded_high[0].Pc);
80 EXPECT_EQ(stored_high[0].dPc, loaded_high[0].dPc);
81}
82
83TEST(PorousFlowVanGenuchtenTest, sat)
84{
85 EXPECT_NEAR(1.0, PorousFlowVanGenuchten::effectiveSaturation(1.0E30, 0.7, 0.5), 1.0E-5);
86 EXPECT_NEAR(1.0, PorousFlowVanGenuchten::effectiveSaturation(1.0, 0.7, 0.5), 1.0E-5);
87 EXPECT_NEAR(1.0, PorousFlowVanGenuchten::effectiveSaturation(0.0, 0.7, 0.5), 1.0E-5);
88 EXPECT_NEAR(1.0, PorousFlowVanGenuchten::effectiveSaturation(1.0E-10, 0.7, 0.5), 1.0E-5);
89 EXPECT_NEAR(
90 0.486841442435055, PorousFlowVanGenuchten::effectiveSaturation(-2.0, 0.7, 0.6), 1.0E-5);
91 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::effectiveSaturation(-1.0E30, 0.7, 0.5), 1.0E-5);
92}
93
94TEST(PorousFlowVanGenuchtenTest, dsat)
95{
96 Real fd;
97 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::dEffectiveSaturation(1.0E30, 0.7, 0.5), 1.0E-5);
98 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::dEffectiveSaturation(1.0, 0.7, 0.5), 1.0E-5);
99 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::dEffectiveSaturation(0.0, 0.7, 0.5), 1.0E-5);
100 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::dEffectiveSaturation(1.0E-10, 0.7, 0.5), 1.0E-5);
101 fd = (PorousFlowVanGenuchten::effectiveSaturation(-2.0 + eps, 0.7, 0.6) -
103 eps;
104 EXPECT_NEAR(fd, PorousFlowVanGenuchten::dEffectiveSaturation(-2.0, 0.7, 0.6), 1.0E-5);
105 fd = (PorousFlowVanGenuchten::effectiveSaturation(-1.1 + eps, 0.9, 0.66) -
107 eps;
108 EXPECT_NEAR(fd, PorousFlowVanGenuchten::dEffectiveSaturation(-1.1, 0.9, 0.66), 1.0E-5);
109 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::dEffectiveSaturation(-1.0E30, 0.7, 0.5), 1.0E-5);
110}
111
112TEST(PorousFlowVanGenuchtenTest, d2sat)
113{
114 Real fd;
115 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::d2EffectiveSaturation(1.0E30, 0.7, 0.5), 1.0E-5);
116 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::d2EffectiveSaturation(1.0, 0.7, 0.5), 1.0E-5);
117 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::d2EffectiveSaturation(0.0, 0.7, 0.5), 1.0E-5);
118 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::d2EffectiveSaturation(1.0E-10, 0.7, 0.5), 1.0E-5);
119 fd = (PorousFlowVanGenuchten::dEffectiveSaturation(-2.0 + eps, 0.7, 0.6) -
121 eps;
122 EXPECT_NEAR(fd, PorousFlowVanGenuchten::d2EffectiveSaturation(-2.0, 0.7, 0.6), 1.0E-5);
123 fd = (PorousFlowVanGenuchten::dEffectiveSaturation(-1.1 + eps, 2.3, 0.67) -
125 eps;
126 EXPECT_NEAR(fd, PorousFlowVanGenuchten::d2EffectiveSaturation(-1.1, 2.3, 0.67), 1.0E-5);
127 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::d2EffectiveSaturation(-1.0E30, 0.7, 0.5), 1.0E-5);
128}
129
130TEST(PorousFlowVanGenuchtenTest, cap)
131{
132 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::capillaryPressure(1.1, 1.0, 0.55, 1.0E30), 1.0E-5);
133 EXPECT_NEAR(4.06172392297447,
134 PorousFlowVanGenuchten::capillaryPressure(0.3, 0.625, 0.55, 1.0E30),
135 1.0E-5);
136 EXPECT_NEAR(2.9, PorousFlowVanGenuchten::capillaryPressure(0.001, 0.625, 0.55, 2.9), 1.0E-5);
137 EXPECT_NEAR(1000.0, PorousFlowVanGenuchten::capillaryPressure(0.0, 0.625, 0.55, 1000.0), 1.0E-5);
138}
139
140TEST(PorousFlowVanGenuchtenTest, dcap)
141{
142 Real fd;
143 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::dCapillaryPressure(0.0, 1.0, 0.55, 1.0E30), 1.0E-5);
144 fd = (PorousFlowVanGenuchten::capillaryPressure(0.3 + eps, 0.625, 0.55, 1.0E30) -
145 PorousFlowVanGenuchten::capillaryPressure(0.3, 0.625, 0.55, 1.0E30)) /
146 eps;
147 EXPECT_NEAR(fd, PorousFlowVanGenuchten::dCapillaryPressure(0.3, 0.625, 0.55, 1.0E30), 1.0E-5);
148 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::dCapillaryPressure(1.0, 1.0, 0.55, 1.0E30), 1.0E-5);
149}
150
151TEST(PorousFlowVanGenuchtenTest, d2cap)
152{
153 Real fd;
154 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::d2CapillaryPressure(0.0, 1.0, 0.55, 1.0E30), 1.0E-5);
155 fd = (PorousFlowVanGenuchten::dCapillaryPressure(0.3 + eps, 0.625, 0.55, 1.0E30) -
156 PorousFlowVanGenuchten::dCapillaryPressure(0.3, 0.625, 0.55, 1.0E30)) /
157 eps;
158 EXPECT_NEAR(fd, PorousFlowVanGenuchten::d2CapillaryPressure(0.3, 0.625, 0.55, 1.0E30), 1.0E-5);
159 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::d2CapillaryPressure(1.0, 0.625, 0.55, 1.0E30), 1.0E-5);
160}
161
162TEST(PorousFlowVanGenuchtenTest, relperm)
163{
164 EXPECT_NEAR(1.0, PorousFlowVanGenuchten::relativePermeability(1.0E30, 0.7), 1.0E-5);
165 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::relativePermeability(-1.0, 0.7), 1.0E-5);
166 EXPECT_NEAR(0.0091160727, PorousFlowVanGenuchten::relativePermeability(0.3, 0.7), 1.0E-5);
167}
168
169TEST(PorousFlowVanGenuchtenTest, drelperm)
170{
171 Real fd;
172 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::dRelativePermeability(1.0E30, 0.7), 1.0E-5);
173 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::dRelativePermeability(-1.0, 0.7), 1.0E-5);
176 eps;
177 EXPECT_NEAR(fd, PorousFlowVanGenuchten::dRelativePermeability(0.3, 0.7), 1.0E-5);
180 eps;
181 EXPECT_NEAR(fd, PorousFlowVanGenuchten::dRelativePermeability(0.8, 0.65), 1.0E-5);
182}
183
184TEST(PorousFlowVanGenuchtenTest, d2relperm)
185{
186 Real fd;
187 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::d2RelativePermeability(1.0E30, 0.7), 1.0E-5);
188 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::d2RelativePermeability(-1.0, 0.7), 1.0E-5);
191 eps;
192 EXPECT_NEAR(fd, PorousFlowVanGenuchten::d2RelativePermeability(0.3, 0.7), 1.0E-5);
195 eps;
196 EXPECT_NEAR(fd, PorousFlowVanGenuchten::d2RelativePermeability(0.8, 0.65), 1.0E-5);
197}
198
199TEST(PorousFlowVanGenuchtenTest, adrelperm)
200{
201 ADReal sat = 0.3;
202 Moose::derivInsert(sat.derivatives(), 0, 1.0);
203
204 const auto adrelperm = PorousFlowVanGenuchten::relativePermeability(sat, 0.7);
205
206 const auto relperm = PorousFlowVanGenuchten::relativePermeability(sat.value(), 0.7);
207 const auto drelperm = PorousFlowVanGenuchten::dRelativePermeability(sat.value(), 0.7);
208
209 EXPECT_NEAR(adrelperm.value(), relperm, 1.0E-5);
210 EXPECT_NEAR(adrelperm.derivatives()[0], drelperm, 1.0E-5);
211}
212
213TEST(PorousFlowVanGenuchtenTest, relpermNW)
214{
215 EXPECT_NEAR(1.0, PorousFlowVanGenuchten::relativePermeabilityNW(1.0E30, 0.7), 1.0E-5);
216 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::relativePermeabilityNW(-1.0, 0.7), 1.0E-5);
217 EXPECT_NEAR(0.664138097, PorousFlowVanGenuchten::relativePermeabilityNW(0.5, 0.3), 1.0E-5);
218 EXPECT_NEAR(0.559879012, PorousFlowVanGenuchten::relativePermeabilityNW(0.7, 0.8), 1.0E-5);
219}
220
221TEST(PorousFlowVanGenuchtenTest, drelpermNW)
222{
223 Real fd;
224 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::dRelativePermeabilityNW(1.0E30, 0.7), 1.0E-5);
225 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::dRelativePermeabilityNW(-1.0, 0.7), 1.0E-5);
228 eps;
229 EXPECT_NEAR(fd, PorousFlowVanGenuchten::dRelativePermeabilityNW(0.3, 0.7), 1.0E-5);
232 eps;
233 EXPECT_NEAR(fd, PorousFlowVanGenuchten::dRelativePermeabilityNW(0.8, 0.65), 1.0E-5);
234}
235
236TEST(PorousFlowVanGenuchtenTest, d2relpermNW)
237{
238 Real fd;
239 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::d2RelativePermeabilityNW(1.0E30, 0.7), 1.0E-5);
240 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::d2RelativePermeabilityNW(-1.0, 0.7), 1.0E-5);
243 eps;
244 EXPECT_NEAR(fd, PorousFlowVanGenuchten::d2RelativePermeabilityNW(0.3, 0.7), 1.0E-5);
247 eps;
248 EXPECT_NEAR(fd, PorousFlowVanGenuchten::d2RelativePermeabilityNW(0.8, 0.65), 1.0E-5);
249}
250
251TEST(PorousFlowVanGenuchtenTest, adrelpermnw)
252{
253 ADReal sat = 0.3;
254 Moose::derivInsert(sat.derivatives(), 0, 1.0);
255
256 const auto adrelperm = PorousFlowVanGenuchten::relativePermeabilityNW(sat, 0.7);
257
258 const auto relperm = PorousFlowVanGenuchten::relativePermeabilityNW(sat.value(), 0.7);
259 const auto drelperm = PorousFlowVanGenuchten::dRelativePermeabilityNW(sat.value(), 0.7);
260
261 EXPECT_NEAR(adrelperm.value(), relperm, 1.0E-5);
262 EXPECT_NEAR(adrelperm.derivatives()[0], drelperm, 1.0E-5);
263}
264
266TEST(PorousFlowVanGenuchtenTest, caphys)
267{
268 // first define some extensions that do not actually induce any extension, so the non-extended Pc
269 // can be checked
270 const std::vector<Real> no_ext_sats{1.1, 0.75, 0.2, 0.4, 0.6};
271 const std::vector<Real> expected_pcs{
272 0.0, 0.0, 0.7233512030263158, 0.18806139488299345, 0.06716785873826017};
273 for (unsigned i = 0; i < no_ext_sats.size(); ++i)
274 {
275 EXPECT_NEAR(expected_pcs[i],
277 no_ext_sats[i], 0.1, 0.3, 10.0, 1.9, no_low_ext, no_high_ext),
278 1.0E-5);
279 EXPECT_NEAR(expected_pcs[i],
280 PorousFlowVanGenuchten::capillaryPressureHys(no_ext_sats[i], 0.1, 0.3, 10.0, 1.9),
281 1.0E-5);
282 }
283 EXPECT_NEAR(123.0,
285 -1.0, 0.1, 0.3, 10.0, 1.9, no_low_ext, no_high_ext),
286 1.0E-5);
287 EXPECT_NEAR(123.0,
289 0.05, 0.1, 0.3, 10.0, 1.9, no_low_ext, no_high_ext),
290 1.0E-5);
291 EXPECT_NEAR(std::numeric_limits<Real>::max(),
292 PorousFlowVanGenuchten::capillaryPressureHys(-1.0, 0.1, 0.3, 10.0, 1.9),
293 1.0E-5);
294 EXPECT_NEAR(std::numeric_limits<Real>::max(),
295 PorousFlowVanGenuchten::capillaryPressureHys(0.05, 0.1, 0.3, 10.0, 1.9),
296 1.0E-5);
297
298 // check the lower extension values
299 EXPECT_NEAR(0.15229665668299805, low_ext_exp.S, 1.0E-5);
300 EXPECT_NEAR(-32.05516428734052, low_ext_exp.dPc, 1.0E-5);
301
302 // check the high extension
303 EXPECT_NEAR(0.05300654102157442, high_ext_power.Pc, 1.0E-5);
304 EXPECT_NEAR(-0.48230528124844047, high_ext_power.dPc, 1.0E-5);
305
306 // using low_ext_exp and high_ext_power
307 const std::vector<Real> sats{0.01, 0.1, 0.15, 0.2, 0.5, 0.63, 0.8, 0.99, 1.0};
308 std::vector<Real> pc;
309 pc = {31.385947046636815,
310 4.5861935551774735,
311 1.5754562501536364,
312 0.7233512030263158,
313 0.11727884570711045,
314 0.05300654102157442,
315 0.006681337544884095,
316 2.7847615834816514e-07,
317 0.0};
318 for (unsigned i = 0; i < sats.size(); ++i)
319 EXPECT_NEAR(pc[i],
321 sats[i], 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power),
322 1.0E-5);
323
324 // using low_ext_quad and high_ext_power
325 pc = {3.9304232526771696,
326 2.8885549236001244,
327 1.5730646091089062,
328 0.7233512030263158,
329 0.11727884570711045,
330 0.05300654102157442,
331 0.006681337544884095,
332 2.7847615834816514e-07,
333 0.0};
334 for (unsigned i = 0; i < sats.size(); ++i)
335 EXPECT_NEAR(pc[i],
337 sats[i], 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power),
338 1.0E-5);
339
340 // using low_ext_none and high_ext_power
341 pc = {1.5,
342 1.5,
343 1.5,
344 0.7233512030263158,
345 0.11727884570711045,
346 0.05300654102157442,
347 0.006681337544884095,
348 2.7847615834816514e-07,
349 0.0};
350 for (unsigned i = 0; i < sats.size(); ++i)
351 EXPECT_NEAR(pc[i],
353 sats[i], 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power),
354 1.0E-5);
355
356 // using low_ext_none and high_ext_none
357 pc = {1.5, 1.5, 1.5, 0.7233512030263158, 0.11727884570711045, 0.05300654102157442, 0.0, 0.0, 0.0};
358 for (unsigned i = 0; i < sats.size(); ++i)
359 EXPECT_NEAR(pc[i],
361 sats[i], 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none),
362 1.0E-5);
363}
364
366TEST(PorousFlowVanGenuchtenTest, sathys)
367{
368 // first define some extensions that do not actually induce any extension, so the non-extended Pc
369 // can be checked
370 const std::vector<Real> expected_sats{1.0, 0.2, 0.4, 0.6};
371 const std::vector<Real> no_ext_pcs{
372 -1.1, 0.7233512030263158, 0.18806139488299345, 0.06716785873826017};
373 for (unsigned i = 0; i < no_ext_pcs.size(); ++i)
374 {
375 EXPECT_NEAR(expected_sats[i],
377 no_ext_pcs[i], 0.1, 0.3, 10.0, 1.9, no_low_ext, no_high_ext),
378 1.0E-5);
379 EXPECT_NEAR(expected_sats[i],
380 PorousFlowVanGenuchten::saturationHys(no_ext_pcs[i], 0.1, 0.3, 10.0, 1.9),
381 1.0E-5);
382 }
383 EXPECT_NEAR(
384 -1.0,
385 PorousFlowVanGenuchten::saturationHys(1234.0, 0.1, 0.3, 10.0, 1.9, no_low_ext, no_high_ext),
386 1.0E-5);
387 EXPECT_NEAR(
388 0.0,
389 PorousFlowVanGenuchten::saturationHys(std::numeric_limits<Real>::max(), 0.1, 0.3, 10.0, 1.9),
390 1.0E-5);
391
392 // now with extensions
393 std::vector<Real> sats{0.01, 0.1, 0.15, 0.2, 0.5, 0.63, 0.8, 0.99, 1.0};
394 std::vector<Real> pc;
395 pc = {31.385947046636815,
396 4.5861935551774735,
397 1.5754562501536364,
398 0.7233512030263158,
399 0.11727884570711045,
400 0.05300654102157442,
401 0.006681337544884095,
402 2.7847615834816514e-07,
403 0.0};
404 for (unsigned i = 0; i < sats.size(); ++i)
405 EXPECT_NEAR(sats[i],
407 pc[i], 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power),
408 1.0E-5);
409
410 // different lower extension
411 pc = {3.9304232526771696,
412 2.8885549236001244,
413 1.5730646091089062,
414 0.7233512030263158,
415 0.11727884570711045,
416 0.05300654102157442,
417 0.006681337544884095,
418 2.7847615834816514e-07,
419 0.0};
420 for (unsigned i = 0; i < sats.size(); ++i)
421 EXPECT_NEAR(sats[i],
423 pc[i], 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power),
424 1.0E-5);
425
426 // different low extension
427 sats = {low_ext_none.S, low_ext_none.S, 0.2, 0.5, 0.63, 0.8, 0.99, 1.0};
428 pc = {2.5,
429 1.5,
430 0.7233512030263158,
431 0.11727884570711045,
432 0.05300654102157442,
433 0.006681337544884095,
434 2.7847615834816514e-07,
435 0.0};
436 for (unsigned i = 0; i < sats.size(); ++i)
437 EXPECT_NEAR(sats[i],
439 pc[i], 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power),
440 1.0E-5);
441
442 // different high extension
443 pc = {2.5, 1.5, 0.7233512030263158, 0.11727884570711045, 0.05300654102157442, 1E-10};
444 sats = {low_ext_none.S, low_ext_none.S, 0.2, 0.5, 0.63, 0.8};
445 for (unsigned i = 0; i < sats.size(); ++i)
446 EXPECT_NEAR(sats[i],
448 pc[i], 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none),
449 1.0E-5);
450}
451
453TEST(PorousFlowVanGenuchtenTest, dcaphys)
454{
455 const Real eps = 1.0E-9;
456
457 // first define some extensions that do not actually induce any extension, so the non-extended
458 // Pc can be checked
459 std::vector<Real> sats{1.1, 0.75, -1.0, 0.05};
460 for (const auto & sat : sats)
461 {
462 EXPECT_NEAR(0.0,
464 sat, 0.1, 0.3, 10.0, 1.9, no_low_ext, no_high_ext),
465 1.0E-5);
466 EXPECT_NEAR(
467 0.0, PorousFlowVanGenuchten::dcapillaryPressureHys(sat, 0.1, 0.3, 10.0, 1.9), 1.0E-5);
468 }
469
470 sats = {0.2, 0.4, 0.6};
471 for (const auto & sat : sats)
472 {
473 const Real fd = 0.5 *
474 (PorousFlowVanGenuchten::capillaryPressureHys(sat + eps, 0.1, 0.3, 10.0, 1.9) -
475 PorousFlowVanGenuchten::capillaryPressureHys(sat - eps, 0.1, 0.3, 10.0, 1.9)) /
476 eps;
477 EXPECT_NEAR(fd,
479 sat, 0.1, 0.3, 10.0, 1.9, no_low_ext, no_high_ext),
480 1.0E-5);
481 EXPECT_NEAR(
482 fd, PorousFlowVanGenuchten::dcapillaryPressureHys(sat, 0.1, 0.3, 10.0, 1.9), 1.0E-5);
483 };
484
485 // now with extensions
486 sats = {0.01, 0.1, 0.15, 0.2, 0.5, 0.63, 0.8, 0.99, 1.0};
487
488 for (const auto & sat : sats)
489 {
490 const Real fd = 0.5 *
492 sat + eps, 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power) -
494 sat - eps, 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power)) /
495 eps;
496 EXPECT_NEAR(fd,
498 sat, 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power),
499 1.0E-5);
500 };
501
502 // different low extension
503 for (const auto & sat : sats)
504 {
505 const Real fd = 0.5 *
507 sat + eps, 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power) -
509 sat - eps, 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power)) /
510 eps;
511 EXPECT_NEAR(fd,
513 sat, 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power),
514 1.0E-5);
515 };
516
517 // different lower extension
518 for (const auto & sat : sats)
519 {
520 const Real fd = 0.5 *
522 sat + eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power) -
524 sat - eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power)) /
525 eps;
526 EXPECT_NEAR(fd,
528 sat, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power),
529 1.0E-5);
530 };
531
532 // different upper extension (cannot evaluate derivative at s = 0.63)
533 sats = {0.01, 0.1, 0.15, 0.2, 0.5, 0.8, 0.99, 1.0};
534 for (const auto & sat : sats)
535 {
536 const Real fd = 0.5 *
538 sat + eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none2) -
540 sat - eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none2)) /
541 eps;
542 EXPECT_NEAR(fd,
544 sat, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none2),
545 1.0E-5);
546 };
547}
548
550TEST(PorousFlowVanGenuchtenTest, d2caphys)
551{
552 const Real eps = 1.0E-9;
553
554 // first define some extensions that do not actually induce any extension, so the non-extended
555 // Pc can be checked
556 std::vector<Real> sats{1.1, 0.75, -1.0, 0.05};
557 for (const auto & sat : sats)
558 {
559 EXPECT_NEAR(0.0,
561 sat, 0.1, 0.3, 10.0, 1.9, no_low_ext, no_high_ext),
562 1.0E-5);
563 EXPECT_NEAR(
564 0.0, PorousFlowVanGenuchten::d2capillaryPressureHys(sat, 0.1, 0.3, 10.0, 1.9), 1.0E-5);
565 }
566
567 sats = {0.2, 0.4, 0.6};
568 for (const auto & sat : sats)
569 {
570 const Real fd =
571 0.5 *
572 (PorousFlowVanGenuchten::dcapillaryPressureHys(sat + eps, 0.1, 0.3, 10.0, 1.9) -
573 PorousFlowVanGenuchten::dcapillaryPressureHys(sat - eps, 0.1, 0.3, 10.0, 1.9)) /
574 eps;
575 EXPECT_NEAR(fd,
577 sat, 0.1, 0.3, 10.0, 1.9, no_low_ext, no_high_ext),
578 1.0E-5);
579 EXPECT_NEAR(
580 fd, PorousFlowVanGenuchten::d2capillaryPressureHys(sat, 0.1, 0.3, 10.0, 1.9), 1.0E-5);
581 };
582
583 // now with extensions
584 sats = {0.01, 0.1, 0.15, 0.2, 0.5, 0.6, 0.7, 0.8, 0.99, 1.0};
585
586 for (const auto & sat : sats)
587 {
588 const Real fd = 0.5 *
590 sat + eps, 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power) -
592 sat - eps, 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power)) /
593 eps;
594 if (std::abs(fd) > 10)
595 EXPECT_NEAR(1.0,
597 sat, 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power),
598 1.0E-5);
599 else
600 EXPECT_NEAR(fd,
602 sat, 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power),
603 1.0E-5);
604 };
605
606 // different low extension
607 for (const auto & sat : sats)
608 {
609 const Real fd = 0.5 *
611 sat + eps, 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power) -
613 sat - eps, 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power)) /
614 eps;
615 if (std::abs(fd) > 10)
616 EXPECT_NEAR(1.0,
618 sat, 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power),
619 1.0E-5);
620 else
621 EXPECT_NEAR(fd,
623 sat, 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power),
624 1.0E-5);
625 };
626
627 // different lower extension
628 for (const auto & sat : sats)
629 {
630 const Real fd = 0.5 *
632 sat + eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power) -
634 sat - eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power)) /
635 eps;
636 if (std::abs(fd) > 10)
637 EXPECT_NEAR(1.0,
639 sat, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power),
640 1.0E-5);
641 else
642 EXPECT_NEAR(fd,
644 sat, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power),
645 1.0E-5);
646 };
647
648 // different upper extension (cannot evaluate derivative at s = 0.63)
649 sats = {0.01, 0.1, 0.15, 0.2, 0.5, 0.8, 0.99, 1.0};
650 for (const auto & sat : sats)
651 {
652 const Real fd = 0.5 *
654 sat + eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none2) -
656 sat - eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none2)) /
657 eps;
658 if (std::abs(fd) > 10)
659 EXPECT_NEAR(1.0,
661 sat, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none2),
662 1.0E-5);
663 else
664 EXPECT_NEAR(fd,
666 sat, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none2),
667 1.0E-5);
668 };
669}
670
672TEST(PorousFlowVanGenuchtenTest, dsathys)
673{
674 const Real eps = 1E-9;
675
676 // first define some extensions that do not actually induce any extension, so the non-extended Pc
677 // can be checked
678 std::vector<Real> pcs{-1.1, 1234.0};
679 for (const auto & pc : pcs)
680 {
681 EXPECT_NEAR(
682 0.0,
684 1.0E-5);
685 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::dsaturationHys(pc, 0.1, 0.3, 10.0, 1.9), 1.0E-5);
686 }
687
688 pcs = {0.7, 0.2, 0.07};
689 for (const auto & pc : pcs)
690 {
691 const Real fd = 0.5 *
693 pc + eps, 0.1, 0.3, 10.0, 1.9, no_low_ext, no_high_ext) -
695 pc - eps, 0.1, 0.3, 10.0, 1.9, no_low_ext, no_high_ext)) /
696 eps;
697 EXPECT_NEAR(
698 fd,
700 1.0E-5);
701 EXPECT_NEAR(fd, PorousFlowVanGenuchten::dsaturationHys(pc, 0.1, 0.3, 10.0, 1.9), 1.0E-5);
702 }
703
704 // now with low and high extensions
705 pcs = {31.385947046636815,
706 4.5861935551774735,
707 1.5754562501536364,
708 0.7233512030263158,
709 0.11727884570711045,
710 0.05300654102157442,
711 0.006681337544884095};
712 for (const auto & pc : pcs)
713 {
714 const Real fd = 0.5 *
716 pc + eps, 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power) -
718 pc - eps, 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power)) /
719 eps;
720 EXPECT_NEAR(fd,
722 pc, 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power),
723 1.0E-5);
724 }
725
726 // different lower extension
727 pcs = {3.9304232526771696,
728 2.8885549236001244,
729 1.5730646091089062,
730 0.7233512030263158,
731 0.11727884570711045,
732 0.05300654102157442,
733 0.006681337544884095};
734 for (const auto & pc : pcs)
735 {
736 const Real fd = 0.5 *
738 pc + eps, 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power) -
740 pc - eps, 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power)) /
741 eps;
742 EXPECT_NEAR(fd,
744 pc, 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power),
745 1.0E-5);
746 }
747
748 // different lower extension
749 pcs = {2.5, 0.7233512030263158, 0.11727884570711045, 0.05300654102157442, 0.006681337544884095};
750 for (const auto & pc : pcs)
751 {
752 const Real fd = 0.5 *
754 pc + eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power) -
756 pc - eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power)) /
757 eps;
758 EXPECT_NEAR(fd,
760 pc, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power),
761 1.0E-5);
762 }
763
764 // different upper extension
765 pcs = {2.5, 0.7233512030263158, 0.11727884570711045, 0.05, 0.04};
766 for (const auto & pc : pcs)
767 {
768 const Real fd = 0.5 *
770 pc + eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none) -
772 pc - eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none)) /
773 eps;
774 EXPECT_NEAR(fd,
776 pc, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none),
777 1.0E-5);
778 }
779}
780
782TEST(PorousFlowVanGenuchtenTest, d2sathys)
783{
784 const Real eps = 1E-9;
785
786 // first define some extensions that do not actually induce any extension, so the non-extended Pc
787 // can be checked
788 std::vector<Real> pcs{-1.1, 1234.0};
789 for (const auto & pc : pcs)
790 {
791 EXPECT_NEAR(
792 0.0,
794 1.0E-5);
795 EXPECT_NEAR(0.0, PorousFlowVanGenuchten::d2saturationHys(pc, 0.1, 0.3, 10.0, 1.9), 1.0E-5);
796 }
797
798 pcs = {0.7, 0.2, 0.07};
799 for (const auto & pc : pcs)
800 {
801 const Real fd = 0.5 *
803 pc + eps, 0.1, 0.3, 10.0, 1.9, no_low_ext, no_high_ext) -
805 pc - eps, 0.1, 0.3, 10.0, 1.9, no_low_ext, no_high_ext)) /
806 eps;
807 EXPECT_NEAR(
808 fd,
810 1.0E-5);
811 EXPECT_NEAR(fd, PorousFlowVanGenuchten::d2saturationHys(pc, 0.1, 0.3, 10.0, 1.9), 1.0E-5);
812 }
813
814 // now with low and high extensions
815 pcs = {31.385947046636815,
816 4.5861935551774735,
817 1.5754562501536364,
818 0.7233512030263158,
819 0.11727884570711045,
820 0.06300654102157442,
821 0.006681337544884095};
822 for (const auto & pc : pcs)
823 {
824 const Real fd = 0.5 *
826 pc + eps, 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power) -
828 pc - eps, 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power)) /
829 eps;
830 EXPECT_NEAR(fd,
832 pc, 0.1, 0.3, 10.0, 1.9, low_ext_exp, high_ext_power),
833 1.0E-5);
834 }
835
836 // different lower extension
837 pcs = {3.9304232526771696,
838 2.8885549236001244,
839 1.5730646091089062,
840 0.7233512030263158,
841 0.11727884570711045,
842 0.06300654102157442,
843 0.006681337544884095};
844 for (const auto & pc : pcs)
845 {
846 const Real fd = 0.5 *
848 pc + eps, 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power) -
850 pc - eps, 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power)) /
851 eps;
852 EXPECT_NEAR(fd,
854 pc, 0.1, 0.3, 10.0, 1.9, low_ext_quad, high_ext_power),
855 1.0E-5);
856 }
857
858 // different lower extension
859 pcs = {2.5, 0.7233512030263158, 0.11727884570711045, 0.06300654102157442, 0.006681337544884095};
860 for (const auto & pc : pcs)
861 {
862 const Real fd = 0.5 *
864 pc + eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power) -
866 pc - eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power)) /
867 eps;
868 EXPECT_NEAR(fd,
870 pc, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_power),
871 1.0E-5);
872 }
873
874 // different upper extension
875 pcs = {2.5, 0.7233512030263158, 0.11727884570711045, 0.05, 0.04};
876 for (const auto & pc : pcs)
877 {
878 const Real fd = 0.5 *
880 pc + eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none) -
882 pc - eps, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none)) /
883 eps;
884 EXPECT_NEAR(fd,
886 pc, 0.1, 0.3, 10.0, 1.9, low_ext_none, high_ext_none),
887 1.0E-5);
888 }
889}
890
892TEST(PorousFlowVanGenuchtenTest, relativePermeabilityHys)
893{
894 // Tests for sldel = 0.5 >= slr = 0.2
895 EXPECT_NEAR(0.0,
897 0.1, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
898 1.0E-12); // zero because sl < slr
899 EXPECT_NEAR(0.0,
901 0.2, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
902 1.0E-12); // zero because sl = slr
903 EXPECT_NEAR(0.002847974503642625,
905 0.3, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
906 1.0E-12); // drying because sl <= sldel
907 EXPECT_NEAR(0.002847974503642625,
909 0.3, 0.2, 0.0, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
910 1.0E-12); // drying because sgrdel = 0
911 EXPECT_NEAR(0.05828443549816974,
913 0.5, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
914 1.0E-12); // drying because sl <= sldel
915 EXPECT_NEAR(0.10056243969693253,
917 0.55, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
918 1.0E-12); // wetting
919 EXPECT_NEAR(0.08943153676247108,
921 0.55, 0.2, 0.0, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
922 1.0E-12); // drying because sgrdel = 0
923 EXPECT_NEAR(0.3159149169921876,
925 0.8, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
926 1.0E-12); // cubic
927 EXPECT_NEAR(0.8011290515690178,
929 0.95, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
930 1.0E-12); // drying, because sl > cubic modification region
931
932 // Tests for sldel = 0.15 < slr = 0.2
933 EXPECT_NEAR(0.0,
935 0.1, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
936 1.0E-12); // zero because sl < slr
937 EXPECT_NEAR(0.0,
939 0.2, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
940 1.0E-12); // zero because sl = slr
941 EXPECT_NEAR(0.005858393312913491,
943 0.3, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
944 1.0E-12); // wetting
945 EXPECT_NEAR(0.002847974503642625,
947 0.3, 0.2, 0.0, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
948 1.0E-12); // drying because sgrdel = 0
949 EXPECT_NEAR(0.1363562523627124,
951 0.55, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
952 1.0E-12); // wetting
953 EXPECT_NEAR(0.31,
955 0.7, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
956 1.0E-12); // cubic
957 EXPECT_NEAR(0.8011290515690178,
959 0.95, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
960 1.0E-12); // drying, because sl > cubic modification region
961}
962
964TEST(PorousFlowVanGenuchtenTest, drelativePermeabilityHys)
965{
966 // essentially follow the testing strategy in the relativePermeabilityHys Test, but do not test
967 // the derivative at the points where it is discontinuous
968 EXPECT_NEAR(0.0,
970 0.1, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
971 1.0E-12);
973 0.3, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
975 0.3 + eps, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2) -
977 0.3, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2)) /
978 eps,
979 1.0E-5);
981 0.3, 0.2, 0.0, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
983 0.3 + eps, 0.2, 0.0, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2) -
985 0.3, 0.2, 0.0, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2)) /
986 eps,
987 1.0E-5);
989 0.55, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
991 0.55 + eps, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2) -
993 0.55, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2)) /
994 eps,
995 1.0E-5);
997 0.55, 0.2, 0.0, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
999 0.55 + eps, 0.2, 0.0, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2) -
1001 0.55, 0.2, 0.0, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2)) /
1002 eps,
1003 1.0E-5);
1005 0.8, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
1007 0.8 + eps, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2) -
1009 0.8, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2)) /
1010 eps,
1011 1.0E-5);
1013 0.95, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
1015 0.95 + eps, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2) -
1017 0.95, 0.2, 0.15, 0.25, 0.5, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2)) /
1018 eps,
1019 1.0E-5);
1020
1021 EXPECT_NEAR(0.0,
1023 0.1, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
1024 1.0E-5);
1026 0.3, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
1028 0.3 + eps, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2) -
1030 0.3, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2)) /
1031 eps,
1032 1.0E-5);
1034 0.3, 0.2, 0.0, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
1036 0.3 + eps, 0.2, 0.0, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2) -
1038 0.3, 0.2, 0.0, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2)) /
1039 eps,
1040 1.0E-5);
1042 0.55, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
1044 0.55 + eps, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2) -
1046 0.55, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2)) /
1047 eps,
1048 1.0E-5);
1050 0.7, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
1052 0.7 + eps, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2) -
1054 0.7, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2)) /
1055 eps,
1056 1.0E-5);
1058 0.95, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2),
1060 0.95 + eps, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2) -
1062 0.95, 0.2, 0.15, 0.25, 0.15, 0.9, 0.9, 0.3, 0.5, 0.45, 2.2)) /
1063 eps,
1064 1.0E-5);
1065}
1066
1068TEST(PorousFlowVanGenuchtenTest, relativePermeabilityNWHys)
1069{
1070 // Tests for sldel = 0.5 >= slr = 0.2
1071 EXPECT_NEAR(0.91875,
1073 0.1, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1074 1.0E-12); // cubic extension region because sl < slr
1075 EXPECT_NEAR(1.0,
1077 0.1, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 1.0, -0.75),
1078 1.0E-12); // cubic extension region because sl < slr, but k_rg_max = 1
1079 EXPECT_NEAR(0.8,
1081 0.2, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1082 1.0E-12); // at boundary of extension since sl = slr
1083 EXPECT_NEAR(0.6368139633459233,
1085 0.3, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1086 1.0E-12); // drying because sl <= sldel
1087 EXPECT_NEAR(0.6368139633459233,
1089 0.3, 0.2, 0.0, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1090 1.0E-12); // drying because sgrdel = 0
1091 EXPECT_NEAR(0.33222054246699,
1093 0.5, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1094 1.0E-12); // drying because sl <= sldel
1095 EXPECT_NEAR(0.24397255389213568,
1097 0.55, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1098 1.0E-12); // wetting
1099 EXPECT_NEAR(0.2691316236913443,
1101 0.55, 0.2, 0.0, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1102 1.0E-12); // drying because sgrdel = 0
1103 EXPECT_NEAR(0.01509148277290631,
1105 0.85, 0.2, 0.05, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1106 1.0E-12); // wetting
1107 EXPECT_NEAR(0.0,
1109 0.85, 0.2, 0.18, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1110 1.0E-12); // sl > 1 - s_gr_del
1111
1112 // Tests for sldel = 0.15 < slr = 0.2
1113 EXPECT_NEAR(0.91875,
1115 0.1, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75),
1116 1.0E-12); // cubic extension region because sl < slr
1117 EXPECT_NEAR(1.0,
1119 0.1, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 1.0, -0.75),
1120 1.0E-12); // cubic extension region because sl < slr, but k_rg_max = 1
1121 EXPECT_NEAR(0.8,
1123 0.2, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75),
1124 1.0E-12); // at boundary of extension since sl = slr
1125 EXPECT_NEAR(0.5616820966427329,
1127 0.3, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75),
1128 1.0E-12); // wetting
1129 EXPECT_NEAR(0.6368139633459233,
1131 0.3, 0.2, 0.0, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75),
1132 1.0E-12); // wetting = drying because sgrdel = 0
1133 EXPECT_NEAR(0.11086138435665097,
1135 0.55, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75),
1136 1.0E-12); // wetting
1137 EXPECT_NEAR(0.0,
1139 0.76, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75),
1140 1.0E-12); // always zero for large saturation
1141}
1142
1144TEST(PorousFlowVanGenuchtenTest, drelativePermeabilityNWHys)
1145{
1146 // Testing strategy follows the relativePermeabilityNWHys strategy, except the points at which the
1147 // derivative is not defined are not tested
1149 0.1, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1151 0.1 + eps, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75) -
1153 0.1, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75)) /
1154 eps,
1155 1.0E-5); // cubic extension region because sl < slr
1156 EXPECT_NEAR(0.0,
1158 0.1, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 1.0, -0.75),
1159 1.0E-12); // cubic extension region because sl < slr, but k_rg_max = 1
1161 0.3, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1163 0.3 + eps, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75) -
1165 0.3, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75)) /
1166 eps,
1167 1.0E-5); // drying because sl <= sldel
1169 0.3, 0.2, 0.0, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1171 0.3 + eps, 0.2, 0.0, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75) -
1173 0.3, 0.2, 0.0, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75)) /
1174 eps,
1175 1.0E-5); // drying because sgrdel = 0
1177 0.45, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1179 0.45 + eps, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75) -
1181 0.45, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75)) /
1182 eps,
1183 1.0E-5); // drying because sl <= sldel
1185 0.55, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1187 0.55 + eps, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75) -
1189 0.55, 0.2, 0.15, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75)) /
1190 eps,
1191 1.0E-5); // wetting
1193 0.55, 0.2, 0.0, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1195 0.55 + eps, 0.2, 0.0, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75) -
1197 0.55, 0.2, 0.0, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75)) /
1198 eps,
1199 1.0E-5); // drying because sgrdel = 0
1201 0.85, 0.2, 0.05, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1203 0.85 + eps, 0.2, 0.05, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75) -
1205 0.85, 0.2, 0.05, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75)) /
1206 eps,
1207 1.0E-5); // wetting
1208 EXPECT_NEAR(0.0,
1210 0.85, 0.2, 0.18, 0.25, 0.5, 0.9, 0.3, 0.8, -0.75),
1211 1.0E-12); // sl > 1 - s_gr_del
1212
1213 // Tests for sldel = 0.15 < slr = 0.2
1215 0.1, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75),
1217 0.1 + eps, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75) -
1219 0.1, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75)) /
1220 eps,
1221 1.0E-5); // cubic extension region because sl < slr
1222 EXPECT_NEAR(0.0,
1224 0.1, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 1.0, -0.75),
1225 1.0E-12); // cubic extension region because sl < slr, but k_rg_max = 1
1227 0.3, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75),
1229 0.3 + eps, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75) -
1231 0.3, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75)) /
1232 eps,
1233 1.0E-5); // wetting
1235 0.3, 0.2, 0.0, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75),
1237 0.3 + eps, 0.2, 0.0, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75) -
1239 0.3, 0.2, 0.0, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75)) /
1240 eps,
1241 1.0E-5); // wetting = drying because sgrdel = 0
1243 0.55, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75),
1245 0.55 + eps, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75) -
1247 0.55, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75)) /
1248 eps,
1249 1.0E-5); // wetting
1250 EXPECT_NEAR(0.0,
1252 0.76, 0.2, 0.18, 0.25, 0.15, 0.9, 0.3, 0.8, -0.75),
1253 1.0E-12); // always zero for large saturation
1254}
DualNumber< Real, DNDerivativeType, true > ADReal
void dataLoad(std::istream &stream, LineSegment &l, void *context)
void dataStore(std::ostream &stream, LineSegment &l, void *context)
const Real low_ext_Pc
const PorousFlowVanGenuchten::LowCapillaryPressureExtension low_ext_exp(PorousFlowVanGenuchten::LowCapillaryPressureExtension::EXPONENTIAL, low_ext_S, low_ext_Pc, low_ext_dPc)
const Real high_ext_dPc
const PorousFlowVanGenuchten::HighCapillaryPressureExtension no_high_ext(PorousFlowVanGenuchten::HighCapillaryPressureExtension::NONE, 2.0, 0.0, 0.0)
const PorousFlowVanGenuchten::HighCapillaryPressureExtension high_ext_power(PorousFlowVanGenuchten::HighCapillaryPressureExtension::POWER, high_ext_S, high_ext_Pc, high_ext_dPc)
const double eps
TEST(PorousFlowVanGenuchtenTest, extensionsDataIO)
const PorousFlowVanGenuchten::HighCapillaryPressureExtension high_ext_none(PorousFlowVanGenuchten::HighCapillaryPressureExtension::NONE, 0.8, high_ext_Pc, high_ext_dPc)
const PorousFlowVanGenuchten::LowCapillaryPressureExtension low_ext_quad(PorousFlowVanGenuchten::LowCapillaryPressureExtension::QUADRATIC, low_ext_S, low_ext_Pc, low_ext_dPc)
const PorousFlowVanGenuchten::HighCapillaryPressureExtension high_ext_none2(PorousFlowVanGenuchten::HighCapillaryPressureExtension::NONE, high_ext_S, high_ext_Pc, high_ext_dPc)
const PorousFlowVanGenuchten::LowCapillaryPressureExtension no_low_ext(PorousFlowVanGenuchten::LowCapillaryPressureExtension::NONE, -1.0, 123.0, 0.0)
const Real high_ext_S
const Real high_ext_Pc
const PorousFlowVanGenuchten::LowCapillaryPressureExtension low_ext_none(PorousFlowVanGenuchten::LowCapillaryPressureExtension::NONE, low_ext_S, low_ext_Pc, low_ext_dPc)
const Real low_ext_S
const Real low_ext_dPc
void derivInsert(SemiDynamicSparseNumberArray< Real, libMesh::dof_id_type, NWrapper< N > > &derivs, libMesh::dof_id_type index, Real value)
Real d2saturationHys(Real pc, Real slmin, Real sgrdel, Real alpha, Real n, const LowCapillaryPressureExtension &low_ext=LowCapillaryPressureExtension(), const HighCapillaryPressureExtension &high_ext=HighCapillaryPressureExtension())
Second derivative of Hysteretic saturation function with respect to pc.
T relativePermeabilityNW(const T &seff, Real m)
Relative permeability for a non-wetting phase as a function of effective saturation.
Real d2capillaryPressureHys(Real sl, Real slmin, Real sgrdel, Real alpha, Real n, const LowCapillaryPressureExtension &low_ext=LowCapillaryPressureExtension(), const HighCapillaryPressureExtension &high_ext=HighCapillaryPressureExtension())
Second derivative of capillaryPressureHys with respect to sl.
Real drelativePermeabilityNWHys(Real sl, Real slr, Real sgrdel, Real sgrmax, Real sldel, Real m, Real gamma, Real k_rg_max, Real y0p)
Derivative of hysteretic relative permeability for gas with respect to the liquid saturation.
Real dRelativePermeability(Real seff, Real m)
Derivative of relative permeability with respect to effective saturation.
T relativePermeability(const T &seff, Real m)
Relative permeability as a function of effective saturation.
Real saturationHys(Real pc, Real slmin, Real sgrdel, Real alpha, Real n, const LowCapillaryPressureExtension &low_ext=LowCapillaryPressureExtension(), const HighCapillaryPressureExtension &high_ext=HighCapillaryPressureExtension())
Hysteretic saturation function (Eqn(1) of Doughty2007) with extensions (page5 and Fig1 of Doughty2008...
Real relativePermeabilityNWHys(Real sl, Real slr, Real sgrdel, Real sgrmax, Real sldel, Real m, Real gamma, Real k_rg_max, Real y0p)
Hysteretic relative permeability for gas.
Real d2EffectiveSaturation(Real p, Real alpha, Real m)
Second derivative of effective saturation wrt porepressure.
Real dEffectiveSaturation(Real p, Real alpha, Real m)
Derivative of effective saturation wrt porepressure.
Real dCapillaryPressure(Real seff, Real alpha, Real m, Real pc_max)
Derivative of capillary pressure wrt effective saturation.
Real capillaryPressureHys(Real sl, Real slmin, Real sgrdel, Real alpha, Real n, const LowCapillaryPressureExtension &low_ext=LowCapillaryPressureExtension(), const HighCapillaryPressureExtension &high_ext=HighCapillaryPressureExtension())
Hysteretic capillary pressure function (Eqn(1) of Doughty2007) with extensions (page5 and Fig1 of Dou...
Real drelativePermeabilityHys(Real sl, Real slr, Real sgrdel, Real sgrmax, Real sldel, Real m, Real upper_liquid_param, Real y0, Real y0p, Real y1, Real y1p)
Derivative of Hysteretic relative permeability for liquid, with respect to liquid saturation.
Real capillaryPressure(Real seff, Real alpha, Real m, Real pc_max)
Capillary pressure as a function of effective saturation.
Real dcapillaryPressureHys(Real sl, Real slmin, Real sgrdel, Real alpha, Real n, const LowCapillaryPressureExtension &low_ext=LowCapillaryPressureExtension(), const HighCapillaryPressureExtension &high_ext=HighCapillaryPressureExtension())
Derivative of capillaryPressureHys with respect to sl.
Real d2CapillaryPressure(Real seff, Real alpha, Real m, Real pc_max)
Second derivative of capillary pressure wrt effective saturation.
Real effectiveSaturation(Real p, Real alpha, Real m)
Effective saturation as a function of porepressure.
Real relativePermeabilityHys(Real sl, Real slr, Real sgrdel, Real sgrmax, Real sldel, Real m, Real upper_liquid_param, Real y0, Real y0p, Real y1, Real y1p)
Hysteretic relative permeability for liquid.
Real d2RelativePermeabilityNW(Real seff, Real m)
Second derivative of relative permeability for a non-wetting phase with respect to effective saturati...
Real dsaturationHys(Real pc, Real slmin, Real sgrdel, Real alpha, Real n, const LowCapillaryPressureExtension &low_ext=LowCapillaryPressureExtension(), const HighCapillaryPressureExtension &high_ext=HighCapillaryPressureExtension())
Derivative of Hysteretic saturation function with respect to pc.
Real d2RelativePermeability(Real seff, Real m)
Second derivative of relative permeability with respect to effective saturation.
Real dRelativePermeabilityNW(Real seff, Real m)
Derivative of relative permeability for a non-wetting phase with respect to effective saturation.
Parameters associated with the extension of the hysteretic wetting capillary pressure function to hig...
Parameters associated with the extension of the hysteretic capillary pressure function to low saturat...