Make PBC type enumeration into PbcType enum class
[alexxy/gromacs.git] / src / gromacs / domdec / dump.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2018,2019,2020, 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.
8  *
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.
13  *
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.
18  *
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.
23  *
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.
31  *
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.
34  */
35 /*! \internal \file
36  *
37  * \brief This file definees functions for DD to write PDB files
38  * e.g. when reporting problems.
39  *
40  * \author Berk Hess <hess@kth.se>
41  * \ingroup module_domdec
42  */
43
44 #include "gmxpre.h"
45
46 #include "dump.h"
47
48 #include "gromacs/domdec/domdec_network.h"
49 #include "gromacs/fileio/gmxfio.h"
50 #include "gromacs/fileio/pdbio.h"
51 #include "gromacs/math/vec.h"
52 #include "gromacs/mdtypes/commrec.h"
53 #include "gromacs/pbcutil/pbc.h"
54 #include "gromacs/topology/mtop_lookup.h"
55 #include "gromacs/utility/cstringutil.h"
56
57 #include "domdec_internal.h"
58
59 void write_dd_grid_pdb(const char* fn, int64_t step, gmx_domdec_t* dd, matrix box, gmx_ddbox_t* ddbox)
60 {
61     rvec   grid_s[2], *grid_r = nullptr, cx, r;
62     char   fname[STRLEN], buf[22];
63     FILE*  out;
64     int    a, i, d, z, y, x;
65     matrix tric;
66     real   vol;
67
68     copy_rvec(dd->comm->cell_x0, grid_s[0]);
69     copy_rvec(dd->comm->cell_x1, grid_s[1]);
70
71     if (DDMASTER(dd))
72     {
73         snew(grid_r, 2 * dd->nnodes);
74     }
75
76     dd_gather(dd, 2 * sizeof(rvec), grid_s, DDMASTER(dd) ? grid_r : nullptr);
77
78     if (DDMASTER(dd))
79     {
80         for (d = 0; d < DIM; d++)
81         {
82             for (i = 0; i < DIM; i++)
83             {
84                 if (d == i)
85                 {
86                     tric[d][i] = 1;
87                 }
88                 else
89                 {
90                     if (d < ddbox->npbcdim && dd->numCells[d] > 1)
91                     {
92                         tric[d][i] = box[i][d] / box[i][i];
93                     }
94                     else
95                     {
96                         tric[d][i] = 0;
97                     }
98                 }
99             }
100         }
101         sprintf(fname, "%s_%s.pdb", fn, gmx_step_str(step, buf));
102         out = gmx_fio_fopen(fname, "w");
103         gmx_write_pdb_box(out, dd->unitCellInfo.haveScrewPBC ? PbcType::Screw : PbcType::Xyz, box);
104         a = 1;
105         for (i = 0; i < dd->nnodes; i++)
106         {
107             vol = dd->nnodes / (box[XX][XX] * box[YY][YY] * box[ZZ][ZZ]);
108             for (d = 0; d < DIM; d++)
109             {
110                 vol *= grid_r[i * 2 + 1][d] - grid_r[i * 2][d];
111             }
112             for (z = 0; z < 2; z++)
113             {
114                 for (y = 0; y < 2; y++)
115                 {
116                     for (x = 0; x < 2; x++)
117                     {
118                         cx[XX] = grid_r[i * 2 + x][XX];
119                         cx[YY] = grid_r[i * 2 + y][YY];
120                         cx[ZZ] = grid_r[i * 2 + z][ZZ];
121                         mvmul(tric, cx, r);
122                         gmx_fprintf_pdb_atomline(out, epdbATOM, a++, "CA", ' ', "GLY", ' ', i + 1, ' ',
123                                                  10 * r[XX], 10 * r[YY], 10 * r[ZZ], 1.0, vol, "");
124                     }
125                 }
126             }
127             for (d = 0; d < DIM; d++)
128             {
129                 for (x = 0; x < 4; x++)
130                 {
131                     switch (d)
132                     {
133                         case 0: y = 1 + i * 8 + 2 * x; break;
134                         case 1: y = 1 + i * 8 + 2 * x - (x % 2); break;
135                         case 2: y = 1 + i * 8 + x; break;
136                     }
137                     fprintf(out, "%6s%5d%5d\n", "CONECT", y, y + (1 << d));
138                 }
139             }
140         }
141         gmx_fio_fclose(out);
142         sfree(grid_r);
143     }
144 }
145
146 void write_dd_pdb(const char*       fn,
147                   int64_t           step,
148                   const char*       title,
149                   const gmx_mtop_t* mtop,
150                   const t_commrec*  cr,
151                   int               natoms,
152                   const rvec        x[],
153                   const matrix      box)
154 {
155     char          fname[STRLEN], buf[22];
156     FILE*         out;
157     int           resnr;
158     const char *  atomname, *resname;
159     gmx_domdec_t* dd;
160
161     dd = cr->dd;
162     if (natoms == -1)
163     {
164         natoms = dd->comm->atomRanges.end(DDAtomRanges::Type::Vsites);
165     }
166
167     sprintf(fname, "%s_%s_n%d.pdb", fn, gmx_step_str(step, buf), cr->sim_nodeid);
168
169     out = gmx_fio_fopen(fname, "w");
170
171     fprintf(out, "TITLE     %s\n", title);
172     gmx_write_pdb_box(out, dd->unitCellInfo.haveScrewPBC ? PbcType::Screw : PbcType::Xyz, box);
173     int molb = 0;
174     for (int i = 0; i < natoms; i++)
175     {
176         int ii = dd->globalAtomIndices[i];
177         mtopGetAtomAndResidueName(mtop, ii, &molb, &atomname, &resnr, &resname, nullptr);
178         int  c;
179         real b;
180         if (i < dd->comm->atomRanges.end(DDAtomRanges::Type::Zones))
181         {
182             c = 0;
183             while (i >= dd->comm->zones.cg_range[c + 1])
184             {
185                 c++;
186             }
187             b = c;
188         }
189         else if (i < dd->comm->atomRanges.end(DDAtomRanges::Type::Vsites))
190         {
191             b = dd->comm->zones.n;
192         }
193         else
194         {
195             b = dd->comm->zones.n + 1;
196         }
197         gmx_fprintf_pdb_atomline(out, epdbATOM, ii + 1, atomname, ' ', resname, ' ', resnr, ' ',
198                                  10 * x[i][XX], 10 * x[i][YY], 10 * x[i][ZZ], 1.0, b, "");
199     }
200     fprintf(out, "TER\n");
201
202     gmx_fio_fclose(out);
203 }