Skip to content

Commit 6fa448a

Browse files
committed
Prototype CGNS blueprint mesh relay output
1 parent 2eec1ad commit 6fa448a

13 files changed

+929
-0
lines changed

src/cmake/Setup3rdParty.cmake

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,19 @@ if(HDF5_DIR)
123123
endif()
124124
endif()
125125

126+
################################
127+
# Setup CGNS if available
128+
################################
129+
# Search for CGNS.
130+
if(CGNS_DIR)
131+
include(cmake/thirdparty/SetupCGNS.cmake)
132+
include_directories(${CGNS_INCLUDE_DIRS})
133+
# if we don't find CGNS, throw a fatal error
134+
if(NOT CGNS_FOUND)
135+
message(FATAL_ERROR "CGNS_DIR is set, but CGNS wasn't found.")
136+
endif()
137+
endif()
138+
126139
################################
127140
# Setup Silo if available
128141
################################

src/cmake/thirdparty/SetupCGNS.cmake

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
# first Check for CGNS_DIR
3+
if(NOT CGNS_DIR)
4+
MESSAGE(FATAL_ERROR "CGNS support needs explicit CGNS_DIR")
5+
endif()
6+
7+
set(CGNS_ROOT ${CGNS_DIR})
8+
9+
find_package(CGNS REQUIRED)
10+
11+
get_target_property(CGNS_INCLUDE_DIRS CGNS::cgns_shared INTERFACE_INCLUDE_DIRECTORIES)
12+
message(STATUS "CGNS Include Directory: ${CGNS_INCLUDE_DIRS}")

src/docs/sphinx/building.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ CMake Options for Third-party Library Paths
143143
* - ``ZLIB_DIR``
144144
- Path to a Zlib install (optional). (Needed for HDF5 support)
145145

146+
* - ``CGNS_DIR``
147+
- Path to a CGNS install (optional). Controls if CGNS I/O support is built into *conduit_relay*.
148+
146149
* - ``SILO_DIR``
147150
- Path to a Silo install (optional). Controls if Silo I/O support is built into *conduit_relay*. Requires HDF5.
148151

src/libs/relay/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ if(HDF5_FOUND)
1616
SET(CONDUIT_RELAY_IO_HDF5_ENABLED TRUE)
1717
endif()
1818

19+
if(CGNS_FOUND)
20+
SET(CONDUIT_RELAY_IO_CGNS_ENABLED TRUE)
21+
endif()
22+
1923
if(H5ZZFP_FOUND)
2024
SET(CONDUIT_RELAY_IO_H5ZZFP_ENABLED TRUE)
2125
endif()
@@ -119,6 +123,13 @@ if(HDF5_FOUND)
119123
list(APPEND conduit_relay_sources conduit_relay_io_hdf5.cpp)
120124
endif()
121125

