LCOV - code coverage report
Current view: top level - src/materials - PorousFlow2PhaseHysPP.C (source / functions) Hit Total Coverage
Test: idaholab/moose porous_flow: #32971 (54bef8) with base c6cf66 Lines: 78 79 98.7 %
Date: 2026-05-29 20:38:56 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "PorousFlow2PhaseHysPP.h"
      11             : 
      12             : registerMooseObject("PorousFlowApp", PorousFlow2PhaseHysPP);
      13             : 
      14             : InputParameters
      15         180 : PorousFlow2PhaseHysPP::validParams()
      16             : {
      17         180 :   InputParameters params = PorousFlowHystereticCapillaryPressure::validParams();
      18         360 :   params.addRequiredCoupledVar("phase0_porepressure",
      19             :                                "Variable that is the porepressure of phase 0.  This is assumed to "
      20             :                                "be the liquid phase.  It will be <= phase1_porepressure.");
      21         360 :   params.addRequiredCoupledVar("phase1_porepressure",
      22             :                                "Variable that is the porepressure of phase 1 (the gas phase)");
      23         360 :   params.addParam<unsigned>(
      24         360 :       "liquid_phase", 0, "Phase number of the liquid phase (more precisely, the phase of phase0)");
      25         180 :   params.addClassDescription(
      26             :       "This Material is used for 2-phase situations.  It calculates the 2 saturations given the 2 "
      27             :       "porepressures, assuming the capillary pressure is hysteretic.  Derivatives of these "
      28             :       "quantities are also computed");
      29         180 :   return params;
      30           0 : }
      31             : 
      32         140 : PorousFlow2PhaseHysPP::PorousFlow2PhaseHysPP(const InputParameters & parameters)
      33             :   : PorousFlowHystereticCapillaryPressure(parameters),
      34          71 :     _pc(_nodal_material ? declareProperty<Real>("PorousFlow_hysteretic_capillary_pressure_nodal")
      35         209 :                         : declareProperty<Real>("PorousFlow_hysteretic_capillary_pressure_qp")),
      36         140 :     _phase0_porepressure(_nodal_material ? coupledDofValues("phase0_porepressure")
      37         209 :                                          : coupledValue("phase0_porepressure")),
      38         140 :     _phase0_gradp_qp(coupledGradient("phase0_porepressure")),
      39         140 :     _phase0_porepressure_varnum(coupled("phase0_porepressure")),
      40         140 :     _p0var(_dictator.isPorousFlowVariable(_phase0_porepressure_varnum)
      41         140 :                ? _dictator.porousFlowVariableNum(_phase0_porepressure_varnum)
      42             :                : 0),
      43             : 
      44         140 :     _phase1_porepressure(_nodal_material ? coupledDofValues("phase1_porepressure")
      45         209 :                                          : coupledValue("phase1_porepressure")),
      46         140 :     _phase1_gradp_qp(coupledGradient("phase1_porepressure")),
      47         140 :     _phase1_porepressure_varnum(coupled("phase1_porepressure")),
      48         140 :     _p1var(_dictator.isPorousFlowVariable(_phase1_porepressure_varnum)
      49         140 :                ? _dictator.porousFlowVariableNum(_phase1_porepressure_varnum)
      50         140 :                : 0)
      51             : {
      52         140 :   if (_num_phases != 2)
      53           4 :     mooseError("The Dictator announces that the number of phases is ",
      54           2 :                _dictator.numPhases(),
      55             :                " whereas PorousFlow2PhaseHysPP can only be used for 2-phase simulation.  When you "
      56             :                "have efficient government, you have dictatorship.");
      57         138 : }
      58             : 
      59             : void
      60         120 : PorousFlow2PhaseHysPP::initQpStatefulProperties()
      61             : {
      62         120 :   PorousFlowHystereticCapillaryPressure::initQpStatefulProperties();
      63         120 :   buildQpPPSS();
      64         120 : }
      65             : 
      66             : void
      67       21540 : PorousFlow2PhaseHysPP::computeQpProperties()
      68             : {
      69             :   // size stuff correctly and prepare the derivative matrices with zeroes
      70       21540 :   PorousFlowHystereticCapillaryPressure::computeQpProperties();
      71             : 
      72       21540 :   buildQpPPSS();
      73       21540 :   const Real pc = _pc[_qp];                // >= 0
      74       21540 :   const Real ds = dliquidSaturationQp(pc); // dS/d(pc)
      75             : 
      76       21540 :   if (!_nodal_material)
      77             :   {
      78       10770 :     (*_gradp_qp)[_qp][0] = _phase0_gradp_qp[_qp];
      79       10770 :     (*_gradp_qp)[_qp][1] = _phase1_gradp_qp[_qp];
      80       10770 :     (*_grads_qp)[_qp][0] = ds * ((*_gradp_qp)[_qp][1] - (*_gradp_qp)[_qp][0]);
      81       10770 :     (*_grads_qp)[_qp][1] = -(*_grads_qp)[_qp][0];
      82             :   }
      83             : 
      84             :   // the derivatives of porepressure with respect to porepressure
      85             :   // remain fixed (at unity) throughout the simulation
      86       21540 :   if (_dictator.isPorousFlowVariable(_phase0_porepressure_varnum))
      87             :   {
      88       21540 :     (*_dporepressure_dvar)[_qp][0][_p0var] = 1.0;
      89       21540 :     if (!_nodal_material)
      90       10770 :       (*_dgradp_qp_dgradv)[_qp][0][_p0var] = 1.0;
      91             :   }
      92       21540 :   if (_dictator.isPorousFlowVariable(_phase1_porepressure_varnum))
      93             :   {
      94       21540 :     (*_dporepressure_dvar)[_qp][1][_p1var] = 1.0;
      95       21540 :     if (!_nodal_material)
      96       10770 :       (*_dgradp_qp_dgradv)[_qp][1][_p1var] = 1.0;
      97             :   }
      98             : 
      99       21540 :   if (_dictator.isPorousFlowVariable(_phase0_porepressure_varnum))
     100             :   {
     101       21540 :     (*_dsaturation_dvar)[_qp][0][_p0var] = -ds;
     102       21540 :     (*_dsaturation_dvar)[_qp][1][_p0var] = ds;
     103             :   }
     104       21540 :   if (_dictator.isPorousFlowVariable(_phase1_porepressure_varnum))
     105             :   {
     106       21540 :     (*_dsaturation_dvar)[_qp][0][_p1var] = ds;
     107       21540 :     (*_dsaturation_dvar)[_qp][1][_p1var] = -ds;
     108             :   }
     109             : 
     110       21540 :   _pc[_qp] = _phase1_porepressure[_qp] - _phase0_porepressure[_qp]; // this is >= 0
     111       21540 :   if (!_nodal_material)
     112             :   {
     113       10770 :     const Real d2s_qp = d2liquidSaturationQp(pc); // d^2(S_qp)/d(pc_qp)^2
     114       10770 :     if (_dictator.isPorousFlowVariable(_phase0_porepressure_varnum))
     115             :     {
     116       10770 :       (*_dgrads_qp_dgradv)[_qp][0][_p0var] = -ds;
     117       10770 :       (*_dgrads_qp_dv)[_qp][0][_p0var] = -d2s_qp * (_phase1_gradp_qp[_qp] - _phase0_gradp_qp[_qp]);
     118       10770 :       (*_dgrads_qp_dgradv)[_qp][1][_p0var] = ds;
     119       10770 :       (*_dgrads_qp_dv)[_qp][1][_p0var] = d2s_qp * (_phase1_gradp_qp[_qp] - _phase0_gradp_qp[_qp]);
     120             :     }
     121       10770 :     if (_dictator.isPorousFlowVariable(_phase1_porepressure_varnum))
     122             :     {
     123       10770 :       (*_dgrads_qp_dgradv)[_qp][0][_p1var] = ds;
     124       10770 :       (*_dgrads_qp_dv)[_qp][0][_p1var] = d2s_qp * (_phase1_gradp_qp[_qp] - _phase0_gradp_qp[_qp]);
     125       10770 :       (*_dgrads_qp_dgradv)[_qp][1][_p1var] = -ds;
     126       10770 :       (*_dgrads_qp_dv)[_qp][1][_p1var] = -d2s_qp * (_phase1_gradp_qp[_qp] - _phase0_gradp_qp[_qp]);
     127             :     }
     128             :   }
     129       21540 : }
     130             : 
     131             : void
     132       21660 : PorousFlow2PhaseHysPP::buildQpPPSS()
     133             : {
     134       21660 :   _porepressure[_qp][0] = _phase0_porepressure[_qp];
     135       21660 :   _porepressure[_qp][1] = _phase1_porepressure[_qp];
     136       21660 :   _pc[_qp] = _phase1_porepressure[_qp] - _phase0_porepressure[_qp]; // this is >= 0
     137       21660 :   const Real sat = liquidSaturationQp(_pc[_qp]);
     138       21660 :   _saturation[_qp][0] = sat;
     139       21660 :   _saturation[_qp][1] = 1.0 - sat;
     140       21660 : }

Generated by: LCOV version 1.14