!-------------------------------------- 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/r opinv6 - inverse of quasi-tridiagonal general operator * in one direction *subroutine opinv6 ( F_r, F_ni, F_nj, F_nk, 2,4 % F_axis, F_a_8, F_b_8, F_c_8, % F_ai_8, F_bi_8, F_ci_8, F_di_8, % F_prep_L, F_case, NIS, NJS, NKS, SKIP ) * #include "impnone.cdk"
* integer F_ni, F_nj, F_nk, NIS, NJS, NKS, SKIP real F_r(SKIP,NIS,NJS,NKS) real*8 F_a_8(*), F_b_8(*), F_c_8(*) real*8 F_ai_8(*), F_bi_8(*), F_ci_8(*), F_di_8(*) logical F_prep_L character*1 F_case, F_axis * *author * alain patoine - after opinvss (remove possibility of having * distinct input and output) * *revision * v2_00 - Lee V. - initial MPI version (from opinv v1_03) * *object * see above ID * *arguments * Name I/O Description *---------------------------------------------------------------- * F_r O - result in an array * F_ni I - number of points in x-direction * F_nj I - number of points in y-direction * F_nk I - number of levels in z-direction * F_axis I - along the x-, y- or z-axis * F_a_8 I - lower diagonal of inverse operator * F_b_8 I - middle diagonal of inverse operator * F_c_8 I - upper diagonal of inverse operator * F_ai_8 I/O - auxiliary vector for inverse * F_bi_8 I/O - auxiliary vector for inverse * F_ci_8 I/O - auxiliary vector for inverse * F_di_8 I/O - auxiliary vector for inverse * F_prep_L I - .true. to prepare F_ai_8, ..., F_di_8 * F_case I - 'N'eumann, 'D'irichlet or 'P'eriodic boundary condition * NIS I - field dimension in x-direction * NJS I - field dimension in y-direction * NKS I - field dimension in z-direction * SKIP I - distance between elements of F_r * ** * logical plbnd, plper, plalonx, plalony, plalonz integer pnm integer i, j, k * real*8 zero, one parameter( zero = 0.0 ) parameter( one = 1.0 ) * * if ( F_case.eq.'D' ) then plbnd = .true. plper = .false. elseif ( F_case.eq.'N' ) then plbnd = .false. plper = .false. elseif ( F_case.eq.'P' ) then plbnd = .false. plper = .true. endif * plalonx = F_axis.eq.'X' plalony = F_axis.eq.'Y' plalonz = F_axis.eq.'Z' * if ( plalonx ) pnm = F_ni if ( plalony ) pnm = F_nj if ( plalonz ) pnm = F_nk * if ( F_prep_L ) then do i=1,pnm F_ai_8(i) = F_a_8(i) F_bi_8(i) = F_b_8(i) F_ci_8(i) = F_c_8(i) enddo if ( plbnd ) then F_bi_8(1) = one F_ci_8(1) = zero F_ai_8(pnm) = zero F_bi_8(pnm) = one endif call set_trig21
% ( F_ai_8, F_bi_8, F_ci_8, F_di_8, F_ai_8, F_bi_8, F_ci_8, % 1,1, pnm, 1, plper ) endif * if ( plper ) pnm = pnm - 1 * ******************************************************************************* * * * for solving along x direction * * * ******************************************************************************* if ( plalonx ) then do j=F_nj+1,NJS do k=1,F_nk do i=1,NIS F_r(1,i,j,k) = zero enddo enddo enddo * if ( plbnd ) then do k=1,F_nk do j=1,NJS F_r(1,1,j,k) = zero F_r(1,F_ni,j,k) = zero enddo enddo endif * call msoltri6
% ( F_r(1,1,1,1), F_r(1,1,1,1), F_bi_8, F_ci_8, F_ai_8, % SKIP, NIS*SKIP, pnm, NJS*F_nk) * if ( plper ) then do k=1,F_nk do j=1,NJS F_r(1,F_ni,j,k) = F_bi_8(F_ni) * F_r(1,F_ni,j,k) % + F_ci_8(F_ni) * F_r(1,1,j,k) % + F_ai_8(1) * F_r(1,pnm,j,k) enddo enddo do i=1,pnm do k=1,F_nk do j=1,NJS F_r(1,i,j,k) = F_r(1,i,j,k) % + F_di_8(i) * F_r(1,F_ni,j,k) enddo enddo enddo endif * ******************************************************************************* * * * for solving along y direction * * * ******************************************************************************* elseif ( plalony ) then * do 100 k=1,F_nk * do i=F_ni+1,NIS do j=1,F_nj F_r(1,i,j,k) = zero enddo enddo * if ( plbnd ) then do i=1,NIS F_r(1,i,1,k) = zero F_r(1,i,F_nj,k) = zero enddo endif * call msoltri6
% ( F_r(1,1,1,k), F_r(1,1,1,k), F_bi_8, F_ci_8, F_ai_8, % NIS*SKIP, SKIP, pnm, F_ni) * if ( plper ) then do i=1,NIS F_r(1,i,F_nj,k) = F_bi_8(F_nj) * F_r(1,i,F_nj,k) % + F_ci_8(F_nj) * F_r(1,i,1,k) % + F_ai_8(1) * F_r(1,i,pnm,k) enddo do j=1,pnm do i=1,NIS F_r(1,i,j,k) = F_r(1,i,j,k) + F_di_8(j) * F_r(1,i,F_nj,k) enddo enddo endif 100 continue * ******************************************************************************* * * * for solving along z direction * * * ******************************************************************************* elseif ( plalonz ) then * do i=F_ni+1,NIS do k=1,F_nk do j=1,F_nj F_r(1,i,j,k) = zero enddo enddo enddo * if ( plbnd ) then do j=1,F_nj do i=1,NIS F_r(1,i,j,1) = zero F_r(1,i,j,F_nk) = zero enddo enddo endif * call msoltri6
% ( F_r(1,1,1,1), F_r(1,1,1,1), F_bi_8, F_ci_8, F_ai_8, % NIS*NJS*SKIP, SKIP, pnm, NIS*F_nj) * if ( plper ) then do j=1,F_nj do i=1,NIS F_r(1,i,j,F_nk) = F_bi_8(F_nk) * F_r(1,i,j,F_nk) % + F_ci_8(F_nk) * F_r(1,i,j,1) % + F_ai_8(1) * F_r(1,i,j,pnm) enddo enddo do k=1,pnm do j=1,F_nj do i=1,NIS F_r(1,i,j,k) = F_r(1,i,j,k) % + F_di_8(k) * F_r(1,i,j,F_nk) enddo enddo enddo endif endif return end