<p><b>duda</b> 2010-04-23 15:06:33 -0600 (Fri, 23 Apr 2010)</p><p>Add implementations of MPAS_TO_CAM(...) and CAM_TO_MPAS(...). For now,<br>
we store the wind and temperature tendencies from CAM physics in new<br>
arrays theta_phys_tend and u_phys_tend, while the new moisture fields<br>
are copied directly, since they aren't provided as tendencies.<br>
<br>
<br>
M    core_hyd_atmos/Registry<br>
M    driver_cam_interface/module_mpas_cam_interface.F<br>
</p><hr noshade><pre><font color="gray">Modified: branches/mpas_cam_coupling/src/core_hyd_atmos/Registry
===================================================================
--- branches/mpas_cam_coupling/src/core_hyd_atmos/Registry        2010-04-23 20:43:27 UTC (rev 208)
+++ branches/mpas_cam_coupling/src/core_hyd_atmos/Registry        2010-04-23 21:06:33 UTC (rev 209)
@@ -152,6 +152,10 @@
 var real    qr_old ( nVertLevels nCells ) - qr_old scalars_old moist_old
 #var real    tracers_old ( nTracers nVertLevels nCells ) - tracers_old - -
 
+# Physics tendencies
+var real    theta_phys_tend ( nVertLevels nCells Time ) - theta_phys_tend - -
+var real    u_phys_tend ( nVertLevels nEdges Time ) - u_phys_tend - -
+
 # Space needed for advection
 var real    deriv_two ( FIFTEEN TWO nEdges ) o deriv_two - -
 var integer advCells ( TWENTYONE nCells ) - advCells - -

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-04-23 20:43:27 UTC (rev 208)
+++ branches/mpas_cam_coupling/src/driver_cam_interface/module_mpas_cam_interface.F        2010-04-23 21:06:33 UTC (rev 209)
@@ -523,37 +523,76 @@
       real (kind=RKIND), dimension(Numcols,Plev), intent(out) :: Omega
       real (kind=RKIND), dimension(Numcols,Plev,Pcnst), intent(out) :: Tracer
 
+      integer :: iCell, k, iScalar
+      real (kind=RKIND), dimension(:), pointer :: latCell, lonCell
+      real (kind=RKIND), dimension(:,:), pointer :: theta, pressure, ww, uReconstX, uReconstY, uReconstZ, east, north
+      real (kind=RKIND), dimension(:,:,:), pointer :: scalars
       type (block_type), pointer :: block
 
       write(0,*) 'Called MPAS_TO_CAM'
 
       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(2) % state % theta % array
+      pressure =&gt; block % time_levs(2) % state % pressure % array
+      ww =&gt; block % time_levs(2) % state % ww % array
+      uReconstX =&gt; block % time_levs(2) % state % uReconstructX % array
+      uReconstY =&gt; block % time_levs(2) % state % uReconstructY % array
+      uReconstZ =&gt; block % time_levs(2) % state % uReconstructZ % array
+      scalars =&gt; block % time_levs(2) % state % scalars % 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
 
 
       !
       ! Fill in CAM arrays from block % time_levs(2) % state arrays
       !
-      Psd = 3.1415926
-      Phis = 3.1415926
-      T = 3.1415926
-      Ux = 3.1415926
-      Uy = 3.1415926
-      Omega = 3.1415926
-      Tracer = 3.1415926
-   
+      do iCell=1,block % mesh % nCellsSolve
+         Psd(iCell) = block % time_levs(2) % state % surface_pressure % array(iCell)
+         Phis(iCell) = block % time_levs(2) % state % geopotential % array(1,iCell)
+         do k=1,block % mesh % nVertLevels
+            T(iCell,k) = theta(k,iCell) * (0.5*(pressure(k,iCell)+pressure(k+1,iCell)) / 100000.0) ** (rgas/cp)
+            Omega(iCell,k) = 0.5*(ww(k,iCell) + ww(k+1,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) = scalars(iScalar,k,iCell)
+            end do
+         end do
+      end do
+
+      do iCell=1,block % mesh % nCellsSolve
+         do k=1,block % mesh % nVertLevels
+            Ux(iCell,k) =   uReconstX(k,iCell) * east(1,iCell)  &amp;
+                          + uReconstY(k,iCell) * east(2,iCell)  &amp;
+                          + uReconstZ(k,iCell) * east(3,iCell)
+            Uy(iCell,k) =   uReconstX(k,iCell) * north(1,iCell) &amp;
+                          + uReconstY(k,iCell) * north(2,iCell) &amp;
+                          + uReconstZ(k,iCell) * north(3,iCell)
+         end do
+      end do 
+
    end subroutine mpas_to_cam
    
    
@@ -581,34 +620,109 @@
       real (kind=RKIND), dimension(Numcols,Plev), intent(in) :: Uy_tend
       real (kind=RKIND), dimension(Numcols,Plev,Pcnst), intent(in) :: Tracer
 
+      integer :: iCell, iEdge, iScalar, k, j
+      integer, dimension(:), pointer :: nEdgesOnCell
+      integer, dimension(:,:), pointer :: edgesOnCell
+      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 :: scalars
       type (block_type), pointer :: block
 
       write(0,*) 'Called CAM_TO_MPAS'
 
       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 % edge_normal % array
+      pressure =&gt; block % time_levs(2) % state % pressure % array
+      scalars =&gt; block % time_levs(2) % state % scalars % array
+      theta_tend =&gt; block % time_levs(2) % state % theta_phys_tend % array
+      u_tend =&gt; block % time_levs(2) % state % u_phys_tend % 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
 
 
       !
       ! 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)
+         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)
+
+      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))
+            end do
+         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) * (100000.0 / (0.5*(pressure(k,iCell)+pressure(k+1,iCell)))) ** (rgas/cp)
+
+            !
+            ! 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
+               scalars(iScalar,k,iCell) = Tracer(iCell,k,iScalar)
+            end do
+         end do
+      end do
+
+
       !
-      ! It might also be necessary to do a ghost-cell update on tendency arrays
+      ! 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 % array(:,:,:), &amp;
+                                       num_scalars, block % mesh % nVertLevels, block % mesh % nCells, &amp;
+                                       block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
    
    end subroutine cam_to_mpas
    

</font>
</pre>