NCL geostrophic

From gfi
;This is a NCL file with custom functions for the GFI dynamic meteorology group


load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl"
load "WRFUserARW_new.ncl"



;a function for calculating the geostrophic and ageostrophic wind along and across a given cross section

undef("wrf_geostrophic")
function wrf_geostrophic(nc_file:file,it:numeric,lat_diff_f:numeric,lon_diff_f:numeric, \
                         WE:logical,NS:logical)

begin
a=nc_file
  P_total        = wrf_user_getvar(a,"pres",it)      
  P_base         = wrf_user_getvar(a,"PB",it)      
  G_pert         = wrf_user_getvar(a,"PH",it)
  G_base         = wrf_user_getvar(a,"PHB",it)
  q_vapor        = wrf_user_getvar(a,"QVAPOR",it)
  q_cloud        = wrf_user_getvar(a,"QCLOUD",it)
  q_rain         = wrf_user_getvar(a,"QRAIN",it)
  mu             = wrf_user_getvar(a,"MU",it)
  mub            = wrf_user_getvar(a,"MUB",it)
  eta_full       = wrf_user_getvar(a,"ZNW",it)
  eta_half       = wrf_user_getvar(a,"ZNU",it)
  f              = wrf_user_getvar(a,"F",it)
  ;P_total        = P_pert+P_base
  G_total        = G_pert+G_base
  mu_total       = mu+mub
  delta_y        = 3000.
  delta_x        = 3000.
  dimG           = dimsizes(G_pert)
  dimP           = dimsizes(P_total)
;;;;;;Calculating all finite differences;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  delta_G_eta    = G_total(1:dimG(0)-1,:,:)-G_total(0:dimG(0)-2,:,:)
  delta_G_x      = G_total(:,:,1:dimG(2)-1)-G_total(:,:,0:dimG(2)-2)
  delta_G_y      = G_total(:,1:dimG(1)-1,:)-G_total(:,0:dimG(1)-2,:)
  delta_P_eta    = P_total(1:dimP(0)-1,:,:)-P_total(0:dimP(0)-2,:,:)
  delta_P_x      = P_total(:,:,1:dimP(2)-1)-P_total(:,:,0:dimP(2)-2)
  delta_P_y      = P_total(:,1:dimP(1)-1,:)-P_total(:,0:dimP(1)-2,:)
  delta_eta_full = eta_full(1:dimG(0)-1)-eta_full(0:dimG(0)-2)
  delta_eta_half = eta_half(1:dimP(0)-1)-eta_half(0:dimP(0)-2)
  
  delta_eta_full_conform_P     = conform_dims((/dimP(0),dimP(1),dimP(2)/),delta_eta_full,0)
  delta_eta_half_conform_G     = conform_dims((/dimG(0)-2,dimG(1),dimG(2)/),delta_eta_half,0)
  delta_G_eta                  = delta_G_eta/delta_eta_full_conform_P
  delta_P_eta                  = delta_P_eta/delta_eta_half_conform_G
;;;;;;;;Calculating alpha and alpha_D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  mu_total_conform_P        = conform_dims((/dimP(0),dimP(1),dimP(2)/),mu_total,(/1,2/))
  alpha_D                   = -delta_G_eta/mu_total_conform_P 
  alpha                     = alpha_D*(1+q_vapor+q_cloud+q_rain)
  
;;;;;;;;getting right dimensions and interpolating to vg;;;;;;;;;;;;;  

  mu_total_interpol_x           = (mu_total(:,0:dimP(2)-2)+mu_total(:,1:dimP(2)-1))/2 
  mu_total_interpol_y           = (mu_total(0:dimP(1)-2,:)+mu_total(1:dimP(1)-1,:))/2
  alpha_interpol_x              = (alpha(:,:,0:dimP(2)-2)+alpha(:,:,1:dimP(2)-1))/2
  alpha_interpol_y              = (alpha(:,0:dimP(1)-2,:)+alpha(:,1:dimP(1)-1,:))/2
  alpha_D_interpol_x            = (alpha_D(:,:,0:dimP(2)-2)+alpha_D(:,:,1:dimP(2)-1))/2
  alpha_D_interpol_y            = (alpha_D(:,0:dimP(1)-2,:)+alpha_D(:,1:dimP(1)-1,:))/2
  f_interpol_x                  = (f(:,0:dimP(2)-2)+f(:,1:dimP(2)-1))/2
  f_interpol_y                  = (f(0:dimP(1)-2,:)+f(1:dimP(1)-1,:))/2
  
  delta_P_eta_interpol_vg       = (delta_P_eta(0:dimG(0)-4,:,0:dimG(2)-2)+delta_P_eta(1:dimG(0)-3,:,0:dimG(2)-2)+delta_P_eta(1:dimG(0)-3,:,1:dimG(2)-1)+delta_P_eta(0:dimG(0)-4,:,1:dimG(2)-1))/4
  delta_P_eta_interpol_ug       = (delta_P_eta(0:dimG(0)-4,0:dimG(1)-2,:)+delta_P_eta(1:dimG(0)-3,0:dimG(1)-2,:)+delta_P_eta(1:dimG(0)-3,1:dimG(1)-1,:)+delta_P_eta(0:dimG(0)-4,1:dimG(1)-1,:))/4
  
  delta_G_x_interpol_vg         = (delta_G_x(1:dimG(0)-3,:,0:dimG(2)-2)+delta_G_x(2:dimG(0)-2,:,0:dimG(2)-2))/2
  delta_G_y_interpol_ug         = (delta_G_y(1:dimG(0)-3,0:dimG(1)-2,:)+delta_G_y(2:dimG(0)-2,0:dimG(1)-2,:))/2

  mu_total_interpol_x_conform_P = conform_dims((/dimP(0),dimP(1),dimP(2)-1/),mu_total_interpol_x,(/1,2/))
  mu_total_interpol_y_conform_P = conform_dims((/dimP(0),dimP(1)-1,dimP(2)/),mu_total_interpol_y,(/1,2/))
  f_interpol_x_conform_P        = conform_dims((/dimP(0),dimP(1),dimP(2)-1/),f_interpol_x,(/1,2/))
  f_interpol_y_conform_P        = conform_dims((/dimP(0),dimP(1)-1,dimP(2)/),f_interpol_y,(/1,2/))
  delta_eta_half_conform_Gx     = conform_dims((/dimG(0)-2,dimG(1),dimG(2)-1/),delta_eta_half,0)
  delta_eta_half_conform_Gy     = conform_dims((/dimG(0)-2,dimG(1)-1,dimG(2)/),delta_eta_half,0)

