<p><b>laura@ucar.edu</b> 2012-08-23 12:18:11 -0600 (Thu, 23 Aug 2012)</p><p>mpas_init_atm_surface.F includes the updated subroutine init_atm_test_case_sfc (moved from mpas_init_atm_test_cases.F). created to start reducing the size of mpas_init_atm_test_cases.F<br>
</p><hr noshade><pre><font color="gray">Added: branches/atmos_physics/src/core_init_nhyd_atmos/mpas_init_atm_surface.F
===================================================================
--- branches/atmos_physics/src/core_init_nhyd_atmos/mpas_init_atm_surface.F                                (rev 0)
+++ branches/atmos_physics/src/core_init_nhyd_atmos/mpas_init_atm_surface.F        2012-08-23 18:18:11 UTC (rev 2119)
@@ -0,0 +1,316 @@
+!==================================================================================================
+ module mpas_init_atm_surface
+ use mpas_configure
+ use mpas_grid_types
+ use mpas_io_output
+ use mpas_timekeeping
+ use mpas_timer

+ use init_atm_hinterp
+ use init_atm_llxy
+ use init_atm_read_met
+
+ implicit none
+ private
+ public:: init_atm_test_case_sfc,interp_sfc_to_MPAS
+
+ contains
+
+!==================================================================================================
+ subroutine init_atm_test_case_sfc(domain,dminfo,mesh,fg,state)
+!==================================================================================================
+
+!input arguments:
+ type(domain_type), intent(inout):: domain
+ type(dm_info), intent(in)       :: dminfo
+ type(mesh_type), intent(inout)  :: mesh
+ type(fg_type), intent(inout)    :: fg
+ type (state_type), intent(inout):: state
+
+!local variables:
+ type(MPAS_Clock_type)       :: fg_clock
+ type(MPAS_Time_type)        :: start_time,stop_time,curr_time
+ type(MPAS_TimeInterval_type):: fg_interval
+
+ type(io_output_object):: sfc_update_obj
+ type(met_data)        :: field !real*4 meteorological data.
+ type(proj_info)       :: proj
+
+ character(len=StrKIND) :: timeString
+
+!==================================================================================================
+
+!set up clock to step through all intermediate file dates to be processed:
+ call mpas_set_time(start_time, dateTimeString=trim(config_start_time))
+ call mpas_set_time(stop_time, dateTimeString=trim(config_stop_time))
+ call mpas_set_timeInterval(fg_interval, S=config_fg_interval)
+ call mpas_create_clock(fg_clock, start_time, fg_interval, stopTime=stop_time) 
+
+!initialize the output file
+ sfc_update_obj % time = 1
+ sfc_update_obj % filename = trim(config_sfc_update_name)
+
+ call mpas_output_state_init(sfc_update_obj, domain, &quot;SFC&quot;)
+
+!loop over all times:
+ curr_time = mpas_get_clock_time(fg_clock, MPAS_NOW) 
+
+ do while (curr_time &lt;= stop_time)
+    call mpas_get_time(curr_time, dateTimeString=timeString)
+!   write(0,*) 'Processing ',trim(config_sfc_prefix)//':'//timeString(1:13)
+
+    !read the sea-surface temperature and sea-ice data from the surface file, and interpolate the
+    !data to the MPAS grid:
+    call interp_sfc_to_MPAS(timeString(1:13),mesh,fg,dminfo)
+
+    !write the interpolated SST/SKINTEMP field as a new time slice in the MPAS output file:
+    call mpas_output_state_for_domain(sfc_update_obj, domain, sfc_update_obj % time)
+    sfc_update_obj % time = sfc_update_obj % time + 1
+
+    call mpas_advance_clock(fg_clock)
+    curr_time = mpas_get_clock_time(fg_clock, MPAS_NOW) 
+
+    call mpas_get_time(curr_time, dateTimeString=timeString)
+    state % xtime % scalar = timeString
+
+ enddo
+
+ call mpas_output_state_finalize(sfc_update_obj, dminfo)
+      
+ end subroutine init_atm_test_case_sfc
+
+!==================================================================================================
+ subroutine interp_sfc_to_MPAS(timeString,mesh,fg,dminfo)
+!==================================================================================================
+
+!input arguments:
+ character(len=*),intent(in):: timeString
+ type(mesh_type), intent(in):: mesh
+ type(dm_info),intent(in)   :: dminfo
+
+!inout arguments:
+ type(fg_type), intent(inout):: fg
+
+!local variables:
+ type(met_data) :: field !real*4 meteorological data.
+ type(proj_info):: proj
+
+ integer:: istatus
+ integer:: masked
+ integer,dimension(5):: interp_list
+ integer,dimension(:),pointer:: mask_array
+
+ real(kind=RKIND):: fillval,maskval,msgval
+ real(kind=RKIND),dimension(:,:),allocatable:: maskslab
+
+ real(kind=RKIND), dimension(:), pointer:: destField1d
+
+!==================================================================================================
+ mask_array =&gt; mesh % landmask % array
+
+!open intermediate file:
+ call read_met_init(trim(config_sfc_prefix),.false.,timeString,istatus)
+ if(istatus /= 0) then
+    write(0,*) 'Error reading   ',trim(config_sfc_prefix)//':'//timeString(1:13)
+    call mpas_dmpar_abort(dminfo)
+ else
+    write(0,*) 'Processing file ',trim(config_sfc_prefix)//':'//timeString(1:13)
+ endif
+
+!scan through all fields in the file, looking for the LANDSEA field:
+ call read_next_met_field(field,istatus)
+ do while (istatus == 0)
+    if(index(field % field, 'LANDSEA') /= 0) then
+       allocate(maskslab(-2:field % nx+3, field % ny))
+       maskslab(1:field % nx, 1:field % ny) = field % slab(1:field % nx, 1:field % ny)
+       maskslab(0, 1:field % ny)  = field % slab(field % nx, 1:field % ny)
+       maskslab(-1, 1:field % ny) = field % slab(field % nx-1, 1:field % ny)
+       maskslab(-2, 1:field % ny) = field % slab(field % nx-2, 1:field % ny)
+       maskslab(field % nx+1, 1:field % ny) = field % slab(1, 1:field % ny)
+       maskslab(field % nx+2, 1:field % ny) = field % slab(2, 1:field % ny)
+       maskslab(field % nx+3, 1:field % ny) = field % slab(3, 1:field % ny)
+!      write(0,*) 'minval, maxval of LANDSEA = ', minval(maskslab), maxval(maskslab)
+    endif
+    deallocate(field % slab)
+    call read_next_met_field(field,istatus)
+ enddo
+ call read_met_close()
+
+!read sea-surface temperatures and seaice data. open intermediate file:
+ call read_met_init(trim(config_sfc_prefix),.false.,timeString(1:13),istatus)
+ if(istatus /= 0) then
+    write(0,*) 'Error reading ',trim(config_sfc_prefix)//':'//timeString(1:13)
+    call mpas_dmpar_abort(dminfo)
+ endif
+
+!scan through all fields in the file, looking for the SST,SKINTEMP, or SEAICE field:
+ call read_next_met_field(field,istatus)
+ do while (istatus == 0)
+
+    !sea-surface data:
+    if(index(field % field, 'SKINTEMP') /= 0 .or. index(field % field, 'SST') /= 0) then
+       write(0,*) '... Processing SST:'
+       fg % sst % array(1:mesh%nCells) = 0.0_RKIND
+       destField1d =&gt; fg % sst % array
+
+       !interpolation to the MPAS grid:
+       interp_list(1) = FOUR_POINT
+       interp_list(2) = SEARCH
+       interp_list(3) = 0
+       interp_list(4) = SEARCH
+       interp_list(5) = 0
+       msgval  = -1.0e30_RKIND !missing value
+       masked  = -1
+       maskval = -1.0_RKIND
+       fillval =  0.0_RKIND
+       call interp_to_MPAS(mesh,field,destField1d,interp_list,msgval,masked,maskval,fillval, &amp;
+                           maskslab,mask_array)
+
+       !field%slab was allocated in the subroutine read_next_met_field
+       deallocate(field%slab)
+
+    !sea-ice data:
+    elseif(index(field % field, 'SEAICE') /= 0) then
+       write(0,*) '... Processing SEAICE:'
+       fg % xice % array(1:mesh%nCells) = 0.0_RKIND
+       destField1d =&gt; fg % xice % array
+
+       !interpolation to the MPAS grid:
+       interp_list(1) = SIXTEEN_POINT
+       interp_list(2) = FOUR_POINT
+       interp_list(3) = W_AVERAGE4
+       interp_list(4) = SEARCH
+       interp_list(5) = 0
+       msgval  = -1.0e30_RKIND  !missing value
+       masked  = 1
+       maskval = 1.0_RKIND
+       fillval = 0.0_RKIND
+       call interp_to_MPAS(mesh,field,destField1d,interp_list,msgval,masked,maskval,fillval, &amp;
+                           maskslab,mask_array)
+
+       !field%slab was allocated in the subroutine read_next_met_field
+       deallocate(field%slab)
+        
+    else
+       deallocate(field%slab)
+
+    endif
+
+    call read_next_met_field(field,istatus)
+ enddo
+
+!close intermediate file:
+ call read_met_close()
+
+!freeze really cold oceans:
+ where(fg%sst%array.lt.271.0_RKIND .and. mesh%landmask%array.eq.0) fg%xice%array = 1.0_RKIND
+
+!limit XICE to values between 0 and 1. Although the input meteorological field is between 0. and 1.
+!interpolation to the MPAS grid can yield values of XiCE less than 0. and greater than 1.:
+ where (fg%xice%array &lt; 0._RKIND) fg%xice%array = 0._RKIND
+ where (fg%xice%array &gt; 1._RKIND) fg%xice%array = 1._RKIND
+
+ end subroutine interp_sfc_to_MPAS
+
+!==================================================================================================
+ subroutine interp_to_MPAS(mesh,field,destField1d,interp_list,msgval,masked,maskval,fillval, &amp;
+                           maskslab,mask_array)
+!==================================================================================================
+
+!input arguments:
+ type(mesh_type),intent(in):: mesh
+ type(met_data),intent(in) :: field !real*4 meteorological data.
+
+ integer,intent(in):: masked
+ integer,dimension(5),intent(in):: interp_list
+ integer,dimension(:),intent(in),pointer:: mask_array
+
+ real(kind=RKIND),intent(in):: fillval,maskval,msgval
+ real(kind=RKIND),intent(in),dimension(*):: maskslab
+
+!inout arguments:
+ real(kind=RKIND),intent(inout),dimension(:),pointer:: destField1d
+
+!local variables:
+ type(proj_info):: proj
+ integer:: i,nInterpPoints
+ real(kind=RKIND):: lat,lon,x,y
+ real(kind=RKIND),dimension(:,:),allocatable:: rslab
+
+ real(kind=RKIND),dimension(:),pointer:: latPoints,lonPoints

