C
C      PROGRAM 7.1 SOLUTION OF LAPLACE'S EQUATION FOR
C      PLANE FREE-SURFACE FLOW USING 8-NODED QUADRILATERALS
C
C      ALTER NEXT LINE TO CHANGE PROBLEM SIZE
C
      PARAMETER (IKV=416000,ILOADS=3500,INF=3000,INO=100,INX=60)
C
      REAL PERMX
      REAL PERMY
      REAL DET
      REAL QUOT
      REAL REACT
      REAL JAC(2,2),JAC1(2,2),KAY(2,2),SAMP(3,2),DTKD(4,8),KP(4,8),
     +COORD(8,2),DER(2,8),DERIV(2,8),DERIVT(8,2),KDERIV(2,8),
     +FUN(8),VAL(INO),KVH(IKV),KV(IKV),LOADS(ILOADS),DISPS(ILOADS),
     +OLDPOT(ILOADS),WIDTH(INX),SURF(INX)
      INTEGER G(4),NO(INO),NF(INF,1)
      DATA IT,IJAC,IJAC1,IKAY,IDER,IDERIV,IKDERV/7*2/,ISAMP/3/
      DATA IDTKD,IKP,ICOORD,IDERVT,NOD/5*4/,NODOF/1/
C
C      INPUT AND INITIALISATION
C
      READ (5,FMT=*) NXE,NYE,N,IW,NN,NR,NGP,ITS,PERMX,PERMY
      READ (5,FMT=*) (WIDTH(I),I=1,NXE+1)
      READ (5,FMT=*) (SURF(I),I=1,NXE+1)
      CALL READNF(NF,INF,NN,NODOF,NR)
      IR = N* (IW+1)
      CALL NULVEC(OLDPOT,N)
      CALL NULL(KAY,IKAY,IT,IT)
      KAY(1,1) = PERMX
      KAY(2,2) = PERMY
      CALL GAUSS(SAMP,ISAMP,NGP)
C
C      ITERATE FOR POSITION OF FREESURFACE
C
      ITERS = 0
   10 ITERS = ITERS + 1
      CALL NULVEC(KV,IR)
C
C      ELEMENT INTEGRATION AND ASSEMBLY
C
      DO 20 IP = 1,NXE
      DO 20 IQ = 1,NYE
      CALL WELGEO(IP,IQ,NXE,NYE,WIDTH,SURF,COORD,ICOORD,G,NF,
     +INF)
      CALL NULL(KP,IKP,NOD,NOD)
      DO 30 I = 1,NGP
      DO 30 J = 1,NGP
      CALL FORMLN(DER,IDER,FUN,SAMP,ISAMP,I,J)
      CALL MATMUL(DER,IDER,COORD,ICOORD,JAC,IJAC,IT,NOD,
     +IT)
      CALL TWOBY2(JAC,IJAC,JAC1,IJAC1,DET)
      CALL MATMUL(JAC1,IJAC1,DER,IDER,DERIV,IDERIV,IT,
     +IT,NOD)
      CALL MATMUL(KAY,IKAY,DERIV,IDERIV,KDERIV,IKDERV,
     +IT,IT,NOD)
      CALL MATRAN(DERIVT,IDERVT,DERIV,IDERIV,IT,NOD)
      CALL MATMUL(DERIVT,IDERVT,KDERIV,IKDERV,DTKD,
     +IDTKD,NOD,IT,NOD)
      QUOT = DET*SAMP(I,2)*SAMP(J,2)
      CALL MSMULT(DTKD,IDTKD,QUOT,NOD,NOD)
   30 CALL MATADD(KP,IKP,DTKD,IDTKD,NOD,NOD)
   20 CALL FORMKV(KV,KP,IKP,G,N,NOD)
      CALL VECCOP(KV,KVH,IR)
C
C      SPECIFY FIXED POTENTIALS AND REDUCE EQUATIONS
C
      IF (ITERS.EQ.1) READ (5,FMT=*) IFIX, (NO(I),I=1,IFIX)
      CALL NULVEC(LOADS,N)
      DO 40 I = 1,IFIX
      KV(NO(I)) = KV(NO(I)) + 1.E20
   40 LOADS(NO(I)) = KV(NO(I))*SURF(NXE+1)
      DO 50 IQ = 1,NYE - 1
      J = IQ* (NXE+1) + 1
   50 LOADS(J) = KV(J)* (NYE-IQ)*SURF(1)/NYE
      CALL BANRED(KV,N,IW)
