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 "CavityPressureUserObject.h" 11 : 12 : using namespace libMesh; 13 : 14 : registerMooseObject("SolidMechanicsApp", CavityPressureUserObject); 15 : 16 : InputParameters 17 0 : CavityPressureUserObject::validParams() 18 : { 19 0 : InputParameters params = GeneralUserObject::validParams(); 20 0 : params.addClassDescription("Uses the ideal gas law to compute internal pressure " 21 : "and an initial moles of gas quantity."); 22 0 : params.addRangeCheckedParam<Real>( 23 : "initial_pressure", 24 0 : 0.0, 25 : "initial_pressure >= 0.0", 26 : "The initial pressure in the cavity. If not given, a zero initial pressure will be used."); 27 0 : params.addParam<std::vector<PostprocessorName>>("material_input", 28 : "The name of the postprocessor(s) that holds the " 29 : "amount of material injected into the cavity."); 30 0 : params.addRequiredRangeCheckedParam<Real>( 31 : "R", "R > 0.0", "The universal gas constant for the units used."); 32 0 : params.addRequiredParam<PostprocessorName>( 33 : "temperature", "The name of the average temperature postprocessor value."); 34 0 : params.addRangeCheckedParam<Real>( 35 : "initial_temperature", "initial_temperature > 0.0", "Initial temperature (optional)"); 36 0 : params.addRequiredParam<std::vector<PostprocessorName>>( 37 : "volume", 38 : "The name of the postprocessor(s) that holds the value of the internal volume in the cavity"); 39 : 40 0 : params.addParam<std::vector<PostprocessorName>>( 41 : "additional_volumes", 42 : "The name of the postprocessor(s) that hold additional volumes that are connected to the " 43 : "cavity but not meshed."); 44 0 : params.addParam<std::vector<PostprocessorName>>( 45 : "temperature_of_additional_volumes", 46 : "The name of the postprocessor(s) that hold the temperatures of the additional volumes."); 47 0 : params.addParam<Real>( 48 : "startup_time", 49 0 : 0.0, 50 : "The amount of time during which the pressure will ramp from zero to its true value."); 51 0 : params.set<bool>("use_displaced_mesh") = true; 52 : 53 0 : return params; 54 0 : } 55 : 56 0 : CavityPressureUserObject::CavityPressureUserObject(const InputParameters & params) 57 : : GeneralUserObject(params), 58 0 : _cavity_pressure(declareRestartableData<Real>("cavity_pressure", 0.0)), 59 0 : _n0(declareRestartableData<Real>("initial_moles", 0.0)), 60 0 : _initial_pressure(getParam<Real>("initial_pressure")), 61 0 : _material_input(params.get<std::vector<PostprocessorName>>("material_input").size()), 62 0 : _volume(params.get<std::vector<PostprocessorName>>("volume").size()), 63 0 : _R(getParam<Real>("R")), 64 0 : _temperature(getPostprocessorValue("temperature")), 65 0 : _init_temp_given(isParamValid("initial_temperature")), 66 0 : _init_temp(_init_temp_given ? getParam<Real>("initial_temperature") : 0.0), 67 0 : _startup_time(getParam<Real>("startup_time")), 68 0 : _initialized(declareRestartableData<bool>("initialized", false)), 69 0 : _additional_volumes( 70 0 : isParamValid("additional_volumes") 71 0 : ? params.get<std::vector<PostprocessorName>>("additional_volumes").size() 72 : : zero), 73 0 : _temperature_of_additional_volumes( 74 0 : isParamValid("temperature_of_additional_volumes") 75 0 : ? params.get<std::vector<PostprocessorName>>("temperature_of_additional_volumes").size() 76 : : zero), 77 0 : _start_time(0.0) 78 : { 79 0 : auto material_names = params.get<std::vector<PostprocessorName>>("material_input"); 80 0 : for (unsigned int i = 0; i < _material_input.size(); ++i) 81 0 : _material_input[i] = &getPostprocessorValueByName(material_names[i]); 82 : 83 0 : auto volume_names = params.get<std::vector<PostprocessorName>>("volume"); 84 0 : for (unsigned int i = 0; i < volume_names.size(); ++i) 85 0 : _volume[i] = &getPostprocessorValueByName(volume_names[i]); 86 : 87 0 : if (isParamValid("additional_volumes") != isParamValid("temperature_of_additional_volumes")) 88 0 : mooseError("Both additional volumes and their corresponding temperatures must be specified"); 89 : 90 0 : if (_additional_volumes.size() != _temperature_of_additional_volumes.size()) 91 0 : mooseError( 92 : "The number of additional volumes and temperatures of additional volumes musts be equal."); 93 : 94 0 : auto additional_volume_names = params.get<std::vector<PostprocessorName>>("additional_volumes"); 95 0 : for (unsigned int i = 0; i < _additional_volumes.size(); ++i) 96 0 : _additional_volumes[i] = &getPostprocessorValueByName(additional_volume_names[i]); 97 : 98 : auto temperature_of_additional_volume_names = 99 0 : params.get<std::vector<PostprocessorName>>("temperature_of_additional_volumes"); 100 0 : for (unsigned int i = 0; i < _temperature_of_additional_volumes.size(); ++i) 101 0 : _temperature_of_additional_volumes[i] = 102 0 : &getPostprocessorValueByName(temperature_of_additional_volume_names[i]); 103 0 : } 104 : 105 : Real 106 0 : CavityPressureUserObject::getValue(const MooseEnum & quantity) const 107 : { 108 : Real value = 0; 109 0 : if (quantity == INITIAL_MOLES) 110 : { 111 0 : if (_n0 < 0.0) 112 0 : mooseError("In ", 113 0 : _name, 114 : ": Negative number of moles calculated as an input for the cavity pressure"); 115 : 116 : value = _n0; 117 : } 118 0 : else if (quantity == CAVITY_PRESSURE) 119 0 : value = _cavity_pressure; 120 : else 121 0 : mooseError("In ", _name, ": Unknown quantity."); 122 : 123 0 : return value; 124 : } 125 : 126 : void 127 0 : CavityPressureUserObject::initialize() 128 : { 129 0 : const Real cavity_volume = computeCavityVolume(); 130 : 131 0 : if (!_initialized) 132 : { 133 0 : Real init_temp = _temperature; 134 0 : if (_init_temp_given) 135 0 : init_temp = _init_temp; 136 : 137 0 : if (MooseUtils::absoluteFuzzyLessEqual(init_temp, 0.0)) 138 0 : mooseError("Cannot have initial temperature of zero when initializing cavity pressure. " 139 : "Does the supplied Postprocessor for temperature execute at initial?"); 140 : 141 0 : Real volume_temp_ratio = cavity_volume / init_temp; 142 : 143 0 : for (unsigned int i = 0; i < _additional_volumes.size(); ++i) 144 0 : volume_temp_ratio += *_additional_volumes[i] / *_temperature_of_additional_volumes[i]; 145 : 146 0 : _n0 = _initial_pressure * volume_temp_ratio / _R; 147 : 148 0 : _start_time = _t - _dt; 149 : const Real factor = 150 0 : _t >= _start_time + _startup_time ? 1.0 : (_t - _start_time) / _startup_time; 151 0 : _cavity_pressure = factor * _initial_pressure; 152 0 : _initialized = true; 153 : } 154 0 : } 155 : 156 : void 157 0 : CavityPressureUserObject::execute() 158 : { 159 0 : const Real cavity_volume = computeCavityVolume(); 160 : 161 : Real mat = 0; 162 : 163 0 : for (unsigned int i = 0; i < _material_input.size(); ++i) 164 0 : mat += *_material_input[i]; 165 : 166 0 : Real volume_temp_ratio = cavity_volume / _temperature; 167 : 168 0 : for (unsigned int i = 0; i < _additional_volumes.size(); ++i) 169 0 : volume_temp_ratio += *_additional_volumes[i] / *_temperature_of_additional_volumes[i]; 170 : 171 0 : const Real pressure = (_n0 + mat) * _R / volume_temp_ratio; 172 0 : const Real factor = _t >= _start_time + _startup_time ? 1.0 : (_t - _start_time) / _startup_time; 173 0 : _cavity_pressure = factor * pressure; 174 0 : } 175 : 176 : Real 177 0 : CavityPressureUserObject::computeCavityVolume() 178 : { 179 : Real volume = 0; 180 0 : for (unsigned int i = 0; i < _volume.size(); ++i) 181 0 : volume += *_volume[i]; 182 : 183 0 : return volume; 184 : }