1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208 | // *****************************************************************************
/*!
\file src/IO/FileConvWriter.cpp
\copyright 2012-2015 J. Bakosi,
2016-2018 Los Alamos National Security, LLC.,
2019-2021 Triad National Security, LLC.
All rights reserved. See the LICENSE file for details.
\brief Converter Writer Files
\details Convert the input file written by RootMeshWriter into ExodusII
layout. We make use of the ExodusIIMeshWriter class to write the
output file.
*/
// *****************************************************************************
#include <cmath>
#include <string>
#include <numeric>
#include <iostream>
#include "NoWarning/exodusII.hpp"
#include "NoWarning/TFile.hpp"
#include "NoWarning/TTree.hpp"
#include "FileConvWriter.hpp"
#include "ContainerUtil.hpp"
#include "Exception.hpp"
using tk::FileConvWriter;
FileConvWriter::FileConvWriter( const std::string& file_root,<--- Member variable 'FileConvWriter::m_nodal_size' is not initialized in the constructor.
const std::string& file_exodus) :
m_file_root( file_root ),
m_file_exodus( file_exodus )
// *****************************************************************************
// Constructor: open Exodus II file, Root file
//! \param[in] file_root File to open as ROOT file
//! \param[in] file_exodus File to be opened as ExodusII file to be written
// *****************************************************************************
{
m_emw = std::make_unique< tk::ExodusIIMeshWriter ><--- Variable 'm_emw' is assigned in constructor body. Consider performing initialization in initialization list. [+]When an object of a class is created, the constructors of all member variables are called consecutively in the order the variables are declared, even if you don't explicitly write them to the initialization list. You could avoid assigning 'm_emw' a value by passing the value to the constructor in the initialization list.
( file_exodus.c_str(), tk::ExoWriter::CREATE );
m_infile = std::make_unique< TFile >( file_root.c_str() );
// If the ROOT file can be opened, fetch the TTree reference
if( m_infile == nullptr ){
std::cerr << "Unable to open the file " << file_root.c_str() << std::endl;
} else {
// the tree is named as ctree in the RootMeshWriter
m_tree_local = static_cast< TTree* >( m_infile->Get( "ctree" ) );
}
}
FileConvWriter::~FileConvWriter() noexcept
// *****************************************************************************
// Destructor
// *****************************************************************************
{
// close the ROOT file
m_infile->Close();
}
void
FileConvWriter::convertFiles()
//*****************************************************************************
// Convert the input file [ROOT] layout to output file [ExodusII] layout
//*****************************************************************************
{
writeHeader();
writeVarNames();
writeConnectivity();
writeCoordinates();
writeData();
}
void
FileConvWriter::writeHeader()
//*****************************************************************************
// Write the Header details
//*****************************************************************************
{
int coord, connect;
m_tree_local->SetBranchAddress( "trian", &connect );
m_tree_local->SetBranchAddress( "coord", &coord );
m_tree_local->GetEntry( 0 );
m_emw->writeHeader( "Data copied from ROOT",
3,
coord,
(connect / 4),
1, 0, 0 );
m_tree_local->ResetBranchAddresses();
}
void
FileConvWriter::writeCoordinates()
//*****************************************************************************
// Write the Coordinates (x,y,z) data
//*****************************************************************************
{
std::vector< tk::real > *mx = nullptr;
std::vector< tk::real > *my = nullptr;
std::vector< tk::real > *mz = nullptr;
m_tree_local->SetBranchAddress( "x_coord", &mx );
m_tree_local->SetBranchAddress( "y_coord", &my );
m_tree_local->SetBranchAddress( "z_coord", &mz );
m_tree_local->GetEntry( 0 );
// write to ExodusII
m_emw->writeNodes( *mx, *my, *mz );
m_tree_local->ResetBranchAddresses();
}
void
FileConvWriter::writeConnectivity()
//*****************************************************************************
// Write the Connectivity between the coordinates.
//*****************************************************************************
{
// param[0] - elclass, refer ExodusIIMeshWriter.C
// param[1] - vertices, 4 is the number of vertices of Tetrahedron
// param[2] - string literal TETRAHEDRA/TRIANGLES
int elclass = 0;
std::vector<std::size_t> *tets_number = nullptr;
m_tree_local->SetBranchAddress( "tetconnect", &tets_number );
m_tree_local->GetEntry( 0 );
m_emw->writeElemBlock( elclass, 4, "TETRAHEDRA", *tets_number );
m_tree_local->ResetBranchAddresses();
}
void
FileConvWriter::writeVarNames()
//*****************************************************************************
// Write the Variables names
//*****************************************************************************
{
std::vector<std::string> *var_copy = nullptr;
m_tree_local->SetBranchAddress( "variables", &var_copy );
m_tree_local->GetEntry(0);
m_emw->writeNodeVarNames( *var_copy );
m_nodal_size = var_copy->size();
m_tree_local->ResetBranchAddresses();
}
void
FileConvWriter::writeData()
//*****************************************************************************
// Write the Timestamp and Variables from Input to Output
//*****************************************************************************
{
std::size_t timestep = 1;
while( true ) {
double dt = 0;
std::string time_branch = "time_branch_" + std::to_string(timestep);
if( m_tree_local->GetBranch( time_branch.c_str() ) == nullptr )
break;
for (std::size_t var_id=1; var_id<=m_nodal_size; ++var_id) {
std::string branch_var = "branch_" + std::to_string(timestep) + "_field_"
+ std::to_string(var_id);
if( m_tree_local->GetBranch( branch_var.c_str() ) == nullptr )
break;
else {
std::vector< double> *var_fields = nullptr;
m_tree_local->SetBranchAddress( branch_var.c_str(), &var_fields );
m_tree_local->SetBranchAddress(time_branch.c_str(), &dt );
m_tree_local->GetEntry(0);
m_emw->writeNodeScalar( timestep,
static_cast<int>(var_id),
*var_fields );
}
} // End the variables loop.
// Write the timestamp variable, once per timestep
m_emw->writeTimeStamp( timestep, dt );
++timestep;
} // break after all the variables for all the timesteps are written
m_tree_local->ResetBranchAddresses();
}
|