https://mooseframework.inl.gov
AnalysisStepUserObject.C
Go to the documentation of this file.
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 "AnalysisStepUserObject.h"
11 #include "MooseUtils.h"
12 #include <limits>
13 #include <algorithm>
14 
15 registerMooseObject("SolidMechanicsApp", AnalysisStepUserObject);
16 
19 {
21  params.addClassDescription(
22  "Maps the time steps and the load step simulation times. It can be "
23  "used in either direction depending on the simulation setup. It "
24  "generates steps to be used in StepPeriod to control the enabled/disabled state of objects "
25  "with user-provided simulation steps.");
26  params.addParam<std::vector<Real>>(
27  "step_start_times",
28  "The beginning of step times. The number of steps is inferred from the number of times. One "
29  "step is defined by its start time; and its end time is taken from the start time of the "
30  "next step (if it exists). This list needs to be in ascending value order.");
31  params.addParam<std::vector<Real>>(
32  "step_end_times",
33  "The end of step times. The number of steps is inferred from the number of times. One "
34  "step is defined by the interval between previous start time and the next. The first step "
35  "is assumed to start at time zero. This list needs to be in ascending value order.");
36  params.addParam<Real>("total_time_interval",
37  "The total time interval in which the steps take place. This option needs "
38  "to be used together with the 'number_steps'.");
39  params.addParam<unsigned int>(
40  "number_steps",
41  "Total number of steps in the total time inteval (provided as total_time_interval).");
42 
43  params.addParam<std::vector<Real>>(
44  "step_durations",
45  "The durations of the steps. 'n' of step time intervals define 'n+1' steps "
46  "starting at time equals zero.");
47 
48  params.addParam<bool>(
49  "set_sync_times", false, "Whether to make the output times include the step times.");
50 
51  return params;
52 }
53 
55  : GeneralUserObject(parameters),
56  _times(0),
57  _step_durations(0),
58  _total_time_interval(0),
59  _number_steps(0)
60 {
61  const bool is_step_start_times = isParamSetByUser("step_start_times");
62  const bool is_step_end_times = isParamSetByUser("step_end_times");
63  const bool is_interval_and_steps =
64  isParamSetByUser("total_time_interval") && isParamSetByUser("number_steps");
65  const bool is_step_durations = isParamSetByUser("step_durations");
66 
67  // check for valid user input
68  if (int(is_step_start_times) + int(is_step_end_times) + int(is_interval_and_steps) +
69  int(is_step_durations) >
70  1)
71  mooseError("In AnalysisStepUserObject, only one of 'step_start_times', 'step_end_times', "
72  "'total_time_interval', and 'step_durations' can be set");
73  if ((isParamSetByUser("total_time_interval") && !isParamSetByUser("number_steps")) ||
74  (!isParamSetByUser("total_time_interval") && isParamSetByUser("number_steps")))
75  mooseError("In AnalysisStepUserObject, both 'total_time_interval' and 'number_steps' need both "
76  "be set.");
77 
78  // define step times
79  if (is_step_start_times)
80  {
81  _times = getParam<std::vector<Real>>("step_start_times");
82  if (!std::is_sorted(_times.begin(), _times.end()))
83  paramError("step_start_times",
84  "start times for AnalysisStepUserObject are not provided in ascending order. "
85  "Please revise "
86  "your input.");
87 
88  mooseInfo("Step start times are used to define simulation steps in ", name(), ".");
89  }
90  else if (is_step_end_times)
91  {
92  _times = getParam<std::vector<Real>>("step_end_times");
93  if (!std::is_sorted(_times.begin(), _times.end()))
94  paramError(
95  "step_end_times",
96  "end times for AnalysisStepUserObject are not provided in ascending order. Please revise "
97  "your input.");
98  _times.insert(_times.begin(), 0.0);
99 
100  mooseInfo("Step start times are used to define simulation steps in ", name(), ".");
101  }
102  else if (is_interval_and_steps)
103  {
104  _total_time_interval = getParam<Real>("total_time_interval");
105  _number_steps = getParam<unsigned int>("number_steps");
106  _times.resize(_number_steps + 1);
107 
108  for (const auto i : index_range(_times))
109  {
110  if (i == 0)
111  _times[0] = 0.0;
112  else
114  }
115 
116  mooseInfo("The total time interval and the provided number of steps are used to define "
117  "simulation steps in ",
118  name(),
119  ".");
120  }
121  else if (is_step_durations)
122  {
123  _step_durations = getParam<std::vector<Real>>("step_durations");
124  _times.resize(_step_durations.size() + 1);
125  for (const auto i : index_range(_times))
126  {
127  if (i == 0)
128  _times[i] = 0.0;
129  else
130  _times[i] = _step_durations[i - 1] + _times[i - 1];
131  }
132  mooseInfo("Step durations are used to define simulation steps in ", name(), ".");
133  }
134  else
135  paramError("step_start_times",
136  "Plese provide 'step_start_times' or 'step_durations' or 'total_time_interval' and "
137  "'number_steps' to define simulation loading steps.");
138 
139  // set sync times
140  if (getParam<bool>("set_sync_times"))
141  {
142  std::set<Real> & sync_times = _app.getOutputWarehouse().getSyncTimes();
143  for (const auto t : _times)
144  sync_times.insert(t);
145  }
146 }
147 
148 Real
149 AnalysisStepUserObject::getStartTime(const unsigned int & step) const
150 {
151  if (_times.size() <= step)
152  mooseError("AnalysisStepUserObject was called with a wrong step number");
153 
154  return _times[step];
155 }
156 
157 Real
158 AnalysisStepUserObject::getEndTime(const unsigned int & step) const
159 {
160  Real end_time(0);
161 
162  if (_times.size() > step + 1)
163  end_time = _times[step + 1];
164  else if (_times.size() == step + 1)
165  end_time = std::numeric_limits<double>::max();
166  else
167  mooseError("AnalysisStepUserObject was called with a wrong step number");
168 
169  return end_time;
170 }
171 
172 unsigned int
173 AnalysisStepUserObject::getStep(const Real & time) const
174 {
175  int which_step = 0;
176 
177  for (const auto i : index_range(_times))
178  {
179  if (i + 1 == _times.size())
180  return i;
181 
182  which_step = i;
185  return which_step;
186  }
187 
188  return which_step;
189 }
190 
191 void
193 {
194 }
195 void
197 {
198 }
199 void
201 {
202 }
static InputParameters validParams()
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
Real getEndTime(const unsigned int &step) const
void mooseInfo(Args &&... args) const
std::vector< Real > _times
virtual const std::string & name() const
AnalysisStepUserObject(const InputParameters &parameters)
Real getStartTime(const unsigned int &step) const
bool absoluteFuzzyLessThan(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
void paramError(const std::string &param, Args... args) const
static InputParameters validParams()
std::vector< Real > _step_durations
bool isParamSetByUser(const std::string &nm) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool absoluteFuzzyGreaterEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
unsigned int getStep(const Real &time) const
User object that provides analysis steps given user input.
registerMooseObject("SolidMechanicsApp", AnalysisStepUserObject)
std::set< Real > & getSyncTimes()
auto index_range(const T &sizable)
OutputWarehouse & getOutputWarehouse()