*/
struct gmx_tng_trajectory
{
- tng_trajectory_t tng; //!< Actual TNG handle (pointer)
- bool lastStepDataIsValid; //!< True if lastStep has been set
- std::int64_t lastStep; //!< Index/step used for last frame
- bool lastTimeDataIsValid; //!< True if lastTime has been set
- double lastTime; //!< Time of last frame (TNG unit is seconds)
- bool timePerFrameIsSet; //!< True if we have set the time per frame
+ tng_trajectory_t tng; //!< Actual TNG handle (pointer)
+ bool lastStepDataIsValid; //!< True if lastStep has been set
+ std::int64_t lastStep; //!< Index/step used for last frame
+ bool lastTimeDataIsValid; //!< True if lastTime has been set
+ double lastTime; //!< Time of last frame (TNG unit is seconds)
+ bool timePerFrameIsSet; //!< True if we have set the time per frame
+ int boxOutputInterval; //!< Number of steps between the output of box size
+ int lambdaOutputInterval; //!< Number of steps between the output of lambdas
};
static const char *modeToVerb(char mode)
set_writing_interval(tng, gcd, 9, TNG_TRAJ_BOX_SHAPE,
"BOX SHAPE", TNG_NON_PARTICLE_BLOCK_DATA,
TNG_GZIP_COMPRESSION);
+ gmx_tng->lambdaOutputInterval = gcd;
+ gmx_tng->boxOutputInterval = gcd;
if (gcd < lowest / 10)
{
gmx_warning("The lowest common denominator of trajectory output is "
}
}
- /* TNG-MF1 compression only compresses positions and velocities. Use lossless
- * compression for lambdas and box shape regardless of output mode */
- if (write_data(tng, step, elapsedSeconds,
- reinterpret_cast<const real *>(box),
- 9, TNG_TRAJ_BOX_SHAPE, "BOX SHAPE",
- TNG_NON_PARTICLE_BLOCK_DATA,
- TNG_GZIP_COMPRESSION) != TNG_SUCCESS)
+ if (box)
{
- gmx_file("Cannot write TNG trajectory frame; maybe you are out of disk space?");
+ /* TNG-MF1 compression only compresses positions and velocities. Use lossless
+ * compression for box shape regardless of output mode */
+ if (write_data(tng, step, elapsedSeconds,
+ reinterpret_cast<const real *>(box),
+ 9, TNG_TRAJ_BOX_SHAPE, "BOX SHAPE",
+ TNG_NON_PARTICLE_BLOCK_DATA,
+ TNG_GZIP_COMPRESSION) != TNG_SUCCESS)
+ {
+ gmx_file("Cannot write TNG trajectory frame; maybe you are out of disk space?");
+ }
}
- if (write_data(tng, step, elapsedSeconds,
- reinterpret_cast<const real *>(&lambda),
- 1, TNG_GMX_LAMBDA, "LAMBDAS",
- TNG_NON_PARTICLE_BLOCK_DATA,
- TNG_GZIP_COMPRESSION) != TNG_SUCCESS)
+ if (lambda >= 0)
{
- gmx_file("Cannot write TNG trajectory frame; maybe you are out of disk space?");
+ /* TNG-MF1 compression only compresses positions and velocities. Use lossless
+ * compression for lambda regardless of output mode */
+ if (write_data(tng, step, elapsedSeconds,
+ reinterpret_cast<const real *>(&lambda),
+ 1, TNG_GMX_LAMBDA, "LAMBDAS",
+ TNG_NON_PARTICLE_BLOCK_DATA,
+ TNG_GZIP_COMPRESSION) != TNG_SUCCESS)
+ {
+ gmx_file("Cannot write TNG trajectory frame; maybe you are out of disk space?");
+ }
}
// Update the data in the wrapper
set_writing_interval(*output, interval, 9, fallbackIds[i],
fallbackNames[i], TNG_NON_PARTICLE_BLOCK_DATA,
TNG_GZIP_COMPRESSION);
+ (*gmx_tng_output)->boxOutputInterval = interval;
break;
case TNG_GMX_LAMBDA:
set_writing_interval(*output, interval, 1, fallbackIds[i],
fallbackNames[i], TNG_NON_PARTICLE_BLOCK_DATA,
TNG_GZIP_COMPRESSION);
+ (*gmx_tng_output)->lambdaOutputInterval = interval;
break;
default:
continue;
return FALSE;
#endif
}
+
+int gmx_tng_get_box_output_interval(gmx_tng_trajectory_t gmx_tng)
+{
+#if GMX_USE_TNG
+ return gmx_tng->boxOutputInterval;
+#else
+ GMX_UNUSED_VALUE(gmx_tng);
+#endif
+}
+
+int gmx_tng_get_lambda_output_interval(gmx_tng_trajectory_t gmx_tng)
+{
+#if GMX_USE_TNG
+ return gmx_tng->lambdaOutputInterval;
+#else
+ GMX_UNUSED_VALUE(gmx_tng);
+#endif
+}
sfree(xxtc);
}
}
+ if (mdof_flags & (MDOF_BOX | MDOF_LAMBDA) && !(mdof_flags & (MDOF_X | MDOF_V | MDOF_F)) )
+ {
+ if (of->tng)
+ {
+ real lambda = -1;
+ rvec *box = nullptr;
+ if (mdof_flags & MDOF_BOX)
+ {
+ box = state_local->box;
+ }
+ if (mdof_flags & MDOF_LAMBDA)
+ {
+ lambda = state_local->lambda[efptFEP];
+ }
+ gmx_fwrite_tng(of->tng, FALSE, step, t, lambda,
+ box, top_global->natoms,
+ nullptr, nullptr, nullptr);
+ }
+ }
+ if (mdof_flags & (MDOF_BOX_COMPRESSED | MDOF_LAMBDA_COMPRESSED) && !(mdof_flags & (MDOF_X_COMPRESSED)) )
+ {
+ if (of->tng_low_prec)
+ {
+ real lambda = -1;
+ rvec *box = nullptr;
+ if (mdof_flags & MDOF_BOX_COMPRESSED)
+ {
+ box = state_local->box;
+ }
+ if (mdof_flags & MDOF_LAMBDA_COMPRESSED)
+ {
+ lambda = state_local->lambda[efptFEP];
+ }
+ gmx_fwrite_tng(of->tng_low_prec, FALSE, step, t, lambda,
+ box, top_global->natoms,
+ nullptr, nullptr, nullptr);
+ }
+ }
}
}
sfree(of);
}
+
+int mdoutf_get_tng_box_output_interval(gmx_mdoutf_t of)
+{
+ if (of->tng)
+ {
+ return gmx_tng_get_box_output_interval(of->tng);
+ }
+ return 0;
+}
+
+int mdoutf_get_tng_lambda_output_interval(gmx_mdoutf_t of)
+{
+ if (of->tng)
+ {
+ return gmx_tng_get_lambda_output_interval(of->tng);
+ }
+ return 0;
+}
+
+int mdoutf_get_tng_compressed_box_output_interval(gmx_mdoutf_t of)
+{
+ if (of->tng_low_prec)
+ {
+ return gmx_tng_get_box_output_interval(of->tng_low_prec);
+ }
+ return 0;
+}
+
+int mdoutf_get_tng_compressed_lambda_output_interval(gmx_mdoutf_t of)
+{
+ if (of->tng_low_prec)
+ {
+ return gmx_tng_get_lambda_output_interval(of->tng_low_prec);
+ }
+ return 0;
+}
ObservablesHistory *observablesHistory,
gmx::ArrayRef<gmx::RVec> f_local);
-#define MDOF_X (1<<0)
-#define MDOF_V (1<<1)
-#define MDOF_F (1<<2)
-#define MDOF_X_COMPRESSED (1<<3)
-#define MDOF_CPT (1<<4)
-#define MDOF_IMD (1<<5)
+/*! \brief Get the output interval of box size of uncompressed TNG output.
+ * Returns 0 if no uncompressed TNG file is open.
+ */
+int mdoutf_get_tng_box_output_interval(gmx_mdoutf_t of);
+
+/*! \brief Get the output interval of lambda of uncompressed TNG output.
+ * Returns 0 if no uncompressed TNG file is open.
+ */
+int mdoutf_get_tng_lambda_output_interval(gmx_mdoutf_t of);
+
+/*! \brief Get the output interval of box size of compressed TNG output.
+ * Returns 0 if no compressed TNG file is open.
+ */
+int mdoutf_get_tng_compressed_box_output_interval(gmx_mdoutf_t of);
+
+/*! \brief Get the output interval of lambda of compressed TNG output.
+ * Returns 0 if no compressed TNG file is open.
+ */
+int mdoutf_get_tng_compressed_lambda_output_interval(gmx_mdoutf_t of);
+
+#define MDOF_X (1<<0)
+#define MDOF_V (1<<1)
+#define MDOF_F (1<<2)
+#define MDOF_X_COMPRESSED (1<<3)
+#define MDOF_CPT (1<<4)
+#define MDOF_IMD (1<<5)
+#define MDOF_BOX (1<<6)
+#define MDOF_LAMBDA (1<<7)
+#define MDOF_BOX_COMPRESSED (1<<8)
+#define MDOF_LAMBDA_COMPRESSED (1<<9)
#endif
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/commandline/filenm.h"
#include "gromacs/fileio/confio.h"
+#include "gromacs/fileio/tngio.h"
#include "gromacs/math/vec.h"
#include "gromacs/mdlib/mdoutf.h"
#include "gromacs/mdlib/mdrun.h"
{
mdof_flags |= MDOF_CPT;
}
- ;
+ if (do_per_step(step, mdoutf_get_tng_box_output_interval(outf)))
+ {
+ mdof_flags |= MDOF_BOX;
+ }
+ if (do_per_step(step, mdoutf_get_tng_lambda_output_interval(outf)))
+ {
+ mdof_flags |= MDOF_LAMBDA;
+ }
+ if (do_per_step(step, mdoutf_get_tng_compressed_box_output_interval(outf)))
+ {
+ mdof_flags |= MDOF_BOX_COMPRESSED;
+ }
+ if (do_per_step(step, mdoutf_get_tng_compressed_lambda_output_interval(outf)))
+ {
+ mdof_flags |= MDOF_LAMBDA_COMPRESSED;
+ }
#if defined(GMX_FAHCORE)
if (bLastStep)