1 // Copyright(C) 1999-2021 National Technology & Engineering Solutions
2 // of Sandia, LLC (NTESS).  Under the terms of Contract DE-NA0003525 with
3 // NTESS, the U.S. Government retains certain rights in this software.
4 //
5 // See packages/seacas/LICENSE for details
6 
7 #ifndef IOSS_Iocgns_DatabaseIO_h
8 #define IOSS_Iocgns_DatabaseIO_h
9 
10 #include <Ioss_CodeTypes.h>
11 #include <Ioss_DBUsage.h>    // for DatabaseUsage
12 #include <Ioss_DatabaseIO.h> // for DatabaseIO
13 #include <Ioss_FaceGenerator.h>
14 #include <Ioss_IOFactory.h> // for IOFactory
15 #include <Ioss_Map.h>       // for Map
16 #include <Ioss_State.h>     // for State
17 #include <cstddef>          // for size_t
18 #include <cstdint>          // for int64_t
19 #include <iostream>         // for ostream
20 #include <map>
21 #include <string> // for string
22 
23 #include <cgns/Iocgns_Defines.h>
24 #include <cgnslib.h>
25 
26 namespace Ioss {
27   class Assembly;
28   class Blob;
29   class CommSet;
30   class EdgeBlock;
31   class EdgeSet;
32   class ElementBlock;
33   class ElementSet;
34   class ElementTopology;
35   class FaceBlock;
36   class FaceSet;
37   class Field;
38   class GroupingEntity;
39   class NodeBlock;
40   class NodeSet;
41   class Region;
42   class SideBlock;
43   class SideSet;
44   class EntityBlock;
45   class StructuredBlock;
46 } // namespace Ioss
47 
48 /** \brief A namespace for the CGNS database format.
49  */
50 namespace Iocgns {
51 
52   class DatabaseIO : public Ioss::DatabaseIO
53   {
54   public:
55     enum class entity_type { NODE, ELEM };
56 
57     DatabaseIO(Ioss::Region *region, const std::string &filename, Ioss::DatabaseUsage db_usage,
58                MPI_Comm communicator, const Ioss::PropertyManager &props);
59 
60     // Check capabilities of input/output database...  Returns an
61     // unsigned int with the supported Ioss::EntityTypes or'ed
62     // together. If "return_value & Ioss::EntityType" is set, then the
63     // database supports that type (e.g. return_value & Ioss::FACESET)
64     unsigned entity_field_support() const override;
65 
66     int64_t node_global_to_local__(int64_t global, bool must_exist) const override;
67     int64_t element_global_to_local__(int64_t global) const override;
68 
69     ~DatabaseIO() override;
70 
get_format()71     const std::string get_format() const override { return "CGNS"; }
72 
73     // This isn't quite true since a CGNS library with cgsize_t == 64-bits can read
74     // a file with 32-bit ints. However,...
int_byte_size_db()75     int int_byte_size_db() const override { return CG_SIZEOF_SIZE; }
76 
node_major()77     bool node_major() const override { return false; }
78 
79     // Metadata-related functions.
80     void read_meta_data__() override;
81     void write_meta_data();
82     void write_results_meta_data();
83 
84     int get_file_pointer() const override;
85 
86   private:
87     void open_state_file(int state);
88     void free_state_pointer();
89 
90     void openDatabase__() const override;
91     void closeDatabase__() const override;
92 
93     bool begin__(Ioss::State state) override;
94     bool end__(Ioss::State state) override;
95 
96     bool begin_state__(int state, double time) override;
97     bool end_state__(int state, double time) override;
98     void flush_database__() const override;
99 
100     bool   check_valid_file_open(int status) const;
101     void   create_structured_block(int base, int zone, size_t &num_node);
102     void   create_structured_block_fpp(int base, int num_zones, size_t &num_node);
103     size_t finalize_structured_blocks();
104     void   finalize_database() const override;
105     void   get_step_times__() override;
106 
107     void create_unstructured_block(int base, int zone, size_t &num_node);
108     void write_adjacency_data();
109 
110     int64_t get_field_internal(const Ioss::Region *reg, const Ioss::Field &field, void *data,
111                                size_t data_size) const override;
112     int64_t get_field_internal(const Ioss::NodeBlock *nb, const Ioss::Field &field, void *data,
113                                size_t data_size) const override;
114     int64_t get_field_internal(const Ioss::EdgeBlock *eb, const Ioss::Field &field, void *data,
115                                size_t data_size) const override;
116     int64_t get_field_internal(const Ioss::FaceBlock *fb, const Ioss::Field &field, void *data,
117                                size_t data_size) const override;
118     int64_t get_field_internal(const Ioss::ElementBlock *eb, const Ioss::Field &field, void *data,
119                                size_t data_size) const override;
120     int64_t get_field_internal(const Ioss::StructuredBlock *sb, const Ioss::Field &field,
121                                void *data, size_t data_size) const override;
122     int64_t get_field_internal(const Ioss::SideBlock *sb, const Ioss::Field &field, void *data,
123                                size_t data_size) const override;
124     int64_t get_field_internal(const Ioss::NodeSet *ns, const Ioss::Field &field, void *data,
125                                size_t data_size) const override;
126     int64_t get_field_internal(const Ioss::EdgeSet *es, const Ioss::Field &field, void *data,
127                                size_t data_size) const override;
128     int64_t get_field_internal(const Ioss::FaceSet *fs, const Ioss::Field &field, void *data,
129                                size_t data_size) const override;
130     int64_t get_field_internal(const Ioss::ElementSet *es, const Ioss::Field &field, void *data,
131                                size_t data_size) const override;
132     int64_t get_field_internal(const Ioss::SideSet *fs, const Ioss::Field &field, void *data,
133                                size_t data_size) const override;
134     int64_t get_field_internal(const Ioss::CommSet *cs, const Ioss::Field &field, void *data,
135                                size_t data_size) const override;
get_field_internal(const Ioss::Assembly *,const Ioss::Field &,void *,size_t)136     int64_t get_field_internal(const Ioss::Assembly * /*sb*/, const Ioss::Field & /*field*/,
137                                void * /*data*/, size_t /*data_size*/) const override
138     {
139       return 0;
140     }
141 
get_field_internal(const Ioss::Blob *,const Ioss::Field &,void *,size_t)142     int64_t get_field_internal(const Ioss::Blob * /*sb*/, const Ioss::Field & /*field*/,
143                                void * /*data*/, size_t /*data_size*/) const override
144     {
145       return 0;
146     }
147 
148     int64_t get_field_internal_sub_nb(const Ioss::NodeBlock *nb, const Ioss::Field &field,
149                                       void *data, size_t data_size) const;
150 
151     int64_t put_field_internal(const Ioss::Region *region, const Ioss::Field &field, void *data,
152                                size_t data_size) const override;
153     int64_t put_field_internal(const Ioss::NodeBlock *nb, const Ioss::Field &field, void *data,
154                                size_t data_size) const override;
155     int64_t put_field_internal(const Ioss::EdgeBlock *eb, const Ioss::Field &field, void *data,
156                                size_t data_size) const override;
157     int64_t put_field_internal(const Ioss::FaceBlock *fb, const Ioss::Field &field, void *data,
158                                size_t data_size) const override;
159     int64_t put_field_internal(const Ioss::ElementBlock *eb, const Ioss::Field &field, void *data,
160                                size_t data_size) const override;
161     int64_t put_field_internal(const Ioss::SideBlock *sb, const Ioss::Field &field, void *data,
162                                size_t data_size) const override;
163     int64_t put_field_internal(const Ioss::NodeSet *ns, const Ioss::Field &field, void *data,
164                                size_t data_size) const override;
165     int64_t put_field_internal(const Ioss::EdgeSet *es, const Ioss::Field &field, void *data,
166                                size_t data_size) const override;
167     int64_t put_field_internal(const Ioss::FaceSet *fs, const Ioss::Field &field, void *data,
168                                size_t data_size) const override;
169     int64_t put_field_internal(const Ioss::ElementSet *es, const Ioss::Field &field, void *data,
170                                size_t data_size) const override;
171     int64_t put_field_internal(const Ioss::SideSet *ss, const Ioss::Field &field, void *data,
172                                size_t data_size) const override;
173     int64_t put_field_internal(const Ioss::CommSet *cs, const Ioss::Field &field, void *data,
174                                size_t data_size) const override;
175     int64_t put_field_internal(const Ioss::StructuredBlock *sb, const Ioss::Field &field,
176                                void *data, size_t data_size) const override;
put_field_internal(const Ioss::Assembly *,const Ioss::Field &,void *,size_t)177     int64_t put_field_internal(const Ioss::Assembly * /*sb*/, const Ioss::Field & /*field*/,
178                                void * /*data*/, size_t /*data_size*/) const override
179     {
180       return 0;
181     }
182 
put_field_internal(const Ioss::Blob *,const Ioss::Field &,void *,size_t)183     int64_t put_field_internal(const Ioss::Blob * /*sb*/, const Ioss::Field & /*field*/,
184                                void * /*data*/, size_t /*data_size*/) const override
185     {
186       return 0;
187     }
188 
189     int64_t put_field_internal_sub_nb(const Ioss::NodeBlock *nb, const Ioss::Field &field,
190                                       void *data, size_t data_size) const;
191 
192     // ID Mapping functions.
193     const Ioss::Map &get_map(entity_type type) const;
194     const Ioss::Map &get_map(Ioss::Map &entity_map, int64_t entityCount, int64_t file_offset,
195                              int64_t file_count, entity_type type) const;
196 
197   private:
198     mutable int m_cgnsFilePtr{-1};
199     mutable int m_cgnsBasePtr{
200         -1}; // If using links to file-per-state, the file pointer for "base" file.
201 
202     int          m_flushInterval{0}; // Default is no flushing after each timestep
203     int          m_currentVertexSolutionIndex{0};
204     int          m_currentCellCenterSolutionIndex{0};
205     mutable bool m_dbFinalized{false};
206 
207     mutable std::vector<size_t> m_zoneOffset; // Offset for local zone/block element ids to global.
208     mutable std::vector<size_t>
209         m_bcOffset; // The BC Section element offsets in unstructured output.
210     mutable std::vector<double>                           m_timesteps;
211     std::vector<CGNSIntVector>                            m_blockLocalNodeMap;
212     std::map<std::string, int>                            m_zoneNameMap;
213     mutable std::map<int, Ioss::Map *>                    m_globalToBlockLocalNodeMap;
214     mutable std::map<std::string, Ioss::FaceUnorderedSet> m_boundaryFaces;
215   };
216 } // namespace Iocgns
217 #endif
218