10 #ifdef NODEGROUP_FORCE_REGISTER 12 ComputeSMDCUDA::ComputeSMDCUDA(
13 std::vector<HomePatch*> &patchList,
14 double springConstant,
15 double transverseSpringConstant,
24 this->patchList = &patchList;
25 this->springConstant = springConstant;
26 this->transverseSpringConstant = transverseSpringConstant;
27 this->velocity = velocity;
28 this->direction = direction;
29 this->outputFrequency = outputFrequency;
30 this->firstTimeStep = firstTimeStep;
31 this->filename = filename;
32 this->numAtoms = numAtoms;
33 smdAtomsGlobalIndex.clear();
35 allocate_host<double3>(&curCOM, 1);
38 smdAtomsSOAIndex.resize(this->numSMDAtoms);
39 allocate_device<unsigned int>(&d_tbcatomic, 1);
40 allocate_device<double3>(&d_curCOM, 1);
41 allocate_device<int>(&d_smdAtomsSOAIndex, this->numSMDAtoms);
46 copy_HtoD<double3>(curCOM, d_curCOM, 1);
47 cudaCheck(cudaMemset(d_tbcatomic, 0,
sizeof(
unsigned int)));
50 ComputeSMDCUDA::~ComputeSMDCUDA(){
51 deallocate_host<double3>(&curCOM);
52 deallocate_device<unsigned int>(&d_tbcatomic);
53 deallocate_device<int>(&d_smdAtomsSOAIndex);
57 void ComputeSMDCUDA::parseAtoms(){
59 origCOM.x = origCOM.y = origCOM.z = 0;
61 int numPDBAtoms = smdpdb.num_atoms();
62 if(numPDBAtoms < 1 )
NAMD_die(
"No Atoms found in SMDFile\n");
66 if (numPDBAtoms != this->numAtoms){
67 fprintf(stderr,
"Error, wrong numPDB (%d vs %d)\n",numPDBAtoms, this->numAtoms);
68 NAMD_die(
"The number of atoms in SMDFile must be equal to the total number of atoms in the structure!\n");
72 for(
int i = 0; i < numPDBAtoms; i++){
76 smdAtomsGlobalIndex.push_back(i);
80 origCOM.x += atom->
xcoor()*mass;
81 origCOM.y += atom->
ycoor()*mass;
82 origCOM.z += atom->
zcoor()*mass;
87 inv_group_mass = 1.0 / imass;
88 origCOM.x *= inv_group_mass;
89 origCOM.y *= inv_group_mass;
90 origCOM.z *= inv_group_mass;
93 NAMD_die(
"SMDFile contained no SMD atoms (atoms w/ nonzero occupancy)\n");
95 this->numSMDAtoms = smdAtomsGlobalIndex.size();
98 void ComputeSMDCUDA::updateAtoms(
99 std::vector<AtomMap*> &atomMapsList,
100 std::vector<CudaLocalRecord> &localRecords,
101 const int* h_globalToLocalID) {
103 for(
int i = 0 ; i < this->numSMDAtoms; i++){
104 int gid = smdAtomsGlobalIndex[i];
107 for(
int j = 0 ; j < atomMapsList.size(); j++){
108 lid = atomMapsList[j]->localID(gid);
109 if( lid.
pid != -1)
break;
115 NAMD_bug(
" LocalAtomID not found in patchMap");
118 int soaPid = h_globalToLocalID[lid.
pid];
119 int soaIndex = localRecords[soaPid].bufferOffset + lid.
index;
121 smdAtomsSOAIndex[i] = soaIndex;
124 std::sort(smdAtomsSOAIndex.begin(), smdAtomsSOAIndex.end());
125 copy_HtoD<int>(smdAtomsSOAIndex.data(), d_smdAtomsSOAIndex, this->numSMDAtoms);
128 void ComputeSMDCUDA::doForce(
133 const double* d_pos_x,
134 const double* d_pos_y,
135 const double* d_pos_z,
136 const char3* d_transform,
137 double* d_f_normal_x,
138 double* d_f_normal_y,
139 double* d_f_normal_z,
147 const int doOutput = (timeStep % this->outputFrequency) == 0;
150 this->inv_group_mass,
151 this->springConstant,
152 this->transverseSpringConstant,
155 doEnergy || doOutput,
167 this->d_smdAtomsSOAIndex,
179 cudaCheck(cudaStreamSynchronize(stream));
180 Vector p(curCOM->x, curCOM->y, curCOM->z);
181 Vector f(h_extForce->x, h_extForce->y, h_extForce->z);
182 if(timeStep % (100*this->outputFrequency) == 0) {
183 iout <<
"SMDTITLE: TS CURRENT_POSITION FORCE\n" <<
endi;
189 #endif // NODEGROUP_FORCE_REGISTER
std::ostream & endi(std::ostream &s)
Molecule stores the structural information for the system.
void NAMD_bug(const char *err_msg)
void NAMD_die(const char *err_msg)
Real atommass(int anum) const