diff --git a/framework/include/base/MooseObjectUnitTest.h b/framework/include/base/MooseObjectUnitTest.h index a6a0a064eba9..020b6cd3849e 100644 --- a/framework/include/base/MooseObjectUnitTest.h +++ b/framework/include/base/MooseObjectUnitTest.h @@ -78,6 +78,7 @@ class MooseObjectUnitTest : public ::testing::Test mesh_params.set("_type") = "GeneratedMesh"; mesh_params.set("dim") = "3"; _mesh = libmesh_make_unique(mesh_params); + _mesh->setMeshBase(_mesh->buildMeshBaseObject()); InputParameters problem_params = _factory.getValidParams("FEProblem"); problem_params.set("mesh") = _mesh.get(); diff --git a/framework/include/mesh/FileMesh.h b/framework/include/mesh/FileMesh.h index 4309a8f70496..8c472892fed5 100644 --- a/framework/include/mesh/FileMesh.h +++ b/framework/include/mesh/FileMesh.h @@ -43,8 +43,12 @@ class FileMesh : public MooseMesh /// Auxiliary object for restart std::unique_ptr _exreader; + /// The requested dimension of the mesh. For some file meshes, this is not required may be implied + /// from the element type(s). + const unsigned int _dim; + /// Timers - PerfID _read_mesh_timer; + const PerfID _read_mesh_timer; }; #endif // FILEMESH_H diff --git a/framework/include/mesh/MooseMesh.h b/framework/include/mesh/MooseMesh.h index f3ebad100447..2faebe3681e3 100644 --- a/framework/include/mesh/MooseMesh.h +++ b/framework/include/mesh/MooseMesh.h @@ -78,11 +78,16 @@ class MooseMesh : public MooseObject, public Restartable, public PerfGraphInterf MooseMesh(const InputParameters & parameters); MooseMesh(const MooseMesh & other_mesh); - /** - * Destructor - */ virtual ~MooseMesh(); + // The type of libMesh::MeshBase that will be used + enum class ParallelType + { + DEFAULT, + REPLICATED, + DISTRIBUTED + }; + /** * Clone method. Allocates memory you are responsible to clean up. */ @@ -95,6 +100,18 @@ class MooseMesh : public MooseObject, public Restartable, public PerfGraphInterf */ virtual std::unique_ptr safeClone() const = 0; + /** + * Method to construct a libMesh::MeshBase object that is normally set and used by the MooseMesh + * object during the "init()" phase. + */ + std::unique_ptr buildMeshBaseObject(ParallelType override_type = ParallelType::DEFAULT); + + /** + * Method to set the mesh_base object. If this method is NOT called prior to calling init(), a + * MeshBase object will be automatically constructed and set. + */ + void setMeshBase(std::unique_ptr mesh_base); + /** * Initialize the Mesh object. Most of the time this will turn around * and call build_mesh so the child class can build the Mesh object. @@ -838,7 +855,7 @@ class MooseMesh : public MooseObject, public Restartable, public PerfGraphInterf /// Can be set to DISTRIBUTED, REPLICATED, or DEFAULT. Determines whether /// the underlying libMesh mesh is a ReplicatedMesh or DistributedMesh. - MooseEnum _mesh_parallel_type; + ParallelType _parallel_type; /// False by default. Final value is determined by several factors /// including the 'distribution' setting in the input file, and whether diff --git a/framework/include/mesh/PatternedMesh.h b/framework/include/mesh/PatternedMesh.h index f8caa973ba30..8bb871747d3b 100644 --- a/framework/include/mesh/PatternedMesh.h +++ b/framework/include/mesh/PatternedMesh.h @@ -38,7 +38,7 @@ class PatternedMesh : public MooseMesh public: PatternedMesh(const InputParameters & parameters); PatternedMesh(const PatternedMesh & other_mesh); - virtual ~PatternedMesh(); + virtual ~PatternedMesh() = default; virtual std::unique_ptr safeClone() const override; diff --git a/framework/include/mesh/StitchedMesh.h b/framework/include/mesh/StitchedMesh.h index 5ff43d3635a3..79a20bd13135 100644 --- a/framework/include/mesh/StitchedMesh.h +++ b/framework/include/mesh/StitchedMesh.h @@ -33,8 +33,6 @@ class StitchedMesh : public MooseMesh StitchedMesh(const InputParameters & parameters); StitchedMesh(const StitchedMesh & other_mesh); - virtual ~StitchedMesh(); - virtual std::unique_ptr safeClone() const override; virtual void buildMesh() override; diff --git a/framework/include/meshgenerators/MeshGenerator.h b/framework/include/meshgenerators/MeshGenerator.h index 38571aafde81..b0eb605aa2bd 100644 --- a/framework/include/meshgenerators/MeshGenerator.h +++ b/framework/include/meshgenerators/MeshGenerator.h @@ -13,6 +13,9 @@ #include "MooseObject.h" #include "Restartable.h" +// Included so mesh generators don't need to include this when constructing MeshBase objects +#include "MooseMesh.h" + #include "libmesh/mesh_base.h" // Forward declarations @@ -66,6 +69,9 @@ class MeshGenerator : public MooseObject, public Restartable std::unique_ptr & getMeshByName(const MeshGeneratorName & input_mesh_generator_parameter_name); + /// References to the mesh and displaced mesh (currently in the ActionWarehouse) + std::shared_ptr & _mesh; + private: /// A list of generators that are required to run before this generator may run std::vector _depends_on; diff --git a/framework/src/actions/AddMeshGeneratorAction.C b/framework/src/actions/AddMeshGeneratorAction.C index 05ed9d242329..bbae85f89fb0 100644 --- a/framework/src/actions/AddMeshGeneratorAction.C +++ b/framework/src/actions/AddMeshGeneratorAction.C @@ -34,5 +34,8 @@ AddMeshGeneratorAction::act() if (_app.isRecovering()) return; + if (!_mesh) + mooseError("No mesh file was supplied and no generation block was provided"); + _app.addMeshGenerator(_type, _name, _moose_object_pars); } diff --git a/framework/src/actions/SetupMeshAction.C b/framework/src/actions/SetupMeshAction.C index b17bb66c7a20..a2151829c9b6 100644 --- a/framework/src/actions/SetupMeshAction.C +++ b/framework/src/actions/SetupMeshAction.C @@ -16,7 +16,7 @@ #include "Factory.h" registerMooseAction("MooseApp", SetupMeshAction, "setup_mesh"); - +registerMooseAction("MooseApp", SetupMeshAction, "set_mesh_base"); registerMooseAction("MooseApp", SetupMeshAction, "init_mesh"); template <> @@ -218,6 +218,12 @@ SetupMeshAction::act() if (isParamValid("displacements") && getParam("use_displaced_mesh")) _displaced_mesh = _factory.create(_type, "displaced_mesh", _moose_object_pars); } + else if (_current_task == "set_mesh_base") + { + _mesh->setMeshBase(_mesh->buildMeshBaseObject()); + if (isParamValid("displacements") && getParam("use_displaced_mesh")) + _displaced_mesh->setMeshBase(_displaced_mesh->buildMeshBaseObject()); + } else if (_current_task == "init_mesh") { _mesh->init(); diff --git a/framework/src/base/Moose.C b/framework/src/base/Moose.C index 965ea01e32fc..9357160cba92 100644 --- a/framework/src/base/Moose.C +++ b/framework/src/base/Moose.C @@ -97,9 +97,10 @@ addActionTypes(Syntax & syntax) registerMooseObjectTask("determine_system_type", Executioner, true); registerMooseObjectTask("setup_mesh", MooseMesh, false); + registerMooseObjectTask("set_mesh_base", MooseMesh, false); registerMooseObjectTask("init_mesh", MooseMesh, false); registerMooseObjectTask("add_mesh_modifier", MeshModifier, false); - registerMooseObjectTask("add_mesh_generator", MeshGenerator, false); + registerMooseObjectTask("add_mesh_generator", MeshGenerator, false); registerMooseObjectTask("add_kernel", Kernel, false); appendMooseObjectTask ("add_kernel", EigenKernel); @@ -171,7 +172,7 @@ addActionTypes(Syntax & syntax) registerTask("uniform_refine_mesh", false); registerTask("prepare_mesh", false); registerTask("add_geometric_rm", true); - registerTask("setup_mesh_complete", false); // calls prepare + registerTask("setup_mesh_complete", true); // calls prepare registerTask("init_displaced_problem", false); @@ -232,10 +233,11 @@ addActionTypes(Syntax & syntax) "(common_output)" "(set_global_params)" "(setup_recover_file_base)" + "(setup_mesh)" "(add_mesh_generator)" "(execute_mesh_generators)" + "(set_mesh_base)" "(check_copy_nodal_vars)" - "(setup_mesh)" "(add_partitioner)" "(add_geometric_rm)" "(init_mesh)" diff --git a/framework/src/base/MooseApp.C b/framework/src/base/MooseApp.C index 6d1a2b06e9fc..9a65a7b252d3 100644 --- a/framework/src/base/MooseApp.C +++ b/framework/src/base/MooseApp.C @@ -1538,9 +1538,6 @@ MooseApp::executeMeshGenerators() } } } - - // Prepare the final mesh - _final_generated_mesh->prepare_for_use(); } } @@ -1589,12 +1586,11 @@ MooseApp::createMinimalApp() { TIME_SECTION(_create_minimal_app_timer); - // SetupMeshAction (setup_mesh) + // SetupMeshAction { // Build the Action parameters InputParameters action_params = _action_factory.getValidParams("SetupMeshAction"); action_params.set("type") = "GeneratedMesh"; - action_params.set("task") = "setup_mesh"; // Create The Action std::shared_ptr action = std::static_pointer_cast( @@ -1609,19 +1605,6 @@ MooseApp::createMinimalApp() _action_warehouse.addActionBlock(action); } - // SetupMeshAction (init_mesh) - { - // Action parameters - InputParameters action_params = _action_factory.getValidParams("SetupMeshAction"); - action_params.set("type") = "GeneratedMesh"; - action_params.set("task") = "init_mesh"; - - // Build the action - std::shared_ptr action = - _action_factory.create("SetupMeshAction", "Mesh", action_params); - _action_warehouse.addActionBlock(action); - } - // Executioner { // Build the Action parameters diff --git a/framework/src/mesh/FileMesh.C b/framework/src/mesh/FileMesh.C index 74e6c8a6a139..22dc85e32a61 100644 --- a/framework/src/mesh/FileMesh.C +++ b/framework/src/mesh/FileMesh.C @@ -32,14 +32,15 @@ validParams() FileMesh::FileMesh(const InputParameters & parameters) : MooseMesh(parameters), _file_name(getParam("file")), + _dim(getParam("dim")), _read_mesh_timer(registerTimedSection("readMesh", 2)) { - getMesh().set_mesh_dimension(getParam("dim")); } FileMesh::FileMesh(const FileMesh & other_mesh) : MooseMesh(other_mesh), _file_name(other_mesh._file_name), + _dim(other_mesh._dim), _read_mesh_timer(other_mesh._read_mesh_timer) { } @@ -57,7 +58,7 @@ FileMesh::buildMesh() { TIME_SECTION(_read_mesh_timer); - std::string _file_name = getParam("file"); + getMesh().set_mesh_dimension(getParam("dim")); if (_is_nemesis) { diff --git a/framework/src/mesh/MooseMesh.C b/framework/src/mesh/MooseMesh.C index 43e1cd2cb1b1..a9efbd91323c 100644 --- a/framework/src/mesh/MooseMesh.C +++ b/framework/src/mesh/MooseMesh.C @@ -63,13 +63,13 @@ validParams() { InputParameters params = validParams(); - MooseEnum mesh_parallel_type("DISTRIBUTED=0 REPLICATED DEFAULT", "DEFAULT"); + MooseEnum parallel_type("DEFAULT REPLICATED DISTRIBUTED", "DEFAULT"); params.addParam("parallel_type", - mesh_parallel_type, - "DISTRIBUTED: Always use libMesh::DistributedMesh " - "REPLICATED: Always use libMesh::ReplicatedMesh " + parallel_type, "DEFAULT: Use libMesh::ReplicatedMesh unless --distributed-mesh is " - "specified on the command line"); + "specified on the command line " + "REPLICATED: Always use libMesh::ReplicatedMesh " + "DISTRIBUTED: Always use libMesh::DistributedMesh"); params.addParam( "allow_renumbering", @@ -152,7 +152,7 @@ MooseMesh::MooseMesh(const InputParameters & parameters) : MooseObject(parameters), Restartable(this, "Mesh"), PerfGraphInterface(this), - _mesh_parallel_type(getParam("parallel_type")), + _parallel_type(getParam("parallel_type").getEnum()), _use_distributed_mesh(false), _distribution_overridden(false), _parallel_type_overridden(false), @@ -170,6 +170,8 @@ MooseMesh::MooseMesh(const InputParameters & parameters) ? getParam("ghosting_patch_size") : 5 * _patch_size), _max_leaf_size(getParam("max_leaf_size")), + _patch_update_strategy( + getParam("patch_update_strategy").getEnum()), _regular_orthogonal_mesh(false), _allow_recovery(true), _construct_node_list_from_side_list(getParam("construct_node_list_from_side_list")), @@ -205,70 +207,16 @@ MooseMesh::MooseMesh(const InputParameters & parameters) _ghost_ghosted_boundaries_timer(registerTimedSection("GhostGhostedBoundaries", 3)), _add_mortar_interface_timer(registerTimedSection("addMortarInterface", 5)) { - MooseEnum temp_patch_update_strategy = getParam("patch_update_strategy"); - if (temp_patch_update_strategy == "never") - _patch_update_strategy = Moose::Never; - else if (temp_patch_update_strategy == "always") - _patch_update_strategy = Moose::Always; - else if (temp_patch_update_strategy == "auto") - _patch_update_strategy = Moose::Auto; - else if (temp_patch_update_strategy == "iteration") - _patch_update_strategy = Moose::Iteration; - else - mooseError("Patch update strategy should be never, always, auto or iteration."); - if (isParamValid("ghosting_patch_size") && (_patch_update_strategy != Moose::Iteration)) mooseError("Ghosting patch size parameter has to be set in the mesh block " "only when 'iteration' patch update strategy is used."); - - switch (_mesh_parallel_type) - { - case 0: // PARALLEL - _use_distributed_mesh = true; - break; - case 1: // SERIAL - if (_app.getDistributedMeshOnCommandLine() || _is_nemesis || _app.isUseSplit()) - _parallel_type_overridden = true; - break; - case 2: // DEFAULT - // The user did not specify 'parallel_type = XYZ' in the input file, - // so we allow the --distributed-mesh command line arg to possibly turn - // on DistributedMesh. If the command line arg is not present, we pick ReplicatedMesh. - if (_app.getDistributedMeshOnCommandLine()) - _use_distributed_mesh = true; - - break; - // No default switch needed for MooseEnum - } - - // If the user specifies 'nemesis = true' in the Mesh block, or they are using --use-split, - // we must use DistributedMesh. - if (_is_nemesis || _app.isUseSplit()) - _use_distributed_mesh = true; - - unsigned dim = getParam("dim"); - - if (_use_distributed_mesh) - { - _mesh = libmesh_make_unique(_communicator, dim); - if (_partitioner_name != "default" && _partitioner_name != "parmetis") - { - _partitioner_name = "parmetis"; - _partitioner_overridden = true; - } - } - else - _mesh = libmesh_make_unique(_communicator, dim); - - if (!getParam("allow_renumbering")) - _mesh->allow_renumbering(false); } MooseMesh::MooseMesh(const MooseMesh & other_mesh) : MooseObject(other_mesh._pars), Restartable(this, "Mesh"), PerfGraphInterface(this, "CopiedMesh"), - _mesh_parallel_type(other_mesh._mesh_parallel_type), + _parallel_type(other_mesh._parallel_type), _use_distributed_mesh(other_mesh._use_distributed_mesh), _distribution_overridden(other_mesh._distribution_overridden), _mesh(other_mesh.getMesh().clone()), @@ -388,6 +336,8 @@ MooseMesh::prepare(bool force) { TIME_SECTION(_prepare_timer); + mooseAssert(_mesh, "The MeshBase has not been constructed"); + if (dynamic_cast(&getMesh()) && !_is_nemesis) { // Call prepare_for_use() and don't mess with the renumbering @@ -1505,6 +1455,7 @@ MooseMesh::dimensionWidth(unsigned int component) const Real MooseMesh::getMinInDimension(unsigned int component) const { + mooseAssert(_mesh, "The MeshBase has not been constructed"); mooseAssert(component < _bounds.size(), "Requested dimension out of bounds"); return _bounds[component][MIN]; @@ -1513,6 +1464,7 @@ MooseMesh::getMinInDimension(unsigned int component) const Real MooseMesh::getMaxInDimension(unsigned int component) const { + mooseAssert(_mesh, "The MeshBase has not been constructed"); mooseAssert(component < _bounds.size(), "Requested dimension out of bounds"); return _bounds[component][MAX]; @@ -2003,9 +1955,81 @@ MooseMesh::clone() const mooseError("MooseMesh::clone() is no longer supported, use MooseMesh::safeClone() instead."); } +std::unique_ptr +MooseMesh::buildMeshBaseObject(ParallelType override_type) +{ + switch (_parallel_type) + { + case ParallelType::DEFAULT: + // The user did not specify 'parallel_type = XYZ' in the input file, + // so we allow the --distributed-mesh command line arg to possibly turn + // on DistributedMesh. If the command line arg is not present, we pick ReplicatedMesh. + if (_app.getDistributedMeshOnCommandLine()) + _use_distributed_mesh = true; + break; + case ParallelType::REPLICATED: + if (_app.getDistributedMeshOnCommandLine() || _is_nemesis || _app.isUseSplit()) + _parallel_type_overridden = true; + break; + case ParallelType::DISTRIBUTED: + _use_distributed_mesh = true; + break; + } + + // If the user specifies 'nemesis = true' in the Mesh block, or they are using --use-split, + // we must use DistributedMesh. + if (_is_nemesis || _app.isUseSplit()) + _use_distributed_mesh = true; + + unsigned dim = getParam("dim"); + + std::unique_ptr mesh; + if (_use_distributed_mesh) + { + if (override_type == ParallelType::REPLICATED) + mooseError("The requested override_type of \"Replicated\" may not be used when MOOSE is " + "running with a DistributedMesh"); + + mesh = libmesh_make_unique(_communicator, dim); + if (_partitioner_name != "default" && _partitioner_name != "parmetis") + { + _partitioner_name = "parmetis"; + _partitioner_overridden = true; + } + } + else + { + if (override_type == ParallelType::DISTRIBUTED) + mooseError("The requested override_type of \"Distributed\" may not be used when MOOSE is " + "running with a ReplicatedMesh"); + + mesh = libmesh_make_unique(_communicator, dim); + } + + if (!getParam("allow_renumbering")) + mesh->allow_renumbering(false); + + return mesh; +} + +void +MooseMesh::setMeshBase(std::unique_ptr mesh_base) +{ + _mesh = std::move(mesh_base); +} + void MooseMesh::init() { + /** + * If the mesh base hasn't been constructed by the time init is called, just do it here. + * This can happen if somebody builds a mesh outside of the normal Action system. Forcing + * developers to create, construct the MeshBase, and then init separately is a bit much for casual + * use but it gives us the ability to run MeshGenerators in-between. + */ + if (!_mesh) + _mesh = buildMeshBaseObject(); + if (_app.isSplitMesh() && _use_distributed_mesh) mooseError("You cannot use the mesh splitter capability with DistributedMesh!"); diff --git a/framework/src/mesh/PatternedMesh.C b/framework/src/mesh/PatternedMesh.C index 230dfe3e52e8..d8c78a226a1d 100644 --- a/framework/src/mesh/PatternedMesh.C +++ b/framework/src/mesh/PatternedMesh.C @@ -65,24 +65,6 @@ PatternedMesh::PatternedMesh(const InputParameters & parameters) errorIfDistributedMesh("PatternedMesh"); _meshes.reserve(_files.size()); - - // Read in all of the meshes - for (auto i = beginIndex(_files); i < _files.size(); ++i) - { - _meshes.emplace_back(libmesh_make_unique(_communicator)); - auto & mesh = _meshes.back(); - - mesh->read(_files[i]); - } - - _original_mesh = dynamic_cast(&getMesh()); - if (!_original_mesh) - mooseError("PatternedMesh does not support DistributedMesh"); - - // Create a mesh for all n-1 rows, the first row is the original mesh - _row_meshes.reserve(_pattern.size() - 1); - for (auto i = beginIndex(_pattern); i < _pattern.size() - 1; ++i) - _row_meshes.emplace_back(libmesh_make_unique(_communicator)); } PatternedMesh::PatternedMesh(const PatternedMesh & other_mesh) @@ -95,8 +77,6 @@ PatternedMesh::PatternedMesh(const PatternedMesh & other_mesh) { } -PatternedMesh::~PatternedMesh() {} - std::unique_ptr PatternedMesh::safeClone() const { @@ -106,11 +86,25 @@ PatternedMesh::safeClone() const void PatternedMesh::buildMesh() { + // Read in all of the meshes + for (auto i = beginIndex(_files); i < _files.size(); ++i) + { + _meshes.emplace_back(libmesh_make_unique(_communicator)); + auto & mesh = _meshes.back(); + + mesh->read(_files[i]); + } + + // Create a mesh for all n-1 rows, the first row is the original mesh + _row_meshes.reserve(_pattern.size() - 1); + for (auto i = beginIndex(_pattern); i < _pattern.size() - 1; ++i) + _row_meshes.emplace_back(libmesh_make_unique(_communicator)); + // Local pointers to simplify algorithm std::vector row_meshes; row_meshes.reserve(_pattern.size()); // First row is the original mesh - row_meshes.push_back(_original_mesh); + row_meshes.push_back(static_cast(&getMesh())); // Copy the remaining raw pointers into the local vector for (const auto & row_mesh : _row_meshes) row_meshes.push_back(row_mesh.get()); diff --git a/framework/src/mesh/StitchedMesh.C b/framework/src/mesh/StitchedMesh.C index 8bab84d27551..9c8b623261b4 100644 --- a/framework/src/mesh/StitchedMesh.C +++ b/framework/src/mesh/StitchedMesh.C @@ -54,11 +54,6 @@ StitchedMesh::StitchedMesh(const InputParameters & parameters) // The StitchedMesh class only works with ReplicatedMesh errorIfDistributedMesh("StitchedMesh"); - // Get the original mesh - _original_mesh = dynamic_cast(&getMesh()); - if (!_original_mesh) - mooseError("StitchedMesh does not support DistributedMesh"); - if (_stitch_boundaries.size() % 2 != 0) mooseError("There must be an even amount of stitch_boundaries in ", name()); @@ -77,8 +72,6 @@ StitchedMesh::StitchedMesh(const StitchedMesh & other_mesh) { } -StitchedMesh::~StitchedMesh() {} - std::unique_ptr StitchedMesh::safeClone() const { @@ -88,6 +81,9 @@ StitchedMesh::safeClone() const void StitchedMesh::buildMesh() { + // Get the original mesh + _original_mesh = static_cast(&getMesh()); + // Read the first mesh into the original mesh... then we'll stitch all of the others into that _original_mesh->read(_files[0]); diff --git a/framework/src/meshgenerators/GeneratedMeshGenerator.C b/framework/src/meshgenerators/GeneratedMeshGenerator.C index 7840608dbd3a..27e565b90687 100644 --- a/framework/src/meshgenerators/GeneratedMeshGenerator.C +++ b/framework/src/meshgenerators/GeneratedMeshGenerator.C @@ -102,7 +102,8 @@ GeneratedMeshGenerator::GeneratedMeshGenerator(const InputParameters & parameter std::unique_ptr GeneratedMeshGenerator::generate() { - std::unique_ptr mesh = libmesh_make_unique(comm(), 2); + // Have MOOSE construct the correct libMesh::Mesh object using Mesh block and CLI parameters. + auto mesh = _mesh->buildMeshBaseObject(); MooseEnum elem_type_enum = getParam("elem_type"); @@ -168,22 +169,25 @@ GeneratedMeshGenerator::generate() // Apply the bias if any exists if (_bias_x != 1.0 || _bias_y != 1.0 || _bias_z != 1.0) { + const auto MIN = std::numeric_limits::max(); // Biases - Real bias[3] = {_bias_x, _bias_y, _bias_z}; + std::array bias = { + {_bias_x, _dim > 1 ? _bias_y : 1.0, _dim > 2 ? _bias_z : 1.0}}; // "width" of the mesh in each direction - Real width[3] = {_xmax - _xmin, _ymax - _ymin, _zmax - _zmin}; + std::array width = { + {_xmax - _xmin, _dim > 1 ? _ymax - _ymin : 0, _dim > 2 ? _zmax - _zmin : 0}}; // Min mesh extent in each direction. - Real mins[3] = {_xmin, _ymin, _zmin}; + std::array mins = {{_xmin, _dim > 1 ? _ymin : MIN, _dim > 2 ? _zmin : MIN}}; // Number of elements in each direction. - unsigned int nelem[3] = {_nx, _ny, _nz}; + std::array nelem = {{_nx, _dim > 1 ? _ny : 1, _dim > 2 ? _nz : 1}}; // We will need the biases raised to integer powers in each // direction, so let's pre-compute those... - std::vector> pows(LIBMESH_DIM); + std::array, LIBMESH_DIM> pows; for (unsigned int dir = 0; dir < LIBMESH_DIM; ++dir) { pows[dir].resize(nelem[dir] + 1); @@ -220,6 +224,9 @@ GeneratedMeshGenerator::generate() // lot (e.g. we want 3.9999 to map to 4.0 instead of 3.0). int index = round(float_index); + mooseAssert(index >= static_cast(0) && index < static_cast(pows[dir].size()), + "Scaled \"index\" out of range"); + // Move node to biased location. node(dir) = mins[dir] + width[dir] * (1. - pows[dir][index]) / (1. - pows[dir][nelem[dir]]); diff --git a/framework/src/meshgenerators/MeshGenerator.C b/framework/src/meshgenerators/MeshGenerator.C index 1b7020c5a62f..6e8c040114ad 100644 --- a/framework/src/meshgenerators/MeshGenerator.C +++ b/framework/src/meshgenerators/MeshGenerator.C @@ -22,7 +22,9 @@ validParams() } MeshGenerator::MeshGenerator(const InputParameters & parameters) - : MooseObject(parameters), Restartable(this, "MeshGenerators") + : MooseObject(parameters), + Restartable(this, "MeshGenerators"), + _mesh(_app.actionWarehouse().mesh()) { } diff --git a/modules/tensor_mechanics/src/actions/LineElementAction.C b/modules/tensor_mechanics/src/actions/LineElementAction.C index f375f7eb9b2b..c1559531b1f0 100644 --- a/modules/tensor_mechanics/src/actions/LineElementAction.C +++ b/modules/tensor_mechanics/src/actions/LineElementAction.C @@ -18,9 +18,7 @@ #include "libmesh/string_to_enum.h" #include -registerMooseAction("TensorMechanicsApp", LineElementAction, "meta_action"); - -registerMooseAction("TensorMechanicsApp", LineElementAction, "setup_mesh_complete"); +registerMooseAction("TensorMechanicsApp", LineElementAction, "create_problem"); registerMooseAction("TensorMechanicsApp", LineElementAction, "add_variable"); @@ -365,7 +363,7 @@ void LineElementAction::act() { // Get the subdomain involved in the action once the mesh setup is complete - if (_current_task == "setup_mesh_complete") + if (_current_task == "create_problem") { // get subdomain IDs for (auto & name : _subdomain_names) diff --git a/test/tests/mesh/no_mesh_block/generators_no_mesh_block.i b/test/tests/mesh/no_mesh_block/generators_no_mesh_block.i new file mode 100644 index 000000000000..9a8b879670b7 --- /dev/null +++ b/test/tests/mesh/no_mesh_block/generators_no_mesh_block.i @@ -0,0 +1,49 @@ +[MeshGenerators] + [gmg] + type = GeneratedMeshGenerator + dim = 3 + nx = 3 + ny = 3 + nz = 4 + bias_x = 2 + bias_z = 0.5 + [] +[] + +[Variables] + [u] + [] +[] + +[Kernels] + [diff] + type = Diffusion + variable = u + [] +[] + +[BCs] + [leftBC] + type = DirichletBC + variable = u + boundary = 10 + value = 1 + [] + [rightBC] + type = DirichletBC + variable = u + boundary = 11 + value = 0 + [] +[] + +[Executioner] + type = Steady + solve_type = 'PJFNK' + petsc_options_iname = '-pc_type -pc_hypre_type' + petsc_options_value = 'hypre boomeramg' +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/mesh/no_mesh_block/no_mesh_block.i b/test/tests/mesh/no_mesh_block/no_mesh_block.i new file mode 100644 index 000000000000..650245a93686 --- /dev/null +++ b/test/tests/mesh/no_mesh_block/no_mesh_block.i @@ -0,0 +1,39 @@ +# No Mesh Block! + +[Variables] + [u] + [] +[] + +[Kernels] + [diff] + type = Diffusion + variable = u + [] +[] + +[BCs] + [leftBC] + type = DirichletBC + variable = u + boundary = 10 + value = 1 + [] + [rightBC] + type = DirichletBC + variable = u + boundary = 11 + value = 0 + [] +[] + +[Executioner] + type = Steady + solve_type = 'PJFNK' + petsc_options_iname = '-pc_type -pc_hypre_type' + petsc_options_value = 'hypre boomeramg' +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/mesh/no_mesh_block/tests b/test/tests/mesh/no_mesh_block/tests new file mode 100644 index 000000000000..00abeecabcfc --- /dev/null +++ b/test/tests/mesh/no_mesh_block/tests @@ -0,0 +1,22 @@ +[Tests] + [./no_mesh_block_err] + type = 'RunException' + input = 'no_mesh_block.i' + expect_err = "No mesh file was supplied and no generation block was provided" + + issues = #2408 + design = "Mesh/index.md" + requirement = "The system shall issue an error if no Mesh block is provided." + [../] + + [./generators_no_mesh_block_err] + type = 'RunException' + input = 'generators_no_mesh_block.i' + expect_err = "No mesh file was supplied and no generation block was provided" + + issues = #2408 + design = "Mesh/index.md" + requirement = "The system shall issue an error if no Mesh block is provided even when MeshGenerators are provided." + [../] + +[] diff --git a/test/tests/meshgenerators/generate_sidesets_bounding_box/error_no_elements_in_bounding_box.i b/test/tests/meshgenerators/generate_sidesets_bounding_box/error_no_elements_in_bounding_box.i index b955a99bb18a..9ae89d9a841e 100644 --- a/test/tests/meshgenerators/generate_sidesets_bounding_box/error_no_elements_in_bounding_box.i +++ b/test/tests/meshgenerators/generate_sidesets_bounding_box/error_no_elements_in_bounding_box.i @@ -27,6 +27,10 @@ [] [] +[Mesh] + type = MeshGeneratorMesh +[] + [Variables] [./u] [../] diff --git a/test/tests/meshgenerators/generate_sidesets_bounding_box/error_no_nodes_found.i b/test/tests/meshgenerators/generate_sidesets_bounding_box/error_no_nodes_found.i index d836bc03efa2..aa0ef743dfcd 100644 --- a/test/tests/meshgenerators/generate_sidesets_bounding_box/error_no_nodes_found.i +++ b/test/tests/meshgenerators/generate_sidesets_bounding_box/error_no_nodes_found.i @@ -28,6 +28,10 @@ [] [] +[Mesh] + type = MeshGeneratorMesh +[] + [Variables] [./u] [../] diff --git a/test/tests/meshgenerators/generate_sidesets_bounding_box/error_no_side_sets_found.i b/test/tests/meshgenerators/generate_sidesets_bounding_box/error_no_side_sets_found.i index 4b3628ea07ae..46f4bd50de4e 100644 --- a/test/tests/meshgenerators/generate_sidesets_bounding_box/error_no_side_sets_found.i +++ b/test/tests/meshgenerators/generate_sidesets_bounding_box/error_no_side_sets_found.i @@ -18,6 +18,10 @@ [] [] +[Mesh] + type = MeshGeneratorMesh +[] + [Variables] [./u] [../] diff --git a/test/tests/meshgenerators/sidesets_bounding_box_generator/error_no_elements_in_bounding_box.i b/test/tests/meshgenerators/sidesets_bounding_box_generator/error_no_elements_in_bounding_box.i index b955a99bb18a..9ae89d9a841e 100644 --- a/test/tests/meshgenerators/sidesets_bounding_box_generator/error_no_elements_in_bounding_box.i +++ b/test/tests/meshgenerators/sidesets_bounding_box_generator/error_no_elements_in_bounding_box.i @@ -27,6 +27,10 @@ [] [] +[Mesh] + type = MeshGeneratorMesh +[] + [Variables] [./u] [../] diff --git a/test/tests/meshgenerators/sidesets_bounding_box_generator/error_no_nodes_found.i b/test/tests/meshgenerators/sidesets_bounding_box_generator/error_no_nodes_found.i index d836bc03efa2..aa0ef743dfcd 100644 --- a/test/tests/meshgenerators/sidesets_bounding_box_generator/error_no_nodes_found.i +++ b/test/tests/meshgenerators/sidesets_bounding_box_generator/error_no_nodes_found.i @@ -28,6 +28,10 @@ [] [] +[Mesh] + type = MeshGeneratorMesh +[] + [Variables] [./u] [../] diff --git a/test/tests/meshgenerators/sidesets_bounding_box_generator/error_no_side_sets_found.i b/test/tests/meshgenerators/sidesets_bounding_box_generator/error_no_side_sets_found.i index 4b3628ea07ae..46f4bd50de4e 100644 --- a/test/tests/meshgenerators/sidesets_bounding_box_generator/error_no_side_sets_found.i +++ b/test/tests/meshgenerators/sidesets_bounding_box_generator/error_no_side_sets_found.i @@ -18,6 +18,10 @@ [] [] +[Mesh] + type = MeshGeneratorMesh +[] + [Variables] [./u] [../] diff --git a/unit/include/ParsedFunctionTest.h b/unit/include/ParsedFunctionTest.h index 20b1974105fc..db54e1834b19 100644 --- a/unit/include/ParsedFunctionTest.h +++ b/unit/include/ParsedFunctionTest.h @@ -36,6 +36,7 @@ class ParsedFunctionTest : public ::testing::Test mesh_params.set("_type") = "GneratedMesh"; _mesh = libmesh_make_unique(mesh_params); + _mesh->setMeshBase(_mesh->buildMeshBaseObject()); InputParameters problem_params = _factory->getValidParams("FEProblem"); problem_params.set("mesh") = _mesh.get();