<p><b>duda</b> 2009-09-04 16:10:17 -0600 (Fri, 04 Sep 2009)</p><p>Switch to a loop-based RK4 implementation with a storage factor of <br>
two; from Bill S.<br>
<br>
M    src/module_time_integration.F<br>
M    src/module_grid_types.F<br>
</p><hr noshade><pre><font color="gray">Modified: trunk/swmodel/src/module_grid_types.F
===================================================================
--- trunk/swmodel/src/module_grid_types.F        2009-09-04 17:07:13 UTC (rev 45)
+++ trunk/swmodel/src/module_grid_types.F        2009-09-04 22:10:17 UTC (rev 46)
@@ -3,7 +3,7 @@
    use dmpar
 
    integer, parameter :: nTimeLevs = 2
-   integer, parameter :: storageFactor = 5    ! Additional storage used by time integration scheme
+   integer, parameter :: storageFactor = 2    ! Additional storage used by time integration scheme
 
   
    ! Derived type describing info for doing I/O specific to a field

Modified: trunk/swmodel/src/module_time_integration.F
===================================================================
--- trunk/swmodel/src/module_time_integration.F        2009-09-04 17:07:13 UTC (rev 45)
+++ trunk/swmodel/src/module_time_integration.F        2009-09-04 22:10:17 UTC (rev 46)
@@ -62,198 +62,137 @@
       integer :: iCell, k
       type (block_type), pointer :: block
 
-      integer, parameter :: TEMP = 1
-      integer, parameter :: Q1   = 2
-      integer, parameter :: Q2   = 3
-      integer, parameter :: Q3   = 4
-      integer, parameter :: Q4   = 5
+      integer, parameter :: PROVIS = 1
+      integer, parameter :: TEND   = 2
+      integer :: rk_step
 
+      real (kind=RKIND), dimension(4) :: rk_weights, rk_substep_weights
 
-      ! Take first RK step
-      block =&gt; domain % blocklist
-      do while (associated(block))
-         call compute_tend(block % intermediate_step(Q1), block % time_levs(1) % state, block % mesh)
-         call compute_scalar_tend(block % intermediate_step(Q1), block % time_levs(1) % state, block % mesh)
-         block % intermediate_step(Q1) % u % array(:,:)       = dt * block % intermediate_step(Q1) % u % array(:,:)
-         block % intermediate_step(Q1) % h % array(:,:)       = dt * block % intermediate_step(Q1) % h % array(:,:)
-         block % intermediate_step(Q1) % tracers % array(:,:,:) = dt * block % intermediate_step(Q1) % tracers % array(:,:,:)
 
-         block =&gt; block % next
-      end do
-
+      !
+      ! Initialize time_levs(2) with state at current time
+      ! Initialize first RK state
+      ! Couple tracers time_levs(2) with h in time-levels
+      ! Initialize RK weights
+      !
       block =&gt; domain % blocklist
       do while (associated(block))
