Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #ifdef MOOSE_MFEM_ENABLED 11 : 12 : #include "MFEMMesh.h" 13 : #include "libmesh/mesh_generation.h" 14 : 15 : registerMooseObject("MooseApp", MFEMMesh); 16 : 17 : InputParameters 18 5862 : MFEMMesh::validParams() 19 : { 20 5862 : InputParameters params = FileMesh::validParams(); 21 17586 : params.addParam<unsigned int>( 22 : "serial_refine", 23 11724 : 0, 24 : "Number of serial refinements to perform on the mesh. Equivalent to uniform_refine."); 25 17586 : params.addParam<unsigned int>( 26 : "uniform_refine", 27 11724 : 0, 28 : "Number of serial refinements to perform on the mesh. Equivalent to serial_refine"); 29 17586 : params.addParam<unsigned int>( 30 11724 : "parallel_refine", 0, "Number of parallel refinements to perform on the mesh."); 31 23448 : params.addParam<std::string>("displacement", "Optional variable to use for mesh displacement."); 32 17586 : params.addParam<bool>("nonconforming", 33 11724 : false, 34 : "Ensures the mesh is non-conforming: necessary for refining quad/hex " 35 : "meshes and load (re)balancing."); 36 17586 : params.addParam<bool>("reorder_mesh", 37 11724 : false, 38 : "Determines whether we reorder the mesh to improve dynamic partitioning. " 39 : "Only Hilbert sorting is supported at present."); 40 : 41 5862 : params.addClassDescription("Class to read in and store an mfem::ParMesh from file."); 42 : 43 5862 : return params; 44 0 : } 45 : 46 1878 : MFEMMesh::MFEMMesh(const InputParameters & parameters) : FileMesh(parameters) {} 47 : 48 2240 : MFEMMesh::~MFEMMesh() {} 49 : 50 : void 51 1878 : MFEMMesh::buildMesh() 52 : { 53 9390 : TIME_SECTION("buildMesh", 2, "Reading Mesh"); 54 : 55 : // Build the MFEM ParMesh from a serial MFEM mesh 56 1878 : mfem::Mesh mfem_ser_mesh(getFileName()); 57 : 58 5690 : if (isParamSetByUser("serial_refine") && isParamSetByUser("uniform_refine")) 59 0 : paramError( 60 : "Cannot define serial_refine and uniform_refine to be nonzero at the same time (they " 61 : "are the same variable). Please choose one.\n"); 62 : 63 1878 : uniformRefinement(mfem_ser_mesh, 64 5690 : isParamSetByUser("serial_refine") ? getParam<unsigned int>("serial_refine") 65 7428 : : getParam<unsigned int>("uniform_refine")); 66 : 67 : // MFEM supports load balancing of parallel non-conforming meshes 68 : // with a space-filling curve partitioning, and we can improve it 69 : // by re-ordering the mesh. For now, we only support the Hilbert 70 : // ordering, although there is one other option. 71 5634 : if (getParam<bool>("reorder_mesh")) 72 : { 73 0 : mfem::Array<int> ordering; 74 0 : mfem_ser_mesh.GetHilbertElementOrdering(ordering); 75 0 : mfem_ser_mesh.ReorderElements(ordering); 76 0 : } 77 : 78 : // Make sure mesh is in non-conforming mode to enable local refinement of 79 : // quadrilaterals/hexahedra (c.f. MFEM example 6p). The argument (true/false) 80 : // determines whether a simplex mesh is considered to be non-conforming. 81 5634 : if (getParam<bool>("nonconforming")) 82 26 : mfem_ser_mesh.EnsureNCMesh(true); 83 : 84 : // multi app should take the mpi comm from moose so is split correctly?? 85 1878 : auto comm = this->comm().get(); 86 1878 : _mfem_par_mesh = std::make_shared<mfem::ParMesh>(comm, mfem_ser_mesh); 87 : 88 : // Perform parallel refinements 89 3756 : uniformRefinement(*_mfem_par_mesh, getParam<unsigned int>("parallel_refine")); 90 : 91 5634 : if (isParamSetByUser("displacement")) 92 33 : _mesh_displacement_variable.emplace(getParam<std::string>("displacement")); 93 : 94 : // Build a dummy MOOSE mesh to enable this class to work with other MOOSE classes. 95 1878 : buildDummyMooseMesh(); 96 1878 : } 97 : 98 : void 99 11 : MFEMMesh::displace(mfem::GridFunction const & displacement) 100 : { 101 11 : _mfem_par_mesh->EnsureNodes(); 102 11 : mfem::GridFunction * nodes = _mfem_par_mesh->GetNodes(); 103 : 104 11 : *nodes += displacement; 105 11 : } 106 : 107 : void 108 1878 : MFEMMesh::buildDummyMooseMesh() 109 : { 110 1878 : auto & dummy = static_cast<UnstructuredMesh &>(getMesh()); 111 1878 : MeshTools::Generation::build_point(dummy); 112 1878 : if (dimension() >= 2) 113 1800 : MeshTools::Generation::build_square(dummy, 1, 1, 0., 1., 0., 1., ElemType::QUAD9); 114 1878 : } 115 : 116 : void 117 3756 : MFEMMesh::uniformRefinement(mfem::Mesh & mesh, const unsigned int nref) const 118 : { 119 3917 : for (unsigned int i = 0; i < nref; ++i) 120 161 : mesh.UniformRefinement(); 121 3756 : } 122 : 123 : std::unique_ptr<MooseMesh> 124 8 : MFEMMesh::safeClone() const 125 : { 126 8 : return _app.getFactory().copyConstruct(*this); 127 : } 128 : 129 : #endif