diff --git a/src/Makefile b/src/Makefile index f289280..e45886c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -62,7 +62,6 @@ endif endif ifeq ($(MPI),1) - F90 = mpif90 DEFS += -D__MPI__ endif @@ -88,7 +87,7 @@ EXTRAINCS += $(HDF5INCS) EXTRAOBJECTS += $(HDF5LIBS) ifeq ($(WEAK_RATES),1) -all: nulib.a ../nulibtable_driver ../point_example ../make_table_weakrates +all: nulib.a ../nulibtable_driver ../point_example ../make_table_weakrates ../make_table_electron_capture else all: nulib.a ../nulibtable_driver ../point_example ../make_table_example endif @@ -105,6 +104,9 @@ endif ../make_table_weakrates: $(EXTRADEPS) $(F_OBJECTS) $(MOD_OBJECTS) $(OBJECTS) $(f90_OBJECTS)make_table_weakrates.F90 $(F90) $(F90FLAGS) $(DEFS) $(MODINC) $(EXTRAINCS) -o $@ make_table_weakrates.F90 $(MOD_OBJECTS) $(OBJECTS) $(F_OBJECTS) $(EXTRAOBJECTS) $(f90_OBJECTS) +../make_table_electron_capture: $(EXTRADEPS) $(F_OBJECTS) $(MOD_OBJECTS) $(OBJECTS) $(f90_OBJECTS)make_table_electron_capture.F90 + $(F90) $(F90FLAGS) $(DEFS) $(MODINC) $(EXTRAINCS) -o $@ make_table_electron_capture.F90 $(MOD_OBJECTS) $(OBJECTS) $(F_OBJECTS) $(EXTRAOBJECTS) $(f90_OBJECTS) + nulib.a: $(EXTRADEPS) $(F_OBJECTS) $(MOD_OBJECTS) $(OBJECTS) $(NT_OBJECTS) ar -r nulib.a *.o nuc_eos/*.o @@ -133,6 +135,7 @@ nuc_eos/nuc_eos.a: nuc_eos/*.F90 nuc_eos/*.f clean: rm -rf ../make_table_example rm -rf ../make_table_weakrates + rm -rf ../make_table_electron_capture rm -rf ../point_example rm -rf ../nulibtable_driver rm -rf test diff --git a/src/make_table_electron_capture.F90 b/src/make_table_electron_capture.F90 new file mode 100644 index 0000000..0e9f7fb --- /dev/null +++ b/src/make_table_electron_capture.F90 @@ -0,0 +1,481 @@ +!-*-f90-*- +program make_table_example + + use nulib + use inputparser + use nuclei_hempel + use weakrates_interface + implicit none +#ifdef __MPI__ + include 'mpif.h' +#endif + !many people use different number of species, this is to denote how they are devided up. + ! mytable_neutrino_scheme = 1 (three output species) + ! species #1: electron neutrino #2 electron antineutrino + ! #3: muon+tau neutrino+antineutrino + ! neutrino_scheme = 2 (four output species) + ! species #1: electron neutrino #2 electron antineutrino + ! #3: muon+tau neutrino #4 mu and tau antineutrino + ! neutrino_scheme = 3 (six output species) + ! species #1: electron neutrino #2 electron antineutrino + ! #3: muon neutrino #4 mu antineutrino + ! #5: tau neutrino #6 tau antineutrino + integer :: mytable_neutrino_scheme = 1 + + !number of species for nulib to calculation interactions for, must + !be six currently, average is done via above parameter + integer :: mytable_number_species = 6 + + !number of energy groups + integer :: mytable_number_groups = 40 ! 18 + + !NuLib parameters file (weak rates and EOS) + character*200 :: parameters_filename = "./parameters" + + + !final table parameters + integer :: final_table_size_ye, final_table_size_rho, final_table_size_temp + real*8 :: min_logrho,max_logrho + real*8 :: min_logtemp,max_logtemp + real*8 :: min_ye,max_ye + character*512 :: finaltable_filename + real*8, allocatable,dimension(:) :: table_rho + real*8, allocatable,dimension(:) :: table_temp + real*8, allocatable,dimension(:) :: table_ye + real*8, allocatable,dimension(:,:,:,:) :: table_emission + + !versioning + real*8 :: timestamp + character(8) :: date + integer :: values(8) + character(100) :: outdir,base,vnum,srho,stemp,sye,sng + + !local variables to help in making tables + integer :: irho,itemp,iye,ns,ng + integer :: ieta,iinE + real*8, allocatable,dimension(:) :: local_emissivity + real*8, allocatable,dimension(:) :: eos_variables + real*8 :: matter_prs,matter_ent,matter_cs2,matter_dedt,matter_dpderho,matter_dpdrhoe + integer :: keytemp,keyerr + real*8 :: precision = 1.0d-10 + integer :: i + real*8 dxfac,mindx + +#ifdef __MPI__ + !MPI variables + integer :: mpirank, nprocs, ierror + integer :: table_size,irho_save,remainder_size,counter,nmin,recvcount + integer, allocatable, dimension(:) :: sendcounts,displs + real*8, allocatable,dimension(:) :: table_rho_subset + integer :: mpi_final_table_size_rho + real*8 :: mpitime1,mpitime2 + real*8, allocatable,dimension(:,:,:,:) :: table_emission_node + + + !MPI initialization + call mpi_init(ierror) + call mpi_comm_rank(mpi_comm_world, mpirank, ierror) + call mpi_comm_size(mpi_comm_world, nprocs, ierror) + mpitime1=mpi_wtime() +#endif + + call input_parser(parameters_filename) + !this sets up many coefficients and creates the energy grid (one + !zone + log spacing) see nulib.F90:initialize_nulib + call initialize_nulib(mytable_neutrino_scheme,mytable_number_species,mytable_number_groups) + call read_eos_table(eos_filename) !read in EOS table & set reference mass + call set_up_Hempel !set's up EOS for nuclear abundances + ! initialize weak-rate library if it is turned on in requested_interactions.inc + call initialize_weakratelib(parameters_filename) + + outdir="./" + base="electron_capture" + vnum="1.0" + + adhoc_nux_factor = 0.0d0 !increase for adhoc nux heating (also set + !add_nux_absorption_on_n_and_p to true) + !set up table + final_table_size_ye = 60 ! 51 + final_table_size_rho = 160 ! 82 + final_table_size_temp = 130 ! 65 + + min_ye = 0.01d0 + max_ye = 0.6d0 + min_logrho = 6.0d0 + max_logrho = 15.5d0 + min_logtemp = log10(0.1d0) + max_logtemp = log10(100.0d0) + + !set up energies bins + do_integrated_BB_and_emissivity = .false. + mindx = 2.0d0 + bin_bottom(1) = 0.0d0 !MeV + bin_bottom(2) = 2.0d0 !MeV + bin_bottom(3) = bin_bottom(2)+mindx + bin_bottom(number_groups) = 250.0d0 + +#ifdef __MPI__ + !set up mpi arrays + counter = 0 + table_size = final_table_size_rho + remainder_size = mod(table_size,nprocs) + nmin = int(table_size/nprocs) + allocate(table_rho_subset(nmin+1)) + allocate(sendcounts(0:nprocs-1)) + allocate(displs(0:nprocs-1)) + table_rho_subset = 0.0d0 + sendcounts = 0 + displs = 0 + + !calculate dimensions for mpi_scatterv + do i=0,nprocs-1 + if(i.lt.remainder_size)then + sendcounts(i) = nmin + 1 + else + sendcounts(i) = nmin + end if + displs(i) = counter + counter = counter + sendcounts(i) + if(i.eq.mpirank)then + recvcount = sendcounts(mpirank) + end if + end do +#endif + + call nulib_series2(number_groups-1,bin_bottom(2),bin_bottom(number_groups),mindx,dxfac) + do i=4,number_groups + bin_bottom(i) = bin_bottom(i-1)+(bin_bottom(i-1)-bin_bottom(i-2))*dxfac + enddo + + !calculate bin widths & energies from the bottom of the bin & energy at top on bin + do i=1,number_groups-1 + energies(i) = (bin_bottom(i)+bin_bottom(i+1))/2.0d0 + bin_widths(i) = bin_bottom(i+1)-bin_bottom(i) + bin_top(i) = bin_bottom(i+1) + enddo + energies(number_groups) = bin_bottom(number_groups)+bin_widths(number_groups-1)*dxfac/2.0d0 + bin_widths(number_groups) = 2.0*(energies(number_groups)-bin_bottom(number_groups)) + bin_top(number_groups) = bin_bottom(number_groups)+bin_widths(number_groups) + + + allocate(table_ye(final_table_size_ye)) + allocate(table_rho(final_table_size_rho)) + allocate(table_temp(final_table_size_temp)) + + allocate(table_emission(final_table_size_rho,final_table_size_temp, & + final_table_size_ye,mytable_number_groups)) + +#ifdef __MPI__ + !mpi node tables + allocate(table_emission_node(final_table_size_rho,final_table_size_temp, & + final_table_size_ye,mytable_number_groups)) + + table_emission_node = 0.0d0 +#endif + + table_emission = 0.0d0 + + do iye=1,final_table_size_ye + table_ye(iye) = min_ye+dble(iye-1)/dble(final_table_size_ye-1)*(max_ye-min_ye) + enddo + + do irho=1,final_table_size_rho + table_rho(irho) = & + 10.0d0**(min_logrho+dble(irho-1)/dble(final_table_size_rho-1)*(max_logrho-min_logrho)) + enddo + + do itemp=1,final_table_size_temp + table_temp(itemp) = & + 10.0d0**(min_logtemp+dble(itemp-1)/dble(final_table_size_temp-1)*(max_logtemp-min_logtemp)) + enddo + +#ifdef __MPI__ + !mpi_scatterv sends portions of table_rho to different nodes + call mpi_scatterv(table_rho,sendcounts,displs,mpi_double,table_rho_subset,& + recvcount,mpi_double,0,mpi_comm_world,ierror) + mpi_final_table_size_rho = recvcount +#endif + + + !$OMP PARALLEL DO PRIVATE(itemp,iye,local_emissivity,local_absopacity,local_scatopacity, & + !$OMP ns,ng,eos_variables,keytemp,keyerr,matter_prs,matter_ent,matter_cs2,matter_dedt, & + !$OMP matter_dpderho,matter_dpdrhoe,hempel_lookup_table) + !loop over rho,temp,ye of table, do each point +#ifdef __MPI__ + do irho=1,mpi_final_table_size_rho +#else + do irho=1,final_table_size_rho +#endif + !must do declarations here for openmp + allocate(local_emissivity(mytable_number_groups)) + allocate(eos_variables(total_eos_variables)) +#ifdef __MPI__ + write(*,"(A,E18.9)") "Rho:", table_rho_subset(irho) +#else + write(*,"(A,E18.9)") "Rho:", table_rho(irho) +#endif + do itemp=1,final_table_size_temp + write(*,*) "Temp:", 100.0*dble(itemp-1)/dble(final_table_size_temp),"%" + do iye=1,final_table_size_ye + + eos_variables = 0.0d0 +#ifdef __MPI__ + eos_variables(rhoindex) = table_rho_subset(irho) +#else + eos_variables(rhoindex) = table_rho(irho) +#endif + eos_variables(tempindex) = table_temp(itemp) + eos_variables(yeindex) = table_ye(iye) + + !! EOS stuff + call set_eos_variables(eos_variables) + + !calculate the rho,temp,ye + call microphysical_electron_capture(1, eos_variables, local_emissivity) + + !check that the number is not NaN or Inf (.gt.1.0d300) + if (local_emissivity(ng).ne.local_emissivity(ng)) then + write(*,"(a,1P3E18.9,i6)") "We have a NaN in emissivity", & + eos_variables(rhoindex),eos_variables(tempindex),eos_variables(yeindex),ng + stop + endif + + if (log10(local_emissivity(ng)).ge.300.0d0) then + write(*,"(a,1P4E18.9,i6)") "We have a Inf in emissivity", & + local_emissivity(ng),eos_variables(rhoindex), & + eos_variables(tempindex),eos_variables(yeindex),ng + stop + endif + + !set global table + do ng=1,mytable_number_groups +#ifdef __MPI__ + table_emission_node(displs(mpirank)+irho,itemp,iye,ng) = local_emissivity(ng) !ergs/cm^3/s/MeV/srad +#else + table_emission(irho,itemp,iye,ng) = local_emissivity(ng) !ergs/cm^3/s/MeV/srad +#endif + enddo !do ng=1,mytable_number_groups + + enddo!do iye=1,final_table_size_ye + enddo!do itemp=1,final_table_size_temp + + deallocate(local_emissivity) + deallocate(eos_variables) + enddo!do irho=1,final_table_size_rho + !$OMP END PARALLEL DO! end do + +#ifdef __MPI__ + call mpi_barrier(mpi_comm_world, ierror) + if(mpirank.eq.0)write(*,*) "Finished Opacity Table" + + table_size = final_table_size_rho*final_table_size_temp* & + final_table_size_ye*mytable_number_groups + call mpi_reduce(table_emission_node,table_emission,& + table_size,mpi_double,mpi_sum,0,mpi_comm_world,ierror) + + !begin inelastic, timing for mpi purposes + call mpi_barrier(mpi_comm_world, ierror) + mpitime2 = mpi_wtime() + if(mpirank.eq.0)write(*,*) "Total time = ",mpitime2-mpitime1 + mpitime1 = mpi_wtime() +#else + write(*,*) "Finished Electron Capture Table" +#endif + + !write out table in H5 format +#ifdef __MPI__ + !only the first mpi node should write + if(mpirank.eq.0)then +#endif + call date_and_time(DATE=date,VALUES=values) + write(srho,*) final_table_size_rho + write(stemp,*) final_table_size_temp + write(sye,*) final_table_size_ye + write(sng,*) mytable_number_groups + timestamp = dble(values(1))*10000.0d0+dble(values(2))*100.0+dble(values(3)) + & + (dble(values(5))+dble(values(6))/60.0d0 + dble(values(7))/3600.0d0 )/24.0 + + finaltable_filename = trim(adjustl(outdir))//trim(adjustl(base))//"_rho"//trim(adjustl(srho))// & + "_temp"//trim(adjustl(stemp))//"_ye"//trim(adjustl(sye))// & + "_ng"//trim(adjustl(sng)) // & + "_version"//trim(adjustl(vnum))//"_"//trim(adjustl(date))//".h5" + + call write_h5(finaltable_filename,timestamp) +#ifdef __MPI__ + end if + + call mpi_barrier(mpi_comm_world, ierror) + call mpi_finalize(ierror) +#endif + +contains + + subroutine write_h5(filename,timestamp) + + use nulib + use hdf5 + implicit none + + character(len=512) :: filename + + !H5 stuff + integer :: error,rank,cerror + integer(HID_T) :: file_id,dset_id,dspace_id + integer(HSIZE_T) :: dims1(1), dims2(2), dims3(3), dims4(4), dims5(5), dims6(6)!, etc.... + + real*8 :: timestamp + character(8) :: date + integer :: values(8) + + cerror = 0 + + !open HDF5 file, given filename + !note: H5F_ACC_TRUNC specifies that if the file already exists, + ! the current contents will be deleted so that the application can + ! rewrite the file with new data. H5F_ACC_EXCL specifies that the open + ! is to fail if the file already exists. If the file does not already + ! exist, the file access parameter is ignored. + !file_id gets set here for future use in distinguishing files + !if error != 0 we will know at the end when we ensure cerror (c=cummulative) == 0 + call h5open_f(error) + cerror = cerror + error + call h5fcreate_f(filename,H5F_ACC_TRUNC_F,file_id,error) + cerror = cerror + error + + !write scalars (rank=1, dims1(1) = 1) + rank = 1 + dims1(1) = 1 + cerror = cerror + error + + call h5screate_simple_f(rank, dims1, dspace_id, error) + call h5dcreate_f(file_id, "timestamp", H5T_NATIVE_DOUBLE, & + dspace_id, dset_id, error) + call h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE, timestamp, & + dims1, error) + call h5dclose_f(dset_id, error) + call h5sclose_f(dspace_id, error) + + call h5screate_simple_f(rank, dims1, dspace_id, error) + call h5dcreate_f(file_id, "number_groups", H5T_NATIVE_INTEGER, & + dspace_id,dset_id, error) + call h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, number_groups, dims1, error) + call h5dclose_f(dset_id, error) + call h5sclose_f(dspace_id, error) + cerror = cerror + error + + call h5screate_simple_f(rank, dims1, dspace_id, error) + call h5dcreate_f(file_id, "nrho", H5T_NATIVE_INTEGER, & + dspace_id,dset_id, error) + call h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, final_table_size_rho, dims1, error) + call h5dclose_f(dset_id, error) + call h5sclose_f(dspace_id, error) + cerror = cerror + error + + call h5screate_simple_f(rank, dims1, dspace_id, error) + call h5dcreate_f(file_id, "ntemp", H5T_NATIVE_INTEGER, & + dspace_id,dset_id, error) + call h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, final_table_size_temp, dims1, error) + call h5dclose_f(dset_id, error) + call h5sclose_f(dspace_id, error) + cerror = cerror + error + + call h5screate_simple_f(rank, dims1, dspace_id, error) + call h5dcreate_f(file_id, "nye", H5T_NATIVE_INTEGER, & + dspace_id,dset_id, error) + call h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, final_table_size_ye, dims1, error) + call h5dclose_f(dset_id, error) + call h5sclose_f(dspace_id, error) + cerror = cerror + error + + !lets also write neutrino energies, bin bottoms,tops and widths + !write 1D arrays (rank=1, dims1(1) = oneDarray_size) + rank = 1 + dims1(1) = number_groups + call h5screate_simple_f(rank, dims1, dspace_id, error) + call h5dcreate_f(file_id, "neutrino_energies", H5T_NATIVE_DOUBLE, & + dspace_id, dset_id, error) + call h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE,energies, dims1, error) + call h5dclose_f(dset_id, error) + call h5sclose_f(dspace_id, error) + cerror = cerror + error + + call h5screate_simple_f(rank, dims1, dspace_id, error) + call h5dcreate_f(file_id, "bin_widths", H5T_NATIVE_DOUBLE, & + dspace_id, dset_id, error) + call h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE,bin_widths, dims1, error) + call h5dclose_f(dset_id, error) + call h5sclose_f(dspace_id, error) + cerror = cerror + error + + call h5screate_simple_f(rank, dims1, dspace_id, error) + call h5dcreate_f(file_id, "bin_bottom", H5T_NATIVE_DOUBLE, & + dspace_id, dset_id, error) + call h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE,bin_bottom, dims1, error) + call h5dclose_f(dset_id, error) + call h5sclose_f(dspace_id, error) + cerror = cerror + error + + call h5screate_simple_f(rank, dims1, dspace_id, error) + call h5dcreate_f(file_id, "bin_top", H5T_NATIVE_DOUBLE, & + dspace_id, dset_id, error) + call h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE,bin_top, dims1, error) + call h5dclose_f(dset_id, error) + call h5sclose_f(dspace_id, error) + cerror = cerror + error + + rank = 1 + dims1(1) = final_table_size_rho + call h5screate_simple_f(rank, dims1, dspace_id, error) + call h5dcreate_f(file_id, "rho_points", H5T_NATIVE_DOUBLE, & + dspace_id, dset_id, error) + call h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE,table_rho, dims1, error) + call h5dclose_f(dset_id, error) + call h5sclose_f(dspace_id, error) + cerror = cerror + error + + rank = 1 + dims1(1) = final_table_size_temp + call h5screate_simple_f(rank, dims1, dspace_id, error) + call h5dcreate_f(file_id, "temp_points", H5T_NATIVE_DOUBLE, & + dspace_id, dset_id, error) + call h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE,table_temp, dims1, error) + call h5dclose_f(dset_id, error) + call h5sclose_f(dspace_id, error) + cerror = cerror + error + + rank = 1 + dims1(1) = final_table_size_ye + call h5screate_simple_f(rank, dims1, dspace_id, error) + call h5dcreate_f(file_id, "ye_points", H5T_NATIVE_DOUBLE, & + dspace_id, dset_id, error) + call h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE,table_ye, dims1, error) + call h5dclose_f(dset_id, error) + call h5sclose_f(dspace_id, error) + cerror = cerror + error + + rank = 4 + dims4(1) = final_table_size_rho + dims4(2) = final_table_size_temp + dims4(3) = final_table_size_ye + dims4(4) = number_groups + + call h5screate_simple_f(rank, dims4, dspace_id, error) + call h5dcreate_f(file_id, "emissivity", H5T_NATIVE_DOUBLE, & + dspace_id, dset_id, error) + call h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE,table_emission, dims4, error) + call h5dclose_f(dset_id, error) + call h5sclose_f(dspace_id, error) + cerror = cerror + error + + !must close h5 files, check for error + if (cerror.ne.0) then + write(*,*) "We have errors on writing HDF5 file", cerror + stop + endif + + call h5fclose_f(file_id,error) + call h5close_f(error) + + end subroutine write_h5 + +end program make_table_example diff --git a/src/nuc_eos/linterp.f b/src/nuc_eos/linterp.f index 282d090..b6a2608 100644 --- a/src/nuc_eos/linterp.f +++ b/src/nuc_eos/linterp.f @@ -50,7 +50,7 @@ SUBROUTINE intp3d ( x, y, z, f, kt, ft, nx, ny, nz, xt, yt, zt, double precision dx,dy,dz,dxi,dyi,dzi,dxyi,dxzi,dyzi,dxyzi integer n,ix,iy,iz - IF (kt .GT. ktx) STOP'***KTX**' + IF (kt .GT. ktx) STOP '***KTX**' c c c------ determine spacing parameters of (equidistant!!!) table diff --git a/src/nuc_eos/linterp_many.F90 b/src/nuc_eos/linterp_many.F90 index 05d9c7a..cc18c54 100644 --- a/src/nuc_eos/linterp_many.F90 +++ b/src/nuc_eos/linterp_many.F90 @@ -43,7 +43,7 @@ SUBROUTINE intp3d_many ( x, y, z, f, kt, ft, nx, ny, nz, nvars, xt, yt, zt) real*8 dx,dy,dz,dxi,dyi,dzi,dxyi,dxzi,dyzi,dxyzi integer n,ix,iy,iz - IF (kt .GT. ktx) STOP'***KTX**' + IF (kt .GT. ktx) STOP '***KTX**' ! ! !------ determine spacing parameters of (equidistant!!!) table