2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
36 * \brief Defines the trajectory element for the modular simulator
38 * \author Pascal Merz <pascal.merz@me.com>
39 * \ingroup module_modularsimulator
43 #include "trajectoryelement.h"
45 #include "gromacs/mdlib/mdoutf.h"
46 #include "gromacs/mdlib/stat.h"
47 #include "gromacs/mdrunutility/handlerestart.h"
48 #include "gromacs/mdtypes/inputrec.h"
52 TrajectoryElement::TrajectoryElement(std::vector<ITrajectoryWriterClient*> writerClients,
56 const MdrunOptions& mdrunOptions,
58 gmx::IMDOutputProvider* outputProvider,
59 const MdModulesNotifier& mdModulesNotifier,
60 const t_inputrec* inputrec,
61 const gmx_mtop_t& top_global,
62 const gmx_output_env_t* oenv,
63 gmx_wallcycle* wcycle,
64 StartingBehavior startingBehavior,
65 const bool simulationsShareState) :
69 outf_(init_mdoutf(fplog,
81 simulationsShareState,
83 writerClients_(std::move(writerClients))
87 int TrajectoryElement::tngBoxOut() const
89 return mdoutf_get_tng_box_output_interval(outf_);
91 int TrajectoryElement::tngLambdaOut() const
93 return mdoutf_get_tng_lambda_output_interval(outf_);
95 int TrajectoryElement::tngBoxOutCompressed() const
97 return mdoutf_get_tng_compressed_box_output_interval(outf_);
99 int TrajectoryElement::tngLambdaOutCompressed() const
101 return mdoutf_get_tng_compressed_lambda_output_interval(outf_);
104 void TrajectoryElement::elementSetup()
106 for (auto& client : writerClients_)
108 auto callback = client->registerTrajectoryWriterCallback(TrajectoryEvent::StateWritingStep);
111 runStateCallbacks_.emplace_back(std::move(*callback));
113 callback = client->registerTrajectoryWriterCallback(TrajectoryEvent::EnergyWritingStep);
116 runEnergyCallbacks_.emplace_back(std::move(*callback));
118 client->trajectoryWriterSetup(outf_);
122 void TrajectoryElement::scheduleTask(Step step, Time time, const RegisterRunFunction& registerRunFunction)
124 const bool writeEnergyThisStep = writeEnergyStep_ == step;
125 const bool writeStateThisStep = writeStateStep_ == step;
126 const bool writeLogThisStep = writeLogStep_ == step;
127 if (writeEnergyThisStep || writeStateThisStep || writeLogThisStep)
129 registerRunFunction([this, step, time, writeStateThisStep, writeEnergyThisStep, writeLogThisStep]() {
130 write(step, time, writeStateThisStep, writeEnergyThisStep, writeLogThisStep);
135 void TrajectoryElement::elementTeardown()
137 for (auto& client : writerClients_)
139 client->trajectoryWriterTeardown(outf_);
141 mdoutf_tng_close(outf_);
145 void TrajectoryElement::write(Step step, Time time, bool writeState, bool writeEnergy, bool writeLog)
147 if (writeState || writeLog)
149 for (auto& callback : runStateCallbacks_)
151 callback(outf_, step, time, writeState, writeLog);
154 if (writeEnergy || writeLog)
156 for (auto& callback : runEnergyCallbacks_)
158 callback(outf_, step, time, writeEnergy, writeLog);
163 std::optional<SignallerCallback> TrajectoryElement::registerLoggingCallback()
165 return [this](Step step, Time /*unused*/) { writeLogStep_ = step; };
168 std::optional<SignallerCallback> TrajectoryElement::registerTrajectorySignallerCallback(TrajectoryEvent event)
170 if (event == TrajectoryEvent::StateWritingStep)
172 return [this](Step step, Time /*unused*/) { this->writeStateStep_ = step; };
174 if (event == TrajectoryEvent::EnergyWritingStep)
176 return [this](Step step, Time /*unused*/) { this->writeEnergyStep_ = step; };
181 void TrajectoryElementBuilder::registerWriterClient(ITrajectoryWriterClient* client)
185 if (state_ == ModularSimulatorBuilderState::NotAcceptingClientRegistrations)
187 throw SimulationAlgorithmSetupError(
188 "Tried to register to signaller after it was built.");
190 writerClients_.emplace_back(client);