1 // Copyright (c) Lawrence Livermore National Security, LLC and other Conduit
2 // Project developers. See top-level LICENSE AND COPYRIGHT files for dates and
3 // other details. No copyright assignment is required to contribute to Conduit.
4 
5 //-----------------------------------------------------------------------------
6 ///
7 /// file: conduit_blueprint_mesh_util.hpp
8 ///
9 //-----------------------------------------------------------------------------
10 
11 #ifndef CONDUIT_BLUEPRINT_MESH_UTILS_HPP
12 #define CONDUIT_BLUEPRINT_MESH_UTILS_HPP
13 
14 //-----------------------------------------------------------------------------
15 // std includes
16 //-----------------------------------------------------------------------------
17 #include <map>
18 #include <set>
19 #include <string>
20 #include <vector>
21 
22 //-----------------------------------------------------------------------------
23 // conduit lib includes
24 //-----------------------------------------------------------------------------
25 #include "conduit.hpp"
26 #include "conduit_blueprint_exports.h"
27 
28 //-----------------------------------------------------------------------------
29 // -- begin conduit --
30 //-----------------------------------------------------------------------------
31 namespace conduit
32 {
33 
34 //-----------------------------------------------------------------------------
35 // -- begin conduit::blueprint --
36 //-----------------------------------------------------------------------------
37 namespace blueprint
38 {
39 
40 //-----------------------------------------------------------------------------
41 // -- begin conduit::blueprint::mesh --
42 //-----------------------------------------------------------------------------
43 namespace mesh
44 {
45 
46 //-----------------------------------------------------------------------------
47 // -- begin conduit::blueprint::mesh::utils --
48 //-----------------------------------------------------------------------------
49 namespace utils
50 {
51 
52 //-----------------------------------------------------------------------------
53 /// blueprint mesh utility constants
54 //-----------------------------------------------------------------------------
55 
56 static const DataType DEFAULT_INT_DTYPE = DataType::int32(1);
57 static const DataType DEFAULT_UINT_DTYPE = DataType::uint32(1);
58 static const DataType DEFAULT_FLOAT_DTYPE = DataType::float32(1);
59 static const std::vector<DataType> DEFAULT_INT_DTYPES = {DEFAULT_INT_DTYPE, DEFAULT_UINT_DTYPE};
60 static const std::vector<DataType> DEFAULT_NUMBER_DTYPES = {DEFAULT_FLOAT_DTYPE, DEFAULT_INT_DTYPE, DEFAULT_UINT_DTYPE};
61 
62 static const std::vector<DataType> INT_DTYPES = {DataType::int32(1), DataType::int64(1)};
63 static const std::vector<DataType> FLOAT_DTYPES = {DataType::float32(1), DataType::float64(1)};
64 
65 static const std::vector<std::string> ASSOCIATIONS = {"vertex", "element"};
66 static const std::vector<std::string> BOOLEANS = {"true", "false"};
67 static const std::vector<std::string> NESTSET_TYPES = {"parent", "child"};
68 
69 static const std::vector<std::string> COORDINATE_AXES = {"x", "y", "z", "r", "z", "theta", "phi"};
70 static const std::vector<std::string> CARTESIAN_AXES = {"x", "y", "z"};
71 static const std::vector<std::string> CYLINDRICAL_AXES = {"r", "z"};
72 static const std::vector<std::string> SPHERICAL_AXES = {"r", "theta", "phi"};
73 static const std::vector<std::string> LOGICAL_AXES = {"i", "j", "k"};
74 
75 static const std::vector<std::string> COORD_TYPES = {"uniform", "rectilinear", "explicit"};
76 static const std::vector<std::string> COORD_SYSTEMS = {"cartesian", "cylindrical", "spherical"};
77 
78 static const std::vector<std::string> TOPO_TYPES = {"points", "uniform", "rectilinear", "structured", "unstructured"};
79 static const std::vector<std::string> TOPO_SHAPES = {"point", "line", "tri", "quad", "tet", "hex", "polygonal", "polyhedral"};
80 static const std::vector<std::string> TOPO_SHAPE_IDS = {"p", "l", "f", "f", "c", "c", "f", "c"};
81 static const std::vector<index_t> TOPO_SHAPE_DIMS = {0, 1, 2, 2, 3, 3, 2, 3};
82 static const std::vector<index_t> TOPO_SHAPE_INDEX_COUNTS = {1, 2, 3, 4, 4, 8, -1, -1};
83 static const std::vector<index_t> TOPO_SHAPE_EMBED_TYPES = {-1, 0, 1, 1, 2, 3, 1, 6};
84 static const std::vector<index_t> TOPO_SHAPE_EMBED_COUNTS = {0, 2, 3, 4, 4, 6, -1, -1};
85 
86 // TODO(JRC): These orientations currently assume the default Conduit-Blueprit
87 // windings are used for the input geometry, which happens to be the case
88 // for all example geometry but cannot be assumed for all inputs. In order
89 // for these arrangements to be used generally, the winding feature needs to
90 // be implemented and used to perform index space transforms.
91 static const index_t TOPO_POINT_EMBEDDING[1][1] = {
92     {0}};
93 static const index_t TOPO_LINE_EMBEDDING[2][1] = {
94     {0}, {1}};
95 static const index_t TOPO_TRI_EMBEDDING[3][2] = {
96     {0, 1}, {1, 2}, {2, 0}};
97 static const index_t TOPO_QUAD_EMBEDDING[4][2] = {
98     {0, 1}, {1, 2}, {2, 3}, {3, 0}};
99 static const index_t TOPO_TET_EMBEDDING[4][3] = {
100     {0, 2, 1}, {0, 1, 3},
101     {0, 3, 2}, {1, 2, 3}};
102 static const index_t TOPO_HEX_EMBEDDING[6][4] = {
103     {0, 3, 2, 1}, {0, 1, 5, 4}, {1, 2, 6, 5},
104     {2, 3, 7, 6}, {3, 0, 4, 7}, {4, 5, 6, 7}};
105 static const std::vector<const index_t*> TOPO_SHAPE_EMBEDDINGS = {
106     &TOPO_POINT_EMBEDDING[0][0], &TOPO_LINE_EMBEDDING[0][0],
107     &TOPO_TRI_EMBEDDING[0][0], &TOPO_QUAD_EMBEDDING[0][0],
108     &TOPO_TET_EMBEDDING[0][0], &TOPO_HEX_EMBEDDING[0][0],
109     NULL, NULL};
110 
111 //-----------------------------------------------------------------------------
112 /// blueprint mesh utility structures
113 //-----------------------------------------------------------------------------
114 
115 //---------------------------------------------------------------------------//
116 struct CONDUIT_BLUEPRINT_API ShapeType
117 {
118 public:
119     ShapeType();
120     ShapeType(const index_t type_id);
121     ShapeType(const std::string &type_name);
122     ShapeType(const conduit::Node &topology);
123 
124     bool is_poly() const;
125     bool is_polygonal() const;
126     bool is_polyhedral() const;
127     bool is_valid() const;
128 
129     std::string type;
130     index_t id, dim, indices;
131     index_t embed_id, embed_count, *embedding;
132 
133 private:
134     void init(const index_t type_id);
135     void init(const std::string &type_name);
136 };
137 
138 //---------------------------------------------------------------------------//
139 struct CONDUIT_BLUEPRINT_API ShapeCascade
140 {
141 public:
142     ShapeCascade(const conduit::Node &topology);
143     ShapeCascade(const ShapeType &shape_type);
144 
145     index_t get_num_embedded(const index_t level) const;
146     const ShapeType& get_shape(const index_t level = -1) const;
147 
148     ShapeType dim_types[4];
149     index_t dim;
150 private:
151     void init(const ShapeType &shape_type);
152 };
153 
154 //---------------------------------------------------------------------------//
155 struct CONDUIT_BLUEPRINT_API TopologyMetadata
156 {
157     // The 'IndexType' indicates the index space to be used when referring to
158     // entities within this topological cascade. The types have the following
159     // meanings:
160     //
161     // - GLOBAL: The unique index for the entity relative to the entire topology.
162     //   Though a point may be shared by many lines/faces/cells, it will only
163     //   have one global index. This is most commonly used for entity identification.
164     // - LOCAL: The index of the entity relative to a cascade context. A point
165     //   will have one local index for each line/face/cell that it participates
166     //   in along the cascade. This is most commonly used to determine entity orientation.
167     //
168     // To clarify, consider the following example, with the following local and
169     // global identifiers:
170     //
171     // - GLOBAL Scheme: Each entity has 1 unique identifier depending on FIFO
172     //   cascade iteration:
173     //
174     //   p3               p4              p5
175     //   +----------------+----------------+
176     //   |       l2       |       l6       |
177     //   |                |                |
178     //   |                |                |
179     //   |l3     f0       |l1     f1     l5|
180     //   |                |                |
181     //   |                |                |
182     //   |       l0       |       l4       |
183     //   +----------------+----------------+
184     //   p0               p1              p2
185     //
186     // - LOCAL Scheme: Each entity has an identifier for each occurence within
187     //   the cascade:
188     //
189     //    p5            p4 p13          p12
190     //   +----------------+----------------+
191     //   |p6     l2     p3|p14    l6    p11|
192     //   |                |                |
193     //   |                |                |
194     //   |l3     f0     l1|l7     f1     l5|
195     //   |                |                |
196     //   |                |                |
197     //   |p7     l0     p2|p15    l4    p10|
198     //   +----------------+----------------+
199     //    p0            p1 p8            p9
200     //
201     enum IndexType { GLOBAL = 0, LOCAL = 1 };
202 
203     TopologyMetadata(const conduit::Node &topology, const conduit::Node &coordset);
204 
205     void add_entity_assoc(IndexType type, index_t e0_id, index_t e0_dim, index_t e1_id, index_t e1_dim);
206 
207     const std::vector<index_t> &get_entity_assocs(IndexType type, index_t entity_id, index_t entity_dim, index_t assoc_dim) const;
208     void get_dim_map(IndexType type, index_t src_dim, index_t dst_dim, Node &map_node) const;
209     void get_entity_data(IndexType type, index_t entity_id, index_t entity_dim, Node &data) const;
210     void get_point_data(IndexType type, index_t point_id, Node &data) const;
211 
212     index_t get_length(index_t dim = -1) const;
213     index_t get_embed_length(index_t entity_dim, index_t embed_dim) const;
214 
215     std::string to_json() const;
216 
217     const conduit::Node *topo, *cset;
218     const conduit::DataType int_dtype, float_dtype;
219     const ShapeCascade topo_cascade;
220     const ShapeType topo_shape;
221 
222     // per-dimension topology nodes (mapped onto 'cset' coordinate set)
223     std::vector< conduit::Node > dim_topos;
224     // per-dimension maps from an entity's point id set to its global entity id
225     std::vector< std::map< std::set<index_t>, index_t > > dim_geid_maps;
226     // per-dimension maps from global entity ids to per-dimension global associate ids
227     std::vector< std::vector< std::vector< std::pair< std::vector<index_t>, std::set<index_t> > > > > dim_geassocs_maps;
228     // per-dimension maps from local entity ids to per-dimension local associate ids
229     std::vector< std::vector< std::vector< std::pair< std::vector<index_t>, std::set<index_t> > > > > dim_leassocs_maps;
230     // per-dimension mapping from local entity ids to global entity ids (delegates)
231     std::vector< std::vector<index_t> > dim_le2ge_maps;
232 };
233 
234 //-----------------------------------------------------------------------------
235 /// blueprint mesh utility functions
236 //-----------------------------------------------------------------------------
237 
238 //-----------------------------------------------------------------------------
239 Node CONDUIT_BLUEPRINT_API link_nodes(const Node &lhs, const Node &rhs);
240 
241 //-----------------------------------------------------------------------------
242 DataType CONDUIT_BLUEPRINT_API find_widest_dtype(const Node &node, const DataType &default_dtype);
243 //-----------------------------------------------------------------------------
244 DataType CONDUIT_BLUEPRINT_API find_widest_dtype(const Node &node, const std::vector<DataType> &default_dtypes);
245 
246 //-----------------------------------------------------------------------------
247 CONDUIT_BLUEPRINT_API const Node * find_reference_node(const Node &node, const std::string &ref_key);
248 //-----------------------------------------------------------------------------
249 index_t CONDUIT_BLUEPRINT_API find_domain_id(const Node &node);
250 
251 //-----------------------------------------------------------------------------
252 // -- begin conduit::blueprint::mesh::utils::connectivity --
253 //-----------------------------------------------------------------------------
254 namespace connectivity
255 {
256     //-------------------------------------------------------------------------
257     typedef std::vector<index_t> ElemType;
258     typedef std::map< index_t, std::vector<index_t> > SubelemMap;
259 
260     //-------------------------------------------------------------------------
261     void CONDUIT_BLUEPRINT_API make_element_2d(std::vector<index_t>& elem,
262                                                index_t element,
263                                                index_t iwidth);
264     //-------------------------------------------------------------------------
265     void CONDUIT_BLUEPRINT_API make_element_3d(ElemType& connect,
266                                                index_t element,
267                                                index_t iwidth,
268                                                index_t jwidth,
269                                                index_t kwidth,
270                                                SubelemMap& faces);
271 
272     //-------------------------------------------------------------------------
273     void CONDUIT_BLUEPRINT_API create_elements_2d(const Node& ref_win,
274                                                   index_t i_lo,
275                                                   index_t j_lo,
276                                                   index_t iwidth,
277                                                   std::map<index_t, std::vector<index_t> >& elems);
278     //-------------------------------------------------------------------------
279     void CONDUIT_BLUEPRINT_API create_elements_3d(const Node& ref_win,
280                                                   index_t i_lo,
281                                                   index_t j_lo,
282                                                   index_t k_lo,
283                                                   index_t iwidth,
284                                                   index_t jwidth,
285                                                   index_t kwidth,
286                                                   std::map<index_t, ElemType>& elems,
287                                                   SubelemMap& faces);
288 
289     //-------------------------------------------------------------------------
290     void CONDUIT_BLUEPRINT_API connect_elements_2d(const Node& ref_win,
291                                                    index_t i_lo,
292                                                    index_t j_lo,
293                                                    index_t iwidth,
294                                                    index_t ratio,
295                                                    index_t& new_vertex,
296                                                    std::map<index_t, std::vector<index_t> >& elems);
297     //-------------------------------------------------------------------------
298     void CONDUIT_BLUEPRINT_API connect_elements_3d(const Node& ref_win,
299                                                    index_t i_lo,
300                                                    index_t j_lo,
301                                                    index_t k_lo,
302                                                    index_t iwidth,
303                                                    index_t jwidth,
304                                                    index_t& new_vertex,
305                                                    std::map<index_t, ElemType>& elems);
306 }
307 //-----------------------------------------------------------------------------
308 // -- end conduit::blueprint::mesh::utils::connectivity --
309 //-----------------------------------------------------------------------------
310 
311 //-----------------------------------------------------------------------------
312 // -- begin conduit::blueprint::mesh::utils::coordset --
313 //-----------------------------------------------------------------------------
314 namespace coordset
315 {
316     //-------------------------------------------------------------------------
317     index_t CONDUIT_BLUEPRINT_API dims(const conduit::Node &coordset);
318 
319     //-------------------------------------------------------------------------
320     index_t CONDUIT_BLUEPRINT_API length(const conduit::Node &coordset);
321 
322     //-----------------------------------------------------------------------------
323     std::vector<std::string> CONDUIT_BLUEPRINT_API axes(const Node &coordset);
324 
325     //-----------------------------------------------------------------------------
326     std::string CONDUIT_BLUEPRINT_API coordsys(const Node &n);
327 
328     //-----------------------------------------------------------------------------
329     /**
330     @brief Updates array d to hold the number of verticies in each dimension
331         for the given coordset. Explicit coordsets will just report their
332         number_of_elements() in d[0].
333     */
334     void logical_dims(const conduit::Node &n, index_t *d, index_t maxdims);
335 
336     //-----------------------------------------------------------------------------
337     /**
338     @brief Reads the coordset's data and determines min/max for each axis.
339     NOTE: This simply takes the min/max of each data array for recilinear/explicit,
340     are there any special considerations for cylindrical and spherical coordinates?
341     For uniform it calculates min/max based off of origin/spacing/dims.
342     @return A vector of float64 in the format {d0min, d0max, ... , dNmin, dNmax}
343     */
344     std::vector<float64> CONDUIT_BLUEPRINT_API extents(const Node &n);
345 
346     namespace uniform
347     {
348         /**
349         @brief Reads the given uniform coordset and extracts to spacing
350                to an index_t vector
351         */
352         std::vector<double> CONDUIT_BLUEPRINT_API spacing(const Node &n);
353 
354         std::vector<index_t> CONDUIT_BLUEPRINT_API origin(const Node &n);
355     }
356 
357     std::string CONDUIT_BLUEPRINT_API coordsys(const Node &coordset);
358 
359     //-------------------------------------------------------------------------
360     // -- begin conduit::blueprint::mesh::utils::coordset::_explicit --
361     //-------------------------------------------------------------------------
362     namespace _explicit
363     {
364         //-------------------------------------------------------------------------
365         std::vector<float64> CONDUIT_BLUEPRINT_API coords(const Node &coordset, const index_t i);
366     }
367     //-------------------------------------------------------------------------
368     // -- end conduit::blueprint::mesh::utils::coordset::_explicit --
369     //-------------------------------------------------------------------------
370 }
371 //-----------------------------------------------------------------------------
372 // -- end conduit::blueprint::mesh::utils::coordset --
373 //-----------------------------------------------------------------------------
374 
375 //-----------------------------------------------------------------------------
376 // -- begin conduit::blueprint::mesh::utils::topology --
377 //-----------------------------------------------------------------------------
378 namespace topology
379 {
380     //-------------------------------------------------------------------------
381     index_t CONDUIT_BLUEPRINT_API dims(const conduit::Node &topo);
382 
383     //-------------------------------------------------------------------------
384     void CONDUIT_BLUEPRINT_API logical_dims(const Node &n, index_t *d, index_t maxdims);
385 
386     //-------------------------------------------------------------------------
387     index_t CONDUIT_BLUEPRINT_API length(const conduit::Node &topo);
388 
389     //-------------------------------------------------------------------------
390     // -- begin conduit::blueprint::mesh::utils::topology::unstructured --
391     //-------------------------------------------------------------------------
392     namespace unstructured
393     {
394         // TODO(JRC): Expose this 'cache' version of the function publicly?
395         //-------------------------------------------------------------------------
396         void CONDUIT_BLUEPRINT_API generate_offsets(Node &topo,
397                                                     Node &dest);
398 
399         //-------------------------------------------------------------------------
400         void CONDUIT_BLUEPRINT_API generate_offsets(const Node &topo,
401                                                     Node &dest);
402 
403         //-------------------------------------------------------------------------
404         std::vector<index_t> CONDUIT_BLUEPRINT_API points(const Node &topo,
405                                                           const index_t i);
406     }
407     //-------------------------------------------------------------------------
408     // -- end conduit::blueprint::mesh::utils::topology::unstructured --
409     //-------------------------------------------------------------------------
410 }
411 //-----------------------------------------------------------------------------
412 // -- end conduit::blueprint::mesh::utils::topology --
413 //-----------------------------------------------------------------------------
414 
415 //-----------------------------------------------------------------------------
416 // -- begin conduit::blueprint::mesh::utils::adjset --
417 //-----------------------------------------------------------------------------
418 namespace adjset
419 {
420     //-------------------------------------------------------------------------
421     void CONDUIT_BLUEPRINT_API canonicalize(Node &adjset);
422 }
423 //-----------------------------------------------------------------------------
424 // -- end conduit::blueprint::mesh::utils::adjset --
425 //-----------------------------------------------------------------------------
426 
427 }
428 //-----------------------------------------------------------------------------
429 // -- end conduit::blueprint::mesh::utils --
430 //-----------------------------------------------------------------------------
431 
432 //-----------------------------------------------------------------------------
433 }
434 //-----------------------------------------------------------------------------
435 // -- end conduit::blueprint::mesh --
436 //-----------------------------------------------------------------------------
437 
438 
439 }
440 //-----------------------------------------------------------------------------
441 // -- end conduit::blueprint --
442 //-----------------------------------------------------------------------------
443 
444 }
445 //-----------------------------------------------------------------------------
446 // -- end conduit:: --
447 //-----------------------------------------------------------------------------
448 
449 
450 #endif
451