https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PressureJumpInterfaceTest.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
9#include "gtest/gtest.h"
10
12
13#include <cmath>
14#include <limits>
15
16TEST(PressureJumpInterface, OrthogonalIsotropic)
17{
18 const RealVectorValue normal(1.0, 0.0, 0.0);
19 const Point half_cell(0.5, 0.0, 0.0);
20 const RealVectorValue diffusion(2.0, 2.0, 2.0);
21 const RealVectorValue gradient(3.0, -4.0, 0.0);
22
23 const auto data = NS::FV::pressureJumpInterfaceData(normal,
24 half_cell,
25 half_cell,
26 diffusion,
27 diffusion,
28 gradient,
29 gradient,
30 {},
31 {},
32 3.0,
33 true,
34 0.0);
35
36 ASSERT_TRUE(data.valid);
37 EXPECT_TRUE(data.is_baffle);
38 EXPECT_DOUBLE_EQ(data.elem_conductance, 12.0);
39 EXPECT_DOUBLE_EQ(data.neighbor_conductance, 12.0);
40 EXPECT_DOUBLE_EQ(data.transmissibility, 6.0);
41 EXPECT_DOUBLE_EQ(data.elem_correction, 0.0);
42 EXPECT_DOUBLE_EQ(data.neighbor_correction, 0.0);
43 EXPECT_DOUBLE_EQ(data.correction, 0.0);
44}
45
46TEST(PressureJumpInterface, ConservesFluxAndPreservesJump)
47{
48 const RealVectorValue normal(0.8, 0.6, 0.0);
49 const Point elem_to_face(0.5, 0.1, 0.0);
50 const Point face_to_neighbor(0.35, 0.3, 0.0);
51 const RealVectorValue elem_diffusion(2.0, 5.0, 1.0);
52 const RealVectorValue neighbor_diffusion(7.0, 3.0, 1.0);
53 const RealVectorValue elem_gradient(1.2, -0.4, 0.0);
54 const RealVectorValue neighbor_gradient(-0.3, 2.1, 0.0);
55 const Real elem_pressure = 11.0;
56 const Real neighbor_pressure = 4.0;
57 const Real jump = 2.5;
58
59 const auto data = NS::FV::pressureJumpInterfaceData(normal,
60 elem_to_face,
61 face_to_neighbor,
62 elem_diffusion,
63 neighbor_diffusion,
64 elem_gradient,
65 neighbor_gradient,
66 RealVectorValue(),
67 RealVectorValue(),
68 1.7,
69 true,
70 jump);
71 ASSERT_TRUE(data.valid);
72 EXPECT_DOUBLE_EQ(data.elem_jump, jump);
73
74 const Real flux = NS::FV::pressureJumpFlux(data, elem_pressure, neighbor_pressure);
75 const Real assembled_flux = data.transmissibility * elem_pressure -
76 data.transmissibility * neighbor_pressure -
77 (data.correction + data.transmissibility * data.elem_jump);
78 const Real elem_face_pressure =
79 elem_pressure - (flux + data.elem_correction) / data.elem_conductance;
80 const Real neighbor_face_pressure =
81 neighbor_pressure + (flux + data.neighbor_correction) / data.neighbor_conductance;
82 const Real elem_half_flux =
83 data.elem_conductance * (elem_pressure - elem_face_pressure) - data.elem_correction;
84 const Real neighbor_half_flux =
85 data.neighbor_conductance * (neighbor_face_pressure - neighbor_pressure) -
86 data.neighbor_correction;
87 const Real recovered_elem_face_pressure =
88 NS::FV::pressureJumpOneSidedFaceValue(data, elem_pressure, flux, /*elem_side=*/true);
89 const Real recovered_neighbor_face_pressure =
90 NS::FV::pressureJumpOneSidedFaceValue(data, neighbor_pressure, flux, /*elem_side=*/false);
91
92 EXPECT_NEAR(elem_face_pressure - neighbor_face_pressure, jump, 1e-13);
93 EXPECT_NEAR(assembled_flux, flux, 1e-13);
94 EXPECT_NEAR(elem_half_flux, flux, 1e-13);
95 EXPECT_NEAR(neighbor_half_flux, flux, 1e-13);
96 EXPECT_NEAR(recovered_elem_face_pressure, elem_face_pressure, 1e-13);
97 EXPECT_NEAR(recovered_neighbor_face_pressure, neighbor_face_pressure, 1e-13);
98}
99
100TEST(PressureJumpInterface, ManufacturedPiecewiseLinearPressure)
101{
102 const RealVectorValue normal(0.8, 0.6, 0.0);
103 const Point elem_to_face(0.5, 0.1, 0.0);
104 const Point face_to_neighbor(0.35, 0.3, 0.0);
105 const RealVectorValue elem_diffusion(2.0, 5.0, 1.0);
106 const RealVectorValue neighbor_diffusion(7.0, 3.0, 1.0);
107 const RealVectorValue elem_gradient(1.2, -0.4, 0.0);
108 const RealVectorValue neighbor_gradient(-0.3, 4.0 / 3.0, 0.0);
109 const Real face_area = 1.7;
110 const Real elem_face_pressure = 11.0;
111 const Real jump = 2.5;
112 const Real neighbor_face_pressure = elem_face_pressure - jump;
113 const Real elem_pressure = elem_face_pressure - elem_gradient * elem_to_face;
114 const Real neighbor_pressure = neighbor_face_pressure + neighbor_gradient * face_to_neighbor;
115 const Real expected_flux = -face_area * normal *
116 RealVectorValue(elem_diffusion(0) * elem_gradient(0),
117 elem_diffusion(1) * elem_gradient(1),
118 elem_diffusion(2) * elem_gradient(2));
119
120 const auto data = NS::FV::pressureJumpInterfaceData(normal,
121 elem_to_face,
122 face_to_neighbor,
123 elem_diffusion,
124 neighbor_diffusion,
125 elem_gradient,
126 neighbor_gradient,
127 RealVectorValue(),
128 RealVectorValue(),
129 face_area,
130 true,
131 jump);
132 ASSERT_TRUE(data.valid);
133
134 const Real flux = NS::FV::pressureJumpFlux(data, elem_pressure, neighbor_pressure);
135 const Real recovered_elem_face_pressure =
136 NS::FV::pressureJumpOneSidedFaceValue(data, elem_pressure, flux, /*elem_side=*/true);
137 const Real recovered_neighbor_face_pressure =
138 NS::FV::pressureJumpOneSidedFaceValue(data, neighbor_pressure, flux, /*elem_side=*/false);
139
140 EXPECT_NEAR(flux, expected_flux, 1e-13);
141 EXPECT_NEAR(recovered_elem_face_pressure, elem_face_pressure, 1e-13);
142 EXPECT_NEAR(recovered_neighbor_face_pressure, neighbor_face_pressure, 1e-13);
143}
144
145TEST(PressureJumpInterface, HydrostaticBalanceAcrossJump)
146{
147 // At rest each side balances its body force with its own pressure gradient,
148 // rho_s (H/A)_s = -(rho_s / A_s) grad(p)_s. With jumps in the diffusion coefficients and the
149 // gradients, the one-sided H/A fluxes h_s differ. Each side's own flux is still zero, so the
150 // face mass flux must vanish and the recovered face pressures must be the one-sided linear
151 // extrapolations.
152 const RealVectorValue normal(0.8, 0.6, 0.0);
153 const Point elem_to_face(0.5, 0.1, 0.0);
154 const Point face_to_neighbor(0.35, 0.3, 0.0);
155 const RealVectorValue elem_diffusion(2.0, 5.0, 1.0);
156 const RealVectorValue neighbor_diffusion(7.0, 3.0, 1.0);
157 const RealVectorValue elem_gradient(1.2, -0.4, 0.0);
158 const RealVectorValue neighbor_gradient(-0.3, 2.1, 0.0);
159 const Real face_area = 1.7;
160 const Real elem_face_pressure = 11.0;
161 const Real jump = 2.5;
162 const Real neighbor_face_pressure = elem_face_pressure - jump;
163 const Real elem_pressure = elem_face_pressure - elem_gradient * elem_to_face;
164 const Real neighbor_pressure = neighbor_face_pressure + neighbor_gradient * face_to_neighbor;
165
166 RealVectorValue elem_rho_hbya;
167 RealVectorValue neighbor_rho_hbya;
168 for (const auto i : make_range(Moose::dim))
169 {
170 elem_rho_hbya(i) = -elem_diffusion(i) * elem_gradient(i);
171 neighbor_rho_hbya(i) = -neighbor_diffusion(i) * neighbor_gradient(i);
172 }
173
174 const auto data = NS::FV::pressureJumpInterfaceData(normal,
175 elem_to_face,
176 face_to_neighbor,
177 elem_diffusion,
178 neighbor_diffusion,
179 elem_gradient,
180 neighbor_gradient,
181 elem_rho_hbya,
182 neighbor_rho_hbya,
183 face_area,
184 true,
185 jump);
186 ASSERT_TRUE(data.valid);
187 // The test is meaningful only if the side H/A fluxes differ; with equal fluxes any weighting of
188 // them gives the same face value.
189 ASSERT_GT(std::abs(data.elem_hbya_flux - data.neighbor_hbya_flux), 1.0);
190
191 const Real mass_flux = NS::FV::pressureJumpFlux(data, elem_pressure, neighbor_pressure) -
193
194 EXPECT_NEAR(mass_flux, 0.0, 1e-13);
195 EXPECT_NEAR(
196 NS::FV::pressureJumpOneSidedFaceValue(data, elem_pressure, mass_flux, /*elem_side=*/true),
197 elem_face_pressure,
198 1e-13);
200 data, neighbor_pressure, mass_flux, /*elem_side=*/false),
201 neighbor_face_pressure,
202 1e-13);
203}
204
205TEST(PressureJumpInterface, OrientationReversal)
206{
207 const RealVectorValue normal(0.8, 0.6, 0.0);
208 const Point elem_to_face(0.5, 0.1, 0.0);
209 const Point face_to_neighbor(0.35, 0.3, 0.0);
210 const RealVectorValue elem_diffusion(2.0, 5.0, 1.0);
211 const RealVectorValue neighbor_diffusion(7.0, 3.0, 1.0);
212 const RealVectorValue elem_gradient(1.2, -0.4, 0.0);
213 const RealVectorValue neighbor_gradient(-0.3, 2.1, 0.0);
214
215 const auto forward = NS::FV::pressureJumpInterfaceData(normal,
216 elem_to_face,
217 face_to_neighbor,
218 elem_diffusion,
219 neighbor_diffusion,
220 elem_gradient,
221 neighbor_gradient,
222 RealVectorValue(),
223 RealVectorValue(),
224 1.7,
225 true,
226 2.5);
227 const auto reverse = NS::FV::pressureJumpInterfaceData(-normal,
228 -face_to_neighbor,
229 -elem_to_face,
230 neighbor_diffusion,
231 elem_diffusion,
232 neighbor_gradient,
233 elem_gradient,
234 RealVectorValue(),
235 RealVectorValue(),
236 1.7,
237 true,
238 -2.5);
239 ASSERT_TRUE(forward.valid);
240 ASSERT_TRUE(reverse.valid);
241
242 const Real forward_flux = NS::FV::pressureJumpFlux(forward, 11.0, 4.0);
243 const Real reverse_flux = NS::FV::pressureJumpFlux(reverse, 4.0, 11.0);
244
245 EXPECT_NEAR(reverse.elem_conductance, forward.neighbor_conductance, 1e-13);
246 EXPECT_NEAR(reverse.neighbor_conductance, forward.elem_conductance, 1e-13);
247 EXPECT_NEAR(reverse.correction, -forward.correction, 1e-13);
248 EXPECT_NEAR(reverse_flux, -forward_flux, 1e-13);
249}
250
251TEST(PressureJumpInterface, RejectsInvalidGeometryAndCoefficients)
252{
253 const auto build_operator =
254 [](const Point & elem_to_face, const RealVectorValue & elem_diffusion, const Real face_area)
255 {
256 return NS::FV::pressureJumpInterfaceData(RealVectorValue(1.0, 0.0, 0.0),
257 elem_to_face,
258 Point(0.5, 0.0, 0.0),
259 elem_diffusion,
260 RealVectorValue(1.0, 1.0, 1.0),
261 RealVectorValue(),
262 RealVectorValue(),
263 RealVectorValue(),
264 RealVectorValue(),
265 face_area,
266 true,
267 0.0);
268 };
269
270 EXPECT_FALSE(build_operator(Point(0.0, 1.0, 0.0), RealVectorValue(1.0, 1.0, 1.0), 1.0).valid);
271 EXPECT_FALSE(build_operator(Point(0.5, 0.0, 0.0), RealVectorValue(0.0, 1.0, 1.0), 1.0).valid);
272 EXPECT_FALSE(build_operator(Point(0.5, 0.0, 0.0),
273 RealVectorValue(std::numeric_limits<Real>::infinity(), 1.0, 1.0),
274 1.0)
275 .valid);
276 EXPECT_FALSE(build_operator(Point(0.5, 0.0, 0.0), RealVectorValue(1.0, 1.0, 1.0), 0.0).valid);
277}
TEST(PressureJumpInterface, OrthogonalIsotropic)
static constexpr std::size_t dim
PressureJumpInterfaceData pressureJumpInterfaceData(const RealVectorValue &normal, const Point &elem_to_face, const Point &face_to_neighbor, const RealVectorValue &elem_diffusion, const RealVectorValue &neighbor_diffusion, const RealVectorValue &elem_gradient, const RealVectorValue &neighbor_gradient, const RealVectorValue &elem_rho_hbya, const RealVectorValue &neighbor_rho_hbya, const Real face_area, const bool use_nonorthogonal_correction, const Real elem_jump)
Construct the conservative half-cell interface coefficients for a diagonal diffusion tensor.
Real pressureJumpOneSidedFaceValue(const PressureJumpInterfaceData &data, const Real cell_pressure, const Real mass_flux, const bool elem_side)
Recover one side's face pressure from the common oriented face mass flux.
Real pressureJumpHbyAFlux(const PressureJumpInterfaceData &data)
Compute the H/A part of the face mass flux after eliminating the interface pressures.
Real pressureJumpFlux(const PressureJumpInterfaceData &data, const Real elem_pressure, const Real neighbor_pressure)
Compute the pressure part of the element-to-neighbor flux after eliminating the interface pressures.