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.