-         call dmpar_exch_halo_field2dReal(domain % dminfo, block % intermediate_step(Q1) % u % array(:,:), &amp;
-                                          block % mesh % nVertLevels, block % mesh % nEdges, &amp;
-                                          block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
-         call dmpar_exch_halo_field2dReal(domain % dminfo, block % intermediate_step(Q1) % h % array(:,:), &amp;
-                                          block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                          block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-         call dmpar_exch_halo_field3dReal(domain % dminfo, block % intermediate_step(Q1) % tracers % array(:,:,:), &amp;
-                                          block % mesh % nTracers, block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                          block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-         block =&gt; block % next
-      end do
 
-
-      ! Take second RK step
-      block =&gt; domain % blocklist
-      do while (associated(block))
-         block % intermediate_step(TEMP) % u % array(:,:)       = block % time_levs(1) % state % u % array(:,:) + &amp;
-                                                                      block % intermediate_step(Q1) % u % array(:,:)/2.0
-         block % intermediate_step(TEMP) % h % array(:,:)       = block % time_levs(1) % state % h % array(:,:) + &amp;
-                                                                      block % intermediate_step(Q1) % h % array(:,:)/2.0
-         do iCell=1,block % mesh % nCells
-            do k=1,block % mesh % nVertLevels
-               block % intermediate_step(TEMP) % tracers % array(:,k,iCell) = ( &amp;
-                                                                  block % time_levs(1) % state % h % array(k,iCell) * &amp;
-                                                                  block % time_levs(1) % state % tracers % array(:,k,iCell) + &amp;
-                                                                  block % intermediate_step(Q1) % tracers % array(:,k,iCell) / 2.0 &amp;
-                                                                ) / block % intermediate_step(TEMP) % h % array(k,iCell)
+         block % time_levs(2) % state % u % array(:,:) = block % time_levs(1) % state % u % array(:,:)
+         block % time_levs(2) % state % h % array(:,:) = block % time_levs(1) % state % h % array(:,:)
+         do iCell=1,block % mesh % nCells  ! couple tracers to h
+           do k=1,block % mesh % nVertLevels
+             block % time_levs(2) % state % tracers % array(:,k,iCell) = block % time_levs(1) % state % tracers % array(:,k,iCell) &amp;
+                                                                       * block % time_levs(1) % state % h % array(k,iCell)
             end do
          end do
-         if (config_test_case == 1) then    ! For case 1, wind field should be fixed
-            block % intermediate_step(TEMP) % u % array(:,:) = block % time_levs(1) % state % u % array(:,:)
-         end if
-         call compute_solve_diagnostics(block % intermediate_step(TEMP), block % mesh)
-         call compute_tend(block % intermediate_step(Q2), block % intermediate_step(TEMP), block % mesh)
-         call compute_scalar_tend(block % intermediate_step(Q2), block % intermediate_step(TEMP), block % mesh)
-         block % intermediate_step(Q2) % u % array(:,:)       = dt * block % intermediate_step(Q2) % u % array(:,:)
-         block % intermediate_step(Q2) % h % array(:,:)       = dt * block % intermediate_step(Q2) % h % array(:,:)
-         block % intermediate_step(Q2) % tracers % array(:,:,:) = dt * block % intermediate_step(Q2) % tracers % array(:,:,:)
 
-         block =&gt; block % next
-      end do
+         call copy_state(block % time_levs(1) % state, block % intermediate_step(PROVIS))
 
-      block =&gt; domain % blocklist
-      do while (associated(block))
-         call dmpar_exch_halo_field2dReal(domain % dminfo, block % intermediate_step(Q2) % u % array(:,:), &amp;
-                                          block % mesh % nVertLevels, block % mesh % nEdges, &amp;
-                                          block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
-         call dmpar_exch_halo_field2dReal(domain % dminfo, block % intermediate_step(Q2) % h % array(:,:), &amp;
-                                          block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                          block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-         call dmpar_exch_halo_field3dReal(domain % dminfo, block % intermediate_step(Q2) % tracers % array(:,:,:), &amp;
-                                          block % mesh % nTracers, block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                          block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
          block =&gt; block % next
       end do
 
+      rk_weights(1) = dt/6.
+      rk_weights(2) = dt/3.
+      rk_weights(3) = dt/3.
+      rk_weights(4) = dt/6.
 
-      ! Take third RK step
-      block =&gt; domain % blocklist
-      do while (associated(block))
-         block % intermediate_step(TEMP) % u % array(:,:)       = block % time_levs(1) % state % u % array(:,:) + &amp;
-                                                                      block % intermediate_step(Q2) % u % array(:,:)/2.0
-         block % intermediate_step(TEMP) % h % array(:,:)       = block % time_levs(1) % state % h % array(:,:) + &amp;
-                                                                      block % intermediate_step(Q2) % h % array(:,:)/2.0
-         do iCell=1,block % mesh % nCells
-            do k=1,block % mesh % nVertLevels
-               block % intermediate_step(TEMP) % tracers % array(:,k,iCell) = ( &amp;
-                                                                  block % time_levs(1) % state % h % array(k,iCell) * &amp;
-                                                                  block % time_levs(1) % state % tracers % array(:,k,iCell) + &amp;
-                                                                  block % intermediate_step(Q2) % tracers % array(:,k,iCell) / 2.0 &amp;
-                                                                ) / block % intermediate_step(TEMP) % h % array(k,iCell)
-            end do
-         end do
-         if (config_test_case == 1) then    ! For case 1, wind field should be fixed
-            block % intermediate_step(TEMP) % u % array(:,:) = block % time_levs(1) % state % u % array(:,:)
-         end if
-         call compute_solve_diagnostics(block % intermediate_step(TEMP), block % mesh)
-         call compute_tend(block % intermediate_step(Q3), block % intermediate_step(TEMP), block % mesh)
-         call compute_scalar_tend(block % intermediate_step(Q3), block % intermediate_step(TEMP), block % mesh)
-         block % intermediate_step(Q3) % u % array(:,:)       = dt * block % intermediate_step(Q3) % u % array(:,:)
-         block % intermediate_step(Q3) % h % array(:,:)       = dt * block % intermediate_step(Q3) % h % array(:,:)
-         block % intermediate_step(Q3) % tracers % array(:,:,:) = dt * block % intermediate_step(Q3) % tracers % array(:,:,:)
+      rk_substep_weights(1) = dt/2.
+      rk_substep_weights(2) = dt/2.
+      rk_substep_weights(3) = dt
+      rk_substep_weights(4) = 0.
 
-         block =&gt; block % next
-      end do
 
-      block =&gt; domain % blocklist
-      do while (associated(block))
-         call dmpar_exch_halo_field2dReal(domain % dminfo, block % intermediate_step(Q3) % u % array(:,:), &amp;
-                                          block % mesh % nVertLevels, block % mesh % nEdges, &amp;
-                                          block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
-         call dmpar_exch_halo_field2dReal(domain % dminfo, block % intermediate_step(Q3) % h % array(:,:), &amp;
-                                          block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                          block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-         call dmpar_exch_halo_field3dReal(domain % dminfo, block % intermediate_step(Q3) % tracers % array(:,:,:), &amp;
-                                          block % mesh % nTracers, block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                          block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-         block =&gt; block % next
-      end do
+      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+      ! BEGIN RK loop 
+      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+      do rk_step = 1, 4
 
+! ---  compute tendencies
 
-      ! Take fourth RK step
-      block =&gt; domain % blocklist
-      do while (associated(block))
-         block % intermediate_step(TEMP) % u % array(:,:)       = block % time_levs(1) % state % u % array(:,:) + &amp;
-                                                                      block % intermediate_step(Q3) % u % array(:,:)
-         block % intermediate_step(TEMP) % h % array(:,:)       = block % time_levs(1) % state % h % array(:,:) + &amp;
-                                                                      block % intermediate_step(Q3) % h % array(:,:)
-         do iCell=1,block % mesh % nCells
-            do k=1,block % mesh % nVertLevels
-               block % intermediate_step(TEMP) % tracers % array(:,k,iCell) = ( &amp;
-                                                                  block % time_levs(1) % state % h % array(k,iCell) * &amp;
-                                                                  block % time_levs(1) % state % tracers % array(:,k,iCell) + &amp;
-                                                                  block % intermediate_step(Q3) % tracers % array(:,k,iCell) &amp;
-                                                                ) / block % intermediate_step(TEMP) % h % array(k,iCell)
-            end do
-         end do
-         if (config_test_case == 1) then    ! For case 1, wind field should be fixed
-            block % intermediate_step(TEMP) % u % array(:,:) = block % time_levs(1) % state % u % array(:,:)
-         end if
-         call compute_solve_diagnostics(block % intermediate_step(TEMP), block % mesh)
-         call compute_tend(block % intermediate_step(Q4), block % intermediate_step(TEMP), block % mesh)
-         call compute_scalar_tend(block % intermediate_step(Q4), block % intermediate_step(TEMP), block % mesh)
-         block % intermediate_step(Q4) % u % array(:,:)       = dt * block % intermediate_step(Q4) % u % array(:,:)
-         block % intermediate_step(Q4) % h % array(:,:)       = dt * block % intermediate_step(Q4) % h % array(:,:)
-         block % intermediate_step(Q4) % tracers % array(:,:,:) = dt * block % intermediate_step(Q4) % tracers % array(:,:,:)
+        block =&gt; domain % blocklist
+        do while (associated(block))
+           call compute_tend(block % intermediate_step(TEND), block % intermediate_step(PROVIS), block % mesh)
+           call compute_scalar_tend(block % intermediate_step(TEND), block % intermediate_step(PROVIS), block % mesh)
+           block =&gt; block % next
+        end do
 
-         block =&gt; block % next
-      end do
+! ---  update halos for prognostic variables
 
-      block =&gt; domain % blocklist
-      do while (associated(block))
-         call dmpar_exch_halo_field2dReal(domain % dminfo, block % intermediate_step(Q4) % u % array(:,:), &amp;
-                                          block % mesh % nVertLevels, block % mesh % nEdges, &amp;
-                                          block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
-         call dmpar_exch_halo_field2dReal(domain % dminfo, block % intermediate_step(Q4) % h % array(:,:), &amp;
-                                          block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                          block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-         call dmpar_exch_halo_field3dReal(domain % dminfo, block % intermediate_step(Q4) % tracers % array(:,:,:), &amp;
-                                          block % mesh % nTracers, block % mesh % nVertLevels, block % mesh % nCells, &amp;
-                                          block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
-         block =&gt; block % next
+        block =&gt; domain % blocklist
+        do while (associated(block))
+           call dmpar_exch_halo_field2dReal(domain % dminfo, block % intermediate_step(TEND) % u % array(:,:), &amp;
+                                            block % mesh % nVertLevels, block % mesh % nEdges, &amp;
+                                            block % parinfo % edgesToSend, block % parinfo % edgesToRecv)
+           call dmpar_exch_halo_field2dReal(domain % dminfo, block % intermediate_step(TEND) % h % array(:,:), &amp;
+                                            block % mesh % nVertLevels, block % mesh % nCells, &amp;
+                                            block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
+           call dmpar_exch_halo_field3dReal(domain % dminfo, block % intermediate_step(TEND) % tracers % array(:,:,:), &amp;
+                                            block % mesh % nTracers, block % mesh % nVertLevels, block % mesh % nCells, &amp;
+                                            block % parinfo % cellsToSend, block % parinfo % cellsToRecv)
+           block =&gt; block % next
+        end do
+
+! ---  compute next substep state
+
+        if (rk_step &lt; 4) then
+           block =&gt; domain % blocklist
+           do while (associated(block))
+              block % intermediate_step(PROVIS) % u % array(:,:)       = block % time_levs(1) % state % u % array(:,:)  &amp;
+                                         + rk_substep_weights(rk_step) * block % intermediate_step(TEND) % u % array(:,:)
+              block % intermediate_step(PROVIS) % h % array(:,:)       = block % time_levs(1) % state % h % array(:,:)  &amp;
+                                         + rk_substep_weights(rk_step) * block % intermediate_step(TEND) % h % array(:,:)
+              do iCell=1,block % mesh % nCells
+                 do k=1,block % mesh % nVertLevels
+                    block % intermediate_step(PROVIS) % tracers % array(:,k,iCell) = ( &amp;
+                                                                      block % time_levs(1) % state % h % array(k,iCell) * &amp;
+                                                                      block % time_levs(1) % state % tracers % array(:,k,iCell)  &amp;
+                                      + rk_substep_weights(rk_step) * block % intermediate_step(TEND) % tracers % array(:,k,iCell) &amp;
+                                                                     ) / block % intermediate_step(PROVIS) % h % array(k,iCell)
+                 end do
+              end do
+              if (config_test_case == 1) then    ! For case 1, wind field should be fixed
+                 block % intermediate_step(PROVIS) % u % array(:,:) = block % time_levs(1) % state % u % array(:,:)
+              end if
+              call compute_solve_diagnostics(block % intermediate_step(PROVIS), block % mesh)
+              block =&gt; block % next
+           end do
+        end if
+
+!--- accumulate update (for RK4)
+
+        block =&gt; domain % blocklist
+        do while (associated(block))
+           block % time_levs(2) % state % u % array(:,:) = block % time_levs(2) % state % u % array(:,:) &amp;
+                                   + rk_weights(rk_step) * block % intermediate_step(TEND) % u % array(:,:) 
+           block % time_levs(2) % state % h % array(:,:) = block % time_levs(2) % state % h % array(:,:) &amp;
+                                   + rk_weights(rk_step) * block % intermediate_step(TEND) % h % array(:,:) 
+           do iCell=1,block % mesh % nCells
+              do k=1,block % mesh % nVertLevels
+                 block % time_levs(2) % state % tracers % array(:,k,iCell) =  &amp;
+                                                                       block % time_levs(2) % state % tracers % array(:,k,iCell) &amp;
+                                               + rk_weights(rk_step) * block % intermediate_step(TEND) % tracers % array(:,k,iCell)
+              end do
+           end do
+           block =&gt; block % next
+        end do
+
       end do
+      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+      ! END RK loop 
+      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
 
-      
-      ! Compute final step and add to starting model state
+
+      !
+      !  A little clean up at the end: decouple new scalar fields and compute diagnostics for new state
+      !
       block =&gt; domain % blocklist
       do while (associated(block))
-         block % time_levs(2) % state % u % array(:,:) = block % time_levs(1) % state % u % array(:,:) + &amp;
-                                            (      block % intermediate_step(Q1) % u % array(:,:) + &amp;
-                                             2.0 * block % intermediate_step(Q2) % u % array(:,:) + &amp;
-                                             2.0 * block % intermediate_step(Q3) % u % array(:,:) + &amp;
-                                                   block % intermediate_step(Q4) % u % array(:,:) &amp;
-                                            ) / 6.0
-         block % time_levs(2) % state % h % array(:,:) = block % time_levs(1) % state % h % array(:,:) + &amp;
-                                            (      block % intermediate_step(Q1) % h % array(:,:) + &amp;
-                                             2.0 * block % intermediate_step(Q2) % h % array(:,:) + &amp;
-                                             2.0 * block % intermediate_step(Q3) % h % array(:,:) + &amp;
-                                                   block % intermediate_step(Q4) % h % array(:,:) &amp;
-                                            ) / 6.0
          do iCell=1,block % mesh % nCells
             do k=1,block % mesh % nVertLevels
-               block % time_levs(2) % state % tracers % array(:,k,iCell) = ( &amp;
-                                                               block % time_levs(1) % state % h % array(k,iCell) * &amp;
-                                                               block % time_levs(1) % state % tracers % array(:,k,iCell) + &amp;
-                                                               (      block % intermediate_step(Q1) % tracers % array(:,k,iCell) + &amp;
-                                                                2.0 * block % intermediate_step(Q2) % tracers % array(:,k,iCell) + &amp;
-                                                                2.0 * block % intermediate_step(Q3) % tracers % array(:,k,iCell) + &amp;
-                                                                      block % intermediate_step(Q4) % tracers % array(:,k,iCell) &amp;
-                                                               ) / 6.0 &amp;
-                                                             ) / block % time_levs(2) % state % h % array(k,iCell)
+               block % time_levs(2) % state % tracers % array(:,k,iCell) = &amp;
+                                                                     block % time_levs(2) % state % tracers % array(:,k,iCell)  &amp;
+                                                                   / block % time_levs(2) % state % h % array(k,iCell)
             end do
          end do
 

</font>
</pre>