      SUBROUTINE ABQMAIN
C====================================================================
C This program must be compiled and linked with the command:
C     abaqus make job=felbow
C Run the program using the command:
C     abaqus felbow
C==================================================================
C
C  PURPOSE: 
C 
C    This program reads results stored in an ABAQUS results (.fil) 
C    file and creates an input file for use in the Visualization 
C    module of ABAQUS/CAE (ABAQUS/Viewer) that permits
C    postprocessing and visualization of elbow element results.
C    
C
C  Input file names: `fname.fil', where fname is the root file name
C                                 of the input file.
C
C  Output file name:  output.dat
C
C==================================================================
C
C  VARIABLES USED BY THIS PROGRAM:
C
C   ndi    -- Number of direct components in stress/strain tensor.
C   nshr   -- Number of shear components in stress/strain tensor.
C   ndip1  -- ndi + 1
C   array  -- Real array containing values read from results file.
C               Equivalenced to jrray.
C   jrray  -- Integer array containing values read from results file.
C               Equivalenced to array.
C   fname  -- Root file name of input file (w/o .fil extension).
C   nru    -- Number of results files (.fil) to be read.
C   lrunit -- Array containing unit number and format of results files:
C               lrunit(1,*) --> Unit number of input file.
C               lrunit(2,*) --> Format of input file.
C   loutf  -- Format of output file:
C               0 --> Standard ASCII format.
C               1 --> ABAQUS results file ASCII format.
C               2 --> ABAQUS results file binary format.
C   junit  -- Unit number of file to be opened.
C   jrcd   -- Error check return code.
C               .EQ. 0 --> No errors.
C               .NE. 0 --> Errors detected.
C   key    -- Current record key identifier.
C   jelnum -- Current element number.
C   intpn  -- Integration point number.
C
C==================================================================
C
C  The use of ABA_PARAM.INC eliminates the need to have different   
C  versions of the code for single and double precision.   
C  ABA_PARAM.INC defines an appropriate IMPLICIT REAL statement 
C  and sets the value of NPRECD to 1 or 2, depending on whether
C  the machine uses single or double precision. ABA_PARAM.INC is  
C  referenced from the \site (for NT) or /site (for Unix) 
C  ABAQUS release subdirectory when ABAQUS/Make is executed.
C
C==================================================================
C
      include 'aba_param.inc'
      parameter (melem=10000,mnode=10000,mkey=3000,mintpt=360)

      dimension array(513),jrray(nprecd,513),lrunit(2,1)
      equivalence (array(1),jrray(1,1))
C
C==================================================================
C
      character  fname*80
C
C SOME DIMENSION STATEMENTS MAY BE NEEDED IF YOU ARE DOING ADDITIONAL
C CALCULATIONS ON THE DATA
C
      dimension coords(3,mintpt)
      dimension iconn(3,melem),loc_el(melem)
      dimension naxipt(melem),iglb_nod(mnode),loc_nod(mnode)
      dimension islct(mkey),nintpt(melem),nodel(melem),iglb_el(melem)
      dimension xyz(3,mnode),xpos(mnode),tang1(3),tang2(3)
      dimension rot(3,3),xc(3),xpr(3,mintpt),scord(3,mintpt),xnorm(3)
      dimension isctchk(melem),icrdchk(melem),ivarchk(melem)

C The following line places array 'var' on the stack. This array is very
C large (~40MB in size). This will cause problems on Windows, where the size 
C of the stack is fixed and cannot be easily grown.
C
C      dimension var(513,melem)
C
C It is advisable to place large data structures like this into 
C dynamically-allocated memory, like so:

      ALLOCATABLE ::var(:,:)
      ALLOCATE(VAR(513,melem))

C
C==================================================================
C
C  GET THE NAME OF THE RESULTS FILE.
C
C==================================================================
C
      isect1 = 0
      intpt1 = 0
      icomp  = 1
C
      write(6,'(A$)') 'Enter the name of the input file (w/o .fil): '
      read(5,'(A)') fname
C
 100  write(6,*) 'Enter the postprocessing option:'
      write(6,*) ' 1 - variation along the riser '
      write(6,*) ' 2 - variation around the circumference'
      write(6,*) '     of the elbow'
      write(6,*) ' 3 - ovalization of elbow cross-section'
      read(5,*) ipost

      if (ipost .ne. 1 .and. ipost .ne. 2 .and.
     &    ipost .ne. 3) then
         write(6,*)'Invalid entry - try again'
         go to 100
      endif
C
      write(6,*)'Enter the first element number'
      read(5,*) jel_1
C
      if (ipost .ne. 1) then
        jel_2 = jel_1
      else
        write(6,*)'Enter the last element number'
        read(5,*) jel_2
      endif
      if (jel_2 .lt. jel_1) then
         write(6,*)'last elem number must be greater than first'
         return
      endif
      jdiff = jel_2 - jel_1 + 1
      if (jdiff .gt. melem) then
         write(6,*)'Too many elements - max is',melem
         return
      endif
C
      if (ipost .lt. 3) then
         write(6,*)'Enter the section point number'
         read(5,*) isect1
      endif
C
      if (ipost .eq. 1) then
        write(6,*)'Enter the integration point number'
        read(5,*) intpt1
      endif
C
      if (ipost .lt. 3) then

 998  write(6,999)
 999  format(' Enter the key for the variable you wish to process:')
C
      write(6,500)
 500  format(2x,'TEMP ......  2',/,
     &       2x,'COORD......  8',/,
     &       2x,'S.......... 11',/,
     &       2x,'SINV....... 12',/,
     &       2x,'SF......... 13',/,
     &       2x,'E.......... 21',/,
     &       2x,'PE......... 22',/,
     &       2x,'CE......... 23',/,
     &       2x,'IE......... 24',/,
     &       2x,'EE......... 25',/,
     &       2x,'THE........ 88',/,
     &       2x,'LE......... 89',/,
     &       2x,'NE......... 90',/,
     &       2x,'SP.........401',/,
     &       2x,'EP.........403',/,
     &       2x,'NEP........404',/,
     &       2x,'LEP........405',/,
     &       2x,'EEP........408',/,
     &       2x,'IEP........409',/,
     &       2x,'THEP.......410',/,
     &       2x,'PEP........411',/,
     &       2x,'CEP........412')
C
      read(5,*) key
C
      if (key .ne. 2 .and. key .ne. 8 .and.
     &    key .ne. 11 .and. key .ne. 12 .and.
     &    key .ne. 13 .and. key .ne. 21 .and. 
     &    key .ne. 22 .and. key .ne. 23 .and.
     &    key .ne. 24 .and. key .ne. 25 .and.
     &    key .ne. 88 .and. key .ne. 89 .and.
     &    key .ne. 90 .and. key .ne. 401 .and.
     &    key .ne. 403 .and. key .ne. 404 .and.
     &    key .ne. 405 .and. key .ne. 408 .and.
     &    key .ne. 409 .and. key .ne. 410 .and.
     &    key .ne. 411 .and. key .ne. 412) then
C
        write(6,*)'Invalid key - try again'
        go to 998
C
      endif
C
C     Integration point coordinates available only at middle surface
C     Overwrite the section point and set to the default
C
      if (key .eq. 8) isect1 = 0
C
      if (key .ge. 8) then
        write(6,*)'Enter the attribute number'
        read(5,*) icomp
      endif
C
      if (key .eq. 13) then
        write(6,*)'Section force data written only once per element'
        if (ipost .eq. 1) then
          write(6,*)'Will use default integration & section point'
          write(6,*)' '
          intpt1 = 1
          isect1 = 0
        elseif (ipost .gt. 1) then
          write(6,*)'Only use with option 1: Processing terminated'
          return
        endif
      endif
C          
      endif
C
      write(6,*)' Enter the step number'
      read(5,*) istep1
      write(6,*)' Enter the increment number'
      read(5,*) iinc1
C
C SELECT THE RECORDS TO BE PROCESSED
C
C IF THE ISLCT ARRAY IS SET TO 1 THE DATA WILL BE PROCESSED
C IF THE ISLCT ARRAY IS SET TO 0 THE DATA WILL NOT BE PROCESSED
C
      do ii = 1, mkey
        islct(ii) = 0
      end do
C
C ELEMENT DEFINITION
      islct(1900)=0
C NODE DEFINITION
      islct(1901)=0
C INCREMENT START
      islct(2000)=0
C ELEMENT HEADER
      islct(1)=0
C COORD
      islct(8)=0
C     
      if (ipost .lt. 3) islct(key) = 1
      keyprv=0
C
      nels = 0
      numnp = 0
C
      itimchk = 0
      ielchk  = 0
      do i = 1, melem
         loc_el(i) = 0
         isctchk(i) = 0
         icrdchk(i) = 0
         ivarchk(i) = 0
         do j = 1, 513
            var(j,i) = 0.0
         end do
      end do
C
C==================================================================
C
C  OPEN THE OUTPUT FILE.
C
C==================================================================
      open(unit=9,file='output.dat',status='unknown')
C
      nru = 1
      loutf = 0
      lrunit(1,1) = 8
      lrunit(2,1) = 2
C
      call initpf(fname,nru,lrunit,loutf)
C
      junit = 8
C
      call dbrnu(junit)
C
C REWIND FILE
C
      call dbfile(2,array,jrcd)
C
C
C==================================================================
C
C  Read records from the results (.fil) file and process the data.
C  Cover a maximum of 10 million records in the file. 
C
C==================================================================
C
      do 1000 k100 = 1, 100
      do 1000 k1 = 1, 99999
C
C READ RECORD FROM .FIL FILE AND PROCESS DATA.
C
      call dbfile(0, array, jrcd)

         if (jrcd .ne. 0 .and. keyprv .eq. 2001) then
           write(6,*)'End of file'
           close(junit)
           go to 1001
         else if (jrcd .ne. 0) then
           write(6,*)'Error reading input file'
           return
         endif
C
C LENGTH AND KEY RECORD NUMBER ARE ALWAYS NEEDED
C
         lenf= jrray(1,1)
         key = jrray(1,2)
C
C SPECIFIC RECORD NUMBERS FOLLOW...
C
C==================================================================
C
C ELEMENT DEFINITIONS
C
C==================================================================
        if ( key .eq. 1900 ) then
            jelnum=jrray(1,3)
            if (jelnum .gt. melem) then
               write(6,*)'Maximum global elem number too large'
               write(6,*)'Increase melem'
               return
            endif
            ctype=  array(4)
            if (jelnum .ge. jel_1 .and. 
     &          jelnum .le. jel_2) then
              ielchk = 1
              nels = nels + 1
              jel = nels
              iglb_el(jel) = jelnum
              loc_el(jelnum) = jel
              nodel(jel) = lenf - 4
              naxipt(jel) = 1
              if (ctype .ne. 'ELBOW31' .and.
     &            ctype .ne. 'ELBOW31B' .and.
     &            ctype .ne. 'ELBOW31C' .and.
     &            ctype .ne. 'ELBOW32') then
                 write(6,*)'Invalid element type encountered'
                 return
              endif
              if (ctype .eq. 'ELBOW32')naxipt(jel) = 2 
              do kk=5,lenf
                ii=kk-4
                iconn(ii,jel)=jrray(1,kk)
              end do
            endif
            keyprv = key
            goto 9099
C
C==================================================================
C
C NODE DEFINITIONS
C
C==================================================================
        else  if ( key .eq. 1901 ) then
            
            jnod = jrray(1,3)
            if (jnod .gt. mnode) then
               write(6,*)'Maximum global node number exceeded'
               write(6,*)'Increase mnode'
               return
            endif
            numnp = numnp + 1
            iglb_nod(numnp) = jnod
            loc_nod(jnod) = numnp
            xyz(1,numnp) =  array(4)
            xyz(2,numnp) =  array(5)
            xyz(3,numnp) =  array(6)
            keyprv = key
            goto 9099
C
C==================================================================
C
C CURRENT STEP AND INCREMENT NUMBER.
C
C==================================================================
        else if ( key .eq. 2000 ) then
            ttime=array(3)
            stime=array(4)
            sfreq=array(12)
            istep=jrray(1,8)
            iinc =jrray(1,9)
C
C           SET THE FLAG ITIME IF THIS IS THE REQUESTED STEP/INC
C
            if (istep .eq. istep1 .and.
     &         iinc  .eq. iinc1) then
              itime = 1
              itimchk = 1
            else
              itime = 0
            endif
c
            keyprv = key
            goto 9099
C
C==================================================================
C
C ELEMENT VARIABLES AT INTEGRATION POINTS WITHIN THE ELEMENT
C
C==================================================================
C
C ELEMENT DATA
C
         else if ( key .eq. 1 ) then
 
C
C    PROCESS THIS RECORD IF THIS IS THE CORRECT STEP/TIME
C
            if (itime .eq. 1) then
              jelnum = jrray(1,3)
              jel    = loc_el(jelnum)
              ielem  = 0
C
C    PROCESS THIS ELEMENT IF IT IS IN THE LIST OF DESIRED ELEMS
C
              if (jel .gt. 0) then
                ielem  =  1
                intpn  =  jrray(1,4)
                if (intpn .gt. mintpt) then
                   write(6,*)'Max number of int points exceeded'
                   write(6,*)'Increase mintpt'
                   return
                endif
                isect  =  jrray(1,5)
                ilocn  =  jrray(1,6)
                if (ilocn .ne. 0) then
                   write(6,*)'Element data must be at the int points'
                   return
                endif
                crbar  =  array(7)
                ndi    =  jrray(1,8)
                nshr   =  jrray(1,9)
                ndir   =  jrray(1,10)
                nsfc   =  jrray(1,11)
                if (isect .eq. isect1)then
                  isctflg = 1
                  isctchk(jel)  = 1
                else
                  isctflg = 0
                endif
                if ( (ipost .eq.1 .and. intpn .eq. intpt1) .or. 
     &                ipost .gt. 1) then
                  iptflg = 1
                else
                  iptflg = 0
                endif
              endif
            endif
            keyprv = key
            goto 9099
C
C==================================================================
C
C COORDINATES
C
C==================================================================
        else  if ( key .eq. 8 .and. ipost .gt. 1) then
C
C       PROCESS IF THIS IS THE CORRECT STEP/INC, ELEMENT, SECTION 
C       POINT, AND INTEGRATION POINT 
C
            icheck = itime*ielem*iptflg
            if (icheck .eq. 1 ) then
c            if (ipost .eq. 3) nintpt(jel) = intpn
               icrdchk(jel) = 1
               if (ipost .gt. 1) nintpt(jel) = intpn
               do kk=3,lenf
                  ii=kk-2
                  coords(ii,intpn)=array(kk)
               end do
C
            if (islct(key) .eq. 1 .and. ipost .lt. 3) then
              ivarchk(jel) = 1
              jvar = intpn
              nintpt(jel) = intpn
              do kk=3,lenf
                ii=kk-2
                var(ii,jvar)=array(kk)
              end do
              if (icomp .gt. ii) then
                 write(6,*)'Invalid component'
                 return
              endif
            endif
C
            endif
            keyprv = key
            goto 9099
C
C==================================================================
C
C VARIABLE RECORD
C
C==================================================================
C       PROCESS IF THIS IS THE DESIRED VARIABLE

        else if (islct(key) .eq. 1 .and. ipost .lt. 3) then
C
C       CONTINUE PROCESSING IF THIS IS THE CORRECT STEP/INC, ELEMENT, 
C       SECTION POINT, AND INTEGRATION POINT 
C
          icheck = itime*ielem*isctflg*iptflg
          if (icheck .eq. 1 ) then
            ivarchk(jel) = 1
            if (ipost .eq. 1) then
             jvar = jel
            else
             jvar = intpn
            endif
            nintpt(jel) = intpn
            do kk=3,lenf
              ii=kk-2
              var(ii,jvar)=array(kk)
            end do
            if (icomp .gt. ii) then
               write(6,*)'Invalid component'
               return
            endif
          endif
        keyprv = key
        goto 9099
C
C==================================================================
C
C    ANYTHING ELSE
C
C==================================================================
         else
c            write (6,9000) key
9000        format(I5,' *** NO CODING FOR THIS RECORD ***')
            keyprv = key
9099     end if
C
C==================================================================
C
C    END LOOPS
C
C==================================================================
 1000 continue
 1001 continue
C
C==================================================================
C     POSTPROCESS DATA HERE
C==================================================================
      do ii = 1, nels
         nintpt(ii) = nintpt(ii)/naxipt(ii)
      end do 
C
C==================================================================
C     VERIFY THAT APPROPRIATE DATA WERE WRITTEN TO RESULTS FILE
C==================================================================
c     iquit = 0
      if (ielchk .eq. 0) then
         write(6,*)'Desired element not found'
         return
      endif
C
      if (itimchk .eq. 0) then
         write(6,*)'Desired step/increment not found'
         return
      endif
C
      do iel = 1, nels
         if (isctchk(iel) .eq. 0 .and. ipost .lt. 3) then
            write(6,*)'Desired element and/or section point not found'
            return
         endif
         if (icrdchk(iel) .eq. 0 .and. ipost .gt. 1) then
            write(6,*)'Integration point coords not found'
            return
         endif
         if (ivarchk(iel) .eq. 0 .and. ipost .lt. 3) then
            write(6,*)'Desired element variable not found'
            return
         endif
      end do
C
C****************************************
C
C     PLOT VARIABLE ALONG ELBOW LENGTH
C
C****************************************
C
      if (ipost .eq. 1) then
C
         nn_old = iconn(nodel(1),1)
         do iel = 1, nels
            nn_new = iconn(1,iel)
            if (iel .gt. 1 .and. nn_new .ne. nn_old) then
               write(6,*)'Error in element connectivity'
               return
            endif
            nnum_b = iconn(1,iel)
            nnum_b = loc_nod(nnum_b)
            nnum_e = iconn(nodel(iel),iel)
            nnum_e = loc_nod(nnum_e)
            if (iel .eq. 1) xpos(nnum_b) = 0.0
            xlength = 0.d+0
            do jj = 1, 3
               delx = xyz(jj,nnum_e) - xyz(jj,nnum_b)
               xlength = xlength + delx*delx
            end do
            xlength = sqrt(xlength)
            xpos(nnum_e) = xpos(nnum_b) + xlength
            x_mid = 0.5*(xpos(nnum_e) + xpos(nnum_b))
C
C     EXTRACT VARIABLE INFORMATION AND WRITE TO FILE
C
            data = var(icomp,iel)
            write(9,2000)x_mid,data
 2000       format(5x,e17.9,5x,e17.9)
C
            nn_old=iconn(nodel(iel),iel)
C
         end do
         return
C
C
C****************************************
C
C     PLOT VARIABLE AROUND CIRCUMFERENCE OF ELBOW
C
C****************************************
C
       else if (ipost .eq. 2) then
C
         xpos(1) = 0.0
C
         locel = loc_el(jel_1)
         iaxial = 1
C
         if (naxipt(locel) .eq. 2) then
 3000       write(6,*)'Enter the axial station'
            read(5,*)iaxial
            if (iaxial .ne. 1 .and. iaxial .ne. 2) then
               write(6,*)'Try again - station must be 1 or 2'
               go to 3000
            endif
         endif
C
         do ipt = 1 , nintpt(locel)
            jpt = ipt + (iaxial - 1)*nintpt(locel)
            if (ipt .gt. 1) then
               xlength = 0.0
               do jj = 1, 3
                  delx = coords(jj,jpt) - coords(jj,jpt-1)
                  xlength = xlength + delx*delx
               end do
               xlength = sqrt(xlength)
               xpos(ipt) = xpos(ipt-1) + xlength
            endif
C
C     EXTRACT VARIABLE INFORMATION AND WRITE TO FILE
C
            data = var(icomp,jpt)
            write(9,2000)xpos(ipt),data
C
         end do

         ipt = 1
         jpt = ipt + (iaxial - 1)*nintpt(locel)
         data = var(icomp,jpt)
         xfinal = xpos(nintpt(locel)) + (xpos(2)- xpos(1)) 
         write(9,2000)xfinal,data

         return 
C
C****************************************
C
C     OVALIZATION PLOT
C
C****************************************
C
       else if (ipost .eq. 3) then
C
         locel = loc_el(jel_1)
         iaxial = 1
C
         if (naxipt(locel) .eq. 2) then
 3500       write(6,*)'Enter the axial station'
            read(5,*)iaxial
            if (iaxial .ne. 1 .and. iaxial .ne. 2) then
               write(6,*)'Try again - station must be 1 or 2'
               go to 3500
            endif
         endif
C
C     AVERAGE THE COORDS OF THE INTEGRATION POINTS TO GET THE CENTER
C            
         do i = 1, 3
            xc(i) = 0.0
         end do
C
         xnint = real(nintpt(locel))
C
         do ipt = 1 , nintpt(locel)
            jpt = ipt + (iaxial - 1)*nintpt(locel)
C
            do i = 1, 3
               xc(i) = xc(i) + coords(i,jpt)/xnint
            end do
C
         end do
C
C     SHIFT THE COORDINATES SO THAT CENTER OF SECTION IS AT ORIGIN
C
         do ipt = 1 , nintpt(locel)
            jpt = ipt + (iaxial - 1)*nintpt(locel)
            do i = 1, 3
               scord(i,jpt) = coords(i,jpt) - xc(i)
            end do
C
         end do
C
C     DETERMINE TANGENT VECTOR 1 (FROM CENTER OF CROSS-SECTION 
C                                 TO INT PT 1)
C
         jpt = 1 + (iaxial - 1)*nintpt(locel)
         xmag = 0.0
         do i = 1, 3
            tang1(i) = coords(i,jpt) - xc(i)
            xmag = xmag + tang1(i)*tang1(i)
         end do
         xmag = sqrt(xmag)
         do i = 1, 3
            tang1(i) =  tang1(i)/xmag
         end do
C
C     GUESS TANGENT VECTOR 2 (FROM CENTER OF CROSS-SECTION 
C                             TO INT PT 2)
C
         jpt = 2 + (iaxial - 1)*nintpt(locel)
         xmag = 0.0
         do i = 1, 3
            tang2(i) = coords(i,jpt) - xc(i)
            xmag = xmag + tang2(i)*tang2(i)
         end do
         xmag = sqrt(xmag)
         do i = 1, 3
            tang2(i) =  tang2(i)/xmag
         end do
C
C     DETERMINE THE NORMAL VECTOR, TANG1 X TANG2
C
         xnorm(1) =   tang1(2)*tang2(3) - tang1(3)*tang2(2)
         xnorm(2) = - tang1(1)*tang2(3) + tang1(3)*tang2(1)
         xnorm(3) =   tang1(1)*tang2(2) - tang1(2)*tang2(1)

         xmag = 0.0
         do i = 1, 3
            xmag = xmag + xnorm(i)*xnorm(i)
         end do
         xmag = sqrt(xmag)
         do i = 1, 3
            xnorm(i) = xnorm(i)/xmag
         end do
C
C     REDEFINE TANGENT VECTOR 2 
C
         tang2(1) = - tang1(2)*xnorm(3) + tang1(3)*xnorm(2)
         tang2(2) =   tang1(1)*xnorm(3) - tang1(3)*xnorm(1)
         tang2(3) = - tang1(1)*xnorm(2) + tang1(2)*xnorm(1)
C
C     DETERMINE THE ROTATION MATRIX
C
         do i = 1, 3
            rot(1,i) = tang1(i)
            rot(2,i) = tang2(i)
            rot(3,i) = xnorm(i)
         end do
C         
C     TRANSFORM COORDINATES INTO LOCAL SYSTEM
C
         do ipt = 1 , nintpt(locel)
            jpt = ipt + (iaxial - 1)*nintpt(locel)
            do i = 1, 3
               xpr(i,ipt) = 0.0
               do j = 1, 3
                  xpr(i,ipt) = xpr(i,ipt) + rot(i,j)*scord(j,jpt)
               end do
            end do
         end do
C
C     OUTPUT COORDS TO FILE
C
         do ipt = 1, nintpt(locel)
            write(9,4000)(xpr(i,ipt),i=1,2)
 4000       format(5x,e17.9,5x,e17.9,5x,e17.9)
         end do
C
         ipt = 1
         write(9,4000)(xpr(i,ipt),i=1,2)

       endif
C
      close (unit=9)
C
      IF( ALLOCATED(var) ) DEALLOCATE(var)

      return
      end
