!-------------------------------------- LICENCE BEGIN ------------------------------------ !Environment Canada - Atmospheric Science and Technology License/Disclaimer, ! version 3; Last Modified: May 7, 2008. !This is free but copyrighted software; you can use/redistribute/modify it under the terms !of the Environment Canada - Atmospheric Science and Technology License/Disclaimer !version 3 or (at your option) any later version that should be found at: !http://collaboration.cmc.ec.gc.ca/science/rpn.comm/license.html ! !This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; !without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. !See the above mentioned License/Disclaimer for more details. !You should have received a copy of the License/Disclaimer along with this software; !if not, you can write to: EC-RPN COMM Group, 2121 TransCanada, suite 500, Dorval (Quebec), !CANADA, H9P 1J3; or send e-mail to service.rpn@ec.gc.ca !-------------------------------------- LICENCE END -------------------------------------- ***s/p adw_trilin_turbo - Optimized tri-linear interpolation * with SETINT inside * #include "model_macros_f.h"*
subroutine adw_trilin_turbo ( F_out, F_in, F_dt, 13 % F_x, F_y, F_z, F_capz, % Fn_I, F_num, i0, in, j0, jn, kn) * implicit none * integer F_num, Fn_I(F_num), i0, in, j0, jn, kn * real F_dt, F_in(*) * real F_out(F_num), F_x(F_num), F_y(F_num), F_z(F_num) real F_capz(F_num) * *authors * Valin & Tanguay * * (Based on adw_trilin v_3.1.1) * *revision * v3_20 -Valin & Tanguay - initial version * v3_21 -Tanguay M. - evaluate min-max vertical CFL as function of k * *object * see id section * * NOTE: capx,capy are recalculated but capz is stored in F_capz * *arguments *______________________________________________________________________ * | | | * NAME | DESCRIPTION | I/O | *--------------|-------------------------------------------------|-----| * F_out | F_dt * result of interpolation | o | * F_in | field to interpolate | i | * | | | * F_dt | multiplicative constant (1.0 or timestep lenght)| i | * | | | * F_x | \ | i | * F_y | x,y,z positions | i | * F_z | / | i | * | | | * F_capz | precomputed displacements along the z-direction | io | * | | | * Fn_I | localisation indices | i | * | | | * F_num | number of points to interpolate | i | *______________|_________________________________________________|_____| * *implicits #include "glb_ld.cdk"
#include "adw.cdk"
#include "v4dcfl.cdk"
************************************************************************ * integer n, n0, nijag, nij, o1, o2, i, j, k, iimax, jjmax, kkmax, % ii,jj,kk * real capx, capy, capz * real*8 rri, rrj, rrk, prf1, prf2, prf3, prf4 * integer cfl,err logical done_L data done_L /.false./ save done_L * * ---------------------------------------------------------------- * * Initialize min-max vertical CFL as function of k * ------------------------------------------------ if(.not.done_L) then call hpalloc(V4dcfl_p_ ,l_nk, err,1) call hpalloc(V4dcfl_n_ ,l_nk, err,1) do k = 1,l_nk V4dcfl_p(k) = 0 V4dcfl_n(k) = 0 enddo done_L = .true. endif * nijag = Adw_nit * Adw_njt nij = l_ni*l_nj * iimax = G_ni+2*Adw_halox-1 jjmax = G_nj+Adw_haloy kkmax = l_nk-1 * !$omp parallel do private(n,n0,ii,jj,kk,rri,rrj,rrk, !$omp& capx,capy,capz,o1,o2,prf1,prf2,prf3,prf4,cfl) do 100 k=1,kn do 90 j=j0,jn n0 = (k-1)*nij + ((j-1)*l_ni) if ( Adw_hor_L ) then do i=i0,in n = n0 + i * rri= F_x(n) ii = ( rri - Adw_x00_8 ) * Adw_ovdx_8 ii = Adw_lcx( ii+1 ) + 1 if ( rri .lt. Adw_bsx_8(ii) ) ii = ii - 1 ii = max(1,min(ii,iimax)) * rrj= F_y(n) jj = ( rrj - Adw_y00_8 ) * Adw_ovdy_8 jj = Adw_lcy( jj+1 ) + 1 if ( rrj .lt. Adw_bsy_8(jj) ) jj = jj - 1 jj = max(Adw_haloy,min(jj,jjmax)) * kk = ishft(Fn_I(n) , -24) Fn_I(n) = ior( ior(ishft(jj,12) , ii) , ishft( kk , 24) ) * enddo endif if ( Adw_ver_L ) then do i=i0,in n = n0 + i * rrk= F_z(n) kk = ( rrk - Adw_z00_8 ) * Adw_ovdz_8 kk = Adw_lcz( kk+1 ) rrk = rrk - Adw_bsz_8(kk) if ( rrk .lt. 0.0 ) kk = kk - 1 * capz = rrk * Adw_diz_8(kk) if ( rrk .lt. 0.0 ) capz = 1.0 + capz * * We keep F_capz, otherwise we would need rrk * ------------------------------------------- F_capz(n) = capz * ii = and( Fn_I(n) , 4095 ) jj = and( ishft( Fn_I(n) , -12 ) , 4095 ) Fn_I(n) = ior( ior(ishft(jj,12) , ii) , ishft( kk , 24) ) * * Evaluate min-max vertical CFL as function of k * ---------------------------------------------- cfl = (kk+1) - k if (cfl.gt.V4dcfl_p(k) ) V4dcfl_p(k) = cfl if (cfl.lt.V4dcfl_n(k) ) V4dcfl_n(k) = cfl * enddo endif do 80 i=i0,in n = n0 + i * ii = and( Fn_I(n) , 4095 ) jj = and( ishft( Fn_I(n) , -12 ) , 4095 ) kk = ishft(Fn_I(n) , -24) * rri= F_x(n) rrj= F_y(n) * o1 = (kk)*nijag + (jj-Adw_int_j_off-1)*Adw_nit + (ii-Adw_int_i_off) o2 = o1 + Adw_nit * ************************************************************************ * x interpolation ************************************************************************ capx = (rri-Adw_bsx_8(ii)) *Adw_xbc_8(ii) * prf1 = (1.0 - capx) * F_in(o1) + capx * F_in(o1+1) prf2 = (1.0 - capx) * F_in(o2) + capx * F_in(o2+1) * o1 = o1 + nijag o2 = o2 + nijag * prf3 = (1.0 - capx) * F_in(o1) + capx * F_in(o1+1) prf4 = (1.0 - capx) * F_in(o2) + capx * F_in(o2+1) * ************************************************************************ * y interpolation ************************************************************************ capy = (rrj-Adw_bsy_8(jj)) *Adw_ybc_8(jj) * prf1 = (1.0 - capy) * prf1 + capy * prf2 prf2 = (1.0 - capy) * prf3 + capy * prf4 ************************************************************************ * z interpolation ************************************************************************ capz = F_capz(n) * F_out(n) = ( (1.0 - capz) * prf1 + capz * prf2 ) * F_dt * 80 continue 90 continue 100 continue !$omp end parallel do * Adw_hor_L = .false. Adw_ver_L = .false. * return end