https://mooseframework.inl.gov
ADFluidPropsTest.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 "ADFluidPropsTest.h"
11 #include "ADReal.h"
12 #include "Moose.h"
13 
15 {
16  Real v = .7;
17  Real e = 214000;
18 
19  Real p = 0;
20  Real dpdv = 0;
21  Real dpde = 0;
22  _fp->p_from_v_e(v, e, p, dpdv, dpde);
23 
24  DNDerivativeType dvdx;
25  DNDerivativeType dedx;
26  Moose::derivInsert(dvdx, 0, 1);
27  Moose::derivInsert(dvdx, 1, 2);
28  Moose::derivInsert(dvdx, 2, 3);
29  Moose::derivInsert(dedx, 0, 1);
30  Moose::derivInsert(dedx, 1, 0);
31  Moose::derivInsert(dedx, 2, 2);
32 
33  ADReal v_ad(v, dvdx);
34  ADReal e_ad(e, dedx);
35  auto p_ad = _fp->p_from_v_e(v_ad, e_ad);
36 
37  EXPECT_DOUBLE_EQ(p, p_ad.value());
38  for (size_t i = 0; i < 3; i++)
39  EXPECT_DOUBLE_EQ(dpdv * dvdx[i] + dpde * dedx[i], p_ad.derivatives()[i]);
40 }
41 
42 TEST_F(ADFluidPropsTest, ad_two_phase)
43 {
44  const Real p = 1e5;
45  const Real T = 300;
46 
47  DNDerivativeType dpdU;
48  Moose::derivInsert(dpdU, 0, 1);
49  Moose::derivInsert(dpdU, 1, 2);
50  Moose::derivInsert(dpdU, 2, 3);
51 
52  DNDerivativeType dTdU;
53  Moose::derivInsert(dTdU, 0, 1);
54  Moose::derivInsert(dTdU, 1, 0);
55  Moose::derivInsert(dTdU, 2, 2);
56 
57  const ADReal p_ad(p, dpdU);
58  const ADReal T_ad(T, dTdU);
59 
60  const auto & fp_2phase = buildTwoPhaseFluidProperties();
61  const auto & fp_liquid = _fe_problem->getUserObject<SinglePhaseFluidProperties>(fp_2phase.getLiquidName());
62  const auto & fp_vapor = _fe_problem->getUserObject<SinglePhaseFluidProperties>(fp_2phase.getVaporName());
63 
64  // Latent heat
65 
66  const Real h_lat = fp_2phase.h_lat(p, T);
67 
68  Real h_liquid = 0;
69  Real dh_liquid_dp = 0;
70  Real dh_liquid_dT = 0;
71  fp_liquid.h_from_p_T(p, T, h_liquid, dh_liquid_dp, dh_liquid_dT);
72 
73  Real h_vapor = 0;
74  Real dh_vapor_dp = 0;
75  Real dh_vapor_dT = 0;
76  fp_vapor.h_from_p_T(p, T, h_vapor, dh_vapor_dp, dh_vapor_dT);
77 
78  const Real dh_lat_dp = dh_vapor_dp - dh_liquid_dp;
79  const Real dh_lat_dT = dh_vapor_dT - dh_liquid_dT;
80 
81  const ADReal h_lat_ad = fp_2phase.h_lat(p_ad, T_ad);
82 
83  EXPECT_DOUBLE_EQ(h_lat, h_lat_ad.value());
84  for (size_t i = 0; i < 3; i++)
85  EXPECT_DOUBLE_EQ(dh_lat_dp * dpdU[i] + dh_lat_dT * dTdU[i], h_lat_ad.derivatives()[i]);
86 
87  // Surface tension
88 
89  const Real sigma = fp_2phase.sigma_from_T(T);
90  const Real dsigma_dT = fp_2phase.dsigma_dT_from_T(T);
91  const ADReal sigma_ad = fp_2phase.sigma_from_T(T_ad);
92 
93  EXPECT_DOUBLE_EQ(sigma, sigma_ad.value());
94  for (size_t i = 0; i < 3; i++)
95  EXPECT_DOUBLE_EQ(dsigma_dT * dTdU[i], sigma_ad.derivatives()[i]);
96 
97  // Saturation temperature
98 
99  const Real T_sat = fp_2phase.T_sat(p);
100  const Real dT_sat_dp = fp_2phase.dT_sat_dp(p);
101  const ADReal T_sat_ad = fp_2phase.T_sat(p_ad);
102 
103  EXPECT_DOUBLE_EQ(T_sat, T_sat_ad.value());
104  for (size_t i = 0; i < 3; i++)
105  EXPECT_DOUBLE_EQ(dT_sat_dp * dpdU[i], T_sat_ad.derivatives()[i]);
106 
107  // Saturation pressure
108 
109  const Real p_sat = fp_2phase.p_sat(T);
110  const Real dp_sat_dT = 1.0 / fp_2phase.dT_sat_dp(p_sat);
111  const ADReal p_sat_ad = fp_2phase.p_sat(T_ad);
112 
113  EXPECT_DOUBLE_EQ(p_sat, p_sat_ad.value());
114  for (size_t i = 0; i < 3; i++)
115  EXPECT_DOUBLE_EQ(dp_sat_dT * dTdU[i], p_sat_ad.derivatives()[i]);
116 }
117 
118 TEST_F(ADFluidPropsTest, error_imperfect_jacobian)
119 {
120  ADReal v = .7;
121  ADReal e = 214000;
122 
123  // This throws because g_from_v_e has no derivatives version implemented:
124  EXPECT_THROW(_fp->g_from_v_e(v, e), std::runtime_error);
125 
126  // create fp with allow_imperfect_jacobians on - but warnings are errors still
127  auto & fp = buildObj("fp2", true);
128  EXPECT_THROW(fp.g_from_v_e(v, e), std::runtime_error);
129 
130  // missing derivs become warnings instead of errors
131  bool wae = Moose::_warnings_are_errors;
132  bool toe = Moose::_throw_on_error;
134  Moose::_throw_on_error = false;
135  EXPECT_NO_THROW(fp.g_from_v_e(v, e));
138 }
SemiDynamicSparseNumberArray< Real, libMesh::dof_id_type, NWrapper< MOOSE_AD_MAX_DOFS_PER_ELEM > > DNDerivativeType
bool _warnings_are_errors
TEST_F(ADFluidPropsTest, ad_basic)
DualNumber< Real, DNDerivativeType, true > ADReal
Common class for single phase fluid properties.
const T & getUserObject(const std::string &param_name, bool is_dependency=true) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string v
Definition: NS.h:84
void derivInsert(SemiDynamicSparseNumberArray< Real, libMesh::dof_id_type, NWrapper< N >> &derivs, libMesh::dof_id_type index, Real value)
bool _throw_on_error