Files
lammps/src/MANIFOLD/manifold_spine.cpp
2021-06-29 20:12:59 -04:00

178 lines
3.3 KiB
C++

// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
----------------------------------------------------------------------- */
#include "manifold_spine.h"
#include <cmath>
#include "math_special.h"
using namespace LAMMPS_NS;
using namespace user_manifold;
manifold_spine::manifold_spine( LAMMPS *lmp, int /*argc*/, char **/*argv*/ )
: manifold(lmp)
{
power = 4;
}
manifold_spine_two::manifold_spine_two( LAMMPS *lmp, int narg, char **argv )
: manifold_spine( lmp, narg, argv )
{
power = 2;
}
/*
* Equation for spine is:
*
* -x^2 - y^2 + (a^2 - (z/c)^2)*( 1 + (A*sin(const(z) *z^2))^4 )
* const(z) = (z < 0) ? B2 : B
* params[5] = { a, A, B, B2, c }
*/
double manifold_spine::g_and_n( const double *x, double *nn )
{
double a = params[0];
double A = params[1];
double B = params[2];
double B2 = params[3];
double c = params[4];
double cc, BB, z2, xy2;
double c2, As, Ac, azc, Apart;
double AMs, AMc;
double dazc, dAMs;
if (x[2] > 0) {
BB = B;
cc = c;
} else {
BB = B2;
cc = 1.0;
}
xy2 = x[0]*x[0] + x[1]*x[1];
z2 = x[2]*x[2];
c2 = 1.0/( cc*cc );
azc = a*a - z2*c2;
As = sin( BB*z2 );
Ac = cos( BB*z2 );
As *= A;
Ac *= A;
Apart = MathSpecial::powint( As, power-1 ); // Much more efficient! =D
//Apart = pow( As, power-1 );
AMs = Apart*As;
AMc = Apart*Ac;
dAMs = power * AMc * 2.0*BB*x[2];
dazc = -2.0*x[2]*c2;
nn[0] = -2*x[0];
nn[1] = -2*x[1];
nn[2] = azc * dAMs + ( 1.0 + AMs ) * dazc;
return -xy2 + azc * ( 1.0 + AMs );
}
void manifold_spine::n( const double *x, double *nn )
{
double a = params[0];
double A = params[1];
double B = params[2];
double B2 = params[3];
double c = params[4];
double cc, BB, z2;
double c2, As, Ac, azc, Apart;
double AMs, AMc;
double dazc, dAMs;
if (x[2] > 0) {
BB = B;
cc = c;
} else {
BB = B2;
cc = 1.0;
}
z2 = x[2]*x[2];
c2 = 1.0/( cc*cc );
azc = a*a - z2*c2;
As = sin( BB*z2 );
Ac = cos( BB*z2 );
As *= A;
Ac *= A;
Apart = MathSpecial::powint( As, power-1 ); // Much more efficient! =D
//Apart = pow( As, power-1 );
AMs = Apart*As;
AMc = Apart*Ac;
dAMs = power * AMc * 2.0*BB*x[2];
dazc = -2.0*x[2]*c2;
nn[0] = -2*x[0];
nn[1] = -2*x[1];
nn[2] = azc * dAMs + ( 1.0 + AMs ) * dazc;
}
double manifold_spine::g( const double *x )
{
double a = params[0];
double A = params[1];
double B = params[2];
double B2 = params[3];
double c = params[4];
double cc, BB, z2, xy2;
double c2, As, azc, Apart;
double AMs;
if (x[2] > 0) {
BB = B;
cc = c;
} else {
BB = B2;
cc = 1.0;
}
xy2 = x[0]*x[0] + x[1]*x[1];
z2 = x[2]*x[2];
c2 = 1.0/( cc*cc );
azc = a*a - z2*c2;
As = sin( BB*z2 );
As *= A;
Apart = MathSpecial::powint( As, power-1 );
AMs = Apart*As;
return -xy2 + azc * ( 1.0 + AMs );
}