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 "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("SolidMechanicsApp", MaterialTimeStepPostprocessor); 21 : 22 : InputParameters 23 350 : MaterialTimeStepPostprocessor::validParams() 24 : { 25 350 : InputParameters params = ElementPostprocessor::validParams(); 26 : 27 350 : params.addClassDescription("This postprocessor estimates a timestep that reduces the increment " 28 : "change in a material property below a given threshold."); 29 : 30 700 : params.addParam<bool>("use_material_timestep_limit", 31 700 : true, 32 : "if true, the time step is limited by the minimum value of the " 33 : "material_timestep_limit property"); 34 : 35 700 : 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 700 : 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 700 : 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 1050 : params.addRangeCheckedParam<Real>("maximum_value", 53 700 : std::numeric_limits<Real>::max(), 54 : "maximum_value>=0", 55 : "Maximum value returned by this postprocessor."); 56 : 57 350 : return params; 58 0 : } 59 : 60 176 : MaterialTimeStepPostprocessor::MaterialTimeStepPostprocessor(const InputParameters & parameters) 61 : : ElementPostprocessor(parameters), 62 176 : _use_material_timestep_limit(getParam<bool>("use_material_timestep_limit")), 63 352 : _matl_time_step(_use_material_timestep_limit 64 342 : ? &getMaterialPropertyByName<Real>("material_timestep_limit") 65 : : nullptr), 66 352 : _matl_value(getParam<Real>("maximum_value")), 67 176 : _use_elements_changed(parameters.isParamSetByUser("elements_changed_property")), 68 352 : _changed_property(_use_elements_changed 69 190 : ? &getMaterialPropertyByName<Real>( 70 : getParam<MaterialPropertyName>("elements_changed_property")) 71 : : nullptr), 72 352 : _changed_property_old(_use_elements_changed 73 190 : ? &getMaterialPropertyOldByName<Real>( 74 : getParam<MaterialPropertyName>("elements_changed_property")) 75 : : nullptr), 76 380 : _elements_changed(isParamValid("elements_changed") ? getParam<int>("elements_changed") : 0), 77 176 : _count(0), 78 176 : _elements_changed_threshold(parameters.isParamSetByUser("elements_changed_threshold'") 79 176 : ? getParam<Real>("elements_changed_threshold'") 80 : : TOLERANCE * TOLERANCE), 81 352 : _max(getParam<Real>("maximum_value")), 82 176 : _qp(0) 83 : { 84 204 : 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 176 : if (!_use_material_timestep_limit && !_use_elements_changed) 88 2 : mooseError("either use_material_timestep_limit needs to be true or elements_changed_property " 89 : "defined"); 90 174 : } 91 : 92 : void 93 2776 : MaterialTimeStepPostprocessor::initialize() 94 : { 95 2776 : _matl_value = _max; // start w/ the maximum allowed value 96 2776 : _count = 0; 97 2776 : } 98 : 99 : void 100 14948 : MaterialTimeStepPostprocessor::execute() 101 : { 102 14948 : if (_use_material_timestep_limit) 103 : { 104 126620 : for (_qp = 0; _qp < _qrule->n_points(); _qp++) 105 119372 : _matl_value = std::min(_matl_value, (*_matl_time_step)[_qp]); 106 : } 107 : 108 14948 : if (_use_elements_changed) 109 : { 110 6460 : for (_qp = 0; _qp < _qrule->n_points(); ++_qp) 111 : { 112 5788 : if (!MooseUtils::absoluteFuzzyEqual((*_changed_property)[_qp], 113 5788 : (*_changed_property_old)[_qp], 114 : _elements_changed_threshold)) 115 : { 116 368 : ++_count; 117 368 : return; 118 : } 119 : } 120 : } 121 : } 122 : 123 : Real 124 2776 : MaterialTimeStepPostprocessor::getValue() const 125 : { 126 2776 : if (_count == 0 || !_use_elements_changed) 127 2626 : return _matl_value; 128 : 129 168 : return std::min(_dt * (Real)_elements_changed / (Real)_count, _matl_value); 130 : } 131 : 132 : void 133 2776 : MaterialTimeStepPostprocessor::finalize() 134 : { 135 2776 : gatherMin(_matl_value); 136 2776 : gatherSum(_count); 137 2776 : } 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 : }