Skip to content

Commit

Permalink
Rework without threads (idaholab#21801)
Browse files Browse the repository at this point in the history
  • Loading branch information
dschwen authored and MengnanLi91 committed Mar 8, 2023
1 parent d275074 commit 3548e6f
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 105 deletions.
13 changes: 11 additions & 2 deletions framework/include/userobject/RenormalizeVector.h
Expand Up @@ -35,9 +35,18 @@ class RenormalizeVector : public GeneralUserObject
/// reference to the mesh
MooseMesh & _mesh;

/// variables to renormalize as a vector
const std::vector<VariableName> & _vars;
/// names of the variables to renormalize
const std::vector<VariableName> & _var_names;

// internal ID numbers of the variables to renormalize
std::vector<unsigned int> _var_numbers;

/// desired norm
const Real _target_norm;

// MOOSE Nonlinear system
NonlinearSystemBase & _nl_sys;

/// libMesh System pointer
System & _sys;
};
133 changes: 30 additions & 103 deletions framework/src/userobject/RenormalizeVector.C
Expand Up @@ -16,29 +16,6 @@

registerMooseObject("MooseApp", RenormalizeVector);

class RenormalizeVectorThread : public ParallelObject
{
public:
RenormalizeVectorThread(FEProblemBase & problem,
const std::vector<VariableName> & vars,
const Real norm);
// Splitting Constructor
RenormalizeVectorThread(RenormalizeVectorThread & x, Threads::split split);
// destructor to close the solution once more
~RenormalizeVectorThread();

void operator()(const ConstElemRange & range);
void join(const RenormalizeVectorThread &) {}

protected:
FEProblemBase & _problem;
System * _sys;
std::vector<unsigned int> _var_numbers;
const Real _target_norm;

THREAD_ID _tid;
};

InputParameters
RenormalizeVector::validParams()
{
Expand All @@ -53,106 +30,46 @@ RenormalizeVector::validParams()
RenormalizeVector::RenormalizeVector(const InputParameters & parameters)
: GeneralUserObject(parameters),
_mesh(_fe_problem.mesh()),
_vars(getParam<std::vector<VariableName>>("v")),
_target_norm(getParam<Real>("norm"))
{
}

void
RenormalizeVector::initialize()
{
}

void
RenormalizeVector::execute()
_var_names(getParam<std::vector<VariableName>>("v")),
_target_norm(getParam<Real>("norm")),
_nl_sys(_fe_problem.getNonlinearSystemBase()),
_sys(_nl_sys.system())
{
RenormalizeVectorThread renorm(_fe_problem, _vars, _target_norm);
ConstElemRange & elem_range = *_mesh.getActiveLocalElementRange();
Threads::parallel_reduce(elem_range, renorm);
}

void
RenormalizeVector::finalize()
{
}

// Thread worker implementation follows

RenormalizeVectorThread::RenormalizeVectorThread(FEProblemBase & problem,
const std::vector<VariableName> & varnames,
const Real norm)
: ParallelObject(problem.comm()), _problem(problem), _sys(nullptr), _target_norm(norm)
{
for (const auto & varname : varnames)
for (const auto & var_name : _var_names)
{
auto & var = _problem.getVariable(0, varname);
if (_sys)
{
if (_sys != &var.sys().system())
mooseError("Variables passed in RenormalizeVectorThread must be all in the same system.");
}
else
_sys = &var.sys().system();
auto & var = _fe_problem.getVariable(0, var_name);
if (_sys.number() != var.sys().system().number())
paramError("v", "Variables must be all in the non-linear system.");

if (var.isArray())
{
const auto & array_var = _problem.getArrayVariable(0, varname);
const auto & array_var = _fe_problem.getArrayVariable(0, var_name);
for (unsigned int p = 0; p < var.count(); ++p)
_var_numbers.push_back(_sys->variable_number(array_var.componentName(p)));
_var_numbers.push_back(_sys.variable_number(array_var.componentName(p)));
}
else
_var_numbers.push_back(_sys->variable_number(varname));
_var_numbers.push_back(_sys.variable_number(var_name));
}

// get the non linear system
const auto & nl_sys = _problem.getNonlinearSystemBase();

if (&(nl_sys.solutionState(0)) != _sys->solution.get())
mooseError("Specify variables from the non-linear system");

// do one solution.close to get updated
_sys->solution->close();
}

RenormalizeVectorThread::~RenormalizeVectorThread()
{
auto & nl_sys = _problem.getNonlinearSystemBase();
for (const auto s : make_range(3))
if (nl_sys.hasSolutionState(s))
nl_sys.solutionState(s).close();

_sys->update();
}

// Splitting Constructor
RenormalizeVectorThread::RenormalizeVectorThread(RenormalizeVectorThread & x,
Threads::split /*split*/)
: ParallelObject(x._problem.comm()),
_problem(x._problem),
_sys(x._sys),
_var_numbers(x._var_numbers),
_target_norm(x._target_norm)
void
RenormalizeVector::initialize()
{
// do one solution.close to get updated
_sys.solution->close();
}

void
RenormalizeVectorThread::operator()(const ConstElemRange & range)
RenormalizeVector::execute()
{
ParallelUniqueId puid;
_tid = puid.id;

// get the non linear system
auto & nl_sys = _problem.getNonlinearSystemBase();

mooseAssert(_sys, "We should have a system, did you forget to specify any variable in vars?");
auto & dof_map = _sys->get_dof_map();
auto & dof_map = _sys.get_dof_map();
const auto local_dof_begin = dof_map.first_dof();
const auto local_dof_end = dof_map.end_dof();

std::vector<std::vector<dof_id_type>> dof_indices(_var_numbers.size());
std::vector<Real> cache(_var_numbers.size());

for (const auto & elem : range)
for (const auto & elem : *_mesh.getActiveLocalElementRange())
{
// prepare variable dofs
for (const auto i : index_range(_var_numbers))
Expand All @@ -166,9 +83,9 @@ RenormalizeVectorThread::operator()(const ConstElemRange & range)

// iterate over current, old, and older solutions
for (const auto s : make_range(3))
if (nl_sys.hasSolutionState(s))
if (_nl_sys.hasSolutionState(s))
{
auto & solution = nl_sys.solutionState(s);
auto & solution = _nl_sys.solutionState(s);

// loop over all DOFs
for (const auto j : index_range(dof_indices[0]))
Expand All @@ -194,3 +111,13 @@ RenormalizeVectorThread::operator()(const ConstElemRange & range)
}
}
}

void
RenormalizeVector::finalize()
{
for (const auto s : make_range(3))
if (_nl_sys.hasSolutionState(s))
_nl_sys.solutionState(s).close();

_sys.update();
}

0 comments on commit 3548e6f

Please sign in to comment.