4778286082bc0d8119e7d4632176dafc2688f824
[alexxy/gromacs.git] / src / gromacs / restraint / manager.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2018, 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
36 /*! \internal \file
37  * \brief Implement the restraint manager.
38  *
39  * \author M. Eric Irrgang <ericirrgang@gmail.com>
40  *
41  * \ingroup module_restraint
42  */
43
44 #include "gmxpre.h"
45
46 #include "manager.h"
47
48 #include <iostream>
49 #include <map>
50 #include <memory>
51 #include <mutex>
52 #include <vector>
53
54 #include "gromacs/compat/make_unique.h"
55 #include "gromacs/utility/exceptions.h"
56
57 namespace gmx
58 {
59
60 /*! \internal
61  * \brief Implementation class for restraint manager.
62  */
63 class RestraintManager::Impl
64 {
65     public:
66
67         /*!
68          * \brief Implement Manager::addToSpec()
69          *
70          * \param restraint Handle to be added to the manager.
71          * \param name Identifying string for restraint.
72          */
73         void add(std::shared_ptr<::gmx::IRestraintPotential> restraint, std::string name);
74
75         /*!
76          * \brief Clear registered restraints and reset the manager.
77          */
78         void clear() noexcept;
79
80         /*!
81          * \brief The list of configured restraints.
82          *
83          * Clients can extend the life of a restraint implementation object that
84          * is being used by holding the shared_ptr handle. A RestraintManager::Impl is logically
85          * const when its owning Manager is logically const, but the Manager can still
86          * grant access to individual restraints.
87          */
88         std::vector< std::shared_ptr<::gmx::IRestraintPotential> > restraint_;
89
90     private:
91         //! Regulate initialization of the shared resource when (re)initialized.
92         static std::mutex initializationMutex_;
93
94 };
95
96 // Initialize static members
97 std::mutex RestraintManager::Impl::initializationMutex_ {};
98
99
100 void RestraintManager::Impl::add(std::shared_ptr<::gmx::IRestraintPotential> restraint, std::string name)
101 {
102     (void)name;
103     restraint_.emplace_back(std::move(restraint));
104 }
105
106 RestraintManager::RestraintManager() : instance_(std::make_shared<RestraintManager::Impl>()) {};
107
108 RestraintManager::~RestraintManager() = default;
109
110 void RestraintManager::Impl::clear() noexcept
111 {
112     std::lock_guard<std::mutex> lock(initializationMutex_);
113     restraint_.resize(0);
114 }
115
116 void RestraintManager::clear() noexcept
117 {
118     GMX_ASSERT(instance_, "instance_ member should never be null.");
119     instance_->clear();
120 }
121
122 void RestraintManager::addToSpec(std::shared_ptr<gmx::IRestraintPotential> puller,
123                                  std::string                               name)
124 {
125     instance_->add(std::move(puller), std::move(name));
126 }
127
128 std::vector< std::shared_ptr<IRestraintPotential> > RestraintManager::getRestraints() const
129 {
130     return instance_->restraint_;
131 }
132
133 unsigned long RestraintManager::countRestraints() noexcept
134 {
135     return instance_->restraint_.size();
136 }
137
138 } // end namespace gmx