Multiple changed mostly focusing on active particle search
* Added optional active particle search via GRAPite. * Fixed ETICS_DTSCF in the Makefile. * Disabled ETICS_CEP by default. * Renamed and improved the initialization Python script
This commit is contained in:
parent
8ae1f0991d
commit
953a8286eb
4 changed files with 136 additions and 78 deletions
4
Makefile
4
Makefile
|
|
@ -2,7 +2,7 @@ CUDAHOME ?= /usr/local/cuda
|
|||
CPPFLAGS += -DYEBISU -DETICS
|
||||
OPTIMIZATION ?= 3
|
||||
|
||||
DTSCF ?= 0.015625
|
||||
ETICS_DTSCF ?= 0.015625
|
||||
|
||||
CUDAINC = -I$(CUDAHOME)/include -I$(CUDAHOME)/samples/common/inc/
|
||||
CUDALIB = -L$(CUDAHOME)/lib64 -lcudart -lcudadevrt
|
||||
|
|
@ -21,7 +21,7 @@ MPICC ?= mpicc
|
|||
EXECUTABLE ?= phi-GRAPE.exe
|
||||
|
||||
default:
|
||||
$(MPICC) $(CPPFLAGS) $(CFLAGS) $(INC) -DDTSCF=$(DTSCF) phi-GRAPE.c -o $(EXECUTABLE) $(LIB)
|
||||
$(MPICC) $(CPPFLAGS) $(CFLAGS) -DETICS_DTSCF=$(ETICS_DTSCF) $(INC) phi-GRAPE.c -o $(EXECUTABLE) $(LIB)
|
||||
|
||||
yebisu: CPPFLAGS := $(filter-out -DETICS, $(CPPFLAGS))
|
||||
yebisu: default
|
||||
|
|
|
|||
74
gen-init.py
74
gen-init.py
|
|
@ -1,74 +0,0 @@
|
|||
import numpy as np
|
||||
import argparse
|
||||
|
||||
def gen_plum(N, seed=None, RMAX=10):
|
||||
if not seed is None: np.random.seed(seed)
|
||||
particle_list = np.zeros((N,6))
|
||||
i = 0
|
||||
while (i < N):
|
||||
X1, X2, X3 = np.random.random(3)
|
||||
R = 1/np.sqrt(X1**(-2/3) - 1)
|
||||
if (R > RMAX): continue
|
||||
Z = (1 - 2*X2)*R
|
||||
X = np.sqrt(R**2 - Z**2) * np.cos(2*np.pi*X3)
|
||||
Y = np.sqrt(R**2 - Z**2) * np.sin(2*np.pi*X3)
|
||||
|
||||
Ve = np.sqrt(2)*(1.0 + R**2)**(-0.25);
|
||||
|
||||
X4, X5 = 0, 0
|
||||
while 0.1*X5 >= X4**2*(1-X4**2)**3.5:
|
||||
X4, X5 = np.random.random(2)
|
||||
|
||||
V = Ve*X4
|
||||
X6, X7 = np.random.random(2)
|
||||
|
||||
Vz = (1 - 2*X6)*V;
|
||||
Vx = np.sqrt(V**2 - Vz**2) * np.cos(2*np.pi*X7);
|
||||
Vy = np.sqrt(V**2 - Vz**2) * np.sin(2*np.pi*X7);
|
||||
|
||||
X, Y, Z = np.array([X, Y, Z])*3*np.pi/16
|
||||
Vx, Vy, Vz = np.array([Vx, Vy, Vz])/np.sqrt(3*np.pi/16)
|
||||
|
||||
particle_list[i,:] = [X, Y, Z, Vx, Vy, Vz]
|
||||
i += 1
|
||||
return particle_list
|
||||
|
||||
parser = argparse.ArgumentParser(description='Process some integers.')
|
||||
parser.add_argument('N', type=str, help='The number of particles (follow by k to multiply by 1024)')
|
||||
parser.add_argument('--seed', type=int, default=42, help='Random seed')
|
||||
parser.add_argument('--eps', type=np.double, default=1E-4, help='Plummer softening parameter (can be even 0)')
|
||||
parser.add_argument('--t_end', type=np.double, default=4, help='end time of calculation')
|
||||
parser.add_argument('--dt_disk', type=np.double, default=1, help='interval of snapshot files output (0xxx.dat)')
|
||||
parser.add_argument('--dt_contr', type=np.double, default=.125, help='interval for the energy control output (contr.dat)')
|
||||
parser.add_argument('--dt_bh', type=np.double, default=.125, help='interval for BH output (bh.dat & bh_nb.dat)')
|
||||
parser.add_argument('--eta', type=np.double, default=.01, help='parameter for timestep determination (0.02 or 0.01)')
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
N = int(args.N)
|
||||
except ValueError:
|
||||
if args.N[-1]=='k': N = int(args.N[:-1])*1024
|
||||
else: raise ValueError('Unable to parse N.')
|
||||
|
||||
f = open('phi-GRAPE.cfg', 'w')
|
||||
f.write('%.4E %.4E %.4E %.4E %.4E %.4E data.con\n' % (args.eps, args.t_end, args.dt_disk, args.dt_contr, args.dt_bh, args.eta))
|
||||
f.close()
|
||||
|
||||
|
||||
particle_list = gen_plum(N)
|
||||
m = np.empty(N)
|
||||
m[:] = 1/N
|
||||
|
||||
f = open('data.con', 'w')
|
||||
f.write('000000\n')
|
||||
f.write('%d\n' % N)
|
||||
f.write('0.0000000000E+00\n')
|
||||
for i in range(N):
|
||||
f.write('%06d%14.6e%14.6e%14.6e%14.6e%14.6e%14.6e%14.6e\n' % (i, m[i], particle_list[i,0], particle_list[i,1], particle_list[i,2], particle_list[i,3], particle_list[i,4], particle_list[i,5]))
|
||||
f.close()
|
||||
|
||||
f = open('grapite.mask', 'w')
|
||||
for i in range(N):
|
||||
f.write('%06d %d\n' % (i, 0))
|
||||
f.close()
|
||||
105
init.py
Normal file
105
init.py
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
import numpy as np
|
||||
import argparse
|
||||
|
||||
def gen_plum(N, seed=None, RMAX=10):
|
||||
if not seed is None: np.random.seed(seed)
|
||||
particle_list = np.zeros((N,6))
|
||||
i = 0
|
||||
while (i < N):
|
||||
X1, X2, X3 = np.random.random(3)
|
||||
R = 1/np.sqrt(X1**(-2/3) - 1)
|
||||
if (R > RMAX): continue
|
||||
Z = (1 - 2*X2)*R
|
||||
X = np.sqrt(R**2 - Z**2) * np.cos(2*np.pi*X3)
|
||||
Y = np.sqrt(R**2 - Z**2) * np.sin(2*np.pi*X3)
|
||||
|
||||
Ve = np.sqrt(2)*(1.0 + R**2)**(-0.25);
|
||||
|
||||
X4, X5 = 0, 0
|
||||
while 0.1*X5 >= X4**2*(1-X4**2)**3.5:
|
||||
X4, X5 = np.random.random(2)
|
||||
|
||||
V = Ve*X4
|
||||
X6, X7 = np.random.random(2)
|
||||
|
||||
Vz = (1 - 2*X6)*V;
|
||||
Vx = np.sqrt(V**2 - Vz**2) * np.cos(2*np.pi*X7);
|
||||
Vy = np.sqrt(V**2 - Vz**2) * np.sin(2*np.pi*X7);
|
||||
|
||||
X, Y, Z = np.array([X, Y, Z])*3*np.pi/16
|
||||
Vx, Vy, Vz = np.array([Vx, Vy, Vz])/np.sqrt(3*np.pi/16)
|
||||
|
||||
particle_list[i,:] = [X, Y, Z, Vx, Vy, Vz]
|
||||
i += 1
|
||||
return particle_list
|
||||
|
||||
def write_phi_grape_config(**kargs):
|
||||
if 'file_name' in kargs: file_name = kargs['file_name']
|
||||
else: file_name = 'phi-GRAPE.cfg'
|
||||
f = open(file_name, 'w')
|
||||
f.write('%.4E %.4E %.4E %.4E %.4E %.4E data.con\n' % (kargs['eps'], kargs['t_end'], kargs['dt_disk'], kargs['dt_contr'], kargs['dt_bh'], kargs['eta']))
|
||||
f.close()
|
||||
|
||||
def write_particles(particle_list, m=None, file_name='data.con'):
|
||||
N = particle_list.shape[0]
|
||||
if m is None:
|
||||
m = np.empty(N)
|
||||
m[:] = 1/N
|
||||
f = open(file_name, 'w')
|
||||
f.write('000000\n')
|
||||
f.write('%d\n' % N)
|
||||
f.write('0.0000000000E+00\n')
|
||||
for i in range(N):
|
||||
f.write('%06d%14.6e%14.6e%14.6e%14.6e%14.6e%14.6e%14.6e\n' % (i, m[i], particle_list[i,0], particle_list[i,1], particle_list[i,2], particle_list[i,3], particle_list[i,4], particle_list[i,5]))
|
||||
f.close()
|
||||
|
||||
def gen_mask(particle_list, frac):
|
||||
N = particle_list.shape[0]
|
||||
if frac==0:
|
||||
mask = np.ones(N, dtype=int)
|
||||
elif frac==1:
|
||||
mask = np.zeros(N, dtype=int)
|
||||
else:
|
||||
X = particle_list[:,:3]
|
||||
V = particle_list[:,3:]
|
||||
L = np.linalg.norm(np.cross(X, V), axis=1)
|
||||
L_sorted = L.copy()
|
||||
L_sorted.sort()
|
||||
L_cutoff = L_sorted[int(N*frac)]
|
||||
mask = np.array(L > L_cutoff, dtype=int)
|
||||
return mask
|
||||
|
||||
def write_mask(mask, file_name='grapite.mask'):
|
||||
f = open(file_name, 'w')
|
||||
for i in range(len(mask)):
|
||||
f.write('%06d %d\n' % (i, mask[i]))
|
||||
f.close()
|
||||
|
||||
if __name__=='__main__':
|
||||
parser = argparse.ArgumentParser(description='Process some integers.')
|
||||
parser.add_argument('N', type=str, help='number of particles (follow by k to multiply by 1024)')
|
||||
parser.add_argument('--seed', type=int, default=42, help='random seed')
|
||||
parser.add_argument('--eps', type=np.double, default=1E-4, help='Plummer softening parameter (can be even 0)')
|
||||
parser.add_argument('--t_end', type=np.double, default=4, help='end time of calculation')
|
||||
parser.add_argument('--dt_disk', type=np.double, default=1, help='interval of snapshot files output (0xxx.dat)')
|
||||
parser.add_argument('--dt_contr', type=np.double, default=.125, help='interval for the energy control output (contr.dat)')
|
||||
parser.add_argument('--dt_bh', type=np.double, default=.125, help='interval for BH output (bh.dat & bh_nb.dat)')
|
||||
parser.add_argument('--eta', type=np.double, default=.01, help='parameter for timestep determination (0.02 or 0.01)')
|
||||
parser.add_argument('--frac', type=np.double, default=0, help='fraction of collisional particles (by angular momentum)')
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
N = int(args.N)
|
||||
except ValueError:
|
||||
if args.N[-1]=='k': N = int(args.N[:-1])*1024
|
||||
else: raise ValueError('Unable to parse N.')
|
||||
|
||||
write_phi_grape_config(**vars(args))
|
||||
|
||||
particle_list = gen_plum(N, seed=args.seed)
|
||||
|
||||
write_particles(particle_list)
|
||||
|
||||
mask = gen_mask(particle_list, args.frac)
|
||||
|
||||
write_mask(mask)
|
||||
31
phi-GRAPE.c
31
phi-GRAPE.c
|
|
@ -134,8 +134,10 @@
|
|||
#ifdef ETICS
|
||||
#include "grapite.h"
|
||||
// why do we need CEP as a compilaion flag... just have it always on when ETICS is on. IF there is no CEP, there should be a graceful skipping of those operations.
|
||||
#define ETICS_CEP
|
||||
#define ETICS_DTSCF 0.125
|
||||
//#define ETICS_CEP
|
||||
#ifndef ETICS_DTSCF
|
||||
#error "ETICS_DTSCF must be defined"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define TIMING
|
||||
|
|
@ -163,6 +165,10 @@
|
|||
|
||||
// #define ACT_DEF_LL
|
||||
|
||||
#if defined(ACT_DEF_LL) && defined(ACT_DEF_GRAPITE)
|
||||
#error "Contradicting preprocessor flags!"
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -5630,6 +5636,9 @@ for(i=0; i<N; i++)
|
|||
// j_loc_beg = myRank*n_loc;
|
||||
// j_loc_end = (myRank+1)*n_loc;
|
||||
|
||||
#ifdef ACT_DEF_GRAPITE
|
||||
min_t_loc = grapite_get_minimum_time();
|
||||
#else
|
||||
min_t_loc = t[0]+dt[0];
|
||||
|
||||
for(j=0; j<n_loc; j++)
|
||||
|
|
@ -5638,6 +5647,7 @@ for(i=0; i<N; i++)
|
|||
tmp = t[jjj] + dt[jjj];
|
||||
if( tmp < min_t_loc ) min_t_loc = tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Wait to all processors to finish his works... */
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
|
|
@ -5659,6 +5669,22 @@ for(i=0; i<N; i++)
|
|||
get_CPU_time(&CPU_tmp_real0, &CPU_tmp_user0, &CPU_tmp_syst0);
|
||||
#endif
|
||||
|
||||
#ifdef ACT_DEF_GRAPITE
|
||||
int ind_act_loc[N_MAX], n_act_loc;
|
||||
grapite_active_search(min_t, ind_act_loc, &n_act_loc);
|
||||
if (myRank > 0)
|
||||
for(int i=0; i<n_act_loc; i++)
|
||||
ind_act_loc[i] += myRank*n_loc;
|
||||
int n_act_arr[256], displs[256]; // Assuming maximum of 256 processes... seems safe.
|
||||
MPI_Allgather(&n_act_loc, 1, MPI_INT, n_act_arr, 1, MPI_INT, MPI_COMM_WORLD);
|
||||
n_act = n_act_arr[0];
|
||||
for (int i=1; i<n_proc; i++)
|
||||
n_act += n_act_arr[i];
|
||||
displs[0] = 0;
|
||||
for (int i=1; i<n_proc; i++)
|
||||
displs[i]=displs[i-1]+n_act_arr[i-1];
|
||||
MPI_Allgatherv(ind_act_loc, n_act_loc, MPI_INT, ind_act, n_act_arr, displs, MPI_INT, MPI_COMM_WORLD);
|
||||
#else
|
||||
n_act = 0;
|
||||
|
||||
//#pragma omp parallel for
|
||||
|
|
@ -5673,6 +5699,7 @@ for(i=0; i<N; i++)
|
|||
}
|
||||
// }
|
||||
} /* i */
|
||||
#endif // ACT_DEF_GRAPITE
|
||||
|
||||
#ifdef TIMING
|
||||
get_CPU_time(&CPU_tmp_real, &CPU_tmp_user, &CPU_tmp_syst);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue