Make stepWorkload.useGpuXBufferOps flag consistent
[alexxy/gromacs.git] / src / gromacs / mdlib / makeconstraints.h
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 /*! \libinternal \file
36  * \brief Declares and implements factory function for Constraints.
37  *
38  * \author Berk Hess <hess@kth.se>
39  * \author Mark Abraham <mark.j.abraham@gmail.com>
40  * \ingroup module_mdlib
41  * \inlibraryapi
42  */
43
44 #ifndef GMX_MDLIB_MAKECONSTRAINTS_H
45 #define GMX_MDLIB_MAKECONSTRAINTS_H
46
47 #include <memory>
48
49 #include "gromacs/mdlib/constr.h"
50 #include "gromacs/mdtypes/inputrec.h"
51 #include "gromacs/pulling/pull.h"
52 #include "gromacs/topology/ifunc.h"
53 #include "gromacs/topology/mtop_util.h"
54
55 struct gmx_mtop_t;
56
57 namespace gmx
58 {
59
60 /*! \internal
61  * \brief Support type to help implement makeConstraints().
62  *
63  * This member type of Constraints also inherits from it, so that it
64  * can access the private constructor of Constraints to support the
65  * implementation of the factory function. This approach avoids having
66  * to declare makeConstraints() as a template friend function. */
67 struct Constraints::CreationHelper : public Constraints
68 {
69 public:
70     /*! \brief Constructor that can call the private constructor
71      * of Constraints.
72      *
73      * The parameter pack insulates this helper type from changes
74      * to the arguments to the constructor. */
75     template<typename... Args>
76     CreationHelper(Args&&... args) : Constraints(std::forward<Args>(args)...)
77     {
78     }
79 };
80
81 /*! \brief Factory function for Constraints.
82  *
83  * We only want an object to manage computing constraints when the
84  * simulation requires one. Checking for whether the object was made
85  * adds overhead to simulations that use constraints, while avoiding
86  * overhead on those that do not, so is a design trade-off we might
87  * reconsider some time.
88  *
89  * Using a private constructor and a factory function ensures that we
90  * can only make a Constraints object when the prerequisites are
91  * satisfied, ie. that something needs them and if necessary has
92  * already been initialized.
93  *
94  * Using the parameter pack insulates the factory function from
95  * changes to the type signature of the constructor that don't
96  * affect the logic here. */
97 template<typename... Args>
98 std::unique_ptr<Constraints> makeConstraints(const gmx_mtop_t& mtop,
99                                              const t_inputrec& ir,
100                                              pull_t*           pull_work,
101                                              bool              doEssentialDynamics,
102                                              Args&&... args)
103 {
104     int numConstraints = (gmx_mtop_ftype_count(mtop, F_CONSTR) + gmx_mtop_ftype_count(mtop, F_CONSTRNC));
105     int numSettles = gmx_mtop_ftype_count(mtop, F_SETTLE);
106     GMX_RELEASE_ASSERT(!ir.bPull || pull_work != nullptr,
107                        "When COM pulling is active, it must be initialized before constraints are "
108                        "initialized");
109     bool doPullingWithConstraints = ir.bPull && pull_have_constraint(*pull_work);
110     if (numConstraints + numSettles == 0 && !doPullingWithConstraints && !doEssentialDynamics)
111     {
112         // No work, so don't make a Constraints object.
113         return nullptr;
114     }
115     return std::make_unique<Constraints::CreationHelper>(
116             mtop, ir, pull_work, std::forward<Args>(args)..., numConstraints, numSettles);
117 }
118
119 } // namespace gmx
120
121 #endif