Skip to content

Commit

Permalink
Support material property integration and volume averaging in ExtraID…
Browse files Browse the repository at this point in the history
…IntegralVectorPostprocessor idaholab#27138
  • Loading branch information
NamjaeChoi committed Mar 20, 2024
1 parent 6767fab commit e1972cf
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 23 deletions.
Expand Up @@ -26,28 +26,35 @@ class ExtraIDIntegralVectorPostprocessor : public ElementVariableVectorPostproce
virtual void finalize() override;
virtual void threadJoin(const UserObject & uo) override;
/// Return extra ID list
const std::vector<VectorPostprocessorValue *> & getUniqueExtraIds() const
{
return _var_extra_ids;
};
const std::vector<VectorPostprocessorValue *> & getUniqueExtraIds() const { return _extra_ids; };
/// Return Integral values
const std::vector<VectorPostprocessorValue *> & getIntegrals() const { return _var_integrals; };
const std::vector<VectorPostprocessorValue *> & 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<MaterialPropertyName> _prop_names;
/// Extra IDs in use
const std::vector<ExtraElementIDName> _extra_id;
/// Number of extra IDs in use
const unsigned int _n_extra_id;
// Map of element ids to parsed vpp ids
std::unordered_map<dof_id_type, dof_id_type> _unique_vpp_ids;
/// Vectors holding extra IDs
std::vector<VectorPostprocessorValue *> _var_extra_ids;
std::vector<VectorPostprocessorValue *> _extra_ids;
/// Coupled MOOSE variables to be integrated
std::vector<const MooseVariable *> _vars;
/// Quadrature point values of coupled MOOSE variables
std::vector<const VariableValue *> _var_values;
/// Vectors holding variable integrals over extra IDs
std::vector<VectorPostprocessorValue *> _var_integrals;
/// Material properties to be integrated
std::vector<const MaterialProperty<Real> *> _props;
/// Vectors holding integrals over extra IDs
std::vector<VectorPostprocessorValue *> _integrals;
/// Vector holding the volume of extra IDs
std::vector<Real> _volumes;
};
Expand Up @@ -20,19 +20,31 @@ InputParameters
ExtraIDIntegralVectorPostprocessor::validParams()
{
InputParameters params = ElementVariableVectorPostprocessor::validParams();
params.addParam<std::vector<MaterialPropertyName>>(
"mat_prop", "The names of material properties that this VectorPostprocessor operates on");
params.addRequiredParam<std::vector<ExtraElementIDName>>(
"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<bool>("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<bool>("average")),
_nvar(isParamValid("variable") ? coupledComponents("variable") : 0),
_nprop(isParamValid("mat_prop") ? getParam<std::vector<MaterialPropertyName>>("mat_prop").size()
: 0),
_prop_names(isParamValid("mat_prop") ? getParam<std::vector<MaterialPropertyName>>("mat_prop")
: std::vector<MaterialPropertyName>()),
_extra_id(getParam<std::vector<ExtraElementIDName>>("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);
Expand All @@ -57,53 +69,86 @@ 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<Real>(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
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
ExtraIDIntegralVectorPostprocessor::threadJoin(const UserObject & s)
{
const auto & sibling = static_cast<const ExtraIDIntegralVectorPostprocessor &>(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];
}

0 comments on commit e1972cf

Please sign in to comment.