08d4d2e00041620909c1969ab84242ef93b27be8
[alexxy/gromacs.git] / src / gromacs / pulling / pull_internal.h
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,2018, by the GROMACS development team, led by
7  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8  * and including many others, as listed in the AUTHORS file in the
9  * top-level source directory and at http://www.gromacs.org.
10  *
11  * GROMACS is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public License
13  * as published by the Free Software Foundation; either version 2.1
14  * of the License, or (at your option) any later version.
15  *
16  * GROMACS is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with GROMACS; if not, see
23  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
25  *
26  * If you want to redistribute modifications to GROMACS, please
27  * consider that scientific software is very special. Version
28  * control is crucial - bugs must be traceable. We will be happy to
29  * consider code for inclusion in the official distribution, but
30  * derived work must not be called official GROMACS. Details are found
31  * in the README & COPYING files - if they are missing, get the
32  * official version at http://www.gromacs.org.
33  *
34  * To help us fund GROMACS development, we humbly ask that you cite
35  * the research papers on the package. Check out http://www.gromacs.org.
36  */
37
38 /*! \internal \file
39  *
40  *
41  * \brief
42  * This file contains datatypes and function declarations for internal
43    use in the pull code.
44  *
45  * \author Berk Hess
46  */
47
48 #ifndef GMX_PULLING_PULL_INTERNAL_H
49 #define GMX_PULLING_PULL_INTERNAL_H
50
51 #include "config.h"
52
53 #include <vector>
54
55 #include "gromacs/domdec/localatomset.h"
56 #include "gromacs/mdtypes/pull-params.h"
57 #include "gromacs/utility/gmxmpi.h"
58
59 /*! \brief Determines up to what local atom count a pull group gets processed single-threaded.
60  *
61  * We set this limit to 1 with debug to catch bugs.
62  * On Haswell with GCC 5 the cross-over point is around 400 atoms,
63  * independent of thread count and hyper-threading.
64  */
65 #ifdef NDEBUG
66 static const int c_pullMaxNumLocalAtomsSingleThreaded = 100;
67 #else
68 static const int c_pullMaxNumLocalAtomsSingleThreaded = 1;
69 #endif
70
71 enum {
72     epgrppbcNONE, epgrppbcREFAT, epgrppbcCOS
73 };
74
75 /*! \internal
76  * \brief Pull group data used during pulling
77  */
78 struct pull_group_work_t
79 {
80     /*! \brief Constructor
81      *
82      * \param[in] params   The group parameters set by the user
83      * \param[in] atomSet  The global to local atom set manager
84      */
85     pull_group_work_t(const t_pull_group &params,
86                       gmx::LocalAtomSet   atomSet);
87
88     /* Data only modified at initialization */
89     const t_pull_group params;        /**< The pull group parameters */
90     const int          epgrppbc;      /**< The type of pbc for this pull group, see enum above */
91     bool               needToCalcCom; /**< Do we need to calculate the COM? (Not for group 0 or if only used as cylinder group) */
92     std::vector<real>  globalWeights; /**< Weights per atom set by the user and/or mass/friction coefficients, if empty all weights are equal */
93
94     /* Data modified only at init or at domain decomposition */
95     gmx::LocalAtomSet  atomSet;       /**< Global to local atom set mapper */
96     std::vector<real>  localWeights;  /**< Weights for the local atoms */
97
98     /* Data, potentially, changed at every pull call */
99     real                                  mwscale; /**< mass*weight scaling factor 1/sum w m */
100     real                                  wscale;  /**< scaling factor for the weights: sum w m/sum w w m */
101     real                                  invtm;   /**< inverse total mass of the group: 1/wscale sum w m */
102     std::vector < gmx::BasicVector < double>> mdw; /**< mass*gradient(weight) for atoms */
103     std::vector<double>                   dv;      /**< distance to the other group(s) along vec */
104     dvec                                  x;       /**< COM before update */
105     dvec                                  xp;      /**< COM after update before constraining */
106 };
107
108 /* Struct describing the instantaneous spatial layout of a pull coordinate */
109 struct PullCoordSpatialData
110 {
111     dvec          dr01;       /* The direction vector of group 1 relative to group 0 */
112     dvec          dr23;       /* The direction vector of group 3 relative to group 2 */
113     dvec          dr45;       /* The direction vector of group 5 relative to group 4 */
114     dvec          vec;        /* The pull direction */
115     double        vec_len;    /* Length of vec for direction-relative */
116     dvec          ffrad;      /* conversion factor from vec to radial force */
117     double        cyl_dev;    /* The deviation from the reference position */
118     dvec          planevec_m; /* Normal of plane for groups 0, 1, 2, 3 for geometry dihedral */
119     dvec          planevec_n; /* Normal of plane for groups 2, 3, 4, 5 for geometry dihedral */
120
121     double        value;      /* The current value of the coordinate, units of nm or rad */
122 };
123
124 /* Struct with parameters and force evaluation local data for a pull coordinate */
125 struct pull_coord_work_t
126 {
127     /* Constructor */
128     pull_coord_work_t(const t_pull_coord &params) :
129         params(params),
130         value_ref(0),
131         spatialData(),
132         scalarForce(0),
133         bExternalPotentialProviderHasBeenRegistered(false)
134     {
135     }
136
137     const t_pull_coord    params;      /* Pull coordinate parameters */
138
139     double                value_ref;   /* The reference value, usually init+rate*t, units of nm or rad */
140
141     PullCoordSpatialData  spatialData; /* Data defining the current geometry */
142
143     double                scalarForce; /* Scalar force for this cooordinate */
144
145     /* For external-potential coordinates only, for checking if a provider has been registered */
146     bool          bExternalPotentialProviderHasBeenRegistered;
147 };
148
149 /* Struct for storing vectorial forces for a pull coordinate */
150 struct PullCoordVectorForces
151 {
152     dvec force01; /* Force due to the pulling/constraining for groups 0, 1 */
153     dvec force23; /* Force for groups 2 and 3 */
154     dvec force45; /* Force for groups 4 and 5 */
155 };
156
157 /* Struct for sums over (local) atoms in a pull group */
158 struct pull_sum_com_t {
159     /* For normal weighting */
160     double sum_wm;    /* Sum of weight*mass        */
161     double sum_wwm;   /* Sum of weight*weight*mass */
162     dvec   sum_wmx;   /* Sum of weight*mass*x      */
163     dvec   sum_wmxp;  /* Sum of weight*mass*xp     */
164
165     /* For cosine weighting */
166     double sum_cm;    /* Sum of cos(x)*mass          */
167     double sum_sm;    /* Sum of sin(x)*mass          */
168     double sum_ccm;   /* Sum of cos(x)*cos(x)*mass   */
169     double sum_csm;   /* Sum of cos(x)*sin(x)*mass   */
170     double sum_ssm;   /* Sum of sin(x)*sin(x)*mass   */
171     double sum_cmp;   /* Sum of cos(xp)*sin(xp)*mass */
172     double sum_smp;   /* Sum of sin(xp)*sin(xp)*mass */
173
174     /* Dummy data to ensure adjacent elements in an array are separated
175      * by a cache line size, max 128 bytes.
176      * TODO: Replace this by some automated mechanism.
177      */
178     int    dummy[32];
179 };
180
181 typedef struct {
182     gmx_bool    bParticipateAll; /* Do all ranks always participate in pulling? */
183     gmx_bool    bParticipate;    /* Does our rank participate in pulling? */
184 #if GMX_MPI
185     MPI_Comm    mpi_comm_com;    /* Communicator for pulling */
186 #endif
187     int         nparticipate;    /* The number of ranks participating */
188     bool        isMasterRank;    /* Tells whether our rank is the master rank and thus should add the pull virial */
189
190     gmx_int64_t setup_count;     /* The number of decomposition calls */
191     gmx_int64_t must_count;      /* The last count our rank needed to be part */
192
193     rvec       *rbuf;            /* COM calculation buffer */
194     dvec       *dbuf;            /* COM calculation buffer */
195     double     *dbuf_cyl;        /* cylinder ref. groups calculation buffer */
196 }
197 pull_comm_t;
198
199 struct pull_t
200 {
201     /* Global parameters */
202     pull_params_t      params;       /* The pull parameters, from inputrec */
203
204     gmx_bool           bPotential;   /* Are there coordinates with potential? */
205     gmx_bool           bConstraint;  /* Are there constrained coordinates? */
206     gmx_bool           bAngle;       /* Are there angle geometry coordinates? */
207
208     int                ePBC;         /* the boundary conditions */
209     int                npbcdim;      /* do pbc in dims 0 <= dim < npbcdim */
210     gmx_bool           bRefAt;       /* do we need reference atoms for a group COM ? */
211     int                cosdim;       /* dimension for cosine weighting, -1 if none */
212     gmx_bool           bCylinder;    /* Is group 0 a cylinder group? */
213
214     /* Parameters + dynamic data for groups */
215     std::vector<pull_group_work_t>  group;  /* The pull group param and work data */
216     std::vector<pull_group_work_t>  dyna;   /* Dynamic groups for geom=cylinder */
217
218     /* Parameters + dynamic data for coordinates */
219     std::vector<pull_coord_work_t> coord;  /* The pull group param and work data */
220
221     /* Global dynamic data */
222     gmx_bool           bSetPBCatoms; /* Do we need to set x_pbc for the groups? */
223
224     int                nthreads;     /* Number of threads used by the pull code */
225     pull_sum_com_t    *sum_com;      /* Work array for summing for COM, 1 entry per thread */
226
227     pull_comm_t        comm;         /* Communication parameters, communicator and buffers */
228
229     FILE              *out_x;        /* Output file for pull data */
230     FILE              *out_f;        /* Output file for pull data */
231
232     /* The number of coordinates using an external potential */
233     int                numCoordinatesWithExternalPotential;
234     /* Counter for checking external potential registration */
235     int                numUnregisteredExternalPotentials;
236     /* */
237     int                numExternalPotentialsStillToBeAppliedThisStep;
238 };
239
240 #endif