diff --git a/framework/doc/content/source/meshgenerators/MeshRepairGenerator.md b/framework/doc/content/source/meshgenerators/MeshRepairGenerator.md index 8222b09d2641..958060e44714 100644 --- a/framework/doc/content/source/meshgenerators/MeshRepairGenerator.md +++ b/framework/doc/content/source/meshgenerators/MeshRepairGenerator.md @@ -18,6 +18,9 @@ The operations currently implemented are: - merging boundaries with the same name but different boundary IDs. +- renumbering the nodes and elements to have a contiguous ordering. + + !syntax parameters /Mesh/MeshRepairGenerator !syntax inputs /Mesh/MeshRepairGenerator diff --git a/framework/src/meshgenerators/MeshRepairGenerator.C b/framework/src/meshgenerators/MeshRepairGenerator.C index a3fc01c4354a..6c26c8183762 100644 --- a/framework/src/meshgenerators/MeshRepairGenerator.C +++ b/framework/src/meshgenerators/MeshRepairGenerator.C @@ -41,6 +41,11 @@ MeshRepairGenerator::validParams() false, "Merge boundaries if they have the same name but different boundary IDs"); + params.addParam( + "renumber_contiguously", + false, + "Whether to renumber the elements of the mesh so the numbering is contiguous"); + return params; } @@ -54,7 +59,7 @@ MeshRepairGenerator::MeshRepairGenerator(const InputParameters & parameters) _boundary_id_merge(getParam("merge_boundary_ids_with_same_name")) { if (!_fix_overlapping_nodes && !_fix_element_orientation && !_elem_type_separation && - !_boundary_id_merge) + !_boundary_id_merge && !getParam("renumber_contiguously")) mooseError("No specific item to fix. Are any of the parameters misspelled?"); } @@ -83,6 +88,15 @@ MeshRepairGenerator::generate() if (_boundary_id_merge) MooseMeshUtils::mergeBoundaryIDsWithSameName(*mesh); + // Renumber the mesh despite any mesh flag + if (getParam("renumber_contiguously")) + { + const auto prev_status = mesh->allow_renumbering(); + mesh->allow_renumbering(true); + mesh->renumber_nodes_and_elements(); + mesh->allow_renumbering(prev_status); + } + mesh->set_isnt_prepared(); return mesh; } diff --git a/framework/src/meshgenerators/SideSetExtruderGenerator.C b/framework/src/meshgenerators/SideSetExtruderGenerator.C index 0a9d1123aac7..f135ed089108 100644 --- a/framework/src/meshgenerators/SideSetExtruderGenerator.C +++ b/framework/src/meshgenerators/SideSetExtruderGenerator.C @@ -79,7 +79,7 @@ SideSetExtruderGenerator::SideSetExtruderGenerator(const InputParameters & param } { - auto params = _app.getFactory().getValidParams("StitchedMeshGenerator"); + auto params = _app.getFactory().getValidParams("StitchMeshGenerator"); // order of vector elements matters for this generator // here order by: original mesh first, our custom mesh second @@ -89,7 +89,7 @@ SideSetExtruderGenerator::SideSetExtruderGenerator(const InputParameters & param {_sideset_name, sideset_to_stitch}}; // stitch the newly made high-dimensional mesh back to the original mesh - addMeshSubgenerator("StitchedMeshGenerator", name() + "_stitched", params); + addMeshSubgenerator("StitchMeshGenerator", name() + "_stitched", params); _build_mesh = &getMeshByName(name() + "_stitched"); } } diff --git a/modules/navier_stokes/src/physics/WCNSFVFlowPhysics.C b/modules/navier_stokes/src/physics/WCNSFVFlowPhysics.C index 6a41cb03e847..afac57d20247 100644 --- a/modules/navier_stokes/src/physics/WCNSFVFlowPhysics.C +++ b/modules/navier_stokes/src/physics/WCNSFVFlowPhysics.C @@ -666,7 +666,7 @@ WCNSFVFlowPhysics::addMomentumFrictionKernels() params.set("Forchheimer_name") = _friction_coeffs[block_i][type_i]; } else - paramError("momentum_friction_types", + paramError("friction_types", "Friction type '", _friction_types[block_i][type_i], "' is not implemented"); diff --git a/modules/navier_stokes/src/physics/WCNSLinearFVFlowPhysics.C b/modules/navier_stokes/src/physics/WCNSLinearFVFlowPhysics.C index a53e8f16e37b..c14d753a8ad2 100644 --- a/modules/navier_stokes/src/physics/WCNSLinearFVFlowPhysics.C +++ b/modules/navier_stokes/src/physics/WCNSLinearFVFlowPhysics.C @@ -325,7 +325,7 @@ WCNSLinearFVFlowPhysics::addMomentumFrictionKernels() params.set("Darcy_name") = _friction_coeffs[block_i][type_i]; } else - paramError("momentum_friction_types", + paramError("friction_types", "Friction type '", _friction_types[block_i][type_i], "' is not implemented"); @@ -528,6 +528,7 @@ void WCNSLinearFVFlowPhysics::addWallsBC() { const std::string u_names[3] = {"u", "v", "w"}; + bool has_symmetry_bc = false; for (const auto & [boundary_name, momentum_wall_type] : _momentum_wall_types) { @@ -548,19 +549,61 @@ WCNSLinearFVFlowPhysics::addWallsBC() getProblem().addLinearFVBC(bc_type, _velocity_names[d] + "_" + boundary_name, params); } } + else if (momentum_wall_type == "symmetry") + { + has_symmetry_bc = true; + { + const std::string bc_type = "LinearFVVelocitySymmetryBC"; + InputParameters params = getFactory().getValidParams(bc_type); + params.set>("boundary") = {boundary_name}; + for (unsigned int d = 0; d < dimension(); ++d) + params.set(u_names[d]) = _velocity_names[d]; + + for (const auto d : make_range(dimension())) + { + params.set("variable") = _velocity_names[d]; + params.set("momentum_component") = NS::directions[d]; + + getProblem().addLinearFVBC(bc_type, _velocity_names[d] + "_" + boundary_name, params); + } + } + { + const std::string bc_type = "LinearFVPressureSymmetryBC"; + InputParameters params = getFactory().getValidParams(bc_type); + params.set>("boundary") = {boundary_name}; + params.set("variable") = _pressure_name; + params.set("HbyA_flux") = "HbyA"; + getProblem().addLinearFVBC(bc_type, _pressure_name + "_" + boundary_name, params); + } + } else mooseError("Unsupported wall boundary condition type: " + std::string(momentum_wall_type)); } if (getParam("pressure_two_term_bc_expansion")) { - const std::string bc_type = "LinearFVExtrapolatedPressureBC"; - InputParameters params = getFactory().getValidParams(bc_type); - params.set>("boundary") = _wall_boundaries; - params.set("variable") = _pressure_name; - params.set("use_two_term_expansion") = true; - getProblem().addLinearFVBC( - bc_type, _pressure_name + "_extrapolation_" + Moose::stringify(_wall_boundaries), params); + if (!has_symmetry_bc) + { + const std::string bc_type = "LinearFVExtrapolatedPressureBC"; + InputParameters params = getFactory().getValidParams(bc_type); + params.set>("boundary") = _wall_boundaries; + params.set("variable") = _pressure_name; + params.set("use_two_term_expansion") = true; + getProblem().addLinearFVBC( + bc_type, _pressure_name + "_extrapolation_" + Moose::stringify(_wall_boundaries), params); + } + else + for (const auto & [boundary_name, momentum_wall_type] : _momentum_wall_types) + if (momentum_wall_type != "symmetry") + { + const std::string bc_type = "LinearFVExtrapolatedPressureBC"; + InputParameters params = getFactory().getValidParams(bc_type); + params.set>("boundary") = {boundary_name}; + params.set("variable") = _pressure_name; + params.set("use_two_term_expansion") = true; + getProblem().addLinearFVBC( + bc_type, _pressure_name + "_extrapolation_" + boundary_name, params); + } } } diff --git a/modules/navier_stokes/test/tests/finite_volume/ins/channel-flow/linear-segregated/2d-symmetric/channel-physics.i b/modules/navier_stokes/test/tests/finite_volume/ins/channel-flow/linear-segregated/2d-symmetric/channel-physics.i new file mode 100644 index 000000000000..74b8c35c74c5 --- /dev/null +++ b/modules/navier_stokes/test/tests/finite_volume/ins/channel-flow/linear-segregated/2d-symmetric/channel-physics.i @@ -0,0 +1,118 @@ +mu = 2.6 +rho = 1.2 +advected_interp_method = 'upwind' +u_inlet = 1.1 +half_width = 0.2 + +[Mesh] + [mesh] + type = CartesianMeshGenerator + dim = 2 + dx = '1.0' + dy = '${half_width}' + ix = '30' + iy = '15' + subdomain_id = '0' + [] + allow_renumbering = false +[] + +[Problem] + linear_sys_names = 'u_system v_system pressure_system' + previous_nl_solution_required = true +[] + +[Physics] + [NavierStokes] + [FlowSegregated/flow] + velocity_variable = 'vel_x vel_y' + pressure_variable = 'pressure' + + initial_velocity = '0.5 0 0' + initial_pressure = '0.2' + + density = ${rho} + dynamic_viscosity = ${mu} + + inlet_boundaries = 'left' + momentum_inlet_types = 'fixed-velocity' + momentum_inlet_functors = '${u_inlet} 0' + + wall_boundaries = 'top bottom' + momentum_wall_types = 'noslip symmetry' + + outlet_boundaries = 'right' + momentum_outlet_types = 'fixed-pressure' + pressure_functors = '1.4' + + orthogonality_correction = false + pressure_two_term_bc_expansion = true + momentum_two_term_bc_expansion = true + momentum_advection_interpolation = ${advected_interp_method} + [] + [] +[] + + +[Functions] + [u_parabolic_profile] + type = ParsedFunction + expression = '3/2*${u_inlet}*(1 - pow(y/${half_width}, 2))' # Poiseuille profile + [] + [u_parabolic_profile_rz] + type = ParsedFunction + expression = '2*${u_inlet}*(1 - pow(y/${half_width}, 2))' # Cylindrical profile + [] +[] + +[AuxVariables] + [vel_exact] + type = MooseLinearVariableFVReal + [] +[] + +[AuxKernels] + [assign_vel_exact] + type = FunctionAux + variable = vel_exact + function = u_parabolic_profile + execute_on = TIMESTEP_END + [] +[] + +[VectorPostprocessors] + [outlet_velocity_profile] + type = SideValueSampler + variable = 'vel_x vel_exact' + boundary = 'right' + sort_by = 'y' + execute_on = TIMESTEP_END + [] +[] + +[Executioner] + type = SIMPLE + momentum_l_abs_tol = 1e-12 + pressure_l_abs_tol = 1e-12 + momentum_l_tol = 0 + pressure_l_tol = 0 + rhie_chow_user_object = 'ins_rhie_chow_interpolator' + momentum_systems = 'u_system v_system' + pressure_system = 'pressure_system' + momentum_equation_relaxation = 0.5 + pressure_variable_relaxation = 0.3 + num_iterations = 1000 + pressure_absolute_tolerance = 1e-10 + momentum_absolute_tolerance = 1e-10 + momentum_petsc_options_iname = '-pc_type -pc_hypre_type' + momentum_petsc_options_value = 'hypre boomeramg' + pressure_petsc_options_iname = '-pc_type -pc_hypre_type' + pressure_petsc_options_value = 'hypre boomeramg' + print_fields = false + continue_on_max_its = true +[] + +[Outputs] + csv = true + execute_on = timestep_end +[] diff --git a/modules/navier_stokes/test/tests/finite_volume/ins/channel-flow/linear-segregated/2d-symmetric/gold/channel-physics_out_outlet_velocity_profile_0001.csv b/modules/navier_stokes/test/tests/finite_volume/ins/channel-flow/linear-segregated/2d-symmetric/gold/channel-physics_out_outlet_velocity_profile_0001.csv new file mode 120000 index 000000000000..60f9947215a1 --- /dev/null +++ b/modules/navier_stokes/test/tests/finite_volume/ins/channel-flow/linear-segregated/2d-symmetric/gold/channel-physics_out_outlet_velocity_profile_0001.csv @@ -0,0 +1 @@ +channel_out_outlet_velocity_profile_0001.csv \ No newline at end of file diff --git a/modules/navier_stokes/test/tests/finite_volume/ins/channel-flow/linear-segregated/2d-symmetric/tests b/modules/navier_stokes/test/tests/finite_volume/ins/channel-flow/linear-segregated/2d-symmetric/tests index 4964e3e1817e..49ea28f7eac5 100644 --- a/modules/navier_stokes/test/tests/finite_volume/ins/channel-flow/linear-segregated/2d-symmetric/tests +++ b/modules/navier_stokes/test/tests/finite_volume/ins/channel-flow/linear-segregated/2d-symmetric/tests @@ -11,6 +11,14 @@ max_threads = 1 # see libmesh issue #3808 detail = "in a Cartesian coordinate system," [] + [cartesian-physics] + type = 'CSVDiff' + input = channel-physics.i + csvdiff = 'channel-physics_out_outlet_velocity_profile_0001.csv' + recover = false # we don't support recovery for SIMPLE yet + max_threads = 1 # see libmesh issue #3808 + detail = "in a Cartesian coordinate system using the Physics shorthand syntax," + [] [rz] type = 'CSVDiff' input = channel.i