48#include "hydrodynamics/HydroIO.hpp"
53#include "utils/simError.h"
59 HydroIO::~HydroIO() {}
61 void HydroIO::openWriter(std::ostream& os) {
62 std::string h =
"OpenMD-Hydro";
63#if defined(NLOHMANN_JSON)
64 j_[h] = ordered_json::array();
66#elif defined(RAPID_JSON)
67 osw_ =
new OStreamWrapper(os);
71 w_.SetMaxDecimalPlaces(7);
80 void HydroIO::writeHydroProp(
HydroProp* hp, RealType viscosity,
81 RealType temperature, std::ostream& os) {
82 if (!writerOpen_) openWriter(os);
84 std::string h =
"OpenMD-Hydro";
85 std::string name = hp->getName();
86 Vector3d cor = hp->getCenterOfResistance();
87 Mat6x6d Xi = hp->getResistanceTensor();
88 Vector3d cod = hp->getCenterOfDiffusion(temperature);
89 Mat6x6d Xid = hp->getDiffusionTensorAtPos(cod, temperature);
90 Vector3d cop = hp->getCenterOfPitch();
95 hp->pitchAxes(pitchAxes, pitches, pitchScalar);
97#if defined(NLOHMANN_JSON)
101 o[
"viscosity"] = viscosity;
102 o[
"centerOfResistance"] = {cor[0], cor[1], cor[2]};
103 o[
"resistanceTensor"] = json::array();
105 for (
unsigned int i = 0; i < 6; i++) {
106 o[
"resistanceTensor"][i] = {Xi(i, 0), Xi(i, 1), Xi(i, 2),
107 Xi(i, 3), Xi(i, 4), Xi(i, 5)};
110 o[
"temperature"] = temperature;
111 o[
"centerOfDiffusion"] = {cod[0], cod[1], cod[2]};
112 o[
"diffusionTensor"] = json::array();
114 for (
unsigned int i = 0; i < 6; i++) {
115 o[
"diffusionTensor"][i] = {Xid(i, 0), Xid(i, 1), Xid(i, 2),
116 Xid(i, 3), Xid(i, 4), Xid(i, 5)};
119 o[
"pitch"] = pitchScalar;
120 o[
"centerOfPitch"] = {cop[0], cop[1], cop[2]};
121 o[
"momentsOfPitch"] = {pitches[0], pitches[1], pitches[2]};
123 o[
"pitchAxes"] = json::array();
124 for (
unsigned int i = 0; i < 3; i++) {
125 o[
"pitchAxes"][i] = {pitchAxes(i, 0), pitchAxes(i, 1), pitchAxes(i, 2)};
130#elif defined(RAPID_JSON)
134 w_.String(name.c_str());
137 w_.Double(viscosity);
138 w_.Key(
"centerOfResistance");
140 w_.SetFormatOptions(kFormatSingleLineArray);
142 for (
unsigned i = 0; i < 3; i++)
145 w_.SetFormatOptions(kFormatDefault);
147 w_.Key(
"resistanceTensor");
149 for (
unsigned i = 0; i < 6; i++) {
151 w_.SetFormatOptions(kFormatSingleLineArray);
153 for (
unsigned j = 0; j < 6; j++) {
157 w_.SetFormatOptions(kFormatDefault);
161 w_.Key(
"temperature");
162 w_.Double(temperature);
163 w_.Key(
"centerOfDiffusion");
165 w_.SetFormatOptions(kFormatSingleLineArray);
167 for (
unsigned i = 0; i < 3; i++)
170 w_.SetFormatOptions(kFormatDefault);
172 w_.Key(
"diffusionTensor");
174 for (
unsigned i = 0; i < 6; i++) {
176 w_.SetFormatOptions(kFormatSingleLineArray);
178 for (
unsigned j = 0; j < 6; j++) {
179 w_.Double(Xid(i, j));
182 w_.SetFormatOptions(kFormatDefault);
187 w_.Double(pitchScalar);
189 w_.Key(
"centerOfPitch");
191 w_.SetFormatOptions(kFormatSingleLineArray);
192 for (
unsigned i = 0; i < 3; i++)
195 w_.SetFormatOptions(kFormatDefault);
197 w_.Key(
"momentsOfPitch");
199 w_.SetFormatOptions(kFormatSingleLineArray);
200 for (
unsigned i = 0; i < 3; i++)
201 w_.Double(pitches[i]);
203 w_.SetFormatOptions(kFormatDefault);
207 for (
unsigned i = 0; i < 3; i++) {
209 w_.SetFormatOptions(kFormatSingleLineArray);
210 for (
unsigned j = 0; j < 3; j++) {
211 w_.Double(pitchAxes(i, j));
214 w_.SetFormatOptions(kFormatDefault);
222 void HydroIO::closeWriter(std::ostream& os) {
223#if defined(NLOHMANN_JSON)
224 os << j_.dump(2) << std::endl;
225#elif defined(RAPID_JSON)
233 map<string, HydroProp*> HydroIO::parseHydroFile(
const string& f) {
234 map<string, HydroProp*> props;
239 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
240 "HydroIO: Cannot open file: %s\n", f.c_str());
241 painCave.isFatal = 1;
245#if defined(NLOHMANN_JSON)
246 json ij = json::parse(ifs);
248 auto& entries = ij[
"OpenMD-Hydro"];
250 for (
auto& entry : entries) {
251 HydroProp* hp =
new HydroProp();
256 name = entry[
"name"].get<std::string>();
258 for (
unsigned int i = 0; i < 3; i++) {
259 cor[i] = entry[
"centerOfResistance"].get<vector<RealType>>()[i];
262 for (
unsigned int i = 0; i < 6; i++) {
263 for (
unsigned int j = 0; j < 6; j++) {
265 entry[
"resistanceTensor"].get<vector<vector<RealType>>>()[i][j];
270 hp->setCenterOfResistance(cor);
271 hp->setResistanceTensor(Xi);
272 props.insert(map<string, HydroProp*>::value_type(name, hp));
274#elif defined(RAPID_JSON)
278 if (ifs.peek() != EOF) {
279 rapidjson::IStreamWrapper isw(ifs);
281 if (d_.HasParseError()) {
282 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
283 "HydroIO: JSON parse error in file %s\n"
284 "\tError: %zu : %s\n",
285 f.c_str(), d_.GetErrorOffset(),
286 rapidjson::GetParseError_En(d_.GetParseError()));
287 painCave.isFatal = 1;
290 if (!d_.IsObject()) {
291 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
292 "HydroIO: OpenMD-Hydro should be a single object.\n");
293 painCave.isFatal = 1;
298 if (!d_.HasMember(
"OpenMD-Hydro")) {
299 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
300 "HydroIO: File %s does not have a OpenMD-Hydro object.\n",
302 painCave.isFatal = 1;
306 const Value& entries = d_[
"OpenMD-Hydro"];
307 for (
auto& entry : entries.GetArray()) {
308 HydroProp* hp =
new HydroProp();
313 name = entry[
"name"].GetString();
315 for (
unsigned int i = 0; i < 3; i++) {
316 cor[i] = entry[
"centerOfResistance"][i].GetDouble();
319 for (
unsigned int i = 0; i < 6; i++) {
320 for (
unsigned int j = 0; j < 6; j++) {
321 Xi(i, j) = entry[
"resistanceTensor"][i][j].GetDouble();
326 hp->setCenterOfResistance(cor);
327 hp->setResistanceTensor(Xi);
328 props.insert(map<string, HydroProp*>::value_type(name, hp));
334 void HydroIO::interpretHydroProp(
HydroProp* hp, RealType viscosity,
335 RealType temperature) {
336 Vector3d ror = hp->getCenterOfResistance();
339 Xi = hp->getResistanceTensor();
345 Xi.getSubMatrix(0, 0, Xirtt);
346 Xi.getSubMatrix(0, 3, Xirrt);
347 Xi.getSubMatrix(3, 0, Xirtr);
348 Xi.getSubMatrix(3, 3, Xirrr);
351 Dr = hp->getDiffusionTensor(temperature);
358 Dr.getSubMatrix(0, 0, Drtt);
359 Dr.getSubMatrix(0, 3, Drrt);
360 Dr.getSubMatrix(3, 0, Drtr);
361 Dr.getSubMatrix(3, 3, Drrr);
364 std::cout <<
"-----------------------------------------\n";
365 std::cout <<
"viscosity = " << viscosity <<
" Poise" << std::endl;
366 std::cout <<
"temperature = " << temperature <<
" K" << std::endl;
367 std::cout <<
"-----------------------------------------\n";
368 std::cout <<
"The centers are based on the elements generated by Hydro "
370 std::cout <<
"which have been placed in an .xyz or .stl file." << std::endl;
371 std::cout <<
"They are not based on the geometry in the .omd file.\n"
373 std::cout <<
"-----------------------------------------\n\n";
374 std::cout <<
"Center of resistance :" << std::endl;
375 std::cout << ror <<
"\n" << std::endl;
376 std::cout <<
"-----------------------------------------\n\n";
377 std::cout <<
"Resistance tensor at center of resistance\n" << std::endl;
378 std::cout <<
"translation [kcal.fs/(mol.A^2)]:" << std::endl;
379 std::cout << Xirtt << std::endl;
380 std::cout <<
"rotation-translation [kcal.fs/(mol.A.radian)]:" << std::endl;
381 std::cout << Xirtr.transpose() << std::endl;
382 std::cout <<
"translation-rotation [kcal.fs/(mol.A.radian)]:" << std::endl;
383 std::cout << Xirtr << std::endl;
384 std::cout <<
"rotation [kcal.fs/(mol.radian^2)]:" << std::endl;
385 std::cout << Xirrr << std::endl;
386 std::cout <<
"-----------------------------------------\n\n";
387 std::cout <<
"Diffusion tensor at center of resistance\n" << std::endl;
388 std::cout <<
"translation (A^2 / fs):" << std::endl;
389 std::cout << Drtt << std::endl;
390 std::cout <<
"rotation-translation (A.radian / fs):" << std::endl;
391 std::cout << Drrt << std::endl;
392 std::cout <<
"translation-rotation (A.radian / fs):" << std::endl;
393 std::cout << Drtr << std::endl;
394 std::cout <<
"rotation (radian^2 / fs):" << std::endl;
395 std::cout << Drrr << std::endl;
396 std::cout <<
"-----------------------------------------\n\n";
401 Vector3d cod = hp->getCenterOfDiffusion(temperature);
402 Mat6x6d Xid = hp->getResistanceTensorAtPos(cod);
409 Xid.getSubMatrix(0, 0, Xidtt);
410 Xid.getSubMatrix(0, 3, Xidrt);
411 Xid.getSubMatrix(3, 0, Xidtr);
412 Xid.getSubMatrix(3, 3, Xidrr);
415 Mat6x6d Dd = hp->getDiffusionTensorAtPos(cod, temperature);
422 Dd.getSubMatrix(0, 0, Ddtt);
423 Dd.getSubMatrix(0, 3, Ddrt);
424 Dd.getSubMatrix(3, 0, Ddtr);
425 Dd.getSubMatrix(3, 3, Ddrr);
427 std::cout <<
"Center of diffusion: " << std::endl;
428 std::cout << cod <<
"\n" << std::endl;
429 std::cout <<
"-----------------------------------------\n\n";
430 std::cout <<
"Diffusion tensor at center of diffusion \n " << std::endl;
431 std::cout <<
"translation (A^2 / fs) :" << std::endl;
432 std::cout << Ddtt << std::endl;
433 std::cout <<
"rotation-translation (A.radian / fs):" << std::endl;
434 std::cout << Ddtr.transpose() << std::endl;
435 std::cout <<
"translation-rotation (A.radian / fs):" << std::endl;
436 std::cout << Ddtr << std::endl;
437 std::cout <<
"rotation (radian^2 / fs):" << std::endl;
438 std::cout << Ddrr << std::endl;
439 std::cout <<
"-----------------------------------------\n\n";
440 std::cout <<
"Resistance tensor at center of diffusion \n " << std::endl;
441 std::cout <<
"translation [kcal.fs/(mol.A^2)]:" << std::endl;
442 std::cout << Xidtt << std::endl;
443 std::cout <<
"rotation-translation [kcal.fs/(mol.A.radian)]:" << std::endl;
444 std::cout << Xidrt << std::endl;
445 std::cout <<
"translation-rotation [kcal.fs/(mol.A.radian)]:" << std::endl;
446 std::cout << Xidtr << std::endl;
447 std::cout <<
"rotation [kcal.fs/(mol.radian^2)]:" << std::endl;
448 std::cout << Xidrr << std::endl;
449 std::cout <<
"-----------------------------------------\n\n";
Container for information about the hydrodynamic behavior of objects interacting with surroundings.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.