SYCL: Avoid using no_init read accessor in rocFFT
[alexxy/gromacs.git] / src / gromacs / gmxana / gmx_principal.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team.
6  * Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
7  * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
8  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
9  * and including many others, as listed in the AUTHORS file in the
10  * top-level source directory and at http://www.gromacs.org.
11  *
12  * GROMACS is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public License
14  * as published by the Free Software Foundation; either version 2.1
15  * of the License, or (at your option) any later version.
16  *
17  * GROMACS is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with GROMACS; if not, see
24  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
26  *
27  * If you want to redistribute modifications to GROMACS, please
28  * consider that scientific software is very special. Version
29  * control is crucial - bugs must be traceable. We will be happy to
30  * consider code for inclusion in the official distribution, but
31  * derived work must not be called official GROMACS. Details are found
32  * in the README & COPYING files - if they are missing, get the
33  * official version at http://www.gromacs.org.
34  *
35  * To help us fund GROMACS development, we humbly ask that you cite
36  * the research papers on the package. Check out http://www.gromacs.org.
37  */
38 #include "gmxpre.h"
39
40 #include <cmath>
41 #include <cstring>
42
43 #include "gromacs/commandline/pargs.h"
44 #include "gromacs/fileio/confio.h"
45 #include "gromacs/fileio/trxio.h"
46 #include "gromacs/fileio/xvgr.h"
47 #include "gromacs/gmxana/gmx_ana.h"
48 #include "gromacs/gmxana/gstat.h"
49 #include "gromacs/gmxana/princ.h"
50 #include "gromacs/math/vec.h"
51 #include "gromacs/pbcutil/rmpbc.h"
52 #include "gromacs/topology/index.h"
53 #include "gromacs/topology/topology.h"
54 #include "gromacs/utility/arraysize.h"
55 #include "gromacs/utility/cstringutil.h"
56 #include "gromacs/utility/futil.h"
57 #include "gromacs/utility/smalloc.h"
58
59
60 static void calc_principal_axes(const t_topology* top, rvec* x, int* index, int n, matrix axes, rvec inertia)
61 {
62     rvec xcm;
63
64     sub_xcm(x, n, index, top->atoms.atom, xcm, FALSE);
65     principal_comp(n, index, top->atoms.atom, x, axes, inertia);
66 }
67
68 int gmx_principal(int argc, char* argv[])
69 {
70     const char* desc[] = {
71         "[THISMODULE] calculates the three principal axes of inertia for a group",
72         "of atoms. NOTE: Old versions of GROMACS wrote the output data in a",
73         "strange transposed way. As of GROMACS 5.0, the output file paxis1.dat",
74         "contains the x/y/z components of the first (major) principal axis for",
75         "each frame, and similarly for the middle and minor axes in paxis2.dat",
76         "and paxis3.dat."
77     };
78     static gmx_bool foo = FALSE;
79
80     t_pargs pa[] = { { "-foo", FALSE, etBOOL, { &foo }, "Dummy option to avoid empty array" } };
81     t_trxstatus* status;
82     t_topology   top;
83     PbcType      pbcType;
84     real         t;
85     rvec*        x;
86
87     int               natoms;
88     char*             grpname;
89     int               i, gnx;
90     int*              index;
91     rvec              moi;
92     FILE*             axis1;
93     FILE*             axis2;
94     FILE*             axis3;
95     FILE*             fmoi;
96     matrix            axes, box;
97     gmx_output_env_t* oenv;
98     gmx_rmpbc_t       gpbc = nullptr;
99     char**            legend;
100
101     t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD },     { efTPS, nullptr, nullptr, ffREAD },
102                        { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, "-a1", "paxis1", ffWRITE },
103                        { efXVG, "-a2", "paxis2", ffWRITE },  { efXVG, "-a3", "paxis3", ffWRITE },
104                        { efXVG, "-om", "moi", ffWRITE } };
105 #define NFILE asize(fnm)
106
107     if (!parse_common_args(&argc,
108                            argv,
109                            PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW,
110                            NFILE,
111                            fnm,
112                            asize(pa),
113                            pa,
114                            asize(desc),
115                            desc,
116                            0,
117                            nullptr,
118                            &oenv))
119     {
120         return 0;
121     }
122
123     snew(legend, DIM);
124     for (i = 0; i < DIM; i++)
125     {
126         snew(legend[i], STRLEN);
127         sprintf(legend[i], "%c component", 'X' + i);
128     }
129
130     axis1 = xvgropen(opt2fn("-a1", NFILE, fnm),
131                      "Principal axis 1 (major axis)",
132                      output_env_get_xvgr_tlabel(oenv),
133                      "Component (nm)",
134                      oenv);
135     xvgr_legend(axis1, DIM, legend, oenv);
136
137     axis2 = xvgropen(opt2fn("-a2", NFILE, fnm),
138                      "Principal axis 2 (middle axis)",
139                      output_env_get_xvgr_tlabel(oenv),
140                      "Component (nm)",
141                      oenv);
142     xvgr_legend(axis2, DIM, legend, oenv);
143
144     axis3 = xvgropen(opt2fn("-a3", NFILE, fnm),
145                      "Principal axis 3 (minor axis)",
146                      output_env_get_xvgr_tlabel(oenv),
147                      "Component (nm)",
148                      oenv);
149     xvgr_legend(axis3, DIM, legend, oenv);
150
151     sprintf(legend[XX], "Axis 1 (major)");
152     sprintf(legend[YY], "Axis 2 (middle)");
153     sprintf(legend[ZZ], "Axis 3 (minor)");
154
155     fmoi = xvgropen(opt2fn("-om", NFILE, fnm),
156                     "Moments of inertia around inertial axes",
157                     output_env_get_xvgr_tlabel(oenv),
158                     "I (au nm\\S2\\N)",
159                     oenv);
160     xvgr_legend(fmoi, DIM, legend, oenv);
161
162     for (i = 0; i < DIM; i++)
163     {
164         sfree(legend[i]);
165     }
166     sfree(legend);
167
168     read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &pbcType, nullptr, nullptr, box, TRUE);
169
170     get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &gnx, &index, &grpname);
171
172     natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
173
174     gpbc = gmx_rmpbc_init(&top.idef, pbcType, natoms);
175
176     do
177     {
178         gmx_rmpbc(gpbc, natoms, box, x);
179
180         calc_principal_axes(&top, x, index, gnx, axes, moi);
181
182         fprintf(axis1, "%15.10f     %15.10f  %15.10f  %15.10f\n", t, axes[XX][XX], axes[XX][YY], axes[XX][ZZ]);
183         fprintf(axis2, "%15.10f     %15.10f  %15.10f  %15.10f\n", t, axes[YY][XX], axes[YY][YY], axes[YY][ZZ]);
184         fprintf(axis3, "%15.10f     %15.10f  %15.10f  %15.10f\n", t, axes[ZZ][XX], axes[ZZ][YY], axes[ZZ][ZZ]);
185         fprintf(fmoi, "%15.10f     %15.10f  %15.10f  %15.10f\n", t, moi[XX], moi[YY], moi[ZZ]);
186     } while (read_next_x(oenv, status, &t, x, box));
187
188     gmx_rmpbc_done(gpbc);
189
190     close_trx(status);
191
192     xvgrclose(axis1);
193     xvgrclose(axis2);
194     xvgrclose(axis3);
195     xvgrclose(fmoi);
196
197     return 0;
198 }