1 /**
2  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3  * storing and accessing finite element mesh data.
4  *
5  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
6  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7  * retains certain rights in this software.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  */
15 
16 //-------------------------------------------------------------------------
17 // Filename      : WriteCCMIO.hpp
18 //
19 // Purpose       : ExodusII writer
20 //
21 // Special Notes : Lots of code taken from verde implementation
22 //
23 // Creator       : Corey Ernst
24 //
25 // Date          : 8/02
26 //
27 // Owner         : Corey Ernst
28 //-------------------------------------------------------------------------
29 
30 #ifndef WRITECCMIO_HPP
31 #define WRITECCMIO_HPP
32 
33 #ifndef IS_BUILDING_MB
34 #error "WriteCCMIO.hpp isn't supposed to be included into an application"
35 #endif
36 
37 #include <vector>
38 #include <string>
39 
40 #include "moab/Forward.hpp"
41 #include "moab/Range.hpp"
42 #include "moab/ExoIIInterface.hpp"
43 #include "moab/WriterIface.hpp"
44 #include "ccmio.h"
45 
46 namespace moab {
47 
48 class WriteUtilIface;
49 
50 class WriteCCMIO : public WriterIface
51 {
52 
53 public:
54 
55    //! Constructor
56    WriteCCMIO(Interface *impl);
57 
58    //! Destructor
59   virtual ~WriteCCMIO();
60 
61   static WriterIface* factory( Interface* );
62 
63     //! writes out a file
64   ErrorCode write_file(const char *file_name,
65                          const bool overwrite,
66                          const FileOptions& opts,
67                           const EntityHandle *output_list,
68                           const int num_sets,
69                           const std::vector<std::string>& qa_list,
70                           const Tag* tag_list = NULL,
71                           int num_tags = 0,
72                           int export_dimension = 3);
73 
74 protected:
75 
76     //! number of dimensions in this file
77   //int number_dimensions();
78 
79     //! open a file for writing
80   ErrorCode open_file(const char *filename, bool overwrite, CCMIOID &rootID);
81 
82   //! contains the general information about a mesh
83   class MeshInfo
84   {
85   public:
86     unsigned int num_dim;
87     unsigned int num_nodes;
88     unsigned int num_elements;
89     unsigned int num_matsets;
90     unsigned int num_dirsets;
91     unsigned int num_neusets;
92     Range nodes;
93 
MeshInfo()94     MeshInfo()
95         : num_dim(0), num_nodes(0), num_elements(0), num_matsets(0),
96           num_dirsets(0), num_neusets(0)
97       {}
98 
99   };
100 
101     // material set information
102   class MaterialSetData
103   {
104   public:
105     Range elems; // elements in material set
106     EntityHandle setHandle; // handle of the material set
107     EntityType entityType; // entity type of these elements
108     int verts_per_element; // number of vertices in each element
109     int matsetId; // id of this matset, from MATERIAL_SET tag
110     int materialId; // materialid, if any (from CCMIO)
111     std::string setName; // name for this matset, if any
112     std::string materialType; // material type for this matset, if any
113 
MaterialSetData()114     MaterialSetData()
115             : setHandle(0), entityType(MBMAXTYPE), verts_per_element(0), matsetId(-1),
116               materialId(-1)
117 
118         {}
119   };
120 
121     // neumann set information
122   class NeumannSetData
123   {
124   public:
125     Range elems; // elements in neumann set
126     EntityHandle setHandle; // handle of the neumann set
127     EntityType entityType; // entity type of these elements
128     int verts_per_element; // number of vertices in each element
129     int neusetId; // id of this matset, from NEUMANN_SET tag
130     std::string setName; // name for this neuset, if any
131 
NeumannSetData()132     NeumannSetData()
133             : setHandle(0), entityType(MBMAXTYPE), verts_per_element(0), neusetId(-1)
134         {}
135   };
136 
137 private:
138 
139     //! interface instance
140   Interface *mbImpl;
141   WriteUtilIface* mWriteIface;
142 
143     //! file name
144   std::string fileName;
145 
146     //! Meshset Handle for the mesh that is currently being read
147   EntityHandle mCurrentMeshHandle;
148 
149   //! Cached tags for reading.  Note that all these tags are defined when the
150   //! core is initialized.
151   Tag mMaterialSetTag;
152   Tag mDirichletSetTag;
153   Tag mNeumannSetTag;
154   Tag mPartitionSetTag;
155   Tag mHasMidNodesTag;
156   Tag mGlobalIdTag;
157   Tag mNameTag, mMaterialIdTag, mMaterialTypeTag;
158   Tag mRadiationTag, mPorosityIdTag, mSpinIdTag, mGroupIdTag, mColorIdxTag,
159       mProcessorIdTag, mLightMaterialTag, mFreeSurfaceMaterialTag;
160   Tag mThicknessTag, mProstarRegionNumberTag, mBoundaryTypeTag, mCreatingProgramTag;
161 
162   Tag mEntityMark;   //used to say whether an entity will be exported
163 
164   int mDimension; // dimension of entities being exported
165 
166   bool mWholeMesh; // if true, whole mesh is being output
167 
168     //! gathers elements in each matset, and all the vertices used by them;
169     //! marks the vertices with the mEntityMark bit flag
170   ErrorCode gather_matset_info(std::vector<EntityHandle> &matsets,
171                                std::vector<MaterialSetData> &matset_data,
172                                Range &all_verts);
173 
174     //! gathers elements in each neuset
175   ErrorCode gather_neuset_info(std::vector<EntityHandle> &neusets,
176                                std::vector<NeumannSetData> &neuset_data);
177 
178   ErrorCode close_and_compress(const char *filename, CCMIOID rootID);
179 
180   ErrorCode initialize_file(MeshInfo &mesh_info);
181 
182     //! write vertices to file
183   ErrorCode write_nodes(CCMIOID rootID, const Range& nodes, const int dimension, CCMIOID &verticesID);
184 
185     //! write cells and internal/boundary faces, using vgids and verts input
186   ErrorCode write_cells_and_faces(CCMIOID rootID,
187                                   std::vector<WriteCCMIO::MaterialSetData> &matset_data,
188                                   std::vector<WriteCCMIO::NeumannSetData> &neuset_data,
189                                   Range &verts, CCMIOID &topologyID);
190 
191     //! write external faces, including connectivity and connected cells
192   ErrorCode write_external_faces(CCMIOID rootID, CCMIOID topologyID, int set_num, Range &facets);
193 
194     // get global ids for these entities; allocates gids and passes back,
195     // caller is responsible for deleting
196   ErrorCode get_gids(const Range &ents, int *&gids,
197                        int &minid, int &maxid);
198 
199   ErrorCode write_meshes(MeshInfo &mesh_info,
200                             std::vector<MaterialSetData> &matset_data,
201                             std::vector<NeumannSetData> &neuset_data,
202                             Range &verts,
203                             const int *vgids);
204 
205   ErrorCode get_valid_sides(Range &elems, const int sense,
206                               WriteCCMIO::NeumannSetData &neuset_data);
207 
208   void reset_matset(std::vector<MaterialSetData> &matset_info);
209 
210   ErrorCode get_neuset_elems(EntityHandle neuset, int current_sense,
211                                Range &forward_elems, Range &reverse_elems);
212 
213   ErrorCode transform_coords(const int dimension, const int num_nodes, double *coords);
214 
215   ErrorCode write_problem_description(CCMIOID rootID, CCMIOID stateID, CCMIOID &problemID,
216                                       CCMIOID processorID,
217                                       std::vector<MaterialSetData> &matset_data,
218                                       std::vector<NeumannSetData> &neuset_data);
219 
220     // get the material, dirichlet, neumann, and partition sets to be written,
221     // either from input sets or in the whole mesh
222   ErrorCode get_sets(const EntityHandle *ent_handles,
223                      int num_sets,
224                      std::vector<EntityHandle> &matsets,
225                      std::vector<EntityHandle> &dirsets,
226                      std::vector<EntityHandle> &neusets,
227                      std::vector<EntityHandle> &partsets);
228 
229     //! create state and processor nodes
230   ErrorCode create_ccmio_structure(CCMIOID rootID, CCMIOID &stateID,
231                                    CCMIOID &processorID);
232 
233     //! write solution (tag) data
234   ErrorCode write_solution_data();
235 
236     //! finalize processor
237   ErrorCode write_processor(CCMIOID processorID, CCMIOID verticesID, CCMIOID topologyID);
238 
239     //! convert MOAB to CCMIO type
240   int moab_to_ccmio_type(EntityType etype, int has_mid_nodes[]);
241 
242   ErrorCode write_int_option(const char *opt_name,
243                              EntityHandle seth,
244                              Tag &tag, CCMIOID &node);
245 
246   ErrorCode write_dbl_option(const char *opt_name,
247                              EntityHandle seth,
248                              Tag &tag, CCMIOID &node);
249 
250   ErrorCode write_str_option(const char *opt_name,
251                              EntityHandle seth,
252                              Tag &tag, CCMIOID &node,
253                              const char *other_name = NULL);
254 };
255 
256 } // namespace moab
257 
258 #endif
259