<p><b>duda</b> 2012-06-21 14:01:09 -0600 (Thu, 21 Jun 2012)</p><p>BRANCH COMMIT<br>
<br>
- update the MPAS_TO_CAM() interface to provide 3d pressure and height at layer<br>
  centers and interfaces to CAM, since we can no longer compute 3d pressure from<br>
  surface pressure and A and B arrays.<br>
<br>
- add basic implementations of interface routines to support a basic cold start<br>
  run of MPAS-A from within CAM.<br>
<br>
<br>
M    src/driver/mpas_cam_interface.F<br>
</p><hr noshade><pre><font color="gray">Modified: branches/cam_mpas_nh/src/driver/mpas_cam_interface.F
===================================================================
--- branches/cam_mpas_nh/src/driver/mpas_cam_interface.F        2012-06-21 18:27:14 UTC (rev 1999)
+++ branches/cam_mpas_nh/src/driver/mpas_cam_interface.F        2012-06-21 20:01:09 UTC (rev 2000)
@@ -6,6 +6,7 @@
    use mpas_io_output
    use mpas_dmpar
    use mpas_constants
+   use mpas_core
 
 
    type (dm_info), pointer :: dminfo
@@ -14,6 +15,7 @@
    integer :: itimestep, n_subcycle_steps
    type (io_output_object), save :: output_obj
    logical :: restart_run
+   integer :: output_frame
 
 
    contains
@@ -43,13 +45,9 @@
 
       write(0,*) 'Called MPAS_INIT1'
 
-#if 0
-      allocate(dminfo)
-      call dmpar_init(dminfo, mpi_comm)
+      call mpas_framework_init(dminfo, domain, mpi_comm)
 
-      call read_namelist(dminfo)
-
-      itimestep = 0
+      itimestep = 1
       restart_run = .false.    ! If a restart run, this will be set to true in cam_restart_to_mpas
 
       !
@@ -60,12 +58,11 @@
       n_subcycle_steps = ceiling(dt_physics / config_dt)
 
 
-      call allocate_domain(domain, dminfo)
 
-      ! NOTE: Really, we only want to read in the grid information, since any state 
-      !       variables will be overwritten by cam_inidat_to_mpas() or cam_restart_to_mpas();
-      !       however, with a suitable registry, this shouldn't be a problem
-      call input_state_for_domain(domain)
+      !
+      ! Read initial conditions
+      !
+      call mpas_input_state_for_domain(domain)
 
       latCell =&gt; domain % blocklist % mesh % latCell % array
       lonCell =&gt; domain % blocklist % mesh % lonCell % array
@@ -89,7 +86,6 @@
          call r3_normalize(north(1,iCell), north(2,iCell), north(3,iCell))
 
       end do
-#endif
    
    end subroutine mpas_init1
    
@@ -142,17 +138,18 @@
    
       write(0,*) 'Called CAM_INIDAT_TO_MPAS'
 
+      p0 = Pref    !MGD this also appears below...
 #if 0
       block =&gt; domain % blocklist
 
-      surface_pressure =&gt; block % time_levs(1) % state % surface_pressure % array
-      t_pot =&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
+      surface_pressure =&gt; block % state % time_levs(1) % state % surface_pressure % array
+      t_pot =&gt; block % state % time_levs(1) % state % theta % array
+      u_normal =&gt; block % state % time_levs(1) % state % u % array
+      pressure =&gt; block % state % time_levs(1) % state % pressure % array
+      geopotential =&gt; block % state % time_levs(1) % state % geopotential % array
+      scalars =&gt; block % state % time_levs(1) % state % scalars % array
+      alpha =&gt; block % state % time_levs(1) % state % alpha % array
+      h =&gt; block % state % time_levs(1) % state % h % array
       rdnu =&gt; block % mesh % rdnu % array
       rdnw =&gt; block % mesh % rdnw % array
       fnm =&gt; block % mesh % fnm % array
@@ -173,8 +170,8 @@
          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
+      if (Pcnst /= block % state % time_levs(1) % state % num_scalars) then
+         write(0,*) 'Error: mismatch between Pcnst and num_scalars: ', Pcnst, block % state % time_levs(1) % state % num_scalars
          return
       end if
 
@@ -319,29 +316,29 @@
       !
       ! Do a ghost-cell update
       !
