From c660dcefd2c6bcf7d6811c158a65b68a85b000d6 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 8 Apr 2021 17:42:32 -0400 Subject: [PATCH] add minimal framework for pair style hybrid/scaled --- src/pair_hybrid_scaled.cpp | 201 +++++++++++++++++++++++++++++++++++++ src/pair_hybrid_scaled.h | 63 ++++++++++++ 2 files changed, 264 insertions(+) create mode 100644 src/pair_hybrid_scaled.cpp create mode 100644 src/pair_hybrid_scaled.h diff --git a/src/pair_hybrid_scaled.cpp b/src/pair_hybrid_scaled.cpp new file mode 100644 index 0000000000..9f3a5d44be --- /dev/null +++ b/src/pair_hybrid_scaled.cpp @@ -0,0 +1,201 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://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. +------------------------------------------------------------------------- */ + +#include "pair_hybrid_scaled.h" + +#include "atom.h" +#include "error.h" +#include "memory.h" + +#include + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +PairHybridScaled::PairHybridScaled(LAMMPS *lmp) : + PairHybrid(lmp), fsum(nullptr), + scaleval(nullptr), scaleidx(nullptr), scalevar(nullptr) +{ + nscalevar = 0; + nmaxfsum = -1; +} + +/* ---------------------------------------------------------------------- */ + +PairHybridScaled::~PairHybridScaled() +{ + for (int i=0; i < nscalevar; ++i) + delete[] scalevar[i]; + delete[] scalevar; + + if (nmaxfsum > 0) + memory->destroy(fsum); + + if (allocated) { + memory->destroy(scaleval); + memory->destroy(scaleidx); + } +} +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairHybridScaled::allocate() +{ + PairHybrid::allocate(); + + const int n = atom->ntypes; + + memory->create(scaleval,n+1,n+1,"pair:scaleval"); + memory->create(scaleidx,n+1,n+1,"pair:scaleidx"); + for (int i = 1; i <= n; i++) { + for (int j = i; j <= n; j++) { + scaleval[i][j] = 0.0; + scaleidx[i][j] = -1; + } + } +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairHybridScaled::coeff(int narg, char **arg) +{ + if (narg < 3) error->all(FLERR,"Incorrect args for pair coefficients"); + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + utils::bounds(FLERR,arg[0],1,atom->ntypes,ilo,ihi,error); + utils::bounds(FLERR,arg[1],1,atom->ntypes,jlo,jhi,error); + + // 3rd arg = scale factor for sub-style, must be either + // a constant or equal stye or compatible variable + + double scale = utils::numeric(FLERR,arg[2],false,lmp); + + // 4th arg = pair sub-style name + // 5th arg = pair sub-style index if name used multiple times + // + // allow for "none" as valid sub-style name + + int multflag; + int m; + + for (m = 0; m < nstyles; m++) { + multflag = 0; + if (strcmp(arg[3],keywords[m]) == 0) { + if (multiple[m]) { + multflag = 1; + if (narg < 5) error->all(FLERR,"Incorrect args for pair coefficients"); + if (multiple[m] == utils::inumeric(FLERR,arg[4],false,lmp)) break; + else continue; + } else break; + } + } + + int none = 0; + if (m == nstyles) { + if (strcmp(arg[3],"none") == 0) none = 1; + else error->all(FLERR,"Pair coeff for hybrid has invalid style"); + } + + // move 1st/2nd args to 3rd/4th args + // if multflag: move 1st/2nd args to 4th/5th args + // just copy ptrs, since arg[] points into original input line + + arg[3+multflag] = arg[1]; + arg[2+multflag] = arg[0]; + + // invoke sub-style coeff() starting with 1st remaining arg + + if (!none) styles[m]->coeff(narg-2-multflag,arg+2+multflag); + + // set setflag and which type pairs map to which sub-style + // if sub-style is none: set hybrid subflag, wipe out map + // else: set hybrid setflag & map only if substyle setflag is set + // if sub-style is new for type pair, add as multiple mapping + // if sub-style exists for type pair, don't add, just update coeffs + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + if (none) { + setflag[i][j] = 1; + nmap[i][j] = 0; + count++; + } else if (styles[m]->setflag[i][j]) { + int k; + for (k = 0; k < nmap[i][j]; k++) + if (map[i][j][k] == m) break; + if (k == nmap[i][j]) map[i][j][nmap[i][j]++] = m; + setflag[i][j] = 1; + scaleval[i][j] = scale; + scaleidx[i][j] = -1; + count++; + } + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + + +/* ---------------------------------------------------------------------- + we need to handle Pair::svector special for hybrid/scaled +------------------------------------------------------------------------- */ + +void PairHybridScaled::init_svector() +{ + // single_extra = list all sub-style single_extra + // allocate svector + + single_extra = 0; + for (int m = 0; m < nstyles; m++) + single_extra += styles[m]->single_extra; + + if (single_extra) { + delete [] svector; + svector = new double[single_extra]; + } +} + +/* ---------------------------------------------------------------------- + we need to handle Pair::svector special for hybrid/scaled +------------------------------------------------------------------------- */ + +void PairHybridScaled::copy_svector(int itype, int jtype) +{ + int n=0; + Pair *this_style; + + // fill svector array. + // copy data from active styles and use 0.0 for inactive ones + for (int m = 0; m < nstyles; m++) { + for (int k = 0; k < nmap[itype][jtype]; ++k) { + if (m == map[itype][jtype][k]) { + this_style = styles[m]; + } else { + this_style = nullptr; + } + } + for (int l = 0; l < styles[m]->single_extra; ++l) { + if (this_style) { + svector[n++] = this_style->svector[l]; + } else { + svector[n++] = 0.0; + } + } + } +} diff --git a/src/pair_hybrid_scaled.h b/src/pair_hybrid_scaled.h new file mode 100644 index 0000000000..d0d2d8838a --- /dev/null +++ b/src/pair_hybrid_scaled.h @@ -0,0 +1,63 @@ +/* -*- 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(hybrid/scaled,PairHybridScaled) + +#else + +#ifndef LMP_PAIR_HYBRID_SCALED_H +#define LMP_PAIR_HYBRID_SCALED_H + +#include "pair_hybrid.h" + +namespace LAMMPS_NS { + +class PairHybridScaled : public PairHybrid { + public: + PairHybridScaled(class LAMMPS *); + virtual ~PairHybridScaled(); + void coeff(int, char **); + //void compute(int, int); + + void init_svector(); + void copy_svector(int,int); + + protected: + double **fsum; + double **scaleval; + int **scaleidx; + char **scalevar; + int nscalevar; + int nmaxfsum; + + void allocate(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Incorrect args for pair coefficients + +Self-explanatory. Check the input script or data file. + +E: Pair coeff for hybrid has invalid style + +Style in pair coeff must have been listed in pair_style command. + +*/