Skip to content

Commit 3d2d7d8

Browse files
authored
Merge pull request #735 from sebproell/exodus-numbering-options
Use the same internal numbering for direct Exodus input
2 parents 19ff3b6 + d866971 commit 3d2d7d8

File tree

6 files changed

+66
-74
lines changed

6 files changed

+66
-74
lines changed

src/core/io/src/4C_io_exodus.cpp

Lines changed: 16 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ namespace
107107
/*----------------------------------------------------------------------*
108108
| ctor (public) maf 12/07|
109109
*----------------------------------------------------------------------*/
110-
Core::IO::Exodus::Mesh::Mesh(const std::string exofilename)
110+
Core::IO::Exodus::Mesh::Mesh(std::filesystem::path exodus_file, MeshParameters mesh_data)
111+
: mesh_data_(mesh_data)
111112
{
112113
int error;
113114
int CPU_word_size, IO_word_size;
@@ -118,8 +119,8 @@ Core::IO::Exodus::Mesh::Mesh(const std::string exofilename)
118119

119120
// open EXODUS II file
120121
int exo_handle =
121-
ex_open(exofilename.c_str(), EX_READ, &CPU_word_size, &IO_word_size, &exoversion);
122-
if (exo_handle <= 0) FOUR_C_THROW("Error while opening EXODUS II file {}", exofilename);
122+
ex_open(exodus_file.c_str(), EX_READ, &CPU_word_size, &IO_word_size, &exoversion);
123+
if (exo_handle <= 0) FOUR_C_THROW("Error while opening EXODUS II file {}", exodus_file.string());
123124

124125
// read database parameters
125126
int num_elem_blk, num_node_sets, num_side_sets, num_nodes;
@@ -138,10 +139,12 @@ Core::IO::Exodus::Mesh::Mesh(const std::string exofilename)
138139
error = ex_get_coord(exo_handle, x.data(), y.data(), z.data());
139140
if (error != 0) FOUR_C_THROW("exo error returned");
140141

142+
FOUR_C_ASSERT_ALWAYS(
143+
mesh_data_.node_start_id >= 0, "Node start id must be greater than or equal to 0");
144+
141145
for (int i = 0; i < num_nodes; ++i)
142146
{
143-
// Node numbering starts at one in 4C
144-
nodes_[i + 1] = {x[i], y[i], z[i]};
147+
nodes_[i + mesh_data_.node_start_id] = {x[i], y[i], z[i]};
145148
}
146149
}
147150

@@ -175,13 +178,16 @@ Core::IO::Exodus::Mesh::Mesh(const std::string exofilename)
175178
error = ex_get_conn(exo_handle, EX_ELEM_BLOCK, ebids[i], allconn.data(), nullptr, nullptr);
176179
if (error != 0) FOUR_C_THROW("exo error returned");
177180
std::map<int, std::vector<int>> eleconn;
181+
182+
// Compare the desired start ID to Exodus' one-based indexing to get the offset.
183+
const int node_offset = mesh_data_.node_start_id - 1;
178184
for (int j = 0; j < num_el_in_blk; ++j)
179185
{
180186
std::vector<int>& actconn = eleconn[j];
181187
actconn.reserve(num_nod_per_elem);
182188
for (int k = 0; k < num_nod_per_elem; ++k)
183189
{
184-
actconn.push_back(allconn[k + j * num_nod_per_elem]);
190+
actconn.push_back(allconn[k + j * num_nod_per_elem] + node_offset);
185191
}
186192
reorder_nodes_exodus_to_four_c(actconn, cell_type_from_exodus_string(ele_type));
187193
}
@@ -217,10 +223,12 @@ Core::IO::Exodus::Mesh::Mesh(const std::string exofilename)
217223
else if (error < 0)
218224
FOUR_C_THROW("error reading node set");
219225
std::set<int> nodes_in_set;
220-
for (int j = 0; j < num_nodes_in_set; ++j) nodes_in_set.insert(node_set_node_list[j]);
226+
// Compare the desired start ID to Exodus' one-based indexing to get the offset.
227+
const int node_offset = mesh_data_.node_start_id - 1;
228+
for (int j = 0; j < num_nodes_in_set; ++j)
229+
nodes_in_set.insert(node_set_node_list[j] + node_offset);
221230
NodeSet actNodeSet(nodes_in_set, nodesetname);
222231

223-
// Add this NodeSet into Mesh map (here prelim due to pro names)
224232
node_sets_.insert(std::pair<int, NodeSet>(npropID[i], actNodeSet));
225233
}
226234
} // end of nodeset section
@@ -362,48 +370,6 @@ void Core::IO::Exodus::Mesh::set_nsd(const int nsd)
362370

