diff --git a/framework/doc/content/source/vectorpostprocessors/ExtraIDIntegralVectorPostprocessor.md b/framework/doc/content/source/vectorpostprocessors/ExtraIDIntegralVectorPostprocessor.md index 35a9ff65a851..384bc3027d08 100644 --- a/framework/doc/content/source/vectorpostprocessors/ExtraIDIntegralVectorPostprocessor.md +++ b/framework/doc/content/source/vectorpostprocessors/ExtraIDIntegralVectorPostprocessor.md @@ -5,19 +5,26 @@ ## Overview -The `ExtraIDIntegralVectorPostprocessor` object is a vector postprocessor to integrate input variables based on multiple extra element integer IDs. -First, it finds unique combinations of extra IDs, and then it computes separate integral values over input variables for elements with these unique combinations. +The `ExtraIDIntegralVectorPostprocessor` object is a vector postprocessor to integrate or average input variables or material properties based on multiple extra element integer IDs. +First, it finds unique combinations of extra IDs, and then it computes separate integral values over input variables and material properties for elements with these unique combinations. For reactor applications, component-wise values such as pin-by-pin power distribution can be easily tallied using this object when the mesh contains the appropriate IDs. -The `ExtraIDIntegralVectorPostprocessor` object needs the following parameters: +The `ExtraIDIntegralVectorPostprocessor` object needs the following parameter: + +- [!param](/VectorPostprocessors/ExtraIDIntegralVectorPostprocessor/id_name): list of extra IDs by which to separate integrals + +The following parameters are optional, but at least one of them should be specified: - [!param](/VectorPostprocessors/ExtraIDIntegralVectorPostprocessor/variable): variables that this VectorPostprocessor operates on. -- [!param](/VectorPostprocessors/ExtraIDIntegralVectorPostprocessor/id_name): list of extra IDs by which to separate integrals +- [!param](/VectorPostprocessors/ExtraIDIntegralVectorPostprocessor/mat_prop): material properties that this VectorPostprocessor operates on. + +Additionally, a user can control whether volume-integrated values or volume-averaged values are computed by setting the following parameter: + +- [!param](/VectorPostprocessors/ExtraIDIntegralVectorPostprocessor/average): whether or not to compute volume average. !alert note title=Vector names / CSV output column names -`ExtraIDIntegralVectorPostprocessor` declares a vector for each variable, named after the variable, -holding the values of the integrals computed. +`ExtraIDIntegralVectorPostprocessor` declares a vector for each variable or material property, named after the variable or material property, holding the values of the integrals computed. ## Example Syntax diff --git a/framework/include/vectorpostprocessors/ExtraIDIntegralVectorPostprocessor.h b/framework/include/vectorpostprocessors/ExtraIDIntegralVectorPostprocessor.h index d16d34560a43..8e77ccb7d38f 100644 --- a/framework/include/vectorpostprocessors/ExtraIDIntegralVectorPostprocessor.h +++ b/framework/include/vectorpostprocessors/ExtraIDIntegralVectorPostprocessor.h @@ -26,16 +26,19 @@ class ExtraIDIntegralVectorPostprocessor : public ElementVariableVectorPostproce virtual void finalize() override; virtual void threadJoin(const UserObject & uo) override; /// Return extra ID list - const std::vector & getUniqueExtraIds() const - { - return _var_extra_ids; - }; + const std::vector & getUniqueExtraIds() const { return _extra_ids; }; /// Return Integral values - const std::vector & getIntegrals() const { return _var_integrals; }; + const std::vector & getIntegrals() const { return _integrals; }; protected: + /// whether or not to compute volume average + const bool _average; /// Number of variables to be integrated const unsigned int _nvar; + /// Number of material properties to be integrated + const unsigned int _nprop; + /// Name of material properties + const std::vector _prop_names; /// Extra IDs in use const std::vector _extra_id; /// Number of extra IDs in use @@ -43,11 +46,15 @@ class ExtraIDIntegralVectorPostprocessor : public ElementVariableVectorPostproce // Map of element ids to parsed vpp ids std::unordered_map _unique_vpp_ids; /// Vectors holding extra IDs - std::vector _var_extra_ids; + std::vector _extra_ids; /// Coupled MOOSE variables to be integrated std::vector _vars; /// Quadrature point values of coupled MOOSE variables std::vector _var_values; - /// Vectors holding variable integrals over extra IDs - std::vector _var_integrals; + /// Material properties to be integrated + std::vector *> _props; + /// Vectors holding integrals over extra IDs + std::vector _integrals; + /// Vector holding the volume of extra IDs + std::vector _volumes; }; diff --git a/framework/src/vectorpostprocessors/ExtraIDIntegralVectorPostprocessor.C b/framework/src/vectorpostprocessors/ExtraIDIntegralVectorPostprocessor.C index caf6ea670f2b..63c3846f81ec 100644 --- a/framework/src/vectorpostprocessors/ExtraIDIntegralVectorPostprocessor.C +++ b/framework/src/vectorpostprocessors/ExtraIDIntegralVectorPostprocessor.C @@ -20,19 +20,31 @@ InputParameters ExtraIDIntegralVectorPostprocessor::validParams() { InputParameters params = ElementVariableVectorPostprocessor::validParams(); + params.addParam>( + "mat_prop", "The names of material properties that this VectorPostprocessor operates on"); params.addRequiredParam>( "id_name", "List of extra element ID names by which to separate integral(s)."); - params.addClassDescription("Integrates variables based on extra element IDs"); + params.addParam("average", false, "Whether or not to compute volume average"); + params.addClassDescription("Integrates or averages variables based on extra element IDs"); + params.makeParamNotRequired("variable"); return params; } ExtraIDIntegralVectorPostprocessor::ExtraIDIntegralVectorPostprocessor( const InputParameters & parameters) : ElementVariableVectorPostprocessor(parameters), - _nvar(coupledComponents("variable")), + _average(getParam("average")), + _nvar(isParamValid("variable") ? coupledComponents("variable") : 0), + _nprop(isParamValid("mat_prop") ? getParam>("mat_prop").size() + : 0), + _prop_names(isParamValid("mat_prop") ? getParam>("mat_prop") + : std::vector()), _extra_id(getParam>("id_name")), _n_extra_id(_extra_id.size()) { + if (!_nvar && !_nprop) + mooseError("Neither 'variable' nor 'mat_prop' was specified."); + // create map of element ids to parsed vpp ids _unique_vpp_ids = MooseMeshUtils::getExtraIDUniqueCombinationMap(_mesh.getMesh(), blockIDs(), _extra_id); @@ -57,25 +69,37 @@ ExtraIDIntegralVectorPostprocessor::ExtraIDIntegralVectorPostprocessor( p.resize(extra_ids.size()); for (auto it : extra_ids) p[it.first] = it.second; - _var_extra_ids.push_back(&p); + _extra_ids.push_back(&p); } - // declare vectors containing integral values + // declare vectors containing variable integral values for (unsigned int i = 0; i < _nvar; ++i) { _vars.push_back(getVar("variable", i)); _var_values.push_back(&coupledValue("variable", i)); auto & p = declareVector(_vars[i]->name()); - p.resize((*_var_extra_ids[0]).size()); - _var_integrals.push_back(&p); + p.resize((*_extra_ids[0]).size()); + _integrals.push_back(&p); + } + + // declare vectors containing material property integral values + for (auto & name : _prop_names) + { + _props.push_back(&getMaterialPropertyByName(name)); + auto & p = declareVector(name); + p.resize((*_extra_ids[0]).size()); + _integrals.push_back(&p); } } void ExtraIDIntegralVectorPostprocessor::initialize() { - for (auto & var_integral : _var_integrals) - std::fill(var_integral->begin(), var_integral->end(), 0); + for (auto & integral : _integrals) + std::fill(integral->begin(), integral->end(), 0); + + if (_average) + _volumes.assign((*_extra_ids[0]).size(), 0); } void @@ -83,19 +107,36 @@ ExtraIDIntegralVectorPostprocessor::execute() { if (hasBlocks(_current_elem->subdomain_id())) { + unsigned int i = 0; auto ipos = _unique_vpp_ids[_current_elem->id()]; - for (unsigned int ivar = 0; ivar < _nvar; ++ivar) + for (unsigned int ivar = 0; ivar < _nvar; ++ivar, ++i) if (_vars[ivar]->hasBlocks(_current_elem->subdomain_id())) for (unsigned int qp = 0; qp < _qrule->n_points(); qp++) - (*_var_integrals[ivar])[ipos] += _JxW[qp] * _coord[qp] * (*_var_values[ivar])[qp]; + (*_integrals[i])[ipos] += _JxW[qp] * _coord[qp] * (*_var_values[ivar])[qp]; + + for (unsigned int iprop = 0; iprop < _nprop; ++iprop, ++i) + for (unsigned int qp = 0; qp < _qrule->n_points(); qp++) + (*_integrals[i])[ipos] += _JxW[qp] * _coord[qp] * (*_props[iprop])[qp]; + + if (_average) + _volumes[ipos] += _current_elem->volume(); } } void ExtraIDIntegralVectorPostprocessor::finalize() { - for (auto & var_integral : _var_integrals) - gatherSum(*var_integral); + for (auto & integral : _integrals) + gatherSum(*integral); + + if (_average) + { + gatherSum(_volumes); + + for (auto & integral : _integrals) + for (unsigned int i = 0; i < integral->size(); ++i) + (*integral)[i] /= _volumes[i]; + } } void @@ -103,7 +144,11 @@ ExtraIDIntegralVectorPostprocessor::threadJoin(const UserObject & s) { const auto & sibling = static_cast(s); - for (unsigned int ivar = 0; ivar < _nvar; ++ivar) - for (size_t i = 0; i < (*_var_integrals[ivar]).size(); ++i) - (*_var_integrals[ivar])[i] += (*sibling._var_integrals[ivar])[i]; + for (unsigned int i = 0; i < _integrals.size(); ++i) + for (size_t j = 0; j < (*_integrals[i]).size(); ++j) + (*_integrals[i])[j] += (*sibling._integrals[i])[j]; + + if (_average) + for (unsigned int i = 0; i < _volumes.size(); ++i) + _volumes[i] += sibling._volumes[i]; } diff --git a/test/tests/vectorpostprocessors/extra_id_integral/extra_id_vpp.i b/test/tests/vectorpostprocessors/extra_id_integral/extra_id_vpp.i index ca44192753fc..fe15d8e4cc3e 100644 --- a/test/tests/vectorpostprocessors/extra_id_integral/extra_id_vpp.i +++ b/test/tests/vectorpostprocessors/extra_id_integral/extra_id_vpp.i @@ -26,6 +26,19 @@ [] [] +[Materials] + [mat1] + type = GenericConstantMaterial + prop_names = 'mat1' + prop_values = 1 + [] + [mat2] + type = GenericConstantMaterial + prop_names = 'mat2' + prop_values = 2 + [] +[] + [VectorPostprocessors] [integral] type = ExtraIDIntegralVectorPostprocessor diff --git a/test/tests/vectorpostprocessors/extra_id_integral/gold/extra_id_vpp_vars_mats_average_integral_0001.csv b/test/tests/vectorpostprocessors/extra_id_integral/gold/extra_id_vpp_vars_mats_average_integral_0001.csv new file mode 100644 index 000000000000..4f7ed933e503 --- /dev/null +++ b/test/tests/vectorpostprocessors/extra_id_integral/gold/extra_id_vpp_vars_mats_average_integral_0001.csv @@ -0,0 +1,65 @@ +Level-0-assembly_id,Level-1-pin_id,mat1,mat2,value1,value2 +0,0,1,2,0.98711580586021,0.8887660956035 +0,1,1,2,0.94920581183897,0.5893305330326 +0,2,1,2,0.87477067973594,0.091034215341872 +0,3,1,2,0.76676255346757,-0.43791208947548 +0,4,1,2,0.94920581183897,0.5893305330326 +0,5,1,2,0.91270498648781,0.39060240400599 +0,6,1,2,0.84117527882971,0.060363736777336 +0,7,1,2,0.73727741367928,-0.29024376865766 +0,8,1,2,0.87477067973594,0.091034215341872 +0,9,1,2,0.84117527882971,0.060363736777336 +0,10,1,2,0.77521172043116,0.009324420006462 +0,11,1,2,0.67949616054256,-0.044854302668972 +0,12,1,2,0.76676255346757,-0.43791208947548 +0,13,1,2,0.73727741367928,-0.29024376865766 +0,14,1,2,0.67949616054256,-0.044854302668972 +0,15,1,2,0.59556811102058,0.21567057545121 +1,0,1,2,0.62926576560107,-0.81927589762484 +1,1,1,2,0.46757467066138,-0.92428588401398 +1,2,1,2,0.28793106125081,-0.71793972856923 +1,3,1,2,0.097224912950836,-0.26966493890232 +1,4,1,2,0.60506793671804,-0.54300790001445 +1,5,1,2,0.4496175547242,-0.61288329448548 +1,6,1,2,0.27687312382771,-0.47605754204168 +1,7,1,2,0.093486219484007,-0.17873123401456 +1,8,1,2,0.55763380426871,-0.083897613212905 +1,9,1,2,0.41436991169421,-0.094693733892316 +1,10,1,2,0.25516773236616,-0.073553426254455 +1,11,1,2,0.086157393333932,-0.027614927775488 +1,12,1,2,0.48878263705635,0.4035820923605 +1,13,1,2,0.36318896250191,0.45531088134177 +1,14,1,2,0.22365065939059,0.35366305622404 +1,15,1,2,0.075519521222152,0.13283918225103 +2,0,1,2,0.62926576560107,-0.81927589762484 +2,1,1,2,0.60506793671804,-0.54300790001445 +2,2,1,2,0.55763380426871,-0.083897613212905 +2,3,1,2,0.48878263705635,0.4035820923605 +2,4,1,2,0.46757467066138,-0.92428588401398 +2,5,1,2,0.4496175547242,-0.61288329448548 +2,6,1,2,0.41436991169421,-0.094693733892316 +2,7,1,2,0.36318896250191,0.45531088134177 +2,8,1,2,0.28793106125081,-0.71793972856923 +2,9,1,2,0.27687312382771,-0.47605754204168 +2,10,1,2,0.25516773236616,-0.073553426254455 +2,11,1,2,0.22365065939059,0.35366305622404 +2,12,1,2,0.097224912950837,-0.26966493890232 +2,13,1,2,0.093486219484007,-0.17873123401456 +2,14,1,2,0.086157393333932,-0.027614927775488 +2,15,1,2,0.075519521222152,0.13283918225103 +3,0,1,2,0.40112326925378,0.75487907000588 +3,1,1,2,0.29806911343396,0.85201849061685 +3,2,1,2,0.18354535282422,0.66165704215143 +3,3,1,2,0.061977269396861,0.24852463061438 +3,4,1,2,0.29806911343396,0.85201849061685 +3,5,1,2,0.22147965957609,0.96122523081555 +3,6,1,2,0.13638999475901,0.74680045686719 +3,7,1,2,0.04605208627399,0.28037906225803 +3,8,1,2,0.18354535282422,0.66165704215143 +3,9,1,2,0.13638999475901,0.74680045686719 +3,10,1,2,0.083986393025862,0.57994725092215 +3,11,1,2,0.028359461169358,0.21783366174506 +3,12,1,2,0.061977269396861,0.24852463061438 +3,13,1,2,0.04605208627399,0.28037906225803 +3,14,1,2,0.028359461169358,0.21783366174506 +3,15,1,2,0.009575573008583,0.081783557102421 diff --git a/test/tests/vectorpostprocessors/extra_id_integral/gold/extra_id_vpp_vars_mats_integral_0001.csv b/test/tests/vectorpostprocessors/extra_id_integral/gold/extra_id_vpp_vars_mats_integral_0001.csv new file mode 100644 index 000000000000..d02401033d91 --- /dev/null +++ b/test/tests/vectorpostprocessors/extra_id_integral/gold/extra_id_vpp_vars_mats_integral_0001.csv @@ -0,0 +1,65 @@ +Level-0-assembly_id,Level-1-pin_id,mat1,mat2,value1,value2 +0,0,1.5876,3.1752,1.5671450533837,1.4110050533801 +0,1,1.5876,3.1752,1.5069591468755,0.93562115424255 +0,2,1.5876,3.1752,1.3887859311488,0.14452592027676 +0,3,1.5876,3.1752,1.2173122298851,-0.69522923325127 +0,4,1.5876,3.1752,1.5069591468755,0.93562115424256 +0,5,1.5876,3.1752,1.4490104365481,0.62012037659991 +0,6,1.5876,3.1752,1.3354498726701,0.095833468507698 +0,7,1.5876,3.1752,1.1705016219572,-0.4607910071209 +0,8,1.5876,3.1752,1.3887859311488,0.14452592027676 +0,9,1.5876,3.1752,1.3354498726701,0.095833468507698 +0,10,1.5876,3.1752,1.2307261273565,0.014803449202259 +0,11,1.5876,3.1752,1.0787681044774,-0.07121069091726 +0,12,1.5876,3.1752,1.2173122298851,-0.69522923325126 +0,13,1.5876,3.1752,1.1705016219572,-0.4607910071209 +0,14,1.5876,3.1752,1.0787681044774,-0.07121069091726 +0,15,1.5876,3.1752,0.94552393305628,0.34239860558635 +1,0,1.5876,3.1752,0.99902232946827,-1.3006824150692 +1,1,1.5876,3.1752,0.74232154714201,-1.4673962694606 +1,2,1.5876,3.1752,0.45711935284178,-1.1398011130765 +1,3,1.5876,3.1752,0.15435427180075,-0.42812005700132 +1,4,1.5876,3.1752,0.96060585633356,-0.86207934206295 +1,5,1.5876,3.1752,0.71381282988013,-0.97301351832515 +1,6,1.5876,3.1752,0.43956377138888,-0.75578895374537 +1,7,1.5876,3.1752,0.14841872205281,-0.28375370712151 +1,8,1.5876,3.1752,0.88529942765701,-0.13319585073681 +1,9,1.5876,3.1752,0.65785367180572,-0.15033577192744 +1,10,1.5876,3.1752,0.40510429190451,-0.11677341952157 +1,11,1.5876,3.1752,0.13678347765695,-0.043841459336365 +1,12,1.5876,3.1752,0.77599131459067,0.64072692983152 +1,13,1.5876,3.1752,0.57659879686803,0.72285155521819 +1,14,1.5876,3.1752,0.3550677868485,0.56147546806129 +1,15,1.5876,3.1752,0.11989479189229,0.21089548574174 +2,0,1.5876,3.1752,0.99902232946826,-1.3006824150692 +2,1,1.5876,3.1752,0.96060585633356,-0.86207934206295 +2,2,1.5876,3.1752,0.88529942765701,-0.13319585073681 +2,3,1.5876,3.1752,0.77599131459067,0.64072692983152 +2,4,1.5876,3.1752,0.74232154714201,-1.4673962694606 +2,5,1.5876,3.1752,0.71381282988013,-0.97301351832515 +2,6,1.5876,3.1752,0.65785367180572,-0.15033577192744 +2,7,1.5876,3.1752,0.57659879686803,0.72285155521819 +2,8,1.5876,3.1752,0.45711935284178,-1.1398011130765 +2,9,1.5876,3.1752,0.43956377138888,-0.75578895374538 +2,10,1.5876,3.1752,0.40510429190451,-0.11677341952157 +2,11,1.5876,3.1752,0.3550677868485,0.56147546806129 +2,12,1.5876,3.1752,0.15435427180075,-0.42812005700132 +2,13,1.5876,3.1752,0.14841872205281,-0.28375370712151 +2,14,1.5876,3.1752,0.13678347765695,-0.043841459336365 +2,15,1.5876,3.1752,0.11989479189229,0.21089548574174 +3,0,1.5876,3.1752,0.63682330226731,1.1984460115413 +3,1,1.5876,3.1752,0.47321452448776,1.3526645557033 +3,2,1.5876,3.1752,0.29139660214373,1.0504467201196 +3,3,1.5876,3.1752,0.098395112894456,0.39455770356339 +3,4,1.5876,3.1752,0.47321452448776,1.3526645557033 +3,5,1.5876,3.1752,0.351621107543,1.5260411764428 +3,6,1.5876,3.1752,0.2165327556794,1.1856204053223 +3,7,1.5876,3.1752,0.073112292168586,0.44512979924085 +3,8,1.5876,3.1752,0.29139660214373,1.0504467201196 +3,9,1.5876,3.1752,0.2165327556794,1.1856204053224 +3,10,1.5876,3.1752,0.13333679756786,0.920724255564 +3,11,1.5876,3.1752,0.045023480552472,0.34583272138645 +3,12,1.5876,3.1752,0.098395112894456,0.39455770356339 +3,13,1.5876,3.1752,0.073112292168586,0.44512979924085 +3,14,1.5876,3.1752,0.045023480552472,0.34583272138645 +3,15,1.5876,3.1752,0.015202179708426,0.1298395752558 diff --git a/test/tests/vectorpostprocessors/extra_id_integral/tests b/test/tests/vectorpostprocessors/extra_id_integral/tests index a12f20129ba8..70ec2f7f6135 100644 --- a/test/tests/vectorpostprocessors/extra_id_integral/tests +++ b/test/tests/vectorpostprocessors/extra_id_integral/tests @@ -1,8 +1,8 @@ [Tests] design = 'vectorpostprocessors/ExtraIDIntegralVectorPostprocessor.md' - issues = '#19617' + issues = '#19617 #27138' [test] - requirement = 'The system shall be able to integrate variables parsed by extra IDs' + requirement = 'The system shall be able to integrate or average variables or material properties parsed by extra IDs' [default] type = 'CSVDiff' input = 'extra_id_vpp.i' @@ -27,5 +27,21 @@ detail = 'with multiple variable integrals and multiple extra IDs' recover = false [] + [vars_and_mats] + type = 'CSVDiff' + input = 'extra_id_vpp.i' + csvdiff = 'extra_id_vpp_vars_mats_integral_0001.csv' + cli_args = "VectorPostprocessors/integral/id_name='assembly_id pin_id' VectorPostprocessors/integral/variable='value1 value2' VectorPostprocessors/integral/mat_prop='mat1 mat2' Outputs/file_base='extra_id_vpp_vars_mats'" + detail = 'with multiple variable and material property integrals and multiple extra IDs' + recover = false + [] + [vars_and_mats_average] + type = 'CSVDiff' + input = 'extra_id_vpp.i' + csvdiff = 'extra_id_vpp_vars_mats_average_integral_0001.csv' + cli_args = "VectorPostprocessors/integral/id_name='assembly_id pin_id' VectorPostprocessors/integral/variable='value1 value2' VectorPostprocessors/integral/mat_prop='mat1 mat2' VectorPostprocessors/integral/average=true Outputs/file_base='extra_id_vpp_vars_mats_average'" + detail = 'with multiple variable and material property averages and multiple extra IDs' + recover = false + [] [] -[] \ No newline at end of file +[]