45#include "hydrodynamics/HydroIO.hpp"
50#include "utils/simError.h"
56 HydroIO::~HydroIO() {}
58 void HydroIO::openWriter(std::ostream& os) {
59 std::string h =
"OpenMD-Hydro";
60#if defined(NLOHMANN_JSON)
61 j_[h] = ordered_json::array();
63#elif defined(RAPID_JSON)
64 osw_ =
new OStreamWrapper(os);
68 w_.SetMaxDecimalPlaces(7);
77 void HydroIO::writeHydroProp(HydroProp* hp, RealType viscosity,
78 RealType temperature, std::ostream& os) {
79 if (!writerOpen_) openWriter(os);
81 std::string h =
"OpenMD-Hydro";
82 std::string name = hp->getName();
83 Vector3d cor = hp->getCenterOfResistance();
84 Mat6x6d Xi = hp->getResistanceTensor();
85 Vector3d cod = hp->getCenterOfDiffusion(temperature);
86 Mat6x6d Xid = hp->getDiffusionTensorAtPos(cod, temperature);
87 Vector3d cop = hp->getCenterOfPitch();
92 hp->pitchAxes(pitchAxes, pitches, pitchScalar);
94#if defined(NLOHMANN_JSON)
98 o[
"viscosity"] = viscosity;
99 o[
"centerOfResistance"] = {cor[0], cor[1], cor[2]};
100 o[
"resistanceTensor"] = json::array();
102 for (
unsigned int i = 0; i < 6; i++) {
103 o[
"resistanceTensor"][i] = {Xi(i, 0), Xi(i, 1), Xi(i, 2),
104 Xi(i, 3), Xi(i, 4), Xi(i, 5)};
107 o[
"temperature"] = temperature;
108 o[
"centerOfDiffusion"] = {cod[0], cod[1], cod[2]};
109 o[
"diffusionTensor"] = json::array();
111 for (
unsigned int i = 0; i < 6; i++) {
112 o[
"diffusionTensor"][i] = {Xid(i, 0), Xid(i, 1), Xid(i, 2),
113 Xid(i, 3), Xid(i, 4), Xid(i, 5)};
116 o[
"pitch"] = pitchScalar;
117 o[
"centerOfPitch"] = {cop[0], cop[1], cop[2]};
118 o[
"momentsOfPitch"] = {pitches[0], pitches[1], pitches[2]};
120 o[
"pitchAxes"] = json::array();
121 for (
unsigned int i = 0; i < 3; i++) {
122 o[
"pitchAxes"][i] = {pitchAxes(i, 0), pitchAxes(i, 1), pitchAxes(i, 2)};
127#elif defined(RAPID_JSON)
131 w_.String(name.c_str());
134 w_.Double(viscosity);
135 w_.Key(
"centerOfResistance");
137 w_.SetFormatOptions(kFormatSingleLineArray);
139 for (
unsigned i = 0; i < 3; i++)
142 w_.SetFormatOptions(kFormatDefault);
144 w_.Key(
"resistanceTensor");
146 for (
unsigned i = 0; i < 6; i++) {
148 w_.SetFormatOptions(kFormatSingleLineArray);
150 for (
unsigned j = 0; j < 6; j++) {
154 w_.SetFormatOptions(kFormatDefault);
158 w_.Key(
"temperature");
159 w_.Double(temperature);
160 w_.Key(
"centerOfDiffusion");
162 w_.SetFormatOptions(kFormatSingleLineArray);
164 for (
unsigned i = 0; i < 3; i++)
167 w_.SetFormatOptions(kFormatDefault);
169 w_.Key(
"diffusionTensor");
171 for (
unsigned i = 0; i < 6; i++) {
173 w_.SetFormatOptions(kFormatSingleLineArray);
175 for (
unsigned j = 0; j < 6; j++) {
176 w_.Double(Xid(i, j));
179 w_.SetFormatOptions(kFormatDefault);
184 w_.Double(pitchScalar);
186 w_.Key(
"centerOfPitch");
188 w_.SetFormatOptions(kFormatSingleLineArray);
189 for (
unsigned i = 0; i < 3; i++)
192 w_.SetFormatOptions(kFormatDefault);
194 w_.Key(
"momentsOfPitch");
196 w_.SetFormatOptions(kFormatSingleLineArray);
197 for (
unsigned i = 0; i < 3; i++)
198 w_.Double(pitches[i]);
200 w_.SetFormatOptions(kFormatDefault);
204 for (
unsigned i = 0; i < 3; i++) {
206 w_.SetFormatOptions(kFormatSingleLineArray);
207 for (
unsigned j = 0; j < 3; j++) {
208 w_.Double(pitchAxes(i, j));
211 w_.SetFormatOptions(kFormatDefault);
219 void HydroIO::closeWriter(std::ostream& os) {
220#if defined(NLOHMANN_JSON)
221 os << j_.dump(2) << std::endl;
222#elif defined(RAPID_JSON)
230 map<string, HydroProp*> HydroIO::parseHydroFile(
const string& f) {
231 map<string, HydroProp*> props;
236 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
237 "HydroIO: Cannot open file: %s\n", f.c_str());
238 painCave.isFatal = 1;
242#if defined(NLOHMANN_JSON)
243 json ij = json::parse(ifs);
245 auto& entries = ij[
"OpenMD-Hydro"];
247 for (
auto& entry : entries) {
248 HydroProp* hp =
new HydroProp();
253 name = entry[
"name"].get<std::string>();
255 for (
unsigned int i = 0; i < 3; i++) {
256 cor[i] = entry[
"centerOfResistance"].get<vector<RealType>>()[i];
259 for (
unsigned int i = 0; i < 6; i++) {
260 for (
unsigned int j = 0; j < 6; j++) {
262 entry[
"resistanceTensor"].get<vector<vector<RealType>>>()[i][j];
267 hp->setCenterOfResistance(cor);
268 hp->setResistanceTensor(Xi);
269 props.insert(map<string, HydroProp*>::value_type(name, hp));
271#elif defined(RAPID_JSON)
275 if (ifs.peek() != EOF) {
276 rapidjson::IStreamWrapper isw(ifs);
278 if (d_.HasParseError()) {
279 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
280 "HydroIO: JSON parse error in file %s\n"
281 "\tError: %zu : %s\n",
282 f.c_str(), d_.GetErrorOffset(),
283 rapidjson::GetParseError_En(d_.GetParseError()));
284 painCave.isFatal = 1;
287 if (!d_.IsObject()) {
288 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
289 "HydroIO: OpenMD-Hydro should be a single object.\n");
290 painCave.isFatal = 1;
295 if (!d_.HasMember(
"OpenMD-Hydro")) {
296 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
297 "HydroIO: File %s does not have a OpenMD-Hydro object.\n",
299 painCave.isFatal = 1;
303 const Value& entries = d_[
"OpenMD-Hydro"];
304 for (
auto& entry : entries.GetArray()) {
305 HydroProp* hp =
new HydroProp();
310 name = entry[
"name"].GetString();
312 for (
unsigned int i = 0; i < 3; i++) {
313 cor[i] = entry[
"centerOfResistance"][i].GetDouble();
316 for (
unsigned int i = 0; i < 6; i++) {
317 for (
unsigned int j = 0; j < 6; j++) {
318 Xi(i, j) = entry[
"resistanceTensor"][i][j].GetDouble();
323 hp->setCenterOfResistance(cor);
324 hp->setResistanceTensor(Xi);
325 props.insert(map<string, HydroProp*>::value_type(name, hp));
331 void HydroIO::interpretHydroProp(HydroProp* hp, RealType viscosity,
332 RealType temperature) {
333 Vector3d ror = hp->getCenterOfResistance();
336 Xi = hp->getResistanceTensor();
342 Xi.getSubMatrix(0, 0, Xirtt);
343 Xi.getSubMatrix(0, 3, Xirrt);
344 Xi.getSubMatrix(3, 0, Xirtr);
345 Xi.getSubMatrix(3, 3, Xirrr);
348 Dr = hp->getDiffusionTensor(temperature);
355 Dr.getSubMatrix(0, 0, Drtt);
356 Dr.getSubMatrix(0, 3, Drrt);
357 Dr.getSubMatrix(3, 0, Drtr);
358 Dr.getSubMatrix(3, 3, Drrr);
361 std::cout <<
"-----------------------------------------\n";
362 std::cout <<
"viscosity = " << viscosity <<
" Poise" << std::endl;
363 std::cout <<
"temperature = " << temperature <<
" K" << std::endl;
364 std::cout <<
"-----------------------------------------\n";
365 std::cout <<
"The centers are based on the elements generated by Hydro "
367 std::cout <<
"which have been placed in an .xyz or .stl file." << std::endl;
368 std::cout <<
"They are not based on the geometry in the .omd file.\n"
370 std::cout <<
"-----------------------------------------\n\n";
371 std::cout <<
"Center of resistance :" << std::endl;
372 std::cout << ror <<
"\n" << std::endl;
373 std::cout <<
"-----------------------------------------\n\n";
374 std::cout <<
"Resistance tensor at center of resistance\n" << std::endl;
375 std::cout <<
"translation [kcal.fs/(mol.A^2)]:" << std::endl;
376 std::cout << Xirtt << std::endl;
377 std::cout <<
"rotation-translation [kcal.fs/(mol.A.radian)]:" << std::endl;
378 std::cout << Xirtr.transpose() << std::endl;
379 std::cout <<
"translation-rotation [kcal.fs/(mol.A.radian)]:" << std::endl;
380 std::cout << Xirtr << std::endl;
381 std::cout <<
"rotation [kcal.fs/(mol.radian^2)]:" << std::endl;
382 std::cout << Xirrr << std::endl;
383 std::cout <<
"-----------------------------------------\n\n";
384 std::cout <<
"Diffusion tensor at center of resistance\n" << std::endl;
385 std::cout <<
"translation (A^2 / fs):" << std::endl;
386 std::cout << Drtt << std::endl;
387 std::cout <<
"rotation-translation (A.radian / fs):" << std::endl;
388 std::cout << Drrt << std::endl;
389 std::cout <<
"translation-rotation (A.radian / fs):" << std::endl;
390 std::cout << Drtr << std::endl;
391 std::cout <<
"rotation (radian^2 / fs):" << std::endl;
392 std::cout << Drrr << std::endl;
393 std::cout <<
"-----------------------------------------\n\n";
398 Vector3d cod = hp->getCenterOfDiffusion(temperature);
399 Mat6x6d Xid = hp->getResistanceTensorAtPos(cod);
406 Xid.getSubMatrix(0, 0, Xidtt);
407 Xid.getSubMatrix(0, 3, Xidrt);
408 Xid.getSubMatrix(3, 0, Xidtr);
409 Xid.getSubMatrix(3, 3, Xidrr);
412 Mat6x6d Dd = hp->getDiffusionTensorAtPos(cod, temperature);
419 Dd.getSubMatrix(0, 0, Ddtt);
420 Dd.getSubMatrix(0, 3, Ddrt);
421 Dd.getSubMatrix(3, 0, Ddtr);
422 Dd.getSubMatrix(3, 3, Ddrr);
424 std::cout <<
"Center of diffusion: " << std::endl;
425 std::cout << cod <<
"\n" << std::endl;
426 std::cout <<
"-----------------------------------------\n\n";
427 std::cout <<
"Diffusion tensor at center of diffusion \n " << std::endl;
428 std::cout <<
"translation (A^2 / fs) :" << std::endl;
429 std::cout << Ddtt << std::endl;
430 std::cout <<
"rotation-translation (A.radian / fs):" << std::endl;
431 std::cout << Ddtr.transpose() << std::endl;
432 std::cout <<
"translation-rotation (A.radian / fs):" << std::endl;
433 std::cout << Ddtr << std::endl;
434 std::cout <<
"rotation (radian^2 / fs):" << std::endl;
435 std::cout << Ddrr << std::endl;
436 std::cout <<
"-----------------------------------------\n\n";
437 std::cout <<
"Resistance tensor at center of diffusion \n " << std::endl;
438 std::cout <<
"translation [kcal.fs/(mol.A^2)]:" << std::endl;
439 std::cout << Xidtt << std::endl;
440 std::cout <<
"rotation-translation [kcal.fs/(mol.A.radian)]:" << std::endl;
441 std::cout << Xidrt << std::endl;
442 std::cout <<
"translation-rotation [kcal.fs/(mol.A.radian)]:" << std::endl;
443 std::cout << Xidtr << std::endl;
444 std::cout <<
"rotation [kcal.fs/(mol.radian^2)]:" << std::endl;
445 std::cout << Xidrr << std::endl;
446 std::cout <<
"-----------------------------------------\n\n";
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.