-      call dmpar_exch_halo_field1dReal(domain % dminfo, block % time_levs(1) % state % surface_pressure % array(:), &amp;
-                                       block % mesh % nCells, &amp;
-                                       block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-      call dmpar_exch_halo_field2dReal(domain % dminfo, block % time_levs(1) % state % theta % array(:,:), &amp;
-                                       block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                       block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-      call dmpar_exch_halo_field2dReal(domain % dminfo, block % time_levs(1) % state % u % array(:,:), &amp;
-                                       block % mesh % nVertLevels, block % mesh % nEdges, &amp;
-                                       block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
-      call dmpar_exch_halo_field2dReal(domain % dminfo, block % time_levs(1) % state % pressure % array(:,:), &amp;
-                                       block % mesh % nVertLevels+1, block % mesh % nCells, &amp;
-                                       block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-      call dmpar_exch_halo_field2dReal(domain % dminfo, block % time_levs(1) % state % geopotential % array(:,:), &amp;
-                                       block % mesh % nVertLevels+1, block % mesh % nCells, &amp;
-                                       block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-      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)
+      call mpas_dmpar_exch_halo_field(domain % dminfo, block % state % time_levs(1) % state % surface_pressure % array(:), &amp;
+                                      block % mesh % nCells, &amp;
+                                      block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
+      call mpas_dmpar_exch_halo_field(domain % dminfo, block % state % time_levs(1) % state % theta % array(:,:), &amp;
+                                      block % mesh % nVertLevels, block % mesh % nCells, &amp;
+                                      block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
+      call mpas_dmpar_exch_halo_field(domain % dminfo, block % state % time_levs(1) % state % u % array(:,:), &amp;
+                                      block % mesh % nVertLevels, block % mesh % nEdges, &amp;
+                                      block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
+      call mpas_dmpar_exch_halo_field(domain % dminfo, block % state % time_levs(1) % state % pressure % array(:,:), &amp;
+                                      block % mesh % nVertLevels+1, block % mesh % nCells, &amp;
+                                      block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
+      call mpas_dmpar_exch_halo_field(domain % dminfo, block % state % time_levs(1) % state % geopotential % array(:,:), &amp;
+                                      block % mesh % nVertLevels+1, block % mesh % nCells, &amp;
+                                      block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
+      call mpas_dmpar_exch_halo_field(domain % dminfo, block % state % time_levs(1) % state % scalars % array(:,:,:), &amp;
+                                      block % state % time_levs(1) % state % 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)
+         call copy_state(block % state % time_levs(1) % state, block % state % time_levs(i) % state)
       end do
-      block % time_levs(1) % state % xtime % scalar = 0.0
+      block % state % time_levs(1) % state % xtime % scalar = 0.0
 #endif
 
    end subroutine cam_inidat_to_mpas
@@ -400,37 +397,37 @@
          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
+      if (Pcnst /= block % state % time_levs(1) % state % num_scalars) then
+         write(0,*) 'Error: mismatch between Pcnst and num_scalars: ', Pcnst, block % state % time_levs(1) % state % num_scalars
          return
       end if
 
 
       !
-      ! Fill in output arrays from block % time_levs(1) % state arrays
+      ! Fill in output arrays from block % state % time_levs(1) % state arrays
       ! NOTE: We must copy from time_levs(1) rather than time_levs(2), since
       !       mpas_dyn_run swaps the new time level into time_levs(1) after
       !       taking a timestep.
       !
       do iCell=1,block % mesh % nCellsSolve
-         Psd(iCell) = block % time_levs(1) % state % surface_pressure % array(iCell)
-         Phis(iCell) = block % time_levs(1) % state % geopotential % array(1,iCell)
+         Psd(iCell) = block % state % time_levs(1) % state % surface_pressure % array(iCell)
+         Phis(iCell) = block % state % time_levs(1) % state % geopotential % array(1,iCell)
          do k=1,block % mesh % nVertLevels
-            Theta(iCell,k) = block % time_levs(1) % state % theta % array(k,iCell)
-            W(iCell,k) = block % time_levs(1) % state % ww % array(k,iCell)
+            Theta(iCell,k) = block % state % time_levs(1) % state % theta % array(k,iCell)
+            W(iCell,k) = block % state % time_levs(1) % state % ww % array(k,iCell)
             !
             ! NOTE: Eventually, we need to ensure that the moisture variables we return to CAM
             !       are what CAM expects, rather than simply what we have in our scalars array
             !
-            do iScalar=1,num_scalars
-               Tracer(iCell,k,iScalar) = block % time_levs(1) % state % scalars % array(iScalar,k,iCell)
+            do iScalar=1,block % state % time_levs(1) % state % num_scalars
+               Tracer(iCell,k,iScalar) = block % state % time_levs(1) % state % scalars % array(iScalar,k,iCell)
             end do
             do i=1,nEdgesOnCell(iCell)
                iEdge = edgesOnCell(i,iCell)
-               U(iCell,i,k) = block % time_levs(1) % state % u % array(k,iEdge)
+               U(iCell,i,k) = block % state % time_levs(1) % state % u % array(k,iEdge)
             end do
          end do
-         W(iCell,k) = block % time_levs(1) % state % ww % array(k,iCell)
+         W(iCell,k) = block % state % time_levs(1) % state % ww % array(k,iCell)
       end do
 #endif
    
@@ -496,14 +493,14 @@
          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
+      if (Pcnst /= block % state % time_levs(1) % state % num_scalars) then
+         write(0,*) 'Error: mismatch between Pcnst and num_scalars: ', Pcnst, block % state % time_levs(1) % state % num_scalars
          return
       end if
 
 
       !
-      ! Fill in MPAS fields in block % time_levs(1) % state arrays from arguments 
+      ! Fill in MPAS fields in block % state % time_levs(1) % state arrays from arguments 
       ! Initialize most variables using cam_inidat_to_mpas
       !
       call cam_inidat_to_mpas(Numcols, MaxEdges, Plev, Pcnst, Pref, Ptop, &amp;
@@ -511,7 +508,7 @@
 
       do iCell=1,Numcols
          do k=1,Plev+1
-            block % time_levs(1) % state % ww % array(k,iCell) = W(iCell,k)
+            block % state % time_levs(1) % state % ww % array(k,iCell) = W(iCell,k)
          end do
       end do
 
@@ -519,12 +516,12 @@
       !
       ! Do a ghost-cell update
       !
-      call dmpar_exch_halo_field2dReal(domain % dminfo, block % time_levs(1) % state % ww % array(:,:), &amp;
+      call mpas_dmpar_exch_halo_field(domain % dminfo, block % state % time_levs(1) % state % ww % array(:,:), &amp;
                                        block % mesh % nVertLevels+1, block % mesh % nCells, &amp;
                                        block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
 
       do i=2,nTimeLevs
-         block % time_levs(i) % state % ww % array(:,:) = block % time_levs(1) % state % ww % array(:,:)
+         block % state % time_levs(i) % state % ww % array(:,:) = block % state % time_levs(1) % state % ww % array(:,:)
       end do
 #endif
    
@@ -536,7 +533,7 @@
    ! SUBROUTINE MPAS_INIT2
    !
    ! Calls the core-specific (most likely the hydrostatic atmosphere core) 
-   !    initialization routine mpas_init() after initial fields have been provided
+   !    initialization routine mpas_core_init() after initial fields have been provided
    !    through a call to either cam_inidat_to_mpas() or cam_restart_to_mpas().
    !
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -546,6 +543,9 @@
       integer :: i, iCell, k, iScalar
       real (kind=RKIND), dimension(:,:,:), pointer :: scalars
       type (block_type), pointer :: block
+
+      integer :: index_qv
+      character (len=StrKIND) :: initialTimeStamp
    
       write(0,*) 'Called MPAS_INIT2' 
 
@@ -556,42 +556,50 @@
       !
       if (.not. restart_run) then
          block =&gt; domain % blocklist
+
+         index_qv = block % state % time_levs(1) % state % index_qv
+
          do while (associated(block))
-            scalars =&gt; block % time_levs(1) % state % scalars % array
+            scalars =&gt; block % state % time_levs(1) % state % scalars % array
 
             do iCell=1,block % mesh % nCells
                do k=1,block % mesh % nVertLevels
-                  do iScalar=1,num_scalars
+                  do iScalar=1,block % state % time_levs(1) % state % num_scalars
                      scalars(iScalar,k,iCell) = scalars(iScalar,k,iCell) * (1.0 + scalars(index_qv,k,iCell))
                   end do
                end do
             end do
 
             do i=2,nTimeLevs
-               block % time_levs(i) % state % scalars % array(:,:,:) = block % time_levs(1) % state % scalars % array(:,:,:)
+               block % state % time_levs(i) % state % scalars % array(:,:,:) = block % state % time_levs(1) % state % scalars % array(:,:,:)
             end do
 
             block =&gt; block % next
          end do
       end if
+#endif
 
       ! Compute diagnostic fields needed in solve loop, and initialize
       !    simulation time to 0 for all blocks
       block =&gt; domain % blocklist
       do while (associated(block))
-         call mpas_init(block, block % mesh, dt_dynamics)
+         call mpas_core_init(domain, initialTimeStamp)
          block =&gt; block % next
       end do
 
       output_frame = 1
-      call output_state_init(output_obj, domain, &quot;OUTPUT&quot;)
-      call output_state_for_domain(output_obj, domain, output_frame)
-#endif
-   
+      if(config_frames_per_outfile &gt; 0) then
+         call mpas_output_state_init(output_obj, domain, &quot;OUTPUT&quot;, trim(initialTimeStamp))
+      else
+         call mpas_output_state_init(output_obj, domain, &quot;OUTPUT&quot;)
+      end if
+      call atm_write_output_frame(output_obj, output_frame, domain)
+
    end subroutine mpas_init2
    
    
-   subroutine mpas_to_cam(Numcols, Plev, Pcnst, Psd, Phis, T, Ux, Uy, Omega, Tracer)
+   subroutine mpas_to_cam(Numcols, Plev, Pcnst, Psd, Phis, Pint, Pmid, Zint, Zmid, &amp;
+                          T, Ux, Uy, Omega, Tracer)
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ! SUBROUTINE MPAS_TO_CAM
    !
@@ -601,6 +609,10 @@
    !
    ! Output: Psd - dry surface pressure (Pa)
    !         Phis - surface geopotential (m^2/s^2)
+   !         Pint - dry pressure at vertical layer interfaces
+   !         Pmid - dry pressure at vertical layer mid-points
+   !         Zint - geopotential height at vertical layer interfaces
+   !         Zmid - geopotential height at vertical layer mid-points
    !         T - temperature (K)
    !         Ux - longitudinal velocity at cell centers (m/s)
    !         Uy - latitudinal velocity at cell centers (m/s)
@@ -616,6 +628,10 @@
       integer, intent(in) :: Pcnst
       real (kind=RKIND), dimension(Numcols), intent(out) :: Psd
       real (kind=RKIND), dimension(Numcols), intent(out) :: Phis
+      real (kind=RKIND), dimension(Numcols,Plev+1), intent(out) :: Pint
+      real (kind=RKIND), dimension(Numcols,Plev), intent(out) :: Pmid
+      real (kind=RKIND), dimension(Numcols,Plev+1), intent(out) :: Zint
+      real (kind=RKIND), dimension(Numcols,Plev), intent(out) :: Zmid
       real (kind=RKIND), dimension(Numcols,Plev), intent(out) :: T
       real (kind=RKIND), dimension(Numcols,Plev), intent(out) :: Ux
       real (kind=RKIND), dimension(Numcols,Plev), intent(out) :: Uy
@@ -623,26 +639,18 @@
       real (kind=RKIND), dimension(Numcols,Plev,Pcnst), intent(out) :: Tracer
 
       integer :: iCell, k, iScalar
+      integer :: index_qv
       real (kind=RKIND), dimension(:), pointer :: latCell, lonCell
-      real (kind=RKIND), dimension(:,:), pointer :: theta, pressure, ww, uReconstZonal, uReconstMeridional, east, north
+      real (kind=RKIND), dimension(:,:), pointer :: theta, pressure_base, pressure_p, ww, uReconstZonal, uReconstMeridional, east, north
       real (kind=RKIND), dimension(:,:,:), pointer :: scalars
       type (block_type), pointer :: block
 
       write(0,*) 'Called MPAS_TO_CAM'
 
-#if 0
+
       block =&gt; domain % blocklist
 
-      latCell =&gt; block % mesh % latCell % array
-      lonCell =&gt; block % mesh % lonCell % array
-      east =&gt; block % mesh % east % array
-      north =&gt; block % mesh % north % array
-      theta =&gt; block % time_levs(1) % state % theta % array
-      pressure =&gt; block % time_levs(1) % state % pressure % array
-      ww =&gt; block % time_levs(1) % state % ww % array
-      uReconstZonal =&gt; block % time_levs(1) % state % uReconstructZonal % array
-      uReconstMeridional =&gt; block % time_levs(1) % state % uReconstructMeridional % array
-      scalars =&gt; block % time_levs(1) % state % scalars % array
+      index_qv = block % state % time_levs(1) % state % index_qv
 
 
       !
@@ -656,29 +664,50 @@
          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
+      if (Pcnst /= block % state % time_levs(1) % state % num_scalars) then
+         write(0,*) 'Error: mismatch between Pcnst and num_scalars: ', Pcnst, block % state % time_levs(1) % state % num_scalars
          return
       end if
 
+      uReconstZonal =&gt; block % diag % uReconstructZonal % array
+      uReconstMeridional =&gt; block % diag % uReconstructMeridional % array
+      scalars =&gt; block % state % time_levs(1) % state % scalars % array
+      theta =&gt; block % diag % theta % array
+      pressure_base =&gt; block % diag % pressure_base % array
+      pressure_p =&gt; block % diag % pressure_p % array
 
       !
-      ! Fill in CAM arrays from block % time_levs(1) % state arrays
+      ! Fill in CAM arrays from block % state % time_levs(1) % state arrays
       !
       do iCell=1,block % mesh % nCellsSolve
-         Psd(iCell) = block % time_levs(1) % state % surface_pressure % array(iCell)
-         Phis(iCell) = block % time_levs(1) % state % geopotential % array(1,iCell)
+         Psd(iCell) = block % diag % surface_pressure % array(iCell)
+         Phis(iCell) = block % mesh % zgrid % array(1,iCell) * 9.81
          do k=1,block % mesh % nVertLevels
-            T(iCell,k) = theta(k,iCell) * (0.5*(pressure(k,iCell)+pressure(k+1,iCell)) / p0) ** (rgas/cp)
-            Omega(iCell,k) = 0.5*(ww(k,iCell) + ww(k+1,iCell))
+            theta(k,iCell) = block % state % time_levs(1) % state % theta_m % array(k,iCell) &amp;
+                             / (1.0 + 1.61 * scalars(index_qv,k,iCell)) 
+            T(iCell,k) = theta(k,iCell) * ((pressure_base(k,iCell)+pressure_p(k,iCell)) / p0) ** (rgas/cp)
+            Pmid(iCell,k) = pressure_base(k,iCell)+pressure_p(k,iCell)
+            if (k == 1) then
+               Pint(iCell,k) = Psd(iCell)
+            else
+               Pint(iCell,k) = block % mesh % fzm % array(k) * Pmid(iCell,k-1) + &amp;
+                               block % mesh % fzp % array(k) * Pmid(iCell,k)
+            end if
+            Zint(iCell,k) = block % mesh % zgrid % array(k,iCell)
+            Zmid(iCell,k) = 0.5*(block % mesh % zgrid % array(k,iCell) + block % mesh % zgrid % array(k+1,iCell))
+
+!            Omega(iCell,k) = 0.5*(ww(k,iCell) + ww(k+1,iCell))
+            Omega(iCell,k) = 0.0   !MGD NEEDS FIXING
             !
             ! NOTE: Eventually, we need to ensure that the moisture variables we return to CAM
             !       are what CAM expects, rather than simply what we have in our scalars array
             !
-            do iScalar=1,num_scalars
+            do iScalar=1,block % state % time_levs(1) % state % num_scalars
                Tracer(iCell,k,iScalar) = scalars(iScalar,k,iCell) / (1.0 + scalars(index_qv,k,iCell))
             end do
          end do
+         Zint(iCell,Plev+1) = block % mesh % zgrid % array(Plev+1,iCell)
+         Pint(iCell,Plev+1) = Pmid(iCell,Plev) + (Pmid(iCell,Plev) - Pint(iCell,Plev))
       end do
 
       do iCell=1,block % mesh % nCellsSolve
@@ -687,8 +716,21 @@
             Uy(iCell,k) =   uReconstMeridional(k,iCell)
          end do
       end do 
-#endif
 
+write(0,*) '&lt;- MPAS DEBUGGING: MIN/MAX uReconstructZonal=', minval(Ux), maxval(Ux)
+write(0,*) '&lt;- MPAS DEBUGGING: MIN/MAX uReconstructMeridional=', minval(Uy), maxval(Uy)
+write(0,*) '&lt;- MPAS DEBUGGING: MIN/MAX Psd=', minval(Psd), maxval(Psd)
+write(0,*) '&lt;- MPAS DEBUGGING: MIN/MAX Phis=', minval(Phis), maxval(Phis)
+write(0,*) '&lt;- MPAS DEBUGGING: MIN/MAX Pint=', minval(Pint), maxval(Pint)
+write(0,*) '&lt;- MPAS DEBUGGING: MIN/MAX Pmid=', minval(Pmid), maxval(Pmid)
+write(0,*) '&lt;- MPAS DEBUGGING: MIN/MAX Zint=', minval(Zint), maxval(Zint)
+write(0,*) '&lt;- MPAS DEBUGGING: MIN/MAX Zmid=', minval(Zmid), maxval(Zmid)
+write(0,*) '&lt;- MPAS DEBUGGING: MIN/MAX T=', minval(T), maxval(T)
+write(0,*) '&lt;- MPAS DEBUGGING: MIN/MAX Omega=', minval(Omega), maxval(Omega)
+write(0,*) '&lt;- MPAS DEBUGGING: MIN/MAX Tracer1=', minval(Tracer(:,:,1)), maxval(Tracer(:,:,1))
+write(0,*) '&lt;- MPAS DEBUGGING: MIN/MAX Tracer2=', minval(Tracer(:,:,2)), maxval(Tracer(:,:,2))
+write(0,*) '&lt;- MPAS DEBUGGING: MIN/MAX Tracer3=', minval(Tracer(:,:,3)), maxval(Tracer(:,:,3))
+
    end subroutine mpas_to_cam
    
    
@@ -717,34 +759,23 @@
       real (kind=RKIND), dimension(Numcols,Plev,Pcnst), intent(in) :: Tracer
 
       integer :: iCell, iEdge, iScalar, k, j
+      integer :: index_qv
       integer, dimension(:), pointer :: nEdgesOnCell
       integer, dimension(:,:), pointer :: edgesOnCell
-      real (kind=RKIND), dimension(:,:), pointer :: h
+      real (kind=RKIND), dimension(:,:), pointer :: pressure_base, pressure_p
       real (kind=RKIND), dimension(:,:), pointer :: east, north, edge_normal, pressure
-      real (kind=RKIND), dimension(:,:), pointer :: Ux_tend_halo, Uy_tend_halo, theta_tend, u_tend
-      real (kind=RKIND), dimension(:,:), pointer :: Ux_phys_tend, Uy_phys_tend
+      real (kind=RKIND), dimension(:,:), pointer :: theta_tend, u_tend
+      real (kind=RKIND), dimension(:,:), pointer :: zonal_tend, meridional_tend
       real (kind=RKIND), dimension(:,:,:), pointer :: scalars, scalars_tend
       type (block_type), pointer :: block
 
       write(0,*) 'Called CAM_TO_MPAS'
 
-#if 0
       block =&gt; domain % blocklist
 
-      nEdgesOnCell =&gt; block % mesh % nEdgesOnCell % array
-      edgesOnCell =&gt; block % mesh % edgesOnCell % array
-      east =&gt; block % mesh % east % array
-      north =&gt; block % mesh % north % array
-      edge_normal =&gt; block % mesh % edgeNormalVectors % array
-      pressure =&gt; block % time_levs(1) % state % pressure % array
-      scalars =&gt; block % time_levs(1) % state % scalars % array
-      scalars_tend =&gt; block % time_levs(1) % state % scalars_phys_tend % array
-      theta_tend =&gt; block % time_levs(1) % state % theta_phys_tend % array
-      u_tend =&gt; block % time_levs(1) % state % u_phys_tend % array
-      Ux_phys_tend =&gt; block % time_levs(1) % state % Ux_phys_tend % array
-      Uy_phys_tend =&gt; block % time_levs(1) % state % Uy_phys_tend % array
-      h =&gt; block % time_levs(1) % state % h % array
+      index_qv = block % state % time_levs(1) % state % index_qv
 
+
       !
       !  Perform basic sanity check on expected and available field dimensions
       !
@@ -756,74 +787,73 @@
          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
+      if (Pcnst /= block % state % time_levs(1) % state % num_scalars) then
+         write(0,*) 'Error: mismatch between Pcnst and num_scalars: ', Pcnst, block % state % time_levs(1) % state % num_scalars
          return
       end if
 
+      nEdgesOnCell =&gt; block % mesh % nEdgesOnCell % array
+      edgesOnCell =&gt; block % mesh % edgesOnCell % array
+      east =&gt; block % mesh % east % array
+      north =&gt; block % mesh % north % array
+      edge_normal =&gt; block % mesh % edgeNormalVectors % array
+      scalars =&gt; block % state % time_levs(1) % state % scalars % array
+      pressure_base =&gt; block % diag % pressure_base % array
+      pressure_p =&gt; block % diag % pressure_p % array
+      scalars_tend =&gt; block % tend_physics % scalars % array
+      theta_tend =&gt; block % tend_physics % theta % array
+      u_tend =&gt; block % tend_physics % u % array
+      zonal_tend =&gt; block % tend_physics % ux % array
+      meridional_tend =&gt; block % tend_physics % uy % array
 
+
       !
       ! Fill in MPAS tendency arrays from arguments
       !
-      allocate(Ux_tend_halo(block % mesh % nVertLevels, block % mesh % nCells))
-      allocate(Uy_tend_halo(block % mesh % nVertLevels, block % mesh % nCells))
-
       do iCell=1,block % mesh % nCellsSolve
          do k=1,block % mesh % nVertLevels
-            Ux_tend_halo(k,iCell) = Ux_tend(iCell,k)
-            Uy_tend_halo(k,iCell) = Uy_tend(iCell,k)
+            zonal_tend(k,iCell) = Ux_tend(iCell,k)
+            meridional_tend(k,iCell) = Uy_tend(iCell,k)
          end do
       end do
 
-      call dmpar_exch_halo_field2dReal(domain % dminfo, Ux_tend_halo, &amp;
-                                       block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                       block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-      call dmpar_exch_halo_field2dReal(domain % dminfo, Uy_tend_halo, &amp;
-                                       block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                       block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
+      call mpas_dmpar_exch_halo_field(block % tend_physics % ux)
+      call mpas_dmpar_exch_halo_field(block % tend_physics % uy)
 
       u_tend(:,:) = 0.0
       do iCell=1,block % mesh % nCells
          do j=1,nEdgesOnCell(iCell)
             iEdge = edgesOnCell(j,iCell)
             do k=1,block % mesh % nVertLevels
-               u_tend(k,iEdge) = u_tend(k,iEdge) + 0.5 * Ux_tend_halo(k,iCell) * (edge_normal(1,iEdge) * east(1,iCell) + &amp;
-                                                                                  edge_normal(2,iEdge) * east(2,iCell) + &amp;
-                                                                                  edge_normal(3,iEdge) * east(3,iCell))  &amp;
-                                                 + 0.5 * Uy_tend_halo(k,iCell) * (edge_normal(1,iEdge) * north(1,iCell) + &amp;
-                                                                                  edge_normal(2,iEdge) * north(2,iCell) + &amp;
-                                                                                  edge_normal(3,iEdge) * north(3,iCell))
+               u_tend(k,iEdge) = u_tend(k,iEdge) + 0.5 * zonal_tend(k,iCell) * (edge_normal(1,iEdge) * east(1,iCell) + &amp;
+                                                                                edge_normal(2,iEdge) * east(2,iCell) + &amp;
+                                                                                edge_normal(3,iEdge) * east(3,iCell))  &amp;
+                                                 + 0.5 * meridional_tend(k,iCell) * (edge_normal(1,iEdge) * north(1,iCell) + &amp;
+                                                                                     edge_normal(2,iEdge) * north(2,iCell) + &amp;
+                                                                                     edge_normal(3,iEdge) * north(3,iCell))
             end do
          end do
 
-         ! Store original zonal and meridional tendencies from CAM to be written to output files for testing
-         do k=1,block % mesh % nVertLevels
-            Ux_phys_tend(k,iCell) = Ux_tend_halo(k,iCell)
-            Uy_phys_tend(k,iCell) = Uy_tend_halo(k,iCell)
-         end do
       end do
 
-      deallocate(Ux_tend_halo)
-      deallocate(Uy_tend_halo)
-
       do iCell=1,block % mesh % nCellsSolve
          do k=1,block % mesh % nVertLevels
-            theta_tend(k,iCell) = T_tend(iCell,k) * (p0 / (0.5*(pressure(k,iCell)+pressure(k+1,iCell)))) ** (rgas/cp)
+            theta_tend(k,iCell) = T_tend(iCell,k) * (p0 / (pressure_base(k,iCell)+pressure_p(k,iCell))) ** (rgas/cp)
             
             ! Couple theta tendency with h valid at time when tendency was computed
-            theta_tend(k,iCell) = theta_tend(k,iCell) * h(k,iCell) 
+!            theta_tend(k,iCell) = theta_tend(k,iCell) * h(k,iCell) 
 
             !
             ! NOTE: Once we begin to use more than just qv in MPAS, we need to make sure to
             !       properly assign variables from Tracer array provided from CAM physics
             !
-            do iScalar=1,num_scalars
+            do iScalar=1,block % state % time_levs(1) % state % num_scalars
                scalars_tend(iScalar,k,iCell) = (Tracer(iCell,k,iScalar) * (1.0 + Tracer(iCell,k,index_qv)) &amp;
                                               - scalars(iScalar,k,iCell)&amp;
                                                ) / dt_physics
 
                ! Couple scalar tendencies with h valid at time when tendencies were computed
-               scalars_tend(iScalar,k,iCell) = scalars_tend(iScalar,k,iCell) * h(k,iCell) 
+!               scalars_tend(iScalar,k,iCell) = scalars_tend(iScalar,k,iCell) * h(k,iCell) 
             end do
          end do
       end do
@@ -832,16 +862,15 @@
       !
       ! Do a ghost-cell update on tendency arrays
       !
-      call dmpar_exch_halo_field2dReal(domain % dminfo, block % time_levs(1) % state % theta_phys_tend % array(:,:), &amp;
-                                       block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                       block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-      call dmpar_exch_halo_field2dReal(domain % dminfo, block % time_levs(1) % state % u_phys_tend % array(:,:), &amp;
-                                       block % mesh % nVertLevels, block % mesh % nEdges, &amp;
-                                       block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
-      call dmpar_exch_halo_field3dReal(domain % dminfo, block % time_levs(1) % state % scalars_phys_tend % array(:,:,:), &amp;
-                                       num_scalars, block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                       block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-#endif
+      call mpas_dmpar_exch_halo_field(block % tend_physics % theta)
+      call mpas_dmpar_exch_halo_field(block % tend_physics % u)
+      call mpas_dmpar_exch_halo_field(block % tend_physics % scalars)
+
+write(0,*) '-&gt; MPAS DEBUGGING: MIN/MAX u_tend=', minval(u_tend(:,1:block % mesh % nEdges)),maxval(u_tend(:,1:block % mesh % nEdges))
+write(0,*) '-&gt; MPAS DEBUGGING: MIN/MAX theta_tend=', minval(theta_tend(:,1:block % mesh % nCells)),maxval(theta_tend(:,1:block % mesh % nCells))
+write(0,*) '-&gt; MPAS DEBUGGING: MIN/MAX qv_tend=', minval(scalars_tend(1,:,1:block % mesh % nCells)),maxval(scalars_tend(1,:,1:block % mesh % nCells))
+write(0,*) '-&gt; MPAS DEBUGGING: MIN/MAX qc_tend=', minval(scalars_tend(2,:,1:block % mesh % nCells)),maxval(scalars_tend(2,:,1:block % mesh % nCells))
+write(0,*) '-&gt; MPAS DEBUGGING: MIN/MAX qr_tend=', minval(scalars_tend(3,:,1:block % mesh % nCells)),maxval(scalars_tend(3,:,1:block % mesh % nCells))
    
    end subroutine cam_to_mpas
    
@@ -855,25 +884,80 @@
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
       implicit none
-   
+
+      real (kind=RKIND) :: dt
+      type (block_type), pointer :: block_ptr
+      
+      type (MPAS_Time_Type) :: currTime
+      character(len=StrKIND) :: timeStamp
+      integer :: itimestep
+      integer :: ierr
       integer :: idynstep
 
       write(0,*) 'Called MPAS_DYN_RUN'
 
-#if 0
+      
+      ! Eventually, dt should be domain specific
+      dt = config_dt
+      
+      ! During integration, time level 1 stores the model state at the beginning of the
+      !   time step, and time level 2 stores the state advanced dt_dynamics in time by timestep(...)
+write(0,*) 'MGD running dynamics for n_subcycle_steps=',n_subcycle_steps
       do idynstep=1,n_subcycle_steps
+      
+         currTime = mpas_get_clock_time(clock, MPAS_NOW, ierr)
+         call mpas_get_time(curr_time=currTime, dateTimeString=timeStamp, ierr=ierr)
+         write(0,*) 'Begin timestep ', trim(timeStamp)
+         
+         ! Input external updates (i.e. surface)
+         if (mpas_is_alarm_ringing(clock, sfcAlarmID, ierr=ierr)) then
+            call mpas_reset_clock_alarm(clock, sfcAlarmID, ierr=ierr)
+            
+            call mpas_read_and_distribute_fields(sfc_update_obj)
+            sfc_update_obj % time = sfc_update_obj % time + 1
+         end if
+         
+         call mpas_timer_start(&quot;time integration&quot;)
+         call atm_do_timestep(domain, dt_dynamics, itimestep)
+         call mpas_timer_stop(&quot;time integration&quot;)   
+         
+         ! Move time level 2 fields back into time level 1 for next time step
+         call mpas_shift_time_levels_state(domain % blocklist % state)
+         
+
+         ! Advance clock before writing output
          itimestep = itimestep + 1
-         call mpas_timestep(domain, itimestep, dt_dynamics)
+         call mpas_advance_clock(clock)
+         currTime = mpas_get_clock_time(clock, MPAS_NOW, ierr)
+         call mpas_get_time(curr_time=currTime, dateTimeString=timeStamp, ierr=ierr)
+         
+         !TODO: MPAS_getClockRingingAlarms is probably faster than multiple MPAS_isAlarmRinging...
+         if (mpas_is_alarm_ringing(clock, outputAlarmID, ierr=ierr)) then
+            call mpas_reset_clock_alarm(clock, outputAlarmID, ierr=ierr)
+            ! output_frame will always be &gt; 1 here unless it was reset after the maximum number of frames per outfile was reached
+            if(output_frame == 1) then 
+               call mpas_output_state_finalize(output_obj, domain % dminfo)
+               call mpas_output_state_init(output_obj, domain, &quot;OUTPUT&quot;, trim(timeStamp))
+            end if
+            call atm_write_output_frame(output_obj, output_frame, domain)
+         end if
+         
+         if (mpas_is_alarm_ringing(clock, restartAlarmID, ierr=ierr)) then
+            call mpas_reset_clock_alarm(clock, restartAlarmID, ierr=ierr)
+            
+            block_ptr =&gt; domain % blocklist
+            do while (associated(block_ptr))
+               call atm_compute_restart_diagnostics(block_ptr % state % time_levs(1) % state, block_ptr % diag, block_ptr % mesh)
+               block_ptr =&gt; block_ptr % next
+            end do
 
-         ! Move time level 2 fields back into time level 1 for next time step
-         call shift_time_levels(domain)
+            ! Write one restart time per file
+            call mpas_output_state_init(restart_obj, domain, &quot;RESTART&quot;, trim(timeStamp))
+            call mpas_output_state_for_domain(restart_obj, domain, 1)
+            call mpas_output_state_finalize(restart_obj, domain % dminfo)
+         end if
 
-         if (mod(itimestep, config_output_interval) == 0) then 
-            output_frame = output_frame + 1
-            call output_state_for_domain(output_obj, domain, output_frame)
-         end if
       end do
-#endif
 
    end subroutine mpas_dyn_run
    
@@ -891,12 +975,12 @@
    
       write(0,*) 'Called MPAS_FINAL'
 
-#if 0
-      call output_state_finalize(output_obj, domain % dminfo)
-      call deallocate_domain(domain)
+      call mpas_output_state_finalize(output_obj, domain % dminfo)
 
-      call dmpar_finalize(dminfo)
-#endif
+      call mpas_core_finalize(domain)
+
+      call mpas_framework_finalize(dminfo, domain)
+
    
    end subroutine mpas_final
 

</font>
</pre>