Skip to content

Commit

Permalink
Merge pull request #29124 from GiudGiud/PR_periodic_impr
Browse files Browse the repository at this point in the history
Add more checks in periodic boundary conditions
  • Loading branch information
GiudGiud authored Nov 27, 2024
2 parents cbffa02 + 739a663 commit 96e51aa
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 51 deletions.
55 changes: 40 additions & 15 deletions framework/src/actions/AddPeriodicBCAction.C
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ AddPeriodicBCAction::validParams()
InputParameters params = Action::validParams();
params.addParam<std::vector<std::string>>("auto_direction",
"If using a generated mesh, you can "
"specifiy just the dimension(s) you "
"specify just the dimension(s) you "
"want to mark as periodic");

params.addParam<BoundaryName>("primary", "Boundary ID associated with the primary boundary.");
Expand All @@ -46,20 +46,36 @@ AddPeriodicBCAction::validParams()
params.addParam<std::vector<std::string>>("inv_transform_func",
"Functions that specify the inverse transformation");

params.addParam<std::vector<VariableName>>("variable", {}, "Variable for the periodic boundary");
params.addParam<std::vector<VariableName>>(
"variable", {}, "Variable for the periodic boundary condition");
params.addClassDescription("Action that adds periodic boundary conditions");
return params;
}

AddPeriodicBCAction::AddPeriodicBCAction(const InputParameters & params)
: Action(params), _mesh(nullptr)
{
// Check for inconsistent parameters
if (isParamValid("auto_direction"))
{
if (isParamValid("primary") || isParamValid("secondary") || isParamValid("translation") ||
isParamValid("transform_func") || isParamValid("inv_transform_func"))
paramError(
"auto_direction",
"Using the automatic periodic boundary detection does not require additional parameters");
}
else if (!isParamValid("primary") || !isParamValid("secondary"))
paramError("primary", "Both a primary and secondary boundary must be specified");
}

