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