C
C Subroutine file 'means.for' containing some utility programs helpful
C when dealing with the model.
C
C Date: 1999, May 17
C Coded by Ludek Klimes
C
C.......................................................................
C
C This file consists of the following subroutines:
C CDE... Subroutine designed to search for the point of
C intersection of the given curve with the boundaries of the
C complex block. The curve is interpolated from the two
C given points. The subroutine performs the steps 5.8.3(c),
C (d) and (e) of the algorithm.
C CDE
C CROSS...Subroutine designed to find the point of intersection of a
C curve with a surface (see C.R.T.5.8.4b).
C CROSS
C HIVD2...Subroutine performing the Hermite interpolation of a
C vector and its derivatives using functional values and
C derivatives at 2 given points (see C.R.T.5.8.4a).
C HIVD2
C SMVPRD..Subroutine designed to evaluate symmetric matrix by vector
C product. It may be, e.g., called after the invocation of
C the METRIC subroutine to transform the covariant vectors
C to the contravariant ones and vice versa.
C SMVPRD
C
C=======================================================================
C
C
C
SUBROUTINE CDE(NOUGHT,NEND,KEND,NBOUND,KBOUND,BOUND,
* KDIM1,KDIM2,NDIM,IY,ERR,X0,X1,Y1,D1,X2,Y2,D2,X,Y,D,XB,YB,DB)
INTEGER NOUGHT,NEND,KEND(*),NBOUND,KBOUND(*)
INTEGER IY(8),KDIM1,KDIM2,NDIM,MY
PARAMETER (MY=35)
REAL BOUND(*),ERR,X0,X1,Y1(NDIM),D1(NDIM),X2,Y2(NDIM),D2(NDIM)
REAL X,Y(NDIM),D(NDIM),XB,YB(NDIM),DB(NDIM)
C
C This subroutine determines the point of intersection of the given
C curve element with the boundary of the complex block. The curve is
C interpolated from the two given points. The subroutine performs the
C steps 5.8.3(c), (d) and (e) of the algorithm.
C
C General meaning of some arguments used:
C X1,X2,X,XB... Independent variable along the curve.
C Y1,Y2,Y,YB,D1,D2,D,DB... Arrays of the dimension NDIM.
C Y1(KDIM1:KDIM2),Y2(KDIM1:KDIM2),Y(KDIM1:KDIM2),YB(KDIM1:KDIM2)...
C Coordinates.
C D1(1:NDIM),D2(1:NDIM),D(1:NDIM),DB(1:NDIM)... Derivatives of
C arrays Y1,Y2,Y,YB with respect to the independent
C variable.
C
C Input:
C NOUGHT..Zero if the curve is not situated along the structural
C interface,
C otherwise the index of the surface on which the curve is
C situated.
C NEND... Number of end surfaces limiting the computational volume.
C Usually NEND=0.
C KEND... Contains the indices of end surfaces.
C Array of dimension NEND, not used if NEND=0.
C NBOUND..Number of isosurfaces of computed quantities, limiting the
C computational volume. These isosurfaces will likely be
C the boundaries X1MIN,X1MAX,X2MIN,X2MAX,X3MIN,X3MAX of the
C computational volume.
C KBOUND..Indices of the quantities corresponding to the
C isosurfaces. The computational volume is limited by the
C inequalities
C Y(IABS(KBOUND(I))).LE.BOUND(I) for KBOUND(I).LT.0,
C Y(IABS(KBOUND(I))).GE.BOUND(I) for KBOUND(I).GT.0.
C Array of dimension NBOUND, not used if NBOUND=0.
C BOUND...Values of the isosurfaces, likely coinciding with
C boundaries X1MIN,X1MAX,X2MIN,X2MAX,X3MIN,X3MAX of the
C computational volume. In such a case, KBOUND would take
C the values KDIM1,-KDIM1,KDIM1+1,-KDIM1-1,KDIM2,-KDIM2.
C Array of dimension NBOUND, not used if NBOUND=0.
C KDIM1,KDIM2... KDIM1-th to KDIM2-th elements of arrays Y1,Y2,Y,YB
C contain coordinates. KDIM2 is assumed to be KDIM1+2.
C NDIM... Dimension of the arrays Y1,Y2,Y,YB,D1,D2,D,DB. It must
C not exceed the parameter MY.
C IY... Integer array of the dimension at least 8.
C IY(4)=ISB1... Index of the simple block containing the point X1.
C IY(5)=ICB1... Index of the complex block containing the point X1.
C It may (but need not) be supplemented by a sign '+' for P
C wave and sign '-' for S wave.
C ERR... Maximum error in independent variable for the
C determination of the point of intersection.
C X0... For X.LE.X0 just the intersection with the boundary of
C the computational volume is checked, not with the
C structural interfaces.
C For X1.LE.X0, the initial point X1 is checked for location
C outside the complex block, but very close to its boundary.
C In such a case, X0 should be close to X1 (within an
C interval of ERR) and may be located inside the complex
C block.
C X1,Y1,D1... Quantities at the initial point of the curve element.
C X2,Y2,D2... Quantities at another point of the curve. The curve
C is interpolated using the values and their derivatives at
C the points X1 and X2.
C X,Y,D...Quantities at the endpoint of the curve element.
C XB,YB,DB... Values ignored.
C
C Output:
C NOUGHT,KDIM1,KDIM2,NDIM,ERR,X0,X1,Y1,D1,X2,Y2,D2... Unchanged
C input.
C IY(1),IY(2),IY(3),IY(5)... Unchanged input.
C IY(4)=ISB1... Index of the simple block containing the point X.
C Output if the endpoint of the curve element is situated in the complex
C block IY(5):
C IY(6),IY(7),IY(8)... Unchanged input.
C X,Y,D...Unchanged input.
C XB,YB,DB... Copy of X,Y,D.
C Output if the endpoint of the curve element is situated in another
C complex block or outside the computational volume:
C IY(6)=ISRF... Index of the surface at which the point of
C intersection with the boundary of the complex block is
C situated, supplemented by a sign '+' or '-' for the point
C situated at the positive or negative side of the surface,
C respectively.
C IY(7)=ISB2... Index of the simple block touching the complex
C block ICB1 from the other side of the surface ISRF at
C the point of intersection.
C ISB2=0 for a free space on the other side of ISRF.
C IY(8)=ICB2... Index of the complex block touching the complex
C block ICB1 from the other side of the surface ISRF at
C the point of intersection.
C ICB2=0 for a free space on the other side of ISRF.
C X,Y,D...Values corresponding to the point of intersection of the
C curve with the boundary of the complex block or the
C computational volume. If possible, this point is situated
C inside the given complex block close to its boundary, or
C directly on its boundary.
C XB,YB,DB... Values corresponding to another approximation of the
C point of intersection. This point is situated outside the
C the given complex block, close to its boundary or directly
C on its boundary.
C Note that XB-X should be less than ERR.
C
C Subroutines and external functions required:
EXTERNAL NSRFC,BLOCK,SRFC2,CROSS
INTEGER NSRFC
C NSRFC,BLOCK... File 'model.for'.
C SRFC2 and subsequent routines... File 'srfc.for' and subsequent
C files (like 'val.for' and 'fit.for').
C CROSS,HIVD2... This file.
C
C Date: 1999, May 17
C Coded by Ludek Klimes
C
C-----------------------------------------------------------------------
C
C Auxiliary storage locations for local model parameters: FAUX(10),
C G(12),GAMMA(18),GSQRD, UP(10),US(10),RO,QP,QS, VP,VS,VD(10),QL:
INCLUDE 'auxmod.inc'
C auxmod.inc
C
C.......................................................................
C
C Other auxiliary storage locations:
INTEGER NSRF1,ISRF(2)
INTEGER ISRAUX,ISBAUX,ISB1,ISRF2,ISB2,ICB2,K0,K1,K2,K,I
REAL XAUX,YAUX(MY),DAUX(MY),X01,Y01(MY),D01(MY)
C
C ISB1,X01,Y01,D01,VD... Used only to check for the location of the
C point X1.
C
C.......................................................................
C
C (c) Check for crossing the coordinate boundaries of the
C computational volume:
DO 31 I=1,NBOUND
K=IABS(KBOUND(I))
IF((KBOUND(I).GT.0.AND.Y(K).LT.BOUND(I)).OR.
* (KBOUND(I).LT.0.AND.Y(K).GT.BOUND(I))) THEN
IY(6)=100+I
FAUX(1)=BOUND(I)
CALL CROSS(SRFC2,IY(6),K,K,NDIM,ERR,X1,Y1,D1,X2,Y2,D2,
* X,Y,D,XB,YB,DB,FAUX)
END IF
31 CONTINUE
IF(IY(6).GT.100) THEN
IY(7)=IY(4)
IY(8)=IABS(IY(5))
END IF
ISB1=IY(4)
C
XB=X
DO 39 I=1,NDIM
YB(I)=Y(I)
DB(I)=D(I)
39 CONTINUE
C
C (d) Check for crossing the boundary of the complex block:
C Note: IY(4)=ISB1, IY(5)=ICB1, IY(6)=ISRF.
IF(NOUGHT.EQ.0) THEN
NSRF1=1
ELSE
NSRF1=2
ISRF(2)=NOUGHT
END IF
IF(X.GT.X0) THEN
ISRF(1)=0
CALL BLOCKS(Y(KDIM1),NSRF1,ISRF,IY(4),ISRF2,ISB2,ICB2)
IF(ISRF2.NE.0) THEN
C Boundary of the simple block is crossed
C Note: in this routine, unlike in the paper on C.R.T., the
C point of intersection with the boundary of the simple block is
C found even if the boundary of the complex block is not
C crossed.
C (d1)
ISRAUX=IY(6)
ISBAUX=ISB2
XAUX=X
DO 41 I=1,NDIM
YAUX(I)=Y(I)
DAUX(I)=D(I)
41 CONTINUE
C 5.30:
CALL SRFC2(IABS(ISRF2),Y(KDIM1),FAUX)
C Following loop is included to avoid infinite repeating of the
C steps (d2) and (d3) of the algorithm
DO 47 K=1,100
C (d2)
IY(6)=ISRF2
C (d3)
C Check for the location of the point X1 before calling cross
IF(X1.LE.X0) THEN
C X1 may be located outside the complex block
CALL SRFC2(IABS(IY(6)),Y1(KDIM1),VD)
IF(VD(1)*FAUX(1).GT.0.) THEN
C Points X1 and X are located outside the complex block,
C looking for the point X01 between X0 and X, situated
C inside the complex block.
X01=X0
42 CONTINUE
CALL HIVD2(KDIM2-KDIM1+1,X1,Y1(KDIM1),D1(KDIM1),X2,
* Y2(KDIM1),D2(KDIM1),X01,Y01(KDIM1),D01(KDIM1))
CALL SRFC2(IABS(IY(6)),Y01(KDIM1),VD)
IF(VD(1)*FAUX(1).LE.0.) THEN
C Point X01 is likely located inside the complex block
ISRF(1)=0
CALL BLOCKS(Y01(KDIM1),NSRF1,ISRF,ISB1,ISRF2,K1,K2)
IF(ISRF2.EQ.0) THEN
C Point X01 is located inside the simple block ISB1,
C point X1 may be replaced by X01.
CALL HIVD2(NDIM,X1,Y1,D1,X2,Y2,D2,X01,Y01,D01)
CALL CROSS(SRFC2,IABS(IY(6)),KDIM1,KDIM2,NDIM,ERR,
* X01,Y01,D01,X2,Y2,D2,X,Y,D,XB,YB,DB,FAUX)
GO TO 43
END IF
ELSE
C Trying a new point X01
IF(X01.EQ.X0) THEN
X01=X01+ERR
ELSE
X01=X01+(X01-X0)
END IF
IF(X01.LT.X) THEN
GO TO 42
END IF
END IF
END IF
END IF
CALL CROSS(SRFC2,IABS(IY(6)),KDIM1,KDIM2,NDIM,ERR,
* X1,Y1,D1,X2,Y2,D2,X,Y,D,XB,YB,DB,FAUX)
43 CONTINUE
C X and XB are the approximations of the point of intersection
C with the surface IY(6)
ISRF(1)=0
CALL BLOCKS(Y(KDIM1),NSRF1,ISRF,IY(4),ISRF2,ISB2,ICB2)
IF(ISRF2.EQ.IY(6).AND.X.NE.X1) THEN
C 587
CALL ERROR('587 in CDE: Boundary point out of block')
C This error should not appear. Contact the authors.
END IF
C 5.30:
IF(ISRF2.NE.0) THEN
CALL SRFC2(IABS(ISRF2),Y(KDIM1),FAUX)
END IF
IF(ISRF2.NE.0.AND.ISRF2.NE.IY(6).AND.
* FAUX(1)*(D(KDIM1)*FAUX(2)+D(KDIM1+1)*FAUX(3)
* +D(KDIM2)*FAUX(4)).GT.0.) THEN
C (d3-i)
C Point X is not situated at the boundary of the simple
C block. It is separated from the simple block IY(4) by
C the surface ISRF2 situated before (not after) the point X.
C Go to (d2)
ELSE
C X is situated at the boundary of the simple block IY(4)
ISRF(1)=0
CALL BLOCKS(YB(KDIM1),NSRF1,ISRF,IY(4),ISRF2,ISB2,ICB2)
IF(ISB2.EQ.IY(4)) THEN
CALL SRFC2(IABS(IY(6)),YB(KDIM1),FAUX)
IF(FAUX(1).NE.0.) THEN
C 582
CALL ERROR('582 in CDE: Excluded program branch')
C This error should not appear. Contact the authors.
END IF
C Point XB is situated exactly at the surface IY(6)
ISRF(1)=IY(6)
CALL BLOCKS(YB(KDIM1),NSRF1,ISRF,IY(4),ISRF2,ISB2,ICB2)
END IF
C Near the edge of a simple block, two different surfaces
C bounding simple block IY(4) may be situated between
C points X and XB. In such a case, only one of them
C separates simple block IY(4) from ISB2 and IY(6) may
C be the second.
ISRF(1)=IY(6)
CALL BLOCKS(Y(KDIM1),NSRF1,ISRF,IY(4),ISRF2,K1,K2)
IF(ISRF2.EQ.0.AND.ISB2.NE.K1) THEN
C Surface IY(6) does not form the interface between
C simple blocks IY(4) and ISB2:
ISRF(1)=IY(6)
CALL BLOCKS(YB(KDIM1),NSRF1,ISRF,IY(4),ISRF2,K1,K2)
IF(ISRF2.NE.0) THEN
C Surface ISRF2 separates the point XB from the simple
C block IY(4):
ISRF(1)=ISRF2
CALL BLOCKS(Y(KDIM1),NSRF1,ISRF,IY(4),K0,K1,K2)
IF(K0.EQ.0.AND.ISB2.EQ.K1) THEN
C Surface ISRF2 forms the interface between simple
C blocks IY(4) and ISB2:
IY(6)=ISRF2
END IF
END IF
END IF
IF(ICB2.EQ.IABS(IY(5))) THEN
C (d3-ii)
C X,Y is situated at the boundary of the simple block
C but not situated at the boundary of the complex block
IY(4)=ISB2
X=XAUX
DO 45 I=1,NDIM
Y(I)=YAUX(I)
D(I)=DAUX(I)
45 CONTINUE
IF(ISB2.EQ.ISBAUX) THEN
C Boundary of the complex block has not been crossed
C during the last step of numerical integration
XB=X
DO 46 I=1,NDIM
YB(I)=Y(I)
DB(I)=D(I)
46 CONTINUE
IY(6)=ISRAUX
GO TO 49
END IF
ISRF(1)=0
CALL BLOCKS
* (YAUX(KDIM1),NSRF1,ISRF,IY(4),ISRF2,ISB2,ICB2)
IF(ISRF2.EQ.0) THEN
C ISRF2 can be zero only if ISBAUX.EQ.0:
IF(ISBAUX.EQ.0) THEN
C 5.30:
CALL BLOCKS
* (Y(KDIM1),NSRF1,ISRF,IY(4),ISRF2,ISB2,ICB2)
IF(ISRF2.EQ.0) THEN
GO TO 49
END IF
ELSE
WRITE(*,'(20(A,I3))') ' ISRFC1=',ISRAUX,
* ' ISB1=',ISBAUX,
* ' ICB1=',IY(5),
* ' ISRFC2=',ISRF2,
* ' ISB2=',IY(4),
* ' ICB2=',ICB2
C 583
CALL ERROR('583 in CDE: Excluded program branch')
C This error should not appear. Contact the authors.
END IF
END IF
C 5.30:
CALL SRFC2(IABS(ISRF2),YAUX(KDIM1),FAUX)
C Go to (d2)
ELSE
C (d3-iii)
C X is situated at the boundary of the simple block and
C X is situated at the boundary of the complex block
GO TO 48
END IF
END IF
47 CONTINUE
C 581
CALL ERROR('581 in CDE: Too many fictitious interfaces')
C More than 100 fictitious interfaces crossed during one
C step of the numerical integration.
C This error should not appear. Contact the authors.
48 CONTINUE
IY(7)=ISB2
IY(8)=ICB2
END IF
49 CONTINUE
END IF
C
C (e) Check for crossing the end surfaces
DO 51 I=1,NEND
IF(IABS(KEND(I)).GT.NSRFC()) THEN
CALL SRFC2(IABS(KEND(I)),Y(KDIM1),FAUX)
IF(FAUX(1)*FLOAT(KEND(I)).LE.0.) THEN
IY(6)=IABS(KEND(I))
CALL CROSS(SRFC2,IY(6),KDIM1,KDIM2,NDIM,ERR,
* X1,Y1,D1,X2,Y2,D2,X,Y,D,XB,YB,DB,FAUX)
END IF
END IF
51 CONTINUE
C
RETURN
END
C
C=======================================================================
C
C
C
SUBROUTINE CROSS(SRFC2,ISRF,KDIM1,KDIM2,NDIM,
* ERR,X1,Y1,D1,X2,Y2,D2,XA,YA,DA,XB,YB,DB,F)
EXTERNAL SRFC2
INTEGER ISRF,KDIM1,KDIM2,NDIM
REAL ERR,X1,Y1(NDIM),D1(NDIM),X2,Y2(NDIM),D2(NDIM)
REAL XA,YA(NDIM),DA(NDIM),XB,YB(NDIM),DB(NDIM),F(10)
C
C This subroutine finds the point of intersection of a curve with
C a surface (see C.R.T.5.8.4b). The curve is parametrized by an
C independent variable X and evaluated by the Hermite interpolation from
C the two given points. The surface is specified in an implicit way by
C subroutine SRFC2 which is described elsewhere, or may coincide with an
C isosurface of a computed quantity (e.g. with a coordinate plane).
C
C Input:
C SRFC2...Name of the external procedure evaluating the function
C describing the surface ISRF, for ISRF.LE.100.
C ISRF... Index of the surface.
C For ISRF.LE.100:
C The surface coincides with the zero isosurface of the
C function no. ISRF evaluated by the subroutine SRFC2.
C For ISRF.GT.100:
C The surface coincides with an isosurface Y(KDIM1)=F(1).
C KDIM1,KDIM2... Indices of quantities on which the function
C describing the surface is dependent:
C For ISRF.LE.100:
C KDIM1-th to KDIM2-th elements of arrays Y1, Y2, YA, and
C YB contain coordinates. KDIM2 is assumed to be KDIM1+1
C (2 coordinates) or KDIM1+2 (3 coordinates).
C The function describing the surface ISRF is determined
C by the subroutine SRFC2.
C For ISRF.GT.100:
C The surface coincides with an isosurface Y(KDIM1)=F(1).
C KDIM2 is assumed to equal KDIM1.
C When searching for the point of intersection, only
C quantities Y(KDIM1:KDIM2) and their derivatives are
C interpolated along the curve.
C NDIM... Dimension of arrays Y1,D1,Y2,D2,YA,DA,YB,DB.
C At the point of intersection, quantities Y(1:NDIM) and
C their derivatives are interpolated.
C ERR... Maximum error in independent variable for the
C determination of the point of intersection.
C X1... Independent variable corresponding to the first point
C given for the interpolation of the curve.
C Y1... Array containing dependent variables at point X1.
C Y1(KDIM1) to Y1(KDIM2) must contain the coordinates of
C point X1.
C D1... Array containing the derivatives of the dependent
C variables at point X1.
C X2... Independent variable corresponding to the second point
C given for the interpolation of the curve.
C Y2... Array containing dependent variables at point X2.
C Y2(KDIM1) to Y2(KDIM2) must contain the coordinates of
C point X2.
C D2... Array containing the derivatives of the dependent
C variables at point X2.
C XA... Independent variable corresponding to the point of the
C curve at which the function specifying the surface has the
C opposite sign than at X1. Then the point of intersection
C is being found between the points X1 and XA. The found
C approximations XA and XB of the point of intersection are
C situated close to the surface, XA at the same side as the
C given point X1, XB at the oposite side than the given
C point X1. If, accidentally, the function has the same
C sign at the points X1 and XA, the value at X1 is assumed
C to equal zero. Then XA=X1 and XB=X1 on output.
C YA... Array of the dimension at least NDIM. YA(KDIM1) to
C YA(KDIM2) must contain the coordinates of the point.
C Other storage locations may be undefined.
C DA... Array of the dimension at least NDIM, containing the
C derivatives of the dependent variables at point X.
C DA(KDIM1) to DA(KDIM2) must contain the derivatives of
C coordinates with respect to X, at the point XA. Other
C storage locations may be undefined.
C YB... Array of the dimension at least NDIM.
C DB... Array of the dimension at least NDIM.
C F... For ISRF.LE.100:
C Array containing the value, and at least first
C derivatives of the function ISRF specifying the surface,
C at point XA.
C For ISRF.GT.100:
C The surface coincides with an isosurface Y(KDIM1)=F(1).
C F(2) to F(10) need not be defined.
C ISRF, KDIM1, KDIM2, NDIM, ERR, X1, Y1, D1, X2, Y2, D2 are unaltered.
C
C Output:
C XA... Independent variable corresponding to the approximation of
C the point of intersection, situated close to the surface
C at the same side as the given point X1. XA=X1 if the
C function had at point X1 the same sign as F(1) on input.
C YA... Array containing dependent variables at the point XA.
C DA... Array containing the derivatives of the dependent
C variables at the point XA.
C XB... Independent variable corresponding to the approximation of
C the point of intersection, situated close to the surface
C at the oposite side than the given point X1. XB=X1 if the
C function had at point X1 the same sign as F(1) on input.
C YB... Array containing dependent variables at the point XB.
C DB... Array containing the derivatives of the dependent
C variables at the point XB.
C F... Undefined.
C
C Subroutines and external functions required:
EXTERNAL HIVD2
C SRFC2 and subsequent routines... File 'srfc.for' and subsequent
C files (like 'val.for' and 'fit.for') - dummy argument.
C HIVD2... This file.
C
C Date: 1996, July 10
C Coded by Ludek Klimes
C
C-----------------------------------------------------------------------
C
C Auxiliary storage locations:
INTEGER I,ITER
REAL FAOLD,X,FX,DFX,FB,DFB,FA,DFA,XC,XCB
*old REAL ,XCA
*!!! REAL XD,XD2,XE,AUX0,AUX1,AUX2,AUX3
*out real xam(50),fam(50),dfam(50),xbm(50),fbm(50),dfbm(50)
*out integer icross,jcross,mcross
*out data icross,jcross,mcross/0,0,0/
C
C.......................................................................
C
C Initial values:
IF(ISRF.LE.100) THEN
FA=F(1)
DFA=F(2)*DA(KDIM1)
DO 1 I=1,KDIM2-KDIM1
DFA=DFA+F(2+I)*DA(KDIM1+I)
1 CONTINUE
ELSE
FA=YA(KDIM1)-F(1)
DFA=DA(KDIM1)
END IF
FAOLD=FA
XB=X1
X =X1
DO 2 I=KDIM1,KDIM2
YB(I)=Y1(I)
DB(I)=D1(I)
2 CONTINUE
C In the beginning, both points XB and X are identical with point X1
C
C Check for zero intervals:
IF(XA.EQ.X1) THEN
DO 3 I=1,NDIM
YA(I)=Y1(I)
DA(I)=D1(I)
YB(I)=Y1(I)
DB(I)=D1(I)
3 CONTINUE
RETURN
END IF
IF(X2.EQ.X1) THEN
C 585
CALL ERROR('585 in CROSS: Zero-length interval')
C Two points X1 and X2 used for interpolation of the given
C line (e.g. the velocity isoline, or the ray), when
C searching for its intersection with the interface, are
C identical and no interpolation is possible. Likely a bug
C in the procedure calling this subroutine.
END IF
C
C Iterations:
DO 9 ITER=1,50
C
C Functional value and derivative at X:
IF(ISRF.LE.100) THEN
CALL SRFC2(ISRF,YB(KDIM1),F)
FX=F(1)
DFX=F(2)*DB(KDIM1)
DO 5 I=1,KDIM2-KDIM1
DFX=DFX+F(2+I)*DB(KDIM1+I)
5 CONTINUE
ELSE
FX=YB(KDIM1)-F(1)
DFX=DB(KDIM1)
END IF
C
C Selection of points:
IF(FX.EQ.0.) THEN
XA=X
FA=FX
ELSE IF(FA*FX.GE.0.) THEN
IF(ITER.EQ.1) THEN
C Input points X1 and XA are situated at the same side
IF(FA.EQ.0.) THEN
X=XA
FX=FA
ELSE
XA=X
FA=FX
END IF
ELSE
C Here FA, FX and FB should be non-zero due to previous checks
XA=XB
FA=FB
DFA=DFB
END IF
END IF
XB=X
FB=FX
DFB=DFX
C
*out xam(iter)=xa
*out fam(iter)=fa
*out dfam(iter)=dfa
*out xbm(iter)=xb
*out fbm(iter)=fb
*out dfbm(iter)=dfb
c
C New point or end of iterations:
IF(ABS(XB-XA).LE.ERR) THEN
C Point of intersection is found within the specified error err
C *** end of iterations ***
IF(FB*FAOLD.LT.0.) THEN
C Point XA is situated at the other side of the surface than
C the point X1 - changing XA and XB
X =XA
XA=XB
XB=X
END IF
IF((XB-XA)*(XB-X1).LT.0.) THEN
C Point XB is closer to X1 than point XA
IF(FA*FB.LT.0.) THEN
C Points XA and XB cannot be changed
C 586
CALL ERROR('586 in CROSS: Reverse order of points')
C A pair of close points XA and XB situated at different
C sides of the surface has been found, but point XA situated
C at the same side as point X1 is far from X1 than point XB.
C This error should not appear. Contact the authors.
ELSE
C Points XA and XB are situated at the same side of the
C surface (and, hopefully, FA and FB should be zero)
C - changing XA and XB
X =XA
XA=XB
XB=X
END IF
END IF
CALL HIVD2(NDIM,X1,Y1,D1,X2,Y2,D2,XA,YA,DA)
CALL HIVD2(NDIM,X1,Y1,D1,X2,Y2,D2,XB,YB,DB)
*out if(icross.eq.0) then
*out open(57,file='cross.out')
*out end if
*out icross=icross+1
*out jcross=jcross+iter-1
*out mcross=max0(mcross,iter-1)
*out if(mod(icross,100).eq.0) then
*out write(57,*) icross,jcross,mcross,float(jcross)/float(icross)
*out end if
*out if(iter.gt.20) then
*out open(58,file='error.out')
*out do 7 I=1,iter
*out write(58,*) xam(i),xbm(i),fam(i),fbm(i),dfam(i),dfbm(i)
*out7 continue
*out endfile (58)
*out backspace(58)
*out pause 'Error new in CROSS: More than 20 iterations'
*out end if
RETURN
END IF
C
cccc (a) Odstranit *old
cccc (b) Odstranit *old, odstranit *???
cccc (c) Odstranit *old, odstranit *???, odstranit *new (nedulezite)
cccc (d) Vratit *old, vratit *???, vratit *new
cccc (e) Odstranit *!!!
cccc (f) Odstranit *!!!, odstranit *old
cccc
C New approximation:
IF(MOD(ITER,2).EQ.1) THEN
C Regula falsi:
X=(FA*XB-FB*XA)/(FA-FB)
C!!! CHECKING THE ACCURACY OF THE REGULA FALSI METHOD:
*!!! IF(ITER.EQ.1) THEN
C!!! COEFFICIENTS OF THE CUBIC TAYLOR EXPANSION AT XC=(XA+XB)/2.:
*!!! XD=XB-XA
*!!! XD2=XD*XD/2.
*!!! AUX3=(DFB+DFA)/2.
*!!! AUX2=(DFB-DFA)/XD
*!!! AUX1=(FB-FA)/XD
*!!! AUX0=(FB+FA)/2.-AUX2*XD2
*!!! AUX1=1.5*AUX1-0.5*AUX3
*!!! AUX3=(AUX3-AUX1)/XD2
C!!! COEFFICIENTS OF THE QUADRATIC TAYLOR EXPANSION AT X:
*!!! XD=X-XC
*!!! XD=X-XC
*!!! XD2=XD*XD/2.
*!!! XE=SIGN(1.,AUX1)
*!!! AUX0=AUX0+AUX1*XD+AUX2*XD2+AUX3*XD*XD2/3.
*!!! AUX1=AUX1+AUX2*XD+AUX3*XD2
*!!! IF(ABS(AUX0).GT.0.5*ERR*ABS(AUX1)) THEN
C!!! THE ACCURACY SHOULD BE IMPROVED:
*!!! AUX2=AUX2+AUX3*XD
*!!! AUX3=AUX1**2-2.*AUX0*AUX2
C!!! HERE 2**(24/2)=4096 ASSUMES 24 BIT FLOATING-POINT ACCURACY
*!!! IF(4096.*ABS(AUX0*AUX2).GT.AUX1**2.AND.AUX3.GE.0.) THEN
*!!! XE=X+(XE*SQRT(AUX3)-AUX1)/AUX2
*!!! ELSE
*!!! XE=X-AUX0/AUX1
*!!! END IF
*!!! IF((XE-XA)*(XE-XB).LE.0.) THEN
*!!! X=XE
*!!! END IF
*!!! END IF
*!!! END IF
ELSE
C Modified Newton-Raphson:
XC=(XA+XB)/2.
*old XCA=XA-FA/DFA+SIGN(ERR/50.,XA-XB)
XCB=XB-FB/DFB+SIGN(ERR/50.,XA-XB)
*old IF((XCA-XC)*(XCA-XB).LT.0.) THEN
*old IF((XCB-XC)*(XCB-XB).LT.0.) THEN
*old IF(ABS(XCA-XB).LT.ABS(XCB-XB)) THEN
*old X=XCA
*old ELSE
*old X=XCB
*old END IF
*old ELSE
*old X=XCA
*old END IF
*old ELSE
IF((XCB-XC)*(XCB-XB).LT.0.) THEN
X=XCB
ELSE
X=XC
*??? IF(ABS(XCB-XB).LT.SQRT(ABS(XC-XB)*ERR)) THEN
C Attempt to halve the number of iterations
*??? X=XB+SIGN(SQRT(ABS(XC-XB)*ERR),XA-XB)
*new IF((X-XC)*(X-XB).GE.0.) THEN
*new X=XC
*new pause 'New warning in CROSS'
*new END IF
*??? END IF
END IF
*old END IF
END IF
C
C Interpolation of the ray:
CALL HIVD2(KDIM2-KDIM1+1,X1,Y1(KDIM1),D1(KDIM1),
* X2,Y2(KDIM1),D2(KDIM1),X,YB(KDIM1),DB(KDIM1))
C
9 CONTINUE
C End of loop for iterations
*out open(58,file='error.out')
*out do 8 iter=1,50
*out write(58,*) xam(iter),xbm(iter),fam(iter),fbm(iter),
*out * dfam(iter),dfbm(iter)
*out8 continue
C 584
CALL ERROR('584 in CROSS: Too many iterations')
C More than 50 iterations when determining the point of
C intersection of the ray with a surface. This may be
C caused by too small upper error bound UEB in the input
C data 'dcrt.dat' - less than rounding errors. Usually,
C this error should not appear. Contact the authors.
END
C
C=======================================================================
C
C
C
SUBROUTINE HIVD2(NDIM,X1,Y1,D1,X2,Y2,D2,X,Y,D)
INTEGER NDIM
REAL X1,Y1(NDIM),D1(NDIM),X2,Y2(NDIM),D2(NDIM)
REAL X,Y(NDIM),D(NDIM)
C
C This subroutine performs Hermite interpolation of a vector and its
C derivatives using functional values and derivatives at 2 given points.
C
C Input:
C NDIM... Dimension of arrays Y1,D1,Y2,D2,Y,D (the number of
C independent variables).
C X1... Independent variable corresponding to the first given
C point.
C Y1... Array containing functional values at the first given
C point.
C D1... Array containing the derivatives at the first given point.
C X2... Independent variable corresponding to the second given
C point.
C Y2... Array containing functional values at the second given
C point.
C D2... Array containing the derivatives at the second given point
C X... Independent variable of the point at which the
C interpolated vector is to be evaluated.
C None of the input parameters are altered.
C
C Output:
C Y... Array containing interpolated functional values at X.
C D... Array containing the derivatives of the interpolated
C functional values at X.
C
C No subroutines and external functions required.
C
C Date: 1989, October 20
C Coded by Ludek Klimes
C
C-----------------------------------------------------------------------
C
C Auxiliary storage locations:
INTEGER I
REAL A,B,A1,A2,B1,B2,DA1,DB1,DB2
C
C Substitutions:
A=(X-X2)/(X1-X2)
B=(A-1.)*A
C
C Basic functions:
A1=(A-B-B)*A
A2=1.-A1
B1=B*(X-X2)
B2=B*(X-X1)
C Derivatives of basic functions:
DA1=6.*B/(X2-X1)
DB1=3.*B+A
DB2=3.*B+1.-A
C
C Interpolation:
DO 1 I=1,NDIM
Y(I)=A1*Y1(I)+A2*Y2(I)+B1*D1(I)+B2*D2(I)
D(I)=DA1*(Y1(I)-Y2(I))+DB1*D1(I)+DB2*D2(I)
1 CONTINUE
C
RETURN
END
C
C=======================================================================
C
C
C
SUBROUTINE SMVPRD(G,A1,A2,A3,B1,B2,B3)
REAL G(6),A1,A2,A3,B1,B2,B3
C
C This subroutine is designed to evaluate symmetric matrix by vector
C product. It may be, e.g., called after the invocation of the METRIC
C subroutine to transform the covariant vectors to the contravariant
C ones and vice versa.
C
C Input:
C G... Array containing components G11, G12, G22, G13, G23, G33
C of the 3*3 symmetric matrix.
C A1,A2,A3... Components of the 3-vector.
C
C Output:
C B1,B2,B3... Components of vector B=G*A.
C
C No subroutines and external functions required.
C
C Date: 1989, September 5
C Coded by Ludek Klimes
C
C-----------------------------------------------------------------------
C
B1=G(1)*A1+G(2)*A2+G(4)*A3
B2=G(2)*A1+G(3)*A2+G(5)*A3
B3=G(4)*A1+G(5)*A2+G(6)*A3
RETURN
END
C
C=======================================================================
C