Write VTU/PVD (and optional strain VTU / particle-location CSV).
32 {
33
34
35
36 {
37 float p = float(
data.d_n) * 100. /
data.d_modelDeck_p->d_Nt;
38 int m = std::max(1,
int(
data.d_modelDeck_p->d_Nt / 10));
39 if (
data.d_n % m == 0 &&
int(p) > 0)
41 data.d_name,
int(p)));
42 ;
43 }
44
45 util::io::log(2, std::format(
"{}: Output step = {}, time = {:.6f} \n",
47
48 if (
data.d_outputDeck_p->d_debug > 0 and
data.getKeyData(
"debug_once") < 0) {
49
50 data.setKeyData(
"debug_once", 1);
51
52 size_t nt = 1;
54 std::ostringstream oss;
55 oss << tabS << "*******************************************\n";
56 oss << tabS << "Debug various input decks\n\n\n";
57 oss <<
data.d_modelDeck_p->printStr(nt + 1);
58 oss <<
data.d_particleDeck_p->printStr(nt + 1);
59 oss <<
data.d_outputDeck_p->printStr(nt + 1);
60 oss <<
data.d_restartDeck_p->printStr(nt + 1);
61 oss <<
data.d_testDeck_p->printStr(nt + 1);
62 oss <<
data.d_bcDeck_p->printStr(nt + 1);
63 oss << tabS << "\n\n*******************************************\n";
64 oss << tabS << "Debug particle data\n\n\n";
65 oss << tabS <<
"Number of particles = " <<
data.d_particlesListTypeAll.size() << std::endl;
66 oss << tabS <<
"Number of particle zones = " <<
data.d_zInfo.size() << std::endl;
67 for (
auto zone :
data.d_zInfo) {
69 << std::endl;
70 }
71
72
73 oss << tabS <<
"Number of walls = " <<
data.d_particlesListTypeWall.size() << std::endl;
74 for (
auto &d_wall :
data.d_particlesListTypeWall)
75 oss << tabS << "Number of nodes in wall " << d_wall->d_id
76 << " is " << d_wall->getNumNodes() << std::endl;
77
78 oss << tabS <<
"h_min = " <<
data.d_hMin <<
", h_max = " <<
data.d_hMax << std::endl;
79
81 }
82
83 size_t dt_out =
data.d_outputDeck_p->d_dtOutCriteria;
84 const size_t frame =
data.d_n / dt_out;
85 const std::string tag =
86 data.d_outputDeck_p->d_tagPPFile.empty()
87 ? std::to_string(frame)
88 :
data.d_outputDeck_p->d_tagPPFile +
"_" + std::to_string(frame);
89 const std::string path =
data.d_outputDeck_p->d_path;
92 const bool parallel_pieces = mpi_size > 1;
93
94
95 std::string piece_stem = path + "output_" + tag;
96 if (parallel_pieces)
97 piece_stem += "_r" + std::to_string(mpi_rank);
98
99 {
101 writer.appendMeshParallelPiece(&
data,
data.d_outputDeck_p->d_outTags);
102 writer.addTimeStep(
data.d_time);
103 writer.close();
104 }
105
106 if (
data.d_outputDeck_p->d_outFormat ==
"vtu" &&
107 data.d_outputDeck_p->d_pvdCollection) {
108 if (parallel_pieces) {
109
111 if (mpi_rank == 0) {
112 std::vector<std::string> pieces;
113 pieces.reserve(static_cast<size_t>(mpi_size));
114 for (int r = 0; r < mpi_size; ++r)
115 pieces.push_back("output_" + tag + "_r" + std::to_string(r) + ".vtu");
116
117
118 const auto &tags =
data.d_outputDeck_p->d_outTags;
119 std::vector<rw::PvtuPointArray> point_arrays;
120 auto add_arr = [&](const char *name, int ncomp) {
121 point_arrays.push_back({name, "Float64", ncomp});
122 };
124 add_arr("Displacement", 3);
126 add_arr("Velocity", 3);
128 add_arr("Force_Density", 3);
130 add_arr("Force", 3);
132 add_arr("Damage_Z", 1);
134 add_arr("Damage", 1);
136 add_arr("Damage_Bond", 1);
138 add_arr("Particle_ID", 1);
139 const std::string pvtu_name = "output_" + tag + ".pvtu";
141 data.d_pvdParticleEntries.push_back({
data.d_time, pvtu_name});
143 data.d_pvdParticleEntries);
144 }
145 } else {
146 data.d_pvdParticleEntries.push_back(
147 {
data.d_time,
"output_" + tag +
".vtu"});
149 data.d_pvdParticleEntries);
150 }
151 }
152
154
155
156 {
157
158 if (
data.d_particlesMatDataList.empty()) {
159 for (
auto &p:
data.d_particlesListTypeAll) {
160 data.d_particlesMatDataList.push_back(p->getMaterial()->computeMaterialProperties(
161 p->getMeshP()->getDimension()));
162 }
163 }
164
165 for (
auto &p:
data.d_particlesListTypeAll) {
166
167 const auto particle_mesh_p = p->getMeshP();
168
170 p->d_globStart,
171 p->d_globQuadStart,
172 data.d_modelDeck_p->d_quadOrder);
173
174 auto isPlaneStrain = p->d_material_p->isPlaneStrain();
176 isPlaneStrain,
178 p->d_globStart,
179 p->d_globQuadStart,
180 data.d_particlesMatDataList[p->getId()].d_nu,
181 data.d_particlesMatDataList[p->getId()].d_lambda,
182 data.d_particlesMatDataList[p->getId()].d_mu,
183 true,
184 data.d_modelDeck_p->d_quadOrder);
185 }
186 }
187
188
189
190 if (mpi_rank == 0) {
191 std::string out_filename = path + "output_strain_" + tag;
193 writer1.appendStrainStress(&
data);
194 writer1.addTimeStep(
data.d_time);
195 writer1.close();
196
197 if (
data.d_outputDeck_p->d_outFormat ==
"vtu" &&
198 data.d_outputDeck_p->d_pvdCollection) {
199 data.d_pvdStrainEntries.push_back(
200 {
data.d_time,
"output_strain_" + tag +
".vtu"});
202 data.d_pvdStrainEntries);
203 }
204 }
205 }
206
207
209 data.d_outputDeck_p->d_outTags) &&
210 mpi_rank == 0) {
211
212 std::string out_filename = path + "particle_locations_" + tag + ".csv";
213 std::ofstream oss(out_filename);
214 oss << "i, x, y, z, r\n";
215 for (
const auto &p :
data.d_particlesListTypeAll) {
216 auto xc = p->getXCenter();
217 oss << p->d_id << ", " << xc.d_x << ", " << xc.d_y << ", " << xc.d_z
218 << ", " << p->d_geom_p->boundingRadius() << "\n";
219 }
220 oss.close();
221 }
222
223}
A vtk writer for simple point data and complex fem mesh data.
void getCurrentQuadPoints(const mesh::Mesh *mesh_p, const std::vector< util::Point > &xRef, const std::vector< util::Point > &u, std::vector< util::Point > &xQuadCur, size_t iNodeStart, size_t iQuadStart, size_t quadOrder)
Get current location of quadrature points of elements in the mesh. This function expects mesh has ele...
void getStrainStress(const mesh::Mesh *mesh_p, const std::vector< util::Point > &xRef, const std::vector< util::Point > &u, bool isPlaneStrain, std::vector< util::SymMatrix3 > &strain, std::vector< util::SymMatrix3 > &stress, size_t iNodeStart, size_t iStrainStart, double nu, double lambda, double mu, bool computeStress, size_t quadOrder)
Strain and stress at quadrature points in the mesh.
void writePvdCollectionFile(const std::string &pvd_path, const std::vector< std::pair< double, std::string > > &time_and_vtu_relative_path)
Write a ParaView VTK collection (.pvd) that lists VTU files with timesteps.
void writePvtuCollectionFile(const std::string &pvtu_path, const std::vector< std::string > &piece_vtu_relative_paths, const std::vector< PvtuPointArray > &point_arrays)
Write a ParaView parallel VTU (.pvtu) that lists per-rank .vtu pieces.
std::string getTabS(int nt)
Returns tab spaces of a given size.
std::string printStr(const T &msg, int nt=print_default_tab)
Returns formatted string for output.
void log(std::ostringstream &oss, bool screen_out=false, int printMpiRank=print_default_mpi_rank)
Global method to log the message.
bool isTagInList(const std::string &tag, const std::vector< std::string > &tags)
Returns true if tag is found in the list of tags.
int mpiSize()
Get size (number) of processors.
int mpiRank()
get rank (id) of this processor
MPI_Comm mpiComm()
Get MPI comm.