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..d627ee5237c7 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,37 @@ 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) + if (hasBlockMaterialProperty(_prop_names[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 +145,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]; }