C
C      SOLVE EQUATIONS
C
      CALL BACSUB(KV,LOADS,N,IW)
      CALL VECCOP(LOADS,SURF,NXE)
C
C      CHECK CONVERGENCE
C
      CALL CHECON(LOADS,OLDPOT,N,0.001,ICON)
      IF (ITERS.NE.ITS .AND. ICON.EQ.0) GO TO 10
      CALL LINMUL(KVH,LOADS,DISPS,N,IW)
      REACT = 0.
      DO 60 I = 1,NYE
   60 REACT = REACT + DISPS(I* (NXE+1))
      REACT = REACT + DISPS(N)
      CALL PRINTV(LOADS,N)
      WRITE (6,FMT='(E12.4)') REACT
      WRITE (6,FMT='(I10)') ITERS
      STOP
      END

      SUBROUTINE READNF(NF,INF,NN,NODOF,NR)
C
C      THIS SUBROUTINE READS THE NODAL FREEDOM DATA
C
      INTEGER NF(INF,*)

      DO 1 I = 1,NN
          DO 1 J = 1,NODOF
    1 NF(I,J) = 1
      IF (NR.GT.0) READ (5,FMT=*) (K, (NF(K,J),J=1,NODOF),I=1,NR)
      N = 0
      DO 2 I = 1,NN
          DO 2 J = 1,NODOF
              IF (NF(I,J).NE.0) THEN
                  N = N + 1
                  NF(I,J) = N
              END IF

    2 CONTINUE
      RETURN

      END
      
      SUBROUTINE GAUSS(SAMP,ISAMP,NGP)
C
C      THIS SUBROUTINE PROVIDES THE WEIGHTS AND SAMPLING POINTS
C      FOR GAUSS-LEGENDRE QUADRATURE
C
      REAL SAMP(ISAMP,*)

      GO TO (1,2,3,4,5,6,7) NGP

    1 SAMP(1,1) = 0.
      SAMP(1,2) = 2.
      GO TO 100

    2 SAMP(1,1) = 1./SQRT(3.)
      SAMP(2,1) = -SAMP(1,1)
      SAMP(1,2) = 1.
      SAMP(2,2) = 1.
      GO TO 100

    3 SAMP(1,1) = .2*SQRT(15.)
      SAMP(2,1) = .0
      SAMP(3,1) = -SAMP(1,1)
      SAMP(1,2) = 5./9.
      SAMP(2,2) = 8./9.
      SAMP(3,2) = SAMP(1,2)
      GO TO 100

    4 SAMP(1,1) = .86113631
      SAMP(2,1) = .33998104
      SAMP(3,1) = -SAMP(2,1)
      SAMP(4,1) = -SAMP(1,1)
      SAMP(1,2) = .34785484
      SAMP(2,2) = .65214515
      SAMP(3,2) = SAMP(2,2)
      SAMP(4,2) = SAMP(1,2)
      GO TO 100

    5 SAMP(1,1) = .90617984
      SAMP(2,1) = .53846931
      SAMP(3,1) = .0
      SAMP(4,1) = -SAMP(2,1)
      SAMP(5,1) = -SAMP(1,1)
      SAMP(1,2) = .23692688
      SAMP(2,2) = .47862867
      SAMP(3,2) = .56888888
      SAMP(4,2) = SAMP(2,2)
      SAMP(5,2) = SAMP(1,2)
      GO TO 100

    6 SAMP(1,1) = .93246951
      SAMP(2,1) = .66120938
      SAMP(3,1) = .23861918
      SAMP(4,1) = -SAMP(3,1)
      SAMP(5,1) = -SAMP(2,1)
      SAMP(6,1) = -SAMP(1,1)
      SAMP(1,2) = .17132449
      SAMP(2,2) = .36076157
      SAMP(3,2) = .46791393
      SAMP(4,2) = SAMP(3,2)
      SAMP(5,2) = SAMP(2,2)
      SAMP(6,2) = SAMP(1,2)
      GO TO 100

    7 SAMP(1,1) = .94910791
      SAMP(2,1) = .74153118
      SAMP(3,1) = .40584515
      SAMP(4,1) = .0
      SAMP(5,1) = -SAMP(3,1)
      SAMP(6,1) = -SAMP(2,1)
      SAMP(7,1) = -SAMP(1,1)
      SAMP(1,2) = .12948496
      SAMP(2,2) = .27970539
      SAMP(3,2) = .38183005
      SAMP(4,2) = .41795918
      SAMP(5,2) = SAMP(3,2)
      SAMP(6,2) = SAMP(2,2)
      SAMP(7,2) = SAMP(1,2)
  100 CONTINUE
      RETURN

      END
      
      SUBROUTINE WELGEO(IP,IQ,NXE,NYE,WIDTH,SURF,COORD,ICOORD,G,NF,INF)
