From 76e47e855be713499116335fcff8aef1ff9e0a83 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 3 Feb 2014 23:34:58 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@11455 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/fix_vector.cpp | 326 +++++++++++++++++++++++++++++++++++++++++++++ src/fix_vector.h | 151 +++++++++++++++++++++ 2 files changed, 477 insertions(+) create mode 100644 src/fix_vector.cpp create mode 100644 src/fix_vector.h diff --git a/src/fix_vector.cpp b/src/fix_vector.cpp new file mode 100644 index 0000000000..a32ad6a68f --- /dev/null +++ b/src/fix_vector.cpp @@ -0,0 +1,326 @@ +/* ---------------------------------------------------------------------- + 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: Pieter in 't Veld (SNL) +------------------------------------------------------------------------- */ + +#include "string.h" +#include "fix_vector.h" +#include "update.h" +#include "force.h" +#include "modify.h" +#include "compute.h" +#include "group.h" +#include "input.h" +#include "variable.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +enum{COMPUTE,FIX,VARIABLE}; +enum{ONE,RUNNING,WINDOW}; +enum{SCALAR,VECTOR}; + +#define INVOKED_SCALAR 1 +#define INVOKED_VECTOR 2 +#define INVOKED_ARRAY 4 + +/* ---------------------------------------------------------------------- */ + +FixVector::FixVector(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg) +{ + if (narg < 5) error->all(FLERR,"Illegal fix vector command"); + + nevery = force->inumeric(FLERR,arg[3]); + if (nevery <= 0) error->all(FLERR,"Illegal fix vector command"); + + nvalues = narg-4; + which = new int[nvalues]; + argindex = new int[nvalues]; + value2index = new int[nvalues]; + ids = new char*[nvalues]; + + nvalues = 0; + for (int iarg = 4; iarg < narg; iarg++) { + if (arg[iarg][0] == 'c') which[nvalues] = COMPUTE; + else if (arg[iarg][0] == 'f') which[nvalues] = FIX; + else if (arg[iarg][0] == 'v') which[nvalues] = VARIABLE; + else error->all(FLERR,"Illegal fix vector command"); + + int n = strlen(arg[iarg]); + char *suffix = new char[n]; + strcpy(suffix,&arg[iarg][2]); + + char *ptr = strchr(suffix,'['); + if (ptr) { + if (suffix[strlen(suffix)-1] != ']') + error->all(FLERR,"Illegal fix vector command"); + argindex[nvalues] = atoi(ptr+1); + *ptr = '\0'; + } else argindex[nvalues] = 0; + + n = strlen(suffix) + 1; + ids[nvalues] = new char[n]; + strcpy(ids[nvalues],suffix); + delete [] suffix; + + nvalues++; + } + + // setup and error check + // for fix inputs, check that fix frequency is acceptable + + for (int i = 0; i < nvalues; i++) { + if (which[i] == COMPUTE) { + int icompute = modify->find_compute(ids[i]); + if (icompute < 0) + error->all(FLERR,"Compute ID for fix vector does not exist"); + if (argindex[i] == 0 && modify->compute[icompute]->scalar_flag == 0) + error->all(FLERR,"Fix vector compute does not calculate a scalar"); + if (argindex[i] && modify->compute[icompute]->vector_flag == 0) + error->all(FLERR,"Fix vector compute does not calculate a vector"); + if (argindex[i] && argindex[i] > modify->compute[icompute]->size_vector) + error->all(FLERR, + "Fix vector compute vector is accessed out-of-range"); + + } else if (which[i] == FIX) { + int ifix = modify->find_fix(ids[i]); + if (ifix < 0) + error->all(FLERR,"Fix ID for fix vector does not exist"); + if (argindex[i] == 0 && modify->fix[ifix]->scalar_flag == 0) + error->all(FLERR,"Fix vector fix does not calculate a scalar"); + if (argindex[i] && modify->fix[ifix]->vector_flag == 0) + error->all(FLERR,"Fix vector fix does not calculate a vector"); + if (argindex[i] && argindex[i] > modify->fix[ifix]->size_vector) + error->all(FLERR,"Fix vector fix vector is accessed out-of-range"); + if (nevery % modify->fix[ifix]->global_freq) + error->all(FLERR, + "Fix for fix vector not computed at compatible time"); + + } else if (which[i] == VARIABLE) { + int ivariable = input->variable->find(ids[i]); + if (ivariable < 0) + error->all(FLERR,"Variable name for fix vector does not exist"); + if (input->variable->equalstyle(ivariable) == 0) + error->all(FLERR,"Fix vector variable is not equal-style variable"); + } + } + + // this fix produces either a global vector or array + // intensive/extensive flags set by compute,fix,variable that produces value + + global_freq = nevery; + + if (nvalues == 1) { + vector_flag = 1; + if (which[0] == COMPUTE) { + Compute *compute = modify->compute[modify->find_compute(ids[0])]; + if (argindex[0] == 0) extvector = compute->extvector; + else if (compute->extvector >= 0) extvector = compute->extvector; + else extvector = compute->extlist[argindex[0]-1]; + } else if (which[0] == FIX) { + Fix *fix = modify->fix[modify->find_fix(ids[0])]; + if (argindex[0] == 0) extvector = fix->extvector; + else if (fix->extvector >= 0) extvector = fix->extvector; + else extvector = fix->extlist[argindex[0]-1]; + } else if (which[0] == VARIABLE) + extvector = 0; + + } else { + size_array_cols = nvalues; + extarray = -1; + for (int i = 0; i < nvalues; i++) { + if (which[i] == COMPUTE) { + Compute *compute = modify->compute[modify->find_compute(ids[i])]; + if (argindex[i] == 0) extlist[i] = compute->extscalar; + else if (compute->extvector >= 0) extlist[i] = compute->extvector; + else extlist[i] = compute->extlist[argindex[i]-1]; + } else if (which[i] == FIX) { + Fix *fix = modify->fix[modify->find_fix(ids[i])]; + if (argindex[i] == 0) extlist[i] = fix->extscalar; + else if (fix->extvector >= 0) extlist[i] = fix->extvector; + else extlist[i] = fix->extlist[argindex[i]-1]; + } else if (which[i] == VARIABLE) + extlist[i] = 0; + } + } + + // ncount = current size of vector or array + + vector = NULL; + array = NULL; + ncount = 0; + if (nvalues == 1) size_vector = 0; + else size_array_rows = 0; + + // nextstep = next step on which end_of_step does something + // add nextstep to all computes that store invocation times + // since don't know a priori which are invoked by this fix + // once in end_of_step() can set timestep for ones actually invoked + + bigint nextstep = (update->ntimestep/nevery)*nevery; + if (nextstep < update->ntimestep) nextstep += nevery; + modify->addstep_compute_all(nextstep); +} + +/* ---------------------------------------------------------------------- */ + +FixVector::~FixVector() +{ + delete [] which; + delete [] argindex; + delete [] value2index; + for (int i = 0; i < nvalues; i++) delete [] ids[i]; + delete [] ids; + + memory->destroy(vector); + memory->destroy(array); +} + +/* ---------------------------------------------------------------------- */ + +int FixVector::setmask() +{ + int mask = 0; + mask |= END_OF_STEP; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixVector::init() +{ + // set current indices for all computes,fixes,variables + + for (int i = 0; i < nvalues; i++) { + if (which[i] == COMPUTE) { + int icompute = modify->find_compute(ids[i]); + if (icompute < 0) + error->all(FLERR,"Compute ID for fix vector does not exist"); + value2index[i] = icompute; + + } else if (which[i] == FIX) { + int ifix = modify->find_fix(ids[i]); + if (ifix < 0) + error->all(FLERR,"Fix ID for fix vector does not exist"); + value2index[i] = ifix; + + } else if (which[i] == VARIABLE) { + int ivariable = input->variable->find(ids[i]); + if (ivariable < 0) + error->all(FLERR,"Variable name for fix vector does not exist"); + value2index[i] = ivariable; + } + } + + // reallocate vector or array for size at end of run + + int nsize = (update->laststep-update->firststep+1) / nevery; + if (nvalues == 1) memory->grow(vector,ncount+nsize,"vector:vector"); + else memory->grow(array,ncount+nsize,nvalues,"vector:array"); +} + +/* ---------------------------------------------------------------------- + only does something if nvalid = current timestep +------------------------------------------------------------------------- */ + +void FixVector::setup(int vflag) +{ + end_of_step(); +} + +/* ---------------------------------------------------------------------- */ + +void FixVector::end_of_step() +{ + // skip if not step which requires doing something + + if (update->ntimestep % nevery) return; + + // accumulate results of computes,fixes,variables to local copy + // compute/fix/variable may invoke computes so wrap with clear/add + + double *result; + if (nvalues == 1) result = &vector[ncount]; + else result = array[ncount]; + + modify->clearstep_compute(); + + for (int i = 0; i < nvalues; i++) { + int m = value2index[i]; + + // invoke compute if not previously invoked + + if (which[i] == COMPUTE) { + Compute *compute = modify->compute[m]; + + if (argindex[i] == 0) { + if (!(compute->invoked_flag & INVOKED_SCALAR)) { + compute->compute_scalar(); + compute->invoked_flag |= INVOKED_SCALAR; + } + result[i] = compute->scalar; + } else { + if (!(compute->invoked_flag & INVOKED_VECTOR)) { + compute->compute_vector(); + compute->invoked_flag |= INVOKED_VECTOR; + } + result[i] = compute->vector[argindex[i]-1]; + } + + // access fix fields, guaranteed to be ready + + } else if (which[i] == FIX) { + if (argindex[i] == 0) + result[i] = modify->fix[m]->compute_scalar(); + else + result[i] = modify->fix[m]->compute_vector(argindex[i]-1); + + // evaluate equal-style variable + + } else if (which[i] == VARIABLE) + result[i] = input->variable->compute_equal(m); + } + + // trigger computes on next needed step + + modify->addstep_compute(update->ntimestep + nevery); + + // update size of vector or array + + ncount++; + if (nvalues == 1) size_vector++; + else size_array_rows++; +} + +/* ---------------------------------------------------------------------- + return Ith vector value +------------------------------------------------------------------------- */ + +double FixVector::compute_vector(int i) +{ + return vector[i]; +} + +/* ---------------------------------------------------------------------- + return I,J array value +------------------------------------------------------------------------- */ + +double FixVector::compute_array(int i, int j) +{ + return array[i][j]; +} diff --git a/src/fix_vector.h b/src/fix_vector.h new file mode 100644 index 0000000000..4bfed79e0c --- /dev/null +++ b/src/fix_vector.h @@ -0,0 +1,151 @@ +/* ---------------------------------------------------------------------- + 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(vector,FixVector) + +#else + +#ifndef LMP_FIX_VECTOR_H +#define LMP_FIX_VECTOR_H + +#include "stdio.h" +#include "fix.h" + +namespace LAMMPS_NS { + +class FixVector : public Fix { + public: + FixVector(class LAMMPS *, int, char **); + ~FixVector(); + int setmask(); + void init(); + void setup(int); + void end_of_step(); + double compute_vector(int); + double compute_array(int,int); + + private: + int nvalues; + int *which,*argindex,*value2index,*offcol; + char **ids; + + int ncount; // # of values currently in growing vector or array + double *vector; + double **array; +}; + +} + +#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. + +E: Compute ID for fix ave/time does not exist + +Self-explanatory. + +E: Fix ID for fix ave/time does not exist + +Self-explanatory. + +E: Invalid fix ave/time off column + +Self-explantory. + +E: Fix ave/time compute does not calculate a scalar + +Self-explantory. + +E: Fix ave/time compute does not calculate a vector + +Self-explantory. + +E: Fix ave/time compute vector is accessed out-of-range + +The index for the vector is out of bounds. + +E: Fix ave/time compute does not calculate an array + +Self-explanatory. + +E: Fix ave/time compute array is accessed out-of-range + +An index for the array is out of bounds. + +E: Fix ave/time fix does not calculate a scalar + +Self-explanatory. + +E: Fix ave/time fix does not calculate a vector + +Self-explanatory. + +E: Fix ave/time fix vector is accessed out-of-range + +The index for the vector is out of bounds. + +E: Fix for fix ave/time not computed at compatible time + +Fixes generate their values on specific timesteps. Fix ave/time +is requesting a value on a non-allowed timestep. + +E: Fix ave/time fix does not calculate an array + +Self-explanatory. + +E: Fix ave/time fix array is accessed out-of-range + +An index for the array is out of bounds. + +E: Variable name for fix ave/time does not exist + +Self-explanatory. + +E: Fix ave/time variable is not equal-style variable + +Self-explanatory. + +E: Fix ave/time cannot use variable with vector mode + +Variables produce scalar values. + +E: Fix ave/time columns are inconsistent lengths + +Self-explanatory. + +E: Fix ave/time cannot set output array intensive/extensive from these inputs + +One of more of the vector inputs has individual elements which are +flagged as intensive or extensive. Such an input cannot be flagged as +all intensive/extensive when turned into an array by fix ave/time. + +E: Cannot open fix ave/time file %s + +The specified file cannot be opened. Check that the path and name are +correct. + +E: Fix ave/time missed timestep + +You cannot reset the timestep to a value beyond where the fix +expects to next perform averaging. + +*/