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 : // MOOSE includes 11 : #include "VectorPostprocessor.h" 12 : #include "SubProblem.h" 13 : #include "Conversion.h" 14 : #include "UserObject.h" 15 : #include "FEProblem.h" 16 : 17 : InputParameters 18 177151 : VectorPostprocessor::validParams() 19 : { 20 177151 : InputParameters params = OutputInterface::validParams(); 21 177151 : params += NonADFunctorInterface::validParams(); 22 354302 : params.addParam<bool>("contains_complete_history", 23 354302 : false, 24 : "Set this flag to indicate that the values in all vectors declared by this " 25 : "VPP represent a time history (e.g. with each invocation, new values are " 26 : "added and old values are never removed). This changes the output so that " 27 : "only a single file is output and updated with each invocation"); 28 : 29 : // VPPs can set this to true if their resulting vectors are naturally replicated in parallel 30 : // setting this to false will keep MOOSE from unnecessarily broadcasting those vectors 31 531453 : params.addPrivateParam<bool>("_auto_broadcast", true); 32 : 33 : // VPPs can operate in "distributed" mode, which disables the automatic broadcasting 34 : // and results in an individual file per processor if CSV output is enabled 35 708604 : MooseEnum parallel_type("DISTRIBUTED REPLICATED", "REPLICATED"); 36 708604 : params.addParam<MooseEnum>( 37 : "parallel_type", 38 : parallel_type, 39 : "Set how the data is represented within the VectorPostprocessor (VPP); 'distributed' " 40 : "indicates that data within the VPP is distributed and no auto communication is performed, " 41 : "this setting will result in parallel output within the CSV output; 'replicated' indicates " 42 : "that the data within the VPP is correct on processor 0, the data will automatically be " 43 : "broadcast to all processors unless the '_auto_broadcast' param is set to false within the " 44 : "validParams function."); 45 : 46 708604 : params.addParamNamesToGroup("outputs", "Advanced"); 47 177151 : params.registerBase("VectorPostprocessor"); 48 354302 : return params; 49 177151 : } 50 : 51 6297 : VectorPostprocessor::VectorPostprocessor(const MooseObject * moose_object) 52 : : OutputInterface(moose_object->parameters()), 53 : NonADFunctorInterface(moose_object), 54 6297 : _vpp_name(moose_object->name()), 55 6297 : _vpp_fe_problem( 56 25188 : *moose_object->parameters().getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")), 57 6297 : _parallel_type(moose_object->parameters().get<MooseEnum>("parallel_type")), 58 6297 : _vpp_moose_object(*moose_object), 59 12594 : _vpp_tid(moose_object->parameters().isParamValid("_tid") 60 6297 : ? moose_object->parameters().get<THREAD_ID>("_tid") 61 : : 0), 62 6297 : _contains_complete_history(moose_object->parameters().get<bool>("contains_complete_history")), 63 6297 : _is_distributed(_parallel_type == "DISTRIBUTED"), 64 12594 : _is_broadcast(_is_distributed || !moose_object->parameters().get<bool>("_auto_broadcast")) 65 : { 66 6297 : } 67 : 68 : #ifdef MOOSE_KOKKOS_ENABLED 69 432 : VectorPostprocessor::VectorPostprocessor(const VectorPostprocessor & object, 70 432 : const Moose::Kokkos::FunctorCopy & key) 71 : : OutputInterface(object, key), 72 : NonADFunctorInterface(object, key), 73 432 : _vpp_name(object._vpp_name), 74 432 : _vpp_fe_problem(object._vpp_fe_problem), 75 432 : _parallel_type(object._parallel_type), 76 432 : _vpp_moose_object(object._vpp_moose_object), 77 432 : _vpp_tid(object._vpp_tid), 78 432 : _contains_complete_history(object._contains_complete_history), 79 432 : _is_distributed(object._is_distributed), 80 432 : _is_broadcast(object._is_broadcast) 81 : { 82 432 : } 83 : #endif 84 : 85 : VectorPostprocessorValue & 86 21959 : VectorPostprocessor::declareVector(const std::string & vector_name) 87 : { 88 21959 : _vector_names.insert(vector_name); 89 : 90 21959 : if (_vpp_tid) 91 538 : return _thread_local_vectors.emplace(vector_name, VectorPostprocessorValue()).first->second; 92 : 93 : // _is_broadcast = true (_auto_broadcast = false) then data is produced in a replicated manner 94 21421 : ReporterMode mode = REPORTER_MODE_ROOT; 95 21421 : if (_is_broadcast) 96 11046 : mode = REPORTER_MODE_REPLICATED; 97 21421 : if (_is_distributed) 98 81 : mode = REPORTER_MODE_DISTRIBUTED; 99 : 100 21421 : return _vpp_fe_problem.getReporterData(ReporterData::WriteKey()) 101 : .declareReporterValue<VectorPostprocessorValue, 102 21421 : VectorPostprocessorContext<VectorPostprocessorValue>>( 103 42842 : VectorPostprocessorReporterName(_vpp_name, vector_name), mode, _vpp_moose_object); 104 21421 : } 105 : 106 : const std::set<std::string> & 107 47 : VectorPostprocessor::getVectorNames() const 108 : { 109 47 : return _vector_names; 110 : } 111 : 112 : const ReporterMode REPORTER_MODE_VPP_SCATTER("VPP_SCATTER"); 113 : 114 : template <typename T> 115 21421 : VectorPostprocessorContext<T>::VectorPostprocessorContext(const libMesh::ParallelObject & other, 116 : const MooseObject & producer, 117 : ReporterState<T> & state) 118 21421 : : ReporterGeneralContext<T>(other, producer, state) 119 : { 120 21421 : } 121 : 122 : template <typename T> 123 : void 124 60221 : VectorPostprocessorContext<T>::finalize() 125 : { 126 60221 : ReporterGeneralContext<T>::finalize(); 127 : 128 60221 : const auto & consumer_modes = this->state().getConsumers(); 129 8418 : auto func = [](const std::pair<ReporterMode, const MooseObject *> & mode_pair) 130 8418 : { return mode_pair.first == REPORTER_MODE_VPP_SCATTER; }; 131 60221 : if (std::find_if(consumer_modes.begin(), consumer_modes.end(), func) != consumer_modes.end()) 132 : { 133 74 : const T & value = this->state().value(); 134 74 : if (this->processor_id() == 0 && value.size() != this->n_processors()) 135 0 : mooseError("The VectorPostprocessor value to be scatter has a length of ", 136 0 : value.size(), 137 : "; it must be the same length as the number of processors (", 138 0 : this->n_processors(), 139 : ")."); 140 : 141 74 : this->comm().scatter(value, _scatter_value); 142 : } 143 60221 : } 144 : 145 : template <typename T> 146 : void 147 39461 : VectorPostprocessorContext<T>::copyValuesBack() 148 : { 149 39461 : ReporterGeneralContext<T>::copyValuesBack(); 150 39461 : _scatter_value_old = _scatter_value; 151 39461 : } 152 : 153 : template <typename T> 154 : const ScatterVectorPostprocessorValue & 155 94 : VectorPostprocessorContext<T>::getScatterValue() const 156 : { 157 94 : return _scatter_value; 158 : } 159 : 160 : template <typename T> 161 : const ScatterVectorPostprocessorValue & 162 0 : VectorPostprocessorContext<T>::getScatterValueOld() const 163 : { 164 0 : return _scatter_value_old; 165 : } 166 : 167 : // Explicit instantiation 168 : template class VectorPostprocessorContext<VectorPostprocessorValue>;