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 114600 : Times::validParams() 15 : { 16 114600 : InputParameters params = GeneralReporter::validParams(); 17 343800 : params.addParam<bool>( 18 229200 : "unique_times", true, "Whether duplicate values should be removed from the Times vector"); 19 343800 : params.addParam<Real>( 20 : "unique_tolerance", 21 229200 : 1e-12, 22 : "Absolute tolerance for removing duplicated times when getting a set of unique times"); 23 458400 : 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 458400 : params.addRequiredParam<bool>("auto_broadcast", 27 : "Wether Times should be broadcasted across all ranks"); 28 458400 : 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 229200 : params.suppressParameter<MaterialPropertyName>("prop_getter_suffix"); 33 229200 : params.suppressParameter<bool>("use_interpolated_state"); 34 : 35 343800 : params.addParam<bool>("dynamic_time_sequence", 36 229200 : true, 37 : "Whether the time sequence is dynamic and thus needs to be updated"); 38 : 39 114600 : params.registerBase("Times"); 40 114600 : return params; 41 0 : } 42 : 43 242 : Times::Times(const InputParameters & parameters) 44 : : GeneralReporter(parameters), 45 : // Times will be replicated on every rank 46 242 : _times(declareValueByName<std::vector<Real>, ReporterVectorContext<Real>>( 47 : "times", REPORTER_MODE_REPLICATED)), 48 484 : _need_broadcast(getParam<bool>("auto_broadcast")), 49 484 : _need_sort(getParam<bool>("auto_sort")), 50 484 : _need_unique(getParam<bool>("unique_times")), 51 484 : _unique_tol(getParam<Real>("unique_tolerance")), 52 726 : _dynamic_time_sequence(getParam<bool>("dynamic_time_sequence")) 53 : { 54 242 : } 55 : 56 : Real 57 51 : Times::getTimeAtIndex(unsigned int index) const 58 : { 59 51 : if (_times.size() < index) 60 0 : mooseError("Times retrieved with an out-of-bound index"); 61 : 62 51 : if (_times.size()) 63 51 : return _times[index]; 64 : else 65 0 : mooseError("Times vector has not been initialized."); 66 : } 67 : 68 : Real 69 533 : Times::getPreviousTime(const Real current_time) const 70 : { 71 533 : if (!_times.size()) 72 0 : mooseError("Times vector has not been initialized."); 73 : 74 533 : Real previous_time = _times[0]; 75 1478 : for (const auto i : make_range(std::size_t(1), _times.size())) 76 : { 77 1430 : const auto & time = _times[i]; 78 1430 : if (MooseUtils::absoluteFuzzyGreaterThan(time, current_time)) 79 485 : return previous_time; 80 945 : previous_time = time; 81 : } 82 : // entire Times vector is prior to current_time 83 48 : return previous_time; 84 : } 85 : 86 : Real 87 557 : Times::getNextTime(const Real current_time, const bool error_if_no_next) const 88 : { 89 2131 : for (const auto i : index_range(_times)) 90 : { 91 2083 : const auto & time = _times[i]; 92 2083 : if (MooseUtils::absoluteFuzzyGreaterThan(time, current_time)) 93 509 : return time; 94 : } 95 48 : if (_times.size() && error_if_no_next) 96 0 : mooseError("No next time in Times vector for time ", 97 : current_time, 98 : ". Maximum time in vector is ", 99 0 : *_times.rbegin()); 100 48 : else if (!error_if_no_next) 101 48 : return std::numeric_limits<Real>::max(); 102 : else 103 0 : mooseError("Times vector has not been initialized."); 104 : } 105 : 106 : const std::vector<Real> & 107 329 : Times::getTimes() const 108 : { 109 329 : if (_times.size()) 110 328 : return _times; 111 : else 112 : { 113 1 : mooseError("Times vector has not been initialized."); 114 : } 115 : } 116 : 117 : void 118 37 : Times::clearTimes() 119 : { 120 37 : _times.clear(); 121 37 : } 122 : 123 : void 124 802 : Times::finalize() 125 : { 126 802 : if (_need_broadcast) 127 : // The consumer/producer reporter interface can keep track of whether a reduction is needed 128 : // (for example if a consumer needs replicated data, but the producer is distributed) however, 129 : // we have currently made the decision that times should ALWAYS be replicated 130 25 : _communicator.allgather(_times, /* identical buffer lengths = */ false); 131 : 132 802 : if (_need_sort) 133 690 : std::sort(_times.begin(), _times.end()); 134 802 : if (_need_unique) 135 1604 : _times.erase(unique(_times.begin(), 136 802 : _times.end(), 137 4466 : [this](Real l, Real r) { return std::abs(l - r) < _unique_tol; }), 138 1604 : _times.end()); 139 802 : }