MDStressLab++
Loading...
Searching...
No Matches
Stress.h
Go to the documentation of this file.
1/*
2 * Stress.h
3 *
4 * Created on: Nov 5, 2019
5 * Author: Nikhil
6 */
7
8#ifndef STRESS_H_
9#define STRESS_H_
10
11#include <vector>
12#include "Grid.h"
13#include "typedef.h"
14#include "SpatialHash.h"
15#include "Method.h"
16#include <string>
17#include <fstream>
18#include <iostream>
19#include <utility>
20
39template<typename TMethod,
40 StressType stressType,
41 typename TGrid = typename std::conditional<stressType==Piola,Grid<Reference>,Grid<Current>>::type>
42class Stress {
43public:
47 std::vector<Matrix3d> field;
48
54 std::vector<Vector3d> momentumDensityField;
55
61 std::vector<double> massDensityField;
62
70 std::vector<Vector3d> velocityField;
71
75 TGrid* pgrid;
76
83
88 std::string name;
89
93 Stress(std::string name,
96 {
97 field.resize(pgrid->ngrid);
98 for(auto& matrix : field)
99 matrix= Matrix3d::Zero();
100 if constexpr (stressType==Cauchy)
101 {
102 momentumDensityField.resize(pgrid->ngrid,Vector3d::Zero());
103 massDensityField.resize(pgrid->ngrid,0.0);
104 velocityField.resize(pgrid->ngrid,Vector3d::Zero());
105 }
106 }
107
112 TGrid* pgrid): pgrid(pgrid),method(method)
113 {
114 field.resize(pgrid->ngrid);
115 for(auto& matrix : field)
116 matrix= Matrix3d::Zero();
117 if constexpr (stressType==Cauchy)
118 {
119 momentumDensityField.resize(pgrid->ngrid,Vector3d::Zero());
120 massDensityField.resize(pgrid->ngrid,0.0);
121 velocityField.resize(pgrid->ngrid,Vector3d::Zero());
122 }
123 }
124
146 void write()
147 {
148 if (name.empty())
149 MY_ERROR("Stress object created without specifying a name. Use write(filename) instead of write()");
150 std::ofstream file(name+".stress");
151
152 file << field.size() << "\n";
153 //file << "\n";
154 int index= 0;
155 //Eigen::IOFormat fmt(Eigen::FullPrecision, 0, " ", "\n", "", "", "");
156 Eigen::IOFormat fmt(Eigen::FullPrecision, 0, " ", "\n", "", "", "");
157 file << std::fixed << std::setprecision(std::numeric_limits<double>::max_digits10);
158 file << "Properties=pos:R:3:stress:R:6" << std::endl;
159 for (auto& stress : field)
160 {
161 //Eigen::Map<Eigen::Matrix<double,1,DIM*DIM>> stressRow(stress.data(), stress.size());
162 //file << pgrid->coordinates[index].format(fmt) << std::setw(5) << stressRow.format(fmt) << std::endl;
163 file << pgrid->coordinates[index].format(fmt)
164 << std::setw(25) << stress(0,0)
165 << std::setw(25) << stress(1,1)
166 << std::setw(25) << stress(2,2)
167 << std::setw(25) << stress(0,1)
168 << std::setw(25) << stress(0,2)
169 << std::setw(25) << stress(1,2)
170 << std::endl;
171 index++;
172 }
173
174 if constexpr (stressType==Cauchy)
175 {
176 std::ofstream momentumDensityFile(name+".momentum_density");
177 std::ofstream massDensityFile(name+".mass_density");
178 momentumDensityFile << momentumDensityField.size() << "\n";
179 massDensityFile << massDensityField.size() << "\n";
180 momentumDensityFile << std::fixed << std::setprecision(std::numeric_limits<double>::max_digits10);
181 massDensityFile << std::fixed << std::setprecision(std::numeric_limits<double>::max_digits10);
182 momentumDensityFile << "Properties=pos:R:3:momentum_density:R:3" << std::endl;
183 massDensityFile << "Properties=pos:R:3:mass_density:R:1" << std::endl;
184 for (int i_grid=0; i_grid<pgrid->coordinates.size(); ++i_grid)
185 {
186 momentumDensityFile << pgrid->coordinates[i_grid].format(fmt)
187 << std::setw(25) << momentumDensityField[i_grid](0)
188 << std::setw(25) << momentumDensityField[i_grid](1)
189 << std::setw(25) << momentumDensityField[i_grid](2)
190 << std::endl;
191 massDensityFile << pgrid->coordinates[i_grid].format(fmt)
192 << std::setw(25) << massDensityField[i_grid]
193 << std::endl;
194 }
195 }
196 }
197
198 void write(const std::string& filename)
199 {
200 if (name.empty())
201 name= filename;
202 else
203 std::cout << "Stress object created with name " << name << ". Ignoring the filename: " << filename << "." << std::endl;
204 write();
205 }
206
227 void write_voxel_grid(const int nx,
228 const int ny,
229 const int nz,
230 const Vector3d& lowerLimit,
231 const Vector3d& upperLimit)
232 {
233 if (name.empty())
234 MY_ERROR("Stress object created without specifying a name. Use write_voxel_grid(filename,...) instead of write_voxel_grid(...)");
235 validateVoxelGridDimensions(nx,ny,nz);
236
237 std::ofstream stressFile(name+".voxel_grid_stress");
238 writeVoxelGridHeader(stressFile,nx,ny,nz,lowerLimit,upperLimit,"SXX SYY SZZ SYZ SXZ SXY");
239 for (const auto& stress : field)
240 {
241 stressFile << std::setw(25) << stress(0,0)
242 << std::setw(25) << stress(1,1)
243 << std::setw(25) << stress(2,2)
244 << std::setw(25) << stress(1,2)
245 << std::setw(25) << stress(0,2)
246 << std::setw(25) << stress(0,1)
247 << std::endl;
248 }
249
250 if constexpr (stressType==Cauchy)
251 {
252 std::ofstream momentumDensityFile(name+".voxel_grid_momentum_density");
253 writeVoxelGridHeader(momentumDensityFile,nx,ny,nz,lowerLimit,upperLimit,"PX PY PZ");
254 for (const auto& momentumDensity : momentumDensityField)
255 {
256 momentumDensityFile << std::setw(25) << momentumDensity(0)
257 << std::setw(25) << momentumDensity(1)
258 << std::setw(25) << momentumDensity(2)
259 << std::endl;
260 }
261
262 std::ofstream massDensityFile(name+".voxel_grid_mass_density");
263 writeVoxelGridHeader(massDensityFile,nx,ny,nz,lowerLimit,upperLimit,"RHO");
264 for (const auto& massDensity : massDensityField)
265 massDensityFile << std::setw(25) << massDensity << std::endl;
266 }
267 }
268
269 void write_voxel_grid(const std::string& filename,
270 const int nx,
271 const int ny,
272 const int nz,
273 const Vector3d& lowerLimit,
274 const Vector3d& upperLimit)
275 {
276 if (name.empty())
277 name= filename;
278 else
279 std::cout << "Stress object created with name " << name << ". Ignoring the filename: " << filename << "." << std::endl;
280 write_voxel_grid(nx,ny,nz,lowerLimit,upperLimit);
281 }
282
284 {
285 // TODO Auto-generated destructor stub
286 }
287
288private:
289 void validateVoxelGridDimensions(const int nx,
290 const int ny,
291 const int nz) const
292 {
293 if (nx<=0 || ny<=0 || nz<=0)
294 MY_ERROR("Voxel grid dimensions must be positive.");
295 const auto numberOfGridPoints= static_cast<std::size_t>(nx)*
296 static_cast<std::size_t>(ny)*
297 static_cast<std::size_t>(nz);
298 if (numberOfGridPoints != field.size())
299 MY_ERROR("Voxel grid dimensions do not match the number of stress grid points.");
300 }
301
302 void writeVoxelGridHeader(std::ofstream& file,
303 const int nx,
304 const int ny,
305 const int nz,
306 const Vector3d& lowerLimit,
307 const Vector3d& upperLimit,
308 const std::string& columns) const
309 {
310 file << std::fixed << std::setprecision(std::numeric_limits<double>::max_digits10);
311 file << "ITEM: TIMESTEP\n";
312 file << "0\n";
313 const auto xBounds= voxelGridBounds(nx,lowerLimit(0),upperLimit(0));
314 const auto yBounds= voxelGridBounds(ny,lowerLimit(1),upperLimit(1));
315 const auto zBounds= voxelGridBounds(nz,lowerLimit(2),upperLimit(2));
316 file << "ITEM: BOX BOUNDS pp pp pp\n";
317 file << xBounds.first << " " << xBounds.second << "\n";
318 file << yBounds.first << " " << yBounds.second << "\n";
319 file << zBounds.first << " " << zBounds.second << "\n";
320 file << "ITEM: DIMENSION\n";
321 file << voxelGridDimension(nx,ny,nz) << "\n";
322 file << "ITEM: GRID SIZE nx ny nz\n";
323 file << nx << " " << ny << " " << nz << "\n";
324 file << "ITEM: GRID CELLS " << columns << "\n";
325 }
326
327 int voxelGridDimension(const int nx,
328 const int ny,
329 const int nz) const
330 {
331 int dimension= 0;
332 if (nx>1) ++dimension;
333 if (ny>1) ++dimension;
334 if (nz>1) ++dimension;
335 return std::max(1,dimension);
336 }
337
338 std::pair<double,double> voxelGridBounds(const int n,
339 const double lowerLimit,
340 const double upperLimit) const
341 {
342 if (n>1)
343 {
344 const double spacing= (upperLimit-lowerLimit)/static_cast<double>(n);
345 return {lowerLimit-0.5*spacing,upperLimit-0.5*spacing};
346 }
347 return {lowerLimit,lowerLimit};
348 }
349
350
351};
352
353#endif /* STRESS_H_ */
Definition Grid.h:38
Three-dimensional stress field on a grid.
Definition Stress.h:42
std::vector< Matrix3d > field
A three-dimensional stress field.
Definition Stress.h:47
std::string name
The prefix of the filename that will be outputted when the stress field is written.
Definition Stress.h:88
void write()
Write stress and, for Cauchy stress, density fields.
Definition Stress.h:146
Stress(const Method< TMethod > &method, TGrid *pgrid)
Constructs a Stress object.
Definition Stress.h:111
std::vector< Vector3d > momentumDensityField
Cauchy-grid momentum density .
Definition Stress.h:54
Stress(std::string name, const Method< TMethod > &method, TGrid *pgrid)
Constructs a Stress object.
Definition Stress.h:93
void write_voxel_grid(const int nx, const int ny, const int nz, const Vector3d &lowerLimit, const Vector3d &upperLimit)
Write structured grid fields in LAMMPS dump-grid format.
Definition Stress.h:227
void write(const std::string &filename)
Definition Stress.h:198
TGrid * pgrid
Pointer to the Grid on which the stress field is defined.
Definition Stress.h:75
std::vector< Vector3d > velocityField
Internal Cauchy-grid continuum velocity.
Definition Stress.h:70
~Stress()
Definition Stress.h:283
void write_voxel_grid(const std::string &filename, const int nx, const int ny, const int nz, const Vector3d &lowerLimit, const Vector3d &upperLimit)
Definition Stress.h:269
const Method< TMethod > & method
The method used to compute the stress field. The Method object provides details about the weighting f...
Definition Stress.h:82
std::vector< double > massDensityField
Cauchy-grid mass density .
Definition Stress.h:61
#define MY_ERROR(message)
Definition typedef.h:17
Eigen::Matrix< double, 1, DIM, Eigen::RowMajor > Vector3d
Definition typedef.h:60
StressType
Definition typedef.h:63
@ Cauchy
Definition typedef.h:64