git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@322 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
@ -50,7 +50,8 @@ class Ewald : public KSpace {
|
|||||||
void slabcorr(int);
|
void slabcorr(int);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -23,15 +23,15 @@ class Compute : protected Pointers {
|
|||||||
char *id,*style;
|
char *id,*style;
|
||||||
int igroup,groupbit;
|
int igroup,groupbit;
|
||||||
|
|
||||||
double scalar; // computed scalar
|
double scalar; // computed global scalar
|
||||||
double *vector; // computed vector
|
double *vector; // computed global vector
|
||||||
double *scalar_atom; // computed per-atom scalar
|
double *scalar_atom; // computed per-atom scalar
|
||||||
double **vector_atom; // computed per-atom vector
|
double **vector_atom; // computed per-atom vector
|
||||||
|
|
||||||
int scalar_flag; // 0/1 if compute_scalar() function exists
|
int scalar_flag; // 0/1 if compute_scalar() function exists
|
||||||
int vector_flag; // 0/1 if compute_vector() function exists
|
int vector_flag; // 0/1 if compute_vector() function exists
|
||||||
int peratom_flag; // 0/1 if compute_peratom() function exists
|
int peratom_flag; // 0/1 if compute_peratom() function exists
|
||||||
int size_vector; // N = size of vector
|
int size_vector; // N = size of global vector
|
||||||
int size_peratom; // 0 = just scalar_atom, N = size of vector_atom
|
int size_peratom; // 0 = just scalar_atom, N = size of vector_atom
|
||||||
|
|
||||||
int extensive; // 0/1 if scalar,vector are intensive/extensive values
|
int extensive; // 0/1 if scalar,vector are intensive/extensive values
|
||||||
|
|||||||
@ -37,6 +37,7 @@ Fix::Fix(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
|
|||||||
restart_peratom = 0;
|
restart_peratom = 0;
|
||||||
force_reneighbor = 0;
|
force_reneighbor = 0;
|
||||||
thermo_energy = 0;
|
thermo_energy = 0;
|
||||||
|
pressure_every = 0;
|
||||||
|
|
||||||
comm_forward = comm_reverse = 0;
|
comm_forward = comm_reverse = 0;
|
||||||
neigh_half_once = neigh_half_every = 0;
|
neigh_half_once = neigh_half_every = 0;
|
||||||
@ -55,6 +56,7 @@ Fix::Fix(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
|
|||||||
POST_FORCE_RESPA = 256;
|
POST_FORCE_RESPA = 256;
|
||||||
FINAL_INTEGRATE_RESPA = 512;
|
FINAL_INTEGRATE_RESPA = 512;
|
||||||
MIN_POST_FORCE = 1024;
|
MIN_POST_FORCE = 1024;
|
||||||
|
MIN_ENERGY = 2048;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|||||||
@ -29,6 +29,7 @@ class Fix : protected Pointers {
|
|||||||
int next_reneighbor; // next timestep to force a reneighboring
|
int next_reneighbor; // next timestep to force a reneighboring
|
||||||
int thermo_energy; // 1 if ThEng enabled via fix_modify, 0 if not
|
int thermo_energy; // 1 if ThEng enabled via fix_modify, 0 if not
|
||||||
int nevery; // how often to call an end_of_step fix
|
int nevery; // how often to call an end_of_step fix
|
||||||
|
int pressure_every; // how often fix needs virial computed
|
||||||
|
|
||||||
int comm_forward; // size of forward communication (0 if none)
|
int comm_forward; // size of forward communication (0 if none)
|
||||||
int comm_reverse; // size of reverse communication (0 if none)
|
int comm_reverse; // size of reverse communication (0 if none)
|
||||||
@ -42,7 +43,7 @@ class Fix : protected Pointers {
|
|||||||
int INITIAL_INTEGRATE,PRE_EXCHANGE,PRE_NEIGHBOR; // mask settings
|
int INITIAL_INTEGRATE,PRE_EXCHANGE,PRE_NEIGHBOR; // mask settings
|
||||||
int POST_FORCE,FINAL_INTEGRATE,END_OF_STEP,THERMO_ENERGY;
|
int POST_FORCE,FINAL_INTEGRATE,END_OF_STEP,THERMO_ENERGY;
|
||||||
int INITIAL_INTEGRATE_RESPA,POST_FORCE_RESPA,FINAL_INTEGRATE_RESPA;
|
int INITIAL_INTEGRATE_RESPA,POST_FORCE_RESPA,FINAL_INTEGRATE_RESPA;
|
||||||
int MIN_POST_FORCE;
|
int MIN_POST_FORCE,MIN_ENERGY;
|
||||||
|
|
||||||
Fix(class LAMMPS *, int, char **);
|
Fix(class LAMMPS *, int, char **);
|
||||||
virtual ~Fix();
|
virtual ~Fix();
|
||||||
@ -76,6 +77,9 @@ class Fix : protected Pointers {
|
|||||||
virtual void final_integrate_respa(int) {}
|
virtual void final_integrate_respa(int) {}
|
||||||
|
|
||||||
virtual void min_post_force(int) {}
|
virtual void min_post_force(int) {}
|
||||||
|
virtual double min_energy(double *, double *) {return 0.0;}
|
||||||
|
virtual int min_dof() {return 0;}
|
||||||
|
virtual void min_xinitial(double *) {}
|
||||||
|
|
||||||
virtual int pack_comm(int, int *, double *, int *) {return 0;}
|
virtual int pack_comm(int, int *, double *, int *) {return 0;}
|
||||||
virtual void unpack_comm(int, int, double *) {}
|
virtual void unpack_comm(int, int, double *) {}
|
||||||
|
|||||||
@ -44,6 +44,7 @@ FixNPH::FixNPH(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
if (narg < 4) error->all("Illegal fix nph command");
|
if (narg < 4) error->all("Illegal fix nph command");
|
||||||
|
|
||||||
restart_global = 1;
|
restart_global = 1;
|
||||||
|
pressure_every = 1;
|
||||||
|
|
||||||
double p_period[3];
|
double p_period[3];
|
||||||
if (strcmp(arg[3],"xyz") == 0) {
|
if (strcmp(arg[3],"xyz") == 0) {
|
||||||
|
|||||||
@ -44,6 +44,7 @@ FixNPT::FixNPT(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
if (narg < 7) error->all("Illegal fix npt command");
|
if (narg < 7) error->all("Illegal fix npt command");
|
||||||
|
|
||||||
restart_global = 1;
|
restart_global = 1;
|
||||||
|
pressure_every = 1;
|
||||||
|
|
||||||
t_start = atof(arg[3]);
|
t_start = atof(arg[3]);
|
||||||
t_stop = atof(arg[4]);
|
t_stop = atof(arg[4]);
|
||||||
|
|||||||
@ -47,6 +47,7 @@ using namespace LAMMPS_NS;
|
|||||||
#define POST_FORCE_RESPA 256
|
#define POST_FORCE_RESPA 256
|
||||||
#define FINAL_INTEGRATE_RESPA 512
|
#define FINAL_INTEGRATE_RESPA 512
|
||||||
#define MIN_POST_FORCE 1024
|
#define MIN_POST_FORCE 1024
|
||||||
|
#define MIN_ENERGY 2048
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ Modify::Modify(LAMMPS *lmp) : Pointers(lmp)
|
|||||||
n_pre_exchange = n_pre_neighbor = 0;
|
n_pre_exchange = n_pre_neighbor = 0;
|
||||||
n_post_force = n_final_integrate = n_end_of_step = n_thermo_energy = 0;
|
n_post_force = n_final_integrate = n_end_of_step = n_thermo_energy = 0;
|
||||||
n_initial_integrate_respa = n_post_force_respa = n_final_integrate_respa = 0;
|
n_initial_integrate_respa = n_post_force_respa = n_final_integrate_respa = 0;
|
||||||
n_min_post_force = 0;
|
n_min_post_force = n_min_energy = 0;
|
||||||
|
|
||||||
fix = NULL;
|
fix = NULL;
|
||||||
fmask = NULL;
|
fmask = NULL;
|
||||||
@ -67,7 +68,7 @@ Modify::Modify(LAMMPS *lmp) : Pointers(lmp)
|
|||||||
list_thermo_energy = NULL;
|
list_thermo_energy = NULL;
|
||||||
list_initial_integrate_respa = list_post_force_respa = NULL;
|
list_initial_integrate_respa = list_post_force_respa = NULL;
|
||||||
list_final_integrate_respa = NULL;
|
list_final_integrate_respa = NULL;
|
||||||
list_min_post_force = NULL;
|
list_min_post_force = list_min_energy = NULL;
|
||||||
|
|
||||||
end_of_step_every = NULL;
|
end_of_step_every = NULL;
|
||||||
|
|
||||||
@ -103,6 +104,7 @@ Modify::~Modify()
|
|||||||
delete [] list_post_force_respa;
|
delete [] list_post_force_respa;
|
||||||
delete [] list_final_integrate_respa;
|
delete [] list_final_integrate_respa;
|
||||||
delete [] list_min_post_force;
|
delete [] list_min_post_force;
|
||||||
|
delete [] list_min_energy;
|
||||||
|
|
||||||
delete [] end_of_step_every;
|
delete [] end_of_step_every;
|
||||||
|
|
||||||
@ -149,6 +151,7 @@ void Modify::init()
|
|||||||
n_final_integrate_respa,list_final_integrate_respa);
|
n_final_integrate_respa,list_final_integrate_respa);
|
||||||
|
|
||||||
list_init(MIN_POST_FORCE,n_min_post_force,list_min_post_force);
|
list_init(MIN_POST_FORCE,n_min_post_force,list_min_post_force);
|
||||||
|
list_init(MIN_ENERGY,n_min_energy,list_min_energy);
|
||||||
|
|
||||||
// init each compute
|
// init each compute
|
||||||
|
|
||||||
@ -283,6 +286,50 @@ void Modify::min_post_force(int vflag)
|
|||||||
fix[list_min_post_force[i]]->min_post_force(vflag);
|
fix[list_min_post_force[i]]->min_post_force(vflag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
minimizer energy, force evaluation only for relevant fixes
|
||||||
|
return energy and forces on extra degrees of freedom
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
double Modify::min_energy(double *xextra, double *fextra)
|
||||||
|
{
|
||||||
|
int ifix,index;
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
double energy_extra = 0.0;
|
||||||
|
for (int i = 0; i < n_min_energy; i++) {
|
||||||
|
ifix = list_min_energy[i];
|
||||||
|
energy_extra += fix[ifix]->min_energy(&xextra[index],&fextra[index]);
|
||||||
|
index += fix[ifix]->min_dof();
|
||||||
|
}
|
||||||
|
return energy_extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
minimizer extra degrees of freedom from relevant fixes
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int Modify::min_dof()
|
||||||
|
{
|
||||||
|
int ndof = 0;
|
||||||
|
for (int i = 0; i < n_min_energy; i++)
|
||||||
|
ndof += fix[list_min_energy[i]]->min_dof();
|
||||||
|
return ndof;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
minimizer initial xextra values only from relevant fixes
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void Modify::min_xinitial(double *xextra)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
for (int i = 0; i < n_min_energy; i++) {
|
||||||
|
fix[list_min_energy[i]]->min_xinitial(&xextra[index]);
|
||||||
|
index += fix[list_min_energy[i]]->min_dof();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
add a new fix or replace one with same ID
|
add a new fix or replace one with same ID
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|||||||
@ -25,7 +25,7 @@ class Modify : protected Pointers {
|
|||||||
int n_initial_integrate,n_pre_decide,n_pre_exchange,n_pre_neighbor;
|
int n_initial_integrate,n_pre_decide,n_pre_exchange,n_pre_neighbor;
|
||||||
int n_post_force,n_final_integrate,n_end_of_step,n_thermo_energy;
|
int n_post_force,n_final_integrate,n_end_of_step,n_thermo_energy;
|
||||||
int n_initial_integrate_respa,n_post_force_respa,n_final_integrate_respa;
|
int n_initial_integrate_respa,n_post_force_respa,n_final_integrate_respa;
|
||||||
int n_min_post_force;
|
int n_min_post_force,n_min_energy;
|
||||||
int nfix_restart_peratom;
|
int nfix_restart_peratom;
|
||||||
|
|
||||||
class Fix **fix; // list of fixes
|
class Fix **fix; // list of fixes
|
||||||
@ -52,6 +52,9 @@ class Modify : protected Pointers {
|
|||||||
void final_integrate_respa(int);
|
void final_integrate_respa(int);
|
||||||
|
|
||||||
void min_post_force(int);
|
void min_post_force(int);
|
||||||
|
double min_energy(double *, double *);
|
||||||
|
int min_dof();
|
||||||
|
void min_xinitial(double *);
|
||||||
|
|
||||||
void add_fix(int, char **);
|
void add_fix(int, char **);
|
||||||
void modify_fix(int, char **);
|
void modify_fix(int, char **);
|
||||||
@ -77,7 +80,7 @@ class Modify : protected Pointers {
|
|||||||
int *list_thermo_energy;
|
int *list_thermo_energy;
|
||||||
int *list_initial_integrate_respa,*list_post_force_respa;
|
int *list_initial_integrate_respa,*list_post_force_respa;
|
||||||
int *list_final_integrate_respa;
|
int *list_final_integrate_respa;
|
||||||
int *list_min_post_force;
|
int *list_min_post_force,*list_min_energy;
|
||||||
|
|
||||||
int *end_of_step_every;
|
int *end_of_step_every;
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,9 @@
|
|||||||
|
|
||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
|
|
||||||
|
#define MIN(A,B) ((A) < (B)) ? (A) : (B)
|
||||||
|
#define MAX(A,B) ((A) > (B)) ? (A) : (B)
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg)
|
Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg)
|
||||||
@ -273,25 +276,30 @@ void Respa::init()
|
|||||||
if (force->pair && force->pair->respa_enable == 0)
|
if (force->pair && force->pair->respa_enable == 0)
|
||||||
error->all("Pair style does not support rRESPA inner/middle/outer");
|
error->all("Pair style does not support rRESPA inner/middle/outer");
|
||||||
|
|
||||||
// set flags for how virial should be computed when needed
|
// setup virial computations for timestepping
|
||||||
// pressure_flag is 1 if NPT,NPH
|
// virial_style = 1 (explicit) since never computed implicitly like Verlet
|
||||||
// virial_every is how virial should be computed every timestep
|
// virial_every = 1 if computed every timestep (NPT,NPH)
|
||||||
// 0 = not computed, 1 = computed explicity by pair
|
// fix arrays store info on fixes that need virial computed occasionally
|
||||||
// virial_thermo is how virial should be computed on thermo timesteps
|
|
||||||
// 1 = computed explicity by pair
|
|
||||||
// unlike Verlet, virial is never computed implicitly
|
|
||||||
|
|
||||||
int pressure_flag = 0;
|
virial_style = 1;
|
||||||
for (int i = 0; i < modify->nfix; i++) {
|
|
||||||
if (strcmp(modify->fix[i]->style,"npt") == 0) pressure_flag = 1;
|
virial_every = 0;
|
||||||
if (strcmp(modify->fix[i]->style,"nph") == 0) pressure_flag = 1;
|
nfix_virial = 0;
|
||||||
|
for (int i = 0; i < modify->nfix; i++)
|
||||||
|
if (modify->fix[i]->pressure_every == 1) virial_every = 1;
|
||||||
|
else if (modify->fix[i]->pressure_every > 1) nfix_virial++;
|
||||||
|
|
||||||
|
if (nfix_virial) {
|
||||||
|
delete [] fix_virial_every;
|
||||||
|
delete [] next_fix_virial;
|
||||||
|
fix_virial_every = new int[nfix_virial];
|
||||||
|
next_fix_virial = new int[nfix_virial];
|
||||||
|
nfix_virial = 0;
|
||||||
|
for (int i = 0; i < modify->nfix; i++)
|
||||||
|
if (modify->fix[i]->pressure_every > 1)
|
||||||
|
fix_virial_every[nfix_virial++] = modify->fix[i]->pressure_every;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pressure_flag) virial_every = 1;
|
|
||||||
else virial_every = 0;
|
|
||||||
|
|
||||||
virial_thermo = 1;
|
|
||||||
|
|
||||||
// step[] = timestep for each level
|
// step[] = timestep for each level
|
||||||
|
|
||||||
step[nlevels-1] = update->dt;
|
step[nlevels-1] = update->dt;
|
||||||
@ -338,8 +346,8 @@ void Respa::setup()
|
|||||||
|
|
||||||
// compute all forces
|
// compute all forces
|
||||||
|
|
||||||
int eflag = 1;
|
eflag = 1;
|
||||||
int vflag = virial_thermo;
|
vflag = virial_style;
|
||||||
|
|
||||||
for (int ilevel = 0; ilevel < nlevels; ilevel++) {
|
for (int ilevel = 0; ilevel < nlevels; ilevel++) {
|
||||||
force_clear(newton[ilevel]);
|
force_clear(newton[ilevel]);
|
||||||
@ -370,6 +378,21 @@ void Respa::setup()
|
|||||||
modify->setup();
|
modify->setup();
|
||||||
sum_flevel_f();
|
sum_flevel_f();
|
||||||
output->setup(1);
|
output->setup(1);
|
||||||
|
|
||||||
|
// setup virial computations for timestepping
|
||||||
|
|
||||||
|
int ntimestep = update->ntimestep;
|
||||||
|
next_virial = 0;
|
||||||
|
if (virial_every) next_virial = ntimestep + 1;
|
||||||
|
else {
|
||||||
|
for (int ivirial = 0; ivirial < nfix_virial; ivirial++) {
|
||||||
|
next_fix_virial[ivirial] =
|
||||||
|
(ntimestep/fix_virial_every[ivirial])*fix_virial_every[ivirial] +
|
||||||
|
fix_virial_every[ivirial];
|
||||||
|
if (ivirial) next_virial = MIN(next_virial,next_fix_virial[ivirial]);
|
||||||
|
else next_virial = next_fix_virial[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
@ -378,22 +401,28 @@ void Respa::setup()
|
|||||||
|
|
||||||
void Respa::iterate(int n)
|
void Respa::iterate(int n)
|
||||||
{
|
{
|
||||||
|
int ntimestep;
|
||||||
|
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
|
|
||||||
update->ntimestep++;
|
ntimestep = ++update->ntimestep;
|
||||||
|
|
||||||
eflag = 0;
|
// eflag/vflag = 0/1 for energy/virial computation
|
||||||
vflag = virial_every;
|
|
||||||
if (output->next_thermo == update->ntimestep) {
|
if (ntimestep == output->next_thermo) eflag = 1;
|
||||||
eflag = 1;
|
else eflag = 0;
|
||||||
vflag = virial_thermo;
|
|
||||||
}
|
if (ntimestep == output->next_thermo || ntimestep == next_virial) {
|
||||||
|
vflag = virial_style;
|
||||||
|
if (virial_every) next_virial++;
|
||||||
|
else next_virial = fix_virial(ntimestep);
|
||||||
|
} else vflag = 0;
|
||||||
|
|
||||||
recurse(nlevels-1);
|
recurse(nlevels-1);
|
||||||
|
|
||||||
if (modify->n_end_of_step) modify->end_of_step();
|
if (modify->n_end_of_step) modify->end_of_step();
|
||||||
|
|
||||||
if (output->next == update->ntimestep) {
|
if (ntimestep == output->next) {
|
||||||
timer->stamp();
|
timer->stamp();
|
||||||
sum_flevel_f();
|
sum_flevel_f();
|
||||||
output->write(update->ntimestep);
|
output->write(update->ntimestep);
|
||||||
@ -582,3 +611,20 @@ void Respa::sum_flevel_f()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
return next timestep virial should be computed
|
||||||
|
based on one or more fixes that need virial computed periodically
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int Respa::fix_virial(int ntimestep)
|
||||||
|
{
|
||||||
|
int next;
|
||||||
|
for (int ivirial = 0; ivirial < nfix_virial; ivirial++) {
|
||||||
|
if (ntimestep == next_fix_virial[ivirial])
|
||||||
|
next_fix_virial[ivirial] += fix_virial_every[ivirial];
|
||||||
|
if (ivirial) next = MIN(next,next_fix_virial[ivirial]);
|
||||||
|
else next = next_fix_virial[0];
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|||||||
11
src/respa.h
11
src/respa.h
@ -44,16 +44,21 @@ class Respa : public Integrate {
|
|||||||
void copy_flevel_f(int);
|
void copy_flevel_f(int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int virial_every; // what vflag should be on every timestep (0,1)
|
int eflag,vflag; // flags for energy/virial computation
|
||||||
int virial_thermo; // what vflag should be on thermo steps (1)
|
int virial_style; // compute virial explicitly (not implicit)
|
||||||
|
int virial_every; // 1 if virial computed every step
|
||||||
|
int next_virial; // next timestep to compute virial
|
||||||
|
int nfix_virial; // # of fixes that need virial occasionally
|
||||||
|
int *fix_virial_every; // frequency they require it
|
||||||
|
int *next_fix_virial; // next timestep they need it
|
||||||
|
|
||||||
int *newton; // newton flag at each level
|
int *newton; // newton flag at each level
|
||||||
int eflag,vflag; // flags for energy/virial computation
|
|
||||||
class FixRespa *fix_respa; // Fix to store the force level array
|
class FixRespa *fix_respa; // Fix to store the force level array
|
||||||
|
|
||||||
void recurse(int);
|
void recurse(int);
|
||||||
void force_clear(int);
|
void force_clear(int);
|
||||||
void sum_flevel_f();
|
void sum_flevel_f();
|
||||||
|
int fix_virial(int);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -84,6 +84,7 @@ CommandStyle(write_restart,WriteRestart)
|
|||||||
#include "compute_temp_partial.h"
|
#include "compute_temp_partial.h"
|
||||||
#include "compute_temp_ramp.h"
|
#include "compute_temp_ramp.h"
|
||||||
#include "compute_temp_region.h"
|
#include "compute_temp_region.h"
|
||||||
|
#include "compute_variable_atom.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ComputeClass
|
#ifdef ComputeClass
|
||||||
@ -99,6 +100,7 @@ ComputeStyle(temp,ComputeTemp)
|
|||||||
ComputeStyle(temp/partial,ComputeTempPartial)
|
ComputeStyle(temp/partial,ComputeTempPartial)
|
||||||
ComputeStyle(temp/ramp,ComputeTempRamp)
|
ComputeStyle(temp/ramp,ComputeTempRamp)
|
||||||
ComputeStyle(temp/region,ComputeTempRegion)
|
ComputeStyle(temp/region,ComputeTempRegion)
|
||||||
|
ComputeStyle(variable/atom,ComputeVariableAtom)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DihedralInclude
|
#ifdef DihedralInclude
|
||||||
@ -124,6 +126,9 @@ DumpStyle(xyz,DumpXYZ)
|
|||||||
#ifdef FixInclude
|
#ifdef FixInclude
|
||||||
#include "fix_add_force.h"
|
#include "fix_add_force.h"
|
||||||
#include "fix_ave_force.h"
|
#include "fix_ave_force.h"
|
||||||
|
#include "fix_ave_spatial.h"
|
||||||
|
#include "fix_ave_time.h"
|
||||||
|
//#include "fix_box_relax.h"
|
||||||
#include "fix_com.h"
|
#include "fix_com.h"
|
||||||
#include "fix_drag.h"
|
#include "fix_drag.h"
|
||||||
#include "fix_deposit.h"
|
#include "fix_deposit.h"
|
||||||
@ -168,6 +173,9 @@ DumpStyle(xyz,DumpXYZ)
|
|||||||
#ifdef FixClass
|
#ifdef FixClass
|
||||||
FixStyle(addforce,FixAddForce)
|
FixStyle(addforce,FixAddForce)
|
||||||
FixStyle(aveforce,FixAveForce)
|
FixStyle(aveforce,FixAveForce)
|
||||||
|
FixStyle(ave/spatial,FixAveSpatial)
|
||||||
|
FixStyle(ave/time,FixAveTime)
|
||||||
|
//FixStyle(box/relax,FixBoxRelax)
|
||||||
FixStyle(com,FixCOM)
|
FixStyle(com,FixCOM)
|
||||||
FixStyle(drag,FixDrag)
|
FixStyle(drag,FixDrag)
|
||||||
FixStyle(deposit,FixDeposit)
|
FixStyle(deposit,FixDeposit)
|
||||||
|
|||||||
417
src/variable.cpp
417
src/variable.cpp
@ -33,7 +33,8 @@ using namespace LAMMPS_NS;
|
|||||||
|
|
||||||
#define VARDELTA 4
|
#define VARDELTA 4
|
||||||
|
|
||||||
enum{INDEX,LOOP,EQUAL,WORLD,UNIVERSE,ULOOP};
|
enum{INDEX,LOOP,EQUAL,WORLD,UNIVERSE,ULOOP,ATOM};
|
||||||
|
enum{VALUE,ATOMARRAY,TYPEARRAY,ADD,SUB,MULT,DIV,NEG,POW,EXP,LN,SQRT};
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
@ -73,9 +74,9 @@ void Variable::set(int narg, char **arg)
|
|||||||
{
|
{
|
||||||
if (narg < 3) error->all("Illegal variable command");
|
if (narg < 3) error->all("Illegal variable command");
|
||||||
|
|
||||||
// if var already exists, just skip (except EQUAL vars)
|
// if var already exists, just skip
|
||||||
|
|
||||||
if (find(arg[0]) >= 0 && strcmp(arg[1],"equal") != 0) return;
|
if (find(arg[0]) >= 0) return;
|
||||||
|
|
||||||
// make space for new variable
|
// make space for new variable
|
||||||
|
|
||||||
@ -90,6 +91,11 @@ void Variable::set(int narg, char **arg)
|
|||||||
memory->srealloc(data,maxvar*sizeof(char **),"var:data");
|
memory->srealloc(data,maxvar*sizeof(char **),"var:data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set name of variable
|
||||||
|
|
||||||
|
names[nvar] = new char[strlen(arg[0]) + 1];
|
||||||
|
strcpy(names[nvar],arg[0]);
|
||||||
|
|
||||||
// INDEX
|
// INDEX
|
||||||
// num = listed args, index = 1st value, data = copied args
|
// num = listed args, index = 1st value, data = copied args
|
||||||
|
|
||||||
@ -111,16 +117,10 @@ void Variable::set(int narg, char **arg)
|
|||||||
for (int i = 0; i < num[nvar]; i++) data[nvar][i] = NULL;
|
for (int i = 0; i < num[nvar]; i++) data[nvar][i] = NULL;
|
||||||
|
|
||||||
// EQUAL
|
// EQUAL
|
||||||
// remove pre-existing var if also style EQUAL (allows it to be reset)
|
|
||||||
// num = 2, index = 1st value
|
// num = 2, index = 1st value
|
||||||
// data = 2 values, 1st is string to eval, 2nd is filled on retrieval
|
// data = 2 values, 1st is string to eval, 2nd is filled on retrieval
|
||||||
|
|
||||||
} else if (strcmp(arg[1],"equal") == 0) {
|
} else if (strcmp(arg[1],"equal") == 0) {
|
||||||
if (find(arg[0]) >= 0) {
|
|
||||||
if (style[find(arg[0])] != EQUAL)
|
|
||||||
error->all("Cannot redefine variable as a different style");
|
|
||||||
remove(find(arg[0]));
|
|
||||||
}
|
|
||||||
style[nvar] = EQUAL;
|
style[nvar] = EQUAL;
|
||||||
num[nvar] = 2;
|
num[nvar] = 2;
|
||||||
index[nvar] = 0;
|
index[nvar] = 0;
|
||||||
@ -187,17 +187,24 @@ void Variable::set(int narg, char **arg)
|
|||||||
arg[0],index[nvar]+1,universe->iworld);
|
arg[0],index[nvar]+1,universe->iworld);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ATOM
|
||||||
|
// num = 1, index = 1st value
|
||||||
|
// data = 1 value, string to eval
|
||||||
|
|
||||||
|
} else if (strcmp(arg[1],"atom") == 0) {
|
||||||
|
style[nvar] = ATOM;
|
||||||
|
num[nvar] = 1;
|
||||||
|
index[nvar] = 0;
|
||||||
|
data[nvar] = new char*[num[nvar]];
|
||||||
|
copy(1,&arg[2],data[nvar]);
|
||||||
|
|
||||||
} else error->all("Illegal variable command");
|
} else error->all("Illegal variable command");
|
||||||
|
|
||||||
// set variable name (after possible EQUAL remove)
|
|
||||||
|
|
||||||
names[nvar] = new char[strlen(arg[0]) + 1];
|
|
||||||
strcpy(names[nvar],arg[0]);
|
|
||||||
nvar++;
|
nvar++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
single-value INDEX variable created by command-line argument
|
single-value EQUAL variable created by command-line argument
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Variable::set(char *name, char *value)
|
void Variable::set(char *name, char *value)
|
||||||
@ -205,25 +212,12 @@ void Variable::set(char *name, char *value)
|
|||||||
int ivar = find(name);
|
int ivar = find(name);
|
||||||
if (ivar >= 0) error->all("Command-line variable already exists");
|
if (ivar >= 0) error->all("Command-line variable already exists");
|
||||||
|
|
||||||
if (nvar == maxvar) {
|
char **newarg = new char*[3];
|
||||||
maxvar += VARDELTA;
|
newarg[0] = name;
|
||||||
names = (char **)
|
newarg[1] = "equal";
|
||||||
memory->srealloc(names,maxvar*sizeof(char *),"var:names");
|
newarg[2] = value;
|
||||||
style = (int *) memory->srealloc(style,maxvar*sizeof(int),"var:style");
|
set(3,newarg);
|
||||||
num = (int *) memory->srealloc(num,maxvar*sizeof(int),"var:num");
|
delete [] newarg;
|
||||||
index = (int *) memory->srealloc(index,maxvar*sizeof(int),"var:index");
|
|
||||||
data = (char ***)
|
|
||||||
memory->srealloc(data,maxvar*sizeof(char **),"var:data");
|
|
||||||
}
|
|
||||||
|
|
||||||
names[nvar] = new char[strlen(name) + 1];
|
|
||||||
strcpy(names[nvar],name);
|
|
||||||
style[nvar] = INDEX;
|
|
||||||
num[nvar] = 1;
|
|
||||||
index[nvar] = 0;
|
|
||||||
data[nvar] = new char*[num[nvar]];
|
|
||||||
copy(1,&value,data[nvar]);
|
|
||||||
nvar++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
@ -247,10 +241,10 @@ int Variable::next(int narg, char **arg)
|
|||||||
error->all("All variables in next command must be same style");
|
error->all("All variables in next command must be same style");
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for invalid styles EQUAL or WORLD
|
// invalid styles EQUAL or WORLD or ATOM
|
||||||
|
|
||||||
int istyle = style[find(arg[0])];
|
int istyle = style[find(arg[0])];
|
||||||
if (istyle == EQUAL || istyle == WORLD)
|
if (istyle == EQUAL || istyle == WORLD || istyle == ATOM)
|
||||||
error->all("Invalid variable style with next command");
|
error->all("Invalid variable style with next command");
|
||||||
|
|
||||||
// increment all variables in list
|
// increment all variables in list
|
||||||
@ -336,14 +330,16 @@ char *Variable::retrieve(char *name)
|
|||||||
delete [] value;
|
delete [] value;
|
||||||
str = data[ivar][0];
|
str = data[ivar][0];
|
||||||
} else if (style[ivar] == EQUAL) {
|
} else if (style[ivar] == EQUAL) {
|
||||||
char *value = evaluate(data[ivar][0]);
|
char result[32];
|
||||||
int n = strlen(value) + 1;
|
double answer = evaluate(data[ivar][0],NULL);
|
||||||
|
sprintf(result,"%.10g",answer);
|
||||||
|
int n = strlen(result) + 1;
|
||||||
if (data[ivar][1]) delete [] data[ivar][1];
|
if (data[ivar][1]) delete [] data[ivar][1];
|
||||||
data[ivar][1] = new char[n];
|
data[ivar][1] = new char[n];
|
||||||
strcpy(data[ivar][1],value);
|
strcpy(data[ivar][1],result);
|
||||||
delete [] value;
|
|
||||||
str = data[ivar][1];
|
str = data[ivar][1];
|
||||||
}
|
} else if (style[ivar] == ATOM) return NULL;
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,34 +400,34 @@ void Variable::copy(int narg, char **from, char **to)
|
|||||||
group function = mass(group), xcm(group,x), ...
|
group function = mass(group), xcm(group,x), ...
|
||||||
atom vector = x[123], y[3], vx[34], ...
|
atom vector = x[123], y[3], vx[34], ...
|
||||||
compute vector = c_mytemp[0], c_thermo_press[3], ...
|
compute vector = c_mytemp[0], c_thermo_press[3], ...
|
||||||
|
numbers start with a digit or "." or "-" (no parens or brackets)
|
||||||
|
keywords start with a lowercase letter (no parens or brackets)
|
||||||
functions contain ()
|
functions contain ()
|
||||||
can have 1 or 2 args, each of which can be a "string"
|
can have 1 or 2 args, each of which can be a "string"
|
||||||
vectors contain []
|
vectors contain []
|
||||||
single arg must be integer
|
single arg must be integer
|
||||||
for atom vectors, it is global ID of atom
|
for atom vectors, arg is global ID of atom
|
||||||
for compute vectors, 0 is the scalar value, 1-N are vector values
|
for compute vectors, 0 is the scalar value, 1-N are vector values
|
||||||
keywords start with a lowercase letter (no parens or brackets)
|
see lists of valid functions & vectors below
|
||||||
numbers start with a digit or "." or "-" (no parens or brackets)
|
return answer = value of string
|
||||||
see lists of valid functions, vectors, keywords below
|
|
||||||
when string is evaluated, put result in a newly allocated string
|
|
||||||
return the address of result string (will be freed by caller)
|
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
char *Variable::evaluate(char *str)
|
double Variable::evaluate(char *str, Tree *tree)
|
||||||
{
|
{
|
||||||
// allocate a new string for the eventual result
|
double answer = 0.0;
|
||||||
|
if (tree) {
|
||||||
char *result = new char[32];
|
tree->type = VALUE;
|
||||||
double answer;
|
tree->left = tree->right = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// string is a "function" since contains ()
|
// string is a "function" since contains ()
|
||||||
// grab one or two args, separated by ","
|
// grab one or two args, separated by ","
|
||||||
// evaulate args recursively
|
// evaulate args recursively
|
||||||
// then evaluate math or group function
|
// if tree = NULL, evaluate math or group function
|
||||||
|
// else store as leaf in tree
|
||||||
|
|
||||||
if (strchr(str,'(')) {
|
if (strchr(str,'(')) {
|
||||||
if (str[strlen(str)-1] != ')')
|
if (str[strlen(str)-1] != ')') error->all("Cannot evaluate variable");
|
||||||
error->all("Cannot evaluate variable equal command");
|
|
||||||
|
|
||||||
char *ptr = strchr(str,'(');
|
char *ptr = strchr(str,'(');
|
||||||
int n = ptr - str;
|
int n = ptr - str;
|
||||||
@ -442,8 +438,7 @@ char *Variable::evaluate(char *str)
|
|||||||
char *comma = ++ptr;
|
char *comma = ++ptr;
|
||||||
int level = 0;
|
int level = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
if (*comma == '\0')
|
if (*comma == '\0') error->all("Cannot evaluate variable");
|
||||||
error->all("Cannot evaluate variable equal command");
|
|
||||||
else if (*comma == ',' && level == 0) break;
|
else if (*comma == ',' && level == 0) break;
|
||||||
else if (*comma == ')' && level == 0) break;
|
else if (*comma == ')' && level == 0) break;
|
||||||
else if (*comma == '(') level++;
|
else if (*comma == '(') level++;
|
||||||
@ -467,106 +462,132 @@ char *Variable::evaluate(char *str)
|
|||||||
} else arg2 = NULL;
|
} else arg2 = NULL;
|
||||||
|
|
||||||
double value1,value2;
|
double value1,value2;
|
||||||
char *strarg1 = NULL;
|
|
||||||
char *strarg2 = NULL;
|
|
||||||
|
|
||||||
// customize by adding math function to this list and to if statement
|
// customize by adding math function to this list and to if statement
|
||||||
// add(x,y),sub(x,y),mult(x,y),div(x,y),neg(x),
|
// add(x,y),sub(x,y),mult(x,y),div(x,y),neg(x),
|
||||||
// pow(x,y),exp(x),ln(x),sqrt(x)
|
// pow(x,y),exp(x),ln(x),sqrt(x)
|
||||||
|
|
||||||
if (strcmp(func,"add") == 0) {
|
if (strcmp(func,"add") == 0) {
|
||||||
if (!arg2) error->all("Cannot evaluate variable equal command");
|
if (!arg2) error->all("Cannot evaluate variable");
|
||||||
strarg1 = evaluate(arg1);
|
if (tree) {
|
||||||
strarg2 = evaluate(arg2);
|
tree->type = ADD;
|
||||||
value1 = atof(strarg1);
|
tree->left = new Tree();
|
||||||
value2 = atof(strarg2);
|
tree->right = new Tree();
|
||||||
answer = value1 + value2;
|
value1 = evaluate(arg1,tree->left);
|
||||||
|
value2 = evaluate(arg2,tree->right);
|
||||||
|
} else answer = evaluate(arg1,NULL) + evaluate(arg2,NULL);
|
||||||
|
|
||||||
} else if (strcmp(func,"sub") == 0) {
|
} else if (strcmp(func,"sub") == 0) {
|
||||||
if (!arg2) error->all("Cannot evaluate variable equal command");
|
if (!arg2) error->all("Cannot evaluate variable");
|
||||||
strarg1 = evaluate(arg1);
|
if (tree) {
|
||||||
strarg2 = evaluate(arg2);
|
tree->type = SUB;
|
||||||
value1 = atof(strarg1);
|
tree->left = new Tree();
|
||||||
value2 = atof(strarg2);
|
tree->right = new Tree();
|
||||||
answer = value1 - value2;
|
value1 = evaluate(arg1,tree->left);
|
||||||
|
value2 = evaluate(arg2,tree->right);
|
||||||
|
} else answer = evaluate(arg1,NULL) - evaluate(arg2,NULL);
|
||||||
|
|
||||||
} else if (strcmp(func,"mult") == 0) {
|
} else if (strcmp(func,"mult") == 0) {
|
||||||
if (!arg2) error->all("Cannot evaluate variable equal command");
|
if (!arg2) error->all("Cannot evaluate variable");
|
||||||
strarg1 = evaluate(arg1);
|
if (tree) {
|
||||||
strarg2 = evaluate(arg2);
|
tree->type = MULT;
|
||||||
value1 = atof(strarg1);
|
tree->left = new Tree();
|
||||||
value2 = atof(strarg2);
|
tree->right = new Tree();
|
||||||
answer = value1 * value2;
|
value1 = evaluate(arg1,tree->left);
|
||||||
|
value2 = evaluate(arg2,tree->right);
|
||||||
|
} else answer = evaluate(arg1,NULL) * evaluate(arg2,NULL);
|
||||||
|
|
||||||
} else if (strcmp(func,"div") == 0) {
|
} else if (strcmp(func,"div") == 0) {
|
||||||
if (!arg2) error->all("Cannot evaluate variable equal command");
|
if (!arg2) error->all("Cannot evaluate variable");
|
||||||
strarg1 = evaluate(arg1);
|
if (tree) {
|
||||||
strarg2 = evaluate(arg2);
|
tree->type = DIV;
|
||||||
value1 = atof(strarg1);
|
tree->left = new Tree();
|
||||||
value2 = atof(strarg2);
|
tree->right = new Tree();
|
||||||
if (value2 == 0.0)
|
value1 = evaluate(arg1,tree->left);
|
||||||
error->all("Cannot evaluate variable equal command");
|
value2 = evaluate(arg2,tree->right);
|
||||||
|
} else {
|
||||||
|
value1 = evaluate(arg1,NULL);
|
||||||
|
value2 = evaluate(arg2,NULL);
|
||||||
|
if (value2 == 0.0) error->all("Cannot evaluate variable");
|
||||||
answer = value1 / value2;
|
answer = value1 / value2;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (strcmp(func,"neg") == 0) {
|
} else if (strcmp(func,"neg") == 0) {
|
||||||
if (arg2) error->all("Cannot evaluate variable equal command");
|
if (arg2) error->all("Cannot evaluate variable");
|
||||||
strarg1 = evaluate(arg1);
|
if (tree) {
|
||||||
value1 = atof(strarg1);
|
tree->type = NEG;
|
||||||
answer = -value1;
|
tree->left = new Tree();
|
||||||
|
value1 = evaluate(arg1,tree->left);
|
||||||
|
} else answer = -evaluate(arg1,NULL);
|
||||||
|
|
||||||
} else if (strcmp(func,"pow") == 0) {
|
} else if (strcmp(func,"pow") == 0) {
|
||||||
if (!arg2) error->all("Cannot evaluate variable equal command");
|
if (!arg2) error->all("Cannot evaluate variable");
|
||||||
strarg1 = evaluate(arg1);
|
if (tree) {
|
||||||
strarg2 = evaluate(arg2);
|
tree->type = POW;
|
||||||
value1 = atof(strarg1);
|
tree->left = new Tree();
|
||||||
value2 = atof(strarg2);
|
tree->right = new Tree();
|
||||||
if (value2 == 0.0)
|
value1 = evaluate(arg1,tree->left);
|
||||||
error->all("Cannot evaluate variable equal command");
|
value2 = evaluate(arg2,tree->right);
|
||||||
|
} else {
|
||||||
|
value1 = evaluate(arg1,NULL);
|
||||||
|
value2 = evaluate(arg2,NULL);
|
||||||
|
if (value2 == 0.0) error->all("Cannot evaluate variable");
|
||||||
answer = pow(value1,value2);
|
answer = pow(value1,value2);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (strcmp(func,"exp") == 0) {
|
} else if (strcmp(func,"exp") == 0) {
|
||||||
if (arg2) error->all("Cannot evaluate variable equal command");
|
if (arg2) error->all("Cannot evaluate variable");
|
||||||
strarg1 = evaluate(arg1);
|
if (tree) {
|
||||||
value1 = atof(strarg1);
|
tree->type = EXP;
|
||||||
answer = exp(value1);
|
tree->left = new Tree();
|
||||||
|
value1 = evaluate(arg1,tree->left);
|
||||||
|
} else answer = exp(evaluate(arg1,NULL));
|
||||||
|
|
||||||
} else if (strcmp(func,"ln") == 0) {
|
} else if (strcmp(func,"ln") == 0) {
|
||||||
if (arg2) error->all("Cannot evaluate variable equal command");
|
if (arg2) error->all("Cannot evaluate variable");
|
||||||
strarg1 = evaluate(arg1);
|
if (tree) {
|
||||||
value1 = atof(strarg1);
|
tree->type = LN;
|
||||||
if (value1 == 0.0)
|
tree->left = new Tree();
|
||||||
error->all("Cannot evaluate variable equal command");
|
value1 = evaluate(arg1,tree->left);
|
||||||
|
} else {
|
||||||
|
value1 = evaluate(arg1,NULL);
|
||||||
|
if (value1 == 0.0) error->all("Cannot evaluate variable");
|
||||||
answer = log(value1);
|
answer = log(value1);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (strcmp(func,"sqrt") == 0) {
|
} else if (strcmp(func,"sqrt") == 0) {
|
||||||
if (arg2) error->all("Cannot evaluate variable equal command");
|
if (arg2) error->all("Cannot evaluate variable");
|
||||||
strarg1 = evaluate(arg1);
|
if (tree) {
|
||||||
value1 = atof(strarg1);
|
tree->type = SQRT;
|
||||||
if (value1 == 0.0)
|
tree->left = new Tree();
|
||||||
error->all("Cannot evaluate variable equal command");
|
value1 = evaluate(arg1,tree->left);
|
||||||
|
} else {
|
||||||
|
value1 = evaluate(arg1,NULL);
|
||||||
|
if (value1 == 0.0) error->all("Cannot evaluate variable");
|
||||||
answer = sqrt(value1);
|
answer = sqrt(value1);
|
||||||
|
}
|
||||||
|
|
||||||
// customize by adding group function to this list and to if statement
|
// customize by adding group function to this list and to if statement
|
||||||
// mass(group),charge(group),xcm(group,dim),vcm(group,dim),
|
// mass(group),charge(group),xcm(group,dim),vcm(group,dim),
|
||||||
// bound(group,xmin),gyration(group)
|
// bound(group,xmin),gyration(group)
|
||||||
|
|
||||||
} else if (strcmp(func,"mass") == 0) {
|
} else if (strcmp(func,"mass") == 0) {
|
||||||
if (arg2) error->all("Cannot evaluate variable equal command");
|
if (arg2) error->all("Cannot evaluate variable");
|
||||||
int igroup = group->find(arg1);
|
int igroup = group->find(arg1);
|
||||||
if (igroup == -1) error->all("Variable equal group ID does not exist");
|
if (igroup == -1) error->all("Variable group ID does not exist");
|
||||||
atom->check_mass();
|
atom->check_mass();
|
||||||
answer = group->mass(igroup);
|
answer = group->mass(igroup);
|
||||||
|
|
||||||
} else if (strcmp(func,"charge") == 0) {
|
} else if (strcmp(func,"charge") == 0) {
|
||||||
if (arg2) error->all("Cannot evaluate variable equal command");
|
if (arg2) error->all("Cannot evaluate variable");
|
||||||
int igroup = group->find(arg1);
|
int igroup = group->find(arg1);
|
||||||
if (igroup == -1) error->all("Variable equal group ID does not exist");
|
if (igroup == -1) error->all("Variable group ID does not exist");
|
||||||
answer = group->charge(igroup);
|
answer = group->charge(igroup);
|
||||||
|
|
||||||
} else if (strcmp(func,"xcm") == 0) {
|
} else if (strcmp(func,"xcm") == 0) {
|
||||||
if (!arg2) error->all("Cannot evaluate variable equal command");
|
if (!arg2) error->all("Cannot evaluate variable");
|
||||||
int igroup = group->find(arg1);
|
int igroup = group->find(arg1);
|
||||||
if (igroup == -1) error->all("Variable equal group ID does not exist");
|
if (igroup == -1) error->all("Variable group ID does not exist");
|
||||||
atom->check_mass();
|
atom->check_mass();
|
||||||
double masstotal = group->mass(igroup);
|
double masstotal = group->mass(igroup);
|
||||||
double xcm[3];
|
double xcm[3];
|
||||||
@ -574,12 +595,12 @@ char *Variable::evaluate(char *str)
|
|||||||
if (strcmp(arg2,"x") == 0) answer = xcm[0];
|
if (strcmp(arg2,"x") == 0) answer = xcm[0];
|
||||||
else if (strcmp(arg2,"y") == 0) answer = xcm[1];
|
else if (strcmp(arg2,"y") == 0) answer = xcm[1];
|
||||||
else if (strcmp(arg2,"z") == 0) answer = xcm[2];
|
else if (strcmp(arg2,"z") == 0) answer = xcm[2];
|
||||||
else error->all("Cannot evaluate variable equal command");
|
else error->all("Cannot evaluate variable");
|
||||||
|
|
||||||
} else if (strcmp(func,"vcm") == 0) {
|
} else if (strcmp(func,"vcm") == 0) {
|
||||||
if (!arg2) error->all("Cannot evaluate variable equal command");
|
if (!arg2) error->all("Cannot evaluate variable");
|
||||||
int igroup = group->find(arg1);
|
int igroup = group->find(arg1);
|
||||||
if (igroup == -1) error->all("Variable equal group ID does not exist");
|
if (igroup == -1) error->all("Variable group ID does not exist");
|
||||||
atom->check_mass();
|
atom->check_mass();
|
||||||
double masstotal = group->mass(igroup);
|
double masstotal = group->mass(igroup);
|
||||||
double vcm[3];
|
double vcm[3];
|
||||||
@ -587,12 +608,12 @@ char *Variable::evaluate(char *str)
|
|||||||
if (strcmp(arg2,"x") == 0) answer = vcm[0];
|
if (strcmp(arg2,"x") == 0) answer = vcm[0];
|
||||||
else if (strcmp(arg2,"y") == 0) answer = vcm[1];
|
else if (strcmp(arg2,"y") == 0) answer = vcm[1];
|
||||||
else if (strcmp(arg2,"z") == 0) answer = vcm[2];
|
else if (strcmp(arg2,"z") == 0) answer = vcm[2];
|
||||||
else error->all("Cannot evaluate variable equal command");
|
else error->all("Cannot evaluate variable");
|
||||||
|
|
||||||
} else if (strcmp(func,"bound") == 0) {
|
} else if (strcmp(func,"bound") == 0) {
|
||||||
if (!arg2) error->all("Cannot evaluate variable equal command");
|
if (!arg2) error->all("Cannot evaluate variable");
|
||||||
int igroup = group->find(arg1);
|
int igroup = group->find(arg1);
|
||||||
if (igroup == -1) error->all("Variable equal group ID does not exist");
|
if (igroup == -1) error->all("Variable group ID does not exist");
|
||||||
double minmax[6];
|
double minmax[6];
|
||||||
group->bounds(igroup,minmax);
|
group->bounds(igroup,minmax);
|
||||||
if (strcmp(arg2,"xmin") == 0) answer = minmax[0];
|
if (strcmp(arg2,"xmin") == 0) answer = minmax[0];
|
||||||
@ -601,28 +622,23 @@ char *Variable::evaluate(char *str)
|
|||||||
else if (strcmp(arg2,"ymax") == 0) answer = minmax[3];
|
else if (strcmp(arg2,"ymax") == 0) answer = minmax[3];
|
||||||
else if (strcmp(arg2,"zmin") == 0) answer = minmax[4];
|
else if (strcmp(arg2,"zmin") == 0) answer = minmax[4];
|
||||||
else if (strcmp(arg2,"zmax") == 0) answer = minmax[5];
|
else if (strcmp(arg2,"zmax") == 0) answer = minmax[5];
|
||||||
else error->all("Cannot evaluate variable equal command");
|
else error->all("Cannot evaluate variable");
|
||||||
|
|
||||||
} else if (strcmp(func,"gyration") == 0) {
|
} else if (strcmp(func,"gyration") == 0) {
|
||||||
if (!arg2) error->all("Cannot evaluate variable equal command");
|
if (!arg2) error->all("Cannot evaluate variable");
|
||||||
int igroup = group->find(arg1);
|
int igroup = group->find(arg1);
|
||||||
if (igroup == -1) error->all("Variable equal group ID does not exist");
|
if (igroup == -1) error->all("Variable group ID does not exist");
|
||||||
atom->check_mass();
|
atom->check_mass();
|
||||||
double masstotal = group->mass(igroup);
|
double masstotal = group->mass(igroup);
|
||||||
double xcm[3];
|
double xcm[3];
|
||||||
group->xcm(igroup,masstotal,xcm);
|
group->xcm(igroup,masstotal,xcm);
|
||||||
answer = group->gyration(igroup,masstotal,xcm);
|
answer = group->gyration(igroup,masstotal,xcm);
|
||||||
|
|
||||||
} else error->all("Invalid math/group function in variable equal command");
|
} else error->all("Invalid math/group function in variable");
|
||||||
|
|
||||||
delete [] func;
|
delete [] func;
|
||||||
delete [] arg1;
|
delete [] arg1;
|
||||||
delete [] strarg1;
|
|
||||||
if (arg2) {
|
|
||||||
delete [] arg2;
|
delete [] arg2;
|
||||||
delete [] strarg2;
|
|
||||||
}
|
|
||||||
sprintf(result,"%.10g",answer);
|
|
||||||
|
|
||||||
// string is a "vector" since contains []
|
// string is a "vector" since contains []
|
||||||
// index = everything between [] evaluated as integer
|
// index = everything between [] evaluated as integer
|
||||||
@ -633,8 +649,7 @@ char *Variable::evaluate(char *str)
|
|||||||
// grab atom-based value with index as global atom ID
|
// grab atom-based value with index as global atom ID
|
||||||
|
|
||||||
} else if (strchr(str,'[')) {
|
} else if (strchr(str,'[')) {
|
||||||
if (str[strlen(str)-1] != ']')
|
if (str[strlen(str)-1] != ']') error->all("Cannot evaluate variable");
|
||||||
error->all("Cannot evaluate variable equal command");
|
|
||||||
|
|
||||||
char *ptr = strchr(str,'[');
|
char *ptr = strchr(str,'[');
|
||||||
int n = ptr - str;
|
int n = ptr - str;
|
||||||
@ -659,7 +674,7 @@ char *Variable::evaluate(char *str)
|
|||||||
for (icompute = 0; icompute < modify->ncompute; icompute++)
|
for (icompute = 0; icompute < modify->ncompute; icompute++)
|
||||||
if (strcmp(id,modify->compute[icompute]->id) == 0) break;
|
if (strcmp(id,modify->compute[icompute]->id) == 0) break;
|
||||||
if (icompute == modify->ncompute)
|
if (icompute == modify->ncompute)
|
||||||
error->all("Invalid compute ID in variable equal");
|
error->all("Invalid compute ID in variable");
|
||||||
delete [] id;
|
delete [] id;
|
||||||
modify->compute[icompute]->init();
|
modify->compute[icompute]->init();
|
||||||
|
|
||||||
@ -672,7 +687,7 @@ char *Variable::evaluate(char *str)
|
|||||||
error->all("Variable compute ID does not compute scalar info");
|
error->all("Variable compute ID does not compute scalar info");
|
||||||
if (modify->compute[icompute]->id_pre) {
|
if (modify->compute[icompute]->id_pre) {
|
||||||
int ipre = modify->find_compute(modify->compute[icompute]->id_pre);
|
int ipre = modify->find_compute(modify->compute[icompute]->id_pre);
|
||||||
if (ipre < 0) error->all("Could not pre-compute in variable equal");
|
if (ipre < 0) error->all("Could not pre-compute in variable");
|
||||||
answer = modify->compute[ipre]->compute_scalar();
|
answer = modify->compute[ipre]->compute_scalar();
|
||||||
}
|
}
|
||||||
answer = modify->compute[icompute]->compute_scalar();
|
answer = modify->compute[icompute]->compute_scalar();
|
||||||
@ -683,28 +698,62 @@ char *Variable::evaluate(char *str)
|
|||||||
error->all("Variable compute ID vector is not large enough");
|
error->all("Variable compute ID vector is not large enough");
|
||||||
if (modify->compute[icompute]->id_pre) {
|
if (modify->compute[icompute]->id_pre) {
|
||||||
int ipre = modify->find_compute(modify->compute[icompute]->id_pre);
|
int ipre = modify->find_compute(modify->compute[icompute]->id_pre);
|
||||||
if (ipre < 0) error->all("Could not pre-compute in variable equal");
|
if (ipre < 0) error->all("Could not pre-compute in variable");
|
||||||
modify->compute[ipre]->compute_vector();
|
modify->compute[ipre]->compute_vector();
|
||||||
}
|
}
|
||||||
modify->compute[icompute]->compute_vector();
|
modify->compute[icompute]->compute_vector();
|
||||||
answer = modify->compute[icompute]->vector[index-1];
|
answer = modify->compute[icompute]->vector[index-1];
|
||||||
} else error->all("Invalid compute ID index in variable equal");
|
} else error->all("Invalid compute ID index in variable");
|
||||||
|
|
||||||
|
} else if (tree) {
|
||||||
|
|
||||||
|
if (strlen(arg)) error->all("Invalid atom vector argument in variable");
|
||||||
|
|
||||||
|
// customize by adding atom vector to this list and to if statement
|
||||||
|
// mass,x,y,z,vx,vy,vz,fx,fy,fz
|
||||||
|
|
||||||
|
tree->type = ATOMARRAY;
|
||||||
|
tree->nstride = 3;
|
||||||
|
|
||||||
|
if (strcmp(vector,"mass") == 0) {
|
||||||
|
if (atom->mass) {
|
||||||
|
tree->type = TYPEARRAY;
|
||||||
|
tree->array = atom->mass;
|
||||||
|
} else {
|
||||||
|
tree->nstride = 1;
|
||||||
|
tree->array = atom->rmass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(vector,"x") == 0) tree->array = &atom->x[0][0];
|
||||||
|
else if (strcmp(vector,"y") == 0) tree->array = &atom->x[0][1];
|
||||||
|
else if (strcmp(vector,"z") == 0) tree->array = &atom->x[0][2];
|
||||||
|
else if (strcmp(vector,"vx") == 0) tree->array = &atom->v[0][0];
|
||||||
|
else if (strcmp(vector,"vy") == 0) tree->array = &atom->v[0][1];
|
||||||
|
else if (strcmp(vector,"vz") == 0) tree->array = &atom->v[0][2];
|
||||||
|
else if (strcmp(vector,"fx") == 0) tree->array = &atom->f[0][0];
|
||||||
|
else if (strcmp(vector,"fy") == 0) tree->array = &atom->f[0][1];
|
||||||
|
else if (strcmp(vector,"fz") == 0) tree->array = &atom->f[0][2];
|
||||||
|
|
||||||
|
else error->all("Invalid atom vector in variable");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (atom->map_style == 0)
|
if (atom->map_style == 0)
|
||||||
error->all("Cannot use atom vectors in variable "
|
error->all("Cannot use atom vector in variable unless atom map exists");
|
||||||
"unless atom map exists");
|
|
||||||
|
|
||||||
int index = atom->map(atoi(arg));
|
int index = atom->map(atoi(arg));
|
||||||
|
|
||||||
// customize by adding atom vector to this list and to if statement
|
// customize by adding atom vector to this list and to if statement
|
||||||
// x,y,z,vx,vy,vz,fx,fy,fz
|
// mass,x,y,z,vx,vy,vz,fx,fy,fz
|
||||||
|
|
||||||
double mine;
|
double mine;
|
||||||
if (index >= 0 && index < atom->nlocal) {
|
if (index >= 0 && index < atom->nlocal) {
|
||||||
|
|
||||||
if (strcmp(vector,"x") == 0) mine = atom->x[index][0];
|
if (strcmp(vector,"mass") == 0) {
|
||||||
|
if (atom->mass) mine = atom->mass[atom->type[index]];
|
||||||
|
else mine = atom->rmass[index];
|
||||||
|
}
|
||||||
|
else if (strcmp(vector,"x") == 0) mine = atom->x[index][0];
|
||||||
else if (strcmp(vector,"y") == 0) mine = atom->x[index][1];
|
else if (strcmp(vector,"y") == 0) mine = atom->x[index][1];
|
||||||
else if (strcmp(vector,"z") == 0) mine = atom->x[index][2];
|
else if (strcmp(vector,"z") == 0) mine = atom->x[index][2];
|
||||||
else if (strcmp(vector,"vx") == 0) mine = atom->v[index][0];
|
else if (strcmp(vector,"vx") == 0) mine = atom->v[index][0];
|
||||||
@ -714,7 +763,7 @@ char *Variable::evaluate(char *str)
|
|||||||
else if (strcmp(vector,"fy") == 0) mine = atom->f[index][1];
|
else if (strcmp(vector,"fy") == 0) mine = atom->f[index][1];
|
||||||
else if (strcmp(vector,"fz") == 0) mine = atom->f[index][2];
|
else if (strcmp(vector,"fz") == 0) mine = atom->f[index][2];
|
||||||
|
|
||||||
else error->one("Invalid atom vector in variable equal command");
|
else error->one("Invalid atom vector in variable");
|
||||||
|
|
||||||
} else mine = 0.0;
|
} else mine = 0.0;
|
||||||
|
|
||||||
@ -723,7 +772,6 @@ char *Variable::evaluate(char *str)
|
|||||||
|
|
||||||
delete [] vector;
|
delete [] vector;
|
||||||
delete [] arg;
|
delete [] arg;
|
||||||
sprintf(result,"%.10g",answer);
|
|
||||||
|
|
||||||
// string is "keyword" since starts with lowercase letter
|
// string is "keyword" since starts with lowercase letter
|
||||||
// if keyword starts with "v_", trailing chars are variable name
|
// if keyword starts with "v_", trailing chars are variable name
|
||||||
@ -731,8 +779,6 @@ char *Variable::evaluate(char *str)
|
|||||||
// else is thermo keyword
|
// else is thermo keyword
|
||||||
// evaluate it via evaluate_keyword()
|
// evaluate it via evaluate_keyword()
|
||||||
|
|
||||||
// compute appropriate value via thermo
|
|
||||||
|
|
||||||
} else if (islower(str[0])) {
|
} else if (islower(str[0])) {
|
||||||
|
|
||||||
if (strncmp(str,"v_",2) == 0) {
|
if (strncmp(str,"v_",2) == 0) {
|
||||||
@ -741,31 +787,98 @@ char *Variable::evaluate(char *str)
|
|||||||
strcpy(id,&str[2]);
|
strcpy(id,&str[2]);
|
||||||
|
|
||||||
char *v = retrieve(id);
|
char *v = retrieve(id);
|
||||||
if (v == NULL)
|
if (v == NULL) error->all("Invalid variable name in variable");
|
||||||
error->all("Invalid variable name in variable equal command");
|
|
||||||
delete [] id;
|
delete [] id;
|
||||||
|
|
||||||
answer = atof(v);
|
answer = atof(v);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
int flag = output->thermo->evaluate_keyword(str,&answer);
|
int flag = output->thermo->evaluate_keyword(str,&answer);
|
||||||
if (flag) error->all("Invalid thermo keyword in variable equal command");
|
if (flag) error->all("Invalid thermo keyword in variable");
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(result,"%.10g",answer);
|
|
||||||
|
|
||||||
// string is a number since starts with digit or "." or "-"
|
// string is a number since starts with digit or "." or "-"
|
||||||
// just copy to result
|
// just copy to result
|
||||||
|
|
||||||
} else if (isdigit(str[0]) || str[0] == '.' || str[0] == '-') {
|
} else if (isdigit(str[0]) || str[0] == '.' || str[0] == '-') {
|
||||||
|
|
||||||
strcpy(result,str);
|
answer = atof(str);
|
||||||
|
|
||||||
// string is an error
|
// string is an error
|
||||||
|
|
||||||
} else error->all("Cannot evaluate variable equal command");
|
} else error->all("Cannot evaluate variable");
|
||||||
|
|
||||||
// return newly allocated string
|
// store answer in tree and return it
|
||||||
|
|
||||||
return result;
|
if (tree) tree->value = answer;
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void Variable::build_parse_tree(int ivar)
|
||||||
|
{
|
||||||
|
if (style[ivar] != ATOM) error->all("");
|
||||||
|
ptree = new Tree();
|
||||||
|
double tmp = evaluate(data[ivar][0],ptree);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void Variable::evaluate_parse_tree(int igroup, double *result)
|
||||||
|
{
|
||||||
|
int groupbit = group->bitmask[igroup];
|
||||||
|
int *mask = atom->mask;
|
||||||
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
|
for (int i = 0; i < nlocal; i++) {
|
||||||
|
if (mask[i] && groupbit) result[i] = eval_tree(ptree,i);
|
||||||
|
else result[i] = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void Variable::free_parse_tree()
|
||||||
|
{
|
||||||
|
free_tree(ptree);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
double Variable::eval_tree(Tree *tree, int i)
|
||||||
|
{
|
||||||
|
if (tree->type == VALUE) return tree->value;
|
||||||
|
if (tree->type == ATOMARRAY) return tree->array[i*tree->nstride];
|
||||||
|
if (tree->type == TYPEARRAY) return tree->array[atom->type[i]];
|
||||||
|
|
||||||
|
if (tree->type == ADD)
|
||||||
|
return eval_tree(tree->left,i) + eval_tree(tree->right,i);
|
||||||
|
if (tree->type == SUB)
|
||||||
|
return eval_tree(tree->left,i) - eval_tree(tree->right,i);
|
||||||
|
if (tree->type == MULT)
|
||||||
|
return eval_tree(tree->left,i) * eval_tree(tree->right,i);
|
||||||
|
if (tree->type == DIV)
|
||||||
|
return eval_tree(tree->left,i) / eval_tree(tree->right,i);
|
||||||
|
if (tree->type == NEG)
|
||||||
|
return -eval_tree(tree->left,i);
|
||||||
|
if (tree->type == POW)
|
||||||
|
return pow(eval_tree(tree->left,i),eval_tree(tree->right,i));
|
||||||
|
if (tree->type == EXP)
|
||||||
|
return exp(eval_tree(tree->left,i));
|
||||||
|
if (tree->type == LN)
|
||||||
|
return log(eval_tree(tree->left,i));
|
||||||
|
if (tree->type == SQRT)
|
||||||
|
return sqrt(eval_tree(tree->left,i));
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void Variable::free_tree(Tree *tree)
|
||||||
|
{
|
||||||
|
if (tree->left) free_tree(tree->left);
|
||||||
|
if (tree->right) free_tree(tree->right);
|
||||||
|
delete tree;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,10 @@ class Variable : protected Pointers {
|
|||||||
int find(char *);
|
int find(char *);
|
||||||
char *retrieve(char *);
|
char *retrieve(char *);
|
||||||
|
|
||||||
|
void build_parse_tree(int);
|
||||||
|
void evaluate_parse_tree(int, double *);
|
||||||
|
void free_parse_tree();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int me;
|
int me;
|
||||||
int nvar; // # of defined variables
|
int nvar; // # of defined variables
|
||||||
@ -38,9 +42,21 @@ class Variable : protected Pointers {
|
|||||||
int *index; // next available value for each variable
|
int *index; // next available value for each variable
|
||||||
char ***data; // str value of each variable's values
|
char ***data; // str value of each variable's values
|
||||||
|
|
||||||
|
struct Tree {
|
||||||
|
double value;
|
||||||
|
double *array;
|
||||||
|
int nstride;
|
||||||
|
int type;
|
||||||
|
Tree *left,*right;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tree *ptree; // parse tree for an ATOM variable
|
||||||
|
|
||||||
void copy(int, char **, char **);
|
void copy(int, char **, char **);
|
||||||
char *evaluate(char *);
|
double evaluate(char *, Tree *);
|
||||||
void remove(int);
|
void remove(int);
|
||||||
|
double eval_tree(Tree *, int);
|
||||||
|
void free_tree(Tree *);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/verlet.h
14
src/verlet.h
@ -21,19 +21,25 @@ namespace LAMMPS_NS {
|
|||||||
class Verlet : public Integrate {
|
class Verlet : public Integrate {
|
||||||
public:
|
public:
|
||||||
Verlet(class LAMMPS *, int, char **);
|
Verlet(class LAMMPS *, int, char **);
|
||||||
|
~Verlet();
|
||||||
void init();
|
void init();
|
||||||
void setup();
|
void setup();
|
||||||
void iterate(int);
|
void iterate(int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int virial_every; // what vflag should be on every timestep (0,1,2)
|
int virial_style; // compute virial explicitly or implicitly
|
||||||
int virial_thermo; // what vflag should be on thermo steps (1,2)
|
int virial_every; // 1 if virial computed every step
|
||||||
int pairflag,torqueflag,granflag;
|
int next_virial; // next timestep to compute virial
|
||||||
|
int nfix_virial; // # of fixes that need virial occasionally
|
||||||
|
int *fix_virial_every; // frequency they require it
|
||||||
|
int *next_fix_virial; // next timestep they need it
|
||||||
|
|
||||||
int maxpair; // copies of Update quantities
|
int pairflag,torqueflag,granflag; // arrays to zero out every step
|
||||||
|
int maxpair; // local copies of Update quantities
|
||||||
double **f_pair;
|
double **f_pair;
|
||||||
|
|
||||||
void force_clear(int);
|
void force_clear(int);
|
||||||
|
int fix_virial(int);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user