Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F91719321
pair_reax_c.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Nov 13, 20:03
Size
20 KB
Mime Type
text/x-c
Expires
Fri, Nov 15, 20:03 (2 d)
Engine
blob
Format
Raw Data
Handle
22313728
Attached To
rLAMMPS lammps
pair_reax_c.cpp
View Options
/* ----------------------------------------------------------------------
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 author: Hasan Metin Aktulga, Purdue University
------------------------------------------------------------------------- */
#include "pair_reax_c.h"
#include "atom.h"
#include "update.h"
#include "force.h"
#include "comm.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "modify.h"
#include "fix.h"
#include "fix_reax_c.h"
#include "memory.h"
#include "error.h"
#include "reaxc_types.h"
#include "reaxc_allocate.h"
#include "reaxc_control.h"
#include "reaxc_ffield.h"
#include "reaxc_forces.h"
#include "reaxc_init_md.h"
#include "reaxc_io_tools.h"
#include "reaxc_list.h"
#include "reaxc_lookup.h"
#include "reaxc_reset_tools.h"
#include "reaxc_traj.h"
#include "reaxc_vector.h"
using
namespace
LAMMPS_NS
;
/* ---------------------------------------------------------------------- */
PairReaxC
::
PairReaxC
(
LAMMPS
*
lmp
)
:
Pair
(
lmp
)
{
system
=
(
reax_system
*
)
memory
->
smalloc
(
sizeof
(
reax_system
),
"reax:system"
);
control
=
(
control_params
*
)
memory
->
smalloc
(
sizeof
(
control_params
),
"reax:control"
);
data
=
(
simulation_data
*
)
memory
->
smalloc
(
sizeof
(
simulation_data
),
"reax:data"
);
workspace
=
(
storage
*
)
memory
->
smalloc
(
sizeof
(
storage
),
"reax:storage"
);
lists
=
(
reax_list
*
)
memory
->
smalloc
(
LIST_N
*
sizeof
(
reax_list
),
"reax:lists"
);
out_control
=
(
output_controls
*
)
memory
->
smalloc
(
sizeof
(
output_controls
),
"reax:out_control"
);
mpi_data
=
(
mpi_datatypes
*
)
memory
->
smalloc
(
sizeof
(
mpi_datatypes
),
"reax:mpi"
);
MPI_Comm_rank
(
world
,
&
system
->
my_rank
);
system
->
my_coords
[
0
]
=
0
;
system
->
my_coords
[
1
]
=
0
;
system
->
my_coords
[
2
]
=
0
;
system
->
num_nbrs
=
0
;
system
->
n
=
0
;
// my atoms
system
->
N
=
0
;
// mine + ghosts
system
->
bigN
=
0
;
// all atoms in the system
system
->
local_cap
=
0
;
system
->
total_cap
=
0
;
system
->
gcell_cap
=
0
;
system
->
bndry_cuts
.
ghost_nonb
=
0
;
system
->
bndry_cuts
.
ghost_hbond
=
0
;
system
->
bndry_cuts
.
ghost_bond
=
0
;
system
->
bndry_cuts
.
ghost_cutoff
=
0
;
system
->
my_atoms
=
NULL
;
fix_reax
=
NULL
;
nextra
=
14
;
pvector
=
new
double
[
nextra
];
setup_flag
=
0
;
}
/* ---------------------------------------------------------------------- */
PairReaxC
::~
PairReaxC
()
{
if
(
fix_reax
)
modify
->
delete_fix
(
"REAXC"
);
Close_Output_Files
(
system
,
control
,
out_control
,
mpi_data
);
// deallocate reax data-structures
if
(
control
->
tabulate
)
Deallocate_Lookup_Tables
(
system
);
if
(
control
->
hbond_cut
>
0
)
Delete_List
(
lists
+
HBONDS
,
world
);
Delete_List
(
lists
+
BONDS
,
world
);
Delete_List
(
lists
+
THREE_BODIES
,
world
);
Delete_List
(
lists
+
FAR_NBRS
,
world
);
// fprintf( stderr, "3\n" );
DeAllocate_Workspace
(
control
,
workspace
);
DeAllocate_System
(
system
);
//fprintf( stderr, "4\n" );
memory
->
sfree
(
system
);
memory
->
sfree
(
control
);
memory
->
sfree
(
data
);
memory
->
sfree
(
workspace
);
memory
->
sfree
(
lists
);
memory
->
sfree
(
out_control
);
memory
->
sfree
(
mpi_data
);
//fprintf( stderr, "5\n" );
// deallocate interface storage
if
(
allocated
)
{
memory
->
destroy_2d_int_array
(
setflag
);
memory
->
destroy_2d_double_array
(
cutsq
);
delete
[]
map
;
delete
[]
chi
;
delete
[]
eta
;
delete
[]
gamma
;
}
delete
[]
pvector
;
//fprintf( stderr, "6\n" );
}
/* ---------------------------------------------------------------------- */
void
PairReaxC
::
allocate
(
)
{
allocated
=
1
;
int
n
=
atom
->
ntypes
;
setflag
=
memory
->
create_2d_int_array
(
n
+
1
,
n
+
1
,
"pair:setflag"
);
cutsq
=
memory
->
create_2d_double_array
(
n
+
1
,
n
+
1
,
"pair:cutsq"
);
map
=
new
int
[
n
+
1
];
chi
=
new
double
[
n
+
1
];
eta
=
new
double
[
n
+
1
];
gamma
=
new
double
[
n
+
1
];
}
/* ---------------------------------------------------------------------- */
void
PairReaxC
::
settings
(
int
narg
,
char
**
arg
)
{
if
(
narg
!=
1
&&
narg
!=
3
)
error
->
all
(
"Illegal pair_style command"
);
// read name of control file or use default controls
if
(
strcmp
(
arg
[
0
],
"NULL"
)
==
0
)
{
strcpy
(
control
->
sim_name
,
"simulate"
);
control
->
ensemble
=
0
;
out_control
->
energy_update_freq
=
0
;
control
->
tabulate
=
0
;
control
->
reneighbor
=
1
;
control
->
vlist_cut
=
control
->
nonb_cut
;
control
->
bond_cut
=
5.
;
control
->
hbond_cut
=
7.50
;
control
->
thb_cut
=
0.001
;
out_control
->
write_steps
=
0
;
out_control
->
traj_method
=
0
;
strcpy
(
out_control
->
traj_title
,
"default_title"
);
out_control
->
atom_info
=
0
;
out_control
->
bond_info
=
0
;
out_control
->
angle_info
=
0
;
}
else
Read_Control_File
(
arg
[
0
],
control
,
out_control
);
// default values
qeqflag
=
1
;
// process optional keywords
int
iarg
=
1
;
while
(
iarg
<
narg
)
{
if
(
strcmp
(
arg
[
iarg
],
"checkqeq"
)
==
0
)
{
if
(
iarg
+
2
>
narg
)
error
->
all
(
"Illegal pair_style reax/c command"
);
if
(
strcmp
(
arg
[
iarg
+
1
],
"yes"
)
==
0
)
qeqflag
=
1
;
else
if
(
strcmp
(
arg
[
iarg
+
1
],
"no"
)
==
0
)
qeqflag
=
0
;
else
error
->
all
(
"Illegal pair_style reax/c command"
);
iarg
+=
2
;
}
else
error
->
all
(
"Illegal pair_style reax/c command"
);
}
// LAMMPS is responsible for generating nbrs
control
->
reneighbor
=
1
;
}
/* ---------------------------------------------------------------------- */
void
PairReaxC
::
coeff
(
int
nargs
,
char
**
args
)
{
if
(
!
allocated
)
allocate
();
if
(
nargs
!=
3
+
atom
->
ntypes
)
error
->
all
(
"Incorrect args for pair coefficients"
);
// insure I,J args are * *
if
(
strcmp
(
args
[
0
],
"*"
)
!=
0
||
strcmp
(
args
[
1
],
"*"
)
!=
0
)
error
->
all
(
"Incorrect args for pair coefficients"
);
// read ffield file
Read_Force_Field
(
args
[
2
],
&
(
system
->
reax_param
),
control
);
// read args that map atom types to elements in potential file
// map[i] = which element the Ith atom type is, -1 if NULL
int
itmp
;
int
nreax_types
=
system
->
reax_param
.
num_atom_types
;
for
(
int
i
=
3
;
i
<
nargs
;
i
++
)
{
if
(
strcmp
(
args
[
i
],
"NULL"
)
==
0
)
{
map
[
i
-
2
]
=
-
1
;
continue
;
}
itmp
=
atoi
(
args
[
i
])
-
1
;
map
[
i
-
2
]
=
itmp
;
// error check
if
(
itmp
<
0
||
itmp
>=
nreax_types
)
error
->
all
(
"Non-existent ReaxFF type"
);
}
int
n
=
atom
->
ntypes
;
int
count
=
0
;
for
(
int
i
=
1
;
i
<=
n
;
i
++
)
for
(
int
j
=
i
;
j
<=
n
;
j
++
)
{
setflag
[
i
][
j
]
=
1
;
count
++
;
}
if
(
count
==
0
)
error
->
all
(
"Incorrect args for pair coefficients"
);
}
/* ---------------------------------------------------------------------- */
void
PairReaxC
::
init_style
(
)
{
if
(
!
atom
->
q_flag
)
error
->
all
(
"Pair reax/c requires atom attribute q"
);
firstwarn
=
1
;
int
iqeq
;
for
(
iqeq
=
0
;
iqeq
<
modify
->
nfix
;
iqeq
++
)
if
(
strcmp
(
modify
->
fix
[
iqeq
]
->
style
,
"qeq/reax"
)
==
0
)
break
;
if
(
iqeq
==
modify
->
nfix
&&
qeqflag
==
1
)
error
->
all
(
"Pair reax/c requires use of fix qeq/reax"
);
system
->
n
=
atom
->
nlocal
;
// my atoms
system
->
N
=
atom
->
nlocal
+
atom
->
nghost
;
// mine + ghosts
system
->
bigN
=
static_cast
<
int
>
(
atom
->
natoms
);
// all atoms in the system
system
->
wsize
=
comm
->
nprocs
;
system
->
big_box
.
V
=
0
;
system
->
big_box
.
box_norms
[
0
]
=
0
;
system
->
big_box
.
box_norms
[
1
]
=
0
;
system
->
big_box
.
box_norms
[
2
]
=
0
;
if
(
atom
->
tag_enable
==
0
)
error
->
all
(
"Pair style reax/c requires atom IDs"
);
if
(
force
->
newton_pair
==
0
)
error
->
all
(
"Pair style reax/c requires newton pair on"
);
// need a half neighbor list w/ Newton off
// built whenever re-neighboring occurs
int
irequest
=
neighbor
->
request
(
this
);
neighbor
->
requests
[
irequest
]
->
newton
=
2
;
cutmax
=
MAX3
(
control
->
nonb_cut
,
control
->
hbond_cut
,
2
*
control
->
bond_cut
);
for
(
int
i
=
0
;
i
<
LIST_N
;
++
i
)
lists
[
i
].
allocated
=
0
;
if
(
fix_reax
==
NULL
)
{
char
**
fixarg
=
new
char
*
[
3
];
fixarg
[
0
]
=
(
char
*
)
"REAXC"
;
fixarg
[
1
]
=
(
char
*
)
"all"
;
fixarg
[
2
]
=
(
char
*
)
"REAXC"
;
modify
->
add_fix
(
3
,
fixarg
);
delete
[]
fixarg
;
fix_reax
=
(
FixReaxC
*
)
modify
->
fix
[
modify
->
nfix
-
1
];
}
}
/* ---------------------------------------------------------------------- */
void
PairReaxC
::
setup
(
)
{
int
oldN
;
system
->
n
=
atom
->
nlocal
;
// my atoms
system
->
N
=
atom
->
nlocal
+
atom
->
nghost
;
// mine + ghosts
oldN
=
system
->
N
;
system
->
bigN
=
static_cast
<
int
>
(
atom
->
natoms
);
// all atoms in the system
if
(
setup_flag
==
0
)
{
setup_flag
=
1
;
int
*
num_bonds
=
fix_reax
->
num_bonds
;
int
*
num_hbonds
=
fix_reax
->
num_hbonds
;
control
->
vlist_cut
=
neighbor
->
cutneighmax
;
// determine the local and total capacity
system
->
local_cap
=
MAX
(
(
int
)(
system
->
n
*
SAFE_ZONE
),
MIN_CAP
);
system
->
total_cap
=
MAX
(
(
int
)(
system
->
N
*
SAFE_ZONE
),
MIN_CAP
);
// initialize my data structures
PreAllocate_Space
(
system
,
control
,
workspace
,
world
);
write_reax_atoms
();
int
num_nbrs
=
estimate_reax_lists
();
if
(
!
Make_List
(
system
->
total_cap
,
num_nbrs
,
TYP_FAR_NEIGHBOR
,
lists
+
FAR_NBRS
,
world
))
error
->
all
(
"Pair reax/c problem in far neighbor list"
);
write_reax_lists
();
Initialize
(
system
,
control
,
data
,
workspace
,
&
lists
,
out_control
,
mpi_data
,
world
);
for
(
int
k
=
0
;
k
<
system
->
N
;
++
k
)
{
num_bonds
[
k
]
=
system
->
my_atoms
[
k
].
num_bonds
;
num_hbonds
[
k
]
=
system
->
my_atoms
[
k
].
num_hbonds
;
}
}
else
{
// fill in reax datastructures
write_reax_atoms
();
// reset the bond list info for new atoms
for
(
int
k
=
oldN
;
k
<
system
->
N
;
++
k
)
Set_End_Index
(
k
,
Start_Index
(
k
,
lists
+
BONDS
),
lists
+
BONDS
);
// check if I need to shrink/extend my data-structs
ReAllocate
(
system
,
control
,
data
,
workspace
,
&
lists
,
mpi_data
);
}
}
/* ---------------------------------------------------------------------- */
double
PairReaxC
::
init_one
(
int
i
,
int
j
)
{
return
cutmax
;
}
/* ---------------------------------------------------------------------- */
void
PairReaxC
::
compute
(
int
eflag
,
int
vflag
)
{
double
evdwl
,
ecoul
;
double
t_start
,
t_end
;
// communicate num_bonds once every reneighboring
// 2 num arrays stored by fix, grab ptr to them
if
(
neighbor
->
ago
==
0
)
comm
->
forward_comm_fix
(
fix_reax
);
int
*
num_bonds
=
fix_reax
->
num_bonds
;
int
*
num_hbonds
=
fix_reax
->
num_hbonds
;
evdwl
=
ecoul
=
0.0
;
if
(
eflag
||
vflag
)
ev_setup
(
eflag
,
vflag
);
else
evflag
=
vflag_fdotr
=
eflag_global
=
vflag_global
=
0
;
if
((
eflag_atom
||
vflag_atom
)
&&
firstwarn
)
{
firstwarn
=
0
;
if
(
comm
->
me
==
0
)
error
->
warning
(
"Pair reax/c cannot yet compute "
"per-atom energy or stress"
);
}
if
(
vflag_global
)
control
->
virial
=
1
;
else
control
->
virial
=
0
;
system
->
n
=
atom
->
nlocal
;
// my atoms
system
->
N
=
atom
->
nlocal
+
atom
->
nghost
;
// mine + ghosts
system
->
bigN
=
static_cast
<
int
>
(
atom
->
natoms
);
// all atoms in the system
system
->
big_box
.
V
=
0
;
system
->
big_box
.
box_norms
[
0
]
=
0
;
system
->
big_box
.
box_norms
[
1
]
=
0
;
system
->
big_box
.
box_norms
[
2
]
=
0
;
if
(
comm
->
me
==
0
)
t_start
=
MPI_Wtime
();
// setup data structures
setup
();
Reset
(
system
,
control
,
data
,
workspace
,
&
lists
,
world
);
workspace
->
realloc
.
num_far
=
write_reax_lists
();
// timing for filling in the reax lists
if
(
comm
->
me
==
0
)
{
t_end
=
MPI_Wtime
();
data
->
timing
.
nbrs
=
t_end
-
t_start
;
}
// forces
Compute_Forces
(
system
,
control
,
data
,
workspace
,
&
lists
,
out_control
,
mpi_data
);
read_reax_forces
();
for
(
int
k
=
0
;
k
<
system
->
N
;
++
k
)
{
num_bonds
[
k
]
=
system
->
my_atoms
[
k
].
num_bonds
;
num_hbonds
[
k
]
=
system
->
my_atoms
[
k
].
num_hbonds
;
}
// energies and pressure
if
(
eflag_global
)
{
evdwl
+=
data
->
my_en
.
e_bond
;
evdwl
+=
data
->
my_en
.
e_ov
;
evdwl
+=
data
->
my_en
.
e_un
;
evdwl
+=
data
->
my_en
.
e_lp
;
evdwl
+=
data
->
my_en
.
e_ang
;
evdwl
+=
data
->
my_en
.
e_pen
;
evdwl
+=
data
->
my_en
.
e_coa
;
evdwl
+=
data
->
my_en
.
e_hb
;
evdwl
+=
data
->
my_en
.
e_tor
;
evdwl
+=
data
->
my_en
.
e_con
;
evdwl
+=
data
->
my_en
.
e_vdW
;
ecoul
+=
data
->
my_en
.
e_ele
;
ecoul
+=
data
->
my_en
.
e_pol
;
eng_vdwl
+=
evdwl
;
eng_coul
+=
ecoul
;
// Store the different parts of the energy
// in a list for output by compute pair command
pvector
[
0
]
=
data
->
my_en
.
e_bond
;
pvector
[
1
]
=
data
->
my_en
.
e_ov
+
data
->
my_en
.
e_un
;
pvector
[
2
]
=
data
->
my_en
.
e_lp
;
pvector
[
3
]
=
0.0
;
pvector
[
4
]
=
data
->
my_en
.
e_ang
;
pvector
[
5
]
=
data
->
my_en
.
e_pen
;
pvector
[
6
]
=
data
->
my_en
.
e_coa
;
pvector
[
7
]
=
data
->
my_en
.
e_hb
;
pvector
[
8
]
=
data
->
my_en
.
e_tor
;
pvector
[
9
]
=
data
->
my_en
.
e_con
;
pvector
[
10
]
=
data
->
my_en
.
e_vdW
;
pvector
[
11
]
=
data
->
my_en
.
e_ele
;
pvector
[
12
]
=
0.0
;
pvector
[
13
]
=
data
->
my_en
.
e_pol
;
}
if
(
vflag_fdotr
)
virial_compute
();
// #if defined(LOG_PERFORMANCE)
// if( comm->me == 0 && fix_qeq != NULL ) {
// data->timing.s_matvecs += fix_qeq->matvecs;
// data->timing.qEq += fix_qeq->qeq_time;
// }
// #endif
Output_Results
(
system
,
control
,
data
,
&
lists
,
out_control
,
mpi_data
);
++
data
->
step
;
}
/* ---------------------------------------------------------------------- */
void
PairReaxC
::
write_reax_atoms
()
{
int
*
num_bonds
=
fix_reax
->
num_bonds
;
int
*
num_hbonds
=
fix_reax
->
num_hbonds
;
for
(
int
i
=
0
;
i
<
system
->
N
;
++
i
){
system
->
my_atoms
[
i
].
orig_id
=
atom
->
tag
[
i
];
system
->
my_atoms
[
i
].
type
=
map
[
atom
->
type
[
i
]];
system
->
my_atoms
[
i
].
x
[
0
]
=
atom
->
x
[
i
][
0
];
system
->
my_atoms
[
i
].
x
[
1
]
=
atom
->
x
[
i
][
1
];
system
->
my_atoms
[
i
].
x
[
2
]
=
atom
->
x
[
i
][
2
];
system
->
my_atoms
[
i
].
q
=
atom
->
q
[
i
];
system
->
my_atoms
[
i
].
num_bonds
=
num_bonds
[
i
];
system
->
my_atoms
[
i
].
num_hbonds
=
num_hbonds
[
i
];
}
}
/* ---------------------------------------------------------------------- */
void
PairReaxC
::
get_distance
(
rvec
xj
,
rvec
xi
,
double
*
d_sqr
,
rvec
*
dvec
)
{
(
*
dvec
)[
0
]
=
xj
[
0
]
-
xi
[
0
];
(
*
dvec
)[
1
]
=
xj
[
1
]
-
xi
[
1
];
(
*
dvec
)[
2
]
=
xj
[
2
]
-
xi
[
2
];
*
d_sqr
=
SQR
((
*
dvec
)[
0
])
+
SQR
((
*
dvec
)[
1
])
+
SQR
((
*
dvec
)[
2
]);
}
/* ---------------------------------------------------------------------- */
void
PairReaxC
::
set_far_nbr
(
far_neighbor_data
*
fdest
,
int
j
,
double
d
,
rvec
dvec
)
{
fdest
->
nbr
=
j
;
fdest
->
d
=
d
;
rvec_Copy
(
fdest
->
dvec
,
dvec
);
ivec_MakeZero
(
fdest
->
rel_box
);
}
/* ---------------------------------------------------------------------- */
int
PairReaxC
::
estimate_reax_lists
()
{
int
itr_i
,
itr_j
,
itr_g
,
i
,
j
,
g
;
int
nlocal
,
nghost
,
num_nbrs
,
num_marked
;
int
*
ilist
,
*
jlist
,
*
numneigh
,
**
firstneigh
,
*
marked
;
double
d_sqr
,
g_d_sqr
;
rvec
dvec
,
g_dvec
;
double
*
dist
,
**
x
;
reax_list
*
far_nbrs
;
far_neighbor_data
*
far_list
;
x
=
atom
->
x
;
nlocal
=
atom
->
nlocal
;
nghost
=
atom
->
nghost
;
ilist
=
list
->
ilist
;
numneigh
=
list
->
numneigh
;
firstneigh
=
list
->
firstneigh
;
far_nbrs
=
lists
+
FAR_NBRS
;
far_list
=
far_nbrs
->
select
.
far_nbr_list
;
num_nbrs
=
0
;
num_marked
=
0
;
marked
=
(
int
*
)
calloc
(
system
->
N
,
sizeof
(
int
)
);
dist
=
(
double
*
)
calloc
(
system
->
N
,
sizeof
(
double
)
);
for
(
itr_i
=
0
;
itr_i
<
list
->
inum
;
++
itr_i
){
i
=
ilist
[
itr_i
];
marked
[
i
]
=
1
;
++
num_marked
;
jlist
=
firstneigh
[
i
];
for
(
itr_j
=
0
;
itr_j
<
numneigh
[
i
];
++
itr_j
){
j
=
jlist
[
itr_j
];
get_distance
(
x
[
j
],
x
[
i
],
&
d_sqr
,
&
dvec
);
dist
[
j
]
=
sqrt
(
d_sqr
);
if
(
dist
[
j
]
<=
control
->
nonb_cut
)
++
num_nbrs
;
}
// compute the nbrs among ghost atoms
for
(
itr_j
=
0
;
itr_j
<
numneigh
[
i
];
++
itr_j
){
j
=
jlist
[
itr_j
];
if
(
j
>=
nlocal
&&
!
marked
[
j
]
&&
dist
[
j
]
<=
(
control
->
vlist_cut
-
control
->
bond_cut
)
){
marked
[
j
]
=
1
;
++
num_marked
;
for
(
itr_g
=
0
;
itr_g
<
numneigh
[
i
];
++
itr_g
){
g
=
jlist
[
itr_g
];
if
(
g
>=
nlocal
&&
!
marked
[
g
]
){
get_distance
(
x
[
g
],
x
[
j
],
&
g_d_sqr
,
&
g_dvec
);
//g_dvec[0] = x[g][0] - x[j][0];
//g_dvec[1] = x[g][1] - x[j][1];
//g_dvec[2] = x[g][2] - x[j][2];
//g_d_sqr = SQR(g_dvec[0]) + SQR(g_dvec[1]) + SQR(g_dvec[2]);
if
(
g_d_sqr
<=
SQR
(
control
->
bond_cut
)
)
++
num_nbrs
;
}
}
}
}
}
for
(
i
=
0
;
i
<
system
->
N
;
++
i
)
if
(
!
marked
[
i
]
)
{
marked
[
i
]
=
1
;
++
num_marked
;
for
(
j
=
i
+
1
;
j
<
system
->
N
;
++
j
)
if
(
!
marked
[
j
]
)
{
get_distance
(
x
[
j
],
x
[
i
],
&
d_sqr
,
&
dvec
);
if
(
d_sqr
<=
SQR
(
control
->
bond_cut
)
)
++
num_nbrs
;
}
}
free
(
marked
);
free
(
dist
);
return
static_cast
<
int
>
(
MAX
(
num_nbrs
*
SAFE_ZONE
,
MIN_CAP
*
MIN_NBRS
));
}
/* ---------------------------------------------------------------------- */
int
PairReaxC
::
write_reax_lists
()
{
int
itr_i
,
itr_j
,
itr_g
,
i
,
j
,
g
;
int
nlocal
,
nghost
,
num_nbrs
;
int
*
ilist
,
*
jlist
,
*
numneigh
,
**
firstneigh
,
*
marked
;
double
d_sqr
,
g_d
,
g_d_sqr
;
rvec
dvec
,
g_dvec
;
double
*
dist
,
**
x
;
reax_list
*
far_nbrs
;
far_neighbor_data
*
far_list
;
x
=
atom
->
x
;
nlocal
=
atom
->
nlocal
;
nghost
=
atom
->
nghost
;
ilist
=
list
->
ilist
;
numneigh
=
list
->
numneigh
;
firstneigh
=
list
->
firstneigh
;
far_nbrs
=
lists
+
FAR_NBRS
;
far_list
=
far_nbrs
->
select
.
far_nbr_list
;
num_nbrs
=
0
;
marked
=
(
int
*
)
calloc
(
system
->
N
,
sizeof
(
int
)
);
dist
=
(
double
*
)
calloc
(
system
->
N
,
sizeof
(
double
)
);
for
(
itr_i
=
0
;
itr_i
<
list
->
inum
;
++
itr_i
){
i
=
ilist
[
itr_i
];
marked
[
i
]
=
1
;
jlist
=
firstneigh
[
i
];
Set_Start_Index
(
i
,
num_nbrs
,
far_nbrs
);
for
(
itr_j
=
0
;
itr_j
<
numneigh
[
i
];
++
itr_j
){
j
=
jlist
[
itr_j
];
get_distance
(
x
[
j
],
x
[
i
],
&
d_sqr
,
&
dvec
);
dist
[
j
]
=
sqrt
(
d_sqr
);
if
(
dist
[
j
]
<=
control
->
nonb_cut
){
set_far_nbr
(
&
far_list
[
num_nbrs
],
j
,
dist
[
j
],
dvec
);
++
num_nbrs
;
}
}
Set_End_Index
(
i
,
num_nbrs
,
far_nbrs
);
// compute the nbrs among ghost atoms
for
(
itr_j
=
0
;
itr_j
<
numneigh
[
i
];
++
itr_j
){
j
=
jlist
[
itr_j
];
if
(
j
>=
nlocal
&&
!
marked
[
j
]
&&
dist
[
j
]
<=
(
control
->
vlist_cut
-
control
->
bond_cut
)
){
marked
[
j
]
=
1
;
Set_Start_Index
(
j
,
num_nbrs
,
far_nbrs
);
for
(
itr_g
=
0
;
itr_g
<
numneigh
[
i
];
++
itr_g
){
g
=
jlist
[
itr_g
];
if
(
g
>=
nlocal
&&
!
marked
[
g
]
){
get_distance
(
x
[
g
],
x
[
j
],
&
g_d_sqr
,
&
g_dvec
);
if
(
g_d_sqr
<=
SQR
(
control
->
bond_cut
)
){
g_d
=
sqrt
(
g_d_sqr
);
set_far_nbr
(
&
far_list
[
num_nbrs
],
g
,
g_d
,
g_dvec
);
++
num_nbrs
;
}
}
}
Set_End_Index
(
j
,
num_nbrs
,
far_nbrs
);
}
}
}
for
(
i
=
0
;
i
<
system
->
N
;
++
i
)
if
(
!
marked
[
i
]
)
{
marked
[
i
]
=
1
;
Set_Start_Index
(
i
,
num_nbrs
,
far_nbrs
);
for
(
j
=
i
+
1
;
j
<
system
->
N
;
++
j
)
if
(
!
marked
[
j
]
)
{
get_distance
(
x
[
j
],
x
[
i
],
&
d_sqr
,
&
dvec
);
if
(
d_sqr
<=
SQR
(
control
->
bond_cut
)
)
{
set_far_nbr
(
&
far_list
[
num_nbrs
],
j
,
sqrt
(
d_sqr
),
dvec
);
++
num_nbrs
;
}
}
Set_End_Index
(
i
,
num_nbrs
,
far_nbrs
);
}
free
(
marked
);
free
(
dist
);
return
num_nbrs
;
}
/* ---------------------------------------------------------------------- */
void
PairReaxC
::
read_reax_forces
()
{
for
(
int
i
=
0
;
i
<
system
->
N
;
++
i
)
{
system
->
my_atoms
[
i
].
f
[
0
]
=
workspace
->
f
[
i
][
0
];
system
->
my_atoms
[
i
].
f
[
1
]
=
workspace
->
f
[
i
][
1
];
system
->
my_atoms
[
i
].
f
[
2
]
=
workspace
->
f
[
i
][
2
];
atom
->
f
[
i
][
0
]
=
-
workspace
->
f
[
i
][
0
];
atom
->
f
[
i
][
1
]
=
-
workspace
->
f
[
i
][
1
];
atom
->
f
[
i
][
2
]
=
-
workspace
->
f
[
i
][
2
];
}
}
/* ---------------------------------------------------------------------- */
void
*
PairReaxC
::
extract
(
char
*
str
,
int
&
dim
)
{
dim
=
1
;
if
(
strcmp
(
str
,
"chi"
)
==
0
&&
chi
)
{
for
(
int
i
=
1
;
i
<=
atom
->
ntypes
;
i
++
)
if
(
map
[
i
]
>=
0
)
chi
[
i
]
=
system
->
reax_param
.
sbp
[
map
[
i
]].
chi
;
else
chi
[
i
]
=
0.0
;
return
(
void
*
)
chi
;
}
if
(
strcmp
(
str
,
"eta"
)
==
0
&&
eta
)
{
for
(
int
i
=
1
;
i
<=
atom
->
ntypes
;
i
++
)
if
(
map
[
i
]
>=
0
)
eta
[
i
]
=
system
->
reax_param
.
sbp
[
map
[
i
]].
eta
;
else
eta
[
i
]
=
0.0
;
return
(
void
*
)
eta
;
}
if
(
strcmp
(
str
,
"gamma"
)
==
0
&&
gamma
)
{
for
(
int
i
=
1
;
i
<=
atom
->
ntypes
;
i
++
)
if
(
map
[
i
]
>=
0
)
gamma
[
i
]
=
system
->
reax_param
.
sbp
[
map
[
i
]].
gamma
;
else
gamma
[
i
]
=
0.0
;
return
(
void
*
)
gamma
;
}
return
NULL
;
}
Event Timeline
Log In to Comment