1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * GROwing Monsters And Cloning Shrimps
56 #include "mtop_util.h"
58 #include "mpelogging.h"
60 #include "groupcoord.h"
63 /* We use the same defines as in mvdata.c here */
64 #define block_bc(cr, d) gmx_bcast( sizeof(d), &(d),(cr))
65 #define nblock_bc(cr,nr,d) gmx_bcast((nr)*sizeof((d)[0]), (d),(cr))
66 #define snew_bc(cr,d,nr) { if (!MASTER(cr)) snew((d),(nr)); }
69 /* enum to identify the type of ED: none, normal ED, flooding */
70 enum {eEDnone
, eEDedsam
, eEDflood
, eEDnr
};
72 /* enum to identify operations on reference, average, origin, target structures */
73 enum {eedREF
, eedAV
, eedORI
, eedTAR
, eedNR
};
78 int neig
; /* nr of eigenvectors */
79 int *ieig
; /* index nrs of eigenvectors */
80 real
*stpsz
; /* stepsizes (per eigenvector) */
81 rvec
**vec
; /* eigenvector components */
82 real
*xproj
; /* instantaneous x projections */
83 real
*fproj
; /* instantaneous f projections */
84 real
*refproj
; /* starting or target projecions */
85 real radius
; /* instantaneous radius */
91 t_eigvec mon
; /* only monitored, no constraints */
92 t_eigvec linfix
; /* fixed linear constraints */
93 t_eigvec linacc
; /* acceptance linear constraints */
94 t_eigvec radfix
; /* fixed radial constraints (exp) */
95 t_eigvec radacc
; /* acceptance radial constraints (exp) */
96 t_eigvec radcon
; /* acceptance rad. contraction constr. */
103 bool bHarmonic
; /* Use flooding for harmonic restraint on eigenvector */
113 rvec
*forces_cartesian
;
114 t_eigvec vecs
; /* use flooding for these */
118 /* This type is for the average, reference, target, and origin structure */
119 typedef struct gmx_edx
121 int nr
; /* number of atoms this structure contains */
122 int nr_loc
; /* number of atoms on local node */
123 int *anrs
; /* atom index numbers */
124 int *anrs_loc
; /* local atom index numbers */
125 int nalloc_loc
; /* allocation size of anrs_loc */
126 int *c_ind
; /* at which position of the whole anrs
127 * array is a local atom?, i.e.
128 * c_ind[0...nr_loc-1] gives the atom index
129 * with respect to the collective
130 * anrs[0...nr-1] array */
131 rvec
*x
; /* positions for this structure */
132 rvec
*x_old
; /* used to keep track of the shift vectors
133 such that the ED molecule can always be
134 made whole in the parallel case */
135 real
*m
; /* masses */
136 real mtot
; /* total mass (only used in sref) */
137 real
*sqrtm
; /* sqrt of the masses used for mass-
138 * weighting of analysis (only used in sav) */
144 int nini
; /* total Nr of atoms */
145 bool fitmas
; /* true if trans fit with cm */
146 bool pcamas
; /* true if mass-weighted PCA */
147 int presteps
; /* number of steps to run without any
148 * perturbations ... just monitoring */
149 int outfrq
; /* freq (in steps) of writing to edo */
150 int maxedsteps
; /* max nr of steps per cycle */
152 /* all gmx_edx datasets are copied to all nodes in the parallel case */
153 struct gmx_edx sref
; /* reference positions, to these fitting
155 bool bRefEqAv
; /* If true, reference & average indices
156 * are the same. Used for optimization */
157 struct gmx_edx sav
; /* average positions */
158 struct gmx_edx star
; /* target positions */
159 struct gmx_edx sori
; /* origin positions */
161 t_edvecs vecs
; /* eigenvectors */
162 real slope
; /* minimal slope in acceptance radexp */
164 bool bNeedDoEdsam
; /* if any of the options mon, linfix, ...
165 * is used (i.e. apart from flooding) */
166 t_edflood flood
; /* parameters especially for flooding */
167 struct t_ed_buffer
*buf
; /* handle to local buffers */
168 struct edpar
*next_edi
; /* Pointer to another ed dataset */
172 typedef struct gmx_edsam
174 int eEDtype
; /* Type of ED: see enums above */
175 const char *edinam
; /* name of ED sampling input file */
176 const char *edonam
; /* output */
177 FILE *edo
; /* output file pointer */
187 rvec old_transvec
,older_transvec
,transvec_compact
;
188 rvec
*xcoll
; /* Positions from all nodes, this is the
189 collective set we work on.
190 These are the positions of atoms with
191 average structure indices */
192 rvec
*xc_ref
; /* same but with reference structure indices */
193 ivec
*shifts_xcoll
; /* Shifts for xcoll */
194 ivec
*extra_shifts_xcoll
; /* xcoll shift changes since last NS step */
195 ivec
*shifts_xc_ref
; /* Shifts for xc_ref */
196 ivec
*extra_shifts_xc_ref
; /* xc_ref shift changes since last NS step */
197 bool bUpdateShifts
; /* TRUE in NS steps to indicate that the
198 ED shifts for this ED dataset need to
203 /* definition of ED buffer structure */
206 struct t_fit_to_ref
* fit_to_ref
;
207 struct t_do_edfit
* do_edfit
;
208 struct t_do_edsam
* do_edsam
;
209 struct t_do_radcon
* do_radcon
;
213 /* Function declarations */
214 static void fit_to_reference(rvec
*xcoll
,rvec transvec
,matrix rotmat
,t_edpar
*edi
);
216 static void translate_and_rotate(rvec
*x
,int nat
,rvec transvec
,matrix rotmat
);
217 /* End function declarations */
220 /* Does not subtract average positions, projection on single eigenvector is returned
221 * used by: do_linfix, do_linacc, do_radfix, do_radacc, do_radcon
222 * Average position is subtracted in ed_apply_constraints prior to calling projectx
224 static real
projectx(t_edpar
*edi
, rvec
*xcoll
, rvec
*vec
)
230 for (i
=0; i
<edi
->sav
.nr
; i
++)
231 proj
+= edi
->sav
.sqrtm
[i
]*iprod(vec
[i
], xcoll
[i
]);
237 /* Specialized: projection is stored in vec->refproj
238 * -> used for radacc, radfix, radcon and center of flooding potential
239 * subtracts average positions, projects vector x */
240 static void rad_project(t_edpar
*edi
, rvec
*x
, t_eigvec
*vec
, t_commrec
*cr
)
245 /* Subtract average positions */
246 for (i
= 0; i
< edi
->sav
.nr
; i
++)
247 rvec_dec(x
[i
], edi
->sav
.x
[i
]);
249 for (i
= 0; i
< vec
->neig
; i
++)
251 vec
->refproj
[i
] = projectx(edi
,x
,vec
->vec
[i
]);
252 rad
+= pow((vec
->refproj
[i
]-vec
->xproj
[i
]),2);
254 vec
->radius
=sqrt(rad
);
256 /* Add average positions */
257 for (i
= 0; i
< edi
->sav
.nr
; i
++)
258 rvec_inc(x
[i
], edi
->sav
.x
[i
]);
262 /* Project vector x, subtract average positions prior to projection and add
263 * them afterwards to retain the unchanged vector. Store in xproj. Mass-weighting
265 static void project_to_eigvectors(rvec
*x
, /* The positions to project to an eigenvector */
266 t_eigvec
*vec
, /* The eigenvectors */
272 if (!vec
->neig
) return;
274 /* Subtract average positions */
275 for (i
=0; i
<edi
->sav
.nr
; i
++)
276 rvec_dec(x
[i
], edi
->sav
.x
[i
]);
278 for (i
=0; i
<vec
->neig
; i
++)
279 vec
->xproj
[i
] = projectx(edi
, x
, vec
->vec
[i
]);
281 /* Add average positions */
282 for (i
=0; i
<edi
->sav
.nr
; i
++)
283 rvec_inc(x
[i
], edi
->sav
.x
[i
]);
287 /* Project vector x onto all edi->vecs (mon, linfix,...) */
288 static void project(rvec
*x
, /* positions to project */
289 t_edpar
*edi
) /* edi data set */
291 /* It is not more work to subtract the average position in every s
292 * ubroutine again, because these routines are rarely used simultanely */
293 project_to_eigvectors(x
, &edi
->vecs
.mon
, edi
);
294 project_to_eigvectors(x
, &edi
->vecs
.linfix
, edi
);
295 project_to_eigvectors(x
, &edi
->vecs
.linacc
, edi
);
296 project_to_eigvectors(x
, &edi
->vecs
.radfix
, edi
);
297 project_to_eigvectors(x
, &edi
->vecs
.radacc
, edi
);
298 project_to_eigvectors(x
, &edi
->vecs
.radcon
, edi
);
302 static real
calc_radius(t_eigvec
*vec
)
308 for (i
=0; i
<vec
->neig
; i
++)
309 rad
+= pow((vec
->refproj
[i
]-vec
->xproj
[i
]),2);
311 return rad
=sqrt(rad
);
317 static void dump_xcoll(t_edpar
*edi
, struct t_do_edsam
*buf
, t_commrec
*cr
,
324 ivec
*shifts
, *eshifts
;
331 shifts
= buf
->shifts_xcoll
;
332 eshifts
= buf
->extra_shifts_xcoll
;
334 sprintf(fn
, "xcolldump_step%d.txt", step
);
337 for (i
=0; i
<edi
->sav
.nr
; i
++)
338 fprintf(fp
, "%d %9.5f %9.5f %9.5f %d %d %d %d %d %d\n",
340 xcoll
[i
][XX
] , xcoll
[i
][YY
] , xcoll
[i
][ZZ
],
341 shifts
[i
][XX
] , shifts
[i
][YY
] , shifts
[i
][ZZ
],
342 eshifts
[i
][XX
], eshifts
[i
][YY
], eshifts
[i
][ZZ
]);
349 static void dump_edi_positions(FILE *out
, struct gmx_edx
*s
, const char name
[])
354 fprintf(out
, "#%s positions:\n%d\n", name
, s
->nr
);
358 fprintf(out
, "#index, x, y, z");
360 fprintf(out
, ", sqrt(m)");
361 for (i
=0; i
<s
->nr
; i
++)
363 fprintf(out
, "\n%6d %11.6f %11.6f %11.6f",s
->anrs
[i
], s
->x
[i
][XX
], s
->x
[i
][YY
], s
->x
[i
][ZZ
]);
365 fprintf(out
,"%9.3f",s
->sqrtm
[i
]);
372 static void dump_edi_eigenvecs(FILE *out
, t_eigvec
*ev
,
373 const char name
[], int length
)
378 fprintf(out
, "#%s eigenvectors:\n%d\n", name
, ev
->neig
);
379 /* Dump the data for every eigenvector: */
380 for (i
=0; i
<ev
->neig
; i
++)
382 fprintf(out
, "EV %4d\ncomponents %d\nstepsize %f\nxproj %f\nfproj %f\nrefproj %f\nradius %f\nComponents:\n",
383 ev
->ieig
[i
], length
, ev
->stpsz
[i
], ev
->xproj
[i
], ev
->fproj
[i
], ev
->refproj
[i
], ev
->radius
);
384 for (j
=0; j
<length
; j
++)
385 fprintf(out
, "%11.6f %11.6f %11.6f\n", ev
->vec
[i
][j
][XX
], ev
->vec
[i
][j
][YY
], ev
->vec
[i
][j
][ZZ
]);
391 static void dump_edi(t_edpar
*edpars
, t_commrec
*cr
, int nr_edi
)
397 sprintf(fn
, "EDdump_node%d_edi%d", cr
->nodeid
, nr_edi
);
398 out
= ffopen(fn
, "w");
400 fprintf(out
,"#NINI\n %d\n#FITMAS\n %d\n#ANALYSIS_MAS\n %d\n",
401 edpars
->nini
,edpars
->fitmas
,edpars
->pcamas
);
402 fprintf(out
,"#OUTFRQ\n %d\n#MAXLEN\n %d\n#SLOPECRIT\n %f\n",
403 edpars
->outfrq
,edpars
->maxedsteps
,edpars
->slope
);
404 fprintf(out
,"#PRESTEPS\n %d\n#DELTA_F0\n %f\n#TAU\n %f\n#EFL_NULL\n %f\n#ALPHA2\n %f\n",
405 edpars
->presteps
,edpars
->flood
.deltaF0
,edpars
->flood
.tau
,
406 edpars
->flood
.constEfl
,edpars
->flood
.alpha2
);
408 /* Dump reference, average, target, origin positions */
409 dump_edi_positions(out
, &edpars
->sref
, "REFERENCE");
410 dump_edi_positions(out
, &edpars
->sav
, "AVERAGE" );
411 dump_edi_positions(out
, &edpars
->star
, "TARGET" );
412 dump_edi_positions(out
, &edpars
->sori
, "ORIGIN" );
414 /* Dump eigenvectors */
415 dump_edi_eigenvecs(out
, &edpars
->vecs
.mon
, "MONITORED", edpars
->sav
.nr
);
416 dump_edi_eigenvecs(out
, &edpars
->vecs
.linfix
, "LINFIX" , edpars
->sav
.nr
);
417 dump_edi_eigenvecs(out
, &edpars
->vecs
.linacc
, "LINACC" , edpars
->sav
.nr
);
418 dump_edi_eigenvecs(out
, &edpars
->vecs
.radfix
, "RADFIX" , edpars
->sav
.nr
);
419 dump_edi_eigenvecs(out
, &edpars
->vecs
.radacc
, "RADACC" , edpars
->sav
.nr
);
420 dump_edi_eigenvecs(out
, &edpars
->vecs
.radcon
, "RADCON" , edpars
->sav
.nr
);
422 /* Dump flooding eigenvectors */
423 dump_edi_eigenvecs(out
, &edpars
->flood
.vecs
, "FLOODING" , edpars
->sav
.nr
);
425 /* Dump ed local buffer */
426 fprintf(out
, "buf->do_edfit =%p\n", (void*)edpars
->buf
->do_edfit
);
427 fprintf(out
, "buf->do_edsam =%p\n", (void*)edpars
->buf
->do_edsam
);
428 fprintf(out
, "buf->do_radcon =%p\n", (void*)edpars
->buf
->do_radcon
);
435 static void dump_rotmat(FILE* out
,matrix rotmat
)
437 fprintf(out
,"ROTMAT: %12.8f %12.8f %12.8f\n",rotmat
[XX
][XX
],rotmat
[XX
][YY
],rotmat
[XX
][ZZ
]);
438 fprintf(out
,"ROTMAT: %12.8f %12.8f %12.8f\n",rotmat
[YY
][XX
],rotmat
[YY
][YY
],rotmat
[YY
][ZZ
]);
439 fprintf(out
,"ROTMAT: %12.8f %12.8f %12.8f\n",rotmat
[ZZ
][XX
],rotmat
[ZZ
][YY
],rotmat
[ZZ
][ZZ
]);
444 static void dump_rvec(FILE *out
, int dim
, rvec
*x
)
449 for (i
=0; i
<dim
; i
++)
450 fprintf(out
,"%4d %f %f %f\n",i
,x
[i
][XX
],x
[i
][YY
],x
[i
][ZZ
]);
455 static void dump_mat(FILE* out
, int dim
, double** mat
)
460 fprintf(out
,"MATRIX:\n");
464 fprintf(out
,"%f ",mat
[i
][j
]);
476 static void do_edfit(int natoms
,rvec
*xp
,rvec
*x
,matrix R
,t_edpar
*edi
)
478 /* this is a copy of do_fit with some modifications */
485 struct t_do_edfit
*loc
;
488 if(edi
->buf
->do_edfit
!= NULL
)
493 snew(edi
->buf
->do_edfit
,1);
495 loc
= edi
->buf
->do_edfit
;
499 snew(loc
->omega
,2*DIM
);
501 for(i
=0; i
<2*DIM
; i
++)
503 snew(loc
->omega
[i
],2*DIM
);
504 snew(loc
->om
[i
],2*DIM
);
518 /* calculate the matrix U */
520 for(n
=0;(n
<natoms
);n
++)
522 for(c
=0; (c
<DIM
); c
++)
525 for(r
=0; (r
<DIM
); r
++)
533 /* construct loc->omega */
534 /* loc->omega is symmetric -> loc->omega==loc->omega' */
539 loc
->omega
[r
][c
]=u
[r
-3][c
];
540 loc
->omega
[c
][r
]=u
[r
-3][c
];
548 /* determine h and k */
552 dump_mat(stderr
,2*DIM
,loc
->omega
);
554 fprintf(stderr
,"d[%d] = %f\n",i
,d
[i
]);
557 jacobi(loc
->omega
,6,d
,loc
->om
,&irot
);
560 fprintf(stderr
,"IROT=0\n");
562 index
=0; /* For the compiler only */
576 vh
[j
][i
]=M_SQRT2
*loc
->om
[i
][index
];
577 vk
[j
][i
]=M_SQRT2
*loc
->om
[i
+DIM
][index
];
584 R
[c
][r
]=vk
[0][r
]*vh
[0][c
]+
590 R
[c
][r
]=vk
[0][r
]*vh
[0][c
]+
596 static void rmfit(int nat
, rvec
*xcoll
, rvec transvec
, matrix rotmat
)
603 * The inverse rotation is described by the transposed rotation matrix */
604 transpose(rotmat
,tmat
);
605 rotate_x(xcoll
, nat
, tmat
);
607 /* Remove translation */
608 vec
[XX
]=-transvec
[XX
];
609 vec
[YY
]=-transvec
[YY
];
610 vec
[ZZ
]=-transvec
[ZZ
];
611 translate_x(xcoll
, nat
, vec
);
615 /**********************************************************************************
616 ******************** FLOODING ****************************************************
617 **********************************************************************************
619 The flooding ability was added later to edsam. Many of the edsam functionality could be reused for that purpose.
620 The flooding covariance matrix, i.e. the selected eigenvectors and their corresponding eigenvalues are
621 read as 7th Component Group. The eigenvalues are coded into the stepsize parameter (as used by -linfix or -linacc).
623 do_md clls right in the beginning the function init_edsam, which reads the edi file, saves all the necessary information in
624 the edi structure and calls init_flood, to initialise some extra fields in the edi->flood structure.
626 since the flooding acts on forces do_flood is called from the function force() (force.c), while the other
627 edsam functionality is hooked into md via the update() (update.c) function acting as constraint on positions.
629 do_flood makes a copy of the positions,
630 fits them, projects them computes flooding_energy, and flooding forces. The forces are computed in the
631 space of the eigenvectors and are then blown up to the full cartesian space and rotated back to remove the
632 fit. Then do_flood adds these forces to the forcefield-forces
633 (given as parameter) and updates the adaptive flooding parameters Efl and deltaF.
635 To center the flooding potential at a different location one can use the -ori option in make_edi. The ori
636 structure is projected to the system of eigenvectors and then this position in the subspace is used as
637 center of the flooding potential. If the option is not used, the center will be zero in the subspace,
638 i.e. the average structure as given in the make_edi file.
640 To use the flooding potential as restraint, make_edi has the option -restrain, which leads to inverted
641 signs of alpha2 and Efl, such that the sign in the exponential of Vfl is not inverted but the sign of
642 Vfl is inverted. Vfl = Efl * exp (- .../Efl/alpha2*x^2...) With tau>0 the negative Efl will grow slowly
643 so that the restraint is switched off slowly. When Efl==0 and inverted flooding is ON is reached no
644 further adaption is applied, Efl will stay constant at zero.
646 To use restraints with harmonic potentials switch -restrain and -harmonic. Then the eigenvalues are
647 used as spring constants for the harmonic potential.
648 Note that eq3 in the flooding paper (J. Comp. Chem. 2006, 27, 1693-1702) defines the parameter lambda \
649 as the inverse of the spring constant, whereas the implementation uses lambda as the spring constant.
651 To use more than one flooding matrix just concatenate several .edi files (cat flood1.edi flood2.edi > flood_all.edi)
652 the routine read_edi_file reads all of theses flooding files.
653 The structure t_edi is now organized as a list of t_edis and the function do_flood cycles through the list
654 calling the do_single_flood() routine for every single entry. Since every state variables have been kept in one
655 edi there is no interdependence whatsoever. The forces are added together.
657 To write energies into the .edr file, call the function
658 get_flood_enx_names(char**, int *nnames) to get the Header (Vfl1 Vfl2... Vfln)
660 get_flood_energies(real Vfl[],int nnames);
663 - one could program the whole thing such that Efl, Vfl and deltaF is written to the .edr file. -- i dont know how to do that, yet.
665 Maybe one should give a range of atoms for which to remove motion, so that motion is removed with
666 two edsam files from two peptide chains
669 static void write_edo_flood(t_edpar
*edi
, FILE *fp
, int step
)
674 fprintf(fp
,"%d.th FL: %d %g %g %g\n",edi
->flood
.flood_id
,step
, edi
->flood
.Efl
, edi
->flood
.Vfl
, edi
->flood
.deltaF
);
675 fprintf(fp
,"FL_FORCES: ");
677 for (i
=0; i
<edi
->flood
.vecs
.neig
; i
++)
678 fprintf(fp
," %f",edi
->flood
.vecs
.fproj
[i
]);
685 /* From flood.xproj compute the Vfl(x) at this point */
686 static real
flood_energy(t_edpar
*edi
)
688 /* compute flooding energy Vfl
689 Vfl = Efl * exp( - \frac {kT} {2Efl alpha^2} * sum_i { \lambda_i c_i^2 } )
690 \lambda_i is the reciproce eigenvalue 1/\sigma_i
691 it is already computed by make_edi and stored in stpsz[i]
693 Vfl = - Efl * 1/2(sum _i {\frac 1{\lambda_i} c_i^2})
701 /* Compute sum which will be the exponent of the exponential */
702 for (i
=0; i
<edi
->flood
.vecs
.neig
; i
++)
703 sum
+= edi
->flood
.vecs
.stpsz
[i
]*(edi
->flood
.vecs
.xproj
[i
]-edi
->flood
.vecs
.refproj
[i
])*(edi
->flood
.vecs
.xproj
[i
]-edi
->flood
.vecs
.refproj
[i
]);
705 /* Compute the Gauss function*/
706 if (edi
->flood
.bHarmonic
)
707 Vfl
= -0.5*edi
->flood
.Efl
*sum
; /* minus sign because Efl is negative, if restrain is on. */
709 Vfl
= edi
->flood
.Efl
!=0 ? edi
->flood
.Efl
*exp(-edi
->flood
.kT
/2/edi
->flood
.Efl
/edi
->flood
.alpha2
*sum
) :0;
715 /* From the position and from Vfl compute forces in subspace -> store in edi->vec.flood.fproj */
716 static void flood_forces(t_edpar
*edi
)
718 /* compute the forces in the subspace of the flooding eigenvectors
719 * by the formula F_i= V_{fl}(c) * ( \frac {kT} {E_{fl}} \lambda_i c_i */
722 real energy
=edi
->flood
.Vfl
;
725 if (edi
->flood
.bHarmonic
)
726 for (i
=0; i
<edi
->flood
.vecs
.neig
; i
++)
728 edi
->flood
.vecs
.fproj
[i
] = edi
->flood
.Efl
* edi
->flood
.vecs
.stpsz
[i
]*(edi
->flood
.vecs
.xproj
[i
]-edi
->flood
.vecs
.refproj
[i
]);
731 for (i
=0; i
<edi
->flood
.vecs
.neig
; i
++)
733 /* if Efl is zero the forces are zero if not use the formula */
734 edi
->flood
.vecs
.fproj
[i
] = edi
->flood
.Efl
!=0 ? edi
->flood
.kT
/edi
->flood
.Efl
/edi
->flood
.alpha2
*energy
*edi
->flood
.vecs
.stpsz
[i
]*(edi
->flood
.vecs
.xproj
[i
]-edi
->flood
.vecs
.refproj
[i
]) : 0;
739 /* Raise forces from subspace into cartesian space */
740 static void flood_blowup(t_edpar
*edi
, rvec
*forces_cart
)
742 /* this function lifts the forces from the subspace to the cartesian space
743 all the values not contained in the subspace are assumed to be zero and then
744 a coordinate transformation from eigenvector to cartesian vectors is performed
745 The nonexistent values don't have to be set to zero explicitly, they would occur
746 as zero valued summands, hence we just stop to compute this part of the sum.
748 for every atom we add all the contributions to this atom from all the different eigenvectors.
750 NOTE: one could add directly to the forcefield forces, would mean we wouldn't have to clear the
751 field forces_cart prior the computation, but momentarily we want to compute the forces seperately
752 to have them accessible for diagnostics
759 forces_sub
= edi
->flood
.vecs
.fproj
;
762 /* Calculate the cartesian forces for the local atoms */
764 /* Clear forces first */
765 for (j
=0; j
<edi
->sav
.nr_loc
; j
++)
766 clear_rvec(forces_cart
[j
]);
768 /* Now compute atomwise */
769 for (j
=0; j
<edi
->sav
.nr_loc
; j
++)
771 /* Compute forces_cart[edi->sav.anrs[j]] */
772 for (eig
=0; eig
<edi
->flood
.vecs
.neig
; eig
++)
774 /* Force vector is force * eigenvector (compute only atom j) */
775 svmul(forces_sub
[eig
],edi
->flood
.vecs
.vec
[eig
][edi
->sav
.c_ind
[j
]],dum
);
776 /* Add this vector to the cartesian forces */
777 rvec_inc(forces_cart
[j
],dum
);
783 /* Update the values of Efl, deltaF depending on tau and Vfl */
784 static void update_adaption(t_edpar
*edi
)
786 /* this function updates the parameter Efl and deltaF according to the rules given in
787 * 'predicting unimolecular chemical reactions: chemical flooding' M Mueller et al,
790 if ((edi
->flood
.tau
< 0 ? -edi
->flood
.tau
: edi
->flood
.tau
) > 0.00000001)
792 edi
->flood
.Efl
= edi
->flood
.Efl
+edi
->flood
.dt
/edi
->flood
.tau
*(edi
->flood
.deltaF0
-edi
->flood
.deltaF
);
793 /* check if restrain (inverted flooding) -> don't let EFL become positive */
794 if (edi
->flood
.alpha2
<0 && edi
->flood
.Efl
>-0.00000001)
797 edi
->flood
.deltaF
= (1-edi
->flood
.dt
/edi
->flood
.tau
)*edi
->flood
.deltaF
+edi
->flood
.dt
/edi
->flood
.tau
*edi
->flood
.Vfl
;
802 static void do_single_flood(FILE *edo
,
811 matrix rotmat
; /* rotation matrix */
812 matrix tmat
; /* inverse rotation */
813 rvec transvec
; /* translation vector */
814 struct t_do_edsam
*buf
;
817 buf
=edi
->buf
->do_edsam
;
819 /* Broadcast the positions of the AVERAGE structure such that they are known on
820 * every processor. Each node contributes its local positions x and stores them in
821 * the collective ED array buf->xcoll */
822 communicate_group_positions(cr
, buf
->xcoll
, buf
->shifts_xcoll
, buf
->extra_shifts_xcoll
, buf
->bUpdateShifts
, x
,
823 edi
->sav
.nr
, edi
->sav
.nr_loc
, edi
->sav
.anrs_loc
, edi
->sav
.c_ind
, edi
->sav
.x_old
, box
);
825 /* Only assembly REFERENCE positions if their indices differ from the average ones */
827 communicate_group_positions(cr
, buf
->xc_ref
, buf
->shifts_xc_ref
, buf
->extra_shifts_xc_ref
, buf
->bUpdateShifts
, x
,
828 edi
->sref
.nr
, edi
->sref
.nr_loc
, edi
->sref
.anrs_loc
, edi
->sref
.c_ind
, edi
->sref
.x_old
, box
);
830 /* If bUpdateShifts was TRUE, the shifts have just been updated in get_positions.
831 * We do not need to update the shifts until the next NS step */
832 buf
->bUpdateShifts
= FALSE
;
834 /* Now all nodes have all of the ED/flooding positions in edi->sav->xcoll,
835 * as well as the indices in edi->sav.anrs */
837 /* Fit the reference indices to the reference structure */
839 fit_to_reference(buf
->xcoll
, transvec
, rotmat
, edi
);
841 fit_to_reference(buf
->xc_ref
, transvec
, rotmat
, edi
);
843 /* Now apply the translation and rotation to the ED structure */
844 translate_and_rotate(buf
->xcoll
, edi
->sav
.nr
, transvec
, rotmat
);
846 /* Project fitted structure onto supbspace -> store in edi->flood.vecs.xproj */
847 project_to_eigvectors(buf
->xcoll
,&edi
->flood
.vecs
,edi
);
849 /* Compute Vfl(x) from flood.xproj */
850 edi
->flood
.Vfl
= flood_energy(edi
);
852 update_adaption(edi
);
854 /* Compute the flooding forces */
857 /* Translate them into cartesian positions */
858 flood_blowup(edi
, edi
->flood
.forces_cartesian
);
860 /* Rotate forces back so that they correspond to the given structure and not to the fitted one */
861 /* Each node rotates back its local forces */
862 transpose(rotmat
,tmat
);
863 rotate_x(edi
->flood
.forces_cartesian
, edi
->sav
.nr_loc
, tmat
);
865 /* Finally add forces to the main force variable */
866 for (i
=0; i
<edi
->sav
.nr_loc
; i
++)
867 rvec_inc(force
[edi
->sav
.anrs_loc
[i
]],edi
->flood
.forces_cartesian
[i
]);
869 /* Output is written by the master process */
870 if (do_per_step(step
,edi
->outfrq
) && MASTER(cr
))
871 write_edo_flood(edi
,edo
,step
);
875 /* Main flooding routine, called from do_force */
876 extern void do_flood(FILE *log
, /* md.log file */
877 t_commrec
*cr
, /* Communication record */
878 rvec x
[], /* Positions on the local processor */
879 rvec force
[], /* forcefield forces, to these the flooding forces are added */
880 gmx_edsam_t ed
, /* ed data structure contains all ED and flooding datasets */
881 matrix box
, /* the box */
882 int step
) /* The time step */
887 if (ed
->eEDtype
!= eEDflood
)
893 /* Call flooding for one matrix */
894 if (edi
->flood
.vecs
.neig
)
895 do_single_flood(ed
->edo
,x
,force
,edi
,step
,box
,cr
);
901 /* Called by init_edi, configure some flooding related variables and structures,
902 * print headers to output files */
903 static void init_flood(t_edpar
*edi
, gmx_edsam_t ed
, real dt
, t_commrec
*cr
)
905 edi
->flood
.Efl
= edi
->flood
.constEfl
;
909 if (edi
->flood
.vecs
.neig
)
911 /* If in any of the datasets we find a flooding vector, flooding is turned on */
912 ed
->eEDtype
= eEDflood
;
914 fprintf(ed
->edo
,"FL_HEADER: Flooding of matrix %d is switched on! The flooding output will have the following format:\n",
915 edi
->flood
.flood_id
);
916 fprintf(stderr
,"ED: Flooding of matrix %d is switched on.\n", edi
->flood
.flood_id
);
917 if (edi
->flood
.flood_id
<1)
918 fprintf(ed
->edo
,"FL_HEADER: Step Efl Vfl deltaF\n");
924 /*********** Energy book keeping ******/
925 static void get_flood_enx_names(t_edpar
*edi
, char** names
, int *nnames
) /* get header of energies */
935 sprintf(buf
,"Vfl_%d",count
);
936 names
[count
-1]=strdup(buf
);
937 actual
=actual
->next_edi
;
944 static void get_flood_energies(t_edpar
*edi
, real Vfl
[],int nnames
)
946 /*fl has to be big enough to capture nnames-many entries*/
955 Vfl
[count
-1]=actual
->flood
.Vfl
;
956 actual
=actual
->next_edi
;
960 gmx_fatal(FARGS
,"Number of energies is not consistent with t_edi structure");
962 /************* END of FLOODING IMPLEMENTATION ****************************/
966 gmx_edsam_t
ed_open(int nfile
,const t_filenm fnm
[],t_commrec
*cr
)
971 /* Allocate space for the ED data structure */
974 /* We want to perform ED (this switch might later be upgraded to eEDflood) */
975 ed
->eEDtype
= eEDedsam
;
979 /* Open .edi input file: */
980 ed
->edinam
=ftp2fn(efEDI
,nfile
,fnm
);
981 /* The master opens the .edo output file */
982 fprintf(stderr
,"ED sampling will be performed!\n");
983 ed
->edonam
= ftp2fn(efEDO
,nfile
,fnm
);
984 ed
->edo
= gmx_fio_fopen(ed
->edonam
,"w");
990 /* Broadcasts the structure data */
991 static void bc_ed_positions(t_commrec
*cr
, struct gmx_edx
*s
, int stype
)
993 snew_bc(cr
, s
->anrs
, s
->nr
); /* Index numbers */
994 snew_bc(cr
, s
->x
, s
->nr
); /* Positions */
995 nblock_bc(cr
, s
->nr
, s
->anrs
);
996 nblock_bc(cr
, s
->nr
, s
->x
);
998 /* For the average & reference structures we need an array for the collective indices,
999 * and we need to broadcast the masses as well */
1000 if (stype
== eedAV
|| stype
== eedREF
)
1002 /* We need these additional variables in the parallel case: */
1003 snew(s
->c_ind
, s
->nr
); /* Collective indices */
1004 /* Local atom indices get assigned in dd_make_local_group_indices.
1005 * There, also memory is allocated */
1006 s
->nalloc_loc
= 0; /* allocation size of s->anrs_loc */
1007 snew_bc(cr
, s
->x_old
, s
->nr
); /* To be able to always make the ED molecule whole, ... */
1008 nblock_bc(cr
, s
->nr
, s
->x_old
); /* ... keep track of shift changes with the help of old coords */
1011 /* broadcast masses for the reference structure (for mass-weighted fitting) */
1012 if (stype
== eedREF
)
1014 snew_bc(cr
, s
->m
, s
->nr
);
1015 nblock_bc(cr
, s
->nr
, s
->m
);
1018 /* For the average structure we might need the masses for mass-weighting */
1021 snew_bc(cr
, s
->sqrtm
, s
->nr
);
1022 nblock_bc(cr
, s
->nr
, s
->sqrtm
);
1023 snew_bc(cr
, s
->m
, s
->nr
);
1024 nblock_bc(cr
, s
->nr
, s
->m
);
1029 /* Broadcasts the eigenvector data */
1030 static void bc_ed_vecs(t_commrec
*cr
, t_eigvec
*ev
, int length
)
1034 snew_bc(cr
, ev
->ieig
, ev
->neig
); /* index numbers of eigenvector */
1035 snew_bc(cr
, ev
->stpsz
, ev
->neig
); /* stepsizes per eigenvector */
1036 snew_bc(cr
, ev
->xproj
, ev
->neig
); /* instantaneous x projection */
1037 snew_bc(cr
, ev
->fproj
, ev
->neig
); /* instantaneous f projection */
1038 snew_bc(cr
, ev
->refproj
, ev
->neig
); /* starting or target projection */
1040 nblock_bc(cr
, ev
->neig
, ev
->ieig
);
1041 nblock_bc(cr
, ev
->neig
, ev
->stpsz
);
1042 nblock_bc(cr
, ev
->neig
, ev
->xproj
);
1043 nblock_bc(cr
, ev
->neig
, ev
->fproj
);
1044 nblock_bc(cr
, ev
->neig
, ev
->refproj
);
1046 snew_bc(cr
, ev
->vec
, ev
->neig
); /* Eigenvector components */
1047 for (i
=0; i
<ev
->neig
; i
++)
1049 snew_bc(cr
, ev
->vec
[i
], length
);
1050 nblock_bc(cr
, length
, ev
->vec
[i
]);
1055 /* Broadcasts the ED / flooding data to other nodes
1056 * and allocates memory where needed */
1057 static void broadcast_ed_data(t_commrec
*cr
, gmx_edsam_t ed
, int numedis
)
1063 /* Master lets the other nodes know if its ED only or also flooding */
1064 gmx_bcast(sizeof(ed
->eEDtype
), &(ed
->eEDtype
), cr
);
1066 snew_bc(cr
, ed
->edpar
,1);
1067 /* Now transfer the ED data set(s) */
1069 for (nr
=0; nr
<numedis
; nr
++)
1071 /* Broadcast a single ED data set */
1074 /* Broadcast positions */
1075 bc_ed_positions(cr
, &(edi
->sref
), eedREF
); /* reference positions (don't broadcast masses) */
1076 bc_ed_positions(cr
, &(edi
->sav
), eedAV
); /* average positions (do broadcast masses as well) */
1077 bc_ed_positions(cr
, &(edi
->star
), eedTAR
); /* target positions */
1078 bc_ed_positions(cr
, &(edi
->sori
), eedORI
); /* origin positions */
1080 /* Broadcast eigenvectors */
1081 bc_ed_vecs(cr
, &edi
->vecs
.mon
, edi
->sav
.nr
);
1082 bc_ed_vecs(cr
, &edi
->vecs
.linfix
, edi
->sav
.nr
);
1083 bc_ed_vecs(cr
, &edi
->vecs
.linacc
, edi
->sav
.nr
);
1084 bc_ed_vecs(cr
, &edi
->vecs
.radfix
, edi
->sav
.nr
);
1085 bc_ed_vecs(cr
, &edi
->vecs
.radacc
, edi
->sav
.nr
);
1086 bc_ed_vecs(cr
, &edi
->vecs
.radcon
, edi
->sav
.nr
);
1087 /* Broadcast flooding eigenvectors */
1088 bc_ed_vecs(cr
, &edi
->flood
.vecs
, edi
->sav
.nr
);
1090 /* Set the pointer to the next ED dataset */
1093 snew_bc(cr
, edi
->next_edi
, 1);
1094 edi
= edi
->next_edi
;
1100 /* init-routine called for every *.edi-cycle, initialises t_edpar structure */
1101 static void init_edi(gmx_mtop_t
*mtop
,t_inputrec
*ir
,
1102 t_commrec
*cr
,gmx_edsam_t ed
,t_edpar
*edi
)
1105 real totalmass
= 0.0;
1109 /* NOTE Init_edi is executed on the master process only
1110 * The initialized data sets are then transmitted to the
1111 * other nodes in broadcast_ed_data */
1113 edi
->bNeedDoEdsam
= edi
->vecs
.mon
.neig
1114 || edi
->vecs
.linfix
.neig
1115 || edi
->vecs
.linacc
.neig
1116 || edi
->vecs
.radfix
.neig
1117 || edi
->vecs
.radacc
.neig
1118 || edi
->vecs
.radcon
.neig
;
1120 /* evaluate masses (reference structure) */
1121 snew(edi
->sref
.m
, edi
->sref
.nr
);
1122 for (i
= 0; i
< edi
->sref
.nr
; i
++)
1126 gmx_mtop_atomnr_to_atom(mtop
,edi
->sref
.anrs
[i
],&atom
);
1127 edi
->sref
.m
[i
] = atom
->m
;
1131 edi
->sref
.m
[i
] = 1.0;
1133 totalmass
+= edi
->sref
.m
[i
];
1135 edi
->sref
.mtot
= totalmass
;
1137 /* Masses m and sqrt(m) for the average structure. Note that m
1138 * is needed if forces have to be evaluated in do_edsam */
1139 snew(edi
->sav
.sqrtm
, edi
->sav
.nr
);
1140 snew(edi
->sav
.m
, edi
->sav
.nr
);
1141 for (i
= 0; i
< edi
->sav
.nr
; i
++)
1143 gmx_mtop_atomnr_to_atom(mtop
,edi
->sav
.anrs
[i
],&atom
);
1144 edi
->sav
.m
[i
] = atom
->m
;
1147 edi
->sav
.sqrtm
[i
] = sqrt(atom
->m
);
1151 edi
->sav
.sqrtm
[i
] = 1.0;
1155 /* put reference structure in origin */
1156 get_center(edi
->sref
.x
, edi
->sref
.m
, edi
->sref
.nr
, com
);
1160 translate_x(edi
->sref
.x
, edi
->sref
.nr
, com
);
1162 /* Init ED buffer */
1167 static void check(const char *line
, const char *label
)
1169 if (!strstr(line
,label
))
1170 gmx_fatal(FARGS
,"Could not find input parameter %s at expected position in edsam input-file (.edi)\nline read instead is %s",label
,line
);
1174 static int read_checked_edint(FILE *file
,const char *label
)
1176 char line
[STRLEN
+1];
1180 fgets2 (line
,STRLEN
,file
);
1182 fgets2 (line
,STRLEN
,file
);
1183 sscanf (line
,"%d",&idum
);
1188 static int read_edint(FILE *file
,bool *bEOF
)
1190 char line
[STRLEN
+1];
1195 eof
=fgets2 (line
,STRLEN
,file
);
1201 eof
=fgets2 (line
,STRLEN
,file
);
1207 sscanf (line
,"%d",&idum
);
1213 static real
read_checked_edreal(FILE *file
,const char *label
)
1215 char line
[STRLEN
+1];
1219 fgets2 (line
,STRLEN
,file
);
1221 fgets2 (line
,STRLEN
,file
);
1222 sscanf (line
,"%lf",&rdum
);
1223 return (real
) rdum
; /* always read as double and convert to single */
1227 static void read_edx(FILE *file
,int number
,int *anrs
,rvec
*x
)
1230 char line
[STRLEN
+1];
1234 for(i
=0; i
<number
; i
++)
1236 fgets2 (line
,STRLEN
,file
);
1237 sscanf (line
,"%d%lf%lf%lf",&anrs
[i
],&d
[0],&d
[1],&d
[2]);
1238 anrs
[i
]--; /* we are reading FORTRAN indices */
1240 x
[i
][j
]=d
[j
]; /* always read as double and convert to single */
1245 static void scan_edvec(FILE *in
,int nr
,rvec
*vec
)
1247 char line
[STRLEN
+1];
1252 for(i
=0; (i
< nr
); i
++)
1254 fgets2 (line
,STRLEN
,in
);
1255 sscanf (line
,"%le%le%le",&x
,&y
,&z
);
1263 static void read_edvec(FILE *in
,int nr
,t_eigvec
*tvec
,bool bReadRefproj
)
1266 double rdum
,refproj_dum
=0.0;
1267 char line
[STRLEN
+1];
1270 tvec
->neig
=read_checked_edint(in
,"NUMBER OF EIGENVECTORS");
1273 snew(tvec
->ieig
,tvec
->neig
);
1274 snew(tvec
->stpsz
,tvec
->neig
);
1275 snew(tvec
->vec
,tvec
->neig
);
1276 snew(tvec
->xproj
,tvec
->neig
);
1277 snew(tvec
->fproj
,tvec
->neig
);
1278 snew(tvec
->refproj
,tvec
->neig
);
1279 for(i
=0; (i
< tvec
->neig
); i
++)
1281 fgets2 (line
,STRLEN
,in
);
1282 if (bReadRefproj
) /* only when using flooding as harmonic restraint */
1284 nscan
= sscanf(line
,"%d%lf%lf",&idum
,&rdum
,&refproj_dum
);
1286 gmx_fatal(FARGS
,"Expected 3 values for flooding vec: <nr> <spring const> <refproj> \n");
1288 tvec
->stpsz
[i
]=rdum
;
1289 tvec
->refproj
[i
]=refproj_dum
;
1293 nscan
= sscanf(line
,"%d%lf",&idum
,&rdum
);
1295 gmx_fatal(FARGS
,"Expected 2 values for flooding vec: <nr> <stpsz>\n");
1297 tvec
->stpsz
[i
]=rdum
;
1300 for(i
=0; (i
< tvec
->neig
); i
++)
1302 snew(tvec
->vec
[i
],nr
);
1303 scan_edvec(in
,nr
,tvec
->vec
[i
]);
1309 /* calls read_edvec for the vector groups, only for flooding there is an extra call */
1310 static void read_edvecs(FILE *in
,int nr
,t_edvecs
*vecs
)
1312 read_edvec(in
,nr
,&vecs
->mon
,FALSE
);
1313 read_edvec(in
,nr
,&vecs
->linfix
,FALSE
);
1314 read_edvec(in
,nr
,&vecs
->linacc
,FALSE
);
1315 read_edvec(in
,nr
,&vecs
->radfix
,FALSE
);
1316 read_edvec(in
,nr
,&vecs
->radacc
,FALSE
);
1317 read_edvec(in
,nr
,&vecs
->radcon
,FALSE
);
1321 /* Check if the same atom indices are used for reference and average positions */
1322 static bool check_if_same(struct gmx_edx sref
, struct gmx_edx sav
)
1327 /* If the number of atoms differs between the two structures,
1328 * they cannot be identical */
1329 if (sref
.nr
!= sav
.nr
)
1332 /* Now that we know that both stuctures have the same number of atoms,
1333 * check if also the indices are identical */
1334 for (i
=0; i
< sav
.nr
; i
++)
1336 if (sref
.anrs
[i
] != sav
.anrs
[i
])
1339 fprintf(stderr
, "ED: Note: Reference and average structure are composed of the same atom indices.\n");
1345 static int read_edi(FILE* in
, gmx_edsam_t ed
,t_edpar
*edi
,int nr_mdatoms
, int edi_nr
, t_commrec
*cr
)
1348 const int magic
=669;
1352 /* the edi file is not free format, so expect problems if the input is corrupt. */
1354 /* check the magic number */
1355 readmagic
=read_edint(in
,&bEOF
);
1356 /* Check whether we have reached the end of the input file */
1360 if (readmagic
!= magic
)
1362 if (readmagic
==666 || readmagic
==667 || readmagic
==668)
1363 gmx_fatal(FARGS
,"wrong magic number: Use newest version of make_edi to produce edi file");
1365 gmx_fatal(FARGS
,"Wrong magic number %d in %s",readmagic
,ed
->edinam
);
1368 /* check the number of atoms */
1369 edi
->nini
=read_edint(in
,&bEOF
);
1370 if (edi
->nini
!= nr_mdatoms
)
1371 gmx_fatal(FARGS
,"Nr of atoms in %s (%d) does not match nr of md atoms (%d)",
1372 ed
->edinam
,edi
->nini
,nr_mdatoms
);
1374 /* Done checking. For the rest we blindly trust the input */
1375 edi
->fitmas
= read_checked_edint(in
,"FITMAS");
1376 edi
->pcamas
= read_checked_edint(in
,"ANALYSIS_MAS");
1377 edi
->outfrq
= read_checked_edint(in
,"OUTFRQ");
1378 edi
->maxedsteps
= read_checked_edint(in
,"MAXLEN");
1379 edi
->slope
= read_checked_edreal(in
,"SLOPECRIT");
1381 edi
->presteps
= read_checked_edint(in
,"PRESTEPS");
1382 edi
->flood
.deltaF0
= read_checked_edreal(in
,"DELTA_F0");
1383 edi
->flood
.deltaF
= read_checked_edreal(in
,"INIT_DELTA_F");
1384 edi
->flood
.tau
= read_checked_edreal(in
,"TAU");
1385 edi
->flood
.constEfl
= read_checked_edreal(in
,"EFL_NULL");
1386 edi
->flood
.alpha2
= read_checked_edreal(in
,"ALPHA2");
1387 edi
->flood
.kT
= read_checked_edreal(in
,"KT");
1388 edi
->flood
.bHarmonic
= read_checked_edint(in
,"HARMONIC");
1389 edi
->flood
.flood_id
= edi_nr
;
1390 edi
->sref
.nr
= read_checked_edint(in
,"NREF");
1392 /* allocate space for reference positions and read them */
1393 snew(edi
->sref
.anrs
,edi
->sref
.nr
);
1394 snew(edi
->sref
.x
,edi
->sref
.nr
);
1396 snew(edi
->sref
.x_old
,edi
->sref
.nr
);
1397 edi
->sref
.sqrtm
=NULL
;
1398 read_edx(in
,edi
->sref
.nr
,edi
->sref
.anrs
,edi
->sref
.x
);
1400 /* average positions. they define which atoms will be used for ED sampling */
1401 edi
->sav
.nr
=read_checked_edint(in
,"NAV");
1402 snew(edi
->sav
.anrs
,edi
->sav
.nr
);
1403 snew(edi
->sav
.x
,edi
->sav
.nr
);
1405 snew(edi
->sav
.x_old
,edi
->sav
.nr
);
1406 read_edx(in
,edi
->sav
.nr
,edi
->sav
.anrs
,edi
->sav
.x
);
1408 /* Check if the same atom indices are used for reference and average positions */
1409 edi
->bRefEqAv
= check_if_same(edi
->sref
, edi
->sav
);
1412 read_edvecs(in
,edi
->sav
.nr
,&edi
->vecs
);
1413 read_edvec(in
,edi
->sav
.nr
,&edi
->flood
.vecs
,edi
->flood
.bHarmonic
);
1415 /* target positions */
1416 edi
->star
.nr
=read_edint(in
,&bEOF
);
1417 if (edi
->star
.nr
> 0)
1419 snew(edi
->star
.anrs
,edi
->star
.nr
);
1420 snew(edi
->star
.x
,edi
->star
.nr
);
1421 edi
->star
.sqrtm
=NULL
;
1422 read_edx(in
,edi
->star
.nr
,edi
->star
.anrs
,edi
->star
.x
);
1425 /* positions defining origin of expansion circle */
1426 edi
->sori
.nr
=read_edint(in
,&bEOF
);
1427 if (edi
->sori
.nr
> 0)
1429 snew(edi
->sori
.anrs
,edi
->sori
.nr
);
1430 snew(edi
->sori
.x
,edi
->sori
.nr
);
1431 edi
->sori
.sqrtm
=NULL
;
1432 read_edx(in
,edi
->sori
.nr
,edi
->sori
.anrs
,edi
->sori
.x
);
1441 /* Read in the edi input file. Note that it may contain several ED data sets which were
1442 * achieved by concatenating multiple edi files. The standard case would be a single ED
1443 * data set, though. */
1444 static void read_edi_file(gmx_edsam_t ed
, t_edpar
*edi
, int nr_mdatoms
, t_commrec
*cr
)
1447 t_edpar
*curr_edi
,*last_edi
;
1452 /* This routine is executed on the master only */
1454 /* Open the .edi parameter input file */
1455 in
= gmx_fio_fopen(ed
->edinam
,"r");
1456 fprintf(stderr
, "ED: Reading edi file %s\n", ed
->edinam
);
1458 /* Now read a sequence of ED input parameter sets from the edi file */
1461 while( read_edi(in
, ed
, curr_edi
, nr_mdatoms
, edi_nr
, cr
) )
1464 /* Make shure that the number of atoms in each dataset is the same as in the tpr file */
1465 if (edi
->nini
!= nr_mdatoms
)
1466 gmx_fatal(FARGS
,"edi file %s (dataset #%d) was made for %d atoms, but the simulation contains %d atoms.",
1467 ed
->edinam
, edi_nr
, edi
->nini
, nr_mdatoms
);
1468 /* Since we arrived within this while loop we know that there is still another data set to be read in */
1469 /* We need to allocate space for the data: */
1471 /* Point the 'next_edi' entry to the next edi: */
1472 curr_edi
->next_edi
=edi_read
;
1473 /* Keep the curr_edi pointer for the case that the next dataset is empty: */
1474 last_edi
= curr_edi
;
1475 /* Let's prepare to read in the next edi data set: */
1476 curr_edi
= edi_read
;
1479 gmx_fatal(FARGS
, "No complete ED data set found in edi file %s.", ed
->edinam
);
1481 /* Terminate the edi dataset list with a NULL pointer: */
1482 last_edi
->next_edi
= NULL
;
1484 fprintf(stderr
, "ED: Found %d ED dataset%s.\n", edi_nr
, edi_nr
>1? "s" : "");
1486 /* Close the .edi file again */
1491 struct t_fit_to_ref
{
1492 rvec
*xcopy
; /* Working copy of the positions in fit_to_reference */
1495 /* Fit the current positions to the reference positions
1496 * Do not actually do the fit, just return rotation and translation.
1497 * Note that the COM of the reference structure was already put into
1498 * the origin by init_edi. */
1499 static void fit_to_reference(rvec
*xcoll
, /* The positions to be fitted */
1500 rvec transvec
, /* The translation vector */
1501 matrix rotmat
, /* The rotation matrix */
1502 t_edpar
*edi
) /* Just needed for do_edfit */
1504 rvec com
; /* center of mass */
1506 struct t_fit_to_ref
*loc
;
1509 GMX_MPE_LOG(ev_fit_to_reference_start
);
1511 /* Allocate memory the first time this routine is called for each edi dataset */
1512 if (NULL
== edi
->buf
->fit_to_ref
)
1514 snew(edi
->buf
->fit_to_ref
, 1);
1515 snew(edi
->buf
->fit_to_ref
->xcopy
, edi
->sref
.nr
);
1517 loc
= edi
->buf
->fit_to_ref
;
1519 /* We do not touch the original positions but work on a copy. */
1520 for (i
=0; i
<edi
->sref
.nr
; i
++)
1521 copy_rvec(xcoll
[i
], loc
->xcopy
[i
]);
1523 /* Calculate the center of mass */
1524 get_center(loc
->xcopy
, edi
->sref
.m
, edi
->sref
.nr
, com
);
1526 transvec
[XX
] = -com
[XX
];
1527 transvec
[YY
] = -com
[YY
];
1528 transvec
[ZZ
] = -com
[ZZ
];
1530 /* Subtract the center of mass from the copy */
1531 translate_x(loc
->xcopy
, edi
->sref
.nr
, transvec
);
1533 /* Determine the rotation matrix */
1534 do_edfit(edi
->sref
.nr
, edi
->sref
.x
, loc
->xcopy
, rotmat
, edi
);
1536 GMX_MPE_LOG(ev_fit_to_reference_finish
);
1540 static void translate_and_rotate(rvec
*x
, /* The positions to be translated and rotated */
1541 int nat
, /* How many positions are there? */
1542 rvec transvec
, /* The translation vector */
1543 matrix rotmat
) /* The rotation matrix */
1546 translate_x(x
, nat
, transvec
);
1549 rotate_x(x
, nat
, rotmat
);
1553 /* Gets the rms deviation of the positions to the structure s */
1554 /* fit_to_structure has to be called before calling this routine! */
1555 static real
rmsd_from_structure(rvec
*x
, /* The positions under consideration */
1556 struct gmx_edx
*s
) /* The structure from which the rmsd shall be computed */
1562 for (i
=0; i
< s
->nr
; i
++)
1563 rmsd
+= distance2(s
->x
[i
], x
[i
]);
1565 rmsd
/= (real
) s
->nr
;
1572 void dd_make_local_ed_indices(gmx_domdec_t
*dd
, struct gmx_edsam
*ed
)
1577 if (ed
->eEDtype
!= eEDnone
)
1579 /* Loop over ED datasets (usually there is just one dataset, though) */
1583 /* Local atoms of the reference structure (for fitting), need only be assembled
1584 * if their indices differ from the average ones */
1586 dd_make_local_group_indices(dd
->ga2la
, edi
->sref
.nr
, edi
->sref
.anrs
,
1587 &edi
->sref
.nr_loc
, &edi
->sref
.anrs_loc
, &edi
->sref
.nalloc_loc
, edi
->sref
.c_ind
);
1589 /* Local atoms of the average structure (on these ED will be performed) */
1590 dd_make_local_group_indices(dd
->ga2la
, edi
->sav
.nr
, edi
->sav
.anrs
,
1591 &edi
->sav
.nr_loc
, &edi
->sav
.anrs_loc
, &edi
->sav
.nalloc_loc
, edi
->sav
.c_ind
);
1593 /* Indicate that the ED shift vectors for this structure need to be updated
1594 * at the next call to communicate_group_positions, since obviously we are in a NS step */
1595 edi
->buf
->do_edsam
->bUpdateShifts
= TRUE
;
1597 /* Set the pointer to the next ED dataset (if any) */
1604 static inline void ed_unshift_single_coord(matrix box
, const rvec x
, const ivec is
, rvec xu
)
1609 GMX_MPE_LOG(ev_unshift_start
);
1617 xu
[XX
] = x
[XX
]-tx
*box
[XX
][XX
]-ty
*box
[YY
][XX
]-tz
*box
[ZZ
][XX
];
1618 xu
[YY
] = x
[YY
]-ty
*box
[YY
][YY
]-tz
*box
[ZZ
][YY
];
1619 xu
[ZZ
] = x
[ZZ
]-tz
*box
[ZZ
][ZZ
];
1622 xu
[XX
] = x
[XX
]-tx
*box
[XX
][XX
];
1623 xu
[YY
] = x
[YY
]-ty
*box
[YY
][YY
];
1624 xu
[ZZ
] = x
[ZZ
]-tz
*box
[ZZ
][ZZ
];
1627 GMX_MPE_LOG(ev_unshift_finish
);
1631 static void do_linfix(rvec
*xcoll
, t_edpar
*edi
, int step
, t_commrec
*cr
)
1638 /* loop over linfix vectors */
1639 for (i
=0; i
<edi
->vecs
.linfix
.neig
; i
++)
1641 /* calculate the projection */
1642 proj
= projectx(edi
, xcoll
, edi
->vecs
.linfix
.vec
[i
]);
1644 /* calculate the correction */
1645 add
= edi
->vecs
.linfix
.refproj
[i
] + step
*edi
->vecs
.linfix
.stpsz
[i
] - proj
;
1647 /* apply the correction */
1648 add
/= edi
->sav
.sqrtm
[i
];
1649 for (j
=0; j
<edi
->sav
.nr
; j
++)
1651 svmul(add
, edi
->vecs
.linfix
.vec
[i
][j
], vec_dum
);
1652 rvec_inc(xcoll
[j
], vec_dum
);
1658 static void do_linacc(rvec
*xcoll
, t_edpar
*edi
, t_commrec
*cr
)
1665 /* loop over linacc vectors */
1666 for (i
=0; i
<edi
->vecs
.linacc
.neig
; i
++)
1668 /* calculate the projection */
1669 proj
=projectx(edi
, xcoll
, edi
->vecs
.linacc
.vec
[i
]);
1671 /* calculate the correction */
1673 if (edi
->vecs
.linacc
.stpsz
[i
] > 0.0)
1675 if ((proj
-edi
->vecs
.linacc
.refproj
[i
]) < 0.0)
1676 add
= edi
->vecs
.linacc
.refproj
[i
] - proj
;
1678 if (edi
->vecs
.linacc
.stpsz
[i
] < 0.0)
1680 if ((proj
-edi
->vecs
.linacc
.refproj
[i
]) > 0.0)
1681 add
= edi
->vecs
.linacc
.refproj
[i
] - proj
;
1684 /* apply the correction */
1685 add
/= edi
->sav
.sqrtm
[i
];
1686 for (j
=0; j
<edi
->sav
.nr
; j
++)
1688 svmul(add
, edi
->vecs
.linacc
.vec
[i
][j
], vec_dum
);
1689 rvec_inc(xcoll
[j
], vec_dum
);
1692 /* new positions will act as reference */
1693 edi
->vecs
.linacc
.refproj
[i
] = proj
+ add
;
1698 static void do_radfix(rvec
*xcoll
, t_edpar
*edi
, int step
, t_commrec
*cr
)
1701 real
*proj
, rad
=0.0, ratio
;
1705 if (edi
->vecs
.radfix
.neig
== 0)
1708 snew(proj
, edi
->vecs
.radfix
.neig
);
1710 /* loop over radfix vectors */
1711 for (i
=0; i
<edi
->vecs
.radfix
.neig
; i
++)
1713 /* calculate the projections, radius */
1714 proj
[i
] = projectx(edi
, xcoll
, edi
->vecs
.radfix
.vec
[i
]);
1715 rad
+= pow(proj
[i
] - edi
->vecs
.radfix
.refproj
[i
], 2);
1719 ratio
= (edi
->vecs
.radfix
.stpsz
[0]+edi
->vecs
.radfix
.radius
)/rad
- 1.0;
1720 edi
->vecs
.radfix
.radius
+= edi
->vecs
.radfix
.stpsz
[0];
1722 /* loop over radfix vectors */
1723 for (i
=0; i
<edi
->vecs
.radfix
.neig
; i
++)
1725 proj
[i
] -= edi
->vecs
.radfix
.refproj
[i
];
1727 /* apply the correction */
1728 proj
[i
] /= edi
->sav
.sqrtm
[i
];
1730 for (j
=0; j
<edi
->sav
.nr
; j
++) {
1731 svmul(proj
[i
], edi
->vecs
.radfix
.vec
[i
][j
], vec_dum
);
1732 rvec_inc(xcoll
[j
], vec_dum
);
1740 static void do_radacc(rvec
*xcoll
, t_edpar
*edi
, t_commrec
*cr
)
1743 real
*proj
, rad
=0.0, ratio
=0.0;
1747 if (edi
->vecs
.radacc
.neig
== 0)
1750 snew(proj
,edi
->vecs
.radacc
.neig
);
1752 /* loop over radacc vectors */
1753 for (i
=0; i
<edi
->vecs
.radacc
.neig
; i
++)
1755 /* calculate the projections, radius */
1756 proj
[i
] = projectx(edi
, xcoll
, edi
->vecs
.radacc
.vec
[i
]);
1757 rad
+= pow(proj
[i
] - edi
->vecs
.radacc
.refproj
[i
], 2);
1761 /* only correct when radius decreased */
1762 if (rad
< edi
->vecs
.radacc
.radius
)
1764 ratio
= edi
->vecs
.radacc
.radius
/rad
- 1.0;
1765 rad
= edi
->vecs
.radacc
.radius
;
1768 edi
->vecs
.radacc
.radius
= rad
;
1770 /* loop over radacc vectors */
1771 for (i
=0; i
<edi
->vecs
.radacc
.neig
; i
++)
1773 proj
[i
] -= edi
->vecs
.radacc
.refproj
[i
];
1775 /* apply the correction */
1776 proj
[i
] /= edi
->sav
.sqrtm
[i
];
1778 for (j
=0; j
<edi
->sav
.nr
; j
++)
1780 svmul(proj
[i
], edi
->vecs
.radacc
.vec
[i
][j
], vec_dum
);
1781 rvec_inc(xcoll
[j
], vec_dum
);
1788 struct t_do_radcon
{
1792 static void do_radcon(rvec
*xcoll
, t_edpar
*edi
, t_commrec
*cr
)
1795 real rad
=0.0, ratio
=0.0;
1796 struct t_do_radcon
*loc
;
1801 if(edi
->buf
->do_radcon
!= NULL
)
1804 loc
= edi
->buf
->do_radcon
;
1809 snew(edi
->buf
->do_radcon
, 1);
1811 loc
= edi
->buf
->do_radcon
;
1813 if (edi
->vecs
.radcon
.neig
== 0)
1817 snew(loc
->proj
, edi
->vecs
.radcon
.neig
);
1819 /* loop over radcon vectors */
1820 for (i
=0; i
<edi
->vecs
.radcon
.neig
; i
++)
1822 /* calculate the projections, radius */
1823 loc
->proj
[i
] = projectx(edi
, xcoll
, edi
->vecs
.radcon
.vec
[i
]);
1824 rad
+= pow(loc
->proj
[i
] - edi
->vecs
.radcon
.refproj
[i
], 2);
1827 /* only correct when radius increased */
1828 if (rad
> edi
->vecs
.radcon
.radius
)
1830 ratio
= edi
->vecs
.radcon
.radius
/rad
- 1.0;
1832 /* loop over radcon vectors */
1833 for (i
=0; i
<edi
->vecs
.radcon
.neig
; i
++)
1835 /* apply the correction */
1836 loc
->proj
[i
] -= edi
->vecs
.radcon
.refproj
[i
];
1837 loc
->proj
[i
] /= edi
->sav
.sqrtm
[i
];
1838 loc
->proj
[i
] *= ratio
;
1840 for (j
=0; j
<edi
->sav
.nr
; j
++)
1842 svmul(loc
->proj
[i
], edi
->vecs
.radcon
.vec
[i
][j
], vec_dum
);
1843 rvec_inc(xcoll
[j
], vec_dum
);
1848 edi
->vecs
.radcon
.radius
= rad
;
1850 if (rad
!= edi
->vecs
.radcon
.radius
)
1853 for (i
=0; i
<edi
->vecs
.radcon
.neig
; i
++)
1855 /* calculate the projections, radius */
1856 loc
->proj
[i
] = projectx(edi
, xcoll
, edi
->vecs
.radcon
.vec
[i
]);
1857 rad
+= pow(loc
->proj
[i
] - edi
->vecs
.radcon
.refproj
[i
], 2);
1864 static void ed_apply_constraints(rvec
*xcoll
, t_edpar
*edi
, int step
, t_commrec
*cr
)
1869 GMX_MPE_LOG(ev_ed_apply_cons_start
);
1871 /* subtract the average positions */
1872 for (i
=0; i
<edi
->sav
.nr
; i
++)
1873 rvec_dec(xcoll
[i
], edi
->sav
.x
[i
]);
1875 /* apply the constraints */
1877 do_linfix(xcoll
, edi
, step
, cr
);
1878 do_linacc(xcoll
, edi
, cr
);
1880 do_radfix(xcoll
, edi
, step
, cr
);
1881 do_radacc(xcoll
, edi
, cr
);
1882 do_radcon(xcoll
, edi
, cr
);
1884 /* add back the average positions */
1885 for (i
=0; i
<edi
->sav
.nr
; i
++)
1886 rvec_inc(xcoll
[i
], edi
->sav
.x
[i
]);
1888 GMX_MPE_LOG(ev_ed_apply_cons_finish
);
1892 /* Write out the projections onto the eigenvectors */
1893 static void write_edo(int nr_edi
, t_edpar
*edi
, gmx_edsam_t ed
, int step
,real rmsd
)
1898 if (edi
->bNeedDoEdsam
)
1901 fprintf(ed
->edo
, "Initial projections:\n");
1904 fprintf(ed
->edo
,"Step %d, ED #%d ",step
,nr_edi
);
1905 fprintf(ed
->edo
," RMSD %f nm\n",rmsd
);
1906 if (ed
->eEDtype
== eEDflood
)
1907 fprintf(ed
->edo
, " Efl=%f deltaF=%f Vfl=%f\n",edi
->flood
.Efl
,edi
->flood
.deltaF
,edi
->flood
.Vfl
);
1910 if (edi
->vecs
.mon
.neig
)
1912 fprintf(ed
->edo
," Monitor eigenvectors");
1913 for (i
=0; i
<edi
->vecs
.mon
.neig
; i
++)
1914 fprintf(ed
->edo
," %d: %12.5e ",edi
->vecs
.mon
.ieig
[i
],edi
->vecs
.mon
.xproj
[i
]);
1915 fprintf(ed
->edo
,"\n");
1917 if (edi
->vecs
.linfix
.neig
)
1919 fprintf(ed
->edo
," Linfix eigenvectors");
1920 for (i
=0; i
<edi
->vecs
.linfix
.neig
; i
++)
1921 fprintf(ed
->edo
," %d: %12.5e ",edi
->vecs
.linfix
.ieig
[i
],edi
->vecs
.linfix
.xproj
[i
]);
1922 fprintf(ed
->edo
,"\n");
1924 if (edi
->vecs
.linacc
.neig
)
1926 fprintf(ed
->edo
," Linacc eigenvectors");
1927 for (i
=0; i
<edi
->vecs
.linacc
.neig
; i
++)
1928 fprintf(ed
->edo
," %d: %12.5e ",edi
->vecs
.linacc
.ieig
[i
],edi
->vecs
.linacc
.xproj
[i
]);
1929 fprintf(ed
->edo
,"\n");
1931 if (edi
->vecs
.radfix
.neig
)
1933 fprintf(ed
->edo
," Radfix eigenvectors");
1934 for (i
=0; i
<edi
->vecs
.radfix
.neig
; i
++)
1935 fprintf(ed
->edo
," %d: %12.5e ",edi
->vecs
.radfix
.ieig
[i
],edi
->vecs
.radfix
.xproj
[i
]);
1936 fprintf(ed
->edo
,"\n");
1937 fprintf(ed
->edo
," fixed increment radius = %f\n", calc_radius(&edi
->vecs
.radfix
));
1939 if (edi
->vecs
.radacc
.neig
)
1941 fprintf(ed
->edo
," Radacc eigenvectors");
1942 for (i
=0; i
<edi
->vecs
.radacc
.neig
; i
++)
1943 fprintf(ed
->edo
," %d: %12.5e ",edi
->vecs
.radacc
.ieig
[i
],edi
->vecs
.radacc
.xproj
[i
]);
1944 fprintf(ed
->edo
,"\n");
1945 fprintf(ed
->edo
," acceptance radius = %f\n", calc_radius(&edi
->vecs
.radacc
));
1947 if (edi
->vecs
.radcon
.neig
)
1949 fprintf(ed
->edo
," Radcon eigenvectors");
1950 for (i
=0; i
<edi
->vecs
.radcon
.neig
; i
++)
1951 fprintf(ed
->edo
," %d: %12.5e ",edi
->vecs
.radcon
.ieig
[i
],edi
->vecs
.radcon
.xproj
[i
]);
1952 fprintf(ed
->edo
,"\n");
1953 fprintf(ed
->edo
," contracting radius = %f\n", calc_radius(&edi
->vecs
.radcon
));
1958 fprintf(ed
->edo
, " NOTE: none of the ED options mon/linfix/linacc/radfix/radacc/radcon were chosen for dataset #%d!\n", nr_edi
);
1962 /* Returns if any constraints are switched on */
1963 static int ed_constraints(bool edtype
, t_edpar
*edi
)
1965 if (edtype
== eEDedsam
|| edtype
== eEDflood
)
1967 return (edi
->vecs
.linfix
.neig
|| edi
->vecs
.linacc
.neig
||
1968 edi
->vecs
.radfix
.neig
|| edi
->vecs
.radacc
.neig
||
1969 edi
->vecs
.radcon
.neig
);
1975 void init_edsam(gmx_mtop_t
*mtop
, /* global topology */
1976 t_inputrec
*ir
, /* input record */
1977 t_commrec
*cr
, /* communication record */
1978 gmx_edsam_t ed
, /* contains all ED data */
1979 rvec x
[], /* positions of the whole MD system */
1980 matrix box
) /* the box */
1982 t_edpar
*edi
= NULL
; /* points to a single edi data set */
1983 int numedis
=0; /* keep track of the number of ED data sets in edi file */
1985 rvec
*x_pbc
= NULL
; /* positions of the whole MD system with pbc removed */
1986 rvec
*xfit
= NULL
; /* the positions which will be fitted to the reference structure */
1987 rvec
*xstart
= NULL
; /* the positions which are subject to ED sampling */
1988 rvec fit_transvec
; /* translation ... */
1989 matrix fit_rotmat
; /* ... and rotation from fit to reference structure */
1992 if (!DOMAINDECOMP(cr
) && PAR(cr
) && MASTER(cr
))
1993 gmx_fatal(FARGS
, "Please switch on domain decomposition to use essential dynamics in parallel.");
1995 GMX_MPE_LOG(ev_edsam_start
);
1998 fprintf(stderr
, "ED: Initializing essential dynamics constraints.\n");
2000 /* Needed for initializing radacc radius in do_edsam */
2003 /* The input file is read by the master and the edi structures are
2004 * initialized here. Input is stored in ed->edpar. Then the edi
2005 * structures are transferred to the other nodes */
2009 /* Read the whole edi file at once: */
2010 read_edi_file(ed
,ed
->edpar
,mtop
->natoms
,cr
);
2012 /* Initialization for every ED/flooding dataset. Flooding uses one edi dataset per
2013 * flooding vector, Essential dynamics can be applied to more than one structure
2014 * as well, but will be done in the order given in the edi file, so
2015 * expect different results for different order of edi file concatenation! */
2019 init_edi(mtop
,ir
,cr
,ed
,edi
);
2021 /* Init flooding parameters if needed */
2022 init_flood(edi
,ed
,ir
->delta_t
,cr
);
2029 /* The master does the work here. The other nodes get the positions
2030 * not before dd_partition_system which is called after init_edsam */
2033 /* Remove pbc, make molecule whole.
2034 * When ir->bContinuation=TRUE this has already been done, but ok.
2036 snew(x_pbc
,mtop
->natoms
);
2037 m_rveccopy(mtop
->natoms
,x
,x_pbc
);
2038 do_pbc_first_mtop(NULL
,ir
->ePBC
,box
,mtop
,x_pbc
);
2040 /* Reset pointer to first ED data set which contains the actual ED data */
2043 /* Loop over all ED/flooding data sets (usually only one, though) */
2044 for (nr_edi
= 1; nr_edi
<= numedis
; nr_edi
++)
2046 /* We use srenew to allocate memory since the size of the buffers
2047 * is likely to change with every ED dataset */
2048 srenew(xfit
, edi
->sref
.nr
);
2049 srenew(xstart
, edi
->sav
.nr
);
2051 /* Extract the positions of the atoms to which will be fitted */
2052 for (i
=0; i
< edi
->sref
.nr
; i
++)
2054 copy_rvec(x_pbc
[edi
->sref
.anrs
[i
]], xfit
[i
]);
2056 /* Save the sref positions such that in the next time step the molecule can
2057 * be made whole again (in the parallel case) */
2059 copy_rvec(xfit
[i
], edi
->sref
.x_old
[i
]);
2062 /* Extract the positions of the atoms subject to ED sampling */
2063 for (i
=0; i
< edi
->sav
.nr
; i
++)
2065 copy_rvec(x_pbc
[edi
->sav
.anrs
[i
]], xstart
[i
]);
2067 /* Save the sav positions such that in the next time step the molecule can
2068 * be made whole again (in the parallel case) */
2070 copy_rvec(xstart
[i
], edi
->sav
.x_old
[i
]);
2073 /* Make the fit to the REFERENCE structure, get translation and rotation */
2074 fit_to_reference(xfit
, fit_transvec
, fit_rotmat
, edi
);
2076 /* Output how well we fit to the reference at the start */
2077 translate_and_rotate(xfit
, edi
->sref
.nr
, fit_transvec
, fit_rotmat
);
2078 fprintf(stderr
, "ED: Initial RMSD from reference after fit = %f nm (dataset #%d)\n",
2079 rmsd_from_structure(xfit
, &edi
->sref
), nr_edi
);
2081 /* Now apply the translation and rotation to the atoms on which ED sampling will be performed */
2082 translate_and_rotate(xstart
, edi
->sav
.nr
, fit_transvec
, fit_rotmat
);
2084 /* calculate initial projections */
2085 project(xstart
, edi
);
2087 /* process target structure, if required */
2088 if (edi
->star
.nr
> 0)
2090 /* get translation & rotation for fit of target structure to reference structure */
2091 fit_to_reference(edi
->star
.x
, fit_transvec
, fit_rotmat
, edi
);
2093 translate_and_rotate(edi
->star
.x
, edi
->sav
.nr
, fit_transvec
, fit_rotmat
);
2094 rad_project(edi
, edi
->star
.x
, &edi
->vecs
.radcon
, cr
);
2096 rad_project(edi
, xstart
, &edi
->vecs
.radcon
, cr
);
2098 /* process structure that will serve as origin of expansion circle */
2099 if (edi
->sori
.nr
> 0)
2101 /* fit this structure to reference structure */
2102 fit_to_reference(edi
->sori
.x
, fit_transvec
, fit_rotmat
, edi
);
2104 translate_and_rotate(edi
->sori
.x
, edi
->sav
.nr
, fit_transvec
, fit_rotmat
);
2105 rad_project(edi
, edi
->sori
.x
, &edi
->vecs
.radacc
, cr
);
2106 rad_project(edi
, edi
->sori
.x
, &edi
->vecs
.radfix
, cr
);
2107 if (ed
->eEDtype
== eEDflood
)
2109 /* Set center of flooding potential to the ORIGIN structure */
2110 rad_project(edi
, edi
->sori
.x
, &edi
->flood
.vecs
, cr
);
2115 rad_project(edi
, xstart
, &edi
->vecs
.radacc
, cr
);
2116 rad_project(edi
, xstart
, &edi
->vecs
.radfix
, cr
);
2117 if (ed
->eEDtype
== eEDflood
)
2119 /* Set center of flooding potential to the center of the covariance matrix,
2120 * i.e. the average structure, i.e. zero in the projected system */
2121 for (i
=0; i
<edi
->flood
.vecs
.neig
; i
++)
2123 if (!edi
->flood
.bHarmonic
)
2124 edi
->flood
.vecs
.refproj
[i
] = 0.0;
2129 /* set starting projections for linsam */
2130 rad_project(edi
, xstart
, &edi
->vecs
.linacc
, cr
);
2131 rad_project(edi
, xstart
, &edi
->vecs
.linfix
, cr
);
2133 /* Output to file, set the step to -1 so that write_edo knows it was called from init_edsam */
2135 write_edo(nr_edi
, edi
, ed
, -1, 0);
2137 /* Prepare for the next edi data set: */
2140 /* Cleaning up on the master node: */
2145 } /* end of MASTER only section */
2149 /* First let everybody know how many ED data sets to expect */
2150 gmx_bcast(sizeof(numedis
), &numedis
, cr
);
2151 /* Broadcast the essential dynamics / flooding data to all nodes */
2152 broadcast_ed_data(cr
, ed
, numedis
);
2156 /* In the single-CPU case, point the local atom numbers pointers to the global
2157 * one, so that we can use the same notation in serial and parallel case: */
2159 /* Loop over all ED data sets (usually only one, though) */
2161 for (nr_edi
= 1; nr_edi
<= numedis
; nr_edi
++)
2163 edi
->sref
.anrs_loc
= edi
->sref
.anrs
;
2164 edi
->sav
.anrs_loc
= edi
->sav
.anrs
;
2165 edi
->star
.anrs_loc
= edi
->star
.anrs
;
2166 edi
->sori
.anrs_loc
= edi
->sori
.anrs
;
2167 /* For the same reason as above, make a dummy c_ind array: */
2168 snew(edi
->sav
.c_ind
, edi
->sav
.nr
);
2169 /* Initialize the array */
2170 for (i
=0; i
<edi
->sav
.nr
; i
++)
2171 edi
->sav
.c_ind
[i
] = i
;
2172 /* In the general case we will need a different-sized array for the reference indices: */
2175 snew(edi
->sref
.c_ind
, edi
->sref
.nr
);
2176 for (i
=0; i
<edi
->sref
.nr
; i
++)
2177 edi
->sref
.c_ind
[i
] = i
;
2179 /* Point to the very same array in case of other structures: */
2180 edi
->star
.c_ind
= edi
->sav
.c_ind
;
2181 edi
->sori
.c_ind
= edi
->sav
.c_ind
;
2182 /* In the serial case, the local number of atoms is the global one: */
2183 edi
->sref
.nr_loc
= edi
->sref
.nr
;
2184 edi
->sav
.nr_loc
= edi
->sav
.nr
;
2185 edi
->star
.nr_loc
= edi
->star
.nr
;
2186 edi
->sori
.nr_loc
= edi
->sori
.nr
;
2188 /* An on we go to the next edi dataset */
2193 /* Allocate space for ED buffer variables */
2194 /* Again, loop over ED data sets */
2196 for (nr_edi
= 1; nr_edi
<= numedis
; nr_edi
++)
2198 /* Allocate space for ED buffer */
2200 snew(edi
->buf
->do_edsam
, 1);
2202 /* Space for collective ED buffer variables */
2204 /* Collective positions of atoms with the average indices */
2205 snew(edi
->buf
->do_edsam
->xcoll
, edi
->sav
.nr
);
2206 snew(edi
->buf
->do_edsam
->shifts_xcoll
, edi
->sav
.nr
); /* buffer for xcoll shifts */
2207 snew(edi
->buf
->do_edsam
->extra_shifts_xcoll
, edi
->sav
.nr
);
2208 /* Collective positions of atoms with the reference indices */
2211 snew(edi
->buf
->do_edsam
->xc_ref
, edi
->sref
.nr
);
2212 snew(edi
->buf
->do_edsam
->shifts_xc_ref
, edi
->sref
.nr
); /* To store the shifts in */
2213 snew(edi
->buf
->do_edsam
->extra_shifts_xc_ref
, edi
->sref
.nr
);
2216 /* Get memory for flooding forces */
2217 snew(edi
->flood
.forces_cartesian
, edi
->sav
.nr
);
2220 /* Dump it all into one file per process */
2221 dump_edi(edi
, cr
, nr_edi
);
2224 /* An on we go to the next edi dataset */
2228 /* Flush the edo file so that the user can check some things
2229 * when the simulation has started */
2233 GMX_MPE_LOG(ev_edsam_finish
);
2237 void do_edsam(t_inputrec
*ir
,
2241 rvec xs
[], /* The local current positions on this processor */
2242 rvec v
[], /* The velocities */
2246 int i
,edinr
,iupdate
=500;
2247 matrix rotmat
; /* rotation matrix */
2248 rvec transvec
; /* translation vector */
2249 rvec dv
,dx
,x_unsh
; /* tmp vectors for velocity, distance, unshifted x coordinate */
2250 real dt_1
; /* 1/dt */
2251 struct t_do_edsam
*buf
;
2253 real rmsdev
=-1; /* RMSD from reference structure prior to applying the constraints */
2254 bool bSuppress
=FALSE
; /* Write .edo file on master? */
2257 /* Check if ED sampling has to be performed */
2258 if ( ed
->eEDtype
==eEDnone
)
2261 /* Suppress output on first call of do_edsam if
2262 * two-step sd2 integrator is used */
2263 if ( (ir
->eI
==eiSD2
) && (v
!= NULL
) )
2266 dt_1
= 1.0/ir
->delta_t
;
2268 /* Loop over all ED datasets (usually one) */
2274 if (edi
->bNeedDoEdsam
)
2277 buf
=edi
->buf
->do_edsam
;
2280 /* initialise radacc radius for slope criterion */
2281 buf
->oldrad
=calc_radius(&edi
->vecs
.radacc
);
2283 /* Copy the positions into buf->xc* arrays and after ED
2284 * feed back corrections to the official positions */
2286 /* Broadcast the ED positions such that every node has all of them
2287 * Every node contributes its local positions xs and stores it in
2288 * the collective buf->xcoll array. Note that for edinr > 1
2289 * xs could already have been modified by an earlier ED */
2291 communicate_group_positions(cr
, buf
->xcoll
, buf
->shifts_xcoll
, buf
->extra_shifts_xcoll
, buf
->bUpdateShifts
, xs
,
2292 edi
->sav
.nr
, edi
->sav
.nr_loc
, edi
->sav
.anrs_loc
, edi
->sav
.c_ind
, edi
->sav
.x_old
, box
);
2295 dump_xcoll(edi
, buf
, cr
, step
);
2297 /* Only assembly reference positions if their indices differ from the average ones */
2299 communicate_group_positions(cr
, buf
->xc_ref
, buf
->shifts_xc_ref
, buf
->extra_shifts_xc_ref
, buf
->bUpdateShifts
, xs
,
2300 edi
->sref
.nr
, edi
->sref
.nr_loc
, edi
->sref
.anrs_loc
, edi
->sref
.c_ind
, edi
->sref
.x_old
, box
);
2302 /* If bUpdateShifts was TRUE then the shifts have just been updated in get_positions.
2303 * We do not need to uptdate the shifts until the next NS step */
2304 buf
->bUpdateShifts
= FALSE
;
2306 /* Now all nodes have all of the ED positions in edi->sav->xcoll,
2307 * as well as the indices in edi->sav.anrs */
2309 /* Fit the reference indices to the reference structure */
2311 fit_to_reference(buf
->xcoll
, transvec
, rotmat
, edi
);
2313 fit_to_reference(buf
->xc_ref
, transvec
, rotmat
, edi
);
2315 /* Now apply the translation and rotation to the ED structure */
2316 translate_and_rotate(buf
->xcoll
, edi
->sav
.nr
, transvec
, rotmat
);
2318 /* Find out how well we fit to the reference (just for output steps) */
2319 if (do_per_step(step
,edi
->outfrq
) && MASTER(cr
))
2323 /* Indices of reference and average structures are identical,
2324 * thus we can calculate the rmsd to SREF using xcoll */
2325 rmsdev
= rmsd_from_structure(buf
->xcoll
,&edi
->sref
);
2329 /* We have to translate & rotate the reference atoms first */
2330 translate_and_rotate(buf
->xc_ref
, edi
->sref
.nr
, transvec
, rotmat
);
2331 rmsdev
= rmsd_from_structure(buf
->xc_ref
,&edi
->sref
);
2335 /* update radsam references, when required */
2336 if (do_per_step(step
,edi
->maxedsteps
) && step
> edi
->presteps
)
2338 project(buf
->xcoll
, edi
);
2339 rad_project(edi
, buf
->xcoll
, &edi
->vecs
.radacc
, cr
);
2340 rad_project(edi
, buf
->xcoll
, &edi
->vecs
.radfix
, cr
);
2344 /* update radacc references, when required */
2345 if (do_per_step(step
,iupdate
) && step
> edi
->presteps
)
2347 edi
->vecs
.radacc
.radius
= calc_radius(&edi
->vecs
.radacc
);
2348 if (edi
->vecs
.radacc
.radius
- buf
->oldrad
< edi
->slope
)
2350 project(buf
->xcoll
, edi
);
2351 rad_project(edi
, buf
->xcoll
, &edi
->vecs
.radacc
, cr
);
2354 buf
->oldrad
= edi
->vecs
.radacc
.radius
;
2357 /* apply the constraints */
2358 if (step
> edi
->presteps
&& ed_constraints(ed
->eEDtype
, edi
))
2359 ed_apply_constraints(buf
->xcoll
, edi
, step
, cr
);
2361 /* write to edo, when required */
2362 if (do_per_step(step
,edi
->outfrq
))
2364 project(buf
->xcoll
, edi
);
2365 if (MASTER(cr
) && !bSuppress
)
2366 write_edo(edinr
, edi
, ed
, step
, rmsdev
);
2369 /* Copy back the positions unless monitoring only */
2370 if (ed_constraints(ed
->eEDtype
, edi
))
2372 /* remove fitting */
2373 rmfit(edi
->sav
.nr
, buf
->xcoll
, transvec
, rotmat
);
2375 /* Copy the ED corrected positions into the coordinate array */
2376 /* Each node copies its local part. In the serial case, nat_loc is the
2377 * total number of ED atoms */
2378 for (i
=0; i
<edi
->sav
.nr_loc
; i
++)
2380 /* Unshift local ED coordinate and store in x_unsh */
2381 ed_unshift_single_coord(box
, buf
->xcoll
[edi
->sav
.c_ind
[i
]],
2382 buf
->shifts_xcoll
[edi
->sav
.c_ind
[i
]], x_unsh
);
2384 /* dx is the ED correction to the positions: */
2385 rvec_sub(x_unsh
, xs
[edi
->sav
.anrs_loc
[i
]], dx
);
2389 /* dv is the ED correction to the velocity: */
2390 svmul(dt_1
, dx
, dv
);
2391 /* apply the velocity correction: */
2392 rvec_inc(v
[edi
->sav
.anrs_loc
[i
]], dv
);
2394 /* Finally apply the position correction due to ED: */
2395 copy_rvec(x_unsh
, xs
[edi
->sav
.anrs_loc
[i
]]);
2398 } /* END of if (edi->bNeedDoEdsam) */
2400 /* Prepare for the next ED dataset */
2401 edi
= edi
->next_edi
;
2403 } /* END of loop over ED datasets */
2407 GMX_MPE_LOG(ev_edsam_finish
);