Chapter 7: Example of Advanced use¶
7.1 Flux correction¶
1. Flux correction (I) (ROMS)¶
How to implement a flux correction procedure ?
\(\frac{\partial T}{\partial t}+\frac{\partial F^x}{\partial x}+\frac{\partial F^y}{\partial y}=0\)
\(T^{n+1}_{i,j}=T^n_{i,j}-\frac{\Delta t}{\Delta x}\left( F^x_{i,j}-F^x_{i-1,j} \right)-\frac{\Delta t}{\Delta y}\left( F^y_{i,j}-F^y_{i,j-1} \right)\)
Store the fluxes on the fine and coarse grid and use the differences to correct the coarse grid points near the interface.
2. Flux correction (II) (ROMS)¶
- Declare flux arrays (\(F_x, F_y\)), compute then and make the summation on the fine grids over a parent time step
b. Declare the profiles corresponding to these fluxes
Call Agrif_Declare_Variable((/1,2/),(/1,1/),(/'x','y'/),(/0,1/),(/nx,ny/),F_xid) Call Agrif_Declare_Variable((/2,1/),(/1,1/),(/'x','y'/),(/1,0/),(/nx,ny/),F_yid)c. Set the update type
Call Agrif_Set_UpdateType(F_xid,update1=Agrif_Update_Copy , update2=Agrif_Update_Average ) Call Agrif_Set_UpdateType(F_yid,update1=Agrif_Update_Average , update2= Agrif_Update_Copy )
3. Make the flux correction inside a call to Agrif_Update¶
Call Agrif_Update_Variable (F_xid, procname = Correct_Flux_x)
Call Agrif_Update_Variable (F_yid, procname = Correct_Flux_y)
4. Flux correction (III) (ROMS)¶
Example: Correct_Flux_x
Subroutine Correct_Flux_x(tabres,i1,i2,j1,j2,before,nb,ndir)
logical :: western_side, eastern_side
if (before) then
tabres = Fx(i1:i2,j1:j2)
else
western_side = (nb == 1).AND.(ndir == 1)
eastern_side = (nb == 1).AND.(ndir == 2)
if (western_side) then
do j=j1,j2
My_traceur(i1,j) = My_traceur(i1,j)-(dt/(dx))(tabres(i1,j)-Fx(i1,j))
enddo
endif
if (eastern_side) then
do j=j1,j2
My_traceur(i2+1,j) = My_traceur(i2+1,j)+(dt/(dx))(tabres(i2,j)-Fx(i2,j))
enddo
endif
endif
End Subroutine Correct_Flux_x
7.2 Wetting and drying¶
Wetting and drying (I) (MARS)
How to specify if we are in land or water through the SpecialValue ?
Example: Interp_Traceur
Agrif_Use_SpecialValue = .TRUE.
Agrif_SpecialValue = -999.
Call Agrif_Bc_Variable(tabtemp, my_Traceur_id,procname = Interp_my_Traceur)
Subroutine Inter_my_Traceur(tabres,i1,i2,j1,j2,before)
if (before) then
where ((h0(i1:i2,j1:j2)+ssh(i1:i2,j1:j2)) < min_depth)
tabres = Agrif_SpecialValue
elsewhere
tabres = my_Traceur(i1:i2,j1:j2)
endwhere
else
where (tabres /= Agrif_SpecialValue)
My_traceur = tabres
endwhere
endif
End Subroutine Inter_my_Traceur
7.3 Vertical refinement¶
7.3.1. Different vertical grids (I) (NEMO)¶
The grids have different vertical meshes. The vertical remapping between the two grids are done in the procnames routines.
Example: Update with different vertical grids
Subroutine Update_My_Traceur(tabres,i1,i2,k1,k2,before)
real,dimension(i1:i2,k1:k2) :: tabres
logical before
if (before) then
! on the child grid
tabres = My_Traceur(i1:i2,k1:k2)
else
! on the parent grid (NB: tabres has a vertical dimension corresponding to the one of fine grid)
do i=i1,i2
call remap(tabres(i,:),My_traceur(i,:)) ! remap is a vertical remapping procedure
enddo
endif
End Subroutine Update_My_Traceur
7.3.2. Different vertical grids (II) (NEMO)¶
The grids have different vertical mesh. The vertical remapping between the two grids are done in the procnames routines.
Example: Interpolation with different vertical grids
Subroutine Interp_My_Traceur(tabres,i1,i2,k1,k2,before)
real,dimension(i1:i2,k1:k2) :: tabres
logical before
if (before) then
! on the parent grid
tabres = My_Traceur(i1:i2,k1:k2)
else
! on the child grid (NB: tabres has a vertical dimension corresponding to the one of parent grid)
do i=i1,i2
call remap(tabres(i,:),My_traceur(i,:)) ! remap is a vertical remapping procedure
enddo
endif
End Subroutine Interp_My_Traceur
7.4 Interpolation with fine grid values¶
7.4.1. Tracer interpolation (I) (NEMO)¶
We want to use internal fine grid values during the interpolation
7.4.2. Tracer interpolation (II) (NEMO)¶
Profiles
decal = Agrif_IRhox() + 1
Call Agrif_Declare_Profiles((/2,2/),(/1,1/),(/-decal,-decal/),(/nx+decal,ny+decal/),My_Traceur_id)
Call Agrif_Set_Bc(My_traceur_id,(/decal-1,decal/))
! NB: if not specified interp type is Agrif_constant
Call Agrif_Set_Bcinterp(My_traceur_id,interp12=Agrif_ppm,interp21=Agrif_ppm)
7.4.3. Tracer interpolation (III) (NEMO)¶
Interpolation procnames
Call Agrif_Bc_Variable(tabtemp, My_traceur_id,procname = Interp_My_Traceur)
Subroutine Interp_My_Traceur(tabres,i1,i2,j1,j2,before,nb,ndir)
if (before) then
tabres = My_Traceur(i1:i2,j1:j2)
else
western_side = (nb == 1).AND.(ndir == 1)
if (western_edge) then
do j=j1,j2
if (u(1,j) <0.) then
My_Traceur(0,j)=a1*tabres(-Agrif_irhox(),j) + b1*My_Traceur(1,j) + (1.-a1-b1)*My_Traceur(2,j)
else
My_Traceur(0,j)=a2*tabres(-Agrif_irhox()-1,j)+b2*tabres(-Agrif_irhox(),j)+(1.-a2-b2)*My_Traceur(1,j)
endif
enddo
endif
endif
End Subroutine Interp_My_Traceur