https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PorousFlowPorosityVinsomeWesterveld.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
11#include "libmesh/utility.h"
12
13#include <algorithm>
14#include <cmath>
15
17
20{
22 params.addRequiredParam<Real>(
23 "thermal_opening_coeff",
24 "Change in porosity per unit heat content of the adjacent matrix. The heat content, "
25 "I = int (T - matrix_reference_temperature) dz, has units K.m, so when porosity represents "
26 "the aperture of a lower-dimensional fracture this coefficient has units 1/K. Porosity "
27 "changes by -thermal_opening_coeff * I, so cooling (I < 0) opens the fracture when this "
28 "coefficient is positive");
30 "matrix_thermal_diffusivity",
31 "matrix_thermal_diffusivity > 0",
32 "Thermal diffusivity of the matrix adjacent to the "
33 "fracture (thermal conductivity divided by "
34 "volumetric heat capacity), m^2/s. This is the diffusivity in the "
35 "direction normal to the fracture (or the matrix is "
36 "assumed isotropic), and it is assumed constant");
38 "matrix_reference_temperature",
39 "Undisturbed temperature of the matrix adjacent to the fracture. This should usually be a "
40 "linear-lagrange variable or a constant");
41 params.addParam<Real>(
42 "vw_start_time",
43 0.0,
44 "Time at which the temperature at the fracture face first starts to change "
45 "(for instance, when injection begins). The matrix adjacent to the fracture "
46 "is at matrix_reference_temperature at this time, and the thermal-opening "
47 "term is zero before it");
49 "This Material calculates porosity (usually the aperture of a lower-dimensional fracture) "
50 "using the PorousFlowPorosityLinear relationship plus a thermal-opening term proportional to "
51 "the heat content of the adjacent matrix, which is computed using the semi-analytic method "
52 "of Vinsome and Westerveld (1980)");
53 return params;
54}
55
57 const InputParameters & parameters)
58 : PorousFlowPorosityLinear(parameters),
59 _thermal_opening_coeff(getParam<Real>("thermal_opening_coeff")),
60 _kappa(getParam<Real>("matrix_thermal_diffusivity")),
61 _T_matrix_ref(nodalOrQpValue("matrix_reference_temperature")),
62 _start_time(getParam<Real>("vw_start_time")),
63 _theta(_nodal_material ? declareProperty<Real>("PorousFlow_vw_theta_nodal")
64 : declareProperty<Real>("PorousFlow_vw_theta_qp")),
65 _theta_old(_nodal_material ? getMaterialPropertyOld<Real>("PorousFlow_vw_theta_nodal")
66 : getMaterialPropertyOld<Real>("PorousFlow_vw_theta_qp")),
67 _heat_content(_nodal_material ? declareProperty<Real>("PorousFlow_vw_heat_content_nodal")
68 : declareProperty<Real>("PorousFlow_vw_heat_content_qp")),
69 _heat_content_old(_nodal_material
70 ? getMaterialPropertyOld<Real>("PorousFlow_vw_heat_content_nodal")
71 : getMaterialPropertyOld<Real>("PorousFlow_vw_heat_content_qp"))
72{
73}
74
75void
77{
80 mooseError("PorousFlowPorosityVinsomeWesterveld: a temperature Material is required");
81}
82
83void
85{
87 // The matrix starts at its reference temperature
88 _theta[_qp] = 0.0;
89 _heat_content[_qp] = 0.0;
90}
91
92void
94{
96
97 const Real theta = (*_temperature)[_qp] - _T_matrix_ref[_qp];
98 _theta[_qp] = theta;
99
100 // dI/dT, used for the Jacobian (equal to dI/dtheta, because theta = T - T_matrix_ref)
101 Real dI_dT = 0.0;
102
103 const Real time = _t - _start_time;
104 if (time <= 0.0)
105 {
106 // Before vw_start_time the matrix is undisturbed, so any difference between the fracture-face
107 // temperature and matrix_reference_temperature at vw_start_time is treated as a step change
108 _theta[_qp] = 0.0;
109 _heat_content[_qp] = 0.0;
110 }
111 else
112 {
113 const Real a = _kappa * std::min(_dt, time);
114 // Vinsome and Westerveld (1980): the profile is
115 // (theta + p z + q z^2) exp(-z / d), with d = sqrt(kappa t) / 2.
116 // Imposing the heat-conduction equation at z = 0 and the energy balance
117 // dI/dt = kappa * (theta / d - p) over the time step gives p and I below.
118 const Real d = 0.5 * std::sqrt(_kappa * time);
119 const Real denom = 3.0 * d * d + a;
120 const Real p = (a * theta / d + _heat_content_old[_qp] -
121 Utility::pow<3>(d) * (theta - _theta_old[_qp]) / a) /
122 denom;
123 _heat_content[_qp] = _heat_content_old[_qp] + a * (theta / d - p);
124
125 const Real dp_dT = (a / d - Utility::pow<3>(d) / a) / denom;
126 dI_dT = a * (1.0 / d - dp_dT);
127 }
128
130 for (unsigned int pvar = 0; pvar < _num_var; ++pvar)
131 (*_dporosity_dvar)[_qp][pvar] -=
132 _thermal_opening_coeff * dI_dT * (*_dtemperature_dvar)[_qp][pvar];
133}
const Real p
void mooseError(Args &&... args)
registerMooseObject("PorousFlowApp", PorousFlowPorosityVinsomeWesterveld)
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
const unsigned int _num_var
Number of PorousFlow variables.
MaterialProperty< std::vector< Real > > *const _dporosity_dvar
d(porosity)/d(PorousFlow variable)
GenericMaterialProperty< Real, is_ad > & _porosity
Computed porosity at the nodes or quadpoints.
Material designed to provide the porosity in PorousFlow simulations porosity_ref + P_coeff * (P - P_r...
virtual void initQpStatefulProperties() override
static InputParameters validParams()
const MaterialProperty< std::vector< Real > > * _dtemperature_dvar
virtual void initialSetup() override
virtual void computeUnboundedPorosityQp()
Computes porosity and its derivatives at the current node or quadrature point, without applying the p...
const MaterialProperty< Real > * _temperature
Porosity (typically the aperture of a lower-dimensional fracture) given by the PorousFlowPorosityLine...
virtual void computeUnboundedPorosityQp() override
Computes porosity and its derivatives at the current node or quadrature point, without applying the p...
const VariableValue & _T_matrix_ref
Undisturbed (reference) matrix temperature.
const Real _kappa
Thermal diffusivity of the matrix in the direction normal to the fracture (m^2/s),...
const Real _thermal_opening_coeff
Change of porosity per unit matrix heat content (units 1/K when porosity is an aperture)
const MaterialProperty< Real > & _heat_content_old
Old value of the heat content.
const MaterialProperty< Real > & _theta_old
Old value of theta.
const Real _start_time
Time at which the matrix temperature profile is undisturbed.
MaterialProperty< Real > & _theta
Temperature change at the fracture face, theta = T - T_matrix_ref.
MaterialProperty< Real > & _heat_content
Heat content of the adjacent matrix, I = int (T - T_matrix_ref) dz.
PorousFlowPorosityVinsomeWesterveld(const InputParameters &parameters)