diff --git a/PyGear/examples.tessel/Readme b/PyGear/examples.tessel/Readme new file mode 100644 index 0000000..7ed6e6d --- /dev/null +++ b/PyGear/examples.tessel/Readme @@ -0,0 +1,12 @@ + +./test_mpi.py + + +./plot_triangles.py triangles.dat +./plot_voronoi.py voronoi.dat + + + + +# +test_evol.py diff --git a/PyGear/examples.tessel/TODO b/PyGear/examples.tessel/TODO index 6c44987..f8956c8 100644 --- a/PyGear/examples.tessel/TODO +++ b/PyGear/examples.tessel/TODO @@ -1,34 +1,98 @@ + + +- dump triangles + +[ {"id":idx, "coord", [[x,y,z],[x,y,z],[x,y,z]] } ] + + +3x +n*(3*3) + + + + + + +######################################## +# + + +######################## +# draw the Voronoi + + +for i in xrange(nbtot.nbody): + vpos = gadget.GetvPointsForOnePoint(i) + #pt.scatter(nb.pos[i,0],nb.pos[i,1],lw=0,s=50) + + plot.draw_cell(vpos,color=[rho[i],rho[i],rho[i]],alpha=0.8) + + + +######################## +# draw the triangles + +TriangleList = gadget.GetAllDelaunayTriangles() + +i = 0 +for Triangle in TriangleList: + P1 = Triangle['coord'][0] + P2 = Triangle['coord'][1] + P3 = Triangle['coord'][2] + plot.draw_triangle(P1,P2,P3,c='r') + + #cm = 1/3.*(P1+P2+P3) + #pt.text(cm[0],cm[1],Triangle['id'],fontsize=12,horizontalalignment='center',verticalalignment='center') + + + + + + + + + + + + + + + + + + + # EnergyInt EnergyPot EnergyKin - pas de baisse de pression... - viscosit� artificielle (Hess) python test_evol.py - snapshot des cellules - graphs des cellules -> film - conservation d'�nergie - rapatrier EnergyInt (Entropy) -> initializer correctement Entropy - - pas de temps -> vsig si on construit 2x delaunay, �a plante.... -- parallelisme diff --git a/PyGear/examples.tessel/plot_triangles.py b/PyGear/examples.tessel/plot_triangles.py new file mode 100755 index 0000000..2927b94 --- /dev/null +++ b/PyGear/examples.tessel/plot_triangles.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python + + +from numpy import * +from pNbody import io +import sys + + +file = sys.argv[1] + + + +def read_triangles(filename): + + + f = open(file,'r') + + header = io.ReadBlock(f,(int32)) + n = header[0] + + triangles = io.ReadDataBlock(f,float,shape=(n,3,3)) + num = io.ReadDataBlock(f,int32,shape=(n,)) + + return triangles,num + + + +triangles,num = read_triangles(file) + + +###################################################################### +# +# PLOT +# +###################################################################### +#sys.exit() + +import Ptools as pt +import plot + + +######################## +# draw a box +plot.draw_box(x=array([0,1,1,0]),y=array([0,0,1,1])) + +######################## +# draw the triangles + + +for Triangle in triangles: + P1 = Triangle[0] + P2 = Triangle[1] + P3 = Triangle[2] + plot.draw_triangle(P1,P2,P3,c='r') + + + + + + + + +pt.axis([-0.1,1.1,-0.1,1.1]) +pt.show() + diff --git a/PyGear/examples.tessel/plot_voronoi.py b/PyGear/examples.tessel/plot_voronoi.py new file mode 100755 index 0000000..6ecf3f7 --- /dev/null +++ b/PyGear/examples.tessel/plot_voronoi.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python + + +from numpy import * +from pNbody import io +import sys + + +file = sys.argv[1] + + + +def read_voronoi(filename): + + + f = open(file,'r') + + header = io.ReadBlock(f,(int32)) + n = header[0] + + cells = n*[""] + + for i in xrange(n): + + header = io.ReadBlock(f,(int32)) + np = header[0] + + points = io.ReadDataBlock(f,float,shape=(np,3)) + + cells[i]=points + + + return cells + + + +cells = read_voronoi(file) + + + +###################################################################### +# +# PLOT +# +###################################################################### +#sys.exit() + +import Ptools as pt +import plot + + +######################## +# draw a box +plot.draw_box(x=array([0,1,1,0]),y=array([0,0,1,1])) + + + +for vpos in cells: + plot.draw_cell(vpos,alpha=0.8) + + + + +pt.axis([-0.1,1.1,-0.1,1.1]) +pt.show() + diff --git a/PyGear/examples.tessel/test_evol.py b/PyGear/examples.tessel/test_evol.py index 2c8443d..6018417 100755 --- a/PyGear/examples.tessel/test_evol.py +++ b/PyGear/examples.tessel/test_evol.py @@ -1,335 +1,339 @@ #!/usr/bin/env python from pNbody import * from pNbody import ic from pNbody import libutil from numpy import * import sys import time import copy from PyGear import gadget def SaveFile(gadget,i): nb.pos = gadget.GetAllPositions() nb.vel = gadget.GetAllVelocities() nb.mass = gadget.GetAllMasses() nb.num = gadget.GetAllID() nb.tpe = None #nb.u = gadget.GetAllEnergySpec() # not defined nb.rho = gadget.GetAllvDensities() # note the v nb.rsp = gadget.GetAllvVolumes() nb.u = gadget.GetAllvEnergySpec() nb.init() # save nb.rename('snap/snap%05d.dat'%i) nb.set_pio("yes") nb.write() def SaveEnergy(gadget,time): nb.pos = gadget.GetAllPositions() nb.vel = gadget.GetAllVelocities() nb.mass = gadget.GetAllMasses() nb.num = gadget.GetAllID() nb.tpe = None #nb.u = gadget.GetAllEnergySpec() # not defined nb.rho = gadget.GetAllvDensities() # note the v nb.rsp = gadget.GetAllvVolumes() nb.u = gadget.GetAllvEnergySpec() nb.init() Ekin = nb.Ekin() Eint = sum(nb.u) Epot = 0 efile = 'snap/energy.txt' if os.path.isfile(efile): f = open(efile,'a') else: f = open(efile,'w') f.write("# Time EnergyInt EnergyPot EnergyKin \n") f.write( "%g %g %g %g\n"%(time,Eint,Epot,Ekin) ) f.close() nb = Nbody("snap.dat",ftype="gadget") ################################### # init PyGear gadget.InitMPI() # init MPI gadget.InitDefaultParameters() # init default parameters gadget.Info() params = {} params['ErrTolTheta'] = 0.7 params['DesNumNgb'] = 15 params['MaxNumNgbDeviation'] = 3 params['UnitLength_in_cm'] = 3.085e+21 params['UnitMass_in_g'] = 4.435693e+44 params['UnitVelocity_in_cm_per_s'] = 97824708.2699 params['BoxSize'] = 1.0 params['PartAllocFactor'] = 10 gadget.SetParameters(params) ################################### # load particles gadget.LoadParticles(array(nb.npart),nb.pos,nb.vel,nb.mass,nb.num,nb.tpe,nb.u) ################################### # compute Delaunay t1 = time.time() gadget.ConstructDelaunay() t2 = time.time() print "Delaunay","in",(t2-t1),"s" ################################### # compute Voronoi t1 = time.time() gadget.ComputeVoronoi() t2 = time.time() print "Voronoi","in",(t2-t1),"s" ################################### # now, we have vDensity, we can compute # the entropy gadget.InitvEntropy() ################################### # retrieve ghost points gpos = gadget.GetAllGhostPositions() gnb = Nbody(pos=gpos,ftype='gadget') gnb.u = zeros(gnb.nbody) gnb.rho = gadget.GetAllGhostvDensities() gnb.rsp = gadget.GetAllGhostvVolumes() gnb.init() # save gnb.rename('ghost.dat') gnb.set_pio("yes") gnb.write() ################################### # retrieve points nb.pos = gadget.GetAllPositions() nb.vel = gadget.GetAllVelocities() nb.mass = gadget.GetAllMasses() nb.num = gadget.GetAllID() nb.tpe = None #nb.u = gadget.GetAllEnergySpec() # not defined nb.rho = gadget.GetAllvDensities() # note the v nb.rsp = gadget.GetAllvVolumes() # note the v nb.u = gadget.GetAllvEnergySpec() # not the v nb.init() # save nb.rename('snap2.dat') nb.set_pio("yes") nb.write() ################################### # first accel gadget.ComputeTesselAccelerations() acc = gadget.GetAllvAccelerations() acc = sqrt(acc[:,0]**2+acc[:,1]**2+acc[:,2]**2) dt = gadget.tessel_get_timestep() # first half drift step gadget.tessel_drift(dt/2) ################################################### # # now loop # ################################################### for step in xrange(10000): print "" print "###########################" print "Step %d dt=%g"%(step,dt ) print "" gadget.domain_Decomposition() gadget.gravity_tree() ################################### # compute Delaunay t1 = time.time() gadget.ConstructDelaunay() t2 = time.time() print "Delaunay","in",(t2-t1),"s" ################################### # compute Voronoi t1 = time.time() gadget.ComputeVoronoi() t2 = time.time() print "Voronoi","in",(t2-t1),"s" ################################### # compute acceleration gadget.ComputeTesselAccelerations() acc = gadget.GetAllvAccelerations() acc = sqrt(acc[:,0]**2+acc[:,1]**2+acc[:,2]**2) # leap frog gadget.tessel_kick(dt/2) # the syst. is inchronized here # new timestep dt = gadget.tessel_get_timestep() gadget.tessel_kick(dt/2) gadget.tessel_drift(dt) # save output if fmod(step,10)==0: SaveFile(gadget,step) # save energy SaveEnergy(gadget,step) - + + + gadget.tessel_dump_triangles('snap/triangles%04d.dat'%step) + gadget.tessel_dump_voronoi('snap/voronoi%04d.dat'%step) + ###################################################################### # PLOT # ###################################################################### # save all #nbtot = nb + gnb nbtot = copy.deepcopy(nb) # this is important to avoid to mix particles nbtot.append(gnb,do_not_sort=True) # then they are incompatible with vpos below nbtot.rename('snap+ghost.dat') nbtot.write() ################################### # get some values TriangleList = gadget.GetAllDelaunayTriangles() rho,mn,mx,cd = libutil.set_ranges(nbtot.rho,scale='log') rho = rho/255. #rho = clip(nbtot.rho,0,1) import Ptools as pt import plot ######################## # draw a box plot.draw_box(x=array([0,1,1,0]),y=array([0,0,1,1])) ######################## # draw the Voronoi cmap = pt.GetColormap('rainbow4',revesed=False) # single point with vpoints for i in xrange(nbtot.nbody): vpos = gadget.GetvPointsForOnePoint(i) #pt.scatter(nb.pos[i,0],nb.pos[i,1],lw=0,s=50) plot.draw_cell(vpos,color=[rho[i],rho[i],rho[i]],alpha=0.8) pt.axis([-0.1,1.1,-0.1,1.1]) pt.show() diff --git a/PyGear/examples.tessel/test_mpi.py b/PyGear/examples.tessel/test_mpi.py index a36ef68..6b0afe7 100755 --- a/PyGear/examples.tessel/test_mpi.py +++ b/PyGear/examples.tessel/test_mpi.py @@ -1,191 +1,194 @@ #!/usr/bin/env python from pNbody import * from pNbody import ic from pNbody import libutil from numpy import * import sys import time import copy from PyGear import gadget nb = Nbody("snap.dat",ftype="gadget") ################################### # init PyGear gadget.InitMPI() # init MPI gadget.InitDefaultParameters() # init default parameters gadget.Info() params = {} params['ErrTolTheta'] = 0.7 params['DesNumNgb'] = 15 params['MaxNumNgbDeviation'] = 3 params['UnitLength_in_cm'] = 3.085e+21 params['UnitMass_in_g'] = 4.435693e+44 params['UnitVelocity_in_cm_per_s'] = 97824708.2699 params['BoxSize'] = 1.0 params['PartAllocFactor'] = 10 gadget.SetParameters(params) ################################### # load particles gadget.LoadParticles(array(nb.npart),nb.pos,nb.vel,nb.mass,nb.num,nb.tpe) ################################### # compute Delaunay t1 = time.time() gadget.ConstructDelaunay() t2 = time.time() print "Delaunay","in",(t2-t1),"s" ################################### # compute Voronoi t1 = time.time() gadget.ComputeVoronoi() t2 = time.time() print "Voronoi","in",(t2-t1),"s" #sys.exit() ################################### # retrieve ghost points gpos = gadget.GetAllGhostPositions() gnb = Nbody(pos=gpos,ftype='gadget') gnb.u = zeros(gnb.nbody) gnb.rho = gadget.GetAllGhostvDensities() gnb.rsp = gadget.GetAllGhostvVolumes() gnb.init() # save gnb.rename('ghost.dat') gnb.set_pio("yes") gnb.write() ################################### # retrieve points nb.pos = gadget.GetAllPositions() nb.vel = gadget.GetAllVelocities() nb.mass = gadget.GetAllMasses() nb.num = gadget.GetAllID() nb.tpe = None nb.u = gadget.GetAllEnergySpec() # not defined nb.rho = gadget.GetAllvDensities() # note the v nb.rsp = gadget.GetAllvVolumes() nb.rsp = gadget.GetAllDensities() # put sph densities in rsp nb.init() # save nb.rename('snap2.dat') nb.set_pio("yes") nb.write() # save all #nbtot = nb + gnb nbtot = copy.deepcopy(nb) # this is important to avoid to mix particles nbtot.append(gnb,do_not_sort=True) # then they are incompatible with vpos below nbtot.rename('snap+ghost.dat') nbtot.write() ################################### # get some values TriangleList = gadget.GetAllDelaunayTriangles() rho,mn,mx,cd = libutil.set_ranges(nbtot.rho,scale='log') rho = rho/255. #rho = clip(nbtot.rho,0,1) +gadget.tessel_dump_triangles('triangles.dat') +gadget.tessel_dump_voronoi('voronoi.dat') + ###################################################################### # # PLOT # ###################################################################### #sys.exit() import Ptools as pt import plot ######################## # draw a box plot.draw_box(x=array([0,1,1,0]),y=array([0,0,1,1])) ######################## # draw the triangles ''' i = 0 for Triangle in TriangleList: P1 = Triangle['coord'][0] P2 = Triangle['coord'][1] P3 = Triangle['coord'][2] plot.draw_triangle(P1,P2,P3,c='r') #cm = 1/3.*(P1+P2+P3) #pt.text(cm[0],cm[1],Triangle['id'],fontsize=12,horizontalalignment='center',verticalalignment='center') ''' ######################## # draw the points #pt.scatter( nb.pos[:,0], nb.pos[:,1],lw=0,s=50,color='r') #pt.scatter(gnb.pos[:,0],gnb.pos[:,1],lw=0,s=50) ######################## # draw the Voronoi cmap = pt.GetColormap('rainbow4',revesed=False) # single point with vpoints for i in xrange(nbtot.nbody): vpos = gadget.GetvPointsForOnePoint(i) #pt.scatter(nb.pos[i,0],nb.pos[i,1],lw=0,s=50) plot.draw_cell(vpos,color=[rho[i],rho[i],rho[i]],alpha=0.8) pt.axis([-0.1,1.1,-0.1,1.1]) pt.show() diff --git a/src/proto.h b/src/proto.h index cc1f65f..055b5a0 100644 --- a/src/proto.h +++ b/src/proto.h @@ -1,527 +1,532 @@ /*! \file proto.h * \brief this file contains all function prototypes of the code */ #ifndef ALLVARS_H #include "allvars.h" #endif #ifdef HAVE_HDF5 #include <hdf5.h> #endif void advance_and_find_timesteps(void); void allocate_commbuffers(void); void allocate_memory(void); void begrun(void); int blockpresent(enum iofields blocknr); #ifdef BLOCK_SKIPPING int blockabsent(enum iofields blocknr); #endif void catch_abort(int sig); void catch_fatal(int sig); void check_omega(void); void close_outputfiles(void); int compare_key(const void *a, const void *b); void compute_accelerations(int mode); void compute_global_quantities_of_system(void); void compute_potential(void); int dens_compare_key(const void *a, const void *b); void density(int mode); void density_decouple(void); void density_evaluate(int i, int mode); #ifdef CHIMIE int stars_dens_compare_key(const void *a, const void *b); void stars_density(void); void stars_density_evaluate(int i, int mode); #endif void distribute_file(int nfiles, int firstfile, int firsttask, int lasttask, int *filenr, int *master, int *last); double dmax(double, double); double dmin(double, double); void do_box_wrapping(void); void domain_Decomposition(void); int domain_compare_key(const void *a, const void *b); int domain_compare_key(const void *a, const void *b); int domain_compare_toplist(const void *a, const void *b); void domain_countToGo(void); void domain_decompose(void); void domain_determineTopTree(void); void domain_exchangeParticles(int partner, int sphflag, int send_count, int recv_count); void domain_findExchangeNumbers(int task, int partner, int sphflag, int *send, int *recv); void domain_findExtent(void); int domain_findSplit(int cpustart, int ncpu, int first, int last); int domain_findSplityr(int cpustart, int ncpu, int first, int last); void domain_shiftSplit(void); void domain_shiftSplityr(void); void domain_sumCost(void); void domain_topsplit(int node, peanokey startkey); void domain_topsplit_local(int node, peanokey startkey); double drift_integ(double a, void *param); void dump_particles(void); void empty_read_buffer(enum iofields blocknr, int offset, int pc, int type); void endrun(int); void energy_statistics(void); #ifdef ADVANCEDSTATISTICS void advanced_energy_statistics(void); #endif void every_timestep_stuff(void); void ewald_corr(double dx, double dy, double dz, double *fper); void ewald_force(int ii, int jj, int kk, double x[3], double force[3]); void ewald_init(void); double ewald_pot_corr(double dx, double dy, double dz); double ewald_psi(double x[3]); void fill_Tab_IO_Labels(void); void fill_write_buffer(enum iofields blocknr, int *pindex, int pc, int type); void find_dt_displacement_constraint(double hfac); int find_files(char *fname); int find_next_outputtime(int time); void find_next_sync_point_and_drift(void); void force_create_empty_nodes(int no, int topnode, int bits, int x, int y, int z, int *nodecount, int *nextfree); void force_exchange_pseudodata(void); void force_flag_localnodes(void); void force_insert_pseudo_particles(void); void force_setupnonrecursive(int no); void force_treeallocate(int maxnodes, int maxpart); int force_treebuild(int npart); int force_treebuild_single(int npart); int force_treeevaluate(int target, int mode, double *ewaldcountsum); int force_treeevaluate_direct(int target, int mode); int force_treeevaluate_ewald_correction(int target, int mode, double pos_x, double pos_y, double pos_z, double aold); void force_treeevaluate_potential(int target, int type); void force_treeevaluate_potential_shortrange(int target, int mode); int force_treeevaluate_shortrange(int target, int mode); void force_treefree(void); void force_treeupdate_pseudos(void); void force_update_hmax(void); void force_update_len(void); void force_update_node(int no, int flag); void force_update_node_hmax_local(void); void force_update_node_hmax_toptree(void); void force_update_node_len_local(void); void force_update_node_len_toptree(void); void force_update_node_recursive(int no, int sib, int father); void force_update_pseudoparticles(void); void force_update_size_of_parent_node(int no); void free_memory(void); int get_bytes_per_blockelement(enum iofields blocknr); void get_dataset_name(enum iofields blocknr, char *buf); int get_datatype_in_block(enum iofields blocknr); double get_drift_factor(int time0, int time1); double get_gravkick_factor(int time0, int time1); double get_hydrokick_factor(int time0, int time1); int get_particles_in_block(enum iofields blocknr, int *typelist); double get_random_number(int id); #ifdef SFR double get_StarFormation_random_number(int id); #endif #ifdef FEEDBACK_WIND double get_FeedbackWind_random_number(int id); #endif #ifdef CHIMIE double get_Chimie_random_number(int id); #endif #ifdef CHIMIE_KINETIC_FEEDBACK double get_ChimieKineticFeedback_random_number(int id); #endif int get_timestep(int p, double *a, int flag); int get_values_per_blockelement(enum iofields blocknr); int grav_tree_compare_key(const void *a, const void *b); void gravity_forcetest(void); void gravity_tree(void); void gravity_tree_shortrange(void); double gravkick_integ(double a, void *param); int hydro_compare_key(const void *a, const void *b); void hydro_evaluate(int target, int mode); void hydro_force(void); double hydrokick_integ(double a, void *param); int imax(int, int); int imin(int, int); void init(void); void init_drift_table(void); void init_peano_map(void); #ifdef COSMICTIME void init_cosmictime_table(void); double get_cosmictime_difference(int time0, int time1); #endif void long_range_force(void); void long_range_init(void); void long_range_init_regionsize(void); void move_particles(int time0, int time1); size_t my_fread(void *ptr, size_t size, size_t nmemb, FILE * stream); size_t my_fwrite(void *ptr, size_t size, size_t nmemb, FILE * stream); int ngb_clear_buf(FLOAT searchcenter[3], FLOAT hguess, int numngb); void ngb_treeallocate(int npart); void ngb_treebuild(void); int ngb_treefind_pairs(FLOAT searchcenter[3], FLOAT hsml, int phase, int *startnode); #ifdef MULTIPHASE int ngb_treefind_phase_pairs(FLOAT searchcenter[3], FLOAT hsml, int phase, int *startnode); int ngb_treefind_sticky_collisions(FLOAT searchcenter[3], FLOAT hguess, int phase, int *startnode); #endif int ngb_treefind_variable(FLOAT searchcenter[3], FLOAT hguess, int phase, int *startnode); #ifdef CHIMIE int ngb_treefind_variable_for_chimie(FLOAT searchcenter[3], FLOAT hguess, int *startnode); #endif void ngb_treefree(void); void ngb_treesearch(int); void ngb_treesearch_pairs(int); void ngb_update_nodes(void); void open_outputfiles(void); peanokey peano_hilbert_key(int x, int y, int z, int bits); void peano_hilbert_order(void); void pm_init_nonperiodic(void); void pm_init_nonperiodic_allocate(int dimprod); void pm_init_nonperiodic_free(void); void pm_init_periodic(void); void pm_init_periodic_allocate(int dimprod); void pm_init_periodic_free(void); void pm_init_regionsize(void); void pm_setup_nonperiodic_kernel(void); int pmforce_nonperiodic(int grnr); void pmforce_periodic(void); int pmpotential_nonperiodic(int grnr); void pmpotential_periodic(void); double pow(double, double); /* on some old DEC Alphas, the correct prototype for pow() is missing, even when math.h is included */ void read_file(char *fname, int readTask, int lastTask); void read_header_attributes_in_hdf5(char *fname); void read_ic(char *fname); int read_outputlist(char *fname); void read_parameter_file(char *fname); void readjust_timebase(double TimeMax_old, double TimeMax_new); void reorder_gas(void); void reorder_particles(void); #ifdef STELLAR_PROP void reorder_stars(void); void reorder_st(void); #endif void restart(int mod); void run(void); void savepositions(int num); double second(void); void seed_glass(void); void set_random_numbers(void); void set_softenings(void); void set_units(void); void init_local_sys_state(void); void setup_smoothinglengths(void); #ifdef CHIMIE void stars_setup_smoothinglengths(void); #endif void statistics(void); void terminate_processes(void); double timediff(double t0, double t1); #ifdef HAVE_HDF5 void write_header_attributes_in_hdf5(hid_t handle); #endif void write_file(char *fname, int readTask, int lastTask); void write_pid_file(void); #ifdef COOLING int init_cooling(FLOAT metallicity); int init_cooling_with_metals(); double cooling_function(double temperature); double cooling_function_with_metals(double temperature,double metal); void init_from_new_redshift(double Redshift); double J_0(); double J_nu(double e); double sigma_rad_HI(double e); double sigma_rad_HeI(double e); double sigma_rad_HeII(double e); double cooling_bremstrahlung_HI(double T); double cooling_bremstrahlung_HeI(double T); double cooling_bremstrahlung_HeII(double T); double cooling_ionization_HI(double T); double cooling_ionization_HeI(double T); double cooling_ionization_HeII(double T); double cooling_recombination_HI(double T); double cooling_recombination_HeI(double T); double cooling_recombination_HeII(double T); double cooling_dielectric_recombination(double T); double cooling_excitation_HI(double T); double cooling_excitation_HII(double T); double cooling_compton(double T); double A_HII(double T); double A_HeIId(double T); double A_HeII(double T); double A_HeIII(double T); double G_HI(double T); double G_HeI(double T); double G_HeII(double T); double G_gHI(); double G_gHeI(); double G_gHeII(); double G_gHI_t(double J0); double G_gHeI_t(double J0); double G_gHeII_t(double J0); double G_gHI_w(); double G_gHeI_w(); double G_gHeII_w(); double heating_radiative_HI(); double heating_radiative_HeI(); double heating_radiative_HeII(); double heating_radiative_HI_t(double J0); double heating_radiative_HeI_t(double J0); double heating_radiative_HeII_t(double J0); double heating_radiative_HI_w(); double heating_radiative_HeI_w(); double heating_radiative_HeII_w(); double heating_compton(); void print_cooling(double T,double c1,double c2,double c3,double c4,double c5,double c6,double c7,double c8,double c9,double c10,double c11,double c12,double c13,double h1, double h2, double h3, double h4); void compute_densities(double T,double X,double* n_H, double* n_HI,double* n_HII,double* n_HEI,double* n_HEII,double* n_HEIII,double* n_E,double* mu); void compute_cooling_from_T_and_Nh(double T,double X,double n_H,double *c1,double *c2,double *c3,double *c4,double *c5,double *c6,double *c7,double *c8,double *c9,double *c10,double *c11,double *c12,double *c13,double *h1, double *h2, double *h3, double *h4); double compute_cooling_from_Egyspec_and_Density(double Egyspec,double Density, double *MeanWeight); double DoCooling(FLOAT Density,FLOAT Entropy,int Phase,int i,FLOAT DtEntropyVisc, double dt, double hubble_a); void CoolingForOne(int i,int t0,int t1,double a3inv,double hubble_a); void cooling(); double lambda(FLOAT density,FLOAT egyspec, int phase, int i); #endif #ifdef HEATING void heating(); double gamma_fct(FLOAT Density,FLOAT Entropy,int i); #endif #ifdef AGN_HEATING void agn_heating(); double gamma_fct(FLOAT density,double r, double SpecPower); double HeatingRadialDependency(double r); #endif #ifdef MULTIPHASE void update_phase(void); void init_sticky(void); void sticky(void); void sticky_compute_energy_kin(int mode); void sticky_collisions(void); void sticky_collisions2(int loop); void sticky_evaluate(int target, int mode, int loop); int sticky_compare_key(const void *a, const void *b); #endif #ifdef FEEDBACK_WIND void feedbackwind_compute_energy_kin(int mode); #endif #ifdef CHIMIE void init_chimie(void); void check_chimie(void); void chimie(void); void do_chimie(void); void chimie_evaluate(int target, int mode); int chimie_compare_key(const void *a, const void *b); int get_nelts(); char* get_Element(i); float get_SolarAbundance(i); #if defined(CHIMIE_THERMAL_FEEDBACK) && defined(CHIMIE_COMPUTE_THERMAL_FEEDBACK_ENERGY) void chimie_compute_energy_int(int mode); #endif #if defined(CHIMIE_KINETIC_FEEDBACK) && defined(CHIMIE_COMPUTE_KINETIC_FEEDBACK_ENERGY) void chimie_compute_energy_kin(int mode); #endif #ifdef CHIMIE_KINETIC_FEEDBACK void chimie_apply_wind(void); #endif #endif #ifdef OUTERPOTENTIAL void init_outer_potential(void); void outer_forces(void); void outer_potential(void); #ifdef NFW void init_outer_potential_nfw(void); void outer_forces_nfw(void); void outer_potential_nfw(void); #endif #ifdef PLUMMER void init_outer_potential_plummer(void); void outer_forces_plummer(void); void outer_potential_plummer(void); #endif #ifdef PISOTHERM void init_outer_potential_pisotherm(void); void outer_forces_pisotherm(void); void outer_potential_pisotherm(void); double potential_f(double r, void * params); double get_potential(double r); #endif #ifdef CORIOLIS void init_outer_potential_coriolis(void); void set_outer_potential_coriolis(void); void outer_forces_coriolis(void); void outer_potential_coriolis(void); #endif #endif #ifdef SFR void star_formation(void); void rearrange_particle_sequence(void); void sfr_compute_energy_int(int mode); void sfr_check_number_of_stars(int mode); #endif #ifdef AGN_ACCRETION void compute_agn_accretion(void); #endif #ifdef BUBBLES void init_bubble(void); void make_bubble(void); void create_bubble(int sign); #endif #ifdef BONDI_ACCRETION void bondi_accretion(void); #endif #ifdef PNBODY void init_pnbody(); void finalize_pnbody(); void compute_pnbody(); #endif #ifdef AB_TURB void init_turb(); #endif #if defined(ART_VISCO_MM)|| defined(ART_VISCO_RO) || defined(ART_VISCO_CD) void move_art_visc(int i,double dt_drift); #ifdef ART_VISCO_CD void art_visc_allocate(); void art_visc_free(); void compute_art_visc(int i); #endif #endif #ifdef TESSEL void ConstructDelaunay(); void ComputeVoronoi(); void setup_searching_radius(); int ngb_treefind_variable_for_tessel(FLOAT searchcenter[3], FLOAT hsml, int phase, int *startnode); void ghost(); void tessel_compute_accelerations(); void tessel_convert_energy_to_entropy(); void tessel_kick(float dt_kick); void tessel_drift(float dt_drift); double tessel_get_timestep(); int CheckCompletenessForThisPoint(int i); int ghost_compare_key(const void *a, const void *b); void CheckTriangles(); void AddGhostPoints(int istart,int nadd); + +void dump_triangles(char *filename); +void dump_voronoi(char *filename); + + #ifdef PY_INTERFACE #include <Python.h> PyObject *gadget_GetAllDelaunayTriangles(self, args); PyObject *gadget_GetAllvPoints(self, args); PyObject *gadget_GetAllvDensities(PyObject* self); PyObject *gadget_GetAllvVolumes(PyObject* self); PyObject *gadget_GetAllvPressures(PyObject* self); PyObject *gadget_GetAllvEnergySpec(PyObject* self); PyObject *gadget_GetAllvAccelerations(PyObject* self); PyObject *gadget_GetvPointsForOnePoint(self, args); PyObject *gadget_GetNgbPointsForOnePoint(self, args); PyObject *gadget_GetNgbPointsAndFacesForOnePoint(self, args); PyObject *gadget_GetAllGhostPositions(PyObject* self); PyObject *gadget_GetAllGhostvDensities(PyObject* self); PyObject *gadget_GetAllGhostvVolumes(PyObject* self); #endif #endif #ifdef PY_INTERFACE void allocate_commbuffersQ(void); void density_sub(void); void density_evaluate_sub(int i, int mode); void do_box_wrappingQ(void); void domain_DecompositionQ(void); void domain_decomposeQ(void); int domain_findSplitQ(int cpustart, int ncpu, int first, int last); void domain_shiftSplitQ(void); void domain_findExchangeNumbersQ(int task, int partner, int sphflag, int *send, int *recv); void domain_exchangeParticlesQ(int partner, int sphflag, int send_count, int recv_count); void domain_countToGoQ(void); void domain_walktoptreeQ(int no); void domain_sumCostQ(void); void domain_findExtentQ(void); void domain_determineTopTreeQ(void); void domain_topsplit_localQ(int node, peanokey startkey); void domain_topsplitQ(int node, peanokey startkey); int force_treeevaluate_sub(int target, int mode, double *ewaldcountsum); void force_treeevaluate_potential_sub(int target, int type); void force_treeevaluate_potential_shortrange_sub(int target, int mode); int force_treeevaluate_shortrange_sub(int target, int mode); void gravity_tree_sub(void); void sph(void); void sph_evaluate(int target, int mode); void sph_sub(void); void sph_evaluate_sub(int target, int mode); void sph_thermal_conductivity(void); void sph_evaluate_thermal_conductivity(int target, int mode); int sph_compare_key(const void *a, const void *b); void peano_hilbert_orderQ(void); void reorder_gasQ(void); void reorder_particlesQ(void); void setup_smoothinglengths_sub(void); #endif diff --git a/src/python_interface.c b/src/python_interface.c index d25f0a9..dd9e4f0 100644 --- a/src/python_interface.c +++ b/src/python_interface.c @@ -1,3336 +1,3368 @@ #ifdef PY_INTERFACE #include <Python.h> #include <math.h> #include <string.h> #include <stdio.h> #include <numpy/arrayobject.h> #include <mpi.h> #include "allvars.h" #include "proto.h" #define TO_INT(a) ( (PyArrayObject*) PyArray_CastToType(a, PyArray_DescrFromType(NPY_INT) ,0) ) #define TO_DOUBLE(a) ( (PyArrayObject*) PyArray_CastToType(a, PyArray_DescrFromType(NPY_DOUBLE) ,0) ) #define TO_FLOAT(a) ( (PyArrayObject*) PyArray_CastToType(a, PyArray_DescrFromType(NPY_FLOAT) ,0) ) static int Init() { /* main.c */ RestartFlag = 0; All.CPU_TreeConstruction = All.CPU_TreeWalk = All.CPU_Gravity = All.CPU_Potential = All.CPU_Domain = All.CPU_Snapshot = All.CPU_Total = All.CPU_CommSum = All.CPU_Imbalance = All.CPU_Hydro = All.CPU_HydCompWalk = All.CPU_HydCommSumm = All.CPU_HydImbalance = All.CPU_EnsureNgb = All.CPU_Predict = All.CPU_TimeLine = All.CPU_PM = All.CPU_Peano = 0; CPUThisRun = 0; /* from init.c, after read ic */ int i, j; double a3; All.Time = All.TimeBegin; All.Ti_Current = 0; if(All.ComovingIntegrationOn) { All.Timebase_interval = (log(All.TimeMax) - log(All.TimeBegin)) / TIMEBASE; a3 = All.Time * All.Time * All.Time; } else { All.Timebase_interval = (All.TimeMax - All.TimeBegin) / TIMEBASE; a3 = 1; } set_softenings(); All.NumCurrentTiStep = 0; /* setup some counters */ All.SnapshotFileCount = 0; if(RestartFlag == 2) All.SnapshotFileCount = atoi(All.InitCondFile + strlen(All.InitCondFile) - 3) + 1; All.TotNumOfForces = 0; All.NumForcesSinceLastDomainDecomp = 0; if(All.ComovingIntegrationOn) if(All.PeriodicBoundariesOn == 1) check_omega(); All.TimeLastStatistics = All.TimeBegin - All.TimeBetStatistics; if(All.ComovingIntegrationOn) /* change to new velocity variable */ { for(i = 0; i < NumPart; i++) for(j = 0; j < 3; j++) P[i].Vel[j] *= sqrt(All.Time) * All.Time; } for(i = 0; i < NumPart; i++) /* start-up initialization */ { for(j = 0; j < 3; j++) P[i].GravAccel[j] = 0; #ifdef PMGRID for(j = 0; j < 3; j++) P[i].GravPM[j] = 0; #endif P[i].Ti_endstep = 0; P[i].Ti_begstep = 0; P[i].OldAcc = 0; P[i].GravCost = 1; P[i].Potential = 0; } #ifdef PMGRID All.PM_Ti_endstep = All.PM_Ti_begstep = 0; #endif #ifdef FLEXSTEPS All.PresentMinStep = TIMEBASE; for(i = 0; i < NumPart; i++) /* start-up initialization */ { P[i].FlexStepGrp = (int) (TIMEBASE * get_random_number(P[i].ID)); } #endif for(i = 0; i < N_gas; i++) /* initialize sph_properties */ { for(j = 0; j < 3; j++) { SphP[i].VelPred[j] = P[i].Vel[j]; SphP[i].HydroAccel[j] = 0; } SphP[i].DtEntropy = 0; if(RestartFlag == 0) { SphP[i].Hsml = 0; SphP[i].Density = -1; } } ngb_treeallocate(MAX_NGB); force_treeallocate(All.TreeAllocFactor * All.MaxPart, All.MaxPart); All.NumForcesSinceLastDomainDecomp = 1 + All.TotNumPart * All.TreeDomainUpdateFrequency; Flag_FullStep = 1; /* to ensure that Peano-Hilber order is done */ domain_Decomposition(); /* do initial domain decomposition (gives equal numbers of particles) */ ngb_treebuild(); /* will build tree */ setup_smoothinglengths(); #ifdef CHIMIE #ifndef CHIMIE_INPUT_ALL stars_setup_smoothinglengths(); #endif #endif #ifdef TESSEL setup_searching_radius(); #endif TreeReconstructFlag = 1; #ifndef TESSEL /*do not convert if tessel is used. In tessel, the conversion is done with tessel_convert_energy_to_entropy() */ /* at this point, the entropy variable normally contains the * internal energy, read in from the initial conditions file, unless the file * explicitly signals that the initial conditions contain the entropy directly. * Once the density has been computed, we can convert thermal energy to entropy. */ #ifndef ISOTHERM_EQS if(header.flag_entropy_instead_u == 0) for(i = 0; i < N_gas; i++) SphP[i].Entropy = GAMMA_MINUS1 * SphP[i].Entropy / pow(SphP[i].Density / a3, GAMMA_MINUS1); #endif #endif /* TESSEL */ return 1; } static void Begrun1() { struct global_data_all_processes all; if(ThisTask == 0) { printf("\nThis is pyGadget, version `%s'.\n", GADGETVERSION); printf("\nRunning on %d processors.\n", NTask); } //read_parameter_file(ParameterFile); /* ... read in parameters for this run */ allocate_commbuffers(); /* ... allocate buffer-memory for particle exchange during force computation */ set_units(); #if defined(PERIODIC) && (!defined(PMGRID) || defined(FORCETEST)) ewald_init(); #endif //open_outputfiles(); random_generator = gsl_rng_alloc(gsl_rng_ranlxd1); gsl_rng_set(random_generator, 42); /* start-up seed */ #ifdef PMGRID long_range_init(); #endif All.TimeLastRestartFile = CPUThisRun; if(RestartFlag == 0 || RestartFlag == 2) { set_random_numbers(); } else { all = All; /* save global variables. (will be read from restart file) */ restart(RestartFlag); /* ... read restart file. Note: This also resets all variables in the struct `All'. However, during the run, some variables in the parameter file are allowed to be changed, if desired. These need to copied in the way below. Note: All.PartAllocFactor is treated in restart() separately. */ All.MinSizeTimestep = all.MinSizeTimestep; All.MaxSizeTimestep = all.MaxSizeTimestep; All.BufferSize = all.BufferSize; All.BunchSizeForce = all.BunchSizeForce; All.BunchSizeDensity = all.BunchSizeDensity; All.BunchSizeHydro = all.BunchSizeHydro; All.BunchSizeDomain = all.BunchSizeDomain; All.TimeLimitCPU = all.TimeLimitCPU; All.ResubmitOn = all.ResubmitOn; All.TimeBetSnapshot = all.TimeBetSnapshot; All.TimeBetStatistics = all.TimeBetStatistics; All.CpuTimeBetRestartFile = all.CpuTimeBetRestartFile; All.ErrTolIntAccuracy = all.ErrTolIntAccuracy; All.MaxRMSDisplacementFac = all.MaxRMSDisplacementFac; All.ErrTolForceAcc = all.ErrTolForceAcc; All.TypeOfTimestepCriterion = all.TypeOfTimestepCriterion; All.TypeOfOpeningCriterion = all.TypeOfOpeningCriterion; All.NumFilesWrittenInParallel = all.NumFilesWrittenInParallel; All.TreeDomainUpdateFrequency = all.TreeDomainUpdateFrequency; All.SnapFormat = all.SnapFormat; All.NumFilesPerSnapshot = all.NumFilesPerSnapshot; All.MaxNumNgbDeviation = all.MaxNumNgbDeviation; All.ArtBulkViscConst = all.ArtBulkViscConst; All.OutputListOn = all.OutputListOn; All.CourantFac = all.CourantFac; All.OutputListLength = all.OutputListLength; memcpy(All.OutputListTimes, all.OutputListTimes, sizeof(double) * All.OutputListLength); strcpy(All.ResubmitCommand, all.ResubmitCommand); strcpy(All.OutputListFilename, all.OutputListFilename); strcpy(All.OutputDir, all.OutputDir); strcpy(All.RestartFile, all.RestartFile); strcpy(All.EnergyFile, all.EnergyFile); strcpy(All.InfoFile, all.InfoFile); strcpy(All.CpuFile, all.CpuFile); strcpy(All.TimingsFile, all.TimingsFile); strcpy(All.SnapshotFileBase, all.SnapshotFileBase); if(All.TimeMax != all.TimeMax) readjust_timebase(All.TimeMax, all.TimeMax); } } static void Begrun2() { if(RestartFlag == 0 || RestartFlag == 2) Init(); /* ... read in initial model */ #ifdef PMGRID long_range_init_regionsize(); #endif if(All.ComovingIntegrationOn) init_drift_table(); //if(RestartFlag == 2) // All.Ti_nextoutput = find_next_outputtime(All.Ti_Current + 1); //else // All.Ti_nextoutput = find_next_outputtime(All.Ti_Current); All.TimeLastRestartFile = CPUThisRun; } /************************************************************/ /* PYTHON INTERFACE */ /************************************************************/ static PyObject *gadget_Info(PyObject *self, PyObject *args, PyObject *kwds) { printf("I am proc %d among %d procs.\n",ThisTask,NTask); return Py_BuildValue("i",1); } static PyObject *gadget_InitMPI(PyObject *self, PyObject *args, PyObject *kwds) { //MPI_Init(0, 0); /* this is done in mpi4py */ MPI_Comm_rank(MPI_COMM_WORLD, &ThisTask); MPI_Comm_size(MPI_COMM_WORLD, &NTask); for(PTask = 0; NTask > (1 << PTask); PTask++); return Py_BuildValue("i",1); } static PyObject * gadget_InitDefaultParameters(PyObject* self) { /* list of Gadget parameters */ /* All.InitCondFile ="ICs/cluster_littleendian.dat"; All.OutputDir ="cluster/"; All.EnergyFile ="energy.txt"; All.InfoFile ="info.txt"; All.TimingsFile ="timings.txt"; All.CpuFile ="cpu.txt"; All.RestartFile ="restart"; All.SnapshotFileBase ="snapshot"; All.OutputListFilename ="parameterfiles/outputs_lcdm_gas.txt"; */ /* CPU time -limit */ All.TimeLimitCPU = 36000; /* = 10 hours */ All.ResubmitOn = 0; //All.ResubmitCommand = "my-scriptfile"; All.ICFormat = 1; All.SnapFormat = 1; All.ComovingIntegrationOn = 0; All.TypeOfTimestepCriterion = 0; All.OutputListOn = 0; All.PeriodicBoundariesOn = 0; /* Caracteristics of run */ All.TimeBegin = 0.0; /*% Begin of the simulation (z=23)*/ All.TimeMax = 1.0; All.Omega0 = 0; All.OmegaLambda = 0; All.OmegaBaryon = 0; All.HubbleParam = 0; All.BoxSize = 0; /* Output frequency */ All.TimeBetSnapshot = 0.1; All.TimeOfFirstSnapshot = 0.0; /*% 5 constant steps in log(a) */ All.CpuTimeBetRestartFile = 36000.0; /* here in seconds */ All.TimeBetStatistics = 0.05; All.NumFilesPerSnapshot = 1; All.NumFilesWrittenInParallel = 1; /* Accuracy of time integration */ All.ErrTolIntAccuracy = 0.025; All.MaxRMSDisplacementFac = 0.2; All.CourantFac = 0.15; All.MaxSizeTimestep = 0.03; All.MinSizeTimestep = 0.0; /* Tree algorithm, force accuracy, domain update frequency */ All.ErrTolTheta = 0.7; All.TypeOfOpeningCriterion = 0; All.ErrTolForceAcc = 0.005; All.TreeDomainUpdateFrequency = 0.1; /* Further parameters of SPH */ All.DesNumNgb = 50; All.MaxNumNgbDeviation = 2; All.ArtBulkViscConst = 0.8; All.InitGasTemp = 0; All.MinGasTemp = 0; /* Memory allocation */ All.PartAllocFactor = 2.0; All.TreeAllocFactor = 2.0; All.BufferSize = 30; /* System of units */ All.UnitLength_in_cm = 3.085678e21; /* 1.0 kpc */ All.UnitMass_in_g = 1.989e43; /* 1.0e10 solar masses */ All.UnitVelocity_in_cm_per_s = 1e5; /* 1 km/sec */ All.GravityConstantInternal = 0; /* Softening lengths */ All.MinGasHsmlFractional = 0.25; All.SofteningGas = 0.5; All.SofteningHalo = 0.5; All.SofteningDisk = 0.5; All.SofteningBulge = 0.5; All.SofteningStars = 0.5; All.SofteningBndry = 0.5; All.SofteningGasMaxPhys = 0.5; All.SofteningHaloMaxPhys = 0.5; All.SofteningDiskMaxPhys = 0.5; All.SofteningBulgeMaxPhys = 0.5; All.SofteningStarsMaxPhys = 0.5; All.SofteningBndryMaxPhys = 0.5; return Py_BuildValue("i",1); } static PyObject * gadget_GetParameters() { PyObject *dict; PyObject *key; PyObject *value; dict = PyDict_New(); /* CPU time -limit */ key = PyString_FromString("TimeLimitCPU"); value = PyFloat_FromDouble(All.TimeLimitCPU); PyDict_SetItem(dict,key,value); key = PyString_FromString("ResubmitOn"); value = PyFloat_FromDouble(All.ResubmitOn); PyDict_SetItem(dict,key,value); //All.ResubmitCommand key = PyString_FromString("ICFormat"); value = PyInt_FromLong(All.ICFormat); PyDict_SetItem(dict,key,value); key = PyString_FromString("SnapFormat"); value = PyInt_FromLong(All.SnapFormat); PyDict_SetItem(dict,key,value); key = PyString_FromString("ComovingIntegrationOn"); value = PyInt_FromLong(All.ComovingIntegrationOn); PyDict_SetItem(dict,key,value); key = PyString_FromString("TypeOfTimestepCriterion"); value = PyInt_FromLong(All.TypeOfTimestepCriterion); PyDict_SetItem(dict,key,value); key = PyString_FromString("OutputListOn"); value = PyInt_FromLong(All.OutputListOn); PyDict_SetItem(dict,key,value); key = PyString_FromString("PeriodicBoundariesOn"); value = PyInt_FromLong(All.PeriodicBoundariesOn); PyDict_SetItem(dict,key,value); /* Caracteristics of run */ key = PyString_FromString("TimeBegin"); value = PyFloat_FromDouble(All.TimeBegin); PyDict_SetItem(dict,key,value); key = PyString_FromString("TimeMax"); value = PyFloat_FromDouble(All.TimeMax); PyDict_SetItem(dict,key,value); key = PyString_FromString("Omega0"); value = PyFloat_FromDouble(All.Omega0); PyDict_SetItem(dict,key,value); key = PyString_FromString("OmegaLambda"); value = PyFloat_FromDouble(All.OmegaLambda); PyDict_SetItem(dict,key,value); key = PyString_FromString("OmegaBaryon"); value = PyFloat_FromDouble(All.OmegaBaryon); PyDict_SetItem(dict,key,value); key = PyString_FromString("HubbleParam"); value = PyFloat_FromDouble(All.HubbleParam); PyDict_SetItem(dict,key,value); key = PyString_FromString("BoxSize"); value = PyFloat_FromDouble(All.BoxSize); PyDict_SetItem(dict,key,value); /* Output frequency */ key = PyString_FromString("TimeBetSnapshot"); value = PyFloat_FromDouble(All.TimeBetSnapshot); PyDict_SetItem(dict,key,value); key = PyString_FromString("TimeOfFirstSnapshot"); value = PyFloat_FromDouble(All.TimeOfFirstSnapshot); PyDict_SetItem(dict,key,value); key = PyString_FromString("CpuTimeBetRestartFile"); value = PyFloat_FromDouble(All.CpuTimeBetRestartFile); PyDict_SetItem(dict,key,value); key = PyString_FromString("TimeBetStatistics"); value = PyFloat_FromDouble(All.TimeBetStatistics); PyDict_SetItem(dict,key,value); key = PyString_FromString("NumFilesPerSnapshot"); value = PyInt_FromLong(All.NumFilesPerSnapshot); PyDict_SetItem(dict,key,value); key = PyString_FromString("NumFilesWrittenInParallel"); value = PyInt_FromLong(All.NumFilesWrittenInParallel); PyDict_SetItem(dict,key,value); /* Accuracy of time integration */ key = PyString_FromString("ErrTolIntAccuracy"); value = PyFloat_FromDouble(All.ErrTolIntAccuracy); PyDict_SetItem(dict,key,value); key = PyString_FromString("MaxRMSDisplacementFac"); value = PyFloat_FromDouble(All.MaxRMSDisplacementFac); PyDict_SetItem(dict,key,value); key = PyString_FromString("CourantFac"); value = PyFloat_FromDouble(All.CourantFac); PyDict_SetItem(dict,key,value); key = PyString_FromString("MaxSizeTimestep"); value = PyFloat_FromDouble(All.MaxSizeTimestep); PyDict_SetItem(dict,key,value); key = PyString_FromString("MinSizeTimestep"); value = PyFloat_FromDouble(All.MinSizeTimestep); PyDict_SetItem(dict,key,value); /* Tree algorithm, force accuracy, domain update frequency */ key = PyString_FromString("ErrTolTheta"); value = PyFloat_FromDouble(All.ErrTolTheta); PyDict_SetItem(dict,key,value); key = PyString_FromString("TypeOfOpeningCriterion"); value = PyInt_FromLong(All.TypeOfOpeningCriterion); PyDict_SetItem(dict,key,value); key = PyString_FromString("ErrTolForceAcc"); value = PyFloat_FromDouble(All.ErrTolForceAcc); PyDict_SetItem(dict,key,value); key = PyString_FromString("TreeDomainUpdateFrequency"); value = PyFloat_FromDouble(All.TreeDomainUpdateFrequency); PyDict_SetItem(dict,key,value); /* Further parameters of SPH */ key = PyString_FromString("DesNumNgb"); value = PyInt_FromLong(All.DesNumNgb); PyDict_SetItem(dict,key,value); key = PyString_FromString("MaxNumNgbDeviation"); value = PyInt_FromLong(All.MaxNumNgbDeviation); PyDict_SetItem(dict,key,value); key = PyString_FromString("ArtBulkViscConst"); value = PyInt_FromLong(All.ArtBulkViscConst); PyDict_SetItem(dict,key,value); key = PyString_FromString("InitGasTemp"); value = PyInt_FromLong(All.InitGasTemp); PyDict_SetItem(dict,key,value); key = PyString_FromString("MinGasTemp"); value = PyInt_FromLong(All.MinGasTemp); PyDict_SetItem(dict,key,value); /* Memory allocation */ key = PyString_FromString("PartAllocFactor"); value = PyFloat_FromDouble(All.PartAllocFactor); PyDict_SetItem(dict,key,value); key = PyString_FromString("TreeAllocFactor"); value = PyFloat_FromDouble(All.TreeAllocFactor); PyDict_SetItem(dict,key,value); key = PyString_FromString("BufferSize"); value = PyInt_FromLong(All.BufferSize); PyDict_SetItem(dict,key,value); /* System of units */ key = PyString_FromString("UnitLength_in_cm"); value = PyFloat_FromDouble(All.UnitLength_in_cm); PyDict_SetItem(dict,key,value); key = PyString_FromString("UnitMass_in_g"); value = PyFloat_FromDouble(All.UnitMass_in_g); PyDict_SetItem(dict,key,value); key = PyString_FromString("UnitVelocity_in_cm_per_s"); value = PyFloat_FromDouble(All.UnitVelocity_in_cm_per_s); PyDict_SetItem(dict,key,value); key = PyString_FromString("GravityConstantInternal"); value = PyFloat_FromDouble(All.GravityConstantInternal); PyDict_SetItem(dict,key,value); /* Softening lengths */ key = PyString_FromString("MinGasHsmlFractional"); value = PyFloat_FromDouble(All.MinGasHsmlFractional); PyDict_SetItem(dict,key,value); key = PyString_FromString("SofteningGas"); value = PyFloat_FromDouble(All.SofteningGas); PyDict_SetItem(dict,key,value); key = PyString_FromString("SofteningHalo"); value = PyFloat_FromDouble(All.SofteningHalo); PyDict_SetItem(dict,key,value); key = PyString_FromString("SofteningDisk"); value = PyFloat_FromDouble(All.SofteningDisk); PyDict_SetItem(dict,key,value); key = PyString_FromString("SofteningBulge"); value = PyFloat_FromDouble(All.SofteningBulge); PyDict_SetItem(dict,key,value); key = PyString_FromString("SofteningStars"); value = PyFloat_FromDouble(All.SofteningStars); PyDict_SetItem(dict,key,value); key = PyString_FromString("SofteningBndry"); value = PyFloat_FromDouble(All.SofteningBndry); PyDict_SetItem(dict,key,value); key = PyString_FromString("SofteningGasMaxPhys"); value = PyFloat_FromDouble(All.SofteningGasMaxPhys); PyDict_SetItem(dict,key,value); key = PyString_FromString("SofteningHaloMaxPhys"); value = PyFloat_FromDouble(All.SofteningHaloMaxPhys); PyDict_SetItem(dict,key,value); key = PyString_FromString("SofteningDiskMaxPhys"); value = PyFloat_FromDouble(All.SofteningDiskMaxPhys); PyDict_SetItem(dict,key,value); key = PyString_FromString("SofteningBulgeMaxPhys"); value = PyFloat_FromDouble(All.SofteningBulgeMaxPhys); PyDict_SetItem(dict,key,value); key = PyString_FromString("SofteningStarsMaxPhys"); value = PyFloat_FromDouble(All.SofteningStarsMaxPhys); PyDict_SetItem(dict,key,value); key = PyString_FromString("SofteningBndryMaxPhys"); value = PyFloat_FromDouble(All.SofteningBndryMaxPhys); PyDict_SetItem(dict,key,value); /* key = PyString_FromString("OutputInfo"); value = PyFloat_FromDouble(All.OutputInfo); PyDict_SetItem(dict,key,value); key = PyString_FromString("PeanoHilbertOrder"); value = PyFloat_FromDouble(All.PeanoHilbertOrder); PyDict_SetItem(dict,key,value); */ return Py_BuildValue("O",dict); } static PyObject * gadget_SetParameters(PyObject *self, PyObject *args) { PyObject *dict; PyObject *key; PyObject *value; int ivalue; float fvalue; double dvalue; /* here, we can have either arguments or dict directly */ if(PyDict_Check(args)) { dict = args; } else { if (! PyArg_ParseTuple(args, "O",&dict)) return NULL; } /* check that it is a PyDictObject */ if(!PyDict_Check(dict)) { PyErr_SetString(PyExc_AttributeError, "argument is not a dictionary."); return NULL; } Py_ssize_t pos=0; while(PyDict_Next(dict,&pos,&key,&value)) { if(PyString_Check(key)) { /* CPU time -limit */ if(strcmp(PyString_AsString(key), "TimeLimitCPU")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.TimeLimitCPU = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "ResubmitOn")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.ResubmitOn = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "ICFormat")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.ICFormat = PyInt_AsLong(value); } if(strcmp(PyString_AsString(key), "SnapFormat")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.SnapFormat = PyInt_AsLong(value); } if(strcmp(PyString_AsString(key), "ComovingIntegrationOn")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.ComovingIntegrationOn = PyInt_AsLong(value); } if(strcmp(PyString_AsString(key), "TypeOfTimestepCriterion")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.TypeOfTimestepCriterion = PyInt_AsLong(value); } if(strcmp(PyString_AsString(key), "OutputListOn")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.OutputListOn = PyInt_AsLong(value); } if(strcmp(PyString_AsString(key), "PeriodicBoundariesOn")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.PeriodicBoundariesOn = PyInt_AsLong(value); } /* Caracteristics of run */ if(strcmp(PyString_AsString(key), "TimeBegin")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.TimeBegin = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "TimeMax")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.TimeMax = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "Omega0")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.Omega0 = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "OmegaLambda")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.OmegaLambda = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "OmegaBaryon")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.OmegaBaryon = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "HubbleParam")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.HubbleParam = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "BoxSize")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.BoxSize = PyFloat_AsDouble(value); } /* Output frequency */ if(strcmp(PyString_AsString(key), "TimeBetSnapshot")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.TimeBetSnapshot = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "TimeOfFirstSnapshot")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.TimeOfFirstSnapshot = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "CpuTimeBetRestartFile")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.CpuTimeBetRestartFile = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "TimeBetStatistics")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.TimeBetStatistics = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "NumFilesPerSnapshot")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.NumFilesPerSnapshot = PyInt_AsLong(value); } if(strcmp(PyString_AsString(key), "NumFilesWrittenInParallel")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.NumFilesWrittenInParallel = PyInt_AsLong(value); } /* Accuracy of time integration */ if(strcmp(PyString_AsString(key), "ErrTolIntAccuracy")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.ErrTolIntAccuracy = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "MaxRMSDisplacementFac")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.MaxRMSDisplacementFac = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "CourantFac")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.CourantFac = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "MaxSizeTimestep")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.MaxSizeTimestep = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "MinSizeTimestep")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.MinSizeTimestep = PyFloat_AsDouble(value); } /* Tree algorithm, force accuracy, domain update frequency */ if(strcmp(PyString_AsString(key), "ErrTolTheta")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.ErrTolTheta = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "TypeOfOpeningCriterion")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.TypeOfOpeningCriterion = PyInt_AsLong(value); } if(strcmp(PyString_AsString(key), "ErrTolForceAcc")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.ErrTolForceAcc = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "TreeDomainUpdateFrequency")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.TreeDomainUpdateFrequency = PyFloat_AsDouble(value); } /* Further parameters of SPH */ if(strcmp(PyString_AsString(key), "DesNumNgb")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.DesNumNgb = PyInt_AsLong(value); } if(strcmp(PyString_AsString(key), "MaxNumNgbDeviation")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.MaxNumNgbDeviation = PyInt_AsLong(value); } if(strcmp(PyString_AsString(key), "ArtBulkViscConst")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.ArtBulkViscConst = PyInt_AsLong(value); } if(strcmp(PyString_AsString(key), "InitGasTemp")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.InitGasTemp = PyInt_AsLong(value); } if(strcmp(PyString_AsString(key), "MinGasTemp")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.MinGasTemp = PyInt_AsLong(value); } /* Memory allocation */ if(strcmp(PyString_AsString(key), "PartAllocFactor")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.PartAllocFactor = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "TreeAllocFactor")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.TreeAllocFactor = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "BufferSize")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.BufferSize = PyInt_AsLong(value); } /* System of units */ if(strcmp(PyString_AsString(key), "UnitLength_in_cm")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.UnitLength_in_cm = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "UnitMass_in_g")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.UnitMass_in_g = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "UnitVelocity_in_cm_per_s")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.UnitVelocity_in_cm_per_s = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "GravityConstantInternal")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.GravityConstantInternal = PyFloat_AsDouble(value); } /* Softening lengths */ if(strcmp(PyString_AsString(key), "MinGasHsmlFractional")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.MinGasHsmlFractional = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "SofteningGas")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.SofteningGas = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "SofteningHalo")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.SofteningHalo = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "SofteningDisk")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.SofteningDisk = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "SofteningBulge")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.SofteningBulge = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "SofteningStars")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.SofteningStars = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "SofteningBndry")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.SofteningBndry = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "SofteningGasMaxPhys")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.SofteningGasMaxPhys = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "SofteningHaloMaxPhys")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.SofteningHaloMaxPhys = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "SofteningDiskMaxPhys")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.SofteningDiskMaxPhys = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "SofteningBulgeMaxPhys")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.SofteningBulgeMaxPhys = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "SofteningStarsMaxPhys")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.SofteningStarsMaxPhys = PyFloat_AsDouble(value); } if(strcmp(PyString_AsString(key), "SofteningBndryMaxPhys")==0) { if(PyInt_Check(value)||PyLong_Check(value)||PyFloat_Check(value)) All.SofteningBndryMaxPhys = PyFloat_AsDouble(value); } } } return Py_BuildValue("i",1); } static PyObject * gadget_check_parser(PyObject *self, PyObject *args, PyObject *keywds) { int voltage; char *state = "a stiff"; char *action = "voom"; char *type = "Norwegian Blue"; static char *kwlist[] = {"voltage", "state", "action", "type", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|sss", kwlist, &voltage, &state, &action, &type)) return NULL; printf("-- This parrot wouldn't %s if you put %i Volts through it.\n", action, voltage); printf("-- Lovely plumage, the %s -- It's %s!\n", type, state); Py_INCREF(Py_None); return Py_None; } static PyObject *gadget_Free(PyObject *self, PyObject *args, PyObject *kwds) { free_memory(); ngb_treefree(); force_treefree(); free(Exportflag ); free(DomainStartList); free(DomainEndList); free(TopNodes); free(DomainWork); free(DomainCount); free(DomainCountSph); free(DomainTask); free(DomainNodeIndex); free(DomainTreeNodeLen); free(DomainHmax); free(DomainMoment); free(CommBuffer); gsl_rng_free(random_generator); return Py_BuildValue("i",1); } static PyObject *gadget_LoadParticles(PyObject *self, PyObject *args, PyObject *kwds) { int i,j; size_t bytes; PyArrayObject *ntype=Py_None; PyArrayObject *pos=Py_None; PyArrayObject *vel=Py_None; PyArrayObject *mass=Py_None; PyArrayObject *num=Py_None; PyArrayObject *tpe=Py_None; PyArrayObject *u=Py_None; PyArrayObject *rho=Py_None; static char *kwlist[] = {"npart", "pos","vel","mass","num","tpe","u","rho", NULL}; if (! PyArg_ParseTupleAndKeywords(args,kwds, "OOOOOO|OO",kwlist,&ntype,&pos,&vel,&mass,&num,&tpe,&u,&rho )) return NULL; /* check type */ if (!(PyArray_Check(pos))) { PyErr_SetString(PyExc_ValueError,"aruments 2 must be array."); return NULL; } /* check type */ if (!(PyArray_Check(mass))) { PyErr_SetString(PyExc_ValueError,"aruments 3 must be array."); return NULL; } /* check dimension */ if ( (pos->nd!=2)) { PyErr_SetString(PyExc_ValueError,"Dimension of argument 2 must be 2."); return NULL; } /* check dimension */ if ( (mass->nd!=1)) { PyErr_SetString(PyExc_ValueError,"Dimension of argument 3 must be 1."); return NULL; } /* check size */ if ( (pos->dimensions[1]!=3)) { PyErr_SetString(PyExc_ValueError,"First size of argument must be 3."); return NULL; } /* check size */ if ( (pos->dimensions[0]!=mass->dimensions[0])) { PyErr_SetString(PyExc_ValueError,"Size of argument 2 must be similar to argument 3."); return NULL; } /* ensure double */ ntype = TO_INT(ntype); pos = TO_FLOAT(pos); vel = TO_FLOAT(vel); mass = TO_FLOAT(mass); num = TO_INT(num); tpe = TO_FLOAT(tpe); /* optional variables */ if (u!=Py_None) u = TO_FLOAT(u); if (rho!=Py_None) rho = TO_FLOAT(rho); /*************************************** * some inits * /***************************************/ RestartFlag = 0; Begrun1(); /*************************************** * LOAD PARTILES * /***************************************/ NumPart = 0; N_gas = *(int*) (ntype->data + 0*(ntype->strides[0])); for (i = 0; i < 6; i++) NumPart += *(int*) (ntype->data + i*(ntype->strides[0])); if (NumPart!=pos->dimensions[0]) { PyErr_SetString(PyExc_ValueError,"Numpart != pos->dimensions[0]."); return NULL; } MPI_Allreduce(&NumPart, &All.TotNumPart, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce(&N_gas, &All.TotN_gas, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); All.MaxPart = All.PartAllocFactor * (All.TotNumPart / NTask); All.MaxPartSph = All.PartAllocFactor * (All.TotN_gas / NTask); /*********************/ /* allocate P */ /*********************/ if(!(P = malloc(bytes = All.MaxPart * sizeof(struct particle_data)))) { printf("failed to allocate memory for `P' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(1); } if(!(SphP = malloc(bytes = All.MaxPartSph * sizeof(struct sph_particle_data)))) { printf("failed to allocate memory for `SphP' (%g MB) %d.\n", bytes / (1024.0 * 1024.0), sizeof(struct sph_particle_data)); endrun(1); } /*********************/ /* init P */ /*********************/ for (i = 0; i < NumPart; i++) { P[i].Pos[0] = *(float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]); P[i].Pos[1] = *(float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]); P[i].Pos[2] = *(float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]); P[i].Vel[0] = *(float *) (vel->data + i*(vel->strides[0]) + 0*vel->strides[1]); P[i].Vel[1] = *(float *) (vel->data + i*(vel->strides[0]) + 1*vel->strides[1]); P[i].Vel[2] = *(float *) (vel->data + i*(vel->strides[0]) + 2*vel->strides[1]); P[i].Mass = *(float *) (mass->data + i*(mass->strides[0])); P[i].ID = *(unsigned int *) (num->data + i*(num->strides[0])); P[i].Type = *(int *) (tpe->data + i*(tpe->strides[0])); //P[i].Active = 1; //printf(" P.ID=%d%09d\n", (int) (P[i].ID / 1000000000), (int) (P[i].ID % 1000000000)); #ifdef TESSEL P[i].iPref = -1; #endif } /*********************/ /* init SphP */ /*********************/ if (u!=Py_None) for (i = 0; i < NumPart; i++) { SphP[i].Entropy = *(float *) (u->data + i*(u->strides[0])); //#ifndef ISOTHERM_EQS // SphP[i].Entropy = GAMMA_MINUS1 * SphP[i].Entropy / pow(SphP[i].Density / a3, GAMMA_MINUS1); //#endif } if (rho!=Py_None) for (i = 0; i < NumPart; i++) { SphP[i].Density = *(float *) (rho->data + i*(rho->strides[0])); } /*************************************** * END LOAD PARTICLES * /***************************************/ /*************************************** * finish inits * /***************************************/ Begrun2(); /*************************************** * free memory * /***************************************/ /* free the memory allocated, because these vectors where casted and their memory is now handeled by the C part */ Py_DECREF(ntype); Py_DECREF(pos); Py_DECREF(vel); Py_DECREF(mass); Py_DECREF(num); Py_DECREF(tpe); /* optional variables */ if (u!=Py_None) Py_DECREF(u); if (rho!=Py_None) Py_DECREF(rho); return Py_BuildValue("i",1); } static PyObject *gadget_LoadParticlesQ(PyObject *self, PyObject *args, PyObject *kwds) { int i,j; size_t bytes; PyArrayObject *ntype,*pos,*vel,*mass,*num,*tpe; static char *kwlist[] = {"npart", "pos","vel","mass","num","tpe", NULL}; if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOOO",kwlist,&ntype,&pos,&vel,&mass,&num,&tpe)) return Py_BuildValue("i",1); /* check type */ if (!(PyArray_Check(pos))) { PyErr_SetString(PyExc_ValueError,"aruments 1 must be array."); return NULL; } /* check type */ if (!(PyArray_Check(mass))) { PyErr_SetString(PyExc_ValueError,"aruments 2 must be array."); return NULL; } /* check dimension */ if ( (pos->nd!=2)) { PyErr_SetString(PyExc_ValueError,"Dimension of argument 1 must be 2."); return NULL; } /* check dimension */ if ( (mass->nd!=1)) { PyErr_SetString(PyExc_ValueError,"Dimension of argument 2 must be 1."); return NULL; } /* check size */ if ( (pos->dimensions[1]!=3)) { PyErr_SetString(PyExc_ValueError,"First size of argument must be 3."); return NULL; } /* check size */ if ( (pos->dimensions[0]!=mass->dimensions[0])) { PyErr_SetString(PyExc_ValueError,"Size of argument 1 must be similar to argument 2."); return NULL; } /* ensure double */ ntype = TO_INT(ntype); pos = TO_FLOAT(pos); vel = TO_FLOAT(vel); mass = TO_FLOAT(mass); num = TO_FLOAT(num); tpe = TO_FLOAT(tpe); /*************************************** * some inits * /***************************************/ allocate_commbuffersQ(); /*************************************** * LOAD PARTILES * /***************************************/ NumPartQ = 0; N_gasQ = *(int*) (ntype->data + 0*(ntype->strides[0])); for (i = 0; i < 6; i++) NumPartQ += *(int*) (ntype->data + i*(ntype->strides[0])); if (NumPartQ!=pos->dimensions[0]) { PyErr_SetString(PyExc_ValueError,"NumpartQ != pos->dimensions[0]."); return NULL; } MPI_Allreduce(&NumPartQ, &All.TotNumPartQ, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce(&N_gasQ, &All.TotN_gasQ, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); All.MaxPartQ = All.PartAllocFactor * (All.TotNumPartQ / NTask); All.MaxPartSphQ = All.PartAllocFactor * (All.TotN_gasQ / NTask); /*********************/ /* allocate Q */ /*********************/ if(!(Q = malloc(bytes = All.MaxPartQ * sizeof(struct particle_data)))) { printf("failed to allocate memory for `Q' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(1); } if(!(SphQ = malloc(bytes = All.MaxPartSphQ * sizeof(struct sph_particle_data)))) { printf("failed to allocate memory for `SphQ' (%g MB) %d.\n", bytes / (1024.0 * 1024.0), sizeof(struct sph_particle_data)); endrun(1); } /*********************/ /* init P */ /*********************/ for (i = 0; i < NumPartQ; i++) { Q[i].Pos[0] = *(float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]); Q[i].Pos[1] = *(float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]); Q[i].Pos[2] = *(float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]); Q[i].Vel[0] = *(float *) (vel->data + i*(vel->strides[0]) + 0*vel->strides[1]); Q[i].Vel[1] = *(float *) (vel->data + i*(vel->strides[0]) + 1*vel->strides[1]); Q[i].Vel[2] = *(float *) (vel->data + i*(vel->strides[0]) + 2*vel->strides[1]); Q[i].Mass = *(float *) (mass->data + i*(mass->strides[0])); Q[i].ID = *(unsigned int *) (num->data + i*(num->strides[0])); Q[i].Type = *(int *) (tpe->data + i*(tpe->strides[0])); //Q[i].Active = 1; } /*************************************** * END LOAD PARTILES * /***************************************/ domain_DecompositionQ(); /*************************************** * finish inits * /***************************************/ return Py_BuildValue("i",1); } static PyObject *gadget_AllPotential(PyObject *self) { compute_potential(); return Py_BuildValue("i",1); } static PyObject * gadget_GetAllPotential(PyObject* self) { PyArrayObject *pot; npy_intp ld[1]; int i; ld[0] = NumPart; pot = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_FLOAT); for (i = 0; i < pot->dimensions[0]; i++) { *(float *) (pot->data + i*(pot->strides[0])) = P[i].Potential; } return PyArray_Return(pot); } static PyObject *gadget_AllAcceleration(PyObject *self) { NumForceUpdate = NumPart; gravity_tree(); return Py_BuildValue("i",1); } static PyObject * gadget_GetAllAcceleration(PyObject* self) { PyArrayObject *acc; npy_intp ld[2]; int i; ld[0] = NumPart; ld[1] = 3; acc = (PyArrayObject *) PyArray_SimpleNew(2,ld,PyArray_FLOAT); for (i = 0; i < acc->dimensions[0]; i++) { *(float *) (acc->data + i*(acc->strides[0]) + 0*acc->strides[1]) = P[i].GravAccel[0]; *(float *) (acc->data + i*(acc->strides[0]) + 1*acc->strides[1]) = P[i].GravAccel[1]; *(float *) (acc->data + i*(acc->strides[0]) + 2*acc->strides[1]) = P[i].GravAccel[2]; } return PyArray_Return(acc); } static PyObject *gadget_GetAllDensities(PyObject* self) { PyArrayObject *rho; npy_intp ld[1]; int i; ld[0] = N_gas; rho = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_FLOAT); for (i = 0; i < rho->dimensions[0]; i++) { *(float *) (rho->data + i*(rho->strides[0])) = SphP[i].Density; } return PyArray_Return(rho); } static PyObject *gadget_GetAllHsml(PyObject* self) { PyArrayObject *hsml; npy_intp ld[1]; int i; ld[0] = N_gas; hsml = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_FLOAT); for (i = 0; i < hsml->dimensions[0]; i++) { *(float *) (hsml->data + i*(hsml->strides[0])) = SphP[i].Hsml; } return PyArray_Return(hsml); } static PyObject *gadget_GetAllPositions(PyObject* self) { PyArrayObject *pos; npy_intp ld[2]; int i; ld[0] = NumPart; ld[1] = 3; pos = (PyArrayObject *) PyArray_SimpleNew(2,ld,PyArray_FLOAT); for (i = 0; i < pos->dimensions[0]; i++) { *(float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]) = P[i].Pos[0]; *(float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]) = P[i].Pos[1]; *(float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]) = P[i].Pos[2]; } return PyArray_Return(pos); } static PyObject *gadget_GetAllVelocities(PyObject* self) { PyArrayObject *vel; npy_intp ld[2]; int i; ld[0] = NumPart; ld[1] = 3; vel = (PyArrayObject *) PyArray_SimpleNew(2,ld,PyArray_FLOAT); for (i = 0; i < vel->dimensions[0]; i++) { *(float *) (vel->data + i*(vel->strides[0]) + 0*vel->strides[1]) = P[i].Vel[0]; *(float *) (vel->data + i*(vel->strides[0]) + 1*vel->strides[1]) = P[i].Vel[1]; *(float *) (vel->data + i*(vel->strides[0]) + 2*vel->strides[1]) = P[i].Vel[2]; } return PyArray_Return(vel); } static PyObject *gadget_GetAllMasses(PyObject* self) { PyArrayObject *mass; npy_intp ld[1]; int i; ld[0] = NumPart; mass = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_FLOAT); for (i = 0; i < mass->dimensions[0]; i++) { *(float *) (mass->data + i*(mass->strides[0])) = P[i].Mass; } return PyArray_Return(mass); } static PyObject *gadget_GetAllEntropy(PyObject* self) { PyArrayObject *entropy; npy_intp ld[1]; int i; ld[0] = NumPart; entropy = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_FLOAT); for (i = 0; i < entropy->dimensions[0]; i++) { *(float *) (entropy->data + i*(entropy->strides[0])) = SphP[i].Entropy; } return PyArray_Return(entropy); } static PyObject *gadget_GetAllEnergySpec(PyObject* self) { PyArrayObject *energy; npy_intp ld[1]; int i; double a3inv; ld[0] = NumPart; energy = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_FLOAT); if(All.ComovingIntegrationOn) { a3inv = 1 / (All.Time * All.Time * All.Time); } else a3inv = 1; for (i = 0; i < energy->dimensions[0]; i++) { #ifdef ISOTHERM_EQS *(float *) (energy->data + i*(energy->strides[0])) = SphP[i].Entropy; #else a3inv = 1.; *(float *) (energy->data + i*(energy->strides[0])) = dmax(All.MinEgySpec,SphP[i].Entropy / GAMMA_MINUS1 * pow(SphP[i].Density * a3inv, GAMMA_MINUS1)); #endif } return PyArray_Return(energy); } static PyObject *gadget_GetAllID(PyObject* self) { PyArrayObject *id; npy_intp ld[1]; int i; ld[0] = NumPart; id = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_INT); for (i = 0; i < id->dimensions[0]; i++) { *(float *) (id->data + i*(id->strides[0])) = P[i].ID; } return PyArray_Return(id); } static PyObject *gadget_GetAllTypes(PyObject* self) { PyArrayObject *type; npy_intp ld[1]; int i; ld[0] = NumPart; type = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_INT); for (i = 0; i < type->dimensions[0]; i++) { *(int *) (type->data + i*(type->strides[0])) = P[i].Type; } return PyArray_Return(type); } static PyObject *gadget_GetAllPositionsQ(PyObject* self) { PyArrayObject *pos; npy_intp ld[2]; int i; ld[0] = NumPartQ; ld[1] = 3; pos = (PyArrayObject *) PyArray_SimpleNew(2,ld,PyArray_FLOAT); for (i = 0; i < pos->dimensions[0]; i++) { *(float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]) = Q[i].Pos[0]; *(float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]) = Q[i].Pos[1]; *(float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]) = Q[i].Pos[2]; } return PyArray_Return(pos); } static PyObject *gadget_GetAllVelocitiesQ(PyObject* self) { PyArrayObject *vel; npy_intp ld[2]; int i; ld[0] = NumPartQ; ld[1] = 3; vel = (PyArrayObject *) PyArray_SimpleNew(2,ld,PyArray_FLOAT); for (i = 0; i < vel->dimensions[0]; i++) { *(float *) (vel->data + i*(vel->strides[0]) + 0*vel->strides[1]) = Q[i].Vel[0]; *(float *) (vel->data + i*(vel->strides[0]) + 1*vel->strides[1]) = Q[i].Vel[1]; *(float *) (vel->data + i*(vel->strides[0]) + 2*vel->strides[1]) = Q[i].Vel[2]; } return PyArray_Return(vel); } static PyObject *gadget_GetAllMassesQ(PyObject* self) { PyArrayObject *mass; npy_intp ld[1]; int i; ld[0] = NumPartQ; mass = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_FLOAT); for (i = 0; i < mass->dimensions[0]; i++) { *(float *) (mass->data + i*(mass->strides[0])) = Q[i].Mass; } return PyArray_Return(mass); } static PyObject *gadget_GetAllIDQ(PyObject* self) { PyArrayObject *id; npy_intp ld[1]; int i; ld[0] = NumPartQ; id = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_INT); for (i = 0; i < id->dimensions[0]; i++) { *(float *) (id->data + i*(id->strides[0])) = Q[i].ID; } return PyArray_Return(id); } static PyObject *gadget_GetAllTypesQ(PyObject* self) { PyArrayObject *type; npy_intp ld[1]; int i; ld[0] = NumPartQ; type = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_INT); for (i = 0; i < type->dimensions[0]; i++) { *(int *) (type->data + i*(type->strides[0])) = Q[i].Type; } return PyArray_Return(type); } static PyObject *gadget_GetPos(PyObject *self, PyObject *args, PyObject *kwds) { int i,j; size_t bytes; PyArrayObject *pos; if (! PyArg_ParseTuple(args, "O",&pos)) return PyString_FromString("error : GetPos"); for (i = 0; i < pos->dimensions[0]; i++) { *(float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]) = P[i].Pos[0]; *(float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]) = P[i].Pos[1]; *(float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]) = P[i].Pos[2]; } //return PyArray_Return(Py_None); return Py_BuildValue("i",1); } static PyObject * gadget_Potential(PyObject* self, PyObject *args) { PyArrayObject *pos; float eps; if (! PyArg_ParseTuple(args, "Of",&pos,&eps)) return PyString_FromString("error"); PyArrayObject *pot; int i; npy_intp ld[1]; int input_dimension; size_t bytes; input_dimension =pos->nd; if (input_dimension != 2) PyErr_SetString(PyExc_ValueError,"dimension of first argument must be 2"); pos = TO_FLOAT(pos); /* create a NumPy object */ ld[0]=pos->dimensions[0]; pot = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_FLOAT); NumPartQ = pos->dimensions[0]; All.ForceSofteningQ = eps; if(!(Q = malloc(bytes = NumPartQ * sizeof(struct particle_data)))) { printf("failed to allocate memory for `Q' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(1); } if(!(SphQ = malloc(bytes = NumPartQ * sizeof(struct sph_particle_data)))) { printf("failed to allocate memory for `SphQ' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(1); } for (i = 0; i < pos->dimensions[0]; i++) { Q[i].Pos[0] = *(float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]); Q[i].Pos[1] = *(float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]); Q[i].Pos[2] = *(float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]); Q[i].Type = 0; Q[i].Mass = 0; Q[i].Potential = 0; } compute_potential_sub(); for (i = 0; i < pos->dimensions[0]; i++) { *(float *)(pot->data + i*(pot->strides[0])) = Q[i].Potential; } free(Q); free(SphQ); return PyArray_Return(pot); } static PyObject * gadget_Acceleration(PyObject* self, PyObject *args) { PyArrayObject *pos; float eps; if (! PyArg_ParseTuple(args, "Of",&pos,&eps)) return PyString_FromString("error"); PyArrayObject *acc; int i; int input_dimension; size_t bytes; input_dimension =pos->nd; if (input_dimension != 2) PyErr_SetString(PyExc_ValueError,"dimension of first argument must be 2"); pos = TO_FLOAT(pos); /* create a NumPy object */ acc = (PyArrayObject *) PyArray_SimpleNew(pos->nd,pos->dimensions,PyArray_FLOAT); NumPartQ = pos->dimensions[0]; All.ForceSofteningQ = eps; if(!(Q = malloc(bytes = NumPartQ * sizeof(struct particle_data)))) { printf("failed to allocate memory for `Q' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(1); } if(!(SphQ = malloc(bytes = NumPartQ * sizeof(struct sph_particle_data)))) { printf("failed to allocate memory for `SphQ' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(1); } for (i = 0; i < pos->dimensions[0]; i++) { Q[i].Pos[0] = *(float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]); Q[i].Pos[1] = *(float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]); Q[i].Pos[2] = *(float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]); Q[i].Type = 0; Q[i].Mass = 0; Q[i].GravAccel[0] = 0; Q[i].GravAccel[1] = 0; Q[i].GravAccel[2] = 0; } gravity_tree_sub(); for (i = 0; i < pos->dimensions[0]; i++) { *(float *)(acc->data + i*(acc->strides[0]) + 0*acc->strides[1]) = Q[i].GravAccel[0]; *(float *)(acc->data + i*(acc->strides[0]) + 1*acc->strides[1]) = Q[i].GravAccel[1]; *(float *)(acc->data + i*(acc->strides[0]) + 2*acc->strides[1]) = Q[i].GravAccel[2]; } free(Q); free(SphQ); return PyArray_Return(acc); } static PyObject * gadget_InitHsml(PyObject* self, PyObject *args) { PyArrayObject *pos,*hsml; if (! PyArg_ParseTuple(args, "OO",&pos,&hsml)) return PyString_FromString("error"); int i; int input_dimension; size_t bytes; int ld[1]; PyArrayObject *vden,*vhsml; input_dimension =pos->nd; if (input_dimension != 2) PyErr_SetString(PyExc_ValueError,"dimension of first argument must be 2"); if (pos->dimensions[0] != hsml->dimensions[0]) PyErr_SetString(PyExc_ValueError,"pos and hsml must have the same dimension."); pos = TO_FLOAT(pos); hsml = TO_FLOAT(hsml); /* create a NumPy object */ ld[0]=pos->dimensions[0]; vden = (PyArrayObject *) PyArray_SimpleNew(1,pos->dimensions,pos->descr->type_num); vhsml = (PyArrayObject *) PyArray_SimpleNew(1,pos->dimensions,pos->descr->type_num); NumPartQ = pos->dimensions[0]; N_gasQ = NumPartQ; All.Ti_Current=1; /* need to flag active particles */ if(!(Q = malloc(bytes = NumPartQ * sizeof(struct particle_data)))) { printf("failed to allocate memory for `Q' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(1); } if(!(SphQ = malloc(bytes = NumPartQ * sizeof(struct sph_particle_data)))) { printf("failed to allocate memory for `SphQ' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(1); } for (i = 0; i < pos->dimensions[0]; i++) { Q[i].Pos[0] = *(float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]); Q[i].Pos[1] = *(float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]); Q[i].Pos[2] = *(float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]); SphQ[i].Hsml = *(float *) (hsml->data + i*(hsml->strides[0])); } setup_smoothinglengths_sub(); for (i = 0; i < pos->dimensions[0]; i++) { *(float *)(vhsml->data + i*(vhsml->strides[0])) = SphQ[i].Hsml; *(float *)(vden->data + i*(vden->strides[0])) = SphQ[i].Density; } free(Q); free(SphQ); return Py_BuildValue("OO",vden,vhsml); } static PyObject * gadget_Density(PyObject* self, PyObject *args) { PyArrayObject *pos,*hsml; if (! PyArg_ParseTuple(args, "OO",&pos,&hsml)) return PyString_FromString("error"); int i; int input_dimension; size_t bytes; int ld[1]; PyArrayObject *vden,*vhsml; input_dimension =pos->nd; if (input_dimension != 2) PyErr_SetString(PyExc_ValueError,"dimension of first argument must be 2"); if (pos->dimensions[0] != hsml->dimensions[0]) PyErr_SetString(PyExc_ValueError,"pos and hsml must have the same dimension."); pos = TO_FLOAT(pos); hsml = TO_FLOAT(hsml); /* create a NumPy object */ ld[0]=pos->dimensions[0]; vden = (PyArrayObject *) PyArray_SimpleNew(1,pos->dimensions,pos->descr->type_num); vhsml = (PyArrayObject *) PyArray_SimpleNew(1,pos->dimensions,pos->descr->type_num); NumPartQ = pos->dimensions[0]; N_gasQ = NumPartQ; All.Ti_Current=1; /* need to flag active particles */ if(!(Q = malloc(bytes = NumPartQ * sizeof(struct particle_data)))) { printf("failed to allocate memory for `Q' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(1); } if(!(SphQ = malloc(bytes = NumPartQ * sizeof(struct sph_particle_data)))) { printf("failed to allocate memory for `SphQ' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(1); } for (i = 0; i < pos->dimensions[0]; i++) { Q[i].Pos[0] = *(float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]); Q[i].Pos[1] = *(float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]); Q[i].Pos[2] = *(float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]); SphQ[i].Hsml = *(float *) (hsml->data + i*(hsml->strides[0])); } density_sub(); for (i = 0; i < pos->dimensions[0]; i++) { *(float *)(vhsml->data + i*(vhsml->strides[0])) = SphQ[i].Hsml; *(float *)(vden->data + i*(vden->strides[0])) = SphQ[i].Density; } free(Q); free(SphQ); return Py_BuildValue("OO",vden,vhsml); } static PyObject * gadget_SphEvaluate(PyObject* self, PyObject *args) { PyArrayObject *pos,*hsml,*obs; if (! PyArg_ParseTuple(args, "OOO",&pos,&hsml,&obs)) return PyString_FromString("error"); int i; int input_dimension; size_t bytes; int ld[1]; PyArrayObject *vobs; input_dimension =pos->nd; if (input_dimension != 2) PyErr_SetString(PyExc_ValueError,"dimension of first argument must be 2"); if (pos->dimensions[0] != hsml->dimensions[0]) PyErr_SetString(PyExc_ValueError,"pos and hsml must have the same dimension."); if (obs->nd != 1) PyErr_SetString(PyExc_ValueError,"dimension of obs must be 1."); if (obs->dimensions[0] != NumPart) PyErr_SetString(PyExc_ValueError,"The size of obs must be NumPart."); pos = TO_FLOAT(pos); hsml = TO_FLOAT(hsml); obs = TO_FLOAT(obs); /* create a NumPy object */ ld[0]=pos->dimensions[0]; vobs = (PyArrayObject *) PyArray_SimpleNew(1,pos->dimensions,pos->descr->type_num); NumPartQ = pos->dimensions[0]; N_gasQ = NumPartQ; All.Ti_Current=1; /* need to flag active particles */ if(!(Q = malloc(bytes = NumPartQ * sizeof(struct particle_data)))) { printf("failed to allocate memory for `Q' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(1); } if(!(SphQ = malloc(bytes = NumPartQ * sizeof(struct sph_particle_data)))) { printf("failed to allocate memory for `SphQ' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(1); } for (i = 0; i < pos->dimensions[0]; i++) { Q[i].Pos[0] = *(float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]); Q[i].Pos[1] = *(float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]); Q[i].Pos[2] = *(float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]); SphQ[i].Hsml = *(float *) (hsml->data + i*(hsml->strides[0])); } /* now, give observable value for P */ for (i = 0; i < NumPart; i++) { SphP[i].Observable = *(float *) (obs->data + i*(obs->strides[0])); } sph_sub(); for (i = 0; i < pos->dimensions[0]; i++) { *(float *)(vobs->data + i*(vobs->strides[0])) = SphQ[i].Observable; } free(Q); free(SphQ); return Py_BuildValue("O",vobs); } static PyObject * gadget_Ngbs(PyObject* self, PyObject *args) { PyArrayObject *pos; float eps; if (! PyArg_ParseTuple(args, "Of",&pos,&eps)) return PyString_FromString("error"); PyArrayObject *poss; int i,j,n,nn; int input_dimension; size_t bytes; int startnode,numngb; int phase=0; FLOAT searchcenter[3]; double dx,dy,dz,r2,eps2; input_dimension =pos->nd; if (input_dimension != 1) PyErr_SetString(PyExc_ValueError,"dimension of first argument must be 1"); pos = TO_FLOAT(pos); eps2 = eps*eps; searchcenter[0] = (FLOAT)*(float *) (pos->data + 0*(pos->strides[0])); searchcenter[1] = (FLOAT)*(float *) (pos->data + 1*(pos->strides[0])); searchcenter[2] = (FLOAT)*(float *) (pos->data + 2*(pos->strides[0])); startnode = All.MaxPart; /* ici, il faut faire une fct qui fonctionne en //, cf hydra --> Exportflag */ numngb = ngb_treefind_pairs(&searchcenter[0], (FLOAT)eps, phase, &startnode); nn=0; for(n = 0;n < numngb; n++) { j = Ngblist[n]; dx = searchcenter[0] - P[j].Pos[0]; dy = searchcenter[1] - P[j].Pos[1]; dz = searchcenter[2] - P[j].Pos[2]; r2 = dx * dx + dy * dy + dz * dz; if (r2<=eps2) { printf("%d r=%g\n",nn,sqrt(r2)); nn++; } } return PyArray_Return(pos); } static PyObject * gadget_SphEvaluateOrigAll(PyObject* self, PyObject *args) { PyArrayObject *obs; if (! PyArg_ParseTuple(args, "O",&obs)) return PyString_FromString("error"); int i; size_t bytes; int ld[1]; PyArrayObject *vobs; if (obs->nd != 1) PyErr_SetString(PyExc_ValueError,"dimension of obs must be 1."); if (obs->dimensions[0] != NumPart) PyErr_SetString(PyExc_ValueError,"The size of obs must be NumPart."); obs = TO_FLOAT(obs); /* create a NumPy object */ ld[0]=NumPart; vobs = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_FLOAT); /* flag all particles as active */ for (i = 0; i < NumPart; i++) P[i].Ti_endstep == All.Ti_Current; /* now, give observable value for P */ for (i = 0; i < NumPart; i++) { SphP[i].Observable = *(float *) (obs->data + i*(obs->strides[0])); } sph_orig(); for (i = 0; i < NumPart; i++) { *(float *)(vobs->data + i*(vobs->strides[0])) = SphP[i].Observable; } return Py_BuildValue("O",vobs); } static PyObject * gadget_SphEvaluateAll(PyObject* self, PyObject *args) { PyArrayObject *obs; if (! PyArg_ParseTuple(args, "O",&obs)) return PyString_FromString("error"); int i; size_t bytes; int ld[1]; PyArrayObject *vobs; if (obs->nd != 1) PyErr_SetString(PyExc_ValueError,"dimension of obs must be 1."); if (obs->dimensions[0] != NumPart) PyErr_SetString(PyExc_ValueError,"The size of obs must be NumPart."); obs = TO_FLOAT(obs); /* create a NumPy object */ ld[0]=NumPart; vobs = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_FLOAT); /* flag all particles as active */ for (i = 0; i < NumPart; i++) P[i].Ti_endstep == All.Ti_Current; /* now, give observable value for P */ for (i = 0; i < NumPart; i++) { SphP[i].Observable = *(float *) (obs->data + i*(obs->strides[0])); } sph(); for (i = 0; i < NumPart; i++) { *(float *)(vobs->data + i*(vobs->strides[0])) = SphP[i].Observable; } return Py_BuildValue("O",vobs); } static PyObject * gadget_SphEvaluateGradientAll(PyObject* self, PyObject *args) { PyArrayObject *obs; if (! PyArg_ParseTuple(args, "O",&obs)) return PyString_FromString("error"); int i; size_t bytes; npy_intp ld[2]; PyArrayObject *grad; if (obs->nd != 1) PyErr_SetString(PyExc_ValueError,"dimension of obs must be 1."); if (obs->dimensions[0] != NumPart) PyErr_SetString(PyExc_ValueError,"The size of obs must be NumPart."); obs = TO_FLOAT(obs); All.Ti_Current=1; /* need to flag active particles */ /* now, give observable value for P */ for (i = 0; i < NumPart; i++) { SphP[i].Observable = *(float *) (obs->data + i*(obs->strides[0])); } sph(); /* create a NumPy object */ ld[0] = NumPart; ld[1] = 3; grad = (PyArrayObject *) PyArray_SimpleNew(2,ld,PyArray_FLOAT); for (i = 0; i < NumPart; i++) { *(float *) (grad->data + i*(grad->strides[0]) + 0*grad->strides[1]) = SphP[i].GradObservable[0]; *(float *) (grad->data + i*(grad->strides[0]) + 1*grad->strides[1]) = SphP[i].GradObservable[1]; *(float *) (grad->data + i*(grad->strides[0]) + 2*grad->strides[1]) = SphP[i].GradObservable[2]; } return PyArray_Return(grad); } static PyObject * gadget_DensityEvaluateAll(PyObject* self, PyObject *args) { int i; /* flag all particles as active */ //All.Ti_Current=1; /* need to flag active particles */ for (i = 0; i < NumPart; i++) P[i].Ti_endstep == All.Ti_Current; density(0); return Py_BuildValue("i",1); } static PyObject * gadget_DensityEvaluateGradientAll(PyObject* self, PyObject *args) { PyArrayObject *obs; if (! PyArg_ParseTuple(args, "O",&obs)) return PyString_FromString("error"); int i; size_t bytes; npy_intp ld[2]; PyArrayObject *grad; if (obs->nd != 1) PyErr_SetString(PyExc_ValueError,"dimension of obs must be 1."); if (obs->dimensions[0] != NumPart) PyErr_SetString(PyExc_ValueError,"The size of obs must be NumPart."); obs = TO_FLOAT(obs); //All.Ti_Current=1; /* need to flag active particles */ for (i = 0; i < NumPart; i++) P[i].Ti_endstep == All.Ti_Current; /* now, give observable value for P */ for (i = 0; i < NumPart; i++) { SphP[i].Observable = *(float *) (obs->data + i*(obs->strides[0])); } density_sph_gradient(); /* create a NumPy object */ ld[0] = NumPart; ld[1] = 3; grad = (PyArrayObject *) PyArray_SimpleNew(2,ld,PyArray_FLOAT); for (i = 0; i < NumPart; i++) { *(float *) (grad->data + i*(grad->strides[0]) + 0*grad->strides[1]) = SphP[i].GradObservable[0]; *(float *) (grad->data + i*(grad->strides[0]) + 1*grad->strides[1]) = SphP[i].GradObservable[1]; *(float *) (grad->data + i*(grad->strides[0]) + 2*grad->strides[1]) = SphP[i].GradObservable[2]; } return PyArray_Return(grad); } static PyObject * gadget_EvaluateThermalConductivity(PyObject* self, PyObject *args) { PyArrayObject *obs; if (! PyArg_ParseTuple(args, "O",&obs)) return PyString_FromString("error"); int i; size_t bytes; npy_intp ld[2]; PyArrayObject *grad; if (obs->nd != 1) PyErr_SetString(PyExc_ValueError,"dimension of obs must be 1."); if (obs->dimensions[0] != NumPart) PyErr_SetString(PyExc_ValueError,"The size of obs must be NumPart."); obs = TO_FLOAT(obs); //All.Ti_Current=1; /* need to flag active particles */ for (i = 0; i < NumPart; i++) P[i].Ti_endstep == All.Ti_Current; /* now, give observable value for P */ for (i = 0; i < NumPart; i++) { SphP[i].Observable = *(float *) (obs->data + i*(obs->strides[0])); } density_sph_gradient(); // equivalent of SphP[i].GradEnergyInt[0] is now in //SphP[i].GradObservable[0] //SphP[i].GradObservable[1] //SphP[i].GradObservable[2] /* now, compute thermal conductivity */ sph_thermal_conductivity(); /* create a NumPy object */ ld[0] = NumPart; ld[1] = 3; grad = (PyArrayObject *) PyArray_SimpleNew(2,ld,PyArray_FLOAT); for (i = 0; i < NumPart; i++) { *(float *) (grad->data + i*(grad->strides[0]) + 0*grad->strides[1]) = SphP[i].GradObservable[0]; *(float *) (grad->data + i*(grad->strides[0]) + 1*grad->strides[1]) = SphP[i].GradObservable[1]; *(float *) (grad->data + i*(grad->strides[0]) + 2*grad->strides[1]) = SphP[i].GradObservable[2]; } return PyArray_Return(grad); } static PyObject *gadget_LoadParticles2(PyObject *self, PyObject *args, PyObject *kwds) { int i,j; size_t bytes; PyArrayObject *ntype,*pos,*vel,*mass,*num,*tpe; static char *kwlist[] = {"npart", "pos","vel","mass","num","tpe", NULL}; if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOOO",kwlist,&ntype,&pos,&vel,&mass,&num,&tpe)) return Py_BuildValue("i",1); /* check type */ if (!(PyArray_Check(pos))) { PyErr_SetString(PyExc_ValueError,"aruments 1 must be array."); return NULL; } /* check type */ if (!(PyArray_Check(mass))) { PyErr_SetString(PyExc_ValueError,"aruments 2 must be array."); return NULL; } /* check dimension */ if ( (pos->nd!=2)) { PyErr_SetString(PyExc_ValueError,"Dimension of argument 1 must be 2."); return NULL; } /* check dimension */ if ( (mass->nd!=1)) { PyErr_SetString(PyExc_ValueError,"Dimension of argument 2 must be 1."); return NULL; } /* check size */ if ( (pos->dimensions[1]!=3)) { PyErr_SetString(PyExc_ValueError,"First size of argument must be 3."); return NULL; } /* check size */ if ( (pos->dimensions[0]!=mass->dimensions[0])) { PyErr_SetString(PyExc_ValueError,"Size of argument 1 must be similar to argument 2."); return NULL; } /* ensure double */ // ntype = TO_INT(ntype); // pos = TO_FLOAT(pos); // vel = TO_FLOAT(vel); // mass = TO_FLOAT(mass); // num = TO_FLOAT(num); // tpe = TO_FLOAT(tpe); /*************************************** * some inits * /***************************************/ RestartFlag = 0; Begrun1(); /*************************************** * LOAD PARTILES * /***************************************/ NumPart = 0; N_gas = *(int*) (ntype->data + 0*(ntype->strides[0])); for (i = 0; i < 6; i++) NumPart += *(int*) (ntype->data + i*(ntype->strides[0])); if (NumPart!=pos->dimensions[0]) { PyErr_SetString(PyExc_ValueError,"Numpart != pos->dimensions[0]."); return NULL; } MPI_Allreduce(&NumPart, &All.TotNumPart, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); MPI_Allreduce(&N_gas, &All.TotN_gas, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); All.MaxPart = All.PartAllocFactor * (All.TotNumPart / NTask); All.MaxPartSph = All.PartAllocFactor * (All.TotN_gas / NTask); /*********************/ /* allocate P */ /*********************/ if(!(P = malloc(bytes = All.MaxPart * sizeof(struct particle_data)))) { printf("failed to allocate memory for `P' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(1); } if(!(SphP = malloc(bytes = All.MaxPartSph * sizeof(struct sph_particle_data)))) { printf("failed to allocate memory for `SphP' (%g MB) %d.\n", bytes / (1024.0 * 1024.0), sizeof(struct sph_particle_data)); endrun(1); } /*********************/ /* init P */ /*********************/ float * fpt; for (i = 0; i < NumPart; i++) { //P[i].Pos[0] = *(float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]); //P[i].Pos[1] = *(float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]); //P[i].Pos[2] = *(float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]); //&P[i].Pos[0] = (float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]); //&P[i].Pos[1] = (float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]); //&P[i].Pos[2] = (float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]); fpt = (float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]); P[i].Vel[0] = *(float *) (vel->data + i*(vel->strides[0]) + 0*vel->strides[1]); P[i].Vel[1] = *(float *) (vel->data + i*(vel->strides[0]) + 1*vel->strides[1]); P[i].Vel[2] = *(float *) (vel->data + i*(vel->strides[0]) + 2*vel->strides[1]); P[i].Mass = *(float *) (mass->data + i*(mass->strides[0])); P[i].ID = *(unsigned int *) (num->data + i*(num->strides[0])); P[i].Type = *(int *) (tpe->data + i*(tpe->strides[0])); //P[i].Active = 1; } /*************************************** * END LOAD PARTILES * /***************************************/ /*************************************** * finish inits * /***************************************/ Begrun2(); return Py_BuildValue("i",1); } static PyObject *gadget_domain_Decomposition(PyObject *self, PyObject *args, PyObject *kwds) { All.NumForcesSinceLastDomainDecomp = 1 + All.TotNumPart * All.TreeDomainUpdateFrequency; Flag_FullStep = 1; /* to ensure that Peano-Hilber order is done */ domain_Decomposition(); return Py_BuildValue("i",1); } static PyObject *gadget_gravity_tree(PyObject *self, PyObject *args, PyObject *kwds) { gravity_tree(); return Py_BuildValue("i",1); } #ifdef TESSEL static PyObject *gadget_ConstructDelaunay(PyObject *self, PyObject *args, PyObject *kwds) { ConstructDelaunay(); return Py_BuildValue("i",1); } static PyObject *gadget_ComputeVoronoi(PyObject *self, PyObject *args, PyObject *kwds) { ComputeVoronoi(); return Py_BuildValue("i",1); } static PyObject *gadget_ComputeTesselAccelerations(PyObject *self, PyObject *args, PyObject *kwds) { tessel_compute_accelerations(); return Py_BuildValue("i",1); } static PyObject *gadget_InitvEntropy(PyObject *self, PyObject *args, PyObject *kwds) { tessel_convert_energy_to_entropy(); return Py_BuildValue("i",1); } static PyObject *gadget_tessel_drift(PyObject *self, PyObject *args, PyObject *kwds) { float dt; if (!PyArg_ParseTuple(args,"f",&dt)) return NULL; tessel_drift(dt); return Py_BuildValue("i",1); } static PyObject *gadget_tessel_kick(PyObject *self, PyObject *args, PyObject *kwds) { float dt; if (!PyArg_ParseTuple(args,"f",&dt)) return NULL; tessel_kick(dt); return Py_BuildValue("i",1); } static PyObject *gadget_tessel_get_timestep(PyObject *self, PyObject *args, PyObject *kwds) { double dt; dt = tessel_get_timestep(); return Py_BuildValue("f",(float)dt); } +static PyObject *gadget_tessel_dump_triangles(PyObject *self, PyObject *args, PyObject *kwds) + { + + char *filename; + if (!PyArg_ParseTuple(args, "s", &filename)) + return NULL; + + dump_triangles(filename); + return Py_BuildValue("i",1); + } + +static PyObject *gadget_tessel_dump_voronoi(PyObject *self, PyObject *args, PyObject *kwds) + { + + char *filename; + if (!PyArg_ParseTuple(args, "s", &filename)) + return NULL; + + dump_voronoi(filename); + return Py_BuildValue("i",1); + } #endif /*TESSEL*/ /* definition of the method table */ static PyMethodDef gadgetMethods[] = { {"Info", (PyCFunction)gadget_Info, METH_VARARGS, "give some info"}, {"InitMPI", (PyCFunction)gadget_InitMPI, METH_VARARGS, "Init MPI"}, {"InitDefaultParameters", (PyCFunction)gadget_InitDefaultParameters, METH_VARARGS, "Init default parameters"}, {"GetParameters", (PyCFunction)gadget_GetParameters, METH_VARARGS, "get gadget parameters"}, {"SetParameters", (PyCFunction)gadget_SetParameters, METH_VARARGS, "Set gadget parameters"}, {"check_parser", (PyCFunction)gadget_check_parser, METH_VARARGS|METH_KEYWORDS, "check the parser"}, {"LoadParticles", (PyCFunction)gadget_LoadParticles, METH_VARARGS|METH_KEYWORDS, "LoadParticles partilces"}, {"LoadParticlesQ", (PyCFunction)gadget_LoadParticlesQ, METH_VARARGS, "LoadParticles partilces Q"}, {"LoadParticles2", (PyCFunction)gadget_LoadParticles2, METH_VARARGS, "LoadParticles partilces"}, {"AllPotential", (PyCFunction)gadget_AllPotential, METH_VARARGS, "Computes the potential for each particle"}, {"AllAcceleration", (PyCFunction)gadget_AllAcceleration, METH_VARARGS, "Computes the gravitational acceleration for each particle"}, {"GetAllAcceleration", (PyCFunction)gadget_GetAllAcceleration, METH_VARARGS, "get the gravitational acceleration for each particle"}, {"GetAllPotential", (PyCFunction)gadget_GetAllPotential, METH_VARARGS, "get the potential for each particle"}, {"GetAllDensities", (PyCFunction)gadget_GetAllDensities, METH_VARARGS, "get the densities for each particle"}, {"GetAllHsml", (PyCFunction)gadget_GetAllHsml, METH_VARARGS, "get the sph smoothing length for each particle"}, {"GetAllPositions", (PyCFunction)gadget_GetAllPositions, METH_VARARGS, "get the position for each particle"}, {"GetAllVelocities", (PyCFunction)gadget_GetAllVelocities, METH_VARARGS, "get the velocities for each particle"}, {"GetAllMasses", (PyCFunction)gadget_GetAllMasses, METH_VARARGS, "get the mass for each particle"}, {"GetAllEnergySpec", (PyCFunction)gadget_GetAllEnergySpec, METH_VARARGS, "get the specific energy for each particle"}, {"GetAllEntropy", (PyCFunction)gadget_GetAllEntropy, METH_VARARGS, "get the entropy for each particle"}, {"GetAllID", (PyCFunction)gadget_GetAllID, METH_VARARGS, "get the ID for each particle"}, {"GetAllTypes", (PyCFunction)gadget_GetAllTypes, METH_VARARGS, "get the type for each particle"}, {"GetPos", (PyCFunction)gadget_GetPos, METH_VARARGS, "get the position for each particle (no memory overhead)"}, {"Potential", (PyCFunction)gadget_Potential, METH_VARARGS, "get the potential for a givent sample of points"}, {"Acceleration", (PyCFunction)gadget_Acceleration, METH_VARARGS, "get the acceleration for a givent sample of points"}, {"SphEvaluateOrigAll", (PyCFunction)gadget_SphEvaluateOrigAll, METH_VARARGS, "run the original sph routine."}, {"SphEvaluateAll", (PyCFunction)gadget_SphEvaluateAll, METH_VARARGS, "compute mean value of a given field based on the sph convolution for all points."}, {"SphEvaluateGradientAll", (PyCFunction)gadget_SphEvaluateGradientAll, METH_VARARGS, "compute the gradient of a given field based on the sph convolution for all points."}, {"DensityEvaluateAll", (PyCFunction)gadget_DensityEvaluateAll, METH_VARARGS, "simply run the density function"}, {"DensityEvaluateGradientAll", (PyCFunction)gadget_DensityEvaluateGradientAll, METH_VARARGS, "run the modified density function and compute a gradient from the given value"}, {"EvaluateThermalConductivity", (PyCFunction)gadget_EvaluateThermalConductivity, METH_VARARGS, "evaluate the thermal coductivity for each particle"}, {"SphEvaluate", (PyCFunction)gadget_SphEvaluate, METH_VARARGS, "compute mean value based on the sph convolution for a given number of points"}, {"InitHsml", (PyCFunction)gadget_InitHsml, METH_VARARGS, "Init hsml based on the three for a given number of points"}, {"Density", (PyCFunction)gadget_Density, METH_VARARGS, "compute Density based on the three for a given number of points"}, {"Ngbs", (PyCFunction)gadget_Ngbs, METH_VARARGS, "return the position of the neighbors for a given point"}, {"GetAllPositionsQ", (PyCFunction)gadget_GetAllPositionsQ, METH_VARARGS, "get the position for each particle Q"}, {"GetAllVelocitiesQ", (PyCFunction)gadget_GetAllVelocitiesQ, METH_VARARGS, "get the velocities for each particle Q"}, {"GetAllMassesQ", (PyCFunction)gadget_GetAllMassesQ, METH_VARARGS, "get the mass for each particle Q"}, {"GetAllIDQ", (PyCFunction)gadget_GetAllIDQ, METH_VARARGS, "get the ID for each particle Q"}, {"GetAllTypesQ", (PyCFunction)gadget_GetAllTypesQ, METH_VARARGS, "get the type for each particle Q"}, {"Free", (PyCFunction)gadget_Free, METH_VARARGS, "release memory"}, {"domain_Decomposition", (PyCFunction)gadget_domain_Decomposition, METH_VARARGS, "call domain_Decomposition"}, {"gravity_tree", (PyCFunction)gadget_gravity_tree, METH_VARARGS, "call gravity_tree"}, #ifdef TESSEL {"ConstructDelaunay", (PyCFunction)gadget_ConstructDelaunay, METH_VARARGS, "Construct the Delaunay tesselation"}, {"ComputeVoronoi", (PyCFunction)gadget_ComputeVoronoi, METH_VARARGS, "Compute the Voronoi tesselation"}, {"ComputeTesselAccelerations", (PyCFunction)gadget_ComputeTesselAccelerations, METH_VARARGS, "Compute the acceleration using the tesselation"}, {"InitvEntropy", (PyCFunction)gadget_InitvEntropy, METH_VARARGS, "Initialize vEntropy using internal energy."}, {"tessel_drift", (PyCFunction)gadget_tessel_drift, METH_VARARGS, "drift particles"}, {"tessel_kick", (PyCFunction)gadget_tessel_kick, METH_VARARGS, "kick particles"}, {"tessel_get_timestep", (PyCFunction)gadget_tessel_get_timestep, METH_VARARGS, "get timestep for tessel"}, + {"tessel_dump_triangles", (PyCFunction)gadget_tessel_dump_triangles, METH_VARARGS, + "dump triangles"}, + + {"tessel_dump_voronoi", (PyCFunction)gadget_tessel_dump_voronoi, METH_VARARGS, + "dump voronoi"}, + + + {"GetAllDelaunayTriangles", (PyCFunction)gadget_GetAllDelaunayTriangles, METH_VARARGS, "Get all the Delaunay Triangles"}, {"GetAllvPoints", gadget_GetAllvPoints, METH_VARARGS, "Get voronoi points"}, {"GetAllvDensities", gadget_GetAllvDensities, METH_VARARGS, "Get voronoi density of all points"}, {"GetAllvVolumes", gadget_GetAllvVolumes, METH_VARARGS, "Get voronoi volumes of all points"}, {"GetAllvPressures", gadget_GetAllvPressures, METH_VARARGS, "Get voronoi presures of all points"}, {"GetAllvEnergySpec", gadget_GetAllvEnergySpec, METH_VARARGS, "Get voronoi energyspec of all points"}, {"GetAllvAccelerations", gadget_GetAllvAccelerations, METH_VARARGS, "Get voronoi accelerations of all points"}, {"GetvPointsForOnePoint", gadget_GetvPointsForOnePoint, METH_VARARGS, "Get voronoi points for a given point"}, {"GetNgbPointsForOnePoint", gadget_GetNgbPointsForOnePoint, METH_VARARGS, "Get neighbors points for a given point"}, {"GetNgbPointsAndFacesForOnePoint", gadget_GetNgbPointsAndFacesForOnePoint, METH_VARARGS, "Get neighbors points and faces for a given point"}, {"GetAllGhostPositions", gadget_GetAllGhostPositions, METH_VARARGS, "Get all positions of the ghosts points"}, {"GetAllGhostvDensities", gadget_GetAllGhostvDensities, METH_VARARGS, "Get all densities of the ghosts points"}, {"GetAllGhostvVolumes", gadget_GetAllGhostvVolumes, METH_VARARGS, - "Get all volumes of the ghosts points"}, + "Get all volumes of the ghosts points"}, + + + #endif {NULL, NULL, 0, NULL} /* Sentinel */ }; void initgadget(void) { (void) Py_InitModule("gadget", gadgetMethods); import_array(); } #endif /*PY_INTERFACE*/ diff --git a/src/tessel.c b/src/tessel.c index 632ecb6..aebbcf6 100644 --- a/src/tessel.c +++ b/src/tessel.c @@ -1,2819 +1,2985 @@ #ifdef TESSEL #include <math.h> #include <string.h> #include <stdio.h> #include <allvars.h> struct Face /* a list of edges (only for 3d tesselation) */ { }; struct Triangle { struct particle_data Pt1[3]; struct particle_data Pt2[3]; struct particle_data Pt3[3]; }; struct TriangleInList { int idx; /* index of current triangle (used for checks) */ struct particle_data* P[3]; /* pointers towards the 3 point */ struct TriangleInList* T[3]; /* pointers towards the 3 triangles */ int idxe[3]; /* index of point in the first triangle, opposite to the common edge */ struct Median* Med[3]; /* pointers towards 3 medians */ }; struct Median { double a; /* params for the equation of the segemnt */ double b; /* params for the equation of the segemnt */ double c; /* params for the equation of the segemnt */ struct vPoint *vPs; /* pointer towards starting vPoint of the segment */ struct vPoint *vPe; /* pointer towards stoping vPoint of the segment */ struct particle_data *Pa; /* pointer towards point A*/ struct particle_data *Pb; /* pointer towards point B*/ }; /* a voronoi point */ struct vPoint { double Pos[3]; int next; }; /* LOCAL VARIABLES */ #define MAXNUMTRIANGLES 1000000 int nT=0,numTinStack=0; /* number of triangles in the list */ struct TriangleInList Triangles[MAXNUMTRIANGLES]; /* list of triangles */ struct TriangleInList *TStack[MAXNUMTRIANGLES]; /* index of triangles to check */ struct Median MediansList[3*MAXNUMTRIANGLES][3]; int nvPoints=0; /* number of Voronoi Points */ int nMedians=0; /* number of Medians */ struct vPoint vPoints[5*MAXNUMTRIANGLES]; struct Median Medians[5*MAXNUMTRIANGLES]; double tesselDomainRadius,tesselDomainCenter[3]; struct particle_data Pe[3]; /* edges */ void setup_searching_radius() { int i; for(i=0;i<NumPart;i++) P[i].rSearch=0.1/10000; } void lines_intersections(double a0, double b0, double c0, double a1, double b1, double c1, double *x, double *y) { *x = (c1*b0 - c0*b1)/(a0*b1 - a1*b0); *y = (c1*a0 - c0*a1)/(a1*b0 - a0*b1); } /*! */ struct Triangle TriangleInList2Triangle(struct TriangleInList Tl) { struct Triangle T; T.Pt1->Pos[0] = Tl.P[0]->Pos[0]; T.Pt1->Pos[1] = Tl.P[0]->Pos[1]; T.Pt2->Pos[0] = Tl.P[1]->Pos[0]; T.Pt2->Pos[1] = Tl.P[1]->Pos[1]; T.Pt3->Pos[0] = Tl.P[2]->Pos[0]; T.Pt3->Pos[1] = Tl.P[2]->Pos[1]; return T; } /*! For a set of three points, construct a triangle */ struct Triangle MakeTriangleFromPoints(struct particle_data Pt1,struct particle_data Pt2,struct particle_data Pt3) { struct Triangle T; T.Pt1->Pos[0] = Pt1.Pos[0]; T.Pt1->Pos[1] = Pt1.Pos[1]; T.Pt2->Pos[0] = Pt2.Pos[0]; T.Pt2->Pos[1] = Pt2.Pos[1]; T.Pt3->Pos[0] = Pt3.Pos[0]; T.Pt3->Pos[1] = Pt3.Pos[1]; return T; } /*! For a set of three points, this function computes the 3 medians. */ void TriangleMedians(struct particle_data Pt1,struct particle_data Pt2,struct particle_data Pt3,struct particle_data *Pmm1,struct particle_data *Pmm2,struct particle_data *Pmm3,struct particle_data *Pme1,struct particle_data *Pme2,struct particle_data *Pme3) { double ma1,mb1,mc1; double ma2,mb2,mc2; double ma3,mb3,mc3; /* median 0-1 */ ma1 = 2*(Pt2.Pos[0] - Pt1.Pos[0]); mb1 = 2*(Pt2.Pos[1] - Pt1.Pos[1]); mc1 = (Pt1.Pos[0]*Pt1.Pos[0]) - (Pt2.Pos[0]*Pt2.Pos[0]) + (Pt1.Pos[1]*Pt1.Pos[1]) - (Pt2.Pos[1]*Pt2.Pos[1]); /* median 1-2 */ ma2 = 2*(Pt3.Pos[0] - Pt2.Pos[0]); mb2 = 2*(Pt3.Pos[1] - Pt2.Pos[1]); mc2 = (Pt2.Pos[0]*Pt2.Pos[0]) - (Pt3.Pos[0]*Pt3.Pos[0]) + (Pt2.Pos[1]*Pt2.Pos[1]) - (Pt3.Pos[1]*Pt3.Pos[1]); /* median 2-0 */ ma3 = 2*(Pt1.Pos[0] - Pt3.Pos[0]); mb3 = 2*(Pt1.Pos[1] - Pt3.Pos[1]); mc3 = (Pt3.Pos[0]*Pt3.Pos[0]) - (Pt1.Pos[0]*Pt1.Pos[0]) + (Pt3.Pos[1]*Pt3.Pos[1]) - (Pt1.Pos[1]*Pt1.Pos[1]); /* intersection m0-1 -- m1-2 */ Pmm1->Pos[0] = (mc2*mb1 - mc1*mb2)/(ma1*mb2 - ma2*mb1); Pmm1->Pos[1] = (mc2*ma1 - mc1*ma2)/(ma2*mb1 - ma1*mb2); /* intersection m1-2 -- m2-0 */ Pmm2->Pos[0] = (mc2*mb1 - mc1*mb2)/(ma1*mb2 - ma2*mb1); Pmm2->Pos[1] = (mc2*ma1 - mc1*ma2)/(ma2*mb1 - ma1*mb2); /* intersection m2-0 -- m0-1 */ Pmm3->Pos[0] = (mc2*mb1 - mc1*mb2)/(ma1*mb2 - ma2*mb1); Pmm3->Pos[1] = (mc2*ma1 - mc1*ma2)/(ma2*mb1 - ma1*mb2); /* intersection m1-2 -- e1-2 */ Pme1->Pos[0] = 0.5*(Pt1.Pos[0] + Pt2.Pos[0]); Pme1->Pos[1] = 0.5*(Pt1.Pos[1] + Pt2.Pos[1]); /* intersection m2-3 -- e3-1 */ Pme2->Pos[0] = 0.5*(Pt2.Pos[0] + Pt3.Pos[0]); Pme2->Pos[1] = 0.5*(Pt2.Pos[1] + Pt3.Pos[1]); /* intersection m3-1 -- e1-2 */ Pme3->Pos[0] = 0.5*(Pt3.Pos[0] + Pt1.Pos[0]); Pme3->Pos[1] = 0.5*(Pt3.Pos[1] + Pt1.Pos[1]); } /*! For a set of three points, this function computes their cirum-circle. * Its radius is return, while the center is return using pointers. */ double CircumCircleProperties(struct particle_data Pt1,struct particle_data Pt2,struct particle_data Pt3, double *xc, double *yc) { double r; double x21,x32,y21,y32; double x12mx22,y12my22,x22mx32,y22my32; double c1,c2; x21 = Pt2.Pos[0]-Pt1.Pos[0]; x32 = Pt3.Pos[0]-Pt2.Pos[0]; y21 = Pt2.Pos[1]-Pt1.Pos[1]; y32 = Pt3.Pos[1]-Pt2.Pos[1]; x12mx22 = (Pt1.Pos[0]*Pt1.Pos[0])-(Pt2.Pos[0]*Pt2.Pos[0]); y12my22 = (Pt1.Pos[1]*Pt1.Pos[1])-(Pt2.Pos[1]*Pt2.Pos[1]); x22mx32 = (Pt2.Pos[0]*Pt2.Pos[0])-(Pt3.Pos[0]*Pt3.Pos[0]); y22my32 = (Pt2.Pos[1]*Pt2.Pos[1])-(Pt3.Pos[1]*Pt3.Pos[1]); c1 = x12mx22 + y12my22; c2 = x22mx32 + y22my32; *xc = (y32*c1 - y21*c2)/2.0/( x32*y21 - x21*y32 ); *yc = (x32*c1 - x21*c2)/2.0/( x21*y32 - x32*y21 ); r = sqrt( (Pt1.Pos[0]-*xc)*(Pt1.Pos[0]-*xc) + (Pt1.Pos[1]-*yc)*(Pt1.Pos[1]-*yc) ) ; return r; } /*! For a given triangle T, the routine tells if the point P4 is in the circum circle of the triangle or not. */ int InCircumCircle(struct Triangle T,struct particle_data Pt4) { double a,b,c; double d,e,f; double g,h,i; double det; /* a = T.Pt1->Pos[0] - Pt4.Pos[0]; b = T.Pt1->Pos[1] - Pt4.Pos[1]; c = (T.Pt1->Pos[0]*T.Pt1->Pos[0] - Pt4.Pos[0]*Pt4.Pos[0]) + (T.Pt1->Pos[1]*T.Pt1->Pos[1] - Pt4.Pos[1]*Pt4.Pos[1]); d = T.Pt2->Pos[0] - Pt4.Pos[0]; e = T.Pt2->Pos[1] - Pt4.Pos[1]; f = (T.Pt2->Pos[0]*T.Pt2->Pos[0] - Pt4.Pos[0]*Pt4.Pos[0]) + (T.Pt2->Pos[1]*T.Pt2->Pos[1] - Pt4.Pos[1]*Pt4.Pos[1]); g = T.Pt3->Pos[0] - Pt4.Pos[0]; h = T.Pt3->Pos[1] - Pt4.Pos[1]; i = (T.Pt3->Pos[0]*T.Pt3->Pos[0] - Pt4.Pos[0]*Pt4.Pos[0]) + (T.Pt3->Pos[1]*T.Pt3->Pos[1] - Pt4.Pos[1]*Pt4.Pos[1]); */ /* Volker Formula */ a = T.Pt2->Pos[0] - T.Pt1->Pos[0]; b = T.Pt2->Pos[1] - T.Pt1->Pos[1]; c = a*a + b*b; d = T.Pt3->Pos[0] - T.Pt1->Pos[0]; e = T.Pt3->Pos[1] - T.Pt1->Pos[1]; f = d*d + e*e; g = Pt4.Pos[0] - T.Pt1->Pos[0]; h = Pt4.Pos[1] - T.Pt1->Pos[1]; i = g*g + h*h; det = a*e*i - a*f*h - b*d*i + b*f*g + c*d*h - c*e*g; if (det<0) return 1; /* inside */ else return 0; /* outside */ } /*! For a given triangle T, the routine tells if the point P4 lie inside the triangle or not. */ int InTriangle(struct Triangle T,struct particle_data Pt4) { double c1,c2,c3; /* here, we use the cross product */ c1 = (T.Pt2->Pos[0]-T.Pt1->Pos[0])*(Pt4.Pos[1]-T.Pt1->Pos[1]) - (T.Pt2->Pos[1]-T.Pt1->Pos[1])*(Pt4.Pos[0]-T.Pt1->Pos[0]); c2 = (T.Pt3->Pos[0]-T.Pt2->Pos[0])*(Pt4.Pos[1]-T.Pt2->Pos[1]) - (T.Pt3->Pos[1]-T.Pt2->Pos[1])*(Pt4.Pos[0]-T.Pt2->Pos[0]); c3 = (T.Pt1->Pos[0]-T.Pt3->Pos[0])*(Pt4.Pos[1]-T.Pt3->Pos[1]) - (T.Pt1->Pos[1]-T.Pt3->Pos[1])*(Pt4.Pos[0]-T.Pt3->Pos[0]); if ( (c1>0) && (c2>0) && (c3>0) ) /* inside */ return 1; else return 0; } int InTriangleOrOutside(struct Triangle T,struct particle_data Pt4) { double c1,c2,c3; c1 = (T.Pt2->Pos[0]-T.Pt1->Pos[0])*(Pt4.Pos[1]-T.Pt1->Pos[1]) - (T.Pt2->Pos[1]-T.Pt1->Pos[1])*(Pt4.Pos[0]-T.Pt1->Pos[0]); if (c1<0) return 2; /* to triangle T[2] */ c2 = (T.Pt3->Pos[0]-T.Pt2->Pos[0])*(Pt4.Pos[1]-T.Pt2->Pos[1]) - (T.Pt3->Pos[1]-T.Pt2->Pos[1])*(Pt4.Pos[0]-T.Pt2->Pos[0]); if (c2<0) return 0; /* to triangle T[1] */ c3 = (T.Pt1->Pos[0]-T.Pt3->Pos[0])*(Pt4.Pos[1]-T.Pt3->Pos[1]) - (T.Pt1->Pos[1]-T.Pt3->Pos[1])*(Pt4.Pos[0]-T.Pt3->Pos[0]); if (c3<0) return 1; /* to triangle T[0] */ return -1; /* the point is inside */ } /*! For a given triangle, orient it positively. */ struct Triangle OrientTriangle(struct Triangle T) { double a,b,c,d; double det; struct particle_data Ptsto; a = T.Pt2->Pos[0] - T.Pt1->Pos[0]; b = T.Pt2->Pos[1] - T.Pt1->Pos[1]; c = T.Pt3->Pos[0] - T.Pt1->Pos[0]; d = T.Pt3->Pos[1] - T.Pt1->Pos[1]; det = (a*d) - (b*c); if (det<0) { Ptsto.Pos[0] = T.Pt1->Pos[0]; Ptsto.Pos[1] = T.Pt1->Pos[1]; T.Pt1->Pos[0] = T.Pt3->Pos[0]; T.Pt1->Pos[1] = T.Pt3->Pos[1]; T.Pt3->Pos[0] = Ptsto.Pos[0]; T.Pt3->Pos[1] = Ptsto.Pos[1]; T = OrientTriangle(T); } return T; } /*! For a given triangle, orient it positively. */ struct TriangleInList OrientTriangleInList(struct TriangleInList T) { double a,b,c,d; double det; struct particle_data Ptsto; a = T.P[1]->Pos[0] - T.P[0]->Pos[0]; b = T.P[1]->Pos[1] - T.P[0]->Pos[1]; c = T.P[2]->Pos[0] - T.P[0]->Pos[0]; d = T.P[2]->Pos[1] - T.P[0]->Pos[1]; det = (a*d) - (b*c); if (det<0) { Ptsto.Pos[0] = T.P[0]->Pos[0]; Ptsto.Pos[1] = T.P[0]->Pos[1]; T.P[0]->Pos[0] = T.P[2]->Pos[0]; T.P[0]->Pos[1] = T.P[2]->Pos[1]; T.P[2]->Pos[0] = Ptsto.Pos[0]; T.P[2]->Pos[1] = Ptsto.Pos[1]; T = OrientTriangleInList(T); } return T; } /*! This function computes the extension of the domain. * It computes: * len : max-min * tesselDomainCenter : min + 0.5*len * tesselDomainRadius = len*1.5; */ void FindTesselExtent() { int i,j; double xmin[3], xmax[3],len; /* determine local extension */ for(j = 0; j < 3; j++) { xmin[j] = MAX_REAL_NUMBER; xmax[j] = -MAX_REAL_NUMBER; } for(i = 0; i < NumPart; i++) { for(j = 0; j < 3; j++) { if(xmin[j] > P[i].Pos[j]) xmin[j] = P[i].Pos[j]; if(xmax[j] < P[i].Pos[j]) xmax[j] = P[i].Pos[j]; } } len = 0; for(j = 0; j < 3; j++) { if(xmax[j] - xmin[j] > len) len = xmax[j] - xmin[j]; } for(j = 0; j < 3; j++) tesselDomainCenter[j] = xmin[j] + len/2.; tesselDomainRadius = len*2; printf("tesselDomainRadius = %g\n",tesselDomainRadius); printf("tesselDomainCenter = (%g %g)\n",tesselDomainCenter[0],tesselDomainCenter[1]); } int FindSegmentInTriangle(struct TriangleInList *T,double v,struct particle_data P[3]) { double v0,v1,v2; double x0,x1,x2; double y0,y1,y2; double f; double x,y; int iP; /* if the triangle as an edge point, do nothing */ if ( (T->P[0]==&Pe[0]) || (T->P[1]==&Pe[0]) || (T->P[2]==&Pe[0]) ) return 0; /* if the triangle as an edge point, do nothing */ if ( (T->P[0]==&Pe[1]) || (T->P[1]==&Pe[1]) || (T->P[2]==&Pe[1]) ) return 0; /* if the triangle as an edge point, do nothing */ if ( (T->P[0]==&Pe[2]) || (T->P[1]==&Pe[2]) || (T->P[2]==&Pe[2]) ) return 0; iP = 0; v0 = T->P[0]->Mass; v1 = T->P[1]->Mass; v2 = T->P[2]->Mass; //printf("Triangle %d : %g %g %g\n",T->idx,v0,v1,v2); /* we could also use the sign v-v0 * v-v1 ??? */ if (( ((v>v0)&&(v<v1)) || ((v>v1)&&(v<v0)) )&& (v0 != v1)) /* in 0-1 */ { x0 = T->P[0]->Pos[0]; y0 = T->P[0]->Pos[1]; x1 = T->P[1]->Pos[0]; y1 = T->P[1]->Pos[1]; f = (v-v0)/(v1-v0); P[iP].Pos[0] = f*(x1-x0) + x0; P[iP].Pos[1] = f*(y1-y0) + y0; iP++; } if (( ((v>v1)&&(v<v2)) || ((v>v2)&&(v<v1)) )&& (v1 != v2)) /* in 1-2 */ { x0 = T->P[1]->Pos[0]; y0 = T->P[1]->Pos[1]; x1 = T->P[2]->Pos[0]; y1 = T->P[2]->Pos[1]; f = (v-v1)/(v2-v1); P[iP].Pos[0] = f*(x1-x0) + x0; P[iP].Pos[1] = f*(y1-y0) + y0; iP++; } if (( ((v>v2)&&(v<v0)) || ((v>v0)&&(v<v2)) )&& (v2 != v0)) /* in 2-0 */ { x0 = T->P[2]->Pos[0]; y0 = T->P[2]->Pos[1]; x1 = T->P[0]->Pos[0]; y1 = T->P[0]->Pos[1]; f = (v-v2)/(v0-v2); P[iP].Pos[0] = f*(x1-x0) + x0; P[iP].Pos[1] = f*(y1-y0) + y0; iP++; } return iP; } void CheckTriangles(void) { int iT; struct TriangleInList *T,*Te; for (iT=0;iT<nT;iT++) { T = &Triangles[iT]; Te = T->T[0]; if (Te!=NULL) { if ((Te->T[0]!=NULL)&&(Te->T[0] == T)) { } else if ((Te->T[1]!=NULL)&&(Te->T[1] == T)) { } else if ((Te->T[2]!=NULL)&&(Te->T[2] == T)) { } else { printf("Triangle %d does not point towards %d, while T->T2=%d\n",Te->idx,T->idx,T->T[0]->idx); exit(-1); } } Te = T->T[1]; if (Te!=NULL) { if ((Te->T[0]!=NULL)&&(Te->T[0] == T)) { } else if ((Te->T[1]!=NULL)&&(Te->T[1] == T)) { } else if ((Te->T[2]!=NULL)&&(Te->T[2] == T)) { } else { printf("Triangle %d does not point towards %d, while T->T2=%d\n",Te->idx,T->idx,T->T[1]->idx); exit(-1); } } Te = T->T[2]; if (Te!=NULL) { if ((Te->T[0]!=NULL)&&(Te->T[0] == T)) { } else if ((Te->T[1]!=NULL)&&(Te->T[1] == T)) { } else if ((Te->T[2]!=NULL)&&(Te->T[2] == T)) { } else { printf("Triangle %d does not point towards %d, while T->T2=%d\n",Te->idx,T->idx,T->T[2]->idx); exit(-1); } } } } void CheckPoints(int n) { int i,p,iT; for (i=0;i<n;i++) { /* find p */ iT = P[i].iT; p=-1; if (Triangles[iT].P[0]==&P[i]) p=0; else if (Triangles[iT].P[1]==&P[i]) p=1; else if (Triangles[iT].P[2]==&P[i]) p=2; // printf(" ---> i=%d (id=%d) iT=%d \n",i,P[i].ID,iT); // printf(" P.ID=%d%09d\n", (int) (Triangles[iT].P[0]->ID / 1000000000), (int) (Triangles[iT].P[0]->ID % 1000000000)); // printf(" P.ID=%d%09d\n", (int) (Triangles[iT].P[1]->ID / 1000000000), (int) (Triangles[iT].P[1]->ID % 1000000000)); // printf(" P.ID=%d%09d\n", (int) (Triangles[iT].P[2]->ID / 1000000000), (int) (Triangles[iT].P[2]->ID % 1000000000)); if (p==-1) endrun(-123555); //printf("%d ok\n",i); } } /*! Flip two triangles. Te = T.T[i] */ void FlipTriangle(int i,struct TriangleInList *T,struct TriangleInList *Te,struct TriangleInList *T1,struct TriangleInList *T2) { struct TriangleInList Ts1,Ts2; int i0,i1,i2; int j0,j1,j2; int j; Ts1 = *T; /* save the content of the pointed triangle */ Ts2 = *Te; /* save the content of the pointed triangle */ j = T->idxe[i]; /* index of point opposite to i */ i0= i; i1= (i+1) % 3; i2= (i+2) % 3; j0= j; j1= (j+1) % 3; j2= (j+2) % 3; /* triangle 1 */ T1->P[0] = Ts1.P[i0]; T1->P[1] = Ts1.P[i1]; T1->P[2] = Ts2.P[j0]; T1->T[0] = Ts2.T[j1]; T1->T[1] = T2; T1->T[2] = Ts1.T[i2]; T1->idxe[0] = Ts2.idxe[j1]; T1->idxe[1] = 1; T1->idxe[2] = Ts1.idxe[i2]; /* triangle 2 */ T2->P[0] = Ts2.P[j0]; T2->P[1] = Ts2.P[j1]; T2->P[2] = Ts1.P[i0]; /* restore links with points */ // if (Ts1.P[i0]->iT==Ts1.idx) // Ts1.P[i0]->iT=T1->idx; // if (Ts1.P[i1]->iT==Ts1.idx) // Ts1.P[i1]->iT=T1->idx; if (Ts1.P[i2]->iT==Ts1.idx) Ts1.P[i2]->iT=T2->idx; /* if (Ts2.P[j0]->iT==Ts2.idx) Ts2.P[j0]->iT=T2->idx; if (Ts2.P[j1]->iT==Ts2.idx) Ts2.P[j1]->iT=T2->idx; */ if (Ts2.P[j2]->iT==Ts2.idx) Ts2.P[j2]->iT=T1->idx; T2->T[0] = Ts1.T[i1]; T2->T[1] = T1; T2->T[2] = Ts2.T[j2]; T2->idxe[0] = Ts1.idxe[i1]; T2->idxe[1] = 1; T2->idxe[2] = Ts2.idxe[j2]; /* restore links with adjacents triangles */ if (Ts1.T[i1]!=NULL) { Ts1.T[i1]->T[ Ts1.idxe[i1] ] = T2; Ts1.T[i1]->idxe[ Ts1.idxe[i1] ] = 0; } if (Ts1.T[i2] !=NULL) { Ts1.T[i2]->T[ Ts1.idxe[i2] ] = T1; Ts1.T[i2]->idxe[ Ts1.idxe[i2] ] = 2; } if (Ts2.T[j1] !=NULL) { Ts2.T[j1]->T[ Ts2.idxe[j1] ] = T1; Ts2.T[j1]->idxe[ Ts2.idxe[j1] ] = 0; } if (Ts2.T[j2] !=NULL) { Ts2.T[j2]->T[ Ts2.idxe[j2] ] = T2; Ts2.T[j2]->idxe[ Ts2.idxe[j2] ] = 2; } } void DoTrianglesInStack(void) { struct TriangleInList *T,*Te,*T1,*T2,*Tee; struct TriangleInList Ts1,Ts2; struct particle_data Pt; int istack; int idx1,idx2; int i; istack=0; while(numTinStack>0) { int insphere=0; T = TStack[istack]; //printf(" DoInStack T=%d (istack=%d, numTinStack=%d)\n",T->idx,istack,numTinStack); /* find the opposite point of the 3 adjacent triangles */ /*******************/ /* triangle 1 */ /*******************/ i = 0; Te = T->T[i]; if (Te!=NULL) { /* index of opposite point */ Pt = *Te->P[T->idxe[i]]; insphere = InCircumCircle(TriangleInList2Triangle(*T),Pt); if (insphere) { //printf("insphere (1)... %g %g %g in T=%d\n",Pt.Pos[0],Pt.Pos[1],Pt.Pos[2],T->idx); /* index of the new triangles */ idx1 = T->idx; idx2 = Te->idx; T1 = &Triangles[idx1]; T2 = &Triangles[idx2]; FlipTriangle(i,T,Te,T1,T2); /* add triangles in stack */ if (numTinStack+1>MAXNUMTRIANGLES) { printf("\nNo more memory !\n"); printf("numTinStack+1=%d > MAXNUMTRIANGLES=%d\n",numTinStack+1,MAXNUMTRIANGLES); printf("You should increase MAXNUMTRIANGLES\n\n"); exit(-1); } TStack[istack ] = T1; TStack[istack+numTinStack] = T2; numTinStack++; continue; } } /*******************/ /* triangle 2 */ /*******************/ i = 1; Te = T->T[i]; if (Te!=NULL) { /* index of opposite point */ Pt = *Te->P[T->idxe[i]]; insphere = InCircumCircle(TriangleInList2Triangle(*T),Pt); if (insphere) { //printf("insphere (2)... %g %g %g in T=%d\n",Pt.Pos[0],Pt.Pos[1],Pt.Pos[2],T->idx); /* index of the new triangles */ idx1 = T->idx; idx2 = Te->idx; T1 = &Triangles[idx1]; T2 = &Triangles[idx2]; FlipTriangle(i,T,Te,T1,T2); /* add triangles in stack */ if (numTinStack+1>MAXNUMTRIANGLES) { printf("\nNo more memory !\n"); printf("numTinStack+1=%d > MAXNUMTRIANGLES=%d\n",numTinStack+1,MAXNUMTRIANGLES); printf("You should increase MAXNUMTRIANGLES\n\n"); exit(-1); } TStack[istack ] = T1; TStack[istack+numTinStack] = T2; numTinStack++; continue; } } /*******************/ /* triangle 3 */ /*******************/ i = 2; Te = T->T[i]; if (Te!=NULL) { /* index of opposite point */ Pt = *Te->P[T->idxe[i]]; insphere = InCircumCircle(TriangleInList2Triangle(*T),Pt); if (insphere) { //printf("insphere (3)... %g %g %g in T=%d\n",Pt.Pos[0],Pt.Pos[1],Pt.Pos[2],T->idx); /* index of the new triangles */ idx1 = T->idx; idx2 = Te->idx; T1 = &Triangles[idx1]; T2 = &Triangles[idx2]; FlipTriangle(i,T,Te,T1,T2); /* add triangles in stack */ if (numTinStack+1>MAXNUMTRIANGLES) { printf("\nNo more memory !\n"); printf("numTinStack+1=%d > MAXNUMTRIANGLES=%d\n",numTinStack+1,MAXNUMTRIANGLES); printf("You should increase MAXNUMTRIANGLES\n\n"); exit(-1); } TStack[istack ] = T1; TStack[istack+numTinStack] = T2; numTinStack++; continue; } } numTinStack--; istack++; //printf("one triangle less...(istack=%d numTinStack=%d)\n",istack,numTinStack); } } void Check(void) { int iT; printf("===========================\n"); for(iT=0;iT<nT;iT++) { printf("* T %d\n",Triangles[iT].idx); printf("pt1 %g %g %g\n",Triangles[iT].P[0]->Pos[0],Triangles[iT].P[0]->Pos[1],Triangles[iT].P[0]->Pos[2]); printf("pt2 %g %g %g\n",Triangles[iT].P[1]->Pos[0],Triangles[iT].P[1]->Pos[1],Triangles[iT].P[1]->Pos[2]); printf("pt3 %g %g %g\n",Triangles[iT].P[2]->Pos[0],Triangles[iT].P[2]->Pos[1],Triangles[iT].P[2]->Pos[2]); if (Triangles[iT].T[0]!=NULL) printf("T1 %d\n",Triangles[iT].T[0]->idx); else printf("T1 x\n"); if (Triangles[iT].T[1]!=NULL) printf("T2 %d\n",Triangles[iT].T[1]->idx); else printf("T2 x\n"); if (Triangles[iT].T[2]!=NULL) printf("T3 %d\n",Triangles[iT].T[2]->idx); else printf("T3 x\n"); } printf("===========================\n"); } /*! Split a triangle in 3, using the point P inside it. Update the global list. */ void SplitTriangle(struct TriangleInList *pT,struct particle_data *Pt) { struct TriangleInList T,*T0,*T1,*T2,*Te; int idx,idx0,idx1,idx2; T = *pT; /* save the content of the pointed triangle */ idx = T.idx; /* index of the new triangles */ idx0 = idx; idx1 = nT; idx2 = nT+1; /* increment counter */ nT=nT+2; /* check memory */ if (nT>MAXNUMTRIANGLES) { printf("\nNo more memory !\n"); printf("nT=%d > MAXNUMTRIANGLES=%d\n",nT,MAXNUMTRIANGLES); printf("You should increase MAXNUMTRIANGLES\n\n"); exit(-1); } /* create pointers towards the triangles */ T0 = &Triangles[idx0]; T1 = &Triangles[idx1]; T2 = &Triangles[idx2]; /* first */ T0->idx = idx0; T0->P[0] = T.P[0]; T0->P[1] = T.P[1]; T0->P[2] = Pt; /* second */ T1->idx = idx1; T1->P[0] = T.P[1]; T1->P[1] = T.P[2]; T1->P[2] = Pt; /* third */ T2->idx = idx2; T2->P[0] = T.P[2]; T2->P[1] = T.P[0]; T2->P[2] = Pt; /* link points with triangles */ /* the new point Pt belongs to the 3 new triangle, link it to the first */ Pt->iT = idx0; /* if P[0] points towards the old Triangle, link it with T0 */ if (T.P[0]->iT==T.idx) { T.P[0]->iT=T0->idx; } /* if P[1] points towards the old Triangle, link it with T1 */ if (T.P[1]->iT==T.idx) { T.P[1]->iT=T1->idx; } /* if P[2] points towards the old Triangle, link it with T2 */ if (T.P[2]->iT==T.idx) { T.P[2]->iT=T2->idx; } /* add adjacents */ T0->T[0] = T1; T0->T[1] = T2; T0->T[2] = T.T[2]; T1->T[0] = T2; T1->T[1] = T0; T1->T[2] = T.T[0]; T2->T[0] = T0; T2->T[1] = T1; T2->T[2] = T.T[1]; /* add ext point */ T0->idxe[0] = 1; T0->idxe[1] = 0; T0->idxe[2] = T.idxe[2]; T1->idxe[0] = 1; T1->idxe[1] = 0; T1->idxe[2] = T.idxe[0]; T2->idxe[0] = 1; T2->idxe[1] = 0; T2->idxe[2] = T.idxe[1]; /* restore links with adgacents triangles */ Te = T0->T[2]; if (Te!=NULL) { Te->T[ T0->idxe[2]] = T0; Te->idxe[T0->idxe[2]] = 2; } Te = T1->T[2]; if (Te!=NULL) { Te->T[ T1->idxe[2]] = T1; Te->idxe[T1->idxe[2]] = 2; } Te = T2->T[2]; if (Te!=NULL) { Te->T[ T2->idxe[2]] = T2; Te->idxe[T2->idxe[2]] = 2; } /* add the new triangles in the stack */ TStack[numTinStack] = T0; numTinStack++; TStack[numTinStack] = T1; numTinStack++; TStack[numTinStack] = T2; numTinStack++; //printf("--> add in stack %d %d %d\n",T0->idx,T1->idx,T2->idx); } int FindTriangle(struct particle_data *Pt) { int iT; /* find triangle containing the point */ for(iT=0;iT<nT;iT++) /* loop over all triangles */ { if (InTriangle(TriangleInList2Triangle( Triangles[iT] ),*Pt)) break; } return iT; } int NewFindTriangle(struct particle_data *Pt) { int iT; struct TriangleInList *T; int e; iT = 0; /* star with first triangle */ T = &Triangles[iT]; while (1) { /* test position of the point relative to the triangle */ e = InTriangleOrOutside(TriangleInList2Triangle( *T ),*Pt); //printf("T=%d e=%d Te=%d\n",T->idx,e,T->T[e]->idx); if (e==-1) /* the point is inside */ break; T = T->T[e]; if (T==NULL) { printf("point lie outside the limits.\n"); printf("Pt x=%g y=%g z=%g\n",Pt->Pos[0],Pt->Pos[1],Pt->Pos[2]); endrun(-1); } } //printf("done with find triangle (T=%d)\n",T->idx); return T->idx; } /*! Add a new point in the tesselation */ void AddPoint(struct particle_data *Pt) { int iT; /* find the triangle that contains the point P */ //iT= FindTriangle(Pt); //printf("Find triangle...\n"); iT= NewFindTriangle(Pt); /* create the new triangles */ //printf("Split triangle...\n"); SplitTriangle(&Triangles[iT],Pt); /* test the new triangles and divide and modify if necessary */ //printf("Do triangles in stack...\n"); DoTrianglesInStack(); /* check */ //CheckTriangles(); } void AddGhostPoints(int istart,int nadd) { int i; if (ThisTask==0) printf("%d new ghost points\n",nadd); /* loop over all ghostpoints */ for (i=istart;i<istart+nadd;i++) { AddPoint(&P[i]); //printf("check after %d\n",i); CheckTriangles(); } if (ThisTask==0) printf("%d triangles\n",nT); CheckTriangles(); printf("check ok\n"); } /*! Add gost points to the tesselation */ void ExtendWithGhostPoints() { size_t bytes; /* all particles try to find ngbs particles that lie in another proc */ if (ThisTask==0) printf("ExtendWithGhostPoints...\n"); All.MaxgPart=All.MaxPart; NumgPart=0; /* if(!(gP = malloc(bytes = All.MaxgPart * sizeof(struct ghost_particle_data)))) { printf("failed to allocate memory for `gP' (%g MB).\n", bytes / (1024.0 * 1024.0)); endrun(1); } */ ghost(); /* free(gP);*/ if (ThisTask==0) printf("ExtendWithGhostPoints done.\n"); } /*! Compute all medians properties (a,b,c) * For each triangle, for each edge, the function computes the * median properties which is stored in MediansList */ void ComputeMediansProperties() { int iT; /* loop over all triangles */ for(iT=0;iT<nT;iT++) { struct particle_data Pt0,Pt1,Pt2; Pt0.Pos[0] = Triangles[iT].P[0]->Pos[0]; Pt0.Pos[1] = Triangles[iT].P[0]->Pos[1]; Pt1.Pos[0] = Triangles[iT].P[1]->Pos[0]; Pt1.Pos[1] = Triangles[iT].P[1]->Pos[1]; Pt2.Pos[0] = Triangles[iT].P[2]->Pos[0]; Pt2.Pos[1] = Triangles[iT].P[2]->Pos[1]; /* median 0-1 */ MediansList[iT][2].a = 2*(Pt1.Pos[0] - Pt0.Pos[0]); MediansList[iT][2].b = 2*(Pt1.Pos[1] - Pt0.Pos[1]); MediansList[iT][2].c = (Pt0.Pos[0]*Pt0.Pos[0]) - (Pt1.Pos[0]*Pt1.Pos[0]) + (Pt0.Pos[1]*Pt0.Pos[1]) - (Pt1.Pos[1]*Pt1.Pos[1]); /* median 1-2 */ MediansList[iT][0].a = 2*(Pt2.Pos[0] - Pt1.Pos[0]); MediansList[iT][0].b = 2*(Pt2.Pos[1] - Pt1.Pos[1]); MediansList[iT][0].c = (Pt1.Pos[0]*Pt1.Pos[0]) - (Pt2.Pos[0]*Pt2.Pos[0]) + (Pt1.Pos[1]*Pt1.Pos[1]) - (Pt2.Pos[1]*Pt2.Pos[1]); /* median 2-0 */ MediansList[iT][1].a = 2*(Pt0.Pos[0] - Pt2.Pos[0]); MediansList[iT][1].b = 2*(Pt0.Pos[1] - Pt2.Pos[1]); MediansList[iT][1].c = (Pt2.Pos[0]*Pt2.Pos[0]) - (Pt0.Pos[0]*Pt0.Pos[0]) + (Pt2.Pos[1]*Pt2.Pos[1]) - (Pt0.Pos[1]*Pt0.Pos[1]); /* link The triangle with the MediansList */ Triangles[iT].Med[0] = &MediansList[iT][0]; /* median 1-2 */ Triangles[iT].Med[1] = &MediansList[iT][1]; /* median 2-0 */ Triangles[iT].Med[2] = &MediansList[iT][2]; /* median 0-1 */ } } /*! Compute the intersetions of medians around a point of index p (index of the point in the triangle T) * */ void ComputeMediansAroundPoint(struct TriangleInList *Tstart,int iPstart) { /* Tstart : pointer to first triangle iPstart : index of master point relative to triangle Tstart if p = 0: T1 = T0->T[iTn]; pn=1 if p = 1: T1 = T0->T[iTn]; pn=2 if p = 0: T1 = T0->T[iTn]; pn=3 iTn = (p+1) % 3; */ double x,y; struct TriangleInList *T0,*T1; int iP0,iP1; int iT1; struct particle_data *initialPoint; int iM0,iM1; int next_Median=-1; /* index towards next median */ int number_of_vPoints=0; int number_of_Medians=0; int next; int initialvPoint; T0 = Tstart; iP0 = iPstart; initialPoint = T0->P[iP0]; initialPoint->ivPoint=nvPoints; initialvPoint=nvPoints; //printf("\n--> rotating around T=%d p=%d\n",T0->idx,iP0); /* rotate around the point */ while (1) { /* next triangle */ iT1= (iP0+1) % 3; T1 = T0->T[iT1]; if (T1==NULL) { //printf("reach an edge\n"); T0->P[iP0]->IsDone=2; //printf("%g %g\n",T0->P[iP0]->Pos[0],T0->P[iP0]->Pos[1]); return; } //printf(" next triangle = %d\n",T1->idx); /* index of point in the triangle */ iP1 = T0->idxe[iT1]; /* index of point opposite to iTn */ iP1 = (iP1+1) % 3; /* next index of point opposite to iTn */ //printf(" initial point=%g %g current point =%g %g iP1=%d\n",initialPoint->Pos[0],initialPoint->Pos[1],T1->P[iP1]->Pos[0],T1->P[iP1]->Pos[1],iP1); /* check */ if (initialPoint!=T1->P[iP1]) { printf(" problem : initial point=%g %g current point =%g %g iP1=%d\n",initialPoint->Pos[0],initialPoint->Pos[1],T1->P[iP1]->Pos[0],T1->P[iP1]->Pos[1],iP1); exit(-1); } /* compute the intersection of the two medians */ iM0 = (iP0+1) % 3; iM1 = (iP1+1) % 3; lines_intersections(T0->Med[iM0]->a,T0->Med[iM0]->b,T0->Med[iM0]->c,T1->Med[iM1]->a,T1->Med[iM1]->b,T1->Med[iM1]->c,&x,&y); /* create a new vPoint and put it to the vPoints list */ vPoints[nvPoints].Pos[0] = x; vPoints[nvPoints].Pos[1] = y; vPoints[nvPoints].Pos[2] = 0.5; vPoints[nvPoints].next = nvPoints+1; /* end point for T0 */ T0->Med[iM0]->vPe = &vPoints[nvPoints]; /* here, we could add the point to T0->Med[(iM0+2) % 3] as Ps */ /* start point for T0 */ T1->Med[iM1]->vPs = &vPoints[nvPoints]; /* here, we could add the point to T1->Med[(iM1+2) % 3] as Ps */ /* increment vPoints */ nvPoints++; number_of_vPoints++; if (T1==Tstart) /* end of loop */ { //printf(" end of loop\n"); initialPoint->nvPoints = number_of_vPoints; if (nvPoints-2<initialvPoint) { printf("this is bad... please check.\n"); endrun(-72354); } initialPoint->ivPoint = nvPoints-2; /* the current point points towards the previous-1 one */ vPoints[nvPoints-1].next = initialvPoint; /* close the loop : the last points towards the first */ /* create the median list */ /* first vPoint */ // next = initialPoint->ivPoint; // // for (j = 0; j < initialPoint->nvPoints; j++) // { // Medians[nMedians].vPe = vPoints[prev]; // Medians[nMedians].vPs = vPoints[next]; // next = vPoints[next].next; // } break; } T0 = T1; iP0 = iP1; } } /*! Compute all medians intersections and define Ps and Pe * For each triangle, compute the medians */ // void oldComputeMediansIntersections() // { // int i,p,iT; // // for (i=0;i<NumPart+NumgPart;i++) // P[i].IsDone = 0; // // /* loop over all triangles */ // for(iT=0;iT<nT;iT++) // { // /* loop over points in triangle */ // for(p=0;p<3;p++) // { // if (!(Triangles[iT].P[p]->IsDone)) // { // //printf("in Triangle T %d do point %d\n",iT,p); // Triangles[iT].P[p]->IsDone = 1; // ComputeMediansAroundPoint(&Triangles[iT],p); // } // } // } // } void ComputeMediansIntersections() { int i,p,iT; for (i=0;i<NumPart+NumgPart;i++) { /* find p */ iT = P[i].iT; p=-1; if (Triangles[iT].P[0]==&P[i]) p=0; else if (Triangles[iT].P[1]==&P[i]) p=1; else if (Triangles[iT].P[2]==&P[i]) p=2; if (p==-1) endrun(-12354); ComputeMediansAroundPoint(&Triangles[P[i].iT],p); } // /* do the same for edges */ // for (i=0;i<3;i++) // { // /* find p */ // iT = Pe[i].iT; // p=-1; // if (Triangles[iT].P[0]->ID==Pe[i].ID) // p=0; // else // if (Triangles[iT].P[1]->ID==Pe[i].ID) // p=1; // else // if (Triangles[iT].P[2]->ID==Pe[i].ID) // p=2; // // // if (p==-1) // endrun(-12354); // // ComputeMediansAroundPoint(&Triangles[Pe[i].iT],p); // } } /*! Compute the density for all particles */ int ComputeDensity() { int i,j; int next; /* next voronoi point */ int np; double x0,y0,x1,y1; double area; /* do the normal points first */ for(i=0;i<NumPart;i++) { next = P[i].ivPoint; np = P[i].nvPoints; x0 = 0; /* this ensure the first loop to give 0 */ y0 = 0; /* this ensure the first loop to give 0 */ area = 0; for (j = 0; j < np; j++) { x1 = vPoints[next].Pos[0]; y1 = vPoints[next].Pos[1]; area = area + (x0*y1 - x1*y0); x0 = x1; y0 = y1; next = vPoints[next].next; } /* connect the last with the first */ next = P[i].ivPoint; x1 = vPoints[next].Pos[0]; y1 = vPoints[next].Pos[1]; area = area + (x0*y1 - x1*y0); /* */ area = 0.5*fabs(area); P[i].Volume=area; P[i].Density=P[i].Mass/area; P[i].Pressure = (SphP[i].Entropy) * pow(P[i].Density, GAMMA); /* SphP[i].Entropy this is bad, as we use SphP */ } /* do the ghost points now */ for(i=NumPart;i<NumPart+NumgPart;i++) { P[i].Volume = P[P[i].iPref].Volume; P[i].Density= P[P[i].iPref].Density; P[i].Pressure = P[P[i].iPref].Pressure; } return 0; } /*! Compute the density for all particles */ int CheckCompletenessForThisPoint(int i) { /* loop over the triangles which contains the point */ /* first triangle */ int iT,iTstart; int p,iP0,iP1,iPnext0; struct TriangleInList *T,*Tnext,*Tstart; double rc,xc,yc,rcmax; iTstart = P[i].iT; Tstart=&Triangles[iTstart]; /* find index in the triangle */ p=-1; if (Tstart->P[0]==&P[i]) p=0; else if (Tstart->P[1]==&P[i]) p=1; else if (Tstart->P[2]==&P[i]) p=2; if (p==-1) endrun(-312354); iT = iTstart; /* index of triangle */ iP0 = p; /* index of the ref point "0" in the triangle */ T = Tstart; /* visit all triangles around the point */ rcmax=0; while (1) { /* compute circumcircle properties of the current tirangle T */ rc = CircumCircleProperties(*T->P[0],*T->P[1],*T->P[2], &xc, &yc); if (rc>rcmax) rcmax=rc; iP1 = (iP0+1) % 3 ; /* point 1 in the current triangle */ Tnext = T->T[iP1]; /* triangle opposit to iP1 */ if (Tnext==NULL) /* we reach an edge */ { printf("mmmh... why are we here ?"); endrun(-31235445); return -1; /* need to increase the size for this point */ } /* now, find the index of the ref. point in the next triangle */ iPnext0 = (T->idxe[iP1] + 1) % 3 ; /* check */ if (&P[i]!=Tnext->P[iPnext0]) //if (P[i].ID!=Tnext->P[iPnext0]->ID) { printf(" problem : initial point %d (id=%d x=%g y=%g z=%g) next-> (id=%d x=%g y=%g z=%g)\n",i,P[i].ID,P[i].Pos[0],P[i].Pos[1],P[i].Pos[2],Tnext->P[iPnext0]->ID,Tnext->P[i]->Pos[0],Tnext->P[i]->Pos[1],Tnext->P[i]->Pos[2]); endrun(-3123544); } /* end of loop */ if (Tnext==Tstart) break; iP0 = iPnext0; T = Tnext; } if (P[i].rSearch>2*rcmax) return 0; /* ok, no need to */ else { /* need to increase hi */ //printf("need to increase hi for i=%d %g %g \n",i,P[i].rSearch,2*rcmax); P[i].rSearch *= 1.5; return 1; } } /*! Construct the Delaunay tesselation */ int ConstructDelaunay() { int i,j; nT=0; if (ThisTask==0) printf("Start ConstructDelaunay...\n"); /* find domain extent */ FindTesselExtent(); /* set edges Pe, the 3 points are in an equilateral triangle around all particles */ for (j=0;j<3;j++) { Pe[j].Pos[0] = tesselDomainCenter[0] + tesselDomainRadius * cos(2./3.*PI*j)*2; Pe[j].Pos[1] = tesselDomainCenter[1] + tesselDomainRadius * sin(2./3.*PI*j)*2; Pe[j].Pos[2] = 0; Pe[j].Mass = 0; } /* Triangle list */ Triangles[0].idx = 0; Triangles[0].P[0] = &Pe[0]; Triangles[0].P[1] = &Pe[1]; Triangles[0].P[2] = &Pe[2]; Triangles[0].T[0] = NULL; Triangles[0].T[1] = NULL; Triangles[0].T[2] = NULL; Triangles[0].idxe[0] = -1; Triangles[0].idxe[1] = 1; Triangles[0].idxe[2] = -1; nT++; OrientTriangleInList(Triangles[0]); if (ThisTask==0) printf("Start local AddPoint in Delaunay.\n"); /* loop over all points */ for (i=0;i<NumPart;i++) { AddPoint(&P[i]); //CheckPoints(i-1); } if (ThisTask==0) printf("%d triangles\n",nT); /* add ghost points */ CheckTriangles(); printf("check after AddPoint local is ok\n"); ExtendWithGhostPoints(); /* check */ CheckTriangles(); CheckPoints(NumPart+NumgPart); if (ThisTask==0) printf("ConstructDelaunay done.\n"); + + } /*! Compute the Voronoi tesselation from the Delonay one */ int ComputeVoronoi() { if (ThisTask==0) printf("Start ComputeVoronoi...\n"); ComputeMediansProperties(); ComputeMediansIntersections(); ComputeDensity(); if (ThisTask==0) printf("ComputeVoronoi done.\n"); } /*! Compute accelerations */ void tessel_convert_energy_to_entropy() { #ifndef ISOTHERM_EQS int i; double a3=1; if(All.ComovingIntegrationOn) a3 = (All.Time * All.Time * All.Time); else a3 = 1; if(header.flag_entropy_instead_u == 0) for(i = 0; i < N_gas; i++) { P[i].Entropy = GAMMA_MINUS1 * SphP[i].Entropy / pow(P[i].Density / a3, GAMMA_MINUS1); } #endif } /*! Compute accelerations */ void tessel_compute_accelerations() { int i; int np; /* first triangle */ int iT,iTstart; int p,iP0,iP1,iPnext0; struct TriangleInList *T,*Tnext,*Tstart; double acc[3]; double dx, dy, dz; double Rij,Aij; double eij[3],mpij[3],cmij[3],cij[3]; struct particle_data *Pi,*Pj; struct vPoint *vP1,*vP2; int nextvp1,nextvp2; double PjpPi,PjmPi; for(i=0;i<N_gas;i++) { /* some init */ acc[0] = acc[1] = acc[2] = 0; Pi=&P[i]; np=0; iTstart = P[i].iT; Tstart=&Triangles[iTstart]; /* find index in the triangle */ p=-1; if (Tstart->P[0]==&P[i]) p=0; else if (Tstart->P[1]==&P[i]) p=1; else if (Tstart->P[2]==&P[i]) p=2; if (p==-1) endrun(-712354); iT = iTstart; /* index of triangle */ iP0 = p; /* index of the ref point "0" in the triangle */ T = Tstart; np = 0; nextvp1 = Pi->ivPoint; /* visit all triangles around the point */ while (1) { iP1 = (iP0+1) % 3 ; /* point 1 in the current triangle */ Tnext = T->T[iP1]; /* triangle opposit to iP1 */ if (Tnext==NULL) /* we reach an edge */ { printf("mmmh... why are we here ?"); endrun(-71235445); return -1; /* need to increase the size for this point */ } /* we have a ngb point */ np++; Pj = T->P[iP1]; nextvp2 = vPoints[nextvp1].next; vP1 = &vPoints[nextvp1]; vP2 = &vPoints[nextvp2]; dx = Pi->Pos[0] - Pj->Pos[0]; dy = Pi->Pos[1] - Pj->Pos[1]; dz = Pi->Pos[2] - Pj->Pos[2]; Rij = sqrt(dx * dx + dy * dy + dz * dz); eij[0] = (Pj->Pos[0]-Pi->Pos[0])/Rij ; eij[1] = (Pj->Pos[1]-Pi->Pos[1])/Rij ; eij[2] = (Pj->Pos[2]-Pi->Pos[2])/Rij ; /* mid point between i and j */ mpij[0] = 0.5*(Pj->Pos[0]+Pi->Pos[0]) ; mpij[1] = 0.5*(Pj->Pos[1]+Pi->Pos[1]) ; mpij[2] = 0.5*(Pj->Pos[2]+Pi->Pos[2]) ; #ifdef TWODIMS /* center of mass of the face */ cmij[0] = 0.5*(vP1->Pos[0]+vP2->Pos[0]); cmij[1] = 0.5*(vP1->Pos[1]+vP2->Pos[1]); cmij[2] = 0.5*(vP1->Pos[2]+vP2->Pos[2]); /* area of the face */ dx = vP2->Pos[0]-vP1->Pos[0]; dy = vP2->Pos[1]-vP1->Pos[1]; dz = vP2->Pos[2]-vP1->Pos[2]; Aij = sqrt(dx * dx + dy * dy + dz * dz); #else need to compute mass center here #endif /* cij (mid point between ij, towards mass center of the face) cmij - mpij */ cij[0] = cmij[0]-mpij[0]; cij[1] = cmij[1]-mpij[1]; cij[2] = cmij[2]-mpij[2]; /* compute pressure */ PjpPi = Pj->Pressure + Pi->Pressure; PjmPi = Pj->Pressure - Pi->Pressure; /* now, the accelection */ acc[0] += -Aij*( 0.5*PjpPi*eij[0] + PjmPi*cij[0]/Rij); acc[1] += -Aij*( 0.5*PjpPi*eij[1] + PjmPi*cij[1]/Rij); acc[2] += -Aij*( 0.5*PjpPi*eij[2] + PjmPi*cij[2]/Rij); /* now, find the index of the ref. point in the next triangle */ iPnext0 = (T->idxe[iP1] + 1) % 3 ; /* check */ if (&P[i]!=Tnext->P[iPnext0]) //if (P[i].ID!=Tnext->P[iPnext0]->ID) { printf(" problem : initial point %d (id=%d x=%g y=%g z=%g) next-> (id=%d x=%g y=%g z=%g)\n",i,P[i].ID,P[i].Pos[0],P[i].Pos[1],P[i].Pos[2],Tnext->P[iPnext0]->ID,Tnext->P[i]->Pos[0],Tnext->P[i]->Pos[1],Tnext->P[i]->Pos[2]); endrun(-7123544); } /* end of loop */ if (Tnext==Tstart) break; iP0 = iPnext0; T = Tnext; nextvp1 = nextvp2; } P[i].tesselAccel[0] = acc[0]; P[i].tesselAccel[1] = acc[1]; P[i].tesselAccel[2] = acc[2]; } } void tessel_kick(float dt_kick) { int i,j; for(i = 0; i < NumPart; i++) { for(j = 0; j < 3; j++) P[i].Vel[j] += P[i].tesselAccel[j] * dt_kick; } } void tessel_drift(float dt_drift) { int i,j; for(i = 0; i < NumPart; i++) { for(j = 0; j < 3; j++) P[i].Pos[j] += P[i].Vel[j] * dt_drift; } } double tessel_get_timestep() { double ax, ay, az, ac, csnd, hsml; int i; double dt,dtmin; dtmin = 1e32; for(i = 0; i < NumPart; i++) { //ax = P[i].tesselAccel[0]; //ay = P[i].tesselAccel[1]; //az = P[i].tesselAccel[2]; //ac = sqrt(ax * ax + ay * ay + az * az); csnd = sqrt(GAMMA * P[i].Pressure / P[i].Density); #ifdef TWODIMS hsml = sqrt(P[i].Volume/PI); #else endrun("-787899"); #endif dt = 2 * All.CourantFac * hsml / csnd; if (dt<dtmin) dtmin = dt; } return dtmin; } +/************************************************************/ +/* */ +/* IO ROUTINES */ +/* */ +/************************************************************/ + + +#define SKIP {my_fwrite(&blksize,sizeof(int),1,fd);} + + + + + + +void dump_triangles(char *fname) + { + + int iT; + FILE *fd = 0; + int blksize; + double f; + int idx; + + //sprintf(fname,"%s%s_%04d","./","tria",1); + + + if(!(fd = fopen(fname, "w"))) + { + printf("can't open file `%s' for writing triangles.\n", fname); + } + else + { + /* number of triangles */ + blksize=sizeof(int); + SKIP; + my_fwrite(&nT, sizeof(nT), 1, fd); + SKIP; + + + /* triangles */ + blksize=sizeof(f)*nT*3*3; + SKIP; + + for (iT=0;iT<nT;iT++) + { + f = Triangles[iT].P[0]->Pos[0]; + my_fwrite(&f, sizeof(f), 1, fd); + f = Triangles[iT].P[0]->Pos[1]; + my_fwrite(&f, sizeof(f), 1, fd); + f = Triangles[iT].P[0]->Pos[2]; + my_fwrite(&f, sizeof(f), 1, fd); + + f = Triangles[iT].P[1]->Pos[0]; + my_fwrite(&f, sizeof(f), 1, fd); + f = Triangles[iT].P[1]->Pos[1]; + my_fwrite(&f, sizeof(f), 1, fd); + f = Triangles[iT].P[1]->Pos[2]; + my_fwrite(&f, sizeof(f), 1, fd); + + f = Triangles[iT].P[2]->Pos[0]; + my_fwrite(&f, sizeof(f), 1, fd); + f = Triangles[iT].P[2]->Pos[1]; + my_fwrite(&f, sizeof(f), 1, fd); + f = Triangles[iT].P[2]->Pos[2]; + my_fwrite(&f, sizeof(f), 1, fd); + } + + SKIP; + + /* triangles */ + blksize=sizeof(idx)*nT; + SKIP; + + for (iT=0;iT<nT;iT++) + { + idx = Triangles[iT].idx; + my_fwrite(&idx, sizeof(idx), 1, fd); + } + + SKIP; + + close(fd); + } + } + + + + +void dump_voronoi(char *fname) + { + + int i,j; + FILE *fd = 0; + int blksize; + double f; + int np; + int n; + + int next; + + + //sprintf(fname,"%s%s_%04d","./","tria",1); + + + if(!(fd = fopen(fname, "w"))) + { + printf("can't open file `%s' for writing voronoi.\n", fname); + } + else + { + + + n = NumPart+NumgPart; + + /* number of points */ + blksize=sizeof(int); + SKIP; + my_fwrite(&n, sizeof(n), 1, fd); + SKIP; + + + + for (i=0;i<n;i++) + { + + + next = P[i].ivPoint; + np = P[i].nvPoints; + + /* number of points in the cell */ + blksize=sizeof(int); + SKIP; + my_fwrite(&np, sizeof(np), 1, fd); + SKIP; + + + blksize=sizeof(f)*np*3; + SKIP; + + for (j = 0; j < np; j++) + { + + f = vPoints[next].Pos[0]; + my_fwrite(&f, sizeof(f), 1, fd); + f = vPoints[next].Pos[1]; + my_fwrite(&f, sizeof(f), 1, fd); + f = 0.5; + my_fwrite(&f, sizeof(f), 1, fd); + + next = vPoints[next].next; + + } + + SKIP; + + } + + + + close(fd); + } + } + + /************************************************************/ /* */ /* PYTHON INTERFACE */ /* */ /************************************************************/ #ifdef PY_INTERFACE #include <Python.h> #include <numpy/arrayobject.h> PyObject *gadget_GetAllDelaunayTriangles(self, args) PyObject *self; PyObject *args; { import_array(); /* needed but strange no ? */ PyObject *OutputList; PyObject *OutputDict; PyArrayObject *tri = NULL; npy_intp dim[2]; int iT; /* loop over all triangles */ OutputList = PyList_New(0); for (iT=0;iT<nT;iT++) { /* 3x3 vector */ dim[0]=3; dim[1]=3; tri = (PyArrayObject *) PyArray_SimpleNew(2,dim,PyArray_DOUBLE); *(double *) (tri->data + 0*(tri->strides[0]) + 0*tri->strides[1]) = Triangles[iT].P[0]->Pos[0]; *(double *) (tri->data + 0*(tri->strides[0]) + 1*tri->strides[1]) = Triangles[iT].P[0]->Pos[1]; *(double *) (tri->data + 0*(tri->strides[0]) + 2*tri->strides[1]) = 0; *(double *) (tri->data + 1*(tri->strides[0]) + 0*tri->strides[1]) = Triangles[iT].P[1]->Pos[0]; *(double *) (tri->data + 1*(tri->strides[0]) + 1*tri->strides[1]) = Triangles[iT].P[1]->Pos[1]; *(double *) (tri->data + 1*(tri->strides[0]) + 2*tri->strides[1]) = 0; *(double *) (tri->data + 2*(tri->strides[0]) + 0*tri->strides[1]) = Triangles[iT].P[2]->Pos[0]; *(double *) (tri->data + 2*(tri->strides[0]) + 1*tri->strides[1]) = Triangles[iT].P[2]->Pos[1]; *(double *) (tri->data + 2*(tri->strides[0]) + 2*tri->strides[1]) = 0; OutputDict = PyDict_New(); PyDict_SetItem(OutputDict,PyString_FromString("id"),PyInt_FromLong(Triangles[iT].idx) ); PyDict_SetItem(OutputDict,PyString_FromString("coord"),(PyObject*)tri); //(PyObject*)tri PyList_Append(OutputList, OutputDict ); } return Py_BuildValue("O",OutputList); } PyObject *gadget_GetAllvPoints(self, args) PyObject *self; PyObject *args; { import_array(); /* needed but strange no ? */ PyArrayObject *pos; npy_intp ld[2]; int i; ld[0] = nvPoints; ld[1] = 3; pos = (PyArrayObject *) PyArray_SimpleNew(2,ld,PyArray_FLOAT); for (i = 0; i < pos->dimensions[0]; i++) { *(float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]) = vPoints[i].Pos[0]; *(float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]) = vPoints[i].Pos[1]; *(float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]) = 0.5; } return PyArray_Return(pos); } PyObject *gadget_GetAllvDensities(PyObject* self) { import_array(); /* needed but strange no ? */ PyArrayObject *rho; npy_intp ld[1]; int i; ld[0] = NumPart; rho = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_DOUBLE); for (i = 0; i < rho->dimensions[0]; i++) { *(double *) (rho->data + i*(rho->strides[0])) = P[i].Density; } return PyArray_Return(rho); } PyObject *gadget_GetAllvVolumes(PyObject* self) { import_array(); /* needed but strange no ? */ PyArrayObject *volume; npy_intp ld[1]; int i; ld[0] = NumPart; volume = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_DOUBLE); for (i = 0; i < volume->dimensions[0]; i++) { *(double *) (volume->data + i*(volume->strides[0])) = P[i].Volume; } return PyArray_Return(volume); } PyObject *gadget_GetAllvPressures(PyObject* self) { import_array(); /* needed but strange no ? */ PyArrayObject *pressure; npy_intp ld[1]; int i; ld[0] = NumPart; pressure = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_DOUBLE); for (i = 0; i < pressure->dimensions[0]; i++) { *(double *) (pressure->data + i*(pressure->strides[0])) = P[i].Pressure; } return PyArray_Return(pressure); } PyObject *gadget_GetAllvEnergySpec(PyObject* self) { import_array(); /* needed but strange no ? */ PyArrayObject *energy; npy_intp ld[1]; int i; double a3inv; double EnergySpec; ld[0] = NumPart; energy = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_DOUBLE); if(All.ComovingIntegrationOn) { a3inv = 1 / (All.Time * All.Time * All.Time); } else a3inv = 1; for (i = 0; i < energy->dimensions[0]; i++) { #ifdef ISOTHERM_EQS *(double *) (energy->data + i*(energy->strides[0])) = P[i].Entropy; #else EnergySpec=P[i].Entropy / GAMMA_MINUS1 * pow(P[i].Density * a3inv, GAMMA_MINUS1); if (EnergySpec<All.MinEgySpec) *(double *) (energy->data + i*(energy->strides[0])) = All.MinEgySpec; else *(double *) (energy->data + i*(energy->strides[0])) = P[i].Entropy / GAMMA_MINUS1 * pow(P[i].Density * a3inv, GAMMA_MINUS1); #endif } return PyArray_Return(energy); } PyObject *gadget_GetAllvAccelerations(PyObject* self) { import_array(); /* needed but strange no ? */ PyArrayObject *acc; npy_intp ld[2]; int i; ld[0] = NumPart; ld[1] = 3; acc = (PyArrayObject *) PyArray_SimpleNew(2,ld,PyArray_FLOAT); for (i = 0; i < acc->dimensions[0]; i++) { *(float *) (acc->data + i*(acc->strides[0]) + 0*acc->strides[1]) = P[i].tesselAccel[0]; *(float *) (acc->data + i*(acc->strides[0]) + 1*acc->strides[1]) = P[i].tesselAccel[1]; *(float *) (acc->data + i*(acc->strides[0]) + 2*acc->strides[1]) = P[i].tesselAccel[2]; } return PyArray_Return(acc); } PyObject *gadget_GetvPointsForOnePoint(self, args) PyObject *self; PyObject *args; { import_array(); /* needed but strange no ? */ PyArrayObject *pos; npy_intp ld[2]; int i; int np=0; if (!PyArg_ParseTuple(args,"i",&i)) return NULL; int next; next = P[i].ivPoint; np = P[i].nvPoints; ld[0] = np; ld[1] = 3; pos = (PyArrayObject *) PyArray_SimpleNew(2,ld,PyArray_FLOAT); for (i = 0; i < pos->dimensions[0]; i++) { *(float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]) = vPoints[next].Pos[0]; *(float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]) = vPoints[next].Pos[1]; *(float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]) = 0.5; next = vPoints[next].next; } next = vPoints[next].next; // if (next!=0) // { // printf("error in tessel_get_vPointsForOnePoint\n"); // return NULL; // } return PyArray_Return(pos); } PyObject *gadget_GetNgbPointsForOnePoint(self, args) PyObject *self; PyObject *args; { import_array(); /* needed but strange no ? */ PyArrayObject *pos; npy_intp ld[2]; int i,k; int np=0; int d=1; /* 1=counterclockwise 2=clockwise */ /* first triangle */ int iT,iTstart; int p,iP0,iP1,iPnext0; struct TriangleInList *T,*Tnext,*Tstart; if (!PyArg_ParseTuple(args,"i",&i)) return NULL; /* first loop to count np (number of ngbs) */ iTstart = P[i].iT; Tstart=&Triangles[iTstart]; /* find index in the triangle */ p=-1; if (Tstart->P[0]==&P[i]) p=0; else if (Tstart->P[1]==&P[i]) p=1; else if (Tstart->P[2]==&P[i]) p=2; if (p==-1) endrun(-712354); iT = iTstart; /* index of triangle */ iP0 = p; /* index of the ref point "0" in the triangle */ T = Tstart; np = 0; /* visit all triangles around the point */ while (1) { iP1 = (iP0+d) % 3 ; /* point 1 in the current triangle */ Tnext = T->T[iP1]; /* triangle opposit to iP1 */ if (Tnext==NULL) /* we reach an edge */ { printf("mmmh... why are we here ?"); endrun(-71235445); return -1; /* need to increase the size for this point */ } /* we have a ngb point */ np++; /* now, find the index of the ref. point in the next triangle */ iPnext0 = (T->idxe[iP1] + d) % 3 ; /* check */ if (&P[i]!=Tnext->P[iPnext0]) //if (P[i].ID!=Tnext->P[iPnext0]->ID) { printf(" problem : initial point %d (id=%d x=%g y=%g z=%g) next-> (id=%d x=%g y=%g z=%g)\n",i,P[i].ID,P[i].Pos[0],P[i].Pos[1],P[i].Pos[2],Tnext->P[iPnext0]->ID,Tnext->P[i]->Pos[0],Tnext->P[i]->Pos[1],Tnext->P[i]->Pos[2]); endrun(-7123544); } /* end of loop */ if (Tnext==Tstart) break; iP0 = iPnext0; T = Tnext; } ld[0] = np; ld[1] = 3; pos = (PyArrayObject *) PyArray_SimpleNew(2,ld,PyArray_FLOAT); /* second loop to record positions */ iTstart = P[i].iT; Tstart=&Triangles[iTstart]; k=0; /* find index in the triangle */ p=-1; if (Tstart->P[0]==&P[i]) p=0; else if (Tstart->P[1]==&P[i]) p=1; else if (Tstart->P[2]==&P[i]) p=2; if (p==-1) endrun(-712354); iT = iTstart; /* index of triangle */ iP0 = p; /* index of the ref point "0" in the triangle */ T = Tstart; np = 0; /* visit all triangles around the point */ while (1) { iP1 = (iP0+d) % 3 ; /* point 1 in the current triangle */ Tnext = T->T[iP1]; /* triangle opposit to iP1 */ if (Tnext==NULL) /* we reach an edge */ { printf("mmmh... why are we here ?"); endrun(-71235445); return -1; /* need to increase the size for this point */ } /* we have a ngb point */ if (T->P[iP1]->iPref==-1) { *(float *) (pos->data + k*(pos->strides[0]) + 0*pos->strides[1]) = T->P[iP1]->Pos[0]; *(float *) (pos->data + k*(pos->strides[0]) + 1*pos->strides[1]) = T->P[iP1]->Pos[1]; *(float *) (pos->data + k*(pos->strides[0]) + 2*pos->strides[1]) = 0; } else /* a ghost point */ { *(float *) (pos->data + k*(pos->strides[0]) + 0*pos->strides[1]) = P[T->P[iP1]->iPref].Pos[0]; *(float *) (pos->data + k*(pos->strides[0]) + 1*pos->strides[1]) = P[T->P[iP1]->iPref].Pos[1]; *(float *) (pos->data + k*(pos->strides[0]) + 2*pos->strides[1]) = 0; } k++; /* now, find the index of the ref. point in the next triangle */ iPnext0 = (T->idxe[iP1] + d) % 3 ; /* check */ if (&P[i]!=Tnext->P[iPnext0]) //if (P[i].ID!=Tnext->P[iPnext0]->ID) { printf(" problem : initial point %d (id=%d x=%g y=%g z=%g) next-> (id=%d x=%g y=%g z=%g)\n",i,P[i].ID,P[i].Pos[0],P[i].Pos[1],P[i].Pos[2],Tnext->P[iPnext0]->ID,Tnext->P[i]->Pos[0],Tnext->P[i]->Pos[1],Tnext->P[i]->Pos[2]); endrun(-7123544); } /* end of loop */ if (Tnext==Tstart) break; iP0 = iPnext0; T = Tnext; } return PyArray_Return(pos); } PyObject *gadget_GetNgbPointsAndFacesForOnePoint(self, args) PyObject *self; PyObject *args; { import_array(); /* needed but strange no ? */ PyArrayObject *list; PyArrayObject *elt; PyArrayObject *pos1,*pos2,*pos3; npy_intp ld[2]; int i; int np=0; int d=1; /* 1=counterclockwise 2=clockwise */ /* first triangle */ int iT,iTstart; int p,iP0,iP1,iPnext0; struct TriangleInList *T,*Tnext,*Tstart; int nextv,nextv2; if (!PyArg_ParseTuple(args,"i",&i)) return NULL; list = PyList_New(0); iTstart = P[i].iT; Tstart=&Triangles[iTstart]; /* find index in the triangle */ p=-1; if (Tstart->P[0]==&P[i]) p=0; else if (Tstart->P[1]==&P[i]) p=1; else if (Tstart->P[2]==&P[i]) p=2; if (p==-1) endrun(-712354); iT = iTstart; /* index of triangle */ iP0 = p; /* index of the ref point "0" in the triangle */ T = Tstart; np = 0; nextv = P[i].ivPoint; /* visit all triangles around the point */ while (1) { iP1 = (iP0+d) % 3 ; /* point 1 in the current triangle */ Tnext = T->T[iP1]; /* triangle opposit to iP1 */ if (Tnext==NULL) /* we reach an edge */ { printf("mmmh... why are we here ?"); endrun(-71235445); return -1; /* need to increase the size for this point */ } /* we have a ngb point */ elt = PyTuple_New(3); pos1 = PyTuple_New(3); pos2 = PyTuple_New(3); pos3 = PyTuple_New(3); PyTuple_SetItem(pos1, (Py_ssize_t)0, PyFloat_FromDouble((double)T->P[iP1]->Pos[0])); PyTuple_SetItem(pos1, (Py_ssize_t)1, PyFloat_FromDouble((double)T->P[iP1]->Pos[1])); PyTuple_SetItem(pos1, (Py_ssize_t)2, PyFloat_FromDouble((double)0.5)); PyTuple_SetItem(pos2, (Py_ssize_t)0, PyFloat_FromDouble((double)vPoints[nextv].Pos[0])); PyTuple_SetItem(pos2, (Py_ssize_t)1, PyFloat_FromDouble((double)vPoints[nextv].Pos[1])); PyTuple_SetItem(pos2, (Py_ssize_t)2, PyFloat_FromDouble((double)0.5)); nextv2 = vPoints[nextv].next; PyTuple_SetItem(pos3, (Py_ssize_t)0, PyFloat_FromDouble((double)vPoints[nextv2].Pos[0])); PyTuple_SetItem(pos3, (Py_ssize_t)1, PyFloat_FromDouble((double)vPoints[nextv2].Pos[1])); PyTuple_SetItem(pos3, (Py_ssize_t)2, PyFloat_FromDouble((double)0.5)); PyTuple_SetItem(elt,(Py_ssize_t)0,pos1); PyTuple_SetItem(elt,(Py_ssize_t)1,pos2); PyTuple_SetItem(elt,(Py_ssize_t)2,pos3); PyList_Append(list,elt); nextv = vPoints[nextv].next; /* now, find the index of the ref. point in the next triangle */ iPnext0 = (T->idxe[iP1] + d) % 3 ; /* check */ if (&P[i]!=Tnext->P[iPnext0]) //if (P[i].ID!=Tnext->P[iPnext0]->ID) { printf(" problem : initial point %d (id=%d x=%g y=%g z=%g) next-> (id=%d x=%g y=%g z=%g)\n",i,P[i].ID,P[i].Pos[0],P[i].Pos[1],P[i].Pos[2],Tnext->P[iPnext0]->ID,Tnext->P[i]->Pos[0],Tnext->P[i]->Pos[1],Tnext->P[i]->Pos[2]); endrun(-7123544); } /* end of loop */ if (Tnext==Tstart) break; iP0 = iPnext0; T = Tnext; } return Py_BuildValue("O",list); } PyObject *gadget_GetAllGhostPositions(PyObject* self) { PyArrayObject *pos; npy_intp ld[2]; int i; import_array(); /* needed but strange no ? */ ld[0] = NumgPart; ld[1] = 3; pos = (PyArrayObject *) PyArray_SimpleNew(2,ld,PyArray_FLOAT); for (i = 0; i < pos->dimensions[0]; i++) { *(float *) (pos->data + i*(pos->strides[0]) + 0*pos->strides[1]) = P[NumPart+i].Pos[0]; *(float *) (pos->data + i*(pos->strides[0]) + 1*pos->strides[1]) = P[NumPart+i].Pos[1]; *(float *) (pos->data + i*(pos->strides[0]) + 2*pos->strides[1]) = P[NumPart+i].Pos[2]; } return PyArray_Return(pos); } PyObject *gadget_GetAllGhostvDensities(PyObject* self) { import_array(); /* needed but strange no ? */ PyArrayObject *rho; npy_intp ld[1]; int i; ld[0] = NumgPart; rho = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_DOUBLE); for (i = 0; i < rho->dimensions[0]; i++) { *(double *) (rho->data + i*(rho->strides[0])) = P[NumPart+i].Density; } return PyArray_Return(rho); } PyObject *gadget_GetAllGhostvVolumes(PyObject* self) { import_array(); /* needed but strange no ? */ PyArrayObject *volume; npy_intp ld[1]; int i; ld[0] = NumgPart; volume = (PyArrayObject *) PyArray_SimpleNew(1,ld,PyArray_DOUBLE); for (i = 0; i < volume->dimensions[0]; i++) { *(double *) (volume->data + i*(volume->strides[0])) = P[NumPart+i].Volume; } return PyArray_Return(volume); } #endif /* PY_INTERFACE */ #endif