+!--------------------------------------------------------------------------------------------------
+
+ call map_init(proj)   
+ if(field % iproj == PROJ_LATLON) then
+    call map_set(PROJ_LATLON, proj, &amp;
+                 latinc = real(field % deltalat,RKIND), &amp;
+                 loninc = real(field % deltalon,RKIND), &amp;
+                 knowni = 1.0_RKIND, &amp;
+                 knownj = 1.0_RKIND, &amp;
+                 lat1 = real(field % startlat,RKIND), &amp;
+                 lon1 = real(field % startlon,RKIND))
+!   write(0,*) '--- The projection is PROJ_LATLON.'
+ elseif(field % iproj == PROJ_GAUSS) then
+    call map_set(PROJ_GAUSS, proj, &amp;
+                 nlat = nint(field % deltalat), &amp;
+                 loninc = real(field % deltalon,RKIND), &amp;
+                 lat1 = real(field % startlat,RKIND), &amp;
+                 lon1 = real(field % startlon,RKIND))
+!   write(0,*) '--- The projection is PROJ_GAUSS.'
+ elseif(field % iproj == PROJ_PS) then
+    call map_set(PROJ_PS, proj, &amp;
+                 dx = real(field % dx,RKIND), &amp;
+                 truelat1 = real(field % truelat1,RKIND), &amp;
+                 stdlon = real(field % xlonc,RKIND), &amp;
+                 knowni = real(field % nx / 2.0,RKIND), &amp;
+                 knownj = real(field % ny / 2.0,RKIND), &amp;
+                 lat1 = real(field % startlat,RKIND), &amp;
+                 lon1 = real(field % startlon,RKIND))
+!   write(0,*) '--- The projection is PROJ_PS.'
+ endif
+
+ nInterpPoints = mesh % nCells
+ latPoints =&gt; mesh % latCell % array
+ lonPoints =&gt; mesh % lonCell % array
+
+ allocate(rslab(-2:field % nx+3, field % ny))
+ rslab(1:field % nx, 1:field % ny) = field % slab(1:field % nx, 1:field % ny)
+ rslab( 0, 1:field % ny) = field % slab(field % nx  , 1:field % ny)
+ rslab(-1, 1:field % ny) = field % slab(field % nx-1, 1:field % ny)
+ rslab(-2, 1:field % ny) = field % slab(field % nx-2, 1:field % ny)
+ rslab(field % nx+1, 1:field % ny) = field % slab(1, 1:field % ny)
+ rslab(field % nx+2, 1:field % ny) = field % slab(2, 1:field % ny)
+ rslab(field % nx+3, 1:field % ny) = field % slab(3, 1:field % ny)
+
+ do i = 1,nInterpPoints
+    if(mask_array(i) /= masked) then
+       lat = latPoints(i) * DEG_PER_RAD
+       lon = lonPoints(i) * DEG_PER_RAD
+       call latlon_to_ij(proj, lat, lon, x, y)
+       if(y &lt; 0.5) then
+          y = 1.0
+       elseif(y &gt;= real(field%ny)+0.5) then
+          y = real(field % ny)
+       endif
+       if(x &lt; 0.5) then
+          lon = lon + 360.0
+          call latlon_to_ij(proj, lat, lon, x, y)
+       elseif (x &gt;= real(field%nx)+0.5) then
+          lon = lon - 360.0
+          call latlon_to_ij(proj, lat, lon, x, y)
+       endif
+       destField1d(i) = interp_sequence(x,y,1,rslab,-2,field%nx+3,1,field%ny,1,1, &amp;
+                        msgval,interp_list,1,maskval=maskval,mask_array=maskslab)
+    else
+       destField1d(i) = fillval
+    endif
+ enddo
+ deallocate(rslab)
+
+ end subroutine interp_to_MPAS
+
+!==================================================================================================
+ end module mpas_init_atm_surface
+!==================================================================================================
+

</font>
</pre>