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) :
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)
{
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);
rhoi = compute_interface->correct_rho(i, j);
} else if ((!fluidi) && (!fluidj)) {
rhoi = rho0;
rhoj = rho0;
rhoi = rho0[itype];
rhoj = rho0[jtype];
}
}

View File

@ -46,7 +46,7 @@ class ComputeRHEOGrad : public Compute {
private:
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 interface_flag, remap_v_flag;

View File

@ -25,6 +25,7 @@
#include "error.h"
#include "force.h"
#include "fix_rheo.h"
#include "fix_rheo_pressure.h"
#include "memory.h"
#include "modify.h"
#include "neighbor.h"
@ -42,7 +43,7 @@ static constexpr double EPSILON = 1e-1;
ComputeRHEOInterface::ComputeRHEOInterface(LAMMPS *lmp, int narg, char **arg) :
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");
@ -86,11 +87,12 @@ void ComputeRHEOInterface::init()
compute_kernel = fix_rheo->compute_kernel;
rho0 = fix_rheo->rho0;
cut = fix_rheo->cut;
csq = fix_rheo->csq;
csq_inv = 1.0 / csq;
cutsq = cut * 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);
}
@ -174,7 +176,7 @@ void ComputeRHEOInterface::compute_peratom()
dot += (-fp_store[j][1] + fp_store[i][1]) * dely;
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;
}
}
@ -189,7 +191,7 @@ void ComputeRHEOInterface::compute_peratom()
dot += (-fp_store[i][1] + fp_store[j][1]) * dely;
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;
}
}
@ -207,9 +209,9 @@ void ComputeRHEOInterface::compute_peratom()
if (status[i] & PHASECHECK) {
if (normwf[i] != 0.0) {
// 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 {
rho[i] = rho0;
rho[i] = rho0[itype];
}
}
}

View File

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

View File

@ -330,11 +330,12 @@ void ComputeRHEOPropertyAtom::pack_coordination(int n)
void ComputeRHEOPropertyAtom::pack_cv(int n)
{
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
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;
n += nvalues;
}

View File

@ -42,7 +42,7 @@ static constexpr double EPSILON = 1e-10;
/* ---------------------------------------------------------------------- */
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)
{
if (narg != 3) error->all(FLERR,"Illegal compute RHEO/SURFACE command");
@ -194,8 +194,8 @@ void ComputeRHEOSurface::compute_peratom()
} else if ((!fluidi) && fluidj) {
rhoi = compute_interface->correct_rho(i, j);
} else if ((!fluidi) && (!fluidj)) {
rhoi = rho0;
rhoj = rho0;
rhoi = rho0[itype];
rhoj = rho0[jtype];
}
}

View File

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

View File

@ -28,6 +28,7 @@
#include "domain.h"
#include "error.h"
#include "force.h"
#include "memory.h"
#include "modify.h"
#include "update.h"
#include "utils.h"
@ -40,7 +41,7 @@ using namespace FixConst;
FixRHEO::FixRHEO(LAMMPS *lmp, int narg, char **arg) :
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;
@ -54,8 +55,14 @@ FixRHEO::FixRHEO(LAMMPS *lmp, int narg, char **arg) :
interface_flag = 0;
surface_flag = 0;
rho0 = 1.0;
csq = 1.0;
int i;
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)
error->all(FLERR, "fix rheo command requires group all");
@ -112,13 +119,17 @@ FixRHEO::FixRHEO(LAMMPS *lmp, int narg, char **arg) :
} else if (strcmp(arg[iarg], "rho/sum") == 0) {
rhosum_flag = 1;
} else if (strcmp(arg[iarg], "density") == 0) {
if(iarg + 1 >= narg) error->all(FLERR,"Illegal rho0 option in fix rheo");
rho0 = utils::numeric(FLERR,arg[iarg + 1],false,lmp);
iarg += 1;
} else if (strcmp(arg[iarg],"sound/squared") == 0) {
if(iarg+1 >= narg) error->all(FLERR,"Illegal csq option in fix rheo");
csq = utils::numeric(FLERR,arg[iarg + 1],false,lmp);
iarg += 1;
if (iarg + n >= narg) error->all(FLERR, "Illegal rho0 option in fix rheo");
for (i = 1; i <= n; i++)
rho0[i] = utils::numeric(FLERR, arg[iarg + i], false, lmp);
iarg += n;
} else if (strcmp(arg[iarg], "speed/sound") == 0) {
if (iarg + n >= narg) error->all(FLERR, "Illegal csq option in fix rheo");
for (i = 1; i <= n; i++) {
csq[i] = utils::numeric(FLERR, arg[iarg + i], false, lmp);
csq[i] *= csq[i];
}
iarg += n;
} else {
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_rhosum) modify->delete_compute("rheo_rhosum");
if (compute_vshift) modify->delete_compute("rheo_vshift");
memory->destroy(csq);
memory->destroy(rho0);
}