363371
four_c_dim_ = nsd;
364372
}
365-
/*----------------------------------------------------------------------*/
366-
/*----------------------------------------------------------------------*/
367-
368-
369-
/*----------------------------------------------------------------------*/
370-
/*----------------------------------------------------------------------*/
371-
std::vector<double> Core::IO::Exodus::Mesh::normal(
372-
const int head1, const int origin, const int head2) const
373-
{
374-
std::vector<double> normal(3);
375-
std::vector<double> h1 = get_node(head1);
376-
std::vector<double> h2 = get_node(head2);
377-
std::vector<double> o = get_node(origin);
378-
379-
normal[0] = ((h1[1] - o[1]) * (h2[2] - o[2]) - (h1[2] - o[2]) * (h2[1] - o[1]));
380-
normal[1] = -((h1[0] - o[0]) * (h2[2] - o[2]) - (h1[2] - o[2]) * (h2[0] - o[0]));
381-
normal[2] = ((h1[0] - o[0]) * (h2[1] - o[1]) - (h1[1] - o[1]) * (h2[0] - o[0]));
382-
383-
double length = sqrt(normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2]);
384-
normal[0] = normal[0] / length;
385-
normal[1] = normal[1] / length;
386-
normal[2] = normal[2] / length;
387-
388-
return normal;
389-
}
390-
391-
/*----------------------------------------------------------------------*/
392-
/*----------------------------------------------------------------------*/
393-
std::vector<double> Core::IO::Exodus::Mesh::node_vec(const int tail, const int head) const
394-
{
395-
std::vector<double> nv(3);
396-
std::vector<double> t = get_node(tail);
397-
std::vector<double> h = get_node(head);
398-
nv[0] = h[0] - t[0];
399-
nv[1] = h[1] - t[1];
400-
nv[2] = h[2] - t[2];
401-
double length = sqrt(nv[0] * nv[0] + nv[1] * nv[1] + nv[2] * nv[2]);
402-
nv[0] = nv[0] / length;
403-
nv[1] = nv[1] / length;
404-
nv[2] = nv[2] / length;
405-
return nv;
406-
}
407373

408374

409375
/*----------------------------------------------------------------------*/

src/core/io/src/4C_io_exodus.hpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "4C_fem_general_element.hpp"
1414

15+
#include <filesystem>
1516
#include <set>
1617
#include <string>
1718
#include <vector>
@@ -25,14 +26,31 @@ namespace Core::IO::Exodus
2526
class NodeSet;
2627
class SideSet;
2728

29+
/**
30+
* Additional parameters that are used in the constructor.
31+
*/
32+
struct MeshParameters
33+
{
34+
/**
35+
* The ID of the first node in the mesh. This defaults to 1, since this is the default in
36+
* the Exodus II mesh format.
37+
*/
38+
int node_start_id{1};
39+
};
40+
2841
/**
2942
* A class that stores the mesh information read from an Exodus file.
3043
*/
3144
class Mesh
3245
{
3346
public:
34-
//! constructor
35-
Mesh(std::string exofilename);
47+
/**
48+
* @brief Read a mesh from an Exodus file.
49+
*
50+
* Read the data from the Exodus file and store it in the class. The optional @p
51+
* mesh_data can be used to set options documented in the MeshData struct.
52+
*/
53+
Mesh(std::filesystem::path exodus_file, MeshParameters mesh_data = {});
3654

3755
//! Print mesh info
3856
void print(std::ostream& os, bool verbose = false) const;
@@ -76,12 +94,6 @@ namespace Core::IO::Exodus
7694
//! Get one SideSet
7795
SideSet get_side_set(const int id) const;
7896

79-
//! Get edge Normal at node
80-
std::vector<double> normal(const int head1, const int origin, const int head2) const;
81-
82-
//! Get normalized Vector between 2 nodes
83-
std::vector<double> node_vec(const int tail, const int head) const;
84-
8597
//! Get Node map
8698
const std::map<int, std::vector<double>>& get_nodes() const { return nodes_; }
8799

@@ -95,6 +107,8 @@ namespace Core::IO::Exodus
95107
void set_nsd(const int nsd);
96108

97109
private:
110+
MeshParameters mesh_data_;
111+
98112
std::map<int, std::vector<double>> nodes_;
99113

100114
std::map<int, ElementBlock> element_blocks_;

src/core/io/src/4C_io_meshreader.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -822,8 +822,11 @@ namespace
822822

823823
const auto& geometry_data = data.group(exodus_reader.section_name);
824824
const auto& exodus_file = geometry_data.get<std::filesystem::path>("FILE");
825-
exodus_reader.mesh_on_rank_zero =
826-
std::make_unique<Core::IO::Exodus::Mesh>(exodus_file.string());
825+
exodus_reader.mesh_on_rank_zero = std::make_unique<Core::IO::Exodus::Mesh>(
826+
exodus_file.string(), Core::IO::Exodus::MeshParameters{
827+
// We internally depend on node numbers starting at 0.
828+
.node_start_id = 0,
829+
});
827830
const auto& mesh = *exodus_reader.mesh_on_rank_zero;
828831

829832
// Initial implementation:

src/core/io/tests/4C_io_exodus_test.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,13 @@ namespace
2929

3030
mesh.print(std::cout, true);
3131
}
32+
33+
TEST(Exodus, NodeOffset)
34+
{
35+
Core::IO::Exodus::Mesh mesh(TESTING::get_support_file_path("test_files/exodus/cube.exo"),
36+
Core::IO::Exodus::MeshParameters{.node_start_id = 100});
37+
EXPECT_EQ(mesh.get_node(100), (std::vector<double>{-5.0, 0.0, 0.0}));
38+
EXPECT_EQ(mesh.get_element_block(1).get_ele_nodes(1),
39+
(std::vector<int>{108, 100, 103, 109, 110, 104, 107, 111}));
40+
}
3241
} // namespace

