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