LCOV - code coverage report
Current view: top level - adipls/adipack.c/gensr - lininh.new.d.f (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 114 0
Test Date: 2025-05-08 18:23:42 Functions: 0.0 % 1 0

            Line data    Source code
       1            0 :       subroutine lininh(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  linear differential equation solver. 
      80              : c  differs from original version
      81              : c  of lininh by incorporating gaussian elimination without pivoting
      82              : c  in subroutine.
      83              : c
      84              : c  original version: 27/8/1991
      85              : c
      86              :       implicit double precision(a-h,o-z)
      87              :       dimension x(nn),y(iy,nn),fd(20,20),finh(20),w(20,20),y1(20)
      88              :       common/modfac/ r21,ntld
      89              : c
      90              : c  common defining standard input and output
      91              : c
      92              :       common/cstdio/ istdin, istdou, istdpr, istder
      93              :       external rhs
      94              : c
      95              : c..      write(6,*) 'Enter lininh with ii, iy, ig =',ii, ig, iy
      96              : c..      write(6,*) 'y(1-2,1) =',(y(i,1),i=1,2)
      97              : c
      98              : c  explicitly disable check for linear dependence
      99              : c
     100            0 :       ifd=20
     101              : c
     102            0 :       iw=20
     103              : c  right hand sides at first point
     104            0 :     5 n=1
     105            0 :       nc=1
     106            0 :       nd=nd1
     107            0 :       ntst=nn-2
     108            0 :       iig=ii*ig
     109            0 :       x2=x(1)
     110            0 :       call rhs(x2,fd,finh,ifd,nd)
     111            0 :       go to 20
     112              : c  right hand sides at next point
     113            0 :    10 nd=nd+isn
     114            0 :       call rhs(x2,fd,finh,ifd,nd)
     115              : c  set coefficient matrix for linear equations
     116            0 :       do 14 i=1,ii
     117            0 :       do 13 j=1,ii
     118            0 :    13 w(i,j)=dx*fd(i,j)
     119            0 :    14 w(i,i)=1+w(i,i)
     120              : c
     121              : c  include inhomogeneous contribution from next point
     122              : c
     123            0 :       do 15 i=1,iig
     124            0 :    15 y(i,n)=y(i,n)-dx*finh(i)
     125              : c
     126              : c..      write(6,15091) n,x(n),((w(i,j),j=1,2),y(i,n),i=1,2)
     127              : c..15091 format(' Equations at n, x =',i5,f10.5/(1p3e13.5))
     128              : c
     129              : c  solve linear equations by gaussian elimination without pivoting
     130              : c
     131            0 :       ii1=ii-1
     132            0 :       if(ii1.gt.0) then
     133              : c
     134              : c  triangularize matrix
     135              : c
     136            0 :         do 17 i=1,ii1
     137            0 :         r=w(i,i)
     138              : c
     139              : c  test for non-zero diagonal element
     140              : c
     141            0 :         if(r.eq.0) then
     142            0 :           if(istdpr.gt.0) write(istdpr,110) i,n
     143            0 :           return
     144              :         end if
     145              : c
     146            0 :         r=-1.d0/r
     147              : c
     148            0 :         i1=i+1
     149              : c
     150            0 :         do 17 j=i1,ii
     151            0 :         rj=r*w(j,i)
     152            0 :         do 16 k=i1,ii
     153            0 :    16   w(j,k)=w(j,k)+rj*w(i,k)
     154              : c
     155            0 :         js=j
     156            0 :         is=i
     157              : c
     158            0 :         do 17 l=1,ig
     159            0 :         y(js,n)=y(js,n)+rj*y(is,n)
     160            0 :         js=js+ii
     161            0 :    17   is=is+ii
     162              : c
     163              :       end if
     164              : c
     165              : c  now matrix is on triangular form
     166              : c
     167              : c  start solution
     168              : c
     169            0 :       i=ii+1
     170            0 :       do 18 icnt=1,ii
     171            0 :       i=i-1
     172              : c
     173            0 :       r=w(i,i)
     174              : c
     175              : c  test for non-zero diagonal element
     176              : c
     177            0 :       if(r.eq.0) then
     178            0 :         if(istdpr.gt.0) write(istdpr,110) i,n
     179            0 :         return
     180              :       end if
     181              : c
     182            0 :       r=1.d0/r
     183            0 :       is=i
     184            0 :       i1=i+1
     185              : c
     186            0 :       do 18 l=1,ig
     187            0 :       sum=y(is,n)
     188              : c
     189            0 :       if(i.lt.ii) then
     190              : c
     191            0 :         j1=is
     192            0 :         do 17100 j=i1,ii
     193            0 :         j1=j1+1
     194            0 : 17100   sum=sum-w(i,j)*y(j1,n)
     195              : c
     196              :       end if
     197              : c
     198            0 :       y(is,n)=r*sum
     199              : c
     200            0 :    18 is=is+ii
     201            0 :       if(nc.eq.nn) return
     202              : c
     203              : c  set up right hand side of linear equation at next point
     204              : c
     205            0 :    20 n1=n
     206            0 :       n=n+isn
     207            0 :       nc=nc+1
     208            0 :       x1=x2
     209            0 :       x2=x(n)
     210            0 :       dx=0.5d0*(x1-x2)
     211            0 :       kg=-ii
     212            0 :       do 25 l=1,ig
     213            0 :       kg=kg+ii
     214            0 :       do 25 i=1,ii
     215            0 :       k=kg+i
     216            0 :       sum=0
     217            0 :       do 22 j=1,ii
     218            0 :       sum=sum+fd(i,j)*y(kg+j,n1)
     219              : c..      write(6,*) 'i,j,kg+j,n1,fd(i,j),y(kg+j,n1),sum:'
     220              : c..      write(6,*)  i,j,kg+j,n1,fd(i,j),y(kg+j,n1),sum
     221            0 :    22 continue
     222            0 :       y(k,n)=y(k,n1)-dx*(sum+finh(k))
     223              : c..      write(6,*) 'k, y(k,n1), dx, sum, finh(k):'
     224              : c..      write(6,*)  k, y(k,n1), dx, sum, finh(k)
     225            0 :    25 continue
     226            0 :       if(ntld.ne.1) go to 10
     227            0 :       if(nc.ne.ntst.or.ig.ne.2) go to 10
     228              : c  test for linear dependence (only implemented for ig = 2)
     229            0 :       do 30 i=1,iig
     230            0 :    30 y1(i)=y(i,n1)
     231            0 :       aym=0
     232            0 :       im=0
     233            0 :       aym2=0
     234            0 :       do 32 i=1,ii
     235            0 :       ay=abs(y1(i))
     236            0 :       aym2=max(aym2,abs(y1(i+ii)))
     237            0 :       if(ay.le.aym) go to 32
     238            0 :       aym=ay
     239            0 :       im=i
     240            0 :    32 continue
     241              : c
     242            0 :       r21=y1(ii+im)/y1(im)
     243            0 :       s1=0
     244            0 :       s2=0
     245            0 :       j=ii
     246            0 :       do 34 i=1,ii
     247            0 :       j=j+1
     248            0 :       yi=y1(i)
     249            0 :       if(yi.ne.0) go to 33
     250            0 :       if(abs(y1(j)).gt.1.d-5*aym2) go to 10
     251            0 :       go to 34
     252            0 :    33 ri=y1(j)/y1(i)
     253            0 :       s1=s1+abs(r21-ri)
     254            0 :       s2=s2+abs(ri)
     255            0 :    34 continue
     256              : c  test
     257            0 :       if(s1/s2.gt.1.d-7) go to 10
     258              : c  nearly linear dependence. modify initial values and start again
     259            0 :       j=0
     260            0 :       aym=0
     261            0 :       do 36 i=1,ii
     262            0 :       y1(i)=y(i+ii,1)-r21*y(i,1)
     263            0 :    36 aym=max(aym,abs(y1(i)))
     264              : c  normalize initial y's
     265            0 :       aym=1.d0/aym
     266            0 :       do 38 i=1,ii
     267            0 :    38 y(ii+i,1)=aym*y1(i)
     268              : c
     269            0 :       if(istdpr.gt.0) write(istdpr,100) (y(i,1),i=1,iig)
     270            0 :       go to 5
     271              : c
     272              :   100 format(//' initial solution has been modified. new y(n=1):'/
     273              :      *  (1p10e13.5))
     274              : c
     275              :   110 format(//'  ***** in s/r lininh zero diagonal element at i =',
     276              :      *  i5,'   n =',i5)
     277              :       end
        

Generated by: LCOV version 2.0-1