/* ---------------------------------------------------------------------- This is the ██╗ ██╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗████████╗███████╗ ██║ ██║██╔════╝ ██╔════╝ ██╔════╝ ██║ ██║╚══██╔══╝██╔════╝ ██║ ██║██║ ███╗██║ ███╗██║ ███╗███████║ ██║ ███████╗ ██║ ██║██║ ██║██║ ██║██║ ██║██╔══██║ ██║ ╚════██║ ███████╗██║╚██████╔╝╚██████╔╝╚██████╔╝██║ ██║ ██║ ███████║ ╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝® DEM simulation engine, released by DCS Computing Gmbh, Linz, Austria http://www.dcs-computing.com, office@dcs-computing.com LIGGGHTS® is part of CFDEM®project: http://www.liggghts.com | http://www.cfdem.com Core developer and main author: Christoph Kloss, christoph.kloss@dcs-computing.com LIGGGHTS® is open-source, distributed under the terms of the GNU Public License, version 2 or later. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have received a copy of the GNU General Public License along with LIGGGHTS®. If not, see http://www.gnu.org/licenses . See also top-level README and LICENSE files. LIGGGHTS® and CFDEM® are registered trade marks of DCS Computing GmbH, the producer of the LIGGGHTS® software and the CFDEM®coupling software See http://www.cfdem.com/terms-trademark-policy for details. ------------------------------------------------------------------------- Contributing author and copyright for this file: This file is from LAMMPS 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. ------------------------------------------------------------------------- */ #include #include "fix_minimize.h" #include "atom.h" #include "domain.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; using namespace FixConst; /* ---------------------------------------------------------------------- */ FixMinimize::FixMinimize(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { nvector = 0; peratom = NULL; vectors = NULL; // register callback to this fix from Atom class // don't perform initial allocation here, must wait until add_vector() atom->add_callback(0); } /* ---------------------------------------------------------------------- */ FixMinimize::~FixMinimize() { // unregister callbacks to this fix from Atom class atom->delete_callback(id,0); // delete locally stored data memory->destroy(peratom); for (int m = 0; m < nvector; m++) memory->destroy(vectors[m]); memory->sfree(vectors); } /* ---------------------------------------------------------------------- */ int FixMinimize::setmask() { return 0; } /* ---------------------------------------------------------------------- allocate/initialize memory for a new vector with N elements per atom ------------------------------------------------------------------------- */ void FixMinimize::add_vector(int n) { memory->grow(peratom,nvector+1,"minimize:peratom"); peratom[nvector] = n; vectors = (double **) memory->srealloc(vectors,(nvector+1)*sizeof(double *),"minimize:vectors"); memory->create(vectors[nvector],atom->nmax*n,"minimize:vector"); int ntotal = n*atom->nlocal; for (int i = 0; i < ntotal; i++) vectors[nvector][i] = 0.0; nvector++; } /* ---------------------------------------------------------------------- return a pointer to the Mth vector ------------------------------------------------------------------------- */ double *FixMinimize::request_vector(int m) { return vectors[m]; } /* ---------------------------------------------------------------------- store box size at beginning of line search ------------------------------------------------------------------------- */ void FixMinimize::store_box() { boxlo[0] = domain->boxlo[0]; boxlo[1] = domain->boxlo[1]; boxlo[2] = domain->boxlo[2]; boxhi[0] = domain->boxhi[0]; boxhi[1] = domain->boxhi[1]; boxhi[2] = domain->boxhi[2]; } /* ---------------------------------------------------------------------- reset x0 for atoms that moved across PBC via reneighboring in line search x0 = 1st vector must do minimum_image using original box stored at beginning of line search swap & set_global_box() change to original box, then restore current box ------------------------------------------------------------------------- */ void FixMinimize::reset_coords() { box_swap(); domain->set_global_box(); double **x = atom->x; double *x0 = vectors[0]; int nlocal = atom->nlocal; double dx,dy,dz,dx0,dy0,dz0; int n = 0; for (int i = 0; i < nlocal; i++) { dx = dx0 = x[i][0] - x0[n]; dy = dy0 = x[i][1] - x0[n+1]; dz = dz0 = x[i][2] - x0[n+2]; domain->minimum_image(dx,dy,dz); if (dx != dx0) x0[n] = x[i][0] - dx; if (dy != dy0) x0[n+1] = x[i][1] - dy; if (dz != dz0) x0[n+2] = x[i][2] - dz; n += 3; } box_swap(); domain->set_global_box(); } /* ---------------------------------------------------------------------- swap current box size with stored box size ------------------------------------------------------------------------- */ void FixMinimize::box_swap() { double tmp; tmp = boxlo[0]; boxlo[0] = domain->boxlo[0]; domain->boxlo[0] = tmp; tmp = boxlo[1]; boxlo[1] = domain->boxlo[1]; domain->boxlo[1] = tmp; tmp = boxlo[2]; boxlo[2] = domain->boxlo[2]; domain->boxlo[2] = tmp; tmp = boxhi[0]; boxhi[0] = domain->boxhi[0]; domain->boxhi[0] = tmp; tmp = boxhi[1]; boxhi[1] = domain->boxhi[1]; domain->boxhi[1] = tmp; tmp = boxhi[2]; boxhi[2] = domain->boxhi[2]; domain->boxhi[2] = tmp; } /* ---------------------------------------------------------------------- memory usage of local atom-based arrays ------------------------------------------------------------------------- */ double FixMinimize::memory_usage() { double bytes = 0.0; for (int m = 0; m < nvector; m++) bytes += atom->nmax*peratom[m]*sizeof(double); return bytes; } /* ---------------------------------------------------------------------- allocate local atom-based arrays ------------------------------------------------------------------------- */ void FixMinimize::grow_arrays(int nmax) { for (int m = 0; m < nvector; m++) memory->grow(vectors[m],peratom[m]*nmax,"minimize:vector"); } /* ---------------------------------------------------------------------- copy values within local atom-based arrays ------------------------------------------------------------------------- */ void FixMinimize::copy_arrays(int i, int j, int delflag) { int m,iper,nper,ni,nj; for (m = 0; m < nvector; m++) { nper = peratom[m]; ni = nper*i; nj = nper*j; for (iper = 0; iper < nper; iper++) vectors[m][nj++] = vectors[m][ni++]; } } /* ---------------------------------------------------------------------- pack values in local atom-based arrays for exchange with another proc ------------------------------------------------------------------------- */ int FixMinimize::pack_exchange(int i, double *buf) { int m,iper,nper,ni; int n = 0; for (m = 0; m < nvector; m++) { nper = peratom[m]; ni = nper*i; for (iper = 0; iper < nper; iper++) buf[n++] = vectors[m][ni++]; } return n; } /* ---------------------------------------------------------------------- unpack values in local atom-based arrays from exchange with another proc ------------------------------------------------------------------------- */ int FixMinimize::unpack_exchange(int nlocal, double *buf) { int m,iper,nper,ni; int n = 0; for (m = 0; m < nvector; m++) { nper = peratom[m]; ni = nper*nlocal; for (iper = 0; iper < nper; iper++) vectors[m][ni++] = buf[n++]; } return n; }