LCOV - code coverage report
Current view: top level - adipls/adipack.c/gensr - lininh4.d.f (source / functions) Coverage Total Hit
Test: coverage.info Lines: 95.6 % 90 86
Test Date: 2025-05-08 18:23:42 Functions: 100.0 % 1 1

            Line data    Source code
       1         1784 :       subroutine lininh4(x,y,rhs,ii,iy,ig,isn,nd1,nn)
       2              : c
       3              : c
       4              : c  Initial value integrator.
       5              : c  =========================
       6              : c  Integrates a set of first-order ordinary
       7              : c  linear inhomogeneous differential equations, by means of second-order
       8              : c  centred difference approximation, from given initial values.
       9              : c
      10              : c  The equations are on the form
      11              : c
      12              : c       d y(i; x)/dx = sum ( a(i,j; x) * y(j; x)) + f(i; x)
      13              : c                       j
      14              : c
      15              : c  The order of the equations is ii.
      16              : c  
      17              : c  The coefficients and the inhomogeneous terms
      18              : c  are set up in the routine rhs, which must be
      19              : c  supplied by the user as external.
      20              : c  
      21              : c  The routine has the option for determining in a single call the
      22              : c  solutions to a given set of equations for several initial conditions;
      23              : c  ig specifies the number of such sets.
      24              : c  
      25              : c  For use with Richardson extrapolation the routine finds the solution
      26              : c  at every isn-th point in the input mesh. For ordinary use 
      27              : c  isn is set to 1.
      28              : c  
      29              : c  nd1 specifies the initial value of the mesh index passed into the
      30              : c  routine rhs (see below).
      31              : c
      32              : c  iy is the first dimension of y in the calling programme.
      33              : c  
      34              : c  On input x(1+isn*(n-1)), n = 1,nn, must contain the mesh in the 
      35              : c  independent variable. The initial conditions for set k must be
      36              : c  set into y(i + ii*(k-1),1), i = 1,ii, for k = 1,ig.
      37              : c  
      38              : c  The routine returns the solution for initial value set k in
      39              : c  y(i+ii*(k-1),1+isn*(n-1)), i=1,ii, n=1,nn, k=1,ig.
      40              : c  
      41              : c  The right hand side subroutine rhs:
      42              : c  -----------------------------------
      43              : c  
      44              : c  This is called by lininh and should be defined as
      45              : c  
      46              : c        subroutine rhs(x,aa,finh,iaa,nd)
      47              : c        dimension aa(iaa,1),finh(1)
      48              : c           .
      49              : c           .
      50              : c           .
      51              : c  
      52              : c  A single call must set the coefficient matrix and inhomogeneous
      53              : c  term at a single point.
      54              : c  On input x (a scalar) gives the value of the independent variable
      55              : c  at the given point; iaa is the first dimension of aa;
      56              : c  nd is passed from lininh and may be used to address a data
      57              : c  array in rhs. 
      58              : c  
      59              : c  The routine should return
      60              : c  
      61              : c  aa(i,j) = a(i,j; x)
      62              : c  finh(i + ii*(k-1)) = f(i; x) for the k-th set, k = 1,ig.
      63              : c  
      64              : c  where a(i,j; x) and f(i; x) as defined above are the 
      65              : c  coefficient matrix and inhomogeneous term in the equations.
      66              : c  
      67              : c  The definition of nd is slightly convoluted. It is assumed that the
      68              : c  use might need certain variables to define the right hand side
      69              : c  of the equations. Assume, for example, that these are passed into 
      70              : c  the routine in
      71              : c  
      72              : c        common/rhsdat/ data(10,200)
      73              : c  
      74              : c  When rhs is called at the meshpoint x(1+isn*(n-1)), nd is
      75              : c  set to nd1+isn*(n-1). The meshpoint should therefore correspond
      76              : c  to the data in data(i,nd). In most cases presumably x and the
      77              : c  data would be given on the same mesh, and nd1 would be 1.
      78              : c
      79              : c  4th order version, using algorithm of Cash & Moore (1980; BIT 20:1, 44 - 52)
      80              : c   
      81              : c  original version: 11/3/05
      82              : c
      83              :       implicit double precision(a-h,o-z)
      84              :       dimension x(nn),y(iy,nn),fd(20,20),fdp(20,20),fdh(20,20),finh(20),
      85              :      *  fp(20),w(20,20),y1(20)
      86              :       common/modfac/ r21,ntld
      87              : c
      88              : c  common defining standard input and output
      89              : c
      90              :       common/cstdio/ istdin, istdou, istdpr, istder
      91              :       external rhs
      92              : c
      93              : c..      write(6,*) 'Enter lininh with ii, iy, ig =',ii, ig, iy
      94              : c..      write(6,*) 'y(1-2,1) =',(y(i,1),i=1,2)
      95              : c
      96              : c  explicitly disable check for linear dependence
      97              : c
      98         1784 :       ifd=20
      99              : c
     100         1784 :       iw=20
     101              : c  right hand sides at first point
     102         1784 :     5 n=1
     103         1784 :       nc=1
     104         1784 :       nd=nd1
     105         1784 :       ntst=nn-2
     106         1784 :       iig=ii*ig
     107         1784 :       x2=x(1)
     108         1784 :       call rhs(x2,fd,finh,ifd,nd)
     109              : c
     110              : c  right hand sides at next point
     111              : c
     112      4280720 :    10 do i=1,ii
     113     16665488 :         do j=1,ii
     114     15715520 :           fdp(i,j)=fd(i,j)
     115              :         end do
     116              :       end do
     117              : c
     118              : c  set up right hand side of linear equation at next point
     119              : c
     120       949968 :       n1=n
     121       949968 :       n=n+isn
     122       949968 :       nc=nc+1
     123       949968 :       x1=x2
     124       949968 :       x2=x(n)
     125              : c
     126       949968 :       nd=nd+isn
     127              : c
     128       949968 :       call rhs(x2,fd,finh,ifd,nd)
     129              : c
     130      4280720 :       do i=1,ii
     131     16665488 :         do j=1,ii
     132     15715520 :           fdh(i,j)=0.5d0*(fd(i,j)+fdp(i,j))
     133              :         end do
     134              :       end do
     135       949968 :       dx=x2-x1
     136       949968 :       kg=-ii
     137      2615344 :       do 25 l=1,ig
     138      1665376 :       kg=kg+ii
     139      7857760 :       do 23 i=1,ii
     140      6192384 :       k=kg+i
     141      6192384 :       sum=0
     142     30023680 :       do 22 j=1,ii
     143     23831296 :       sum=sum+fdp(i,j)*y(kg+j,n1)
     144      6192384 :    22 continue
     145      6192384 :       fp(i)=sum
     146      1665376 :    23 continue
     147              : c
     148      7857760 :       do i=1,ii
     149      6192384 :         sum1=0
     150      6192384 :         sum2=0
     151     30023680 :         do j=1,ii
     152     23831296 :           sum1=sum1+fdh(i,j)*y(kg+j,n1)
     153     30023680 :           sum2=sum2+fdh(i,j)*fp(j)
     154              :         end do
     155              :         y(kg+i,n)=y(kg+i,n1)+dx*fp(i)/6.d0+dx*sum1/3.d0
     156      7857760 :      *            +dx*dx*sum2/12.d0
     157              :       end do
     158              : c
     159       949968 :    25 continue
     160              : c  set coefficient matrix for linear equations
     161      4280720 :       do i=1,ii
     162     15715520 :         do j=1,ii
     163     12384768 :           sum=0
     164     60047360 :           do k=1,ii
     165     60047360 :             sum=sum+fdh(i,k)*fd(k,j)
     166              :           end do
     167     15715520 :           w(i,j)=-(fd(i,j)+2.d0*fdh(i,j))*dx/6.d0+sum*dx*dx/12.d0
     168              :         end do
     169      4280720 :         w(i,i)=1.d0+w(i,i)
     170              :       end do
     171              : c
     172              : c  include inhomogeneous contribution from next point (needs to be added)
     173              : c
     174              : c..      do 15 i=1,iig
     175              : c..   15 y(i,n)=y(i,n)-dx*finh(i)
     176              : c
     177              : c..      write(6,15091) n,x(n),((w(i,j),j=1,2),y(i,n),i=1,2)
     178              : c..15091 format(' Equations at n, x =',i5,f10.5/(1p3e13.5))
     179              : c
     180              : c  solve linear equations by gaussian elimination without pivoting
     181              : c
     182       949968 :       ii1=ii-1
     183       949968 :       if(ii1.gt.0) then
     184              : c
     185              : c  triangularize matrix
     186              : c
     187      3330752 :         do 27 i=1,ii1
     188      2380784 :         r=w(i,i)
     189              : c
     190              : c  test for non-zero diagonal element
     191              : c
     192      2380784 :         if(r.eq.0) then
     193            0 :           if(istdpr.gt.0) write(istdpr,110) i,n
     194            0 :           return
     195              :         end if
     196              : c
     197      2380784 :         r=-1.d0/r
     198              : c
     199      2380784 :         i1=i+1
     200              : c
     201      7857760 :         do 27 j=i1,ii
     202      4527008 :         rj=r*w(j,i)
     203     14777280 :         do 26 k=i1,ii
     204     14777280 :    26   w(j,k)=w(j,k)+rj*w(i,k)
     205              : c
     206      4527008 :         js=j
     207      4527008 :         is=i
     208              : c
     209     15727248 :         do 27 l=1,ig
     210      8819456 :         y(js,n)=y(js,n)+rj*y(is,n)
     211      8819456 :         js=js+ii
     212     13346464 :    27   is=is+ii
     213              : c
     214              :       end if
     215              : c
     216              : c  now matrix is on triangular form
     217              : c
     218              : c  start solution
     219              : c
     220       949968 :       i=ii+1
     221      4280720 :       do 28 icnt=1,ii
     222      3330752 :       i=i-1
     223              : c
     224      3330752 :       r=w(i,i)
     225              : c
     226              : c  test for non-zero diagonal element
     227              : c
     228      3330752 :       if(r.eq.0) then
     229            0 :         if(istdpr.gt.0) write(istdpr,110) i,n
     230            0 :         return
     231              :       end if
     232              : c
     233      3330752 :       r=1.d0/r
     234      3330752 :       is=i
     235      3330752 :       i1=i+1
     236              : c
     237     10473104 :       do 28 l=1,ig
     238      6192384 :       sum=y(is,n)
     239              : c
     240      6192384 :       if(i.lt.ii) then
     241              : c
     242      4527008 :         j1=is
     243     13346464 :         do j=i1,ii
     244      8819456 :           j1=j1+1
     245     13346464 :           sum=sum-w(i,j)*y(j1,n)
     246              :         end do
     247              : c
     248              :       end if
     249              : c
     250      6192384 :       y(is,n)=r*sum
     251              : c
     252      9523136 :    28 is=is+ii
     253       949968 :       if(nc.eq.nn) return
     254              : c
     255       948184 :       go to 10
     256              : c
     257              :   110 format(//'  ***** in s/r lininh zero diagonal element at i =',
     258              :      *  i5,'   n =',i5)
     259              :       end
        

Generated by: LCOV version 2.0-1