C
C      THIS SUBROUTINE FORMS THE COORDINATES AND STEERING VECTOR
C      FOR 4-NODE QUADS NUMBERING IN THE X-DIRECTION
C      LAPLACE'S EQUATION,VARIABLE MESH, 1-FREEDOM PER NODE
C
      REAL BB
      REAL BVAR
      REAL COORD(ICOORD,*),WIDTH(*),SURF(*)
      INTEGER NUM(4),G(*),NF(INF,*)

      NUM(1) = IQ* (NXE+1) + IP
      NUM(2) = (IQ-1)* (NXE+1) + IP
      NUM(3) = NUM(2) + 1
      NUM(4) = NUM(1) + 1
      DO 1 I = 1,4
    1 G(I) = NF(NUM(I),1)
      BB = SURF(IP)/NYE
      BVAR = SURF(IP+1)/NYE
      COORD(1,1) = WIDTH(IP)
      COORD(2,1) = WIDTH(IP)
      COORD(3,1) = WIDTH(IP+1)
      COORD(4,1) = WIDTH(IP+1)
      COORD(1,2) = (NYE-IQ)*BB
      COORD(2,2) = (NYE-IQ+1)*BB
      COORD(3,2) = (NYE-IQ+1)*BVAR
      COORD(4,2) = (NYE-IQ)*BVAR
      RETURN

      END
      
      SUBROUTINE NULL(A,IA,M,N)
C
C      THIS SUBROUTINE NULLS A 2-D ARRAY
C
      REAL A(IA,*)

      DO 1 I = 1,M
          DO 1 J = 1,N
    1 A(I,J) = 0.0
      RETURN
      
      END
      
      SUBROUTINE FORMLN(DER,IDER,FUN,SAMP,ISAMP,I,J)
C
C      THIS SUBROUTINE FORMS THE SHAPE FUNCTIONS AND
C      THEIR DERIVATIVES FOR 4-NODED QUADRILATERAL ELEMENTS
C
      REAL ETA
      REAL XI
      REAL ETAM
      REAL ETAP
      REAL XIM
      REAL XIP
      REAL DER(IDER,*),FUN(*),SAMP(ISAMP,*)

      ETA = SAMP(I,1)
      XI = SAMP(J,1)
      ETAM = .25* (1.-ETA)
      ETAP = .25* (1.+ETA)
      XIM = .25* (1.-XI)
      XIP = .25* (1.+XI)
      FUN(1) = 4.*XIM*ETAM
      FUN(2) = 4.*XIM*ETAP
      FUN(3) = 4.*XIP*ETAP
      FUN(4) = 4.*XIP*ETAM
      DER(1,1) = -ETAM
      DER(1,2) = -ETAP
      DER(1,3) = ETAP
      DER(1,4) = ETAM
      DER(2,1) = -XIM
      DER(2,2) = XIM
      DER(2,3) = XIP
      DER(2,4) = -XIP
      RETURN

      END
      
      SUBROUTINE TWOBY2(JAC,IJAC,JAC1,IJAC1,DET)
C
C      THIS SUBROUTINE FORMS THE INVERSE OF A 2 BY 2 MATRIX
C
      REAL DET
      REAL JAC(IJAC,*),JAC1(IJAC1,*)

      DET = JAC(1,1)*JAC(2,2) - JAC(1,2)*JAC(2,1)
      JAC1(1,1) = JAC(2,2)
      JAC1(1,2) = -JAC(1,2)
      JAC1(2,1) = -JAC(2,1)
      JAC1(2,2) = JAC(1,1)
      DO 1 K = 1,2
          DO 1 L = 1,2
    1 JAC1(K,L) = JAC1(K,L)/DET
      RETURN

      END
      
      SUBROUTINE MATRAN(A,IA,B,IB,M,N)
C
C      THIS SUBROUTINE FORMS THE TRANSPOSE OF A MATRIX
C
      REAL A(IA,*),B(IB,*)

      DO 1 I = 1,M
          DO 1 J = 1,N
    1 A(J,I) = B(I,J)
      RETURN

      END
      
      SUBROUTINE MATMUL(A,IA,B,IB,C,IC,L,M,N)
