9 #ifdef NODEGROUP_FORCE_REGISTER 15 inv_group1_mass = 0.0;
16 inv_group2_mass = 0.0;
19 numRestrainedGroup1 = group1Index.size();
20 numRestrainedGroup2 = group2Index.size();
21 totalNumRestrained = numRestrainedGroup1 + numRestrainedGroup2;
24 calcGroup1COM = (numRestrainedGroup1 ? true :
false);
27 groupAtomsSOAIndex.resize(totalNumRestrained);
35 allocate_host<double>(&h_resEnergy, 1);
36 allocate_host<double3>(&h_diffCOM, 1);
37 allocate_host<double3>(&h_group1COM, 1);
38 allocate_host<double3>(&h_group2COM, 1);
39 allocate_host<double3>(&h_resForce, 1);
40 allocate_device<double3>(&d_group1COM, 1);
41 allocate_device<double3>(&d_group2COM, 1);
42 allocate_device<int>(&d_groupAtomsSOAIndex, totalNumRestrained);
43 allocate_device<unsigned int>(&d_tbcatomic, 1);
45 cudaCheck(cudaMemset(d_tbcatomic, 0,
sizeof(
unsigned int)));
50 double total_mass = 0.0;
52 for (
int i = 0; i < numRestrainedGroup2; ++i) {
53 int index = group2Index[i];
54 if (index > -1 && index < totalAtoms) {
58 sprintf(err_msg,
"Group restraints: Bad atom index for %s!" 59 " Atom indices must be within [%d, %d].\n", groupName, 0, totalAtoms - 1);
63 inv_group2_mass = 1.0 / total_mass;
69 for (
int i = 0; i < numRestrainedGroup1; ++i) {
70 int index = group1Index[i];
71 if (index > -1 && index < totalAtoms) {
75 sprintf(err_msg,
"Group restraints: Bad atom index for %s!" 76 " Atom indices must be within [%d, %d].\n", groupName, 0, totalAtoms - 1);
80 inv_group1_mass = 1.0 / total_mass;
86 h_group1COM->
x = ref.
x;
87 h_group1COM->y = ref.
y;
88 h_group1COM->z = ref.
z;
92 GroupRestraintsCUDA::~GroupRestraintsCUDA() {
93 deallocate_host<double>(&h_resEnergy);
94 deallocate_host<double3>(&h_resForce);
95 deallocate_host<double3>(&h_diffCOM);
96 deallocate_host<double3>(&h_group1COM);
97 deallocate_host<double3>(&h_group2COM);
98 deallocate_device<double3>(&d_group1COM);
99 deallocate_device<double3>(&d_group2COM);
100 deallocate_device<int>(&d_groupAtomsSOAIndex);
101 deallocate_device<unsigned int>(&d_tbcatomic);
105 void GroupRestraintsCUDA::updateAtoms(
106 std::vector<AtomMap*> &atomMapsList,
107 std::vector<CudaLocalRecord> &localRecords,
108 const int *h_globalToLocalID) {
113 const std::vector<int> &group1Index = resParam->GetGroup1AtomIndex();
114 if(numRestrainedGroup1 != group1Index.size()) {
116 sprintf(
"Number of atoms in group 1 restraint for '%s' is changed!", groupName);
121 for(
int i = 0 ; i < numRestrainedGroup1; ++i){
122 int gid = group1Index[i];
125 for(
int j = 0 ; j < atomMapsList.size(); ++j){
126 lid = atomMapsList[j]->localID(gid);
135 NAMD_bug(
"LocalAtomID not found in patchMap");
139 int soaPid = h_globalToLocalID[lid.
pid];
140 int soaIndex = localRecords[soaPid].bufferOffset + lid.
index;
142 groupAtomsSOAIndex[i] = soaIndex;
145 std::sort(groupAtomsSOAIndex.begin(), groupAtomsSOAIndex.begin() + numRestrainedGroup1);
150 const std::vector<int> &group2Index = resParam->GetGroup2AtomIndex();
151 if(numRestrainedGroup2 != group2Index.size()) {
153 sprintf(
"Number of atoms in group 2 restraint for '%s' is changed!", groupName);
158 for(
int i = 0 ; i < numRestrainedGroup2; ++i){
159 int gid = group2Index[i];
162 for(
int j = 0 ; j < atomMapsList.size(); ++j){
163 lid = atomMapsList[j]->localID(gid);
172 NAMD_bug(
"LocalAtomID not found in patchMap");
176 int soaPid = h_globalToLocalID[lid.
pid];
177 int soaIndex = localRecords[soaPid].bufferOffset + lid.
index;
179 groupAtomsSOAIndex[i + numRestrainedGroup1] = soaIndex;
182 std::sort(groupAtomsSOAIndex.begin() + numRestrainedGroup1, groupAtomsSOAIndex.end());
185 copy_HtoD<int>(groupAtomsSOAIndex.data(), d_groupAtomsSOAIndex, totalNumRestrained);
189 void GroupRestraintsCUDA::doForce(
195 const char3* d_transform,
197 const double* d_pos_x,
198 const double* d_pos_y,
199 const double* d_pos_z,
200 double* d_f_normal_x,
201 double* d_f_normal_y,
202 double* d_f_normal_z,
207 cudaStream_t stream) {
210 computeGroupRestraint_2Group(
214 this->numRestrainedGroup1,
215 this->totalNumRestrained,
220 this->inv_group1_mass,
221 this->inv_group2_mass,
222 this->d_groupAtomsSOAIndex,
244 computeGroupRestraint_1Group(
248 this->numRestrainedGroup2,
253 this->inv_group2_mass,
254 this->d_groupAtomsSOAIndex,
278 cudaCheck(cudaStreamSynchronize(stream));
280 h_extEnergy[0] += h_resEnergy[0];
283 if (!calcGroup1COM) {
284 h_extForce->x += h_resForce->x;
285 h_extForce->y += h_resForce->y;
286 h_extForce->z += h_resForce->z;
290 sprintf(msg,
"GRES: %9d %14s %14.4f %14.4f %14.4f %19.4f %14.4f %14.4f %14.4f\n",
291 timeStep, groupName, h_diffCOM->x, h_diffCOM->y, h_diffCOM->z,
292 h_resForce->x, h_resForce->y, h_resForce->z, h_resEnergy[0]);
310 ComputeGroupRestraintsCUDA::ComputeGroupRestraintsCUDA(
const int ouputFreq,
312 gResOutputFreq = ouputFreq;
313 const std::map<std::string, GroupRestraintParam*> & groupMap = resList.
GetGroupResMap();
314 for (
auto it = groupMap.begin(); it != groupMap.end(); ++it) {
315 GroupRestraintsCUDA * gResCUDA =
new GroupRestraintsCUDA(it->second);
316 restraintsCUDAList.push_back(gResCUDA);
320 ComputeGroupRestraintsCUDA::~ComputeGroupRestraintsCUDA() {
321 int numGroup = restraintsCUDAList.size();
322 for (
int i = 0; i < numGroup; ++i) {
323 delete restraintsCUDAList[i];
325 restraintsCUDAList.clear();
329 void ComputeGroupRestraintsCUDA::updateAtoms(
330 std::vector<AtomMap*> &atomMapsList,
331 std::vector<CudaLocalRecord> &localRecords,
332 const int *h_globalToLocalID) {
334 int numGroup = restraintsCUDAList.size();
335 for (
int i = 0; i < numGroup; ++i) {
336 restraintsCUDAList[i]->updateAtoms(atomMapsList, localRecords, h_globalToLocalID);
341 void ComputeGroupRestraintsCUDA::doForce(
346 const char3* d_transform,
348 const double* d_pos_x,
349 const double* d_pos_y,
350 const double* d_pos_z,
351 double* d_f_normal_x,
352 double* d_f_normal_y,
353 double* d_f_normal_z,
358 cudaStream_t stream) {
360 const int doOutput = (timeStep % gResOutputFreq) == 0;
363 int doVirCalc = (doOutput ? 1 : doVirial);
364 int numGroup = restraintsCUDAList.size();
368 h_extEnergy[0] = 0.0;
372 h_extVirial->
xx = 0.0;
373 h_extVirial->
xy = 0.0;
374 h_extVirial->
xz = 0.0;
375 h_extVirial->
yx = 0.0;
376 h_extVirial->
yy = 0.0;
377 h_extVirial->
yz = 0.0;
378 h_extVirial->
zx = 0.0;
379 h_extVirial->
zy = 0.0;
380 h_extVirial->
zz = 0.0;
383 if(timeStep % (100 * gResOutputFreq) == 0) {
385 sprintf(msg,
"\nGRES_TITLE: %3s %14s %14s %14s %14s %19s %14s %14s %14s\n",
386 "TS",
"GROUP_NAME",
"DISTANCE.X",
"DISTANCE.Y",
"DISTANCE.Z",
387 "FORCE.X",
"FORCE.Y",
"FORCE.Z",
"ENERGY");
392 for (
int gIdx = 0; gIdx < numGroup; ++gIdx) {
393 restraintsCUDAList[gIdx]->doForce(
394 timeStep, doEnergy, doVirCalc, doOutput, lat, d_transform,
395 d_mass, d_pos_x, d_pos_y, d_pos_z,
396 d_f_normal_x, d_f_normal_y, d_f_normal_z, d_virial,
397 h_extEnergy, h_extForce, h_extVirial, stream);
std::ostream & endi(std::ostream &s)
Molecule stores the structural information for the system.
const std::map< std::string, GroupRestraintParam * > & GetGroupResMap() const
Vector GetGroupRes1Position() const
Vector GetResDirection() const
NAMD_HOST_DEVICE double3 make_double3(float3 a)
void NAMD_bug(const char *err_msg)
const char * GetGroupName() const
void NAMD_die(const char *err_msg)
Real atommass(int anum) const
Vector GetResCenter() const
const std::vector< int > & GetGroup2AtomIndex() const
bool GetUseDistMagnitude() const
const std::vector< int > & GetGroup1AtomIndex() const