Attachment 'holmboe1.py'

Download

   1 import sys; sys.path.append('../py_src')
   2 
   3 from pyOM_gui import pyOM_gui as pyOM
   4 #from pyOM_cdf import pyOM_cdf as pyOM
   5 from numpy import *
   6 
   7 
   8 fac = 0.5
   9 mix = 2e-5/fac**2
  10 
  11 class kelv2(pyOM):
  12    """ 
  13    """
  14    def set_parameter(self):
  15      """set main parameter
  16      """
  17      M=self.fortran.main_module   
  18 
  19      (M.nx,M.ny,M.nz)=(int(64),  1, int(40) )
  20      M.dt_mom     = 0.05/fac
  21      M.dt_tracer  = 0.05/fac
  22 
  23      M.enable_conserve_energy = 0
  24      M.coord_degree           = 0
  25      M.enable_cyclic_x        = 1
  26      M.enable_hydrostatic     = 0
  27      M.eq_of_state_type       = 1 
  28 
  29      M.congr_epsilon = 1e-12
  30      M.congr_max_iterations = 5000
  31      M.congr_epsilon_non_hydro=   1e-8
  32      M.congr_max_itts_non_hydro = 5000    
  33 
  34      M.enable_explicit_vert_friction = 1
  35      M.kappam_0 = mix/fac**2
  36      M.enable_hor_friction = 1
  37      M.a_h = mix/fac**2
  38 
  39      M.enable_superbee_advection = 1
  40      return
  41 
  42    def set_mean_state1(self,dz):
  43      # two vorticity jumps and one density jump
  44      M=self.fortran.main_module   
  45      zw=arange(M.nz)*dz+ dz
  46      zt=zw-dz/2.0
  47      zt = zt - zw[-1]
  48      zw = zw - zw[-1]
  49      alpha = self.fortran.linear_eq_of_state.linear_eq_of_state_drhodt()
  50      u=1
  51      z1=-15.0
  52      z2=-5.0
  53      S=2*u/(z2-z1)
  54      self.U=0*zt-u
  55      for k in range(M.nz):
  56          if   zt[k]>z1 and zt[k]< z2: self.U[k]=S*(zt[k]-z1)-u
  57          elif zt[k]>=z2:              self.U[k]=u
  58      T0 = 1.0
  59      z3=-10.0
  60      self.T=0*zt
  61      for k in range(M.nz):
  62            if zt[k]>z3: self.T[k]=T0
  63      self.B=-self.T*alpha*9.81/1024.
  64      return
  65 
  66 
  67    def set_mean_state2(self,dz):
  68      # two layer flow
  69      M=self.fortran.main_module   
  70      zw=arange(M.nz)*dz+ dz
  71      zt=zw-dz/2.0
  72      zt = zt - zw[-1]
  73      zw = zw - zw[-1]
  74      alpha = self.fortran.linear_eq_of_state.linear_eq_of_state_drhodt()
  75      self.T=-(9.85-6.5*tanh( (zt-zt[M.nz/2-1] ) /zt[0]*10 ))
  76      self.B=-self.T*alpha*9.81/1024.
  77      self.U=0.6+0.5*tanh( (zt-zt[M.nz/2-1])/zt[0]*10)
  78      return 
  79  
  80    def calc_lin_stab(self,dz):
  81      M=self.fortran.main_module   
  82      alpha = self.fortran.linear_eq_of_state.linear_eq_of_state_drhodt()
  83      
  84      self.set_mean_state1(dz)
  85      #self.set_mean_state2(dz)
  86      
  87      k=linspace(0,1.0,50);   
  88      om_max,om,kmax,u,v,w,b,p=pe(self.U,self.B,dz,k,0,0)
  89      print ' Max. growth rate %f 1/s ' % (-imag(om))
  90      print ' k_max = %f ' % (kmax,)
  91      self.kmax = kmax
  92      self.u_pert = 5e-2*real(u)
  93      self.w_pert = 5e-2*real(w)
  94      self.T_pert = -5e-2*real(b)/alpha*1024/9.81
  95      return 
  96  
  97 
  98    def set_grid(self):
  99      M=self.fortran.main_module   
 100      M.dzt[:]=0.25/fac
 101      self.calc_lin_stab(0.25/fac)
 102 
 103      L = 2*2*pi/self.kmax    # two waves
 104      dx  =   L/M.nx 
 105      M.dt_tracer  = dx*0.02/0.25   # c = 0.25/0.05  dt =dx/c
 106      M.dt_mom     = dx*0.02/0.25
 107      print "dx=%f m, dt= %f s "%(dx,M.dt_tracer)
 108      
 109      M.dxt[:]=dx
 110      M.dyt[:]=dx
 111      return
 112 
 113          
 114    def set_initial_conditions(self):
 115      """ setup initial conditions
 116      """
 117      M=self.fortran.main_module
 118      for k in range(M.nz):
 119        for i in range(M.xt.shape[0]):
 120         M.temp[i,:,k,:] = self.T[k]+self.T_pert[k]*sin( self.kmax*M.xt[i] ) 
 121         M.u[i,:,k,:]    = self.U[k]+self.u_pert[k]*sin( self.kmax*M.xt[i] ) 
 122         M.w[i,:,k,:]    =           self.w_pert[k]*sin( self.kmax*M.xt[i] ) 
 123      return
 124 
 125 
 126    def user_defined_signal(self):
 127        """ this routine must be called by all processors
 128        """
 129        M=self.fortran.main_module  
 130        a = zeros( (M.nx,M.ny), 'd', order = 'F')
 131        a[M.is_pe-1:M.ie_pe,0] = M.xt[2:-2]
 132        self.fortran.pe0_recv_2d(a)
 133        self.xt_gl = a[:,0].copy()
 134        
 135        self.temp_gl = zeros( (M.nx,M.ny,M.nz), 'd', order = 'F')
 136        self.u_gl = zeros( (M.nx,M.ny,M.nz), 'd', order = 'F')
 137        self.w_gl = zeros( (M.nx,M.ny,M.nz), 'd', order = 'F')
 138        for k in range(M.nz):
 139          a[M.is_pe-1:M.ie_pe,M.js_pe-1:M.je_pe] = where( M.maskt[2:-2,2:-2,k] >0,  M.temp[2:-2,2:-2,k,M.tau-1] , NaN) 
 140          self.fortran.pe0_recv_2d(a)
 141          self.temp_gl[:,:,k]=a.copy()
 142 
 143          a[M.is_pe-1:M.ie_pe,M.js_pe-1:M.je_pe] = where( M.masku[2:-2,2:-2,k] >0,  M.u[2:-2,2:-2,k,M.tau-1] , NaN) 
 144          self.fortran.pe0_recv_2d(a)
 145          self.u_gl[:,:,k]=a.copy()
 146 
 147          a[M.is_pe-1:M.ie_pe,M.js_pe-1:M.je_pe] = where( M.maskw[2:-2,2:-2,k] >0,  M.w[2:-2,2:-2,k,M.tau-1] , NaN) 
 148          self.fortran.pe0_recv_2d(a)
 149          self.w_gl[:,:,k]=a.copy()
 150 
 151        return
 152 
 153    def make_plot(self):
 154        M=self.fortran.main_module
 155        
 156        self.set_signal('user_defined') # following routine is called by all PEs
 157        self.user_defined_signal()
 158        
 159        self.figure.clf()
 160        ax=self.figure.add_subplot(211)
 161        
 162        co=ax.contourf(self.xt_gl,M.zt, self.temp_gl[:,0,:].transpose())
 163        self.figure.colorbar(co)
 164        ax.quiver(self.xt_gl[::2],M.zt[::2],self.u_gl[::2,0,::2].transpose(),self.w_gl[::2,0,::2].transpose() )
 165        ax.set_title('Temperature [deg C]')
 166        ax.set_ylabel('z [m]')
 167        #ax.axis('tight')
 168        
 169        ax=self.figure.add_subplot(212)
 170        co=ax.contourf(self.xt_gl,M.zt, self.w_gl[:,0,:].transpose())
 171        self.figure.colorbar(co)
 172        ax.set_title('vertical velocity [m/s]')
 173        ax.set_xlabel('x [m]')
 174        return
 175 
 176 
 177 
 178 def pe(U,B0,dz,kx,fh,f0):
 179   # solution for primitive equations
 180   import numpy as np
 181   import sys
 182   cs = 150 # speed of sound, artificially reduced
 183   N=U.shape[0]
 184   # derivatives of U,V and B
 185   UZ=np.zeros(N,'d');BZ=np.zeros(N,'d')
 186   for n in range(1,N-1):
 187    UZ[n]=(U[n+1]-U[n-1])/(2*dz)
 188    BZ[n]=(B0[n+1]-B0[n-1])/(2*dz)
 189   UZ[0]=UZ[1];UZ[-1]=UZ[-2];
 190   BZ[0]=BZ[1];BZ[-1]=BZ[-2];
 191   # allocate some variables
 192   I=complex(0,1)
 193   A  = np.zeros((5,5,N),'Complex64')
 194   B  = np.zeros((5,5,N),'Complex64')
 195   C  = np.zeros((5,5,N),'Complex64')
 196   AA = np.zeros((5*N,5*N),'Complex64')
 197   om_max= np.zeros((kx.shape[0],),'Complex64');
 198   omax  = complex(0,0)
 199   AAmax = np.zeros((5*N,5*N),'Complex64')
 200   kmax  = 0;
 201   # enter main loop
 202   for i in range(kx.shape[0]): # loop over zonal wavelength
 203       sys.stdout.write('\b'*21+'calculating i=%3i/%3i'%(i,kx.shape[0]) )
 204       sys.stdout.flush()
 205 
 206       Uk   = kx[i]*U # k \cdot \v U
 207       UZk  = kx[i]*UZ # k \cdot \v U'
 208 
 209       kh2 = kx[i]**2 + 1e-18
 210 
 211       for n in range(N): # loop over depth
 212         np1 = min(N-1,n+1)
 213         nm  = max(0,n-1)
 214 
 215         B[0,2,n]=  0.
 216         B[1,2,n]= -(kx[i]*fh+UZk[n])/(2*kh2)
 217         B[3,2,n]= I*BZ[n]/2
 218         B[4,2,n]= -cs**2*I/dz
 219 
 220         C[2,0,n]=  0
 221         C[2,1,n]= -kx[i]*fh/2
 222         C[2,3,n]= -I/2
 223         C[2,4,n]=  I/dz
 224 
 225         A[0,:,n]= [ Uk[n],I*f0,0,0,0 ]
 226         A[1,:,n]= [-I*f0 ,Uk[n], -(kx[i]*fh+UZk[n])/(2*kh2),0,I]
 227         A[2,:,n]= [ 0 ,-kx[i]*fh/2 ,(Uk[n]+Uk[np1])/2,-I/2,-I/dz ]
 228         A[3,:,n]= [ -f0*UZk[n],0,I*BZ[n]/2,Uk[n], 0  ]
 229         A[4,:,n]= [ 0, -I*cs**2*kh2 ,  I*cs**2/dz, 0   , 0 ]
 230 
 231       # upper boundary condition
 232       A[2,:,-1]=0; B[2,:,-1]=0; C[2,:,-1]=0;
 233       A[:,2,-1]=0
 234       C[:,2,-1]=0
 235       C[:,2,-2]=0
 236 
 237       # lower boundary condition
 238       A[:,2,0]=A[:,2,0]-B[:,2,0]
 239 
 240       # build large matrix
 241       n1 = 0; n2 = 5
 242       AA[ n1:n2,(n1+5):(n2+5) ] = C[:,:,0]
 243       AA[ n1:n2,n1:n2         ] = A[:,:,0]
 244       for n in range(1,N-1):
 245         n1 = 5*n; n2 = 5*(n+1)
 246         AA[ n1:n2, n1  :n2  ]     = A[:,:,n]
 247         AA[ n1:n2, (n1-5):(n2-5)] = B[:,:,n]
 248         AA[ n1:n2, (n1+5):(n2+5)] = C[:,:,n]
 249       n1 = 5*(N-1); n2 = 5*N
 250       AA[ n1:n2, n1    :n2     ] = A[:,:,-1];
 251       AA[ n1:n2, (n1-5):(n2-5) ] = B[:,:,-1];
 252 
 253       # eigenvalues of matrix
 254       om = np.linalg.eigvals(AA)
 255       kh=kx[i]
 256       # search minimal imaginary eigenvalue
 257       if kh>0: 
 258         om = np.extract( np.abs( np.real( om/kh )) <0.5*cs, om )
 259         n=np.argmin( np.imag(om) )
 260         om_max[i]=om[n]
 261         # look for global minimum
 262         if np.imag(om[n]) < np.imag(omax):
 263            omax=om[n]; kmax=kx[i]; AAmax[:,:] = AA
 264   sys.stdout.write('\n')
 265 
 266   #eigenvectors for global minimum
 267   om, phi=np.linalg.eig(AAmax)
 268   n=np.argmin( np.imag(om) )
 269   om=om[n]
 270   phi = phi[:,n]
 271 
 272   #complete solution
 273   str= phi[0::5]
 274   pot= phi[1::5]
 275   u= -complex(0,1)*kmax*pot
 276   v=-complex(0,1)*kmax*str
 277   w= phi[2::5]
 278   b= phi[3::5]
 279   p= phi[4::5]
 280 
 281   return om_max,om,kmax,u,v,w,b,p
 282 
 283 
 284 if __name__ == "__main__":
 285       m=kelv2()
 286       dt=m.fortran.main_module.dt_tracer
 287       m.run( snapint = dt*100 ,runlen = dt*10000)

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2014-09-13 14:08:12, 8.2 KB) [[attachment:holmboe1.py]]
  • [get | view] (2014-09-13 15:06:26, 106.1 KB) [[attachment:snapshot1.png]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.