;;;;;;split it up in two terms and adding afterwards;;;;;;;;;;;;;;;;;
vg_term1 = mu_total_interpol_x_conform_P(1:dimP(0)-2,:,:)*alpha_interpol_x(1:dimG(0)-3,:,:)/f_interpol_x_conform_P(1:dimP(0)-2,:,:)*delta_P_x(1:dimP(0)-2,:,:)/delta_x

ug_term1 = -mu_total_interpol_y_conform_P(1:dimP(0)-2,:,:)*alpha_interpol_y(1:dimG(0)-3,:,:)/f_interpol_y_conform_P(1:dimP(0)-2,:,:)*delta_P_y(1:dimP(0)-2,:,:)/delta_y

vg_term2 = delta_P_eta_interpol_vg*delta_G_x_interpol_vg/delta_x*alpha_interpol_x(1:dimG(0)-3,:,:)/(alpha_D_interpol_x(1:dimG(0)-3,:,:)*f_interpol_x_conform_P(1:dimP(0)-2,:,:))


ug_term2 = -delta_P_eta_interpol_ug*delta_G_y_interpol_ug/delta_y*alpha_interpol_y(1:dimG(0)-3,:,:)/(alpha_D_interpol_y(1:dimG(0)-3,:,:)*f_interpol_y_conform_P(1:dimP(0)-2,:,:))

vg=(vg_term1+vg_term2)/mu_total_interpol_x_conform_P(1:dimP(0)-2,:,:)
ug=(ug_term1+ug_term2)/mu_total_interpol_y_conform_P(1:dimP(0)-2,:,:)

;interpolate the geostrophic winds to mass points
vga=(vg(:,:,0:dimP(2)-3)+vg(:,:,1:dimP(2)-2))/2
uga=(ug(:,0:dimP(1)-3,:)+ug(:,1:dimP(1)-2,:))/2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Calculate the angle between th cross section and the regular grid
 if(WE .and. lat_diff_f.ne.0.) then
    gamma            = atan(lat_diff_f/lon_diff_f)
 else if(WE .and. lat_diff_f.eq.0.) then
        gamma=0.
      end if
 end if  

 if(NS .and. lon_diff_f.lt.0.)then
   lat_diff_f=-lat_diff_f
   gamma=3.14/2.0-atan(lat_diff_f/lon_diff_f)
 else if(NS .and. lon_diff_f.gt.0.)then
          gamma=atan(lat_diff_f/lon_diff_f)+3.14/2.
      else if(NS .and. lon_diff_f.eq.0)then
             gamma=0.
           end if
      end if
 end if

;;;;Make use of vector algebra and use a rotation matrix :-);;;;;;;;;
 print(gamma*180/3.14)
 wwg_along      = cos(gamma)*uga(:,:,1:dimP(2)-2)+sin(gamma)*vga(:,1:dimP(1)-2,:)
 wwg_across     = -sin(gamma)*uga(:,:,1:dimP(2)-2)+cos(gamma)*vga(:,1:dimP(1)-2,:)
 wwg_along@description  = "Along geostrophic Wind"
 wwg_across@description = "Across geostrophic Wind"


 u             = wrf_user_getvar(a,"U",it)      ; 3D U at mass points
 v             = wrf_user_getvar(a,"V",it)      ; 3D V at mass points
 theta         = wrf_user_getvar(a,"theta",it)

;;;;interpolate it to masspoints myself, since i don't know what wrf_user_getvar is really doing;;;;;;; 

 ua=(u(1:dimP(0)-2,1:dimP(1)-2,0:dimP(2)-1)+u(1:dimP(0)-2,1:dimP(1)-2,1:dimP(2)))/2
 va=(v(1:dimP(0)-2,0:dimP(1)-1,1:dimP(2)-2)+v(1:dimP(0)-2,1:dimP(1),1:dimP(2)-2))/2


 ww_along      = cos(gamma)*ua(:,:,1:dimP(2)-2)+sin(gamma)*va(:,1:dimP(1)-2,:)
 ww_across     = -sin(gamma)*ua(:,:,1:dimP(2)-2)+cos(gamma)*va(:,1:dimP(1)-2,:)
;calculating the ageostrophic components along and across the cross section


wwageo_along  = ww_along-wwg_along
wwageo_across = ww_across-wwg_across
wwageo_along@description = "Along ageostrophic wind"
wwageo_across@description= "Across ageostrophic wind" 




all_winds=new((/dimP(0)-2,dimP(1)-2,dimP(2)-2,6/),typeof(ww_along))
all_winds(:,:,:,0)=ww_along

all_winds(:,:,:,0)=ww_along
all_winds(:,:,:,1)=ww_across
all_winds(:,:,:,2)=wwg_along
all_winds(:,:,:,3)=wwg_across
all_winds(:,:,:,4)=wwageo_along
all_winds(:,:,:,5)=wwageo_across


return(all_winds)

end