Multiphase support

This commit is contained in:
jtclemm
2023-11-14 12:33:51 -07:00
parent 73a3ae7602
commit f9b385061b
18 changed files with 430 additions and 337 deletions

View File

@ -41,7 +41,7 @@ enum{COMMGRAD, COMMFIELD};
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeRHEOGrad::ComputeRHEOGrad(LAMMPS *lmp, int narg, char **arg) : ComputeRHEOGrad::ComputeRHEOGrad(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), fix_rheo(nullptr), list(nullptr), compute_interface(nullptr), compute_kernel(nullptr), Compute(lmp, narg, arg), fix_rheo(nullptr), list(nullptr), rho0(nullptr), compute_interface(nullptr), compute_kernel(nullptr),
gradv(nullptr), gradr(nullptr), gradt(nullptr), gradn(nullptr) gradv(nullptr), gradr(nullptr), gradt(nullptr), gradn(nullptr)
{ {
if (narg < 4) error->all(FLERR,"Illegal compute rheo/grad command"); if (narg < 4) error->all(FLERR,"Illegal compute rheo/grad command");
@ -221,8 +221,8 @@ void ComputeRHEOGrad::compute_peratom()
//compute_interface->correct_v(vi, vj, i, j); //compute_interface->correct_v(vi, vj, i, j);
rhoi = compute_interface->correct_rho(i, j); rhoi = compute_interface->correct_rho(i, j);
} else if ((!fluidi) && (!fluidj)) { } else if ((!fluidi) && (!fluidj)) {
rhoi = rho0; rhoi = rho0[itype];
rhoj = rho0; rhoj = rho0[jtype];
} }
} }

View File

@ -46,7 +46,7 @@ class ComputeRHEOGrad : public Compute {
private: private:
int comm_stage, ncomm_grad, ncomm_field, nmax_store; int comm_stage, ncomm_grad, ncomm_field, nmax_store;
double cut, cutsq, rho0; double cut, cutsq, *rho0;
int velocity_flag, temperature_flag, rho_flag, eta_flag; int velocity_flag, temperature_flag, rho_flag, eta_flag;
int interface_flag, remap_v_flag; int interface_flag, remap_v_flag;

View File

@ -25,6 +25,7 @@
#include "error.h" #include "error.h"
#include "force.h" #include "force.h"
#include "fix_rheo.h" #include "fix_rheo.h"
#include "fix_rheo_pressure.h"
#include "memory.h" #include "memory.h"
#include "modify.h" #include "modify.h"
#include "neighbor.h" #include "neighbor.h"
@ -42,7 +43,7 @@ static constexpr double EPSILON = 1e-1;
ComputeRHEOInterface::ComputeRHEOInterface(LAMMPS *lmp, int narg, char **arg) : ComputeRHEOInterface::ComputeRHEOInterface(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), fix_rheo(nullptr), compute_kernel(nullptr), fp_store(nullptr), Compute(lmp, narg, arg), fix_rheo(nullptr), compute_kernel(nullptr), fp_store(nullptr),
norm(nullptr), normwf(nullptr), chi(nullptr), id_fix_pa(nullptr) rho0(nullptr), norm(nullptr), normwf(nullptr), chi(nullptr), id_fix_pa(nullptr)
{ {
if (narg != 3) error->all(FLERR,"Illegal compute rheo/interface command"); if (narg != 3) error->all(FLERR,"Illegal compute rheo/interface command");
@ -86,11 +87,12 @@ void ComputeRHEOInterface::init()
compute_kernel = fix_rheo->compute_kernel; compute_kernel = fix_rheo->compute_kernel;
rho0 = fix_rheo->rho0; rho0 = fix_rheo->rho0;
cut = fix_rheo->cut; cut = fix_rheo->cut;
csq = fix_rheo->csq;
csq_inv = 1.0 / csq;
cutsq = cut * cut; cutsq = cut * cut;
wall_max = sqrt(3.0) / 12.0 * cut; wall_max = sqrt(3.0) / 12.0 * cut;
auto fixes = modify->get_fix_by_style("rheo/pressure");
fix_pressure = dynamic_cast<FixRHEOPressure *>(fixes[0]);
neighbor->add_request(this, NeighConst::REQ_DEFAULT); neighbor->add_request(this, NeighConst::REQ_DEFAULT);
} }
@ -174,7 +176,7 @@ void ComputeRHEOInterface::compute_peratom()
dot += (-fp_store[j][1] + fp_store[i][1]) * dely; dot += (-fp_store[j][1] + fp_store[i][1]) * dely;
dot += (-fp_store[j][2] + fp_store[i][2]) * delz; dot += (-fp_store[j][2] + fp_store[i][2]) * delz;
rho[i] += w * (csq * (rho[j] - rho0) - rho[j] * dot); rho[i] += w * (fix_pressure->calc_pressure(rho[j], jtype) - rho[j] * dot);
normwf[i] += w; normwf[i] += w;
} }
} }
@ -189,7 +191,7 @@ void ComputeRHEOInterface::compute_peratom()
dot += (-fp_store[i][1] + fp_store[j][1]) * dely; dot += (-fp_store[i][1] + fp_store[j][1]) * dely;
dot += (-fp_store[i][2] + fp_store[j][2]) * delz; dot += (-fp_store[i][2] + fp_store[j][2]) * delz;
rho[j] += w * (csq * (rho[i] - rho0) + rho[i] * dot); rho[j] += w * (fix_pressure->calc_pressure(rho[i], itype) + rho[i] * dot);
normwf[j] += w; normwf[j] += w;
} }
} }
@ -207,9 +209,9 @@ void ComputeRHEOInterface::compute_peratom()
if (status[i] & PHASECHECK) { if (status[i] & PHASECHECK) {
if (normwf[i] != 0.0) { if (normwf[i] != 0.0) {
// Stores rho for solid particles 1+Pw in Adami Adams 2012 // Stores rho for solid particles 1+Pw in Adami Adams 2012
rho[i] = MAX(EPSILON, rho0 + (rho[i] / normwf[i]) * csq_inv); rho[i] = MAX(EPSILON, fix_pressure->calc_rho(rho[i] / normwf[i], type[i]));
} else { } else {
rho[i] = rho0; rho[i] = rho0[itype];
} }
} }
} }

View File

@ -45,13 +45,14 @@ class ComputeRHEOInterface : public Compute {
private: private:
int nmax_store, comm_stage; int nmax_store, comm_stage;
double rho0, cut, cutsq, csq, csq_inv, wall_max; double *rho0, cut, cutsq, wall_max;
double *norm, *normwf; double *norm, *normwf;
char *id_fix_pa; char *id_fix_pa;
class NeighList *list; class NeighList *list;
class ComputeRHEOKernel *compute_kernel; class ComputeRHEOKernel *compute_kernel;
class FixRHEOPressure *fix_pressure;
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS

View File

@ -330,11 +330,12 @@ void ComputeRHEOPropertyAtom::pack_coordination(int n)
void ComputeRHEOPropertyAtom::pack_cv(int n) void ComputeRHEOPropertyAtom::pack_cv(int n)
{ {
int *type = atom->type;
int *mask = atom->mask; int *mask = atom->mask;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) { for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = fix_thermal->calc_cv(i); if (mask[i] & groupbit) buf[n] = fix_thermal->calc_cv(i, type[i]);
else buf[n] = 0.0; else buf[n] = 0.0;
n += nvalues; n += nvalues;
} }

View File

@ -42,7 +42,7 @@ static constexpr double EPSILON = 1e-10;
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeRHEOSurface::ComputeRHEOSurface(LAMMPS *lmp, int narg, char **arg) : ComputeRHEOSurface::ComputeRHEOSurface(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), fix_rheo(nullptr), list(nullptr), compute_kernel(nullptr), compute_interface(nullptr), Compute(lmp, narg, arg), fix_rheo(nullptr), list(nullptr), rho0(nullptr), compute_kernel(nullptr), compute_interface(nullptr),
B(nullptr), gradC(nullptr), nsurface(nullptr), divr(nullptr), rsurface(nullptr) B(nullptr), gradC(nullptr), nsurface(nullptr), divr(nullptr), rsurface(nullptr)
{ {
if (narg != 3) error->all(FLERR,"Illegal compute RHEO/SURFACE command"); if (narg != 3) error->all(FLERR,"Illegal compute RHEO/SURFACE command");
@ -194,8 +194,8 @@ void ComputeRHEOSurface::compute_peratom()
} else if ((!fluidi) && fluidj) { } else if ((!fluidi) && fluidj) {
rhoi = compute_interface->correct_rho(i, j); rhoi = compute_interface->correct_rho(i, j);
} else if ((!fluidi) && (!fluidj)) { } else if ((!fluidi) && (!fluidj)) {
rhoi = rho0; rhoi = rho0[itype];
rhoj = rho0; rhoj = rho0[jtype];
} }
} }