126+
if(CGNS_FOUND)
127+
list(APPEND conduit_relay_headers
128+
conduit_relay_io_cgns.hpp
129+
)
130+
list(APPEND conduit_relay_sources conduit_relay_io_cgns.cpp)
131+
endif()
132+
122133
if(SILO_FOUND)
123134
list(APPEND conduit_relay_headers
124135
conduit_relay_silo.hpp
@@ -193,6 +204,10 @@ if(HDF5_FOUND)
193204
endif()
194205
endif()
195206

207+
if(CGNS_FOUND)
208+
list(APPEND conduit_relay_deps CGNS::pcgns_shared)
209+
endif()
210+
196211
if(H5ZZFP_FOUND)
197212
list(APPEND conduit_relay_deps h5zzfp)
198213
endif()

src/libs/relay/conduit_relay_config.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
#cmakedefine CONDUIT_RELAY_IO_HDF5_ENABLED
2424

25+
#cmakedefine CONDUIT_RELAY_IO_CGNS_ENABLED
26+
2527
#cmakedefine CONDUIT_RELAY_IO_H5ZZFP_ENABLED
2628

2729
#cmakedefine CONDUIT_RELAY_IO_SILO_ENABLED

src/libs/relay/conduit_relay_io.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ about(Node &n)
9898
io_protos["sidre_hdf5"] = "enabled";
9999
#endif
100100

101+
#ifdef CONDUIT_RELAY_IO_CGNS_ENABLED
102+
io_protos["cgns"] = "enabled";
103+
#else
104+
io_protos["cgns"] = "disabled";
105+
#endif
106+
101107
#ifdef CONDUIT_RELAY_IO_H5ZZFP_ENABLED
102108
io_protos["h5z-zfp"] = "enabled";
103109
#else
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
#include "conduit_relay_io_cgns.hpp"
2+
3+
//-----------------------------------------------------------------------------
4+
// external lib includes
5+
//-----------------------------------------------------------------------------
6+
#ifdef CONDUIT_RELAY_IO_CGNS_ENABLED
7+
#include <pcgnslib.h>
8+
#endif
9+
10+
namespace {
11+
12+
std::string meshType(const conduit::Node &node) {
13+
return node["/topologies/mesh/elements/shape"].as_string();
14+
}
15+
16+
int physicalDimension(const conduit::Node &node) {
17+
return node["/coordsets/coords/values"].number_of_children();
18+
}
19+
20+
int cellDimension(const conduit::Node &node) {
21+
const auto type = meshType(node);
22+
if (type == "tet") {
23+
return 3;
24+
} else if (type == "hex") {
25+
return 3;
26+
} else if (type == "tri") {
27+
return 2;
28+
} else if (type == "quad") {
29+
return 2;
30+
} else {
31+
CONDUIT_ERROR("cellDimension: unknown type " << type);
32+
}
33+
return 0;
34+
}
35+
36+
std::int64_t nVerts(const conduit::Node &node) {
37+
return node["/coordsets/coords/values/x"].dtype().is_float64()
38+
? node["/coordsets/coords/values/x"].as_float64_array()
39+
.number_of_elements()
40+
: node["/coordsets/coords/values/x"].as_float32_array()
41+
.number_of_elements();
42+
}
43+
44+
std::int64_t nConn(const conduit::Node &node) {
45+
return node["/topologies/mesh/elements/connectivity"]
46+
.dtype()
47+
.is_int64()
48+
? node["/topologies/mesh/elements/connectivity"]
49+
.as_int64_array()
50+
.number_of_elements()
51+
: node["/topologies/mesh/elements/connectivity"]
52+
.as_int32_array()
53+
.number_of_elements();
54+
}
55+
56+
std::int64_t nCells(const conduit::Node &node) {
57+
const std::int64_t nconn = nConn(node);
58+
const auto type = meshType(node);
59+
if (type == "tet"){
60+
return nconn/4;
61+
} else if (type == "hex"){
62+
return nconn/8;
63+
} else if (type == "tri"){
64+
return nconn/3;
65+
} else if (type == "quad"){
66+
return nconn/4;
67+
} else {
68+
CONDUIT_ERROR("ncells: unknown type " << type);
69+
}
70+
return 0;
71+
}
72+
73+
} // namespace
74+
75+
//-----------------------------------------------------------------------------
76+
// -- begin conduit:: --
77+
//-----------------------------------------------------------------------------
78+
namespace conduit {
79+
80+
//-----------------------------------------------------------------------------
81+
// -- begin conduit::relay --
82+
//-----------------------------------------------------------------------------
83+
namespace relay {
84+
85+
//-----------------------------------------------------------------------------
86+
// -- begin conduit::relay::io --
87+
//-----------------------------------------------------------------------------
88+
namespace io {
89+
90+
//-----------------------------------------------------------------------------
91+
// -- begin conduit::relay::io::cgns --
92+
//-----------------------------------------------------------------------------
93+
namespace cgns {
94+
95+
void save_mesh(const conduit::Node &mesh, const std::string &path) {
96+
97+
CONDUIT_INFO("conduit::relay::io::cgns__save_mesh(const Node &node, const "
98+
"std::string &path)\n");
99+
if (mesh["/coordsets/coords/type"].as_string() != "explicit") {
100+
CONDUIT_ERROR(
101+
"cgns::save_mesh only supports reading 'explicit' coordinate sets "
102+
"at this time.");
103+
}
104+
105+
mesh.print();
106+
107+
// for multi-file, maybe ".root.cgns"
108+
const std::string filename = path + ".cgns";
109+
110+
int file_index;
111+
if (cg_open(filename.c_str(), CG_MODE_WRITE, &file_index)) {
112+
cg_error_exit();
113+
}
114+
const int cell_dim = cellDimension(mesh);
115+
const int phys_dim = physicalDimension(mesh);
116+
117+
int base_index;
118+
if (cg_base_write(file_index, "Base", cell_dim, phys_dim, &base_index)) {
119+
cg_error_exit();
120+
}
121+
122+
123+
cgsize_t isize[3][1];
124+
isize[0][0] = nVerts(mesh);
125+
isize[1][0] = nCells(mesh);
126+
isize[2][0] = 0;
127+
int zone_index;
128+
if (cg_zone_write(file_index, base_index, "Zone", isize[0], CG_Unstructured,
129+
&zone_index)) {
130+
cg_error_exit();
131+
}
132+
133+
134+
auto write_coord = [&](const std::string &coord_path,
135+
const std::string &coord_name) {
136+
int coord_index;
137+
if (mesh[coord_path].dtype().is_float64()) {
138+
if (cg_coord_write(file_index, base_index, zone_index, CG_RealDouble,
139+
coord_name.c_str(),
140+
mesh[coord_path].as_float64_array().data_ptr(),
141+
&coord_index)) {
142+
cg_error_exit();
143+
}
144+
} else if (mesh[coord_path].dtype().is_float32()) {
145+
if (cg_coord_write(file_index, base_index, zone_index, CG_RealSingle,
146+
coord_name.c_str(),
147+
mesh[coord_path].as_float32_array().data_ptr(),
148+
&coord_index)) {
149+
cg_error_exit();
150+
}
151+
} else {
152+
CONDUIT_ERROR("CGNSHandle coordinate only supports float32 and float64.");
153+
}
154+
};
155+
156+
write_coord("/coordsets/coords/values/x", "CoordinateX");
157+
if (phys_dim > 1){
158+
write_coord("/coordsets/coords/values/y", "CoordinateY");
159+
}
160+
if (phys_dim > 2){
161+
write_coord("/coordsets/coords/values/z", "CoordinateZ");
162+
}
163+
164+
if (cg_close(file_index)) {
165+
cg_error_exit();
166+
}
167+
}
168+
169+
void load_mesh(const std::string &root_file_path, conduit::Node &mesh) {}
170+
171+
} // namespace cgns
172+
//-----------------------------------------------------------------------------
173+
// -- end conduit::relay::io::cgns --
174+
//-----------------------------------------------------------------------------
175+
176+
} // namespace io
177+
//-----------------------------------------------------------------------------
178+
// -- end conduit::relay::io --
179+
//-----------------------------------------------------------------------------
180+
181+
} // namespace relay
182+
// namespace relay
183+
//-----------------------------------------------------------------------------
184+
// -- end conduit::relay --
185+
//-----------------------------------------------------------------------------
186+
187+
} // namespace conduit
188+
// namespace conduit
189+
//-----------------------------------------------------------------------------
190+
// -- end conduit:: --
191+
//-----------------------------------------------------------------------------
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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_relay_io_cgns.hpp
8+
///
9+
//-----------------------------------------------------------------------------
10+
11+
#ifndef CONDUIT_RELAY_IO_CGNS_HPP
12+
#define CONDUIT_RELAY_IO_CGNS_HPP
13+
14+
//-----------------------------------------------------------------------------
15+
// conduit lib include
16+
//-----------------------------------------------------------------------------
17+
#include "conduit.hpp"
18+
#include "conduit_relay_config.h"
19+
#include "conduit_relay_exports.h"
20+
21+
//-----------------------------------------------------------------------------
22+
// -- begin conduit:: --
23+
//-----------------------------------------------------------------------------
24+
namespace conduit {
25+
26+
//-----------------------------------------------------------------------------
27+
// -- begin conduit::relay --
28+
//-----------------------------------------------------------------------------
29+
namespace relay {
30+
31+
//-----------------------------------------------------------------------------
32+
// -- begin conduit::relay::io --
33+
//-----------------------------------------------------------------------------
34+
namespace io {
35+
36+
37+
//-----------------------------------------------------------------------------
38+
// -- begin conduit::relay::io::cgns --
39+
//-----------------------------------------------------------------------------
40+
namespace cgns {
41+
42+
//-----------------------------------------------------------------------------
43+
// Save a blueprint mesh to cgns
44+
//-----------------------------------------------------------------------------
45+
/// These methods assume `mesh` is a valid blueprint mesh.
46+
///
47+
/// Note: These methods use "save" semantics, they will overwrite existing
48+
/// files.
49+
///
50+
///
51+
//-----------------------------------------------------------------------------
52+
void CONDUIT_RELAY_API save_mesh(const conduit::Node &mesh,
53+
const std::string &path);
54+
55+
//-----------------------------------------------------------------------------
56+
// The load semantics, the mesh node is reset before reading.
57+
//-----------------------------------------------------------------------------
58+
59+
//-----------------------------------------------------------------------------
60+
void CONDUIT_RELAY_API load_mesh(const std::string &root_file_path,
61+
conduit::Node &mesh);
62+
63+
}
64+
//-----------------------------------------------------------------------------
65+
// -- end conduit::relay::io::cgns --
66+
//-----------------------------------------------------------------------------
67+
68+
//-----------------------------------------------------------------------------
69+
/// Save node data to a given path.
70+
///
71+
/// Save Semantics: Existing file will be overwritten
72+
//-----------------------------------------------------------------------------
73+
void CONDUIT_RELAY_API cgns_save(const Node &node,
74+
const std::string &path);
75+
}
76+
//-----------------------------------------------------------------------------
77+
// -- end conduit::relay::io --
78+
//-----------------------------------------------------------------------------
79+
80+
}
81+
// namespace relay
82+
//-----------------------------------------------------------------------------
83+
// -- end conduit::relay --
84+
//-----------------------------------------------------------------------------
85+
86+
} // namespace conduit
87+
//-----------------------------------------------------------------------------
88+
// -- end conduit:: --
89+
//-----------------------------------------------------------------------------
90+
91+
#endif

0 commit comments

Comments
 (0)