LCOV - code coverage report
Current view: top level - kap/private - op_osc.f (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 403 0
Test Date: 2025-05-08 18:23:42 Functions: 0.0 % 23 0

            Line data    Source code
       1              : ! ***********************************************************************
       2              : !
       3              : !   Copyright (C) 2013-2019  Haili Hu & The MESA Team
       4              : !
       5              : !   This program is free software: you can redistribute it and/or modify
       6              : !   it under the terms of the GNU Lesser General Public License
       7              : !   as published by the Free Software Foundation,
       8              : !   either version 3 of the License, or (at your option) any later version.
       9              : !
      10              : !   This program is distributed in the hope that it will be useful,
      11              : !   but WITHOUT ANY WARRANTY; without even the implied warranty of
      12              : !   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      13              : !   See the GNU Lesser General Public License for more details.
      14              : !
      15              : !   You should have received a copy of the GNU Lesser General Public License
      16              : !   along with this program. If not, see <https://www.gnu.org/licenses/>.
      17              : !
      18              : ! ***********************************************************************
      19              : 
      20              :       module op_osc
      21              :       use math_lib
      22              :       use op_def
      23              :       use const_def
      24              :       use kap_def, only: kap_test_partials, kap_test_partials_val, kap_test_partials_dval_dx
      25              : 
      26              :       contains
      27              : ! **********************************************************************
      28            0 :       subroutine abund(nel, izz, fa, flmu, nkz)
      29              :       implicit none
      30              :       integer, intent(in) :: nel, izz(ipe)
      31              :       real, intent(in) :: fa(ipe)
      32              :       real, intent(out) :: flmu
      33              :       integer, intent(out) :: nkz(ipe)
      34              :       integer :: k, k1, k2, m
      35            0 :       real :: amamu(ipe), fmu
      36              : 
      37              : ! Get k1,get amamu(k)
      38            0 :       do k = 1, nel
      39            0 :          do m = 1, ipe
      40            0 :             if (izz(k) == kz(m)) then
      41            0 :                amamu(k) = amass(m)
      42            0 :                nkz(k) = m
      43              :                cycle
      44              :             end if
      45            0 :             write(*,*) ' k=',k,', izz(k)=',izz(k)
      46            0 :             write(*,*) ' kz(m) not found'
      47            0 :             stop
      48              :          end do
      49              :       end do
      50              : 
      51              : !  Mean atomic weight = fmu
      52            0 :       fmu = 0.
      53            0 :       do k = 1, nel
      54            0 :          fmu = fmu + fa(k)*amamu(k)
      55              :       end do
      56              : 
      57            0 :       fmu = fmu*1.660531e-24 ! Convert to cgs
      58            0 :       flmu = log10(dble(fmu))
      59              : 
      60            0 :       end subroutine abund
      61              : ! *********************************************************************
      62            0 :       subroutine xindex(flt, ilab, xi, ih, i3, ierr)
      63              :       implicit none
      64              :       integer, intent(in) :: i3
      65              :       real, intent(in) :: flt
      66              :       integer, intent(out) :: ih(0:5), ilab(0:5)
      67              :       real, intent(out) :: xi
      68              :       integer, intent(out) :: ierr
      69              :       integer :: i, ih2
      70            0 :       real :: x
      71              : 
      72            0 :       ierr = 0
      73            0 :       if (flt < 3.5) then
      74            0 :         ierr = 102
      75            0 :         return
      76            0 :       else if (flt > 8.) then
      77            0 :         ierr = 102
      78            0 :         return
      79              :       end if
      80              : 
      81            0 :       x = 40.*flt/real(i3)
      82            0 :       ih2 = x
      83            0 :       ih2 = max(ih2, 140/i3+2)
      84            0 :       ih2 = min(ih2, 320/i3-3)
      85            0 :       do i = 0, 5
      86            0 :          ih(i) = ih2 + i - 2
      87            0 :          ilab(i) = i3*ih(i)
      88              :       end do
      89            0 :       xi = 2.*(x-ih2) - 1
      90              : 
      91              :       end subroutine xindex
      92              : ! *********************************************************************
      93            0 :       subroutine jrange(ih, jhmin, jhmax, i3)
      94              :       implicit none
      95              :       integer, intent(in) :: ih(0:5), i3
      96              :       integer, intent(out) :: jhmin, jhmax
      97              :       integer :: i
      98              : 
      99            0 :       jhmin = 0
     100            0 :       jhmax = 1000
     101            0 :       do i = 0, 5
     102            0 :          jhmin = max(jhmin, js(ih(i)*i3)/i3)
     103            0 :          jhmax = min(jhmax, je(ih(i)*i3)/i3)
     104              :       end do
     105              : 
     106            0 :       end subroutine jrange
     107              : ! *********************************************************************
     108            0 :       subroutine findne(ilab, fa, nel, nkz, jhmin, jhmax, ih, flrho, flt, xi, flne, flmu, flr, epa, uy, i3, ierr)
     109              :       use op_load, only : solve
     110              :       implicit none
     111              :       integer, intent(in) :: ilab(0:5), nel, nkz(ipe), jhmin, ih(0:5), i3
     112              :       integer, intent(inout) :: jhmax
     113              :       integer, intent(out) :: ierr
     114              :       real, intent(in) :: fa(ipe), flt, xi, flmu
     115              :       real,intent(out) :: flne, uy, epa
     116              :       real, intent(inout) :: flrho
     117              :       integer :: i, j, n, jh, jm, itt, jne, jnn
     118            0 :       real :: flrmin, flrmax, flr(4,4), uyi(4), efa(0:5, 7:118), flrh(0:5, 7:118), u(4), flnei(4), y, zeta, efa_temp
     119              : ! declare variables in common block, by default: real (a-h, o-z), integer (i-n)
     120              : !       integer :: ite1, ite2, ite3, jn1, jn2, jne3, ntot, nc, nf, int, ne1, ne2, np, kp1, kp2, kp3, npp, mx, nx
     121              : !       real :: umin, umax, epatom, oplnck, fion, yy1, yy2, yx
     122              : !       common /atomdata/ ite1,ite2,ite3,jn1(91),jn2(91),jne3,umin,umax,ntot, &
     123              : !        nc,nf,int(17),epatom(17,91,25),oplnck(17,91,25),ne1(17,91,25), &
     124              : !        ne2(17,91,25),fion(-1:28,28,91,25),np(17,91,25),kp1(17,91,25), &
     125              : !        kp2(17,91,25),kp3(17,91,25),npp(17,91,25),mx(33417000), &
     126              : !        yy1(33417000),yy2(120000000),nx(19305000),yx(19305000)
     127              : !       save /atomdata/
     128              : !
     129              : !  efa(i,jh)=sum_n epa(i,jh,n)*fa(n)
     130              : !  flrh(i,jh)=log10(rho(i,jh))
     131              : !
     132              : !  Get efa
     133            0 :       do i = 0, 5
     134            0 :          itt = (ilab(i)-ite1)/2 + 1
     135            0 :          do jne = jn1(itt), jn2(itt), i3
     136            0 :             jnn = (jne-jn1(itt))/2 + 1
     137            0 :             jh = jne/i3
     138            0 :             efa_temp = 0.
     139            0 :             do n = 1, nel
     140            0 :                efa_temp = efa_temp + epatom(nkz(n), itt, jnn)*fa(n)
     141              :             end do !n
     142            0 :             efa(i, jh) = efa_temp
     143              :          end do !jne
     144              :       end do !i
     145              : 
     146              : ! Get range for efa > 0
     147            0 :       do i = 0, 5
     148            0 :          do jh = jhmin, jhmax
     149            0 :             if (efa(i, jh) <= 0.) then
     150            0 :                jm = jh - 1
     151            0 :                jhmax = min(jhmax, jm)
     152            0 :                cycle
     153              :             end if
     154              :          end do
     155              :       end do
     156              : 
     157              : ! Get flrh
     158            0 :       do jh = jhmin,jhmax
     159            0 :         do i = 0,5
     160            0 :          flrh(i, jh) = flmu + 0.25*i3*jh - log10(dble(efa(i,jh)))
     161              :         end do
     162              :       end do
     163              : 
     164              : !  Find flrmin and flrmax
     165            0 :       flrmin = -1000
     166            0 :       flrmax = 1000
     167            0 :       do i = 0, 5
     168            0 :          flrmin = max(flrmin, flrh(i,jhmin))
     169            0 :          flrmax = min(flrmax, flrh(i,jhmax))
     170              :       end do
     171              : 
     172              : !  Check range of flrho
     173            0 :       if (flrho < flrmin .or. flrho > flrmax) then
     174            0 :          ierr = 101
     175            0 :          return
     176              :       end if
     177              : 
     178              : !  Interpolations in j for flne
     179            0 :       do jh = jhmin, jhmax
     180            0 :          if (flrh(2,jh) > flrho) then
     181            0 :             jm = jh - 1
     182              :             cycle
     183              :          end if
     184            0 :          write(*,*) ' Interpolations in j for flne'
     185            0 :          write(*,*) ' Not found, i=',i
     186            0 :          stop
     187              :       end do
     188            0 :       jm=max(jm,jhmin+1)
     189            0 :       jm=min(jm,jhmax-2)
     190              : 
     191            0 :       do i = 1, 4
     192            0 :          do j = 1, 4
     193            0 :             u(j) = flrh(i, jm+j-2)
     194            0 :             flr(i,j) = flrh(i, jm+j-2)
     195              :          end do
     196            0 :          call solve(u, flrho, zeta, uyi(i), ierr)
     197            0 :          if (ierr /= 0) return
     198            0 :          y = jm + 0.5*(zeta+1)
     199            0 :          flnei(i) = .25*i3*y
     200              :       end do
     201              : 
     202              : !  Interpolations in i
     203            0 :       flne = fint(flnei, xi)
     204            0 :       uy = fint(uyi, xi)
     205              : ! Get epa
     206            0 :       epa = exp10(dble(flne + flmu - flrho))
     207              : 
     208            0 :       return
     209              : 
     210              : !  601 format(' For flt=',1p,e11.3,', flrho=',e11.3,' is out of range. Allowed range for flrho is ',e11.3,' to ',e11.3)
     211            0 :       end subroutine findne
     212              : 
     213              : ! **********************************************************************
     214            0 :       subroutine yindex(jhmin, jhmax, flne, jh, i3, eta)
     215              :       implicit none
     216              :       integer, intent(in) :: jhmin, jhmax, i3
     217              :       real, intent(in) :: flne
     218              :       integer, intent(out) :: jh(0:5)
     219              :       real, intent(out) :: eta
     220              :       integer :: j, k
     221            0 :       real :: y
     222              : 
     223            0 :       y = 4.*flne/real(i3)
     224            0 :       j = y
     225            0 :       j = max(j,jhmin+2)
     226            0 :       j = min(j,jhmax-3)
     227            0 :       do k = 0, 5
     228            0 :          jh(k) = j + k - 2
     229              :       end do
     230            0 :       eta = 2.*(y-j)-1
     231              : 
     232            0 :       end subroutine yindex
     233              : ! **********************************************************************
     234            0 :       subroutine findux(flr, xi, eta, ux)
     235              :       implicit none
     236              :       real, intent(in) :: flr(4, 4), xi, eta
     237              :       real, intent(out) :: ux
     238              :       integer :: i, j
     239            0 :       real :: uxj(4), u(4)
     240              : 
     241            0 :       do j = 1, 4
     242            0 :          do i = 1, 4
     243            0 :             u(i) = flr(i, j)
     244              :          end do
     245            0 :          uxj(j) = fintp(u, xi)
     246              :       end do
     247            0 :       ux = fint(uxj, eta)
     248              : 
     249            0 :       end subroutine findux
     250              : ! *********************************************************************
     251            0 :       subroutine rd(nel, nkz, izz, ilab, jh, n_tot, ff, rr, i3, umesh, fac)
     252              :       implicit none
     253              :       integer, intent(in) :: nel,nkz(ipe),izz(ipe),ilab(0:5),jh(0:5),n_tot,i3
     254              :       real, intent(in) :: umesh(nptot)
     255              :       real(dp), intent(in) :: fac(nel)
     256              :       real, intent(out) :: ff(:,:,0:,0:)  ! (nptot, ipe, 6, 6)
     257              :       real, intent(out) :: rr(28, ipe, 0:5, 0:5)
     258              :       integer :: i, j, k, l, m, n, itt, jnn, izp, ne1, ne2, ne, ib, ia
     259            0 :       real :: fion(-1:28), yb, ya, d
     260              : ! declare variables in common block (instead of by default: real (a-h, o-z), integer (i-n))
     261              : !       integer :: ite1, ite2, ite3, jn1, jn2, jne3, ntot, nc, nf, int, ne1p, ne2p, np, kp1, kp2, kp3, npp, mx, nx
     262              : !       real :: umin, umax, epatom, oplnck, fionp, yy1, yy2, yx
     263              : !       common /atomdata/ ite1,ite2,ite3,jn1(91),jn2(91),jne3,umin,umax,ntot, &
     264              : !        nc,nf,int(17),epatom(17,91,25),oplnck(17,91,25),ne1p(17,91,25), &
     265              : !        ne2p(17,91,25),fionp(-1:28,28,91,25),np(17,91,25),kp1(17,91,25), &
     266              : !        kp2(17,91,25),kp3(17,91,25),npp(17,91,25),mx(33417000), &
     267              : !        yy1(33417000),yy2(120000000),nx(19305000),yx(19305000)
     268              : !       save /atomdata/
     269              : !
     270              : !  i=temperature index
     271              : !  j=density index
     272              : !  k=frequency index
     273              : !  n=element index
     274              : !  Get:
     275              : !    mono opacity cross-section ff(k,n,i,j)
     276              : !    modified cross-section for selected element, ta(k,i,j)
     277              : !
     278              : !     Initialisations
     279            0 :       rr=0.
     280            0 :       ff=0.
     281              : 
     282              : !  Start loop on i (temperature index)
     283            0 :       do i = 0, 5
     284            0 :          itt = (ilab(i) - ite1)/2 + 1
     285            0 :          do j = 0, 5
     286            0 :             jnn = (jh(j)*i3 - jn1(itt))/2 + 1
     287              : !        Read mono opacities
     288            0 :             do n = 1, nel
     289            0 :                izp = izz(n)
     290            0 :                ne1 = ne1p(nkz(n), itt, jnn)
     291            0 :                ne2 = ne2p(nkz(n), itt, jnn)
     292            0 :                do ne = ne1, ne2
     293            0 :                   fion(ne) = fionp(ne, nkz(n), itt, jnn)
     294              :                end do
     295            0 :                do ne = ne1, min(ne2, izp-2)
     296            0 :                   rr(izp-1-ne, n, i, j) = fion(ne)
     297              :                end do
     298              : 
     299            0 :                do k = 1, n_tot
     300            0 :                   ff(k, n, i, j) = yy2(k+kp2(nkz(n), itt, jnn))
     301              :                end do
     302              : 
     303            0 :                if (fac(n) /= 1d0) then
     304            0 :                   do k = 1, size(ff,dim=1)
     305            0 :                      ff(k,n,i,j) = fac(n)*ff(k,n,i,j)
     306              :                   end do
     307              :                end if
     308              :             end do !n
     309              :          end do !j
     310              :       end do !i
     311              : 
     312            0 :       return
     313              : 
     314              :       end subroutine rd
     315              : ! **********************************************************************
     316            0 :       subroutine ross(flmu, dv, ntot,rs, rossl)
     317              :       implicit none
     318              :       integer, intent(in) :: ntot
     319              :       real, intent(in) :: flmu, dv, rs(nptot, 0:5, 0:5)
     320              :       real, intent(out) :: rossl(0:5, 0:5)
     321              :       integer :: i, j, n
     322            0 :       real(dp) :: drs, dd, oross
     323              :       real :: fmu, tt
     324              : 
     325              : !  oross=cross-section in a.u.
     326              : !  rossl=log10(ROSS in cgs)
     327            0 :       do i = 0, 5
     328            0 :          do j = 0, 5
     329            0 :             drs = 0.d0
     330            0 :             do n = 1, ntot
     331            0 :                dd = 1.d0/rs(n, i, j)
     332            0 :                drs = drs + dd
     333              :             end do
     334            0 :             oross = 1.d0/(drs*dv)
     335            0 :             rossl(i, j) = log10(oross) - 16.55280d0 - flmu !log10(fmu)
     336              :          end do !j
     337              :       end do !i
     338              : 
     339            0 :       end subroutine ross
     340              : ! **********************************************************************
     341            0 :       subroutine mix(ntot, nel, fa, ff, rs, rr, rion)
     342              :       implicit none
     343              :       integer, intent(in) :: ntot, nel
     344              :       real, intent(in) :: ff(nptot, ipe, 0:5, 0:5), fa(ipe), rr(28, 17, 0:5, 0:5)
     345              :       real, intent(out) :: rs(nptot, 0:5, 0:5), rion(28, 0:5, 0:5)
     346              :       integer :: i, j, k, n, m
     347              :       real :: rs_temp, rion_temp
     348              : 
     349            0 :       do i = 0, 5
     350            0 :          do j = 0, 5
     351            0 :             do n = 1, ntot
     352              :                !rs_temp = ff(n,1,i,j)*fa(1)
     353              :                !do k = 2, nel
     354              :                !   rs_temp = rs_temp + ff(n,k,i,j)*fa(k)
     355              :                !end do
     356              :                !rs(n,i,j) = rs_temp
     357            0 :                rs(n, i, j) = dot_product(ff(n,1:nel,i,j),fa(1:nel))
     358              :             end do
     359            0 :             do m = 1, 28
     360              :                !rion_temp = rr(m, 1, i, j)*fa(1)
     361              :                !do k = 2, nel
     362              :                !   rion_temp = rion_temp + rr(m,k,i,j)*fa(k)
     363              :                !end do
     364              :                !rion(m,i,j) = rion_temp
     365            0 :                rion(m,i,j) = dot_product(rr(m,1:nel,i,j),fa(1:nel))
     366              :             end do
     367              :          end do
     368              :       end do
     369              : 
     370            0 :       end subroutine mix
     371              : ! **********************************************************************
     372            0 :       subroutine interp(nel, rossl, xi, eta, g, i3, ux, uy, gx, gy)
     373              :       implicit none
     374              :       integer, intent(in) :: nel, i3
     375              :       real, intent(in) :: ux, uy, xi, eta
     376              :       real, intent(out) :: gx, gy, g
     377              :       integer :: i, j, l
     378              :       real :: V(4), U(4),  vyi(4)
     379            0 :       real :: x3(3), fx3!, fxxy(0:5, 0:5), fyxy(0:5, 0:5)
     380              : ! pointers and targets
     381            0 :       real, target :: fx(0:5, 0:5), fy(0:5, 0:5), fxy(0:5, 0:5), fyx(0:5, 0:5), fxx(0:5, 0:5), fyy(0:5, 0:5), rossl(0:5, 0:5)
     382            0 :       real, pointer :: f3(:), fin(:, :), finx(:, :), finy(:, :)
     383              : !
     384              : !     interpolation of g (=rosseland mean opacity)
     385              : ! Use refined techniques of bi-cubic spline interpolation (Seaton 1993):
     386              : !      call deriv(rossl, fx, fy, fxy)
     387              : !      call interp2(rossl, fx, fy, fxy, xi, eta, g, gx, gy)
     388              : !      gy = 0.5*gy/uy
     389              : !      gx = (80./real(i3))*(0.5*gx-gy*ux)
     390              : ! Alternatively, use interpolation techniques by M.-A. Dupret to ensure smooothness required
     391              : ! for pulsation studies:
     392            0 :       do i = 0, 3
     393            0 :          x3(1) = i
     394            0 :          x3(2) = i+1
     395            0 :          x3(3) = i+2
     396            0 :          do j = 1, 4
     397            0 :             f3 => rossl(i:i+2, j)
     398            0 :             call deriv3(f3, x3, fx3)
     399            0 :             fx(i+1, j) = fx3
     400              :          end do
     401              :       end do
     402            0 :       do i = 0, 3
     403            0 :          x3(1) = i
     404            0 :          x3(2) = i+1
     405            0 :          x3(3) = i+2
     406            0 :          do j = 1, 4
     407            0 :             f3 => rossl(j, i:i+2)
     408            0 :             call deriv3(f3, x3, fx3)
     409            0 :             fy(j, i+1) = fx3
     410              :          end do
     411              :       end do
     412            0 :       do i = 1, 2
     413            0 :          x3(1) = i
     414            0 :          x3(2) = i+1
     415            0 :          x3(3) = i+2
     416            0 :          do j = 2, 3
     417            0 :             f3 => fx(i:i+2, j)
     418            0 :             call deriv3(f3, x3, fx3)
     419            0 :             fxx(i+1, j) = fx3
     420              :          end do
     421              :       end do
     422            0 :       do i = 1, 2
     423            0 :          x3(1) = i
     424            0 :          x3(2) = i+1
     425            0 :          x3(3) = i+2
     426            0 :          do j = 2, 3
     427            0 :             f3 => fx(j, i:i+2)
     428            0 :             call deriv3(f3, x3, fx3)
     429            0 :             fxy(j, i+1) = fx3
     430              :          end do
     431              :       end do
     432            0 :        do i = 1, 2
     433            0 :          x3(1) = i
     434            0 :          x3(2) = i+1
     435            0 :          x3(3) = i+2
     436            0 :          do j = 2, 3
     437            0 :             f3 => fy(i:i+2, j)
     438            0 :             call deriv3(f3, x3, fx3)
     439            0 :             fyx(i+1, j) = fx3
     440              :          end do
     441              :       end do
     442            0 :       do i = 1, 2
     443            0 :          x3(1) = i
     444            0 :          x3(2) = i+1
     445            0 :          x3(3) = i+2
     446            0 :          do j = 2, 3
     447            0 :             f3 => fy(j, i:i+2)
     448            0 :             call deriv3(f3, x3, fx3)
     449            0 :             fyy(j, i+1) = fx3
     450              :          end do
     451              :       end do
     452              : !      call deriv(rossl, fx, fy, fxy)
     453              : !      call deriv(fx, fxx, fxy, fxxy)
     454              : !      call deriv(fy, fyx, fyy, fyxy)
     455            0 :       fin => rossl(2:3, 2:3)
     456            0 :       finx => fx(2:3, 2:3)
     457            0 :       finy => fy(2:3, 2:3)
     458            0 :       call interp3(fin, finx, finy, xi, eta, g)
     459            0 :       fin => fx(2:3, 2:3)
     460            0 :       finx => fxx(2:3, 2:3)
     461            0 :       finy => fxy(2:3, 2:3)
     462            0 :       call interp3(fin, finx, finy, xi, eta, gx)
     463            0 :       fin => fy(2:3, 2:3)
     464            0 :       finx => fyx(2:3, 2:3)
     465            0 :       finy => fyy(2:3, 2:3)
     466            0 :       call interp3(fin, finx, finy, xi, eta, gy)
     467            0 :       gy = 0.5*gy/uy
     468            0 :       gx = (80./real(i3))*(0.5*gx-gy*ux)
     469              : 
     470            0 :       end subroutine interp
     471              : ! *************************************
     472            0 :       function fint(u,r)
     473              :       dimension u(4)
     474              : 
     475              : !  If  P(R) =   u(1)  u(2)  u(3)  u(4)
     476              : !  for   R  =    -3    -1     1     3
     477              : !  then a cubic fit is:
     478              :       P(R)=(
     479              :      &  27*(u(3)+u(2))-3*(u(1)+u(4)) +R*(
     480              :      &  27*(u(3)-u(2))-(u(4)-u(1))   +R*(
     481              :      &  -3*(u(2)+u(3))+3*(u(4)+u(1)) +R*(
     482              :      &  -3*(u(3)-u(2))+(u(4)-u(1)) ))))/48.
     483              : 
     484            0 :         fint=p(r)
     485              : 
     486            0 :       end function fint
     487              : ! **********************************************************************
     488            0 :       function fintp(u,r)
     489              :       dimension u(4)
     490              : 
     491              : !  If  P(R) =   u(1)  u(2)  u(3)  u(4)
     492              : !  for   R  =    -3    -1     1     3
     493              : !  then a cubic fit to the derivative is:
     494              :       PP(R)=(
     495              :      &  27*(u(3)-u(2))-(u(4)-u(1))   +2.*R*(
     496              :      &  -3*(u(2)+u(3))+3*(u(4)+u(1)) +3.*R*(
     497              :      &  -3*(u(3)-u(2))+(u(4)-u(1)) )))/48.
     498              : 
     499            0 :         fintp=pp(r)
     500              : 
     501            0 :       end function fintp
     502              : 
     503              : ! **********************************************************************
     504            0 :       subroutine DERIV(f, fx, fy, fxy)
     505              : 
     506              :       real, intent(in) :: f(0:5, 0:5)
     507              :       real, intent(out) :: fx(0:5, 0:5), fy(0:5, 0:5), fxy(0:5, 0:5)
     508            0 :       real :: C(6)
     509              : 
     510              : !  GET FX
     511            0 :       do J = 0, 5
     512            0 :          L=0
     513            0 :          do I = 0, 5
     514            0 :             L=L+1
     515            0 :             C(L)=F(I,J)
     516              :       end do
     517            0 :          call GET(C,L)
     518            0 :          L=0
     519            0 :          do I = 0, 5
     520            0 :             L = L + 1
     521            0 :             FX(I, J) = C(L)
     522              :          end do
     523              :       end do
     524              : 
     525              : !  GET FY
     526            0 :       do I = 0, 5
     527            0 :          L=0
     528            0 :          do J = 0, 5
     529            0 :             L = L + 1
     530            0 :             C(L) = F(I, J)
     531              :          end do
     532            0 :          call GET(C,L)
     533            0 :          L=0
     534            0 :          do J = 0, 5
     535            0 :             L = L + 1
     536            0 :             FY(I,J) = C(L)
     537              :          end do
     538              :       end do
     539              : 
     540              : !  GET FXY
     541            0 :       do I = 0, 5
     542            0 :          L = 0
     543            0 :          do J = 0, 5
     544            0 :             L = L + 1
     545            0 :             C(L) = FX(I, J)
     546              :          end do
     547            0 :          call GET(C,L)
     548            0 :          L=0
     549            0 :          do J = 0, 5
     550            0 :             L = L + 1
     551            0 :             FXY(I,J) = C(L)
     552              :          end do
     553              :       end do
     554              : 
     555            0 :       end subroutine DERIV
     556              : ! *****************************************************************
     557              : !
     558            0 :       subroutine GET(F,N)
     559              : !
     560              : !  SIMPLIFIED CODE FOR SPLINE COEFFICIENTS, FOR CASE OF INTERVALS
     561              : !  OF UNITY.
     562              : !  returnS DERIVATIVES OF ORIGINAL F IN LOCATION F
     563              : !
     564              : !  REVISED 5.5.95
     565              : !
     566              :       parameter (IPI=6)
     567            0 :       DIMENSION F(IPI),D(IPI),T(IPI)
     568              : 
     569            0 :       if (N <= 0) then
     570            0 :          WRITE(6,*)' Error in subroutine GET: N=',N
     571            0 :          STOP
     572            0 :       else if (N == 1) then
     573            0 :          F(1)=0.
     574            0 :          return
     575            0 :       else if (N == 2) then
     576            0 :          F(1)=F(2)-F(1)
     577            0 :          F(2)=F(1)
     578            0 :          return
     579            0 :       else if (N == 3) then
     580            0 :          FP1=.5*(-3.*F(1)+4.*F(2)-F(3))
     581            0 :          FPN=.5*(F(1)-4.*F(2)+3.*F(3))
     582              :       else
     583            0 :          FP1=(-11.*F(1)+18.*F(2)-9.*F(3)+2.*F(4))/6.
     584            0 :          FPN=(11.*F(N)-18.*F(N-1)+9.*F(N-2)-2.*F(N-3))/6.
     585              :       end if
     586              : 
     587            0 :       D(1)=-.5
     588            0 :       T(1)=.5*(-F(1)+F(2)-FP1)
     589              : 
     590            0 :       do J=2,N-1
     591            0 :          D(J)=-1./(4.+D(J-1))
     592            0 :          T(J)=-D(J)*(F(J-1)-2.*F(J)+F(J+1)-T(J-1))
     593              :       end do
     594              : 
     595            0 :       D(N)=(FPN+F(N-1)-F(N)-T(N-1))/(2.+D(N-1))
     596              : 
     597            0 :       do J=N-1,1,-1
     598            0 :          D(J)=D(J)*D(J+1)+T(J)
     599              :       end do
     600              : 
     601            0 :       do J=2,N-1
     602            0 :          F(J)=-F(J)+F(J+1)-2.*D(J)-D(J+1)
     603              :       end do
     604            0 :       F(1)=FP1
     605            0 :       F(N)=FPN
     606              : 
     607              :       end subroutine GET
     608              : 
     609              : ! **********************************************************************
     610            0 :       subroutine INTERP2(f, fx, fy, fxy, xi, eta, g, gx, gy)
     611              :       real, intent(in) :: eta, xi, f(0:5, 0:5), fx(0:5, 0:5), fy(0:5, 0:5), fxy(0:5, 0:5)
     612              :       real, intent(out) :: g, gx, gy
     613              :       integer :: i , j
     614            0 :       real :: x, y, B(16)
     615              : !
     616              : !  function DEFINITIONS FOR CUBIC EXPANSION
     617              : !
     618            0 :       FF(S,T)=    B( 1)+T*(B( 2)+T*(B( 3)+T*B( 4)))
     619              :      &   +S*(     B( 5)+T*(B( 6)+T*(B( 7)+T*B( 8)))
     620              :      &   +S*(     B( 9)+T*(B(10)+T*(B(11)+T*B(12)))
     621              :      &   +S*(     B(13)+T*(B(14)+T*(B(15)+T*B(16))) )))
     622              : 
     623              :       FFX(S,T)=   B( 5)+T*(B( 6)+T*(B( 7)+T*B( 8)))
     624              :      &   +S*(  2*(B( 9)+T*(B(10)+T*(B(11)+T*B(12))))
     625              :      &   +S*(  3*(B(13)+T*(B(14)+T*(B(15)+T*B(16)))) ))
     626              : 
     627              :       FFY(S,T)=   B( 2)+S*(B( 6)+S*(B(10)+S*B(14)))
     628              :      &   +T*(  2*(B( 3)+S*(B( 7)+S*(B(11)+S*B(15))))
     629              :      &   +T*(  3*(B( 4)+S*(B( 8)+S*(B(12)+S*B(16)))) ))
     630              : 
     631            0 :       Y = (eta + 5.)/2.
     632            0 :       X = (xi + 5.)/2.
     633              : !      i = floor(x)
     634              : !      j = floor(y)
     635            0 :       I = X + 1.E-5
     636            0 :       if (ABS(X-I) <= 1.E-5) X = I
     637            0 :       J = Y + 1.E-5
     638            0 :       if (ABS(Y-J) <= 1.E-5) Y = J
     639              : !
     640              : !     INTERPOLATE
     641              : !
     642              : !  GIVEN FUNCTIONS AND DERIVATIVES AT GRID POINTS, COMPUTE COEFFICIENTS.
     643            0 :       B(1)=F(I,J)
     644            0 :       B(2)=FY(I,J)
     645            0 :       B(3)=3*(-F(I,J)+F(I,J+1))-2*FY(I,J)-FY(I,J+1)
     646            0 :       B(4)=2*(F(I,J)-F(I,J+1))+FY(I,J)+FY(I,J+1)
     647              : 
     648            0 :       B(5)=FX(I,J)
     649            0 :       B(6)=FXY(I,J)
     650            0 :       B(7)=3*(-FX(I,J)+FX(I,J+1))-2*FXY(I,J)-FXY(I,J+1)
     651            0 :       B(8)=2*(FX(I,J)-FX(I,J+1))+FXY(I,J)+FXY(I,J+1)
     652              : 
     653            0 :       B(9)=3*(-F(I,J)+F(I+1,J))-2*FX(I,J)-FX(I+1,J)
     654            0 :       B(10)=3*(-FY(I,J)+FY(I+1,J))-2*FXY(I,J)-FXY(I+1,J)
     655              :       B(11)=9*(F(I,J)-F(I+1,J)+F(I+1,J+1)-F(I,J+1))
     656              :      & +6*(FX(I,J)-FX(I,J+1)+FY(I,J)-FY(I+1,J))
     657              :      & +4*FXY(I,J)
     658              :      & +3*(FX(I+1,J)-FX(I+1,J+1)-FY(I+1,J+1)+FY(I,J+1))
     659              :      & +2*(FXY(I,J+1)+FXY(I+1,J))
     660            0 :      & +FXY(I+1,J+1)
     661              :       B(12)=6*(-F(I,J)+F(I+1,J)-F(I+1,J+1)+F(I,J+1))
     662              :      & +4*(-FX(I,J)+FX(I,J+1))
     663              :      & +3*(-FY(I,J)+FY(I+1,J)+FY(I+1,J+1)-FY(I,J+1))
     664              :      & +2*(-FX(I+1,J)+FX(I+1,J+1)-FXY(I,J)-FXY(I,J+1))
     665            0 :      & -FXY(I+1,J)-FXY(I+1,J+1)
     666              : 
     667            0 :       B(13)=2*(F(I,J)-F(I+1,J))+FX(I,J)+FX(I+1,J)
     668            0 :       B(14)=2*(FY(I,J)-FY(I+1,J))+FXY(I,J)+FXY(I+1,J)
     669              :       B(15)=6*(-F(I,J)+F(I+1,J)-F(I+1,J+1)+F(I,J+1))
     670              :      & +4*(-FY(I,J)+FY(I+1,J))
     671              :      & +3*(-FX(I,J)-FX(I+1,J)+FX(I+1,J+1)+FX(I,J+1))
     672              :      & +2*(FY(I+1,J+1)-FY(I,J+1)-FXY(I,J)-FXY(I+1,J))
     673            0 :      & -FXY(I+1,J+1)-FXY(I,J+1)
     674              :       B(16)=4*(F(I,J)-F(I+1,J)+F(I+1,J+1)-F(I,J+1))
     675              :      & +2*(FX(I,J)+FX(I+1,J)-FX(I+1,J+1)-FX(I,J+1)
     676              :      &    +FY(I,J)-FY(I+1,J)-FY(I+1,J+1)+FY(I,J+1))
     677            0 :      & +FXY(I,J)+FXY(I+1,J)+FXY(I+1,J+1)+FXY(I,J+1)
     678              : !
     679              : !  GET G=LOG10(ROSS), DGDT=d LOG10(ROSS)/d LOG10(T),
     680              : !      DGDRHO=d LOG10(ROSS)/d LOG10(RHO)
     681            0 :       U = X - I
     682            0 :       V = Y - J
     683            0 :       G = FF(U, V)
     684            0 :       gx = FFX(U, V)
     685            0 :       gy = FFY(U, V)
     686              : !      DGDT=(1./CT)*FFX(U,V)-(3./CN)*FFY(U,V)
     687              : !      DGDRHO=(1./CN)*FFY(U,V)
     688              : 
     689            0 :       end subroutine INTERP2
     690              : ! ************************************************************
     691              : ! This subroutine estimates the partial derivative of a function
     692              : ! as described in the PhD thesis by M.-A. Dupret.
     693            0 :       subroutine deriv3(f, x, fx)
     694              :       real, intent(in) :: f(3), x(3)
     695              :       real, intent(out) :: fx
     696            0 :       real :: a, a1, a2, b, x1, x2
     697              : 
     698            0 :       x1 = (f(3)- f(2))/(x(3)-x(2))
     699            0 :       x2 = (f(2)-f(1))/(x(2)-x(1))
     700            0 :       b = abs(x1/x2)
     701            0 :       a = (2.*x(2) - x(1) - x(3))/((x(2)-x(1))*(x(2)-x(3)))
     702            0 :       a1 = (x(2)-x(3))/((x(1)-x(3))*(x(1)-x(2)))
     703            0 :       a2 = (x(2)-x(1))/((x(3)-x(2))*(x(3)-x(1)))
     704            0 :       if (b >= 0.2 .and. b <= 5.) then
     705            0 :          fx = a*f(2) + a1*f(1) + a2*f(3)
     706              :       else
     707            0 :          if (abs(x1)<abs(x2)) fx = sign(1.0,x1)*min(abs(x1), abs(x2))
     708            0 :          if (abs(x2)<abs(x1)) fx = sign(1.0,x2)*min(abs(x1), abs(x2))
     709              :       end if
     710              : 
     711            0 :       end subroutine deriv3
     712              : ! **********************************************************************
     713            0 :       subroutine interp3(f, fx, fy, xi, eta, g)
     714              :       real, intent(in) :: eta, xi, f(2:3, 2:3), fx(2:3, 2:3), fy(2:3, 2:3)
     715              :       real, intent(out) :: g
     716              :       real :: x, y
     717              : 
     718            0 :       x = (xi + 5.)/2.
     719            0 :       y = (eta + 5.)/2.
     720              : 
     721            0 :       P11 = P1(x,2.,3.)*P1(y,2.,3.)
     722            0 :       P21 = P2(x,2.,3.)*P1(y,2.,3.)
     723            0 :       P12 = P1(x,2.,3.)*P2(y,2.,3.)
     724            0 :       P22 = P2(x,2.,3.)*P2(y,2.,3.)
     725            0 :       Px11 = Px1(x,2.,3.)*P1(y,2.,3.)
     726            0 :       Px21 = Px2(x,2.,3.)*P1(y,2.,3.)
     727            0 :       Px12 = Px1(x,2.,3.)*P2(y,2.,3.)
     728            0 :       Px22 = Px2(x,2.,3.)*P2(y,2.,3.)
     729            0 :       Py11 = P1(x,2.,3.)*Px1(y,2.,3.)
     730            0 :       Py21 = P2(x,2.,3.)*Px1(y,2.,3.)
     731            0 :       Py12 = P1(x,2.,3.)*Px2(y,2.,3.)
     732            0 :       Py22 = P2(x,2.,3.)*Px2(y,2.,3.)
     733              : 
     734              :       g = f(2,2)*P11 + f(3,2)*P21 + f(2,3)*P12 + f(3,3)*P22
     735              :      &    + fx(2,2)*Px11 + fx(3,2)*Px21 + fx(2,3)*Px12 + fx(3,3)*Px22
     736            0 :      &    + fy(2,2)*Py11 + fy(3,2)*Py21 + fy(2,3)*Py12 + fy(3,3)*Py22
     737              : 
     738            0 :       end subroutine interp3
     739              : ! **********************************************************************
     740            0 :       function P1(x, xi, xj)
     741              : 
     742            0 :          P1 = (x - xj)*(x - xj) * (2*x - 3*xi + xj)/((xj - xi)*(xj - xi)*(xj - xi))
     743              : 
     744            0 :       end function P1
     745              : ! **********************************************************************
     746            0 :       function P2(x, xi, xj)
     747              :       real, intent(in) :: x, xi, xj
     748              : 
     749            0 :          P2 = -(x - xi)*(x - xi) * (2*x - 3*xj + xi)/((xj - xi)*(xj - xi)*(xj - xi))
     750              : 
     751            0 :       end function P2
     752              : ! **********************************************************************
     753            0 :       function Px1(x, xi, xj)
     754              : 
     755            0 :          Px1 = (x - xi) * (x - xj)*(x - xj)/((xj - xi)*(xj - xi))
     756              : 
     757            0 :       end function Px1
     758              : ! **********************************************************************
     759            0 :       function Px2(x, xi, xj)
     760              : 
     761            0 :          Px2 = (x - xi)*(x - xi) * (x - xj)/((xj - xi)*(xj - xi))
     762              : 
     763            0 :       end function Px2
     764              : ! **********************************************************************
     765            0 :       subroutine scatt(ih, jh, rion, uf, f, umesh, semesh, dscat, ntot, epa, ierr)
     766              :       use op_load, only: BRCKR
     767              :       integer, intent(inout) :: ierr
     768              :       dimension rion(28, 0:5, 0:5),uf(0:100),f(nptot,0:5,0:5),umesh(nptot),
     769            0 :      &  semesh(nptot),fscat(0:100),p(nptot),rr(28),ih(0:5),jh(0:5)
     770              :       integer::  i,j,k,n
     771              : ! HH: always use meshtype q='m'
     772            0 :       ite3=2
     773            0 :       umin=umesh(1)
     774            0 :       CSCAT=EPA*2.37567E-8
     775            0 :       ierr = 0
     776              : 
     777            0 :       do i = 0, 5
     778            0 :          ft = exp10(ITE3*dble(ih(i))/40d0)
     779            0 :          do j = 0, 5
     780            0 :             fne = exp10(ITE3*dble(jh(j))/4d0)
     781            0 :             do k = 1, ntot
     782            0 :                p(k) = f(k, i, j)
     783              :             end do
     784            0 :             do m = 1, 28
     785            0 :               rr(m) = rion(m, i, j)
     786              :             end do
     787            0 :             call BRCKR(FT,FNE,RR,28,UF,100,FSCAT,ierr)
     788            0 :             if (ierr /= 0) return
     789            0 :             do n = 0, 100
     790            0 :               u = uf(n)
     791            0 :               fscat(n) = cscat*(fscat(n)-1)
     792              :             end do
     793            0 :             do n = 2, ntot-1
     794            0 :               u = umesh(n)
     795            0 :               se = semesh(n)
     796            0 :               m=(u-umin)/dscat
     797            0 :               ua=umin+dscat*m
     798            0 :               ub=ua+dscat
     799            0 :               p(n)=p(n)+((ub-u)*fscat(m)+(u-ua)*fscat(m+1))/(dscat*se)
     800              :             end do
     801            0 :             u=umesh(ntot)
     802            0 :             se=semesh(ntot)
     803            0 :             p(ntot)=p(ntot)+fscat(100)/se
     804            0 :             p(1)=p(1)+fscat(1)/(1.-.5*umin)
     805            0 :             do k=1,ntot
     806            0 :               f(k,i,j)=p(k)
     807              :             end do
     808              :          end do
     809              :       end do
     810              : 
     811            0 :       end subroutine scatt
     812              : ! **********************************************************************
     813            0 :       subroutine screen1(ih,jh,rion,umesh,ntot,epa,f)
     814            0 :       use op_load, only: screen2
     815              :       dimension uf(0:100), umesh(nptot),fscat(0:100), ih(0:5), jh(0:5)
     816              :       real, target :: f(nptot, 0:5, 0:5), rion(28, 0:5, 0:5)
     817              :       integer :: i, j, k, m
     818            0 :       real, pointer :: p(:), rr(:)
     819              : 
     820            0 :       ite3=2
     821            0 :       umin=umesh(1)
     822            0 :       umax=umesh(ntot)
     823              : 
     824            0 :       do i = 0, 5
     825            0 :          ft=exp10(ITE3*dble(ih(i))/40d0)
     826            0 :          do j = 0, 5
     827            0 :             fne=exp10(ITE3*dble(jh(j))/4d0)
     828              : !            do k=1,ntot
     829            0 :               p => f(1:ntot,i,j)
     830              : !            end do
     831              : !            do m=1,28
     832            0 :               rr => rion(1:28,i,j)
     833              : !            end do
     834            0 :             call screen2(ft,fne,rr,epa,ntot,umin,umax,umesh,p)
     835              : !            do k=1,ntot
     836              : !              f(k,i,j)=p(k)
     837              : !            end do
     838              :         end do
     839              :       end do
     840              : 
     841            0 :       end subroutine screen1
     842              : 
     843              :       end module op_osc
        

Generated by: LCOV version 2.0-1