Skip to content

Commit

Permalink
Merge pull request #28570 from jmeier/FEProblem_deduplicate_variable_…
Browse files Browse the repository at this point in the history
…checks

check block-restriction in duplicateVariableCheck
  • Loading branch information
GiudGiud authored Sep 24, 2024
2 parents ee78ae4 + dcd356f commit f5681a9
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 28 deletions.
5 changes: 4 additions & 1 deletion framework/include/problems/FEProblemBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -2588,7 +2588,10 @@ class FEProblemBase : public SubProblem, public Restartable
void meshChangedHelper(bool intermediate_change = false);

/// Helper to check for duplicate variable names across systems or within a single system
bool duplicateVariableCheck(const std::string & var_name, const FEType & type, bool is_aux);
bool duplicateVariableCheck(const std::string & var_name,
const FEType & type,
bool is_aux,
const std::set<SubdomainID> * const active_subdomains);

void computeUserObjectsInternal(const ExecFlagType & type,
const Moose::AuxGroup & group,
Expand Down
105 changes: 95 additions & 10 deletions framework/src/problems/FEProblemBase.C
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ FEProblemBase::validParams()
"List of subdomains for material coverage check. The meaning of this list is controlled by "
"the parameter 'material_coverage_check' (whether this is the list of subdomains to be "
"checked, not to be checked or not taken into account).");

