Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://www.mooseframework.org 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 "MaterialTimeStepPostprocessor.h" 11 : #include "MooseVariable.h" 12 : #include "SubProblem.h" 13 : #include "MooseTypes.h" 14 : 15 : #include "libmesh/quadrature.h" 16 : 17 : #include <algorithm> 18 : #include <limits> 19 : 20 : registerMooseObject("TensorMechanicsApp", MaterialTimeStepPostprocessor); 21 : 22 : InputParameters 23 163 : MaterialTimeStepPostprocessor::validParams() 24 : { 25 163 : InputParameters params = ElementPostprocessor::validParams(); 26 : 27 163 : params.addClassDescription("This postprocessor estimates a timestep that reduces the increment " 28 : "change in a material property below a given threshold."); 29 : 30 326 : params.addParam<bool>("use_material_timestep_limit", 31 326 : true, 32 : "if true, the time step is limited by the minimum value of the " 33 : "material_timestep_limit property"); 34 : 35 326 : params.addParam<MaterialPropertyName>("elements_changed_property", 36 : "Name of the material property used to limit the time step " 37 : "if its value changes by more than " 38 : "'elements_changed_threshold' in at least " 39 : "'elements_changed' elements"); 40 : 41 326 : params.addRangeCheckedParam<int>("elements_changed", 42 : "elements_changed > 0", 43 : "Maximum number of elements within which the property named in " 44 : "'elements_changed_property' is allowed to change by more than " 45 : "'elements_changed_threshold' before the time step is limited."); 46 : 47 326 : params.addRangeCheckedParam<Real>("elements_changed_threshold", 48 : "elements_changed_threshold' > 0", 49 : "Maximum permitted change in the value of " 50 : "'elements_changed_property' in 'elements_changed' elements " 51 : "before the time step is limited."); 52 489 : params.addRangeCheckedParam<Real>("maximum_value", 53 326 : std::numeric_limits<Real>::max(), 54 : "maximum_value>=0", 55 : "Maximum value returned by this postprocessor."); 56 : 57 163 : return params; 58 0 : } 59 : 60 82 : MaterialTimeStepPostprocessor::MaterialTimeStepPostprocessor(const InputParameters & parameters) 61 : : ElementPostprocessor(parameters), 62 82 : _use_material_timestep_limit(getParam<bool>("use_material_timestep_limit")), 63 164 : _matl_time_step(_use_material_timestep_limit 64 159 : ? &getMaterialPropertyByName<Real>("material_timestep_limit") 65 : : nullptr), 66 164 : _matl_value(getParam<Real>("maximum_value")), 67 82 : _use_elements_changed(parameters.isParamSetByUser("elements_changed_property")), 68 164 : _changed_property(_use_elements_changed 69 89 : ? &getMaterialPropertyByName<Real>( 70 : getParam<MaterialPropertyName>("elements_changed_property")) 71 : : nullptr), 72 164 : _changed_property_old(_use_elements_changed 73 89 : ? &getMaterialPropertyOldByName<Real>( 74 : getParam<MaterialPropertyName>("elements_changed_property")) 75 : : nullptr), 76 178 : _elements_changed(isParamValid("elements_changed") ? getParam<int>("elements_changed") : 0), 77 82 : _count(0), 78 82 : _elements_changed_threshold(parameters.isParamSetByUser("elements_changed_threshold'") 79 82 : ? getParam<Real>("elements_changed_threshold'") 80 : : TOLERANCE * TOLERANCE), 81 164 : _max(getParam<Real>("maximum_value")), 82 82 : _qp(0) 83 : { 84 96 : if (_use_elements_changed && !parameters.isParamSetByUser("elements_changed")) 85 0 : paramError("elements_changed", "needs to be set when elements_changed_property is defined"); 86 : 87 82 : if (!_use_material_timestep_limit && !_use_elements_changed) 88 1 : mooseError("either use_material_timestep_limit needs to be true or elements_changed_property " 89 : "defined"); 90 81 : } 91 : 92 : void 93 1358 : MaterialTimeStepPostprocessor::initialize() 94 : { 95 1358 : _matl_value = _max; // start w/ the maximum allowed value 96 1358 : _count = 0; 97 1358 : } 98 : 99 : void 100 7454 : MaterialTimeStepPostprocessor::execute() 101 : { 102 7454 : if (_use_material_timestep_limit) 103 : { 104 63130 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 105 58785 : _matl_value = std::min(_matl_value, (*_matl_time_step)[_qp]); 106 : } 107 : 108 7454 : if (_use_elements_changed) 109 : { 110 3230 : for (_qp = 0; _qp < _qrule->n_points(); ++_qp) 111 : { 112 2894 : if (!MooseUtils::absoluteFuzzyEqual((*_changed_property)[_qp], 113 2894 : (*_changed_property_old)[_qp], 114 : _elements_changed_threshold)) 115 : { 116 184 : ++_count; 117 184 : return; 118 : } 119 : } 120 : } 121 : } 122 : 123 : Real 124 1358 : MaterialTimeStepPostprocessor::getValue() const 125 : { 126 1358 : if (_count == 0 || !_use_elements_changed) 127 1283 : return _matl_value; 128 : 129 84 : return std::min(_dt * (Real)_elements_changed / (Real)_count, _matl_value); 130 : } 131 : 132 : void 133 1358 : MaterialTimeStepPostprocessor::finalize() 134 : { 135 1358 : gatherMin(_matl_value); 136 1358 : gatherSum(_count); 137 1358 : } 138 : 139 : void 140 0 : MaterialTimeStepPostprocessor::threadJoin(const UserObject & y) 141 : { 142 : const auto & pps = static_cast<const MaterialTimeStepPostprocessor &>(y); 143 0 : if (_use_material_timestep_limit) 144 0 : _matl_value = std::min(_matl_value, pps._matl_value); 145 0 : if (_use_elements_changed) 146 0 : _count += pps._count; 147 0 : }