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

Generated by: LCOV version 2.0-1