!-------------------------------------- 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_ad - ADJ of adw_trilin_turbo_tl * #include "model_macros_f.h"*
subroutine adw_trilin_turbo_ad ( F_out, F_in, F_dt, F_x, F_y, F_z, 8 % F_inm, % F_capxm,F_capym,F_capzm, % Fn_I,F_num,i0,in,j0,jn,kn) * implicit none * integer F_num, i0, in, j0, jn, kn, Fn_I(F_num) * real F_dt, F_in(*), F_inm(*) * real F_out (F_num),F_x (F_num),F_y (F_num),F_z (F_num) * real F_capxm(F_num),F_capym(F_num),F_capzm(F_num) * *authors * Monique Tanguay * * (Based on adw_trilin_ad v_3.1.1) * *revision * v3_20 - Tanguay M. - initial version * v3_21 - Tanguay M. - OPENMP based on min-max vertical CFL * *object * see id section * *ADJ of *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_n | positions in the 3D volume of interpolation | i | * | boxes | | * | | | * F_capx | \ | i | * F_capy | precomputed displacements | i | * F_capz | / along the x,y,z directions | i | * | | | * F_num | number of points to interpolate | i | *______________|_________________________________________________|_____| * *implicits #include "glb_ld.cdk"
#include "adw.cdk"
#include "ptopo.cdk"
#include "lun.cdk"
#include "v4dcfl.cdk"
************************************************************************ integer n,nn,n0,nijag,o1,o2,i,j,k,nij,shift * integer ii,jj,kk real*8 rri, rrj, rrk * real capx, capy, capz, capxm, capym, capzm * real*8 prf1_8, prf2_8, prf3_8, prf4_8, prf1_y_8, prf2_y_8 real*8 prf1m_8,prf2m_8,prf3m_8,prf4m_8,prf1m_y_8,prf2m_y_8 * real*8, parameter :: ZERO_8 = 0.0 * logical done_L data done_L /.false./ save done_L integer cflp(Ptopo_numproc),cfln(Ptopo_numproc),iproc,err * * ------------------------------------------------------------------ * if(.not.done_L) then * * Evaluate min-max vertical CFL * ----------------------------- V4dcfl_p0 = V4dcfl_p(1) V4dcfl_n0 = V4dcfl_n(1) do k=2,l_nk if (V4dcfl_p(k).gt.V4dcfl_p0) then V4dcfl_p0 = V4dcfl_p(k) endif if (V4dcfl_n(k).lt.V4dcfl_n0) then V4dcfl_n0 = V4dcfl_n(k) endif enddo * call RPN_COMM_gather (V4dcfl_p0,1,"MPI_INTEGER",cflp,1, $ "MPI_INTEGER",0,"GRID", err) call RPN_COMM_gather (V4dcfl_n0,1,"MPI_INTEGER",cfln,1, $ "MPI_INTEGER",0,"GRID", err) * if (Ptopo_myproc.eq.0) then * V4dcfl_p0 = cflp(1) V4dcfl_n0 = cfln(1) do iproc = 2, Ptopo_numproc if (cflp(iproc).gt.V4dcfl_p0) % V4dcfl_p0 = cflp(iproc) if (cfln(iproc).lt.V4dcfl_n0) % V4dcfl_n0 = cfln(iproc) end do * endif * call RPN_COMM_bcast(V4dcfl_p0,1,"MPI_INTEGER",0,"grid",err ) call RPN_COMM_bcast(V4dcfl_n0,1,"MPI_INTEGER",0,"grid",err ) * * Evaluate admissible distance between threads * -------------------------------------------- V4dcfl_dist = max((kn+Ptopo_npeOpenMP-1)/Ptopo_npeOpenMP, % 2 + V4dcfl_p0 - V4dcfl_n0) * if (Ptopo_myproc.eq.0.and.Lun_out.gt.0) then write(Lun_out,*) 'ADW_TRILIN_AD: max vertical CFL =',V4dcfl_p0 write(Lun_out,*) 'ADW_TRILIN_AD: min vertical CFL =',V4dcfl_n0 write(Lun_out,*) 'ADW_TRILIN_AD: Distance between threads =',V4dcfl_dist endif * done_L = .true. endif * * Initializations * --------------- nij = l_ni*l_nj nijag = Adw_nit * Adw_njt * * Distribute levels respecting admissible distance between threads * ---------------------------------------------------------------- do shift=1,V4dcfl_dist * !$omp parallel do private(n,nn,n0,o1,o2,i,j,k, !$omp& ii,jj,kk,rri,rrj,rrk, !$omp& capx, capy, capz, capxm, capym, capzm, !$omp& prf1_8, prf2_8, prf3_8, prf4_8, !$omp& prf1_y_8,prf2_y_8,prf1m_8, prf2m_8, !$omp& prf3m_8, prf4m_8, prf1m_y_8,prf2m_y_8) !$omp& shared(shift) * do k=shift,kn,V4dcfl_dist * do j=j0,jn * n0 = (k-1)*nij + ((j-1)*l_ni) * do i=i0,in * n = n0 + i * * ------------------ * TRAJECTORY (START) * ------------------ ii = and( Fn_I(n) , 4095 ) jj = and( ishft( Fn_I(n) , -12 ) , 4095 ) kk = ishft(Fn_I(n) , -24) * o1 = (kk)*nijag + (jj-Adw_int_j_off-1)*Adw_nit + (ii-Adw_int_i_off) o2 = o1 + Adw_nit * ************************************************************************ * x interpolation ************************************************************************ capxm = F_capxm(n) * prf1m_8 = (1.0 - capxm) * F_inm(o1) + capxm * F_inm(o1+1) prf2m_8 = (1.0 - capxm) * F_inm(o2) + capxm * F_inm(o2+1) * o1 = o1 + nijag o2 = o2 + nijag * prf3m_8 = (1.0 - capxm) * F_inm(o1) + capxm * F_inm(o1+1) prf4m_8 = (1.0 - capxm) * F_inm(o2) + capxm * F_inm(o2+1) ************************************************************************ * y interpolation ************************************************************************ capym = F_capym(n) * prf1m_y_8= (1.0 - capym) * prf1m_8 + capym * prf2m_8 prf2m_y_8= (1.0 - capym) * prf3m_8 + capym * prf4m_8 * ************************************************************************ * z interpolation ************************************************************************ capzm = F_capzm(n) * * ---------------- * TRAJECTORY (END) * ---------------- * ************************************************************************ * ADJ of * z interpolation ************************************************************************ prf2_y_8 = capzm * F_out(n) * F_dt prf1_y_8 = (1.0-capzm) * F_out(n) * F_dt capz = (prf2m_y_8 - prf1m_y_8) * F_out(n) * F_dt F_out (n) = ZERO_8 * rrk = capz * Adw_diz_8(kk) * ************************************************************************ * ADJ of * y interpolation ************************************************************************ prf4_8 = capym * prf2_y_8 prf3_8 = (1.0-capym) * prf2_y_8 * prf2_8 = capym * prf1_y_8 prf1_8 = (1.0-capym) * prf1_y_8 * capy = (prf4m_8 - prf3m_8) * prf2_y_8 % + (prf2m_8 - prf1m_8) * prf1_y_8 * rrj = capy *Adw_ybc_8(jj) * ************************************************************************ * x interpolation ************************************************************************ F_in(o2+1) = F_in(o2+1) + capxm * prf4_8 F_in(o2 ) = F_in(o2 ) + (1.0-capxm) * prf4_8 * F_in(o1+1) = F_in(o1+1) + capxm * prf3_8 F_in(o1 ) = F_in(o1 ) + (1.0-capxm) * prf3_8 * capx = (F_inm(o2+1) - F_inm(o2)) * prf4_8 % + (F_inm(o1+1) - F_inm(o1)) * prf3_8 * o1 = o1 - nijag o2 = o2 - nijag * F_in(o2+1) = F_in(o2+1) + capxm * prf2_8 F_in(o2 ) = F_in(o2 ) + (1.0-capxm) * prf2_8 * F_in(o1+1) = F_in(o1+1) + capxm * prf1_8 F_in(o1 ) = F_in(o1 ) + (1.0-capxm) * prf1_8 * capx = (F_inm(o2+1) - F_inm(o2)) * prf2_8 % + (F_inm(o1+1) - F_inm(o1)) * prf1_8 + capx * rri = capx *Adw_xbc_8(ii) * F_x(n) = rri + F_x(n) F_y(n) = rrj + F_y(n) F_z(n) = rrk + F_z(n) * enddo enddo enddo !$omp end parallel do * enddo * return end