Repository navigation
Expand file tree
/
Copy pathpppm_bsct.cpp
More file actions
149 lines (118 loc) · 4.18 KB
/
Copy pathpppm_bsct.cpp
File metadata and controls
149 lines (118 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors: Tommi Järvi (Fh-IWM), Lars Pastewka (KIT)
------------------------------------------------------------------------- */
/*
1. Check nbuf
2. There is an if differentiation_flag != 1 in poisson_peratom. Check if
we can only compute potential if differentiation_flag != 1.
*/
#include "mpi.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "pppm_bsct.h"
#include "atom.h"
#include "comm.h"
#include "gridcomm.h"
#include "neighbor.h"
#include "force.h"
#include "pair.h"
#include "bond.h"
#include "angle.h"
#include "domain.h"
#include "fft3d_wrap.h"
#include "remap_wrap.h"
#include "memory.h"
#include "error.h"
#include "math_const.h"
#include "math_special.h"
using namespace LAMMPS_NS;
using namespace MathConst;
using namespace MathSpecial;
/* ---------------------------------------------------------------------- */
PPPMBSCT::PPPMBSCT(LAMMPS *lmp) : PPPM(lmp)
{
}
/* ----------------------------------------------------------------------
free all memory
------------------------------------------------------------------------- */
PPPMBSCT::~PPPMBSCT()
{
}
/* ----------------------------------------------------------------------
Return electrostatic potential (Compute has to have been run
prior to this as the actual computation is done there. This only
extracts the potential from the internal arrays.)
------------------------------------------------------------------------- */
void PPPMBSCT::phi(FFT_SCALAR *phi)
{
int i,l,m,n,nx,ny,nz,mx,my,mz;
FFT_SCALAR dx,dy,dz,x0,y0,z0;
// loop over my charges, interpolate electric field from nearby grid points
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// (dx,dy,dz) = distance to "lower left" grid pt
// (mx,my,mz) = global coords of moving stencil pt
double *q = atom->q;
double **x = atom->x;
double **f = atom->f;
int nlocal = atom->nlocal;
const double qscale = qqrd2e * scale;
for (i = 0; i < nlocal; i++) {
nx = part2grid[i][0];
ny = part2grid[i][1];
nz = part2grid[i][2];
dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv;
dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv;
dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv;
compute_rho1d(dx,dy,dz);
for (n = nlower; n <= nupper; n++) {
mz = n+nz;
z0 = rho1d[2][n];
for (m = nlower; m <= nupper; m++) {
my = m+ny;
y0 = z0*rho1d[1][m];
for (l = nlower; l <= nupper; l++) {
mx = l+nx;
x0 = y0*rho1d[0][l];
phi[i] += qscale*x0*u_brick[mz][my][mx];
}
}
}
}
for (i = 0; i < nlocal; i++) {
phi[i] -= 2*qscale*(g_ewald*q[i]/MY_PIS + MY_PI2*qsum / (g_ewald*g_ewald*volume));
}
// slab correction
if(slabflag) phi_slabcorr(phi);
}
/* ----------------------------------------------------------------------
Slab correction for phi. Not tested too well.
------------------------------------------------------------------------- */
void PPPMBSCT::phi_slabcorr(FFT_SCALAR *phi)
{
// compute local contribution to global dipole moment
double *q = atom->q;
double **x = atom->x;
int nlocal = atom->nlocal;
double dipole = 0.0;
for (int i = 0; i < nlocal; i++) dipole += q[i]*x[i][2];
// sum local contributions to get global dipole moment
double dipole_all;
MPI_Allreduce(&dipole,&dipole_all,1,MPI_DOUBLE,MPI_SUM,world);
// compute corrections
double ffact = -4.0*MY_PI*dipole_all/volume;
for (int i = 0; i < nlocal; i++) {
phi[i] += qqrd2e*(-ffact)*atom->x[i][2];
}
}