C
C      THIS SUBROUTINE FORMS THE PRODUCT OF TWO MATRICES
C
      REAL X
      REAL A(IA,*),B(IB,*),C(IC,*)

      DO 1 I = 1,L
          DO 1 J = 1,N
              X = 0.0
              DO 2 K = 1,M
    2         X = X + A(I,K)*B(K,J)
              C(I,J) = X
    1 CONTINUE
      RETURN

      END
      
      SUBROUTINE MSMULT(A,IA,C,M,N)
C
C      THIS SUBROUTINE MULTIPLIES A MATRIX BY A SCALAR
C
      REAL C
      REAL A(IA,*)

      DO 1 I = 1,M
          DO 1 J = 1,N
    1 A(I,J) = A(I,J)*C
      RETURN

      END
      
      SUBROUTINE MATADD(A,IA,B,IB,M,N)
C
C      THIS SUBROUTINE ADDS TWO EQUAL SIZED ARRAYS
C
      REAL A(IA,*),B(IB,*)

      DO 1 I = 1,M
          DO 1 J = 1,N
    1 A(I,J) = A(I,J) + B(I,J)
      RETURN

      END
      
      SUBROUTINE FORMKV(BK,KM,IKM,G,N,IDOF)
C
C      THIS SUBROUTINE FORMS THE GLOBAL STIFFNESS MATRIX
C      STORING THE UPPER TRIANGLE AS A VECTOR BK(N*(IW+1))
C
      REAL BK(*),KM(IKM,*)
      INTEGER G(*)

      DO 1 I = 1,IDOF
          IF (G(I).EQ.0) GO TO 1
          DO 5 J = 1,IDOF
              IF (G(J).EQ.0) GO TO 5
              ICD = G(J) - G(I) + 1
              IF (ICD-1) 5,4,4
    4         IVAL = N* (ICD-1) + G(I)
              BK(IVAL) = BK(IVAL) + KM(I,J)
    5     CONTINUE
    1 CONTINUE
      RETURN

      END
      
      SUBROUTINE NULVEC(VEC,N)
C
C      THIS SUBROUTINE NULLS A COLUMN VECTOR
C
      REAL VEC(*)

      DO 1 I = 1,N
    1 VEC(I) = 0.
      RETURN

      END
      
      SUBROUTINE BANRED(BK,N,IW)
C
C      THIS SUBROUTINE PERFORMS GAUSSIAN REDUCTION OF
C      THE STIFFNESS MATRIX STORED AS A VECTOR BK(N*(IW+1))
C
      REAL SUM
      REAL BK(*)

      DO 1 I = 2,N
          IL1 = I - 1
          KBL = IL1 + IW + 1
          IF (KBL-N) 3,3,2
    2     KBL = N
    3     DO 1 J = I,KBL
              IJ = (J-I)*N + I
              SUM = BK(IJ)
              NKB = J - IW
              IF (NKB) 4,4,5
    4         NKB = 1
    5         IF (NKB-IL1) 6,6,8
    6         DO 7 M = NKB,IL1
                  NI = (I-M)*N + M
                  NJ = (J-M)*N + M
    7         SUM = SUM - BK(NI)*BK(NJ)/BK(M)
    8         BK(IJ) = SUM
    1 CONTINUE
      RETURN

      END
      
      SUBROUTINE BACSUB(BK,LOADS,N,IW)
C
C      THIS SUBROUTINE PERFORMS THE GAUSSIAN BACK-SUBSTITUTION
C
      REAL SUM
      REAL BK(*),LOADS(*)

      LOADS(1) = LOADS(1)/BK(1)
      DO 1 I = 2,N
          SUM = LOADS(I)
          I1 = I - 1
          NKB = I - IW
          IF (NKB) 2,2,3
    2     NKB = 1
    3     DO 4 K = NKB,I1
              JN = (I-K)*N + K
              SUM = SUM - BK(JN)*LOADS(K)
    4     CONTINUE
          LOADS(I) = SUM/BK(I)
    1 CONTINUE
      DO 5 JJ = 2,N
          I = N - JJ + 1
          SUM = 0.
          I1 = I + 1
          NKB = I + IW
          IF (NKB-N) 7,7,6
    6     NKB = N
    7     DO 8 K = I1,NKB
              JN = (K-I)*N + I
    8     SUM = SUM + BK(JN)*LOADS(K)
          LOADS(I) = LOADS(I) - SUM/BK(I)
    5 CONTINUE
      RETURN

      END
      
      SUBROUTINE VECCOP(A,B,N)
