Difference between revisions of "Team 6 Solution"
From Interactive System for Ice sheet Simulation
Line 23: | Line 23: | ||
integer :: nx ! Number of nodes | integer :: nx ! Number of nodes | ||
− | real, parameter :: dt = 1 ! length time step (years) | + | real, parameter :: dt = 0.1 ! length time step (years) |
− | integer, parameter :: nt = | + | integer, parameter :: nt = 10000 ! number of time steps |
integer :: t ! current time step | integer :: t ! current time step | ||
real :: xl ! start of domain | real :: xl ! start of domain | ||
Line 30: | Line 30: | ||
real :: Const ! (2*A)*(rho*grav)^n/(n+2) | real :: Const ! (2*A)*(rho*grav)^n/(n+2) | ||
real, parameter :: dx = 1000 ! node spacing (m) | real, parameter :: dx = 1000 ! node spacing (m) | ||
− | real, parameter :: dbdx = -0. | + | real, parameter :: dbdx = -0.1 ! bedslope (m/m) |
real, parameter :: g = 9.8 ! gravity (m/s2) | real, parameter :: g = 9.8 ! gravity (m/s2) | ||
real, parameter :: rho = 917 ! density of ice (g/cm3) | real, parameter :: rho = 917 ! density of ice (g/cm3) | ||
Line 93: | Line 93: | ||
!Constant C | !Constant C | ||
− | Const = (2.*A)*(rho*g)**n | + | Const = (2.0*A)/real(n+2)*(rho*g)**n |
!Initial conditions | !Initial conditions | ||
Line 103: | Line 103: | ||
spatial_midpoint_loop: do ii=1,nx-1 | spatial_midpoint_loop: do ii=1,nx-1 | ||
!Calculate flux midway between elevation points | !Calculate flux midway between elevation points | ||
− | + | d(ii) = Const * ((H(ii)+H(ii+1))/2.0)**(n+2) * ((elev(ii+1)-elev(ii))/(dx))**(n-1) | |
+ | mflux(ii)= -d(ii) * (elev(ii+1)-elev(ii) )/dx | ||
enddo spatial_midpoint_loop | enddo spatial_midpoint_loop | ||
Line 109: | Line 110: | ||
spatial_gridpoint_loop: do jj=2,nx-1 | spatial_gridpoint_loop: do jj=2,nx-1 | ||
− | dhdt_store(jj) = - (mflux(jj | + | dhdt_store(jj) = - (mflux(jj)-mflux(jj-1))/dx + Mb(jj) |
H(jj) = H(jj) + dhdt_store(jj) * dt !new thickness | H(jj) = H(jj) + dhdt_store(jj) * dt !new thickness | ||
!search for terminus location... | !search for terminus location... | ||
Line 123: | Line 124: | ||
!output geometry (also need to output geom at t=0 ?) | !output geometry (also need to output geom at t=0 ?) | ||
− | write (*,*) | + | if (mod(t,10)==0) then |
+ | write (*,*) elev | ||
+ | endif | ||
end do time_loop | end do time_loop | ||
Line 140: | Line 143: | ||
end program OurCode | end program OurCode | ||
+ | |||
+ | |||
</source> | </source> |
Latest revision as of 14:34, 6 August 2009
!> 1D Convection Diffusion equations solver in Fortran !! !! Solves the equation: !! !!\f[ !!\frac{du}{dt}=\frac{d}{dx}D(x)\frac{du}{dx} + C(x)\frac{du}{dx}+F(x)u-S(x) !!\f] !! for \f$u\f$, given functions for \f$D\f$, \f$C\f$, \f$F\f$, and \f$S\f$, defined in this program !! !! Explicit methods are used !! !! \author Matt & Erin & Sophie (jvj) !! \date 8-5-09 program OurCode implicit none ! local variables integer :: nx ! Number of nodes real, parameter :: dt = 0.1 ! length time step (years) integer, parameter :: nt = 10000 ! number of time steps integer :: t ! current time step real :: xl ! start of domain real :: xr ! end of domain (m) real :: Const ! (2*A)*(rho*grav)^n/(n+2) real, parameter :: dx = 1000 ! node spacing (m) real, parameter :: dbdx = -0.1 ! bedslope (m/m) real, parameter :: g = 9.8 ! gravity (m/s2) real, parameter :: rho = 917 ! density of ice (g/cm3) real, parameter :: A = 1e-16 ! Glen rate factor (kPa-3 a-1) real, parameter :: n = 3 ! Glen Flow Exponent (unitless) real, parameter :: M0 = 4.0 ! m/yr real, parameter :: M1 = 2.0/10000.0 ! m/yr/m real, dimension(:), allocatable :: elev ! surface elevation (m) real, dimension(:), allocatable :: bedelev ! bed elevation (m), y origin is at the bed elev in the left of the domain. up is up! real, dimension(:), allocatable :: H ! thicknesss (m) real, dimension(:), allocatable :: Mb ! Mass Balance (m/yr) real, dimension(:), allocatable :: dhdt_store ! space to store du/dx real, dimension(:), allocatable :: xref ! refence distance real, dimension(:), allocatable :: d ! diffusivity coeff real, dimension(:), allocatable :: mflux ! mass flux between grid points integer :: ii ! a counter integer :: jj integer :: errstat ! for error checking ! Set up grid ! Space xl = 0.0 xr = 60000.0 !(m) our guess at how large of a domain we need (started with 60km) nx = int( ((xr - xl) / dx) +1 ) ! let's allocate some memory allocate(elev(nx),stat=errstat) call checkerr(errstat,"failed to allocate elev") allocate(xref(nx),stat=errstat) call checkerr(errstat,"failed to allocate xref") allocate(bedelev(nx),stat=errstat) call checkerr(errstat,"failed to allocate bedelev") allocate(H(nx),stat=errstat) call checkerr(errstat,"failed to allocate H") allocate(Mb(nx),stat=errstat) call checkerr(errstat,"failed to allocate Mb") allocate(d(nx-1),stat=errstat) call checkerr(errstat,"failed to allocate d") allocate(mflux(nx-1),stat=errstat) call checkerr(errstat,"failed to allocate mflux") allocate(dhdt_store(nx),stat=errstat) call checkerr(errstat,"failed to allocate dhdt_store") !We could've done this as a function, Matt and Erin revolted vs. Sophie. Said No. do ii=1,nx bedelev(ii) = dx*dbdx*real(ii-1) !reminder, at x = 0, bedelev = 0 m Mb(ii) = M0 - M1*(dx*real(ii-1)) !Mass balance equation (m/yr) xref(ii)= real(ii-1)*dx enddo !Constant C Const = (2.0*A)/real(n+2)*(rho*g)**n !Initial conditions H = 0.0 !set thickness everywhere in x as 0.0 m elev = bedelev + H !No glacier yet time_loop: do t=1,nt spatial_midpoint_loop: do ii=1,nx-1 !Calculate flux midway between elevation points d(ii) = Const * ((H(ii)+H(ii+1))/2.0)**(n+2) * ((elev(ii+1)-elev(ii))/(dx))**(n-1) mflux(ii)= -d(ii) * (elev(ii+1)-elev(ii) )/dx enddo spatial_midpoint_loop H(1) = 0.0 ! left boundary condition (this could be moved above time_loop) spatial_gridpoint_loop: do jj=2,nx-1 dhdt_store(jj) = - (mflux(jj)-mflux(jj-1))/dx + Mb(jj) H(jj) = H(jj) + dhdt_store(jj) * dt !new thickness !search for terminus location... if (H(jj)<0) then H(jj) = 0 !write (*,*) jj, (jj-1)*dx endif enddo spatial_gridpoint_loop !to update 'elev' elev = bedelev + H !output geometry (also need to output geom at t=0 ?) if (mod(t,10)==0) then write (*,*) elev endif end do time_loop contains subroutine checkerr(errstat,msg) implicit none integer, intent(in) :: errstat character(*), intent(in) :: msg if (errstat /= 0) then write(*,*) "ERROR:", msg stop end if end subroutine checkerr end program OurCode