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 "PorousFlowAqueousPreDisMineral.h" 11 : 12 : registerMooseObject("PorousFlowApp", PorousFlowAqueousPreDisMineral); 13 : 14 : InputParameters 15 1181 : PorousFlowAqueousPreDisMineral::validParams() 16 : { 17 1181 : InputParameters params = PorousFlowMaterialVectorBase::validParams(); 18 2362 : params.addCoupledVar("initial_concentrations", 19 : "Initial concentrations for the mineral species " 20 : "(m^{3}(precipitate)/m^{3}(porous material)). Default = 0"); 21 2362 : params.addPrivateParam<std::string>("pf_material_type", "mineral"); 22 1181 : params.addClassDescription("This Material forms a std::vector of mineral concentrations " 23 : "(volume-of-mineral/volume-of-material) appropriate to the aqueous " 24 : "precipitation-dissolution system provided."); 25 1181 : return params; 26 0 : } 27 : 28 902 : PorousFlowAqueousPreDisMineral::PorousFlowAqueousPreDisMineral(const InputParameters & parameters) 29 : : PorousFlowMaterialVectorBase(parameters), 30 1804 : _num_reactions(_dictator.numAqueousKinetic()), 31 902 : _aq_ph(_dictator.aqueousPhaseNumber()), 32 1804 : _saturation(_nodal_material 33 902 : ? getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_nodal") 34 1542 : : getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_qp")), 35 1804 : _sec_conc(_nodal_material 36 902 : ? declareProperty<std::vector<Real>>("PorousFlow_mineral_concentration_nodal") 37 1222 : : declareProperty<std::vector<Real>>("PorousFlow_mineral_concentration_qp")), 38 : 39 902 : _porosity_old(_nodal_material ? getMaterialPropertyOld<Real>("PorousFlow_porosity_nodal") 40 1542 : : getMaterialPropertyOld<Real>("PorousFlow_porosity_qp")), 41 902 : _sec_conc_old( 42 902 : _nodal_material 43 902 : ? getMaterialPropertyOld<std::vector<Real>>("PorousFlow_mineral_concentration_nodal") 44 1542 : : getMaterialPropertyOld<std::vector<Real>>("PorousFlow_mineral_concentration_qp")), 45 902 : _reaction_rate( 46 902 : _nodal_material 47 902 : ? getMaterialProperty<std::vector<Real>>("PorousFlow_mineral_reaction_rate_nodal") 48 1542 : : getMaterialProperty<std::vector<Real>>("PorousFlow_mineral_reaction_rate_qp")), 49 : 50 1804 : _initial_conc_supplied(isParamValid("initial_concentrations")), 51 1666 : _num_initial_conc(_initial_conc_supplied ? coupledComponents("initial_concentrations") 52 902 : : _num_reactions) 53 : { 54 : /* Not needed due to PorousFlow_mineral_reaction_rate already checking this condition 55 : if (_dictator.numPhases() < 1) 56 : mooseError("PorousFlowAqueousPreDisMineral: The number of fluid phases must not be zero"); 57 : */ 58 : 59 902 : if (_num_initial_conc != _dictator.numAqueousKinetic()) 60 4 : mooseError("PorousFlowAqueousPreDisMineral: The number of initial concentrations is ", 61 2 : _num_initial_conc, 62 : " but the Dictator knows that the number of aqueous kinetic " 63 : "(precipitation-dissolution) reactions is ", 64 2 : _dictator.numAqueousKinetic()); 65 : 66 900 : _initial_conc.resize(_num_initial_conc); 67 900 : if (_initial_conc_supplied) 68 1734 : for (unsigned r = 0; r < _num_reactions; ++r) 69 : { 70 : // If initial_concentrations are elemental AuxVariables (or constants), we want to use 71 : // coupledGenericValue() rather than coupledGenericDofValue() 72 972 : const bool is_nodal = isCoupled("initial_concentrations") 73 1944 : ? getFieldVar("initial_concentrations", r)->isNodal() 74 : : false; 75 : 76 972 : _initial_conc[r] = 77 1944 : (_nodal_material && is_nodal ? &coupledDofValues("initial_concentrations", r) 78 1260 : : &coupledValue("initial_concentrations", r)); 79 : } 80 900 : } 81 : 82 : void 83 14082 : PorousFlowAqueousPreDisMineral::initQpStatefulProperties() 84 : { 85 14082 : _sec_conc[_qp].assign(_num_reactions, 0.0); 86 14082 : if (_initial_conc_supplied) 87 11684 : for (unsigned r = 0; r < _num_reactions; ++r) 88 5922 : _sec_conc[_qp][r] = (*_initial_conc[r])[_qp]; 89 14082 : } 90 : 91 : void 92 638622 : PorousFlowAqueousPreDisMineral::computeQpProperties() 93 : { 94 638622 : _sec_conc[_qp].resize(_num_reactions); 95 : 96 : /* 97 : * 98 : * Note the use of the OLD value of porosity here. 99 : * This strategy, which breaks the cyclic dependency between porosity 100 : * and mineral concentration, is used in 101 : * Kernel: PorousFlowPreDis 102 : * Material: PorousFlowPorosity 103 : * Material: PorousFlowAqueousPreDisChemistry 104 : * Material: PorousFlowAqueousPreDisMineral 105 : * 106 : */ 107 1278236 : for (unsigned r = 0; r < _num_reactions; ++r) 108 639614 : _sec_conc[_qp][r] = _sec_conc_old[_qp][r] + _porosity_old[_qp] * _reaction_rate[_qp][r] * 109 639614 : _saturation[_qp][_aq_ph] * _dt; 110 638622 : }