<p><b>duda</b> 2010-03-31 16:55:43 -0600 (Wed, 31 Mar 2010)</p><p>BRANCH COMMIT<br>
<br>
module_mpas_cam_interface.F:<br>
   - Add implementation of CAM_INIDAT_TO_MPAS(...)<br>
<br>
   - Add routine mpas_write_output() to allow us to <br>
     write output.nc file from CAM test driver<br>
<br>
   - Fix MPAS_DYN_RUN: after taking a timestep, we<br>
     need to shift fields in time_levs(2) to<br>
     time_levs(1)<br>
<br>
test_driver.F:<br>
   - Rename variable 'Omega' to 'dPdt' to avoid name<br>
     conflict with variable omega that gets use-associated<br>
     from mpas_cam_interface via constants module<br>
<br>
   - Run MPAS for 24 timesteps after calling CAM_INIDAT_TO_MPAS(...)<br>
     and write an output file<br>
<br>
<br>
M    src/driver_cam_interface/module_mpas_cam_interface.F<br>
M    src/driver_cam_interface/test_driver.F<br>
</p><hr noshade><pre><font color="gray">Modified: branches/mpas_cam_coupling/src/driver_cam_interface/module_mpas_cam_interface.F
===================================================================
--- branches/mpas_cam_coupling/src/driver_cam_interface/module_mpas_cam_interface.F        2010-03-31 20:43:23 UTC (rev 175)
+++ branches/mpas_cam_coupling/src/driver_cam_interface/module_mpas_cam_interface.F        2010-03-31 22:55:43 UTC (rev 176)
@@ -5,6 +5,7 @@
    use io_input
    use dmpar
    use subdriver
+   use constants
 
 
    type (dm_info), pointer :: dminfo
@@ -97,36 +98,189 @@
       real (kind=RKIND), dimension(Numcols,MaxEdges,Plev), intent(in) :: U
       real (kind=RKIND), dimension(Numcols,Plev,Pcnst), intent(in) :: Tracer
 
+      integer :: iCell, iEdge, iScalar, k, i
+      real (kind=RKIND) :: p0
+      real (kind=RKIND), dimension(Plev+1) :: znu, znw, znwc, znwv
+      real (kind=RKIND), dimension(Plev+1) :: znuc, znuv, bn, divh, dpn
       type (block_type), pointer :: block
+      real (kind=RKIND), dimension(:), pointer :: surface_pressure, rdnu, rdnw, fnm, fnp, dbn, dnu, dnw
+      real (kind=RKIND), dimension(:,:), pointer :: theta, u_normal, pressure, geopotential, alpha, h
+      real (kind=RKIND), dimension(:,:,:), pointer :: scalars
    
       write(0,*) 'Called CAM_INIDAT_TO_MPAS'
 
       block =&gt; domain % blocklist
 
+      surface_pressure =&gt; block % time_levs(1) % state % surface_pressure % array
+      theta =&gt; block % time_levs(1) % state % theta % array
+      u_normal =&gt; block % time_levs(1) % state % u % array
+      pressure =&gt; block % time_levs(1) % state % pressure % array
+      geopotential =&gt; block % time_levs(1) % state % geopotential % array
+      scalars =&gt; block % time_levs(1) % state % scalars % array
+      alpha =&gt; block % time_levs(1) % state % alpha % array
+      h =&gt; block % time_levs(1) % state % h % array
+      rdnu =&gt; block % mesh % rdnu % array
+      rdnw =&gt; block % mesh % rdnw % array
+      fnm =&gt; block % mesh % fnm % array
+      fnp =&gt; block % mesh % fnp % array
+      dbn =&gt; block % mesh % dbn % array
+      dnu =&gt; block % mesh % dnu % array
+      dnw =&gt; block % mesh % dnw % array
+
+
       !
       !  Perform basic sanity check on expected and available field dimensions
       !
       if (Numcols /= block % mesh % nCellsSolve) then
          write(0,*) 'Error: mismatch between Numcols and nCellsSolve: ', Numcols, block % mesh % nCellsSolve