void
AddPeriodicBCAction::setPeriodicVars(PeriodicBoundaryBase & p,
const std::vector<VariableName> & var_names)
{
// TODO: multi-system
if (_problem->numSolverSystems() > 1)
mooseError("Multiple solver systems currently not supported");

NonlinearSystemBase & nl = _problem->getNonlinearSystemBase(/*nl_sys_num=*/0);
const std::vector<VariableName> * var_names_ptr;

Expand All @@ -71,6 +87,7 @@ AddPeriodicBCAction::setPeriodicVars(PeriodicBoundaryBase & p,

for (const auto & var_name : *var_names_ptr)
{
// Exclude scalar variables for which periodic boundary conditions dont make sense
if (!nl.hasScalarVariable(var_name))
{
unsigned int var_num = nl.getVariable(0, var_name).number();
Expand Down Expand Up @@ -128,9 +145,10 @@ AddPeriodicBCAction::autoTranslationBoundaries()
v(component) = _mesh->dimensionWidth(component);
PeriodicBoundary p(v);

if (boundary_ids == NULL)
mooseError(
"Couldn't auto-detect a paired boundary for use with periodic boundary conditions");
if (boundary_ids == nullptr)
mooseError("Couldn't auto-detect a paired boundary for use with periodic boundary "
"conditions in the '" +
dir + "' direction");

p.myboundary = boundary_ids->first;
p.pairedboundary = boundary_ids->second;
Expand Down Expand Up @@ -169,8 +187,8 @@ AddPeriodicBCAction::act()
"_mesh by now");

rm_params.set<MooseMesh *>("mesh") = _mesh;
// The default GhostPointNeighbors ghosting functor in libMesh handles the geometric ghosting of
// periodic boundaries for us, so we only need to handle the algebraic ghosting here
// The default GhostPointNeighbors ghosting functor in libMesh handles the geometric ghosting
// of periodic boundaries for us, so we only need to handle the algebraic ghosting here
rm_params.set<Moose::RelationshipManagerType>("rm_type") =
Moose::RelationshipManagerType::ALGEBRAIC;

Expand All @@ -194,13 +212,21 @@ AddPeriodicBCAction::act()

if (!autoTranslationBoundaries())
{
// Check that the boundaries exist in the mesh
const auto & primary_name = getParam<BoundaryName>("primary");
const auto & secondary_name = getParam<BoundaryName>("secondary");
if (!MooseMeshUtils::hasBoundaryName(*_mesh, primary_name))
paramError("primary", "Boundary '" + primary_name + "' does not exist in the mesh");
if (!MooseMeshUtils::hasBoundaryName(*_mesh, secondary_name))
paramError("secondary", "Boundary '" + secondary_name + "' does not exist in the mesh");

if (_pars.isParamValid("translation"))
{
RealVectorValue translation = getParam<RealVectorValue>("translation");

PeriodicBoundary p(translation);
p.myboundary = _mesh->getBoundaryID(getParam<BoundaryName>("primary"));
p.pairedboundary = _mesh->getBoundaryID(getParam<BoundaryName>("secondary"));
p.myboundary = _mesh->getBoundaryID(primary_name);
p.pairedboundary = _mesh->getBoundaryID(secondary_name);
setPeriodicVars(p, getParam<std::vector<VariableName>>("variable"));

auto & eq = _problem->es();
Expand All @@ -225,15 +251,13 @@ AddPeriodicBCAction::act()
mooseError("You must provide an inv_transform_func for FunctionPeriodicBoundary!");

FunctionPeriodicBoundary pb(*_problem, fn_names);
pb.myboundary = _mesh->getBoundaryID(getParam<BoundaryName>("primary"));
pb.pairedboundary = _mesh->getBoundaryID(getParam<BoundaryName>("secondary"));
pb.myboundary = _mesh->getBoundaryID(primary_name);
pb.pairedboundary = _mesh->getBoundaryID(secondary_name);
setPeriodicVars(pb, getParam<std::vector<VariableName>>("variable"));

FunctionPeriodicBoundary ipb(*_problem, inv_fn_names);
ipb.myboundary =
_mesh->getBoundaryID(getParam<BoundaryName>("secondary")); // these are swapped
ipb.pairedboundary =
_mesh->getBoundaryID(getParam<BoundaryName>("primary")); // these are swapped
ipb.myboundary = _mesh->getBoundaryID(secondary_name); // these are swapped
ipb.pairedboundary = _mesh->getBoundaryID(primary_name); // these are swapped
setPeriodicVars(ipb, getParam<std::vector<VariableName>>("variable"));

// Add the pair of periodic boundaries to the dof map
Expand All @@ -257,6 +281,7 @@ AddPeriodicBCAction::act()
}

// Now make sure that the mesh default ghosting functor has its periodic bcs set
// TODO: multi-system
_mesh->getMesh().default_ghosting().set_periodic_boundaries(
nl.dofMap().get_periodic_boundaries());
if (displaced_problem)
Expand Down
18 changes: 18 additions & 0 deletions framework/src/mesh/MooseMesh.C
Original file line number Diff line number Diff line change
Expand Up @@ -2047,14 +2047,32 @@ MooseMesh::detectPairedSidesets()
if (minus_x_ids[side_dim].size() == 1 && plus_x_ids[side_dim].size() == 1)
_paired_boundary.emplace_back(
std::make_pair(*(minus_x_ids[side_dim].begin()), *(plus_x_ids[side_dim].begin())));
else
mooseInfoRepeated(
"For side dimension " + std::to_string(side_dim) +
" we did not find paired boundaries (sidesets) in X due to the presence of " +
std::to_string(minus_x_ids[side_dim].size()) + " -X normal and " +
std::to_string(plus_x_ids[side_dim].size()) + " +X normal boundaries.");

if (minus_y_ids[side_dim].size() == 1 && plus_y_ids[side_dim].size() == 1)
_paired_boundary.emplace_back(
std::make_pair(*(minus_y_ids[side_dim].begin()), *(plus_y_ids[side_dim].begin())));
else
mooseInfoRepeated(
"For side dimension " + std::to_string(side_dim) +
" we did not find paired boundaries (sidesets) in Y due to the presence of " +
std::to_string(minus_y_ids[side_dim].size()) + " -Y normal and " +
std::to_string(plus_y_ids[side_dim].size()) + " +Y normal boundaries.");

if (minus_z_ids[side_dim].size() == 1 && plus_z_ids[side_dim].size() == 1)
_paired_boundary.emplace_back(
std::make_pair(*(minus_z_ids[side_dim].begin()), *(plus_z_ids[side_dim].begin())));
else
mooseInfoRepeated(
"For side dimension " + std::to_string(side_dim) +
" we did not find paired boundaries (sidesets) in Z due to the presence of " +
std::to_string(minus_z_ids[side_dim].size()) + " -Z normal and " +
std::to_string(plus_z_ids[side_dim].size()) + " +Z normal boundaries.");
}
}

Expand Down
105 changes: 69 additions & 36 deletions test/tests/bcs/periodic/tests
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
[Tests]
issues = '#935 #1530'
design = 'syntax/BCs/Periodic/index.md'
[./all_periodic_trans_test]
[all_periodic_trans_test]
type = 'Exodiff'
input = 'all_periodic_trans.i'
exodiff = 'all_periodic_trans_out.e'
requirement = "The system shall support periodic boundary conditions with transforms defined as functions."
[../]
[]

[./auto_wrap_2d_test]
[auto_wrap_2d_test]
type = 'Exodiff'
input = 'auto_periodic_bc_test.i'
exodiff = 'out_auto.e'
group = 'periodic'
abs_zero = 1e-6
rel_err = 1e-5
requirement = "The system shall support periodic boundary conditions with transforms that are computed automatically in the 'x' and 'y' directions."
[../]
[]

[./auto_wrap_2d_test_non_generated]
[auto_wrap_2d_test_non_generated]
type = 'Exodiff'
input = 'auto_periodic_bc_non_generated.i'
exodiff = 'out_auto_non_generated.e'
requirement = "The system shall support periodic boundary conditions with transforms that are computed automatically in the 'x' and 'y' directions using a non-generated mesh."
[../]
[]

[./auto_wrap_2d_test_error_check]
[auto_wrap_2d_test_error_check]
type = 'RunException'
input = 'auto_periodic_bc_test.i'
expect_err = '"point" is outside of the domain'
cli_args = 'AuxKernels/periodic_dist/point="0 99999 0"'
prereq = 'auto_wrap_2d_test'
requirement = "The system shall produce an error within the PeriodicDistanceAux object when a point is provided that is outside the mesh domain."
[../]
[]

[./auto_wrap_3d_test]
[auto_wrap_3d_test]
type = 'Exodiff'
input = ' auto_periodic_bc_test_3d.i '
exodiff = 'out_auto_3d.e'
Expand All @@ -45,63 +45,63 @@
# GridPartitioner is robust and beautiful
cli_args = 'Mesh/Partitioner/type=GridPartitioner'
requirement = "The system shall support periodic boundary conditions with transforms that are computed automatically in the 'x', 'y', and 'z' directions."
[../]
[]

[./orthogonal_pbc_on_square_test]
[orthogonal_pbc_on_square_test]
type = 'Exodiff'
input = 'orthogonal_pbc_on_square.i'
exodiff = 'orthogonal_pbc_on_square_out.e'
use_old_floor = true
requirement = "The system shall support periodic boundary conditions on orthogonal boundaries with transforms defined as functions."
[../]
[]

[./parallel_pbc_using_trans_test]
[parallel_pbc_using_trans_test]
type = 'Exodiff'
input = ' parallel_pbc_using_trans.i '
exodiff = 'parallel_pbc_using_trans_out.e'
requirement = "The system shall support periodic boundary conditions on parallel boundaries with transforms defined as functions."
[../]
[]

[./subdomain_restricted_vars_test]
[subdomain_restricted_vars_test]
type = 'Exodiff'
input = 'periodic_subdomain_restricted_test.i'
exodiff = 'out_restrict.e'
group = 'periodic'
deleted = 'Libmesh Bug #1410'
requirement = "The system shall support periodic boundary conditions on subdomain restricted variables."
[../]
[]

[./testlevel1]
[testlevel1]
type = 'Exodiff'
input = 'periodic_level_1_test.i'
exodiff = 'periodic_level_1_test_out.e periodic_level_1_test_out.e-s004 periodic_level_1_test_out.e-s007'
max_parallel = 4
valgrind = 'HEAVY'
abs_zero = 1e-6
requirement = "The system shall support periodic boundary conditions with mesh adaptivity."
[../]
[]

[./testperiodic]
[testperiodic]
type = 'Exodiff'
input = 'periodic_bc_test.i'
exodiff = 'out.e'
group = 'periodic'
abs_zero = 1e-6
rel_err = 1e-5
requirement = "The system shall support periodic boundary conditions with transforms prescribed as a translation."
[../]
[]

[./testperiodic_vector]
[testperiodic_vector]
type = 'Exodiff'
input = 'periodic_vector_bc_test.i'
exodiff = 'vector_out.e'
group = 'periodic'
abs_zero = 1e-6
rel_err = 1e-5
requirement = "The system shall support periodic boundary conditions on vector variables with transforms prescribed as a translation."
[../]
[]

[./testperiodic_dp]
[testperiodic_dp]
type = 'Exodiff'
input = 'periodic_bc_displaced_problem.i'
exodiff = 'out_displaced_problem.e'
Expand All @@ -110,53 +110,86 @@
max_parallel = 2
min_parallel = 2
requirement = "The system shall support periodic boundary conditions with displacements."
[../]
[]

[./testtrapezoid]
[testtrapezoid]
type = 'Exodiff'
input = 'trapezoid.i'
exodiff = 'out_trapezoid.e'
requirement = "The system shall support periodic boundary conditions on a trapezoid domain with transforms prescribed as functions."
[../]
[]

[./trapezoid_non_periodic]
[trapezoid_non_periodic]
type = 'Exodiff'
input = 'trapezoid_non_periodic.i'
exodiff = 'trapezoid_non_periodic_out.e'
design = 'mesh/MooseMesh.md'
issues = '#11939'
requirement = "The system shall support calls to periodic distance and bounds methods on the mesh when periodic boundary conditions are not used."
[../]
[]

[./testwedge]
[testwedge]
type = 'Exodiff'
input = 'wedge.i'
exodiff = 'out_wedge.e'
requirement = "The system shall support periodic boundary conditions on a wedge domain with transforms prescribed as functions."
[../]
[]

[./testwedgesys]
[testwedgesys]
type = 'Exodiff'
input = ' wedge_sys.i '
exodiff = 'out_wedge_sys.e'
max_parallel = 1
requirement = "The system shall support periodic boundary conditions for a single variable on a wedge domain with transforms prescribed as functions."
[../]
[]

[./auto_dir_repeated_id]
[auto_dir_repeated_id]
type = 'Exodiff'
input = 'auto_dir_repeated_id.i'
exodiff = 'auto_dir_repeated_id_out.e'
requirement = "The system shall support periodic boundary conditions for input meshes that have repeated element ids."
[../]
[]

[./no_add_scalar]
[no_add_scalar]
type = 'Exodiff'
input = 'no_add_scalar.i'
exodiff = 'no_add_scalar_out.e'

requirement = "When using periodic boundary detection, the system shall not attempt to add periodic boundary conditions to scalar variables."
design = 'source/actions/AddPeriodicBCAction.md'
issues = '#11417'
[../]
[]

[exceptions]
requirement = 'The system shall throw an error if'
issues = '#22496'
[multi_sys]
type = RunException
expect_err = 'Multiple solver systems currently not supported'
input = 'all_periodic_trans.i'
cli_args = "Problem/nl_sys_names='nl0 nl1'"
detail = 'multiple solver systems are being used as it is currently unsupported,'
[]
[bad_params]
type = RunException
expect_err = 'Using the automatic periodic boundary detection does not require additional parameters'
input = 'all_periodic_trans.i'
cli_args = "BCs/Periodic/x/auto_direction=x"
detail = 'additional parameters are passed when using the automatic periodic boundary detection option,'
[]
[bad_primary]
type = RunException
expect_err = "Boundary 'abs' does not exist in the mesh"
input = 'all_periodic_trans.i'
cli_args = "BCs/Periodic/x/primary='abs'"
detail = 'the primary boundary of a periodic boundary condition does not exist on the mesh, or'
[]
[bad_secondary]
type = RunException
expect_err = "Boundary 'abs' does not exist in the mesh"
input = 'all_periodic_trans.i'
cli_args = "BCs/Periodic/x/secondary='abs'"
detail = 'the secondary boundary of a periodic boundary condition does not exist on the mesh.'
[]
[]
[]

0 comments on commit 96e51aa

Please sign in to comment.