2 Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
3 (HOOMD-blue) Open Source Software License Copyright 2009-2014 The Regents of
4 the University of Michigan All rights reserved.
6 HOOMD-blue may contain modifications ("Contributions") provided, and to which
7 copyright is held, by various Contributors who have granted The Regents of the
8 University of Michigan the right to modify and/or distribute such Contributions.
10 You may redistribute, use, and create derivate works of HOOMD-blue, in source
11 and binary forms, provided you abide by the following conditions:
13 * Redistributions of source code must retain the above copyright notice, this
14 list of conditions, and the following disclaimer both in the code and
15 prominently in any materials provided with the distribution.
17 * Redistributions in binary form must reproduce the above copyright notice, this
18 list of conditions, and the following disclaimer in the documentation and/or
19 other materials provided with the distribution.
21 * All publications and presentations based on HOOMD-blue, including any reports
22 or published results obtained, in whole or in part, with HOOMD-blue, will
23 acknowledge its use according to the terms posted at the time of submission on:
24 http://codeblue.umich.edu/hoomd-blue/citations.html
26 * Any electronic documents citing HOOMD-Blue will link to the HOOMD-Blue website:
27 http://codeblue.umich.edu/hoomd-blue/
29 * Apart from the above required attributions, neither the name of the copyright
30 holder nor the names of HOOMD-blue's contributors may be used to endorse or
31 promote products derived from this software without specific prior written
36 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND
37 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR ANY
39 WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.
41 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
42 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
43 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
45 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
46 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
47 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 // Maintainer: joaander
52 #include <boost/shared_ptr.hpp>
57 #include "ComputeThermoTypes.h"
58 #include "ParticleGroup.h"
60 /*! \file ComputeThermo.h
61 \brief Declares a class for computing thermodynamic quantities
65 #error This header cannot be compiled by nvcc
68 #ifndef __COMPUTE_THERMO_H__
69 #define __COMPUTE_THERMO_H__
71 //! Computes thermodynamic properties of a group of particles
72 /*! ComputeThermo calculates instantaneous thermodynamic properties and provides them for the logger.
73 All computed values are stored in a GPUArray so that they can be accessed on the GPU without intermediate copies.
74 Use the enum values in thermo_index to index the array and extract the properties of interest. Convenience functions
75 are provided for accessing the values on the CPU. Certain properties, loke ndof and num_particles are always known
76 and there is no need for them to be accessible via the GPUArray.
78 Computed quantities available in the GPUArray:
79 - temperature of the group
80 - pressure (valid for the all group)
84 Values available all the time
85 - number of degrees of freedom (ndof)
86 - number of particles in the group
88 ndof is utilized in calculating the temperature from the kinetic energy. setNDOF() changes it to any value
89 the user desires (the default is one!). In standard usage, the python interface queries the number of degrees
90 of freedom from the integrators and sets that value for each ComputeThermo so that it is always correct.
92 All quantities are made available for the logger. ComputerThermo can be given a suffix which it will append
93 to each quantity provided to the logger. Typical usage is to provide _groupname as the suffix so that properties
94 of different groups can be logged seperately (e.g. temperature_group1 and temperature_group2).
98 class ComputeThermo
: public Compute
101 //! Constructs the compute
102 ComputeThermo(boost::shared_ptr
<SystemDefinition
> sysdef
,
103 boost::shared_ptr
<ParticleGroup
> group
,
104 const std::string
& suffix
= std::string(""));
107 virtual ~ComputeThermo();
109 //! Compute the temperature
110 virtual void compute(unsigned int timestep
);
112 //! Change the number of degrees of freedom
113 void setNDOF(unsigned int ndof
);
115 //! Get the number of degrees of freedom
116 unsigned int getNDOF()
121 //! Returns the temperature last computed by compute()
122 /*! \returns Instantaneous temperature of the system
124 Scalar
getTemperature()
127 if (!m_properties_reduced
) reduceProperties();
129 ArrayHandle
<Scalar
> h_properties(m_properties
, access_location::host
, access_mode::read
);
130 return h_properties
.data
[thermo_index::temperature
];
133 //! Returns the pressure last computed by compute()
134 /*! \returns Instantaneous pressure of the system
138 // return NaN if the flags are not valid
139 PDataFlags flags
= m_pdata
->getFlags();
140 if (flags
[pdata_flag::isotropic_virial
])
142 // return the pressure
144 if (!m_properties_reduced
) reduceProperties();
147 ArrayHandle
<Scalar
> h_properties(m_properties
, access_location::host
, access_mode::read
);
148 return h_properties
.data
[thermo_index::pressure
];
152 return std::numeric_limits
<Scalar
>::quiet_NaN();
156 //! Returns the kinetic energy last computed by compute()
157 /*! \returns Instantaneous kinetic energy of the system
159 Scalar
getKineticEnergy()
162 if (!m_properties_reduced
) reduceProperties();
165 ArrayHandle
<Scalar
> h_properties(m_properties
, access_location::host
, access_mode::read
);
166 return h_properties
.data
[thermo_index::kinetic_energy
];
169 //! Returns the potential energy last computed by compute()
170 /*! \returns Instantaneous potential energy of the system, or NaN if the energy is not valid
172 Scalar
getPotentialEnergy()
175 if (!m_properties_reduced
) reduceProperties();
178 // return NaN if the flags are not valid
179 PDataFlags flags
= m_pdata
->getFlags();
180 if (flags
[pdata_flag::potential_energy
])
182 ArrayHandle
<Scalar
> h_properties(m_properties
, access_location::host
, access_mode::read
);
183 return h_properties
.data
[thermo_index::potential_energy
];
187 return std::numeric_limits
<Scalar
>::quiet_NaN();
191 //! Returns the upper triangular virial tensor last computed by compute()
192 /*! \returns Instantaneous virial tensor, or virial tensor containing NaN entries if it is
195 PressureTensor
getPressureTensor()
197 // return tensor of NaN's if flags are not valid
198 PDataFlags flags
= m_pdata
->getFlags();
200 if (flags
[pdata_flag::pressure_tensor
])
203 if (!m_properties_reduced
) reduceProperties();
206 ArrayHandle
<Scalar
> h_properties(m_properties
, access_location::host
, access_mode::read
);
208 p
.xx
= h_properties
.data
[thermo_index::pressure_xx
];
209 p
.xy
= h_properties
.data
[thermo_index::pressure_xy
];
210 p
.xz
= h_properties
.data
[thermo_index::pressure_xz
];
211 p
.yy
= h_properties
.data
[thermo_index::pressure_yy
];
212 p
.yz
= h_properties
.data
[thermo_index::pressure_yz
];
213 p
.zz
= h_properties
.data
[thermo_index::pressure_zz
];
217 p
.xx
= std::numeric_limits
<Scalar
>::quiet_NaN();
218 p
.xy
= std::numeric_limits
<Scalar
>::quiet_NaN();
219 p
.xz
= std::numeric_limits
<Scalar
>::quiet_NaN();
220 p
.yy
= std::numeric_limits
<Scalar
>::quiet_NaN();
221 p
.yz
= std::numeric_limits
<Scalar
>::quiet_NaN();
222 p
.zz
= std::numeric_limits
<Scalar
>::quiet_NaN();
227 //! Get the gpu array of properties
228 const GPUArray
<Scalar
>& getProperties()
231 if (!m_properties_reduced
) reduceProperties();
237 //! Returns a list of log quantities this compute calculates
238 virtual std::vector
< std::string
> getProvidedLogQuantities();
240 //! Calculates the requested log value and returns it
241 virtual Scalar
getLogValue(const std::string
& quantity
, unsigned int timestep
);
244 boost::shared_ptr
<ParticleGroup
> m_group
; //!< Group to compute properties for
245 GPUArray
<Scalar
> m_properties
; //!< Stores the computed properties
246 unsigned int m_ndof
; //!< Stores the number of degrees of freedom in the system
247 vector
<string
> m_logname_list
; //!< Cache all generated logged quantities names
249 //! Does the actual computation
250 virtual void computeProperties();
253 bool m_properties_reduced
; //!< True if properties have been reduced across MPI
255 //! Reduce properties over MPI
256 virtual void reduceProperties();
260 //! Exports the ComputeThermo class to python
261 void export_ComputeThermo();