OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
DynamicProps.cpp
1/*
2 * Copyright (c) 2004-present, The University of Notre Dame. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
32 * research, please cite the following paper when you publish your work:
33 *
34 * [1] Drisko et al., J. Open Source Softw. 9, 7004 (2024).
35 *
36 * Good starting points for code and simulation methodology are:
37 *
38 * [2] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
39 * [3] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
40 * [4] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
41 * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
42 * [6] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
43 * [7] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
44 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
45 * [9] Drisko & Gezelter, J. Chem. Theory Comput. 20, 4986-4997 (2024).
46 */
47
48#include <fstream>
49#include <iostream>
50#include <memory>
51#include <string>
52
53#include "DynamicPropsCmd.hpp"
54#include "applications/dynamicProps/AngularVelVelOutProdCorrFunc.hpp"
55#include "applications/dynamicProps/AngularVelocityAutoOutProductCorrFunc.hpp"
56#include "applications/dynamicProps/BondCorrFunc.hpp"
57#include "applications/dynamicProps/ChargeKineticCorrFunc.hpp"
58#include "applications/dynamicProps/ChargeOrientationCorrFunc.hpp"
59#include "applications/dynamicProps/CollectiveDipoleDisplacement.hpp"
60#include "applications/dynamicProps/CurrentDensityAutoCorrFunc.hpp"
61#include "applications/dynamicProps/DipoleCorrFunc.hpp"
62#include "applications/dynamicProps/DirectionalRCorrFunc.hpp"
63#include "applications/dynamicProps/Displacement.hpp"
64#include "applications/dynamicProps/ForTorCorrFunc.hpp"
65#include "applications/dynamicProps/ForceAutoCorrFunc.hpp"
67#include "applications/dynamicProps/HBondJump.hpp"
68#include "applications/dynamicProps/HBondPersistence.hpp"
69#include "applications/dynamicProps/LegendreCorrFunc.hpp"
70#include "applications/dynamicProps/LegendreCorrFuncZ.hpp"
71#include "applications/dynamicProps/MeanDisplacement.hpp"
72#include "applications/dynamicProps/MomAngMomCorrFunc.hpp"
73#include "applications/dynamicProps/OnsagerCorrFunc.hpp"
74#include "applications/dynamicProps/RCorrFunc.hpp"
75#include "applications/dynamicProps/RotAngleDisplacement.hpp"
76#include "applications/dynamicProps/SelectionCorrFunc.hpp"
77#include "applications/dynamicProps/StressCorrFunc.hpp"
78#include "applications/dynamicProps/SystemDipoleCorrFunc.hpp"
79#include "applications/dynamicProps/ThetaCorrFunc.hpp"
80#include "applications/dynamicProps/TorForCorrFunc.hpp"
81#include "applications/dynamicProps/TorqueAutoCorrFunc.hpp"
82#include "applications/dynamicProps/VCorrFunc.hpp"
83#include "applications/dynamicProps/VelAngularVelOutProdCorrFunc.hpp"
84#include "applications/dynamicProps/VelocityAutoOutProductCorrFunc.hpp"
85#include "applications/dynamicProps/WCorrFunc.hpp"
86#include "applications/dynamicProps/cOHz.hpp"
87#include "applications/dynamicProps/SFG.hpp"
88#include "brains/SimCreator.hpp"
89#include "brains/SimInfo.hpp"
90#include "utils/Revision.hpp"
91#include "utils/StringUtils.hpp"
92#include "utils/simError.h"
93
94using namespace OpenMD;
95
96int main(int argc, char* argv[]) {
97 struct gengetopt_args_info args_info;
98
99 // parse the command line option
100
101 if (cmdline_parser(argc, argv, &args_info) != 0) {
103 exit(1);
104 }
105
106 // get the dumpfile name and meta-data file name
107 std::string dumpFileName = args_info.input_arg;
108
109 std::string sele1;
110 std::string sele2;
111
112 // check the first selection argument, or set it to the environment
113 // variable, or failing that, set it to "select all"
114
115 if (args_info.sele1_given) {
116 sele1 = args_info.sele1_arg;
117 } else {
118 char* sele1Env = getenv("SELECTION1");
119 if (sele1Env) {
120 sele1 = sele1Env;
121 } else {
122 sele1 = "select all";
123 }
124 }
125
126 // check the second selection argument, or set it to the environment
127 // variable, or failing that, set it to the first selection
128
129 if (args_info.sele2_given) {
130 sele2 = args_info.sele2_arg;
131 } else {
132 char* sele2Env = getenv("SELECTION2");
133 if (sele2Env) {
134 sele2 = sele2Env;
135 } else {
136 // If sele2 is not specified, then the default behavior
137 // should be what is already intended for sele1
138 sele2 = sele1;
139 }
140 }
141
142 // convert privilegedAxis to corresponding integer
143 // x axis -> 0
144 // y axis -> 1
145 // z axis -> 2 (default)
146
147 int privilegedAxis;
148 switch (args_info.privilegedAxis_arg) {
149 case privilegedAxis_arg_x:
150 privilegedAxis = 0;
151 break;
152 case privilegedAxis_arg_y:
153 privilegedAxis = 1;
154 break;
155 case privilegedAxis_arg_z:
156 default:
157 privilegedAxis = 2;
158 break;
159 }
160
161 // use the memory string to figure out how much memory we can use:
162 // char *end;
163 // long long int memSize = memparse(args_info.memory_arg, &end);
164
165 // We don't really need to print this out anymore:
166 // snprintf( painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
167 // "Amount of memory being used: %llu bytes\n", memSize);
168 // painCave.severity = OPENMD_INFO;
169 // painCave.isFatal = 0;
170 // simError();
171
172 // parse md file and set up the system
173 SimCreator creator;
174 SimInfo* info = creator.createSim(dumpFileName, false);
175
176 RealType maxLen;
177 if (args_info.length_given) {
178 maxLen = args_info.length_arg;
179 } else {
180 maxLen = 100.0;
181 }
182
183 std::unique_ptr<DynamicProperty> corrFunc {nullptr};
184
185 if (args_info.sdcorr_given) {
186 corrFunc = std::make_unique<SystemDipoleCorrFunc>(info, dumpFileName, sele1,
187 sele2);
188 } else if (args_info.selecorr_given) {
189 corrFunc =
190 std::make_unique<SelectionCorrFunc>(info, dumpFileName, sele1, sele2);
191 } else if (args_info.dcorr_given) {
192 corrFunc =
193 std::make_unique<DipoleCorrFunc>(info, dumpFileName, sele1, sele2);
194 } else if (args_info.rcorr_given) {
195 corrFunc = std::make_unique<RCorrFunc>(info, dumpFileName, sele1, sele2);
196 } else if (args_info.r_rcorr_given) {
197 corrFunc = std::make_unique<RCorrFuncR>(info, dumpFileName, sele1, sele2);
198 } else if (args_info.thetacorr_given) {
199 corrFunc =
200 std::make_unique<ThetaCorrFunc>(info, dumpFileName, sele1, sele2);
201 } else if (args_info.drcorr_given) {
202 corrFunc = std::make_unique<DirectionalRCorrFunc>(info, dumpFileName, sele1,
203 sele2);
204 } else if (args_info.rcorrZ_given) {
205 corrFunc = std::make_unique<RCorrFuncZ>(
206 info, dumpFileName, sele1, sele2, args_info.nzbins_arg, privilegedAxis);
207 } else if (args_info.vcorr_given) {
208 corrFunc = std::make_unique<VCorrFunc>(info, dumpFileName, sele1, sele2);
209 } else if (args_info.vcorrZ_given) {
210 corrFunc = std::make_unique<VCorrFuncZ>(info, dumpFileName, sele1, sele2);
211 } else if (args_info.vcorrR_given) {
212 corrFunc = std::make_unique<VCorrFuncR>(info, dumpFileName, sele1, sele2);
213 } else if (args_info.wcorr_given) {
214 corrFunc = std::make_unique<WCorrFunc>(info, dumpFileName, sele1, sele2);
215 } else if (args_info.pjcorr_given) {
216 corrFunc =
217 std::make_unique<MomAngMomCorrFunc>(info, dumpFileName, sele1, sele2);
218 } else if (args_info.ftcorr_given) {
219 corrFunc =
220 std::make_unique<ForTorCorrFunc>(info, dumpFileName, sele1, sele2);
221 } else if (args_info.ckcorr_given) {
222 corrFunc = std::make_unique<ChargeKineticCorrFunc>(
223 info, dumpFileName, sele1, sele2, args_info.rcut_arg);
224 } else if (args_info.cscorr_given) {
225 if (args_info.dipoleX_given && args_info.dipoleY_given &&
226 args_info.dipoleZ_given) {
227 corrFunc = std::make_unique<ChargeOrientationCorrFunc>(
228 info, dumpFileName, sele1, sele2, args_info.dipoleX_arg,
229 args_info.dipoleY_arg, args_info.dipoleZ_arg, args_info.rcut_arg);
230 }
231 } else if (args_info.facorr_given) {
232 corrFunc =
233 std::make_unique<ForceAutoCorrFunc>(info, dumpFileName, sele1, sele2);
234 } else if (args_info.tfcorr_given) {
235 corrFunc =
236 std::make_unique<TorForCorrFunc>(info, dumpFileName, sele1, sele2);
237 } else if (args_info.tacorr_given) {
238 corrFunc =
239 std::make_unique<TorqueAutoCorrFunc>(info, dumpFileName, sele1, sele2);
240 } else if (args_info.bondcorr_given) {
241 corrFunc = std::make_unique<BondCorrFunc>(info, dumpFileName, sele1, sele2);
242 } else if (args_info.stresscorr_given) {
243 corrFunc =
244 std::make_unique<StressCorrFunc>(info, dumpFileName, sele1, sele2);
245 } else if (args_info.freqfluccorr_given) {
246 corrFunc =
247 std::make_unique<FreqFlucCorrFunc>(info, dumpFileName, sele1, sele2);
248 } else if (args_info.lcorr_given) {
249 int order(0);
250 if (args_info.order_given)
251 order = args_info.order_arg;
252 else {
253 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
254 "--order must be set if --lcorr is set\n");
255 painCave.severity = OPENMD_ERROR;
256 painCave.isFatal = 1;
257 simError();
258 }
259
260 if (args_info.seleoffset_given) {
261 corrFunc = std::make_unique<LegendreCorrFunc>(info, dumpFileName, sele1,
262 sele2,
263 args_info.seleoffset_arg,
264 order);
265 } else {
266
267 corrFunc = std::make_unique<LegendreCorrFunc>(info, dumpFileName, sele1,
268 sele2, order);
269 }
270 } else if (args_info.lcorrZ_given) {
271 int order(0);
272 if (args_info.order_given)
273 order = args_info.order_arg;
274 else {
275 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
276 "--order must be set if --lcorrZ is set\n");
277 painCave.severity = OPENMD_ERROR;
278 painCave.isFatal = 1;
279 simError();
280 }
281
282 corrFunc = std::make_unique<LegendreCorrFuncZ>(
283 info, dumpFileName, sele1, sele2, order, args_info.nzbins_arg,
284 privilegedAxis);
285
286 } else if (args_info.cohZ_given) {
287 int order(0);
288 if (args_info.order_given)
289 order = args_info.order_arg;
290 else {
291 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
292 "--order must be set if --cohZ is set\n");
293 painCave.severity = OPENMD_ERROR;
294 painCave.isFatal = 1;
295 simError();
296 }
297
298 corrFunc = std::make_unique<COHZ>(info, dumpFileName, sele1, sele2, order,
299 args_info.nzbins_arg, privilegedAxis);
300
301 } else if (args_info.jumptime_given) {
302 corrFunc = std::make_unique<HBondJump>(
303 info, dumpFileName, sele1, sele2, args_info.OOcut_arg,
304 args_info.thetacut_arg, args_info.OHcut_arg);
305 } else if (args_info.jumptimeZ_given) {
306 corrFunc = std::make_unique<HBondJumpZ>(
307 info, dumpFileName, sele1, sele2, args_info.OOcut_arg,
308 args_info.thetacut_arg, args_info.OHcut_arg, args_info.nzbins_arg,
309 privilegedAxis);
310 } else if (args_info.jumptimeR_given) {
311 if (args_info.sele3_given) {
312 corrFunc = std::make_unique<HBondJumpR>(
313 info, dumpFileName, sele1, sele2, args_info.sele3_arg,
314 args_info.OOcut_arg, args_info.thetacut_arg, args_info.OHcut_arg,
315 maxLen, args_info.nbins_arg);
316 } else {
317 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
318 "--sele3 must be set if --jumptimeR is set\n");
319 painCave.severity = OPENMD_ERROR;
320 painCave.isFatal = 1;
321 simError();
322 }
323 } else if (args_info.persistence_given) {
324 corrFunc = std::make_unique<HBondPersistence>(
325 info, dumpFileName, sele1, sele2, args_info.OOcut_arg,
326 args_info.thetacut_arg, args_info.OHcut_arg);
327 } else if (args_info.disp_given) {
328 corrFunc = std::make_unique<Displacement>(info, dumpFileName, sele1, sele2);
329 } else if (args_info.dispZ_given) {
330 corrFunc = std::make_unique<DisplacementZ>(
331 info, dumpFileName, sele1, sele2, args_info.nzbins_arg, privilegedAxis);
332 } else if (args_info.current_given) {
333 corrFunc = std::make_unique<CurrentDensityAutoCorrFunc>(info, dumpFileName,
334 sele1, sele2);
335 } else if (args_info.onsager_given) {
336 if (args_info.sele1_given) {
337 corrFunc =
338 std::make_unique<OnsagerCorrFunc>(info, dumpFileName, sele1, sele2);
339 } else {
340 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
341 "--sele1 must be set for Center of Mass Rcorr\n");
342 painCave.severity = OPENMD_ERROR;
343 painCave.isFatal = 1;
344 simError();
345 }
346 } else if (args_info.ddisp_given) {
347 corrFunc = std::make_unique<CollectiveDipoleDisplacement>(
348 info, dumpFileName, sele1, sele2);
349 } else if (args_info.vaOutProdcorr_given) {
350 corrFunc = std::make_unique<VelocityAutoOutProductCorrFunc>(
351 info, dumpFileName, sele1, sele2);
352 } else if (args_info.waOutProdcorr_given) {
353 corrFunc = std::make_unique<AngularVelocityAutoOutProductCorrFunc>(
354 info, dumpFileName, sele1, sele2);
355 } else if (args_info.vwOutProdcorr_given) {
356 corrFunc = std::make_unique<VelAngularVelOutProdCorrFunc>(
357 info, dumpFileName, sele1, sele2);
358 } else if (args_info.wvOutProdcorr_given) {
359 corrFunc = std::make_unique<AngularVelVelOutProdCorrFunc>(
360 info, dumpFileName, sele1, sele2);
361 } else if (args_info.rotAngleDisp_given) {
362 corrFunc = std::make_unique<RotAngleDisplacement>(info, dumpFileName, sele1,
363 sele2);
364 } else if (args_info.meandisp_given) {
365 corrFunc =
366 std::make_unique<MeanDisplacement>(info, dumpFileName, sele1, sele2);
367 } else if (args_info.sfg_given) {
368 corrFunc = std::make_unique<SFG>(info, dumpFileName, sele1, sele2,
369 args_info.sfgPolarization_arg,
370 privilegedAxis, args_info.t_apod_arg,
371 args_info.t_zerofill_arg,
372 args_info.fermiCoupling_arg);
373 }
374
375 if (args_info.selectionMode_arg == selectionMode_arg_restart) {
376 corrFunc->setSelectionModeRestart();
377 }
378 if (args_info.output_given) { corrFunc->setOutputName(args_info.output_arg); }
379
380 corrFunc->setWindowingParameters(args_info.tcorr_arg, // fs, double
381 args_info.nstart_arg, // frames, int
382 args_info.tsep_arg); // fs, double
383 corrFunc->doCorrelate();
384
385 delete info;
386 return 0;
387}
void cmdline_parser_print_help(void)
Print the help.
The header file for the command line option parser generated by GNU Gengetopt version 2....
Frequency Fluctuation Correlation Function.
The only responsibility of SimCreator is to parse the meta-data file and create a SimInfo instance ba...
SimInfo * createSim(const std::string &mdFileName, bool loadInitCoords=true)
Setup Simulation.
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Definition SimInfo.hpp:96
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
Where the command line options are stored.
char * input_arg
input dump file.
int cmdline_parser(int argc, char **argv, struct gengetopt_args_info *args_info)
The command line parser.