Cloned SEACAS for EXODUS library with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

250 lines
7.3 KiB

C Copyright(C) 1999-2020 National Technology & Engineering Solutions
C of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
C NTESS, the U.S. Government retains certain rights in this software.
C
C See packages/seacas/LICENSE for details
SUBROUTINE LINLEN (MP, COOR, LINKP, KNUM, LNUM, KT, I3, J1, J2,
& J3, DIST, ERR)
C***********************************************************************
C SUBROUTINE LINLEN = CALCULATES THE LENGTH OF A GIVEN LINE
C***********************************************************************
C VARIABLES USED:
C NID = AN ARRAY OF UNIQUE NODE IDENTIFIERS.
C REAL = .TRUE. FOR AN ACTUAL GENERATION
C = .FALSE. FOR A TRIAL GENERATION
C ERR = .TRUE. IF AN ERROR WAS ENCOUNTERED
C J1 = POINTER FOR THE FIRST POINT
C J2 = POINTER FOR THE SECOND POINT
C J3 = POINTER FOR THE THIRD POINT
C MAXNP = MAXIMUM NUMBER OF NODES ON THE PERIMETER
C NOTE: MAXNP MUST BE ADJUSTED FOR THE CURRENT
C LOCATION IN X, Y, & NID
C KT = THE LINE TYPE:
C = 1 FOR STRAIGHT LINES
C = 2 FOR CORNER LINES
C = 3 FOR ARC WITH CENTER GIVEN
C = 4 FOR ARC WITH THIRD POINT ON THE ARC
C = 5 FOR PARABOLA
C = 6 FOR ARC WITH RADIUS GIVEN
C***********************************************************************
DIMENSION COOR (2, MP), LINKP (2, MP)
LOGICAL ERR
PI = ATAN2(0.0, -1.0)
DIST = 0.
ERR = .TRUE.
C STRAIGHT LINE GENERATION
IF (KT.EQ.1) THEN
YDIFF = COOR (2, J2) -COOR (2, J1)
XDIFF = COOR (1, J2) -COOR (1, J1)
DIST = SQRT (YDIFF ** 2 + XDIFF ** 2)
IF (DIST.EQ.0.) THEN
WRITE (*, 10000) KNUM
RETURN
ENDIF
C CORNER GENERATION
ELSEIF (KT.EQ.2) THEN
XDA = COOR (1, J3) -COOR (1, J1)
YDA = COOR (2, J3) -COOR (2, J1)
XDB = COOR (1, J2) -COOR (1, J3)
YDB = COOR (2, J2) -COOR (2, J3)
DA = SQRT (XDA ** 2 + YDA ** 2)
DB = SQRT (XDB ** 2 + YDB ** 2)
IF ((DA.EQ.0.) .OR. (DB.EQ.0.) )THEN
WRITE (*, 10000) KNUM
RETURN
ENDIF
DIST = DA+DB
C CIRCULAR ARC
ELSEIF ((KT.EQ.3) .OR. (KT.EQ.4) .OR. (KT.EQ.6) )THEN
XSTART = COOR (1, J1)
YSTART = COOR (2, J1)
CALL ARCPAR (MP, KT, KNUM, COOR, LINKP, J1, J2, J3, I3,
& XCEN, YCEN, THETA1, THETA2, TANG, R1, R2, ERR, ICCW, ICW,
& XK, XA)
C GENERATE THE CIRCLE
ANG = THETA1
DEL = TANG/30
DO 100 I = 2, 29
ANG = ANG+DEL
RADIUS = XA * EXP (XK * ANG)
XEND = XCEN+COS (ANG) * RADIUS
YEND = YCEN+SIN (ANG) * RADIUS
DIST = DIST+SQRT ((XEND-XSTART) ** 2 + (YEND-YSTART) ** 2)
XSTART = XEND
YSTART = YEND
100 CONTINUE
XEND = COOR (1, J2)
YEND = COOR (2, J2)
DIST = DIST+SQRT ((XEND-XSTART) ** 2 + (YEND-YSTART) ** 2)
C ELIPSE
ELSEIF (KT .EQ. 7) THEN
XSTART = COOR (1, J1)
YSTART = COOR (2, J1)
CALL ELPSPR (MP, KT, KNUM, COOR, LINKP, J1, J2, J3,
& I3, XCEN, YCEN, THETA1, THETA2, TANG, IDUM1, IDUM2,
& AVALUE, BVALUE, ERR)
C GENERATE THE ELIPSE
ANG = THETA1
DEL = TANG/30
DO 110 I = 2, 29
ANG = ANG+DEL
RADIUS = SQRT ( (AVALUE **2 * BVALUE **2) /
& ( (BVALUE **2 * COS (ANG) **2) +
& (AVALUE **2 * SIN (ANG) **2) ) )
XEND = XCEN+COS (ANG) * RADIUS
YEND = YCEN+SIN (ANG) * RADIUS
DIST = DIST+SQRT ((XEND-XSTART) ** 2 + (YEND-YSTART) ** 2)
XSTART = XEND
YSTART = YEND
110 CONTINUE
XEND = COOR (1, J2)
YEND = COOR (2, J2)
DIST = DIST+SQRT ((XEND-XSTART) ** 2 + (YEND-YSTART) ** 2)
C PARABOLA
ELSEIF (KT.EQ.5) THEN
C CHECK LEGITIMACY OF DATA
XMID = (COOR (1, J1) +COOR (1, J2) ) * 0.5
YMID = (COOR (2, J1) +COOR (2, J2) ) * 0.5
DOT = (COOR (1, J2) -COOR (1, J1) ) * (COOR (1, J3) -XMID)
& + (COOR (2, J2) -COOR (2, J1) ) * (COOR (2, J3) -YMID)
PERP = SQRT ((COOR (1, J2) -COOR (1, J1) ) ** 2 +
& (COOR (2, J2) - COOR (2, J1) ) ** 2) *
& SQRT ((COOR (1, J3) -XMID) ** 2 + (COOR (2, J3)
& -YMID) ** 2)
IF (DOT.GE.0.05 * PERP) THEN
WRITE (*, 10030) KNUM
RETURN
ENDIF
C GETARC LENGTH
HALFW = SQRT ((COOR (1, J2) -COOR (1, J1) ) ** 2 +
& (COOR (2, J2) - COOR (2, J1) ) ** 2 ) * 0.5
IF (HALFW.EQ.0.) THEN
WRITE (*, 10000) KNUM
RETURN
ENDIF
HEIGHT = SQRT ((XMID-COOR (1, J3) ) ** 2
& + (YMID-COOR (2, J3) ) ** 2)
COEF = HEIGHT/HALFW ** 2
TCOEF = 2.0 * COEF
C PARC IS A STATEMENT FUNCTION
PLEFT = PARC (-TCOEF * HALFW, TCOEF)
ARCTOT = 2.0 * PARC (TCOEF * HALFW, TCOEF)
ARCDEL = ARCTOT/30
ARCNXT = ARCDEL
ARCNOW = 0.0
THETA = ATAN2 (COOR (2, J2) -COOR (2, J1) , COOR (1, J2)
& - COOR (1, J1) )
C CORRECT FOR ORIENTATION
CROSS = (COOR (1, J3) -XMID) * (COOR (2, J2) -COOR (2, J1) )-
& (COOR (2, J3) -YMID) * (COOR (1, J2) -COOR (1, J1) )
IF (CROSS.LT.0.0) THETA = THETA+PI
SINT = SIN (THETA)
COST = COS (THETA)
C FIND POINTS APPROXIMATELY BY INTEGRATION
XL = -HALFW
FL = SQRT (1.0+ (TCOEF * XL) ** 2)
KOUNT = 1
DELX = 2.0 * HALFW/200.0
XSTART = COOR (1, J1)
YSTART = COOR (2, J1)
DO 120 I = 1, 100
FM = SQRT (1.0+ (TCOEF * (XL+DELX) ) ** 2)
XR = - HALFW + DBLE(I) * 2.0 * DELX
FR = SQRT (1.0+ (TCOEF * XR) ** 2)
ARCOLD = ARCNOW
ARCNOW = ARCNOW+DELX * (FL+4.0 * FM+FR) / 3.0
IF (ARCNOW.GE.ARCNXT) THEN
C COMPUTE POSITION IN LOCAL COORDINATE SYSTEM
FRAC = (ARCNXT-ARCOLD) / (ARCNOW-ARCOLD)
XK = XL+FRAC * 2.0 * DELX
YK = COEF * XK ** 2
C CORRECT FOR ORIENTATION PROBLEM
IF (CROSS.LT.0.0) XK = -XK
C ROTATE IN LINE WITH GLOBAL COORDINATE SYSTEM
ROTX = XK * COST - YK * SINT
ROTY = YK * COST + XK * SINT
C RESTORE XK
IF (CROSS.LT.0.0) XK = -XK
C TRANSLATE
XEND = ROTX+COOR (1, J3)
YEND = ROTY+COOR (2, J3)
DIST = DIST+SQRT ((XEND-XSTART) ** 2 + (YEND-YSTART) **2)
KOUNT = KOUNT+1
XSTART = XEND
YSTART = YEND
C PREPARE FOR NEXT POINT
IF (KOUNT.GE.29) GOTO 130
ARCNXT = ARCNXT+ARCDEL
C RESTART INTEGRATION
XR = XK
FR = SQRT (1.0+ (TCOEF * XR) ** 2)
C CORRECT FOR INTEGRATION ERROR
ARCNOW = PARC (TCOEF * XR, TCOEF) -PLEFT
ENDIF
XL = XR
FL = FR
120 CONTINUE
130 CONTINUE
XEND = COOR (1, J2)
YEND = COOR (2, J2)
DIST = DIST+SQRT ((XEND-XSTART) ** 2+ (YEND-YSTART) ** 2)
ENDIF
C NORMAL EXIT
ERR = .FALSE.
RETURN
10000 FORMAT (' ZERO LINE LENGTH ENCOUNTERED FOR LINE', I5)
10030 FORMAT (' POINTS GIVEN FOR LINE', I5, ' DO NOT DEFINE A PARABOLA')
END