View File

@ -39,7 +39,8 @@ class FixRHEO : public Fix {
void reset_dt() override;
// Model parameters
double h, cut, rho0, csq;
double h, cut;
double *rho0, *csq;
int zmin_kernel, zmin_surface, zmin_splash;
int kernel_style, surface_style;
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) :
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");
pressure_style = NONE;
comm_forward = 1;
// Currently can only have one instance of fix rheo/pressure
if (igroup != 0)
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;
if (strcmp(arg[iarg], "linear") == 0) {
pressure_style = LINEAR;
} else if (strcmp(arg[iarg], "taitwater") == 0) {
pressure_style = TAITWATER;
} else if (strcmp(arg[iarg], "cubic") == 0) {
pressure_style = CUBIC;
if (iarg + 1 >= narg) error->all(FLERR, "Insufficient arguments for pressure option");
c_cubic = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
while (iarg < narg) {
utils::bounds(FLERR, arg[iarg], 1, n, nlo, nhi, error);
if (iarg + 1 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/pressure", error);
if (strcmp(arg[iarg + 1], "linear") == 0) {
for (i = nlo; i <= nhi; i++)
pressure_style[i] = LINEAR;
} else if (strcmp(arg[iarg + 1], "taitwater") == 0) {
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)
error->all(FLERR,"Must specify pressure style for fix/rheo/pressure");
for (i = 1; i <= n; i++)
if (pressure_style[i] == NONE)
error->all(FLERR,"Must specify pressure for atom type {} in fix/rheo/pressure", i);
}
/* ---------------------------------------------------------------------- */
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;
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)
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;
int *mask = atom->mask;
int *type = atom->type;
double *rho = atom->rho;
double *pressure = atom->pressure;
@ -124,7 +154,7 @@ void FixRHEOPressure::pre_force(int /*vflag*/)
for (i = 0; i < nlocal; i++)
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);
}
@ -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;
if (pressure_style == LINEAR) {
p = csq * (rho - rho0);
} else if (pressure_style == CUBIC) {
dr = rho - rho0;
p = csq * (dr + c_cubic * dr * dr * dr);
} else if (pressure_style == TAITWATER) {
rho_ratio = rho / rho0inv;
if (pressure_style[type] == LINEAR) {
p = csq[type] * (rho - rho0[type]);
} else if (pressure_style[type] == CUBIC) {
dr = rho - rho0[type];
p = csq[type] * (dr + c_cubic[type] * dr * dr * dr);
} else if (pressure_style[type] == TAITWATER) {
rho_ratio = rho * rho0inv[type];
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;
}
/* ---------------------------------------------------------------------- */
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;
int pack_forward_comm(int, int *, double *, int, int *) override;
void unpack_forward_comm(int, int, double *) override;
double calc_pressure(double);
double calc_pressure(double, int);
double calc_rho(double, int);
private:
double c_cubic, csq, rho0, rho0inv;
int pressure_style;
double *c_cubic, *csq, *csqinv, *rho0, *rho0inv;
int *pressure_style;
class FixRHEO *fix_rheo;
};

