Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more checks in periodic boundary conditions #29124

Open
wants to merge 3 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.'
[]
[]
[]