tests/input_files/contact3D_exodus_in.4C.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,13 @@ DESIGN SURF DIRICH CONDITIONS:
8282
RESULT DESCRIPTION:
8383
- STRUCTURE:
8484
DIS: structure
85-
NODE: 1270
85+
NODE: 1269
8686
QUANTITY: dispx
8787
VALUE: -8.31974725251016095e-03
8888
TOLERANCE: 1e-8
8989
- STRUCTURE:
9090
DIS: structure
91-
NODE: 1372
91+
NODE: 1371
9292
QUANTITY: dispx
9393
VALUE: -8.36015173005985428e-03
9494
TOLERANCE: 1e-8

tests/input_files/fluid_exodus_in.4C.yaml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,73 +65,73 @@ DESIGN POINT DIRICH CONDITIONS:
6565
RESULT DESCRIPTION:
6666
- FLUID:
6767
DIS: "fluid"
68-
NODE: 2912
68+
NODE: 2911
6969
QUANTITY: "velx"
7070
VALUE: 0
7171
TOLERANCE: 1e-08
7272
- FLUID:
7373
DIS: "fluid"
74-
NODE: 2912
74+
NODE: 2911
7575
QUANTITY: "vely"
7676
VALUE: 0
7777
TOLERANCE: 1e-08
7878
- FLUID:
7979
DIS: "fluid"
80-
NODE: 2912
80+
NODE: 2911
8181
QUANTITY: "pressure"
8282
VALUE: 2.316272235592883
8383
TOLERANCE: 1e-10
8484
- FLUID:
8585
DIS: "fluid"
86-
NODE: 4034
86+
NODE: 4033
8787
QUANTITY: "velx"
8888
VALUE: 0
8989
TOLERANCE: 1e-08
9090
- FLUID:
9191
DIS: "fluid"
92-
NODE: 4034
92+
NODE: 4033
9393
QUANTITY: "vely"
9494
VALUE: 0
9595
TOLERANCE: 1e-08
9696
- FLUID:
9797
DIS: "fluid"
98-
NODE: 4034
98+
NODE: 4033
9999
QUANTITY: "pressure"
100100
VALUE: 1.5110014506671248
101101
TOLERANCE: 1e-08
102102
- FLUID:
103103
DIS: "fluid"
104-
NODE: 6667
104+
NODE: 6666
105105
QUANTITY: "velx"
106106
VALUE: 0.8140348125434049
107107
TOLERANCE: 1e-08
108108
- FLUID:
109109
DIS: "fluid"
110-
NODE: 6667
110+
NODE: 6666
111111
QUANTITY: "vely"
112112
VALUE: -0.022743581282554975
113113
TOLERANCE: 1e-10
114114
- FLUID:
115115
DIS: "fluid"
116-
NODE: 6667
116+
NODE: 6666
117117
QUANTITY: "pressure"
118118
VALUE: 2.0581385928541125
119119
TOLERANCE: 1e-10
120120
- FLUID:
121121
DIS: "fluid"
122-
NODE: 6998
122+
NODE: 6997
123123
QUANTITY: "velx"
124124
VALUE: 0.9708173796517694
125125
TOLERANCE: 1e-08
126126
- FLUID:
127127
DIS: "fluid"
128-
NODE: 6998
128+
NODE: 6997
129129
QUANTITY: "vely"
130130
VALUE: -7.977045433472414e-16
131131
TOLERANCE: 1e-08
132132
- FLUID:
133133
DIS: "fluid"
134-
NODE: 6998
134+
NODE: 6997
135135
QUANTITY: "pressure"
136136
VALUE: 1.8450141345624358
137137
TOLERANCE: 1e-10

0 commit comments

Comments
 (0)