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 "Times.h" 11 : #include "libmesh/parallel_algebra.h" 12 : 13 : InputParameters 14 100251 : Times::validParams() 15 : { 16 100251 : InputParameters params = GeneralReporter::validParams(); 17 300753 : params.addParam<bool>( 18 200502 : "unique_times", true, "Whether duplicate values should be removed from the Times vector"); 19 300753 : params.addParam<Real>( 20 : "unique_tolerance", 21 200502 : 1e-12, 22 : "Absolute tolerance for removing duplicated times when getting a set of unique times"); 23 100251 : params.addParam<bool>("auto_sort", true, "Whether Times should be sorted"); 24 : // This parameter should be set by each derived class depending on whether the generation of 25 : // times is replicated or distributed. We want times to be replicated across all ranks 26 100251 : params.addRequiredParam<bool>("auto_broadcast", 27 : "Wether Times should be broadcasted across all ranks"); 28 100251 : params.addParamNamesToGroup("auto_broadcast auto_sort unique_times unique_tolerance", "Advanced"); 29 : 30 : // Unlikely to ever be used as Times do not loop over the mesh and use material properties, 31 : // let alone stateful 32 100251 : params.suppressParameter<MaterialPropertyName>("prop_getter_suffix"); 33 100251 : params.suppressParameter<bool>("use_interpolated_state"); 34 : 35 100251 : params.registerBase("Times"); 36 100251 : return params; 37 0 : } 38 : 39 200 : Times::Times(const InputParameters & parameters) 40 : : GeneralReporter(parameters), 41 : // Times will be replicated on every rank 42 200 : _times(declareValueByName<std::vector<Real>, ReporterVectorContext<Real>>( 43 : "times", REPORTER_MODE_REPLICATED)), 44 200 : _need_broadcast(getParam<bool>("auto_broadcast")), 45 200 : _need_sort(getParam<bool>("auto_sort")), 46 200 : _need_unique(getParam<bool>("unique_times")), 47 400 : _unique_tol(getParam<Real>("unique_tolerance")) 48 : { 49 200 : } 50 : 51 : Real 52 47 : Times::getTimeAtIndex(unsigned int index) const 53 : { 54 47 : if (_times.size() < index) 55 0 : mooseError("Times retrieved with an out-of-bound index"); 56 : 57 47 : if (_times.size()) 58 47 : return _times[index]; 59 : else 60 0 : mooseError("Times vector has not been initialized."); 61 : } 62 : 63 : Real 64 489 : Times::getPreviousTime(const Real current_time) const 65 : { 66 489 : if (!_times.size()) 67 0 : mooseError("Times vector has not been initialized."); 68 : 69 489 : Real previous_time = _times[0]; 70 1356 : for (const auto i : make_range(std::size_t(1), _times.size())) 71 : { 72 1312 : const auto & time = _times[i]; 73 1312 : if (MooseUtils::absoluteFuzzyGreaterThan(time, current_time)) 74 445 : return previous_time; 75 867 : previous_time = time; 76 : } 77 : // entire Times vector is prior to current_time 78 44 : return previous_time; 79 : } 80 : 81 : Real 82 511 : Times::getNextTime(const Real current_time, const bool error_if_no_next) const 83 : { 84 1955 : for (const auto i : index_range(_times)) 85 : { 86 1911 : const auto & time = _times[i]; 87 1911 : if (MooseUtils::absoluteFuzzyGreaterThan(time, current_time)) 88 467 : return time; 89 : } 90 44 : if (_times.size() && error_if_no_next) 91 0 : mooseError("No next time in Times vector for time ", 92 : current_time, 93 : ". Maximum time in vector is ", 94 0 : *_times.rbegin()); 95 44 : else if (!error_if_no_next) 96 44 : return std::numeric_limits<Real>::max(); 97 : else 98 0 : mooseError("Times vector has not been initialized."); 99 : } 100 : 101 : const std::vector<Real> & 102 36 : Times::getTimes() const 103 : { 104 36 : if (_times.size()) 105 35 : return _times; 106 : else 107 1 : mooseError("Times vector has not been initialized."); 108 : } 109 : 110 : void 111 34 : Times::clearTimes() 112 : { 113 34 : _times.clear(); 114 34 : } 115 : 116 : void 117 603 : Times::finalize() 118 : { 119 603 : if (_need_broadcast) 120 : // The consumer/producer reporter interface can keep track of whether a reduction is needed 121 : // (for example if a consumer needs replicated data, but the producer is distributed) however, 122 : // we have currently made the decision that times should ALWAYS be replicated 123 23 : _communicator.allgather(_times, /* identical buffer lengths = */ false); 124 : 125 603 : if (_need_sort) 126 500 : std::sort(_times.begin(), _times.end()); 127 603 : if (_need_unique) 128 1206 : _times.erase(unique(_times.begin(), 129 603 : _times.end(), 130 3260 : [this](Real l, Real r) { return std::abs(l - r) < _unique_tol; }), 131 1206 : _times.end()); 132 603 : }