+         return
       end if
       if (Plev /= block % mesh % nVertLevels) then
          write(0,*) 'Error: mismatch between Plev and nVertLevels: ', Plev, block % mesh % nVertLevels
+         return
       end if
       if (Pcnst /= num_scalars) then
          write(0,*) 'Error: mismatch between Pcnst and num_scalars: ', Pcnst, num_scalars
+         return
       end if
 
+      write(0,*) 'Numcols = ', Numcols
+      write(0,*) 'MaxEdges = ', MaxEdges
+      write(0,*) 'Plev = ', Plev
+      write(0,*) 'Pcnst = ', Pcnst
+      write(0,*) 'Pref = ', Pref
+      write(0,*) 'Ptop = ', Ptop
+      write(0,*) 'min/max for Ae = ', minval(Ae), maxval(Ae)
+      write(0,*) 'min/max for Be = ', minval(Be), maxval(Be)
+      write(0,*) 'min/max for Ac = ', minval(Ac), maxval(Ac)
+      write(0,*) 'min/max for Bc = ', minval(Bc), maxval(Bc)
+      write(0,*) 'min/max for Psd = ', minval(Psd), maxval(Psd)
+      write(0,*) 'min/max for Phis = ', minval(Phis), maxval(Phis)
+      write(0,*) 'min/max for T = ', minval(T), maxval(T)
+      write(0,*) 'min/max for U = ', minval(U), maxval(U)
+      write(0,*) 'min/max for Tracer = ', minval(Tracer), maxval(Tracer)
 
+
       !
-      ! Fill in MPAS fields in block % time_levs(1) % state arrays from arguments 
+      ! Scale geometry information from unit sphere to sphere with radius a (Earth radius defined in constants module)
       !
+      block % mesh % xCell % array   = block % mesh % xCell % array * a
+      block % mesh % yCell % array   = block % mesh % yCell % array * a
+      block % mesh % zCell % array   = block % mesh % zCell % array * a
+      block % mesh % xVertex % array = block % mesh % xVertex % array * a
+      block % mesh % yVertex % array = block % mesh % yVertex % array * a
+      block % mesh % zVertex % array = block % mesh % zVertex % array * a
+      block % mesh % xEdge % array   = block % mesh % xEdge % array * a
+      block % mesh % yEdge % array   = block % mesh % yEdge % array * a
+      block % mesh % zEdge % array   = block % mesh % zEdge % array * a
+      block % mesh % dvEdge % array  = block % mesh % dvEdge % array * a
+      block % mesh % dcEdge % array  = block % mesh % dcEdge % array * a
+      block % mesh % areaCell % array = block % mesh % areaCell % array * a**2.0
+      block % mesh % areaTriangle % array = block % mesh % areaTriangle % array * a**2.0
+      block % mesh % kiteAreasOnVertex % array = block % mesh % kiteAreasOnVertex % array * a**2.0
 
-! TEMPORARY: until we are actually given fields, just call one of the test case
-! setup routines to initialize the MPAS prognostic fields
-      call mpas_setup_test_case(domain)
 
+      !
+      ! Derive vertical coordinate information
+      !
+      p0 = Pref
+      bn (1) = 1.
+      znw(1) = 1.
+      znwc(1) = 1.
+      znwv(1) = (znwc(1)-.252)*pii/2.
 
