From db977dac7ccf4c84600d796566d38bb25bf325b8 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Sat, 2 Jun 2018 08:10:35 -0400 Subject: [PATCH 01/54] Commit change in fix_wall_region before merge. --- src/fix_wall_region.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fix_wall_region.cpp b/src/fix_wall_region.cpp index 1d22e6141b..02fe359c4e 100644 --- a/src/fix_wall_region.cpp +++ b/src/fix_wall_region.cpp @@ -1,4 +1,4 @@ -/* ---------------------------------------------------------------------- + seems------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov From 12385480ab0df097d25cb324d27188efa50459f6 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Mon, 22 Oct 2018 11:12:46 -0400 Subject: [PATCH 02/54] Started work on a patchy sphere model. --- src/ASPHERE/pair_patchy_sphere.cpp | 884 +++++++++++++++++++++++++++++ src/ASPHERE/pair_patchy_sphere.h | 93 +++ 2 files changed, 977 insertions(+) create mode 100644 src/ASPHERE/pair_patchy_sphere.cpp create mode 100644 src/ASPHERE/pair_patchy_sphere.h diff --git a/src/ASPHERE/pair_patchy_sphere.cpp b/src/ASPHERE/pair_patchy_sphere.cpp new file mode 100644 index 0000000000..928edb415a --- /dev/null +++ b/src/ASPHERE/pair_patchy_sphere.cpp @@ -0,0 +1,884 @@ +/* ---------------------------------------------------------------------- + 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: Stefan Paquay (Brandeis University) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_patchy_sphere.h" + +#include "atom.h" +#include "atom_vec_ellipsoid.h" +#include "comm.h" +#include "force.h" +#include "math_const.h" +#include "math_extra.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "integrate.h" +#include "citeme.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +constexpr const bool nine_pairs = false; + +/* ---------------------------------------------------------------------- */ + +PairPatchySphere::PairPatchySphere(LAMMPS *lmp) : Pair(lmp) +{ + single_enable = 0; + // writedata = 1; // Add later. + allocated = 0; + setflag = NULL; + +} + +/* ---------------------------------------------------------------------- */ + + +PairPatchySphere::~PairPatchySphere() +{ + if (allocated) { + memory->destroy(cutsq); + memory->destroy(cut); + memory->destroy(inner_cut); + + memory->destroy(offset); + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(epsilon_b); + memory->destroy(phi_m); + memory->destroy(theta_m); + + memory->destroy(bond_pairs); + memory->destroy(bond_vectors); + + memory->destroy(setflag); + + } +} + +/* ---------------------------------------------------------------------- */ + + +void PairPatchySphere::allocate() +{ + int n = atom->ntypes; + + memory->create(cutsq, n+1,n+1, "pair:cutsq"); + memory->create(cut, n+1,n+1, "pair:cut"); + memory->create(inner_cut, n+1,n+1, "pair:inner_cut"); + memory->create(offset, n+1,n+1, "pair:offset"); + memory->create(epsilon, n+1,n+1, "pair:epsilon"); + memory->create(sigma, n+1,n+1, "pair:sigma"); + memory->create(epsilon_b, n+1,n+1, "pair:epsilon_b"); + memory->create(phi_m, n+1, n+1, "pair:phi_m"); + memory->create(theta_m, n+1, n+1, "pair:theta_m"); + + // For now the complementary pairs are fixed. + n_bonds = 3; + if (nine_pairs){ + n_bond_pairs = 9; + } else { + n_bond_pairs = 3; + } + memory->create(bond_pairs, n_bond_pairs, 6, "pair:bond_pairs"); + memory->create(bond_vectors, n_bonds, 3, "pair:bond_vectors"); + + if( comm->me == 0 ) fprintf(screen, "n is %d\n", n); + memory->create(setflag, n+1, n+1, "pair:setflag"); + + + allocated = 1; +} + + +/* ---------------------------------------------------------------------- */ + + +void PairPatchySphere::settings(int narg, char **arg) +{ + // params: phi_m, theta_m, cut-off + if (narg != 1 && narg != 2) error->all(FLERR,"Illegal pair_style command"); + + if (debug_output && comm->me == 0) { + fprintf(screen, "Got %d args:", narg); + for (int i = 0; i < narg; ++i) { + fprintf(screen, " %s", arg[i]); + } + fprintf(screen, "\n"); + } + cut_global = force->numeric(FLERR, arg[0]); + + if (narg == 2) + debug_output = force->inumeric(FLERR, arg[1]); + + if (allocated){ + for (int i = 1; i < atom->ntypes; ++i){ + for (int j = 1; j <= atom->ntypes; ++j){ + cut[i][j] = cut_global; + cutsq[i][j] = cut[i][j]*cut[i][j]; + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +void PairPatchySphere::coeff(int narg, char **arg) +{ + // Coeffs are epsilon, sigma, epsilon_b, phi_m, theta_m + if (narg < 7 || narg > 8) + error->all(FLERR, "Incorrect args for pair coefficients"); + + if (!allocated) allocate(); + + double cut_one = cut_global; + int ilo, ihi, jlo, jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + double epsilon_one = force->numeric(FLERR, arg[2]); + double sigma_one = force->numeric(FLERR, arg[3]); + double epsilon_b_one = force->numeric(FLERR, arg[4]); + double phi_m_one = force->numeric(FLERR, arg[5]); + double theta_m_one = force->numeric(FLERR, arg[6]); + + double rc_one = sigma_one * pow(2.0,1.0/6.0); + + if (narg == 8) cut_one = force->numeric(FLERR, arg[7]); + + int count = 0; + for (int i = ilo; i <= ihi; ++i){ + for (int j = jlo; j <= jhi; ++j ){ + epsilon[i][j] = epsilon_one; + sigma[i][j] = sigma_one; + epsilon_b[i][j] = epsilon_b_one; + phi_m[i][j] = phi_m_one; + theta_m[i][j] = theta_m_one; + cut[i][j] = cut_one; + cutsq[i][j] = cut_one*cut_one; + inner_cut[i][j] = rc_one; + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- */ + +void PairPatchySphere::init_style() +{ + avec = static_cast(atom->style_match("ellipsoid")); + if (!avec) error->all(FLERR, "Pair patchy_sphere requires atom style ellipsoid"); + + neighbor->request(this,instance_me); + + // Set up the bond vectors here: + bond_pairs[0][0] = 0; + bond_pairs[0][1] = 1; + bond_pairs[0][2] = 1; + bond_pairs[0][3] = 0; + bond_pairs[0][4] = 2; + bond_pairs[0][5] = 2; + + bond_pairs[1][0] = 1; + bond_pairs[1][1] = 0; + bond_pairs[1][2] = 0; + bond_pairs[1][3] = 1; + bond_pairs[1][4] = 2; + bond_pairs[1][5] = 2; + + bond_pairs[2][0] = 2; + bond_pairs[2][1] = 2; + bond_pairs[2][2] = 0; + bond_pairs[2][3] = 1; + bond_pairs[2][4] = 1; + bond_pairs[2][5] = 0; + + if (nine_pairs) { + bond_pairs[3][0] = 0; + bond_pairs[3][1] = 2; + bond_pairs[3][2] = 2; + bond_pairs[3][3] = 0; + bond_pairs[3][4] = 1; + bond_pairs[3][5] = 1; + + bond_pairs[4][0] = 1; + bond_pairs[4][1] = 1; + bond_pairs[4][2] = 2; + bond_pairs[4][3] = 0; + bond_pairs[4][4] = 0; + bond_pairs[4][5] = 2; + + bond_pairs[5][0] = 2; + bond_pairs[5][1] = 0; + bond_pairs[5][2] = 0; + bond_pairs[5][3] = 2; + bond_pairs[5][4] = 1; + bond_pairs[5][5] = 1; + + bond_pairs[6][0] = 0; + bond_pairs[6][1] = 0; + bond_pairs[6][2] = 1; + bond_pairs[6][3] = 2; + bond_pairs[6][4] = 2; + bond_pairs[6][5] = 1; + + bond_pairs[7][0] = 1; + bond_pairs[7][1] = 2; + bond_pairs[7][2] = 0; + bond_pairs[7][3] = 0; + bond_pairs[7][4] = 2; + bond_pairs[7][5] = 1; + + bond_pairs[8][0] = 2; + bond_pairs[8][1] = 1; + bond_pairs[8][2] = 0; + bond_pairs[8][3] = 0; + bond_pairs[8][4] = 1; + bond_pairs[8][5] = 2; + } + + bond_vectors[2][0] = 1.0; + bond_vectors[2][1] = 0.0; + bond_vectors[2][2] = 0.0; + + bond_vectors[1][0] = -0.309017; + bond_vectors[1][1] = 0.951057; + bond_vectors[1][2] = 0.0; + + bond_vectors[0][0] = -0.309017; + bond_vectors[0][1] = -0.425325; + bond_vectors[0][2] = 0.850651; + + for (int i = 0; i < n_bonds; ++i) { + double bx = bond_vectors[i][0]; + double by = bond_vectors[i][1]; + double bz = bond_vectors[i][2]; + + double nb2 = bx*bx + by*by + bz*bz; + if ( fabs(nb2 - 1.0) > 1e-4 ){ + char msg[2048]; + snprintf(msg, 2048, "Bond vector %d is not of unit length! norm^2 - 1.0 = %g", + i+1, nb2 - 1.0); + error->all(FLERR,msg); + } + } + +} + +/* ---------------------------------------------------------------------- */ + +double PairPatchySphere::init_one(int i, int j) +{ + if (setflag[i][j] == 0) + error->all(FLERR, "Not all patchy sphere coefficients set!"); + + epsilon[j][i] = epsilon[i][j]; + sigma[j][i] = sigma[i][j]; + epsilon_b[j][i] = epsilon_b[i][j]; + phi_m[j][i] = phi_m[i][j]; + theta_m[j][i] = theta_m[i][j]; + cut[j][i] = cut[i][j]; + setflag[j][i] = setflag[i][j]; + inner_cut[j][i] = inner_cut[i][j]; + + + return cut[i][j]; +} + +/* ---------------------------------------------------------------------- */ + +void PairPatchySphere::compute(int eflag, int vflag) +{ + int i, j, ii, jj, inum, jnum, itype, jtype; + double evdwl, one_eng, rsq, r2inv, r6inv, forcelj, factor_lj; + double fforce[3], ttor[3], rtor[3], r12[3]; + double a1[3][3], a2[3][3]; + int *ilist, *jlist, *numneigh, **firstneigh; + double *iquat, *jquat; + + evdwl = 0.0; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + AtomVecEllipsoid::Bonus *bonus = avec->bonus; + int *ellipsoid = atom->ellipsoid; + double **x = atom->x; + double **f = atom->f; + double **tor = atom->torque; + int *type = atom->type; + int nlocal = atom->nlocal; + double *special_lj = force->special_lj; + int newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // loop over neighbors of my atoms + + // For now always assume you are dealing with patchy <--> patchy + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + itype = type[i]; + + iquat = bonus[ellipsoid[i]].quat; + MathExtra::quat_to_mat_trans(iquat,a1); // a1 is rotation matrix + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + factor_lj = special_lj[sbmask(j)]; + j &= NEIGHMASK; + + // r12 = center to center vector + + r12[0] = x[j][0]-x[i][0]; + r12[1] = x[j][1]-x[i][1]; + r12[2] = x[j][2]-x[i][2]; + rsq = MathExtra::dot3(r12,r12); + jtype = type[j]; + + // compute if less than cutoff + + if (rsq < cutsq[itype][jtype]) { + + jquat = bonus[ellipsoid[j]].quat; + MathExtra::quat_to_mat_trans(jquat,a2); + one_eng = bond_vec_analytic(i,j,a1,a2,r12,rsq, + fforce,ttor,rtor); + + + fforce[0] *= factor_lj; + fforce[1] *= factor_lj; + fforce[2] *= factor_lj; + ttor[0] *= factor_lj; + ttor[1] *= factor_lj; + ttor[2] *= factor_lj; + + f[i][0] += fforce[0]; + f[i][1] += fforce[1]; + f[i][2] += fforce[2]; + tor[i][0] += ttor[0]; + tor[i][1] += ttor[1]; + tor[i][2] += ttor[2]; + + if (newton_pair || j < nlocal) { + rtor[0] *= factor_lj; + rtor[1] *= factor_lj; + rtor[2] *= factor_lj; + f[j][0] -= fforce[0]; + f[j][1] -= fforce[1]; + f[j][2] -= fforce[2]; + tor[j][0] += rtor[0]; + tor[j][1] += rtor[1]; + tor[j][2] += rtor[2]; + } + + if (eflag) evdwl = factor_lj*one_eng; + + if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair, + evdwl,0.0,fforce[0],fforce[1],fforce[2], + -r12[0],-r12[1],-r12[2]); + } + } + } + + if (vflag_fdotr) virial_fdotr_compute(); +} + +/* ------------------------------------------------------------ */ + +double PairPatchySphere::bond_vec_analytic (const int i, const int j, + double a1[3][3], double a2[3][3], + double *r12, const double rsq, + double *fforce, double *ttor, + double *rtor) +{ + // At this point, rsq and r12 contain the distance vector and distance + // squared, a1 and a2 contain the rotation matrices. + // We need to calculate fforce, ttor and rtor. + + // For each bond vector pair: + int *type = atom->type; + int itype = type[i]; + int jtype = type[j]; + double s = sigma[itype][jtype]; + double sigma2 = s*s; + double inner_rc = inner_cut[itype][jtype]; + double inner_rc2 = inner_rc*inner_rc; + double energy = 0.0; + + ttor[0] = ttor[1] = ttor[2] = 0.0; + rtor[0] = rtor[1] = rtor[2] = 0.0; + fforce[0] = fforce[1] = fforce[2] = 0.0; + + // Distance criterion for repulsive LJ part: + if (rsq < inner_rc2) { + double rinv2 = 1.0 / rsq; + double s6 = sigma2*sigma2*sigma2; + double r6 = rinv2*rinv2*rinv2; + s6 *= r6; + + double force_lj = 48.0*epsilon[itype][jtype]*s6*(s6-0.5); + force_lj *= -rinv2; + + // Add force to the force vector: + fforce[0] += r12[0] * force_lj; + fforce[1] += r12[1] * force_lj; + fforce[2] += r12[2] * force_lj; + + energy += 4.0*epsilon[itype][jtype]*( s6*(s6-1.0) + 0.25 ); + } + + // Calculate the rotated vectors here: + double b_rot[3*6]; + + MathExtra::matvec(a1, bond_vectors[0], b_rot); + MathExtra::matvec(a1, bond_vectors[1], b_rot+3); + MathExtra::matvec(a1, bond_vectors[2], b_rot+6); + + MathExtra::matvec(a2, bond_vectors[0], b_rot+9); + MathExtra::matvec(a2, bond_vectors[1], b_rot+12); + MathExtra::matvec(a2, bond_vectors[2], b_rot+15); + + // Contributions of the bond vectors: + for (int pair_i = 0; pair_i < n_bond_pairs; ++pair_i){ + bool bail = false; + // Calculate for each pair the attractive patch part: + int alpha_i = bond_pairs[pair_i][0]; + int beta_i = bond_pairs[pair_i][1]; + int gamma_i = bond_pairs[pair_i][2]; + int epsilon_i = bond_pairs[pair_i][3]; + int eta_i = bond_pairs[pair_i][4]; + int nu_i = bond_pairs[pair_i][5]; + + /* + if (debug_output && comm->me == 0 && i == 1) { + fprintf( screen, "At i=1: pairs: %d %d %d %d %d %d\n", alpha_i, beta_i, + gamma_i, epsilon_i, eta_i, nu_i ); + } + */ + + // Alpha, gamma and eta belong to particle i, + // beta, epsilon and nu belong to particle j. + double *b_alp = b_rot + 3*alpha_i; + double *b_bet = b_rot + 3*beta_i + 9; + double *b_gam = b_rot + 3*gamma_i; + double *b_eps = b_rot + 3*epsilon_i + 9; + double *b_eta = b_rot + 3*eta_i; + double *b_nu = b_rot + 3*nu_i + 9; + + // Distance between bond vectors, attractive force: + double patch_dist[3]; + const double patch_b = 0.56123102415468651; + + patch_dist[0] = r12[0] + patch_b*(b_alp[0] - b_bet[0]); + patch_dist[1] = r12[1] + patch_b*(b_alp[1] - b_bet[1]); + patch_dist[2] = r12[2] + patch_b*(b_alp[2] - b_bet[2]); + double patch_r2 = patch_dist[0]*patch_dist[0] + patch_dist[1]*patch_dist[1] + + patch_dist[2]*patch_dist[2]; + double criterion = cut[itype][jtype] - s*1.122462048309373; + if (debug_output) { + fprintf(screen,"Distance criterion is %g\n", criterion); + } + double crit2 = criterion*criterion; + + if (patch_r2 >= crit2) { + // The attraction is out of range. Ignore this contribution. + bail = true; + } + + double patch_r = sqrt(patch_r2); + if (debug_output) { + fprintf(screen, "r_ij is %g (vector: %g %g %g)\n", + sqrt(rsq), r12[0], r12[1], r12[2]); + fprintf(screen, "b_alpha = (%g %g %g)\n", + b_alp[0], b_alp[1], b_alp[2]); + fprintf(screen, "b_beta = (%g %g %g)\n", + b_bet[0], b_bet[1], b_bet[2]); + fprintf(screen, "Patch distance is %g (vector: %g %g %g)\n", + patch_r, patch_dist[0], patch_dist[1], patch_dist[2]); + } + + + bool calc_theta = true; + + // The total force, torque and reverse torque from this bond vector pair + // will be tallied in these: + double acc_force[3] = { 0.0, 0.0, 0.0 }; + double acc_ttor[3] = { 0.0, 0.0, 0.0 }; + double acc_rtor[3] = { 0.0, 0.0, 0.0 }; + + double u_theta = 2.0; + double theta_force[3] = {0.0,0.0,0.0}; + double theta_ttor[3] = {0.0,0.0,0.0}; + double theta_rtor[3] = {0.0,0.0,0.0}; + + if (calc_theta && !bail) { + // Switching function: Theta + u_theta = bond_vec_theta_part(i, j, itype, jtype, r12, b_alp, b_bet, + theta_force, theta_ttor, theta_rtor); + if (debug_output) { + fprintf(screen, "u_theta = %g\n", u_theta); + } + if (u_theta == 0) { + // No contribution from this bond vector set. + bail = true; + theta_force[0] = theta_force[1] = theta_force[2] = 0.0; + theta_ttor[0] = theta_ttor[1] = theta_ttor[2] = 0.0; + theta_rtor[0] = theta_rtor[1] = theta_rtor[2] = 0.0; + } + } + + if (debug_output) + fprintf(screen, "u_theta = %g\n", u_theta); + + // Tally force and torque: + bool calc_phi1 = true; + bool calc_phi2 = true; + + // phi_1: + double u_phi1 = 2.0; + double phi1_force[3] = {0.0,0.0,0.0}; + double phi1_ttor[3] = {0.0,0.0,0.0}; + double phi1_rtor[3] = {0.0,0.0,0.0}; + + if (!bail && calc_phi1) { + u_phi1 = bond_vec_phi_part(i, j, itype, jtype, r12, rsq, b_alp, b_bet, + b_gam, b_eps, phi1_force, phi1_ttor, phi1_rtor); + if (u_phi1 == 0) { + // No contribution from this bond vector pair. + bail = true; + } + }else{ + phi1_force[0] = phi1_force[1] = phi1_force[2] = 0.0; + phi1_ttor[0] = phi1_ttor[1] = phi1_ttor[2] = 0.0; + phi1_rtor[0] = phi1_rtor[1] = phi1_rtor[2] = 0.0; + // If do not calc, ignore its contributino to forces and torques + // but put u_phi1 to 2.0 so that the phi factor does not change anything. + u_phi1 = 2.0; + } + + double phi2_force[3] = {0.0,0.0,0.0}; + double phi2_ttor[3] = {0.0,0.0,0.0}; + double phi2_rtor[3] = {0.0,0.0,0.0}; + + double u_phi2 = 2.0; + + if (!bail && calc_phi2) { + u_phi2 = bond_vec_phi_part(i, j, itype, jtype, r12, rsq, b_alp, b_bet, + b_eta, b_nu, phi2_force, phi2_ttor, phi2_rtor); + if (u_phi2 == 0) { + // No contribution from this bond vector pair. + bail = true; + } + }else{ + phi2_force[0] = phi2_force[1] = phi2_force[2] = 0.0; + phi2_ttor[0] = phi2_ttor[1] = phi2_ttor[2] = 0.0; + phi2_rtor[0] = phi2_rtor[1] = phi2_rtor[2] = 0.0; + // If do not calc, ignore its contributino to forces and torques + // but put u_phi1 to 2.0 so that the phi factor does not change anything. + u_phi2 = 2.0; + } + + // attractive LJ force. Has weird shape of 2^{1/6} + patch_dist. + double rr = patch_r + inner_cut[itype][jtype]; + double sr2 = sigma2 / (rr*rr); + double sr6 = sr2*sr2*sr2; + + // 0.5 instead of 4 because we omit the factors 0.5 for switching functions. + double bond_eps = 0.5*epsilon_b[itype][jtype]; + // Add the offset. + double src2 = sigma2 / cutsq[itype][jtype]; + double src6 = src2*src2*src2; + double u_LJ = bond_eps * ( sr6 * ( sr6 - 1.0 ) - src6 * ( src6 - 1.0 ) ); + + if (debug_output) { + fprintf(screen, "patch distance was %g, u_LJ = %g\n", + patch_r, u_LJ); + } + + // LJ force: + double lj_force[3] = {0.0, 0.0, 0.0}; + + if (!bail) { + // bond_eps is already a factor 8 smaller so this is regular LJ: + double pair_f = 48.0*bond_eps*sr6*(sr6 - 0.5)/patch_r2; + lj_force[0] = pair_f*patch_dist[0]; + lj_force[1] = pair_f*patch_dist[1]; + lj_force[2] = pair_f*patch_dist[2]; + + const double c1 = u_LJ*u_phi1*u_phi2; + const double c2 = u_theta*u_phi1*u_phi2; + const double c3 = u_LJ*u_theta*u_phi2; + const double c4 = u_LJ*u_theta*u_phi1; + + // Theta part produces no force. + acc_force[0] = lj_force[0]*c2 + phi1_force[0]*c3 + phi2_force[0]*c4; + acc_force[1] = lj_force[1]*c2 + phi1_force[1]*c3 + phi2_force[1]*c4; + acc_force[2] = lj_force[2]*c2 + phi1_force[2]*c3 + phi2_force[2]*c4; + + // There is another torque coming from the lj force. + double force_ttor[3], force_rtor[3]; + MathExtra::cross3(b_alp, lj_force, force_ttor); + MathExtra::cross3(b_bet, lj_force, force_rtor); + + acc_ttor[0] = force_ttor[0]*c2 + theta_ttor[0]*c1 + phi1_ttor[0]*c3 + phi2_ttor[0]*c4; + acc_ttor[1] = force_ttor[1]*c2 + theta_ttor[1]*c1 + phi1_ttor[1]*c3 + phi2_ttor[1]*c4; + acc_ttor[2] = force_ttor[2]*c2 + theta_ttor[2]*c1 + phi1_ttor[2]*c3 + phi2_ttor[2]*c4; + + acc_rtor[0] = force_rtor[0]*c2 + theta_rtor[0]*c1 + phi1_rtor[0]*c3 + phi2_rtor[0]*c4; + acc_rtor[1] = force_rtor[1]*c2 + theta_rtor[1]*c1 + phi1_rtor[1]*c3 + phi2_rtor[1]*c4; + acc_rtor[2] = force_rtor[2]*c2 + theta_rtor[2]*c1 + phi1_rtor[2]*c3 + phi2_rtor[2]*c4; + + double dE = u_LJ*u_phi1*u_phi2*u_theta; + if (debug_output) + fprintf(screen, " Energy contribution of this pair is %g\n", dE); + energy += dE; + + fforce[0] += acc_force[0]; + fforce[1] += acc_force[1]; + fforce[2] += acc_force[2]; + + ttor[0] += acc_ttor[0]; + ttor[1] += acc_ttor[1]; + ttor[2] += acc_ttor[2]; + + rtor[0] += acc_rtor[0]; + rtor[1] += acc_rtor[1]; + rtor[2] += acc_rtor[2]; + } + + if (debug_output && comm->me == 0 && !bail) { + fprintf(screen, "Energy contributions: %g %g %g %g\n", + u_LJ,u_theta, u_phi1, u_phi2); + fprintf(screen, "Forces: (%g %g %g) (%g %g %g)\n", + acc_force[0], acc_force[1], acc_force[2], + fforce[0], fforce[1], fforce[2]); + fprintf(screen, "Torque (t): (%g %g %g) (%g %g %g)\n", + acc_ttor[0], acc_ttor[1], acc_ttor[2], + ttor[0], ttor[1], ttor[2]); + fprintf(screen, "Torque (r): (%g %g %g) (%g %g %g)\n\n", + acc_rtor[0], acc_rtor[1], acc_rtor[2], + rtor[0], rtor[1], rtor[2]); + fprintf(screen, "pair %d, bond vectors: b1.b2 = %g, b1.b3 = %g, b2.b3 = %g\n\n\n", + pair_i, MathExtra::dot3(b_alp, b_bet), MathExtra::dot3(b_alp,b_gam), + MathExtra::dot3(b_bet, b_gam)); + } + } + + return energy; +} + + + +double PairPatchySphere::bond_vec_theta_part(const int i, const int j, + const int itype, const int jtype, + const double *r12, const double *b_alp, + const double *b_bet, double *fforce, + double *ttor, double *rtor) +{ + // Calculate the force and torque acquired due to the gradient in theta_12 + double cos_theta = -MathExtra::dot3(b_alp, b_bet); + const double theta_param = MathConst::MY_PI / theta_m[itype][jtype]; + + const double cos_theta_tol = cos(theta_m[itype][jtype]); + if (cos_theta <= cos_theta_tol) { + // There is no theta-contribution to the potential energy. + // This means the switching function is 0 and hence the entire potential + // is 0 too. + fforce[0] = fforce[1] = fforce[2] = 0.0; + ttor[0] = ttor[1] = ttor[2] = 0.0; + rtor[0] = rtor[1] = rtor[2] = 0.0; + return 0; + } + + double theta = (cos_theta >= 1.0 ? 0.0 :acos(cos_theta)); + + // Determine the forces and torques coming from theta: + + const double patch_b = 0.56123102415468651; + if (theta == 0.0) { + ttor[0] = ttor[1] = ttor[2] = 0.0; + rtor[0] = rtor[1] = rtor[2] = 0.0; + fforce[0] = fforce[1] = fforce[2] = 0.0; + return 2.0; // At theta == 0 the switching function has its maximum, 2. + }else{ + double c[3]; + MathExtra::cross3(b_alp, b_bet, c); + double factor = patch_b*patch_b*theta_param * sin(theta_param*theta)/(2.0*sin(theta)); + ttor[0] = factor*c[0]; + ttor[1] = factor*c[1]; + ttor[2] = factor*c[2]; + + rtor[0] = -ttor[0]; + rtor[1] = -ttor[1]; + rtor[2] = -ttor[2]; + + fforce[0] = fforce[1] = fforce[2] = 0.0; + return cos(theta * theta_param) + 1.0; + } +} + + +/** + Calculates the phi part to the force and torque. + It returns the value of the switching function (in range of [0,2]). + The force and torque needs to be multiplied by the other switching + functions and potentials u_LJ, u_phi (the other one) and u_theta. + + If this return 0, you know there is no torque or force for this bond pair. + If it return 2, the potential is maximal and there is no torque or force from + this phi but there might be from others. +*/ +double PairPatchySphere::bond_vec_phi_part( const int i, const int j, + const int itype, const int jtype, + const double *r12, const double rsq, + const double *b_alp, const double *b_bet, + const double *b_gam, const double *b_eps, + double *fforce, double *ttor, double *rtor) +{ + + // Calculate the force and torque acquired due to the gradient in phi + + const double patch_b = 0.56123102415468651; + const double patch_b2 = patch_b*patch_b; + + const double gamma_dot_rij = patch_b*MathExtra::dot3(b_gam, r12); + const double eps_dot_rij = patch_b*MathExtra::dot3(b_eps, r12); + const double gamma_dot_eps = patch_b2*MathExtra::dot3(b_gam, b_eps); + + const double r_eps_rij = rsq - eps_dot_rij*eps_dot_rij; + const double r_gam_rij = rsq - gamma_dot_rij*gamma_dot_rij; + + constexpr const double tol = 1e-4; + if (r_eps_rij < tol || r_gam_rij < tol) { + // This means phi is close to 0. In that case, the switching function + // Is close to 2.0 and there is no torque or force coming from this. + fforce[0] = fforce[1] = fforce[2] = 0.0; + ttor[0] = ttor[1] = ttor[2] = 0.0; + rtor[0] = rtor[1] = rtor[2] = 0.0; + return 2.0; + } + + double inv_sq = 1.0 / sqrt(r_gam_rij * r_eps_rij); + double cos_phi = gamma_dot_eps * rsq - gamma_dot_rij * eps_dot_rij; + cos_phi *= inv_sq; + + double phi = 0.0; + if (cos_phi >= 1.0) { + phi = 0.0; + }else if (cos_phi < -1.0) { + phi = MathConst::MY_PI; + }else{ + phi = acos(cos_phi); + } + + const double phi_tol = phi_m[itype][jtype]; + if (phi >= phi_tol) { + fforce[0] = fforce[1] = fforce[2] = 0.0; + ttor[0] = ttor[1] = ttor[2] = 0.0; + rtor[0] = rtor[1] = rtor[2]; + // In this case the switching function is 0. + return 0.0; + } + + double psi = gamma_dot_rij * eps_dot_rij - gamma_dot_eps * rsq; + double grad_cos_phi[3]; + double grad_cos_phi_gam[3]; + double fbj[3]; + + /* + grad_cos_phi = b_eps * gamma_dot_rij + b_gam * eps_dot_rij + - 2.0*r12*gamma_dot_eps - (r12 - b_eps * eps_dot_rij)*(psi/r_eps_rij) + - (r12 - b_gam * gamma_dot_rij)*(psi/r_gam_rij); + */ + const double p_eps_rij = psi/r_eps_rij; + const double p_gam_rij = psi/r_gam_rij; + + const double eps_p_eps = eps_dot_rij * p_eps_rij; + const double gam_p_gam = gamma_dot_rij * p_gam_rij; + + double c1 = gamma_dot_rij + eps_p_eps; + double c2 = eps_dot_rij + gam_p_gam; + double c3 = 2.0 * gamma_dot_eps + p_eps_rij + p_gam_rij; + + c1 *= inv_sq; + c2 *= inv_sq; + c3 *= inv_sq; + + grad_cos_phi[0] = c1*b_eps[0] + c2*b_gam[0] - c3*r12[0]; + grad_cos_phi[1] = c1*b_eps[1] + c2*b_gam[1] - c3*r12[1]; + grad_cos_phi[2] = c1*b_eps[2] + c2*b_gam[2] - c3*r12[2]; + + c1 = eps_dot_rij + gamma_dot_rij * p_gam_rij; + c2 = rsq * p_gam_rij; + c1 *= inv_sq; + c2 *= inv_sq; + + grad_cos_phi_gam[0] = r12[0] * c1 - b_eps[0] * rsq - b_gam[0] * c2; + grad_cos_phi_gam[1] = r12[1] * c1 - b_eps[1] * rsq - b_gam[1] * c2; + grad_cos_phi_gam[2] = r12[2] * c1 - b_eps[2] * rsq - b_gam[2] * c2; + + c1 = gamma_dot_rij + eps_dot_rij * p_eps_rij; + c2 = rsq * p_eps_rij; + c1 *= inv_sq; + c2 *= inv_sq; + + fbj[0] = r12[0] * c1 - b_gam[0] * rsq - b_eps[0] * c2; + fbj[1] = r12[1] * c1 - b_gam[1] * rsq - b_eps[1] * c2; + fbj[2] = r12[2] * c1 - b_gam[2] * rsq - b_eps[2] * c2; + + const double phi_param = MathConst::MY_PI / phi_m[itype][jtype]; + double sinc = phi > 0.001 ? sin(phi*phi_param)/sin(phi) : phi_param; + + // The torque is + double chain = 0.5*phi_param * sinc; + + fforce[0] = grad_cos_phi[0] * chain; + fforce[1] = grad_cos_phi[1] * chain; + fforce[2] = grad_cos_phi[2] * chain; + + double c[3]; + MathExtra::cross3(b_gam, grad_cos_phi_gam, c); + + ttor[0] = c[0] * chain; + ttor[1] = c[1] * chain; + ttor[2] = c[2] * chain; + + double k[3]; + MathExtra::cross3(b_eps, fbj, k); + rtor[0] = k[0] * chain; + rtor[1] = k[1] * chain; + rtor[2] = k[2] * chain; + + fforce[0] = grad_cos_phi[0] * chain; + fforce[1] = grad_cos_phi[1] * chain; + fforce[2] = grad_cos_phi[2] * chain; + + return cos(phi*phi_param) + 1.0; +} diff --git a/src/ASPHERE/pair_patchy_sphere.h b/src/ASPHERE/pair_patchy_sphere.h new file mode 100644 index 0000000000..9409026d1d --- /dev/null +++ b/src/ASPHERE/pair_patchy_sphere.h @@ -0,0 +1,93 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS + +PairStyle(patchysphere,PairPatchySphere) + +#else + +#ifndef LMP_PAIR_PATCHY_SPHERE_H +#define LMP_PAIR_PATCHY_SPHERE_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairPatchySphere : public Pair { + public: + PairPatchySphere(LAMMPS *); + virtual ~PairPatchySphere(); + virtual void compute(int, int); + virtual void settings(int, char **); + void coeff(int, char **); + virtual void init_style(); + double init_one(int, int); + //void write_restart(FILE *); + //void read_restart(FILE *); + //void write_restart_settings(FILE *); + //void read_restart_settings(FILE *); + //void write_data(FILE *); + //void write_data_all(FILE *); + + protected: + // enumerate the "encounter" possibilities. + enum{SPHERE_SPHERE,SPHERE_PATCHY,PATCHY_SPHERE,PATCHY_PATCHY}; + + double cut_global; + double **cut; + double **inner_cut; + double **offset; + double **epsilon, **sigma; + + + // Whole bunch of stuff related to bond vectors... + double **epsilon_b; // Patch binding strength. + int n_bond_pairs; // Number of bond pairs (combinations of alpha, beta, ...) + int **bond_pairs; // Enumerate bond pairs. + + double **phi_m, **theta_m; // Theta and phi scale factors. + + int n_bonds; // Number of bond vectors. + double **bond_vectors; // Bond vectors. + + class AtomVecEllipsoid *avec; + + bool debug_output; + + + void allocate(); + double bond_vec_analytic(const int i, const int j, double a1[3][3], + double a2[3][3], double *r12, const double rsq, + double *fforce, double *ttor, double *rtor); + + + double bond_vec_theta_part(const int i, const int j, + const int itype, const int jtype, + const double *r12, const double *b_alp, + const double *b_bet, double *fforce, double *ttor, + double *rtor); + double bond_vec_phi_part(const int i, const int j, + const int itype, const int jtype, + const double *r12, const double rsq, + const double *b_alp, const double *b_bet, + const double *b_gam, const double *b_eps, + double *fforce, double *ttor, double *rtor); + +}; + + +} // namespace + +#endif // LMP_PAIR_PATCHY_SPHERE_H +#endif // PAIR_CLASS From 8b055ee4efc753eb563d58c679d3e2c6684ee334 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Mon, 22 Oct 2018 11:24:11 -0400 Subject: [PATCH 03/54] Fixed compile error for fix_momentum_kokkos. --- src/KOKKOS/fix_momentum_kokkos.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/KOKKOS/fix_momentum_kokkos.cpp b/src/KOKKOS/fix_momentum_kokkos.cpp index 9af7e79da8..30cca73765 100644 --- a/src/KOKKOS/fix_momentum_kokkos.cpp +++ b/src/KOKKOS/fix_momentum_kokkos.cpp @@ -120,12 +120,13 @@ void FixMomentumKokkos::end_of_step() auto xflag2 = xflag; auto yflag2 = yflag; auto zflag2 = zflag; + const Few &vcm_ref = vcm; Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { if (mask(i) & groupbit2) { - if (xflag2) v(i,0) -= vcm[0]; - if (yflag2) v(i,1) -= vcm[1]; - if (zflag2) v(i,2) -= vcm[2]; + if (xflag2) v(i,0) -= vcm_ref[0]; + if (yflag2) v(i,1) -= vcm_ref[1]; + if (zflag2) v(i,2) -= vcm_ref[2]; } }); atomKK->modified(execution_space, V_MASK); @@ -158,6 +159,10 @@ void FixMomentumKokkos::end_of_step() auto prd = Few(domain->prd); auto h = Few(domain->h); auto triclinic = domain->triclinic; + + const Few &xcm_ref = xcm; + const Few &omega_ref = omega; + Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { if (mask[i] & groupbit2) { Few x_i; @@ -165,12 +170,12 @@ void FixMomentumKokkos::end_of_step() x_i[1] = x(i,1); x_i[2] = x(i,2); auto unwrap = DomainKokkos::unmap(prd,h,triclinic,x_i,image(i)); - auto dx = unwrap[0] - xcm[0]; - auto dy = unwrap[1] - xcm[1]; - auto dz = unwrap[2] - xcm[2]; - v(i,0) -= omega[1]*dz - omega[2]*dy; - v(i,1) -= omega[2]*dx - omega[0]*dz; - v(i,2) -= omega[0]*dy - omega[1]*dx; + auto dx = unwrap[0] - xcm_ref[0]; + auto dy = unwrap[1] - xcm_ref[1]; + auto dz = unwrap[2] - xcm_ref[2]; + v(i,0) -= omega_ref[1]*dz - omega_ref[2]*dy; + v(i,1) -= omega_ref[2]*dx - omega_ref[0]*dz; + v(i,2) -= omega_ref[0]*dy - omega_ref[1]*dx; } }); atomKK->modified(execution_space, V_MASK); @@ -201,4 +206,3 @@ template class FixMomentumKokkos; template class FixMomentumKokkos; #endif } - From 6618ca2270ab1ca8a87eb158a17c8bdc152596c7 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Wed, 24 Oct 2018 11:10:53 -0400 Subject: [PATCH 04/54] Makefile.kokkos_cuda_mpi --- src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi b/src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi index d6c5c566aa..57fc37c10e 100644 --- a/src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi +++ b/src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi @@ -6,7 +6,7 @@ SHELL = /bin/sh # compiler/linker settings # specify flags and libraries needed for your compiler -KOKKOS_ABSOLUTE_PATH = $(shell cd $(KOKKOS_PATH); pwd) +KOKKOS_ABSOLUTE_PATH = /home/stefan/projects/lammps-mine/lib/kokkos export MPICH_CXX = $(KOKKOS_ABSOLUTE_PATH)/bin/nvcc_wrapper export OMPI_CXX = $(KOKKOS_ABSOLUTE_PATH)/bin/nvcc_wrapper CC = mpicxx @@ -33,7 +33,7 @@ KOKKOS_ARCH = Kepler35 # LAMMPS ifdef settings # see possible settings in Section 2.2 (step 4) of manual -LMP_INC = -DLAMMPS_GZIP +LMP_INC = -DLAMMPS_GZIP -DLAMMPS_PNG -DLAMMPS_JPEG -DLAMMPS_FFMPEG # MPI library # see discussion in Section 2.2 (step 5) of manual @@ -55,9 +55,9 @@ MPI_LIB = # PATH = path for FFT library # LIB = name of FFT library -FFT_INC = -FFT_PATH = -FFT_LIB = +FFT_INC = -I/usr/include/ +FFT_PATH = -L/usr/lib/ +FFT_LIB = -lfftw3 # JPEG and/or PNG library # see discussion in Section 2.2 (step 7) of manual @@ -68,7 +68,7 @@ FFT_LIB = JPG_INC = JPG_PATH = -JPG_LIB = +JPG_LIB = -ljpeg -lpng # --------------------------------------------------------------------- # build rules and dependencies From 07ccfc355d7eac10057d20cec095f221435febec Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 25 Oct 2018 11:34:54 -0400 Subject: [PATCH 05/54] Added a fix to add active force to particles. --- doc/src/fix_active.txt | 50 ++++++ examples/USER/misc/active/active_langevin.in | 61 +++++++ examples/USER/misc/active/active_viscous.in | 66 ++++++++ src/KOKKOS/fix_momentum_kokkos.cpp | 24 ++- src/USER-MISC/fix_active.cpp | 163 +++++++++++++++++++ src/USER-MISC/fix_active.h | 55 +++++++ 6 files changed, 405 insertions(+), 14 deletions(-) create mode 100644 doc/src/fix_active.txt create mode 100644 examples/USER/misc/active/active_langevin.in create mode 100644 examples/USER/misc/active/active_viscous.in create mode 100644 src/USER-MISC/fix_active.cpp create mode 100644 src/USER-MISC/fix_active.h diff --git a/doc/src/fix_active.txt b/doc/src/fix_active.txt new file mode 100644 index 0000000000..3bc6c15326 --- /dev/null +++ b/doc/src/fix_active.txt @@ -0,0 +1,50 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +fix active command :pre + +[Syntax:] + +fix ID group-ID magnitude + +ID, group-ID are documented in "fix"_fix.html command :ulb,l +addforce = style name of this fix command :l +magnitude = magnitude of the active force :l +:ule + +[Examples:] + +fix active_group all active 1.0 +fix constant_velocity all viscous 1.0 + +[Description:] + +Adds a force of a constant magnitude to each atom in the group. The direction +of the force is along the axis obtained by rotating the z-axis along the atom's +quaternion. In other words, the force is along the z-axis in the atom's body +frame. + +:line + +[Restart, fix_modify, output, run start/stop, minimize info:] + +No information about this fix is written to "binary restart +files"_restart.html. + +This fix is not imposed during minimization. + +[Restrictions:] + +This fix makes use of per-atom quaternions to take into +account the fact that the orientation can rotate and hence the direction +of the active force can change. Therefore, this fix only works with +ellipsoidal particles. + +[Related commands:] + +"fix setforce"_fix_setforce.html, "fix addforce"_fix_addforce.html diff --git a/examples/USER/misc/active/active_langevin.in b/examples/USER/misc/active/active_langevin.in new file mode 100644 index 0000000000..3854729fc5 --- /dev/null +++ b/examples/USER/misc/active/active_langevin.in @@ -0,0 +1,61 @@ +# Uses a combnation of fix active and fix langevin to achieve +# self-propelled particles. + +dimension 3 +boundary p p p +units lj + +# Fix active uses quaternions to orient the active force so you need +# ellipsoidal particles, even if you do not care about asymmetric shape +atom_style ellipsoid + + +# Set up box and particles: +variable L equal 10 +region total block -$L $L -$L $L -$L $L +create_box 1 total +variable N equal 1000 +create_atoms 1 random $N 123456 total + +# Set particle shape: +set group all shape 1 1 1 +set group all quat/random 18238 +variable V equal "4.0*PI" +variable rho equal "1.0 / v_V" +# Density so that mass = 1 +set group all density ${rho} + +# Simple repulsive LJ +pair_style lj/cut 1.1225 +pair_coeff * * 1.0 1.0 +pair_modify shift yes + +# Remove initial overlap: +minimize 1e-4 1e-6 1000 10000 +reset_timestep 0 + +# Fixes for time integration +fix step all nve/asphere +fix active all active 1.0 +fix temp all langevin 1.0 1.0 1.0 12341 angmom 3.333333333333 + +variable DUMP_OUT string "active_langevin.dump" +variable MSD_OUT string "active_langevin_msd.dat" + +# Compute temperature and orientation +compute T all temp/asphere +compute quat all property/atom quatw quati quatj quatk +compute msd all msd +compute vacf all vacf + +# Some output: +thermo_style custom time step pe ke etotal temp c_T +thermo 1000 + +dump traj all custom 100 ${DUMP_OUT} id type x y z & + c_quat[1] c_quat[2] c_quat[3] c_quat[4] + +fix msd all ave/time 1 10 50 c_msd[4] c_vacf[1] c_vacf[2] c_vacf[3] c_vacf[4] file ${MSD_OUT} + +timestep 0.001 +run 10000 diff --git a/examples/USER/misc/active/active_viscous.in b/examples/USER/misc/active/active_viscous.in new file mode 100644 index 0000000000..f7660187e1 --- /dev/null +++ b/examples/USER/misc/active/active_viscous.in @@ -0,0 +1,66 @@ +# Uses a combnation of fix active and fix langevin to achieve +# self-propelled particles. + +dimension 3 +boundary p p p +units lj + +# Fix active uses quaternions to orient the active force so you need +# ellipsoidal particles, even if you do not care about asymmetric shape +atom_style ellipsoid + + +# Set up box and particles: +variable L equal 10 +region total block -$L $L -$L $L -$L $L +create_box 1 total +variable N equal 1000 +create_atoms 1 random $N 123456 total + +# Set particle shape: +set group all shape 1 1 1 +set group all quat/random 18238 +variable V equal "4.0*PI" +variable rho equal "1.0 / v_V" +# Density so that mass = 1 +set group all density ${rho} + +# Simple repulsive LJ +pair_style lj/cut 1.1225 +pair_coeff * * 0.0 1.0 +pair_modify shift yes + +# Remove initial overlap: +minimize 1e-4 1e-6 1000 10000 +reset_timestep 0 + +# Fixes for time integration +fix step all nve/asphere + +# Should lead to constant velocity of 10 per particle +fix active all active 1.0 +fix visc all viscous 0.1 + +# Initial velocities: +velocity all create 1.0 1234 + +variable DUMP_OUT string "active_viscous.dump" +variable MSD_OUT string "active_viscous_msd.dat" + +# Compute temperature and orientation +compute T all temp/asphere +compute quat all property/atom quatw quati quatj quatk +compute msd all msd +compute vacf all vacf + +# Some output: +thermo_style custom time step pe ke etotal temp c_T +thermo 1000 + +dump traj all custom 100 ${DUMP_OUT} id type x y z & + c_quat[1] c_quat[2] c_quat[3] c_quat[4] + +fix msd all ave/time 1 10 50 c_msd[4] c_vacf[1] c_vacf[2] c_vacf[3] c_vacf[4] file ${MSD_OUT} + +timestep 0.001 +run 10000 diff --git a/src/KOKKOS/fix_momentum_kokkos.cpp b/src/KOKKOS/fix_momentum_kokkos.cpp index dd86222227..493dffc3d9 100644 --- a/src/KOKKOS/fix_momentum_kokkos.cpp +++ b/src/KOKKOS/fix_momentum_kokkos.cpp @@ -121,13 +121,12 @@ void FixMomentumKokkos::end_of_step() auto xflag2 = xflag; auto yflag2 = yflag; auto zflag2 = zflag; - const Few &vcm_ref = vcm; Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { if (mask(i) & groupbit2) { - if (xflag2) v(i,0) -= vcm_ref[0]; - if (yflag2) v(i,1) -= vcm_ref[1]; - if (zflag2) v(i,2) -= vcm_ref[2]; + if (xflag2) v(i,0) -= vcm[0]; + if (yflag2) v(i,1) -= vcm[1]; + if (zflag2) v(i,2) -= vcm[2]; } }); atomKK->modified(execution_space, V_MASK); @@ -161,10 +160,6 @@ void FixMomentumKokkos::end_of_step() auto prd = Few(domain->prd); auto h = Few(domain->h); auto triclinic = domain->triclinic; - - const Few &xcm_ref = xcm; - const Few &omega_ref = omega; - Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { if (mask[i] & groupbit2) { Few x_i; @@ -172,12 +167,12 @@ void FixMomentumKokkos::end_of_step() x_i[1] = x(i,1); x_i[2] = x(i,2); auto unwrap = DomainKokkos::unmap(prd,h,triclinic,x_i,image(i)); - auto dx = unwrap[0] - xcm_ref[0]; - auto dy = unwrap[1] - xcm_ref[1]; - auto dz = unwrap[2] - xcm_ref[2]; - v(i,0) -= omega_ref[1]*dz - omega_ref[2]*dy; - v(i,1) -= omega_ref[2]*dx - omega_ref[0]*dz; - v(i,2) -= omega_ref[0]*dy - omega_ref[1]*dx; + auto dx = unwrap[0] - xcm[0]; + auto dy = unwrap[1] - xcm[1]; + auto dz = unwrap[2] - xcm[2]; + v(i,0) -= omega[1]*dz - omega[2]*dy; + v(i,1) -= omega[2]*dx - omega[0]*dz; + v(i,2) -= omega[0]*dy - omega[1]*dx; } }); atomKK->modified(execution_space, V_MASK); @@ -208,3 +203,4 @@ template class FixMomentumKokkos; template class FixMomentumKokkos; #endif } + diff --git a/src/USER-MISC/fix_active.cpp b/src/USER-MISC/fix_active.cpp new file mode 100644 index 0000000000..1bb0726748 --- /dev/null +++ b/src/USER-MISC/fix_active.cpp @@ -0,0 +1,163 @@ +/* ---------------------------------------------------------------------- + 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. + ------------------------------------------------------------------------- */ + +/* ----------------------------------------------------------------------- + Contributed by Stefan Paquay @ Brandeis University + + Thanks to Liesbeth Janssen @ Eindhoven University for useful discussions! + ----------------------------------------------------------------------- */ + + +#include +#include + +#include "fix_active.h" + +#include "atom.h" +#include "atom_vec_ellipsoid.h" +#include "citeme.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "group.h" +#include "math.h" +#include "math_const.h" +#include "math_extra.h" +#include "math_vector.h" +#include "modify.h" +#include "random_mars.h" +#include "respa.h" +#include "update.h" + + +using namespace LAMMPS_NS; +using namespace FixConst; +using namespace MathConst; + +/* + Might be used later, who knows... +static const char* cite_fix_active = + "fix active command:\n\n" + "@article{paquay-2018,\n" + " author = {Paquay, Stefan},\n" + " doi = {},\n" + " issn = {},\n" + " journal = {},\n" + " month = ,\n" + " number = ,\n" + " pages = ,\n" + " title = ,\n" + " volume = ,\n" + " year = \n" + "}\n\n"; +*/ + +static constexpr const bool debug_out = false; + +FixActive::FixActive( LAMMPS *lmp, int narg, char **argv ) + : Fix(lmp, narg, argv) +{ + // if( lmp->citeme) lmp->citeme->add(cite_fix_active); + if( narg < 4 ) error->all(FLERR, "Illegal fix active command"); + + AtomVecEllipsoid *av = static_cast(atom->avec); + if (!av) error->all(FLERR, "FixActive requires atom_style ellipsoid"); + + if( debug_out && comm->me == 0 ){ + fprintf(screen, "This is fix active, narg is %d\n", narg ); + fprintf(screen, "args:"); + for( int i = 0; i < narg; ++i ){ + fprintf(screen, " %s", argv[i]); + } + fprintf(screen, "\n"); + } + + // args: fix ID all active magnitude prop1 prop2 prop3 + // Optional args are + magnitude = force->numeric( FLERR, argv[3] ); +} + + +FixActive::~FixActive() +{} + + +int FixActive::setmask() +{ + int mask = 0; + mask |= POST_FORCE; + + return mask; +} + + +double FixActive::memory_usage() +{ + double bytes = 0.0; + return bytes; +} + + + +void FixActive::post_force(int /* vflag */ ) +{ + // Then do the rest: + double **f = atom->f; + + AtomVecEllipsoid *av = static_cast(atom->avec); + + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + AtomVecEllipsoid::Bonus *bonus = av->bonus; + // Add the active force to the atom force: + for( int i = 0; i < nlocal; ++i ){ + if( mask[i] & groupbit ){ + double f_act[3] = { 0.0, 0.0, 1.0 }; + double f_rot[3]; + + int* ellipsoid = atom->ellipsoid; + double *quat = bonus[ellipsoid[i]].quat; + tagint *tag = atom->tag; + + double Q[3][3]; + MathExtra::quat_to_mat( quat, Q ); + MathExtra::matvec( Q, f_act, f_rot ); + + if (debug_out && comm->me == 0) { + // Magical reference particle: + if (tag[i] == 12) { + fprintf(screen, "rotation quaternion: (%f %f %f %f)\n", + quat[0], quat[1], quat[2], quat[3]); + fprintf(screen, "rotation matrix: / %f %f %f \\\n", + Q[0][0] ,Q[0][1], Q[0][2]); + fprintf(screen, " | %f %f %f |\n", + Q[1][0] ,Q[1][1], Q[1][2]); + fprintf(screen, " \\ %f %f %f /\n", + Q[2][0] ,Q[2][1], Q[2][2]); + + fprintf(screen, "Active force on atom %d: (%f %f %f)\n", + tag[i], f_rot[0], f_rot[1], f_rot[2]); + fprintf(screen, " Total force before: (%f %f %f)\n", + f[i][0], f[i][1], f[i][2]); + } + } + + f[i][0] += magnitude * f_rot[0]; + f[i][1] += magnitude * f_rot[1]; + f[i][2] += magnitude * f_rot[2]; + + } + } +} diff --git a/src/USER-MISC/fix_active.h b/src/USER-MISC/fix_active.h new file mode 100644 index 0000000000..02a91db14a --- /dev/null +++ b/src/USER-MISC/fix_active.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(active,FixActive) + +#else + +#ifndef LMP_FIX_ACTIVE_H +#define LMP_FIX_ACTIVE_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixActive : public Fix { + public: + FixActive(class LAMMPS *, int, char **); + virtual ~FixActive(); + virtual int setmask(); + virtual void post_force(int); + // virtual void post_force_respa(int, int, int); + + double memory_usage(); + +protected: + double magnitude; + int thermostat_orient; +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Illegal ... command + +Self-explanatory. Check the input script syntax and compare to the +documentation for the command. You can use -echo screen as a +command-line option when running LAMMPS to see the offending line. + +*/ From 06cdf5545eaf499eb308842da402903eed96afe9 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 25 Oct 2018 11:41:58 -0400 Subject: [PATCH 06/54] Slightly modified example. --- examples/USER/misc/active/active_viscous.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/USER/misc/active/active_viscous.in b/examples/USER/misc/active/active_viscous.in index f7660187e1..62fdaa7751 100644 --- a/examples/USER/misc/active/active_viscous.in +++ b/examples/USER/misc/active/active_viscous.in @@ -27,7 +27,7 @@ set group all density ${rho} # Simple repulsive LJ pair_style lj/cut 1.1225 -pair_coeff * * 0.0 1.0 +pair_coeff * * 1.0 1.0 pair_modify shift yes # Remove initial overlap: @@ -63,4 +63,4 @@ dump traj all custom 100 ${DUMP_OUT} id type x y z & fix msd all ave/time 1 10 50 c_msd[4] c_vacf[1] c_vacf[2] c_vacf[3] c_vacf[4] file ${MSD_OUT} timestep 0.001 -run 10000 +run 100000 From 501e4572010cb94449912901b4209cb6c1da596a Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Sat, 29 Dec 2018 18:25:40 -0500 Subject: [PATCH 07/54] Commit before merge. --- .../cgdna/examples/oxDNA2/duplex2/input.duplex2 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/examples/USER/cgdna/examples/oxDNA2/duplex2/input.duplex2 b/examples/USER/cgdna/examples/oxDNA2/duplex2/input.duplex2 index 451fe62e3c..27b6d31049 100644 --- a/examples/USER/cgdna/examples/oxDNA2/duplex2/input.duplex2 +++ b/examples/USER/cgdna/examples/oxDNA2/duplex2/input.duplex2 @@ -14,8 +14,8 @@ atom_style hybrid bond ellipsoid atom_modify sort 0 1.0 # Pair interactions require lists of neighbours to be calculated -neighbor 1.0 bin -neigh_modify every 1 delay 0 check yes +neighbor 3.0 bin +neigh_modify every 30 delay 0 check yes read_data data.duplex2 @@ -67,11 +67,13 @@ variable erot equal c_erot variable ekin equal c_ekin variable epot equal c_epot variable etot equal c_erot+c_ekin+c_epot -fix 5 all print ${efreq} "$(step) ekin = ${ekin} | erot = ${erot} | epot = ${epot} | etot = ${etot}" screen yes +fix 5 all print ${efreq} "$(step) ekin = ${ekin} | erot = ${erot} | epot = ${epot} | etot = ${etot}" screen no file oxdna_thermo.dat -#dump out all custom ${ofreq} out.${number}.txt id x y z vx vy vz fx fy fz tqx tqy tqz -#dump_modify out sort id -#dump_modify out format line "%d %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le" +thermo 100000 + +dump out all custom ${ofreq} out.${number}.txt id x y z vx vy vz fx fy fz tqx tqy tqz +dump_modify out sort id +# dump_modify out format line "%d %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le" run 1000000 From 2b518f5a12fe5c3dcd588f6319bd666758342b15 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Tue, 9 Jul 2019 10:24:17 -0400 Subject: [PATCH 08/54] Renamed fix active to fix propel/self --- doc/src/fix_propel_self.txt | 50 ++++++++++ src/USER-MISC/fix_propel_self.cpp | 147 ++++++++++++++++++++++++++++++ src/USER-MISC/fix_propel_self.h | 55 +++++++++++ 3 files changed, 252 insertions(+) create mode 100644 doc/src/fix_propel_self.txt create mode 100644 src/USER-MISC/fix_propel_self.cpp create mode 100644 src/USER-MISC/fix_propel_self.h diff --git a/doc/src/fix_propel_self.txt b/doc/src/fix_propel_self.txt new file mode 100644 index 0000000000..3bc6c15326 --- /dev/null +++ b/doc/src/fix_propel_self.txt @@ -0,0 +1,50 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +fix active command :pre + +[Syntax:] + +fix ID group-ID magnitude + +ID, group-ID are documented in "fix"_fix.html command :ulb,l +addforce = style name of this fix command :l +magnitude = magnitude of the active force :l +:ule + +[Examples:] + +fix active_group all active 1.0 +fix constant_velocity all viscous 1.0 + +[Description:] + +Adds a force of a constant magnitude to each atom in the group. The direction +of the force is along the axis obtained by rotating the z-axis along the atom's +quaternion. In other words, the force is along the z-axis in the atom's body +frame. + +:line + +[Restart, fix_modify, output, run start/stop, minimize info:] + +No information about this fix is written to "binary restart +files"_restart.html. + +This fix is not imposed during minimization. + +[Restrictions:] + +This fix makes use of per-atom quaternions to take into +account the fact that the orientation can rotate and hence the direction +of the active force can change. Therefore, this fix only works with +ellipsoidal particles. + +[Related commands:] + +"fix setforce"_fix_setforce.html, "fix addforce"_fix_addforce.html diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp new file mode 100644 index 0000000000..623c82185d --- /dev/null +++ b/src/USER-MISC/fix_propel_self.cpp @@ -0,0 +1,147 @@ +/* ---------------------------------------------------------------------- + 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. + ------------------------------------------------------------------------- */ + +/* ----------------------------------------------------------------------- + Contributed by Stefan Paquay @ Brandeis University + + Thanks to Liesbeth Janssen @ Eindhoven University for useful discussions! + ----------------------------------------------------------------------- */ + + +#include +#include + +#include "fix_propel_self.h" + +#include "atom.h" +#include "atom_vec_ellipsoid.h" +#include "citeme.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "group.h" +#include "math.h" +#include "math_const.h" +#include "math_extra.h" +#include "math_vector.h" +#include "modify.h" +#include "random_mars.h" +#include "respa.h" +#include "update.h" + + +using namespace LAMMPS_NS; +using namespace FixConst; +using namespace MathConst; + + +static constexpr const bool debug_out = false; + + +FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) + : Fix(lmp, narg, argv) +{ + // if( lmp->citeme) lmp->citeme->add(cite_fix_active); + if( narg < 4 ) error->all(FLERR, "Illegal fix propel/self command"); + + AtomVecEllipsoid *av = static_cast(atom->avec); + if (!av) error->all(FLERR, "FixPropelSelf requires atom_style ellipsoid"); + + if( debug_out && comm->me == 0 ){ + fprintf(screen, "This is fix active, narg is %d\n", narg ); + fprintf(screen, "args:"); + for( int i = 0; i < narg; ++i ){ + fprintf(screen, " %s", argv[i]); + } + fprintf(screen, "\n"); + } + + // args: fix ID all active magnitude prop1 prop2 prop3 + // Optional args are + magnitude = force->numeric( FLERR, argv[3] ); +} + + +FixPropelSelf::~FixPropelSelf() +{} + + +int FixPropelSelf::setmask() +{ + int mask = 0; + mask |= POST_FORCE; + + return mask; +} + + +double FixPropelSelf::memory_usage() +{ + double bytes = 0.0; + return bytes; +} + + + +void FixPropelSelf::post_force(int /* vflag */ ) +{ + // Then do the rest: + double **f = atom->f; + + AtomVecEllipsoid *av = static_cast(atom->avec); + + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + AtomVecEllipsoid::Bonus *bonus = av->bonus; + // Add the active force to the atom force: + for( int i = 0; i < nlocal; ++i ){ + if( mask[i] & groupbit ){ + double f_act[3] = { 0.0, 0.0, 1.0 }; + double f_rot[3]; + + int* ellipsoid = atom->ellipsoid; + double *quat = bonus[ellipsoid[i]].quat; + tagint *tag = atom->tag; + + double Q[3][3]; + MathExtra::quat_to_mat( quat, Q ); + MathExtra::matvec( Q, f_act, f_rot ); + + if (debug_out && comm->me == 0) { + // Magical reference particle: + if (tag[i] == 12) { + fprintf(screen, "rotation quaternion: (%f %f %f %f)\n", + quat[0], quat[1], quat[2], quat[3]); + fprintf(screen, "rotation matrix: / %f %f %f \\\n", + Q[0][0] ,Q[0][1], Q[0][2]); + fprintf(screen, " | %f %f %f |\n", + Q[1][0] ,Q[1][1], Q[1][2]); + fprintf(screen, " \\ %f %f %f /\n", + Q[2][0] ,Q[2][1], Q[2][2]); + + fprintf(screen, "Active force on atom %d: (%f %f %f)\n", + tag[i], f_rot[0], f_rot[1], f_rot[2]); + fprintf(screen, " Total force before: (%f %f %f)\n", + f[i][0], f[i][1], f[i][2]); + } + } + + f[i][0] += magnitude * f_rot[0]; + f[i][1] += magnitude * f_rot[1]; + f[i][2] += magnitude * f_rot[2]; + + } + } +} diff --git a/src/USER-MISC/fix_propel_self.h b/src/USER-MISC/fix_propel_self.h new file mode 100644 index 0000000000..d6f114527a --- /dev/null +++ b/src/USER-MISC/fix_propel_self.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(propel/self,FixPropelSelf) + +#else + +#ifndef LMP_FIX_PROPEL_SELF_H +#define LMP_FIX_PROPEL_SELF_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixPropelSelf : public Fix { + public: + FixPropelSelf(class LAMMPS *, int, char **); + virtual ~FixPropelSelf(); + virtual int setmask(); + virtual void post_force(int); + // virtual void post_force_respa(int, int, int); + + double memory_usage(); + +protected: + double magnitude; + int thermostat_orient; +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Illegal ... command + +Self-explanatory. Check the input script syntax and compare to the +documentation for the command. You can use -echo screen as a +command-line option when running LAMMPS to see the offending line. + +*/ From cb3dce182bb23402048dde294dc6120dbf5640dc Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Tue, 9 Jul 2019 10:29:42 -0400 Subject: [PATCH 09/54] Commit before changing branches. --- src/USER-MISC/fix_propel_self.cpp | 2 +- src/fix_wall_region.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index 623c82185d..1786281928 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -66,7 +66,7 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) fprintf(screen, "\n"); } - // args: fix ID all active magnitude prop1 prop2 prop3 + // args: fix ID all propel/self magnitude prop1 prop2 prop3 // Optional args are magnitude = force->numeric( FLERR, argv[3] ); } diff --git a/src/fix_wall_region.cpp b/src/fix_wall_region.cpp index b33e7f1b0b..ff147d7446 100644 --- a/src/fix_wall_region.cpp +++ b/src/fix_wall_region.cpp @@ -1,4 +1,4 @@ - seems------------------------------------------------------------------- +/* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov From 8339d962009a164f850fe4afb75338bee5252ff6 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Tue, 9 Jul 2019 10:31:03 -0400 Subject: [PATCH 10/54] Undid weird change in random source file. --- src/fix_wall_region.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fix_wall_region.cpp b/src/fix_wall_region.cpp index b33e7f1b0b..ff147d7446 100644 --- a/src/fix_wall_region.cpp +++ b/src/fix_wall_region.cpp @@ -1,4 +1,4 @@ - seems------------------------------------------------------------------- +/* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov From 920ea89c37b88f96daf1bce8cbb6b4a4871a856c Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Tue, 9 Jul 2019 15:07:04 -0400 Subject: [PATCH 11/54] Added two modes, one via velocity and one via quaternion. --- src/USER-MISC/fix_propel_self.cpp | 126 +++++++++++++++++++++++++----- src/USER-MISC/fix_propel_self.h | 15 +++- 2 files changed, 120 insertions(+), 21 deletions(-) diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index 1786281928..13c5e0ef90 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -51,24 +51,34 @@ static constexpr const bool debug_out = false; FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) : Fix(lmp, narg, argv) { - // if( lmp->citeme) lmp->citeme->add(cite_fix_active); - if( narg < 4 ) error->all(FLERR, "Illegal fix propel/self command"); - - AtomVecEllipsoid *av = static_cast(atom->avec); - if (!av) error->all(FLERR, "FixPropelSelf requires atom_style ellipsoid"); + if( narg < 5 ) error->all(FLERR, "Illegal fix propel/self command"); - if( debug_out && comm->me == 0 ){ - fprintf(screen, "This is fix active, narg is %d\n", narg ); - fprintf(screen, "args:"); - for( int i = 0; i < narg; ++i ){ - fprintf(screen, " %s", argv[i]); + // The fix is to support the following cases: + // 1. Simple atoms, in which case the force points along the velocity + // 2. Cases where the atoms have an internal ellipsoid. Currently those + // styles are only body and aspherical particles. + // The first argument (mode) is used to differentiate between these. + + // args: fix ID all propel/self mode magnitude + // Optional args are + const char *mode_str = argv[3]; + if (strncmp(mode_str, "velocity", 8) == 0) { + mode = VELOCITY; + } else if (strncmp(mode_str, "quaternion", 10) == 0) { + // This mode should only be supported if the atom style has + // a quaternion (and if all atoms in the group have it) + if (verify_atoms_have_quaternion()) { + error->all(FLERR, "All atoms need a quaternion"); } - fprintf(screen, "\n"); + mode = QUATERNION; + } else { + char msg[2048]; + sprintf(msg, "Illegal mode \"%s\" for fix propel/self", mode_str); + error->all(FLERR, msg); } - // args: fix ID all propel/self magnitude prop1 prop2 prop3 - // Optional args are - magnitude = force->numeric( FLERR, argv[3] ); + + magnitude = force->numeric( FLERR, argv[4] ); } @@ -92,17 +102,29 @@ double FixPropelSelf::memory_usage() } - -void FixPropelSelf::post_force(int /* vflag */ ) +void FixPropelSelf::post_force(int vflag ) { - // Then do the rest: - double **f = atom->f; + switch(mode) { + case QUATERNION: + post_force_quaternion(vflag); + break; + case VELOCITY: + post_force_velocity(vflag); + break; + default: + error->all(FLERR, "reached statement that should be unreachable"); + } +} + + +void FixPropelSelf::post_force_quaternion(int /* vflag */ ) +{ + double **f = atom->f; AtomVecEllipsoid *av = static_cast(atom->avec); int *mask = atom->mask; int nlocal = atom->nlocal; - if (igroup == atom->firstgroup) nlocal = atom->nfirst; AtomVecEllipsoid::Bonus *bonus = av->bonus; // Add the active force to the atom force: @@ -141,7 +163,71 @@ void FixPropelSelf::post_force(int /* vflag */ ) f[i][0] += magnitude * f_rot[0]; f[i][1] += magnitude * f_rot[1]; f[i][2] += magnitude * f_rot[2]; - } } } + + + +void FixPropelSelf::post_force_velocity(int /*vflag*/ ) +{ + double **f = atom->f; + double **v = atom->v; + int *mask = atom->mask; + int nlocal = atom->nlocal; + tagint *tag = atom->tag; + + // Add the active force to the atom force: + for( int i = 0; i < nlocal; ++i ){ + if( mask[i] & groupbit ){ + const double *vi = v[i]; + double f_act[3] = { vi[0], vi[1], vi[2] }; + double nv2 = vi[0]*vi[0] + vi[1]*vi[1] + vi[2]*vi[2]; + double fnorm = magnitude / sqrt(nv2); + + if (debug_out && comm->me == 0) { + // Magical reference particle: + if (tag[i] == 12) { + fprintf(screen, "Active force on atom %d: (%f %f %f)\n", + tag[i], f_act[0], f_act[1], f_act[2]); + fprintf(screen, " Total force before: (%f %f %f)\n", + f[i][0], f[i][1], f[i][2]); + } + } + + f[i][0] += fnorm * f_act[0]; + f[i][1] += fnorm * f_act[1]; + f[i][2] += fnorm * f_act[2]; + } + } +} + + +int FixPropelSelf::verify_atoms_have_quaternion() +{ + int ellipsoid_flag = atom->ellipsoid_flag; + int body_flag = atom->body_flag; + int *mask = atom->mask; + if (! (ellipsoid_flag || body_flag) ){ + error->all(FLERR, "mode quaternion requires body or ellipsoid atoms"); + } + + // Make sure all atoms have ellipsoid or body set: + for (int i = 0; i < atom->nlocal; ++i) { + if (mask[i] & groupbit) { + if (ellipsoid_flag && atom->ellipsoid[i] < 0) { + error->all(FLERR, "Got atom without ellipsoid set"); + // Kind-of pointless but silences some compiler warnings: + return 1; + } + if (body_flag && atom->body[i] < 0) { + error->all(FLERR, "Got atom without body set"); + // Kind-of pointless but silences some compiler warnings: + return 1; + } + } + } + + return 0; +} + diff --git a/src/USER-MISC/fix_propel_self.h b/src/USER-MISC/fix_propel_self.h index d6f114527a..45b2afffc3 100644 --- a/src/USER-MISC/fix_propel_self.h +++ b/src/USER-MISC/fix_propel_self.h @@ -26,6 +26,12 @@ namespace LAMMPS_NS { class FixPropelSelf : public Fix { public: + + enum operation_modes { + VELOCITY = 0, + QUATERNION = 1 + }; + FixPropelSelf(class LAMMPS *, int, char **); virtual ~FixPropelSelf(); virtual int setmask(); @@ -34,9 +40,16 @@ class FixPropelSelf : public Fix { double memory_usage(); -protected: +private: double magnitude; int thermostat_orient; + int mode; + + int verify_atoms_have_quaternion(); + void post_force_velocity(int); + void post_force_quaternion(int); + + }; } From f2b567bfb638437d4b6249615624ae747c6fe37a Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 29 Aug 2019 09:00:36 -0400 Subject: [PATCH 12/54] Commit before merging latest changes in master. --- doc/src/fix_active.txt | 50 --------------- doc/src/fix_propel_self.txt | 21 ++++--- examples/USER/misc/active/active_langevin.in | 61 ------------------ examples/USER/misc/active/active_viscous.in | 66 -------------------- src/USER-MISC/fix_propel_self.cpp | 7 +-- 5 files changed, 16 insertions(+), 189 deletions(-) delete mode 100644 doc/src/fix_active.txt delete mode 100644 examples/USER/misc/active/active_langevin.in delete mode 100644 examples/USER/misc/active/active_viscous.in diff --git a/doc/src/fix_active.txt b/doc/src/fix_active.txt deleted file mode 100644 index 3bc6c15326..0000000000 --- a/doc/src/fix_active.txt +++ /dev/null @@ -1,50 +0,0 @@ -"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c - -:link(lws,http://lammps.sandia.gov) -:link(ld,Manual.html) -:link(lc,Section_commands.html#comm) - -:line - -fix active command :pre - -[Syntax:] - -fix ID group-ID magnitude - -ID, group-ID are documented in "fix"_fix.html command :ulb,l -addforce = style name of this fix command :l -magnitude = magnitude of the active force :l -:ule - -[Examples:] - -fix active_group all active 1.0 -fix constant_velocity all viscous 1.0 - -[Description:] - -Adds a force of a constant magnitude to each atom in the group. The direction -of the force is along the axis obtained by rotating the z-axis along the atom's -quaternion. In other words, the force is along the z-axis in the atom's body -frame. - -:line - -[Restart, fix_modify, output, run start/stop, minimize info:] - -No information about this fix is written to "binary restart -files"_restart.html. - -This fix is not imposed during minimization. - -[Restrictions:] - -This fix makes use of per-atom quaternions to take into -account the fact that the orientation can rotate and hence the direction -of the active force can change. Therefore, this fix only works with -ellipsoidal particles. - -[Related commands:] - -"fix setforce"_fix_setforce.html, "fix addforce"_fix_addforce.html diff --git a/doc/src/fix_propel_self.txt b/doc/src/fix_propel_self.txt index 3bc6c15326..b65b4780e9 100644 --- a/doc/src/fix_propel_self.txt +++ b/doc/src/fix_propel_self.txt @@ -6,28 +6,33 @@ :line -fix active command :pre +fix propel/self command :pre [Syntax:] -fix ID group-ID magnitude +fix ID group-ID propel/self mode magnitude ID, group-ID are documented in "fix"_fix.html command :ulb,l -addforce = style name of this fix command :l +propel/self = style name of this fix command :l +mode = velocity or quaternion :l magnitude = magnitude of the active force :l :ule [Examples:] -fix active_group all active 1.0 +fix active_group all propel/self velocity 1.0 fix constant_velocity all viscous 1.0 [Description:] -Adds a force of a constant magnitude to each atom in the group. The direction -of the force is along the axis obtained by rotating the z-axis along the atom's -quaternion. In other words, the force is along the z-axis in the atom's body -frame. +Adds a force of a constant magnitude to each atom in the group. The nature in +which the force is added depends on the mode. +For mode = velocity, the active force acts along the velocity vector of each +atom. +For mode = quaternion the force is along the axis obtained by rotating the +z-axis along the atom's quaternion. In other words, the force is along the +z-axis in the atom's body frame. This mode requires all atoms in the group +to have a quaternion, so atom_style should either be ellipsoid or body. :line diff --git a/examples/USER/misc/active/active_langevin.in b/examples/USER/misc/active/active_langevin.in deleted file mode 100644 index 3854729fc5..0000000000 --- a/examples/USER/misc/active/active_langevin.in +++ /dev/null @@ -1,61 +0,0 @@ -# Uses a combnation of fix active and fix langevin to achieve -# self-propelled particles. - -dimension 3 -boundary p p p -units lj - -# Fix active uses quaternions to orient the active force so you need -# ellipsoidal particles, even if you do not care about asymmetric shape -atom_style ellipsoid - - -# Set up box and particles: -variable L equal 10 -region total block -$L $L -$L $L -$L $L -create_box 1 total -variable N equal 1000 -create_atoms 1 random $N 123456 total - -# Set particle shape: -set group all shape 1 1 1 -set group all quat/random 18238 -variable V equal "4.0*PI" -variable rho equal "1.0 / v_V" -# Density so that mass = 1 -set group all density ${rho} - -# Simple repulsive LJ -pair_style lj/cut 1.1225 -pair_coeff * * 1.0 1.0 -pair_modify shift yes - -# Remove initial overlap: -minimize 1e-4 1e-6 1000 10000 -reset_timestep 0 - -# Fixes for time integration -fix step all nve/asphere -fix active all active 1.0 -fix temp all langevin 1.0 1.0 1.0 12341 angmom 3.333333333333 - -variable DUMP_OUT string "active_langevin.dump" -variable MSD_OUT string "active_langevin_msd.dat" - -# Compute temperature and orientation -compute T all temp/asphere -compute quat all property/atom quatw quati quatj quatk -compute msd all msd -compute vacf all vacf - -# Some output: -thermo_style custom time step pe ke etotal temp c_T -thermo 1000 - -dump traj all custom 100 ${DUMP_OUT} id type x y z & - c_quat[1] c_quat[2] c_quat[3] c_quat[4] - -fix msd all ave/time 1 10 50 c_msd[4] c_vacf[1] c_vacf[2] c_vacf[3] c_vacf[4] file ${MSD_OUT} - -timestep 0.001 -run 10000 diff --git a/examples/USER/misc/active/active_viscous.in b/examples/USER/misc/active/active_viscous.in deleted file mode 100644 index 62fdaa7751..0000000000 --- a/examples/USER/misc/active/active_viscous.in +++ /dev/null @@ -1,66 +0,0 @@ -# Uses a combnation of fix active and fix langevin to achieve -# self-propelled particles. - -dimension 3 -boundary p p p -units lj - -# Fix active uses quaternions to orient the active force so you need -# ellipsoidal particles, even if you do not care about asymmetric shape -atom_style ellipsoid - - -# Set up box and particles: -variable L equal 10 -region total block -$L $L -$L $L -$L $L -create_box 1 total -variable N equal 1000 -create_atoms 1 random $N 123456 total - -# Set particle shape: -set group all shape 1 1 1 -set group all quat/random 18238 -variable V equal "4.0*PI" -variable rho equal "1.0 / v_V" -# Density so that mass = 1 -set group all density ${rho} - -# Simple repulsive LJ -pair_style lj/cut 1.1225 -pair_coeff * * 1.0 1.0 -pair_modify shift yes - -# Remove initial overlap: -minimize 1e-4 1e-6 1000 10000 -reset_timestep 0 - -# Fixes for time integration -fix step all nve/asphere - -# Should lead to constant velocity of 10 per particle -fix active all active 1.0 -fix visc all viscous 0.1 - -# Initial velocities: -velocity all create 1.0 1234 - -variable DUMP_OUT string "active_viscous.dump" -variable MSD_OUT string "active_viscous_msd.dat" - -# Compute temperature and orientation -compute T all temp/asphere -compute quat all property/atom quatw quati quatj quatk -compute msd all msd -compute vacf all vacf - -# Some output: -thermo_style custom time step pe ke etotal temp c_T -thermo 1000 - -dump traj all custom 100 ${DUMP_OUT} id type x y z & - c_quat[1] c_quat[2] c_quat[3] c_quat[4] - -fix msd all ave/time 1 10 50 c_msd[4] c_vacf[1] c_vacf[2] c_vacf[3] c_vacf[4] file ${MSD_OUT} - -timestep 0.001 -run 100000 diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index 13c5e0ef90..8f98de518b 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -58,7 +58,7 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) // 2. Cases where the atoms have an internal ellipsoid. Currently those // styles are only body and aspherical particles. // The first argument (mode) is used to differentiate between these. - + // args: fix ID all propel/self mode magnitude // Optional args are const char *mode_str = argv[3]; @@ -77,7 +77,6 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) error->all(FLERR, msg); } - magnitude = force->numeric( FLERR, argv[4] ); } @@ -217,12 +216,12 @@ int FixPropelSelf::verify_atoms_have_quaternion() if (mask[i] & groupbit) { if (ellipsoid_flag && atom->ellipsoid[i] < 0) { error->all(FLERR, "Got atom without ellipsoid set"); - // Kind-of pointless but silences some compiler warnings: + // Kind-of pointless return but silences compiler warnings: return 1; } if (body_flag && atom->body[i] < 0) { error->all(FLERR, "Got atom without body set"); - // Kind-of pointless but silences some compiler warnings: + // Kind-of pointless return silences compiler warnings: return 1; } } From e0aefd6b44a94c726b2e781fd879a9e128af8798 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 29 Aug 2019 09:41:50 -0400 Subject: [PATCH 13/54] Some code clean-up, added safety check in post_force_velocity. --- .../2d_velocity/in.2d_langevin | 37 +++++++++++++ .../fix_propel_self/2d_velocity/in.2d_viscous | 37 +++++++++++++ .../3d_quaternion/in.3d_quaternion | 40 ++++++++++++++ src/USER-MISC/fix_propel_self.cpp | 54 ++++++++++--------- 4 files changed, 144 insertions(+), 24 deletions(-) create mode 100644 examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin create mode 100644 examples/USER/misc/fix_propel_self/2d_velocity/in.2d_viscous create mode 100644 examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion diff --git a/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin new file mode 100644 index 0000000000..b7a1b93745 --- /dev/null +++ b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin @@ -0,0 +1,37 @@ +dimension 2 +boundary p p p + +variable L equal 20 +region total block -$L $L -$L $L -0.5 0.5 +lattice hex 0.3 +create_box 2 total +create_atoms 1 box + +# Set random fraction to passive: +set type 1 type/fraction 2 0.5 1337 + +# Purely repulsive particles: +variable rc equal "2^(1.0/6.0)" +pair_style lj/cut ${rc} +pair_coeff * * 1.0 1.0 +pair_modify shift yes + +mass * 1.0 + +fix step all nve +fix temp all langevin 1.0 1.0 1.0 13 +fix twod all enforce2d + +neighbor 0.6 bin + +dump traj all custom 250 2d_active.dump.bin id type x y z + +thermo_style custom time step pe ke etotal temp +thermo 1000 +run 25000 + +fix active all propel/self velocity 1.0 + +# With active force there is more motion so increase bin size: +neighbor 1.0 bin +run 25000 diff --git a/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_viscous b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_viscous new file mode 100644 index 0000000000..e6bb1169e0 --- /dev/null +++ b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_viscous @@ -0,0 +1,37 @@ +dimension 2 +boundary p p p + +variable L equal 20 +region total block -$L $L -$L $L -0.5 0.5 +lattice hex 0.3 +create_box 2 total +create_atoms 1 box + +# Set random fraction to passive: +set type 1 type/fraction 2 0.5 1337 + +# Purely repulsive particles: +variable rc equal "2^(1.0/6.0)" +pair_style lj/cut ${rc} +pair_coeff * * 1.0 1.0 +pair_modify shift yes + +mass * 1.0 + +fix step all nve +fix twod all enforce2d + +neighbor 0.6 bin + +dump traj all custom 250 2d_active.dump.bin id type x y z + +thermo_style custom time step pe ke etotal temp +thermo 1000 +run 25000 + +fix active all propel/self velocity 1.0 +fix fric all viscous 1.0 + +# With active force there is more motion so increase bin size: +neighbor 1.0 bin +run 25000 diff --git a/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion b/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion new file mode 100644 index 0000000000..b43d6304b3 --- /dev/null +++ b/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion @@ -0,0 +1,40 @@ +dimension 3 +boundary p p p + +atom_style ellipsoid +variable L equal 20 +region total block -$L $L -$L $L -$L $L +lattice sc 0.1 +create_box 2 total +create_atoms 1 box + +# Set random fraction to passive: +set type 1 type/fraction 2 0.5 1337 + +# Purely repulsive particles: +variable rc equal "2^(1.0/6.0)" +pair_style lj/cut ${rc} +pair_coeff * * 1.0 1.0 +pair_modify shift yes + +# mass * 1.0 +set type * density 1.0 +set type * shape 1.0 1.0 1.0 +set type * quat 0 0 1 0 + +fix step all nve +fix temp all langevin 1.0 1.0 1.0 13 + +neighbor 0.6 bin + +dump traj all custom 100 3d_active.dump.bin id type x y z fx fy fz + +thermo_style custom time step pe ke etotal temp +thermo 100 +run 5000 + +fix active all propel/self quaternion 1.0 + +# With active force there is more motion so increase bin size: +neighbor 1.0 bin +run 5000 diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index 8f98de518b..9cb5bb2207 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -103,16 +103,16 @@ double FixPropelSelf::memory_usage() void FixPropelSelf::post_force(int vflag ) { - switch(mode) { - case QUATERNION: - post_force_quaternion(vflag); - break; - case VELOCITY: - post_force_velocity(vflag); - break; - default: - error->all(FLERR, "reached statement that should be unreachable"); - } + switch(mode) { + case QUATERNION: + post_force_quaternion(vflag); + break; + case VELOCITY: + post_force_velocity(vflag); + break; + default: + error->all(FLERR, "reached statement that should be unreachable"); + } } @@ -179,10 +179,16 @@ void FixPropelSelf::post_force_velocity(int /*vflag*/ ) // Add the active force to the atom force: for( int i = 0; i < nlocal; ++i ){ if( mask[i] & groupbit ){ - const double *vi = v[i]; - double f_act[3] = { vi[0], vi[1], vi[2] }; - double nv2 = vi[0]*vi[0] + vi[1]*vi[1] + vi[2]*vi[2]; - double fnorm = magnitude / sqrt(nv2); + const double *vi = v[i]; + double f_act[3] = { vi[0], vi[1], vi[2] }; + double nv2 = vi[0]*vi[0] + vi[1]*vi[1] + vi[2]*vi[2]; + double fnorm = 0.0; + constexpr const double TOL = 1e-14; + if (nv2 > TOL) { + // Without this check you can run into numerical issues + // because fnorm will blow up. + fnorm = magnitude / sqrt(nv2); + } if (debug_out && comm->me == 0) { // Magical reference particle: @@ -214,16 +220,16 @@ int FixPropelSelf::verify_atoms_have_quaternion() // Make sure all atoms have ellipsoid or body set: for (int i = 0; i < atom->nlocal; ++i) { if (mask[i] & groupbit) { - if (ellipsoid_flag && atom->ellipsoid[i] < 0) { - error->all(FLERR, "Got atom without ellipsoid set"); - // Kind-of pointless return but silences compiler warnings: - return 1; - } - if (body_flag && atom->body[i] < 0) { - error->all(FLERR, "Got atom without body set"); - // Kind-of pointless return silences compiler warnings: - return 1; - } + if (ellipsoid_flag && atom->ellipsoid[i] < 0) { + error->all(FLERR, "Got atom without ellipsoid set"); + // Kind-of pointless return but silences compiler warnings: + return 1; + } + if (body_flag && atom->body[i] < 0) { + error->all(FLERR, "Got atom without body set"); + // Kind-of pointless return silences compiler warnings: + return 1; + } } } From 712b385b67c0169c1f5b897b85adce28871d64eb Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 29 Aug 2019 09:44:54 -0400 Subject: [PATCH 14/54] Updated docs --- doc/src/fix_propel_self.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/src/fix_propel_self.txt b/doc/src/fix_propel_self.txt index b65b4780e9..e3a686802e 100644 --- a/doc/src/fix_propel_self.txt +++ b/doc/src/fix_propel_self.txt @@ -21,7 +21,9 @@ magnitude = magnitude of the active force :l [Examples:] fix active_group all propel/self velocity 1.0 -fix constant_velocity all viscous 1.0 +fix constant_velocity all viscous 1.0 :pre + +fix active_group all propel/self quaternion 1.0 :pre [Description:] @@ -47,8 +49,8 @@ This fix is not imposed during minimization. This fix makes use of per-atom quaternions to take into account the fact that the orientation can rotate and hence the direction -of the active force can change. Therefore, this fix only works with -ellipsoidal particles. +of the active force can change. Therefore, this fix only works with atom_styles +that have a quaternion. [Related commands:] From cdca2f2d7ce5c624b11d7a42d780e2ad60e6fd6a Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 29 Aug 2019 09:50:27 -0400 Subject: [PATCH 15/54] Removed spurious file changes not belonging to this branch. --- .../cgdna/examples/oxDNA2/duplex2/in.duplex2 | 80 -- src/ASPHERE/pair_patchy_sphere.cpp | 884 ------------------ src/ASPHERE/pair_patchy_sphere.h | 93 -- src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi | 125 --- src/USER-MISC/fix_active.cpp | 163 ---- src/USER-MISC/fix_active.h | 55 -- 6 files changed, 1400 deletions(-) delete mode 100644 examples/USER/cgdna/examples/oxDNA2/duplex2/in.duplex2 delete mode 100644 src/ASPHERE/pair_patchy_sphere.cpp delete mode 100644 src/ASPHERE/pair_patchy_sphere.h delete mode 100644 src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi delete mode 100644 src/USER-MISC/fix_active.cpp delete mode 100644 src/USER-MISC/fix_active.h diff --git a/examples/USER/cgdna/examples/oxDNA2/duplex2/in.duplex2 b/examples/USER/cgdna/examples/oxDNA2/duplex2/in.duplex2 deleted file mode 100644 index 694d426140..0000000000 --- a/examples/USER/cgdna/examples/oxDNA2/duplex2/in.duplex2 +++ /dev/null @@ -1,80 +0,0 @@ -variable number equal 2 -variable ofreq equal 1000 -variable efreq equal 1000 - -units lj - -dimension 3 - -newton off - -boundary p p p - -atom_style hybrid bond ellipsoid -atom_modify sort 0 1.0 - -# Pair interactions require lists of neighbours to be calculated -neighbor 3.0 bin -neigh_modify every 30 delay 0 check yes - -read_data data.duplex2 - -set atom * mass 3.1575 - -group all type 1 4 - -# oxDNA bond interactions - FENE backbone -bond_style oxdna2/fene -bond_coeff * 2.0 0.25 0.7564 - -# oxDNA pair interactions -pair_style hybrid/overlay oxdna2/excv oxdna2/stk oxdna2/hbond oxdna2/xstk oxdna2/coaxstk oxdna2/dh -pair_coeff * * oxdna2/excv 2.0 0.7 0.675 2.0 0.515 0.5 2.0 0.33 0.32 -pair_coeff * * oxdna2/stk seqav 0.1 6.0 0.4 0.9 0.32 0.6 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 2.0 0.65 2.0 0.65 -pair_coeff * * oxdna2/hbond seqav 0.0 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45 -pair_coeff 1 4 oxdna2/hbond seqav 1.0678 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45 -pair_coeff 2 3 oxdna2/hbond seqav 1.0678 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45 -pair_coeff * * oxdna2/xstk 47.5 0.575 0.675 0.495 0.655 2.25 0.791592653589793 0.58 1.7 1.0 0.68 1.7 1.0 0.68 1.5 0 0.65 1.7 0.875 0.68 1.7 0.875 0.68 -pair_coeff * * oxdna2/coaxstk 58.5 0.4 0.6 0.22 0.58 2.0 2.891592653589793 0.65 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 40.0 3.116592653589793 -pair_coeff * * oxdna2/dh 0.1 1.0 0.815 - -# NVE ensemble -#fix 1 all nve/dot -fix 1 all nve/dotc/langevin 0.1 0.1 0.03 457145 angmom 10 -#fix 1 all nve/asphere -#fix 2 all langevin 0.1 0.1 0.03 457145 angmom 10 - -timestep 1e-5 - -#comm_style tiled -#fix 3 all balance 10000 1.1 rcb - -#compute mol all chunk/atom molecule -#compute mychunk all vcm/chunk mol -#fix 4 all ave/time 10000 1 10000 c_mychunk[1] c_mychunk[2] c_mychunk[3] file vcm.txt mode vector - -#dump pos all xyz ${ofreq} traj.${number}.xyz - -#compute quat all property/atom quatw quati quatj quatk -#dump quat all custom ${ofreq} quat.${number}.txt id c_quat[1] c_quat[2] c_quat[3] c_quat[4] -#dump_modify quat sort id -#dump_modify quat format line "%d %13.6le %13.6le %13.6le %13.6le" - -compute erot all erotate/asphere -compute ekin all ke -compute epot all pe -variable erot equal c_erot -variable ekin equal c_ekin -variable epot equal c_epot -variable etot equal c_erot+c_ekin+c_epot -fix 5 all print ${efreq} "$(step) ekin = ${ekin} | erot = ${erot} | epot = ${epot} | etot = ${etot}" screen no file oxdna_thermo.dat - -thermo 100000 - -dump out all custom ${ofreq} out.${number}.txt id x y z vx vy vz fx fy fz tqx tqy tqz -dump_modify out sort id -# dump_modify out format line "%d %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le" - -run 10000 - -#write_restart config.${number}.* diff --git a/src/ASPHERE/pair_patchy_sphere.cpp b/src/ASPHERE/pair_patchy_sphere.cpp deleted file mode 100644 index 928edb415a..0000000000 --- a/src/ASPHERE/pair_patchy_sphere.cpp +++ /dev/null @@ -1,884 +0,0 @@ -/* ---------------------------------------------------------------------- - 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: Stefan Paquay (Brandeis University) -------------------------------------------------------------------------- */ - -#include -#include -#include -#include -#include "pair_patchy_sphere.h" - -#include "atom.h" -#include "atom_vec_ellipsoid.h" -#include "comm.h" -#include "force.h" -#include "math_const.h" -#include "math_extra.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "integrate.h" -#include "citeme.h" -#include "memory.h" -#include "error.h" - -using namespace LAMMPS_NS; - -constexpr const bool nine_pairs = false; - -/* ---------------------------------------------------------------------- */ - -PairPatchySphere::PairPatchySphere(LAMMPS *lmp) : Pair(lmp) -{ - single_enable = 0; - // writedata = 1; // Add later. - allocated = 0; - setflag = NULL; - -} - -/* ---------------------------------------------------------------------- */ - - -PairPatchySphere::~PairPatchySphere() -{ - if (allocated) { - memory->destroy(cutsq); - memory->destroy(cut); - memory->destroy(inner_cut); - - memory->destroy(offset); - memory->destroy(epsilon); - memory->destroy(sigma); - memory->destroy(epsilon_b); - memory->destroy(phi_m); - memory->destroy(theta_m); - - memory->destroy(bond_pairs); - memory->destroy(bond_vectors); - - memory->destroy(setflag); - - } -} - -/* ---------------------------------------------------------------------- */ - - -void PairPatchySphere::allocate() -{ - int n = atom->ntypes; - - memory->create(cutsq, n+1,n+1, "pair:cutsq"); - memory->create(cut, n+1,n+1, "pair:cut"); - memory->create(inner_cut, n+1,n+1, "pair:inner_cut"); - memory->create(offset, n+1,n+1, "pair:offset"); - memory->create(epsilon, n+1,n+1, "pair:epsilon"); - memory->create(sigma, n+1,n+1, "pair:sigma"); - memory->create(epsilon_b, n+1,n+1, "pair:epsilon_b"); - memory->create(phi_m, n+1, n+1, "pair:phi_m"); - memory->create(theta_m, n+1, n+1, "pair:theta_m"); - - // For now the complementary pairs are fixed. - n_bonds = 3; - if (nine_pairs){ - n_bond_pairs = 9; - } else { - n_bond_pairs = 3; - } - memory->create(bond_pairs, n_bond_pairs, 6, "pair:bond_pairs"); - memory->create(bond_vectors, n_bonds, 3, "pair:bond_vectors"); - - if( comm->me == 0 ) fprintf(screen, "n is %d\n", n); - memory->create(setflag, n+1, n+1, "pair:setflag"); - - - allocated = 1; -} - - -/* ---------------------------------------------------------------------- */ - - -void PairPatchySphere::settings(int narg, char **arg) -{ - // params: phi_m, theta_m, cut-off - if (narg != 1 && narg != 2) error->all(FLERR,"Illegal pair_style command"); - - if (debug_output && comm->me == 0) { - fprintf(screen, "Got %d args:", narg); - for (int i = 0; i < narg; ++i) { - fprintf(screen, " %s", arg[i]); - } - fprintf(screen, "\n"); - } - cut_global = force->numeric(FLERR, arg[0]); - - if (narg == 2) - debug_output = force->inumeric(FLERR, arg[1]); - - if (allocated){ - for (int i = 1; i < atom->ntypes; ++i){ - for (int j = 1; j <= atom->ntypes; ++j){ - cut[i][j] = cut_global; - cutsq[i][j] = cut[i][j]*cut[i][j]; - } - } - } -} - -/* ---------------------------------------------------------------------- */ - -void PairPatchySphere::coeff(int narg, char **arg) -{ - // Coeffs are epsilon, sigma, epsilon_b, phi_m, theta_m - if (narg < 7 || narg > 8) - error->all(FLERR, "Incorrect args for pair coefficients"); - - if (!allocated) allocate(); - - double cut_one = cut_global; - int ilo, ihi, jlo, jhi; - force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); - force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); - - double epsilon_one = force->numeric(FLERR, arg[2]); - double sigma_one = force->numeric(FLERR, arg[3]); - double epsilon_b_one = force->numeric(FLERR, arg[4]); - double phi_m_one = force->numeric(FLERR, arg[5]); - double theta_m_one = force->numeric(FLERR, arg[6]); - - double rc_one = sigma_one * pow(2.0,1.0/6.0); - - if (narg == 8) cut_one = force->numeric(FLERR, arg[7]); - - int count = 0; - for (int i = ilo; i <= ihi; ++i){ - for (int j = jlo; j <= jhi; ++j ){ - epsilon[i][j] = epsilon_one; - sigma[i][j] = sigma_one; - epsilon_b[i][j] = epsilon_b_one; - phi_m[i][j] = phi_m_one; - theta_m[i][j] = theta_m_one; - cut[i][j] = cut_one; - cutsq[i][j] = cut_one*cut_one; - inner_cut[i][j] = rc_one; - setflag[i][j] = 1; - count++; - } - } - - if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); -} - -/* ---------------------------------------------------------------------- */ - -void PairPatchySphere::init_style() -{ - avec = static_cast(atom->style_match("ellipsoid")); - if (!avec) error->all(FLERR, "Pair patchy_sphere requires atom style ellipsoid"); - - neighbor->request(this,instance_me); - - // Set up the bond vectors here: - bond_pairs[0][0] = 0; - bond_pairs[0][1] = 1; - bond_pairs[0][2] = 1; - bond_pairs[0][3] = 0; - bond_pairs[0][4] = 2; - bond_pairs[0][5] = 2; - - bond_pairs[1][0] = 1; - bond_pairs[1][1] = 0; - bond_pairs[1][2] = 0; - bond_pairs[1][3] = 1; - bond_pairs[1][4] = 2; - bond_pairs[1][5] = 2; - - bond_pairs[2][0] = 2; - bond_pairs[2][1] = 2; - bond_pairs[2][2] = 0; - bond_pairs[2][3] = 1; - bond_pairs[2][4] = 1; - bond_pairs[2][5] = 0; - - if (nine_pairs) { - bond_pairs[3][0] = 0; - bond_pairs[3][1] = 2; - bond_pairs[3][2] = 2; - bond_pairs[3][3] = 0; - bond_pairs[3][4] = 1; - bond_pairs[3][5] = 1; - - bond_pairs[4][0] = 1; - bond_pairs[4][1] = 1; - bond_pairs[4][2] = 2; - bond_pairs[4][3] = 0; - bond_pairs[4][4] = 0; - bond_pairs[4][5] = 2; - - bond_pairs[5][0] = 2; - bond_pairs[5][1] = 0; - bond_pairs[5][2] = 0; - bond_pairs[5][3] = 2; - bond_pairs[5][4] = 1; - bond_pairs[5][5] = 1; - - bond_pairs[6][0] = 0; - bond_pairs[6][1] = 0; - bond_pairs[6][2] = 1; - bond_pairs[6][3] = 2; - bond_pairs[6][4] = 2; - bond_pairs[6][5] = 1; - - bond_pairs[7][0] = 1; - bond_pairs[7][1] = 2; - bond_pairs[7][2] = 0; - bond_pairs[7][3] = 0; - bond_pairs[7][4] = 2; - bond_pairs[7][5] = 1; - - bond_pairs[8][0] = 2; - bond_pairs[8][1] = 1; - bond_pairs[8][2] = 0; - bond_pairs[8][3] = 0; - bond_pairs[8][4] = 1; - bond_pairs[8][5] = 2; - } - - bond_vectors[2][0] = 1.0; - bond_vectors[2][1] = 0.0; - bond_vectors[2][2] = 0.0; - - bond_vectors[1][0] = -0.309017; - bond_vectors[1][1] = 0.951057; - bond_vectors[1][2] = 0.0; - - bond_vectors[0][0] = -0.309017; - bond_vectors[0][1] = -0.425325; - bond_vectors[0][2] = 0.850651; - - for (int i = 0; i < n_bonds; ++i) { - double bx = bond_vectors[i][0]; - double by = bond_vectors[i][1]; - double bz = bond_vectors[i][2]; - - double nb2 = bx*bx + by*by + bz*bz; - if ( fabs(nb2 - 1.0) > 1e-4 ){ - char msg[2048]; - snprintf(msg, 2048, "Bond vector %d is not of unit length! norm^2 - 1.0 = %g", - i+1, nb2 - 1.0); - error->all(FLERR,msg); - } - } - -} - -/* ---------------------------------------------------------------------- */ - -double PairPatchySphere::init_one(int i, int j) -{ - if (setflag[i][j] == 0) - error->all(FLERR, "Not all patchy sphere coefficients set!"); - - epsilon[j][i] = epsilon[i][j]; - sigma[j][i] = sigma[i][j]; - epsilon_b[j][i] = epsilon_b[i][j]; - phi_m[j][i] = phi_m[i][j]; - theta_m[j][i] = theta_m[i][j]; - cut[j][i] = cut[i][j]; - setflag[j][i] = setflag[i][j]; - inner_cut[j][i] = inner_cut[i][j]; - - - return cut[i][j]; -} - -/* ---------------------------------------------------------------------- */ - -void PairPatchySphere::compute(int eflag, int vflag) -{ - int i, j, ii, jj, inum, jnum, itype, jtype; - double evdwl, one_eng, rsq, r2inv, r6inv, forcelj, factor_lj; - double fforce[3], ttor[3], rtor[3], r12[3]; - double a1[3][3], a2[3][3]; - int *ilist, *jlist, *numneigh, **firstneigh; - double *iquat, *jquat; - - evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; - - AtomVecEllipsoid::Bonus *bonus = avec->bonus; - int *ellipsoid = atom->ellipsoid; - double **x = atom->x; - double **f = atom->f; - double **tor = atom->torque; - int *type = atom->type; - int nlocal = atom->nlocal; - double *special_lj = force->special_lj; - int newton_pair = force->newton_pair; - - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - - // loop over neighbors of my atoms - - // For now always assume you are dealing with patchy <--> patchy - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - itype = type[i]; - - iquat = bonus[ellipsoid[i]].quat; - MathExtra::quat_to_mat_trans(iquat,a1); // a1 is rotation matrix - jlist = firstneigh[i]; - jnum = numneigh[i]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - factor_lj = special_lj[sbmask(j)]; - j &= NEIGHMASK; - - // r12 = center to center vector - - r12[0] = x[j][0]-x[i][0]; - r12[1] = x[j][1]-x[i][1]; - r12[2] = x[j][2]-x[i][2]; - rsq = MathExtra::dot3(r12,r12); - jtype = type[j]; - - // compute if less than cutoff - - if (rsq < cutsq[itype][jtype]) { - - jquat = bonus[ellipsoid[j]].quat; - MathExtra::quat_to_mat_trans(jquat,a2); - one_eng = bond_vec_analytic(i,j,a1,a2,r12,rsq, - fforce,ttor,rtor); - - - fforce[0] *= factor_lj; - fforce[1] *= factor_lj; - fforce[2] *= factor_lj; - ttor[0] *= factor_lj; - ttor[1] *= factor_lj; - ttor[2] *= factor_lj; - - f[i][0] += fforce[0]; - f[i][1] += fforce[1]; - f[i][2] += fforce[2]; - tor[i][0] += ttor[0]; - tor[i][1] += ttor[1]; - tor[i][2] += ttor[2]; - - if (newton_pair || j < nlocal) { - rtor[0] *= factor_lj; - rtor[1] *= factor_lj; - rtor[2] *= factor_lj; - f[j][0] -= fforce[0]; - f[j][1] -= fforce[1]; - f[j][2] -= fforce[2]; - tor[j][0] += rtor[0]; - tor[j][1] += rtor[1]; - tor[j][2] += rtor[2]; - } - - if (eflag) evdwl = factor_lj*one_eng; - - if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair, - evdwl,0.0,fforce[0],fforce[1],fforce[2], - -r12[0],-r12[1],-r12[2]); - } - } - } - - if (vflag_fdotr) virial_fdotr_compute(); -} - -/* ------------------------------------------------------------ */ - -double PairPatchySphere::bond_vec_analytic (const int i, const int j, - double a1[3][3], double a2[3][3], - double *r12, const double rsq, - double *fforce, double *ttor, - double *rtor) -{ - // At this point, rsq and r12 contain the distance vector and distance - // squared, a1 and a2 contain the rotation matrices. - // We need to calculate fforce, ttor and rtor. - - // For each bond vector pair: - int *type = atom->type; - int itype = type[i]; - int jtype = type[j]; - double s = sigma[itype][jtype]; - double sigma2 = s*s; - double inner_rc = inner_cut[itype][jtype]; - double inner_rc2 = inner_rc*inner_rc; - double energy = 0.0; - - ttor[0] = ttor[1] = ttor[2] = 0.0; - rtor[0] = rtor[1] = rtor[2] = 0.0; - fforce[0] = fforce[1] = fforce[2] = 0.0; - - // Distance criterion for repulsive LJ part: - if (rsq < inner_rc2) { - double rinv2 = 1.0 / rsq; - double s6 = sigma2*sigma2*sigma2; - double r6 = rinv2*rinv2*rinv2; - s6 *= r6; - - double force_lj = 48.0*epsilon[itype][jtype]*s6*(s6-0.5); - force_lj *= -rinv2; - - // Add force to the force vector: - fforce[0] += r12[0] * force_lj; - fforce[1] += r12[1] * force_lj; - fforce[2] += r12[2] * force_lj; - - energy += 4.0*epsilon[itype][jtype]*( s6*(s6-1.0) + 0.25 ); - } - - // Calculate the rotated vectors here: - double b_rot[3*6]; - - MathExtra::matvec(a1, bond_vectors[0], b_rot); - MathExtra::matvec(a1, bond_vectors[1], b_rot+3); - MathExtra::matvec(a1, bond_vectors[2], b_rot+6); - - MathExtra::matvec(a2, bond_vectors[0], b_rot+9); - MathExtra::matvec(a2, bond_vectors[1], b_rot+12); - MathExtra::matvec(a2, bond_vectors[2], b_rot+15); - - // Contributions of the bond vectors: - for (int pair_i = 0; pair_i < n_bond_pairs; ++pair_i){ - bool bail = false; - // Calculate for each pair the attractive patch part: - int alpha_i = bond_pairs[pair_i][0]; - int beta_i = bond_pairs[pair_i][1]; - int gamma_i = bond_pairs[pair_i][2]; - int epsilon_i = bond_pairs[pair_i][3]; - int eta_i = bond_pairs[pair_i][4]; - int nu_i = bond_pairs[pair_i][5]; - - /* - if (debug_output && comm->me == 0 && i == 1) { - fprintf( screen, "At i=1: pairs: %d %d %d %d %d %d\n", alpha_i, beta_i, - gamma_i, epsilon_i, eta_i, nu_i ); - } - */ - - // Alpha, gamma and eta belong to particle i, - // beta, epsilon and nu belong to particle j. - double *b_alp = b_rot + 3*alpha_i; - double *b_bet = b_rot + 3*beta_i + 9; - double *b_gam = b_rot + 3*gamma_i; - double *b_eps = b_rot + 3*epsilon_i + 9; - double *b_eta = b_rot + 3*eta_i; - double *b_nu = b_rot + 3*nu_i + 9; - - // Distance between bond vectors, attractive force: - double patch_dist[3]; - const double patch_b = 0.56123102415468651; - - patch_dist[0] = r12[0] + patch_b*(b_alp[0] - b_bet[0]); - patch_dist[1] = r12[1] + patch_b*(b_alp[1] - b_bet[1]); - patch_dist[2] = r12[2] + patch_b*(b_alp[2] - b_bet[2]); - double patch_r2 = patch_dist[0]*patch_dist[0] + patch_dist[1]*patch_dist[1] - + patch_dist[2]*patch_dist[2]; - double criterion = cut[itype][jtype] - s*1.122462048309373; - if (debug_output) { - fprintf(screen,"Distance criterion is %g\n", criterion); - } - double crit2 = criterion*criterion; - - if (patch_r2 >= crit2) { - // The attraction is out of range. Ignore this contribution. - bail = true; - } - - double patch_r = sqrt(patch_r2); - if (debug_output) { - fprintf(screen, "r_ij is %g (vector: %g %g %g)\n", - sqrt(rsq), r12[0], r12[1], r12[2]); - fprintf(screen, "b_alpha = (%g %g %g)\n", - b_alp[0], b_alp[1], b_alp[2]); - fprintf(screen, "b_beta = (%g %g %g)\n", - b_bet[0], b_bet[1], b_bet[2]); - fprintf(screen, "Patch distance is %g (vector: %g %g %g)\n", - patch_r, patch_dist[0], patch_dist[1], patch_dist[2]); - } - - - bool calc_theta = true; - - // The total force, torque and reverse torque from this bond vector pair - // will be tallied in these: - double acc_force[3] = { 0.0, 0.0, 0.0 }; - double acc_ttor[3] = { 0.0, 0.0, 0.0 }; - double acc_rtor[3] = { 0.0, 0.0, 0.0 }; - - double u_theta = 2.0; - double theta_force[3] = {0.0,0.0,0.0}; - double theta_ttor[3] = {0.0,0.0,0.0}; - double theta_rtor[3] = {0.0,0.0,0.0}; - - if (calc_theta && !bail) { - // Switching function: Theta - u_theta = bond_vec_theta_part(i, j, itype, jtype, r12, b_alp, b_bet, - theta_force, theta_ttor, theta_rtor); - if (debug_output) { - fprintf(screen, "u_theta = %g\n", u_theta); - } - if (u_theta == 0) { - // No contribution from this bond vector set. - bail = true; - theta_force[0] = theta_force[1] = theta_force[2] = 0.0; - theta_ttor[0] = theta_ttor[1] = theta_ttor[2] = 0.0; - theta_rtor[0] = theta_rtor[1] = theta_rtor[2] = 0.0; - } - } - - if (debug_output) - fprintf(screen, "u_theta = %g\n", u_theta); - - // Tally force and torque: - bool calc_phi1 = true; - bool calc_phi2 = true; - - // phi_1: - double u_phi1 = 2.0; - double phi1_force[3] = {0.0,0.0,0.0}; - double phi1_ttor[3] = {0.0,0.0,0.0}; - double phi1_rtor[3] = {0.0,0.0,0.0}; - - if (!bail && calc_phi1) { - u_phi1 = bond_vec_phi_part(i, j, itype, jtype, r12, rsq, b_alp, b_bet, - b_gam, b_eps, phi1_force, phi1_ttor, phi1_rtor); - if (u_phi1 == 0) { - // No contribution from this bond vector pair. - bail = true; - } - }else{ - phi1_force[0] = phi1_force[1] = phi1_force[2] = 0.0; - phi1_ttor[0] = phi1_ttor[1] = phi1_ttor[2] = 0.0; - phi1_rtor[0] = phi1_rtor[1] = phi1_rtor[2] = 0.0; - // If do not calc, ignore its contributino to forces and torques - // but put u_phi1 to 2.0 so that the phi factor does not change anything. - u_phi1 = 2.0; - } - - double phi2_force[3] = {0.0,0.0,0.0}; - double phi2_ttor[3] = {0.0,0.0,0.0}; - double phi2_rtor[3] = {0.0,0.0,0.0}; - - double u_phi2 = 2.0; - - if (!bail && calc_phi2) { - u_phi2 = bond_vec_phi_part(i, j, itype, jtype, r12, rsq, b_alp, b_bet, - b_eta, b_nu, phi2_force, phi2_ttor, phi2_rtor); - if (u_phi2 == 0) { - // No contribution from this bond vector pair. - bail = true; - } - }else{ - phi2_force[0] = phi2_force[1] = phi2_force[2] = 0.0; - phi2_ttor[0] = phi2_ttor[1] = phi2_ttor[2] = 0.0; - phi2_rtor[0] = phi2_rtor[1] = phi2_rtor[2] = 0.0; - // If do not calc, ignore its contributino to forces and torques - // but put u_phi1 to 2.0 so that the phi factor does not change anything. - u_phi2 = 2.0; - } - - // attractive LJ force. Has weird shape of 2^{1/6} + patch_dist. - double rr = patch_r + inner_cut[itype][jtype]; - double sr2 = sigma2 / (rr*rr); - double sr6 = sr2*sr2*sr2; - - // 0.5 instead of 4 because we omit the factors 0.5 for switching functions. - double bond_eps = 0.5*epsilon_b[itype][jtype]; - // Add the offset. - double src2 = sigma2 / cutsq[itype][jtype]; - double src6 = src2*src2*src2; - double u_LJ = bond_eps * ( sr6 * ( sr6 - 1.0 ) - src6 * ( src6 - 1.0 ) ); - - if (debug_output) { - fprintf(screen, "patch distance was %g, u_LJ = %g\n", - patch_r, u_LJ); - } - - // LJ force: - double lj_force[3] = {0.0, 0.0, 0.0}; - - if (!bail) { - // bond_eps is already a factor 8 smaller so this is regular LJ: - double pair_f = 48.0*bond_eps*sr6*(sr6 - 0.5)/patch_r2; - lj_force[0] = pair_f*patch_dist[0]; - lj_force[1] = pair_f*patch_dist[1]; - lj_force[2] = pair_f*patch_dist[2]; - - const double c1 = u_LJ*u_phi1*u_phi2; - const double c2 = u_theta*u_phi1*u_phi2; - const double c3 = u_LJ*u_theta*u_phi2; - const double c4 = u_LJ*u_theta*u_phi1; - - // Theta part produces no force. - acc_force[0] = lj_force[0]*c2 + phi1_force[0]*c3 + phi2_force[0]*c4; - acc_force[1] = lj_force[1]*c2 + phi1_force[1]*c3 + phi2_force[1]*c4; - acc_force[2] = lj_force[2]*c2 + phi1_force[2]*c3 + phi2_force[2]*c4; - - // There is another torque coming from the lj force. - double force_ttor[3], force_rtor[3]; - MathExtra::cross3(b_alp, lj_force, force_ttor); - MathExtra::cross3(b_bet, lj_force, force_rtor); - - acc_ttor[0] = force_ttor[0]*c2 + theta_ttor[0]*c1 + phi1_ttor[0]*c3 + phi2_ttor[0]*c4; - acc_ttor[1] = force_ttor[1]*c2 + theta_ttor[1]*c1 + phi1_ttor[1]*c3 + phi2_ttor[1]*c4; - acc_ttor[2] = force_ttor[2]*c2 + theta_ttor[2]*c1 + phi1_ttor[2]*c3 + phi2_ttor[2]*c4; - - acc_rtor[0] = force_rtor[0]*c2 + theta_rtor[0]*c1 + phi1_rtor[0]*c3 + phi2_rtor[0]*c4; - acc_rtor[1] = force_rtor[1]*c2 + theta_rtor[1]*c1 + phi1_rtor[1]*c3 + phi2_rtor[1]*c4; - acc_rtor[2] = force_rtor[2]*c2 + theta_rtor[2]*c1 + phi1_rtor[2]*c3 + phi2_rtor[2]*c4; - - double dE = u_LJ*u_phi1*u_phi2*u_theta; - if (debug_output) - fprintf(screen, " Energy contribution of this pair is %g\n", dE); - energy += dE; - - fforce[0] += acc_force[0]; - fforce[1] += acc_force[1]; - fforce[2] += acc_force[2]; - - ttor[0] += acc_ttor[0]; - ttor[1] += acc_ttor[1]; - ttor[2] += acc_ttor[2]; - - rtor[0] += acc_rtor[0]; - rtor[1] += acc_rtor[1]; - rtor[2] += acc_rtor[2]; - } - - if (debug_output && comm->me == 0 && !bail) { - fprintf(screen, "Energy contributions: %g %g %g %g\n", - u_LJ,u_theta, u_phi1, u_phi2); - fprintf(screen, "Forces: (%g %g %g) (%g %g %g)\n", - acc_force[0], acc_force[1], acc_force[2], - fforce[0], fforce[1], fforce[2]); - fprintf(screen, "Torque (t): (%g %g %g) (%g %g %g)\n", - acc_ttor[0], acc_ttor[1], acc_ttor[2], - ttor[0], ttor[1], ttor[2]); - fprintf(screen, "Torque (r): (%g %g %g) (%g %g %g)\n\n", - acc_rtor[0], acc_rtor[1], acc_rtor[2], - rtor[0], rtor[1], rtor[2]); - fprintf(screen, "pair %d, bond vectors: b1.b2 = %g, b1.b3 = %g, b2.b3 = %g\n\n\n", - pair_i, MathExtra::dot3(b_alp, b_bet), MathExtra::dot3(b_alp,b_gam), - MathExtra::dot3(b_bet, b_gam)); - } - } - - return energy; -} - - - -double PairPatchySphere::bond_vec_theta_part(const int i, const int j, - const int itype, const int jtype, - const double *r12, const double *b_alp, - const double *b_bet, double *fforce, - double *ttor, double *rtor) -{ - // Calculate the force and torque acquired due to the gradient in theta_12 - double cos_theta = -MathExtra::dot3(b_alp, b_bet); - const double theta_param = MathConst::MY_PI / theta_m[itype][jtype]; - - const double cos_theta_tol = cos(theta_m[itype][jtype]); - if (cos_theta <= cos_theta_tol) { - // There is no theta-contribution to the potential energy. - // This means the switching function is 0 and hence the entire potential - // is 0 too. - fforce[0] = fforce[1] = fforce[2] = 0.0; - ttor[0] = ttor[1] = ttor[2] = 0.0; - rtor[0] = rtor[1] = rtor[2] = 0.0; - return 0; - } - - double theta = (cos_theta >= 1.0 ? 0.0 :acos(cos_theta)); - - // Determine the forces and torques coming from theta: - - const double patch_b = 0.56123102415468651; - if (theta == 0.0) { - ttor[0] = ttor[1] = ttor[2] = 0.0; - rtor[0] = rtor[1] = rtor[2] = 0.0; - fforce[0] = fforce[1] = fforce[2] = 0.0; - return 2.0; // At theta == 0 the switching function has its maximum, 2. - }else{ - double c[3]; - MathExtra::cross3(b_alp, b_bet, c); - double factor = patch_b*patch_b*theta_param * sin(theta_param*theta)/(2.0*sin(theta)); - ttor[0] = factor*c[0]; - ttor[1] = factor*c[1]; - ttor[2] = factor*c[2]; - - rtor[0] = -ttor[0]; - rtor[1] = -ttor[1]; - rtor[2] = -ttor[2]; - - fforce[0] = fforce[1] = fforce[2] = 0.0; - return cos(theta * theta_param) + 1.0; - } -} - - -/** - Calculates the phi part to the force and torque. - It returns the value of the switching function (in range of [0,2]). - The force and torque needs to be multiplied by the other switching - functions and potentials u_LJ, u_phi (the other one) and u_theta. - - If this return 0, you know there is no torque or force for this bond pair. - If it return 2, the potential is maximal and there is no torque or force from - this phi but there might be from others. -*/ -double PairPatchySphere::bond_vec_phi_part( const int i, const int j, - const int itype, const int jtype, - const double *r12, const double rsq, - const double *b_alp, const double *b_bet, - const double *b_gam, const double *b_eps, - double *fforce, double *ttor, double *rtor) -{ - - // Calculate the force and torque acquired due to the gradient in phi - - const double patch_b = 0.56123102415468651; - const double patch_b2 = patch_b*patch_b; - - const double gamma_dot_rij = patch_b*MathExtra::dot3(b_gam, r12); - const double eps_dot_rij = patch_b*MathExtra::dot3(b_eps, r12); - const double gamma_dot_eps = patch_b2*MathExtra::dot3(b_gam, b_eps); - - const double r_eps_rij = rsq - eps_dot_rij*eps_dot_rij; - const double r_gam_rij = rsq - gamma_dot_rij*gamma_dot_rij; - - constexpr const double tol = 1e-4; - if (r_eps_rij < tol || r_gam_rij < tol) { - // This means phi is close to 0. In that case, the switching function - // Is close to 2.0 and there is no torque or force coming from this. - fforce[0] = fforce[1] = fforce[2] = 0.0; - ttor[0] = ttor[1] = ttor[2] = 0.0; - rtor[0] = rtor[1] = rtor[2] = 0.0; - return 2.0; - } - - double inv_sq = 1.0 / sqrt(r_gam_rij * r_eps_rij); - double cos_phi = gamma_dot_eps * rsq - gamma_dot_rij * eps_dot_rij; - cos_phi *= inv_sq; - - double phi = 0.0; - if (cos_phi >= 1.0) { - phi = 0.0; - }else if (cos_phi < -1.0) { - phi = MathConst::MY_PI; - }else{ - phi = acos(cos_phi); - } - - const double phi_tol = phi_m[itype][jtype]; - if (phi >= phi_tol) { - fforce[0] = fforce[1] = fforce[2] = 0.0; - ttor[0] = ttor[1] = ttor[2] = 0.0; - rtor[0] = rtor[1] = rtor[2]; - // In this case the switching function is 0. - return 0.0; - } - - double psi = gamma_dot_rij * eps_dot_rij - gamma_dot_eps * rsq; - double grad_cos_phi[3]; - double grad_cos_phi_gam[3]; - double fbj[3]; - - /* - grad_cos_phi = b_eps * gamma_dot_rij + b_gam * eps_dot_rij - - 2.0*r12*gamma_dot_eps - (r12 - b_eps * eps_dot_rij)*(psi/r_eps_rij) - - (r12 - b_gam * gamma_dot_rij)*(psi/r_gam_rij); - */ - const double p_eps_rij = psi/r_eps_rij; - const double p_gam_rij = psi/r_gam_rij; - - const double eps_p_eps = eps_dot_rij * p_eps_rij; - const double gam_p_gam = gamma_dot_rij * p_gam_rij; - - double c1 = gamma_dot_rij + eps_p_eps; - double c2 = eps_dot_rij + gam_p_gam; - double c3 = 2.0 * gamma_dot_eps + p_eps_rij + p_gam_rij; - - c1 *= inv_sq; - c2 *= inv_sq; - c3 *= inv_sq; - - grad_cos_phi[0] = c1*b_eps[0] + c2*b_gam[0] - c3*r12[0]; - grad_cos_phi[1] = c1*b_eps[1] + c2*b_gam[1] - c3*r12[1]; - grad_cos_phi[2] = c1*b_eps[2] + c2*b_gam[2] - c3*r12[2]; - - c1 = eps_dot_rij + gamma_dot_rij * p_gam_rij; - c2 = rsq * p_gam_rij; - c1 *= inv_sq; - c2 *= inv_sq; - - grad_cos_phi_gam[0] = r12[0] * c1 - b_eps[0] * rsq - b_gam[0] * c2; - grad_cos_phi_gam[1] = r12[1] * c1 - b_eps[1] * rsq - b_gam[1] * c2; - grad_cos_phi_gam[2] = r12[2] * c1 - b_eps[2] * rsq - b_gam[2] * c2; - - c1 = gamma_dot_rij + eps_dot_rij * p_eps_rij; - c2 = rsq * p_eps_rij; - c1 *= inv_sq; - c2 *= inv_sq; - - fbj[0] = r12[0] * c1 - b_gam[0] * rsq - b_eps[0] * c2; - fbj[1] = r12[1] * c1 - b_gam[1] * rsq - b_eps[1] * c2; - fbj[2] = r12[2] * c1 - b_gam[2] * rsq - b_eps[2] * c2; - - const double phi_param = MathConst::MY_PI / phi_m[itype][jtype]; - double sinc = phi > 0.001 ? sin(phi*phi_param)/sin(phi) : phi_param; - - // The torque is - double chain = 0.5*phi_param * sinc; - - fforce[0] = grad_cos_phi[0] * chain; - fforce[1] = grad_cos_phi[1] * chain; - fforce[2] = grad_cos_phi[2] * chain; - - double c[3]; - MathExtra::cross3(b_gam, grad_cos_phi_gam, c); - - ttor[0] = c[0] * chain; - ttor[1] = c[1] * chain; - ttor[2] = c[2] * chain; - - double k[3]; - MathExtra::cross3(b_eps, fbj, k); - rtor[0] = k[0] * chain; - rtor[1] = k[1] * chain; - rtor[2] = k[2] * chain; - - fforce[0] = grad_cos_phi[0] * chain; - fforce[1] = grad_cos_phi[1] * chain; - fforce[2] = grad_cos_phi[2] * chain; - - return cos(phi*phi_param) + 1.0; -} diff --git a/src/ASPHERE/pair_patchy_sphere.h b/src/ASPHERE/pair_patchy_sphere.h deleted file mode 100644 index 9409026d1d..0000000000 --- a/src/ASPHERE/pair_patchy_sphere.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - 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. -------------------------------------------------------------------------- */ - -#ifdef PAIR_CLASS - -PairStyle(patchysphere,PairPatchySphere) - -#else - -#ifndef LMP_PAIR_PATCHY_SPHERE_H -#define LMP_PAIR_PATCHY_SPHERE_H - -#include "pair.h" - -namespace LAMMPS_NS { - -class PairPatchySphere : public Pair { - public: - PairPatchySphere(LAMMPS *); - virtual ~PairPatchySphere(); - virtual void compute(int, int); - virtual void settings(int, char **); - void coeff(int, char **); - virtual void init_style(); - double init_one(int, int); - //void write_restart(FILE *); - //void read_restart(FILE *); - //void write_restart_settings(FILE *); - //void read_restart_settings(FILE *); - //void write_data(FILE *); - //void write_data_all(FILE *); - - protected: - // enumerate the "encounter" possibilities. - enum{SPHERE_SPHERE,SPHERE_PATCHY,PATCHY_SPHERE,PATCHY_PATCHY}; - - double cut_global; - double **cut; - double **inner_cut; - double **offset; - double **epsilon, **sigma; - - - // Whole bunch of stuff related to bond vectors... - double **epsilon_b; // Patch binding strength. - int n_bond_pairs; // Number of bond pairs (combinations of alpha, beta, ...) - int **bond_pairs; // Enumerate bond pairs. - - double **phi_m, **theta_m; // Theta and phi scale factors. - - int n_bonds; // Number of bond vectors. - double **bond_vectors; // Bond vectors. - - class AtomVecEllipsoid *avec; - - bool debug_output; - - - void allocate(); - double bond_vec_analytic(const int i, const int j, double a1[3][3], - double a2[3][3], double *r12, const double rsq, - double *fforce, double *ttor, double *rtor); - - - double bond_vec_theta_part(const int i, const int j, - const int itype, const int jtype, - const double *r12, const double *b_alp, - const double *b_bet, double *fforce, double *ttor, - double *rtor); - double bond_vec_phi_part(const int i, const int j, - const int itype, const int jtype, - const double *r12, const double rsq, - const double *b_alp, const double *b_bet, - const double *b_gam, const double *b_eps, - double *fforce, double *ttor, double *rtor); - -}; - - -} // namespace - -#endif // LMP_PAIR_PATCHY_SPHERE_H -#endif // PAIR_CLASS diff --git a/src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi b/src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi deleted file mode 100644 index 57fc37c10e..0000000000 --- a/src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi +++ /dev/null @@ -1,125 +0,0 @@ -# kokkos_cuda_mpi = KOKKOS/CUDA package, MPICH or OpenMPI with nvcc compiler, Kepler GPU - -SHELL = /bin/sh - -# --------------------------------------------------------------------- -# compiler/linker settings -# specify flags and libraries needed for your compiler - -KOKKOS_ABSOLUTE_PATH = /home/stefan/projects/lammps-mine/lib/kokkos -export MPICH_CXX = $(KOKKOS_ABSOLUTE_PATH)/bin/nvcc_wrapper -export OMPI_CXX = $(KOKKOS_ABSOLUTE_PATH)/bin/nvcc_wrapper -CC = mpicxx -CCFLAGS = -g -O3 -SHFLAGS = -fPIC -DEPFLAGS = -M - -LINK = mpicxx -LINKFLAGS = -g -O3 -LIB = -SIZE = size - -ARCHIVE = ar -ARFLAGS = -rc -SHLIBFLAGS = -shared -KOKKOS_DEVICES = Cuda -KOKKOS_ARCH = Kepler35 - -# --------------------------------------------------------------------- -# LAMMPS-specific settings, all OPTIONAL -# specify settings for LAMMPS features you will use -# if you change any -D setting, do full re-compile after "make clean" - -# LAMMPS ifdef settings -# see possible settings in Section 2.2 (step 4) of manual - -LMP_INC = -DLAMMPS_GZIP -DLAMMPS_PNG -DLAMMPS_JPEG -DLAMMPS_FFMPEG - -# MPI library -# see discussion in Section 2.2 (step 5) of manual -# MPI wrapper compiler/linker can provide this info -# can point to dummy MPI library in src/STUBS as in Makefile.serial -# use -D MPICH and OMPI settings in INC to avoid C++ lib conflicts -# INC = path for mpi.h, MPI compiler settings -# PATH = path for MPI library -# LIB = name of MPI library - -MPI_INC = -DMPICH_SKIP_MPICXX -DOMPI_SKIP_MPICXX=1 -MPI_PATH = -MPI_LIB = - -# FFT library -# see discussion in Section 2.2 (step 6) of manaul -# can be left blank to use provided KISS FFT library -# INC = -DFFT setting, e.g. -DFFT_FFTW, FFT compiler settings -# PATH = path for FFT library -# LIB = name of FFT library - -FFT_INC = -I/usr/include/ -FFT_PATH = -L/usr/lib/ -FFT_LIB = -lfftw3 - -# JPEG and/or PNG library -# see discussion in Section 2.2 (step 7) of manual -# only needed if -DLAMMPS_JPEG or -DLAMMPS_PNG listed with LMP_INC -# INC = path(s) for jpeglib.h and/or png.h -# PATH = path(s) for JPEG library and/or PNG library -# LIB = name(s) of JPEG library and/or PNG library - -JPG_INC = -JPG_PATH = -JPG_LIB = -ljpeg -lpng - -# --------------------------------------------------------------------- -# build rules and dependencies -# do not edit this section - -include Makefile.package.settings -include Makefile.package - -EXTRA_INC = $(LMP_INC) $(PKG_INC) $(MPI_INC) $(FFT_INC) $(JPG_INC) $(PKG_SYSINC) -EXTRA_PATH = $(PKG_PATH) $(MPI_PATH) $(FFT_PATH) $(JPG_PATH) $(PKG_SYSPATH) -EXTRA_LIB = $(PKG_LIB) $(MPI_LIB) $(FFT_LIB) $(JPG_LIB) $(PKG_SYSLIB) -EXTRA_CPP_DEPENDS = $(PKG_CPP_DEPENDS) -EXTRA_LINK_DEPENDS = $(PKG_LINK_DEPENDS) - -# Path to src files - -vpath %.cpp .. -vpath %.h .. - -# Link target - -$(EXE): $(OBJ) $(EXTRA_LINK_DEPENDS) - $(LINK) $(LINKFLAGS) $(EXTRA_PATH) $(OBJ) $(EXTRA_LIB) $(LIB) -o $(EXE) - $(SIZE) $(EXE) - -# Library targets - -lib: $(OBJ) $(EXTRA_LINK_DEPENDS) - $(ARCHIVE) $(ARFLAGS) $(EXE) $(OBJ) - -shlib: $(OBJ) $(EXTRA_LINK_DEPENDS) - $(CC) $(CCFLAGS) $(SHFLAGS) $(SHLIBFLAGS) $(EXTRA_PATH) -o $(EXE) \ - $(OBJ) $(EXTRA_LIB) $(LIB) - -# Compilation rules - -%.o:%.cpp $(EXTRA_CPP_DEPENDS) - $(CC) $(CCFLAGS) $(SHFLAGS) $(EXTRA_INC) -c $< - -%.d:%.cpp $(EXTRA_CPP_DEPENDS) - $(CC) $(CCFLAGS) $(EXTRA_INC) $(DEPFLAGS) $< > $@ - -%.o:%.cu $(EXTRA_CPP_DEPENDS) - $(CC) $(CCFLAGS) $(SHFLAGS) $(EXTRA_INC) -c $< - -# Individual dependencies - -depend : fastdep.exe $(SRC) - @./fastdep.exe $(EXTRA_INC) -- $^ > .depend || exit 1 - -fastdep.exe: ../DEPEND/fastdep.c - cc -O -o $@ $< - -sinclude .depend diff --git a/src/USER-MISC/fix_active.cpp b/src/USER-MISC/fix_active.cpp deleted file mode 100644 index 1bb0726748..0000000000 --- a/src/USER-MISC/fix_active.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* ---------------------------------------------------------------------- - 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. - ------------------------------------------------------------------------- */ - -/* ----------------------------------------------------------------------- - Contributed by Stefan Paquay @ Brandeis University - - Thanks to Liesbeth Janssen @ Eindhoven University for useful discussions! - ----------------------------------------------------------------------- */ - - -#include -#include - -#include "fix_active.h" - -#include "atom.h" -#include "atom_vec_ellipsoid.h" -#include "citeme.h" -#include "comm.h" -#include "error.h" -#include "force.h" -#include "group.h" -#include "math.h" -#include "math_const.h" -#include "math_extra.h" -#include "math_vector.h" -#include "modify.h" -#include "random_mars.h" -#include "respa.h" -#include "update.h" - - -using namespace LAMMPS_NS; -using namespace FixConst; -using namespace MathConst; - -/* - Might be used later, who knows... -static const char* cite_fix_active = - "fix active command:\n\n" - "@article{paquay-2018,\n" - " author = {Paquay, Stefan},\n" - " doi = {},\n" - " issn = {},\n" - " journal = {},\n" - " month = ,\n" - " number = ,\n" - " pages = ,\n" - " title = ,\n" - " volume = ,\n" - " year = \n" - "}\n\n"; -*/ - -static constexpr const bool debug_out = false; - -FixActive::FixActive( LAMMPS *lmp, int narg, char **argv ) - : Fix(lmp, narg, argv) -{ - // if( lmp->citeme) lmp->citeme->add(cite_fix_active); - if( narg < 4 ) error->all(FLERR, "Illegal fix active command"); - - AtomVecEllipsoid *av = static_cast(atom->avec); - if (!av) error->all(FLERR, "FixActive requires atom_style ellipsoid"); - - if( debug_out && comm->me == 0 ){ - fprintf(screen, "This is fix active, narg is %d\n", narg ); - fprintf(screen, "args:"); - for( int i = 0; i < narg; ++i ){ - fprintf(screen, " %s", argv[i]); - } - fprintf(screen, "\n"); - } - - // args: fix ID all active magnitude prop1 prop2 prop3 - // Optional args are - magnitude = force->numeric( FLERR, argv[3] ); -} - - -FixActive::~FixActive() -{} - - -int FixActive::setmask() -{ - int mask = 0; - mask |= POST_FORCE; - - return mask; -} - - -double FixActive::memory_usage() -{ - double bytes = 0.0; - return bytes; -} - - - -void FixActive::post_force(int /* vflag */ ) -{ - // Then do the rest: - double **f = atom->f; - - AtomVecEllipsoid *av = static_cast(atom->avec); - - int *mask = atom->mask; - int nlocal = atom->nlocal; - if (igroup == atom->firstgroup) nlocal = atom->nfirst; - - AtomVecEllipsoid::Bonus *bonus = av->bonus; - // Add the active force to the atom force: - for( int i = 0; i < nlocal; ++i ){ - if( mask[i] & groupbit ){ - double f_act[3] = { 0.0, 0.0, 1.0 }; - double f_rot[3]; - - int* ellipsoid = atom->ellipsoid; - double *quat = bonus[ellipsoid[i]].quat; - tagint *tag = atom->tag; - - double Q[3][3]; - MathExtra::quat_to_mat( quat, Q ); - MathExtra::matvec( Q, f_act, f_rot ); - - if (debug_out && comm->me == 0) { - // Magical reference particle: - if (tag[i] == 12) { - fprintf(screen, "rotation quaternion: (%f %f %f %f)\n", - quat[0], quat[1], quat[2], quat[3]); - fprintf(screen, "rotation matrix: / %f %f %f \\\n", - Q[0][0] ,Q[0][1], Q[0][2]); - fprintf(screen, " | %f %f %f |\n", - Q[1][0] ,Q[1][1], Q[1][2]); - fprintf(screen, " \\ %f %f %f /\n", - Q[2][0] ,Q[2][1], Q[2][2]); - - fprintf(screen, "Active force on atom %d: (%f %f %f)\n", - tag[i], f_rot[0], f_rot[1], f_rot[2]); - fprintf(screen, " Total force before: (%f %f %f)\n", - f[i][0], f[i][1], f[i][2]); - } - } - - f[i][0] += magnitude * f_rot[0]; - f[i][1] += magnitude * f_rot[1]; - f[i][2] += magnitude * f_rot[2]; - - } - } -} diff --git a/src/USER-MISC/fix_active.h b/src/USER-MISC/fix_active.h deleted file mode 100644 index 02a91db14a..0000000000 --- a/src/USER-MISC/fix_active.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - 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. -------------------------------------------------------------------------- */ - -#ifdef FIX_CLASS - -FixStyle(active,FixActive) - -#else - -#ifndef LMP_FIX_ACTIVE_H -#define LMP_FIX_ACTIVE_H - -#include "fix.h" - -namespace LAMMPS_NS { - -class FixActive : public Fix { - public: - FixActive(class LAMMPS *, int, char **); - virtual ~FixActive(); - virtual int setmask(); - virtual void post_force(int); - // virtual void post_force_respa(int, int, int); - - double memory_usage(); - -protected: - double magnitude; - int thermostat_orient; -}; - -} - -#endif -#endif - -/* ERROR/WARNING messages: - -E: Illegal ... command - -Self-explanatory. Check the input script syntax and compare to the -documentation for the command. You can use -echo screen as a -command-line option when running LAMMPS to see the offending line. - -*/ From 04571ca6c247d4557ee82ede35331ab3d468a07b Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 29 Aug 2019 09:51:54 -0400 Subject: [PATCH 16/54] Undid incorrect deletion of files. --- .../cgdna/examples/oxDNA2/duplex2/in.duplex2 | 78 +++++++++++ src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi | 125 ++++++++++++++++++ 2 files changed, 203 insertions(+) create mode 100644 examples/USER/cgdna/examples/oxDNA2/duplex2/in.duplex2 create mode 100644 src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi diff --git a/examples/USER/cgdna/examples/oxDNA2/duplex2/in.duplex2 b/examples/USER/cgdna/examples/oxDNA2/duplex2/in.duplex2 new file mode 100644 index 0000000000..3850dfcedf --- /dev/null +++ b/examples/USER/cgdna/examples/oxDNA2/duplex2/in.duplex2 @@ -0,0 +1,78 @@ +variable number equal 2 +variable ofreq equal 1000 +variable efreq equal 1000 +variable T equal 0.1 +units lj + +dimension 3 + +newton off + +boundary p p p + +atom_style hybrid bond ellipsoid +atom_modify sort 0 1.0 + +# Pair interactions require lists of neighbours to be calculated +neighbor 1.0 bin +neigh_modify every 1 delay 0 check yes + +read_data data.duplex2 + +set atom * mass 3.1575 + +group all type 1 4 + +# oxDNA bond interactions - FENE backbone +bond_style oxdna2/fene +bond_coeff * 2.0 0.25 0.7564 + +# oxDNA pair interactions +pair_style hybrid/overlay oxdna2/excv oxdna2/stk oxdna2/hbond oxdna2/xstk oxdna2/coaxstk oxdna2/dh +pair_coeff * * oxdna2/excv 2.0 0.7 0.675 2.0 0.515 0.5 2.0 0.33 0.32 +pair_coeff * * oxdna2/stk seqav ${T} 1.3523 2.6717 6.0 0.4 0.9 0.32 0.6 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 2.0 0.65 2.0 0.65 +pair_coeff * * oxdna2/hbond seqav 0.0 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45 +pair_coeff 1 4 oxdna2/hbond seqav 1.0678 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45 +pair_coeff 2 3 oxdna2/hbond seqav 1.0678 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45 +pair_coeff * * oxdna2/xstk 47.5 0.575 0.675 0.495 0.655 2.25 0.791592653589793 0.58 1.7 1.0 0.68 1.7 1.0 0.68 1.5 0 0.65 1.7 0.875 0.68 1.7 0.875 0.68 +pair_coeff * * oxdna2/coaxstk 58.5 0.4 0.6 0.22 0.58 2.0 2.891592653589793 0.65 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 40.0 3.116592653589793 +pair_coeff * * oxdna2/dh ${T} 1.0 0.815 + +# NVE ensemble +#fix 1 all nve/dot +fix 1 all nve/dotc/langevin ${T} ${T} 0.03 457145 angmom 10 +#fix 1 all nve/asphere +#fix 2 all langevin ${T} ${T} 0.03 457145 angmom 10 + +timestep 1e-5 + +#comm_style tiled +#fix 3 all balance 10000 1.1 rcb + +#compute mol all chunk/atom molecule +#compute mychunk all vcm/chunk mol +#fix 4 all ave/time 10000 1 10000 c_mychunk[1] c_mychunk[2] c_mychunk[3] file vcm.txt mode vector + +#dump pos all xyz ${ofreq} traj.${number}.xyz + +#compute quat all property/atom quatw quati quatj quatk +#dump quat all custom ${ofreq} quat.${number}.txt id c_quat[1] c_quat[2] c_quat[3] c_quat[4] +#dump_modify quat sort id +#dump_modify quat format line "%d %13.6le %13.6le %13.6le %13.6le" + +compute erot all erotate/asphere +compute ekin all ke +compute epot all pe +variable erot equal c_erot +variable ekin equal c_ekin +variable epot equal c_epot +variable etot equal c_erot+c_ekin+c_epot +fix 5 all print ${efreq} "$(step) ekin = ${ekin} | erot = ${erot} | epot = ${epot} | etot = ${etot}" screen yes + +#dump out all custom ${ofreq} out.${number}.txt id x y z vx vy vz fx fy fz tqx tqy tqz +#dump_modify out sort id +#dump_modify out format line "%d %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le %13.6le" + +run 1000000 + +#write_restart config.${number}.* diff --git a/src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi b/src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi new file mode 100644 index 0000000000..d6c5c566aa --- /dev/null +++ b/src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi @@ -0,0 +1,125 @@ +# kokkos_cuda_mpi = KOKKOS/CUDA package, MPICH or OpenMPI with nvcc compiler, Kepler GPU + +SHELL = /bin/sh + +# --------------------------------------------------------------------- +# compiler/linker settings +# specify flags and libraries needed for your compiler + +KOKKOS_ABSOLUTE_PATH = $(shell cd $(KOKKOS_PATH); pwd) +export MPICH_CXX = $(KOKKOS_ABSOLUTE_PATH)/bin/nvcc_wrapper +export OMPI_CXX = $(KOKKOS_ABSOLUTE_PATH)/bin/nvcc_wrapper +CC = mpicxx +CCFLAGS = -g -O3 +SHFLAGS = -fPIC +DEPFLAGS = -M + +LINK = mpicxx +LINKFLAGS = -g -O3 +LIB = +SIZE = size + +ARCHIVE = ar +ARFLAGS = -rc +SHLIBFLAGS = -shared +KOKKOS_DEVICES = Cuda +KOKKOS_ARCH = Kepler35 + +# --------------------------------------------------------------------- +# LAMMPS-specific settings, all OPTIONAL +# specify settings for LAMMPS features you will use +# if you change any -D setting, do full re-compile after "make clean" + +# LAMMPS ifdef settings +# see possible settings in Section 2.2 (step 4) of manual + +LMP_INC = -DLAMMPS_GZIP + +# MPI library +# see discussion in Section 2.2 (step 5) of manual +# MPI wrapper compiler/linker can provide this info +# can point to dummy MPI library in src/STUBS as in Makefile.serial +# use -D MPICH and OMPI settings in INC to avoid C++ lib conflicts +# INC = path for mpi.h, MPI compiler settings +# PATH = path for MPI library +# LIB = name of MPI library + +MPI_INC = -DMPICH_SKIP_MPICXX -DOMPI_SKIP_MPICXX=1 +MPI_PATH = +MPI_LIB = + +# FFT library +# see discussion in Section 2.2 (step 6) of manaul +# can be left blank to use provided KISS FFT library +# INC = -DFFT setting, e.g. -DFFT_FFTW, FFT compiler settings +# PATH = path for FFT library +# LIB = name of FFT library + +FFT_INC = +FFT_PATH = +FFT_LIB = + +# JPEG and/or PNG library +# see discussion in Section 2.2 (step 7) of manual +# only needed if -DLAMMPS_JPEG or -DLAMMPS_PNG listed with LMP_INC +# INC = path(s) for jpeglib.h and/or png.h +# PATH = path(s) for JPEG library and/or PNG library +# LIB = name(s) of JPEG library and/or PNG library + +JPG_INC = +JPG_PATH = +JPG_LIB = + +# --------------------------------------------------------------------- +# build rules and dependencies +# do not edit this section + +include Makefile.package.settings +include Makefile.package + +EXTRA_INC = $(LMP_INC) $(PKG_INC) $(MPI_INC) $(FFT_INC) $(JPG_INC) $(PKG_SYSINC) +EXTRA_PATH = $(PKG_PATH) $(MPI_PATH) $(FFT_PATH) $(JPG_PATH) $(PKG_SYSPATH) +EXTRA_LIB = $(PKG_LIB) $(MPI_LIB) $(FFT_LIB) $(JPG_LIB) $(PKG_SYSLIB) +EXTRA_CPP_DEPENDS = $(PKG_CPP_DEPENDS) +EXTRA_LINK_DEPENDS = $(PKG_LINK_DEPENDS) + +# Path to src files + +vpath %.cpp .. +vpath %.h .. + +# Link target + +$(EXE): $(OBJ) $(EXTRA_LINK_DEPENDS) + $(LINK) $(LINKFLAGS) $(EXTRA_PATH) $(OBJ) $(EXTRA_LIB) $(LIB) -o $(EXE) + $(SIZE) $(EXE) + +# Library targets + +lib: $(OBJ) $(EXTRA_LINK_DEPENDS) + $(ARCHIVE) $(ARFLAGS) $(EXE) $(OBJ) + +shlib: $(OBJ) $(EXTRA_LINK_DEPENDS) + $(CC) $(CCFLAGS) $(SHFLAGS) $(SHLIBFLAGS) $(EXTRA_PATH) -o $(EXE) \ + $(OBJ) $(EXTRA_LIB) $(LIB) + +# Compilation rules + +%.o:%.cpp $(EXTRA_CPP_DEPENDS) + $(CC) $(CCFLAGS) $(SHFLAGS) $(EXTRA_INC) -c $< + +%.d:%.cpp $(EXTRA_CPP_DEPENDS) + $(CC) $(CCFLAGS) $(EXTRA_INC) $(DEPFLAGS) $< > $@ + +%.o:%.cu $(EXTRA_CPP_DEPENDS) + $(CC) $(CCFLAGS) $(SHFLAGS) $(EXTRA_INC) -c $< + +# Individual dependencies + +depend : fastdep.exe $(SRC) + @./fastdep.exe $(EXTRA_INC) -- $^ > .depend || exit 1 + +fastdep.exe: ../DEPEND/fastdep.c + cc -O -o $@ $< + +sinclude .depend From 6084fc23ce998ca4fc1da89326221095ce2b8a9a Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 29 Aug 2019 09:55:22 -0400 Subject: [PATCH 17/54] Added angular momentum thermostatting to 3d quaternion example. --- .../USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion b/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion index b43d6304b3..152a06d82e 100644 --- a/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion +++ b/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion @@ -23,7 +23,7 @@ set type * shape 1.0 1.0 1.0 set type * quat 0 0 1 0 fix step all nve -fix temp all langevin 1.0 1.0 1.0 13 +fix temp all langevin 1.0 1.0 1.0 13 angmom yes neighbor 0.6 bin From 17886f1e62e5684ec777a7240b8b0c04efc90b63 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 29 Aug 2019 09:56:37 -0400 Subject: [PATCH 18/54] Fixed example 3d_quaternion --- .../USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion b/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion index 152a06d82e..11f2ea8a07 100644 --- a/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion +++ b/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion @@ -23,7 +23,7 @@ set type * shape 1.0 1.0 1.0 set type * quat 0 0 1 0 fix step all nve -fix temp all langevin 1.0 1.0 1.0 13 angmom yes +fix temp all langevin 1.0 1.0 1.0 13 angmom 3.333333333 neighbor 0.6 bin From e919edb7a7f4f6b32e4f1cf1c8de8a8d5347be2f Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Wed, 11 Sep 2019 09:28:42 -0400 Subject: [PATCH 19/54] Updated documentation. --- doc/src/fix_propel_self.txt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/doc/src/fix_propel_self.txt b/doc/src/fix_propel_self.txt index e3a686802e..73c7837d33 100644 --- a/doc/src/fix_propel_self.txt +++ b/doc/src/fix_propel_self.txt @@ -30,7 +30,8 @@ fix active_group all propel/self quaternion 1.0 :pre Adds a force of a constant magnitude to each atom in the group. The nature in which the force is added depends on the mode. For mode = velocity, the active force acts along the velocity vector of each -atom. +atom. This can be interpreted as an overdamped form of the model used by +"(Szabo)"_#Szabo and "(Henkes)"_#Henkes. For mode = quaternion the force is along the axis obtained by rotating the z-axis along the atom's quaternion. In other words, the force is along the z-axis in the atom's body frame. This mode requires all atoms in the group @@ -55,3 +56,12 @@ that have a quaternion. [Related commands:] "fix setforce"_fix_setforce.html, "fix addforce"_fix_addforce.html + +:link(Szabo) +[(Szabo)] Szabo, B, Szollosi, G. J., Gonci, B., Juranyi, Zs., Selmeczi, D. and Viscek, T., +Phys. Rev. E, 74, 061908, 2006 + +:link(Henkes) +[(Henkes)] Henkes, S, Fily, Y., and Marchetti, M. C. +Phys. Rev. E, 84, 040301(R), 2011 + From dd0ceec0dcd55fc0f1bd04a3215ef55c54687cd7 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Wed, 11 Sep 2019 10:26:03 -0400 Subject: [PATCH 20/54] Added type support. --- src/USER-MISC/fix_propel_self.cpp | 69 ++++++++++++++++++++++++++++--- src/USER-MISC/fix_propel_self.h | 12 +++++- 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index 9cb5bb2207..f8c00e5ca8 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -49,7 +49,8 @@ static constexpr const bool debug_out = false; FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) - : Fix(lmp, narg, argv) + : Fix(lmp, narg, argv), magnitude(1.0), thermostat_orient(0), + mode(VELOCITY), n_types_filter(0), apply_to_type(NULL) { if( narg < 5 ) error->all(FLERR, "Illegal fix propel/self command"); @@ -78,6 +79,49 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) } magnitude = force->numeric( FLERR, argv[4] ); + + // Handle rest of args: + int iarg = 5; + while (iarg < narg) { + const char *arg = argv[iarg]; + if (strncmp(arg, "types", 5) == 0) { + // In this case we need to allocate the type list. + // First find the largest given type: + int max_type_in_list = 0; + while (!isalpha(arg[iarg + n_types_filter][0])) { + int curr_type = force->numeric(FLERR, arg[iarg + n_types_filter]); + if (curr_type > max_type_in_list) max_type_in_list = curr_type; + ++n_types_filter; + } + if (n_types_filter == 0) { + error->all(FLERR, "\"types\" option requires at least one type"); + } + + // sanity check: + if (max_type_in_list < n_types_filter) { + error->warning(FLERR, "Found duplicate type in \"types\" option"); + } + + apply_to_type = new int[max_type_in_list+1]; + if (!apply_to_type) error->all(FLERR, "Failed to allocate type storage!"); + + for (int i = 0; i < max_type_in_list+1; ++i) { + apply_to_type[i] = 0; + } + + for (int i = 0; i < n_types_filter; ++i) { + int curr_type = force->numeric(FLERR, arg[iarg + i]); + apply_to_type[curr_type] = 1; + } + // Done handling types argument. + } else { + char msg[2048]; + sprintf(msg, "Illegal fix propel/self command: " + "Unrecognized argument %s", arg); + error->all(FLERR, msg); + } + } + } @@ -96,7 +140,10 @@ int FixPropelSelf::setmask() double FixPropelSelf::memory_usage() { - double bytes = 0.0; + // magnitude + thermostat_orient + mode + n_types_filter + apply_to_type + double bytes = sizeof(double) + 3*sizeof(int) + sizeof(int*); + bytes += sizeof(int)*n_types_filter; + return bytes; } @@ -105,11 +152,12 @@ void FixPropelSelf::post_force(int vflag ) { switch(mode) { case QUATERNION: - post_force_quaternion(vflag); + if (n_types_filter) post_force_quaternion<1>(vflag); + else post_force_quaternion<0>(vflag); break; case VELOCITY: - post_force_velocity(vflag); - break; + if (n_types_filter) post_force_velocity<1>(vflag); + else post_force_velocity<0>(vflag); default: error->all(FLERR, "reached statement that should be unreachable"); } @@ -117,6 +165,7 @@ void FixPropelSelf::post_force(int vflag ) +template void FixPropelSelf::post_force_quaternion(int /* vflag */ ) { double **f = atom->f; @@ -129,6 +178,10 @@ void FixPropelSelf::post_force_quaternion(int /* vflag */ ) // Add the active force to the atom force: for( int i = 0; i < nlocal; ++i ){ if( mask[i] & groupbit ){ + if (filter_by_type && !apply_to_type[type[i]]) { + continue; + } + double f_act[3] = { 0.0, 0.0, 1.0 }; double f_rot[3]; @@ -167,7 +220,7 @@ void FixPropelSelf::post_force_quaternion(int /* vflag */ ) } - +template void FixPropelSelf::post_force_velocity(int /*vflag*/ ) { double **f = atom->f; @@ -179,6 +232,10 @@ void FixPropelSelf::post_force_velocity(int /*vflag*/ ) // Add the active force to the atom force: for( int i = 0; i < nlocal; ++i ){ if( mask[i] & groupbit ){ + if (filter_by_type && !apply_to_type[type[i]]) { + continue; + } + const double *vi = v[i]; double f_act[3] = { vi[0], vi[1], vi[2] }; double nv2 = vi[0]*vi[0] + vi[1]*vi[1] + vi[2]*vi[2]; diff --git a/src/USER-MISC/fix_propel_self.h b/src/USER-MISC/fix_propel_self.h index 45b2afffc3..2b44b8e1ce 100644 --- a/src/USER-MISC/fix_propel_self.h +++ b/src/USER-MISC/fix_propel_self.h @@ -45,9 +45,17 @@ private: int thermostat_orient; int mode; + + // If 0, apply fix to everything in group. If > 0, apply only to those + // types i for which i <= n_types_filter _and_ apply_to_type[i] == 1: + int n_types_filter; + int *apply_to_type; //< Specifies, per type, if the fix applies to it or not. + + int verify_atoms_have_quaternion(); - void post_force_velocity(int); - void post_force_quaternion(int); + + template void post_force_velocity(int); + template void post_force_quaternion(int); }; From 2430c7bcffcdb7c4847860cf12c0e793386ad242 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Wed, 11 Sep 2019 10:58:45 -0400 Subject: [PATCH 21/54] Added option to impose fix propel/self only to specific types --- .../fix_propel_self/2d_velocity/in.2d_langevin | 17 +++++++++++++++++ src/USER-MISC/fix_propel_self.cpp | 16 +++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin index b7a1b93745..563c0bd969 100644 --- a/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin +++ b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin @@ -30,8 +30,25 @@ thermo_style custom time step pe ke etotal temp thermo 1000 run 25000 +group one type 1 +group two type 2 + +compute ke1 one ke +compute ke2 two ke + +thermo_style custom time step pe ke etotal temp c_ke1 c_ke2 + fix active all propel/self velocity 1.0 # With active force there is more motion so increase bin size: neighbor 1.0 bin run 25000 + +# Only make type 1 active: +fix active all propel/self velocity 1.0 types 1 + +# With active force there is more motion so increase bin size: +neighbor 1.0 bin +run 25000 + + diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index f8c00e5ca8..56f5e44869 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -88,8 +88,10 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) // In this case we need to allocate the type list. // First find the largest given type: int max_type_in_list = 0; - while (!isalpha(arg[iarg + n_types_filter][0])) { - int curr_type = force->numeric(FLERR, arg[iarg + n_types_filter]); + ++iarg; + while ( (iarg + n_types_filter < narg) && + (!isalpha(argv[iarg + n_types_filter][0]))) { + int curr_type = force->numeric(FLERR, argv[iarg + n_types_filter]); if (curr_type > max_type_in_list) max_type_in_list = curr_type; ++n_types_filter; } @@ -110,10 +112,11 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) } for (int i = 0; i < n_types_filter; ++i) { - int curr_type = force->numeric(FLERR, arg[iarg + i]); + int curr_type = force->numeric(FLERR, argv[iarg + i]); apply_to_type[curr_type] = 1; } // Done handling types argument. + iarg += n_types_filter; // -1 because we incremented by 1 previously. } else { char msg[2048]; sprintf(msg, "Illegal fix propel/self command: " @@ -158,6 +161,7 @@ void FixPropelSelf::post_force(int vflag ) case VELOCITY: if (n_types_filter) post_force_velocity<1>(vflag); else post_force_velocity<0>(vflag); + break; default: error->all(FLERR, "reached statement that should be unreachable"); } @@ -173,7 +177,9 @@ void FixPropelSelf::post_force_quaternion(int /* vflag */ ) int *mask = atom->mask; int nlocal = atom->nlocal; - + int *type = atom->type; + int* ellipsoid = atom->ellipsoid; + AtomVecEllipsoid::Bonus *bonus = av->bonus; // Add the active force to the atom force: for( int i = 0; i < nlocal; ++i ){ @@ -185,7 +191,6 @@ void FixPropelSelf::post_force_quaternion(int /* vflag */ ) double f_act[3] = { 0.0, 0.0, 1.0 }; double f_rot[3]; - int* ellipsoid = atom->ellipsoid; double *quat = bonus[ellipsoid[i]].quat; tagint *tag = atom->tag; @@ -228,6 +233,7 @@ void FixPropelSelf::post_force_velocity(int /*vflag*/ ) int *mask = atom->mask; int nlocal = atom->nlocal; tagint *tag = atom->tag; + int *type = atom->type; // Add the active force to the atom force: for( int i = 0; i < nlocal; ++i ){ From 86179478d240c9009ffff9df1418c3156c4fba57 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Wed, 11 Sep 2019 11:05:04 -0400 Subject: [PATCH 22/54] Updated documentation regarding types keyword. --- doc/src/fix_propel_self.txt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/src/fix_propel_self.txt b/doc/src/fix_propel_self.txt index 73c7837d33..7c3dfd3f45 100644 --- a/doc/src/fix_propel_self.txt +++ b/doc/src/fix_propel_self.txt @@ -10,12 +10,16 @@ fix propel/self command :pre [Syntax:] -fix ID group-ID propel/self mode magnitude +fix ID group-ID propel/self mode magnitude keyword values ... ID, group-ID are documented in "fix"_fix.html command :ulb,l propel/self = style name of this fix command :l mode = velocity or quaternion :l magnitude = magnitude of the active force :l +one or more keyword/value pairs may be appended to args :l +keyword = {types} :l + {types} values = one or more atom types + :ule [Examples:] @@ -25,6 +29,9 @@ fix constant_velocity all viscous 1.0 :pre fix active_group all propel/self quaternion 1.0 :pre +fix active all propel/self quaternion 1.0 types 1 2 4 :pre + + [Description:] Adds a force of a constant magnitude to each atom in the group. The nature in @@ -37,6 +44,10 @@ z-axis along the atom's quaternion. In other words, the force is along the z-axis in the atom's body frame. This mode requires all atoms in the group to have a quaternion, so atom_style should either be ellipsoid or body. +By default, this fix is applied to all atoms in the group. You can override this +behavior by specifying the atom types the fix should work on through the {types} +keyword. + :line [Restart, fix_modify, output, run start/stop, minimize info:] @@ -65,3 +76,5 @@ Phys. Rev. E, 74, 061908, 2006 [(Henkes)] Henkes, S, Fily, Y., and Marchetti, M. C. Phys. Rev. E, 84, 040301(R), 2011 + +[Default:] types From 913c9a7b33c04ad811807a5c670876707fdd35e7 Mon Sep 17 00:00:00 2001 From: Pierre de Buyl Date: Tue, 17 Dec 2019 11:54:30 +0100 Subject: [PATCH 23/54] Update documentation of fix propel/self MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Remove reference to velocity alignment model. 2. Use reference to velocity-dependent friction for mode velocity 3. Add references to Fily & Marchetti and Bialké, Speck & Löwen for the quaternion mode. --- doc/src/Commands_fix.txt | 1 + doc/src/fix.txt | 1 + doc/src/fix_propel_self.txt | 42 ++++++++++++++++++++++--------------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/doc/src/Commands_fix.txt b/doc/src/Commands_fix.txt index cfd2bcf2ef..eb080f8b12 100644 --- a/doc/src/Commands_fix.txt +++ b/doc/src/Commands_fix.txt @@ -157,6 +157,7 @@ OPT. "precession/spin"_fix_precession_spin.html, "press/berendsen"_fix_press_berendsen.html, "print"_fix_print.html, +"propel/self"_fix_propel_self.html, "property/atom (k)"_fix_property_atom.html, "python/invoke"_fix_python_invoke.html, "python/move"_fix_python_move.html, diff --git a/doc/src/fix.txt b/doc/src/fix.txt index 1dd9cc9f1b..a6013673f1 100644 --- a/doc/src/fix.txt +++ b/doc/src/fix.txt @@ -296,6 +296,7 @@ accelerated styles exist. "precession/spin"_fix_precession_spin.html - "press/berendsen"_fix_press_berendsen.html - pressure control by Berendsen barostat "print"_fix_print.html - print text and variables during a simulation +"propel/self"_fix_propel_self.html - add self-propelling force "property/atom"_fix_property_atom.html - add customized per-atom values "python/invoke"_fix_python_invoke.html - call a Python function during a simulation "python/move"_fix_python_move.html - call a Python function during a simulation run diff --git a/doc/src/fix_propel_self.txt b/doc/src/fix_propel_self.txt index 7c3dfd3f45..3e351ba56a 100644 --- a/doc/src/fix_propel_self.txt +++ b/doc/src/fix_propel_self.txt @@ -6,7 +6,7 @@ :line -fix propel/self command :pre +fix propel/self command :h3 [Syntax:] @@ -36,13 +36,16 @@ fix active all propel/self quaternion 1.0 types 1 2 4 :pre Adds a force of a constant magnitude to each atom in the group. The nature in which the force is added depends on the mode. -For mode = velocity, the active force acts along the velocity vector of each -atom. This can be interpreted as an overdamped form of the model used by -"(Szabo)"_#Szabo and "(Henkes)"_#Henkes. -For mode = quaternion the force is along the axis obtained by rotating the -z-axis along the atom's quaternion. In other words, the force is along the -z-axis in the atom's body frame. This mode requires all atoms in the group -to have a quaternion, so atom_style should either be ellipsoid or body. + +For mode = velocity, the active force acts along the velocity vector of each atom. This can +be interpreted as a velocity-dependent friction, such as proposed by "(Erdmann)"_#Erdmann. + +For mode = quaternion the force is along the axis obtained by rotating the z-axis along the +atom's quaternion. In other words, the force is along the z-axis in the atom's body +frame. This mode requires all atoms in the group to have a quaternion, so atom_style should +either be ellipsoid or body. In combination with Langevin thermostat for translation and +rotation in the overdamped regime, the quaternion mode corresponds to the active Brownian +particle model introduced by "(Henkes)"_#Henkes, "(Bialke)"_#Bialke and "(Fily)"_#Fily. By default, this fix is applied to all atoms in the group. You can override this behavior by specifying the atom types the fix should work on through the {types} @@ -59,22 +62,27 @@ This fix is not imposed during minimization. [Restrictions:] -This fix makes use of per-atom quaternions to take into -account the fact that the orientation can rotate and hence the direction -of the active force can change. Therefore, this fix only works with atom_styles -that have a quaternion. +In quaternion mode, this fix makes use of per-atom quaternions to take into account the fact +that the orientation can rotate and hence the direction of the active force can +change. Therefore, the quaternion mode of this fix only works with atom_styles that have a +quaternion. [Related commands:] "fix setforce"_fix_setforce.html, "fix addforce"_fix_addforce.html -:link(Szabo) -[(Szabo)] Szabo, B, Szollosi, G. J., Gonci, B., Juranyi, Zs., Selmeczi, D. and Viscek, T., -Phys. Rev. E, 74, 061908, 2006 +:link(Erdmann) +[(Erdmann)] U. Erdmanna , W. Ebeling, L. Schimansky-Geier, and F. Schweitzer, +Eur. Phys. J. B 15, 105-113, 2000. :link(Henkes) -[(Henkes)] Henkes, S, Fily, Y., and Marchetti, M. C. -Phys. Rev. E, 84, 040301(R), 2011 +[(Henkes)] Henkes, S, Fily, Y., and Marchetti, M. C. Phys. Rev. E, 84, 040301(R), 2011 + +:link(Bialke) +[(Bialke)] J. Bialké, T. Speck, and H Löwen, Phys. Rev. Lett. 108, 168301, 2012. + +:link(Fily) +[(Fily)] Y. Fily and M.C. Marchetti, Phys. Rev. Lett. 108, 235702, 2012. [Default:] types From a65e2a5de441b69323499f1f0a59ed8ed4a9a4e8 Mon Sep 17 00:00:00 2001 From: Pierre de Buyl Date: Thu, 19 Dec 2019 21:34:49 +0100 Subject: [PATCH 24/54] Use x-axis along the particle's quaternion. This change allows the fix to work in 2D as well. --- doc/src/fix_propel_self.txt | 4 ++-- src/USER-MISC/fix_propel_self.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/fix_propel_self.txt b/doc/src/fix_propel_self.txt index 3e351ba56a..dbde99f48a 100644 --- a/doc/src/fix_propel_self.txt +++ b/doc/src/fix_propel_self.txt @@ -40,8 +40,8 @@ which the force is added depends on the mode. For mode = velocity, the active force acts along the velocity vector of each atom. This can be interpreted as a velocity-dependent friction, such as proposed by "(Erdmann)"_#Erdmann. -For mode = quaternion the force is along the axis obtained by rotating the z-axis along the -atom's quaternion. In other words, the force is along the z-axis in the atom's body +For mode = quaternion the force is along the axis obtained by rotating the x-axis along the +atom's quaternion. In other words, the force is along the x-axis in the atom's body frame. This mode requires all atoms in the group to have a quaternion, so atom_style should either be ellipsoid or body. In combination with Langevin thermostat for translation and rotation in the overdamped regime, the quaternion mode corresponds to the active Brownian diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index 56f5e44869..57ca30e838 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -188,7 +188,7 @@ void FixPropelSelf::post_force_quaternion(int /* vflag */ ) continue; } - double f_act[3] = { 0.0, 0.0, 1.0 }; + double f_act[3] = { 1.0, 0.0, 0.0 }; double f_rot[3]; double *quat = bonus[ellipsoid[i]].quat; From 4853b43f1697f616ee6486ee2c573b6cddf8b6b2 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Sat, 2 Jun 2018 08:10:35 -0400 Subject: [PATCH 25/54] Commit change in fix_wall_region before merge. --- src/fix_wall_region.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fix_wall_region.cpp b/src/fix_wall_region.cpp index 70bde90d2b..f63a3774cc 100644 --- a/src/fix_wall_region.cpp +++ b/src/fix_wall_region.cpp @@ -1,4 +1,4 @@ -/* ---------------------------------------------------------------------- + seems------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov From 7af38e0862529fa24f3c27538f3773e150b218ef Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Wed, 24 Oct 2018 11:10:53 -0400 Subject: [PATCH 26/54] Makefile.kokkos_cuda_mpi --- src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi b/src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi index d6c5c566aa..57fc37c10e 100644 --- a/src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi +++ b/src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi @@ -6,7 +6,7 @@ SHELL = /bin/sh # compiler/linker settings # specify flags and libraries needed for your compiler -KOKKOS_ABSOLUTE_PATH = $(shell cd $(KOKKOS_PATH); pwd) +KOKKOS_ABSOLUTE_PATH = /home/stefan/projects/lammps-mine/lib/kokkos export MPICH_CXX = $(KOKKOS_ABSOLUTE_PATH)/bin/nvcc_wrapper export OMPI_CXX = $(KOKKOS_ABSOLUTE_PATH)/bin/nvcc_wrapper CC = mpicxx @@ -33,7 +33,7 @@ KOKKOS_ARCH = Kepler35 # LAMMPS ifdef settings # see possible settings in Section 2.2 (step 4) of manual -LMP_INC = -DLAMMPS_GZIP +LMP_INC = -DLAMMPS_GZIP -DLAMMPS_PNG -DLAMMPS_JPEG -DLAMMPS_FFMPEG # MPI library # see discussion in Section 2.2 (step 5) of manual @@ -55,9 +55,9 @@ MPI_LIB = # PATH = path for FFT library # LIB = name of FFT library -FFT_INC = -FFT_PATH = -FFT_LIB = +FFT_INC = -I/usr/include/ +FFT_PATH = -L/usr/lib/ +FFT_LIB = -lfftw3 # JPEG and/or PNG library # see discussion in Section 2.2 (step 7) of manual @@ -68,7 +68,7 @@ FFT_LIB = JPG_INC = JPG_PATH = -JPG_LIB = +JPG_LIB = -ljpeg -lpng # --------------------------------------------------------------------- # build rules and dependencies From 5139f3af3322927172a2adb7552b0c79df23913b Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Mon, 22 Oct 2018 11:24:11 -0400 Subject: [PATCH 27/54] Fixed compile error for fix_momentum_kokkos. --- src/KOKKOS/fix_momentum_kokkos.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/KOKKOS/fix_momentum_kokkos.cpp b/src/KOKKOS/fix_momentum_kokkos.cpp index 2d4911bfda..3b615e82e9 100644 --- a/src/KOKKOS/fix_momentum_kokkos.cpp +++ b/src/KOKKOS/fix_momentum_kokkos.cpp @@ -121,12 +121,13 @@ void FixMomentumKokkos::end_of_step() auto xflag2 = xflag; auto yflag2 = yflag; auto zflag2 = zflag; + const Few &vcm_ref = vcm; Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { if (mask(i) & groupbit2) { - if (xflag2) v(i,0) -= vcm[0]; - if (yflag2) v(i,1) -= vcm[1]; - if (zflag2) v(i,2) -= vcm[2]; + if (xflag2) v(i,0) -= vcm_ref[0]; + if (yflag2) v(i,1) -= vcm_ref[1]; + if (zflag2) v(i,2) -= vcm_ref[2]; } }); atomKK->modified(execution_space, V_MASK); @@ -160,6 +161,10 @@ void FixMomentumKokkos::end_of_step() auto prd = Few(domain->prd); auto h = Few(domain->h); auto triclinic = domain->triclinic; + + const Few &xcm_ref = xcm; + const Few &omega_ref = omega; + Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { if (mask[i] & groupbit2) { Few x_i; @@ -167,12 +172,12 @@ void FixMomentumKokkos::end_of_step() x_i[1] = x(i,1); x_i[2] = x(i,2); auto unwrap = DomainKokkos::unmap(prd,h,triclinic,x_i,image(i)); - auto dx = unwrap[0] - xcm[0]; - auto dy = unwrap[1] - xcm[1]; - auto dz = unwrap[2] - xcm[2]; - v(i,0) -= omega[1]*dz - omega[2]*dy; - v(i,1) -= omega[2]*dx - omega[0]*dz; - v(i,2) -= omega[0]*dy - omega[1]*dx; + auto dx = unwrap[0] - xcm_ref[0]; + auto dy = unwrap[1] - xcm_ref[1]; + auto dz = unwrap[2] - xcm_ref[2]; + v(i,0) -= omega_ref[1]*dz - omega_ref[2]*dy; + v(i,1) -= omega_ref[2]*dx - omega_ref[0]*dz; + v(i,2) -= omega_ref[0]*dy - omega_ref[1]*dx; } }); atomKK->modified(execution_space, V_MASK); @@ -203,4 +208,3 @@ template class FixMomentumKokkos; template class FixMomentumKokkos; #endif } - From c93ca5b4a407985850c99a650d281cf4ed79ef2a Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 25 Oct 2018 11:34:54 -0400 Subject: [PATCH 28/54] Added a fix to add active force to particles. --- doc/src/fix_active.txt | 50 ++++++ examples/USER/misc/active/active_langevin.in | 61 +++++++ examples/USER/misc/active/active_viscous.in | 66 ++++++++ src/KOKKOS/fix_momentum_kokkos.cpp | 24 ++- src/USER-MISC/fix_active.cpp | 163 +++++++++++++++++++ src/USER-MISC/fix_active.h | 55 +++++++ 6 files changed, 405 insertions(+), 14 deletions(-) create mode 100644 doc/src/fix_active.txt create mode 100644 examples/USER/misc/active/active_langevin.in create mode 100644 examples/USER/misc/active/active_viscous.in create mode 100644 src/USER-MISC/fix_active.cpp create mode 100644 src/USER-MISC/fix_active.h diff --git a/doc/src/fix_active.txt b/doc/src/fix_active.txt new file mode 100644 index 0000000000..3bc6c15326 --- /dev/null +++ b/doc/src/fix_active.txt @@ -0,0 +1,50 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +fix active command :pre + +[Syntax:] + +fix ID group-ID magnitude + +ID, group-ID are documented in "fix"_fix.html command :ulb,l +addforce = style name of this fix command :l +magnitude = magnitude of the active force :l +:ule + +[Examples:] + +fix active_group all active 1.0 +fix constant_velocity all viscous 1.0 + +[Description:] + +Adds a force of a constant magnitude to each atom in the group. The direction +of the force is along the axis obtained by rotating the z-axis along the atom's +quaternion. In other words, the force is along the z-axis in the atom's body +frame. + +:line + +[Restart, fix_modify, output, run start/stop, minimize info:] + +No information about this fix is written to "binary restart +files"_restart.html. + +This fix is not imposed during minimization. + +[Restrictions:] + +This fix makes use of per-atom quaternions to take into +account the fact that the orientation can rotate and hence the direction +of the active force can change. Therefore, this fix only works with +ellipsoidal particles. + +[Related commands:] + +"fix setforce"_fix_setforce.html, "fix addforce"_fix_addforce.html diff --git a/examples/USER/misc/active/active_langevin.in b/examples/USER/misc/active/active_langevin.in new file mode 100644 index 0000000000..3854729fc5 --- /dev/null +++ b/examples/USER/misc/active/active_langevin.in @@ -0,0 +1,61 @@ +# Uses a combnation of fix active and fix langevin to achieve +# self-propelled particles. + +dimension 3 +boundary p p p +units lj + +# Fix active uses quaternions to orient the active force so you need +# ellipsoidal particles, even if you do not care about asymmetric shape +atom_style ellipsoid + + +# Set up box and particles: +variable L equal 10 +region total block -$L $L -$L $L -$L $L +create_box 1 total +variable N equal 1000 +create_atoms 1 random $N 123456 total + +# Set particle shape: +set group all shape 1 1 1 +set group all quat/random 18238 +variable V equal "4.0*PI" +variable rho equal "1.0 / v_V" +# Density so that mass = 1 +set group all density ${rho} + +# Simple repulsive LJ +pair_style lj/cut 1.1225 +pair_coeff * * 1.0 1.0 +pair_modify shift yes + +# Remove initial overlap: +minimize 1e-4 1e-6 1000 10000 +reset_timestep 0 + +# Fixes for time integration +fix step all nve/asphere +fix active all active 1.0 +fix temp all langevin 1.0 1.0 1.0 12341 angmom 3.333333333333 + +variable DUMP_OUT string "active_langevin.dump" +variable MSD_OUT string "active_langevin_msd.dat" + +# Compute temperature and orientation +compute T all temp/asphere +compute quat all property/atom quatw quati quatj quatk +compute msd all msd +compute vacf all vacf + +# Some output: +thermo_style custom time step pe ke etotal temp c_T +thermo 1000 + +dump traj all custom 100 ${DUMP_OUT} id type x y z & + c_quat[1] c_quat[2] c_quat[3] c_quat[4] + +fix msd all ave/time 1 10 50 c_msd[4] c_vacf[1] c_vacf[2] c_vacf[3] c_vacf[4] file ${MSD_OUT} + +timestep 0.001 +run 10000 diff --git a/examples/USER/misc/active/active_viscous.in b/examples/USER/misc/active/active_viscous.in new file mode 100644 index 0000000000..f7660187e1 --- /dev/null +++ b/examples/USER/misc/active/active_viscous.in @@ -0,0 +1,66 @@ +# Uses a combnation of fix active and fix langevin to achieve +# self-propelled particles. + +dimension 3 +boundary p p p +units lj + +# Fix active uses quaternions to orient the active force so you need +# ellipsoidal particles, even if you do not care about asymmetric shape +atom_style ellipsoid + + +# Set up box and particles: +variable L equal 10 +region total block -$L $L -$L $L -$L $L +create_box 1 total +variable N equal 1000 +create_atoms 1 random $N 123456 total + +# Set particle shape: +set group all shape 1 1 1 +set group all quat/random 18238 +variable V equal "4.0*PI" +variable rho equal "1.0 / v_V" +# Density so that mass = 1 +set group all density ${rho} + +# Simple repulsive LJ +pair_style lj/cut 1.1225 +pair_coeff * * 0.0 1.0 +pair_modify shift yes + +# Remove initial overlap: +minimize 1e-4 1e-6 1000 10000 +reset_timestep 0 + +# Fixes for time integration +fix step all nve/asphere + +# Should lead to constant velocity of 10 per particle +fix active all active 1.0 +fix visc all viscous 0.1 + +# Initial velocities: +velocity all create 1.0 1234 + +variable DUMP_OUT string "active_viscous.dump" +variable MSD_OUT string "active_viscous_msd.dat" + +# Compute temperature and orientation +compute T all temp/asphere +compute quat all property/atom quatw quati quatj quatk +compute msd all msd +compute vacf all vacf + +# Some output: +thermo_style custom time step pe ke etotal temp c_T +thermo 1000 + +dump traj all custom 100 ${DUMP_OUT} id type x y z & + c_quat[1] c_quat[2] c_quat[3] c_quat[4] + +fix msd all ave/time 1 10 50 c_msd[4] c_vacf[1] c_vacf[2] c_vacf[3] c_vacf[4] file ${MSD_OUT} + +timestep 0.001 +run 10000 diff --git a/src/KOKKOS/fix_momentum_kokkos.cpp b/src/KOKKOS/fix_momentum_kokkos.cpp index 3b615e82e9..2d4911bfda 100644 --- a/src/KOKKOS/fix_momentum_kokkos.cpp +++ b/src/KOKKOS/fix_momentum_kokkos.cpp @@ -121,13 +121,12 @@ void FixMomentumKokkos::end_of_step() auto xflag2 = xflag; auto yflag2 = yflag; auto zflag2 = zflag; - const Few &vcm_ref = vcm; Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { if (mask(i) & groupbit2) { - if (xflag2) v(i,0) -= vcm_ref[0]; - if (yflag2) v(i,1) -= vcm_ref[1]; - if (zflag2) v(i,2) -= vcm_ref[2]; + if (xflag2) v(i,0) -= vcm[0]; + if (yflag2) v(i,1) -= vcm[1]; + if (zflag2) v(i,2) -= vcm[2]; } }); atomKK->modified(execution_space, V_MASK); @@ -161,10 +160,6 @@ void FixMomentumKokkos::end_of_step() auto prd = Few(domain->prd); auto h = Few(domain->h); auto triclinic = domain->triclinic; - - const Few &xcm_ref = xcm; - const Few &omega_ref = omega; - Kokkos::parallel_for(nlocal, LAMMPS_LAMBDA(int i) { if (mask[i] & groupbit2) { Few x_i; @@ -172,12 +167,12 @@ void FixMomentumKokkos::end_of_step() x_i[1] = x(i,1); x_i[2] = x(i,2); auto unwrap = DomainKokkos::unmap(prd,h,triclinic,x_i,image(i)); - auto dx = unwrap[0] - xcm_ref[0]; - auto dy = unwrap[1] - xcm_ref[1]; - auto dz = unwrap[2] - xcm_ref[2]; - v(i,0) -= omega_ref[1]*dz - omega_ref[2]*dy; - v(i,1) -= omega_ref[2]*dx - omega_ref[0]*dz; - v(i,2) -= omega_ref[0]*dy - omega_ref[1]*dx; + auto dx = unwrap[0] - xcm[0]; + auto dy = unwrap[1] - xcm[1]; + auto dz = unwrap[2] - xcm[2]; + v(i,0) -= omega[1]*dz - omega[2]*dy; + v(i,1) -= omega[2]*dx - omega[0]*dz; + v(i,2) -= omega[0]*dy - omega[1]*dx; } }); atomKK->modified(execution_space, V_MASK); @@ -208,3 +203,4 @@ template class FixMomentumKokkos; template class FixMomentumKokkos; #endif } + diff --git a/src/USER-MISC/fix_active.cpp b/src/USER-MISC/fix_active.cpp new file mode 100644 index 0000000000..1bb0726748 --- /dev/null +++ b/src/USER-MISC/fix_active.cpp @@ -0,0 +1,163 @@ +/* ---------------------------------------------------------------------- + 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. + ------------------------------------------------------------------------- */ + +/* ----------------------------------------------------------------------- + Contributed by Stefan Paquay @ Brandeis University + + Thanks to Liesbeth Janssen @ Eindhoven University for useful discussions! + ----------------------------------------------------------------------- */ + + +#include +#include + +#include "fix_active.h" + +#include "atom.h" +#include "atom_vec_ellipsoid.h" +#include "citeme.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "group.h" +#include "math.h" +#include "math_const.h" +#include "math_extra.h" +#include "math_vector.h" +#include "modify.h" +#include "random_mars.h" +#include "respa.h" +#include "update.h" + + +using namespace LAMMPS_NS; +using namespace FixConst; +using namespace MathConst; + +/* + Might be used later, who knows... +static const char* cite_fix_active = + "fix active command:\n\n" + "@article{paquay-2018,\n" + " author = {Paquay, Stefan},\n" + " doi = {},\n" + " issn = {},\n" + " journal = {},\n" + " month = ,\n" + " number = ,\n" + " pages = ,\n" + " title = ,\n" + " volume = ,\n" + " year = \n" + "}\n\n"; +*/ + +static constexpr const bool debug_out = false; + +FixActive::FixActive( LAMMPS *lmp, int narg, char **argv ) + : Fix(lmp, narg, argv) +{ + // if( lmp->citeme) lmp->citeme->add(cite_fix_active); + if( narg < 4 ) error->all(FLERR, "Illegal fix active command"); + + AtomVecEllipsoid *av = static_cast(atom->avec); + if (!av) error->all(FLERR, "FixActive requires atom_style ellipsoid"); + + if( debug_out && comm->me == 0 ){ + fprintf(screen, "This is fix active, narg is %d\n", narg ); + fprintf(screen, "args:"); + for( int i = 0; i < narg; ++i ){ + fprintf(screen, " %s", argv[i]); + } + fprintf(screen, "\n"); + } + + // args: fix ID all active magnitude prop1 prop2 prop3 + // Optional args are + magnitude = force->numeric( FLERR, argv[3] ); +} + + +FixActive::~FixActive() +{} + + +int FixActive::setmask() +{ + int mask = 0; + mask |= POST_FORCE; + + return mask; +} + + +double FixActive::memory_usage() +{ + double bytes = 0.0; + return bytes; +} + + + +void FixActive::post_force(int /* vflag */ ) +{ + // Then do the rest: + double **f = atom->f; + + AtomVecEllipsoid *av = static_cast(atom->avec); + + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + AtomVecEllipsoid::Bonus *bonus = av->bonus; + // Add the active force to the atom force: + for( int i = 0; i < nlocal; ++i ){ + if( mask[i] & groupbit ){ + double f_act[3] = { 0.0, 0.0, 1.0 }; + double f_rot[3]; + + int* ellipsoid = atom->ellipsoid; + double *quat = bonus[ellipsoid[i]].quat; + tagint *tag = atom->tag; + + double Q[3][3]; + MathExtra::quat_to_mat( quat, Q ); + MathExtra::matvec( Q, f_act, f_rot ); + + if (debug_out && comm->me == 0) { + // Magical reference particle: + if (tag[i] == 12) { + fprintf(screen, "rotation quaternion: (%f %f %f %f)\n", + quat[0], quat[1], quat[2], quat[3]); + fprintf(screen, "rotation matrix: / %f %f %f \\\n", + Q[0][0] ,Q[0][1], Q[0][2]); + fprintf(screen, " | %f %f %f |\n", + Q[1][0] ,Q[1][1], Q[1][2]); + fprintf(screen, " \\ %f %f %f /\n", + Q[2][0] ,Q[2][1], Q[2][2]); + + fprintf(screen, "Active force on atom %d: (%f %f %f)\n", + tag[i], f_rot[0], f_rot[1], f_rot[2]); + fprintf(screen, " Total force before: (%f %f %f)\n", + f[i][0], f[i][1], f[i][2]); + } + } + + f[i][0] += magnitude * f_rot[0]; + f[i][1] += magnitude * f_rot[1]; + f[i][2] += magnitude * f_rot[2]; + + } + } +} diff --git a/src/USER-MISC/fix_active.h b/src/USER-MISC/fix_active.h new file mode 100644 index 0000000000..02a91db14a --- /dev/null +++ b/src/USER-MISC/fix_active.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(active,FixActive) + +#else + +#ifndef LMP_FIX_ACTIVE_H +#define LMP_FIX_ACTIVE_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixActive : public Fix { + public: + FixActive(class LAMMPS *, int, char **); + virtual ~FixActive(); + virtual int setmask(); + virtual void post_force(int); + // virtual void post_force_respa(int, int, int); + + double memory_usage(); + +protected: + double magnitude; + int thermostat_orient; +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Illegal ... command + +Self-explanatory. Check the input script syntax and compare to the +documentation for the command. You can use -echo screen as a +command-line option when running LAMMPS to see the offending line. + +*/ From 3d813fec6b17cff701607baae075f0ab724d5951 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 25 Oct 2018 11:41:58 -0400 Subject: [PATCH 29/54] Slightly modified example. --- examples/USER/misc/active/active_viscous.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/USER/misc/active/active_viscous.in b/examples/USER/misc/active/active_viscous.in index f7660187e1..62fdaa7751 100644 --- a/examples/USER/misc/active/active_viscous.in +++ b/examples/USER/misc/active/active_viscous.in @@ -27,7 +27,7 @@ set group all density ${rho} # Simple repulsive LJ pair_style lj/cut 1.1225 -pair_coeff * * 0.0 1.0 +pair_coeff * * 1.0 1.0 pair_modify shift yes # Remove initial overlap: @@ -63,4 +63,4 @@ dump traj all custom 100 ${DUMP_OUT} id type x y z & fix msd all ave/time 1 10 50 c_msd[4] c_vacf[1] c_vacf[2] c_vacf[3] c_vacf[4] file ${MSD_OUT} timestep 0.001 -run 10000 +run 100000 From 2a0081d1352aa3a6bc0dca10256b5dd98dda4e49 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Tue, 9 Jul 2019 10:24:17 -0400 Subject: [PATCH 30/54] Renamed fix active to fix propel/self --- doc/src/fix_propel_self.txt | 50 ++++++++++ src/USER-MISC/fix_propel_self.cpp | 147 ++++++++++++++++++++++++++++++ src/USER-MISC/fix_propel_self.h | 55 +++++++++++ 3 files changed, 252 insertions(+) create mode 100644 doc/src/fix_propel_self.txt create mode 100644 src/USER-MISC/fix_propel_self.cpp create mode 100644 src/USER-MISC/fix_propel_self.h diff --git a/doc/src/fix_propel_self.txt b/doc/src/fix_propel_self.txt new file mode 100644 index 0000000000..3bc6c15326 --- /dev/null +++ b/doc/src/fix_propel_self.txt @@ -0,0 +1,50 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Section_commands.html#comm) + +:line + +fix active command :pre + +[Syntax:] + +fix ID group-ID magnitude + +ID, group-ID are documented in "fix"_fix.html command :ulb,l +addforce = style name of this fix command :l +magnitude = magnitude of the active force :l +:ule + +[Examples:] + +fix active_group all active 1.0 +fix constant_velocity all viscous 1.0 + +[Description:] + +Adds a force of a constant magnitude to each atom in the group. The direction +of the force is along the axis obtained by rotating the z-axis along the atom's +quaternion. In other words, the force is along the z-axis in the atom's body +frame. + +:line + +[Restart, fix_modify, output, run start/stop, minimize info:] + +No information about this fix is written to "binary restart +files"_restart.html. + +This fix is not imposed during minimization. + +[Restrictions:] + +This fix makes use of per-atom quaternions to take into +account the fact that the orientation can rotate and hence the direction +of the active force can change. Therefore, this fix only works with +ellipsoidal particles. + +[Related commands:] + +"fix setforce"_fix_setforce.html, "fix addforce"_fix_addforce.html diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp new file mode 100644 index 0000000000..623c82185d --- /dev/null +++ b/src/USER-MISC/fix_propel_self.cpp @@ -0,0 +1,147 @@ +/* ---------------------------------------------------------------------- + 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. + ------------------------------------------------------------------------- */ + +/* ----------------------------------------------------------------------- + Contributed by Stefan Paquay @ Brandeis University + + Thanks to Liesbeth Janssen @ Eindhoven University for useful discussions! + ----------------------------------------------------------------------- */ + + +#include +#include + +#include "fix_propel_self.h" + +#include "atom.h" +#include "atom_vec_ellipsoid.h" +#include "citeme.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "group.h" +#include "math.h" +#include "math_const.h" +#include "math_extra.h" +#include "math_vector.h" +#include "modify.h" +#include "random_mars.h" +#include "respa.h" +#include "update.h" + + +using namespace LAMMPS_NS; +using namespace FixConst; +using namespace MathConst; + + +static constexpr const bool debug_out = false; + + +FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) + : Fix(lmp, narg, argv) +{ + // if( lmp->citeme) lmp->citeme->add(cite_fix_active); + if( narg < 4 ) error->all(FLERR, "Illegal fix propel/self command"); + + AtomVecEllipsoid *av = static_cast(atom->avec); + if (!av) error->all(FLERR, "FixPropelSelf requires atom_style ellipsoid"); + + if( debug_out && comm->me == 0 ){ + fprintf(screen, "This is fix active, narg is %d\n", narg ); + fprintf(screen, "args:"); + for( int i = 0; i < narg; ++i ){ + fprintf(screen, " %s", argv[i]); + } + fprintf(screen, "\n"); + } + + // args: fix ID all active magnitude prop1 prop2 prop3 + // Optional args are + magnitude = force->numeric( FLERR, argv[3] ); +} + + +FixPropelSelf::~FixPropelSelf() +{} + + +int FixPropelSelf::setmask() +{ + int mask = 0; + mask |= POST_FORCE; + + return mask; +} + + +double FixPropelSelf::memory_usage() +{ + double bytes = 0.0; + return bytes; +} + + + +void FixPropelSelf::post_force(int /* vflag */ ) +{ + // Then do the rest: + double **f = atom->f; + + AtomVecEllipsoid *av = static_cast(atom->avec); + + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + AtomVecEllipsoid::Bonus *bonus = av->bonus; + // Add the active force to the atom force: + for( int i = 0; i < nlocal; ++i ){ + if( mask[i] & groupbit ){ + double f_act[3] = { 0.0, 0.0, 1.0 }; + double f_rot[3]; + + int* ellipsoid = atom->ellipsoid; + double *quat = bonus[ellipsoid[i]].quat; + tagint *tag = atom->tag; + + double Q[3][3]; + MathExtra::quat_to_mat( quat, Q ); + MathExtra::matvec( Q, f_act, f_rot ); + + if (debug_out && comm->me == 0) { + // Magical reference particle: + if (tag[i] == 12) { + fprintf(screen, "rotation quaternion: (%f %f %f %f)\n", + quat[0], quat[1], quat[2], quat[3]); + fprintf(screen, "rotation matrix: / %f %f %f \\\n", + Q[0][0] ,Q[0][1], Q[0][2]); + fprintf(screen, " | %f %f %f |\n", + Q[1][0] ,Q[1][1], Q[1][2]); + fprintf(screen, " \\ %f %f %f /\n", + Q[2][0] ,Q[2][1], Q[2][2]); + + fprintf(screen, "Active force on atom %d: (%f %f %f)\n", + tag[i], f_rot[0], f_rot[1], f_rot[2]); + fprintf(screen, " Total force before: (%f %f %f)\n", + f[i][0], f[i][1], f[i][2]); + } + } + + f[i][0] += magnitude * f_rot[0]; + f[i][1] += magnitude * f_rot[1]; + f[i][2] += magnitude * f_rot[2]; + + } + } +} diff --git a/src/USER-MISC/fix_propel_self.h b/src/USER-MISC/fix_propel_self.h new file mode 100644 index 0000000000..d6f114527a --- /dev/null +++ b/src/USER-MISC/fix_propel_self.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- ---------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS + +FixStyle(propel/self,FixPropelSelf) + +#else + +#ifndef LMP_FIX_PROPEL_SELF_H +#define LMP_FIX_PROPEL_SELF_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixPropelSelf : public Fix { + public: + FixPropelSelf(class LAMMPS *, int, char **); + virtual ~FixPropelSelf(); + virtual int setmask(); + virtual void post_force(int); + // virtual void post_force_respa(int, int, int); + + double memory_usage(); + +protected: + double magnitude; + int thermostat_orient; +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Illegal ... command + +Self-explanatory. Check the input script syntax and compare to the +documentation for the command. You can use -echo screen as a +command-line option when running LAMMPS to see the offending line. + +*/ From 942812a6540b9dee792ee88ee7948c160ee161af Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Tue, 9 Jul 2019 10:29:42 -0400 Subject: [PATCH 31/54] Commit before changing branches. --- src/USER-MISC/fix_propel_self.cpp | 2 +- src/fix_wall_region.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index 623c82185d..1786281928 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -66,7 +66,7 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) fprintf(screen, "\n"); } - // args: fix ID all active magnitude prop1 prop2 prop3 + // args: fix ID all propel/self magnitude prop1 prop2 prop3 // Optional args are magnitude = force->numeric( FLERR, argv[3] ); } diff --git a/src/fix_wall_region.cpp b/src/fix_wall_region.cpp index f63a3774cc..70bde90d2b 100644 --- a/src/fix_wall_region.cpp +++ b/src/fix_wall_region.cpp @@ -1,4 +1,4 @@ - seems------------------------------------------------------------------- +/* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov From 8c7890b6dfa72f1f27f4cbbd98fe9227d70123d3 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Tue, 9 Jul 2019 15:07:04 -0400 Subject: [PATCH 33/54] Added two modes, one via velocity and one via quaternion. --- src/USER-MISC/fix_propel_self.cpp | 126 +++++++++++++++++++++++++----- src/USER-MISC/fix_propel_self.h | 15 +++- 2 files changed, 120 insertions(+), 21 deletions(-) diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index 1786281928..13c5e0ef90 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -51,24 +51,34 @@ static constexpr const bool debug_out = false; FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) : Fix(lmp, narg, argv) { - // if( lmp->citeme) lmp->citeme->add(cite_fix_active); - if( narg < 4 ) error->all(FLERR, "Illegal fix propel/self command"); - - AtomVecEllipsoid *av = static_cast(atom->avec); - if (!av) error->all(FLERR, "FixPropelSelf requires atom_style ellipsoid"); + if( narg < 5 ) error->all(FLERR, "Illegal fix propel/self command"); - if( debug_out && comm->me == 0 ){ - fprintf(screen, "This is fix active, narg is %d\n", narg ); - fprintf(screen, "args:"); - for( int i = 0; i < narg; ++i ){ - fprintf(screen, " %s", argv[i]); + // The fix is to support the following cases: + // 1. Simple atoms, in which case the force points along the velocity + // 2. Cases where the atoms have an internal ellipsoid. Currently those + // styles are only body and aspherical particles. + // The first argument (mode) is used to differentiate between these. + + // args: fix ID all propel/self mode magnitude + // Optional args are + const char *mode_str = argv[3]; + if (strncmp(mode_str, "velocity", 8) == 0) { + mode = VELOCITY; + } else if (strncmp(mode_str, "quaternion", 10) == 0) { + // This mode should only be supported if the atom style has + // a quaternion (and if all atoms in the group have it) + if (verify_atoms_have_quaternion()) { + error->all(FLERR, "All atoms need a quaternion"); } - fprintf(screen, "\n"); + mode = QUATERNION; + } else { + char msg[2048]; + sprintf(msg, "Illegal mode \"%s\" for fix propel/self", mode_str); + error->all(FLERR, msg); } - // args: fix ID all propel/self magnitude prop1 prop2 prop3 - // Optional args are - magnitude = force->numeric( FLERR, argv[3] ); + + magnitude = force->numeric( FLERR, argv[4] ); } @@ -92,17 +102,29 @@ double FixPropelSelf::memory_usage() } - -void FixPropelSelf::post_force(int /* vflag */ ) +void FixPropelSelf::post_force(int vflag ) { - // Then do the rest: - double **f = atom->f; + switch(mode) { + case QUATERNION: + post_force_quaternion(vflag); + break; + case VELOCITY: + post_force_velocity(vflag); + break; + default: + error->all(FLERR, "reached statement that should be unreachable"); + } +} + + +void FixPropelSelf::post_force_quaternion(int /* vflag */ ) +{ + double **f = atom->f; AtomVecEllipsoid *av = static_cast(atom->avec); int *mask = atom->mask; int nlocal = atom->nlocal; - if (igroup == atom->firstgroup) nlocal = atom->nfirst; AtomVecEllipsoid::Bonus *bonus = av->bonus; // Add the active force to the atom force: @@ -141,7 +163,71 @@ void FixPropelSelf::post_force(int /* vflag */ ) f[i][0] += magnitude * f_rot[0]; f[i][1] += magnitude * f_rot[1]; f[i][2] += magnitude * f_rot[2]; - } } } + + + +void FixPropelSelf::post_force_velocity(int /*vflag*/ ) +{ + double **f = atom->f; + double **v = atom->v; + int *mask = atom->mask; + int nlocal = atom->nlocal; + tagint *tag = atom->tag; + + // Add the active force to the atom force: + for( int i = 0; i < nlocal; ++i ){ + if( mask[i] & groupbit ){ + const double *vi = v[i]; + double f_act[3] = { vi[0], vi[1], vi[2] }; + double nv2 = vi[0]*vi[0] + vi[1]*vi[1] + vi[2]*vi[2]; + double fnorm = magnitude / sqrt(nv2); + + if (debug_out && comm->me == 0) { + // Magical reference particle: + if (tag[i] == 12) { + fprintf(screen, "Active force on atom %d: (%f %f %f)\n", + tag[i], f_act[0], f_act[1], f_act[2]); + fprintf(screen, " Total force before: (%f %f %f)\n", + f[i][0], f[i][1], f[i][2]); + } + } + + f[i][0] += fnorm * f_act[0]; + f[i][1] += fnorm * f_act[1]; + f[i][2] += fnorm * f_act[2]; + } + } +} + + +int FixPropelSelf::verify_atoms_have_quaternion() +{ + int ellipsoid_flag = atom->ellipsoid_flag; + int body_flag = atom->body_flag; + int *mask = atom->mask; + if (! (ellipsoid_flag || body_flag) ){ + error->all(FLERR, "mode quaternion requires body or ellipsoid atoms"); + } + + // Make sure all atoms have ellipsoid or body set: + for (int i = 0; i < atom->nlocal; ++i) { + if (mask[i] & groupbit) { + if (ellipsoid_flag && atom->ellipsoid[i] < 0) { + error->all(FLERR, "Got atom without ellipsoid set"); + // Kind-of pointless but silences some compiler warnings: + return 1; + } + if (body_flag && atom->body[i] < 0) { + error->all(FLERR, "Got atom without body set"); + // Kind-of pointless but silences some compiler warnings: + return 1; + } + } + } + + return 0; +} + diff --git a/src/USER-MISC/fix_propel_self.h b/src/USER-MISC/fix_propel_self.h index d6f114527a..45b2afffc3 100644 --- a/src/USER-MISC/fix_propel_self.h +++ b/src/USER-MISC/fix_propel_self.h @@ -26,6 +26,12 @@ namespace LAMMPS_NS { class FixPropelSelf : public Fix { public: + + enum operation_modes { + VELOCITY = 0, + QUATERNION = 1 + }; + FixPropelSelf(class LAMMPS *, int, char **); virtual ~FixPropelSelf(); virtual int setmask(); @@ -34,9 +40,16 @@ class FixPropelSelf : public Fix { double memory_usage(); -protected: +private: double magnitude; int thermostat_orient; + int mode; + + int verify_atoms_have_quaternion(); + void post_force_velocity(int); + void post_force_quaternion(int); + + }; } From 074dfd8651177d476b99492bbcb59ef092db8c90 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 29 Aug 2019 09:00:36 -0400 Subject: [PATCH 34/54] Commit before merging latest changes in master. --- doc/src/fix_active.txt | 50 --------------- doc/src/fix_propel_self.txt | 21 ++++--- examples/USER/misc/active/active_langevin.in | 61 ------------------ examples/USER/misc/active/active_viscous.in | 66 -------------------- src/USER-MISC/fix_propel_self.cpp | 7 +-- 5 files changed, 16 insertions(+), 189 deletions(-) delete mode 100644 doc/src/fix_active.txt delete mode 100644 examples/USER/misc/active/active_langevin.in delete mode 100644 examples/USER/misc/active/active_viscous.in diff --git a/doc/src/fix_active.txt b/doc/src/fix_active.txt deleted file mode 100644 index 3bc6c15326..0000000000 --- a/doc/src/fix_active.txt +++ /dev/null @@ -1,50 +0,0 @@ -"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c - -:link(lws,http://lammps.sandia.gov) -:link(ld,Manual.html) -:link(lc,Section_commands.html#comm) - -:line - -fix active command :pre - -[Syntax:] - -fix ID group-ID magnitude - -ID, group-ID are documented in "fix"_fix.html command :ulb,l -addforce = style name of this fix command :l -magnitude = magnitude of the active force :l -:ule - -[Examples:] - -fix active_group all active 1.0 -fix constant_velocity all viscous 1.0 - -[Description:] - -Adds a force of a constant magnitude to each atom in the group. The direction -of the force is along the axis obtained by rotating the z-axis along the atom's -quaternion. In other words, the force is along the z-axis in the atom's body -frame. - -:line - -[Restart, fix_modify, output, run start/stop, minimize info:] - -No information about this fix is written to "binary restart -files"_restart.html. - -This fix is not imposed during minimization. - -[Restrictions:] - -This fix makes use of per-atom quaternions to take into -account the fact that the orientation can rotate and hence the direction -of the active force can change. Therefore, this fix only works with -ellipsoidal particles. - -[Related commands:] - -"fix setforce"_fix_setforce.html, "fix addforce"_fix_addforce.html diff --git a/doc/src/fix_propel_self.txt b/doc/src/fix_propel_self.txt index 3bc6c15326..b65b4780e9 100644 --- a/doc/src/fix_propel_self.txt +++ b/doc/src/fix_propel_self.txt @@ -6,28 +6,33 @@ :line -fix active command :pre +fix propel/self command :pre [Syntax:] -fix ID group-ID magnitude +fix ID group-ID propel/self mode magnitude ID, group-ID are documented in "fix"_fix.html command :ulb,l -addforce = style name of this fix command :l +propel/self = style name of this fix command :l +mode = velocity or quaternion :l magnitude = magnitude of the active force :l :ule [Examples:] -fix active_group all active 1.0 +fix active_group all propel/self velocity 1.0 fix constant_velocity all viscous 1.0 [Description:] -Adds a force of a constant magnitude to each atom in the group. The direction -of the force is along the axis obtained by rotating the z-axis along the atom's -quaternion. In other words, the force is along the z-axis in the atom's body -frame. +Adds a force of a constant magnitude to each atom in the group. The nature in +which the force is added depends on the mode. +For mode = velocity, the active force acts along the velocity vector of each +atom. +For mode = quaternion the force is along the axis obtained by rotating the +z-axis along the atom's quaternion. In other words, the force is along the +z-axis in the atom's body frame. This mode requires all atoms in the group +to have a quaternion, so atom_style should either be ellipsoid or body. :line diff --git a/examples/USER/misc/active/active_langevin.in b/examples/USER/misc/active/active_langevin.in deleted file mode 100644 index 3854729fc5..0000000000 --- a/examples/USER/misc/active/active_langevin.in +++ /dev/null @@ -1,61 +0,0 @@ -# Uses a combnation of fix active and fix langevin to achieve -# self-propelled particles. - -dimension 3 -boundary p p p -units lj - -# Fix active uses quaternions to orient the active force so you need -# ellipsoidal particles, even if you do not care about asymmetric shape -atom_style ellipsoid - - -# Set up box and particles: -variable L equal 10 -region total block -$L $L -$L $L -$L $L -create_box 1 total -variable N equal 1000 -create_atoms 1 random $N 123456 total - -# Set particle shape: -set group all shape 1 1 1 -set group all quat/random 18238 -variable V equal "4.0*PI" -variable rho equal "1.0 / v_V" -# Density so that mass = 1 -set group all density ${rho} - -# Simple repulsive LJ -pair_style lj/cut 1.1225 -pair_coeff * * 1.0 1.0 -pair_modify shift yes - -# Remove initial overlap: -minimize 1e-4 1e-6 1000 10000 -reset_timestep 0 - -# Fixes for time integration -fix step all nve/asphere -fix active all active 1.0 -fix temp all langevin 1.0 1.0 1.0 12341 angmom 3.333333333333 - -variable DUMP_OUT string "active_langevin.dump" -variable MSD_OUT string "active_langevin_msd.dat" - -# Compute temperature and orientation -compute T all temp/asphere -compute quat all property/atom quatw quati quatj quatk -compute msd all msd -compute vacf all vacf - -# Some output: -thermo_style custom time step pe ke etotal temp c_T -thermo 1000 - -dump traj all custom 100 ${DUMP_OUT} id type x y z & - c_quat[1] c_quat[2] c_quat[3] c_quat[4] - -fix msd all ave/time 1 10 50 c_msd[4] c_vacf[1] c_vacf[2] c_vacf[3] c_vacf[4] file ${MSD_OUT} - -timestep 0.001 -run 10000 diff --git a/examples/USER/misc/active/active_viscous.in b/examples/USER/misc/active/active_viscous.in deleted file mode 100644 index 62fdaa7751..0000000000 --- a/examples/USER/misc/active/active_viscous.in +++ /dev/null @@ -1,66 +0,0 @@ -# Uses a combnation of fix active and fix langevin to achieve -# self-propelled particles. - -dimension 3 -boundary p p p -units lj - -# Fix active uses quaternions to orient the active force so you need -# ellipsoidal particles, even if you do not care about asymmetric shape -atom_style ellipsoid - - -# Set up box and particles: -variable L equal 10 -region total block -$L $L -$L $L -$L $L -create_box 1 total -variable N equal 1000 -create_atoms 1 random $N 123456 total - -# Set particle shape: -set group all shape 1 1 1 -set group all quat/random 18238 -variable V equal "4.0*PI" -variable rho equal "1.0 / v_V" -# Density so that mass = 1 -set group all density ${rho} - -# Simple repulsive LJ -pair_style lj/cut 1.1225 -pair_coeff * * 1.0 1.0 -pair_modify shift yes - -# Remove initial overlap: -minimize 1e-4 1e-6 1000 10000 -reset_timestep 0 - -# Fixes for time integration -fix step all nve/asphere - -# Should lead to constant velocity of 10 per particle -fix active all active 1.0 -fix visc all viscous 0.1 - -# Initial velocities: -velocity all create 1.0 1234 - -variable DUMP_OUT string "active_viscous.dump" -variable MSD_OUT string "active_viscous_msd.dat" - -# Compute temperature and orientation -compute T all temp/asphere -compute quat all property/atom quatw quati quatj quatk -compute msd all msd -compute vacf all vacf - -# Some output: -thermo_style custom time step pe ke etotal temp c_T -thermo 1000 - -dump traj all custom 100 ${DUMP_OUT} id type x y z & - c_quat[1] c_quat[2] c_quat[3] c_quat[4] - -fix msd all ave/time 1 10 50 c_msd[4] c_vacf[1] c_vacf[2] c_vacf[3] c_vacf[4] file ${MSD_OUT} - -timestep 0.001 -run 100000 diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index 13c5e0ef90..8f98de518b 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -58,7 +58,7 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) // 2. Cases where the atoms have an internal ellipsoid. Currently those // styles are only body and aspherical particles. // The first argument (mode) is used to differentiate between these. - + // args: fix ID all propel/self mode magnitude // Optional args are const char *mode_str = argv[3]; @@ -77,7 +77,6 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) error->all(FLERR, msg); } - magnitude = force->numeric( FLERR, argv[4] ); } @@ -217,12 +216,12 @@ int FixPropelSelf::verify_atoms_have_quaternion() if (mask[i] & groupbit) { if (ellipsoid_flag && atom->ellipsoid[i] < 0) { error->all(FLERR, "Got atom without ellipsoid set"); - // Kind-of pointless but silences some compiler warnings: + // Kind-of pointless return but silences compiler warnings: return 1; } if (body_flag && atom->body[i] < 0) { error->all(FLERR, "Got atom without body set"); - // Kind-of pointless but silences some compiler warnings: + // Kind-of pointless return silences compiler warnings: return 1; } } From 3144b91fb3f07b520f77b298db1e2065b16b81f5 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 29 Aug 2019 09:41:50 -0400 Subject: [PATCH 35/54] Some code clean-up, added safety check in post_force_velocity. --- .../2d_velocity/in.2d_langevin | 37 +++++++++++++ .../fix_propel_self/2d_velocity/in.2d_viscous | 37 +++++++++++++ .../3d_quaternion/in.3d_quaternion | 40 ++++++++++++++ src/USER-MISC/fix_propel_self.cpp | 54 ++++++++++--------- 4 files changed, 144 insertions(+), 24 deletions(-) create mode 100644 examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin create mode 100644 examples/USER/misc/fix_propel_self/2d_velocity/in.2d_viscous create mode 100644 examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion diff --git a/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin new file mode 100644 index 0000000000..b7a1b93745 --- /dev/null +++ b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin @@ -0,0 +1,37 @@ +dimension 2 +boundary p p p + +variable L equal 20 +region total block -$L $L -$L $L -0.5 0.5 +lattice hex 0.3 +create_box 2 total +create_atoms 1 box + +# Set random fraction to passive: +set type 1 type/fraction 2 0.5 1337 + +# Purely repulsive particles: +variable rc equal "2^(1.0/6.0)" +pair_style lj/cut ${rc} +pair_coeff * * 1.0 1.0 +pair_modify shift yes + +mass * 1.0 + +fix step all nve +fix temp all langevin 1.0 1.0 1.0 13 +fix twod all enforce2d + +neighbor 0.6 bin + +dump traj all custom 250 2d_active.dump.bin id type x y z + +thermo_style custom time step pe ke etotal temp +thermo 1000 +run 25000 + +fix active all propel/self velocity 1.0 + +# With active force there is more motion so increase bin size: +neighbor 1.0 bin +run 25000 diff --git a/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_viscous b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_viscous new file mode 100644 index 0000000000..e6bb1169e0 --- /dev/null +++ b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_viscous @@ -0,0 +1,37 @@ +dimension 2 +boundary p p p + +variable L equal 20 +region total block -$L $L -$L $L -0.5 0.5 +lattice hex 0.3 +create_box 2 total +create_atoms 1 box + +# Set random fraction to passive: +set type 1 type/fraction 2 0.5 1337 + +# Purely repulsive particles: +variable rc equal "2^(1.0/6.0)" +pair_style lj/cut ${rc} +pair_coeff * * 1.0 1.0 +pair_modify shift yes + +mass * 1.0 + +fix step all nve +fix twod all enforce2d + +neighbor 0.6 bin + +dump traj all custom 250 2d_active.dump.bin id type x y z + +thermo_style custom time step pe ke etotal temp +thermo 1000 +run 25000 + +fix active all propel/self velocity 1.0 +fix fric all viscous 1.0 + +# With active force there is more motion so increase bin size: +neighbor 1.0 bin +run 25000 diff --git a/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion b/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion new file mode 100644 index 0000000000..b43d6304b3 --- /dev/null +++ b/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion @@ -0,0 +1,40 @@ +dimension 3 +boundary p p p + +atom_style ellipsoid +variable L equal 20 +region total block -$L $L -$L $L -$L $L +lattice sc 0.1 +create_box 2 total +create_atoms 1 box + +# Set random fraction to passive: +set type 1 type/fraction 2 0.5 1337 + +# Purely repulsive particles: +variable rc equal "2^(1.0/6.0)" +pair_style lj/cut ${rc} +pair_coeff * * 1.0 1.0 +pair_modify shift yes + +# mass * 1.0 +set type * density 1.0 +set type * shape 1.0 1.0 1.0 +set type * quat 0 0 1 0 + +fix step all nve +fix temp all langevin 1.0 1.0 1.0 13 + +neighbor 0.6 bin + +dump traj all custom 100 3d_active.dump.bin id type x y z fx fy fz + +thermo_style custom time step pe ke etotal temp +thermo 100 +run 5000 + +fix active all propel/self quaternion 1.0 + +# With active force there is more motion so increase bin size: +neighbor 1.0 bin +run 5000 diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index 8f98de518b..9cb5bb2207 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -103,16 +103,16 @@ double FixPropelSelf::memory_usage() void FixPropelSelf::post_force(int vflag ) { - switch(mode) { - case QUATERNION: - post_force_quaternion(vflag); - break; - case VELOCITY: - post_force_velocity(vflag); - break; - default: - error->all(FLERR, "reached statement that should be unreachable"); - } + switch(mode) { + case QUATERNION: + post_force_quaternion(vflag); + break; + case VELOCITY: + post_force_velocity(vflag); + break; + default: + error->all(FLERR, "reached statement that should be unreachable"); + } } @@ -179,10 +179,16 @@ void FixPropelSelf::post_force_velocity(int /*vflag*/ ) // Add the active force to the atom force: for( int i = 0; i < nlocal; ++i ){ if( mask[i] & groupbit ){ - const double *vi = v[i]; - double f_act[3] = { vi[0], vi[1], vi[2] }; - double nv2 = vi[0]*vi[0] + vi[1]*vi[1] + vi[2]*vi[2]; - double fnorm = magnitude / sqrt(nv2); + const double *vi = v[i]; + double f_act[3] = { vi[0], vi[1], vi[2] }; + double nv2 = vi[0]*vi[0] + vi[1]*vi[1] + vi[2]*vi[2]; + double fnorm = 0.0; + constexpr const double TOL = 1e-14; + if (nv2 > TOL) { + // Without this check you can run into numerical issues + // because fnorm will blow up. + fnorm = magnitude / sqrt(nv2); + } if (debug_out && comm->me == 0) { // Magical reference particle: @@ -214,16 +220,16 @@ int FixPropelSelf::verify_atoms_have_quaternion() // Make sure all atoms have ellipsoid or body set: for (int i = 0; i < atom->nlocal; ++i) { if (mask[i] & groupbit) { - if (ellipsoid_flag && atom->ellipsoid[i] < 0) { - error->all(FLERR, "Got atom without ellipsoid set"); - // Kind-of pointless return but silences compiler warnings: - return 1; - } - if (body_flag && atom->body[i] < 0) { - error->all(FLERR, "Got atom without body set"); - // Kind-of pointless return silences compiler warnings: - return 1; - } + if (ellipsoid_flag && atom->ellipsoid[i] < 0) { + error->all(FLERR, "Got atom without ellipsoid set"); + // Kind-of pointless return but silences compiler warnings: + return 1; + } + if (body_flag && atom->body[i] < 0) { + error->all(FLERR, "Got atom without body set"); + // Kind-of pointless return silences compiler warnings: + return 1; + } } } From 060c45d36e4da41f52d7bed7eae9df8c10d07e7d Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 29 Aug 2019 09:44:54 -0400 Subject: [PATCH 36/54] Updated docs --- doc/src/fix_propel_self.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/src/fix_propel_self.txt b/doc/src/fix_propel_self.txt index b65b4780e9..e3a686802e 100644 --- a/doc/src/fix_propel_self.txt +++ b/doc/src/fix_propel_self.txt @@ -21,7 +21,9 @@ magnitude = magnitude of the active force :l [Examples:] fix active_group all propel/self velocity 1.0 -fix constant_velocity all viscous 1.0 +fix constant_velocity all viscous 1.0 :pre + +fix active_group all propel/self quaternion 1.0 :pre [Description:] @@ -47,8 +49,8 @@ This fix is not imposed during minimization. This fix makes use of per-atom quaternions to take into account the fact that the orientation can rotate and hence the direction -of the active force can change. Therefore, this fix only works with -ellipsoidal particles. +of the active force can change. Therefore, this fix only works with atom_styles +that have a quaternion. [Related commands:] From f7bbc81d9b7c3959d572d4e0dfe0678ef47cbf9b Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 29 Aug 2019 09:55:22 -0400 Subject: [PATCH 37/54] Added angular momentum thermostatting to 3d quaternion example. --- .../USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion b/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion index b43d6304b3..152a06d82e 100644 --- a/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion +++ b/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion @@ -23,7 +23,7 @@ set type * shape 1.0 1.0 1.0 set type * quat 0 0 1 0 fix step all nve -fix temp all langevin 1.0 1.0 1.0 13 +fix temp all langevin 1.0 1.0 1.0 13 angmom yes neighbor 0.6 bin From 6240a7e278a743d8b7426ccaa82ba3fdb48c071e Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Thu, 29 Aug 2019 09:56:37 -0400 Subject: [PATCH 38/54] Fixed example 3d_quaternion --- .../USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion b/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion index 152a06d82e..11f2ea8a07 100644 --- a/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion +++ b/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion @@ -23,7 +23,7 @@ set type * shape 1.0 1.0 1.0 set type * quat 0 0 1 0 fix step all nve -fix temp all langevin 1.0 1.0 1.0 13 angmom yes +fix temp all langevin 1.0 1.0 1.0 13 angmom 3.333333333 neighbor 0.6 bin From 2eb3f4e169aa944a15ceda18d2347b5c4e0cecb5 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Wed, 11 Sep 2019 09:28:42 -0400 Subject: [PATCH 39/54] Updated documentation. --- doc/src/fix_propel_self.txt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/doc/src/fix_propel_self.txt b/doc/src/fix_propel_self.txt index e3a686802e..73c7837d33 100644 --- a/doc/src/fix_propel_self.txt +++ b/doc/src/fix_propel_self.txt @@ -30,7 +30,8 @@ fix active_group all propel/self quaternion 1.0 :pre Adds a force of a constant magnitude to each atom in the group. The nature in which the force is added depends on the mode. For mode = velocity, the active force acts along the velocity vector of each -atom. +atom. This can be interpreted as an overdamped form of the model used by +"(Szabo)"_#Szabo and "(Henkes)"_#Henkes. For mode = quaternion the force is along the axis obtained by rotating the z-axis along the atom's quaternion. In other words, the force is along the z-axis in the atom's body frame. This mode requires all atoms in the group @@ -55,3 +56,12 @@ that have a quaternion. [Related commands:] "fix setforce"_fix_setforce.html, "fix addforce"_fix_addforce.html + +:link(Szabo) +[(Szabo)] Szabo, B, Szollosi, G. J., Gonci, B., Juranyi, Zs., Selmeczi, D. and Viscek, T., +Phys. Rev. E, 74, 061908, 2006 + +:link(Henkes) +[(Henkes)] Henkes, S, Fily, Y., and Marchetti, M. C. +Phys. Rev. E, 84, 040301(R), 2011 + From 768fd8f7febd67223ee1fd14d2174d8315900ad8 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Wed, 11 Sep 2019 10:26:03 -0400 Subject: [PATCH 40/54] Added type support. --- src/USER-MISC/fix_propel_self.cpp | 69 ++++++++++++++++++++++++++++--- src/USER-MISC/fix_propel_self.h | 12 +++++- 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index 9cb5bb2207..f8c00e5ca8 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -49,7 +49,8 @@ static constexpr const bool debug_out = false; FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) - : Fix(lmp, narg, argv) + : Fix(lmp, narg, argv), magnitude(1.0), thermostat_orient(0), + mode(VELOCITY), n_types_filter(0), apply_to_type(NULL) { if( narg < 5 ) error->all(FLERR, "Illegal fix propel/self command"); @@ -78,6 +79,49 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) } magnitude = force->numeric( FLERR, argv[4] ); + + // Handle rest of args: + int iarg = 5; + while (iarg < narg) { + const char *arg = argv[iarg]; + if (strncmp(arg, "types", 5) == 0) { + // In this case we need to allocate the type list. + // First find the largest given type: + int max_type_in_list = 0; + while (!isalpha(arg[iarg + n_types_filter][0])) { + int curr_type = force->numeric(FLERR, arg[iarg + n_types_filter]); + if (curr_type > max_type_in_list) max_type_in_list = curr_type; + ++n_types_filter; + } + if (n_types_filter == 0) { + error->all(FLERR, "\"types\" option requires at least one type"); + } + + // sanity check: + if (max_type_in_list < n_types_filter) { + error->warning(FLERR, "Found duplicate type in \"types\" option"); + } + + apply_to_type = new int[max_type_in_list+1]; + if (!apply_to_type) error->all(FLERR, "Failed to allocate type storage!"); + + for (int i = 0; i < max_type_in_list+1; ++i) { + apply_to_type[i] = 0; + } + + for (int i = 0; i < n_types_filter; ++i) { + int curr_type = force->numeric(FLERR, arg[iarg + i]); + apply_to_type[curr_type] = 1; + } + // Done handling types argument. + } else { + char msg[2048]; + sprintf(msg, "Illegal fix propel/self command: " + "Unrecognized argument %s", arg); + error->all(FLERR, msg); + } + } + } @@ -96,7 +140,10 @@ int FixPropelSelf::setmask() double FixPropelSelf::memory_usage() { - double bytes = 0.0; + // magnitude + thermostat_orient + mode + n_types_filter + apply_to_type + double bytes = sizeof(double) + 3*sizeof(int) + sizeof(int*); + bytes += sizeof(int)*n_types_filter; + return bytes; } @@ -105,11 +152,12 @@ void FixPropelSelf::post_force(int vflag ) { switch(mode) { case QUATERNION: - post_force_quaternion(vflag); + if (n_types_filter) post_force_quaternion<1>(vflag); + else post_force_quaternion<0>(vflag); break; case VELOCITY: - post_force_velocity(vflag); - break; + if (n_types_filter) post_force_velocity<1>(vflag); + else post_force_velocity<0>(vflag); default: error->all(FLERR, "reached statement that should be unreachable"); } @@ -117,6 +165,7 @@ void FixPropelSelf::post_force(int vflag ) +template void FixPropelSelf::post_force_quaternion(int /* vflag */ ) { double **f = atom->f; @@ -129,6 +178,10 @@ void FixPropelSelf::post_force_quaternion(int /* vflag */ ) // Add the active force to the atom force: for( int i = 0; i < nlocal; ++i ){ if( mask[i] & groupbit ){ + if (filter_by_type && !apply_to_type[type[i]]) { + continue; + } + double f_act[3] = { 0.0, 0.0, 1.0 }; double f_rot[3]; @@ -167,7 +220,7 @@ void FixPropelSelf::post_force_quaternion(int /* vflag */ ) } - +template void FixPropelSelf::post_force_velocity(int /*vflag*/ ) { double **f = atom->f; @@ -179,6 +232,10 @@ void FixPropelSelf::post_force_velocity(int /*vflag*/ ) // Add the active force to the atom force: for( int i = 0; i < nlocal; ++i ){ if( mask[i] & groupbit ){ + if (filter_by_type && !apply_to_type[type[i]]) { + continue; + } + const double *vi = v[i]; double f_act[3] = { vi[0], vi[1], vi[2] }; double nv2 = vi[0]*vi[0] + vi[1]*vi[1] + vi[2]*vi[2]; diff --git a/src/USER-MISC/fix_propel_self.h b/src/USER-MISC/fix_propel_self.h index 45b2afffc3..2b44b8e1ce 100644 --- a/src/USER-MISC/fix_propel_self.h +++ b/src/USER-MISC/fix_propel_self.h @@ -45,9 +45,17 @@ private: int thermostat_orient; int mode; + + // If 0, apply fix to everything in group. If > 0, apply only to those + // types i for which i <= n_types_filter _and_ apply_to_type[i] == 1: + int n_types_filter; + int *apply_to_type; //< Specifies, per type, if the fix applies to it or not. + + int verify_atoms_have_quaternion(); - void post_force_velocity(int); - void post_force_quaternion(int); + + template void post_force_velocity(int); + template void post_force_quaternion(int); }; From 60c0270375bed62ce39e1c7b733cacffdb96dc8b Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Wed, 11 Sep 2019 10:58:45 -0400 Subject: [PATCH 41/54] Added option to impose fix propel/self only to specific types --- .../fix_propel_self/2d_velocity/in.2d_langevin | 17 +++++++++++++++++ src/USER-MISC/fix_propel_self.cpp | 16 +++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin index b7a1b93745..563c0bd969 100644 --- a/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin +++ b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin @@ -30,8 +30,25 @@ thermo_style custom time step pe ke etotal temp thermo 1000 run 25000 +group one type 1 +group two type 2 + +compute ke1 one ke +compute ke2 two ke + +thermo_style custom time step pe ke etotal temp c_ke1 c_ke2 + fix active all propel/self velocity 1.0 # With active force there is more motion so increase bin size: neighbor 1.0 bin run 25000 + +# Only make type 1 active: +fix active all propel/self velocity 1.0 types 1 + +# With active force there is more motion so increase bin size: +neighbor 1.0 bin +run 25000 + + diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index f8c00e5ca8..56f5e44869 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -88,8 +88,10 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) // In this case we need to allocate the type list. // First find the largest given type: int max_type_in_list = 0; - while (!isalpha(arg[iarg + n_types_filter][0])) { - int curr_type = force->numeric(FLERR, arg[iarg + n_types_filter]); + ++iarg; + while ( (iarg + n_types_filter < narg) && + (!isalpha(argv[iarg + n_types_filter][0]))) { + int curr_type = force->numeric(FLERR, argv[iarg + n_types_filter]); if (curr_type > max_type_in_list) max_type_in_list = curr_type; ++n_types_filter; } @@ -110,10 +112,11 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) } for (int i = 0; i < n_types_filter; ++i) { - int curr_type = force->numeric(FLERR, arg[iarg + i]); + int curr_type = force->numeric(FLERR, argv[iarg + i]); apply_to_type[curr_type] = 1; } // Done handling types argument. + iarg += n_types_filter; // -1 because we incremented by 1 previously. } else { char msg[2048]; sprintf(msg, "Illegal fix propel/self command: " @@ -158,6 +161,7 @@ void FixPropelSelf::post_force(int vflag ) case VELOCITY: if (n_types_filter) post_force_velocity<1>(vflag); else post_force_velocity<0>(vflag); + break; default: error->all(FLERR, "reached statement that should be unreachable"); } @@ -173,7 +177,9 @@ void FixPropelSelf::post_force_quaternion(int /* vflag */ ) int *mask = atom->mask; int nlocal = atom->nlocal; - + int *type = atom->type; + int* ellipsoid = atom->ellipsoid; + AtomVecEllipsoid::Bonus *bonus = av->bonus; // Add the active force to the atom force: for( int i = 0; i < nlocal; ++i ){ @@ -185,7 +191,6 @@ void FixPropelSelf::post_force_quaternion(int /* vflag */ ) double f_act[3] = { 0.0, 0.0, 1.0 }; double f_rot[3]; - int* ellipsoid = atom->ellipsoid; double *quat = bonus[ellipsoid[i]].quat; tagint *tag = atom->tag; @@ -228,6 +233,7 @@ void FixPropelSelf::post_force_velocity(int /*vflag*/ ) int *mask = atom->mask; int nlocal = atom->nlocal; tagint *tag = atom->tag; + int *type = atom->type; // Add the active force to the atom force: for( int i = 0; i < nlocal; ++i ){ From 95784f70661415c4cacf88d9cb894d7dd59b9748 Mon Sep 17 00:00:00 2001 From: Stefan Paquay Date: Wed, 11 Sep 2019 11:05:04 -0400 Subject: [PATCH 42/54] Updated documentation regarding types keyword. --- doc/src/fix_propel_self.txt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/src/fix_propel_self.txt b/doc/src/fix_propel_self.txt index 73c7837d33..7c3dfd3f45 100644 --- a/doc/src/fix_propel_self.txt +++ b/doc/src/fix_propel_self.txt @@ -10,12 +10,16 @@ fix propel/self command :pre [Syntax:] -fix ID group-ID propel/self mode magnitude +fix ID group-ID propel/self mode magnitude keyword values ... ID, group-ID are documented in "fix"_fix.html command :ulb,l propel/self = style name of this fix command :l mode = velocity or quaternion :l magnitude = magnitude of the active force :l +one or more keyword/value pairs may be appended to args :l +keyword = {types} :l + {types} values = one or more atom types + :ule [Examples:] @@ -25,6 +29,9 @@ fix constant_velocity all viscous 1.0 :pre fix active_group all propel/self quaternion 1.0 :pre +fix active all propel/self quaternion 1.0 types 1 2 4 :pre + + [Description:] Adds a force of a constant magnitude to each atom in the group. The nature in @@ -37,6 +44,10 @@ z-axis along the atom's quaternion. In other words, the force is along the z-axis in the atom's body frame. This mode requires all atoms in the group to have a quaternion, so atom_style should either be ellipsoid or body. +By default, this fix is applied to all atoms in the group. You can override this +behavior by specifying the atom types the fix should work on through the {types} +keyword. + :line [Restart, fix_modify, output, run start/stop, minimize info:] @@ -65,3 +76,5 @@ Phys. Rev. E, 74, 061908, 2006 [(Henkes)] Henkes, S, Fily, Y., and Marchetti, M. C. Phys. Rev. E, 84, 040301(R), 2011 + +[Default:] types From 7b977856b944460380561908dc7bacde28636e4a Mon Sep 17 00:00:00 2001 From: Pierre de Buyl Date: Tue, 17 Dec 2019 11:54:30 +0100 Subject: [PATCH 43/54] Update documentation of fix propel/self MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Remove reference to velocity alignment model. 2. Use reference to velocity-dependent friction for mode velocity 3. Add references to Fily & Marchetti and Bialké, Speck & Löwen for the quaternion mode. --- doc/src/fix_propel_self.txt | 42 ++++++++++++++++++++++--------------- doc/txt/fix.txt | 1 + 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/doc/src/fix_propel_self.txt b/doc/src/fix_propel_self.txt index 7c3dfd3f45..3e351ba56a 100644 --- a/doc/src/fix_propel_self.txt +++ b/doc/src/fix_propel_self.txt @@ -6,7 +6,7 @@ :line -fix propel/self command :pre +fix propel/self command :h3 [Syntax:] @@ -36,13 +36,16 @@ fix active all propel/self quaternion 1.0 types 1 2 4 :pre Adds a force of a constant magnitude to each atom in the group. The nature in which the force is added depends on the mode. -For mode = velocity, the active force acts along the velocity vector of each -atom. This can be interpreted as an overdamped form of the model used by -"(Szabo)"_#Szabo and "(Henkes)"_#Henkes. -For mode = quaternion the force is along the axis obtained by rotating the -z-axis along the atom's quaternion. In other words, the force is along the -z-axis in the atom's body frame. This mode requires all atoms in the group -to have a quaternion, so atom_style should either be ellipsoid or body. + +For mode = velocity, the active force acts along the velocity vector of each atom. This can +be interpreted as a velocity-dependent friction, such as proposed by "(Erdmann)"_#Erdmann. + +For mode = quaternion the force is along the axis obtained by rotating the z-axis along the +atom's quaternion. In other words, the force is along the z-axis in the atom's body +frame. This mode requires all atoms in the group to have a quaternion, so atom_style should +either be ellipsoid or body. In combination with Langevin thermostat for translation and +rotation in the overdamped regime, the quaternion mode corresponds to the active Brownian +particle model introduced by "(Henkes)"_#Henkes, "(Bialke)"_#Bialke and "(Fily)"_#Fily. By default, this fix is applied to all atoms in the group. You can override this behavior by specifying the atom types the fix should work on through the {types} @@ -59,22 +62,27 @@ This fix is not imposed during minimization. [Restrictions:] -This fix makes use of per-atom quaternions to take into -account the fact that the orientation can rotate and hence the direction -of the active force can change. Therefore, this fix only works with atom_styles -that have a quaternion. +In quaternion mode, this fix makes use of per-atom quaternions to take into account the fact +that the orientation can rotate and hence the direction of the active force can +change. Therefore, the quaternion mode of this fix only works with atom_styles that have a +quaternion. [Related commands:] "fix setforce"_fix_setforce.html, "fix addforce"_fix_addforce.html -:link(Szabo) -[(Szabo)] Szabo, B, Szollosi, G. J., Gonci, B., Juranyi, Zs., Selmeczi, D. and Viscek, T., -Phys. Rev. E, 74, 061908, 2006 +:link(Erdmann) +[(Erdmann)] U. Erdmanna , W. Ebeling, L. Schimansky-Geier, and F. Schweitzer, +Eur. Phys. J. B 15, 105-113, 2000. :link(Henkes) -[(Henkes)] Henkes, S, Fily, Y., and Marchetti, M. C. -Phys. Rev. E, 84, 040301(R), 2011 +[(Henkes)] Henkes, S, Fily, Y., and Marchetti, M. C. Phys. Rev. E, 84, 040301(R), 2011 + +:link(Bialke) +[(Bialke)] J. Bialké, T. Speck, and H Löwen, Phys. Rev. Lett. 108, 168301, 2012. + +:link(Fily) +[(Fily)] Y. Fily and M.C. Marchetti, Phys. Rev. Lett. 108, 235702, 2012. [Default:] types diff --git a/doc/txt/fix.txt b/doc/txt/fix.txt index fd281bce83..c272bbb397 100644 --- a/doc/txt/fix.txt +++ b/doc/txt/fix.txt @@ -296,6 +296,7 @@ accelerated styles exist. "precession/spin"_fix_precession_spin.html - "press/berendsen"_fix_press_berendsen.html - pressure control by Berendsen barostat "print"_fix_print.html - print text and variables during a simulation +"propel/self"_fix_propel_self.html - add self-propelling force "property/atom"_fix_property_atom.html - add customized per-atom values "python/invoke"_fix_python_invoke.html - call a Python function during a simulation "python/move"_fix_python_move.html - call a Python function during a simulation run From fe4f7899d2072fcd0ad4bd5f453c1f432cd4d872 Mon Sep 17 00:00:00 2001 From: Pierre de Buyl Date: Thu, 19 Dec 2019 21:34:49 +0100 Subject: [PATCH 44/54] Use x-axis along the particle's quaternion. This change allows the fix to work in 2D as well. --- doc/src/fix_propel_self.txt | 4 ++-- src/USER-MISC/fix_propel_self.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/fix_propel_self.txt b/doc/src/fix_propel_self.txt index 3e351ba56a..dbde99f48a 100644 --- a/doc/src/fix_propel_self.txt +++ b/doc/src/fix_propel_self.txt @@ -40,8 +40,8 @@ which the force is added depends on the mode. For mode = velocity, the active force acts along the velocity vector of each atom. This can be interpreted as a velocity-dependent friction, such as proposed by "(Erdmann)"_#Erdmann. -For mode = quaternion the force is along the axis obtained by rotating the z-axis along the -atom's quaternion. In other words, the force is along the z-axis in the atom's body +For mode = quaternion the force is along the axis obtained by rotating the x-axis along the +atom's quaternion. In other words, the force is along the x-axis in the atom's body frame. This mode requires all atoms in the group to have a quaternion, so atom_style should either be ellipsoid or body. In combination with Langevin thermostat for translation and rotation in the overdamped regime, the quaternion mode corresponds to the active Brownian diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index 56f5e44869..57ca30e838 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -188,7 +188,7 @@ void FixPropelSelf::post_force_quaternion(int /* vflag */ ) continue; } - double f_act[3] = { 0.0, 0.0, 1.0 }; + double f_act[3] = { 1.0, 0.0, 0.0 }; double f_rot[3]; double *quat = bonus[ellipsoid[i]].quat; From 13ee0c173952421f176413173dba15ccc1ae70b7 Mon Sep 17 00:00:00 2001 From: Pierre de Buyl Date: Fri, 10 Jan 2020 13:42:43 +0100 Subject: [PATCH 45/54] fix doc for fix propel/self to sphinx system --- doc/src/Commands_fix.rst | 2 +- doc/src/fix_propel_self.rst | 109 +++++++++++++++++++++++++++ doc/{src => txt}/fix_propel_self.txt | 2 +- 3 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 doc/src/fix_propel_self.rst rename doc/{src => txt}/fix_propel_self.txt (99%) diff --git a/doc/src/Commands_fix.rst b/doc/src/Commands_fix.rst index 4cd9a4487c..16b9ea8090 100644 --- a/doc/src/Commands_fix.rst +++ b/doc/src/Commands_fix.rst @@ -155,6 +155,7 @@ OPT. * :doc:`precession/spin ` * :doc:`press/berendsen ` * :doc:`print ` + * :doc:`propel/self ` * :doc:`property/atom (k) ` * :doc:`python/invoke ` * :doc:`python/move ` @@ -237,4 +238,3 @@ OPT. * :doc:`wall/region/ees ` * :doc:`wall/srd ` * - * diff --git a/doc/src/fix_propel_self.rst b/doc/src/fix_propel_self.rst new file mode 100644 index 0000000000..840f92a39b --- /dev/null +++ b/doc/src/fix_propel_self.rst @@ -0,0 +1,109 @@ +.. index:: fix propel/self + +fix propel/self command +======================= + +Syntax +"""""" + +fix ID group-ID propel/self mode magnitude keyword values ... + +* ID, group-ID are documented in :doc:`fix ` command +* propel/self = style name of this fix command +* mode = velocity or quaternion +* magnitude = magnitude of the active force +* one or more keyword/value pairs may be appended to args +* keyword = *types* + + *types* values = one or more atom types + + + +Examples +"""""""" + + +.. parsed-literal:: + + fix active_group all propel/self velocity 1.0 + fix constant_velocity all viscous 1.0 + + fix active_group all propel/self quaternion 1.0 + + fix active all propel/self quaternion 1.0 types 1 2 4 + +Description +""""""""""" + +Adds a force of a constant magnitude to each atom in the group. The nature in +which the force is added depends on the mode. + +For mode = velocity, the active force acts along the velocity vector of each atom. This can +be interpreted as a velocity-dependent friction, such as proposed by :ref:`(Erdmann) `. + +For mode = quaternion the force is along the axis obtained by rotating the x-axis along the +atom's quaternion. In other words, the force is along the x-axis in the atom's body +frame. This mode requires all atoms in the group to have a quaternion, so atom\_style should +either be ellipsoid or body. In combination with Langevin thermostat for translation and +rotation in the overdamped regime, the quaternion mode corresponds to the active Brownian +particle model introduced by :ref:`(Henkes) `, :ref:`(Bialke) ` and :ref:`(Fily) `. + +By default, this fix is applied to all atoms in the group. You can override this +behavior by specifying the atom types the fix should work on through the *types* +keyword. + + +---------- + + +**Restart, fix\_modify, output, run start/stop, minimize info:** + +No information about this fix is written to :doc:`binary restart files `. + +This fix is not imposed during minimization. + +Restrictions +"""""""""""" + + +In quaternion mode, this fix makes use of per-atom quaternions to take into account the fact +that the orientation can rotate and hence the direction of the active force can +change. Therefore, the quaternion mode of this fix only works with atom\_styles that have a +quaternion. + +Related commands +"""""""""""""""" + +:doc:`fix setforce `, :doc:`fix addforce ` + +.. _Erdmann: + + + +**(Erdmann)** U. Erdmanna , W. Ebeling, L. Schimansky-Geier, and F. Schweitzer, +Eur. Phys. J. B 15, 105-113, 2000. + +.. _Henkes: + + + +**(Henkes)** Henkes, S, Fily, Y., and Marchetti, M. C. Phys. Rev. E, 84, 040301(R), 2011. + +.. _Bialke: + + + +**(Bialke)** J. Bialké, T. Speck, and H Löwen, Phys. Rev. Lett. 108, 168301, 2012. + +.. _Fily: + + + +**(Fily)** Y. Fily and M.C. Marchetti, Phys. Rev. Lett. 108, 235702, 2012. + +**Default:** types + + +.. _lws: http://lammps.sandia.gov +.. _ld: Manual.html +.. _lc: Commands_all.html diff --git a/doc/src/fix_propel_self.txt b/doc/txt/fix_propel_self.txt similarity index 99% rename from doc/src/fix_propel_self.txt rename to doc/txt/fix_propel_self.txt index dbde99f48a..a7b491bfd6 100644 --- a/doc/src/fix_propel_self.txt +++ b/doc/txt/fix_propel_self.txt @@ -76,7 +76,7 @@ quaternion. Eur. Phys. J. B 15, 105-113, 2000. :link(Henkes) -[(Henkes)] Henkes, S, Fily, Y., and Marchetti, M. C. Phys. Rev. E, 84, 040301(R), 2011 +[(Henkes)] Henkes, S, Fily, Y., and Marchetti, M. C. Phys. Rev. E, 84, 040301(R), 2011. :link(Bialke) [(Bialke)] J. Bialké, T. Speck, and H Löwen, Phys. Rev. Lett. 108, 168301, 2012. From d739e017ad68ad1a136968e81671d3a550faee24 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 19 Jan 2020 12:22:22 -0500 Subject: [PATCH 46/54] tweak examples to be shorter/faster --- .../USER/misc/fix_propel_self/2d_velocity/in.2d_langevin | 8 ++++---- .../USER/misc/fix_propel_self/2d_velocity/in.2d_viscous | 6 +++--- .../misc/fix_propel_self/3d_quaternion/in.3d_quaternion | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin index 563c0bd969..6a23e0d005 100644 --- a/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin +++ b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin @@ -28,7 +28,7 @@ dump traj all custom 250 2d_active.dump.bin id type x y z thermo_style custom time step pe ke etotal temp thermo 1000 -run 25000 +run 5000 group one type 1 group two type 2 @@ -36,19 +36,19 @@ group two type 2 compute ke1 one ke compute ke2 two ke -thermo_style custom time step pe ke etotal temp c_ke1 c_ke2 +thermo_style custom step pe ke etotal temp c_ke1 c_ke2 fix active all propel/self velocity 1.0 # With active force there is more motion so increase bin size: neighbor 1.0 bin -run 25000 +run 10000 # Only make type 1 active: fix active all propel/self velocity 1.0 types 1 # With active force there is more motion so increase bin size: neighbor 1.0 bin -run 25000 +run 10000 diff --git a/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_viscous b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_viscous index e6bb1169e0..1283a5d574 100644 --- a/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_viscous +++ b/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_viscous @@ -25,13 +25,13 @@ neighbor 0.6 bin dump traj all custom 250 2d_active.dump.bin id type x y z -thermo_style custom time step pe ke etotal temp +thermo_style custom step pe ke etotal temp thermo 1000 -run 25000 +run 10000 fix active all propel/self velocity 1.0 fix fric all viscous 1.0 # With active force there is more motion so increase bin size: neighbor 1.0 bin -run 25000 +run 10000 diff --git a/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion b/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion index 11f2ea8a07..5c632000a7 100644 --- a/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion +++ b/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion @@ -29,12 +29,12 @@ neighbor 0.6 bin dump traj all custom 100 3d_active.dump.bin id type x y z fx fy fz -thermo_style custom time step pe ke etotal temp +thermo_style custom step pe ke etotal temp thermo 100 -run 5000 +run 500 fix active all propel/self quaternion 1.0 # With active force there is more motion so increase bin size: neighbor 1.0 bin -run 5000 +run 500 From f4d9715cc7e4d275f4d982b136e064ffba6b1ccd Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 19 Jan 2020 13:06:12 -0500 Subject: [PATCH 47/54] make code follow LAMMPS conventions more closely and do some cleanups - remove tabs and trailing whitespace - remove references to atom style body, since code only works with ellipsoid - adjust function names and tests for requirements to be more obvious and work correctly in parallel - remove rather specific debug code - remove non-essential c++11 features - refactor, correct, and simplify parsing of types keyword arguments --- src/USER-MISC/fix_propel_self.cpp | 223 +++++++++++++----------------- src/USER-MISC/fix_propel_self.h | 21 ++- 2 files changed, 103 insertions(+), 141 deletions(-) diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index 57ca30e838..9abd1cb791 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -9,20 +9,20 @@ the GNU General Public License. See the README file in the top-level LAMMPS directory. - ------------------------------------------------------------------------- */ +------------------------------------------------------------------------- */ -/* ----------------------------------------------------------------------- +/* ----------------------------------------------------------------------- Contributed by Stefan Paquay @ Brandeis University Thanks to Liesbeth Janssen @ Eindhoven University for useful discussions! - ----------------------------------------------------------------------- */ - - -#include -#include +----------------------------------------------------------------------- */ #include "fix_propel_self.h" +#include +#include +#include + #include "atom.h" #include "atom_vec_ellipsoid.h" #include "citeme.h" @@ -39,39 +39,43 @@ #include "respa.h" #include "update.h" - using namespace LAMMPS_NS; using namespace FixConst; using namespace MathConst; +#define PRINT_DEBUG_OUTPUT 0 -static constexpr const bool debug_out = false; - +/* ---------------------------------------------------------------------- */ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) - : Fix(lmp, narg, argv), magnitude(1.0), thermostat_orient(0), - mode(VELOCITY), n_types_filter(0), apply_to_type(NULL) + : Fix(lmp, narg, argv), magnitude(0.0), + mode(VELOCITY), n_types_filter(0), apply_to_type(NULL) { - if( narg < 5 ) error->all(FLERR, "Illegal fix propel/self command"); + if (narg < 5) error->all(FLERR, "Illegal fix propel/self command"); // The fix is to support the following cases: // 1. Simple atoms, in which case the force points along the velocity - // 2. Cases where the atoms have an internal ellipsoid. Currently those - // styles are only body and aspherical particles. + // 2. Aspherical particles with an orientation. // The first argument (mode) is used to differentiate between these. - + // args: fix ID all propel/self mode magnitude // Optional args are + const char *mode_str = argv[3]; + if (strncmp(mode_str, "velocity", 8) == 0) { mode = VELOCITY; + } else if (strncmp(mode_str, "quaternion", 10) == 0) { + // This mode should only be supported if the atom style has // a quaternion (and if all atoms in the group have it) - if (verify_atoms_have_quaternion()) { - error->all(FLERR, "All atoms need a quaternion"); + + if (!atoms_have_quaternion()) { + error->all(FLERR, "All fix atoms need to be extended particles"); } mode = QUATERNION; + } else { char msg[2048]; sprintf(msg, "Illegal mode \"%s\" for fix propel/self", mode_str); @@ -80,57 +84,48 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) magnitude = force->numeric( FLERR, argv[4] ); - // Handle rest of args: + // Handle rest of args: + int iarg = 5; while (iarg < narg) { - const char *arg = argv[iarg]; - if (strncmp(arg, "types", 5) == 0) { - // In this case we need to allocate the type list. - // First find the largest given type: - int max_type_in_list = 0; - ++iarg; - while ( (iarg + n_types_filter < narg) && - (!isalpha(argv[iarg + n_types_filter][0]))) { - int curr_type = force->numeric(FLERR, argv[iarg + n_types_filter]); - if (curr_type > max_type_in_list) max_type_in_list = curr_type; - ++n_types_filter; + + if (strcmp(argv[iarg],"types") == 0) { + + apply_to_type = new int[atom->ntypes+1]; + memset(apply_to_type, 0, atom->ntypes * sizeof(int)); + + // consume all following numerical arguments as types + + iarg++; + int flag=0; + while (iarg < narg) { + if (isdigit(argv[iarg][0])) { + int thistype = force->inumeric(FLERR,argv[iarg]); + if ((thistype < 1) || (thistype > atom->ntypes)) + error->all(FLERR,"Illegal atom type to types keyword"); + apply_to_type[thistype] = 1; + flag = 1; + iarg++; + } else break; } - if (n_types_filter == 0) { - error->all(FLERR, "\"types\" option requires at least one type"); - } - - // sanity check: - if (max_type_in_list < n_types_filter) { - error->warning(FLERR, "Found duplicate type in \"types\" option"); - } - - apply_to_type = new int[max_type_in_list+1]; - if (!apply_to_type) error->all(FLERR, "Failed to allocate type storage!"); - - for (int i = 0; i < max_type_in_list+1; ++i) { - apply_to_type[i] = 0; - } - - for (int i = 0; i < n_types_filter; ++i) { - int curr_type = force->numeric(FLERR, argv[iarg + i]); - apply_to_type[curr_type] = 1; - } - // Done handling types argument. - iarg += n_types_filter; // -1 because we incremented by 1 previously. + if (!flag) + error->all(FLERR,"'types' keyword requires at least one type"); + else + n_types_filter = 1; + } else { - char msg[2048]; - sprintf(msg, "Illegal fix propel/self command: " - "Unrecognized argument %s", arg); - error->all(FLERR, msg); + error->all(FLERR,"Illegal fix propel/self command."); } } - } +/* ---------------------------------------------------------------------- */ FixPropelSelf::~FixPropelSelf() -{} - +{ + delete[] apply_to_type; +} +/* ---------------------------------------------------------------------- */ int FixPropelSelf::setmask() { @@ -140,16 +135,18 @@ int FixPropelSelf::setmask() return mask; } +/* ---------------------------------------------------------------------- */ double FixPropelSelf::memory_usage() { // magnitude + thermostat_orient + mode + n_types_filter + apply_to_type double bytes = sizeof(double) + 3*sizeof(int) + sizeof(int*); - bytes += sizeof(int)*n_types_filter; - + bytes += sizeof(int)*atom->ntypes*n_types_filter; + return bytes; } +/* ---------------------------------------------------------------------- */ void FixPropelSelf::post_force(int vflag ) { @@ -163,11 +160,11 @@ void FixPropelSelf::post_force(int vflag ) else post_force_velocity<0>(vflag); break; default: - error->all(FLERR, "reached statement that should be unreachable"); + ; } } - +/* ---------------------------------------------------------------------- */ template void FixPropelSelf::post_force_quaternion(int /* vflag */ ) @@ -179,44 +176,26 @@ void FixPropelSelf::post_force_quaternion(int /* vflag */ ) int nlocal = atom->nlocal; int *type = atom->type; int* ellipsoid = atom->ellipsoid; - + AtomVecEllipsoid::Bonus *bonus = av->bonus; + // Add the active force to the atom force: + for( int i = 0; i < nlocal; ++i ){ if( mask[i] & groupbit ){ if (filter_by_type && !apply_to_type[type[i]]) { continue; } - + double f_act[3] = { 1.0, 0.0, 0.0 }; double f_rot[3]; double *quat = bonus[ellipsoid[i]].quat; - tagint *tag = atom->tag; double Q[3][3]; MathExtra::quat_to_mat( quat, Q ); MathExtra::matvec( Q, f_act, f_rot ); - if (debug_out && comm->me == 0) { - // Magical reference particle: - if (tag[i] == 12) { - fprintf(screen, "rotation quaternion: (%f %f %f %f)\n", - quat[0], quat[1], quat[2], quat[3]); - fprintf(screen, "rotation matrix: / %f %f %f \\\n", - Q[0][0] ,Q[0][1], Q[0][2]); - fprintf(screen, " | %f %f %f |\n", - Q[1][0] ,Q[1][1], Q[1][2]); - fprintf(screen, " \\ %f %f %f /\n", - Q[2][0] ,Q[2][1], Q[2][2]); - - fprintf(screen, "Active force on atom %d: (%f %f %f)\n", - tag[i], f_rot[0], f_rot[1], f_rot[2]); - fprintf(screen, " Total force before: (%f %f %f)\n", - f[i][0], f[i][1], f[i][2]); - } - } - f[i][0] += magnitude * f_rot[0]; f[i][1] += magnitude * f_rot[1]; f[i][2] += magnitude * f_rot[2]; @@ -224,44 +203,38 @@ void FixPropelSelf::post_force_quaternion(int /* vflag */ ) } } +/* ---------------------------------------------------------------------- */ -template -void FixPropelSelf::post_force_velocity(int /*vflag*/ ) +template +void FixPropelSelf::post_force_velocity(int /*vflag*/) { double **f = atom->f; double **v = atom->v; int *mask = atom->mask; int nlocal = atom->nlocal; - tagint *tag = atom->tag; int *type = atom->type; // Add the active force to the atom force: - for( int i = 0; i < nlocal; ++i ){ + + for(int i = 0; i < nlocal; ++i) { if( mask[i] & groupbit ){ if (filter_by_type && !apply_to_type[type[i]]) { continue; } - + const double *vi = v[i]; double f_act[3] = { vi[0], vi[1], vi[2] }; double nv2 = vi[0]*vi[0] + vi[1]*vi[1] + vi[2]*vi[2]; double fnorm = 0.0; - constexpr const double TOL = 1e-14; + const double TOL = 1e-14; + if (nv2 > TOL) { - // Without this check you can run into numerical issues - // because fnorm will blow up. + + // Without this check you can run into numerical + // issues because fnorm will blow up. + fnorm = magnitude / sqrt(nv2); } - - if (debug_out && comm->me == 0) { - // Magical reference particle: - if (tag[i] == 12) { - fprintf(screen, "Active force on atom %d: (%f %f %f)\n", - tag[i], f_act[0], f_act[1], f_act[2]); - fprintf(screen, " Total force before: (%f %f %f)\n", - f[i][0], f[i][1], f[i][2]); - } - } f[i][0] += fnorm * f_act[0]; f[i][1] += fnorm * f_act[1]; @@ -270,32 +243,26 @@ void FixPropelSelf::post_force_velocity(int /*vflag*/ ) } } +/* ---------------------------------------------------------------------- */ -int FixPropelSelf::verify_atoms_have_quaternion() +int FixPropelSelf::atoms_have_quaternion() { - int ellipsoid_flag = atom->ellipsoid_flag; - int body_flag = atom->body_flag; - int *mask = atom->mask; - if (! (ellipsoid_flag || body_flag) ){ - error->all(FLERR, "mode quaternion requires body or ellipsoid atoms"); + if (!atom->ellipsoid_flag) { + error->all(FLERR, "Mode 'quaternion' requires atom style ellipsoid"); + return 0; } - - // Make sure all atoms have ellipsoid or body set: - for (int i = 0; i < atom->nlocal; ++i) { - if (mask[i] & groupbit) { - if (ellipsoid_flag && atom->ellipsoid[i] < 0) { - error->all(FLERR, "Got atom without ellipsoid set"); - // Kind-of pointless return but silences compiler warnings: - return 1; - } - if (body_flag && atom->body[i] < 0) { - error->all(FLERR, "Got atom without body set"); - // Kind-of pointless return silences compiler warnings: - return 1; - } - } - } - - return 0; -} + int *mask = atom->mask; + int flag=0,flagall=0; + + // Make sure all atoms have ellipsoid data: + + for (int i = 0; i < atom->nlocal; ++i) + if (mask[i] & groupbit) + if (atom->ellipsoid[i] < 0) ++flag; + + MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); + if (flagall > 0) return 0; + + return 1; +} diff --git a/src/USER-MISC/fix_propel_self.h b/src/USER-MISC/fix_propel_self.h index 2b44b8e1ce..47d1e1255b 100644 --- a/src/USER-MISC/fix_propel_self.h +++ b/src/USER-MISC/fix_propel_self.h @@ -27,39 +27,34 @@ namespace LAMMPS_NS { class FixPropelSelf : public Fix { public: - enum operation_modes { - VELOCITY = 0, - QUATERNION = 1 - }; - FixPropelSelf(class LAMMPS *, int, char **); virtual ~FixPropelSelf(); virtual int setmask(); virtual void post_force(int); - // virtual void post_force_respa(int, int, int); double memory_usage(); + protected: + enum operation_modes { + VELOCITY = 0, + QUATERNION = 1 + }; + private: double magnitude; - int thermostat_orient; int mode; - // If 0, apply fix to everything in group. If > 0, apply only to those // types i for which i <= n_types_filter _and_ apply_to_type[i] == 1: int n_types_filter; int *apply_to_type; //< Specifies, per type, if the fix applies to it or not. - - int verify_atoms_have_quaternion(); + + int atoms_have_quaternion(); template void post_force_velocity(int); template void post_force_quaternion(int); - - }; - } #endif From 5e740c9cc5744655163a7606b869778dafc4b618 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 19 Jan 2020 13:29:52 -0500 Subject: [PATCH 48/54] documentation and examples cleanup for fix propel/self - rename example folder - remove .txt format docs - remove obsolete fix active sources - update readme in src/USER-MISC - replace non-ASCII characters and fix spelling issues --- doc/src/fix.rst | 1 + doc/src/fix_propel_self.rst | 38 ++-- doc/txt/fix_propel_self.txt | 88 ---------- doc/utils/sphinx-config/false_positives.txt | 10 ++ .../2d_velocity/in.2d_langevin | 0 .../2d_velocity/in.2d_viscous | 0 .../3d_quaternion/in.3d_quaternion | 0 src/USER-MISC/README | 1 + src/USER-MISC/fix_active.cpp | 163 ------------------ src/USER-MISC/fix_active.h | 55 ------ 10 files changed, 33 insertions(+), 323 deletions(-) delete mode 100644 doc/txt/fix_propel_self.txt rename examples/USER/misc/{fix_propel_self => propel_self}/2d_velocity/in.2d_langevin (100%) rename examples/USER/misc/{fix_propel_self => propel_self}/2d_velocity/in.2d_viscous (100%) rename examples/USER/misc/{fix_propel_self => propel_self}/3d_quaternion/in.3d_quaternion (100%) delete mode 100644 src/USER-MISC/fix_active.cpp delete mode 100644 src/USER-MISC/fix_active.h diff --git a/doc/src/fix.rst b/doc/src/fix.rst index ae0c3d625a..801479de6e 100644 --- a/doc/src/fix.rst +++ b/doc/src/fix.rst @@ -308,6 +308,7 @@ accelerated styles exist. * :doc:`precession/spin ` - * :doc:`press/berendsen ` - pressure control by Berendsen barostat * :doc:`print ` - print text and variables during a simulation +* :doc:`propel/self ` - model self-propelled particles * :doc:`property/atom ` - add customized per-atom values * :doc:`python/invoke ` - call a Python function during a simulation * :doc:`python/move ` - call a Python function during a simulation run diff --git a/doc/src/fix_propel_self.rst b/doc/src/fix_propel_self.rst index 840f92a39b..f8cd7f7faa 100644 --- a/doc/src/fix_propel_self.rst +++ b/doc/src/fix_propel_self.rst @@ -38,19 +38,23 @@ Description Adds a force of a constant magnitude to each atom in the group. The nature in which the force is added depends on the mode. -For mode = velocity, the active force acts along the velocity vector of each atom. This can -be interpreted as a velocity-dependent friction, such as proposed by :ref:`(Erdmann) `. +For *mode* = *velocity*, the active force acts along the velocity vector of +each atom. This can be interpreted as a velocity-dependent friction, +such as proposed by :ref:`(Erdmann) `. -For mode = quaternion the force is along the axis obtained by rotating the x-axis along the -atom's quaternion. In other words, the force is along the x-axis in the atom's body -frame. This mode requires all atoms in the group to have a quaternion, so atom\_style should -either be ellipsoid or body. In combination with Langevin thermostat for translation and -rotation in the overdamped regime, the quaternion mode corresponds to the active Brownian -particle model introduced by :ref:`(Henkes) `, :ref:`(Bialke) ` and :ref:`(Fily) `. +For *mode* = *quaternion* the force is applied along the axis obtained +by rotating the x-axis along the atom's quaternion. In other words, the +force is along the x-axis in the atom's body frame. This mode requires +all atoms in the group to have a quaternion, so atom\_style should +either be ellipsoid or body. In combination with Langevin thermostat +for translation and rotation in the overdamped regime, the quaternion +mode corresponds to the active Brownian particle model introduced by +:ref:`(Henkes) `, :ref:`(Bialke) ` and :ref:`(Fily) +`. -By default, this fix is applied to all atoms in the group. You can override this -behavior by specifying the atom types the fix should work on through the *types* -keyword. +By default, this fix is applied to all atoms in the group. You can +override this behavior by specifying the atom types the fix should work +on through the *types* keyword. ---------- @@ -66,10 +70,10 @@ Restrictions """""""""""" -In quaternion mode, this fix makes use of per-atom quaternions to take into account the fact -that the orientation can rotate and hence the direction of the active force can -change. Therefore, the quaternion mode of this fix only works with atom\_styles that have a -quaternion. +In quaternion mode, this fix makes use of per-atom quaternions to take +into account the fact that the orientation can rotate and hence the +direction of the active force can change. The quaternion mode +of this fix only works with atom\_style ellipsoid. Related commands """""""""""""""" @@ -80,7 +84,7 @@ Related commands -**(Erdmann)** U. Erdmanna , W. Ebeling, L. Schimansky-Geier, and F. Schweitzer, +**(Erdmann)** U. Erdmann , W. Ebeling, L. Schimansky-Geier, and F. Schweitzer, Eur. Phys. J. B 15, 105-113, 2000. .. _Henkes: @@ -93,7 +97,7 @@ Eur. Phys. J. B 15, 105-113, 2000. -**(Bialke)** J. Bialké, T. Speck, and H Löwen, Phys. Rev. Lett. 108, 168301, 2012. +**(Bialke)** J. Bialke, T. Speck, and H Loewen, Phys. Rev. Lett. 108, 168301, 2012. .. _Fily: diff --git a/doc/txt/fix_propel_self.txt b/doc/txt/fix_propel_self.txt deleted file mode 100644 index a7b491bfd6..0000000000 --- a/doc/txt/fix_propel_self.txt +++ /dev/null @@ -1,88 +0,0 @@ -"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c - -:link(lws,http://lammps.sandia.gov) -:link(ld,Manual.html) -:link(lc,Section_commands.html#comm) - -:line - -fix propel/self command :h3 - -[Syntax:] - -fix ID group-ID propel/self mode magnitude keyword values ... - -ID, group-ID are documented in "fix"_fix.html command :ulb,l -propel/self = style name of this fix command :l -mode = velocity or quaternion :l -magnitude = magnitude of the active force :l -one or more keyword/value pairs may be appended to args :l -keyword = {types} :l - {types} values = one or more atom types - -:ule - -[Examples:] - -fix active_group all propel/self velocity 1.0 -fix constant_velocity all viscous 1.0 :pre - -fix active_group all propel/self quaternion 1.0 :pre - -fix active all propel/self quaternion 1.0 types 1 2 4 :pre - - -[Description:] - -Adds a force of a constant magnitude to each atom in the group. The nature in -which the force is added depends on the mode. - -For mode = velocity, the active force acts along the velocity vector of each atom. This can -be interpreted as a velocity-dependent friction, such as proposed by "(Erdmann)"_#Erdmann. - -For mode = quaternion the force is along the axis obtained by rotating the x-axis along the -atom's quaternion. In other words, the force is along the x-axis in the atom's body -frame. This mode requires all atoms in the group to have a quaternion, so atom_style should -either be ellipsoid or body. In combination with Langevin thermostat for translation and -rotation in the overdamped regime, the quaternion mode corresponds to the active Brownian -particle model introduced by "(Henkes)"_#Henkes, "(Bialke)"_#Bialke and "(Fily)"_#Fily. - -By default, this fix is applied to all atoms in the group. You can override this -behavior by specifying the atom types the fix should work on through the {types} -keyword. - -:line - -[Restart, fix_modify, output, run start/stop, minimize info:] - -No information about this fix is written to "binary restart -files"_restart.html. - -This fix is not imposed during minimization. - -[Restrictions:] - -In quaternion mode, this fix makes use of per-atom quaternions to take into account the fact -that the orientation can rotate and hence the direction of the active force can -change. Therefore, the quaternion mode of this fix only works with atom_styles that have a -quaternion. - -[Related commands:] - -"fix setforce"_fix_setforce.html, "fix addforce"_fix_addforce.html - -:link(Erdmann) -[(Erdmann)] U. Erdmanna , W. Ebeling, L. Schimansky-Geier, and F. Schweitzer, -Eur. Phys. J. B 15, 105-113, 2000. - -:link(Henkes) -[(Henkes)] Henkes, S, Fily, Y., and Marchetti, M. C. Phys. Rev. E, 84, 040301(R), 2011. - -:link(Bialke) -[(Bialke)] J. Bialké, T. Speck, and H Löwen, Phys. Rev. Lett. 108, 168301, 2012. - -:link(Fily) -[(Fily)] Y. Fily and M.C. Marchetti, Phys. Rev. Lett. 108, 235702, 2012. - - -[Default:] types diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index c9f1c0cd8e..3a40587d9b 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -220,6 +220,7 @@ Bext Bfrac bgq Bh +Bialke Biersack bigbig bigint @@ -691,6 +692,7 @@ eangle eatom Eb Eba +Ebeling ebond ebook ebt @@ -789,6 +791,7 @@ equilibration Equilibria equilization Ercolessi +Erdmann eradius erate erc @@ -879,6 +882,7 @@ filename Filename filenames Filenames +Fily fileper filesystem Fincham @@ -975,6 +979,7 @@ gcc gcmc gdot GeC +Geier gencode georg Georg @@ -1087,6 +1092,7 @@ Heenen Hendrik Henin Henkelman +Henkes henrich Henrich Herrmann @@ -1534,6 +1540,7 @@ lmptype ln localTemp localvectors +Loewen logfile logfreq logicals @@ -1598,6 +1605,7 @@ manpages manybody MANYBODY Maras +Marchetti Marrink Marroquin Marsaglia @@ -2093,6 +2101,7 @@ outfile outmost outputss Ouyang +overdamped overlayed Ovito oxdna @@ -2529,6 +2538,7 @@ scalexz scaleyz Schaik Schilfgarde +Schimansky Schiotz Schlitter Schmid diff --git a/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin b/examples/USER/misc/propel_self/2d_velocity/in.2d_langevin similarity index 100% rename from examples/USER/misc/fix_propel_self/2d_velocity/in.2d_langevin rename to examples/USER/misc/propel_self/2d_velocity/in.2d_langevin diff --git a/examples/USER/misc/fix_propel_self/2d_velocity/in.2d_viscous b/examples/USER/misc/propel_self/2d_velocity/in.2d_viscous similarity index 100% rename from examples/USER/misc/fix_propel_self/2d_velocity/in.2d_viscous rename to examples/USER/misc/propel_self/2d_velocity/in.2d_viscous diff --git a/examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion b/examples/USER/misc/propel_self/3d_quaternion/in.3d_quaternion similarity index 100% rename from examples/USER/misc/fix_propel_self/3d_quaternion/in.3d_quaternion rename to examples/USER/misc/propel_self/3d_quaternion/in.3d_quaternion diff --git a/src/USER-MISC/README b/src/USER-MISC/README index ab646aab5a..9fdc18fbe5 100644 --- a/src/USER-MISC/README +++ b/src/USER-MISC/README @@ -60,6 +60,7 @@ fix ipi, Michele Ceriotti (EPFL Lausanne), michele.ceriotti at gmail.com, 24 Nov fix npt/cauchy, R. E. Miller (Carleton University), F. Pavia and S. Pattamatta, 12 Jan 2020 fix nvk, Efrem Braun (UC Berkeley), efrem.braun at gmail.com, https://github.com/lammps/lammps/pull/310 fix pimd, Yuxing Peng (U Chicago), yuxing at uchicago.edu, 24 Nov 2014 +fix propel/self, Stefan Paquay (Brandeis U), stefanpaquay at gmail.com, 20 Jan 2020 fix rhok, Ulf Pedersen (Roskilde U), ulf at urp.dk, 25 Sep 2017 fix smd, Axel Kohlmeyer, akohlmey at gmail.com, 19 May 2008 fix ti/spring, Rodrigo Freitas (Unicamp/Brazil), rodrigohb at gmail.com, 7 Nov 2013 diff --git a/src/USER-MISC/fix_active.cpp b/src/USER-MISC/fix_active.cpp deleted file mode 100644 index 1bb0726748..0000000000 --- a/src/USER-MISC/fix_active.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* ---------------------------------------------------------------------- - 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. - ------------------------------------------------------------------------- */ - -/* ----------------------------------------------------------------------- - Contributed by Stefan Paquay @ Brandeis University - - Thanks to Liesbeth Janssen @ Eindhoven University for useful discussions! - ----------------------------------------------------------------------- */ - - -#include -#include - -#include "fix_active.h" - -#include "atom.h" -#include "atom_vec_ellipsoid.h" -#include "citeme.h" -#include "comm.h" -#include "error.h" -#include "force.h" -#include "group.h" -#include "math.h" -#include "math_const.h" -#include "math_extra.h" -#include "math_vector.h" -#include "modify.h" -#include "random_mars.h" -#include "respa.h" -#include "update.h" - - -using namespace LAMMPS_NS; -using namespace FixConst; -using namespace MathConst; - -/* - Might be used later, who knows... -static const char* cite_fix_active = - "fix active command:\n\n" - "@article{paquay-2018,\n" - " author = {Paquay, Stefan},\n" - " doi = {},\n" - " issn = {},\n" - " journal = {},\n" - " month = ,\n" - " number = ,\n" - " pages = ,\n" - " title = ,\n" - " volume = ,\n" - " year = \n" - "}\n\n"; -*/ - -static constexpr const bool debug_out = false; - -FixActive::FixActive( LAMMPS *lmp, int narg, char **argv ) - : Fix(lmp, narg, argv) -{ - // if( lmp->citeme) lmp->citeme->add(cite_fix_active); - if( narg < 4 ) error->all(FLERR, "Illegal fix active command"); - - AtomVecEllipsoid *av = static_cast(atom->avec); - if (!av) error->all(FLERR, "FixActive requires atom_style ellipsoid"); - - if( debug_out && comm->me == 0 ){ - fprintf(screen, "This is fix active, narg is %d\n", narg ); - fprintf(screen, "args:"); - for( int i = 0; i < narg; ++i ){ - fprintf(screen, " %s", argv[i]); - } - fprintf(screen, "\n"); - } - - // args: fix ID all active magnitude prop1 prop2 prop3 - // Optional args are - magnitude = force->numeric( FLERR, argv[3] ); -} - - -FixActive::~FixActive() -{} - - -int FixActive::setmask() -{ - int mask = 0; - mask |= POST_FORCE; - - return mask; -} - - -double FixActive::memory_usage() -{ - double bytes = 0.0; - return bytes; -} - - - -void FixActive::post_force(int /* vflag */ ) -{ - // Then do the rest: - double **f = atom->f; - - AtomVecEllipsoid *av = static_cast(atom->avec); - - int *mask = atom->mask; - int nlocal = atom->nlocal; - if (igroup == atom->firstgroup) nlocal = atom->nfirst; - - AtomVecEllipsoid::Bonus *bonus = av->bonus; - // Add the active force to the atom force: - for( int i = 0; i < nlocal; ++i ){ - if( mask[i] & groupbit ){ - double f_act[3] = { 0.0, 0.0, 1.0 }; - double f_rot[3]; - - int* ellipsoid = atom->ellipsoid; - double *quat = bonus[ellipsoid[i]].quat; - tagint *tag = atom->tag; - - double Q[3][3]; - MathExtra::quat_to_mat( quat, Q ); - MathExtra::matvec( Q, f_act, f_rot ); - - if (debug_out && comm->me == 0) { - // Magical reference particle: - if (tag[i] == 12) { - fprintf(screen, "rotation quaternion: (%f %f %f %f)\n", - quat[0], quat[1], quat[2], quat[3]); - fprintf(screen, "rotation matrix: / %f %f %f \\\n", - Q[0][0] ,Q[0][1], Q[0][2]); - fprintf(screen, " | %f %f %f |\n", - Q[1][0] ,Q[1][1], Q[1][2]); - fprintf(screen, " \\ %f %f %f /\n", - Q[2][0] ,Q[2][1], Q[2][2]); - - fprintf(screen, "Active force on atom %d: (%f %f %f)\n", - tag[i], f_rot[0], f_rot[1], f_rot[2]); - fprintf(screen, " Total force before: (%f %f %f)\n", - f[i][0], f[i][1], f[i][2]); - } - } - - f[i][0] += magnitude * f_rot[0]; - f[i][1] += magnitude * f_rot[1]; - f[i][2] += magnitude * f_rot[2]; - - } - } -} diff --git a/src/USER-MISC/fix_active.h b/src/USER-MISC/fix_active.h deleted file mode 100644 index 02a91db14a..0000000000 --- a/src/USER-MISC/fix_active.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - 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. -------------------------------------------------------------------------- */ - -#ifdef FIX_CLASS - -FixStyle(active,FixActive) - -#else - -#ifndef LMP_FIX_ACTIVE_H -#define LMP_FIX_ACTIVE_H - -#include "fix.h" - -namespace LAMMPS_NS { - -class FixActive : public Fix { - public: - FixActive(class LAMMPS *, int, char **); - virtual ~FixActive(); - virtual int setmask(); - virtual void post_force(int); - // virtual void post_force_respa(int, int, int); - - double memory_usage(); - -protected: - double magnitude; - int thermostat_orient; -}; - -} - -#endif -#endif - -/* ERROR/WARNING messages: - -E: Illegal ... command - -Self-explanatory. Check the input script syntax and compare to the -documentation for the command. You can use -echo screen as a -command-line option when running LAMMPS to see the offending line. - -*/ From 074e18d9cb84bd5c849e90d84448fcb34ba65d07 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 19 Jan 2020 13:34:21 -0500 Subject: [PATCH 49/54] fix one more whitespace issue --- src/USER-MISC/fix_propel_self.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index 9abd1cb791..a2d1c4166c 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -263,6 +263,6 @@ int FixPropelSelf::atoms_have_quaternion() MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); if (flagall > 0) return 0; - + return 1; } From af1e797271442c20959e6da091441874048ca183 Mon Sep 17 00:00:00 2001 From: Pierre de Buyl Date: Mon, 20 Jan 2020 12:48:26 +0100 Subject: [PATCH 50/54] fix mass and nve/asphere 1. Set mass to 1. The radius is 1/2, so the density must be 1/(4/3 pi 1/2^3) 2. Use nve/asphere instead of nve. Else, the particle's orientation are not integrated. --- examples/USER/misc/propel_self/3d_quaternion/in.3d_quaternion | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/USER/misc/propel_self/3d_quaternion/in.3d_quaternion b/examples/USER/misc/propel_self/3d_quaternion/in.3d_quaternion index 5c632000a7..8e8e4573d0 100644 --- a/examples/USER/misc/propel_self/3d_quaternion/in.3d_quaternion +++ b/examples/USER/misc/propel_self/3d_quaternion/in.3d_quaternion @@ -18,11 +18,11 @@ pair_coeff * * 1.0 1.0 pair_modify shift yes # mass * 1.0 -set type * density 1.0 set type * shape 1.0 1.0 1.0 +set type * density 1.9098593171027443 set type * quat 0 0 1 0 -fix step all nve +fix step all nve/asphere fix temp all langevin 1.0 1.0 1.0 13 angmom 3.333333333 neighbor 0.6 bin From 8ed271f16f74fdec5b93bc2aa80e74ab229a9ca0 Mon Sep 17 00:00:00 2001 From: Pierre de Buyl Date: Mon, 20 Jan 2020 17:41:20 +0100 Subject: [PATCH 51/54] change mode of propel/self to quat instead of quaternion --- doc/src/fix_propel_self.rst | 12 ++++++------ .../misc/propel_self/3d_quaternion/in.3d_quaternion | 2 +- src/USER-MISC/fix_propel_self.cpp | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/src/fix_propel_self.rst b/doc/src/fix_propel_self.rst index f8cd7f7faa..005657c759 100644 --- a/doc/src/fix_propel_self.rst +++ b/doc/src/fix_propel_self.rst @@ -10,7 +10,7 @@ fix ID group-ID propel/self mode magnitude keyword values ... * ID, group-ID are documented in :doc:`fix ` command * propel/self = style name of this fix command -* mode = velocity or quaternion +* mode = velocity or quat * magnitude = magnitude of the active force * one or more keyword/value pairs may be appended to args * keyword = *types* @@ -28,9 +28,9 @@ Examples fix active_group all propel/self velocity 1.0 fix constant_velocity all viscous 1.0 - fix active_group all propel/self quaternion 1.0 + fix active_group all propel/self quat 1.0 - fix active all propel/self quaternion 1.0 types 1 2 4 + fix active all propel/self quat 1.0 types 1 2 4 Description """"""""""" @@ -42,7 +42,7 @@ For *mode* = *velocity*, the active force acts along the velocity vector of each atom. This can be interpreted as a velocity-dependent friction, such as proposed by :ref:`(Erdmann) `. -For *mode* = *quaternion* the force is applied along the axis obtained +For *mode* = *quat* the force is applied along the axis obtained by rotating the x-axis along the atom's quaternion. In other words, the force is along the x-axis in the atom's body frame. This mode requires all atoms in the group to have a quaternion, so atom\_style should @@ -70,9 +70,9 @@ Restrictions """""""""""" -In quaternion mode, this fix makes use of per-atom quaternions to take +In quat mode, this fix makes use of per-atom quaternions to take into account the fact that the orientation can rotate and hence the -direction of the active force can change. The quaternion mode +direction of the active force can change. The quat mode of this fix only works with atom\_style ellipsoid. Related commands diff --git a/examples/USER/misc/propel_self/3d_quaternion/in.3d_quaternion b/examples/USER/misc/propel_self/3d_quaternion/in.3d_quaternion index 8e8e4573d0..d6b6aff7dd 100644 --- a/examples/USER/misc/propel_self/3d_quaternion/in.3d_quaternion +++ b/examples/USER/misc/propel_self/3d_quaternion/in.3d_quaternion @@ -33,7 +33,7 @@ thermo_style custom step pe ke etotal temp thermo 100 run 500 -fix active all propel/self quaternion 1.0 +fix active all propel/self quat 1.0 # With active force there is more motion so increase bin size: neighbor 1.0 bin diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index a2d1c4166c..dcc027aab1 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -66,7 +66,7 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) if (strncmp(mode_str, "velocity", 8) == 0) { mode = VELOCITY; - } else if (strncmp(mode_str, "quaternion", 10) == 0) { + } else if (strncmp(mode_str, "quat", 10) == 0) { // This mode should only be supported if the atom style has // a quaternion (and if all atoms in the group have it) @@ -248,7 +248,7 @@ void FixPropelSelf::post_force_velocity(int /*vflag*/) int FixPropelSelf::atoms_have_quaternion() { if (!atom->ellipsoid_flag) { - error->all(FLERR, "Mode 'quaternion' requires atom style ellipsoid"); + error->all(FLERR, "Mode 'quat' requires atom style ellipsoid"); return 0; } From b0ba91d353a345bda048b70583a2e91b1cb0652e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 20 Jan 2020 11:58:59 -0500 Subject: [PATCH 52/54] add false positive --- doc/utils/sphinx-config/false_positives.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 3a40587d9b..43a4207fc1 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -2336,6 +2336,7 @@ quadratically quadrupolar Quant quartic +quat quaternion quaternions quati From 3ccab876f712b4ae3448299d399588028cb92aa1 Mon Sep 17 00:00:00 2001 From: Pierre de Buyl Date: Mon, 20 Jan 2020 18:15:37 +0100 Subject: [PATCH 53/54] fix string length for strncmp --- src/USER-MISC/fix_propel_self.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index dcc027aab1..e8485c48a4 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -66,7 +66,7 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) if (strncmp(mode_str, "velocity", 8) == 0) { mode = VELOCITY; - } else if (strncmp(mode_str, "quat", 10) == 0) { + } else if (strncmp(mode_str, "quat", 4) == 0) { // This mode should only be supported if the atom style has // a quaternion (and if all atoms in the group have it) From 7766b29c97018a70d1a86476ace680b2ba37a570 Mon Sep 17 00:00:00 2001 From: Pierre de Buyl Date: Mon, 20 Jan 2020 21:54:29 +0100 Subject: [PATCH 54/54] replace strncmp by strcmp --- src/USER-MISC/fix_propel_self.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/USER-MISC/fix_propel_self.cpp b/src/USER-MISC/fix_propel_self.cpp index e8485c48a4..921ce9b9ef 100644 --- a/src/USER-MISC/fix_propel_self.cpp +++ b/src/USER-MISC/fix_propel_self.cpp @@ -63,10 +63,10 @@ FixPropelSelf::FixPropelSelf( LAMMPS *lmp, int narg, char **argv ) const char *mode_str = argv[3]; - if (strncmp(mode_str, "velocity", 8) == 0) { + if (strcmp(mode_str, "velocity") == 0) { mode = VELOCITY; - } else if (strncmp(mode_str, "quat", 4) == 0) { + } else if (strcmp(mode_str, "quat") == 0) { // This mode should only be supported if the atom style has // a quaternion (and if all atoms in the group have it)