1 // The libMesh Finite Element Library. 2 // Copyright (C) 2002-2020 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 4 // This library is free software; you can redistribute it and/or 5 // modify it under the terms of the GNU Lesser General Public 6 // License as published by the Free Software Foundation; either 7 // version 2.1 of the License, or (at your option) any later version. 8 9 // This library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 // Lesser General Public License for more details. 13 14 // You should have received a copy of the GNU Lesser General Public 15 // License along with this library; if not, write to the Free Software 16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 18 19 20 #ifndef LIBMESH_DYNA_IO_H 21 #define LIBMESH_DYNA_IO_H 22 23 // Local includes 24 #include "libmesh/libmesh_common.h" 25 #include "libmesh/mesh_input.h" 26 #include "libmesh/mesh_output.h" 27 28 // C++ includes 29 #include <algorithm> 30 #include <cstddef> 31 #include <map> 32 #include <vector> 33 34 namespace libMesh 35 { 36 37 // Forward declarations 38 class MeshBase; 39 40 41 42 /** 43 * \brief Reading and writing meshes in (a subset of) LS-DYNA format. 44 * 45 * The initial implementation only handles cards in the format 46 * described in "Geometry import to LS-DYNA", for isogeometric 47 * analysis. 48 * 49 * \author Roy H. Stogner 50 * \date 2019 51 */ 52 class DynaIO : public MeshInput<MeshBase> 53 { 54 public: 55 56 /** 57 * Constructor. Takes a non-const Mesh reference which it 58 * will fill up with elements via the read() command. 59 */ 60 explicit 61 DynaIO (MeshBase & mesh); 62 63 /** 64 * Reads in a mesh in the Dyna format from the ASCII file given by 65 * name. 66 * 67 * \note The user is responsible for calling Mesh::prepare_for_use() 68 * after reading the mesh and before using it. 69 * 70 * \note To safely use DynaIO::add_spline_constraints with a 71 * DistributedMesh, currently the user must 72 * allow_remote_element_removal(false) and allow_renumbering(false) 73 * before the mesh is read. 74 * 75 * The patch ids defined in the Dyna file are stored as subdomain 76 * ids. 77 * 78 * The spline nodes defined in the Dyna file are added to the mesh 79 * with type NodeElem. The only connection between spline nodes and 80 * finite element nodes will be user constraint equations, so using 81 * a space-filling-curve partitioner for these meshes might be a 82 * good idea. 83 */ 84 virtual void read (const std::string & name) override; 85 86 /** 87 * Constrains finite element degrees of freedom in terms of spline 88 * degrees of freedom by adding user-defined constraint rows to \p 89 * sys 90 */ 91 void add_spline_constraints(DofMap & dof_map, 92 unsigned int sys_num, 93 unsigned int var_num); 94 95 private: 96 // Keep track of spline node indexing, so as to enable adding 97 // constraint rows easily later. 98 std::vector<Node *> spline_node_ptrs; 99 100 // Keep track of the constraint equations associated with each FE 101 // node. 102 // 103 // constraint_rows[FE_node][i].first is the constraining spline 104 // node, and .second is the constraining coefficient. 105 std::map<dof_id_type, std::vector<std::pair<dof_id_type, Real>>> 106 constraint_rows; 107 108 // Have we broadcast the constraint_rows to non-root procs yet? 109 bool constraint_rows_broadcast; 110 111 /** 112 * Implementation of the read() function. This function 113 * is called by the public interface function and implements 114 * reading the file. 115 */ 116 void read_mesh (std::istream & in); 117 118 /** 119 * The integer type DYNA uses 120 */ 121 typedef int32_t dyna_int_type; 122 123 /** 124 * How many can we find on a line? 125 */ 126 static const int max_ints_per_line = 10; 127 128 /** 129 * The floating-point type DYNA uses 130 */ 131 typedef double dyna_fp_type; 132 133 /** 134 * How many can we find on a line? 135 */ 136 static const int max_fps_per_line = 5; 137 138 /** 139 * Defines mapping from libMesh element types to LS-DYNA element 140 * types or vice-versa. 141 * 142 * For the foreseeable future only isotropic p elements, with the 143 * same polynomial degree in every direction, are supported. 144 */ 145 struct ElementDefinition 146 { 147 ElementDefinition(ElemType type_in, 148 dyna_int_type dyna_type_in, 149 dyna_int_type dim_in, 150 dyna_int_type p_in); 151 152 ElementDefinition(ElemType type_in, 153 dyna_int_type dyna_type_in, 154 dyna_int_type dim_in, 155 dyna_int_type p_in, 156 std::vector<unsigned int> && nodes_in); 157 158 ElemType type; 159 dyna_int_type dyna_type; 160 dyna_int_type dim; 161 dyna_int_type p; 162 std::vector<unsigned int> nodes; 163 }; 164 165 /** 166 * struct which holds a map from LS-DYNA to libMesh element numberings 167 * and vice-versa. 168 */ 169 struct ElementMaps 170 { 171 // Helper function to add a (key, value) pair to both maps add_defElementMaps172 void add_def(const ElementDefinition & eledef) 173 { 174 out.emplace(eledef.type, eledef); 175 in.emplace(std::make_tuple(eledef.dyna_type, eledef.dim, eledef.p), eledef); 176 } 177 178 std::map<ElemType, ElementDefinition> out; 179 180 typedef std::tuple<dyna_int_type, dyna_int_type, dyna_int_type> Key; 181 182 std::map<Key, ElementDefinition> in; 183 }; 184 185 /** 186 * A static ElementMaps object that is built statically and used by 187 * all instances of this class. 188 */ 189 static ElementMaps _element_maps; 190 191 /** 192 * A static function used to construct the _element_maps struct, 193 * statically. 194 */ 195 static ElementMaps build_element_maps(); 196 }; 197 198 199 } // namespace libMesh 200 201 #endif // LIBMESH_DYNA_IO_H 202