Computes absolute mass-weighted harmonic restraints for atoms. More...
#include <HarmonicRestraintForce.h>
Public Member Functions | |
| HarmonicRestraintForce (void)=delete | |
| Prevents construction without an explicit positive atom count. | |
| HarmonicRestraintForce (const int numAtoms) | |
| Constructs a harmonic restraint for a fixed number of atoms. | |
| ~HarmonicRestraintForce (void) noexcept | |
| Destroys the private CUDA stream and releases owned resources. | |
| void | setSelection (const AtomSelection &selection) |
| Sets the atoms that may receive harmonic restraint constants. | |
| void | setForceConstant (const double forceConstant) |
| Sets one force constant for every currently selected atom. | |
| void | setForceConstants (const std::vector< double > &forceConstants) |
| Sets one force constant per atom. | |
| void | setReferenceCoordinates (const std::vector< double3 > &referenceCoordinates) |
| Sets one Cartesian reference position per atom. | |
| void | setReferenceCoordinates (const std::vector< std::vector< double > > &referenceCoordinates) |
| Sets reference positions from nested Cartesian rows. | |
| void | setMasses (const std::vector< double > &masses) |
| Sets the per-atom masses or restraint weights. | |
| std::shared_ptr< cudaStream_t > | getStream (void) |
| Returns shared access to the private CUDA stream holder. | |
| void | initialize (const int numAtoms, const std::vector< double > &boxDimensions) |
| Validates manager state and stores current box dimensions. | |
| void | clear (void) |
| Enqueues clearing of the force, energy, and virial output storage. | |
| void | calcForce (const float4 *xyzq, const bool calcEnergy, const bool calcVirial) |
| Enqueues harmonic force-array and optional energy accumulation. | |
| void | setBoxDimensions (const std::vector< double > &boxDimensions) |
| Stores the current orthogonal box lengths. | |
| std::shared_ptr< Force< AT > > | getForce (void) |
| Returns shared ownership of the device force-array storage. | |
| std::shared_ptr< CudaEnergyVirial > | getEnergyVirial (void) |
| Returns shared ownership of the energy-virial output object. | |
Static Public Attributes | |
| static constexpr bool | contributesVirial = false |
| Reports that this restraint does not contribute to virial aggregation. | |
Computes absolute mass-weighted harmonic restraints for atoms.
For atom i, the restraint stores an absolute reference position (x0_i, y0_i, z0_i), a non-negative force constant k_i, and a non-negative mass or weight m_i. Define the Cartesian displacement as:
The selected atoms contribute the following energy:
The device force array receives the following potential-gradient components:
apoCHARMM integration code subtracts this stored potential gradient, so the corresponding physical restoring force has the opposite sign. Contributions are accumulated atomically into the force and optional harm energy buffers.
Selection is implemented by setting the force constant of every unselected atom to zero. Current coordinates are read from a borrowed device float4 array; its w charge component is ignored. Reference coordinates and current coordinates are compared directly without minimum-image wrapping.
Construction allocates per-atom host/device parameter mirrors, one CUDA stream, one fixed-point force array, and one energy-virial object. Parameter setters copy caller data and perform synchronous host-to-device transfers. Force calculation and output clearing enqueue work on the private stream without synchronizing it before return.
| AT | Device force-accumulator representation. The library explicitly instantiates only long long int, using apoCHARMM's fixed-point force scale. |
| CT | Arithmetic representation used inside the restraint kernel. The library explicitly instantiates float and double. |
clear() before the first calculation and before any calculation that requires fresh rather than accumulated output.| HarmonicRestraintForce< AT, CT >::HarmonicRestraintForce | ( | const int | numAtoms | ) |
Constructs a harmonic restraint for a fixed number of atoms.
All atoms are initially selected. Force constants and reference coordinates are initialized to zero, per-atom weights are initialized to one, and the stored box dimensions are initialized to zero. Host and device parameter mirrors are coherent when construction succeeds.
The constructor also creates a private CUDA stream, allocates a Force<AT> with numAtoms active vectors, and creates a CudaEnergyVirial containing the named energy term harm. Output force and energy storage must be cleared before its first use.
| [in] | numAtoms | Dimensionless atom count. The value must be greater than zero and remains fixed for the lifetime of the restraint. |
| ApoCharmmError | With code ApoCharmmErrorCode::InvalidArgument if numAtoms is not positive. |
| ApoCharmmError | With code ApoCharmmErrorCode::Cuda if CUDA allocation, parameter initialization, force allocation, transfer, synchronization, or stream creation fails. |
| std::bad_alloc | If host storage, shared ownership state, or an error diagnostic cannot be allocated. |
| std::length_error | If requested host storage or an error diagnostic exceeds an implementation-defined limit. |
getForce()->size() == numAtoms. (0, 0, 0), and every weight is one.
|
noexcept |
Destroys the private CUDA stream and releases owned resources.
The underlying CUDA stream is destroyed without propagating cleanup failures. A std::shared_ptr<cudaStream_t> previously returned by getStream() may keep the host-side stream holder alive, but the stored CUDA stream value is set to nullptr during destruction.
Shared force and energy objects returned by getForce() and getEnergyVirial() may remain allocated while another shared owner exists. They no longer have an owning restraint capable of calculating into them.
| void HarmonicRestraintForce< AT, CT >::calcForce | ( | const float4 * | xyzq, |
| const bool | calcEnergy, | ||
| const bool | calcVirial | ||
| ) |
Enqueues harmonic force-array and optional energy accumulation.
One logical input record is read for each atom. Components x, y, and z are Cartesian coordinates in angstroms; w is ignored. Force-array contributions are always accumulated. The harm energy is accumulated only when calcEnergy is true.
The method launches one of four compile-time kernel variants on the private stream and performs only the immediate kernel-launch check. It does not synchronize the stream. Asynchronous execution errors can surface from a later CUDA synchronization or dependent operation.
| [in] | xyzq | Borrowed CUDA-device pointer to at least the fixed atom count of contiguous float4 records. The pointer may not be null and must remain valid until the enqueued kernel completes. |
| [in] | calcEnergy | true to atomically add the harmonic energy to the named harm device term; false to leave that energy term unchanged. |
| [in] | calcVirial | Accepted for the force-manager interface but ignored because this restraint does not currently calculate a virial contribution. |
| ApoCharmmError | With code ApoCharmmErrorCode::Cuda if CUDA reports an immediate kernel-launch failure. |
| std::bad_alloc | If construction of a CUDA failure diagnostic cannot allocate storage. |
| std::length_error | If a CUDA failure diagnostic exceeds an implementation-defined limit. |
xyzq addresses at least the fixed atom count of live device records. clear() first when fresh rather than accumulated output is required. getStream() but need not be complete. xyzq, output storage, parameter sizes, or stream state. | void HarmonicRestraintForce< AT, CT >::clear | ( | void | ) |
Enqueues clearing of the force, energy, and virial output storage.
Device clearing is enqueued on the restraint's private CUDA stream. The method does not synchronize that stream before return. The host buffer owned by CudaEnergyVirial is zeroed during the call.
Call this method before the first calculation and before every calculation that requires fresh output, because calcForce() atomically adds rather than replaces force and energy contributions.
| ApoCharmmError | With code ApoCharmmErrorCode::Cuda if output allocation, clearing, or immediate CUDA launch checking fails. |
| std::bad_alloc | If output or diagnostic storage cannot be allocated. |
| std::length_error | If output or diagnostic storage exceeds an implementation-defined limit. |
getStream() completes, the restraint force array and energy-virial device buffer are zero. | std::shared_ptr< CudaEnergyVirial > HarmonicRestraintForce< AT, CT >::getEnergyVirial | ( | void | ) |
Returns shared ownership of the energy-virial output object.
The object contains the named scalar energy term harm, in kilocalories per mole. The restraint does not populate a virial contribution. Device energy is accumulated by calcForce() only when energy calculation is requested.
No device-to-host transfer or stream synchronization is performed. CudaEnergyVirial::getEnergy("harm") reads the host mirror and therefore remains stale until the caller orders an appropriate copyToHost() and synchronization, or until a manager operation performs them.
| std::shared_ptr< Force< AT > > HarmonicRestraintForce< AT, CT >::getForce | ( | void | ) |
Returns shared ownership of the device force-array storage.
The force object contains the fixed atom count of vectors in structure-of-arrays form: X components begin at offset zero, Y components begin at stride(), and Z components begin at 2 * stride().
For the supported AT = long long int instantiations, values use apoCHARMM's fixed-point scale of 2^40. Divide each stored integer by 2^40 to recover the force-array quantity in kilocalories per mole per angstrom.
No transfer, clearing, or stream synchronization is performed.
clear(), calcForce(), and stream synchronization correctly. | std::shared_ptr< cudaStream_t > HarmonicRestraintForce< AT, CT >::getStream | ( | void | ) |
Returns shared access to the private CUDA stream holder.
The returned std::shared_ptr is a copied shared owner of the host scalar containing the CUDA stream handle. No stream synchronization is performed.
The restraint remains responsible for destroying the underlying CUDA stream. Its destructor writes nullptr into the shared scalar before releasing its own shared owner.
std::shared_ptr does not extend the lifetime of the underlying CUDA stream beyond restraint destruction. | void HarmonicRestraintForce< AT, CT >::initialize | ( | const int | numAtoms, |
| const std::vector< double > & | boxDimensions | ||
| ) |
Validates manager state and stores current box dimensions.
This method is the initialization hook used by ForceManager. It verifies that the manager atom count equals the immutable construction count and then delegates to setBoxDimensions().
The call does not allocate new per-atom storage, clear outputs, mark a separate initialized state, or alter reference coordinates. Direct native force calculation is not gated by a successful prior call, although manager-driven use calls this hook as part of subscription initialization.
| [in] | numAtoms | Dimensionless atom count supplied by the manager. It must equal the construction count. |
| [in] | boxDimensions | Three finite, positive box lengths in [x, y, z] order and angstrom units. |
| ApoCharmmError | With code ApoCharmmErrorCode::InvalidArgument if numAtoms differs from the fixed atom count or boxDimensions violates the box contract. |
| ApoCharmmError | With code ApoCharmmErrorCode::Cuda if a changed box cannot be transferred or synchronized. |
| std::bad_alloc | If box copying or diagnostic construction cannot allocate storage. |
| std::length_error | If box storage or an error diagnostic exceeds an implementation-defined limit. |
boxDimensions. | void HarmonicRestraintForce< AT, CT >::setBoxDimensions | ( | const std::vector< double > & | boxDimensions | ) |
Stores the current orthogonal box lengths.
The vector must contain [x, y, z] box lengths in angstroms. When all three values exactly equal the stored values, the method returns without a transfer. Otherwise, the vector is copied into the host mirror and then transferred to the device with a device-wide CUDA synchronization.
The current force kernel does not read these dimensions, apply minimum-image displacement, or rescale stored reference positions.
| [in] | boxDimensions | Host vector containing exactly three finite, strictly positive lengths in [x, y, z] order and angstrom units. The vector is borrowed for the call and is not retained. |
| ApoCharmmError | With code ApoCharmmErrorCode::InvalidArgument if the vector does not contain exactly three values or any value is non-positive, NaN, or infinite. |
| ApoCharmmError | With code ApoCharmmErrorCode::Cuda if copying or synchronizing a changed box fails. |
| std::bad_alloc | If host copying or diagnostic construction cannot allocate storage. |
| std::length_error | If host storage or an error diagnostic exceeds an implementation-defined limit. |
boxDimensions. | void HarmonicRestraintForce< AT, CT >::setForceConstant | ( | const double | forceConstant | ) |
Sets one force constant for every currently selected atom.
The method first sets every per-atom force constant to zero and then assigns forceConstant to the selected atoms. Unselected atoms therefore remain disabled.
With weights supplied in atomic mass units, forceConstant has units of kilocalories per mole per square angstrom per atomic mass unit. When every weight is one, its numerical effect is the ordinary per-atom harmonic constant in kilocalories per mole per square angstrom.
| [in] | forceConstant | Finite, non-negative force constant applied to every selected atom. |
| ApoCharmmError | With code ApoCharmmErrorCode::InvalidArgument if forceConstant is negative, NaN, or infinite. |
| ApoCharmmError | With code ApoCharmmErrorCode::Cuda if clearing, transferring, or synchronizing force constants fails. |
| std::bad_alloc | If selected-index storage or an error diagnostic cannot be allocated. |
| std::length_error | If selected-index storage or a diagnostic exceeds an implementation-defined limit. |
forceConstant and all other atoms have zero force constants. | void HarmonicRestraintForce< AT, CT >::setForceConstants | ( | const std::vector< double > & | forceConstants | ) |
Sets one force constant per atom.
The vector is indexed in atom order and must contain exactly one value for every atom. Only values belonging to currently selected atoms are validated and used. Values at unselected indices are ignored, and the corresponding stored constants are set to zero.
With weights supplied in atomic mass units, each selected value has units of kilocalories per mole per square angstrom per atomic mass unit.
| [in] | forceConstants | Contiguous host vector in atom order. Its length must equal the fixed atom count. Every selected value must be finite and non-negative. The vector is borrowed for the call and is not retained. |
| ApoCharmmError | With code ApoCharmmErrorCode::InvalidArgument if the vector length differs from the atom count or a selected value is negative, NaN, or infinite. |
| ApoCharmmError | With code ApoCharmmErrorCode::Cuda if clearing, transferring, or synchronizing force constants fails. |
| std::bad_alloc | If selected-index storage or diagnostic construction cannot allocate storage. |
| std::length_error | If selected-index storage or a diagnostic exceeds an implementation-defined limit. |
| void HarmonicRestraintForce< AT, CT >::setMasses | ( | const std::vector< double > & | masses | ) |
Sets the per-atom masses or restraint weights.
Each value is stored in component w of the corresponding reference double4. Existing reference-position components are preserved. The complete reference array is transferred to device memory, followed by a device-wide CUDA synchronization.
A zero value is accepted and suppresses the harmonic energy and force-array contribution for that atom, even when the atom is selected and has a nonzero force constant.
| [in] | masses | Contiguous host vector containing exactly one finite, non-negative value per atom, normally in atomic mass units. The vector is borrowed for the call and is not retained. |
| ApoCharmmError | With code ApoCharmmErrorCode::InvalidArgument if the vector length differs from the atom count or any value is negative, NaN, or infinite. |
| ApoCharmmError | With code ApoCharmmErrorCode::Cuda if the host-to-device transfer or synchronization fails. |
| std::bad_alloc | If an error diagnostic cannot be allocated. |
| std::length_error | If an error diagnostic exceeds an implementation-defined limit. |
masses and all reference-position components are preserved. | void HarmonicRestraintForce< AT, CT >::setReferenceCoordinates | ( | const std::vector< double3 > & | referenceCoordinates | ) |
Sets one Cartesian reference position per atom.
Components x, y, and z are copied into the host reference mirror in atom order. The existing per-atom mass or weight stored in component w is preserved. The complete double4 reference array is then transferred to device memory, followed by a device-wide CUDA synchronization.
Reference positions are absolute. They are not wrapped, imaged, or rescaled when box dimensions change.
| [in] | referenceCoordinates | Contiguous host vector containing exactly one finite double3 position per atom, in angstroms. The vector is borrowed for the call and is not retained. |
| ApoCharmmError | With code ApoCharmmErrorCode::InvalidArgument if the vector length differs from the atom count or any Cartesian component is NaN or infinite. |
| ApoCharmmError | With code ApoCharmmErrorCode::Cuda if the host-to-device transfer or synchronization fails. |
| std::bad_alloc | If an error diagnostic cannot be allocated. |
| std::length_error | If an error diagnostic exceeds an implementation-defined limit. |
| void HarmonicRestraintForce< AT, CT >::setReferenceCoordinates | ( | const std::vector< std::vector< double > > & | referenceCoordinates | ) |
Sets reference positions from nested Cartesian rows.
The outer vector must contain one row per atom. Every row must contain exactly three values in [x, y, z] order and angstrom units. The method copies the rows into a temporary double3 vector and delegates to the primary reference-coordinate setter.
| [in] | referenceCoordinates | Host rows in atom order. The outer vector must have the fixed atom count, and every row must have exactly three finite values. No caller storage is retained. |
| ApoCharmmError | With code ApoCharmmErrorCode::InvalidArgument if the row count differs from the atom count, a row does not have exactly three values, or a Cartesian value is NaN or infinite. |
| ApoCharmmError | With code ApoCharmmErrorCode::Cuda if the delegated host-to-device transfer or synchronization fails. |
| std::bad_alloc | If the temporary coordinate vector or an error diagnostic cannot be allocated. |
| std::length_error | If temporary storage or an error diagnostic exceeds an implementation-defined limit. |
double3 overload with the converted rows. | void HarmonicRestraintForce< AT, CT >::setSelection | ( | const AtomSelection & | selection | ) |
Sets the atoms that may receive harmonic restraint constants.
The selection is copied and is not retained. Every atom that is unselected by the new value has its stored force constant set to zero. Selecting an atom does not restore a force constant that was zeroed by an earlier selection change; call setForceConstant() or setForceConstants() after expanding a selection.
Updated force constants are transferred from host to device, followed by a device-wide CUDA synchronization.
| [in] | selection | Selection with exactly the restraint's fixed atom count. The object is borrowed for the call and remains unchanged. |
| ApoCharmmError | With code ApoCharmmErrorCode::InvalidArgument if the represented atom count differs from the restraint atom count. |
| ApoCharmmError | With code ApoCharmmErrorCode::Cuda if the force-constant transfer or synchronization fails. |
| std::bad_alloc | If selection copying or diagnostic construction cannot allocate storage. |
| std::length_error | If copied selection storage or a diagnostic exceeds an implementation-defined limit. |
selection and every unselected atom has a zero force constant.