params.addParam<bool>("fv_bcs_integrity_check",
true,
"Set to false to disable checking of overlapping Dirichlet and Flux BCs "
Expand Down Expand Up @@ -2519,8 +2520,19 @@ FEProblemBase::getSampler(const std::string & name, const THREAD_ID tid)
bool
FEProblemBase::duplicateVariableCheck(const std::string & var_name,
const FEType & type,
bool is_aux)
bool is_aux,
const std::set<SubdomainID> * const active_subdomains)
{

std::set<SubdomainID> subdomainIDs;
if (active_subdomains->size() == 0)
{
const auto subdomains = _mesh.meshSubdomains();
subdomainIDs.insert(subdomains.begin(), subdomains.end());
}
else
subdomainIDs.insert(active_subdomains->begin(), active_subdomains->end());

for (auto & sys : _solver_systems)
{
SystemBase * curr_sys_ptr = sys.get();
Expand All @@ -2530,7 +2542,7 @@ FEProblemBase::duplicateVariableCheck(const std::string & var_name,
{
curr_sys_ptr = _aux.get();
other_sys_ptr = sys.get();
error_prefix = "Aux";
error_prefix = "aux";
}

if (other_sys_ptr->hasVariable(var_name))
Expand All @@ -2541,11 +2553,74 @@ FEProblemBase::duplicateVariableCheck(const std::string & var_name,
{
const Variable & var =
curr_sys_ptr->system().variable(curr_sys_ptr->system().variable_number(var_name));

// variable type
if (var.type() != type)
mooseError(error_prefix,
"Variable with name '",
{
const auto stringifyType = [](FEType t)
{ return Moose::stringify(t.family) + " of order " + Moose::stringify(t.order); };

mooseError("Mismatching types are specified for ",
error_prefix,
"variable with name '",
var_name,
"' already exists but is of a differing type!");
"': '",
stringifyType(var.type()),
"' and '",
stringifyType(type),
"'");
}

// block-restriction
if (!(active_subdomains->size() == 0 && var.active_subdomains().size() == 0))
{
const auto varActiveSubdomains = var.active_subdomains();
std::set<SubdomainID> varSubdomainIDs;
if (varActiveSubdomains.size() == 0)
{
const auto subdomains = _mesh.meshSubdomains();
varSubdomainIDs.insert(subdomains.begin(), subdomains.end());
}
else
varSubdomainIDs.insert(varActiveSubdomains.begin(), varActiveSubdomains.end());

// Is subdomainIDs a subset of varSubdomainIDs? With this we allow the case that the newly
// requested block restriction is only a subset of the existing one.
const auto isSubset = std::includes(varSubdomainIDs.begin(),
varSubdomainIDs.end(),
subdomainIDs.begin(),
subdomainIDs.end());

if (!isSubset)
{
// helper function: make a string from a set of subdomain ids
const auto stringifySubdomains = [this](std::set<SubdomainID> subdomainIDs)
{
std::stringstream s;
for (auto const i : subdomainIDs)
{
// do we need to insert a comma?
if (s.tellp() != 0)
s << ", ";

// insert subdomain name and id -or- only the id (if no name is given)
const auto subdomainName = _mesh.getSubdomainName(i);
if (subdomainName.empty())
s << i;
else
s << subdomainName << " (" << i << ")";
}
return s.str();
};

const std::string msg = "Mismatching block-restrictions are specified for " +
error_prefix + "variable with name '" + var_name + "': {" +
stringifySubdomains(varSubdomainIDs) + "} and {" +
stringifySubdomains(subdomainIDs) + "}";

mooseError(msg);
}
}

return true;
}
Expand All @@ -2564,7 +2639,12 @@ FEProblemBase::addVariable(const std::string & var_type,
auto fe_type = FEType(Utility::string_to_enum<Order>(params.get<MooseEnum>("order")),
Utility::string_to_enum<FEFamily>(params.get<MooseEnum>("family")));

if (duplicateVariableCheck(var_name, fe_type, /* is_aux = */ false))
const auto active_subdomains_vector =
_mesh.getSubdomainIDs(params.get<std::vector<SubdomainName>>("block"));
const std::set<SubdomainID> active_subdomains(active_subdomains_vector.begin(),
active_subdomains_vector.end());

if (duplicateVariableCheck(var_name, fe_type, /* is_aux = */ false, &active_subdomains))
return;

params.set<FEProblemBase *>("_fe_problem_base") = this;
Expand Down Expand Up @@ -2840,7 +2920,12 @@ FEProblemBase::addAuxVariable(const std::string & var_type,
auto fe_type = FEType(Utility::string_to_enum<Order>(params.get<MooseEnum>("order")),
Utility::string_to_enum<FEFamily>(params.get<MooseEnum>("family")));

if (duplicateVariableCheck(var_name, fe_type, /* is_aux = */ true))
const auto active_subdomains_vector =
_mesh.getSubdomainIDs(params.get<std::vector<SubdomainName>>("block"));
const std::set<SubdomainID> active_subdomains(active_subdomains_vector.begin(),
active_subdomains_vector.end());

if (duplicateVariableCheck(var_name, fe_type, /* is_aux = */ true, &active_subdomains))
return;

params.set<FEProblemBase *>("_fe_problem_base") = this;
Expand All @@ -2862,7 +2947,7 @@ FEProblemBase::addAuxVariable(const std::string & var_name,

mooseDeprecated("Please use the addAuxVariable(var_type, var_name, params) API instead");

if (duplicateVariableCheck(var_name, type, /* is_aux = */ true))
if (duplicateVariableCheck(var_name, type, /* is_aux = */ true, active_subdomains))
return;

std::string var_type;
Expand Down Expand Up @@ -2901,7 +2986,7 @@ FEProblemBase::addAuxArrayVariable(const std::string & var_name,

mooseDeprecated("Please use the addAuxVariable(var_type, var_name, params) API instead");

if (duplicateVariableCheck(var_name, type, /* is_aux = */ true))
if (duplicateVariableCheck(var_name, type, /* is_aux = */ true, active_subdomains))
return;

InputParameters params = _factory.getValidParams("ArrayMooseVariable");
Expand Down Expand Up @@ -2935,7 +3020,7 @@ FEProblemBase::addAuxScalarVariable(const std::string & var_name,
_max_scalar_order = order;

FEType type(order, SCALAR);
if (duplicateVariableCheck(var_name, type, /* is_aux = */ true))
if (duplicateVariableCheck(var_name, type, /* is_aux = */ true, active_subdomains))
return;

InputParameters params = _factory.getValidParams("MooseVariableScalar");
Expand Down
1 change: 0 additions & 1 deletion modules/contact/examples/2d_indenter/indenter_rz_fine.i
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@

[Modules/TensorMechanics/Master]
[all]
add_variables = true
strain = FINITE
block = '1 2'
use_automatic_differentiation = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ offset = -0.045

[Modules/TensorMechanics/DynamicMaster]
[all]
add_variables = true
hht_alpha = 0.0
newmark_beta = 0.25
newmark_gamma = 0.5
mass_damping_coefficient = 0.0
stiffness_damping_coefficient = 1.0
accelerations = 'accel_x accel_y'
generate_output = 'stress_xx stress_yy'
block = '1 2'
strain = FINITE
Expand Down Expand Up @@ -87,6 +87,22 @@ offset = -0.045
[gap_vel]
block = 'normal_secondary_subdomain'
[]
[vel_x]
order = FIRST
family = LAGRANGE
[]
[vel_y]
order = FIRST
family = LAGRANGE
[]
[accel_x]
order = FIRST
family = LAGRANGE
[]
[accel_y]
order = FIRST
family = LAGRANGE
[]
[]

[AuxKernels]
Expand Down
33 changes: 27 additions & 6 deletions modules/porous_flow/test/tests/actions/block_restricted.i
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ PorousFlowDictatorName = 'dictator'
material_coverage_check = false
[]


[Mesh]
active_block_names = 'BaseMesh Box1'
[BaseMesh]
Expand Down Expand Up @@ -50,17 +49,33 @@ PorousFlowDictatorName = 'dictator'
[Physics]
[SolidMechanics]
[QuasiStatic]
[./all]
[all]
strain = SMALL
incremental = true
add_variables = true
block = ${Mesh/active_block_names}
generate_output = 'stress_xx stress_yy stress_zz'
[]
[]
[]
[]

[AuxVariables]
[stress_xx]
order = CONSTANT
family = MONOMIAL
block = 'BaseMesh'
[]
[stress_yy]
order = CONSTANT
family = MONOMIAL
block = 'BaseMesh'
[]
[stress_zz]
order = CONSTANT
family = MONOMIAL
block = 'BaseMesh'
[]
[]

[PorousFlowFullySaturated]
coupling_type = HydroMechanical
porepressure = porepressure
Expand All @@ -74,6 +89,12 @@ PorousFlowDictatorName = 'dictator'
[]

[Variables]
[disp_x]
[]
[disp_y]
[]
[disp_z]
[]
[porepressure]
order = SECOND
family = LAGRANGE
Expand Down Expand Up @@ -137,7 +158,7 @@ PorousFlowDictatorName = 'dictator'
[]

[FluidProperties]
[./simple_fluid]
[simple_fluid]
type = SimpleFluidProperties
bulk_modulus = 2E3
density0 = 1000
Expand Down Expand Up @@ -190,7 +211,7 @@ PorousFlowDictatorName = 'dictator'
poissons_ratio = 0.15
[]

[./stress]
[stress]
type = ComputeMultipleInelasticStress
inelastic_models = ''
perform_finite_strain_rotations = false
Expand Down
Binary file not shown.
6 changes: 4 additions & 2 deletions modules/solid_mechanics/src/actions/LineElementAction.C
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,8 @@ LineElementAction::actAddVariables()
for (const auto & disp : _displacements)
{
// Create displacement variables
_problem->addVariable("MooseVariable", disp, params);
if (!_problem->hasVariable(disp))
_problem->addVariable("MooseVariable", disp, params);
}

// Add rotation variables if line element is a beam.
Expand All @@ -486,7 +487,8 @@ LineElementAction::actAddVariables()
for (const auto & rot : _rotations)
{
// Create rotation variables
_problem->addVariable("MooseVariable", rot, params);
if (!_problem->hasVariable(rot))
_problem->addVariable("MooseVariable", rot, params);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ offset = 1.0
[]

[AuxVariables]
[vel_x]
order = FIRST
family = LAGRANGE
[]
[vel_y]
order = FIRST
family = LAGRANGE
[]
[accel_x]
order = FIRST
family = LAGRANGE
[]
[accel_y]
order = FIRST
family = LAGRANGE
[]
[pid]
order = CONSTANT
family = MONOMIAL
Expand Down Expand Up @@ -62,13 +78,13 @@ offset = 1.0

[Physics/SolidMechanics/Dynamic]
[all]
add_variables = true
hht_alpha = 0.0
beta = 0.25
gamma = 0.5
mass_damping_coefficient = 0.0
stiffness_damping_coefficient = 0.0
displacements = 'disp_x disp_y'
accelerations = 'accel_x accel_y'
generate_output = 'stress_xx stress_yy'
block = '1 2'
strain = FINITE
Expand Down Expand Up @@ -129,10 +145,8 @@ offset = 1.0
dt = 0.01
dtmin = .05
solve_type = 'PJFNK'
petsc_options = '-snes_converged_reason -ksp_converged_reason -pc_svd_monitor '
'-snes_linesearch_monitor'
petsc_options_iname = '-pc_type -pc_factor_shift_type -pc_factor_shift_amount -mat_mffd_err '
'-ksp_gmres_restart'
petsc_options = '-snes_converged_reason -ksp_converged_reason -pc_svd_monitor -snes_linesearch_monitor'
petsc_options_iname = '-pc_type -pc_factor_shift_type -pc_factor_shift_amount -mat_mffd_err -ksp_gmres_restart'
petsc_options_value = 'lu NONZERO 1e-15 1e-5 100'
l_max_its = 100
nl_max_its = 20
Expand Down
Loading

0 comments on commit f5681a9

Please sign in to comment.