View File

@ -44,7 +44,7 @@ class ComputeRHEOSurface : public Compute {
int threshold_style, comm_stage; int threshold_style, comm_stage;
int index_divr, index_rsurf, index_nsurf; int index_divr, index_rsurf, index_nsurf;
double cut, cutsq, rho0, threshold_divr; double cut, cutsq, *rho0, threshold_divr;
double **B, **gradC; double **B, **gradC;
class NeighList *list; class NeighList *list;

View File

@ -28,6 +28,7 @@
#include "domain.h" #include "domain.h"
#include "error.h" #include "error.h"
#include "force.h" #include "force.h"
#include "memory.h"
#include "modify.h" #include "modify.h"
#include "update.h" #include "update.h"
#include "utils.h" #include "utils.h"
@ -40,7 +41,7 @@ using namespace FixConst;
FixRHEO::FixRHEO(LAMMPS *lmp, int narg, char **arg) : FixRHEO::FixRHEO(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), compute_grad(nullptr), compute_kernel(nullptr), compute_surface(nullptr), Fix(lmp, narg, arg), compute_grad(nullptr), compute_kernel(nullptr), compute_surface(nullptr),
compute_interface(nullptr), compute_rhosum(nullptr), compute_vshift(nullptr) compute_interface(nullptr), compute_rhosum(nullptr), compute_vshift(nullptr), rho0(nullptr), csq(nullptr)
{ {
time_integrate = 1; time_integrate = 1;
@ -54,71 +55,81 @@ FixRHEO::FixRHEO(LAMMPS *lmp, int narg, char **arg) :
interface_flag = 0; interface_flag = 0;
surface_flag = 0; surface_flag = 0;
rho0 = 1.0; int i;
csq = 1.0; int n = atom->ntypes;
memory->create(rho0, n + 1, "rheo:rho0");
memory->create(csq, n + 1, "rheo:csq");
for (i = 1; i <= n; i++) {
rho0[i] = 1.0;
csq[i] = 1.0;
}
if (igroup != 0) if (igroup != 0)
error->all(FLERR,"fix rheo command requires group all"); error->all(FLERR, "fix rheo command requires group all");
if (atom->pressure_flag != 1) if (atom->pressure_flag != 1)
error->all(FLERR,"fix rheo command requires atom_style with pressure"); error->all(FLERR, "fix rheo command requires atom_style with pressure");
if (atom->rho_flag != 1) if (atom->rho_flag != 1)
error->all(FLERR,"fix rheo command requires atom_style with density"); error->all(FLERR, "fix rheo command requires atom_style with density");
if (atom->viscosity_flag != 1) if (atom->viscosity_flag != 1)
error->all(FLERR,"fix rheo command requires atom_style with viscosity"); error->all(FLERR, "fix rheo command requires atom_style with viscosity");
if (atom->status_flag != 1) if (atom->status_flag != 1)
error->all(FLERR,"fix rheo command requires atom_style with status"); error->all(FLERR, "fix rheo command requires atom_style with status");
if (narg < 5) if (narg < 5)
error->all(FLERR,"Insufficient arguments for fix rheo command"); error->all(FLERR, "Insufficient arguments for fix rheo command");
h = utils::numeric(FLERR,arg[3],false,lmp); h = utils::numeric(FLERR, arg[3], false, lmp);
cut = h; cut = h;
if (strcmp(arg[4],"quintic") == 0) { if (strcmp(arg[4], "quintic") == 0) {
kernel_style = QUINTIC; kernel_style = QUINTIC;
} else if (strcmp(arg[4],"RK0") == 0) { } else if (strcmp(arg[4], "RK0") == 0) {
kernel_style = RK0; kernel_style = RK0;
} else if (strcmp(arg[4],"RK1") == 0) { } else if (strcmp(arg[4], "RK1") == 0) {
kernel_style = RK1; kernel_style = RK1;
} else if (strcmp(arg[4],"RK2") == 0) { } else if (strcmp(arg[4], "RK2") == 0) {
kernel_style = RK2; kernel_style = RK2;
} else error->all(FLERR,"Unknown kernel style {} in fix rheo", arg[4]); } else error->all(FLERR, "Unknown kernel style {} in fix rheo", arg[4]);
zmin_kernel = utils::numeric(FLERR,arg[5],false,lmp); zmin_kernel = utils::numeric(FLERR, arg[5], false, lmp);
int iarg = 6; int iarg = 6;
while (iarg < narg){ while (iarg < narg){
if (strcmp(arg[iarg],"shift") == 0) { if (strcmp(arg[iarg], "shift") == 0) {
shift_flag = 1; shift_flag = 1;
} else if (strcmp(arg[iarg],"thermal") == 0) { } else if (strcmp(arg[iarg], "thermal") == 0) {
thermal_flag = 1; thermal_flag = 1;
} else if (strcmp(arg[iarg],"surface/detection") == 0) { } else if (strcmp(arg[iarg], "surface/detection") == 0) {
surface_flag = 1; surface_flag = 1;
if(iarg + 2 >= narg) error->all(FLERR,"Illegal surface/detection option in fix rheo"); if(iarg + 2 >= narg) error->all(FLERR, "Illegal surface/detection option in fix rheo");
if (strcmp(arg[iarg + 1], "coordination") == 0) { if (strcmp(arg[iarg + 1], "coordination") == 0) {
surface_style = COORDINATION; surface_style = COORDINATION;
zmin_surface = utils::inumeric(FLERR,arg[iarg + 2],false,lmp); zmin_surface = utils::inumeric(FLERR, arg[iarg + 2], false, lmp);
zmin_splash = utils::inumeric(FLERR,arg[iarg + 3],false,lmp); zmin_splash = utils::inumeric(FLERR, arg[iarg + 3], false, lmp);
} else if (strcmp(arg[iarg + 1], "divergence") == 0) { } else if (strcmp(arg[iarg + 1], "divergence") == 0) {
surface_style = DIVR; surface_style = DIVR;
divr_surface = utils::numeric(FLERR,arg[iarg + 2],false,lmp); divr_surface = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
zmin_splash = utils::inumeric(FLERR,arg[iarg + 3],false,lmp); zmin_splash = utils::inumeric(FLERR, arg[iarg + 3], false, lmp);
} else { } else {
error->all(FLERR,"Illegal surface/detection option in fix rheo, {}", arg[iarg + 1]); error->all(FLERR, "Illegal surface/detection option in fix rheo, {}", arg[iarg + 1]);
} }
iarg += 3; iarg += 3;
} else if (strcmp(arg[iarg],"interface/reconstruct") == 0) { } else if (strcmp(arg[iarg], "interface/reconstruct") == 0) {
interface_flag = 1; interface_flag = 1;
} else if (strcmp(arg[iarg],"rho/sum") == 0) { } else if (strcmp(arg[iarg], "rho/sum") == 0) {
rhosum_flag = 1; rhosum_flag = 1;
} else if (strcmp(arg[iarg],"density") == 0) { } else if (strcmp(arg[iarg], "density") == 0) {
if(iarg + 1 >= narg) error->all(FLERR,"Illegal rho0 option in fix rheo"); if (iarg + n >= narg) error->all(FLERR, "Illegal rho0 option in fix rheo");
rho0 = utils::numeric(FLERR,arg[iarg + 1],false,lmp); for (i = 1; i <= n; i++)
iarg += 1; rho0[i] = utils::numeric(FLERR, arg[iarg + i], false, lmp);
} else if (strcmp(arg[iarg],"sound/squared") == 0) { iarg += n;
if(iarg+1 >= narg) error->all(FLERR,"Illegal csq option in fix rheo"); } else if (strcmp(arg[iarg], "speed/sound") == 0) {
csq = utils::numeric(FLERR,arg[iarg + 1],false,lmp); if (iarg + n >= narg) error->all(FLERR, "Illegal csq option in fix rheo");
iarg += 1; for (i = 1; i <= n; i++) {
csq[i] = utils::numeric(FLERR, arg[iarg + i], false, lmp);
csq[i] *= csq[i];
}
iarg += n;
} else { } else {
error->all(FLERR, "Illegal fix rheo command: {}", arg[iarg]); error->all(FLERR, "Illegal fix rheo command: {}", arg[iarg]);
} }
@ -136,6 +147,9 @@ FixRHEO::~FixRHEO()
if (compute_surface) modify->delete_compute("rheo_surface"); if (compute_surface) modify->delete_compute("rheo_surface");
if (compute_rhosum) modify->delete_compute("rheo_rhosum"); if (compute_rhosum) modify->delete_compute("rheo_rhosum");
if (compute_vshift) modify->delete_compute("rheo_vshift"); if (compute_vshift) modify->delete_compute("rheo_vshift");
memory->destroy(csq);
memory->destroy(rho0);
} }
@ -198,7 +212,7 @@ void FixRHEO::init()
dtf = 0.5 * update->dt * force->ftm2v; dtf = 0.5 * update->dt * force->ftm2v;
if (modify->get_fix_by_style("^rheo$").size() > 1) if (modify->get_fix_by_style("^rheo$").size() > 1)
error->all(FLERR,"Can only specify one instance of fix rheo"); error->all(FLERR, "Can only specify one instance of fix rheo");
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */

View File

@ -39,7 +39,8 @@ class FixRHEO : public Fix {
void reset_dt() override; void reset_dt() override;
// Model parameters // Model parameters
double h, cut, rho0, csq; double h, cut;
double *rho0, *csq;
int zmin_kernel, zmin_surface, zmin_splash; int zmin_kernel, zmin_surface, zmin_splash;
int kernel_style, surface_style; int kernel_style, surface_style;
double divr_surface; double divr_surface;

View File

@ -38,39 +38,62 @@ static constexpr double SEVENTH = 1.0 / 7.0;
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
FixRHEOPressure::FixRHEOPressure(LAMMPS *lmp, int narg, char **arg) : FixRHEOPressure::FixRHEOPressure(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), fix_rheo(nullptr) Fix(lmp, narg, arg), fix_rheo(nullptr), rho0(nullptr), csq(nullptr), rho0inv(nullptr), csqinv(nullptr), c_cubic(nullptr), pressure_style(nullptr)
{ {
if (narg < 4) error->all(FLERR,"Illegal fix command"); if (narg < 4) error->all(FLERR,"Illegal fix command");
pressure_style = NONE;
comm_forward = 1; comm_forward = 1;
// Currently can only have one instance of fix rheo/pressure // Currently can only have one instance of fix rheo/pressure
if (igroup != 0) if (igroup != 0)
error->all(FLERR,"fix rheo/pressure command requires group all"); error->all(FLERR,"fix rheo/pressure command requires group all");
int ntypes = atom->ntypes; int i, nlo, nhi;
int n = atom->ntypes;
memory->create(pressure_style, n + 1, "rheo:pressure_style");
for (i = 1; i <= n; i++) pressure_style[i] = NONE;
int iarg = 3; int iarg = 3;
if (strcmp(arg[iarg], "linear") == 0) { while (iarg < narg) {
pressure_style = LINEAR; utils::bounds(FLERR, arg[iarg], 1, n, nlo, nhi, error);
} else if (strcmp(arg[iarg], "taitwater") == 0) {
pressure_style = TAITWATER; if (iarg + 1 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/pressure", error);
} else if (strcmp(arg[iarg], "cubic") == 0) {
pressure_style = CUBIC; if (strcmp(arg[iarg + 1], "linear") == 0) {
if (iarg + 1 >= narg) error->all(FLERR, "Insufficient arguments for pressure option"); for (i = nlo; i <= nhi; i++)
c_cubic = utils::numeric(FLERR, arg[iarg + 1], false, lmp); pressure_style[i] = LINEAR;
} else { } else if (strcmp(arg[iarg + 1], "taitwater") == 0) {
error->all(FLERR,"Illegal fix command, {}", arg[iarg]); for (i = nlo; i <= nhi; i++)
pressure_style[i] = TAITWATER;
} else if (strcmp(arg[iarg + 1], "cubic") == 0) {
if (iarg + 2 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/pressure cubic", error);
double c_cubic_one = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
iarg += 1;
for (i = nlo; i <= nhi; i++) {
pressure_style[i] = CUBIC;
c_cubic[i] = c_cubic_one;
}
} else {
error->all(FLERR,"Illegal fix command, {}", arg[iarg]);
}
iarg += 2;
} }
if (pressure_style == NONE) for (i = 1; i <= n; i++)
error->all(FLERR,"Must specify pressure style for fix/rheo/pressure"); if (pressure_style[i] == NONE)
error->all(FLERR,"Must specify pressure for atom type {} in fix/rheo/pressure", i);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
FixRHEOPressure::~FixRHEOPressure() FixRHEOPressure::~FixRHEOPressure()
{ {
memory->destroy(pressure_style);
memory->destroy(csqinv);
memory->destroy(rho0inv);
memory->destroy(c_cubic);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -92,9 +115,15 @@ void FixRHEOPressure::init()
csq = fix_rheo->csq; csq = fix_rheo->csq;
rho0 = fix_rheo->rho0; rho0 = fix_rheo->rho0;
rho0inv = 1.0 / rho0;
// Cannot define multiple as pair rheo cannot currently distinguish int n = atom->ntypes;
memory->create(csqinv, n + 1, "rheo:rho0inv");
memory->create(rho0inv, n + 1, "rheo:rho0inv");
for (int i = 0; i <= n; i++) {
csqinv[i] = 1.0 / csq[i];
rho0inv[i] = 1.0 / rho0[i];
}
if (modify->get_fix_by_style("rheo/pressure").size() > 1) if (modify->get_fix_by_style("rheo/pressure").size() > 1)
error->all(FLERR, "Can only specify one instance of fix rheo/pressure"); error->all(FLERR, "Can only specify one instance of fix rheo/pressure");
} }
@ -117,6 +146,7 @@ void FixRHEOPressure::pre_force(int /*vflag*/)
double dr, rr3, rho_ratio; double dr, rr3, rho_ratio;
int *mask = atom->mask; int *mask = atom->mask;
int *type = atom->type;
double *rho = atom->rho; double *rho = atom->rho;
double *pressure = atom->pressure; double *pressure = atom->pressure;
@ -124,7 +154,7 @@ void FixRHEOPressure::pre_force(int /*vflag*/)
for (i = 0; i < nlocal; i++) for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) if (mask[i] & groupbit)
pressure[i] = calc_pressure(rho[i]); pressure[i] = calc_pressure(rho[i], type[i]);
if (comm_forward) comm->forward_comm(this); if (comm_forward) comm->forward_comm(this);
} }
@ -161,19 +191,37 @@ void FixRHEOPressure::unpack_forward_comm(int n, int first, double *buf)
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
double FixRHEOPressure::calc_pressure(double rho) double FixRHEOPressure::calc_pressure(double rho, int type)
{ {
double p, dr, rr3, rho_ratio; double p, dr, rr3, rho_ratio;
if (pressure_style == LINEAR) { if (pressure_style[type] == LINEAR) {
p = csq * (rho - rho0); p = csq[type] * (rho - rho0[type]);
} else if (pressure_style == CUBIC) { } else if (pressure_style[type] == CUBIC) {
dr = rho - rho0; dr = rho - rho0[type];
p = csq * (dr + c_cubic * dr * dr * dr); p = csq[type] * (dr + c_cubic[type] * dr * dr * dr);
} else if (pressure_style == TAITWATER) { } else if (pressure_style[type] == TAITWATER) {
rho_ratio = rho / rho0inv; rho_ratio = rho * rho0inv[type];
rr3 = rho_ratio * rho_ratio * rho_ratio; rr3 = rho_ratio * rho_ratio * rho_ratio;
p = csq * rho0 * SEVENTH * (rr3 * rr3 * rho_ratio - 1.0); p = csq[type] * rho0[type] * SEVENTH * (rr3 * rr3 * rho_ratio - 1.0);
} }
return p; return p;
} }
/* ---------------------------------------------------------------------- */
double FixRHEOPressure::calc_rho(double p, int type)
{
double rho, dr, rr3, rho_ratio;
if (pressure_style[type] == LINEAR) {
rho = csqinv[type] * p + rho0[type];
} else if (pressure_style[type] == CUBIC) {
error->one(FLERR, "Rho calculation from pressure not yet supported for cubic pressure equation");
} else if (pressure_style[type] == TAITWATER) {
rho = pow(7.0 * p + csq[type] * rho0[type], SEVENTH);
rho *= pow(rho0[type], 6.0 * SEVENTH);
rho *= pow(csq[type], -SEVENTH);
}
return rho;
}

View File

@ -34,11 +34,12 @@ class FixRHEOPressure : public Fix {
void pre_force(int) override; void pre_force(int) override;
int pack_forward_comm(int, int *, double *, int, int *) override; int pack_forward_comm(int, int *, double *, int, int *) override;
void unpack_forward_comm(int, int, double *) override; void unpack_forward_comm(int, int, double *) override;
double calc_pressure(double); double calc_pressure(double, int);
double calc_rho(double, int);
private: private:
double c_cubic, csq, rho0, rho0inv; double *c_cubic, *csq, *csqinv, *rho0, *rho0inv;
int pressure_style; int *pressure_style;
class FixRHEO *fix_rheo; class FixRHEO *fix_rheo;
}; };

View File

@ -41,108 +41,124 @@
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
using namespace RHEO_NS; using namespace RHEO_NS;
using namespace FixConst; using namespace FixConst;
enum {NONE, CONSTANT, TYPE}; enum {NONE, CONSTANT};
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
FixRHEOThermal::FixRHEOThermal(LAMMPS *lmp, int narg, char **arg) : FixRHEOThermal::FixRHEOThermal(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), fix_rheo(nullptr), compute_grad(nullptr), compute_vshift(nullptr), Fix(lmp, narg, arg), fix_rheo(nullptr), compute_grad(nullptr), compute_vshift(nullptr),
Tc_type(nullptr), kappa_type(nullptr), cv_type(nullptr), fix_update_special_bonds(nullptr) Tc(nullptr), kappa(nullptr), cv(nullptr), Tc_style(nullptr), kappa_style(nullptr), cv_style(nullptr),
fix_update_special_bonds(nullptr)
{ {
if (narg < 4) error->all(FLERR,"Illegal fix command"); if (narg < 4) error->all(FLERR,"Illegal fix command");
force_reneighbor = 1; force_reneighbor = 1;
next_reneighbor = -1; next_reneighbor = -1;
Tc_style = NONE;
cv_style = NONE;
conductivity_style = NONE;
cut_bond = 0; cut_bond = 0;
comm_forward = 0; comm_forward = 0;
int ntypes = atom->ntypes; if (igroup != 0)
error->all(FLERR,"fix rheo/thermal command requires group all");
int i, nlo, nhi;
int n = atom->ntypes;
memory->create(Tc_style, n + 1, "rheo:Tc_style");
memory->create(kappa_style, n + 1, "rheo:kappa_style");
memory->create(cv_style, n + 1, "rheo:cv_style");
for (i = 1; i <= n; i++) {
Tc_style[i] = NONE;
kappa_style[i] = NONE;
cv_style[i] = NONE;
}
int iarg = 3; int iarg = 3;
while (iarg < narg) { while (iarg < narg) {
if (strcmp(arg[iarg],"conductivity") == 0) { if (strcmp(arg[iarg],"conductivity") == 0) {
if (iarg + 2 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal conductivity", error);
utils::bounds(FLERR, arg[iarg + 1], 1, n, nlo, nhi, error);
// Conductivity arguments // Conductivity arguments
if (iarg + 1 >= narg) error->all(FLERR, "Insufficient arguments for conductivity option"); if (strcmp(arg[iarg + 2], "constant") == 0) {
if (strcmp(arg[iarg + 1], "constant") == 0) { if (iarg + 3 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal conductivity constant", error);
if (iarg + 2 >= narg) error->all(FLERR, "Insufficient arguments for conductivity option");
conductivity_style = CONSTANT; double kappa_one = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
kappa = utils::numeric(FLERR, arg[iarg + 2], false, lmp); if (kappa_one < 0.0) error->all(FLERR, "The conductivity must be positive");
if (kappa < 0.0) error->all(FLERR, "The conductivity must be positive"); iarg += 1;
iarg += 2;
} else if (strcmp(arg[iarg + 1], "type") == 0) { for (i = nlo; i <= nhi; i++) {
if (iarg + 1 + ntypes >= narg) error->all(FLERR, "Insufficient arguments for conductivity option"); kappa_style[i] = CONSTANT;
conductivity_style = TYPE; kappa[i] = kappa_one;
memory->create(kappa_type, ntypes+1, "rheo_thermal:kappa_type");
for (int i = 1; i <= ntypes; i++) {
kappa_type[i] = utils::numeric(FLERR, arg[iarg + i], false, lmp);
if (kappa_type[i] < 0.0) error->all(FLERR, "The conductivity must be positive");
} }
iarg += 1 + ntypes;
} else { } else {
error->all(FLERR,"Illegal fix command, {}", arg[iarg + 1]); error->all(FLERR,"Illegal fix command, {}", arg[iarg + 2]);
} }
iarg += 2;
} else if (strcmp(arg[iarg], "specific/heat") == 0) { } else if (strcmp(arg[iarg], "specific/heat") == 0) {
if (iarg + 2 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal specific/heat", error);
utils::bounds(FLERR, arg[iarg + 1], 1, n, nlo, nhi, error);
// Cv arguments // Cv arguments
if (iarg + 1 >= narg) error->all(FLERR, "Insufficient arguments for cv option"); if (strcmp(arg[iarg + 2], "constant") == 0) {
if (strcmp(arg[iarg + 1], "constant") == 0) { if (iarg + 3 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal specific/heat constant", error);
if (iarg + 2 >= narg) error->all(FLERR, "Insufficient arguments for cv option");
cv_style = CONSTANT; double cv_one = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
cv = utils::numeric(FLERR, arg[iarg + 2], false, lmp); if (cv_one < 0.0) error->all(FLERR, "The specific heat must be positive");
if (cv < 0.0) error->all(FLERR, "The specific heat must be positive"); iarg += 1;
iarg += 2;
} else if (strcmp(arg[iarg + 1], "type") == 0) { for (i = nlo; i <= nhi; i++) {
if (iarg + 1 + ntypes >= narg) error->all(FLERR, "Insufficient arguments for cv option"); cv_style[i] = CONSTANT;
cv_style = TYPE; cv[i] = cv_one;
memory->create(cv_type,ntypes + 1, "rheo_thermal:cv_type");
for (int i = 1; i <= ntypes; i++) {
cv_type[i] = utils::numeric(FLERR, arg[iarg + 1 + i], false, lmp);
if (cv_type[i] < 0.0) error->all(FLERR, "The specific heat must be positive");
} }
iarg += 1 + ntypes;
} else { } else {
error->all(FLERR,"Illegal fix command, {}", arg[iarg + 1]); error->all(FLERR,"Illegal fix command, {}", arg[iarg + 2]);
} }
iarg += 2;
} else if (strcmp(arg[iarg], "Tfreeze") == 0) { } else if (strcmp(arg[iarg], "Tfreeze") == 0) {
if (iarg + 2 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal Tfreeze", error);
utils::bounds(FLERR, arg[iarg + 1], 1, n, nlo, nhi, error);
// T freeze arguments // T freeze arguments
if (iarg + 1 >= narg) error->all(FLERR, "Insufficient arguments for Tfreeze option"); if (strcmp(arg[iarg + 2], "constant") == 0) {
if (strcmp(arg[iarg + 1], "constant") == 0) { if (iarg + 3 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal Tfreeze constant", error);
if (iarg + 2 >= narg) error->all(FLERR, "Insufficient arguments for Tfreeze option");
Tc_style = CONSTANT; double Tc_one = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
Tc = utils::numeric(FLERR, arg[iarg + 2], false, lmp); iarg += 1;
iarg += 2;
} else if (strcmp(arg[iarg + 1], "type") == 0) { for (i = nlo; i <= nhi; i++) {
if (iarg + 1 + ntypes >= narg) error->all(FLERR, "Insufficient arguments for Tfreeze option"); Tc_style[i] = CONSTANT;
Tc_style = TYPE; Tc[i] = Tc_one;
memory->create(Tc_type, ntypes + 1, "rheo_thermal:Tc_type");
for (int i = 1; i <= ntypes; i++) {
Tc_type[i] = utils::numeric(FLERR, arg[iarg + i], false, lmp);
if (Tc_type[i] < 0.0) error->all(FLERR, "The melting temperature must be positive");
} }
iarg += 1 + ntypes;
} else { } else {
error->all(FLERR, "Illegal fix command, {}", arg[iarg + 1]); error->all(FLERR, "Illegal fix command, {}", arg[iarg + 2]);
} }
iarg += 2;
} else if (strcmp(arg[iarg], "react") == 0) { } else if (strcmp(arg[iarg], "react") == 0) {
if (iarg + 2 >= narg) error->all(FLERR, "Insufficient arguments for react option"); if (iarg + 2 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal react", error);
cut_bond = utils::numeric(FLERR, arg[iarg + 1], false, lmp); cut_bond = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
btype = utils::numeric(FLERR, arg[iarg + 2], false, lmp); btype = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
comm_forward = 1; comm_forward = 1;
if (cut_bond <= 0.0) error->all(FLERR, "Illegal value for bond lengths");\ if (cut_bond <= 0.0) error->all(FLERR, "Illegal max bond length must be greater than zero");\
if (btype < 1 || btype > atom->nbondtypes) error->all(FLERR, "Illegal value for bond type"); if (btype < 1 || btype > atom->nbondtypes) error->all(FLERR, "Illegal value for bond type");
cutsq_bond = cut_bond * cut_bond; cutsq_bond = cut_bond * cut_bond;
iarg += 2; iarg += 3;
} else { } else {
error->all(FLERR,"Illegal fix command, {}", arg[iarg]); error->all(FLERR,"Illegal fix command, {}", arg[iarg]);
} }
iarg += 1;
} }
if (cv_style == NONE || conductivity_style == NONE)
error->all(FLERR, "Must specify specific heat and conductivity styles\n"); for (i = 1; i <= n; i++) {
if (cv_style[i] == NONE)
error->all(FLERR,"Must specify specific/heat for atom type {} in fix/rheo/thermal", i);
if (kappa_style[i] == NONE)
error->all(FLERR,"Must specify conductivity for atom type {} in fix/rheo/thermal", i);
}
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -154,9 +170,12 @@ FixRHEOThermal::~FixRHEOThermal()
index = atom->find_custom("rheo_conductivity", tmp1, tmp2); index = atom->find_custom("rheo_conductivity", tmp1, tmp2);
if (index != -1) atom->remove_custom(index, 1, 0); if (index != -1) atom->remove_custom(index, 1, 0);
memory->destroy(cv_type); memory->destroy(cv_style);
memory->destroy(Tc_type); memory->destroy(Tc_style);
memory->destroy(kappa_type); memory->destroy(kappa_style);
memory->destroy(cv);
memory->destroy(Tc);
memory->destroy(kappa);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -198,7 +217,6 @@ void FixRHEOThermal::init()
if (atom->conductivity_flag != 1) if (atom->conductivity_flag != 1)
error->all(FLERR,"fix rheo/thermal command requires atom property conductivity"); error->all(FLERR,"fix rheo/thermal command requires atom property conductivity");
if (cut_bond > 0.0) { if (cut_bond > 0.0) {
if (!force->bond) error->all(FLERR,"Must define a bond style to use reactive bond generation with fix rheo/thermal"); if (!force->bond) error->all(FLERR,"Must define a bond style to use reactive bond generation with fix rheo/thermal");
if (!atom->avec->bonds_allow) error->all(FLERR, "Reactive bond generation in fix rheo/thermal requires atom bonds"); if (!atom->avec->bonds_allow) error->all(FLERR, "Reactive bond generation in fix rheo/thermal requires atom bonds");
@ -249,7 +267,6 @@ void FixRHEOThermal::initial_integrate(int /*vflag*/)
int i, a; int i, a;
int *status = atom->status; int *status = atom->status;
int *mask = atom->mask;
double *temperature = atom->temperature; double *temperature = atom->temperature;
double **gradt = compute_grad->gradt; double **gradt = compute_grad->gradt;
double **vshift = compute_vshift->array_atom; double **vshift = compute_vshift->array_atom;
@ -263,11 +280,8 @@ void FixRHEOThermal::initial_integrate(int /*vflag*/)
for (i = 0; i < nlocal; i++) { for (i = 0; i < nlocal; i++) {
if (status[i] & STATUS_NO_SHIFT) continue; if (status[i] & STATUS_NO_SHIFT) continue;
if (mask[i] & groupbit) { for (a = 0; a < dim; a++)
for (a = 0; a < dim; a++) { temperature[i] += dtv * vshift[i][a] * gradt[i][a];
temperature[i] += dtv * vshift[i][a] * gradt[i][a];
}
}
} }
} }
@ -275,52 +289,50 @@ void FixRHEOThermal::initial_integrate(int /*vflag*/)
void FixRHEOThermal::post_integrate() void FixRHEOThermal::post_integrate()
{ {
int i, itype;
double cvi, Tci, Ti;
int *status = atom->status; int *status = atom->status;
double *temperature = atom->temperature; double *temperature = atom->temperature;
double *heatflow = atom->heatflow; double *heatflow = atom->heatflow;
double *rho = atom->rho; double *rho = atom->rho;
int *mask = atom->mask;
int *type = atom->type; int *type = atom->type;
double cvi, Tci, Ti;
int n_melt = 0; int n_melt = 0;
int n_freeze = 0; int n_freeze = 0;
//Integrate temperature and check status //Integrate temperature and check status
for (int i = 0; i < atom->nlocal; i++) { for (i = 0; i < atom->nlocal; i++) {
if (mask[i] & groupbit) { if (status[i] & STATUS_NO_INTEGRATION) continue;
if (status[i] & STATUS_NO_INTEGRATION) continue;
cvi = calc_cv(i); itype = type[i];
temperature[i] += dtf * heatflow[i] / cvi; cvi = calc_cv(i, type[i]);
temperature[i] += dtf * heatflow[i] / cvi;
if (Tc_style != NONE) { if (Tc_style[itype] != NONE) {
Ti = temperature[i]; Ti = temperature[i];
if (Tc_style == CONSTANT) { if (Tc_style[itype] == CONSTANT) {
Tci = Tc; Tci = Tc[itype];
} else if (Tc_style == TYPE) { }
Tci = Tc_type[type[i]];
if (Ti > Tci) {
// If solid, melt
if (status[i] & STATUS_SOLID) {
status[i] &= PHASEMASK;
status[i] |= STATUS_MELTING;
n_melt += 1;
} }
} else {
if (Ti > Tci) { // If fluid, freeze
// If solid, melt if (!(status[i] & STATUS_SOLID)) {
if (status[i] & STATUS_SOLID) { status[i] &= PHASEMASK;
status[i] &= PHASEMASK; status[i] |= STATUS_SOLID;
status[i] |= STATUS_MELTING; status[i] |= STATUS_FREEZING;
n_melt += 1; n_freeze += 1;
}
} else {
// If fluid, freeze
if (!(status[i] & STATUS_SOLID)) {
status[i] &= PHASEMASK;
status[i] |= STATUS_SOLID;
status[i] |= STATUS_FREEZING;
n_freeze += 1;
}
} }
} }
} }
} }
int n_melt_all, n_freeze_all; int n_melt_all, n_freeze_all;
@ -344,19 +356,16 @@ void FixRHEOThermal::post_integrate()
void FixRHEOThermal::post_neighbor() void FixRHEOThermal::post_neighbor()
{ {
int i; int i, itype;
int *type = atom->type; int *type = atom->type;
int *mask = atom->mask;
double *conductivity = atom->conductivity; double *conductivity = atom->conductivity;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = nlocal + atom->nghost; int nall = nlocal + atom->nghost;
if (conductivity_style == CONSTANT) { for (i = 0; i < nall; i++) {
for (i = 0; i < nall; i++) itype = type[i];
if (mask[i] & groupbit) conductivity[i] = kappa; if (kappa_style[itype] == CONSTANT)
} else if (conductivity_style == TYPE) { conductivity[i] = kappa[itype];
for (i = 0; i < nall; i++)
if (mask[i] & groupbit) conductivity[i] = kappa_type[type[i]];
} }
} }
@ -372,21 +381,18 @@ void FixRHEOThermal::pre_force(int /*vflag*/)
void FixRHEOThermal::final_integrate() void FixRHEOThermal::final_integrate()
{ {
int *status = atom->status;
int *type = atom->type;
double *temperature = atom->temperature; double *temperature = atom->temperature;
double *heatflow = atom->heatflow; double *heatflow = atom->heatflow;
int *status = atom->status;
int *mask = atom->mask;
double cvi; double cvi;
//Integrate temperature and check status //Integrate temperature and check status
for (int i = 0; i < atom->nlocal; i++) { for (int i = 0; i < atom->nlocal; i++) {
if (mask[i] & groupbit) { if (status[i] & STATUS_NO_INTEGRATION) continue;
if (status[i] & STATUS_NO_INTEGRATION) continue;
cvi = calc_cv(i); cvi = calc_cv(i, type[i]);
temperature[i] += dtf * heatflow[i] / cvi; temperature[i] += dtf * heatflow[i] / cvi;
}
} }
} }
@ -522,12 +528,10 @@ void FixRHEOThermal::create_bonds()
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
double FixRHEOThermal::calc_cv(int i) double FixRHEOThermal::calc_cv(int i, int itype)
{ {
if (cv_style == CONSTANT) { if (cv_style[itype] == CONSTANT) {
return cv; return cv[itype];
} else if (cv_style == TYPE) {
return(cv_type[atom->type[i]]);
} }
} }

View File

@ -42,17 +42,14 @@ class FixRHEOThermal : public Fix {
int pack_forward_comm(int, int *, double *, int, int *) override; int pack_forward_comm(int, int *, double *, int, int *) override;
void unpack_forward_comm(int, int, double *) override; void unpack_forward_comm(int, int, double *) override;
void reset_dt() override; void reset_dt() override;
double calc_cv(int); double calc_cv(int, int);
private: private:
double *cv_type, cv; double *cv, *Tc, *kappa;
double *Tc_type, Tc;
double *kappa_type, kappa;
double dtf, dtv; double dtf, dtv;
double cut_kernel, cut_bond, cutsq_bond; double cut_kernel, cut_bond, cutsq_bond;
int Tc_style, cv_style; int *cv_style, *Tc_style, *kappa_style;
int btype; int btype;
int conductivity_style;
class NeighList *list; class NeighList *list;
int n_histories; int n_histories;

View File

@ -32,60 +32,87 @@
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
using namespace FixConst; using namespace FixConst;
enum {NONE, CONSTANT, TYPE, POWER}; enum {NONE, CONSTANT, POWER};
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
FixRHEOViscosity::FixRHEOViscosity(LAMMPS *lmp, int narg, char **arg) : FixRHEOViscosity::FixRHEOViscosity(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg), fix_rheo(nullptr), compute_grad(nullptr), eta_type(nullptr) Fix(lmp, narg, arg), fix_rheo(nullptr), compute_grad(nullptr), eta(nullptr),
npow(nullptr), K(nullptr), gd0(nullptr), tau0(nullptr), viscosity_style(nullptr)
{ {
if (narg < 4) error->all(FLERR,"Illegal fix command"); if (narg < 4) error->all(FLERR, "Illegal fix command");
viscosity_style = NONE;
comm_forward = 0; comm_forward = 0;
constant_flag = 0;
evolve_flag = 0;
if (igroup != 0)
error->all(FLERR,"fix rheo/viscosity command requires group all");
int i, nlo, nhi;
int n = atom->ntypes;
memory->create(viscosity_style, n + 1, "rheo:viscosity_style");
for (i = 1; i <= n; i++) viscosity_style[i] = NONE;
int ntypes = atom->ntypes;
int iarg = 3; int iarg = 3;
if (strcmp(arg[iarg],"constant") == 0) { while (iarg < narg) {
if (iarg + 1 >= narg) error->all(FLERR,"Insufficient arguments for viscosity option"); utils::bounds(FLERR, arg[iarg], 1, n, nlo, nhi, error);
viscosity_style = CONSTANT;
eta = utils::numeric(FLERR,arg[iarg + 1],false,lmp); if (iarg + 1 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/viscosity", error);
if (eta < 0.0) error->all(FLERR,"The viscosity must be positive");
iarg += 1; if (strcmp(arg[iarg + 1], "constant") == 0) {
} else if (strcmp(arg[iarg],"type") == 0) { if (iarg + 2 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/viscosity constant", error);
if (iarg + ntypes >= narg) error->all(FLERR,"Insufficient arguments for viscosity option");
viscosity_style = TYPE; constant_flag = 1;
memory->create(eta_type, ntypes + 1, "rheo_thermal:eta_type"); double eta_one = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
for (int i = 1; i <= ntypes; i++) { if (eta_one < 0.0) error->all(FLERR, "The viscosity must be positive");
eta_type[i] = utils::numeric(FLERR,arg[iarg + i], false, lmp); iarg += 1;
if (eta_type[i] < 0.0) error->all(FLERR,"The viscosity must be positive");
for (i = nlo; i <= nhi; i++) {
viscosity_style[i] = CONSTANT;
eta[i] = eta_one;
}
} else if (strcmp(arg[iarg], "power") == 0) {
if (iarg + 5 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/viscosity power", error);
comm_forward = 1;
evolve_flag = 1;
double eta_one = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
double gd0_one = utils::numeric(FLERR, arg[iarg + 3], false, lmp);
double K_one = utils::numeric(FLERR, arg[iarg + 4], false, lmp);
double npow_one = utils::numeric(FLERR, arg[iarg + 5], false, lmp);
if (eta_one < 0.0) error->all(FLERR, "The viscosity must be positive");
iarg += 4;
for (i = nlo; i <= nhi; i++) {
viscosity_style[i] = POWER;
eta[i] = eta_one;
gd0[i] = gd0_one;
K[i] = K_one;
npow[i] = npow_one;
tau0[i] = eta[i] * gd0[i] - K[i] * pow(gd0[i], npow[i]);
}
} else {
error->all(FLERR, "Illegal fix command, {}", arg[iarg]);
} }
iarg += ntypes; iarg += 2;
} else if (strcmp(arg[iarg],"power") == 0) {
if (iarg + 4 >= narg) error->all(FLERR,"Insufficient arguments for viscosity option");
viscosity_style = POWER;
comm_forward = 1;
eta = utils::numeric(FLERR,arg[iarg + 1],false,lmp);
gd0 = utils::numeric(FLERR,arg[iarg + 2],false,lmp);
K = utils::numeric(FLERR,arg[iarg + 3],false,lmp);
npow = utils::numeric(FLERR,arg[iarg + 4],false,lmp);
tau0 = eta * gd0 - K * pow(gd0, npow);
if (eta < 0.0) error->all(FLERR,"The viscosity must be positive");
iarg += 5;
} else {
error->all(FLERR,"Illegal fix command, {}", arg[iarg]);
} }
if (viscosity_style == NONE) for (i = 1; i <= n; i++)
error->all(FLERR,"Must specify viscosity style for fix/rheo/viscosity"); if (viscosity_style[i] == NONE)
error->all(FLERR,"Must specify viscosity for atom type {} in fix/rheo/viscosity", i);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
FixRHEOViscosity::~FixRHEOViscosity() FixRHEOViscosity::~FixRHEOViscosity()
{ {
memory->destroy(eta_type); memory->destroy(viscosity_style);
memory->destroy(eta);
memory->destroy(gd0);
memory->destroy(K);
memory->destroy(npow);
memory->destroy(tau0);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -115,17 +142,8 @@ void FixRHEOViscosity::setup_pre_force(int /*vflag*/)
{ {
fix_rheo->viscosity_fix_defined = 1; fix_rheo->viscosity_fix_defined = 1;
// Identify whether this is the last instance of fix viscosity if (modify->get_fix_by_style("rheo/viscosity").size() > 1)
last_flag = 0; error->all(FLERR, "More than one fix rheo/viscosity defined");
int i = 0;
auto fixlist = modify->get_fix_by_style("rheo/viscosity");
for (const auto &fix : fixlist) {
if (strcmp(fix->id, id) == 0) break;
i++;
}
if ((i + 1) == fixlist.size()) last_flag = 1;
post_neighbor(); post_neighbor();
pre_force(0); pre_force(0);
@ -137,20 +155,18 @@ void FixRHEOViscosity::setup_pre_force(int /*vflag*/)
void FixRHEOViscosity::post_neighbor() void FixRHEOViscosity::post_neighbor()
{ {
int i; if (!constant_flag) return;
int i, itype;
int *type = atom->type; int *type = atom->type;
int *mask = atom->mask;
double *viscosity = atom->viscosity; double *viscosity = atom->viscosity;
int nall = atom->nlocal + atom->nghost; int nall = atom->nlocal + atom->nghost;
if (viscosity_style == CONSTANT) { for (i = 0; i < nall; i++) {
for (i = 0; i < nall; i++) itype = type[i];
if (mask[i] & groupbit) viscosity[i] = eta; if (viscosity_style[itype])
} else if (viscosity_style == TYPE) { viscosity[i] = eta[itype];
for (i = 0; i < nall; i++)
if (mask[i] & groupbit) viscosity[i] = eta_type[type[i]];
} }
} }
@ -160,39 +176,41 @@ void FixRHEOViscosity::post_neighbor()
void FixRHEOViscosity::pre_force(int /*vflag*/) void FixRHEOViscosity::pre_force(int /*vflag*/)
{ {
int i, a, b; if (!evolve_flag) return;
int i, itype, a, b;
double tmp, gdot; double tmp, gdot;
int *mask = atom->mask; int *type = atom->type;
double *viscosity = atom->viscosity; double *viscosity = atom->viscosity;
double **gradv = compute_grad->gradv; double **gradv = compute_grad->gradv;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int dim = domain->dimension; int dim = domain->dimension;
if (viscosity_style == POWER) {
for (i = 0; i < nlocal; i++) { for (i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) { itype = type[i];
gdot = 0.0; if (viscosity_style[itype] == POWER) {
for (a = 0; a < dim; a++) { gdot = 0.0;
for (b = a; b < dim; b++) { for (a = 0; a < dim; a++) {
tmp = gradv[i][a * dim + b] + gradv[i][b * dim + a]; for (b = a; b < dim; b++) {
tmp = tmp * tmp; tmp = gradv[i][a * dim + b] + gradv[i][b * dim + a];
if (a == b) tmp *= 0.5; tmp = tmp * tmp;
gdot += tmp; if (a == b) tmp *= 0.5;
} gdot += tmp;
}
gdot = sqrt(gdot);
if (gdot <= gd0) {
viscosity[i] = eta;
} else {
viscosity[i] = K * pow(gdot, npow - 1) + tau0 / gdot;
} }
} }
gdot = sqrt(gdot);
if (gdot <= gd0[itype]) {
viscosity[i] = eta[itype];
} else {
viscosity[i] = K[itype] * pow(gdot, npow[itype] - 1) + tau0[itype] / gdot;
}
} }
} }
if (last_flag && comm_forward) comm->forward_comm(this); if (comm_forward) comm->forward_comm(this);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */

View File

@ -37,9 +37,8 @@ class FixRHEOViscosity : public Fix {
void unpack_forward_comm(int, int, double *) override; void unpack_forward_comm(int, int, double *) override;
private: private:
double *eta_type, eta; double *eta, *npow, *K, *gd0, *tau0;
double npow, K, gd0, tau0; int *viscosity_style, constant_flag, evolve_flag;
int viscosity_style, last_flag;
class FixRHEO *fix_rheo; class FixRHEO *fix_rheo;
class ComputeRHEOGrad *compute_grad; class ComputeRHEOGrad *compute_grad;

View File

@ -47,8 +47,8 @@ static constexpr double EPSILON = 1e-2;
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
PairRHEO::PairRHEO(LAMMPS *lmp) : PairRHEO::PairRHEO(LAMMPS *lmp) :
Pair(lmp), compute_kernel(nullptr), compute_grad(nullptr), Pair(lmp), compute_kernel(nullptr), compute_grad(nullptr), compute_interface(nullptr), fix_rheo(nullptr),
compute_interface(nullptr), fix_rheo(nullptr), fix_pressure(nullptr) fix_pressure(nullptr), rho0(nullptr), csq(nullptr), cs(nullptr)
{ {
restartinfo = 0; restartinfo = 0;
single_enable = 0; single_enable = 0;
@ -68,6 +68,8 @@ PairRHEO::~PairRHEO()
memory->destroy(setflag); memory->destroy(setflag);
memory->destroy(cutsq); memory->destroy(cutsq);
} }
memory->destroy(cs);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -77,8 +79,8 @@ void PairRHEO::compute(int eflag, int vflag)
int i, j, a, b, ii, jj, inum, jnum, itype, jtype; int i, j, a, b, ii, jj, inum, jnum, itype, jtype;
int pair_force_flag, pair_rho_flag, pair_avisc_flag; int pair_force_flag, pair_rho_flag, pair_avisc_flag;
int fluidi, fluidj; int fluidi, fluidj;
double xtmp, ytmp, ztmp, w, wp, Ti, Tj, dT; double xtmp, ytmp, ztmp, w, wp, Ti, Tj, dT, csq_ave, cs_ave;
double rhoi, rhoj, voli, volj, Pi, Pj, etai, etaj, kappai, kappaj; double rhoi, rhoj, rho0i, rho0j, voli, volj, Pi, Pj, etai, etaj, kappai, kappaj;
double mu, q, fp_prefactor, drho_damp, fmag, psi_ij, Fij; double mu, q, fp_prefactor, drho_damp, fmag, psi_ij, Fij;
double *dWij, *dWji, *dW1ij, *dW1ji; double *dWij, *dWji, *dW1ij, *dW1ji;
double dx[3], du[3], dv[3], fv[3], dfp[3], fsolid[3], ft[3], vi[3], vj[3]; double dx[3], du[3], dv[3], fv[3], dfp[3], fsolid[3], ft[3], vi[3], vj[3];
@ -178,6 +180,9 @@ void PairRHEO::compute(int eflag, int vflag)
kappaj = conductivity[j]; kappaj = conductivity[j];
} }
cs_ave = 0.5 * (cs[itype] + cs[jtype]);
csq_ave = cs_ave * cs_ave;
pair_rho_flag = 0; pair_rho_flag = 0;
pair_force_flag = 0; pair_force_flag = 0;
pair_avisc_flag = 0; pair_avisc_flag = 0;
@ -201,31 +206,31 @@ void PairRHEO::compute(int eflag, int vflag)
// Add corrections for walls // Add corrections for walls
rhoi = rho[i]; rhoi = rho[i];
rhoj = rho[j]; rhoj = rho[j];
rho0i = rho[itype];
rho0j = rho[jtype];
Pi = pressure[i]; Pi = pressure[i];
Pj = pressure[j]; Pj = pressure[j];
fmag = 0; fmag = 0;
if (interface_flag) { if (interface_flag) {
if (fluidi && (!fluidj)) { if (fluidi && (!fluidj)) {
compute_interface->correct_v(vi, vj, i, j); compute_interface->correct_v(vi, vj, i, j);
//compute_interface->correct_v(vj, vi, j, i);
rhoj = compute_interface->correct_rho(j, i); rhoj = compute_interface->correct_rho(j, i);
Pj = fix_pressure->calc_pressure(rhoj); Pj = fix_pressure->calc_pressure(rhoj, jtype);
if ((chi[j] > 0.9) && (r < (h * 0.5))) if ((chi[j] > 0.9) && (r < (h * 0.5)))
fmag = (chi[j] - 0.9) * (h * 0.5 - r) * rho0 * csq * h * rinv; fmag = (chi[j] - 0.9) * (h * 0.5 - r) * rho0j * csq_ave * h * rinv;
} else if ((!fluidi) && fluidj) { } else if ((!fluidi) && fluidj) {
compute_interface->correct_v(vj, vi, j, i); compute_interface->correct_v(vj, vi, j, i);
//compute_interface->correct_v(vi, vj, i, j);
rhoi = compute_interface->correct_rho(i, j); rhoi = compute_interface->correct_rho(i, j);
Pi = fix_pressure->calc_pressure(rhoi); Pi = fix_pressure->calc_pressure(rhoi, itype);
if (chi[i] > 0.9 && r < (h * 0.5)) if (chi[i] > 0.9 && r < (h * 0.5))
fmag = (chi[i] - 0.9) * (h * 0.5 - r) * rho0 * csq * h * rinv; fmag = (chi[i] - 0.9) * (h * 0.5 - r) * rho0i * csq_ave * h * rinv;
} else if ((!fluidi) && (!fluidj)) { } else if ((!fluidi) && (!fluidj)) {
rhoi = rho0; rhoi = rho0i;
rhoj = rho0; rhoj = rho0j;
} }
} }
@ -239,12 +244,12 @@ void PairRHEO::compute(int eflag, int vflag)
// Thermal Evolution // Thermal Evolution
if (thermal_flag) { if (thermal_flag) {
dT = dot3(dx, dWij); dT = dot3(dx, dWij);
dT *= (kappai + kappaj) * (Ti - Tj) * rinv * rinv * voli * volj / rho0; dT *= (kappai + kappaj) * (Ti - Tj) * rinv * rinv * voli * volj * 2.0 / (rhoi + rhoj);
heatflow[i] += dT; heatflow[i] += dT;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
dT = dot3(dx, dWji); dT = dot3(dx, dWji);
dT *= (kappai + kappaj) * (Tj - Ti) * rinv * rinv * voli * volj / rho0; dT *= (kappai + kappaj) * (Tj - Ti) * rinv * rinv * voli * volj * 2.0 / (rhoi + rhoj);
heatflow[j] -= dT; heatflow[j] -= dT;
} }
} }
@ -266,7 +271,7 @@ void PairRHEO::compute(int eflag, int vflag)
mu = dot3(du, dx) * hinv3; mu = dot3(du, dx) * hinv3;
mu /= (rsq * hinv3 * hinv3 + EPSILON); mu /= (rsq * hinv3 * hinv3 + EPSILON);
mu = MIN(0.0, mu); mu = MIN(0.0, mu);
q = av * (-2.0 * cs * mu + mu * mu); q = av * (-2.0 * cs_ave * mu + mu * mu);
fp_prefactor += voli * volj * q * (rhoj + rhoi); fp_prefactor += voli * volj * q * (rhoj + rhoi);
} }
@ -334,7 +339,7 @@ void PairRHEO::compute(int eflag, int vflag)
psi_ij += 0.5 * (gradr[i][a] + gradr[j][a]) * dx[a]; psi_ij += 0.5 * (gradr[i][a] + gradr[j][a]) * dx[a];
drho[i] += 2 * rho_damp * psi_ij * Fij * volj; drho[i] += 2 * rho_damp * psi_ij * Fij * volj;
} else { } else {
drho_damp = 2 * rho_damp * (rhoj - rhoi) * rinv * wp; drho_damp = 2 * rho_damp * ((rhoj - rho0[jtype]) - (rhoi - rho0[itype])) * rinv * wp;
drho[i] -= drho_damp * volj; drho[i] -= drho_damp * volj;
} }
@ -383,23 +388,23 @@ void PairRHEO::allocate()
void PairRHEO::settings(int narg, char **arg) void PairRHEO::settings(int narg, char **arg)
{ {
if (narg < 1) error->all(FLERR,"Illegal pair_style command"); if (narg < 1) error->all(FLERR, "Illegal pair_style command");
h = utils::numeric(FLERR,arg[0],false,lmp); h = utils::numeric(FLERR, arg[0], false, lmp);
int iarg = 1; int iarg = 1;
while (iarg < narg) { while (iarg < narg) {
if (strcmp(arg[iarg], "rho/damp") == 0) { if (strcmp(arg[iarg], "rho/damp") == 0) {
if (iarg + 1 >= narg) error->all(FLERR,"Illegal pair_style command"); if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_style command");
rho_damp_flag = 1; rho_damp_flag = 1;
rho_damp = utils::numeric(FLERR,arg[iarg + 1],false,lmp); rho_damp = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
iarg++; iarg++;
} else if (strcmp(arg[iarg], "artificial/visc") == 0) { } else if (strcmp(arg[iarg], "artificial/visc") == 0) {
if (iarg + 1 >= narg) error->all(FLERR,"Illegal pair_style command"); if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_style command");
artificial_visc_flag = 1; artificial_visc_flag = 1;
av = utils::numeric(FLERR,arg[iarg + 1],false,lmp); av = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
iarg++; iarg++;
} else error->all(FLERR,"Illegal pair_style command, {}", arg[iarg]); } else error->all(FLERR, "Illegal pair_style command, {}", arg[iarg]);
iarg++; iarg++;
} }
} }
@ -411,13 +416,13 @@ void PairRHEO::settings(int narg, char **arg)
void PairRHEO::coeff(int narg, char **arg) void PairRHEO::coeff(int narg, char **arg)
{ {
if (narg != 2) if (narg != 2)
error->all(FLERR,"Incorrect number of args for pair_style rheo coefficients"); error->all(FLERR, "Incorrect number of args for pair_style rheo coefficients");
if (!allocated) if (!allocated)
allocate(); allocate();
int ilo, ihi, jlo, jhi; int ilo, ihi, jlo, jhi;
utils::bounds(FLERR, arg[0], 1, atom->ntypes, ilo, ihi,error); utils::bounds(FLERR, arg[0], 1, atom->ntypes, ilo, ihi, error);
utils::bounds(FLERR, arg[1], 1, atom->ntypes, jlo, jhi,error); utils::bounds(FLERR, arg[1], 1, atom->ntypes, jlo, jhi, error);
int count = 0; int count = 0;
for (int i = ilo; i <= ihi; i++) { for (int i = ilo; i <= ihi; i++) {
@ -428,7 +433,7 @@ void PairRHEO::coeff(int narg, char **arg)
} }
if (count == 0) if (count == 0)
error->all(FLERR,"Incorrect args for pair rheo coefficients"); error->all(FLERR, "Incorrect args for pair rheo coefficients");
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -460,11 +465,14 @@ void PairRHEO::setup()
hsq = h * h; hsq = h * h;
hinv = 1.0 / h; hinv = 1.0 / h;
hinv3 = hinv * 3.0; hinv3 = hinv * 3.0;
cs = sqrt(csq);
laplacian_order = -1; laplacian_order = -1;
int n = atom->ntypes;
memory->create(cs, n + 1, "rheo:cs");
for (int i = 0; i <= n; i++) cs[i] = sqrt(csq[i]);
if (comm->ghost_velocity == 0) if (comm->ghost_velocity == 0)
error->all(FLERR,"Pair RHEO requires ghost atoms store velocity"); error->all(FLERR, "Pair RHEO requires ghost atoms store velocity");
if (laplacian_order == -1) { if (laplacian_order == -1) {
if (fix_rheo->kernel_style == RK2) if (fix_rheo->kernel_style == RK2)
@ -482,9 +490,8 @@ void PairRHEO::setup()
double PairRHEO::init_one(int i, int j) double PairRHEO::init_one(int i, int j)
{ {
if (setflag[i][j] == 0) { if (setflag[i][j] == 0)
error->all(FLERR,"All pair rheo coeffs are not set"); error->all(FLERR, "All pair rheo coeffs are not set");
}
return h; return h;
} }

View File

@ -37,8 +37,8 @@ class PairRHEO : public Pair {
void unpack_reverse_comm(int, int *, double *) override; void unpack_reverse_comm(int, int *, double *) override;
protected: protected:
double h, csq, rho0; // From fix RHEO double h, *csq, *rho0; // From fix RHEO
double cs, hsq, hinv, hinv3, av, rho_damp; double *cs, hsq, hinv, hinv3, av, rho_damp;
int laplacian_order; int laplacian_order;
int artificial_visc_flag; int artificial_visc_flag;

View File

@ -296,20 +296,20 @@ void PairRHEOReact::allocate()
allocated = 1; allocated = 1;
int n = atom->ntypes; int n = atom->ntypes;
memory->create(setflag, n+1, n+1,"pair:setflag"); memory->create(setflag, n + 1, n + 1, "pair:setflag");
for (int i = 1; i <= n; i++) for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++) for (int j = i; j <= n; j++)
setflag[i][j] = 0; setflag[i][j] = 0;
memory->create(cut, n+1, n+1,"pair:cut"); memory->create(cut, n + 1, n + 1, "pair:cut");
memory->create(cutbond, n+1, n+1,"pair:cutbond"); memory->create(cutbond, n + 1, n + 1, "pair:cutbond");
memory->create(cutsq, n+1, n+1,"pair:cutsq"); memory->create(cutsq, n + 1, n + 1, "pair:cutsq");
memory->create(cutbsq, n+1, n+1,"pair:cutbsq"); memory->create(cutbsq, n + 1, n + 1, "pair:cutbsq");
memory->create(k, n+1, n+1,"pair:k"); memory->create(k, n + 1, n + 1, "pair:k");
memory->create(eps, n+1, n+1,"pair:eps"); memory->create(eps, n + 1, n + 1, "pair:eps");
memory->create(gamma, n+1, n+1,"pair:gamma"); memory->create(gamma, n + 1, n + 1, "pair:gamma");
memory->create(t_form, n+1, n+1,"pair:t_form"); memory->create(t_form, n + 1, n + 1, "pair:t_form");
memory->create(rlimit, n+1, n+1,"pair:rlimit"); memory->create(rlimit, n + 1, n + 1, "pair:rlimit");
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -326,7 +326,7 @@ void PairRHEOReact::settings(int narg, char **arg)
void PairRHEOReact::coeff(int narg, char **arg) void PairRHEOReact::coeff(int narg, char **arg)
{ {
if (narg != 9) error->all(FLERR,"Incorrect args for pair coefficients"); if (narg != 9) error->all(FLERR, "Incorrect args for pair coefficients");
if (!allocated) allocate(); if (!allocated) allocate();
int ilo, ihi, jlo, jhi; int ilo, ihi, jlo, jhi;
@ -343,7 +343,7 @@ void PairRHEOReact::coeff(int narg, char **arg)
if (k_one < 0.0 || eps_one < 0.0 || if (k_one < 0.0 || eps_one < 0.0 ||
t_form_one < 0.0 || (1.0 + eps_one) * cutb_one > cut_one) t_form_one < 0.0 || (1.0 + eps_one) * cutb_one > cut_one)
error->all(FLERR,"Illegal pair_style command"); error->all(FLERR, "Illegal pair_style command");
int count = 0; int count = 0;
for (int i = ilo; i <= ihi; i++) { for (int i = ilo; i <= ihi; i++) {
@ -360,7 +360,7 @@ void PairRHEOReact::coeff(int narg, char **arg)
} }
} }
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); if (count == 0) error->all(FLERR, "Incorrect args for pair coefficients");
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -406,7 +406,7 @@ void PairRHEOReact::setup()
double PairRHEOReact::init_one(int i, int j) double PairRHEOReact::init_one(int i, int j)
{ {
if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); if (setflag[i][j] == 0) error->all(FLERR, "All pair coeffs are not set");
cutbsq[i][j] = cutbond[i][j] * cutbond[i][j]; cutbsq[i][j] = cutbond[i][j] * cutbond[i][j];