/wrfv2_fire/share/interp_fcn.F
FORTRAN Legacy | 4745 lines | 2932 code | 628 blank | 1185 comment | 18 complexity | dc16ac86532aa48d91fa387825e5a956 MD5 | raw file
Possible License(s): AGPL-1.0
Large files files are truncated, but you can click here to view the full file
- !WRF:MEDIATION_LAYER:INTERPOLATIONFUNCTION
- !
- #if (DA_CORE != 1)
- #define MM5_SINT
- #endif
- !#define DUMBCOPY
- ! Note, NMM-specific routines moved to end. 20080612. JM
- SUBROUTINE interp_fcn ( cfld, & ! CD field
- cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nfld, & ! ND field
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, & ! stencil half width for interp
- imask, & ! interpolation mask
- xstag, ystag, & ! staggering of field
- ipos, jpos, & ! Position of lower left of nest in CD
- nri, nrj ) ! nest ratios
- USE module_timing
- USE module_configure
- IMPLICIT NONE
- INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, &
- ipos, jpos, &
- nri, nrj
- LOGICAL, INTENT(IN) :: xstag, ystag
- REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
- REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
- INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
- ! Local
- !logical first
- INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, nioff, njoff
- #ifdef MM5_SINT
- INTEGER nfx, ior
- PARAMETER (ior=2)
- INTEGER nf
- REAL psca(cims:cime,cjms:cjme,nri*nrj)
- LOGICAL icmask( cims:cime, cjms:cjme )
- INTEGER i,j,k
- INTEGER nrio2, nrjo2
- #endif
- ! Iterate over the ND tile and compute the values
- ! from the CD tile.
- #ifdef MM5_SINT
- ioff = 0 ; joff = 0
- nioff = 0 ; njoff = 0
- IF ( xstag ) THEN
- ioff = (nri-1)/2
- nioff = nri
- ENDIF
- IF ( ystag ) THEN
- joff = (nrj-1)/2
- njoff = nrj
- ENDIF
- nrio2 = nri/2
- nrjo2 = nrj/2
- nfx = nri * nrj
- !$OMP PARALLEL DO &
- !$OMP PRIVATE ( i,j,k,ni,nj,ci,cj,ip,jp,nk,ck,nf,icmask,psca )
- DO k = ckts, ckte
- icmask = .FALSE.
- DO nf = 1,nfx
- DO j = cjms,cjme
- nj = (j-jpos) * nrj + ( nrjo2 + 1 ) ! j point on nest
- DO i = cims,cime
- ni = (i-ipos) * nri + ( nrio2 + 1 ) ! i point on nest
- if ( ni .ge. nits-nioff-nrio2 .and. &
- ni .le. nite+nioff+nrio2 .and. &
- nj .ge. njts-njoff-nrjo2 .and. &
- nj .le. njte+njoff+nrjo2 ) then
- ! if ( imask(ni,nj) .eq. 1 .or. imask(ni-nioff,nj-njoff) .eq. 1 ) then
- ! icmask( i, j ) = .TRUE.
- ! endif
- if ( ni.ge.nims.and.ni.le.nime.and.nj.ge.njms.and.nj.le.njme) then
- if ( imask(ni,nj) .eq. 1 ) then
- icmask( i, j ) = .TRUE.
- endif
- endif
- if ( ni-nioff.ge.nims.and.ni.le.nime.and.nj-njoff.ge.njms.and.nj.le.njme) then
- if (ni .ge. nits-nioff .and. nj .ge. njts-njoff ) then
- if ( imask(ni-nioff,nj-njoff) .eq. 1) then
- icmask( i, j ) = .TRUE.
- endif
- endif
- endif
- endif
- psca(i,j,nf) = cfld(i,k,j)
- ENDDO
- ENDDO
- ENDDO
- ! tile dims in this call to sint are 1-over to account for the fact
- ! that the number of cells on the nest local subdomain is not
- ! necessarily a multiple of the nest ratio in a given dim.
- ! this could be a little less ham-handed.
- !call start_timing
- CALL sint( psca, &
- cims, cime, cjms, cjme, icmask, &
- cits-1, cite+1, cjts-1, cjte+1, nrj*nri, xstag, ystag )
- !call end_timing( ' sint ' )
- DO nj = njts, njte+joff
- cj = jpos + (nj-1) / nrj ! j coord of CD point
- jp = mod ( nj-1 , nrj ) ! coord of ND w/i CD point
- nk = k
- ck = nk
- DO ni = nits, nite+ioff
- ci = ipos + (ni-1) / nri ! i coord of CD point
- ip = mod ( ni-1 , nri ) ! coord of ND w/i CD point
- if ( imask ( ni, nj ) .eq. 1 .or. imask ( ni-ioff, nj-joff ) .eq. 1 ) then
- nfld( ni-ioff, nk, nj-joff ) = psca( ci , cj, ip+1 + (jp)*nri )
- endif
- ENDDO
- ENDDO
- ENDDO
- !$OMP END PARALLEL DO
- #endif
- #ifdef DUMBCOPY
- !write(0,'(") cims:cime, ckms:ckme, cjms:cjme ",6i4)')cims,cime, ckms,ckme, cjms,cjme
- !write(0,'(") nims:nime, nkms:nkme, njms:njme ",6i4)')nims,nime, nkms,nkme, njms,njme
- !write(0,'(") cits:cite, ckts:ckte, cjts:cjte ",6i4)')cits,cite, ckts,ckte, cjts,cjte
- !write(0,'(") nits:nite, nkts:nkte, njts:njte ",6i4)')nits,nite, nkts,nkte, njts,njte
- DO nj = njts, njte
- cj = jpos + (nj-1) / nrj ! j coord of CD point
- jp = mod ( nj , nrj ) ! coord of ND w/i CD point
- DO nk = nkts, nkte
- ck = nk
- DO ni = nits, nite
- ci = ipos + (ni-1) / nri ! j coord of CD point
- ip = mod ( ni , nri ) ! coord of ND w/i CD point
- ! This is a trivial implementation of the interp_fcn; just copies
- ! the values from the CD into the ND
- if ( imask ( ni, nj ) .eq. 1 ) then
- nfld( ni, nk, nj ) = cfld( ci , ck , cj )
- endif
- ENDDO
- ENDDO
- ENDDO
- #endif
- RETURN
- END SUBROUTINE interp_fcn
- !==================================
- ! this is the default function used in feedback.
- SUBROUTINE copy_fcn ( cfld, & ! CD field
- cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nfld, & ! ND field
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, & ! stencil half width for interp
- imask, & ! interpolation mask
- xstag, ystag, & ! staggering of field
- ipos, jpos, & ! Position of lower left of nest in CD
- nri, nrj ) ! nest ratios
- USE module_configure
- IMPLICIT NONE
- INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, &
- ipos, jpos, &
- nri, nrj
- LOGICAL, INTENT(IN) :: xstag, ystag
- REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(OUT) :: cfld
- REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ),INTENT(IN) :: nfld
- INTEGER, DIMENSION ( nims:nime, njms:njme ),INTENT(IN) :: imask
- ! Local
- INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, ioffa, joffa
- INTEGER :: icmin,icmax,jcmin,jcmax
- INTEGER :: istag,jstag, ipoints,jpoints,ijpoints
- INTEGER , PARAMETER :: passes = 2
- INTEGER spec_zone
- ! Loop over the coarse grid in the area of the fine mesh. Do not
- ! process the coarse grid values that are along the lateral BC
- ! provided to the fine grid. Since that is in the specified zone
- ! for the fine grid, it should not be used in any feedback to the
- ! coarse grid as it should not have changed.
- ! Due to peculiarities of staggering, it is simpler to handle the feedback
- ! for the staggerings based upon whether it is a even ratio (2::1, 4::1, etc.) or
- ! an odd staggering ratio (3::1, 5::1, etc.).
- ! Though there are separate grid ratios for the i and j directions, this code
- ! is not general enough to handle aspect ratios .NE. 1 for the fine grid cell.
-
- ! These are local integer increments in the looping. Basically, istag=1 means
- ! that we will assume one less point in the i direction. Note that ci and cj
- ! have a maximum value that is decreased by istag and jstag, respectively.
- ! Horizontal momentum feedback is along the face, not within the cell. For a
- ! 3::1 ratio, temperature would use 9 pts for feedback, while u and v use
- ! only 3 points for feedback from the nest to the parent.
- CALL nl_get_spec_zone( 1 , spec_zone )
- istag = 1 ; jstag = 1
- IF ( xstag ) istag = 0
- IF ( ystag ) jstag = 0
- IF( MOD(nrj,2) .NE. 0) THEN ! odd refinement ratio
- IF ( ( .NOT. xstag ) .AND. ( .NOT. ystag ) ) THEN
- DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
- nj = (cj-jpos)*nrj + jstag + 1
- DO ck = ckts, ckte
- nk = ck
- DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
- ni = (ci-ipos)*nri + istag + 1
- cfld( ci, ck, cj ) = 0.
- DO ijpoints = 1 , nri * nrj
- ipoints = MOD((ijpoints-1),nri) + 1 - nri/2 - 1
- jpoints = (ijpoints-1)/nri + 1 - nrj/2 - 1
- cfld( ci, ck, cj ) = cfld( ci, ck, cj ) + &
- 1./REAL(nri*nrj) * nfld( ni+ipoints , nk , nj+jpoints )
- END DO
- ! cfld( ci, ck, cj ) = 1./9. * &
- ! ( nfld( ni-1, nk , nj-1) + &
- ! nfld( ni , nk , nj-1) + &
- ! nfld( ni+1, nk , nj-1) + &
- ! nfld( ni-1, nk , nj ) + &
- ! nfld( ni , nk , nj ) + &
- ! nfld( ni+1, nk , nj ) + &
- ! nfld( ni-1, nk , nj+1) + &
- ! nfld( ni , nk , nj+1) + &
- ! nfld( ni+1, nk , nj+1) )
- ENDDO
- ENDDO
- ENDDO
- ELSE IF ( ( xstag ) .AND. ( .NOT. ystag ) ) THEN
- DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
- nj = (cj-jpos)*nrj + jstag + 1
- DO ck = ckts, ckte
- nk = ck
- DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
- ni = (ci-ipos)*nri + istag + 1
- cfld( ci, ck, cj ) = 0.
- DO ijpoints = (nri+1)/2 , (nri+1)/2 + nri*(nri-1) , nri
- ipoints = MOD((ijpoints-1),nri) + 1 - nri/2 - 1
- jpoints = (ijpoints-1)/nri + 1 - nrj/2 - 1
- cfld( ci, ck, cj ) = cfld( ci, ck, cj ) + &
- 1./REAL(nri ) * nfld( ni+ipoints , nk , nj+jpoints )
- END DO
- ! cfld( ci, ck, cj ) = 1./3. * &
- ! ( nfld( ni , nk , nj-1) + &
- ! nfld( ni , nk , nj ) + &
- ! nfld( ni , nk , nj+1) )
- ENDDO
- ENDDO
- ENDDO
- ELSE IF ( ( .NOT. xstag ) .AND. ( ystag ) ) THEN
- DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
- nj = (cj-jpos)*nrj + jstag + 1
- DO ck = ckts, ckte
- nk = ck
- DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
- ni = (ci-ipos)*nri + istag + 1
- cfld( ci, ck, cj ) = 0.
- DO ijpoints = ( nrj*nrj +1 )/2 - nrj/2 , ( nrj*nrj +1 )/2 - nrj/2 + nrj-1
- ipoints = MOD((ijpoints-1),nri) + 1 - nri/2 - 1
- jpoints = (ijpoints-1)/nri + 1 - nrj/2 - 1
- cfld( ci, ck, cj ) = cfld( ci, ck, cj ) + &
- 1./REAL( nrj) * nfld( ni+ipoints , nk , nj+jpoints )
- END DO
- ! cfld( ci, ck, cj ) = 1./3. * &
- ! ( nfld( ni-1, nk , nj ) + &
- ! nfld( ni , nk , nj ) + &
- ! nfld( ni+1, nk , nj ) )
- ENDDO
- ENDDO
- ENDDO
- END IF
- ! Even refinement ratio
- ELSE IF ( MOD(nrj,2) .EQ. 0) THEN
- IF ( ( .NOT. xstag ) .AND. ( .NOT. ystag ) ) THEN
- ! This is a simple schematic of the feedback indexing used in the even
- ! ratio nests. For simplicity, a 2::1 ratio is depicted. Only the
- ! mass variable staggering is shown.
- ! Each of
- ! the boxes with a "T" and four small "t" represents a coarse grid (CG)
- ! cell, that is composed of four (2::1 ratio) fine grid (FG) cells.
-
- ! Shown below is the area of the CG that is in the area of the FG. The
- ! first grid point of the depicted CG is the starting location of the nest
- ! in the parent domain (ipos,jpos - i_parent_start and j_parent_start from
- ! the namelist).
-
- ! For each of the CG points, the feedback loop is over each of the FG points
- ! within the CG cell. For a 2::1 ratio, there are four total points (this is
- ! the ijpoints loop). The feedback value to the CG is the arithmetic mean of
- ! all of the FG values within each CG cell.
- ! |-------------||-------------| |-------------||-------------|
- ! | t t || t t | | t t || t t |
- ! jpos+ | || | | || |
- ! (njde-njds)- | T || T | | T || T |
- ! jstag | || | | || |
- ! | t t || t t | | t t || t t |
- ! |-------------||-------------| |-------------||-------------|
- ! |-------------||-------------| |-------------||-------------|
- ! | t t || t t | | t t || t t |
- ! | || | | || |
- ! | T || T | | T || T |
- ! | || | | || |
- ! | t t || t t | | t t || t t |
- ! |-------------||-------------| |-------------||-------------|
- !
- ! ...
- ! ...
- ! ...
- ! ...
- ! ...
- ! |-------------||-------------| |-------------||-------------|
- ! jpoints = 1 | t t || t t | | t t || t t |
- ! | || | | || |
- ! | T || T | | T || T |
- ! | || | | || |
- ! jpoints = 0, | t t || t t | | t t || t t |
- ! nj=3 |-------------||-------------| |-------------||-------------|
- ! |-------------||-------------| |-------------||-------------|
- ! jpoints = 1 | t t || t t | | t t || t t |
- ! | || | | || |
- ! jpos | T || T | ... | T || T |
- ! | || | ... | || |
- ! jpoints = 0, | t t || t t | ... | t t || t t |
- ! nj=1 |-------------||-------------| |-------------||-------------|
- ! ^ ^
- ! | |
- ! | |
- ! ipos ipos+
- ! ni = 1 3 (nide-nids)/nri
- ! ipoints= 0 1 0 1 -istag
- !
- ! For performance benefits, users can comment out the inner most loop (and cfld=0) and
- ! hardcode the loop feedback. For example, it is set up to run a 2::1 ratio
- ! if uncommented. This lacks generality, but is likely to gain timing benefits
- ! with compilers unable to unroll inner loops that do not have parameterized sizes.
-
- ! The extra +1 ---------/ and the extra -1 ----\ (both for ci and cj)
- ! / \ keeps the feedback out of the
- ! / \ outer row/col, since that CG data
- ! / \ specified the nest boundary originally
- ! / \ This
- ! / \ is just
- ! / \ a sentence to not end a line
- ! / \ with a stupid backslash
- DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
- nj = (cj-jpos)*nrj + jstag
- DO ck = ckts, ckte
- nk = ck
- DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
- ni = (ci-ipos)*nri + istag
- cfld( ci, ck, cj ) = 0.
- DO ijpoints = 1 , nri * nrj
- ipoints = MOD((ijpoints-1),nri)
- jpoints = (ijpoints-1)/nri
- cfld( ci, ck, cj ) = cfld( ci, ck, cj ) + &
- 1./REAL(nri*nrj) * nfld( ni+ipoints , nk , nj+jpoints )
- END DO
- ! cfld( ci, ck, cj ) = 1./4. * &
- ! ( nfld( ni , nk , nj ) + &
- ! nfld( ni+1, nk , nj ) + &
- ! nfld( ni , nk , nj+1) + &
- ! nfld( ni+1, nk , nj+1) )
- END DO
- END DO
- END DO
- ! U
- ELSE IF ( ( xstag ) .AND. ( .NOT. ystag ) ) THEN
- ! |---------------|
- ! | |
- ! jpoints = 1 u u |
- ! | |
- ! U |
- ! | |
- ! jpoints = 0, u u |
- ! nj=3 | |
- ! |---------------|
- ! |---------------|
- ! | |
- ! jpoints = 1 u u |
- ! | |
- ! jpos U |
- ! | |
- ! jpoints = 0, u u |
- ! nj=1 | |
- ! |---------------|
- !
- ! ^
- ! |
- ! |
- ! ipos
- ! ni = 1 3
- ! ipoints= 0 1 0
- !
- DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
- nj = (cj-jpos)*nrj + 1
- DO ck = ckts, ckte
- nk = ck
- DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
- ni = (ci-ipos)*nri + 1
- cfld( ci, ck, cj ) = 0.
- DO ijpoints = 1 , nri*nrj , nri
- ipoints = MOD((ijpoints-1),nri)
- jpoints = (ijpoints-1)/nri
- cfld( ci, ck, cj ) = cfld( ci, ck, cj ) + &
- 1./REAL(nri ) * nfld( ni+ipoints , nk , nj+jpoints )
- END DO
- ! cfld( ci, ck, cj ) = 1./2. * &
- ! ( nfld( ni , nk , nj ) + &
- ! nfld( ni , nk , nj+1) )
- ENDDO
- ENDDO
- ENDDO
- ! V
- ELSE IF ( ( .NOT. xstag ) .AND. ( ystag ) ) THEN
- DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
- nj = (cj-jpos)*nrj + 1
- DO ck = ckts, ckte
- nk = ck
- DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
- ni = (ci-ipos)*nri + 1
- cfld( ci, ck, cj ) = 0.
- DO ijpoints = 1 , nri
- ipoints = MOD((ijpoints-1),nri)
- jpoints = (ijpoints-1)/nri
- cfld( ci, ck, cj ) = cfld( ci, ck, cj ) + &
- 1./REAL(nri ) * nfld( ni+ipoints , nk , nj+jpoints )
- END DO
- ! cfld( ci, ck, cj ) = 1./2. * &
- ! ( nfld( ni , nk , nj ) + &
- ! nfld( ni+1, nk , nj ) )
- ENDDO
- ENDDO
- ENDDO
- END IF
- END IF
- RETURN
- END SUBROUTINE copy_fcn
- !==================================
- ! this is the 1pt function used in feedback.
- SUBROUTINE copy_fcnm ( cfld, & ! CD field
- cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nfld, & ! ND field
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, & ! stencil half width for interp
- imask, & ! interpolation mask
- xstag, ystag, & ! staggering of field
- ipos, jpos, & ! Position of lower left of nest in CD
- nri, nrj ) ! nest ratios
- USE module_configure
- USE module_wrf_error
- IMPLICIT NONE
- INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, &
- ipos, jpos, &
- nri, nrj
- LOGICAL, INTENT(IN) :: xstag, ystag
- REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(OUT) :: cfld
- REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ), INTENT(IN) :: nfld
- INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: imask
- ! Local
- INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, ioffa, joffa
- INTEGER :: icmin,icmax,jcmin,jcmax
- INTEGER :: istag,jstag, ipoints,jpoints,ijpoints
- INTEGER , PARAMETER :: passes = 2
- INTEGER spec_zone
- CALL nl_get_spec_zone( 1, spec_zone )
- istag = 1 ; jstag = 1
- IF ( xstag ) istag = 0
- IF ( ystag ) jstag = 0
- IF( MOD(nrj,2) .NE. 0) THEN ! odd refinement ratio
- DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
- nj = (cj-jpos)*nrj + jstag + 1
- DO ck = ckts, ckte
- nk = ck
- DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
- ni = (ci-ipos)*nri + istag + 1
- cfld( ci, ck, cj ) = nfld( ni , nk , nj )
- ENDDO
- ENDDO
- ENDDO
- ELSE ! even refinement ratio, pick nearest neighbor on SW corner
- DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
- nj = (cj-jpos)*nrj + 1
- DO ck = ckts, ckte
- nk = ck
- DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
- ni = (ci-ipos)*nri + 1
- ipoints = nri/2 -1
- jpoints = nrj/2 -1
- cfld( ci, ck, cj ) = nfld( ni+ipoints , nk , nj+jpoints )
- END DO
- END DO
- END DO
- END IF
- RETURN
- END SUBROUTINE copy_fcnm
- !==================================
- ! this is the 1pt function used in feedback for integers
- SUBROUTINE copy_fcni ( cfld, & ! CD field
- cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nfld, & ! ND field
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, & ! stencil half width for interp
- imask, & ! interpolation mask
- xstag, ystag, & ! staggering of field
- ipos, jpos, & ! Position of lower left of nest in CD
- nri, nrj ) ! nest ratios
- USE module_configure
- USE module_wrf_error
- IMPLICIT NONE
- INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, &
- ipos, jpos, &
- nri, nrj
- LOGICAL, INTENT(IN) :: xstag, ystag
- INTEGER, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(OUT) :: cfld
- INTEGER, DIMENSION ( nims:nime, nkms:nkme, njms:njme ), INTENT(IN) :: nfld
- INTEGER, DIMENSION ( nims:nime, njms:njme ), INTENT(IN) :: imask
- ! Local
- INTEGER ci, cj, ck, ni, nj, nk, ip, jp, ioff, joff, ioffa, joffa
- INTEGER :: icmin,icmax,jcmin,jcmax
- INTEGER :: istag,jstag, ipoints,jpoints,ijpoints
- INTEGER , PARAMETER :: passes = 2
- INTEGER spec_zone
- CALL nl_get_spec_zone( 1, spec_zone )
- istag = 1 ; jstag = 1
- IF ( xstag ) istag = 0
- IF ( ystag ) jstag = 0
- IF( MOD(nrj,2) .NE. 0) THEN ! odd refinement ratio
- DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
- nj = (cj-jpos)*nrj + jstag + 1
- DO ck = ckts, ckte
- nk = ck
- DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
- ni = (ci-ipos)*nri + istag + 1
- cfld( ci, ck, cj ) = nfld( ni , nk , nj )
- ENDDO
- ENDDO
- ENDDO
- ELSE ! even refinement ratio
- DO cj = MAX(jpos+spec_zone,cjts),MIN(jpos+(njde-njds)/nrj-jstag-spec_zone,cjte)
- nj = (cj-jpos)*nrj + 1
- DO ck = ckts, ckte
- nk = ck
- DO ci = MAX(ipos+spec_zone,cits),MIN(ipos+(nide-nids)/nri-istag-spec_zone,cite)
- ni = (ci-ipos)*nri + 1
- ipoints = nri/2 -1
- jpoints = nrj/2 -1
- cfld( ci, ck, cj ) = nfld( ni+ipoints , nk , nj+jpoints )
- END DO
- END DO
- END DO
- END IF
- RETURN
- END SUBROUTINE copy_fcni
- !==================================
- SUBROUTINE p2c ( cfld, & ! CD field
- cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nfld, & ! ND field
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, & ! stencil half width
- imask, & ! interpolation mask
- xstag, ystag, & ! staggering of field
- ipos, jpos, & ! Position of lower left of nest in CD
- nri, nrj & ! nest ratios
- )
- USE module_configure
- IMPLICIT NONE
- INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, &
- ipos, jpos, &
- nri, nrj
- LOGICAL, INTENT(IN) :: xstag, ystag
- REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
- REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
- INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
- CALL interp_fcn (cfld, & ! CD field
- cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nfld, & ! ND field
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, & ! stencil half width for interp
- imask, & ! interpolation mask
- xstag, ystag, & ! staggering of field
- ipos, jpos, & ! Position of lower left of nest in CD
- nri, nrj ) ! nest ratios
- END SUBROUTINE p2c
- !==================================
- SUBROUTINE bdy_interp ( cfld, & ! CD field
- cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nfld, & ! ND field
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, & ! stencil half width
- imask, & ! interpolation mask
- xstag, ystag, & ! staggering of field
- ipos, jpos, & ! Position of lower left of nest in CD
- nri, nrj, & ! nest ratios
- cbdy_xs, nbdy_xs, &
- cbdy_xe, nbdy_xe, &
- cbdy_ys, nbdy_ys, &
- cbdy_ye, nbdy_ye, &
- cbdy_txs, nbdy_txs, &
- cbdy_txe, nbdy_txe, &
- cbdy_tys, nbdy_tys, &
- cbdy_tye, nbdy_tye, &
- cdt, ndt &
- ) ! boundary arrays
- USE module_configure
- IMPLICIT NONE
- INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, &
- ipos, jpos, &
- nri, nrj
- LOGICAL, INTENT(IN) :: xstag, ystag
- REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
- REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
- INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
- REAL, DIMENSION( * ), INTENT(INOUT) :: cbdy_xs, cbdy_txs, nbdy_xs, nbdy_txs
- REAL, DIMENSION( * ), INTENT(INOUT) :: cbdy_xe, cbdy_txe, nbdy_xe, nbdy_txe
- REAL, DIMENSION( * ), INTENT(INOUT) :: cbdy_ys, cbdy_tys, nbdy_ys, nbdy_tys
- REAL, DIMENSION( * ), INTENT(INOUT) :: cbdy_ye, cbdy_tye, nbdy_ye, nbdy_tye
- REAL cdt, ndt
- ! Local
- INTEGER nijds, nijde, spec_bdy_width
- nijds = min(nids, njds)
- nijde = max(nide, njde)
- CALL nl_get_spec_bdy_width( 1, spec_bdy_width )
- CALL bdy_interp1( cfld, & ! CD field
- cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nfld, & ! ND field
- nijds, nijde , spec_bdy_width , &
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, imask, &
- xstag, ystag, & ! staggering of field
- ipos, jpos, & ! Position of lower left of nest in CD
- nri, nrj, &
- cbdy_xs, nbdy_xs, &
- cbdy_xe, nbdy_xe, &
- cbdy_ys, nbdy_ys, &
- cbdy_ye, nbdy_ye, &
- cbdy_txs, nbdy_txs, &
- cbdy_txe, nbdy_txe, &
- cbdy_tys, nbdy_tys, &
- cbdy_tye, nbdy_tye, &
- cdt, ndt &
- )
- RETURN
- END SUBROUTINE bdy_interp
- SUBROUTINE bdy_interp1( cfld, & ! CD field
- cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nfld, & ! ND field
- nijds, nijde, spec_bdy_width , &
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw1, &
- imask, & ! interpolation mask
- xstag, ystag, & ! staggering of field
- ipos, jpos, & ! Position of lower left of nest in CD
- nri, nrj, &
- cbdy_xs, bdy_xs, &
- cbdy_xe, bdy_xe, &
- cbdy_ys, bdy_ys, &
- cbdy_ye, bdy_ye, &
- cbdy_txs, bdy_txs, &
- cbdy_txe, bdy_txe, &
- cbdy_tys, bdy_tys, &
- cbdy_tye, bdy_tye, &
- cdt, ndt &
- )
- USE module_configure
- use module_state_description
- IMPLICIT NONE
- INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw1, & ! ignore
- ipos, jpos, &
- nri, nrj
- INTEGER, INTENT(IN) :: nijds, nijde, spec_bdy_width
- LOGICAL, INTENT(IN) :: xstag, ystag
- REAL, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ), INTENT(INOUT) :: cfld
- REAL, DIMENSION ( nims:nime, nkms:nkme, njms:njme ), INTENT(INOUT) :: nfld
- INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
- REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_xs, cbdy_txs ! not used
- REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_xe, cbdy_txe ! not used
- REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_ys, cbdy_tys ! not used
- REAL, DIMENSION ( * ), INTENT(INOUT) :: cbdy_ye, cbdy_tye ! not used
- REAL :: cdt, ndt
- REAL, DIMENSION ( njms:njme, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_xs, bdy_txs
- REAL, DIMENSION ( njms:njme, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_xe, bdy_txe
- REAL, DIMENSION ( nims:nime, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_ys, bdy_tys
- REAL, DIMENSION ( nims:nime, nkms:nkme, spec_bdy_width ), INTENT(INOUT) :: bdy_ye, bdy_tye
- ! Local
- REAL*8 rdt
- INTEGER ci, cj, ck, ni, nj, nk, ni1, nj1, nk1, ip, jp, ioff, joff
- #ifdef MM5_SINT
- INTEGER nfx, ior
- PARAMETER (ior=2)
- INTEGER nf
- REAL psca1(cims:cime,cjms:cjme,nri*nrj)
- REAL psca(cims:cime,cjms:cjme,nri*nrj)
- LOGICAL icmask( cims:cime, cjms:cjme )
- INTEGER i,j,k
- #endif
- INTEGER shw
- INTEGER spec_zone
- INTEGER relax_zone
- INTEGER sz
- INTEGER n2ci,n
- INTEGER n2cj
- ! statement functions for converting a nest index to coarse
- n2ci(n) = (n+ipos*nri-1)/nri
- n2cj(n) = (n+jpos*nrj-1)/nrj
- rdt = 1.D0/cdt
- shw = 0
- ioff = 0 ; joff = 0
- IF ( xstag ) THEN
- ioff = (nri-1)/2
- ENDIF
- IF ( ystag ) THEN
- joff = (nrj-1)/2
- ENDIF
- ! Iterate over the ND tile and compute the values
- ! from the CD tile.
- #ifdef MM5_SINT
- CALL nl_get_spec_zone( 1, spec_zone )
- CALL nl_get_relax_zone( 1, relax_zone )
- sz = MIN(MAX( spec_zone, relax_zone + 1 ),spec_bdy_width)
- nfx = nri * nrj
- !$OMP PARALLEL DO &
- !$OMP PRIVATE ( i,j,k,ni,nj,ni1,nj1,ci,cj,ip,jp,nk,ck,nf,icmask,psca,psca1 )
- DO k = ckts, ckte
- DO nf = 1,nfx
- DO j = cjms,cjme
- nj = (j-jpos) * nrj + ( nrj / 2 + 1 ) ! j point on nest
- DO i = cims,cime
- ni = (i-ipos) * nri + ( nri / 2 + 1 ) ! i point on nest
- psca1(i,j,nf) = cfld(i,k,j)
- ENDDO
- ENDDO
- ENDDO
- ! hopefully less ham handed but still correct and more efficient
- ! sintb ignores icmask so it does not matter that icmask is not set
- !
- ! SOUTH BDY
- IF ( njts .ge. njds .and. njts .le. njds + sz + joff ) THEN
- CALL sintb( psca1, psca, &
- cims, cime, cjms, cjme, icmask, &
- n2ci(nits)-1, n2ci(nite)+1, n2cj(MAX(njts,njds)), n2cj(MIN(njte,njds+sz+joff)), nrj*nri, xstag, ystag )
- ENDIF
- ! NORTH BDY
- IF ( njte .le. njde .and. njte .ge. njde - sz - joff ) THEN
- CALL sintb( psca1, psca, &
- cims, cime, cjms, cjme, icmask, &
- n2ci(nits)-1, n2ci(nite)+1, n2cj(MAX(njts,njde-sz-joff)), n2cj(MIN(njte,njde-1+joff)), nrj*nri, xstag, ystag )
- ENDIF
- ! WEST BDY
- IF ( nits .ge. nids .and. nits .le. nids + sz + ioff ) THEN
- CALL sintb( psca1, psca, &
- cims, cime, cjms, cjme, icmask, &
- n2ci(MAX(nits,nids)), n2ci(MIN(nite,nids+sz+ioff)), n2cj(njts)-1, n2cj(njte)+1, nrj*nri, xstag, ystag )
- ENDIF
- ! EAST BDY
- IF ( nite .le. nide .and. nite .ge. nide - sz - ioff ) THEN
- CALL sintb( psca1, psca, &
- cims, cime, cjms, cjme, icmask, &
- n2ci(MAX(nits,nide-sz-ioff)), n2ci(MIN(nite,nide-1+ioff)), n2cj(njts)-1, n2cj(njte)+1, nrj*nri, xstag, ystag )
- ENDIF
- DO nj1 = MAX(njds,njts-1), MIN(njde+joff,njte+joff+1)
- cj = jpos + (nj1-1) / nrj ! j coord of CD point
- jp = mod ( nj1-1 , nrj ) ! coord of ND w/i CD point
- nk = k
- ck = nk
- DO ni1 = MAX(nids,nits-1), MIN(nide+ioff,nite+ioff+1)
- ci = ipos + (ni1-1) / nri ! j coord of CD point
- ip = mod ( ni1-1 , nri ) ! coord of ND w/i CD point
- ni = ni1-ioff
- nj = nj1-joff
- IF ( ( ni.LT.nids) .OR. (nj.LT.njds) ) THEN
- CYCLE
- END IF
- !bdy contains the value at t-dt. psca contains the value at t
- !compute dv/dt and store in bdy_t
- !afterwards store the new value of v at t into bdy
- ! WEST
- IF ( ni .ge. nids .and. ni .lt. nids + sz ) THEN
- bdy_txs( nj,k,ni ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
- bdy_xs( nj,k,ni ) = psca(ci+shw,cj+shw,ip+1+(jp)*nri )
- ENDIF
- ! SOUTH
- IF ( nj .ge. njds .and. nj .lt. njds + sz ) THEN
- bdy_tys( ni,k,nj ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
- bdy_ys( ni,k,nj ) = psca(ci+shw,cj+shw,ip+1+(jp)*nri )
- ENDIF
- ! EAST
- IF ( xstag ) THEN
- IF ( ni .ge. nide - sz + 1 .AND. ni .le. nide ) THEN
- bdy_txe( nj,k,nide-ni+1 ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
- bdy_xe( nj,k,nide-ni+1 ) = psca(ci+shw,cj+shw,ip+1+(jp)*nri )
- ENDIF
- ELSE
- IF ( ni .ge. nide - sz .AND. ni .le. nide-1 ) THEN
- bdy_txe( nj,k,nide-ni ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
- bdy_xe( nj,k,nide-ni ) = psca(ci+shw,cj+shw,ip+1+(jp)*nri )
- ENDIF
- ENDIF
- ! NORTH
- IF ( ystag ) THEN
- IF ( nj .ge. njde - sz + 1 .AND. nj .le. njde ) THEN
- bdy_tye( ni,k,njde-nj+1 ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
- bdy_ye( ni,k,njde-nj+1 ) = psca(ci+shw,cj+shw,ip+1+(jp)*nri )
- ENDIF
- ELSE
- IF ( nj .ge. njde - sz .AND. nj .le. njde-1 ) THEN
- bdy_tye(ni,k,njde-nj ) = rdt*(psca(ci+shw,cj+shw,ip+1+(jp)*nri)-nfld(ni,k,nj))
- bdy_ye( ni,k,njde-nj ) = psca(ci+shw,cj+shw,ip+1+(jp)*nri )
- ENDIF
- ENDIF
- ENDDO
- ENDDO
- ENDDO
- !$OMP END PARALLEL DO
- #endif
- RETURN
- END SUBROUTINE bdy_interp1
- SUBROUTINE interp_fcni( cfld, & ! CD field
- cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nfld, & ! ND field
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, & ! stencil half width
- imask, & ! interpolation mask
- xstag, ystag, & ! staggering of field
- ipos, jpos, & ! Position of lower left of nest in CD
- nri, nrj ) ! nest ratios
- USE module_configure
- IMPLICIT NONE
- INTEGER, INTENT(IN) :: cids, cide, ckds, ckde, cjds, cjde, &
- cims, cime, ckms, ckme, cjms, cjme, &
- cits, cite, ckts, ckte, cjts, cjte, &
- nids, nide, nkds, nkde, njds, njde, &
- nims, nime, nkms, nkme, njms, njme, &
- nits, nite, nkts, nkte, njts, njte, &
- shw, &
- ipos, jpos, &
- nri, nrj
- LOGICAL, INTENT(IN) :: xstag, ystag
- INTEGER, DIMENSION ( cims:cime, ckms:ckme, cjms:cjme ) :: cfld
- INTEGER, DIMENSION ( nims:nime, nkms:nkme, njms:njme ) :: nfld
- INTEGER, DIMENSION ( nims:nime, njms:njme ) :: imask
- ! Local
- INTEGER ci, cj, ck, ni, nj, nk, ip, jp
- ! Iterate over the ND tile and compute the values
- ! from the CD tile.
- !write(0,'("cits:cite, ckts:ckte, cjts:cjte ",6i4)')cits,cite, ckts,ckte, cjts,cjte
- !write(0,'("nits:nite, nkts:nkte, njts:njte ",6i4)')nits,nite, nkts,nkte, njts,njte
- DO nj = njts, njte
- cj = jpos + (nj-1) / nrj ! j coord of CD point
- jp = mod ( nj , nrj ) ! coord of ND w/i CD point
- DO n…
Large files files are truncated, but you can click here to view the full file