Files
lammps/src/MESONT/bond_mesocnt.cpp
2024-02-28 15:37:13 -05:00

118 lines
3.7 KiB
C++

/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Philipp Kloza (University of Cambridge)
pak37@cam.ac.uk
------------------------------------------------------------------------- */
#include "bond_mesocnt.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "update.h"
#include <cmath>
#include <cstring>
using namespace LAMMPS_NS;
using MathConst::MY_2PI;
static constexpr double A_CC = 1.421;
/* ---------------------------------------------------------------------- */
BondMesoCNT::BondMesoCNT(LAMMPS *_lmp) : BondHarmonic(_lmp)
{
born_matrix_enable = 1;
}
/* ---------------------------------------------------------------------- */
BondMesoCNT::~BondMesoCNT()
{
if (allocated && !copymode) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(r0);
}
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void BondMesoCNT::coeff(int narg, char **arg)
{
if (narg < 1) utils::missing_cmd_args(FLERR, "bond_coeff", error);
// units, eV to energy unit conversion
double ang = force->angstrom;
double eunit;
if (strcmp(update->unit_style, "real") == 0)
eunit = 23.06054966;
else if (strcmp(update->unit_style, "metal") == 0)
eunit = 1.0;
else if (strcmp(update->unit_style, "si") == 0)
eunit = 1.6021765e-19;
else if (strcmp(update->unit_style, "cgs") == 0)
eunit = 1.6021765e-12;
else if (strcmp(update->unit_style, "electron") == 0)
eunit = 3.674932248e-2;
else if (strcmp(update->unit_style, "micro") == 0)
eunit = 1.6021765e-4;
else if (strcmp(update->unit_style, "nano") == 0)
eunit = 1.6021765e2;
else
error->all(FLERR, "Bond style mesocnt does not support {} units", update->unit_style);
// set parameters
double k_one, r0_one;
if (strcmp(arg[1], "custom") == 0) {
if (narg != 4) error->all(FLERR, "Incorrect number of args for 'custom' bond coefficients");
k_one = utils::numeric(FLERR, arg[2], false, lmp);
r0_one = utils::numeric(FLERR, arg[3], false, lmp);
} else if (strcmp(arg[1], "C") == 0) {
if (narg != 5)
error->all(FLERR, "Incorrect number of args for 'C' preset in bond coefficients");
int n = utils::inumeric(FLERR, arg[2], false, lmp);
int m = utils::inumeric(FLERR, arg[3], false, lmp);
r0_one = utils::numeric(FLERR, arg[4], false, lmp);
double r_ang = sqrt(3.0 * (n * n + n * m + m * m)) * A_CC / MY_2PI;
k_one = 0.5 * (86.64 + 100.56 * r_ang) * eunit / (ang * r0_one);
} else
error->all(FLERR, "Unknown {} preset in bond coefficients", arg[1]);
if (!allocated) allocate();
int ilo, ihi;
utils::bounds(FLERR, arg[0], 1, atom->nbondtypes, ilo, ihi, error);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
r0[i] = r0_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR, "Invalid bond type {}", arg[0]);
}