C
C      THIS SUBROUTINE COPIES VECTOR A INTO VECTOR B
C
      REAL A(*),B(*)

      DO 1 I = 1,N
    1 B(I) = A(I)
      RETURN

      END
      
      SUBROUTINE CHECON(LOADS,OLDLDS,N,TOL,ICON)
C
C      THIS SUBROUTINE SETS ICON TO ZERO IF THE RELATIVE CHANGE
C      IN VECTORS 'LOADS' AND 'OLDLDS' IS GREATER THAN 'TOL'
C
      REAL TOL
      REAL BIG
      REAL LOADS(*),OLDLDS(*)

      ICON = 1
      BIG = 0.
      DO 1 I = 1,N
    1 IF (ABS(LOADS(I)).GT.BIG) BIG = ABS(LOADS(I))
      DO 2 I = 1,N
          IF (ABS(LOADS(I)-OLDLDS(I))/BIG.GT.TOL) ICON = 0
    2 OLDLDS(I) = LOADS(I)
      RETURN

      END
      
      SUBROUTINE LINMUL(BK,DISPS,LOADS,N,IW)
C
C      THIS SUBROUTINE MULTIPLIES A MATRIX BY A VECTOR
C      THE MATRIX IS SYMMETRICAL WITH ITS UPPER TRIANGLE
C      STORED AS A VECTOR
C
      REAL X
      REAL BK(*),DISPS(*),LOADS(*)

      DO 1 I = 1,N
          X = 0.
          DO 2 J = 1,IW + 1
              IF (I+J.LE.N+1) X = X + BK(N* (J-1)+I)*DISPS(I+J-1)
    2     CONTINUE
          DO 3 J = 2,IW + 1
              IF (I-J+1.GE.1) X = X + BK((N-1)* (J-1)+I)*DISPS(I-J+1)
    3     CONTINUE
          LOADS(I) = X
    1 CONTINUE
      RETURN

      END
      
      
      
      
      
      
      
      
      
      
 

Fortran Online Compiler

Write, Run & Share Fortran code online using OneCompiler's Fortran online compiler for free. It's one of the robust, feature-rich online compilers for Fortran language, running on the latest version 7. Getting started with the OneCompiler's Fortran compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as Fortran and start coding.

Read inputs from stdin

OneCompiler's Fortran online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample Fortran program which takes name as input and prints hello message with your name.

program hello
  character :: name*30
  read *, name
	print *, "Hello ", name
end program hello

About Fortran

Fortran language was initially developed for scientific calculations by IBM in 1957. It has a number of in-built functions to perform mathematical calculations and is ideal for applications which has more mathematical calculations.

Syntax help

Data Types

Data typeDescriptionUsage
IntegerTo store integer variablesinteger :: x
RealTo store float valuesreal :: x
ComplexTo store complex numberscomplex :: x,y
LogicalTo store boolean values True or falselogical :: x=.True. , logical :: x = .FALSE.
CharacterTo store characters and stringscharacter :: x

Variables

Variable is a name given to the storage area in order to manipulate them in our programs.

data type :: variable_name

Arrays

Array is a collection of similar data which is stored in continuous memory addresses.

Syntax

data-type, dimension (x,y) :: array-name

Example

integer, dimension(3,3) :: cube

Loops

1. Do:

Do is used to execute a set of statement(s) iteratively when a given condition is true and the loop variable must be an integer.

do i = start, stop [,step]    
   ! code
end do

2. Do-While:

Do-While is used to execute a set of statement(s) iteratively when a given condition is true.

do while (condition) 
   !Code
end do

3. If:

If is used to execute a set of statements based on a condition.

if (logical-expression) then      
   !Code  
end if

4. If-Else:

If is used to execute a set of statements based on a condition and execute another set of statements present in else block, if condition specified in If block fails.

if (logical-expression) then     
   !code when the condition is true
else
   !code when the condition fails
end if

5. Case:

Case is similar to switch in C language.

[name:] select case (regular-expression) 
   case (value1)          
   ! code for value 1          
   ... case (value2)           
   ! code for value 2           
   ...       
   case default          
   ! default code          
   ...   
end select [name]