diff --git a/src/ASPHERE/compute_temp_asphere.cpp b/src/ASPHERE/compute_temp_asphere.cpp index 48b443f04..0f2fea035 100755 --- a/src/ASPHERE/compute_temp_asphere.cpp +++ b/src/ASPHERE/compute_temp_asphere.cpp @@ -1,401 +1,401 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Mike Brown (SNL) ------------------------------------------------------------------------- */ #include "mpi.h" #include "string.h" #include "compute_temp_asphere.h" #include "math_extra.h" #include "atom.h" #include "atom_vec_ellipsoid.h" #include "update.h" #include "force.h" #include "domain.h" #include "modify.h" #include "group.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; enum{ROTATE,ALL}; #define INERTIA 0.2 // moment of inertia prefactor for ellipsoid /* ---------------------------------------------------------------------- */ ComputeTempAsphere::ComputeTempAsphere(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (narg < 3) error->all(FLERR,"Illegal compute temp/asphere command"); scalar_flag = vector_flag = 1; size_vector = 6; extscalar = 0; extvector = 1; tempflag = 1; tempbias = 0; id_bias = NULL; mode = ALL; int iarg = 3; while (iarg < narg) { if (strcmp(arg[iarg],"bias") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal compute temp/asphere command"); tempbias = 1; int n = strlen(arg[iarg+1]) + 1; id_bias = new char[n]; strcpy(id_bias,arg[iarg+1]); iarg += 2; } else if (strcmp(arg[iarg],"dof") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal compute temp/asphere command"); if (strcmp(arg[iarg+1],"rotate") == 0) mode = ROTATE; else if (strcmp(arg[iarg+1],"all") == 0) mode = ALL; else error->all(FLERR,"Illegal compute temp/asphere command"); iarg += 2; } else error->all(FLERR,"Illegal compute temp/asphere command"); } vector = new double[6]; } /* ---------------------------------------------------------------------- */ ComputeTempAsphere::~ComputeTempAsphere() { delete [] id_bias; delete [] vector; } /* ---------------------------------------------------------------------- */ void ComputeTempAsphere::init() { // error check avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); if (!avec) error->all(FLERR,"Compute temp/asphere requires atom style ellipsoid"); // check that all particles are finite-size, no point particles allowed int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) if (ellipsoid[i] < 0) error->one(FLERR,"Compute temp/asphere requires extended particles"); if (tempbias) { int i = modify->find_compute(id_bias); if (i < 0) error->all(FLERR,"Could not find compute ID for temperature bias"); tbias = modify->compute[i]; if (tbias->tempflag == 0) error->all(FLERR,"Bias compute does not calculate temperature"); if (tbias->tempbias == 0) error->all(FLERR,"Bias compute does not calculate a velocity bias"); if (tbias->igroup != igroup) error->all(FLERR,"Bias compute group does not match compute group"); if (strcmp(tbias->style,"temp/region") == 0) tempbias = 2; else tempbias = 1; // init and setup bias compute because // this compute's setup()->dof_compute() may be called first tbias->init(); tbias->setup(); } } /* ---------------------------------------------------------------------- */ void ComputeTempAsphere::setup() { dynamic = 0; if (dynamic_user || group->dynamic[igroup]) dynamic = 1; dof_compute(); } /* ---------------------------------------------------------------------- */ void ComputeTempAsphere::dof_compute() { adjust_dof_fix(); // 6 dof for 3d, 3 dof for 2d // which dof are included also depends on mode // assume full rotation of extended particles // user should correct this via compute_modify if needed - double natoms = group->count(igroup); + natoms_temp = group->count(igroup); int nper; if (domain->dimension == 3) { if (mode == ALL) nper = 6; else nper = 3; } else { if (mode == ALL) nper = 3; else nper = 1; } - dof = nper*natoms; + dof = nper*natoms_temp; // additional adjustments to dof if (tempbias == 1) { - if (mode == ALL) dof -= tbias->dof_remove(-1) * natoms; + if (mode == ALL) dof -= tbias->dof_remove(-1) * natoms_temp; } else if (tempbias == 2) { int *mask = atom->mask; int nlocal = atom->nlocal; tbias->dof_remove_pre(); int count = 0; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) if (tbias->dof_remove(i)) count++; int count_all; MPI_Allreduce(&count,&count_all,1,MPI_INT,MPI_SUM,world); dof -= nper*count_all; } dof -= extra_dof + fix_dof; - if (dof < 0.0 && natoms > 0.0) - error->all(FLERR,"Temperature compute degrees of freedom < 0"); if (dof > 0) tfactor = force->mvv2e / (dof * force->boltz); else tfactor = 0.0; } /* ---------------------------------------------------------------------- */ double ComputeTempAsphere::compute_scalar() { invoked_scalar = update->ntimestep; if (tempbias) { if (tbias->invoked_scalar != update->ntimestep) tbias->compute_scalar(); tbias->remove_bias_all(); } AtomVecEllipsoid::Bonus *bonus = avec->bonus; double **v = atom->v; double **angmom = atom->angmom; double *rmass = atom->rmass; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; double *shape,*quat; double wbody[3],inertia[3]; double rot[3][3]; // sum translational and rotational energy for each particle // no point particles since divide by inertia double t = 0.0; if (mode == ALL) { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { t += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) * rmass[i]; // principal moments of inertia shape = bonus[ellipsoid[i]].shape; quat = bonus[ellipsoid[i]].quat; inertia[0] = INERTIA*rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]); inertia[1] = INERTIA*rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]); inertia[2] = INERTIA*rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]); // wbody = angular velocity in body frame MathExtra::quat_to_mat(quat,rot); MathExtra::transpose_matvec(rot,angmom[i],wbody); wbody[0] /= inertia[0]; wbody[1] /= inertia[1]; wbody[2] /= inertia[2]; t += inertia[0]*wbody[0]*wbody[0] + inertia[1]*wbody[1]*wbody[1] + inertia[2]*wbody[2]*wbody[2]; } } else { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { // principal moments of inertia shape = bonus[ellipsoid[i]].shape; quat = bonus[ellipsoid[i]].quat; inertia[0] = INERTIA*rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]); inertia[1] = INERTIA*rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]); inertia[2] = INERTIA*rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]); // wbody = angular velocity in body frame MathExtra::quat_to_mat(quat,rot); MathExtra::transpose_matvec(rot,angmom[i],wbody); wbody[0] /= inertia[0]; wbody[1] /= inertia[1]; wbody[2] /= inertia[2]; t += inertia[0]*wbody[0]*wbody[0] + inertia[1]*wbody[1]*wbody[1] + inertia[2]*wbody[2]*wbody[2]; } } if (tempbias) tbias->restore_bias_all(); MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world); if (dynamic || tempbias == 2) dof_compute(); + if (dof < 0.0 && natoms_temp > 0.0) + error->all(FLERR,"Temperature compute degrees of freedom < 0"); scalar *= tfactor; return scalar; } /* ---------------------------------------------------------------------- */ void ComputeTempAsphere::compute_vector() { int i; invoked_vector = update->ntimestep; if (tempbias) { if (tbias->invoked_vector != update->ntimestep) tbias->compute_vector(); tbias->remove_bias_all(); } AtomVecEllipsoid::Bonus *bonus = avec->bonus; double **v = atom->v; double **angmom = atom->angmom; double *rmass = atom->rmass; int *ellipsoid = atom->ellipsoid; int *mask = atom->mask; int nlocal = atom->nlocal; double *shape,*quat; double wbody[3],inertia[3],t[6]; double rot[3][3]; double massone; // sum translational and rotational energy for each particle // no point particles since divide by inertia for (i = 0; i < 6; i++) t[i] = 0.0; if (mode == ALL) { for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) { massone = rmass[i]; t[0] += massone * v[i][0]*v[i][0]; t[1] += massone * v[i][1]*v[i][1]; t[2] += massone * v[i][2]*v[i][2]; t[3] += massone * v[i][0]*v[i][1]; t[4] += massone * v[i][0]*v[i][2]; t[5] += massone * v[i][1]*v[i][2]; // principal moments of inertia shape = bonus[ellipsoid[i]].shape; quat = bonus[ellipsoid[i]].quat; inertia[0] = INERTIA*massone * (shape[1]*shape[1]+shape[2]*shape[2]); inertia[1] = INERTIA*massone * (shape[0]*shape[0]+shape[2]*shape[2]); inertia[2] = INERTIA*massone * (shape[0]*shape[0]+shape[1]*shape[1]); // wbody = angular velocity in body frame MathExtra::quat_to_mat(quat,rot); MathExtra::transpose_matvec(rot,angmom[i],wbody); wbody[0] /= inertia[0]; wbody[1] /= inertia[1]; wbody[2] /= inertia[2]; // rotational kinetic energy t[0] += inertia[0]*wbody[0]*wbody[0]; t[1] += inertia[1]*wbody[1]*wbody[1]; t[2] += inertia[2]*wbody[2]*wbody[2]; t[3] += inertia[0]*wbody[0]*wbody[1]; t[4] += inertia[1]*wbody[0]*wbody[2]; t[5] += inertia[2]*wbody[1]*wbody[2]; } } else { for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) { // principal moments of inertia shape = bonus[ellipsoid[i]].shape; quat = bonus[ellipsoid[i]].quat; massone = rmass[i]; inertia[0] = INERTIA*massone * (shape[1]*shape[1]+shape[2]*shape[2]); inertia[1] = INERTIA*massone * (shape[0]*shape[0]+shape[2]*shape[2]); inertia[2] = INERTIA*massone * (shape[0]*shape[0]+shape[1]*shape[1]); // wbody = angular velocity in body frame MathExtra::quat_to_mat(quat,rot); MathExtra::transpose_matvec(rot,angmom[i],wbody); wbody[0] /= inertia[0]; wbody[1] /= inertia[1]; wbody[2] /= inertia[2]; // rotational kinetic energy t[0] += inertia[0]*wbody[0]*wbody[0]; t[1] += inertia[1]*wbody[1]*wbody[1]; t[2] += inertia[2]*wbody[2]*wbody[2]; t[3] += inertia[0]*wbody[0]*wbody[1]; t[4] += inertia[1]*wbody[0]*wbody[2]; t[5] += inertia[2]*wbody[1]*wbody[2]; } } if (tempbias) tbias->restore_bias_all(); MPI_Allreduce(t,vector,6,MPI_DOUBLE,MPI_SUM,world); for (i = 0; i < 6; i++) vector[i] *= force->mvv2e; } /* ---------------------------------------------------------------------- remove velocity bias from atom I to leave thermal velocity ------------------------------------------------------------------------- */ void ComputeTempAsphere::remove_bias(int i, double *v) { if (tbias) tbias->remove_bias(i,v); } /* ---------------------------------------------------------------------- add back in velocity bias to atom I removed by remove_bias() assume remove_bias() was previously called ------------------------------------------------------------------------- */ void ComputeTempAsphere::restore_bias(int i, double *v) { if (tbias) tbias->restore_bias(i,v); } diff --git a/src/CORESHELL/compute_temp_cs.cpp b/src/CORESHELL/compute_temp_cs.cpp index 807a132e9..cd577291f 100644 --- a/src/CORESHELL/compute_temp_cs.cpp +++ b/src/CORESHELL/compute_temp_cs.cpp @@ -1,499 +1,499 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Hendrik Heenen (Technical University of Munich) (hendrik.heenen at mytum.com) ------------------------------------------------------------------------- */ #include "mpi.h" #include "stdlib.h" #include "string.h" #include "math.h" #include "compute_temp_cs.h" #include "atom.h" #include "atom_vec.h" #include "domain.h" #include "update.h" #include "force.h" #include "group.h" #include "modify.h" #include "fix.h" #include "fix_store.h" #include "comm.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputeTempCS::ComputeTempCS(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (narg != 5) error->all(FLERR,"Illegal compute temp/cs command"); if (atom->avec->bonds_allow == 0) error->all(FLERR,"Compute temp/cs used when bonds are not allowed"); scalar_flag = vector_flag = 1; size_vector = 6; extscalar = 0; extvector = 1; tempflag = 1; tempbias = 1; extarray = 0; // find and define groupbits for core and shell groups cgroup = group->find(arg[3]); if (cgroup == -1) error->all(FLERR,"Cannot find specified group ID for core particles"); groupbit_c = group->bitmask[cgroup]; sgroup = group->find(arg[4]); if (sgroup == -1) error->all(FLERR,"Cannot find specified group ID for shell particles"); groupbit_s = group->bitmask[sgroup]; // create a new fix STORE style // id = compute-ID + COMPUTE_STORE, fix group = compute group int n = strlen(id) + strlen("_COMPUTE_STORE") + 1; id_fix = new char[n]; strcpy(id_fix,id); strcat(id_fix,"_COMPUTE_STORE"); char **newarg = new char*[5]; newarg[0] = id_fix; newarg[1] = group->names[igroup]; newarg[2] = (char *) "STORE"; newarg[3] = (char *) "0"; newarg[4] = (char *) "1"; modify->add_fix(5,newarg); fix = (FixStore *) modify->fix[modify->nfix-1]; delete [] newarg; // set fix store values = 0 for now // fill them in via setup() once Comm::borders() has been called // skip if resetting from restart file if (fix->restart_reset) { fix->restart_reset = 0; firstflag = 0; } else { double *partner = fix->vstore; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) partner[i] = ubuf(0).d; firstflag = 1; } // allocate memory vector = new double[6]; maxatom = 0; vint = NULL; // set comm size needed by this Compute comm_reverse = 1; } /* ---------------------------------------------------------------------- */ ComputeTempCS::~ComputeTempCS() { // check nfix in case all fixes have already been deleted if (modify->nfix) modify->delete_fix(id_fix); delete [] id_fix; delete [] vector; memory->destroy(vint); } /* ---------------------------------------------------------------------- */ void ComputeTempCS::init() { if (comm->ghost_velocity == 0) error->all(FLERR,"Compute temp/cs requires ghost atoms store velocity"); } /* ---------------------------------------------------------------------- */ void ComputeTempCS::setup() { if (firstflag) { firstflag = 0; // insure # of core atoms = # of shell atoms int ncores = group->count(cgroup); nshells = group->count(sgroup); if (ncores != nshells) error->all(FLERR,"Number of core atoms != number of shell atoms"); // for each C/S pair: // set partner IDs of both atoms if this atom stores bond between them // will set partner IDs for ghost atoms if needed by another proc // nall loop insures all ghost atom partner IDs are set before reverse comm int *num_bond = atom->num_bond; tagint **bond_atom = atom->bond_atom; tagint *tag = atom->tag; int *mask = atom->mask; int nlocal = atom->nlocal; double *partner = fix->vstore; tagint partnerID; int nall = nlocal + atom->nghost; for (int i = nlocal; i < nall; i++) partner[i] = ubuf(0).d; int i,j,m,match; for (i = 0; i < nlocal; i++) { if (mask[i] & groupbit_c || mask[i] & groupbit_s) { for (m = 0; m < num_bond[i]; m++) { partnerID = bond_atom[i][m]; j = atom->map(partnerID); if (j == -1) error->one(FLERR,"Core/shell partner atom not found"); match = 0; if (mask[i] & groupbit_c && mask[j] & groupbit_s) match = 1; if (mask[i] & groupbit_s && mask[j] & groupbit_c) match = 1; if (match) { partner[i] = ubuf(partnerID).d; partner[j] = ubuf(tag[i]).d; } } } } // reverse comm to acquire unknown partner IDs from ghost atoms // only needed if newton_bond = on if (force->newton_bond) comm->reverse_comm_compute(this); // check that all C/S partners were found int flag = 0; for (i = 0; i < nlocal; i++) { if (mask[i] & groupbit_c || mask[i] & groupbit_s) { partnerID = (tagint) ubuf(partner[i]).i; if (partnerID == 0) flag = 1; } } int flagall; MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); if (flagall) error->all(FLERR,"Core/shell partners were not all found"); } // calculate DOF for temperature dof_compute(); } /* ---------------------------------------------------------------------- */ void ComputeTempCS::dof_compute() { adjust_dof_fix(); int nper = domain->dimension; - double natoms = group->count(igroup); - dof = nper * natoms; + natoms_temp = group->count(igroup); + dof = nper * natoms_temp; dof -= nper * nshells; dof -= extra_dof + fix_dof; - if (dof < 0.0 && natoms > 0.0) - error->all(FLERR,"Temperature compute degrees of freedom < 0"); if (dof > 0) tfactor = force->mvv2e / (dof * force->boltz); else tfactor = 0.0; } /* ---------------------------------------------------------------------- */ double ComputeTempCS::compute_scalar() { double vthermal[3]; invoked_scalar = update->ntimestep; vcm_pairs(); // calculate thermal scalar in respect to atom velocities as center-of-mass // velocities of its according core/shell pairs double **v = atom->v; int *mask = atom->mask; int *type = atom->type; double *mass = atom->mass; double *rmass = atom->rmass; int nlocal = atom->nlocal; double t = 0.0; for (int i = 0; i < nlocal; i++){ if (mask[i] & groupbit) { vthermal[0] = v[i][0] - vint[i][0]; vthermal[1] = v[i][1] - vint[i][1]; vthermal[2] = v[i][2] - vint[i][2]; if (rmass) t += (vthermal[0]*vthermal[0] + vthermal[1]*vthermal[1] + vthermal[2]*vthermal[2]) * rmass[i]; else t += (vthermal[0]*vthermal[0] + vthermal[1]*vthermal[1] + vthermal[2]*vthermal[2]) * mass[type[i]]; } } MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world); if (dynamic) dof_compute(); + if (dof < 0.0 && natoms_temp > 0.0) + error->all(FLERR,"Temperature compute degrees of freedom < 0"); scalar *= tfactor; return scalar; } /* ---------------------------------------------------------------------- */ void ComputeTempCS::compute_vector() { double vthermal[3]; invoked_vector = update->ntimestep; vcm_pairs(); // calculate thermal vector in respect to atom velocities as center-of-mass // velocities of its according C/S pairs double **v = atom->v; int *mask = atom->mask; int *type = atom->type; double *mass = atom->mass; double *rmass = atom->rmass; int nlocal = atom->nlocal; double massone; double t[6]; for (int i = 0; i < 6; i++) t[i] = 0.0; for (int i = 0; i < nlocal; i++){ if (mask[i] & groupbit) { vthermal[0] = v[i][0] - vint[i][0]; vthermal[1] = v[i][1] - vint[i][1]; vthermal[2] = v[i][2] - vint[i][2]; if (rmass) massone = rmass[i]; else massone = mass[type[i]]; t[0] += massone * vthermal[0]*vthermal[0]; t[1] += massone * vthermal[1]*vthermal[1]; t[2] += massone * vthermal[2]*vthermal[2]; t[3] += massone * vthermal[0]*vthermal[1]; t[4] += massone * vthermal[0]*vthermal[2]; t[5] += massone * vthermal[1]*vthermal[2]; } } MPI_Allreduce(t,vector,6,MPI_DOUBLE,MPI_SUM,world); for (int i = 0; i < 6; i++) vector[i] *= force->mvv2e; } /* ---------------------------------------------------------------------- */ void ComputeTempCS::vcm_pairs() { int i,j; double massone,masstwo; double vcm[3]; // reallocate vint if necessary int nlocal = atom->nlocal; if (nlocal > maxatom) { memory->destroy(vint); maxatom = atom->nmax; memory->create(vint,maxatom,3,"temp/cs:vint"); } // vcm = COM velocity of each CS pair // vint = internal velocity of each C/S atom, used as bias double **v = atom->v; int *mask = atom->mask; int *type = atom->type; double *mass = atom->mass; double *rmass = atom->rmass; double *partner = fix->vstore; tagint partnerID; for (i = 0; i < nlocal; i++) { if ((mask[i] & groupbit) && (mask[i] & groupbit_c || mask[i] & groupbit_s)) { if (rmass) massone = rmass[i]; else massone = mass[type[i]]; vcm[0] = v[i][0]*massone; vcm[1] = v[i][1]*massone; vcm[2] = v[i][2]*massone; partnerID = (tagint) ubuf(partner[i]).i; j = atom->map(partnerID); if (j == -1) error->one(FLERR,"Core/shell partner atom not found"); if (rmass) masstwo = rmass[j]; else masstwo = mass[type[j]]; vcm[0] += v[j][0]*masstwo; vcm[1] += v[j][1]*masstwo; vcm[2] += v[j][2]*masstwo; vcm[0] /= (massone + masstwo); vcm[1] /= (massone + masstwo); vcm[2] /= (massone + masstwo); vint[i][0] = v[i][0] - vcm[0]; vint[i][1] = v[i][1] - vcm[1]; vint[i][2] = v[i][2] - vcm[2]; } else vint[i][0] = vint[i][1] = vint[i][2] = 0.0; } } /* ---------------------------------------------------------------------- remove velocity bias from atom I to leave thermal velocity thermal velocity in this case is COM velocity of C/S pair ------------------------------------------------------------------------- */ void ComputeTempCS::remove_bias(int i, double *v) { v[0] -= vint[i][0]; v[1] -= vint[i][1]; v[2] -= vint[i][2]; } /* ---------------------------------------------------------------------- remove velocity bias from all atoms to leave thermal velocity thermal velocity in this case is COM velocity of C/S pair ------------------------------------------------------------------------- */ void ComputeTempCS::remove_bias_all() { double **v = atom->v; int *mask = atom->mask; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { v[i][0] -= vint[i][0]; v[i][1] -= vint[i][1]; v[i][2] -= vint[i][2]; } } /* ---------------------------------------------------------------------- reset thermal velocity of all atoms to be consistent with bias called from velocity command after it creates thermal velocities this resets each atom's velocity to COM velocity of C/S pair ------------------------------------------------------------------------- */ void ComputeTempCS::reapply_bias_all() { double **v = atom->v; int *mask = atom->mask; int nlocal = atom->nlocal; // recalculate current COM velocities vcm_pairs(); // zero vint after using ti so that Velocity call to restore_bias_all() // will not further alter the velocities within a C/S pair for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { v[i][0] -= vint[i][0]; v[i][1] -= vint[i][1]; v[i][2] -= vint[i][2]; vint[i][0] = 0.0; vint[i][1] = 0.0; vint[i][2] = 0.0; } } /* ---------------------------------------------------------------------- add back in velocity bias to atom I removed by remove_bias() assume remove_bias() was previously called ------------------------------------------------------------------------- */ void ComputeTempCS::restore_bias(int i, double *v) { v[0] += vint[i][0]; v[1] += vint[i][1]; v[2] += vint[i][2]; } /* ---------------------------------------------------------------------- add back in velocity bias to all atoms removed by remove_bias_all() assume remove_bias_all() was previously called ------------------------------------------------------------------------- */ void ComputeTempCS::restore_bias_all() { double **v = atom->v; int *mask = atom->mask; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { v[i][0] += vint[i][0]; v[i][1] += vint[i][1]; v[i][2] += vint[i][2]; } } /* ---------------------------------------------------------------------- */ int ComputeTempCS::pack_reverse_comm(int n, int first, double *buf) { int i,m,last; double *partner = fix->vstore; m = 0; last = first + n; for (i = first; i < last; i++) buf[m++] = partner[i]; return m; } /* ---------------------------------------------------------------------- */ void ComputeTempCS::unpack_reverse_comm(int n, int *list, double *buf) { int i,j,m; double *partner = fix->vstore; tagint partnerID; m = 0; for (i = 0; i < n; i++) { j = list[i]; partnerID = (tagint) ubuf(buf[m++]).i; if (partnerID) partner[j] = ubuf(partnerID).d; } } /* ---------------------------------------------------------------------- memory usage of local data ------------------------------------------------------------------------- */ double ComputeTempCS::memory_usage() { double bytes = (bigint) maxatom * 3 * sizeof(double); return bytes; } diff --git a/src/USER-EFF/compute_temp_deform_eff.cpp b/src/USER-EFF/compute_temp_deform_eff.cpp index 92ebdb298..8ff1d6f76 100644 --- a/src/USER-EFF/compute_temp_deform_eff.cpp +++ b/src/USER-EFF/compute_temp_deform_eff.cpp @@ -1,327 +1,327 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Andres Jaramillo-Botero (Caltech) ------------------------------------------------------------------------- */ #include "mpi.h" #include "math.h" #include "string.h" #include "stdlib.h" #include "compute_temp_deform_eff.h" #include "domain.h" #include "atom.h" #include "update.h" #include "force.h" #include "modify.h" #include "fix.h" #include "fix_deform.h" #include "group.h" #include "comm.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; enum{NO_REMAP,X_REMAP,V_REMAP}; // same as fix_deform.cpp /* ---------------------------------------------------------------------- */ ComputeTempDeformEff::ComputeTempDeformEff(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (narg != 3) error->all(FLERR,"Illegal compute temp/deform/eff command"); if (!atom->electron_flag) error->all(FLERR,"Compute temp/deform/eff requires atom style electron"); scalar_flag = vector_flag = 1; size_vector = 6; extscalar = 0; extvector = 1; tempflag = 1; tempbias = 1; maxbias = 0; vbiasall = NULL; vector = new double[6]; } /* ---------------------------------------------------------------------- */ ComputeTempDeformEff::~ComputeTempDeformEff() { memory->destroy(vbiasall); delete [] vector; } /* ---------------------------------------------------------------------- */ void ComputeTempDeformEff::init() { // check fix deform remap settings int i; for (i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"deform") == 0) { if (((FixDeform *) modify->fix[i])->remapflag == X_REMAP && comm->me == 0) error->warning(FLERR,"Using compute temp/deform/eff with inconsistent " "fix deform remap option"); break; } if (i == modify->nfix && comm->me == 0) error->warning(FLERR, "Using compute temp/deform/eff with no fix deform defined"); } /* ---------------------------------------------------------------------- */ void ComputeTempDeformEff::setup() { dynamic = 0; if (dynamic_user || group->dynamic[igroup]) dynamic = 1; dof_compute(); } /* ---------------------------------------------------------------------- */ void ComputeTempDeformEff::dof_compute() { adjust_dof_fix(); - double natoms = group->count(igroup); - dof = domain->dimension * natoms; + natoms_temp = group->count(igroup); + dof = domain->dimension * natoms_temp; dof -= extra_dof + fix_dof; // just include nuclear dof int *spin = atom->spin; int *mask = atom->mask; int nlocal = atom->nlocal; int one = 0; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { if (abs(spin[i]) == 1) one++; } int nelectrons; MPI_Allreduce(&one,&nelectrons,1,MPI_INT,MPI_SUM,world); // Assume 3/2 k T per nucleus dof -= domain->dimension * nelectrons; - if (dof < 0.0 && natoms > 0.0) - error->all(FLERR,"Temperature compute degrees of freedom < 0"); if (dof > 0) tfactor = force->mvv2e / (dof * force->boltz); else tfactor = 0.0; } /* ---------------------------------------------------------------------- */ double ComputeTempDeformEff::compute_scalar() { double lamda[3],vstream[3],vthermal[3]; invoked_scalar = update->ntimestep; double **x = atom->x; double **v = atom->v; double *ervel = atom->ervel; double *mass = atom->mass; int *spin = atom->spin; int *type = atom->type; int *mask = atom->mask; int nlocal = atom->nlocal; double mefactor = domain->dimension/4.0; // lamda = 0-1 triclinic lamda coords // vstream = streaming velocity = Hrate*lamda + Hratelo // vthermal = thermal velocity = v - vstream double *h_rate = domain->h_rate; double *h_ratelo = domain->h_ratelo; double t = 0.0; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { domain->x2lamda(x[i],lamda); vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] + h_rate[4]*lamda[2] + h_ratelo[0]; vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1]; vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2]; vthermal[0] = v[i][0] - vstream[0]; vthermal[1] = v[i][1] - vstream[1]; vthermal[2] = v[i][2] - vstream[2]; if (mass) { t += (vthermal[0]*vthermal[0] + vthermal[1]*vthermal[1] + vthermal[2]*vthermal[2])* mass[type[i]]; if (abs(spin[i])==1) t += mefactor*mass[type[i]]*ervel[i]*ervel[i]; } } MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world); if (dynamic) dof_compute(); + if (dof < 0.0 && natoms_temp > 0.0) + error->all(FLERR,"Temperature compute degrees of freedom < 0"); scalar *= tfactor; return scalar; } /* ---------------------------------------------------------------------- */ void ComputeTempDeformEff::compute_vector() { double lamda[3],vstream[3],vthermal[3]; invoked_vector = update->ntimestep; double **x = atom->x; double **v = atom->v; double *ervel = atom->ervel; double *mass = atom->mass; int *spin = atom->spin; int *type = atom->type; int *mask = atom->mask; int nlocal = atom->nlocal; double mefactor = domain->dimension/4.0; double *h_rate = domain->h_rate; double *h_ratelo = domain->h_ratelo; double massone,t[6]; for (int i = 0; i < 6; i++) t[i] = 0.0; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { domain->x2lamda(x[i],lamda); vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] + h_rate[4]*lamda[2] + h_ratelo[0]; vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1]; vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2]; vthermal[0] = v[i][0] - vstream[0]; vthermal[1] = v[i][1] - vstream[1]; vthermal[2] = v[i][2] - vstream[2]; massone = mass[type[i]]; t[0] += massone * vthermal[0]*vthermal[0]; t[1] += massone * vthermal[1]*vthermal[1]; t[2] += massone * vthermal[2]*vthermal[2]; t[3] += massone * vthermal[0]*vthermal[1]; t[4] += massone * vthermal[0]*vthermal[2]; t[5] += massone * vthermal[1]*vthermal[2]; if (abs(spin[i])==1) { t[0] += mefactor * massone * ervel[i]*ervel[i]; t[1] += mefactor * massone * ervel[i]*ervel[i]; t[2] += mefactor * massone * ervel[i]*ervel[i]; } } MPI_Allreduce(t,vector,6,MPI_DOUBLE,MPI_SUM,world); for (int i = 0; i < 6; i++) vector[i] *= force->mvv2e; } /* ---------------------------------------------------------------------- remove velocity bias from atom I to leave thermal velocity ------------------------------------------------------------------------- */ void ComputeTempDeformEff::remove_bias(int i, double *v) { double lamda[3]; double *h_rate = domain->h_rate; double *h_ratelo = domain->h_ratelo; domain->x2lamda(atom->x[i],lamda); vbias[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] + h_rate[4]*lamda[2] + h_ratelo[0]; vbias[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1]; vbias[2] = h_rate[2]*lamda[2] + h_ratelo[2]; v[0] -= vbias[0]; v[1] -= vbias[1]; v[2] -= vbias[2]; } /* ---------------------------------------------------------------------- remove velocity bias from all atoms to leave thermal velocity NOTE: only removes translational velocity bias from electrons ------------------------------------------------------------------------- */ void ComputeTempDeformEff::remove_bias_all() { double **v = atom->v; int *mask = atom->mask; int nlocal = atom->nlocal; if (nlocal > maxbias) { memory->destroy(vbiasall); maxbias = atom->nmax; memory->create(vbiasall,maxbias,3,"temp/deform/eff:vbiasall"); } double lamda[3]; double *h_rate = domain->h_rate; double *h_ratelo = domain->h_ratelo; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { domain->x2lamda(atom->x[i],lamda); vbiasall[i][0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] + h_rate[4]*lamda[2] + h_ratelo[0]; vbiasall[i][1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1]; vbiasall[i][2] = h_rate[2]*lamda[2] + h_ratelo[2]; v[i][0] -= vbiasall[i][0]; v[i][1] -= vbiasall[i][1]; v[i][2] -= vbiasall[i][2]; } } /* ---------------------------------------------------------------------- add back in velocity bias to atom I removed by remove_bias() assume remove_bias() was previously called ------------------------------------------------------------------------- */ void ComputeTempDeformEff::restore_bias(int i, double *v) { v[0] += vbias[0]; v[1] += vbias[1]; v[2] += vbias[2]; } /* ---------------------------------------------------------------------- add back in velocity bias to all atoms removed by remove_bias_all() assume remove_bias_all() was previously called ------------------------------------------------------------------------- */ void ComputeTempDeformEff::restore_bias_all() { double **v = atom->v; int *mask = atom->mask; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { v[i][0] += vbiasall[i][0]; v[i][1] += vbiasall[i][1]; v[i][2] += vbiasall[i][2]; } } /* ---------------------------------------------------------------------- */ double ComputeTempDeformEff::memory_usage() { double bytes = maxbias * sizeof(double); return bytes; } diff --git a/src/USER-EFF/compute_temp_eff.cpp b/src/USER-EFF/compute_temp_eff.cpp index 9b24e0a70..2b4e50709 100644 --- a/src/USER-EFF/compute_temp_eff.cpp +++ b/src/USER-EFF/compute_temp_eff.cpp @@ -1,167 +1,167 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Andres Jaramillo-Botero (Caltech) ------------------------------------------------------------------------- */ #include "mpi.h" #include "math.h" #include "string.h" #include "stdlib.h" #include "compute_temp_eff.h" #include "atom.h" #include "update.h" #include "force.h" #include "domain.h" #include "group.h" #include "error.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputeTempEff::ComputeTempEff(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (!atom->electron_flag) error->all(FLERR,"Compute temp/eff requires atom style electron"); scalar_flag = vector_flag = 1; size_vector = 6; extscalar = 0; extvector = 1; tempflag = 1; vector = new double[size_vector]; } /* ---------------------------------------------------------------------- */ ComputeTempEff::~ComputeTempEff() { delete [] vector; } /* ---------------------------------------------------------------------- */ void ComputeTempEff::setup() { dynamic = 0; if (dynamic_user || group->dynamic[igroup]) dynamic = 1; dof_compute(); } /* ---------------------------------------------------------------------- */ void ComputeTempEff::dof_compute() { adjust_dof_fix(); - double natoms = group->count(igroup); - dof = domain->dimension * natoms; + natoms_temp = group->count(igroup); + dof = domain->dimension * natoms_temp; dof -= extra_dof + fix_dof; int *spin = atom->spin; int *mask = atom->mask; int nlocal = atom->nlocal; int one = 0; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { if (abs(spin[i])==1) one++; } int nelectrons; MPI_Allreduce(&one,&nelectrons,1,MPI_INT,MPI_SUM,world); // Assume 3/2 k T per nucleus dof -= domain->dimension * nelectrons; - if (dof < 0.0 && natoms > 0.0) - error->all(FLERR,"Temperature compute degrees of freedom < 0"); if (dof > 0.0) tfactor = force->mvv2e / (dof * force->boltz); else tfactor = 0.0; } /* ---------------------------------------------------------------------- */ double ComputeTempEff::compute_scalar() { invoked_scalar = update->ntimestep; double **v = atom->v; double *ervel = atom->ervel; double *mass = atom->mass; int *spin = atom->spin; int *type = atom->type; int *mask = atom->mask; int nlocal = atom->nlocal; double mefactor = domain->dimension/4.0; double t = 0.0; if (mass) { for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { t += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) * mass[type[i]]; if (abs(spin[i])==1) t += mefactor*mass[type[i]]*ervel[i]*ervel[i]; } } } MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world); if (dynamic) dof_compute(); + if (dof < 0.0 && natoms_temp > 0.0) + error->all(FLERR,"Temperature compute degrees of freedom < 0"); scalar *= tfactor; return scalar; } /* ---------------------------------------------------------------------- */ void ComputeTempEff::compute_vector() { int i; invoked_vector = update->ntimestep; double **v = atom->v; double *ervel = atom->ervel; double *mass = atom->mass; int *spin = atom->spin; int *type = atom->type; int *mask = atom->mask; int nlocal = atom->nlocal; double mefactor = domain->dimension/4.0; double massone,t[6]; for (i = 0; i < 6; i++) t[i] = 0.0; for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) { massone = mass[type[i]]; t[0] += massone * v[i][0]*v[i][0]; t[1] += massone * v[i][1]*v[i][1]; t[2] += massone * v[i][2]*v[i][2]; t[3] += massone * v[i][0]*v[i][1]; t[4] += massone * v[i][0]*v[i][2]; t[5] += massone * v[i][1]*v[i][2]; if (abs(spin[i])==1) { t[0] += mefactor*massone*ervel[i]*ervel[i]; t[1] += mefactor*massone*ervel[i]*ervel[i]; t[2] += mefactor*massone*ervel[i]*ervel[i]; } } MPI_Allreduce(t,vector,6,MPI_DOUBLE,MPI_SUM,world); for (i = 0; i < 6; i++) vector[i] *= force->mvv2e; } diff --git a/src/USER-EFF/compute_temp_region_eff.cpp b/src/USER-EFF/compute_temp_region_eff.cpp index d2517d879..3c762e5d7 100644 --- a/src/USER-EFF/compute_temp_region_eff.cpp +++ b/src/USER-EFF/compute_temp_region_eff.cpp @@ -1,296 +1,298 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Andres Jaramillo-Botero (Caltech) ------------------------------------------------------------------------- */ #include "mpi.h" #include "math.h" #include "string.h" #include "stdlib.h" #include "compute_temp_region_eff.h" #include "atom.h" #include "update.h" #include "force.h" #include "modify.h" #include "domain.h" #include "region.h" #include "group.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputeTempRegionEff::ComputeTempRegionEff(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { if (!atom->electron_flag) error->all(FLERR,"Compute temp/region/eff requires atom style electron"); if (narg != 4) error->all(FLERR,"Illegal compute temp/region/eff command"); iregion = domain->find_region(arg[3]); if (iregion == -1) error->all(FLERR,"Region ID for compute temp/region/eff does not exist"); int n = strlen(arg[3]) + 1; idregion = new char[n]; strcpy(idregion,arg[3]); scalar_flag = vector_flag = 1; size_vector = 6; extscalar = 0; extvector = 1; tempflag = 1; tempbias = 1; maxbias = 0; vbiasall = NULL; vector = new double[6]; } /* ---------------------------------------------------------------------- */ ComputeTempRegionEff::~ComputeTempRegionEff() { delete [] idregion; memory->destroy(vbiasall); delete [] vector; } /* ---------------------------------------------------------------------- */ void ComputeTempRegionEff::init() { // set index and check validity of region iregion = domain->find_region(idregion); if (iregion == -1) error->all(FLERR,"Region ID for compute temp/region/eff does not exist"); } /* ---------------------------------------------------------------------- */ void ComputeTempRegionEff::setup() { dynamic = 0; if (dynamic_user || group->dynamic[igroup]) dynamic = 1; dof = 0.0; } /* ---------------------------------------------------------------------- */ void ComputeTempRegionEff::dof_remove_pre() { domain->regions[iregion]->prematch(); } /* ---------------------------------------------------------------------- */ int ComputeTempRegionEff::dof_remove(int i) { double *x = atom->x[i]; if (domain->regions[iregion]->match(x[0],x[1],x[2])) return 0; return 1; } /* ---------------------------------------------------------------------- */ double ComputeTempRegionEff::compute_scalar() { invoked_scalar = update->ntimestep; double **x = atom->x; double **v = atom->v; double *ervel = atom->ervel; double *mass = atom->mass; int *spin = atom->spin; int *type = atom->type; int *mask = atom->mask; int nlocal = atom->nlocal; double mefactor = domain->dimension/4.0; Region *region = domain->regions[iregion]; region->prematch(); int count = 0; int ecount = 0; double t = 0.0; if (mass) { for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) { count++; t += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) * mass[type[i]]; if (abs(spin[i])==1) { t += mefactor*mass[type[i]]*ervel[i]*ervel[i]; ecount++; } } } double tarray[2],tarray_all[2]; // Assume 3/2 k T per nucleus tarray[0] = count-ecount; tarray[1] = t; MPI_Allreduce(tarray,tarray_all,2,MPI_DOUBLE,MPI_SUM,world); dof = domain->dimension * tarray_all[0] - extra_dof; + if (dof < 0.0 && tarray_all[0] > 0.0) + error->all(FLERR,"Temperature compute degrees of freedom < 0"); int one = 0; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) { if (abs(spin[i])==1) one++; } - if (dof > 0) scalar = force->mvv2e * tarray_all[1] / (dof * force->boltz); + if (dof > 0.0) scalar = force->mvv2e * tarray_all[1] / (dof * force->boltz); else scalar = 0.0; return scalar; } /* ---------------------------------------------------------------------- */ void ComputeTempRegionEff::compute_vector() { int i; invoked_vector = update->ntimestep; double **x = atom->x; double **v = atom->v; double *ervel = atom->ervel; double *mass = atom->mass; int *spin = atom->spin; int *type = atom->type; int *mask = atom->mask; int nlocal = atom->nlocal; double mefactor = domain->dimension/4.0; Region *region = domain->regions[iregion]; region->prematch(); double massone,t[6]; for (i = 0; i < 6; i++) t[i] = 0.0; for (i = 0; i < nlocal; i++) if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) { massone = mass[type[i]]; t[0] += massone * v[i][0]*v[i][0]; t[1] += massone * v[i][1]*v[i][1]; t[2] += massone * v[i][2]*v[i][2]; t[3] += massone * v[i][0]*v[i][1]; t[4] += massone * v[i][0]*v[i][2]; t[5] += massone * v[i][1]*v[i][2]; if (abs(spin[i])==1) { t[0] += mefactor * massone * ervel[i]*ervel[i]; t[1] += mefactor * massone * ervel[i]*ervel[i]; t[2] += mefactor * massone * ervel[i]*ervel[i]; } } MPI_Allreduce(t,vector,6,MPI_DOUBLE,MPI_SUM,world); for (i = 0; i < 6; i++) vector[i] *= force->mvv2e; } /* ---------------------------------------------------------------------- remove velocity bias from atom I to leave thermal velocity NOTE: the following commands do not bias the radial electron velocities ------------------------------------------------------------------------- */ void ComputeTempRegionEff::remove_bias(int i, double *v) { double *x = atom->x[i]; if (domain->regions[iregion]->match(x[0],x[1],x[2])) vbias[0] = vbias[1] = vbias[2] = 0.0; else { vbias[0] = v[0]; vbias[1] = v[1]; vbias[2] = v[2]; v[0] = v[1] = v[2] = 0.0; } } /* ---------------------------------------------------------------------- remove velocity bias from all atoms to leave thermal velocity ------------------------------------------------------------------------- */ void ComputeTempRegionEff::remove_bias_all() { double **x = atom->x; double **v = atom->v; int *mask = atom->mask; int nlocal = atom->nlocal; if (nlocal > maxbias) { memory->destroy(vbiasall); maxbias = atom->nmax; memory->create(vbiasall,maxbias,3,"temp/region:vbiasall"); } Region *region = domain->regions[iregion]; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { if (region->match(x[i][0],x[i][1],x[i][2])) vbiasall[i][0] = vbiasall[i][1] = vbiasall[i][2] = 0.0; else { vbiasall[i][0] = v[i][0]; vbiasall[i][1] = v[i][1]; vbiasall[i][2] = v[i][2]; v[i][0] = v[i][1] = v[i][2] = 0.0; } } } /* ---------------------------------------------------------------------- add back in velocity bias to atom I removed by remove_bias() assume remove_bias() was previously called ------------------------------------------------------------------------- */ void ComputeTempRegionEff::restore_bias(int i, double *v) { v[0] += vbias[0]; v[1] += vbias[1]; v[2] += vbias[2]; } /* ---------------------------------------------------------------------- add back in velocity bias to all atoms removed by remove_bias_all() assume remove_bias_all() was previously called ------------------------------------------------------------------------- */ void ComputeTempRegionEff::restore_bias_all() { double **v = atom->v; int *mask = atom->mask; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { v[i][0] += vbiasall[i][0]; v[i][1] += vbiasall[i][1]; v[i][2] += vbiasall[i][2]; } } /* ---------------------------------------------------------------------- */ double ComputeTempRegionEff::memory_usage() { double bytes = maxbias * sizeof(double); return bytes; }