+      do k=1,Plev
+         znuc(Plev+1-k)   = Ac(k) + Bc(k)
+         znwc(Plev+1-k+1) = Ae(k) + Be(k)
+         znu (Plev+1-k  ) = (znuc(Plev+1-k  )*p0-Ptop)/(p0-Ptop)
+         znw (Plev+1-k+1) = (znwc(Plev+1-k+1)*p0-Ptop)/(p0-Ptop)
+         bn(k+1) = Be(Plev+1-k)
+      end do
+
+      do k=1,Plev
+        znuv(k  ) = (znuc(k  )-.252)*pii/2.
+        znwv(k+1) = (znwc(k+1)-.252)*pii/2.
+        dnw (k) = znw(k+1)-znw(k)
+        rdnw(k) = 1./dnw(k)
+        dbn (k) = rdnw(k)*(bn(k+1)-bn(k))
+        dpn (k) = 0.
+        divh(k) = 0.
+      end do
+
+      dpn(Plev+1)=0.
+      fnm(1) = 0.
+      fnp(1) = 0.
+      do k=2,Plev
+         dnu (k)  = .5*(dnw(k)+dnw(k-1))
+         rdnu(k)  = 1./dnu(k)
+         fnp (k)  = .5* dnw(k  )/dnu(k)
+         fnm (k)  = .5* dnw(k-1)/dnu(k)
+      end do
+
       !
