first version of fix ttm/grid
This commit is contained in:
@ -31,7 +31,6 @@
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
|
||||
|
||||
#include "tokenizer.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
@ -108,45 +107,36 @@ FixTTM::FixTTM(LAMMPS *lmp, int narg, char **arg) :
|
||||
gfactor1 = new double[atom->ntypes+1];
|
||||
gfactor2 = new double[atom->ntypes+1];
|
||||
|
||||
// allocate 3d grid variables
|
||||
// check for allowed maxium number of total grid nodes
|
||||
|
||||
total_nnodes = (bigint)nxnodes * (bigint)nynodes * (bigint)nznodes;
|
||||
if (total_nnodes > MAXSMALLINT)
|
||||
error->all(FLERR,"Too many nodes in fix ttm");
|
||||
|
||||
memory->create(nsum,nxnodes,nynodes,nznodes,"ttm:nsum");
|
||||
memory->create(nsum_all,nxnodes,nynodes,nznodes,"ttm:nsum_all");
|
||||
memory->create(sum_vsq,nxnodes,nynodes,nznodes,"ttm:sum_vsq");
|
||||
memory->create(sum_mass_vsq,nxnodes,nynodes,nznodes,"ttm:sum_mass_vsq");
|
||||
memory->create(sum_vsq_all,nxnodes,nynodes,nznodes,"ttm:sum_vsq_all");
|
||||
memory->create(sum_mass_vsq_all,nxnodes,nynodes,nznodes,
|
||||
"ttm:sum_mass_vsq_all");
|
||||
memory->create(T_electron_old,nxnodes,nynodes,nznodes,"ttm:T_electron_old");
|
||||
memory->create(T_electron,nxnodes,nynodes,nznodes,"ttm:T_electron");
|
||||
memory->create(net_energy_transfer,nxnodes,nynodes,nznodes,
|
||||
"TTM:net_energy_transfer");
|
||||
memory->create(net_energy_transfer_all,nxnodes,nynodes,nznodes,
|
||||
"TTM:net_energy_transfer_all");
|
||||
// allocate 3d grid variables
|
||||
|
||||
allocate_grid();
|
||||
|
||||
// allocate per-atom flangevin and zero it
|
||||
// NOTE: is init to zero necessary?
|
||||
|
||||
flangevin = nullptr;
|
||||
grow_arrays(atom->nmax);
|
||||
|
||||
// zero out the flangevin array
|
||||
|
||||
for (int i = 0; i < atom->nmax; i++) {
|
||||
flangevin[i][0] = 0;
|
||||
flangevin[i][1] = 0;
|
||||
flangevin[i][2] = 0;
|
||||
flangevin[i][0] = 0.0;
|
||||
flangevin[i][1] = 0.0;
|
||||
flangevin[i][2] = 0.0;
|
||||
}
|
||||
|
||||
// set 2 callbacks
|
||||
|
||||
atom->add_callback(Atom::GROW);
|
||||
atom->add_callback(Atom::RESTART);
|
||||
|
||||
// set initial electron temperatures from user input file
|
||||
|
||||
if (comm->me == 0) read_initial_electron_temperatures(arg[13]);
|
||||
MPI_Bcast(&T_electron[0][0][0],total_nnodes,MPI_DOUBLE,0,world);
|
||||
read_initial_electron_temperatures(arg[13]);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -160,17 +150,9 @@ FixTTM::~FixTTM()
|
||||
delete [] gfactor1;
|
||||
delete [] gfactor2;
|
||||
|
||||
memory->destroy(nsum);
|
||||
memory->destroy(nsum_all);
|
||||
memory->destroy(sum_vsq);
|
||||
memory->destroy(sum_mass_vsq);
|
||||
memory->destroy(sum_vsq_all);
|
||||
memory->destroy(sum_mass_vsq_all);
|
||||
memory->destroy(T_electron_old);
|
||||
memory->destroy(T_electron);
|
||||
memory->destroy(flangevin);
|
||||
memory->destroy(net_energy_transfer);
|
||||
memory->destroy(net_energy_transfer_all);
|
||||
|
||||
deallocate_grid();
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -203,13 +185,12 @@ void FixTTM::init()
|
||||
sqrt(24.0*force->boltz*gamma_p/update->dt/force->mvv2e) / force->ftm2v;
|
||||
}
|
||||
|
||||
for (int ixnode = 0; ixnode < nxnodes; ixnode++)
|
||||
for (int iynode = 0; iynode < nynodes; iynode++)
|
||||
for (int iznode = 0; iznode < nznodes; iznode++)
|
||||
net_energy_transfer_all[ixnode][iynode][iznode] = 0;
|
||||
|
||||
if (utils::strmatch(update->integrate_style,"^respa"))
|
||||
nlevels_respa = ((Respa *) update->integrate)->nlevels;
|
||||
|
||||
// initialize grid quantities
|
||||
|
||||
init_grid();
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -227,6 +208,25 @@ void FixTTM::setup(int vflag)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixTTM::post_force_setup(int /*vflag*/)
|
||||
{
|
||||
double **f = atom->f;
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
// apply langevin forces that have been stored from previous run
|
||||
|
||||
for (int i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) {
|
||||
f[i][0] += flangevin[i][0];
|
||||
f[i][1] += flangevin[i][1];
|
||||
f[i][2] += flangevin[i][2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixTTM::post_force(int /*vflag*/)
|
||||
{
|
||||
double **x = atom->x;
|
||||
@ -279,32 +279,6 @@ void FixTTM::post_force(int /*vflag*/)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixTTM::post_force_setup(int /*vflag*/)
|
||||
{
|
||||
double **f = atom->f;
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
// apply langevin forces that have been stored from previous run
|
||||
|
||||
for (int i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) {
|
||||
f[i][0] += flangevin[i][0];
|
||||
f[i][1] += flangevin[i][1];
|
||||
f[i][2] += flangevin[i][2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixTTM::post_force_respa(int vflag, int ilevel, int /*iloop*/)
|
||||
{
|
||||
if (ilevel == nlevels_respa-1) post_force(vflag);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixTTM::post_force_respa_setup(int vflag, int ilevel, int /*iloop*/)
|
||||
{
|
||||
if (ilevel == nlevels_respa-1) post_force_setup(vflag);
|
||||
@ -312,68 +286,9 @@ void FixTTM::post_force_respa_setup(int vflag, int ilevel, int /*iloop*/)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixTTM::reset_dt()
|
||||
void FixTTM::post_force_respa(int vflag, int ilevel, int /*iloop*/)
|
||||
{
|
||||
for (int i = 1; i <= atom->ntypes; i++)
|
||||
gfactor2[i] =
|
||||
sqrt(24.0*force->boltz*gamma_p/update->dt/force->mvv2e) / force->ftm2v;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
read in initial electron temperatures from a user-specified file
|
||||
only called by proc 0
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTM::read_initial_electron_temperatures(const char *filename)
|
||||
{
|
||||
int ***T_initial_set;
|
||||
memory->create(T_initial_set,nxnodes,nynodes,nznodes,"ttm:T_initial_set");
|
||||
memset(&T_initial_set[0][0][0],0,total_nnodes*sizeof(int));
|
||||
|
||||
std::string name = utils::get_potential_file_path(filename);
|
||||
if (name.empty())
|
||||
error->one(FLERR,"Cannot open input file: {}",
|
||||
filename);
|
||||
FILE *fpr = fopen(name.c_str(),"r");
|
||||
|
||||
// read initial electron temperature values from file
|
||||
|
||||
char line[MAXLINE];
|
||||
int ixnode,iynode,iznode;
|
||||
double T_tmp;
|
||||
while (1) {
|
||||
if (fgets(line,MAXLINE,fpr) == nullptr) break;
|
||||
ValueTokenizer values(line);
|
||||
if (values.has_next()) ixnode = values.next_int();
|
||||
if (values.has_next()) iynode = values.next_int();
|
||||
if (values.has_next()) iznode = values.next_int();
|
||||
if (values.has_next()) T_tmp = values.next_double();
|
||||
else error->one(FLERR,"Incorrect format in fix ttm input file");
|
||||
|
||||
// check correctness of input data
|
||||
|
||||
if ((ixnode < 0) || (ixnode >= nxnodes)
|
||||
|| (iynode < 0) || (iynode >= nynodes)
|
||||
|| (iznode < 0) || (iznode >= nznodes))
|
||||
error->one(FLERR,"Fix ttm invalide node index in fix ttm input");
|
||||
|
||||
if (T_tmp < 0.0)
|
||||
error->one(FLERR,"Fix ttm electron temperatures must be > 0.0");
|
||||
|
||||
T_electron[ixnode][iynode][iznode] = T_tmp;
|
||||
T_initial_set[ixnode][iynode][iznode] = 1;
|
||||
}
|
||||
fclose(fpr);
|
||||
|
||||
// check completeness of input data
|
||||
|
||||
for (int ixnode = 0; ixnode < nxnodes; ixnode++)
|
||||
for (int iynode = 0; iynode < nynodes; iynode++)
|
||||
for (int iznode = 0; iznode < nznodes; iznode++)
|
||||
if (T_initial_set[ixnode][iynode][iznode] == 0)
|
||||
error->one(FLERR,"Initial temperatures not all set in fix ttm");
|
||||
|
||||
memory->destroy(T_initial_set);
|
||||
if (ilevel == nlevels_respa-1) post_force(vflag);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -552,55 +467,20 @@ void FixTTM::end_of_step()
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
memory usage of 3d grid
|
||||
------------------------------------------------------------------------- */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
double FixTTM::memory_usage()
|
||||
void FixTTM::reset_dt()
|
||||
{
|
||||
double bytes = 0.0;
|
||||
bytes += (double)5*total_nnodes * sizeof(int);
|
||||
bytes += (double)14*total_nnodes * sizeof(double);
|
||||
return bytes;
|
||||
for (int i = 1; i <= atom->ntypes; i++)
|
||||
gfactor2[i] =
|
||||
sqrt(24.0*force->boltz*gamma_p/update->dt/force->mvv2e) / force->ftm2v;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixTTM::grow_arrays(int ngrow)
|
||||
{
|
||||
|
||||
memory->grow(flangevin,ngrow,3,"TTM:flangevin");
|
||||
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return the energy of the electronic subsystem or the net_energy transfer
|
||||
between the subsystems
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double FixTTM::compute_vector(int n)
|
||||
{
|
||||
double e_energy = 0.0;
|
||||
double transfer_energy = 0.0;
|
||||
|
||||
double dx = domain->xprd/nxnodes;
|
||||
double dy = domain->yprd/nynodes;
|
||||
double dz = domain->zprd/nznodes;
|
||||
double del_vol = dx*dy*dz;
|
||||
|
||||
for (int ixnode = 0; ixnode < nxnodes; ixnode++)
|
||||
for (int iynode = 0; iynode < nynodes; iynode++)
|
||||
for (int iznode = 0; iznode < nznodes; iznode++) {
|
||||
e_energy +=
|
||||
T_electron[ixnode][iynode][iznode]*electronic_specific_heat*
|
||||
electronic_density*del_vol;
|
||||
transfer_energy +=
|
||||
net_energy_transfer_all[ixnode][iynode][iznode]*update->dt;
|
||||
}
|
||||
|
||||
if (n == 0) return e_energy;
|
||||
if (n == 1) return transfer_energy;
|
||||
return 0.0;
|
||||
memory->grow(flangevin,ngrow,3,"TTM:flangevin");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -685,6 +565,15 @@ void FixTTM::unpack_restart(int nlocal, int nth)
|
||||
flangevin[nlocal][2] = extra[nlocal][m++];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
size of atom nlocal's restart data
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int FixTTM::size_restart(int /*nlocal*/)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
maxsize of any atom's restart data
|
||||
------------------------------------------------------------------------- */
|
||||
@ -695,10 +584,157 @@ int FixTTM::maxsize_restart()
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
size of atom nlocal's restart data
|
||||
return the energy of the electronic subsystem or the net_energy transfer
|
||||
between the subsystems
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int FixTTM::size_restart(int /*nlocal*/)
|
||||
double FixTTM::compute_vector(int n)
|
||||
{
|
||||
return 4;
|
||||
double e_energy = 0.0;
|
||||
double transfer_energy = 0.0;
|
||||
|
||||
double dx = domain->xprd/nxnodes;
|
||||
double dy = domain->yprd/nynodes;
|
||||
double dz = domain->zprd/nznodes;
|
||||
double del_vol = dx*dy*dz;
|
||||
|
||||
for (int ixnode = 0; ixnode < nxnodes; ixnode++)
|
||||
for (int iynode = 0; iynode < nynodes; iynode++)
|
||||
for (int iznode = 0; iznode < nznodes; iznode++) {
|
||||
e_energy +=
|
||||
T_electron[ixnode][iynode][iznode]*electronic_specific_heat*
|
||||
electronic_density*del_vol;
|
||||
transfer_energy +=
|
||||
net_energy_transfer_all[ixnode][iynode][iznode]*update->dt;
|
||||
}
|
||||
|
||||
if (n == 0) return e_energy;
|
||||
if (n == 1) return transfer_energy;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
memory usage for flangevin and 3d grid
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double FixTTM::memory_usage()
|
||||
{
|
||||
double bytes = 0.0;
|
||||
bytes += (double)atom->nmax * 3 * sizeof(double);
|
||||
|
||||
bytes += (double)5*total_nnodes * sizeof(int);
|
||||
bytes += (double)14*total_nnodes * sizeof(double);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
allocate 3d grid quantities
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTM::allocate_grid()
|
||||
{
|
||||
memory->create(nsum,nxnodes,nynodes,nznodes,"ttm:nsum");
|
||||
memory->create(nsum_all,nxnodes,nynodes,nznodes,"ttm:nsum_all");
|
||||
memory->create(sum_vsq,nxnodes,nynodes,nznodes,"ttm:sum_vsq");
|
||||
memory->create(sum_mass_vsq,nxnodes,nynodes,nznodes,"ttm:sum_mass_vsq");
|
||||
memory->create(sum_vsq_all,nxnodes,nynodes,nznodes,"ttm:sum_vsq_all");
|
||||
memory->create(sum_mass_vsq_all,nxnodes,nynodes,nznodes,
|
||||
"ttm:sum_mass_vsq_all");
|
||||
memory->create(T_electron_old,nxnodes,nynodes,nznodes,"ttm:T_electron_old");
|
||||
memory->create(T_electron,nxnodes,nynodes,nznodes,"ttm:T_electron");
|
||||
memory->create(net_energy_transfer,nxnodes,nynodes,nznodes,
|
||||
"TTM:net_energy_transfer");
|
||||
memory->create(net_energy_transfer_all,nxnodes,nynodes,nznodes,
|
||||
"TTM:net_energy_transfer_all");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
initialize 3d grid quantities
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTM::init_grid()
|
||||
{
|
||||
for (int ixnode = 0; ixnode < nxnodes; ixnode++)
|
||||
for (int iynode = 0; iynode < nynodes; iynode++)
|
||||
for (int iznode = 0; iznode < nznodes; iznode++)
|
||||
net_energy_transfer_all[ixnode][iynode][iznode] = 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
deallocate 3d grid quantities
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTM::deallocate_grid()
|
||||
{
|
||||
memory->destroy(nsum);
|
||||
memory->destroy(nsum_all);
|
||||
memory->destroy(sum_vsq);
|
||||
memory->destroy(sum_mass_vsq);
|
||||
memory->destroy(sum_vsq_all);
|
||||
memory->destroy(sum_mass_vsq_all);
|
||||
memory->destroy(T_electron_old);
|
||||
memory->destroy(T_electron);
|
||||
memory->destroy(flangevin);
|
||||
memory->destroy(net_energy_transfer);
|
||||
memory->destroy(net_energy_transfer_all);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
read in initial electron temperatures from a user-specified file
|
||||
only called by proc 0
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTM::read_initial_electron_temperatures(const char *filename)
|
||||
{
|
||||
int ***T_initial_set;
|
||||
memory->create(T_initial_set,nxnodes,nynodes,nznodes,"ttm:T_initial_set");
|
||||
memset(&T_initial_set[0][0][0],0,total_nnodes*sizeof(int));
|
||||
|
||||
std::string name = utils::get_potential_file_path(filename);
|
||||
if (name.empty())
|
||||
error->one(FLERR,"Cannot open input file: {}",
|
||||
filename);
|
||||
FILE *fpr = fopen(name.c_str(),"r");
|
||||
|
||||
// read initial electron temperature values from file
|
||||
|
||||
char line[MAXLINE];
|
||||
int ixnode,iynode,iznode;
|
||||
double T_tmp;
|
||||
while (1) {
|
||||
if (fgets(line,MAXLINE,fpr) == nullptr) break;
|
||||
ValueTokenizer values(line);
|
||||
if (values.has_next()) ixnode = values.next_int();
|
||||
if (values.has_next()) iynode = values.next_int();
|
||||
if (values.has_next()) iznode = values.next_int();
|
||||
if (values.has_next()) T_tmp = values.next_double();
|
||||
else error->one(FLERR,"Incorrect format in fix ttm input file");
|
||||
|
||||
// check correctness of input data
|
||||
|
||||
if ((ixnode < 0) || (ixnode >= nxnodes)
|
||||
|| (iynode < 0) || (iynode >= nynodes)
|
||||
|| (iznode < 0) || (iznode >= nznodes))
|
||||
error->one(FLERR,"Fix ttm invalide node index in fix ttm input");
|
||||
|
||||
if (T_tmp < 0.0)
|
||||
error->one(FLERR,"Fix ttm electron temperatures must be > 0.0");
|
||||
|
||||
T_electron[ixnode][iynode][iznode] = T_tmp;
|
||||
T_initial_set[ixnode][iynode][iznode] = 1;
|
||||
}
|
||||
fclose(fpr);
|
||||
|
||||
// check completeness of input data
|
||||
|
||||
for (int ixnode = 0; ixnode < nxnodes; ixnode++)
|
||||
for (int iynode = 0; iynode < nynodes; iynode++)
|
||||
for (int iznode = 0; iznode < nznodes; iznode++)
|
||||
if (T_initial_set[ixnode][iynode][iznode] == 0)
|
||||
error->one(FLERR,"Initial temperatures not all set in fix ttm");
|
||||
|
||||
memory->destroy(T_initial_set);
|
||||
|
||||
MPI_Bcast(&T_electron[0][0][0],total_nnodes,MPI_DOUBLE,0,world);
|
||||
}
|
||||
|
||||
@ -27,27 +27,27 @@ namespace LAMMPS_NS {
|
||||
class FixTTM : public Fix {
|
||||
public:
|
||||
FixTTM(class LAMMPS *, int, char **);
|
||||
~FixTTM();
|
||||
virtual ~FixTTM();
|
||||
int setmask();
|
||||
void init();
|
||||
void setup(int);
|
||||
void post_force(int);
|
||||
void post_force_respa(int, int, int);
|
||||
void post_force_setup(int);
|
||||
virtual void post_force(int);
|
||||
void post_force_respa_setup(int, int, int);
|
||||
void end_of_step();
|
||||
void post_force_respa(int, int, int);
|
||||
virtual void end_of_step();
|
||||
void reset_dt();
|
||||
void write_restart(FILE *);
|
||||
void restart(char *);
|
||||
void grow_arrays(int);
|
||||
virtual void write_restart(FILE *);
|
||||
virtual void restart(char *);
|
||||
int pack_restart(int, double *);
|
||||
void unpack_restart(int, int);
|
||||
int size_restart(int);
|
||||
int maxsize_restart();
|
||||
double memory_usage();
|
||||
void grow_arrays(int);
|
||||
double compute_vector(int);
|
||||
virtual double compute_vector(int);
|
||||
virtual double memory_usage();
|
||||
|
||||
private:
|
||||
protected:
|
||||
int nfileevery;
|
||||
int nlevels_respa;
|
||||
int seed;
|
||||
@ -65,7 +65,10 @@ class FixTTM : public Fix {
|
||||
double electronic_thermal_conductivity;
|
||||
double gamma_p, gamma_s, v_0, v_0_sq;
|
||||
|
||||
void read_initial_electron_temperatures(const char *);
|
||||
virtual void allocate_grid();
|
||||
virtual void init_grid();
|
||||
virtual void deallocate_grid();
|
||||
virtual void read_initial_electron_temperatures(const char *);
|
||||
};
|
||||
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
609
src/MISC/fix_ttm_grid.cpp
Normal file
609
src/MISC/fix_ttm_grid.cpp
Normal file
@ -0,0 +1,609 @@
|
||||
// clang-format off
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
https://www.lammps.org/, 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 authors: Paul Crozier (SNL)
|
||||
Carolyn Phillips (University of Michigan)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "fix_ttm_grid.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include "atom.h"
|
||||
#include "force.h"
|
||||
#include "update.h"
|
||||
#include "domain.h"
|
||||
#include "comm.h"
|
||||
#include "gridcomm.h"
|
||||
#include "neighbor.h"
|
||||
#include "random_mars.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
|
||||
#include "tokenizer.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace FixConst;
|
||||
|
||||
#define MAXLINE 1024
|
||||
#define OFFSET 16384
|
||||
|
||||
enum{T_ELECTRON,NET_ENERGY_TRANSFER,DSUM,SUM_VSQ,SUM_MASS_VSQ};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
FixTTMGrid::FixTTMGrid(LAMMPS *lmp, int narg, char **arg) :
|
||||
FixTTM(lmp, narg, arg) {}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixTTMGrid::post_force(int /*vflag*/)
|
||||
{
|
||||
int ix,iy,iz;
|
||||
|
||||
double **x = atom->x;
|
||||
double **v = atom->v;
|
||||
double **f = atom->f;
|
||||
int *type = atom->type;
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
double gamma1,gamma2;
|
||||
|
||||
double *boxlo = domain->boxlo;
|
||||
|
||||
// apply damping and thermostat to all atoms in fix group
|
||||
|
||||
int flag = 0;
|
||||
|
||||
for (int i = 0; i < nlocal; i++) {
|
||||
if (mask[i] & groupbit) {
|
||||
|
||||
ix = static_cast<int> ((x[i][0]-boxlo[0])*delxinv + shift) - OFFSET;
|
||||
iy = static_cast<int> ((x[i][1]-boxlo[1])*delyinv + shift) - OFFSET;
|
||||
iz = static_cast<int> ((x[i][2]-boxlo[2])*delzinv + shift) - OFFSET;
|
||||
|
||||
if (T_electron[ix][iy][iz] < 0)
|
||||
error->all(FLERR,"Electronic temperature dropped below zero");
|
||||
|
||||
// check that ix,iy,iz is within my ghost cell range
|
||||
|
||||
if (ix < nxlo_out || ix > nxhi_out || iy < nylo_out || iy > nyhi_out ||
|
||||
iz < nzlo_out || iz > nzhi_out) flag = 1;
|
||||
|
||||
double tsqrt = sqrt(T_electron[ix][iy][iz]);
|
||||
|
||||
gamma1 = gfactor1[type[i]];
|
||||
double vsq = v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2];
|
||||
if (vsq > v_0_sq) gamma1 *= (gamma_p + gamma_s)/gamma_p;
|
||||
gamma2 = gfactor2[type[i]] * tsqrt;
|
||||
|
||||
flangevin[i][0] = gamma1*v[i][0] + gamma2*(random->uniform()-0.5);
|
||||
flangevin[i][1] = gamma1*v[i][1] + gamma2*(random->uniform()-0.5);
|
||||
flangevin[i][2] = gamma1*v[i][2] + gamma2*(random->uniform()-0.5);
|
||||
|
||||
f[i][0] += flangevin[i][0];
|
||||
f[i][1] += flangevin[i][1];
|
||||
f[i][2] += flangevin[i][2];
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) error->one(FLERR,"Out of range fix ttm/grid atoms");
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixTTMGrid::end_of_step()
|
||||
{
|
||||
int ix,iy,iz;
|
||||
|
||||
double **x = atom->x;
|
||||
double **v = atom->v;
|
||||
double *mass = atom->mass;
|
||||
double *rmass = atom->rmass;
|
||||
int *type = atom->type;
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
double *boxlo = domain->boxlo;
|
||||
|
||||
memset(&net_energy_transfer[nzlo_out][nylo_out][nxlo_out],0,
|
||||
ngridout*sizeof(double));
|
||||
|
||||
for (int i = 0; i < nlocal; i++)
|
||||
if (mask[i] & groupbit) {
|
||||
ix = static_cast<int> ((x[i][0]-boxlo[0])*delxinv+shift) - OFFSET;
|
||||
iy = static_cast<int> ((x[i][1]-boxlo[1])*delyinv+shift) - OFFSET;
|
||||
iz = static_cast<int> ((x[i][2]-boxlo[2])*delzinv+shift) - OFFSET;
|
||||
net_energy_transfer[ix][iy][iz] +=
|
||||
(flangevin[i][0]*v[i][0] + flangevin[i][1]*v[i][1] +
|
||||
flangevin[i][2]*v[i][2]);
|
||||
}
|
||||
|
||||
gc->reverse_comm(1,this,1,sizeof(double),NET_ENERGY_TRANSFER,
|
||||
gc_buf1,gc_buf2,MPI_DOUBLE);
|
||||
|
||||
double dx = domain->xprd/nxnodes;
|
||||
double dy = domain->yprd/nynodes;
|
||||
double dz = domain->zprd/nznodes;
|
||||
double del_vol = dx*dy*dz;
|
||||
|
||||
// num_inner_timesteps = # of inner steps (thermal solves)
|
||||
// required this MD step to maintain a stable explicit solve
|
||||
|
||||
int num_inner_timesteps = 1;
|
||||
double inner_dt = update->dt;
|
||||
|
||||
double stability_criterion = 1.0 -
|
||||
2.0*inner_dt/(electronic_specific_heat*electronic_density) *
|
||||
(electronic_thermal_conductivity*(1.0/dx/dx + 1.0/dy/dy + 1.0/dz/dz));
|
||||
|
||||
if (stability_criterion < 0.0) {
|
||||
inner_dt = 0.5*(electronic_specific_heat*electronic_density) /
|
||||
(electronic_thermal_conductivity*(1.0/dx/dx + 1.0/dy/dy + 1.0/dz/dz));
|
||||
num_inner_timesteps = static_cast<int>(update->dt/inner_dt) + 1;
|
||||
inner_dt = update->dt/double(num_inner_timesteps);
|
||||
if (num_inner_timesteps > 1000000)
|
||||
error->warning(FLERR,"Too many inner timesteps in fix ttm/grid");
|
||||
}
|
||||
|
||||
for (int ith_inner_timestep = 0; ith_inner_timestep < num_inner_timesteps;
|
||||
ith_inner_timestep++) {
|
||||
|
||||
memcpy(&T_electron_old[nzlo_out][nylo_out][nxlo_out],
|
||||
&T_electron[nzlo_out][nylo_out][nxlo_out],ngridout*sizeof(double));
|
||||
|
||||
// compute new electron T profile
|
||||
|
||||
for (iz = nzlo_in; iz <= nzhi_in; iz++)
|
||||
for (iy = nylo_in; iy <= nyhi_in; iy++)
|
||||
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
|
||||
T_electron[ix][iy][iz] =
|
||||
T_electron_old[ix][iy][iz] +
|
||||
inner_dt/(electronic_specific_heat*electronic_density) *
|
||||
(electronic_thermal_conductivity *
|
||||
|
||||
((T_electron_old[ix-1][iy][iz] + T_electron_old[ix+1][iy][iz] -
|
||||
2*T_electron_old[ix][iy][iz])/dx/dx +
|
||||
(T_electron_old[ix][iy-1][iz] + T_electron_old[ix][iy+1][iz] -
|
||||
2*T_electron_old[ix][iy][iz])/dy/dy +
|
||||
(T_electron_old[ix][iy][iz-1] + T_electron_old[ix][iy][iz+1] -
|
||||
2*T_electron_old[ix][iy][iz])/dz/dz) -
|
||||
|
||||
net_energy_transfer_all[ix][iy][iz]/del_vol);
|
||||
}
|
||||
}
|
||||
|
||||
// comm new T_electron to ghost grid points
|
||||
|
||||
gc->forward_comm(1,this,1,sizeof(double),T_ELECTRON,
|
||||
gc_buf1,gc_buf2,MPI_DOUBLE);
|
||||
|
||||
// output nodal temperatures for current timestep
|
||||
|
||||
if ((nfileevery) && !(update->ntimestep % nfileevery)) {
|
||||
|
||||
// compute atomic Ta for each grid point
|
||||
|
||||
memset(&dsum[nzlo_out][nylo_out][nxlo_out],0,
|
||||
ngridout*sizeof(double));
|
||||
memset(&sum_vsq[nzlo_out][nylo_out][nxlo_out],0,
|
||||
ngridout*sizeof(double));
|
||||
memset(&sum_mass_vsq[nzlo_out][nylo_out][nxlo_out],0,
|
||||
ngridout*sizeof(double));
|
||||
|
||||
double massone;
|
||||
for (int i = 0; i < nlocal; i++)
|
||||
if (mask[i] & groupbit) {
|
||||
if (rmass) massone = rmass[i];
|
||||
else massone = mass[type[i]];
|
||||
double vsq = v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2];
|
||||
|
||||
ix = static_cast<int> ((x[i][0]-boxlo[0])*delxinv+shift) - OFFSET;
|
||||
iy = static_cast<int> ((x[i][1]-boxlo[1])*delyinv+shift) - OFFSET;
|
||||
iz = static_cast<int> ((x[i][2]-boxlo[2])*delzinv+shift) - OFFSET;
|
||||
|
||||
dsum[ix][iy][iz] += 1.0;
|
||||
sum_vsq[ix][iy][iz] += vsq;
|
||||
sum_mass_vsq[ix][iy][iz] += massone*vsq;
|
||||
}
|
||||
|
||||
// can GridComm work on a larger struct of several values?
|
||||
|
||||
gc->reverse_comm(1,this,1,sizeof(double),DSUM,
|
||||
gc_buf1,gc_buf2,MPI_DOUBLE);
|
||||
gc->reverse_comm(1,this,1,sizeof(double),SUM_VSQ,
|
||||
gc_buf1,gc_buf2,MPI_DOUBLE);
|
||||
gc->reverse_comm(1,this,1,sizeof(double),SUM_MASS_VSQ,
|
||||
gc_buf1,gc_buf2,MPI_DOUBLE);
|
||||
|
||||
// NOTE: should this be a write function, work with parallel pings
|
||||
|
||||
if (comm->me == 0) {
|
||||
fmt::print(fp,"{}",update->ntimestep);
|
||||
|
||||
double T_a;
|
||||
for (iz = nzlo_in; iz <= nzhi_in; iz++)
|
||||
for (iy = nylo_in; iy <= nyhi_in; iy++)
|
||||
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
|
||||
T_a = 0;
|
||||
if (dsum[ix][iy][iz] > 0)
|
||||
T_a = sum_mass_vsq[ix][iy][iz] /
|
||||
(3.0*force->boltz*dsum[ix][iy][iz]/force->mvv2e);
|
||||
fmt::print(fp," {}",T_a);
|
||||
}
|
||||
|
||||
fputs("\t",fp);
|
||||
for (iz = nzlo_in; iz <= nzhi_in; iz++)
|
||||
for (iy = nylo_in; iy <= nyhi_in; iy++)
|
||||
for (ix = nxlo_in; ix <= nxhi_in; ix++)
|
||||
fmt::print(fp," {}",T_electron[ix][iy][iz]);
|
||||
fputs("\n",fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
pack own values to buf to send to another proc
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTMGrid::pack_forward_grid(int flag, void *vbuf, int nlist, int *list)
|
||||
{
|
||||
double *buf = (double *) vbuf;
|
||||
|
||||
double *src;
|
||||
if (flag == T_ELECTRON)
|
||||
src = &T_electron[nzlo_out][nylo_out][nxlo_out];
|
||||
|
||||
for (int i = 0; i < nlist; i++)
|
||||
buf[i] = src[list[i]];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
unpack another proc's own values from buf and set own ghost values
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTMGrid::unpack_forward_grid(int flag, void *vbuf, int nlist, int *list)
|
||||
{
|
||||
double *buf = (double *) vbuf;
|
||||
|
||||
double *dest;
|
||||
if (flag == T_ELECTRON)
|
||||
dest = &T_electron[nzlo_out][nylo_out][nxlo_out];
|
||||
|
||||
for (int i = 0; i < nlist; i++)
|
||||
dest[list[i]] = buf[i];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
pack ghost values into buf to send to another proc
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTMGrid::pack_reverse_grid(int flag, void *vbuf, int nlist, int *list)
|
||||
{
|
||||
double *buf = (double *) vbuf;
|
||||
|
||||
double *src;
|
||||
if (flag == NET_ENERGY_TRANSFER)
|
||||
src = &net_energy_transfer[nzlo_out][nylo_out][nxlo_out];
|
||||
else if (flag == DSUM)
|
||||
src = &dsum[nzlo_out][nylo_out][nxlo_out];
|
||||
else if (flag == SUM_VSQ)
|
||||
src = &sum_vsq[nzlo_out][nylo_out][nxlo_out];
|
||||
else if (flag == SUM_MASS_VSQ)
|
||||
src = &sum_mass_vsq[nzlo_out][nylo_out][nxlo_out];
|
||||
|
||||
for (int i = 0; i < nlist; i++)
|
||||
buf[i] = src[list[i]];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
unpack another proc's ghost values from buf and add to own values
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTMGrid::unpack_reverse_grid(int flag, void *vbuf, int nlist, int *list)
|
||||
{
|
||||
double *buf = (double *) vbuf;
|
||||
|
||||
double *dest;
|
||||
if (flag == NET_ENERGY_TRANSFER)
|
||||
dest = &net_energy_transfer[nzlo_out][nylo_out][nxlo_out];
|
||||
else if (flag == DSUM)
|
||||
dest = &dsum[nzlo_out][nylo_out][nxlo_out];
|
||||
else if (flag == SUM_VSQ)
|
||||
dest = &sum_vsq[nzlo_out][nylo_out][nxlo_out];
|
||||
else if (flag == SUM_MASS_VSQ)
|
||||
dest = &sum_mass_vsq[nzlo_out][nylo_out][nxlo_out];
|
||||
|
||||
for (int i = 0; i < nlist; i++)
|
||||
dest[list[i]] += buf[i];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return the energy of the electronic subsystem or the net_energy transfer
|
||||
between the subsystems
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double FixTTMGrid::compute_vector(int n)
|
||||
{
|
||||
int ix,iy,iz;
|
||||
|
||||
double dx = domain->xprd/nxnodes;
|
||||
double dy = domain->yprd/nynodes;
|
||||
double dz = domain->zprd/nznodes;
|
||||
double del_vol = dx*dy*dz;
|
||||
|
||||
double e_energy_me = 0.0;
|
||||
double transfer_energy_me = 0.0;
|
||||
|
||||
for (iz = nzlo_in; iz <= nzhi_in; iz++)
|
||||
for (iy = nylo_in; iy <= nyhi_in; iy++)
|
||||
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
|
||||
e_energy_me +=
|
||||
T_electron[ix][iy][iz]*electronic_specific_heat*
|
||||
electronic_density*del_vol;
|
||||
transfer_energy_me +=
|
||||
net_energy_transfer_all[ix][iy][iz]*update->dt;
|
||||
}
|
||||
|
||||
// NOTE: only do allreduce once ?
|
||||
double e_energy,transfer_energy;
|
||||
MPI_Allreduce(&e_energy_me,&e_energy,1,MPI_DOUBLE,MPI_SUM,world);
|
||||
MPI_Allreduce(&transfer_energy_me,&transfer_energy,1,MPI_DOUBLE,MPI_SUM,world);
|
||||
|
||||
if (n == 0) return e_energy;
|
||||
if (n == 1) return transfer_energy;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
pack entire state of Fix into one write
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTMGrid::write_restart(FILE *fp)
|
||||
{
|
||||
int ix,iy,iz;
|
||||
|
||||
double *rlist;
|
||||
memory->create(rlist,nxnodes*nynodes*nznodes+1,"TTM:rlist");
|
||||
|
||||
int n = 0;
|
||||
rlist[n++] = seed;
|
||||
|
||||
// NOTE: this is a parallel grid now, not a serial grid
|
||||
|
||||
for (iz = nzlo_in; iz <= nzhi_in; iz++)
|
||||
for (iy = nylo_in; iy <= nyhi_in; iy++)
|
||||
for (ix = nxlo_in; ix <= nxhi_in; ix++)
|
||||
rlist[n++] = T_electron[ix][iy][iz];
|
||||
|
||||
if (comm->me == 0) {
|
||||
int size = n * sizeof(double);
|
||||
fwrite(&size,sizeof(int),1,fp);
|
||||
fwrite(rlist,sizeof(double),n,fp);
|
||||
}
|
||||
|
||||
memory->destroy(rlist);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
use state info from restart file to restart the Fix
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTMGrid::restart(char *buf)
|
||||
{
|
||||
int ix,iy,iz;
|
||||
|
||||
int n = 0;
|
||||
double *rlist = (double *) buf;
|
||||
|
||||
// the seed must be changed from the initial seed
|
||||
// NOTE: 0.5 is whacky, could go to zero
|
||||
// NOTE: maybe GridComm should provide a method to pack a grid with bounds
|
||||
|
||||
seed = static_cast<int> (0.5*rlist[n++]);
|
||||
|
||||
for (iz = nzlo_in; iz <= nzhi_in; iz++)
|
||||
for (iy = nylo_in; iy <= nyhi_in; iy++)
|
||||
for (ix = nxlo_in; ix <= nxhi_in; ix++)
|
||||
T_electron[ix][iy][iz] = rlist[n++];
|
||||
|
||||
delete random;
|
||||
random = new RanMars(lmp,seed+comm->me);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
memory usage for flangevin and 3d grid
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double FixTTMGrid::memory_usage()
|
||||
{
|
||||
double bytes = 0.0;
|
||||
bytes += (double)3*atom->nmax * sizeof(double);
|
||||
bytes += (double)6*ngridout * sizeof(double);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
allocate 3d grid quantities
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTMGrid::allocate_grid()
|
||||
{
|
||||
// global indices of grid range from 0 to N-1
|
||||
// nlo_in,nhi_in = lower/upper limits of the 3d sub-brick of
|
||||
// global grid that I own without ghost cells
|
||||
// both non-tiled and tiled proc layouts use 0-1 fractional subdomain info
|
||||
|
||||
if (comm->layout != Comm::LAYOUT_TILED) {
|
||||
nxlo_in = static_cast<int> (comm->xsplit[comm->myloc[0]] * nxnodes);
|
||||
nxhi_in = static_cast<int> (comm->xsplit[comm->myloc[0]+1] * nxnodes) - 1;
|
||||
|
||||
nylo_in = static_cast<int> (comm->ysplit[comm->myloc[1]] * nynodes);
|
||||
nyhi_in = static_cast<int> (comm->ysplit[comm->myloc[1]+1] * nynodes) - 1;
|
||||
|
||||
nzlo_in = static_cast<int> (comm->zsplit[comm->myloc[2]] * nznodes);
|
||||
nzhi_in = static_cast<int> (comm->zsplit[comm->myloc[2]+1] * nznodes) - 1;
|
||||
|
||||
} else {
|
||||
nxlo_in = static_cast<int> (comm->mysplit[0][0] * nxnodes);
|
||||
nxhi_in = static_cast<int> (comm->mysplit[0][1] * nxnodes) - 1;
|
||||
|
||||
nylo_in = static_cast<int> (comm->mysplit[1][0] * nynodes);
|
||||
nyhi_in = static_cast<int> (comm->mysplit[1][1] * nynodes) - 1;
|
||||
|
||||
nzlo_in = static_cast<int> (comm->mysplit[1][0] * nznodes);
|
||||
nzhi_in = static_cast<int> (comm->mysplit[1][1] * nznodes) - 1;
|
||||
}
|
||||
|
||||
// nlo,nhi = min/max index of global grid pt my owned atoms can be mapped to
|
||||
// finite difference stencil requires extra grid pt around my owned grid pts
|
||||
// max of these 2 quantities is the ghost cells needed in each di
|
||||
// nlo_out,nhi_out = nlo_in,nhi_in + ghost cells
|
||||
|
||||
// NOTE: need to wait until init() when neighskin is defined?
|
||||
|
||||
double *boxlo = domain->boxlo;
|
||||
double *sublo = domain->sublo;
|
||||
double *subhi = domain->subhi;
|
||||
|
||||
shift = OFFSET + 0.0; // change this to 0.5 for nearest grid pt
|
||||
delxinv = nxnodes/domain->xprd;
|
||||
delyinv = nxnodes/domain->yprd;
|
||||
delzinv = nxnodes/domain->zprd;
|
||||
|
||||
int nlo,nhi;
|
||||
double cuthalf = 0.5*neighbor->skin;
|
||||
|
||||
nlo = static_cast<int> ((sublo[0]-cuthalf-boxlo[0])*delxinv + shift) - OFFSET;
|
||||
nhi = static_cast<int> ((subhi[0]+cuthalf-boxlo[0])*delxinv + shift) - OFFSET;
|
||||
nxlo_out = MIN(nlo,nxlo_in-1);
|
||||
nxhi_out = MAX(nhi,nxhi_in+1);
|
||||
|
||||
nlo = static_cast<int> ((sublo[1]-cuthalf-boxlo[1])*delyinv + shift) - OFFSET;
|
||||
nhi = static_cast<int> ((subhi[1]+cuthalf-boxlo[1])*delyinv + shift) - OFFSET;
|
||||
nylo_out = MIN(nlo,nylo_in-1);
|
||||
nyhi_out = MAX(nhi,nyhi_in+1);
|
||||
|
||||
nlo = static_cast<int> ((sublo[2]-cuthalf-boxlo[2])*delzinv + shift) - OFFSET;
|
||||
nhi = static_cast<int> ((subhi[2]+cuthalf-boxlo[2])*delzinv + shift) - OFFSET;
|
||||
nzlo_out = MIN(nlo,nzlo_in-1);
|
||||
nzhi_out = MAX(nhi,nzhi_in+1);
|
||||
|
||||
ngridout = (nxhi_out-nxlo_out+1) * (nyhi_out-nylo_out+1) *
|
||||
(nzhi_out-nzlo_out+1);
|
||||
|
||||
gc = new GridComm(lmp,world,nxnodes,nynodes,nznodes,
|
||||
nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in,
|
||||
nxlo_out,nxhi_out,nylo_out,nyhi_out,nzlo_out,nzhi_out);
|
||||
|
||||
gc->setup(ngc_buf1,ngc_buf2);
|
||||
|
||||
memory->create(gc_buf1,ngc_buf1,"ttm/grid:gc_buf1");
|
||||
memory->create(gc_buf2,ngc_buf2,"ttm/grid:gc_buf2");
|
||||
|
||||
memory->create3d_offset(nsum,nzlo_out,nzhi_out,nylo_out,nyhi_out,
|
||||
nxlo_out,nxhi_out,"ttm:nsum");
|
||||
memory->create3d_offset(sum_vsq,nzlo_out,nzhi_out,nylo_out,nyhi_out,
|
||||
nxlo_out,nxhi_out,"ttm:sum_vsq");
|
||||
memory->create3d_offset(sum_mass_vsq,nzlo_out,nzhi_out,nylo_out,nyhi_out,
|
||||
nxlo_out,nxhi_out,"ttm:sum_mass_vsq");
|
||||
memory->create3d_offset(T_electron_old,nzlo_out,nzhi_out,nylo_out,nyhi_out,
|
||||
nxlo_out,nxhi_out,"ttm:T_electron_old");
|
||||
memory->create3d_offset(T_electron,nzlo_out,nzhi_out,nylo_out,nyhi_out,
|
||||
nxlo_out,nxhi_out,"ttm:T_electron");
|
||||
memory->create3d_offset(net_energy_transfer,nzlo_out,nzhi_out,nylo_out,nyhi_out,
|
||||
nxlo_out,nxhi_out,"ttm:net_energy_transfer");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
initialize 3d grid quantities
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTMGrid::init_grid()
|
||||
{
|
||||
memset(&net_energy_transfer[nzlo_out][nylo_out][nxlo_out],0,
|
||||
ngridout*sizeof(double));
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
deallocate 3d grid quantities
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTMGrid::deallocate_grid()
|
||||
{
|
||||
memory->destroy3d_offset(nsum,nzlo_out,nylo_out,nxlo_out);
|
||||
memory->destroy3d_offset(sum_vsq,nzlo_out,nylo_out,nxlo_out);
|
||||
memory->destroy3d_offset(sum_mass_vsq,nzlo_out,nylo_out,nxlo_out);
|
||||
memory->destroy3d_offset(T_electron_old,nzlo_out,nylo_out,nxlo_out);
|
||||
memory->destroy3d_offset(T_electron,nzlo_out,nylo_out,nxlo_out);
|
||||
memory->destroy3d_offset(net_energy_transfer,nzlo_out,nylo_out,nxlo_out);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
read in initial electron temperatures from a user-specified file
|
||||
only called by proc 0
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixTTMGrid::read_initial_electron_temperatures(const char *filename)
|
||||
{
|
||||
int ***T_initial_set;
|
||||
memory->create(T_initial_set,nxnodes,nynodes,nznodes,"ttm:T_initial_set");
|
||||
memset(&T_initial_set[0][0][0],0,total_nnodes*sizeof(int));
|
||||
|
||||
std::string name = utils::get_potential_file_path(filename);
|
||||
if (name.empty())
|
||||
error->one(FLERR,"Cannot open input file: {}",filename);
|
||||
FILE *fpr = fopen(name.c_str(),"r");
|
||||
|
||||
// read initial electron temperature values from file
|
||||
|
||||
char line[MAXLINE];
|
||||
int ixnode,iynode,iznode;
|
||||
double T_tmp;
|
||||
while (1) {
|
||||
if (fgets(line,MAXLINE,fpr) == nullptr) break;
|
||||
ValueTokenizer values(line);
|
||||
if (values.has_next()) ixnode = values.next_int();
|
||||
if (values.has_next()) iynode = values.next_int();
|
||||
if (values.has_next()) iznode = values.next_int();
|
||||
if (values.has_next()) T_tmp = values.next_double();
|
||||
else error->one(FLERR,"Incorrect format in fix ttm/grid input file");
|
||||
|
||||
// check correctness of input data
|
||||
|
||||
if ((ixnode < 0) || (ixnode >= nxnodes)
|
||||
|| (iynode < 0) || (iynode >= nynodes)
|
||||
|| (iznode < 0) || (iznode >= nznodes))
|
||||
error->one(FLERR,"Fix ttm/grid invalid node index in input");
|
||||
|
||||
if (T_tmp < 0.0)
|
||||
error->one(FLERR,"Fix ttm/grid electron temperatures must be > 0.0");
|
||||
|
||||
T_electron[ixnode][iynode][iznode] = T_tmp;
|
||||
T_initial_set[ixnode][iynode][iznode] = 1;
|
||||
}
|
||||
fclose(fpr);
|
||||
|
||||
// check completeness of input data
|
||||
|
||||
for (int ixnode = 0; ixnode < nxnodes; ixnode++)
|
||||
for (int iynode = 0; iynode < nynodes; iynode++)
|
||||
for (int iznode = 0; iznode < nznodes; iznode++)
|
||||
if (T_initial_set[ixnode][iynode][iznode] == 0)
|
||||
error->one(FLERR,"Initial temperatures not all set in fix ttm/grid");
|
||||
|
||||
memory->destroy(T_initial_set);
|
||||
}
|
||||
148
src/MISC/fix_ttm_grid.h
Normal file
148
src/MISC/fix_ttm_grid.h
Normal file
@ -0,0 +1,148 @@
|
||||
/* -*- c++ -*- ----------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
https://www.lammps.org/, 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
|
||||
// clang-format off
|
||||
FixStyle(ttm/grid,FixTTMGrid);
|
||||
// clang-format on
|
||||
#else
|
||||
|
||||
#ifndef LMP_FIX_TTM_GRID_H
|
||||
#define LMP_FIX_TTM_GRID_H
|
||||
|
||||
#include "fix_ttm.h"
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
class FixTTMGrid : public FixTTM {
|
||||
public:
|
||||
FixTTMGrid(class LAMMPS *, int, char **);
|
||||
~FixTTMGrid() {}
|
||||
void post_force(int);
|
||||
void end_of_step();
|
||||
double compute_vector(int);
|
||||
void write_restart(FILE *);
|
||||
void restart(char *);
|
||||
double memory_usage();
|
||||
|
||||
// grid communication
|
||||
|
||||
void pack_forward_grid(int, void *, int, int *);
|
||||
void unpack_forward_grid(int, void *, int, int *);
|
||||
void pack_reverse_grid(int, void *, int, int *);
|
||||
void unpack_reverse_grid(int, void *, int, int *);
|
||||
|
||||
private:
|
||||
int ngridout;
|
||||
int nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in;
|
||||
int nxlo_out,nxhi_out,nylo_out,nyhi_out,nzlo_out,nzhi_out;
|
||||
double shift;
|
||||
double delxinv,delyinv,delzinv;
|
||||
double ***dsum;
|
||||
|
||||
class GridComm *gc;
|
||||
int ngc_buf1,ngc_buf2;
|
||||
double *gc_buf1,*gc_buf2;
|
||||
|
||||
void allocate_grid();
|
||||
void init_grid();
|
||||
void deallocate_grid();
|
||||
|
||||
void read_initial_electron_temperatures(const char *);
|
||||
};
|
||||
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
#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: Cannot open file %s
|
||||
|
||||
The specified file cannot be opened. Check that the path and name are
|
||||
correct. If the file is a compressed file, also check that the gzip
|
||||
executable can be found and run.
|
||||
|
||||
E: Cannot open fix ttm file %s
|
||||
|
||||
The output file for the fix ttm command cannot be opened. Check that
|
||||
the path and name are correct.
|
||||
|
||||
E: Invalid random number seed in fix ttm command
|
||||
|
||||
Random number seed must be > 0.
|
||||
|
||||
E: Fix ttm electronic_specific_heat must be > 0.0
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
E: Fix ttm electronic_density must be > 0.0
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
E: Fix ttm electronic_thermal_conductivity must be >= 0.0
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
E: Fix ttm gamma_p must be > 0.0
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
E: Fix ttm gamma_s must be >= 0.0
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
E: Fix ttm v_0 must be >= 0.0
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
E: Fix ttm number of nodes must be > 0
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
E: Cannot use fix ttm with 2d simulation
|
||||
|
||||
This is a current restriction of this fix due to the grid it creates.
|
||||
|
||||
E: Cannot use non-periodic boundares with fix ttm
|
||||
|
||||
This fix requires a fully periodic simulation box.
|
||||
|
||||
E: Cannot use fix ttm with triclinic box
|
||||
|
||||
This is a current restriction of this fix due to the grid it creates.
|
||||
|
||||
E: Electronic temperature dropped below zero
|
||||
|
||||
Something has gone wrong with the fix ttm electron temperature model.
|
||||
|
||||
E: Fix ttm electron temperatures must be > 0.0
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
E: Initial temperatures not all set in fix ttm
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
W: Too many inner timesteps in fix ttm
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
*/
|
||||
@ -205,6 +205,11 @@ class Fix : protected Pointers {
|
||||
virtual int pack_reverse_comm(int, int, double *) { return 0; }
|
||||
virtual void unpack_reverse_comm(int, int *, double *) {}
|
||||
|
||||
virtual void pack_forward_grid(int, void *, int, int *) {};
|
||||
virtual void unpack_forward_grid(int, void *, int, int *) {};
|
||||
virtual void pack_reverse_grid(int, void *, int, int *) {};
|
||||
virtual void unpack_reverse_grid(int, void *, int, int *) {};
|
||||
|
||||
virtual double compute_scalar() { return 0.0; }
|
||||
virtual double compute_vector(int) { return 0.0; }
|
||||
virtual double compute_array(int, int) { return 0.0; }
|
||||
|
||||
@ -18,11 +18,13 @@
|
||||
#include "error.h"
|
||||
#include "irregular.h"
|
||||
#include "kspace.h"
|
||||
#include "fix.h"
|
||||
#include "memory.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
enum{REGULAR,TILED};
|
||||
enum{KSPACE,FIX};
|
||||
|
||||
#define DELTA 16
|
||||
|
||||
@ -164,10 +166,14 @@ GridComm::~GridComm()
|
||||
|
||||
void GridComm::initialize(MPI_Comm gcomm,
|
||||
int gnx, int gny, int gnz,
|
||||
int ixlo, int ixhi, int iylo, int iyhi, int izlo, int izhi,
|
||||
int oxlo, int oxhi, int oylo, int oyhi, int ozlo, int ozhi,
|
||||
int fxlo, int fxhi, int fylo, int fyhi, int fzlo, int fzhi,
|
||||
int pxlo, int pxhi, int pylo, int pyhi, int pzlo, int pzhi)
|
||||
int ixlo, int ixhi, int iylo, int iyhi,
|
||||
int izlo, int izhi,
|
||||
int oxlo, int oxhi, int oylo, int oyhi,
|
||||
int ozlo, int ozhi,
|
||||
int fxlo, int fxhi, int fylo, int fyhi,
|
||||
int fzlo, int fzhi,
|
||||
int pxlo, int pxhi, int pylo, int pyhi,
|
||||
int pzlo, int pzhi)
|
||||
{
|
||||
gridcomm = gcomm;
|
||||
MPI_Comm_rank(gridcomm,&me);
|
||||
@ -926,31 +932,43 @@ int GridComm::ghost_adjacent_tiled()
|
||||
forward comm of my owned cells to other's ghost cells
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void GridComm::forward_comm_kspace(KSpace *kspace, int nper, int nbyte, int which,
|
||||
void *buf1, void *buf2, MPI_Datatype datatype)
|
||||
void GridComm::forward_comm(int caller, void *ptr, int nper, int nbyte, int which,
|
||||
void *buf1, void *buf2, MPI_Datatype datatype)
|
||||
{
|
||||
if (layout == REGULAR)
|
||||
forward_comm_kspace_regular(kspace,nper,nbyte,which,buf1,buf2,datatype);
|
||||
else
|
||||
forward_comm_kspace_tiled(kspace,nper,nbyte,which,buf1,buf2,datatype);
|
||||
if (layout == REGULAR) {
|
||||
if (caller == KSPACE)
|
||||
forward_comm_regular<KSpace>((KSpace *)ptr,nper,nbyte,which,
|
||||
buf1,buf2,datatype);
|
||||
else if (caller == FIX)
|
||||
forward_comm_regular<Fix>((Fix *)ptr,nper,nbyte,which,
|
||||
buf1,buf2,datatype);
|
||||
} else {
|
||||
if (caller == KSPACE)
|
||||
forward_comm_tiled<KSpace>((KSpace *)ptr,nper,nbyte,which,
|
||||
buf1,buf2,datatype);
|
||||
else if (caller == FIX)
|
||||
forward_comm_tiled<Fix>((Fix *)ptr,nper,nbyte,
|
||||
which,buf1,buf2,datatype);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
forward comm on regular grid of procs via list of swaps with 6 neighbor procs
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
template < class T >
|
||||
void GridComm::
|
||||
forward_comm_kspace_regular(KSpace *kspace, int nper, int /*nbyte*/, int which,
|
||||
void *buf1, void *buf2, MPI_Datatype datatype)
|
||||
forward_comm_regular(T *ptr, int nper, int /*nbyte*/, int which,
|
||||
void *buf1, void *buf2, MPI_Datatype datatype)
|
||||
{
|
||||
int m;
|
||||
MPI_Request request;
|
||||
|
||||
for (m = 0; m < nswap; m++) {
|
||||
if (swap[m].sendproc == me)
|
||||
kspace->pack_forward_grid(which,buf2,swap[m].npack,swap[m].packlist);
|
||||
ptr->pack_forward_grid(which,buf2,swap[m].npack,swap[m].packlist);
|
||||
else
|
||||
kspace->pack_forward_grid(which,buf1,swap[m].npack,swap[m].packlist);
|
||||
ptr->pack_forward_grid(which,buf1,swap[m].npack,swap[m].packlist);
|
||||
|
||||
if (swap[m].sendproc != me) {
|
||||
if (swap[m].nunpack) MPI_Irecv(buf2,nper*swap[m].nunpack,datatype,
|
||||
@ -960,7 +978,7 @@ forward_comm_kspace_regular(KSpace *kspace, int nper, int /*nbyte*/, int which,
|
||||
if (swap[m].nunpack) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
}
|
||||
|
||||
kspace->unpack_forward_grid(which,buf2,swap[m].nunpack,swap[m].unpacklist);
|
||||
ptr->unpack_forward_grid(which,buf2,swap[m].nunpack,swap[m].unpacklist);
|
||||
}
|
||||
}
|
||||
|
||||
@ -968,9 +986,10 @@ forward_comm_kspace_regular(KSpace *kspace, int nper, int /*nbyte*/, int which,
|
||||
forward comm on tiled grid decomp via Send/Recv lists of each neighbor proc
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
template < class T >
|
||||
void GridComm::
|
||||
forward_comm_kspace_tiled(KSpace *kspace, int nper, int nbyte, int which,
|
||||
void *buf1, void *vbuf2, MPI_Datatype datatype)
|
||||
forward_comm_tiled(T *ptr, int nper, int nbyte, int which,
|
||||
void *buf1, void *vbuf2, MPI_Datatype datatype)
|
||||
{
|
||||
int i,m,offset;
|
||||
|
||||
@ -987,15 +1006,15 @@ forward_comm_kspace_tiled(KSpace *kspace, int nper, int nbyte, int which,
|
||||
// perform all sends to other procs
|
||||
|
||||
for (m = 0; m < nsend; m++) {
|
||||
kspace->pack_forward_grid(which,buf1,send[m].npack,send[m].packlist);
|
||||
ptr->pack_forward_grid(which,buf1,send[m].npack,send[m].packlist);
|
||||
MPI_Send(buf1,nper*send[m].npack,datatype,send[m].proc,0,gridcomm);
|
||||
}
|
||||
|
||||
// perform all copies to self
|
||||
|
||||
for (m = 0; m < ncopy; m++) {
|
||||
kspace->pack_forward_grid(which,buf1,copy[m].npack,copy[m].packlist);
|
||||
kspace->unpack_forward_grid(which,buf1,copy[m].nunpack,copy[m].unpacklist);
|
||||
ptr->pack_forward_grid(which,buf1,copy[m].npack,copy[m].packlist);
|
||||
ptr->unpack_forward_grid(which,buf1,copy[m].nunpack,copy[m].unpacklist);
|
||||
}
|
||||
|
||||
// unpack all received data
|
||||
@ -1003,8 +1022,8 @@ forward_comm_kspace_tiled(KSpace *kspace, int nper, int nbyte, int which,
|
||||
for (i = 0; i < nrecv; i++) {
|
||||
MPI_Waitany(nrecv,requests,&m,MPI_STATUS_IGNORE);
|
||||
offset = nper * recv[m].offset * nbyte;
|
||||
kspace->unpack_forward_grid(which,(void *) &buf2[offset],
|
||||
recv[m].nunpack,recv[m].unpacklist);
|
||||
ptr->unpack_forward_grid(which,(void *) &buf2[offset],
|
||||
recv[m].nunpack,recv[m].unpacklist);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1012,31 +1031,43 @@ forward_comm_kspace_tiled(KSpace *kspace, int nper, int nbyte, int which,
|
||||
reverse comm of my ghost cells to sum to owner cells
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void GridComm::reverse_comm_kspace(KSpace *kspace, int nper, int nbyte, int which,
|
||||
void *buf1, void *buf2, MPI_Datatype datatype)
|
||||
void GridComm::reverse_comm(int caller, void *ptr, int nper, int nbyte, int which,
|
||||
void *buf1, void *buf2, MPI_Datatype datatype)
|
||||
{
|
||||
if (layout == REGULAR)
|
||||
reverse_comm_kspace_regular(kspace,nper,nbyte,which,buf1,buf2,datatype);
|
||||
else
|
||||
reverse_comm_kspace_tiled(kspace,nper,nbyte,which,buf1,buf2,datatype);
|
||||
if (layout == REGULAR) {
|
||||
if (caller == KSPACE)
|
||||
reverse_comm_regular<KSpace>((KSpace *)ptr,nper,nbyte,which,
|
||||
buf1,buf2,datatype);
|
||||
else if (caller == FIX)
|
||||
reverse_comm_regular<Fix>((Fix *)ptr,nper,nbyte,which,
|
||||
buf1,buf2,datatype);
|
||||
} else {
|
||||
if (caller == KSPACE)
|
||||
reverse_comm_tiled<KSpace>((KSpace *)ptr,nper,nbyte,which,
|
||||
buf1,buf2,datatype);
|
||||
else if (caller == FIX)
|
||||
reverse_comm_tiled<Fix>((Fix *)ptr,nper,nbyte,which,
|
||||
buf1,buf2,datatype);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
reverse comm on regular grid of procs via list of swaps with 6 neighbor procs
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
template < class T >
|
||||
void GridComm::
|
||||
reverse_comm_kspace_regular(KSpace *kspace, int nper, int /*nbyte*/, int which,
|
||||
void *buf1, void *buf2, MPI_Datatype datatype)
|
||||
reverse_comm_regular(T *ptr, int nper, int /*nbyte*/, int which,
|
||||
void *buf1, void *buf2, MPI_Datatype datatype)
|
||||
{
|
||||
int m;
|
||||
MPI_Request request;
|
||||
|
||||
for (m = nswap-1; m >= 0; m--) {
|
||||
if (swap[m].recvproc == me)
|
||||
kspace->pack_reverse_grid(which,buf2,swap[m].nunpack,swap[m].unpacklist);
|
||||
ptr->pack_reverse_grid(which,buf2,swap[m].nunpack,swap[m].unpacklist);
|
||||
else
|
||||
kspace->pack_reverse_grid(which,buf1,swap[m].nunpack,swap[m].unpacklist);
|
||||
ptr->pack_reverse_grid(which,buf1,swap[m].nunpack,swap[m].unpacklist);
|
||||
|
||||
if (swap[m].recvproc != me) {
|
||||
if (swap[m].npack) MPI_Irecv(buf2,nper*swap[m].npack,datatype,
|
||||
@ -1046,7 +1077,7 @@ reverse_comm_kspace_regular(KSpace *kspace, int nper, int /*nbyte*/, int which,
|
||||
if (swap[m].npack) MPI_Wait(&request,MPI_STATUS_IGNORE);
|
||||
}
|
||||
|
||||
kspace->unpack_reverse_grid(which,buf2,swap[m].npack,swap[m].packlist);
|
||||
ptr->unpack_reverse_grid(which,buf2,swap[m].npack,swap[m].packlist);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1054,9 +1085,10 @@ reverse_comm_kspace_regular(KSpace *kspace, int nper, int /*nbyte*/, int which,
|
||||
reverse comm on tiled grid decomp via Send/Recv lists of each neighbor proc
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
template < class T >
|
||||
void GridComm::
|
||||
reverse_comm_kspace_tiled(KSpace *kspace, int nper, int nbyte, int which,
|
||||
void *buf1, void *vbuf2, MPI_Datatype datatype)
|
||||
reverse_comm_tiled(T *ptr, int nper, int nbyte, int which,
|
||||
void *buf1, void *vbuf2, MPI_Datatype datatype)
|
||||
{
|
||||
int i,m,offset;
|
||||
|
||||
@ -1073,15 +1105,15 @@ reverse_comm_kspace_tiled(KSpace *kspace, int nper, int nbyte, int which,
|
||||
// perform all sends to other procs
|
||||
|
||||
for (m = 0; m < nrecv; m++) {
|
||||
kspace->pack_reverse_grid(which,buf1,recv[m].nunpack,recv[m].unpacklist);
|
||||
ptr->pack_reverse_grid(which,buf1,recv[m].nunpack,recv[m].unpacklist);
|
||||
MPI_Send(buf1,nper*recv[m].nunpack,datatype,recv[m].proc,0,gridcomm);
|
||||
}
|
||||
|
||||
// perform all copies to self
|
||||
|
||||
for (m = 0; m < ncopy; m++) {
|
||||
kspace->pack_reverse_grid(which,buf1,copy[m].nunpack,copy[m].unpacklist);
|
||||
kspace->unpack_reverse_grid(which,buf1,copy[m].npack,copy[m].packlist);
|
||||
ptr->pack_reverse_grid(which,buf1,copy[m].nunpack,copy[m].unpacklist);
|
||||
ptr->unpack_reverse_grid(which,buf1,copy[m].npack,copy[m].packlist);
|
||||
}
|
||||
|
||||
// unpack all received data
|
||||
@ -1089,8 +1121,8 @@ reverse_comm_kspace_tiled(KSpace *kspace, int nper, int nbyte, int which,
|
||||
for (i = 0; i < nsend; i++) {
|
||||
MPI_Waitany(nsend,requests,&m,MPI_STATUS_IGNORE);
|
||||
offset = nper * send[m].offset * nbyte;
|
||||
kspace->unpack_reverse_grid(which,(void *) &buf2[offset],
|
||||
send[m].npack,send[m].packlist);
|
||||
ptr->unpack_reverse_grid(which,(void *) &buf2[offset],
|
||||
send[m].npack,send[m].packlist);
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,8 +27,8 @@ class GridComm : protected Pointers {
|
||||
virtual ~GridComm();
|
||||
void setup(int &, int &);
|
||||
int ghost_adjacent();
|
||||
void forward_comm_kspace(class KSpace *, int, int, int, void *, void *, MPI_Datatype);
|
||||
void reverse_comm_kspace(class KSpace *, int, int, int, void *, void *, MPI_Datatype);
|
||||
void forward_comm(int, void *, int, int, int, void *, void *, MPI_Datatype);
|
||||
void reverse_comm(int, void *, int, int, int, void *, void *, MPI_Datatype);
|
||||
|
||||
protected:
|
||||
int me, nprocs;
|
||||
@ -181,10 +181,14 @@ class GridComm : protected Pointers {
|
||||
int ghost_adjacent_regular();
|
||||
int ghost_adjacent_tiled();
|
||||
|
||||
void forward_comm_kspace_regular(class KSpace *, int, int, int, void *, void *, MPI_Datatype);
|
||||
void forward_comm_kspace_tiled(class KSpace *, int, int, int, void *, void *, MPI_Datatype);
|
||||
void reverse_comm_kspace_regular(class KSpace *, int, int, int, void *, void *, MPI_Datatype);
|
||||
void reverse_comm_kspace_tiled(class KSpace *, int, int, int, void *, void *, MPI_Datatype);
|
||||
template <class T>
|
||||
void forward_comm_regular(T *, int, int, int, void *, void *, MPI_Datatype);
|
||||
template <class T>
|
||||
void forward_comm_tiled(T *, int, int, int, void *, void *, MPI_Datatype);
|
||||
template <class T>
|
||||
void reverse_comm_regular(T *, int, int, int, void *, void *, MPI_Datatype);
|
||||
template <class T>
|
||||
void reverse_comm_tiled(T *, int, int, int, void *, void *, MPI_Datatype);
|
||||
|
||||
virtual void grow_swap();
|
||||
void grow_overlap();
|
||||
Reference in New Issue
Block a user