|
|
|
|
@ -72,7 +72,8 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in,
|
|
|
|
|
double delspx,delspy,delspz;
|
|
|
|
|
|
|
|
|
|
etol = etol_in;
|
|
|
|
|
ftol = ftol_in;
|
|
|
|
|
//ftol = ftol_in;
|
|
|
|
|
ttol = ftol_in;
|
|
|
|
|
n1steps = n1steps_in;
|
|
|
|
|
n2steps = n2steps_in;
|
|
|
|
|
nevery = nevery_in;
|
|
|
|
|
@ -85,12 +86,10 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in,
|
|
|
|
|
uworld = universe->uworld;
|
|
|
|
|
MPI_Comm_rank(world,&me);
|
|
|
|
|
|
|
|
|
|
// generate linear interpolate replica
|
|
|
|
|
// fraction to interpolate intermediate replica
|
|
|
|
|
|
|
|
|
|
double fraction = ireplica/(nreplica-1.0);
|
|
|
|
|
|
|
|
|
|
double **x = atom->x;
|
|
|
|
|
// spin quantitites
|
|
|
|
|
double **sp = atom->sp;
|
|
|
|
|
int nlocal = atom->nlocal;
|
|
|
|
|
|
|
|
|
|
@ -111,19 +110,11 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in,
|
|
|
|
|
sp[i][1] = spfinal[1];
|
|
|
|
|
sp[i][2] = spfinal[2];
|
|
|
|
|
|
|
|
|
|
//delx = buf_final[ii] - buf_init[ii];
|
|
|
|
|
//dely = buf_final[ii+1] - buf_init[ii+1];
|
|
|
|
|
//delz = buf_final[ii+2] - buf_init[ii+2];
|
|
|
|
|
|
|
|
|
|
// adjust distance if pbc
|
|
|
|
|
// not implemented yet
|
|
|
|
|
//domain->minimum_image(delx,dely,delz);
|
|
|
|
|
|
|
|
|
|
// need to define a procedure for circular initialization
|
|
|
|
|
|
|
|
|
|
//x[i][0] = buf_init[ii] + fraction*delx;
|
|
|
|
|
//x[i][1] = buf_init[ii+1] + fraction*dely;
|
|
|
|
|
//x[i][2] = buf_init[ii+2] + fraction*delz;
|
|
|
|
|
// need to define a better procedure for circular initialization
|
|
|
|
|
|
|
|
|
|
ii += 3;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -143,22 +134,14 @@ NEB_spin::~NEB_spin()
|
|
|
|
|
|
|
|
|
|
void NEB_spin::command(int narg, char **arg)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//printf("test 1 \n");
|
|
|
|
|
|
|
|
|
|
// test 1
|
|
|
|
|
double **sp1 = atom->sp;
|
|
|
|
|
//printf("test 1 atom: i=%d,%g,%g,%g \n",1,sp1[1][0],sp1[1][1],sp1[1][2]);
|
|
|
|
|
//error->all(FLERR,"end neb_spin test");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (domain->box_exist == 0)
|
|
|
|
|
error->all(FLERR,"NEB_spin command before simulation box is defined");
|
|
|
|
|
|
|
|
|
|
if (narg < 6) error->universe_all(FLERR,"Illegal NEB_spin command");
|
|
|
|
|
|
|
|
|
|
etol = force->numeric(FLERR,arg[0]);
|
|
|
|
|
ftol = force->numeric(FLERR,arg[1]);
|
|
|
|
|
//ftol = force->numeric(FLERR,arg[1]);
|
|
|
|
|
ttol = force->numeric(FLERR,arg[1]);
|
|
|
|
|
n1steps = force->inumeric(FLERR,arg[2]);
|
|
|
|
|
n2steps = force->inumeric(FLERR,arg[3]);
|
|
|
|
|
nevery = force->inumeric(FLERR,arg[4]);
|
|
|
|
|
@ -166,7 +149,8 @@ void NEB_spin::command(int narg, char **arg)
|
|
|
|
|
// error checks
|
|
|
|
|
|
|
|
|
|
if (etol < 0.0) error->all(FLERR,"Illegal NEB_spin command");
|
|
|
|
|
if (ftol < 0.0) error->all(FLERR,"Illegal NEB_spin command");
|
|
|
|
|
//if (ftol < 0.0) error->all(FLERR,"Illegal NEB_spin command");
|
|
|
|
|
if (ttol < 0.0) error->all(FLERR,"Illegal NEB_spin command");
|
|
|
|
|
if (nevery <= 0) error->universe_all(FLERR,"Illegal NEB_spin command");
|
|
|
|
|
if (n1steps % nevery || n2steps % nevery)
|
|
|
|
|
error->universe_all(FLERR,"Illegal NEB_spin command");
|
|
|
|
|
@ -209,14 +193,6 @@ void NEB_spin::command(int narg, char **arg)
|
|
|
|
|
|
|
|
|
|
verbose=false;
|
|
|
|
|
if (strcmp(arg[narg-1],"verbose") == 0) verbose=true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// test 1
|
|
|
|
|
double **sp = atom->sp;
|
|
|
|
|
//printf("test 2 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]);
|
|
|
|
|
//error->all(FLERR,"end neb_spin test");
|
|
|
|
|
|
|
|
|
|
// run the NEB_spin calculation
|
|
|
|
|
|
|
|
|
|
run();
|
|
|
|
|
}
|
|
|
|
|
@ -250,22 +226,24 @@ void NEB_spin::run()
|
|
|
|
|
|
|
|
|
|
update->whichflag = 2;
|
|
|
|
|
update->etol = etol;
|
|
|
|
|
update->ftol = ftol;
|
|
|
|
|
//update->ftol = ftol;
|
|
|
|
|
update->ftol = ttol; // update->ftol is a torque tolerance
|
|
|
|
|
update->multireplica = 1;
|
|
|
|
|
|
|
|
|
|
lmp->init();
|
|
|
|
|
|
|
|
|
|
// put flag to check gilbert damping procedure is set
|
|
|
|
|
// check if correct minimizer is setup
|
|
|
|
|
|
|
|
|
|
//if (update->minimize->searchflag)
|
|
|
|
|
// error->all(FLERR,"NEB_spin requires damped dynamics minimizer");
|
|
|
|
|
if (update->minimize->searchflag)
|
|
|
|
|
error->all(FLERR,"NEB_spin requires damped dynamics minimizer");
|
|
|
|
|
if (strcmp(update->minimize_style,"spinmin") != 0)
|
|
|
|
|
error->all(FLERR,"NEB_spin requires spinmin minimizer");
|
|
|
|
|
|
|
|
|
|
// setup regular NEB_spin minimization
|
|
|
|
|
|
|
|
|
|
FILE *uscreen = universe->uscreen;
|
|
|
|
|
FILE *ulogfile = universe->ulogfile;
|
|
|
|
|
|
|
|
|
|
//printf("test before run 1 \n");
|
|
|
|
|
|
|
|
|
|
if (me_universe == 0 && uscreen)
|
|
|
|
|
fprintf(uscreen,"Setting up regular NEB_spin ...\n");
|
|
|
|
|
|
|
|
|
|
@ -276,22 +254,23 @@ void NEB_spin::run()
|
|
|
|
|
if (update->laststep < 0)
|
|
|
|
|
error->all(FLERR,"Too many timesteps for NEB_spin");
|
|
|
|
|
|
|
|
|
|
//printf("test before run 2 \n");
|
|
|
|
|
|
|
|
|
|
update->minimize->setup();
|
|
|
|
|
|
|
|
|
|
//printf("test before run 3 \n");
|
|
|
|
|
|
|
|
|
|
if (me_universe == 0) {
|
|
|
|
|
if (uscreen) {
|
|
|
|
|
if (verbose) {
|
|
|
|
|
fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce "
|
|
|
|
|
fprintf(uscreen,"Step MaxReplicaTorque MaxAtomTorque "
|
|
|
|
|
"GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... "
|
|
|
|
|
"RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 "
|
|
|
|
|
"ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 "
|
|
|
|
|
"... ReplicaForceN MaxAtomForceN\n");
|
|
|
|
|
"... ReplicaTorqueN MaxAtomTorqueN\n");
|
|
|
|
|
//fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce "
|
|
|
|
|
// "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... "
|
|
|
|
|
// "RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 "
|
|
|
|
|
// "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 "
|
|
|
|
|
// "... ReplicaForceN MaxAtomForceN\n");
|
|
|
|
|
} else {
|
|
|
|
|
fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce "
|
|
|
|
|
fprintf(uscreen,"Step MaxReplicaTorque MaxAtomTorque "
|
|
|
|
|
"GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... "
|
|
|
|
|
"RDN PEN\n");
|
|
|
|
|
}
|
|
|
|
|
@ -299,21 +278,19 @@ void NEB_spin::run()
|
|
|
|
|
|
|
|
|
|
if (ulogfile) {
|
|
|
|
|
if (verbose) {
|
|
|
|
|
fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce "
|
|
|
|
|
fprintf(ulogfile,"Step MaxReplicaTorque MaxAtomTorque "
|
|
|
|
|
"GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... "
|
|
|
|
|
"RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 "
|
|
|
|
|
"ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 "
|
|
|
|
|
"... ReplicaForceN MaxAtomForceN\n");
|
|
|
|
|
"... ReplicaTorqueN MaxAtomTorqueN\n");
|
|
|
|
|
} else {
|
|
|
|
|
fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce "
|
|
|
|
|
fprintf(ulogfile,"Step MaxReplicaTorque MaxAtomTorque "
|
|
|
|
|
"GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... "
|
|
|
|
|
"RDN PEN\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//printf("test before run 4 \n");
|
|
|
|
|
print_status();
|
|
|
|
|
//printf("test before run 5 \n");
|
|
|
|
|
|
|
|
|
|
// perform regular NEB_spin for n1steps or until replicas converge
|
|
|
|
|
// retrieve PE values from fix NEB_spin and print every nevery iterations
|
|
|
|
|
@ -323,35 +300,11 @@ void NEB_spin::run()
|
|
|
|
|
timer->init();
|
|
|
|
|
timer->barrier_start();
|
|
|
|
|
|
|
|
|
|
// test import fix_nve scheme
|
|
|
|
|
|
|
|
|
|
//printf("test 2 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]);
|
|
|
|
|
//error->all(FLERR,"end neb_spin test");
|
|
|
|
|
double dts;
|
|
|
|
|
while (update->minimize->niter < n1steps) {
|
|
|
|
|
//dts = evaluate_dt();
|
|
|
|
|
//advance_spins(dts);
|
|
|
|
|
//fneb->
|
|
|
|
|
|
|
|
|
|
//dts = fneb->evaluate_dt();
|
|
|
|
|
//fneb->advance_spins(dts);
|
|
|
|
|
|
|
|
|
|
// no minimizer for spins
|
|
|
|
|
update->minimize->run(nevery);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// no minimizer for spins
|
|
|
|
|
//update->minimize->run(nevery);
|
|
|
|
|
//
|
|
|
|
|
// evaluate dts
|
|
|
|
|
// loop on spins, damped advance
|
|
|
|
|
//
|
|
|
|
|
print_status();
|
|
|
|
|
if (update->minimize->stop_condition) break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// test neb end
|
|
|
|
|
//error->all(FLERR,"end neb_spin test");
|
|
|
|
|
|
|
|
|
|
timer->barrier_stop();
|
|
|
|
|
|
|
|
|
|
@ -393,22 +346,19 @@ void NEB_spin::run()
|
|
|
|
|
|
|
|
|
|
update->minimize->init();
|
|
|
|
|
fneb->rclimber = top;
|
|
|
|
|
printf("test print 6.2 \n");
|
|
|
|
|
update->minimize->setup();
|
|
|
|
|
|
|
|
|
|
printf("test print 6.3 \n");
|
|
|
|
|
|
|
|
|
|
if (me_universe == 0) {
|
|
|
|
|
if (uscreen) {
|
|
|
|
|
if (verbose) {
|
|
|
|
|
fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce "
|
|
|
|
|
fprintf(uscreen,"Step MaxReplicaTorque MaxAtomTorque "
|
|
|
|
|
"GradV0 GradV1 GradVc EBF EBR RDT "
|
|
|
|
|
"RD1 PE1 RD2 PE2 ... RDN PEN "
|
|
|
|
|
"pathangle1 angletangrad1 anglegrad1 gradV1 "
|
|
|
|
|
"ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 "
|
|
|
|
|
"... ReplicaForceN MaxAtomForceN\n");
|
|
|
|
|
} else {
|
|
|
|
|
fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce "
|
|
|
|
|
fprintf(uscreen,"Step MaxReplicaTorque MaxAtomTorque "
|
|
|
|
|
"GradV0 GradV1 GradVc "
|
|
|
|
|
"EBF EBR RDT "
|
|
|
|
|
"RD1 PE1 RD2 PE2 ... RDN PEN\n");
|
|
|
|
|
@ -416,14 +366,14 @@ void NEB_spin::run()
|
|
|
|
|
}
|
|
|
|
|
if (ulogfile) {
|
|
|
|
|
if (verbose) {
|
|
|
|
|
fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce "
|
|
|
|
|
fprintf(ulogfile,"Step MaxReplicaTorque MaxAtomTorque "
|
|
|
|
|
"GradV0 GradV1 GradVc EBF EBR RDT "
|
|
|
|
|
"RD1 PE1 RD2 PE2 ... RDN PEN "
|
|
|
|
|
"pathangle1 angletangrad1 anglegrad1 gradV1 "
|
|
|
|
|
"ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 "
|
|
|
|
|
"... ReplicaForceN MaxAtomForceN\n");
|
|
|
|
|
} else {
|
|
|
|
|
fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce "
|
|
|
|
|
fprintf(ulogfile,"Step MaxReplicaTorque MaxAtomTorque "
|
|
|
|
|
"GradV0 GradV1 GradVc "
|
|
|
|
|
"EBF EBR RDT "
|
|
|
|
|
"RD1 PE1 RD2 PE2 ... RDN PEN\n");
|
|
|
|
|
@ -441,10 +391,6 @@ void NEB_spin::run()
|
|
|
|
|
timer->barrier_start();
|
|
|
|
|
|
|
|
|
|
while (update->minimize->niter < n2steps) {
|
|
|
|
|
//dts = evaluate_dt();
|
|
|
|
|
//advance_spins(dts);
|
|
|
|
|
//dts = fneb->evaluate_dt();
|
|
|
|
|
//fneb->advance_spins(dts);
|
|
|
|
|
update->minimize->run(nevery);
|
|
|
|
|
print_status();
|
|
|
|
|
if (update->minimize->stop_condition) break;
|
|
|
|
|
@ -462,174 +408,6 @@ void NEB_spin::run()
|
|
|
|
|
update->beginstep = update->endstep = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
|
geodesic distance calculation (Vincenty's formula)
|
|
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
//double NEB_spin::geodesic_distance2(double spi[3], double spj[3])
|
|
|
|
|
//{
|
|
|
|
|
// double dist;
|
|
|
|
|
// double crossx,crossy,crossz;
|
|
|
|
|
// double dotx,doty,dotz;
|
|
|
|
|
// double crosslen,dots;
|
|
|
|
|
//
|
|
|
|
|
// crossx = spi[1]*spj[2]-spi[2]*spj[1];
|
|
|
|
|
// crossy = spi[2]*spj[0]-spi[0]*spj[2];
|
|
|
|
|
// crossz = spi[0]*spj[1]-spi[1]*spj[0];
|
|
|
|
|
// crosslen = sqrt(crossx*crossx + crossy*crossy + crossz*crossz);
|
|
|
|
|
// dotx = spi[0]*spj[0];
|
|
|
|
|
// doty = spi[1]*spj[1];
|
|
|
|
|
// dotz = spi[2]*spj[2];
|
|
|
|
|
// dots = dotx+doty+dotz;
|
|
|
|
|
//
|
|
|
|
|
// dist = atan2(crosslen,dots);
|
|
|
|
|
//
|
|
|
|
|
// return dist;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
|
evaluate max timestep
|
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
//double NEB_spin::evaluate_dt()
|
|
|
|
|
//{
|
|
|
|
|
// double dtmax;
|
|
|
|
|
// double fmsq;
|
|
|
|
|
// double fmaxsqone,fmaxsqloc,fmaxsqall;
|
|
|
|
|
// int nlocal = atom->nlocal;
|
|
|
|
|
// int *mask = atom->mask;
|
|
|
|
|
// double **fm = atom->fm;
|
|
|
|
|
//
|
|
|
|
|
// // finding max fm on this proc.
|
|
|
|
|
//
|
|
|
|
|
// fmsq = fmaxsqone = fmaxsqloc = fmaxsqall = 0.0;
|
|
|
|
|
// for (int i = 0; i < nlocal; i++)
|
|
|
|
|
// if (mask[i] & groupbit) {
|
|
|
|
|
// fmsq = fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2];
|
|
|
|
|
// fmaxsqone = MAX(fmaxsqone,fmsq);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // finding max fm on this replica
|
|
|
|
|
//
|
|
|
|
|
// fmaxsqloc = fmaxsqone;
|
|
|
|
|
// MPI_Allreduce(&fmaxsqone,&fmaxsqloc,1,MPI_DOUBLE,MPI_MAX,world);
|
|
|
|
|
//
|
|
|
|
|
// // finding max fm over all replicas, if necessary
|
|
|
|
|
// // this communicator would be invalid for multiprocess replicas
|
|
|
|
|
//
|
|
|
|
|
// if (update->multireplica == 1) {
|
|
|
|
|
// fmaxsqall = fmaxsqloc;
|
|
|
|
|
// MPI_Allreduce(&fmaxsqloc,&fmaxsqall,1,MPI_DOUBLE,MPI_MAX,universe->uworld);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (fmaxsqall < fmaxsqloc)
|
|
|
|
|
// error->all(FLERR,"Incorrect fmaxall calc.");
|
|
|
|
|
//
|
|
|
|
|
// // define max timestep
|
|
|
|
|
// // dividing by 10 the inverse of max frequency
|
|
|
|
|
//
|
|
|
|
|
// dtmax = MY_2PI/(10.0*sqrt(fmaxsqall));
|
|
|
|
|
//
|
|
|
|
|
// return dtmax;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
|
geometric damped advance os spins
|
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
//void NEB_spin::advance_spins(double dts)
|
|
|
|
|
//{
|
|
|
|
|
// //int j=0;
|
|
|
|
|
// //int *sametag = atom->sametag;
|
|
|
|
|
// int nlocal = atom->nlocal;
|
|
|
|
|
// int *mask = atom->mask;
|
|
|
|
|
// double **sp = atom->sp;
|
|
|
|
|
// double **fm = atom->fm;
|
|
|
|
|
// double tdampx,tdampy,tdampz;
|
|
|
|
|
// double msq,scale,fm2,energy,dts2;
|
|
|
|
|
// double alpha;
|
|
|
|
|
// double spi[3],fmi[3];
|
|
|
|
|
// double cp[3],g[3];
|
|
|
|
|
//
|
|
|
|
|
// //cp[0] = cp[1] = cp[2] = 0.0;
|
|
|
|
|
// //g[0] = g[1] = g[2] = 0.0;
|
|
|
|
|
// dts2 = dts*dts;
|
|
|
|
|
//
|
|
|
|
|
// // fictitious Gilbert damping of 1
|
|
|
|
|
// alpha = 1.0;
|
|
|
|
|
//
|
|
|
|
|
// // loop on all spins on proc.
|
|
|
|
|
//
|
|
|
|
|
// if (ireplica != nreplica-1 && ireplica != 0)
|
|
|
|
|
// for (int i = 0; i < nlocal; i++)
|
|
|
|
|
// if (mask[i] & groupbit) {
|
|
|
|
|
//
|
|
|
|
|
// spi[0] = sp[i][0];
|
|
|
|
|
// spi[1] = sp[i][1];
|
|
|
|
|
// spi[2] = sp[i][2];
|
|
|
|
|
//
|
|
|
|
|
// fmi[0] = fm[i][0];
|
|
|
|
|
// fmi[1] = fm[i][1];
|
|
|
|
|
// fmi[2] = fm[i][2];
|
|
|
|
|
//
|
|
|
|
|
// // calc. damping torque
|
|
|
|
|
//
|
|
|
|
|
// tdampx = -alpha*(fmi[1]*spi[2] - fmi[2]*spi[1]);
|
|
|
|
|
// tdampy = -alpha*(fmi[2]*spi[0] - fmi[0]*spi[2]);
|
|
|
|
|
// tdampz = -alpha*(fmi[0]*spi[1] - fmi[1]*spi[0]);
|
|
|
|
|
//
|
|
|
|
|
// // apply advance algorithm (geometric, norm preserving)
|
|
|
|
|
//
|
|
|
|
|
// fm2 = (tdampx*tdampx+tdampy*tdampy+tdampz*tdampz);
|
|
|
|
|
// energy = (sp[i][0]*tdampx)+(sp[i][1]*tdampy)+(sp[i][2]*tdampz);
|
|
|
|
|
//
|
|
|
|
|
// cp[0] = tdampy*sp[i][2]-tdampz*sp[i][1];
|
|
|
|
|
// cp[1] = tdampz*sp[i][0]-tdampx*sp[i][2];
|
|
|
|
|
// cp[2] = tdampx*sp[i][1]-tdampy*sp[i][0];
|
|
|
|
|
//
|
|
|
|
|
// g[0] = sp[i][0]+cp[0]*dts;
|
|
|
|
|
// g[1] = sp[i][1]+cp[1]*dts;
|
|
|
|
|
// g[2] = sp[i][2]+cp[2]*dts;
|
|
|
|
|
//
|
|
|
|
|
// g[0] += (fm[i][0]*energy-0.5*sp[i][0]*fm2)*0.5*dts2;
|
|
|
|
|
// g[1] += (fm[i][1]*energy-0.5*sp[i][1]*fm2)*0.5*dts2;
|
|
|
|
|
// g[2] += (fm[i][2]*energy-0.5*sp[i][2]*fm2)*0.5*dts2;
|
|
|
|
|
//
|
|
|
|
|
// g[0] /= (1+0.25*fm2*dts2);
|
|
|
|
|
// g[1] /= (1+0.25*fm2*dts2);
|
|
|
|
|
// g[2] /= (1+0.25*fm2*dts2);
|
|
|
|
|
//
|
|
|
|
|
// sp[i][0] = g[0];
|
|
|
|
|
// sp[i][1] = g[1];
|
|
|
|
|
// sp[i][2] = g[2];
|
|
|
|
|
//
|
|
|
|
|
// // renormalization (check if necessary)
|
|
|
|
|
//
|
|
|
|
|
// msq = g[0]*g[0] + g[1]*g[1] + g[2]*g[2];
|
|
|
|
|
// scale = 1.0/sqrt(msq);
|
|
|
|
|
// sp[i][0] *= scale;
|
|
|
|
|
// sp[i][1] *= scale;
|
|
|
|
|
// sp[i][2] *= scale;
|
|
|
|
|
//
|
|
|
|
|
// // comm. sp[i] to atoms with same tag (for serial algo)
|
|
|
|
|
//
|
|
|
|
|
// // no need for simplecticity
|
|
|
|
|
// //if (sector_flag == 0) {
|
|
|
|
|
// // if (sametag[i] >= 0) {
|
|
|
|
|
// // j = sametag[i];
|
|
|
|
|
// // while (j >= 0) {
|
|
|
|
|
// // sp[j][0] = sp[i][0];
|
|
|
|
|
// // sp[j][1] = sp[i][1];
|
|
|
|
|
// // sp[j][2] = sp[i][2];
|
|
|
|
|
// // j = sametag[j];
|
|
|
|
|
// // }
|
|
|
|
|
// // }
|
|
|
|
|
// //}
|
|
|
|
|
// //
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
|
read initial config atom coords from file
|
|
|
|
|
flag = 0
|
|
|
|
|
@ -654,7 +432,6 @@ void NEB_spin::readfile(char *file, int flag)
|
|
|
|
|
double xx,yy,zz,delx,dely,delz;
|
|
|
|
|
// spin quantities
|
|
|
|
|
double musp,spx,spy,spz;
|
|
|
|
|
//,delx,dely,delz;
|
|
|
|
|
|
|
|
|
|
if (me_universe == 0 && screen)
|
|
|
|
|
fprintf(screen,"Reading NEB_spin coordinate file(s) ...\n");
|
|
|
|
|
@ -703,12 +480,6 @@ void NEB_spin::readfile(char *file, int flag)
|
|
|
|
|
double spinit[3],spfinal[3];
|
|
|
|
|
int nlocal = atom->nlocal;
|
|
|
|
|
|
|
|
|
|
// test 1.2
|
|
|
|
|
//double **sp = atom->sp;
|
|
|
|
|
//printf("test 1.2 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]);
|
|
|
|
|
//error->all(FLERR,"end neb_spin test");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// loop over chunks of lines read from file
|
|
|
|
|
// two versions of read_lines_from_file() for world vs universe bcast
|
|
|
|
|
// count # of atom coords changed so can check for invalid atom IDs in file
|
|
|
|
|
@ -765,44 +536,27 @@ void NEB_spin::readfile(char *file, int flag)
|
|
|
|
|
spx = atof(values[5]);
|
|
|
|
|
spy = atof(values[6]);
|
|
|
|
|
spz = atof(values[7]);
|
|
|
|
|
//xx = atof(values[1]);
|
|
|
|
|
//yy = atof(values[2]);
|
|
|
|
|
//zz = atof(values[3]);
|
|
|
|
|
|
|
|
|
|
if (flag == 0) {
|
|
|
|
|
|
|
|
|
|
// here, function interp. spin states
|
|
|
|
|
|
|
|
|
|
//spinit[0] = x[m][0];
|
|
|
|
|
//spinit[1] = x[m][1];
|
|
|
|
|
//spinit[2] = x[m][2];
|
|
|
|
|
spinit[0] = sp[m][0];
|
|
|
|
|
spinit[1] = sp[m][1];
|
|
|
|
|
spinit[2] = sp[m][2];
|
|
|
|
|
spfinal[0] = spx;
|
|
|
|
|
spfinal[1] = spy;
|
|
|
|
|
spfinal[2] = spz;
|
|
|
|
|
//domain->minimum_image(delx,dely,delz);
|
|
|
|
|
|
|
|
|
|
// to be used it atomic displacements with pbc
|
|
|
|
|
//domain->minimum_image(delx,dely,delz);
|
|
|
|
|
|
|
|
|
|
// test
|
|
|
|
|
//printf("spinit: %g %g %g \n",spinit[0],spinit[1],spinit[2]);
|
|
|
|
|
//printf("spfinal bef: %g %g %g \n",spfinal[0],spfinal[1],spfinal[2]);
|
|
|
|
|
// interpolate intermediate spin states
|
|
|
|
|
|
|
|
|
|
initial_rotation(spinit,spfinal,fraction);
|
|
|
|
|
|
|
|
|
|
// test
|
|
|
|
|
//printf("spfinal aft: %g %g %g \n",spfinal[0],spfinal[1],spfinal[2]);
|
|
|
|
|
|
|
|
|
|
sp[m][0] = spfinal[0];
|
|
|
|
|
sp[m][1] = spfinal[1];
|
|
|
|
|
sp[m][2] = spfinal[2];
|
|
|
|
|
sp[m][3] = musp;
|
|
|
|
|
//delx = xx - x[m][0];
|
|
|
|
|
//dely = yy - x[m][1];
|
|
|
|
|
//delz = zz - x[m][2];
|
|
|
|
|
//x[m][0] += fraction*delx;
|
|
|
|
|
//x[m][1] += fraction*dely;
|
|
|
|
|
//x[m][2] += fraction*delz;
|
|
|
|
|
} else {
|
|
|
|
|
sp[m][3] = musp;
|
|
|
|
|
x[m][0] = xx;
|
|
|
|
|
@ -820,12 +574,6 @@ void NEB_spin::readfile(char *file, int flag)
|
|
|
|
|
nread += nchunk;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// test 1.3
|
|
|
|
|
//double **sp = atom->sp;
|
|
|
|
|
//printf("test 1.3 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]);
|
|
|
|
|
//error->all(FLERR,"end neb_spin test");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check that all atom IDs in file were found by a proc
|
|
|
|
|
|
|
|
|
|
if (flag == 0) {
|
|
|
|
|
@ -867,13 +615,11 @@ void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// implementing initial rotation using atan2
|
|
|
|
|
//atan2(crosslen,dots);
|
|
|
|
|
|
|
|
|
|
// this is not a sufficient routine,
|
|
|
|
|
// we need more accurate verifications
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// initial and final and inter ang. values
|
|
|
|
|
// initial, final and inter ang. values
|
|
|
|
|
double itheta,iphi,ftheta,fphi,ktheta,kphi;
|
|
|
|
|
double spix,spiy,spiz,spfx,spfy,spfz;
|
|
|
|
|
double spkx,spky,spkz,iknorm;
|
|
|
|
|
@ -909,58 +655,6 @@ void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction)
|
|
|
|
|
sploc[1] = spky;
|
|
|
|
|
sploc[2] = spkz;
|
|
|
|
|
|
|
|
|
|
//double theta,spdot;
|
|
|
|
|
//double inormdot,ispinorm;
|
|
|
|
|
//double kix,kiy,kiz;
|
|
|
|
|
//double kinorm, ikinorm;
|
|
|
|
|
//double crossx,crossy,crossz;
|
|
|
|
|
|
|
|
|
|
////printf("inside rot, spi %g, spf %g \n",spi[0],sploc[0]);
|
|
|
|
|
|
|
|
|
|
//spdot = spi[0]*sploc[0]+spi[1]*sploc[1]+spi[2]*sploc[2];
|
|
|
|
|
//theta = fraction*acos(spdot);
|
|
|
|
|
|
|
|
|
|
//printf("inside rot, theta %g \n",theta);
|
|
|
|
|
|
|
|
|
|
//kix = spi[1]*sploc[2]-spi[2]*sploc[1];
|
|
|
|
|
//kiy = spi[2]*sploc[0]-spi[0]*sploc[2];
|
|
|
|
|
//kiz = spi[0]*sploc[1]-spi[1]*sploc[0];
|
|
|
|
|
//
|
|
|
|
|
////printf("inside rot1.1, ki %g %g %g \n",kix,kiy,kiz);
|
|
|
|
|
|
|
|
|
|
//inormdot = 1.0/sqrt(spdot);
|
|
|
|
|
//kinorm = kix*kix+kiy*kiy+kiz*kiz;
|
|
|
|
|
//if (kinorm == 0.0) {
|
|
|
|
|
// kix = 0.0;
|
|
|
|
|
// kiy = 0.0;
|
|
|
|
|
// kiz = 0.0;
|
|
|
|
|
//} else {
|
|
|
|
|
// ikinorm = 1.0/kinorm;
|
|
|
|
|
// kix *= ikinorm;
|
|
|
|
|
// kiy *= ikinorm;
|
|
|
|
|
// kiz *= ikinorm;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
////printf("inside rot1.2, kin %g %g %g \n",kix,kiy,kiz);
|
|
|
|
|
|
|
|
|
|
//crossx = kiy*spi[2]-kiz*spi[1];
|
|
|
|
|
//crossy = kiz*spi[0]-kix*spi[2];
|
|
|
|
|
//crossz = kix*spi[1]-kiy*spi[0];
|
|
|
|
|
//
|
|
|
|
|
////printf("inside rot1.3, cross %g %g %g \n",crossx,crossy,crossz);
|
|
|
|
|
|
|
|
|
|
//sploc[0] = spi[0]*cos(theta)+crossx*sin(theta);
|
|
|
|
|
//sploc[1] = spi[1]*cos(theta)+crossy*sin(theta);
|
|
|
|
|
//sploc[2] = spi[2]*cos(theta)+crossz*sin(theta);
|
|
|
|
|
//
|
|
|
|
|
////printf("inside rot2, spf %g %g %g \n",sploc[0],sploc[1],sploc[2]);
|
|
|
|
|
|
|
|
|
|
//ispinorm = 1.0/sqrt(sploc[0]*sploc[0]+sploc[1]*sploc[1]+sploc[2]*sploc[2]);
|
|
|
|
|
|
|
|
|
|
//sploc[0] *= ispinorm;
|
|
|
|
|
//sploc[1] *= ispinorm;
|
|
|
|
|
//sploc[2] *= ispinorm;
|
|
|
|
|
//printf("inside rot2, spf %g %g %g \n",sploc[0],sploc[1],sploc[2]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
|
@ -1007,30 +701,43 @@ void NEB_spin::print_status()
|
|
|
|
|
|
|
|
|
|
//double fnorm2 = sqrt(update->minimize->fnorm_sqr());
|
|
|
|
|
|
|
|
|
|
// test fmax spin
|
|
|
|
|
int nlocal = atom->nlocal;
|
|
|
|
|
double tx,ty,tz;
|
|
|
|
|
double tnorm2,local_norm_inf,temp_inf;
|
|
|
|
|
double **sp = atom->sp;
|
|
|
|
|
double **fm = atom->fm;
|
|
|
|
|
double fnorm2;
|
|
|
|
|
for (int i = 0; i < nlocal; i++)
|
|
|
|
|
fnorm2 += (fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]);
|
|
|
|
|
//for (int i = 0; i < nlocal; i++)
|
|
|
|
|
// if (mask[i] & groupbit) {
|
|
|
|
|
// fnorm2 += (fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// calc. magnetic torques
|
|
|
|
|
|
|
|
|
|
tnorm2 = local_norm_inf = temp_inf = 0.0;
|
|
|
|
|
for (int i = 0; i < nlocal; i++) {
|
|
|
|
|
tx = (fm[i][1]*sp[i][2] - fm[i][2]*sp[i][1]);
|
|
|
|
|
ty = (fm[i][2]*sp[i][0] - fm[i][0]*sp[i][2]);
|
|
|
|
|
tz = (fm[i][0]*sp[i][1] - fm[i][1]*sp[i][0]);
|
|
|
|
|
tnorm2 += tx*tx + ty*ty + tz*tz;
|
|
|
|
|
|
|
|
|
|
temp_inf = MAX(fabs(tx),fabs(ty));
|
|
|
|
|
temp_inf = MAX(fabs(tz),temp_inf);
|
|
|
|
|
local_norm_inf = MAX(temp_inf,local_norm_inf);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double fmaxreplica;
|
|
|
|
|
MPI_Allreduce(&fnorm2,&fmaxreplica,1,MPI_DOUBLE,MPI_MAX,roots);
|
|
|
|
|
//MPI_Allreduce(&fnorm2,&fmaxreplica,1,MPI_DOUBLE,MPI_MAX,roots);
|
|
|
|
|
MPI_Allreduce(&tnorm2,&fmaxreplica,1,MPI_DOUBLE,MPI_MAX,roots);
|
|
|
|
|
|
|
|
|
|
// no minimize->fnorm_inf for spins
|
|
|
|
|
//double fnorminf = update->minimize->fnorm_inf();
|
|
|
|
|
//double fmaxatom;
|
|
|
|
|
//MPI_Allreduce(&fnorminf,&fmaxatom,1,MPI_DOUBLE,MPI_MAX,roots);
|
|
|
|
|
double fnorminf = 0.0;
|
|
|
|
|
double fmaxatom = 0.0;
|
|
|
|
|
MPI_Allreduce(&local_norm_inf,&fnorminf,1,MPI_DOUBLE,MPI_MAX,world);
|
|
|
|
|
double fmaxatom;
|
|
|
|
|
MPI_Allreduce(&fnorminf,&fmaxatom,1,MPI_DOUBLE,MPI_MAX,roots);
|
|
|
|
|
|
|
|
|
|
if (verbose) {
|
|
|
|
|
freplica = new double[nreplica];
|
|
|
|
|
MPI_Allgather(&fnorm2,1,MPI_DOUBLE,&freplica[0],1,MPI_DOUBLE,roots);
|
|
|
|
|
//MPI_Allgather(&fnorm2,1,MPI_DOUBLE,&freplica[0],1,MPI_DOUBLE,roots);
|
|
|
|
|
MPI_Allgather(&tnorm2,1,MPI_DOUBLE,&freplica[0],1,MPI_DOUBLE,roots);
|
|
|
|
|
fmaxatomInRepl = new double[nreplica];
|
|
|
|
|
MPI_Allgather(&fnorminf,1,MPI_DOUBLE,&fmaxatomInRepl[0],1,MPI_DOUBLE,roots);
|
|
|
|
|
}
|
|
|
|
|
|