From f7a98c17fe0924ba7c24d187675e237334ff2d89 Mon Sep 17 00:00:00 2001 From: DavidBamba Date: Fri, 12 Jul 2024 14:20:16 -0230 Subject: [PATCH] (gr) can use tabulated metric independently of einstein toolkit --- build/Makefile | 20 ++++- src/main/initial.F90 | 11 ++- src/main/metric_et.f90 | 83 +++++++++++------- src/main/metric_et_utils.f90 | 150 +++++++++++++++++++++++++++++++++ src/utils/einsteintk_utils.f90 | 36 ++------ src/utils/tabulate_metric.f90 | 67 +++++++++++++++ 6 files changed, 307 insertions(+), 60 deletions(-) create mode 100644 src/main/metric_et_utils.f90 create mode 100644 src/utils/tabulate_metric.f90 diff --git a/build/Makefile b/build/Makefile index a6a52c554..4a609420c 100644 --- a/build/Makefile +++ b/build/Makefile @@ -488,7 +488,7 @@ ifdef METRIC else SRCMETRIC= metric_minkowski.f90 endif -SRCGR=inverse4x4.f90 einsteintk_utils.f90 $(SRCMETRIC) metric_tools.f90 utils_gr.f90 interpolate3D.f90 tmunu2grid.f90 +SRCGR=inverse4x4.f90 metric_et_utils.f90 einsteintk_utils.f90 $(SRCMETRIC) metric_tools.f90 utils_gr.f90 interpolate3D.f90 tmunu2grid.f90 # # chemistry and cooling # @@ -1230,6 +1230,24 @@ combinedustdumps: checksys checkparams $(OBJCDD) cleancombinedustdumps: rm -f $(BINDIR)/combinedustdumps +#---------------------------------------------------- +# these are the sources for the tabulate_metric tility +.PHONY: tabulate_metric +SRCTAB= io.F90 utils_infiles.f90 metric_${METRIC}.f90 metric_et_utils.f90 tabulate_metric.f90 #metric_tools.F90 +OBJTAB1= $(SRCTAB:.F90=.o) +OBJTAB= $(OBJTAB1:.f90=.o) + +tabulate_metric: checksys $(OBJTAB) + @echo "" + @echo "tabulate_metric: Because grids are great" + @echo "" + $(FC) $(FFLAGS) -o $(BINDIR)/$@ $(OBJTAB) + +cleantabulatemetric: + rm -f $(BINDIR)/tabulate_metric + + + include Makefile_qscripts diff --git a/src/main/initial.F90 b/src/main/initial.F90 index 4c9a97aa2..6f81d142f 100644 --- a/src/main/initial.F90 +++ b/src/main/initial.F90 @@ -41,7 +41,7 @@ module initial !+ !---------------------------------------------------------------- subroutine initialise() - use dim, only:mpi + use dim, only:mpi,gr use io, only:fatal,die,id,master,nprocs,ievfile #ifdef FINVSQRT use fastmath, only:testsqrt @@ -56,6 +56,8 @@ subroutine initialise() use cpuinfo, only:print_cpuinfo use checkoptions, only:check_compile_time_settings use readwrite_dumps, only:init_readwrite_dumps + use metric, only:metric_type + use metric_et_utils, only:read_tabulated_metric,gridinit integer :: ierr ! !--write 'PHANTOM' and code version @@ -99,6 +101,13 @@ subroutine initialise() !--initialise MPI domains ! call init_domains(nprocs) +! +!--initialise metric if tabulated +! + if (gr .and. metric_type=='et') then + call read_tabulated_metric('tabuled_metric.dat',ierr) + gridinit = .true. + endif call init_readwrite_dumps() diff --git a/src/main/metric_et.f90 b/src/main/metric_et.f90 index ce133ea83..97dceb66d 100644 --- a/src/main/metric_et.f90 +++ b/src/main/metric_et.f90 @@ -32,33 +32,37 @@ module metric !+ !---------------------------------------------------------------- pure subroutine get_metric_cartesian(position,gcov,gcon,sqrtg) - use einsteintk_utils, only:gridinit + use metric_et_utils, only:gridinit real, intent(in) :: position(3) real, intent(out) :: gcov(0:3,0:3) real, intent(out), optional :: gcon(0:3,0:3) real, intent(out), optional :: sqrtg + integer :: ierr ! The subroutine that computes the metric tensor for a given position ! In this case it is interpolated from the global grid values ! Perform trilenar interpolation if ( .not. gridinit) then + ierr = 1 ! This is required for phantomsetup ! As no grid information has been passed to phantom from ET ! So interpolation cannot be performed - gcov = 0. - gcov(0,0) = -1. - gcov(1,1) = 1. - gcov(2,2) = 1. - gcov(3,3) = 1. - if (present(gcon)) then - gcon = 0. - gcon(0,0) = -1. - gcon(1,1) = 1. - gcon(2,2) = 1. - gcon(3,3) = 1. + if (ierr /= 0) then + gcov = 0. + gcov(0,0) = -1. + gcov(1,1) = 1. + gcov(2,2) = 1. + gcov(3,3) = 1. + if (present(gcon)) then + gcon = 0. + gcon(0,0) = -1. + gcon(1,1) = 1. + gcon(2,2) = 1. + gcon(3,3) = 1. + endif + if (present(sqrtg)) sqrtg = -1. endif - if (present(sqrtg)) sqrtg = -1. elseif (present(gcon) .and. present(sqrtg)) then call interpolate_metric(position,gcov,gcon,sqrtg) else @@ -95,17 +99,26 @@ pure subroutine get_metric_spherical(position,gcov,gcon,sqrtg) end subroutine get_metric_spherical + pure subroutine metric_cartesian_derivatives(position,dgcovdx, dgcovdy, dgcovdz) - use einsteintk_utils, only:gridinit - real, intent(in) :: position(3) - real, intent(out) :: dgcovdx(0:3,0:3), dgcovdy(0:3,0:3), dgcovdz(0:3,0:3) - if (.not. gridinit) then - dgcovdx = 0. - dgcovdy = 0. - dgcovdz = 0. - else - call interpolate_metric_derivs(position,dgcovdx,dgcovdy,dgcovdz) - endif + use metric_et_utils, only:gridinit +! use grid, only:read_tabulated_metric + real, intent(in) :: position(3) + real, intent(out) :: dgcovdx(0:3,0:3), dgcovdy(0:3,0:3), dgcovdz(0:3,0:3) + integer :: ierr + if (.not. gridinit) then + ierr = 1 + if (ierr /= 0) then + dgcovdx = 0. + dgcovdy = 0. + dgcovdz = 0. + else + ! gridinit = .true. + call interpolate_metric_derivs(position,dgcovdx,dgcovdy,dgcovdz) + endif + else + call interpolate_metric_derivs(position,dgcovdx,dgcovdy,dgcovdz) + endif end subroutine metric_cartesian_derivatives pure subroutine metric_spherical_derivatives(position,dgcovdr, dgcovdtheta, dgcovdphi) @@ -154,6 +167,7 @@ subroutine write_options_metric(iunit) integer, intent(in) :: iunit write(iunit,"(/,a)") '# There are no options relating to the '//trim(metric_type)//' metric' + !call write_inopt(metric_file,'metric_file','file from which to read tabulated metric (blank if used with einsteintk)',iunit) end subroutine write_options_metric @@ -166,9 +180,17 @@ subroutine read_options_metric(name,valstring,imatch,igotall,ierr) character(len=*), intent(in) :: name,valstring logical, intent(out) :: imatch,igotall integer, intent(out) :: ierr - - ! imatch = .true. - ! igotall = .true. + integer, save :: ngot = 0 + + select case(trim(name)) + !case('metric_file') + ! read(valstring,*,iostat=ierr) metric_file + ! ngot = ngot + 1 + case default + imatch = .false. + end select + !igotall = (ngot >= 1) + igotall = .true. end subroutine read_options_metric @@ -181,8 +203,8 @@ end subroutine read_options_metric pure subroutine interpolate_metric(position,gcov,gcon,sqrtg) ! linear and cubic interpolators should be moved to their own subroutine ! away from eos_shen - use eos_shen, only:linear_interpolator_one_d - use einsteintk_utils, only:gcovgrid,gcongrid,sqrtggrid,dxgrid,gridorigin!,gridsize + use eos_shen, only:linear_interpolator_one_d + use metric_et_utils, only:gcovgrid,gcongrid,sqrtggrid,dxgrid,gridorigin!,gridsize real, intent(in) :: position(3) real, intent(out) :: gcov(0:3,0:3) real, intent(out), optional :: gcon(0:3,0:3), sqrtg @@ -291,7 +313,7 @@ end subroutine interpolate_metric pure subroutine interpolate_metric_derivs(position,dgcovdx, dgcovdy, dgcovdz) use eos_shen, only:linear_interpolator_one_d - use einsteintk_utils, only:metricderivsgrid, dxgrid,gridorigin + use metric_et_utils, only:metricderivsgrid, dxgrid,gridorigin real, intent(out) :: dgcovdx(0:3,0:3), dgcovdy(0:3,0:3),dgcovdz(0:3,0:3) real, intent(in) :: position(3) integer :: xlower,ylower,zlower!,xupper,yupper,zupper @@ -389,7 +411,7 @@ pure subroutine interpolate_metric_derivs(position,dgcovdx, dgcovdy, dgcovdz) end subroutine interpolate_metric_derivs pure subroutine get_grid_neighbours(position,dx,xlower,ylower,zlower) - use einsteintk_utils, only:gridorigin + use metric_et_utils, only:gridorigin real, intent(in) :: position(3) real, intent(in) :: dx(3) integer, intent(out) :: xlower,ylower,zlower @@ -414,3 +436,4 @@ end subroutine get_grid_neighbours end module metric + diff --git a/src/main/metric_et_utils.f90 b/src/main/metric_et_utils.f90 new file mode 100644 index 000000000..2a8a89493 --- /dev/null +++ b/src/main/metric_et_utils.f90 @@ -0,0 +1,150 @@ +module metric_et_utils + implicit none + + real, allocatable :: gcovgrid(:,:,:,:,:) + real, allocatable :: gcongrid(:,:,:,:,:) + real, allocatable :: sqrtggrid(:,:,:) + real, allocatable :: metricderivsgrid(:,:,:,:,:,:) + real :: dxgrid(3), gridorigin(3) + integer :: gridsize(3) + logical :: gridinit = .false. + + ! Declaration of grid limits and dimensions + integer, public :: nx,ny,nz + real, parameter :: xmin = -10.0, xmax = 10.0 + real, parameter :: ymin = -10.0, ymax = 10.0 + real, parameter :: zmin = -10.0, zmax = 10.0 + real, parameter :: mass = 1.0 ! Mass of the central object + + contains + + subroutine allocate_grid(nxin,nyin,nzin,dx,dy,dz,originx,originy,originz) + integer, intent(in) :: nxin,nyin,nzin + real, intent(in) :: dx,dy,dz,originx,originy,originz + + nx = nxin + ny = nyin + nz = nzin + gridsize(1) = nx + gridsize(2) = ny + gridsize(3) = nz + + dxgrid(1) = dx + dxgrid(2) = dy + dxgrid(3) = dz + + gridorigin(1) = originx + gridorigin(2) = originy + gridorigin(3) = originz + + allocate(gcovgrid(0:3,0:3,nx,ny,nz)) + allocate(gcongrid(0:3,0:3,nx,ny,nz)) + allocate(sqrtggrid(nx,ny,nz)) + + !metric derivs are stored in the form + ! mu comp, nu comp, deriv, gridx,gridy,gridz + ! Note that this is only the spatial derivs of + ! the metric and we will need an additional array + ! for time derivs + allocate(metricderivsgrid(0:3,0:3,3,nx,ny,nz)) + + end subroutine allocate_grid + + subroutine initialize_grid() + ! Local variable declarations + real :: dx, dy, dz, x0(3) + + nx = 100 + ny = 100 + nz = 100 + + ! Calculate the step size in each direction + dx = (xmax - xmin) / (nx - 1) + dy = (ymax - ymin) / (ny - 1) + dz = (zmax - zmin) / (nz - 1) + + x0 = [0.,0.,0.] + call allocate_grid(nx,ny,nz,dx,dy,dz,x0(1),x0(2),x0(3)) + + gridinit = .true. + + end subroutine initialize_grid + + subroutine print_metric_grid() + ! Subroutine for printing quantities of the ET grid + + print*, "Grid spacing (x,y,z) is : ", dxgrid + print*, "Grid origin (x,y,z) is: ", gridorigin + print*, "Covariant metric tensor of the grid is: ", gcovgrid(:,:,1,1,1) + + end subroutine print_metric_grid + + subroutine write_tabulated_metric(metric_file, ierr) + character(len=*), intent(in) :: metric_file + integer, intent(out) :: ierr + integer :: iunit + + ! Open the file for writing + open(newunit=iunit, file=metric_file, status='replace', form='unformatted',action='write', iostat=ierr) + if (ierr /= 0) then + ierr = 1 + return + endif + + ! Write the dimensions of the grid + write(iunit) gridsize + + ! Write the grid origin and spacing + write(iunit) gridorigin + write(iunit) dxgrid + + ! Write the metric values to the file + write(iunit) gcovgrid + write(iunit) gcongrid + write(iunit) sqrtggrid + write(iunit) metricderivsgrid + + ! Close the file + close(iunit) + ierr = 0 + end subroutine write_tabulated_metric + + subroutine read_tabulated_metric(metric_file, ierr) + character(len=*), intent(in) :: metric_file + integer, intent(out) :: ierr + integer :: iunit + + + ! Open the file for reading + open(newunit=iunit, file=metric_file, status='old', form='unformatted', action='read', iostat=ierr) + if (ierr /= 0) return + + ! Read the dimensions of the grid + read(iunit) gridsize + + ! Read the grid origin and spacing + read(iunit) gridorigin + read(iunit) dxgrid + + nx = gridsize(1) + ny = gridsize(2) + nz = gridsize(3) + + call allocate_grid(nx,ny,nz,& + dxgrid(1),dxgrid(2),dxgrid(3),& + gridorigin(1),gridorigin(2),gridorigin(3)) + + ! Read the metric values from the file + read(iunit) gcovgrid + read(iunit) gcongrid + read(iunit) sqrtggrid + read(iunit) metricderivsgrid + + gridinit = .true. + + ! Close the file + close(iunit) + ierr = 0 + end subroutine read_tabulated_metric + +end module metric_et_utils diff --git a/src/utils/einsteintk_utils.f90 b/src/utils/einsteintk_utils.f90 index 6ec6668ef..c3fe29ae7 100644 --- a/src/utils/einsteintk_utils.f90 +++ b/src/utils/einsteintk_utils.f90 @@ -16,22 +16,18 @@ module einsteintk_utils ! ! :Dependencies: part ! + use metric_et_utils, only:gridorigin,dxgrid,gridsize implicit none - real, allocatable :: gcovgrid(:,:,:,:,:) - real, allocatable :: gcongrid(:,:,:,:,:) - real, allocatable :: sqrtggrid(:,:,:) real, allocatable :: tmunugrid(:,:,:,:,:) real, allocatable :: rhostargrid(:,:,:) real, allocatable :: pxgrid(:,:,:,:) real, allocatable :: entropygrid(:,:,:) - real, allocatable :: metricderivsgrid(:,:,:,:,:,:) - real :: dxgrid(3), gridorigin(3), boundsize(3) - integer :: gridsize(3) - logical :: gridinit = .false. + real :: boundsize(3) logical :: exact_rendering character(len=128) :: logfilestor,evfilestor,dumpfilestor,infilestor contains subroutine init_etgrid(nx,ny,nz,dx,dy,dz,originx,originy,originz) + use metric_et_utils, only:allocate_grid,gridsize,dxgrid,gridorigin integer, intent(in) :: nx,ny,nz real, intent(in) :: dx,dy,dz,originx,originy,originz @@ -47,40 +43,24 @@ subroutine init_etgrid(nx,ny,nz,dx,dy,dz,originx,originy,originz) gridorigin(2) = originy gridorigin(3) = originz - - allocate(gcovgrid(0:3,0:3,nx,ny,nz)) - allocate(gcongrid(0:3,0:3,nx,ny,nz)) - allocate(sqrtggrid(nx,ny,nz)) + call allocate_grid(nx,ny,nz,dx,dy,dz,originx,originy,originz) ! Will need to delete this at somepoint ! For now it is the simplest way allocate(tmunugrid(0:3,0:3,nx,ny,nz)) - allocate(pxgrid(3,nx,ny,nz)) - allocate(rhostargrid(nx,ny,nz)) - allocate(entropygrid(nx,ny,nz)) - ! metric derivs are stored in the form - ! mu comp, nu comp, deriv, gridx,gridy,gridz - ! Note that this is only the spatial derivs of - ! the metric and we will need an additional array - ! for time derivs - allocate(metricderivsgrid(0:3,0:3,3,nx,ny,nz)) - - gridinit = .true. !exact_rendering = exact end subroutine init_etgrid subroutine print_etgrid() - ! Subroutine for printing quantities of the ET grid - - print*, "Grid spacing (x,y,z) is : ", dxgrid - print*, "Grid origin (x,y,z) is: ", gridorigin - print*, "Covariant metric tensor of the grid is: ", gcovgrid(:,:,1,1,1) - + use metric_et_utils, only:print_metric_grid + + call print_metric_grid() + end subroutine print_etgrid subroutine get_particle_rhs(i,vx,vy,vz,fx,fy,fz,e_rhs) diff --git a/src/utils/tabulate_metric.f90 b/src/utils/tabulate_metric.f90 new file mode 100644 index 000000000..1e8232a6c --- /dev/null +++ b/src/utils/tabulate_metric.f90 @@ -0,0 +1,67 @@ +program tabulate_metric + use metric_et_utils + !use metric + + implicit none + + integer :: ierr + character(len=64) :: metric_file = 'tabuled_metric.dat' + + + ! Init grid and tabulated metric + call initialize_grid() + + ! Fill and interpolate metric in the grid + call fill_grid() + + ! Write Data in file + call write_tabulated_metric(metric_file, ierr) + + if (ierr /= 0) then + print *, 'Error writing metric data to file' + else + print *, 'Metric data successfully written to file' + endif + +contains + +subroutine fill_grid() + use metric + integer :: i, j, k + real :: dx, dy, dz + real :: position(3) + real :: gcov(0:3,0:3) + real :: gcon(0:3,0:3) + real :: sqrtg + real :: dgcovdx(0:3,0:3) + real :: dgcovdy(0:3,0:3) + real :: dgcovdz(0:3,0:3) + ! Triple loop to fill the grid + dx = (xmax - xmin) / (nx - 1) + dy = (ymax - ymin) / (ny - 1) + dz = (zmax - zmin) / (nz - 1) + + do i = 1, nx + do j = 1, ny + do k = 1, nz + ! Calculate the current position in the grid + position(1) = xmin + (i - 1) * dx + position(2) = ymin + (j - 1) * dy + position(3) = zmin + (k - 1) * dz + ! Store the calculated values in the grid arrays + call get_metric_cartesian(position,gcov,gcon,sqrtg) + !call get_metric_derivs(position,dgcovdx, dgcovdy, dgcovdz) + call metric_cartesian_derivatives(position,dgcovdx, dgcovdy, dgcovdz) + gcovgrid(:,:,i,j,k) = gcov + gcongrid(:,:,i,j,k) = gcon + sqrtggrid(i,j,k) = sqrtg + metricderivsgrid(:,:,1,i,j,k) = dgcovdx + metricderivsgrid(:,:,2,i,j,k) = dgcovdy + metricderivsgrid(:,:,3,i,j,k) = dgcovdz + end do + end do + end do +end subroutine fill_grid + +end program tabulate_metric +