24 #define MIN_DEBUG_LEVEL 1 29 void GlobalMasterSymmetry::parseMatrix(
int id,
char fileName []){
32 ifstream matrixFile (fileName);
33 if (! matrixFile.is_open()){
34 NAMD_err((std::string(
"Error opening symmetry matrix file ") + fileName).c_str());
36 while (!matrixFile.eof()){
38 for (
int i = 0; i < 4; i++){
39 getline(matrixFile, line);
40 istringstream iss(line);
41 copy(istream_iterator<string>(iss),
42 istream_iterator<string>(),
43 back_inserter<vector <string> >(tmp));
45 getline(matrixFile, line);
47 if (tmp.size() < 16){
NAMD_die(
"Error reading matrix file. Please check layout of the matrix file(s).");}
48 for(
int j = 0; j < 16; j++){
49 tmpmatrix.
mat[j] = atof(tmp[j].c_str());
52 matrices.push_back(tmpmatrix);
59 DebugM(3,
"initialize called\n");
71 if (!klist){
NAMD_die(
"A pdb file containing per-atom force constants must be specified if symmetryk is not in configuration file!");}
75 if (scaleForces && lastStep == -1){
76 NAMD_die(
"symmetryLastStep must be specified if symmetryScaleForces is enabled!");
81 if (!K) {symmetrykfile = klist->
data;}
82 for (; symmetryList; symmetryList = symmetryList->
next) {
86 if (klist){ symmetrykfile = klist->
data;}
90 map<int, vector<int> >::iterator it = simmap.begin();
91 if (!matrixList) {initialTransform();}
92 for (; matrixList; matrixList = matrixList->
next, ++it){
93 parseMatrix(it->first, matrixList->
data);
96 DebugM(1,
"done with initialize\n");
117 bool GlobalMasterSymmetry::gluInvertMatrix(
const BigReal m[16],
BigReal invOut[16])
122 inv[0] = m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15]
123 + m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10];
124 inv[4] = -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15]
125 - m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10];
126 inv[8] = m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15]
127 + m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9];
128 inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14]
129 - m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9];
130 inv[1] = -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15]
131 - m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10];
132 inv[5] = m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15]
133 + m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10];
134 inv[9] = -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15]
135 - m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9];
136 inv[13] = m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14]
137 + m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9];
138 inv[2] = m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15]
139 + m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6];
140 inv[6] = -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15]
141 - m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6];
142 inv[10] = m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15]
143 + m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5];
144 inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14]
145 - m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5];
146 inv[3] = -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11]
147 - m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6];
148 inv[7] = m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11]
149 + m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6];
150 inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11]
151 - m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5];
152 inv[15] = m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10]
153 + m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5];
155 det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12];
161 for (i = 0; i < 16; i++)
162 invOut[i] = inv[i] * det;
167 void GlobalMasterSymmetry::initialTransform(){
168 map<int, vector<int> >::iterator simit = simmap.begin();
170 for (; simit!=simmap.end(); ++simit){
171 map<int, vector<int> >::iterator fit = dmap.find(simit->second[0]);
173 for(
int i = 0; i < fit->second.size(); i++){
174 map<int, BigReal *>::iterator sit = posmap.find(fit->second[i]);
175 first[3*i] = sit->second[0];
176 first[3*i+1] = sit->second[1];
177 first[3*i+2] = sit->second[2];
180 map<int, vector<int> >::iterator it = dmap.begin();
181 for(; it != dmap.end(); ++it){
182 if (std::find(simit->second.begin(), simit->second.end(), it->first)!=simit->second.end()){
184 for (
int i = 0; i<it->second.size(); i++){
185 map<int, BigReal *>::iterator sit = posmap.find(it->second[i]);
186 arr[3*i] = sit->second[0];
187 arr[3*i+1] = sit->second[1];
188 arr[3*i+2] = sit->second[2];
190 BigReal ttt[16], pre[3], post[3];
193 for (j=0; j<3; j++) {
194 post[j] = ttt[4*j+3];
203 matrices.push_back(result);
211 for (
int i = 0; i < matrices.size(); i++) {
212 matrices[i].transpose();
218 matrices[i].transpose();
222 void GlobalMasterSymmetry::parseAtoms(
const char *file,
int numTotalAtoms,
int symfileindex) {
223 DebugM(3,
"parseAtoms called\n");
227 NAMD_die(
"No atoms found in symmetryFile\n");
229 iout <<
iWARN <<
"The number of atoms in symmetryFile is less than the total number of atoms in the structure.\n" <<
endi;
231 NAMD_die(
"The number of atoms in symmetryFile must not exceed the total number of atoms in the structure!");
236 tmdpdb.get_all_positions(atompos);
237 if (K){symmetrykfile = file;}
238 PDB kpdb(symmetrykfile);
242 #ifdef MEM_OPT_VERSION 243 PDBCoreData *atom = tmdpdb.atom(i);
245 PDBAtom *atom = tmdpdb.atom(i);
250 modifyRequestedAtoms().add(i);
252 #ifdef MEM_OPT_VERSION 253 PDBCoreData *atomk = kpdb.atom(i);
261 arr[0] = atompos[i].
x;
262 arr[1] = atompos[i].
y;
263 arr[2] = atompos[i].
z;
268 map <int, vector<int> >::iterator it = dmap.find((
int)atom->
temperaturefactor());
269 map <int, vector<int> >::iterator simit = simmap.find((
int)atom->
occupancy());
270 if (it != dmap.end()){
271 it->second.push_back(i);
276 if (simit != simmap.end()){
277 if (std::find(simit->second.begin(), simit->second.end(), atom->
temperaturefactor()) == simit->second.end()){
287 map <int, vector<int> >::iterator simit = simmap.begin();
288 for (; simit != simmap.end(); ++simit){
289 map <int, vector<int> >::iterator sit = dmap.find(simit->second[0]);
291 for (
int i = 0; i<simit->second.size(); i++){
292 map <int, vector<int> >::iterator fit = dmap.find(simit->second[i]);
293 if (fit->second.size() !=
numatoms){
294 NAMD_die(
"Every monomer must contain the same number of atoms!");
301 void GlobalMasterSymmetry::determineAverage() {
303 map <int, vector<BigReal *> >::iterator delit = averagePos.begin();
304 for (; delit != averagePos.end(); ++delit){
305 for (
int i = 0; i < delit->second.size(); i++){
306 delete [] delit->second[i];
308 delit->second.erase(delit->second.begin(), delit->second.end());
311 map <int, BigReal *>::iterator posit;
312 map <int, vector<int> >::iterator simit = simmap.begin();
313 for (; simit != simmap.end(); ++simit){
316 map <int, BigReal *>::iterator pit = posmap.begin();
317 for (; pit != posmap.end(); ++pit){
delete [] pit->second;}
320 map <int, vector<int> >::iterator dit = dmap.begin();
321 for (; dit!=dmap.end(); ++dit){
322 for (
int i = 0; i < dit->second.size(); i++){
323 if (std::find(simit->second.begin(), simit->second.end(), dit->first)!=simit->second.end()){
326 arr[0] = positions[dit->second[i]].x;
327 arr[1] = positions[dit->second[i]].y;
328 arr[2] = positions[dit->second[i]].z;
330 posmap[dit->second[i]] = arr;
334 averagePos[simit->first] = vector <BigReal *> ();
335 map <int, vector<int> >::iterator it = dmap.begin();
336 map <int, vector<int> >::iterator sit = dmap.find(simit->second[0]);
343 for (; it!=dmap.end(); ++it){
344 if (std::find(simit->second.begin(), simit->second.end(), it->first)!=simit->second.end()){
345 posit = posmap.find(it->second[i]);
346 matrices[(it->first)-1].multpoint(posit->second);
347 arr[0] += posit->second[0];
348 arr[1] += posit->second[1];
349 arr[2] += posit->second[2];
354 avg[0] = arr[0]/(simit->second.size());
355 avg[1] = arr[1]/(simit->second.size());
356 avg[2] = arr[2]/(simit->second.size());
357 averagePos[simit->first].push_back(avg);
365 void GlobalMasterSymmetry::backTransform(){
366 map <int, BigReal *>::iterator bit = backavg.begin();
367 for (; bit != backavg.end(); ++bit){
delete [] bit->second;}
370 map <int, vector<int> >::iterator it = dmap.begin();
371 for (; it!=dmap.end(); ++it){
372 map<int, int >::iterator bmit = bmap.find(it->first);
373 int bm = bmit->second;
374 map<int, vector <BigReal *> >::iterator avit = averagePos.find(bmit->second);
378 avg[3*i] = avit->second[i][0];
379 avg[3*i+1] = avit->second[i][1];
380 avg[3*i+2] = avit->second[i][2];
383 matrices[it->first-1].transpose();
384 gluInvertMatrix(matrices[it->first-1].mat, inverse);
387 matrices[it->first-1].transpose();
390 inv.multpoint(avg+3*k);
392 backavg[it->first] = avg;
397 map <int, BigReal *>::iterator pit = posmap.begin();
398 for (; pit != posmap.end(); ++pit){
delete pit->second;}
400 void GlobalMasterSymmetry::calculate() {
402 modifyAppliedForces().resize(0);
403 modifyForcedAtoms().resize(0);
406 if (currentStep < firstStep || (currentStep >= lastStep && lastStep != -1)) {
418 for ( ; a_i != a_e; ++a_i, ++p_i ){
419 positions[*a_i] = *p_i;
422 map <int, vector<int> >::iterator it;
446 for (it = dmap.begin(); it != dmap.end(); ++it){
450 for (
int i = 0; i < it->second.size(); i++){
451 curpos[3*i ] = positions[it->second[i]].x;
452 curpos[3*i+1] = positions[it->second[i]].y;
453 curpos[3*i+2] = positions[it->second[i]].z;
457 BigReal *tmpavg = backavg[it->first];
459 for (
int i=0; i<it->second.size(); i++) {
463 k = kdmap[it->first][it->second[i]];
466 k = K/it->second.size();
472 if (currentStep < firstFullStep){
474 (firstFullStep-firstStep);
475 frac = frac*(linear_evolve);
477 if (currentStep > lastFullStep)
480 (lastStep-lastFullStep);
481 frac = frac*(1-linear_evolve);
485 BigReal dx = curpos[3*i ] - tmpavg[3*i];
487 BigReal dy = curpos[3*i+1] - tmpavg[3*i+1];
488 BigReal dz = curpos[3*i+2] - tmpavg[3*i+2];
489 BigReal fvec[3] = { dx, dy, dz };
490 Vector force(fvec[0]*frac, fvec[1]*frac, fvec[2]*frac);
491 modifyForcedAtoms().add(it->second[i]);
492 modifyAppliedForces().add(force);
493 BigReal force2 = force.length2();
494 if ( force2 > maxforce2 ) maxforce2 = force2;
void NAMD_err(const char *err_msg)
void multmatrix(const Matrix4Symmetry &)
premultiply the matrix by the given matrix, this->other * this
BigReal temperaturefactor(void)
void translate(BigReal x, BigReal y, BigReal z)
SimParameters * simParameters
std::ostream & endi(std::ostream &s)
std::ostream & iWARN(std::ostream &s)
const AtomID * const_iterator
void NAMD_die(const char *err_msg)
BigReal MatrixFitRMS(int n, BigReal *v1, BigReal *v2, const BigReal *wt, BigReal *ttt)
int symmetryFirstFullStep
StringList * find(const char *name) const