C
C Program FDMOD to generate finite-difference effective parameters
C (harmonic averages of elastic parameters) in 2-D models specified in
C terms of homogeneous convex polygons
C
C Version: 5.30
C Date: 1999, April 2
C
C Program written by Jiri Zahradnik
C Department of Geophysics, Charles University Prague
C V Holesovickach 2, 180 00 Praha 8, Czech Republic
C Tel.: +420-2-21912546, Fax: +420-2-21912555
C E-mail: jz@karel.troja.mff.cuni.cz
C Data input and output modified by Ludek Klimes
C
C.......................................................................
C
C Contents:
C Description of the polygonal model
C Description of data files
C List of external procedures
C
C For the description of effective elastic parameters refer to file
C modfd.for.
C
C.......................................................................
C
C Description of the polygonal model:
C
C The medium is composed of homogeneous polygonal blocks. The
C blocks do not overlap each other and cover the computational region.
C Convex blocks only are allowed (internal angles.le.180 degrees).
C For this reason even some physically homogeneous parts
C of the model must be subdivided in several (formal) blocks.
C Numbering of the blocks is arbitrary.
C Each block is characterized by the physical coordinates of its
C nodes (in meters), S-wave velocity (m/s), P/S velocity ratio,
C and density (kg/m**3). The nodes are numbered counterclockwise.
C Also specified for each block segment is the serial number of the
C neighbouring block.
C See the accompanying example, or ask the author of the program
C for more details.
C
C Description and remarks on FD method
C
C.......................................................................
C
C Description of data files:
C
C Main input data read from the * input device:
C The data are read in by the list directed input (free format), by
C a single READ statement. The data consist of character strings
C which have to be enclosed in apostrophes. Note that the
C interactive * external unit may be piped or redirected to a file.
C The following items are read:
C (1) 'FDSEP' /
C 'FDSEP'... String in apostrophes containing the name of the main
C input data file with FD parameters in the SEP format.
C The file specifies the filename of the polygonal model,
C dimensions of the grid of N1*N2*N3 gridpoints, the form
C and names of the files with effective elastic parameters,
C etc.
C /... It is recommended to terminate these data by a slash.
C Default: 'FDSEP'='fd.h'.
C
C Data file 'FDSEP' has the form of the SEP (Stanford Exploration
C Project) parameter file:
C All the data are specified in the form of PARAMETER=VALUE, e.g.
C N1=50, with PARAMETER directly preceding = without intervening
C spaces and with VALUE directly following = without intervening
C spaces. The PARAMETER=VALUE couple must be delimited by a space
C or comma from both sides.
C The PARAMETER string is not case-sensitive.
C PARAMETER= followed by a space resets the default parameter value.
C All other text in the input files is ignored. The file thus may
C contain unused data or comments without leading comment character.
C Everything between comment character # and the end of the
C respective line is ignored, too.
C The PARAMETER=VALUE couples may be specified in any order.
C The last appearance takes precedence.
C Data specifying the model by means of the MODEL package:
C FDMOD='string'... Name of the input data file describing a 2-D
C model composed of homogeneous convex polygons.
C The data file contains the name of the model, the number
C of blocks, and for each block:
C number of edges of the block, shear-wave velocity
C (e.g., in m/s) inside the block, P/S velocity ratio inside
C the block, density (e.g., in kg/m**3) inside the block,
C x and z coordinates (e.g., in m) of the initial point of
C segment, sequential number of the neighbouring block
C (outside put 0).
C Parameter FDMOD is required by this program (but no other
C one).
C Example of data set FDMOD
C Default: FDMOD=' '
C This program understands the following parameters common to nearly all
C programs dealing with SEP-like gridded data formats:
C N1=positive integer... Number of gridpoints of the basic grid
C along the X1 axis. Default: N1=1
C N3=positive integer... Number of gridpoints of the basic grid
C along the X3 axis. Default: N3=1
C O1=real... X1 coordinate of the origin of the grid. Default: O1=0.
C O3=real... X3 coordinate of the origin of the grid.
C Note that FD program 'fd2d.for' assumes the free Earth
C surface at vertical coordinate X3=O3.
C Default: O3=0.
C D1=real... Grid spacing along the X1 axis. Default: D1=1.
C D3=real... Grid spacing along the X3 axis. Default: D3=1.
C The grid intervals may also be negative.
C And the following parameters specific to effective-parameter FD codes:
C FORM='string'... Form of the output files:
C FORM='formatted': Formatted ASCII output files,
C FORM='unformatted': Unformatted output files.
C A11='string', B11='string', C11='string'... Strings in apostrophes
C containing the names of the output files with (N1-1)*N2*N3
C values of the elastic parameters averaged in the direction
C the X1 axis, along the gridlines.
C Defaults: A11=' ', B11=' ', C11=' '.
C A33='string', B33='string', C33='string'... Strings in apostrophes
C containing the names of the output files with N1*N2*(N3-1)
C values of the elastic parameters averaged in the direction
C the X3 axis, along the gridlines.
C Defaults: A33=' ', B33=' ', C33=' '.
C A13='string', B13='string', C13='string'... Strings in apostrophes
C containing the names of the output files with
C (N1-1)*N2*(N3-1) values of the elastic parameters averaged
C in the direction the X1 axis, along the gridlines shifted
C half a grid interval in the direction of the X3 axis.
C Defaults: A13=' ', B13=' ', C13=' '.
C A31='string', B31='string', C31='string'... Strings in apostrophes
C containing the names of the output files with
C (N1-1)*N2*(N3-1) values of the elastic parameters averaged
C in the direction the X3 axis, along the gridlines shifted
C half a grid interval in the direction of the X1 axis.
C Defaults: A31=' ', B31=' ', C31=' '.
C DEN='string'... String in apostrophes containing the name of the
C output ASCII file with N1*N2*N3 grid values of the
C density.
C Default: DEN=' '.
C QFC='string'... String in apostrophes containing the name of the
C output ASCII file with N1*N2*N3 grid values of the P-wave
C quality factor.
C Default: QFC=' '
C Example of data set FDSEP
C
C.......................................................................
C
C This file consists of the following external procedures:
C FDMOD...Main program allocating the memory for FDPAR.
C FDMOD
C FDPAR...Subroutine to generate the parameters (originally the main
C program).
C FDPAR
C XLEG... Subroutine for computation of effective (mean) squared
C velocities for a grid leg.
C XLEG
C GRPT... Subroutine for location of grid point (XPT,ZPT) with
C respect to block IBL.
C GRPT
C TWOPT...Subroutine for location of a grid leg with respect to
C boundary of block IB.
C TWOPT
C
C=======================================================================
C
C
C
PROGRAM FDMOD
C
C Main program allocating the memory.
C
C Subroutines and external functions required:
EXTERNAL FDPAR,RSEP1,RSEP3I
C FDPAR...This file.
C RSEP1,RSEP3I... File 'sep.for'.
C Note that the above subroutines reference many other external
C procedures from various subroutine files. These indirectly
C referenced procedures are not named here, but are listed in the
C particular subroutine files.
C
C-----------------------------------------------------------------------
C
C Common block /RAMC/ to allocate large array RAM:
INCLUDE 'ram.inc'
C ram.inc
C
C-----------------------------------------------------------------------
C
C Input data filenames and logical unit numbers:
INTEGER LU
PARAMETER (LU=1)
CHARACTER*80 FSEP
C LU... Logical unit number to be used to read and write all data
C files.
C FSEP... The name of the input data file with FD parameters in SEP
C format.
C
INTEGER N1,N3,N,NR,NS,NGRID,I1,I2,I3,I4
C
C.......................................................................
C
C Main input data:
C Default:
FSEP='fd.h'
C Reading main input data:
WRITE(*,'(A)') ' FDMOD: Enter name of input SEP file [''fd.h'']: '
READ (*,*) FSEP
WRITE(*,'(A)') '+FDMOD: Working... '
C
C Reading all the data from input SEP parameter file:
CALL RSEP1(LU1,FSEP)
C
C Data specifying numbers of gridpoints:
CALL RSEP3I('N1' ,N1 ,1)
CALL RSEP3I('N2' ,N3 ,1)
C
C Allocating the memory in array RAM:
NGRID=15*N1*N3
IF(NGRID.GT.MRAM) THEN
C FDMOD-01
CALL ERROR('FDMOD-01: Small dimension MRAM in ram.inc')
C Dimension MRAM must be at least
C 15*N1*N3 ,
C where N1 and N3 are parameters in the main input file.
END IF
N =N1*N3
C
CALL FDPAR(LU,N,
* RAM( 1),RAM( N + 1),RAM( 2*N + 1),RAM( 3*N + 1),
* RAM( 4*N + 1),RAM( 5*N + 1),RAM( 6*N + 1),RAM( 7*N + 1),
* RAM( 8*N + 1),RAM( 9*N + 1),RAM(10*N + 1),RAM(11*N + 1),
* RAM(12*N + 1),RAM(13*N + 1),RAM(14*N + 1))
C
WRITE(*,'(A)') '+FDMOD: Done. '
STOP
END
C
C=======================================================================
C
C
C
SUBROUTINE FDPAR(LU,KLMAX,
* AHS,BHS,CHS,AVS,BVS,CVS,
* AHL,BHL,CHL,AVL,BVL,CVL,DEN,QFC,WORK)
INTEGER LU,KLMAX
REAL AHS(KLMAX),BHS(KLMAX),CHS(KLMAX)
REAL AVS(KLMAX),BVS(KLMAX),CVS(KLMAX)
REAL AHL(KLMAX),BHL(KLMAX),CHL(KLMAX)
REAL AVL(KLMAX),BVL(KLMAX),CVL(KLMAX)
REAL DEN(KLMAX),QFC(KLMAX),WORK(KLMAX)
C
C Subroutine (originally main program) to read the input data and
C generate finite-difference effective parameters.
C
C Input:
C LU... Logical unit number to be used to read and write data
C files.
C KLMAX...Array dimension.
C AHL,BHL,CHL,
C AVL,BVL,CVL,
C AHS,BHS,CHS,
C AVS,BVS,CVS,
C DEN,QFC...arrays with effective parameters
C WORK... temporary working array
C
C No output.
C
C Subroutines and external functions required:
EXTERNAL XLEG,GRPT,TWOPT
EXTERNAL RSEP3T,FDGRID,FDOUT1
C XLEG... This file.
C GRPT... This file.
C TWOPT.. This file.
C RSEP3T..File 'sep.for'.
C FDGRID..File 'fdaux.for'.
C FDOUT1..File 'fdaux.for'.
C Note that the above subroutines reference many other external
C procedures from various subroutine files. These indirectly
C referenced procedures are not named here, but are listed in the
C particular subroutine files.
C
C
C-----------------------------------------------------------------------
C
C Storage locations:
C
C Maximum array dimensions:
PARAMETER (MAXBL=50,MAXEDG=10)
C MAXBL.. Max number of polygonal blocks.
C MAXEDG..Max number of edges for any block.
C
C Arrays:
DIMENSION NOED(0:MAXBL),VS(0:MAXBL),PSRAT(0:MAXBL),HU(0:MAXBL)
DIMENSION XED(MAXEDG,MAXBL),ZED(MAXEDG,MAXBL),NOVIC(MAXEDG,MAXBL)
C
COMMON /BLO1/ NOBL,NOED,VS,PSRAT,DX,HU
COMMON /BLO2/ XED,ZED,NOVIC
C NOBL... Number of blocks.
C NOED... Number of edges of the block.
C VS... Shear-wave velocity (m/s) inside the block.
C PSRAT.. P/S velocity ratio inside the block.
C HU... Density (kg/m**3) inside the block.
C XED,ZED. X and Z coordinates (m) of the initial point of segment.
C NOVIC... Serial number of the neigh. block (outside put 0).
C
CHARACTER*80 FMOD
CHARACTER *5 NAMDUM
C FMOD... The name of the input data file with model parameters in
C list directed (free) format.
C NAMDUM... Auxiliary storage location.
C
C.......................................................................
C
C Data specifying grid dimensions
CALL FDGRID(KLMAX,KLMAX,KLMAX,NX,NZ,DX)
C
C Reading data describing a model composed of homogeneous polygons:
CALL RSEP3T('FDMOD',FMOD,' ')
OPEN(LU,FILE=FMOD,STATUS='OLD')
C
READ(1,'(1X,A5)') NAMDUM
C READ(1,'(25X,I5)') NSYM
NSYM=0
C
READ(1,'(25X,I5)') NOBL
DO 150 I=1,NOBL
READ(1,'(25X,I5,3F10.0)') NOED(I),VS(I),PSRAT(I),HU(I)
DO 100 J=1,NOED(I)
READ(1,'(25X,2F10.0,I5)') XED(J,I),ZED(J,I),NOVIC(J,I)
100 CONTINUE
150 CONTINUE
C
WRITE(*,'(A)') '+FDMOD: Computing effective parameters '
C
C Auxiliary parameters.
LACC=0
C
DO 310 I=1,NOBL
C Attention: Now VS no more contains shear velocity but rigidity
C and PSRAT is squared Vp/Vs ratio. The corresponding
C change was made in FLERIB,FBOB,FCORNB.
C VS(I)=VS(I)*VS(I)
VS(I)=VS(I)*VS(I)*HU(I)
PSRAT(I)=PSRAT(I)*PSRAT(I)
310 CONTINUE
C
NOED(0)=0
VS(0)=0.
PSRAT(0)=1.
C
DXA=DX
C
C Vertical and horizontal parameters of medium for INTERlegs
C (i.e. for legs between grid lines)
NPUP=(NX-1)*(NZ-1)
DO 430 IPU=1,NPUP
NVER=NZ-1
NP=IFIX((IPU-0.01)/NVER)
XSOUR=DX/2.+FLOAT(NP)*DX
NPOR=IPU-NP*NVER
ZSOUR=FLOAT(NPOR-1)*DX
CALL XLEG(0,XSOUR,ZSOUR,DXA,AL,BE,RH)
AVS(IPU)=AL
BVS(IPU)=BE
CVS(IPU)=AL-2.*BE
NHOR=NZ-1
NP=IFIX((IPU-0.01)/NHOR)
XSOUR=FLOAT(NP)*DX
NPOR=IPU-NP*NHOR
ZSOUR=DX/2.+FLOAT(NPOR-1)*DX
CALL XLEG(1,XSOUR,ZSOUR,DXA,AL,BE,RH)
AHS(IPU)=AL
BHS(IPU)=BE
CHS(IPU)=AL-2.*BE
430 CONTINUE
C
C Vertical parameters of medium for LARGE squares (= grid legs)
C (for ignoring detailed computations, choose LACC=0)
DO 450 K=2,NX-1
XOLD=FLOAT(K-1)*DX
LAU=(K-1)*NZ
XNZ=FLOAT(NZ)
DO 400 L=1,NZ-1
ICEN=L+LAU
JCEN=ICEN-IFIX(FLOAT(ICEN)/XNZ)
ZOLD=FLOAT(L-1)*DX
IF(L.LT.LACC) THEN
CALL XLEG(0,XOLD,ZOLD,DXA/2.,AL1,BE1,RH1)
ZNEW=ZOLD+DX/2.
CALL XLEG(0,XOLD,ZNEW,DXA/2.,AL2,BE2,RH2)
AL=(AL1+AL2)/2.
BE=(BE1+BE2)/2.
ELSE
CALL XLEG(0,XOLD,ZOLD,DXA,AL,BE,RH)
ENDIF
AVL(JCEN)=AL
BVL(JCEN)=BE
CVL(JCEN)=AL-2.*BE
400 CONTINUE
450 CONTINUE
C
C Horizontal parameters of medium for LARGE squares (=grid legs)
C (incl. density)
DO 550 K=1,NX-1
XOLD=FLOAT(K-1)*DX
LAU=(K-1)*NZ
DO 500 L=1,NZ-1
ICEN=L+LAU
ZOLD=FLOAT(L-1)*DX
IF(L.LE.LACC) THEN
CALL XLEG(1,XOLD,ZOLD,DXA/2.,AL1,BE1,RH1)
XNEW=XOLD+DX/2.
CALL XLEG(1,XNEW,ZOLD,DXA/2.,AL2,BE2,RH2)
AL=(AL1+AL2)/2.
BE=(BE1+BE2)/2.
ELSE
CALL XLEG(1,XOLD,ZOLD,DXA,AL,BE,RH)
ENDIF
AHL(ICEN)=AL
BHL(ICEN)=BE
CHL(ICEN)=AL-2.*BE
DEN(ICEN)=RH
500 CONTINUE
550 CONTINUE
C
C Vertical and horizontal parameters for legs in the strip between
C the inner and outer nonreflecting boundaries (a continuation)
C (incl. density for horizontal legs)
DO 600 L=1,NZ-1
ICEN=L
ICEN2=ICEN+NZ
JCEN=L
JCEN2=JCEN+NZ-1
AVL(JCEN)=AVL(JCEN2)
BVL(JCEN)=BVL(JCEN2)
CVL(JCEN)=CVL(JCEN2)
600 CONTINUE
LAU=(NX-1)*NZ
DO 610 L=1,NZ-1
ICEN=L+LAU
JCEN=ICEN-IFIX(FLOAT(ICEN)/FLOAT(NZ))
JCEN2=JCEN-NZ+1
AVL(JCEN)=AVL(JCEN2)
BVL(JCEN)=BVL(JCEN2)
CVL(JCEN)=CVL(JCEN2)
610 CONTINUE
DO 620 K=1,NX-1
ICEN=K*NZ
ICEN2=ICEN-1
AHL(ICEN)=AHL(ICEN2)
BHL(ICEN)=BHL(ICEN2)
CHL(ICEN)=CHL(ICEN2)
DEN(ICEN)=DEN(ICEN2)
620 CONTINUE
C
C Halving the density at the free surface IZ=1:
DO 70 I=1,NX*NZ,NZ
DEN(I)=0.5*DEN(I)
70 CONTINUE
C
C No attenuation is considered in this version
DO 80 I=1,NX*NZ
QFC(I)=0.
80 CONTINUE
C
C Writing the gridded effective elastic parameters:
CALL FDOUT1(LU,NX-1,NZ ,1.,'A11',AHL,WORK)
CALL FDOUT1(LU,NX-1,NZ ,1.,'B11',BHL,WORK)
CALL FDOUT1(LU,NX-1,NZ ,1.,'C11',CHL,WORK)
CALL FDOUT1(LU,NX ,NZ-1,1.,'A33',AVL,WORK)
CALL FDOUT1(LU,NX ,NZ-1,1.,'B33',BVL,WORK)
CALL FDOUT1(LU,NX ,NZ-1,1.,'C33',CVL,WORK)
CALL FDOUT1(LU,NX-1,NZ-1,1.,'A13',AHS,WORK)
CALL FDOUT1(LU,NX-1,NZ-1,1.,'B13',BHS,WORK)
CALL FDOUT1(LU,NX-1,NZ-1,1.,'C13',CHS,WORK)
CALL FDOUT1(LU,NX-1,NZ-1,1.,'A31',AVS,WORK)
CALL FDOUT1(LU,NX-1,NZ-1,1.,'B31',BVS,WORK)
CALL FDOUT1(LU,NX-1,NZ-1,1.,'C31',CVS,WORK)
CALL FDOUT1(LU,NX ,NZ ,1.,'DEN',DEN,WORK)
CALL FDOUT1(LU,NX ,NZ ,1.,'QFC',QFC,WORK)
C
RETURN
END
C
C=======================================================================
C
C
C
SUBROUTINE XLEG(KEY,XPT,ZPT,DEL,ALF,BET,RHO)
C
C Purpose:
C Effective (mean) squared velocities for a grid leg
C
C Input:
C KEY=0.....vertical leg
C =1.....horizontal leg
C XPT,ZPT...x,z coordinates of the grid point
C DEL.......length of the leg
C
C Output:
C ALF,BET...P and S squared velocities for the leg
C
C
DIMENSION NOED(0:50),VS(0:50),PSRAT(0:50),HU(0:50)
DIMENSION XED(10,50),ZED(10,50),NOVIC(10,50)
COMMON /BLO1/ NOBL,NOED,VS,PSRAT,DX,HU
COMMON /BLO2/ XED,ZED,NOVIC
C
RHO=0.
C
C An artificial shortening of the leg to avoid numerical problems
C !!!!!!Some models possible with 0.01 instead of this 0.03!!!!!!
C
DELSA=DEL-0.03*DEL
cc DELSA=DEL
cc DELSA=DEL-0.0001*DEL
C
C Location of the grid point with respect to a block
C
DO 100 J=1,NOBL
DIST=0.
CALL GRPT(XPT,ZPT,J,IPRES,IVIC,DIST,ISEG,IBLVC,IORT)
DIST=DIST/DELSA
IF(IPRES.EQ.0) GOTO 100
IBL=J
GOTO 200
100 CONTINUE
WRITE(*,'(A,2F10.3/A)')
* '+FDMOD: Gridpoint not located successfully at x,z=',XPT,ZPT,' '
200 CONTINUE
IF(IPRES.EQ.2) GOTO 1000
C
C The grid point inside block IBL
C
RHO=HU(IBL)
CALL TWOPT(XPT,ZPT,IBL,DELSA,KEY,0,ISG,IVC,PART)
IF(ISG.NE.0) GOTO 400
C
C No intersection of the leg with any boundary segment
C
300 BET=VS(IBL)
ALF=BET*PSRAT(IBL)
RETURN
C
C The leg is intersecting segment ISG
C Locating the end point of the leg with respect to block IVC
C
400 IF(KEY.EQ.0) THEN
XEND=XPT
ZEND=ZPT+DELSA
ELSE
XEND=XPT+DELSA
ZEND=ZPT
ENDIF
DIS2=0.
CALL GRPT(XEND,ZEND,IVC,IPR2,IVI2,DIS2,ISE2,IBL2,IOR2)
DIS2=DIS2/DELSA
IF(IPR2.EQ.0) GOTO 600
IF(IPR2.EQ.1) GOTO 450
IF(IPR2.EQ.2.AND.KEY.EQ.0.AND.IOR2.EQ.0) GOTO 500
IF(IPR2.EQ.2.AND.KEY.EQ.1.AND.IOR2.EQ.1) GOTO 500
C
C The end point located inside block IVC
C (or on its boundary segment not coinciding with the leg)
C
450 VSIN=VS(IBL)
VSOU=VS(IVC)
VPIN=VSIN*PSRAT(IBL)
VPOU=VSOU*PSRAT(IVC)
c BET=PART*VSIN+(1.-PART)*VSOU
c ALF=PART*VPIN+(1.-PART)*VPOU
BET=1./(PART/VSIN+(1.-PART)/VSOU)
ALF=1./(PART/VPIN+(1.-PART)/VPOU)
RETURN
C
C The end point located on a vertical/horizontal boundary
C between blocks IVC and IBL2
C
500 VSIN=VS(IBL)
VSOU1=VS(IVC)
VSOU2=VS(IBL2)
VSOU=(VSOU1+VSOU2)/2.
VPIN=VSIN*PSRAT(IBL)
VPOU=(VSOU1*PSRAT(IVC)+VSOU2*PSRAT(IBL2))/2.
c BET=PART*VSIN+(1.-PART)*VSOU
c ALF=PART*VPIN+(1.-PART)*VPOU
BET=1./(PART/VSIN+(1.-PART)/VSOU)
ALF=1./(PART/VPIN+(1.-PART)/VPOU)
RETURN
C
C The end point located outside block IVC,inside block IBLNEW
C
600 DO 700 J=1,NOBL
CALL GRPT(XEND,ZEND,J,IPR3,IVI3,DIS3,ISE3,IBL3,IOR3)
IF(IPR3.EQ.0) GOTO 700
IBLNEW=J
GOTO 800
700 CONTINUE
WRITE(*,'(A,2F10.3/A)')
*'+FDMOD: Gridpoint not located successfully at x,z=',XEND,ZEND,' '
C
C The end point in block IBLNEW, the leg in blocks IBL, IVC, IBLNEW
C
800 CALL TWOPT(XEND,ZEND,IBLNEW,DELSA,KEY,1,ISG2,IVC2, PART2)
VSIN=VS(IBL)
VSOU1=VS(IVC)
VSOU2=VS(IBLNEW)
VPIN=VSIN*PSRAT(IBL)
VPOU1=VSOU1*PSRAT(IVC)
VPOU2=VSOU2*PSRAT(IBLNEW)
c BET=PART*VSIN+(1.-PART-PART2)*VSOU1+PART2*VSOU2
c ALF=PART*VPIN+(1.-PART-PART2)*VPOU1+PART2*VPOU2
BET=1./(PART/VSIN+(1.-PART-PART2)/VSOU1+PART2/VSOU2)
ALF=1./(PART/VPIN+(1.-PART-PART2)/VPOU1+PART2/VPOU2)
RETURN
C
C The grid point located on the boundary of block IBL
C (on segment ISEG, neighbouring to block IBLVC)
C Locating the end point with respect to block IBL
C
1000 CONTINUE
if(ibl.eq.0) rho=hu(iblvc)
if(iblvc.eq.0) rho=hu(ibl)
if(ibl.ne.0.and.iblvc.ne.0) RHO=(HU(IBL)+HU(IBLVC))/2.
IF(KEY.EQ.0) THEN
XEND=XPT
ZEND=ZPT+DELSA
ELSE
XEND=XPT+DELSA
ZEND=ZPT
ENDIF
DIS2=0.
CALL GRPT(XEND,ZEND,IBL,IPR2,IVI2,DIS2,ISE2,IBL2,IOR2)
DIS2=DIS2/DELSA
IF(IPR2.EQ.0) GOTO 1800
IF(IPR2.EQ.1) GOTO 1600
IF(IPR2.EQ.2.AND.KEY.EQ.0.AND.IOR2.EQ.0) GOTO 1700
IF(IPR2.EQ.2.AND.KEY.EQ.1.AND.IOR2.EQ.1) GOTO 1700
C
C The end point located inside block IBL
C (or on its boundary segment not coinciding with the leg)
C
1600 BET=VS(IBL)
ALF=BET*PSRAT(IBL)
RETURN
C
C The leg is coinciding with a segment
C
1700 VSIN=VS(IBL)
C VSOU=VS(IBLVC)
VSOU=VS(IBL2)
VPIN=VSIN*PSRAT(IBL)
C VPOU=VSOU*PSRAT(IBLVC)
VPOU=VSOU*PSRAT(IBL2)
BET=(VSIN+VSOU)/2.
ALF=(VPIN+VPOU)/2.
RETURN
C
C The end point located outside block IBL
C Locating the end point with respect to block IBLVC
C
1800 DIS3=0.
CALL GRPT(XEND,ZEND,IBLVC,IPR3,IVI3,DIS3,ISE3,IBL3,IOR3)
DIS3=DIS3/DELSA
IF(IPR3.EQ.0) GOTO 2100
IF(IPR3.EQ.1) GOTO 1850
IF(IPR3.EQ.2) GOTO 1900
C
C The end point located inside block IBLVC
C
1850 BET=VS(IBLVC)
ALF=BET*PSRAT(IBLVC)
RETURN
C
C The end point located on segment ISE3 of block IBLVC
C
1900 IF(KEY.EQ.0.AND.IOR3.EQ.0) GOTO 2000
IF(KEY.EQ.1.AND.IOR3.EQ.1) GOTO 2000
C
1950 BET=VS(IBLVC)
ALF=BET*PSRAT(IBLVC)
RETURN
C
C The end point located on a vertical/horizontal boundary
C between blocks IBLVC and IBL3
C
2000 VSIN=VS(IBL)
VSOU=(VS(IBLVC)+VS(IBL3))/2.
VPIN=VS(IBL)*PSRAT(IBL)
VPOU=(VS(IBLVC)*PSRAT(IBLVC)+VS(IBL3)*PSRAT(IBL3))/2.
c BET=DIST*VSIN+(1.-DIST)*VSOU
c ALF=DIST*VPIN+(1.-DIST)*VPOU
BET=1./(DIST/VSIN+(1.-DIST)/VSOU)
ALF=1./(DIST/VPIN+(1.-DIST)/VPOU)
RETURN
C
C The end point located outside block IBLVC, inside block IBLNEW
C
2100 DO 2150 J=1,NOBL
DIS5=0.
CALL GRPT(XEND,ZEND,J,IPR5,IVI5,DIS5,ISE5,IBL5,IOR5)
DIS5=DIS5/DELSA
IF(IPR5.EQ.0) GOTO 2150
IBLNEW=J
GOTO 2170
2150 CONTINUE
2170 CONTINUE
IF(KEY.EQ.0.AND.IORT.EQ.0) GOTO 2200
IF(KEY.EQ.1.AND.IORT.EQ.1) GOTO 2200
GOTO 2400
2200 IF(IPR5.EQ.1) GOTO 2300
IF(IPR5.EQ.2) GOTO 2350
C
C The grid point located on a vertical/horizontal boundary
C between blocks IBL and IBLVC
C The end point inside block IBLNEW
C
2300 VSIN=(VS(IBL)+VS(IBLVC))/2.
VSOU=VS(IBLNEW)
VPIN=(VS(IBL)*PSRAT(IBL)+VS(IBLVC)*PSRAT(IBLVC))/2.
VPOU=VSOU*PSRAT(IBLNEW)
c BET=DIST*VSIN+(1.-DIST)*VSOU
c ALF=DIST*VPIN+(1.-DIST)*VPOU
BET=1./(DIST/VSIN+(1.-DIST)/VSOU)
ALF=1./(DIST/VPIN+(1.-DIST)/VPOU)
RETURN
C
C The grid point located on a vertical/horizontal boundary
C between blocks IBL and IBLVC
C The end point located on a vertical/horizontal boundary
C between blocks IBLNEW and IBL5
C
2350 VSIN=(VS(IBL)+VS(IBLVC))/2.
VSOU=(VS(IBLNEW)+VS(IBL5))/2.
VPIN=(VS(IBL)*PSRAT(IBL)+VS(IBLVC)*PSRAT(IBLVC))/2.
VPOU=(VS(IBLNEW)*PSRAT(IBLNEW)+VS(IBL5)*PSRAT(IBL5))/2.
c BET=DIST*VSIN+(1.-DIST)*VSOU
c ALF=DIST*VPIN+(1.-DIST)*VPOU
BET=1./(DIST/VSIN+(1.-DIST)/VSOU)
ALF=1./(DIST/VPIN+(1.-DIST)/VPOU)
RETURN
C
C The end point located inside block IBLNEW,
C the leg in blocks IBLNEW and IVC4 (where IVC4=IBL or IBLVC)
C
2400 IF(IPR5.EQ.1) GOTO 2600
IF(IPR5.EQ.2.AND.KEY.EQ.0.AND.IOR5.EQ.0) GOTO 2800
IF(IPR5.EQ.2.AND.KEY.EQ.1.AND.IOR5.EQ.1) GOTO 2800
2600 CALL TWOPT(XEND,ZEND,IBLNEW,DELSA,KEY,1,ISG4,IVC4,PART4)
VSIN=VS(IVC4)
VSOU=VS(IBLNEW)
VPIN=VSIN*PSRAT(IVC4)
VPOU=VSOU*PSRAT(IBLNEW)
c BET=(1.-PART4)*VSIN+PART4*VSOU
c ALF=(1.-PART4)*VPIN+PART4*VPOU
c some models with inclined boundaries ending at left or right sides
c require the following modification:
c if(vsin.eq.0.) then
c BET=1./(PART4/VSOU)
c ALF=1./(PART4/VPOU)
c RETURN
c endif
BET=1./((1.-PART4)/VSIN+PART4/VSOU)
ALF=1./((1.-PART4)/VPIN+PART4/VPOU)
RETURN
2800 CALL TWOPT(XEND,ZEND,IBL,DELSA,KEY,1,ISG5,IVC5,PART5)
IF(ISG5.NE.0) THEN
IVXX=IBL
PARTX=PART5
GOTO 2900
ELSE
CALL TWOPT(XEND,ZEND,IBLVC,DELSA,KEY,1,ISG6,IVC6,PART6)
IF(ISG6.NE.0) THEN
IVXX=IBLVC
PARTX=PART6
GOTO 2900
ELSE
c
2850 BET=(VS(IBLNEW)+VS(IBL5))/2.
ALF=(VS(IBLNEW)*PSRAT(IBLNEW)+VS(IBL5)*PSRAT(IBL5))/2.
RETURN
ENDIF
ENDIF
2900 VSIN=VS(IVXX)
VSOU=(VS(IBLNEW)+VS(IBL5))/2.
VPIN=VSIN*PSRAT(IVXX)
VPOU=(VS(IBLNEW)*PSRAT(IBLNEW)+VS(IBL5)*PSRAT(IBL5))/2.
c BET=(1.-PARTX)*VSIN+PARTX*VSOU
c ALF=(1.-PARTX)*VPIN+PARTX*VPOU
BET=1./((1.-PARTX)/VSIN+PARTX/VSOU)
ALF=1./((1.-PARTX)/VPIN+PARTX/VPOU)
RETURN
END
C DEBUG SUBCHK
C END DEBUG
C
C=======================================================================
C
C
C
SUBROUTINE GRPT(XPT,ZPT,IBL,IPRES,IVIC,DIST,ISEG,IBLVC,IORT)
C
C Purpose:
C Location of grid point (XPT,ZPT) with respect to block IBL
C
C Input:
C XPT,ZPT......x,z coordinates of the grid point
C IBL..........the block to be tested
C
C Output:
C IPRES=0......the grid point located outside the block
C =1......the grid point located inside the block
C =2......the grid point located on the block boundary
C
C IVIC=0.......the grid point not in vicinity (.LT.DX) of any edge
C .ne.0.......the grid point in vicinity of edge IVIC
C
C DIST.........distance from the edge (for IVIC.ne.0)
C
C ISEG.........the grid point on segment ISEG (for IPRES=2)
C
C IBLVC........the block neighbouring to ISEG (for IPRES=2)
C
C IORT=0.......a vertical segment (for IPRES=2)
C =1.......a horizontal segment (for IPRES=2)
C =2.......an oblique segment (for IPRES=2)
C
C
DIMENSION NOED(0:50),VS(0:50),PSRAT(0:50),HU(0:50)
DIMENSION XED(10,50),ZED(10,50),NOVIC(10,50)
COMMON /BLO1/ NOBL,NOED,VS,PSRAT,DX,HU
COMMON /BLO2/ XED,ZED,NOVIC
C
I=IBL
IF(I.EQ.0) THEN
IPRES=0
RETURN
ENDIF
NEDG=NOED(I)
DO 200 J=1,NEDG
C
C Unit position vector (PX,PZ) of grid point (XPT,ZPT)
C with respect to the origin of J-th segment of I-th block
C
PX=XPT-XED(J,I)
PZ=ZPT-ZED(J,I)
SIZ=SQRT(PX*PX+PZ*PZ)
IF(ABS(SIZ).LT.0.00001) GOTO 300
PX=PX/SIZ
PZ=PZ/SIZ
C
C Unit vector (BX,BZ) of J-th segment of I-th block
C
IF(J.LT.NEDG) THEN
BX=XED(J+1,I)-XED(J,I)
BZ=ZED(J+1,I)-ZED(J,I)
ELSE
BX=XED(1,I)-XED(J,I)
BZ=ZED(1,I)-ZED(J,I)
ENDIF
SIZ=SQRT(BX*BX+BZ*BZ)
BX=BX/SIZ
BZ=BZ/SIZ
C
C Y-component (=PROD) of the vector product (PX,PZ)x(BX,BZ)
C
PROD=PZ*BX-PX*BZ
IF(PROD.LT.-0.00001) GOTO 200
IF(ABS(PROD).LT.0.00001) GOTO 300
C
C The grid point located outside the block
C
250 IPRES=0
GOTO 600
C
C The grid point possibly located on J-th segment
C
300 IPRES=2
ISEG=J
IBLVC=NOVIC(J,I)
C
C End points of J-th segment, orientation of the segment
C
X1=XED(J,I)
Z1=ZED(J,I)
IF(J.LT.NEDG) THEN
X2=XED(J+1,I)
Z2=ZED(J+1,I)
ELSE
X2=XED(1,I)
Z2=ZED(1,I)
ENDIF
SEGLEN=SQRT((X2-X1)**2+(Z2-Z1)**2)
IORT=2
IF(ABS(X1-X2).LT.0.00001) IORT=0
IF(ABS(Z1-Z2).LT.0.00001) IORT=1
C
C Distances of the grid point from the end points
C
DIST1=SQRT((XPT-X1)**2+(ZPT-Z1)**2)
DIST2=SQRT((XPT-X2)**2+(ZPT-Z2)**2)
ROZ1=DIST1-SEGLEN
ROZ2=DIST2-SEGLEN
C IF(DIST1.GT.SEGLEN.OR.DIST2.GT.SEGLEN) GOTO 250
IF(ROZ1.GT.0.0001.OR.ROZ2.GT.0.0001) GOTO 250
C
C The grid point certainly located on J-th segment
C
IVIC=0
IF(DIST1.LT.DX) GOTO 400
IF(DIST2.LT.DX) GOTO 500
GOTO 600
400 IVIC=J
DIST=DIST1
GOTO 600
500 IF(J.LT.NEDG) THEN
IVIC=J+1
ELSE
IVIC=1
ENDIF
DIST=DIST2
GOTO 600
200 CONTINUE
C
C The grid point 'on the left' with respect to all segments,
C i.e., the grid point located inside I-th block
C
IPRES=1
C
C Distances from all edges of the block
C (The program cannot detect proximity of two edges simultan.)
C
IVIC=0
DO 550 J=1,NEDG
DISTX=SQRT((XPT-XED(J,I))**2+(ZPT-ZED(J,I))**2)
IF(DISTX.GT.DX) GOTO 550
IVIC=J
DIST=DISTX
GOTO 600
550 CONTINUE
600 RETURN
END
C DEBUG SUBCHK
C END DEBUG
C
C=======================================================================
C
C
C
SUBROUTINE TWOPT(X,Z,IB,DELSA,KY,KYOR,ISG,IVC,PART)
C
C Purpose:
C Location of a grid leg with respect to boundary of block IB
C
C Input:
C X,Z........x,z coordinates of the grid point
C IB.........the block to which the grid point is belonging
C DELSA........length of the leg
C KY=0.......vertical leg
C =1.......horizontal leg
C KYOR=0.....leg oriented down, or right, of the grid point
C =1.....up or left
C
C Output:
C ISG=0......no intersection of the leg with the block boundary
C .ne.0....intersection with ISG-th segment
C IVC........the neighbouring block (for ISG.ne.0)
C PART.......a relative distance of the grid point from
C the intersection (for ISG.ne.0)
C
C
DIMENSION NOED(0:50),VS(0:50),PSRAT(0:50),HU(0:50)
DIMENSION XED(10,50),ZED(10,50),NOVIC(10,50)
COMMON /BLO1/ NOBL,NOED,VS,PSRAT,DX,HU
COMMON /BLO2/ XED,ZED,NOVIC
C
IF(IB.EQ.0) THEN
ISG=0
RETURN
ENDIF
C
C End point (XX,ZZ) of the leg (the leg from (X,Z) to (XX,ZZ))
C
IF(KY.EQ.0) GOTO 100
IF(KY.EQ.1) GOTO 200
100 XX=X
IF(KYOR.EQ.0) THEN
ZZ=Z+DELSA
ELSE
ZZ=Z-DELSA
ENDIF
GOTO 300
200 ZZ=Z
IF(KYOR.EQ.0) THEN
XX=X+DELSA
ELSE
XX=X-DELSA
ENDIF
C Intersection of the leg with the block boundary
C (legs coinciding with boundaries are not allowed)
C
300 NEDG=NOED(IB)
DO 500 J=1,NEDG
C
C The end points (X1,Z1) and (X2,Z2) of J-th segment
C
X1=XED(J,IB)
Z1=ZED(J,IB)
IF(J.LT.NEDG) THEN
X2=XED(J+1,IB)
Z2=ZED(J+1,IB)
ELSE
X2=XED(1,IB)
Z2=ZED(1,IB)
ENDIF
IF(KY.EQ.0) GOTO 600
IF(KY.EQ.1) GOTO 700
600 IF(X1.LT.X2) THEN
XMIN=X1
XMAX=X2
ELSE
XMIN=X2
XMAX=X1
ENDIF
IF(X.LT.XMIN.OR.X.GT.XMAX) GOTO 500
ZSEC=Z1+(X-X1)*(Z2-Z1)/(X2-X1)
IF(KYOR.EQ.0) THEN
ZBOT=Z
ZTOP=ZZ
ELSE
ZBOT=ZZ
ZTOP=Z
ENDIF
IF(ZSEC.LT.ZBOT.OR.ZSEC.GT.ZTOP) GOTO 500
ISG=J
IVC=NOVIC(J,IB)
PART=ABS(ZSEC-Z)/DELSA
GOTO 1000
700 IF(Z1.LT.Z2) THEN
ZMIN=Z1
ZMAX=Z2
ELSE
ZMIN=Z2
ZMAX=Z1
ENDIF
IF(Z.LT.ZMIN.OR.Z.GT.ZMAX) GOTO 500
XSEC=X1+(Z-Z1)*(X2-X1)/(Z2-Z1)
IF(KYOR.EQ.0) THEN
XBOT=X
XTOP=XX
ELSE
XBOT=XX
XTOP=X
ENDIF
IF(XSEC.LT.XBOT.OR.XSEC.GT.XTOP) GOTO 500
ISG=J
IVC=NOVIC(J,IB)
PART=ABS(XSEC-X)/DELSA
GOTO 1000
500 CONTINUE
ISG=0
1000 RETURN
END
C DEBUG SUBCHK
C END DEBUG
C
C=======================================================================
C
INCLUDE 'error.for'
C error.for
INCLUDE 'fdaux.for'
C fdaux.for
INCLUDE 'gmtra.for'
C gmtra.for
INCLUDE 'sep.for'
C sep.for
INCLUDE 'forms.for'
C forms.for
INCLUDE 'length.for'
C length.for
C
C=======================================================================
C