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 2251 : PorousFlowAqueousPreDisMineral::validParams() 16 : { 17 2251 : InputParameters params = PorousFlowMaterialVectorBase::validParams(); 18 4502 : params.addCoupledVar("initial_concentrations", 19 : "Initial concentrations for the mineral species " 20 : "(m^{3}(precipitate)/m^{3}(porous material)). Default = 0"); 21 4502 : params.addPrivateParam<std::string>("pf_material_type", "mineral"); 22 2251 : 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 2251 : return params; 26 0 : } 27 : 28 1754 : PorousFlowAqueousPreDisMineral::PorousFlowAqueousPreDisMineral(const InputParameters & parameters) 29 : : PorousFlowMaterialVectorBase(parameters), 30 3508 : _num_reactions(_dictator.numAqueousKinetic()), 31 1754 : _aq_ph(_dictator.aqueousPhaseNumber()), 32 3508 : _saturation(_nodal_material 33 1754 : ? getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_nodal") 34 3114 : : getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_qp")), 35 3508 : _sec_conc(_nodal_material 36 1754 : ? declareProperty<std::vector<Real>>("PorousFlow_mineral_concentration_nodal") 37 2434 : : declareProperty<std::vector<Real>>("PorousFlow_mineral_concentration_qp")), 38 : 39 1754 : _porosity_old(_nodal_material ? getMaterialPropertyOld<Real>("PorousFlow_porosity_nodal") 40 3114 : : getMaterialPropertyOld<Real>("PorousFlow_porosity_qp")), 41 1754 : _sec_conc_old( 42 1754 : _nodal_material 43 1754 : ? getMaterialPropertyOld<std::vector<Real>>("PorousFlow_mineral_concentration_nodal") 44 3114 : : getMaterialPropertyOld<std::vector<Real>>("PorousFlow_mineral_concentration_qp")), 45 1754 : _reaction_rate( 46 1754 : _nodal_material 47 1754 : ? getMaterialProperty<std::vector<Real>>("PorousFlow_mineral_reaction_rate_nodal") 48 3114 : : getMaterialProperty<std::vector<Real>>("PorousFlow_mineral_reaction_rate_qp")), 49 : 50 3508 : _initial_conc_supplied(isParamValid("initial_concentrations")), 51 3226 : _num_initial_conc(_initial_conc_supplied ? coupledComponents("initial_concentrations") 52 1754 : : _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 1754 : 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 1752 : _initial_conc.resize(_num_initial_conc); 67 1752 : if (_initial_conc_supplied) 68 3270 : 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 1800 : const bool is_nodal = isCoupled("initial_concentrations") 73 3600 : ? getFieldVar("initial_concentrations", r)->isNodal() 74 : : false; 75 : 76 1800 : _initial_conc[r] = 77 3600 : (_nodal_material && is_nodal ? &coupledDofValues("initial_concentrations", r) 78 2412 : : &coupledValue("initial_concentrations", r)); 79 : } 80 1752 : } 81 : 82 : void 83 22666 : PorousFlowAqueousPreDisMineral::initQpStatefulProperties() 84 : { 85 22666 : _sec_conc[_qp].assign(_num_reactions, 0.0); 86 22666 : if (_initial_conc_supplied) 87 18652 : for (unsigned r = 0; r < _num_reactions; ++r) 88 9426 : _sec_conc[_qp][r] = (*_initial_conc[r])[_qp]; 89 22666 : } 90 : 91 : void 92 951658 : PorousFlowAqueousPreDisMineral::computeQpProperties() 93 : { 94 951658 : _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 1904556 : for (unsigned r = 0; r < _num_reactions; ++r) 108 952898 : _sec_conc[_qp][r] = _sec_conc_old[_qp][r] + _porosity_old[_qp] * _reaction_rate[_qp][r] * 109 952898 : _saturation[_qp][_aq_ph] * _dt; 110 951658 : }