View File

@ -41,108 +41,124 @@
using namespace LAMMPS_NS;
using namespace RHEO_NS;
using namespace FixConst;
enum {NONE, CONSTANT, TYPE};
enum {NONE, CONSTANT};
/* ---------------------------------------------------------------------- */
FixRHEOThermal::FixRHEOThermal(LAMMPS *lmp, int narg, char **arg) :
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");
force_reneighbor = 1;
next_reneighbor = -1;
Tc_style = NONE;
cv_style = NONE;
conductivity_style = NONE;
cut_bond = 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;
while (iarg < narg) {
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
if (iarg + 1 >= narg) error->all(FLERR, "Insufficient arguments for conductivity option");
if (strcmp(arg[iarg + 1], "constant") == 0) {
if (iarg + 2 >= narg) error->all(FLERR, "Insufficient arguments for conductivity option");
conductivity_style = CONSTANT;
kappa = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
if (kappa < 0.0) error->all(FLERR, "The conductivity must be positive");
iarg += 2;
} else if (strcmp(arg[iarg + 1], "type") == 0) {
if (iarg + 1 + ntypes >= narg) error->all(FLERR, "Insufficient arguments for conductivity option");
conductivity_style = TYPE;
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");
if (strcmp(arg[iarg + 2], "constant") == 0) {
if (iarg + 3 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal conductivity constant", error);
double kappa_one = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
if (kappa_one < 0.0) error->all(FLERR, "The conductivity must be positive");
iarg += 1;
for (i = nlo; i <= nhi; i++) {
kappa_style[i] = CONSTANT;
kappa[i] = kappa_one;
}
iarg += 1 + ntypes;
} 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) {
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
if (iarg + 1 >= narg) error->all(FLERR, "Insufficient arguments for cv option");
if (strcmp(arg[iarg + 1], "constant") == 0) {
if (iarg + 2 >= narg) error->all(FLERR, "Insufficient arguments for cv option");
cv_style = CONSTANT;
cv = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
if (cv < 0.0) error->all(FLERR, "The specific heat must be positive");
iarg += 2;
} else if (strcmp(arg[iarg + 1], "type") == 0) {
if (iarg + 1 + ntypes >= narg) error->all(FLERR, "Insufficient arguments for cv option");
cv_style = TYPE;
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");
if (strcmp(arg[iarg + 2], "constant") == 0) {
if (iarg + 3 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal specific/heat constant", error);
double cv_one = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
if (cv_one < 0.0) error->all(FLERR, "The specific heat must be positive");
iarg += 1;
for (i = nlo; i <= nhi; i++) {
cv_style[i] = CONSTANT;
cv[i] = cv_one;
}
iarg += 1 + ntypes;
} 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) {
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
if (iarg + 1 >= narg) error->all(FLERR, "Insufficient arguments for Tfreeze option");
if (strcmp(arg[iarg + 1], "constant") == 0) {
if (iarg + 2 >= narg) error->all(FLERR, "Insufficient arguments for Tfreeze option");
Tc_style = CONSTANT;
Tc = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
iarg += 2;
} else if (strcmp(arg[iarg + 1], "type") == 0) {
if (iarg + 1 + ntypes >= narg) error->all(FLERR, "Insufficient arguments for Tfreeze option");
Tc_style = TYPE;
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");
if (strcmp(arg[iarg + 2], "constant") == 0) {
if (iarg + 3 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/thermal Tfreeze constant", error);
double Tc_one = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
iarg += 1;
for (i = nlo; i <= nhi; i++) {
Tc_style[i] = CONSTANT;
Tc[i] = Tc_one;
}
iarg += 1 + ntypes;
} 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) {
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);
btype = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
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");
cutsq_bond = cut_bond * cut_bond;
iarg += 2;
iarg += 3;
} else {
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);
if (index != -1) atom->remove_custom(index, 1, 0);
memory->destroy(cv_type);
memory->destroy(Tc_type);
memory->destroy(kappa_type);
memory->destroy(cv_style);
memory->destroy(Tc_style);
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)
error->all(FLERR,"fix rheo/thermal command requires atom property conductivity");
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 (!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 *status = atom->status;
int *mask = atom->mask;
double *temperature = atom->temperature;
double **gradt = compute_grad->gradt;
double **vshift = compute_vshift->array_atom;
@ -263,44 +280,39 @@ void FixRHEOThermal::initial_integrate(int /*vflag*/)
for (i = 0; i < nlocal; i++) {
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];
}
}
}
}
/* ---------------------------------------------------------------------- */
void FixRHEOThermal::post_integrate()
{
int i, itype;
double cvi, Tci, Ti;
int *status = atom->status;
double *temperature = atom->temperature;
double *heatflow = atom->heatflow;
double *rho = atom->rho;
int *mask = atom->mask;
int *type = atom->type;
double cvi, Tci, Ti;
int n_melt = 0;
int n_freeze = 0;
//Integrate temperature and check status
for (int i = 0; i < atom->nlocal; i++) {
if (mask[i] & groupbit) {
for (i = 0; i < atom->nlocal; i++) {
if (status[i] & STATUS_NO_INTEGRATION) continue;
cvi = calc_cv(i);
itype = type[i];
cvi = calc_cv(i, type[i]);
temperature[i] += dtf * heatflow[i] / cvi;
if (Tc_style != NONE) {
if (Tc_style[itype] != NONE) {
Ti = temperature[i];
if (Tc_style == CONSTANT) {
Tci = Tc;
} else if (Tc_style == TYPE) {
Tci = Tc_type[type[i]];
if (Tc_style[itype] == CONSTANT) {
Tci = Tc[itype];
}
if (Ti > Tci) {
@ -320,7 +332,7 @@ void FixRHEOThermal::post_integrate()
}
}
}
}
}
int n_melt_all, n_freeze_all;
@ -344,19 +356,16 @@ void FixRHEOThermal::post_integrate()
void FixRHEOThermal::post_neighbor()
{
int i;
int i, itype;
int *type = atom->type;
int *mask = atom->mask;
double *conductivity = atom->conductivity;
int nlocal = atom->nlocal;
int nall = nlocal + atom->nghost;
if (conductivity_style == CONSTANT) {
for (i = 0; i < nall; i++)
if (mask[i] & groupbit) conductivity[i] = kappa;
} else if (conductivity_style == TYPE) {
for (i = 0; i < nall; i++)
if (mask[i] & groupbit) conductivity[i] = kappa_type[type[i]];
for (i = 0; i < nall; i++) {
itype = type[i];
if (kappa_style[itype] == CONSTANT)
conductivity[i] = kappa[itype];
}
}
@ -372,23 +381,20 @@ void FixRHEOThermal::pre_force(int /*vflag*/)
void FixRHEOThermal::final_integrate()
{
int *status = atom->status;
int *type = atom->type;
double *temperature = atom->temperature;
double *heatflow = atom->heatflow;
int *status = atom->status;
int *mask = atom->mask;
double cvi;
//Integrate temperature and check status
for (int i = 0; i < atom->nlocal; i++) {
if (mask[i] & groupbit) {
if (status[i] & STATUS_NO_INTEGRATION) continue;
cvi = calc_cv(i);
cvi = calc_cv(i, type[i]);
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) {
return cv;
} else if (cv_style == TYPE) {
return(cv_type[atom->type[i]]);
if (cv_style[itype] == CONSTANT) {
return cv[itype];
}
}

View File

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

View File

@ -32,60 +32,87 @@
using namespace LAMMPS_NS;
using namespace FixConst;
enum {NONE, CONSTANT, TYPE, POWER};
enum {NONE, CONSTANT, POWER};
/* ---------------------------------------------------------------------- */
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");
viscosity_style = NONE;
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;
if (strcmp(arg[iarg],"constant") == 0) {
if (iarg + 1 >= narg) error->all(FLERR,"Insufficient arguments for viscosity option");
viscosity_style = CONSTANT;
eta = utils::numeric(FLERR,arg[iarg + 1],false,lmp);
if (eta < 0.0) error->all(FLERR,"The viscosity must be positive");
while (iarg < narg) {
utils::bounds(FLERR, arg[iarg], 1, n, nlo, nhi, error);
if (iarg + 1 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/viscosity", error);
if (strcmp(arg[iarg + 1], "constant") == 0) {
if (iarg + 2 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/viscosity constant", error);
constant_flag = 1;
double eta_one = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
if (eta_one < 0.0) error->all(FLERR, "The viscosity must be positive");
iarg += 1;
} else if (strcmp(arg[iarg],"type") == 0) {
if (iarg + ntypes >= narg) error->all(FLERR,"Insufficient arguments for viscosity option");
viscosity_style = TYPE;
memory->create(eta_type, ntypes + 1, "rheo_thermal:eta_type");
for (int i = 1; i <= ntypes; i++) {
eta_type[i] = utils::numeric(FLERR,arg[iarg + i], false, lmp);
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;
}
iarg += ntypes;
} else if (strcmp(arg[iarg], "power") == 0) {
if (iarg + 4 >= narg) error->all(FLERR,"Insufficient arguments for viscosity option");
viscosity_style = POWER;
if (iarg + 5 >= narg) utils::missing_cmd_args(FLERR, "fix rheo/viscosity power", error);
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;
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 += 2;
}
if (viscosity_style == NONE)
error->all(FLERR,"Must specify viscosity style for fix/rheo/viscosity");
for (i = 1; i <= n; i++)
if (viscosity_style[i] == NONE)
error->all(FLERR,"Must specify viscosity for atom type {} in fix/rheo/viscosity", i);
}
/* ---------------------------------------------------------------------- */
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;
// Identify whether this is the last instance of fix viscosity
last_flag = 0;
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;
if (modify->get_fix_by_style("rheo/viscosity").size() > 1)
error->all(FLERR, "More than one fix rheo/viscosity defined");
post_neighbor();
pre_force(0);
@ -137,20 +155,18 @@ void FixRHEOViscosity::setup_pre_force(int /*vflag*/)
void FixRHEOViscosity::post_neighbor()
{
int i;
if (!constant_flag) return;
int i, itype;
int *type = atom->type;
int *mask = atom->mask;
double *viscosity = atom->viscosity;
int nall = atom->nlocal + atom->nghost;
if (viscosity_style == CONSTANT) {
for (i = 0; i < nall; i++)
if (mask[i] & groupbit) viscosity[i] = eta;
} else if (viscosity_style == TYPE) {
for (i = 0; i < nall; i++)
if (mask[i] & groupbit) viscosity[i] = eta_type[type[i]];
for (i = 0; i < nall; i++) {
itype = type[i];
if (viscosity_style[itype])
viscosity[i] = eta[itype];
}
}
@ -160,19 +176,22 @@ void FixRHEOViscosity::post_neighbor()
void FixRHEOViscosity::pre_force(int /*vflag*/)
{
int i, a, b;
if (!evolve_flag) return;
int i, itype, a, b;
double tmp, gdot;
int *mask = atom->mask;
int *type = atom->type;
double *viscosity = atom->viscosity;
double **gradv = compute_grad->gradv;
int nlocal = atom->nlocal;
int dim = domain->dimension;
if (viscosity_style == POWER) {
for (i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
itype = type[i];
if (viscosity_style[itype] == POWER) {
gdot = 0.0;
for (a = 0; a < dim; a++) {
for (b = a; b < dim; b++) {
@ -183,16 +202,15 @@ void FixRHEOViscosity::pre_force(int /*vflag*/)
}
}
gdot = sqrt(gdot);
if (gdot <= gd0) {
viscosity[i] = eta;
if (gdot <= gd0[itype]) {
viscosity[i] = eta[itype];
} else {
viscosity[i] = K * pow(gdot, npow - 1) + tau0 / gdot;
}
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;
private:
double *eta_type, eta;
double npow, K, gd0, tau0;
int viscosity_style, last_flag;
double *eta, *npow, *K, *gd0, *tau0;
int *viscosity_style, constant_flag, evolve_flag;
class FixRHEO *fix_rheo;
class ComputeRHEOGrad *compute_grad;

View File

@ -47,8 +47,8 @@ static constexpr double EPSILON = 1e-2;
/* ---------------------------------------------------------------------- */
PairRHEO::PairRHEO(LAMMPS *lmp) :
Pair(lmp), compute_kernel(nullptr), compute_grad(nullptr),
compute_interface(nullptr), fix_rheo(nullptr), fix_pressure(nullptr)
Pair(lmp), compute_kernel(nullptr), compute_grad(nullptr), compute_interface(nullptr), fix_rheo(nullptr),
fix_pressure(nullptr), rho0(nullptr), csq(nullptr), cs(nullptr)
{
restartinfo = 0;
single_enable = 0;
@ -68,6 +68,8 @@ PairRHEO::~PairRHEO()
memory->destroy(setflag);
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 pair_force_flag, pair_rho_flag, pair_avisc_flag;
int fluidi, fluidj;
double xtmp, ytmp, ztmp, w, wp, Ti, Tj, dT;
double rhoi, rhoj, voli, volj, Pi, Pj, etai, etaj, kappai, kappaj;
double xtmp, ytmp, ztmp, w, wp, Ti, Tj, dT, csq_ave, cs_ave;
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 *dWij, *dWji, *dW1ij, *dW1ji;
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];
}
cs_ave = 0.5 * (cs[itype] + cs[jtype]);
csq_ave = cs_ave * cs_ave;
pair_rho_flag = 0;
pair_force_flag = 0;
pair_avisc_flag = 0;
@ -201,31 +206,31 @@ void PairRHEO::compute(int eflag, int vflag)
// Add corrections for walls
rhoi = rho[i];
rhoj = rho[j];
rho0i = rho[itype];
rho0j = rho[jtype];
Pi = pressure[i];
Pj = pressure[j];
fmag = 0;
if (interface_flag) {
if (fluidi && (!fluidj)) {
compute_interface->correct_v(vi, vj, i, j);
//compute_interface->correct_v(vj, vi, 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)))
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) {
compute_interface->correct_v(vj, vi, j, i);
//compute_interface->correct_v(vi, vj, 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))
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)) {
rhoi = rho0;
rhoj = rho0;
rhoi = rho0i;
rhoj = rho0j;
}
}
@ -239,12 +244,12 @@ void PairRHEO::compute(int eflag, int vflag)
// Thermal Evolution
if (thermal_flag) {
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;
if (newton_pair || j < nlocal) {
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;
}
}
@ -266,7 +271,7 @@ void PairRHEO::compute(int eflag, int vflag)
mu = dot3(du, dx) * hinv3;
mu /= (rsq * hinv3 * hinv3 + EPSILON);
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);
}
@ -334,7 +339,7 @@ void PairRHEO::compute(int eflag, int vflag)
psi_ij += 0.5 * (gradr[i][a] + gradr[j][a]) * dx[a];
drho[i] += 2 * rho_damp * psi_ij * Fij * volj;
} 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;
}
@ -460,9 +465,12 @@ void PairRHEO::setup()
hsq = h * h;
hinv = 1.0 / h;
hinv3 = hinv * 3.0;
cs = sqrt(csq);
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)
error->all(FLERR, "Pair RHEO requires ghost atoms store velocity");
@ -482,9 +490,8 @@ void PairRHEO::setup()
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");
}
return h;
}

View File

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