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 "PorousFlowMassVolumetricExpansion.h" 11 : 12 : #include "MooseVariable.h" 13 : 14 : registerMooseObject("PorousFlowApp", PorousFlowMassVolumetricExpansion); 15 : 16 : InputParameters 17 608 : PorousFlowMassVolumetricExpansion::validParams() 18 : { 19 608 : InputParameters params = TimeKernel::validParams(); 20 1216 : params.addParam<bool>("strain_at_nearest_qp", 21 1216 : false, 22 : "When calculating nodal porosity that depends on strain, use the strain at " 23 : "the nearest quadpoint. This adds a small extra computational burden, and " 24 : "is not necessary for simulations involving only linear lagrange elements. " 25 : " If you set this to true, you will also want to set the same parameter to " 26 : "true for related Kernels and Materials"); 27 1216 : params.addParam<bool>( 28 : "multiply_by_density", 29 1216 : true, 30 : "If true, then this Kernel represents component_mass*rate_of_solid_volumetric_expansion. If " 31 : "flase, then this Kernel represents component_volume*rate_of_solid_volumetric_expansion " 32 : "(care must then be taken when using other PorousFlow objects, such as the " 33 : "PorousFlowFluidMass postprocessor)."); 34 1216 : params.addParam<unsigned int>( 35 1216 : "fluid_component", 0, "The index corresponding to the component for this kernel"); 36 1216 : params.addRequiredParam<UserObjectName>( 37 : "PorousFlowDictator", "The UserObject that holds the list of PorousFlow variable names."); 38 608 : params.set<bool>("use_displaced_mesh") = false; 39 608 : params.suppressParameter<bool>("use_displaced_mesh"); 40 608 : params.addClassDescription("Component_mass*rate_of_solid_volumetric_expansion. This Kernel " 41 : "lumps the component mass to the nodes."); 42 608 : return params; 43 0 : } 44 : 45 321 : PorousFlowMassVolumetricExpansion::PorousFlowMassVolumetricExpansion( 46 321 : const InputParameters & parameters) 47 : : TimeKernel(parameters), 48 321 : _fluid_component(getParam<unsigned int>("fluid_component")), 49 321 : _dictator(getUserObject<PorousFlowDictator>("PorousFlowDictator")), 50 321 : _var_is_porflow_var(!_dictator.notPorousFlowVariable(_var.number())), 51 321 : _num_phases(_dictator.numPhases()), 52 642 : _strain_at_nearest_qp(getParam<bool>("strain_at_nearest_qp")), 53 642 : _multiply_by_density(getParam<bool>("multiply_by_density")), 54 642 : _porosity(getMaterialProperty<Real>("PorousFlow_porosity_nodal")), 55 642 : _dporosity_dvar(getMaterialProperty<std::vector<Real>>("dPorousFlow_porosity_nodal_dvar")), 56 321 : _dporosity_dgradvar( 57 321 : getMaterialProperty<std::vector<RealGradient>>("dPorousFlow_porosity_nodal_dgradvar")), 58 642 : _nearest_qp(_strain_at_nearest_qp 59 338 : ? &getMaterialProperty<unsigned int>("PorousFlow_nearestqp_nodal") 60 : : nullptr), 61 635 : _fluid_density(_multiply_by_density ? &getMaterialProperty<std::vector<Real>>( 62 : "PorousFlow_fluid_phase_density_nodal") 63 : : nullptr), 64 642 : _dfluid_density_dvar(_multiply_by_density 65 635 : ? &getMaterialProperty<std::vector<std::vector<Real>>>( 66 : "dPorousFlow_fluid_phase_density_nodal_dvar") 67 : : nullptr), 68 642 : _fluid_saturation(getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_nodal")), 69 321 : _dfluid_saturation_dvar( 70 321 : getMaterialProperty<std::vector<std::vector<Real>>>("dPorousFlow_saturation_nodal_dvar")), 71 642 : _mass_frac(getMaterialProperty<std::vector<std::vector<Real>>>("PorousFlow_mass_frac_nodal")), 72 642 : _dmass_frac_dvar(getMaterialProperty<std::vector<std::vector<std::vector<Real>>>>( 73 : "dPorousFlow_mass_frac_nodal_dvar")), 74 642 : _strain_rate_qp(getMaterialProperty<Real>("PorousFlow_volumetric_strain_rate_qp")), 75 642 : _dstrain_rate_qp_dvar(getMaterialProperty<std::vector<RealGradient>>( 76 321 : "dPorousFlow_volumetric_strain_rate_qp_dvar")) 77 : { 78 321 : if (_fluid_component >= _dictator.numComponents()) 79 0 : mooseError("The Dictator proclaims that the number of components in this simulation is ", 80 0 : _dictator.numComponents(), 81 : " whereas you have used the Kernel PorousFlowComponetMassVolumetricExpansion with " 82 : "component = ", 83 0 : _fluid_component, 84 : ". The Dictator is watching you"); 85 321 : } 86 : 87 : Real 88 46588656 : PorousFlowMassVolumetricExpansion::computeQpResidual() 89 : { 90 : Real mass = 0.0; 91 93207072 : for (unsigned ph = 0; ph < _num_phases; ++ph) 92 : { 93 46618416 : const Real dens = (_multiply_by_density ? (*_fluid_density)[_i][ph] : 1.0); 94 46618416 : mass += dens * _fluid_saturation[_i][ph] * _mass_frac[_i][ph][_fluid_component]; 95 : } 96 : 97 46588656 : return _test[_i][_qp] * mass * _porosity[_i] * _strain_rate_qp[_qp]; 98 : } 99 : 100 : Real 101 245563200 : PorousFlowMassVolumetricExpansion::computeQpJacobian() 102 : { 103 245563200 : return computedMassQpJac(_var.number()) + computedVolQpJac(_var.number()); 104 : } 105 : 106 : Real 107 223381312 : PorousFlowMassVolumetricExpansion::computeQpOffDiagJacobian(unsigned int jvar) 108 : { 109 223381312 : return computedMassQpJac(jvar) + computedVolQpJac(jvar); 110 : } 111 : 112 : Real 113 468944512 : PorousFlowMassVolumetricExpansion::computedVolQpJac(unsigned int jvar) const 114 : { 115 468944512 : if (_dictator.notPorousFlowVariable(jvar)) 116 : return 0.0; 117 : 118 468944512 : const unsigned int pvar = _dictator.porousFlowVariableNum(jvar); 119 : 120 : Real mass = 0.0; 121 938273024 : for (unsigned ph = 0; ph < _num_phases; ++ph) 122 : { 123 469328512 : const Real dens = (_multiply_by_density ? (*_fluid_density)[_i][ph] : 1.0); 124 469328512 : mass += dens * _fluid_saturation[_i][ph] * _mass_frac[_i][ph][_fluid_component]; 125 : } 126 : 127 468944512 : Real dvol = _dstrain_rate_qp_dvar[_qp][pvar] * _grad_phi[_j][_qp]; 128 : 129 468944512 : return _test[_i][_qp] * mass * _porosity[_i] * dvol; 130 : } 131 : Real 132 468944512 : PorousFlowMassVolumetricExpansion::computedMassQpJac(unsigned int jvar) const 133 : { 134 468944512 : if (_dictator.notPorousFlowVariable(jvar)) 135 : return 0.0; 136 : 137 468944512 : const unsigned int pvar = _dictator.porousFlowVariableNum(jvar); 138 468944512 : const unsigned nearest_qp = (_strain_at_nearest_qp ? (*_nearest_qp)[_i] : _i); 139 : 140 : Real dmass = 0.0; 141 938273024 : for (unsigned ph = 0; ph < _num_phases; ++ph) 142 : { 143 469328512 : const Real dens = (_multiply_by_density ? (*_fluid_density)[_i][ph] : 1.0); 144 469328512 : dmass += dens * _fluid_saturation[_i][ph] * _mass_frac[_i][ph][_fluid_component] * 145 469328512 : _dporosity_dgradvar[_i][pvar] * _grad_phi[_j][nearest_qp]; 146 : } 147 : 148 468944512 : if (_i != _j) 149 418702080 : return _test[_i][_qp] * dmass * _strain_rate_qp[_qp]; 150 : 151 100580864 : for (unsigned ph = 0; ph < _num_phases; ++ph) 152 : { 153 50338432 : if (_multiply_by_density) 154 50337408 : dmass += (*_dfluid_density_dvar)[_i][ph][pvar] * _fluid_saturation[_i][ph] * 155 50337408 : _mass_frac[_i][ph][_fluid_component] * _porosity[_i]; 156 50338432 : const Real dens = (_multiply_by_density ? (*_fluid_density)[_i][ph] : 1.0); 157 50338432 : dmass += dens * _dfluid_saturation_dvar[_i][ph][pvar] * _mass_frac[_i][ph][_fluid_component] * 158 50338432 : _porosity[_i]; 159 50338432 : dmass += dens * _fluid_saturation[_i][ph] * _dmass_frac_dvar[_i][ph][_fluid_component][pvar] * 160 : _porosity[_i]; 161 50338432 : dmass += dens * _fluid_saturation[_i][ph] * _mass_frac[_i][ph][_fluid_component] * 162 50338432 : _dporosity_dvar[_i][pvar]; 163 : } 164 : 165 50242432 : return _test[_i][_qp] * dmass * _strain_rate_qp[_qp]; 166 : }