+      ! Initialize u_normal
+      !
+      u_normal(:,:) = 0.0
+      do iCell=1,Numcols
+         do i=1,block % mesh % nEdgesOnCell % array(iCell)
+            iEdge = block % mesh % edgesOnCell % array(i,iCell)
+            do k=1,Plev
+               u_normal(k,iEdge) = U(iCell,i,k)
+            end do
+         end do
+      end do
+
+      !
+      ! Initialize surface pressure
+      !
+      surface_pressure(:) = 0.0
+      do iCell=1,Numcols
+         surface_pressure(iCell) = Psd(iCell)
+      end do
+
+      !
+      ! Initialize pressure, theta, alpha, and geopotential
+      !
+      h(:,:) = 0.0
+      pressure(:,:) = 0.0
+      theta(:,:) = 0.0
+      alpha(:,:) = 0.0
+      geopotential(:,:) = 0.0
+      do iCell=1,Numcols
+         do k=1,Plev
+            h(k,iCell) = (1.-dbn(k))*(p0-Ptop)+dbn(k)*(surface_pressure(iCell)-Ptop)
+         end do
+
+         pressure(Plev+1,iCell) = Ptop
+         do k=Plev,1,-1
+            pressure(k,iCell) = pressure(k+1,iCell)-dnw(k)*h(k,iCell)
+         end do
+
+         do k=1,Plev
+            theta(k,iCell) = T(iCell,k) * (0.5*(pressure(k,iCell) + pressure(k+1,iCell))/p0)**(-rgas/cp)
+            alpha(k,iCell) = (rgas/p0) * theta(k,iCell) * (0.5*(pressure(k,iCell)+pressure(k+1,iCell))/p0)**cvpm
+         end do
+
+         geopotential(1,iCell) = Phis(iCell)
+         do k=1,Plev
+           geopotential(k+1,iCell) = geopotential(k,iCell)-dnw(k)*h(k,iCell)*alpha(k,iCell)
+         end do
+      end do
+
+      !
+      ! Initialize scalars
+      !
+      scalars(:,:,:) = 0.0
+      do iCell=1,Numcols
+         do k=1,Plev
+            do iScalar=1,Pcnst
+               scalars(iScalar,k,iCell) = Tracer(iCell,k,iScalar)
+            end do
+         end do
+      end do
+
+
+      !
       ! Do a ghost-cell update
       !
       call dmpar_exch_halo_field1dReal(domain % dminfo, block % time_levs(1) % state % surface_pressure % array(:), &amp;
@@ -147,7 +301,12 @@
       call dmpar_exch_halo_field3dReal(domain % dminfo, block % time_levs(1) % state % scalars % array(:,:,:), &amp;
                                        num_scalars, block % mesh % nVertLevels, block % mesh % nCells, &amp;
                                        block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-   
+
+      do i=2,nTimeLevs
+         call copy_state(block % time_levs(1) % state, block % time_levs(i) % state)
+      end do
+      block % time_levs(1) % state % xtime % scalar = 0.0
+
    end subroutine cam_inidat_to_mpas
    
    
@@ -399,10 +558,36 @@
 
       itimestep = 1
       call mpas_timestep(domain, itimestep, dt)
+
+      ! Move time level 2 fields back into time level 1 for next time step
+      call shift_time_levels(domain)
    
    end subroutine mpas_dyn_run
    
    
+!************** TEST ROUTINE -- NOT PART OF CAM-MPAS INTERFACE *************
+   subroutine mpas_write_output()
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   ! SUBROUTINE MPAS_WRITE_OUTPUT
+   !
+   ! Write MPAS output.nc file
+   !
+   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   
+      implicit none
+
+      type (io_output_object) :: output_obj
+   
+      write(0,*) 'Called MPAS_WRITE_OUTPUT'
+
+      call output_state_init(output_obj, domain, &quot;OUTPUT&quot;)
+      call output_state_for_domain(output_obj, domain, 1)
+      call output_state_finalize(output_obj, domain % dminfo)
+
+   end subroutine mpas_write_output
+!************** TEST ROUTINE -- NOT PART OF CAM-MPAS INTERFACE *************
+   
+   
    subroutine mpas_final()
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ! SUBROUTINE MPAS_FINAL

Modified: branches/mpas_cam_coupling/src/driver_cam_interface/test_driver.F
===================================================================
--- branches/mpas_cam_coupling/src/driver_cam_interface/test_driver.F        2010-03-31 20:43:23 UTC (rev 175)
+++ branches/mpas_cam_coupling/src/driver_cam_interface/test_driver.F        2010-03-31 22:55:43 UTC (rev 176)
@@ -8,12 +8,12 @@
    integer :: mpi_procID, mpi_nprocs, mpi_ierr
    character (len=32) :: filename
 
-   integer :: nCellsSolve, maxEdges, nVertLevels, nScalars
+   integer :: nCellsSolve, maxEdges, nVertLevels, nScalars, istep
    real (kind=RKIND) :: Pref, Ptop
    real (kind=RKIND), dimension(26) :: Ac, Bc
    real (kind=RKIND), dimension(27) :: Ae, Be
    real (kind=RKIND), dimension(:), pointer :: Psd, Phis
-   real (kind=RKIND), dimension(:,:), pointer :: T, Ux, Uy, Omega
+   real (kind=RKIND), dimension(:,:), pointer :: T, Ux, Uy, dPdt
    real (kind=RKIND), dimension(:,:), pointer :: T_tend, Ux_tend, Uy_tend
    real (kind=RKIND), dimension(:,:,:), pointer :: U, Tracer
 
@@ -65,7 +65,7 @@
    allocate(U(nCellsSolve,maxEdges,nVertLevels))
    allocate(Ux(nCellsSolve,nVertLevels))
    allocate(Uy(nCellsSolve,nVertLevels))
-   allocate(Omega(nCellsSolve,nVertLevels))
+   allocate(dPdt(nCellsSolve,nVertLevels))
    allocate(Tracer(nCellsSolve,nVertLevels,nScalars))
    allocate(T_tend(nCellsSolve,nVertLevels))
    allocate(Ux_tend(nCellsSolve,nVertLevels))
@@ -93,10 +93,15 @@
 
    call mpas_init2()
 
-   call mpas_dyn_run()
+   do istep=1,24
+      call mpas_dyn_run()
+   end do
 
+   ! *** Test routine to write model state -- not part of MPAS-CAM interface
+   call mpas_write_output()
+
    call mpas_to_cam(nCellsSolve, nVertLevels, nScalars, &amp;
-                    Psd, Phis, T, Ux, Uy, Omega, Tracer)
+                    Psd, Phis, T, Ux, Uy, dPdt, Tracer)
 
    call cam_to_mpas(nCellsSolve, nVertLevels, nScalars, &amp;
                     T_tend, Ux_tend, Uy_tend, Tracer)
@@ -114,7 +119,7 @@
    deallocate(U)
    deallocate(Ux)
    deallocate(Uy)
-   deallocate(Omega)
+   deallocate(dPdt)
    deallocate(Tracer)
    deallocate(T_tend)
    deallocate(Ux_tend)

</font>
</pre>