Anda di halaman 1dari 48

Generation of Graded Triangular

and Quadrilateral Mesh

Appendix: Source Codes Listing

TUE-Research Report
Gaohong Xie

Oct. 1992 WPA 1417

Fac. of WPA, Dept. of Mechanical Engineering


Eindhoven University of Technology
P.O.Box 513,5600 MB
Eindhoven, The Netherlands
GENERATION OF GRADED TRIANGULAR
AND QUADRILATERAL MESH
Appendix: Source Code Listing

G. Xie
Fac. of WPA, Dept. of Mechanical Engineering
Eindhoven University of Technology
P.O.Box 513, 5600 MB, Eindhoven, The Netherlands

Introduction
The complete package of mesh generator is composed of 48 subroutines written in standard
FORTRAN 77 computer language. The additional 4 subroutines are machine/compiler re-
lated for building plot file and getting CPU time, All these subroutines were indicated in
the source codes and can be dropped. The package itself will perform all input data check-
ing and report to the output file on errors, warnings and advises to the solution. To install
the package, the user have to make necessary changes in subroutines gtimeJor, pltcv.for,
dminmx.for and transc.for. After that compile them with a compatible FORTRAN com-
piler and link them to generate executable file mesh.exe

To generate mesh, the user need prepare an input file named meshin, the results without
graphic possibilities are written into the file meshout which include all input and output
information in text form. The implementation of input file is described in the report WPA
1409, Oct. 1992, Eindhoven University of Technology, The Netherlands.

The necessary control and output variables are listed in the following table. The integer is
given by its range, the real is given by its sign ( + ). In case of array, the array's dimension
is given. (IK=1000)

Name I/O Min/Max Type Function

ishape I 3/6 I Element type number (3,4,6)


nsurf I 1/15 I Total number of surfaces
ncurve I 3/50 I Total number of curves (including inner opennings)
nuspnt I 3/100 I Total number of user points (numbered from 1 to nuspnt)
nspint I 1/20 I Total number of internal control points
lcurve I 6/100 I Nodal number of each curve

1
isurf I 3/15 I Curve number of each surface
cunit I + R Nodal spacing unit
corase I 3/100 R Nodal spacing of each user point
rinput I 6/200 R Coordinates of each user point
fact I + R Local refinement area factor
cascon I 1/20 R Internal controll point spacing
xycon I 2/40 R Internal controll point coordinates
nelem 0 1/6K I Total number of elements in the mesh
npoint 0 1/5K I Total number of nodal points (including user points)
ntadj 0 1/24K I Nodal number of each element (right hand squence)
neadj 0 1/45K I Element number connected to each node
ibncv 0 1/400 I In case of 3 node element, outer bounary nodal numbers
mner 0 1/50 I Inner boundary curve numbers
rinput 0 6/IOK R Coordinates of each nodal point

The other variables can be found in the source code. When calling from other program
to start mesh generator, the necessary information concerned in subroutine rdmesh input
records should be supplied. If you have any questions and comments, please contact the
author.

Gaohong Xie
Wh -1.15, tel:(040)-474828
Fac. of WPA, Dept. of Mech. Eng.
Eindhoven University of Technology

2
Source Codes Listing

c *** ********.****************************************************
c
c programmer Xie Gaohong
c version 1.0 date 20-08-92
c
c copyright (c) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MB, Eindhoven, The Netherlands"
c
c ****.*.****************** ***************.************************

program mesh
implicit double precision (a-h,o-z)
dimension isurfI15,30),ncsf(15),icurve(100).ibncv(50.400),
v inner(SO).neadj(45000),ntadj(24000).nelmcv(50)
dimension corese(' OOI,rinput(1 0000)
common/controll nspint,fact,cescon,xycon
integer nspint
dimension cascon(20),xycon(40},usnsp(' CO}
double precision pi,tol,tolin,corase,rinput
reel ttl,tt2
common/const/ pi,tol
commonliounit/ iore,iowr
character * 20 namere, nemewr
integer ncsf,isurf,ncurve,nsurf,icurve,ibncv.inner,nelmcv
integer nuspnt, npoint, nelem,ishape
integer needj,ntadj
integer iore,iowr
save IconsU, liounit/, Icontroll
c
c********************************************************************
c This part purely for the interface of sepren

call start(O, 1 ,1 ,n
c**********************************************************************
c
c initialise some constants
c
tolin = lOe-6
call initcb(tolin)
c
namere = 'meshln'
=
namewr 'meshout'
open (unit=iore, file=namere)
open (unit =iowr, file = namewr)
c
c read all necessary information on mesh region, perform check
c get time routine gtime is machine dependent, FTN77 compiler only
c
call gtime(tt1 )
call rdmesh(nsurf,ncurve,nuspnt,isurf,icurve,ncsf,ishape,
v cunit,corase,rinput,nspint,cascon,xycon)
call gtime(tt2}
tt2 =tt2-ttl
write(iowr, *) 'CPU time in rdmesh is',tt2
caliloopck(nsurf,ncurve,nuspnt,isurf,ncsf,icurve}
nelem=O
c
c initialise global arrays and build up fronts and adjacence
c
caU gtime(tt1}
call initia(neadj,ntadj,nsurf ,isurf, ncsf ,ncurve,icurve,
v nuspnt,npoint,nelmcv,ibncv,cunit,corase,rinput,usnsp)
call gtime{tt2)
tt2=tt2-ttl
writeliowr, *) 'CPU time in initia is' ,tt2
call cklimt(nsurf,isurf, ncsf ,nelmcv}
c
c print out boundary information
c
call prtbn(nuspnt,ncurve,nelmcv,ibncv,rinput}
c
c figure out inner boundaries
c
call innerc(nsurf,isurf,ncsf,ncurve,inner)
c
c generate mesh on each surfaces and put data to adjacence array
c
call gtime(ttl)
call genmsh(nsurf,isurf,ncsf,ncurve,icurve,nuspnt,npoint,
v nelem,nelmcv,ibncv,neadj,ntadj,rinput,usnsp)
call gtime(tt2)
tt2 = tt2-ttl
write(iowr, iI) 'CPU time in genmsh is',tt2
write(iowr, )'number of node points in base mesh',npoint
write(iowr, "I'number of elements in base mesh', nelam
c
c subroutine pltcv is machine dependent routine
c it will call sepran routine plafp6 for plot
c
call pltcv(3,nuspnt,nelem,ntadj,rinput)
c
c swap operation before smoothing the generated mesh
c
call gtime(ttl1
call s waped(nelem,neadj, ntadj, ri nputl
call gtime(tt2)
tt2 = tt2-tt 1
write(iowr, "} 'CPU time in swaped is',tt2
c
c centroid method for smoothing the generated mesh
c
call gtime(ttl}
call csmoth(3,npoint,ncurve,nuspnt,neadj,ntadj,
v inner,ibncv,nelmcv,rinput)
call gtime(tt21
tt2 =tt2-ttl
write(iowr, *) 'CPU time in csomth is',tt2
call pltcv(3,nuspnt,nelem,ntadj,rinputl

if(nspint.ge.l1 then
call gtime(ttll
c apply local refinement to base mesh
call refine(npoint,nelem,ishape,neadj,ntadj,rinput)
call gtime(tt21
tt2 =tt2-ttl
write(iowr, *1 'CPU time in local refine is',tt2
call gtime(ttl)
call swaped (nelem, neadj, ntadj, rinput,
call csmoth(3,npoint,ncurve,nuspnt,neadj,ntadj,
v inner,ibncv,nelmcv,rinput)
call gtime(tt2)
tt2 = tt2-ttl
write(iowr, *) 'CPU time in swap and smooth after
v local refinement is',tt2
call pltcv(3,nuspnt,nelem,ntadj,rinput)
endif

if(ishape.eq.6) then
call gtime(ttl)
call trans6(nelem,npoint,neadj,ntadj,rinput)
call gtime(tt2)
tt2 =u2-ttl
write(iowr, *) 'CPU time in trans6 is',tt2
endif
if(ishape.eqA) then
call gtime(ttl)
call trans4(nelem. npoint.neadj. ntadj. rinput)
call gtime(tt2)
tt2 .. tt2-ttl
writeliowr, *) 'CPU time in trans4 is',tt2
call gtime(ttl)
call csmoth(ishape.npoint.ncurve,nuspnt.neadj.
v ntadj.inner.ibncv,nelmcv,rinput)
oall gtimeltt2)
tt2 = tt2-ttl
write(iowr.*) 'CPU time in csomth to q-mesh is',tt2
call pltcvCishape, nuspnt,nelem, ntadj. rinput)
endif

writeliowr, *) 'number of node points', npoint


write(iowr, *) 'number of elements', nelem
write(iowr, *) 'outputs after swapping and smoothing'
call gtimelttl)
call prtneo(ishape.nelem.npoint.neadj,ntadj.rinput)
call gtime(tt2)
tt2 =tt2-ttl
write(iowr, *) 'CPU time in prtneo is' .tt2
close(iowr)
call finish(O)
end
c ********************* *** *******************.**************.****
c
c programmer Xie Gaohong
o version 1.0 date 17-08-92
c
c function area calculate the double aree value of a given
c triangule composed by points al.a2,a3
c
c *.*.***** ****.**** **.******.*****.**** ***.*.***********.***
c
o input/output
c
c a1,a2,a3 array of length 2, contains the coordinates of three
c point of triangular
o 0 area the double value of an area of triangular
c
c *********************** *********.************.*****.***.*********
c
funotion area(a1,a2,a3)
double preoision a1(*),a2(*),a3(*),area

area = a1 (1)*a2(2) +a2(1) *a3(2) + a3(1) *al (2)-


v al (1) *a3(2)-a2(1 )*a1{2)-a3(1) *a2(2)
end
c *********** ********************************************* *******
c ..
c" subroutine to update adjaoence lists when bi-secting is performed
c
c ********************************** ***************************.*******
c
c programmer Xie Gaohong
C .. version 1.0 date 08-08-92
c ..
c * copyright (c) 1992 "WPA, Dept. of Mechanical Engineering
c .. Eindhoven University of Technology
c .. 5600 MB. Eindhoven. The Netherlands.
c ..
c *****************************************.***************.***********.*
c ..
subroutine bisect(ip,ifirst.ipoint,ilast,nelem.npoint,
v nptemp,nnadj,neadj,ntadj)
implicit double precision la-h,o-zl
dimension nnadj(800,3),neadj(*),ntadj()
integer ipoint,ifirst,ilast,nelem,npoint,nnadj,neadj,ntadj
integer ip,ipnew,nptemp

c ipoint: euurent point in consideration.


e ifrist: backward point, ilast: forward point
c nelem: current element number, npoint: current node number
o nnadj: node-node adjaoence list, neadj: node-element adjacence list
o ntadj: element-node adjaoenee list

npoint = npoint + ,
cell update(nelem,ipoint, npoint,ifirst, neadj, ntadj)

o update second element-node adjacence list

call update(nelem,ipoint,ilast,npoint,neadj,ntadj)

o update node-node adjaoence list


c since biseot only adds one new node, and one node was
c made inaotive, therefore only ohange the current point position

nnadjlip, , I = npoint
call findip(ifirst,ipnew, nptemp,nnadj)
nnadj(ipnew,3) = npoint
call findip(ilast,ipnew,nptemp,nnadjl
nnadj{ipnew ,2) = npoint
return
end
c*****************************************************************
o
o programmer Xie Gaohong
c version 1.0 date 10-08-92
c
c oopyright (0) 1992 "WPA Dept. of Mechanioal Engineering,
o Eindhoven University of TEohnology,
c 5600 MB, Eindhoven, The Netherlands"
c
c *********.*******************.**************************************
c
o subroutine to check if one triangles or one quadrangle left
e
c ****************************.*.***************.*********************
o
subroutine chkfin(nptemp,nnadj)
implicit double precision (a-h, o-z)
integer nptemp,nnadj,jj,iaot
dimension nnadj(800,3)
o
iact=O
do 301 jj = l,nptemp
if(nnadj(jj,l ).gt.O) iact =iact + 1
if(iact.ge.4) return
301 continue
if(iaot.lt.3) then
nptemp =-nptemp
return
endif
end
c ***********************************************************************
elf
o If subroutine to estimate total nodal number and total elements
c * number in each surface to ensure given array bounds fit
c *
c ***** *************** *.**.*.*********.**** *****.*****************.
c
c programmer Xie Gaohong
o * version 1.0 date 28-08-92
o
c copyright (c) 1992 "WPA, Dept. of Mechanical Engineering
c * Eindhoven University of Technology
o 5600 MB, Eindhoven, The Netherlands.
0*
c**********************************************************************
subroutine cklimt(nsurf,isurf,ncsf ,nelmcv)
implicit double precision (a-h,o-z)
integer isc,isf,nenow,ncsf(*),isurf(15,30),nelmcv()
integer npetot,nstotl,maxelm,maxpnt,maxtmp

c" for current isnum surface do

maxelm = 8000
maxpnt = 5000
maxtmp=800
npetot=O
nstot/=O

do 350 isf = , ,nsurf


do 300 isc = l,ncsf(isf)
neno w = nelmcv(abs(isurf(isf ,isc)))
nstott = nstotl + nenow
300 continue
if(nstotl.ge.maxtmp) call ermess(O,
V 'cklimt: current active nodes in one surface are more
v than array upper bounds, try to reduce nodal spacing')
npetot = npetot + nstotl
350 continue
npetot =npetotf4
npetot =npetot npetot
if(npetot.ge.maxpnt) call ermess(1,
v 'cklimt: total nodal points could be more than erray
v upper bounds, try to reduce nodal spacing')
npetot = nint(npetot" 1.6)
if(npetot.ge.maxelm) call ermess(l,
v 'cklimt: total element number could be more than array
v upper bounds, try to reduce nodal spacing')
return
end
c *.*****************************************.***************************

c
c subroutine to update adjacence lists when closing is performed
c *
c .*****.********************************************.*******************
c"
c " programmer Xie Gaohong
c " version 1.0 date 08-08-92
c"
c .. copyright (e) 1992 "WPA, Dept. of Mechanical Engineering
e .. Eindhoven University of Technology
c " 5600 MB, Eindhoven, The Netherlands.
c ..
c *************** ******************************************************

c
subroutine closep(ip,ifirst,ipoint,ilast,nelem,nptemp,
v nnadj,neadj,ntadj)
implicit double precision (<,-h,o-z)
dimension nnadj(800,3),neadj(*),ntadj(*)
integer ipoint,ifirst,ilast,nelem,nnadj,neadj,ntadj
integer nptemp,ip,ifdex

c ipoint: cuurent point in consideration.


c ifrist: backward point, ilast: forward point
c nelem: current element number
c nnadj: node-node adjacence list, neadj: node-element adjacence list
c ntadj; element-node adjaoence list

call update(nelem,ipoint,ilast,ifirst,neadj,ntadj)

c update node-node adjacence list

ifdex=O
call findip(ifirst,ipnew,nptemp,nnadj)
if(nnadj(ipnew,2).eq.i1ast) ifdex = ipnew
nnadj(ipnew,31 =ilast
call findiplilast,ipnew,nptemp,nnadj}
nnadj(ipnew,2) =ifirst

c mark node ipoint as inactive node

nnadj(ip, 1) =-ipoint
if(ifdex.ne.O) then
nnadjlifdex,l) =-ifirst
nnadj(ipnew,1) = -ilast
end if
return
end
c *********.**.* *.*.*** ****** *********************************
c
c programmer Xie Gaohong
c version 1.0 date 16-08-92
c
c copyright (c) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MB, Eindhoven, The Netherlands"
c
c **** ******** *.***********************************************
c
c This subroutine is called to smooth the generated mesh with
c centroid method (see 'mesh generation for planar reggions'
c by L. Sezer end I. Zeid, int.j.for numer. methods in eng.1991
c
c *********.***************************.******************************
c
subroutine csmoth{ishape,npoint,ncurve,nuspnt,neadj,
v ntadj,inner,ibncv,nelmcv,rinput)
implicit double precision (a-h,o-z)
integer npoint,ncurve,nuspnt,neadj,ntadj,inner,ibncv,npqout
integer ishape,ivl,iv2,iv3,iv4,itime,ip,ichois,ie,ine,iem
dimension neadj(*),ntadj(*),rinput(*)
dimension ibncv(50,400),nelmcv(*)
dimension inner( *),a 1 (21,a2(2),a3(2),a4(2I,xy(2),c(2)
c
c .*******************************************************************
c
do 900 itime =1 ,3
do 100 ip = nuspnt + 1,npoint
call ifoutb(ip,ichois,ncurve,ibncv,nelmcv,innerl
c
c ichois = 1, ip point is outer boundary point
c
iflichois.eq.1) go to 100
if(ishape.eq.4) then
if(npqout(ip,neadj).eq.l) go to 100
endif
c
c stotal = 0, xylil = 0
c
stotal=O
xyll) =0
xy(2) =0
do 200 ie=1,9
iem = neadj(9 *(ip-1) + ie)
if(iem.eq.O) go to 210
ine =3*(iem-l)
if(ishape.eq.41 ine =4 * Oem-l)
ivl == ntadj(ine + 11
iv2 = ntadj(ine + 2)
iv3 ==ntadj(ine + 3)
if(ishape.eq.4) iv4 =ntadjline + 4)
c
c get current element's three vertices and calculate center
c
do 300 i=1,2
a1 Ii) = rinput(2 *(jv1-1) +i)
a21i) = rinput(2 *Ov2-1) + i)
e3(i) '" rinput(2 * (iv3-1) + il
if(ishape.aq.4) a4(i) =rinput(2*(iv4-1) +i)
c(i) = (al Ii) + a2m + a3(ill/3.0
if(ishapa.eq.4) eli) = (a1 (i) + a2(i) + a31i) + a4(i})/4.0
300 continue
atri =0.5*abs(area(a1,a2,a311
if(ishape.eq.4) atri == atri + 0.5 * abs(area(a3.a4,a 1))
xy(l) =xy(l) + c(l )*atri
xy(2) =xy(2) +c(2)*atri
stotal '" stotal + atri
200 continue
210 continue
xy(1 ) = xy(1 )/stotal
xy(2) =xy(2)/stotal
rinput(2 *ip-l) '" xyll)
rinput(2*ipl ",xy(2)
100 continue
900 continue
end
c*********************************************************************
c
c Programmer Xie Gaohong
c Version 1.0 date 11-08-92
c
c copyright (c) 1992 WWPA Dept. of Mechanical Engineering.
c Eindhoven University of TEchnology,
c 5600 MB. Eindhoven. The Netherlands"
c *****.**************************************************************
c
c This subroutine is called to determine the number of elements
c along the two user given points ipl to ip2
c
c **************************************************************************
c
subroutine curvne(ipl,ip2,irevs,nelm,rinput,cunit,corase,
v coas.edges,diffl
implicit double precision (a-h, o-z)
integer ip l,ip2.nelm,irevs
common/constl pi.tol
dimension rinput(*),corase(*)
c
c ip l,ip2 i points of line ip 1 to ip2
c
c rinput i array filled with user points coordinates
c
c corase i array filled with user points coarseness
c
c **************._****************************************************
c
irevs=O
cl =corase{ipll
c2 =corese(ip2)
xl =rinput(2*ipl-1l
yl =rinput(2*ipl)
=
x2 rinput(2 ip2-l1
y2=rinput(2*ip2)
c> > calculate length square
sleng = sqrt((x2-xl) *(x2-xl ) + (y2-yl) * (y2-yll1
c check
if(sleng.le.tol*(abs(x2-xl) + abs(y2-yl III call ermess(l,
v 'cufvne: two user given points too close to each other')
ooas=c2/cl
if(coas.lt.l dO) then
ooas=01/02
irevs=l
tem=cl
cl =02
c2=tem
endif
avesp =0.5*(02 + (1)
If(00as.ge.2) avesp =0.5*(0.6*02 + (1)
If(ooas.ge.4) avesp =0.5*(0.3*02 +(1)
if(coas.ge.10) avesp =0.5*(0.1 *c2+(1)
i1(coas.ge.20) evesp =0.5"(0.03 *02 +(1)
nelm .. nint(sleng/avesp" ounit + 0.9)
if(nelm.le.l.end.(coes-1I.le.0.l) then
nelm-l
return
endif
slenl =c1 "cunit

if Icoes.lt. 1. 1) then
edges = 1dO/float(nelm)
diff-ldO
else
if(nelm.eq.l) nelm = nelm + 1
101 continue
cr = log(ooas)/float{nelm-l)
diff .. exp(or)
if(diff .ge. 1 .2) then
nelm = nelm + 1
go to 101
endif
edges = (diff-l)/{diff* "nelm-1)
teml =edges"sleng
tem =tem '-slen l/slen 1
if(tem.le.0.1S) return
if(teml.gt.slenl) then
nelm = nelm + 1
go to 101
endif
endif
end
c**********************************************************************
o
c programmer Xie Gaohong
c version 1.0 date 20-09-92
c
c copyright (c) 1992 "WPA Dept. of Meohanioal Engineering,
c Eindhoven University of TEchnology,
c 5600 MS, Eindhoven, The Netherlands"
c
c ********************************************************************
c
c subroutine to form triangles in connector area
c
c ***.*.***.******.******** *.***************.**.********************
c
subroutine divide(idid,indexl,ip l,index2.ip2,in .iI2.nelem.
v npoint. nptemp.nnadj,neadj. ntadj,rinput)
implicit double precision (a-h, o-z)
integer npoint.nelem,nptemp,nnadj(SOO,3),neadj(*).ntadj(")
integer idid,indexl.ipl.index2.ip2.ifdex.ildex.ifl.iI2
double precision rinput(*}.cosl,cos2,sinl,sin2
double precision vl (2},v2(2),vt(2I,sp.sl,sf
c
idid=O
iflif1 .eq.i12) then
idid=1
call findipUf1,ifdex,nptemp.nnadj)
call update(nelem,ipl.ip2,ifl ,neadj,ntadjl
nnadj(indexl,2) =ip2
nnadj(index2,31 =ipl
nnadj(ifdex,l) = -ifl
return
endif

call getcr(ipl,vl.rinput)
call getcr(ip2.v2.rinput)
call getcr{ifl.vt,rinputl
call dotvec(vl. v2. vt,cos l.sin 1.sp.sf)
call getcr(il2.vt,rinput)
call dotvec{v2.vl.vt,cos2.sin2,sp.sl)
jf(sinl.1t.0.S.and.sin2.1t.0.S.and.
v cos1.lt.0.and.cos2.1t.0) return
call findip(ifl.ifdex.nptemp.nnadj)
call findip(il2.ildex,nptemp.nnadj)
c
c added a point in the middle of (ip1.ip2) three triagnles formed
c
if(cosl.ge.OdO.and.cos2.ge.OdO) then

if(sp.le.O.4*(sl + sf)) return


idid=l
c
c added a middla point of Up 1.ip2) and form three triangles
c
opoint = npoint + 1
rinput(2* npoint-1) =O.S"(vl (1) +v2(1))
rinput(2 "npoint) =O.S"lvl (2) +v2(2))
c
c three triangles (ifl.ip 1.npoint) (ifl.npoint.il2) (iI2.npoint,ip2)
c
call update{nelem,ip l,npoint,ifl,neadj.ntadj)
call update{nelem,ifl,npoint.il2.neadj.ntadj)
call update(nelem,il2,npoint.ip2,neadj.ntadj}
c
c update nnadj list
c
nnadj(ifdex.3) =il2
nnadj(ildex,2) -if1
nptemp = nptemp + 1
nnadj(nptemp. 1) = npoint
nnadj(nptemp,2) =ip2
nnadj(nptemp.3} =ipl
nnadj(indexl.2) =npoint
nnadj(index2.3) =npoint
return
endif
if(cosl.ge.OdO.and.cos2.1t.O) then
idid=l
c
c two triangles (ifl.ipl.ip2) lifl,ip2,il2)
c
call update(nelem,if1.ip 1.ip2.neadj.ntadj)
call update(nelem.ifl,ip2.iI2.neadj.ntadj)
c
c update nnadj list
c
nnadj(ifdex,3) =i12
nnadj(ildex.2) =ifl
nnadj(indexl.2) =ip2
nnadjlindex2.3} =ipl
return
endif
if{cos2.ge.OdO.and.cosl.1t.O) then
idid=l
c
c two traingles (ip2,U2.ipl) (if1.ipl.il2)
c
call update(nelem,ip2,iI2,ipl,neadj,ntadj)
call update(nelem,ifl,ip 1.iI2,neadi,ntadj)
c
c update nnadj list
c
nnadjlifdex.31 =il2
nnadjlildex.2) =if1
nnadj(indexl.21 = ip2
nnadjlindex2.3) -ip1
return
endif
if(cos2.1t.0.and.cos1.1t.0) then
idid - 1
c
c three traingles (ifl,ip1.npoint) lip1,ip2,npoint)
c (ip2,il2,npoint) and a new point npoint formed
c
call tsolxy(-l,l,vl,v2,vt,sl)
npoint - npoint + 1
rinputl2 *npoint-ll = vt(l )
rinput{2' npoint} =vt(2)
call updatelnelem,ifl,ip l,npoint,neadj,ntadj)
call update{nelem,ip 1,ip2,npoint,neadj,ntedj)
call update(nelem,ip2,il2,npoint,neadj,ntadjl
nnadj(ifdex,3) - npoint
nnadjlildex,2) -npoint
nnadjlindex1,2) - ip2
nnadj(index2,3) =ipl
nptemp - nptemp + 1
nnadj(nptemp,l) "" npoint
nnadj(nptemp,2) -ifl
nnadj(nptemp,3) -i12
return
endif
end
c **********************.*****.** *** *** **********.*****.** * **
c
c programmer Xie Gaohong
c version 1.0 date 10-09-92
c
c copyright (0)1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MS, Eindhoven, The Netherlands"
c
c **-*-** - _-*-****-_._._.* ... ***_._**-* ***._ **.* *.***
c
c This subroutine sort out the maximum and minimum x y coordinates
c
c*_ __ ******-*****_**.***.* .. ******
c
c input/output
c
c nuspnt number of points sort
c
c i rinput array sequentially stored x,y coordinates
c
c 0 ymax,ymin maximum and minimum y ooordinates
o
c 0 xmax,xmin maximum and minimum x ooordinates
c
c * -.** - - _._._*-----_._._-*.**_._.-- ... *_ ****.*
o
c This routine is only usad for plotting purpose, oan be dropad
c
subroutine dminmx(nuspnt, rinput,xmin,xmax, ymin, ymax)
implicit double preoision (a-h,o-z)
integer nuspnt,i
double preoision rinput,xmax,xmin,ymax,ymin
dimension rinput(*)
c
xmax = rinputl1}
xmin = rinput(1)
ymax = rinput(2)
ymin - rinput(2)
do 100 i-2,nuspnt
if(rinput(2 *i-1 ).gt.xmax) xmax = rinput{2 *j-1)
if(rinput(2 *i-1 ).It.xmin) xmin = rinput(2 *i-l)
if(rinput{2 *i).gt.ymax) ymax = rinput(2 "i)
if(rinput(2 *i).lt.ymin) ymin "" rinput(2 *i)
100 continue
return
end
c **********.*******.*************************************************
c
c programmer Xie Gaohong
c version 1.0 date 02-09-92
c
c copyright (c) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MB, Eindhoven, The Netherlands"
c
c******************************************************************
c
c This subroutine is called to a triangle's length sum and
c compare the distanoe with any internal control points
c
c ***.*****.******************.*.*.*.* *******.*****************
c
subroutine doref(ichois.vl, v2, v3)
implicit double precision (a-h,o-zl
double precision dtotal,dx,dy,dxy
integer iohois,nspint
dimension vl (*),v2(*),v3(*)
common/control/nspint, fact,cascon,xycon
dimension xycon(40),cascon(20)
c
c *******************************.**********************._*_ * **
o
dtotal =0
ichois= 1
dx =v1 (1 )-v2(1)
dy =v1(2)-v2(2)
dxy =sqrt(dx*dx +dy*dy)
dsl=dxy
dtotal = dtotal + dxy
dx =v2(1)-v3(1)
dy =v2(21-v3(2)
dxy = sqrt(dx*dx + dy* dy)
if(dxy.gt.dsl) then
dsl=dxy
ichois=2
endif
dtotal =dtotal + dxy
dx = v3(1)-v1(1)
dy .. v3 (2)-v1(2)
dxy=sqrt(dx*dx + dy*dy)
if(dxy.gt.dsl) ichois .. 3
dtotal =dtotal +dxy
dtotal=fact*dtotm/3.0
xc =(v1 (1) +v211 I +v3(1))/3.0
yc = Ivl 121 + v2(2) + v3(2))/3.0

do 100 ip ... l,nspint


dx=xycon(2*ip-l)-xc
dy=xyconl2 *ipl-yo
dxy = sqrt(dx * dx + dy" dy)
if(dxy.le.dtotal) return
ichois=O
100 continue
end
c ********** *******************************.***** *****************
c ..
c .. programmer Xie Gaohong
c .. version 1.0 date 12-08-92
c ..
c .. copyright (c) 1992 WPA, Dept. of Mechanical Engineering
c * Eindhoven UniVersity of Technology
c It 5600 MB, Eindhoven, The Netherlands.
c *
c ******************************.******************.*********************
c" Subroutine to determine the dot product of (ei,ef).(ei,es)
c" also sin value of these vectors, the length of (ei,cs) and
c * (ef ,cil are returned
c **************************************** *******.****.*.*** _*

subroutine dotvee(ci .cf ,es,eosvee,outp,slengf ,slengs)


implicit double precision (a-h,o-z)
double precision cf( ),ci(* ),cs( l,ff(2),ss(2),
v eosvec,outp,slengf,slengs,stmp
integer i
common/const/pi, tol
c
c calculate the differences
c

do 200 i=1,2
ffm = cfm-cili}
ssm = cs(i)-oHi)
200 continue

=
slengs sqrt(sslll *ss(l} + ss(2} 'ss(2}}
slengf =sqrt(ff(1 )*ff(l) + ff(2) *ffl2l)
stmp =slengs*slengf

c calculate inner produots of vector (if.is)

oosvec = (ff(1 )*ss(1) + ff(2)" ss(211/stmp


outp = (ff(2) *ss(1 }-ffO) *ss(2l)/stmp
return
end
c ******** *** ***** *.******* ** ************ *--_
o
e programmer Xie Gaohong
c version 1.0 date 10-08-92
c
c copyright (011992 "WPA Dept. of Mechanical Engineering,
o Eindhoven University of TEchnology,
c 5600 MB, Eindhoven, The Netherlands
c

c
c This subroutine is called to print error message and stop
c
c *************.*****************.****.************** ****************
c
c input/output
c
e string name of the calling routine
c
c o a t output the error message was printed and program was stoped
c
c **._ *.*.***_ _** _**.*** _** * *.** *
c
subroutine ermess(ichois,string)
charaoter*!*) string
integer iore, iowr,ichois
commonliounitl iore,iowr
c
if(ichois.eq.OI then
write(io wr, '(a)')string
stop
else
write(iowr, 'Ia) ')stri ng
endif
end
c * **- ******.*******.**************.******.************** *****
c"
c * programmer Xie Gaohong
c * version 1.0 date 08-08-92
c *
c " copyright (cl 1992 "WPA, Dept. of Mechanical Engineering
c " Eindhoven University of Technology
c " 5600 MB, Eindhoven, The Netherlands.
e ..
o *****.******.*.*************************.******************************
c ..
c subroutine to build up initil front for curve
c ..
subroutine fillbn(ifirst,ilast,irevs,ie,nelm,npoint,
v ibncv,c08s,edges,diff ,rinput,usnsp)
implicit double precision (a-h,o-zl
integer ifirst,ilast,irevs,ic,nelm,npoint
integer ibncv(50,400I,nptemp
dimension c1 (2),c2(2I,xy(2)
dimension rinput(),usnsp(*)

c nelm: local element number on this curve


c local extra nodes added are nelm-1
c save node point numbers along this curve
c this routine will both fill node point numbers in ibncv
c and calcualte the coordinates along this curve, save to rinput
c the updated user nodal spacing is stored in array usnsp

c 1 (1) = rinput(2 "ifirst-1)


c1 (2) = rinput(2 "ifirst)
e2{1) = rinput(2 "j(ast-l)
c2(2) = rinput(2 "ilast)
dl =c2(1)-c1(1)
d2 =c2(2)-cl (2)
d2 =sqrtldl"dl +d2*d2)

if(nelm.eq.1} then
ibncv(ic,l) =ifirst
ibncv(ic,2) =ilast
call upnsp(ifirst,usnsp,d2)
call upnsp(ilast,usnsp,d21
return
endif
c
if(nelm.eq.21 then
npoint .. npoint + 1
rinput(2" npoint-l) =0.5* (ct (1) + c2(t II
rinput(2" npoint) = 0.5" (c 1(21 + c2(2)}
ibncv(ic,l) =ifirst
ibncv(ic,2) =npoint
ibncv(ic,3) .. ilast
dl =d2/2.0
call upnsp(ifirst,usnsp,dl)
call upnsp(ilast,usnsp,d 1 I
return
endif

e when element number great than 2


e in reverse case, first elements size bigger than last one

if(irevs.eq.l I then
do 70 i=1,2
xyli) = C 1 iii
c 1 (i) = c2(i)
e2m = xy!i)
70 continue
endif

nptemp = npoint
ibncv{ic,l I =ifirst
ibncv(ic,nelm + 1) =ilast
do 100 i=2,nelm
nptemp = nptemp + 1
ibncvlic,iI =nptemp
100 continue

dl =edges"d2
d2=edges"d2*(diff* *(nelm-l))

if(irevs.eq.1) then
call upnsp(ifirst.usnsp.d2)
oall upnsplilast.usnsp.d 1)
else
call upnsp(ifirst.usnsp.d 11
call upnsp{ilast,usnsp.d2)
endif

ratio=OdO
do 200 ip = 1.nelm-l
npoint = npoint + 1
ratio = ratio + edges*(diff* "(ipol
call ratiop(ratio,o l,02.xy)
iflirevs.eq.ll then
rinput(2* (nptemp-ip) + 1) =xy(ll
rinput{2*{nptemp-ip) + 2) =xy(2)
else
rinput(2 "npoint-l) =xy(l)
rinput(2*npoint) =xy(2)
endif
200 continue
end
c **************************************************-********************
o
c" subroutine to find given point ip's position in nnadj(ipnew.1)
c"
c*********************************************************************
c "
c" programmer Xie Gaohong
0" version 1.0 date 20-08-92
c
c " copyright (c) 1992 WPA, Dept. of Mechanical Engineering
c " Eindhoven University of Technology
0 5600 MB, Eindhoven, The Netherlands.
c *
c **************************************************************** *****
c
subroutine findip(ip,ipnew,nptemp,nnadj)
dimension nnadj(800,3)
integer ip,ipnew,nptemp,nnadj,i
commonliounitliore,iowr

ipnew=O
do lOO i = l,nptemp
if{nnadj(i,l ).eq.ipl then
ipnew=i
return
endif
100 continue
iflipnew.le.O) then
write(iowr. *) 'index of point',ip: can not found'
call ermess(O:findip: can not find index of given point')
endif
end
c **********************************.************************************
0*
c" subroutine to find middle node number along an edge ip1 ip2
c *
c ***************.***.***************************************************
c *
c * programmer Xie Gaohong
o " version 1.0 date 10-09-92
0"
c * copyright (cl 1992 "WPA. Dept. of Mechanical Engineering
c" Eindhoven University of Technology
c 5600 MB, Eindhoven, The Netherlands.
c
c .***********.**********************************************************
c ..
subroutine findmn(iein,ip 1.ip2,ipm,ntadj)
implicit double precision (a-h,o-z)
dimension ntadj(*)
integer ip 1.ip2.iein,ipm.ntadj,i l,i2,i3,ie6

ie6 =6"(ieio-1)
i1 =ntadj(ie6 + 1)
i2 = ntadj(ie6 + 2)
i3 >= ntadj(ie6 + 3)
if(il.eq.ip 1 .end.i2.eq.ip2.or .i1 .eq.ip2.and.i2.eq.ip 1) then
ipm = ntadj(ie6 + 41
return
endif
if(i2.eq.ip 1.and.i3.eq.ip2.or.i2.eq.ip2.and.i3.eq.ip 1) then
ipm = ntadj(ie6 + 5)
return
endif
if(i3.eq.ip 1.and.il.eq.ip2.or.i3.eq.ip2.and.il.eq.ip 1) then
ipm =nt",djlie6 + 6)
return
endif
end
c*****************************************************
c
c programmer Xie Gaohong
c version 1.0 date 10-08-92
c
c copyright Ie) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MB, Eindhoven, The Netherlands"
c
c ****************************************************** *****.*.*.*.
c
c subroutine to form triangles for each surface
c
c **._-* _ * *.*_._._ ..... *._ ....... **.*_ _ _. __ ._-.*
c
subroutine genmsh(nsurf,isurf,ncsf,ncurve,icurve,nuspnt.npoint,
v nelem,nelmcv,ibncv,neadj,ntadj,rinput,usnsp)
implicit double precision (a-h, o-zl
integer npoint,ncurve,nsurf,icurve,isurf,ncsf,nelem,nelmcv
integer neadj,ntadj,ibncv,ipoint,nptemp,ifirst,ilast,if2,il2
double precision rinput,cosvec,outp,coslim
dimension isurfI15,30).ncsf( "),icurve(" ),rinput( * ),nelmcv( *)
dimension ibncv(50,4oo),neadj(*),ntadj(*),usnsp(*)
dimension vl (2).v2(2).v3(2),wl (2),w2(2),nnadj(800,3)
commonfcontroll nspint, fact,cascon,xycon
integer nspint
dimension cascon(20).xycon(40)
c
c *.**************.******.*.******************************************
c ncurve 0 number of curves
c
c nsurf 0 number of surfaces
c
c isurf 0 array contains each surface's curve number in CCW
c
c icurve 0 array contains each curve's ends point number
c
c rinput 0 array to be filled with coordinates
c ** *** ** **.*** ****** * ******* ****.*************
c
c for each surface do
c
npboun - npoint
do 100 isnum=l,nsurf
do 150 jj=1,800
nnadj(jj,1) = 0
nnadj(jj.2) =0
nnadj(jj,3) ... 0
150 continue

call iniadjlnptemp.nnadj,isnum.isurf,ncsf.nelmcv,ibncv)
c
c first check closing operation
c
icount=O
icont=O
coslim=0.08
do 201 ip '" 1.nptemp
ipoint =nnadjlip,1)
iflipoint.le.O) go to 201
ifirst ... nnadjlip.2)
ilast,.. nnadj(ip.3)
cell getcr(ifirst. vl.rinput)
call getcr(ipoint. v2.rinput)
call getcr(ilast.v3.rinput)
call dotvec(v2,v1.v3.cosvec,outp,s12.s23)
iflcosvec .ge.coslim.and .0utp.gt.0) then
call closep(ip,ifirst,ipoint,ilast,nelem,nptemp,
v nnadj.neadj,ntadj)
endif
201 continue
call chkfin(nptemp,nnadj)
if(nptemp.lt.O) go to 100
7000 continue
if(icount.ne.O) coslim =-0.08
idid=O
do 202 ip = l,nptemp
ipoint = nnadj(ip, 1)
if(ipoint.le.O} go to 202
ifirst = nnadj(ip,2)
ilast= nnadjlip.3)
call geter(ifirst, vl ,rinput}
call getcrlipoint, v2,rinput)
call getcr(ilast,v3,rinput)
call dotvec(v2,vl ,v3,cosvec,outp,s1 2,s23)
if(cosvec.ge.coslim.and.outp.gt.O) then
idid=l
call closep(ip,ifirst,ipoint,ilast.nelem,nptemp,
v nnadj,neadj,ntadj)
go to 202
endif

if(ipoint.gt.npboun.and .nspint.ge.1) then


saver=0.5*ls12+s23)
call spnint(icont,nuspnt,usnsp,saver, v2,rinput)
endif

if(cosvec.lt.coslim.and.outp.gt.O) then
c
c for convex corners, try to bi-sect the corner with Iv1,v2) and
c Iv2,v3) as bases to find vertices of equal side triangles, then
c use the weighted middle point as new vertice
c
call tsolxy(icont,idid. v1.v2, w l,disl1)
call tsolxy(icont,idid,v2.v3. w2,disl2)
wl (1) = Iwl (1) + w2(1 /2.0
wl (2) =(wl (2) + w2(2/2.0
dislmx =max(disll,disI2)
dislmn = min(disl1,disI2)
c
c check the new point w1's location and distance with current active
c nodes and fronts. ichois =-1: accept new point; ichois =0: do nothing;
e iehois = 1 : form two reduced size triangles
c
call inside(ichois,ifirst,ipoint,ilast,index,ipcls,
v nptemp,nnadj, w 1.dislmn,dislmx,rinputl
it(ichois.eq.2) then
il2 = nnadj(index, 3)
call divide(idone,ip,ipoint,index,ipcls,ifirst,il2,
v nelem,npoint,nptemp,nnadj,neadj,ntadj,rinput)
if(idone.eq.O} then
it2 = nnadj(index, 2)
call divide{idone,index,ipcls,ip,ipoint,if2,i1ast,
v nelem,npoint,nptemp,nnadj,neadj,ntadj,rinput)
endif
iHidone.eq.l} idid = 1
endif
if(ichois.eq.l) then
idid=l
call tsolxy(icont,ichois, v1, v2, wl ,disI1)
call tsolxy(icont,ichois, v2, v3, w2,disI2)
wl (1J =(wl (1) + w2(111/2.0
wl (2)=(w1 (2) + w2(2))/2.0
call bisect(ip,ifirst,ipoint,ilast,nelem,
v npoint,nptemp,nnadj,neadj,ntadj)
rinput(2"npoint1) = wl (1)
rinput{2 "npoint) = w1 (2)
call nbpcls(ifirst,nelem,nptemp,nnadj,
v neadj,ntadj,rinput)
call nbpcls{ilast,nelem,nptemp,nnadj,
v neadj,ntadj,rinput)
endif
if(ichois.eq.l) then
idid=l
call bisect(ip,ifirst,ipoint.ilast.nelem.
v npoint.nptemp,nnadj,neadj.ntadj)
rinput(2"npointl) =wl (1)
rinput(2" npoint) = wl (2)
call nbpcls(ifirst.nelem.nptemp.nnadj.
v neadj.ntadj,rinput)
call nbpcls(ilast,nelem,nptemp.nnadj,
v neadj.ntadj,rinput)
endif
go to 202
endif

if(outpJe.OI then
icase=l
if(s 1 2.gt.s23} icase "" 2
c
c concave corner. form a new triangle with smaller bases
c
if(icase.eq.1) call
v tsolxy(icont.idid, vl ,v2. w 1 .disl1)
if(icase.eq.2) call
v tsolxy(icont,idid,v2,v3,wl,disI1)

call inside(ichois,ifirst,ipoint,ilast,index,ipcls,
v nptemp,nnadj,wl,disll,disll,rinputl
if(ichois.eq.2) then
i12 =nnadj(index,3)
call divide(idone,ip.ipoint,index,ipcls,ifirst,il2.
v nelem,npoint,nptemp,nnadj,neadj,ntadj.rinput)
if{idone.eq.O) then
if2 =nnadjCindex, 2)
call divide(idone,index,ipcls,ip,ipoint,if2,ilast,
v nelem,npoint,nptemp,nnadj,neadj,ntadj,rinput)
endif
if(idone.eq.l) idid =1
endif
if(ic hois.eq. 1) then
idid=l
if(icase.eq.l) call
v tsolxy(icont,ichois,v1,v2,wl ,disll)
if(icase.eq.2) call
v tsolxy(icont,ichois, v2, v3, wl,disl1)
call tform(icase,ifirst,ipoint,ilast,nelem,
v npoint,nptemp,nnadj,neadj,ntadj)
rinput(2 *npoint-' ) .. W 1 (1 )
rinput(2 npoint) = w 1 (2)
call nbpcls(ipoint,nelem,nptemp,nnadj,
v neadj,ntadj,rinput)
if(icase.eq. , ) then
call nbpcls(ifirst,nelem,nptemp,nnadj,
v neadj,ntadj,rinput)
else
call nbpcls(ilast,nelem,nptemp,nnadj,
v neadj,ntadj,rinput)
endif
endif
if(ichois.eq.-1) then
idid=1
call tform(icase,ifirst,ipoint,ilast,nelem,
v npoint,nptemp,nnadj.neadj.ntadj)
rinput(2 *npoint') = wl (1)
rinput(2*npoint) =wl (2)
call nbpcls(ipoint,nelem,nptemp,nnadj,
v neadj.ntadj,rinput)
if(icase.eq.l) then
call nbpcls(ifirst,nelem,nptemp,nnadj,
v neadj,ntadj,rinput)
else
call nbpcls(ilast,nelem,nptemp,nnadj,
v neadj,ntadj,rinput)
endif
endif
endif
202 continue
call chkfin(nptemp,nnadjl
if(nptemp.lt.O) go to 100
if(idid.eq.O) icount .. icount+ 1
c if(mod(icount,2).ne.0) call
c v pltcv(3,nuspnt,nelem,ntadj,rinput)
if(icount.ge.20) call ermess(O,
v 'genmsh: please adjust node spacing,try again')
go to 7000
1 00 continue
end
c**************************************************
c
c programmer Xie Gaohong
c version 1.0 date 10-08-92
c
c copyright (c) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MS, Eindhoven, The Netherlands"
c
c ******.**** *******.**********************************************
c
c subroutine to get one point coordinate
c
c _.*-*-*--* .. _**_ * - _.* *.--*-*.*.- ....
**-** ****.* *
c
subroutine getcr(ipoint,xy,rinput)
implicit double precision (a-h, o-z)
dimension rinput(*),xy(*)
integer ipoint
c
xy(1)" rinput(2 *ipoint-1)
xy(2) .. rinput(2*ipoint)
end
c ****************************.********* ****.***********************
c
c programmer Xie Gaohong
c version 1.0 date 10-08-92
c
c copyright (c) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MS, Eindhoven, The Netherlands"
c
c ***.******* *** ********** **** *****.****.**.*************
c
c This subroutine is caned to get current time in seconds
c This routine is machine dependent routine, can be changed
c
c *************.*.*.*************************************.*.********.***
e
subroutine gtime( time )
real time

c time Real parameter giving the time in seconds


c IBM PC with the 80386 processor and FTN77/386 compiler

call olock@ (time)


end
c .****** ********************.*** **********.****************
c
c programmer xie gaohong
c version 1.0 date 17-08-92
c
c copyright (0) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of Technology,
c 5600 MB, Eindhoven, The Netherlands"
c
C *.a _.*._._ ......... _*.*_ *_. __ _-_._*_ ...
* * __ _ ** *
c
c Determine whether 02 or 13 is the diagonal edge chosen
c based on the circumcircle criterion, where (xO,yOl, (xl ,yl),
e (x2,y2), (x3,y3) are the vertices of a simple quadrilateral
o in counterclockwise order.
c
c diaedg: , if diagonal edge 02 is chosen, i.e. 02 is inside
c quadrilateral + vertex 3 is outside circumcircle 012
c -, if diagonal edge 13 is chosen, i.e. 13 is inside
c quadrilateral + vertex 0 is outside circumcircle 123
c O i f four vertices are cocircular
c
integer function idiadg(xO,yO,xl ,yl,x2.y2,x3,y3)
implicit double precision (a-h,o-z)
common/const/pi, tol
c
dxl0=xl-xO
dyl0=y'-yO
dx12=xl-x2
dy12=yl-y2
dx30 .. x3-xO
dy30=y3-yO
dx32=x3-x2
dy32=y3-y2
tola =tol*max(abs(dx1 O),abs(dyl O),abs(dx30),abs(dy30))
tolb =tol*max(abs(dx12),abs(dy12),abs(dx321.absldy32))
oa =dxl0*dx30+dyl0*dy30
cb=dx12*dx32 +dy12*dy32
if (ca.gt.tola.and.cb.gt.tolb) then
idiadg=-1
else if(ca.lt.-tola.and.ob.lt.-tolb) then
idiadg=l
else
tola =max(tola,tolbl
s .. (dxl0*dy30-dx30*dyl0) *cb + (dx32 *dy12-dx12 *dy32) oa
if(s.gt.tola) then
idiadg",-l
else ifls.lt.-tola) then
idiadg=l
else
idisdg=O
endif
endif
end
c*____*__***-_-_***_****************
e
c programmer Xie Gaohong
c version 1.0 date 17-08-92
c
e copyright (c) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MB, Eindhoven, The Netherlands"
c
c_--_------*._.* .. __ ._._-_.
c
subroutine ifoutb(ipoint,ichois,ncurve,ibncv,nelmcv,inner)
implicit double precision (s-h,o-z)
integer ipoint,ichois,ncurve,ibncv(50,400),inner( *),nelmcv( *)
c
c * * __ _._. __ ._-_ _ -** - **-_._--_ .. ****.***4********
c This subroutine is called to identify out boundary point
c loop for each curve, if the point is on the curve, then check
c
c --**_ _. __ _._. __ _ _--*--_._. __ .. -.. -.. _.* ...... _.
if this curve is inner boundary, if not then it is out boundary

c
ichois=O
do 100 icurv,", 1,ncurve
c
e check if point is on sny outer boundary
e
if(inner(ieurv).eq.l) go to 100
np = nelmcv(icurv)
if(np.eq.1) go to 100
ipl =ibncv(icurv,2)
ip2 = ibncv(icurv,np)
if(ipoint.ge.ipl.and.ipoint.le.ip2) then
ichois= 1
return
endif
100 continue
end
c ****** * ***********************.************.**************.******
c ..
c subroutine to build up initil node-node adjacent list for current
c" surface in consideration
c "
c .** * * **** ******.*.**************.**********.* **********
e ..
c .. programmer Xie Gaohong
c .. version 1.0 date 18-08-92
c ..
c" copyright (e) 1992 "WPA, Dept. of Mechanicsl Engineering
e" Eindhoven University of Technology
c .. 5600 MB, Eindhoven, The Netherlands.
c ..
c****************************************************************
subroutine iniadj(nptemp.nnadj,isnum,isurf.ncsf,nelmcv,ibncv)
implicit double precision (s-h,o-z)
dimension isurf( 1 5,30) ,ibncv(50 .400) ,nnadj(800, 3)
integer isnum,ncsf(*),isurf,nelmcv(").lbncv
integer nnadj,nptemp,netotl,ip.nenow.icnow

e" for current isnum surface do


e * get curve number in isurf
c" for this curve, get number of elements snd all node points
c" for tempary array nnadj, first element (i, 1) is the node number,
c" 0,2) is backward node number, (i,3) is forwsrd node number
nptemp=O
netotl=O
ip=l

do 350 i = l,ncsf(isnum)
icnow = isurf(isnum,il
ifO.eq.l) icf=icnow
if(i.eq.ncsf(isnum)) icl =icnow
nenow =nelmcv(abs(icnow))
netotl = netotl + neno w
if(icnow.gt.O) then

c * the curve is in CCW, else is in anti-CCW

100 continue
nptemp = nptemp + 1
nnadj(nptemp,l) =ibncv(icnow,ip)
if(ip.ge.nenow) then
ip=l
go to 350
endif
ip=ip+ 1
go to 100
else
200 continue
nptemp = nptemp + 1
nnadj(nptemp,l) =ibncv(abs(icnow),nenow + 2-ip)
iflip.ge.nenow) then
ip=l
go to 350
endif
ip=ip+ 1
go to 200
endif
350 continue
if(nptemp.gt.800) call ermess(O:iniadj: total node points on
v a closed polygon excess the array limit. you can divide the
v biggest surface into two surface or decrease nodal spacing')
if(nptemp.ne.netotl) call ermess(O:iniadj: total node points on
v a closed polygon must equal to line segments on the polygon')
do 400 i = l,netotl
if(Leq.1) then
nnadj(i,2) = nnadj(netotl, 1)
else
nnadjli.2) =nnadj(i-l,l)
endif
if(i.eq.netotll then
nnadj(netotl,3) = nnadjl1, 1)
else
nnadj(i,3) =nn&djU + 1,1 ,
endif
400 continue
end

c ***.* *.***.****.*****************.*.**********************.*******
c
c programmer Xie Gaohong
e version 1.0 date 14-08-92
c
e copyright (e' 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
e 5600 MB, Eindhoven, The Netherlands
c
c **.*********************************.******.*.**********************
c
c subroutine to initialise common constants
c
c ********.********************.*.************.***********************
c
subroutine initeb(tolin)
implicit none
c
c Input parameters:
c tolin - relative tolerance used to determine tol
c
commonliounitl iore,iowr
integer iore,iowr
common Iconst/pi,tol
double precision pi.tol
double precision tolin,eps,epsp 1
save Iconst/,liounit/
c
ior8=5
iowr=6
pi = 8COS(-1.000)

eps = 1.000
10 continue
eps = eps/2.000
epsp 1 = 1 .000 + eps
if(epsp1.gt.l.000) go to 10
tol = max(tolin, 1OO.ODO*eps)
end
c ******.****.* ***.************************************ **.*********
c
c .. programmer Xie Gaohong
c * version 1.0 date 080892
c
c .. copyright (c) 1992 "WPA, Dept. of Mechanical Engineering
c * Eindhoven University of Technology
c 5600 MS, Eindhoven, The Netherlands.
c ..
c_*-*********************--****_*****-.***.**.*.********
c ..
c.. subroutine to initialise all necessary information
c ..
subroutine initialneadj,ntadj,nsurf,isurf,ncsf,ncurve,icurve,
v nuspnt,npoint,nelmcv,jbncv,cunit,corase,rinput,usnsp)
implicit double precision (a-h,ooz)
dimension icurve(*),ibncv(50,400I,neadj(I,ntadj(*),
v nelmcv(* ),ncst( * I,corase( * I,rinput( * ),usnsp( *)
integer ncurve,icurve,nuspnt,npoint,ibncv,nelmcv
integer neadj,ntadj.ip 1.ip2.irevs

c.. Starting node point number npoint

npoint = nuspnt

c.. initialise all adjacent arrays

do 100 i=1,45000
neadj(jl =0
100 continue
do 200 i 1: 1,24000
ntadj(i) =0
200 continue

c * for each curve do


c calculate number of elements along the curve
c * calculate starting edge and density ratio
c" fill boundary node coordinates along the curve

do 350 ic = 1.ncurve
ip 1 =icurve(2 *ic-1)
ip2 =icurve(2 *icl
call curvnelipl.ip2.irevs,nelm.rinput,cunit,corase,
v coas,edges.diff)
nelmcv(icl =nelm

if(nelm.gt.4001 cell ermess(O:ermess: the elements


v along one curve excess the array bounds, you should
v reduce the nodal spacing ratio and try again')

call fUlbn(ip l,ip2,irevs,ic,nelm,npoint,ibncv,


v coas,edges,diff.rinput,usnsp)
350 continue
return
end
c ********.* ****.**************************************************
o
c programmer Xie Gaohong
c version 1.0 date 10-08-92
c
c copyright (c) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MB, Eindhoven, The Netherlands"
c
c ********************************************************************
c
c This subroutine is called to identify all inner boundaries
c
subroutine innerclnsurf,isurf,ncsf,ncurve,innerl
implicit double precision (a-h, o-z)
integer nsurf,isurf(15,30),ncsf( "I,inner!)
c
c *****.*****************************************.*******.*.4**********.*
c
do 5 i == l,ncurve
inner(i) =0
5 continue
jftnsurf .eq.1) return

do 100 isnum == 1,nsurf-1


do 100 isc == l,ncsf(isnum)
ic ==isurf(isnum,isc)

c for each surface's curve number comparing to other surface's curve

do 200 ils ==isnum + 1.nsurf


do 200 ite == 1,ncsf(ils)
ifiabs{ie).eq.abs(isurf(ils.itc) inner(abs(ic)) == 1
200 continue
100 continue
end
c *_ _ _-* -.-
_* *._.***.****._**.*.*** *-*._.*.4***.4**.*4.
C ..
C .. programmer Xie Gaohong
c " version 1.0 date 15-08-92
c ..
c .. copyright (c) 1992 "WPA, Dept. of Mechanical Engineering
c .. Eindhoven University of Technology
c .. 5600 MB, Eindhoven, The Netherlands.
c ..
c _.-._.- **--*.*_.* *.*****************.**.******************
c ..
c * subroutine to check the minmum distance from given point to all
c.. current active nodes and sides and check new point is in the region
c*
subroutine inside(ichois,ifirst,ipoint,ilast,index,ipcls,
v nptemp.nnadj,xy,dislmn,dislmx,rinput)
implicit double precision (a-h,o-z)
dimension rinput(*).xy(*),nnadj(800.3),ref(2).vl (2),v2(2}
integer ichois,ip l,ip2,kint,nptemp.ishort
c
c ichois ==-1 normal inside, far away from either nodes and sides
c ichois =0 close to some node
c =
ichois 1 in the neibour of the point but far away to the side
c
ichois=-l
kint== 1
dismn=O.S*(dislmn+dislmxl
dislmx = , .1 dislmx
xmin =xy(1 I-dislmx
ymin =xy(21-dislmx
xmax =xy(l) +dislmx
ymax =xy(2) + dislmx
ref(1) = rinput(2 * ipoint-ll
ref(2) = rinput(2 *ipoint)
do 100 i = l,nptemp
if(nnadjli,1 ).Ie.O) go to 100
iflnnadj(i.ll.eq.ipointl go to 100
if(nnadjli,1 ).eq.ifirstl go to 100
c
c for each active node. which formed closed Count Clock Wise loop
c
ip 1 = nnadj(i, 11
ip2 = nnadjli,31
do 30 j= 1,2
vl Ijl =rinputl2 * lip 1-11 + j)
v2(j) = rinput(2 *(ip2-1) + jl
30 continue
if(v1(l ).le.xmin.and.v2(1I.1e.xminl go to 100
if(vl (1 ).ge.xmax.and.v2(1).ge.xmax) go to 100
if(v1(2).Ie.ymin.and.v2(2).le.ymin) go to 100
if(vl (2).ge.ymax.and.v2121.ge.ymax) go to 100
dx=xy(1)-v1(1)
dy=xy(2)-vl (21
dx =sqrtldx dx + dy* dy)
if(dx.le.dislmn) then
ichois=O
if(dx.le.0.17 *dislmnl then
index=i
ipcls=ipl
ichois=2
return
endif
if(dx.le.0.7*dislmnl return
call Irlinelich.xy,vl,v2,dv)
if(ich.eq.O) go to 100
ifldv.le.0.52*dislmn) return
ichois=-l
ishort= 1
endif
c
c check reference point's relation with each line segment
c
call1rline(iref,ref,vl,v2,dvl
if(iref.eq.O) go to 100
call Irline(ixy,xy. vl, v2,dv)
if(iref*ixy.ge.O) go to 100
callirline(iref,vl,ref,xy,dv)
call1rline(ixy,v2,ref,xy,dvl
if(iref*ixy.ge.O) go to 100
kint =kint + 1
100 continue
iflmod(kint,2).eq.01 ichois =0
iflishort.eq.1.and.ichois.eq.-l I ichois = ,
end
c ****.**.*.*********.*.********* *.*.*.*.*****.*.*******************
c
c programmer Xie Gaohong
c version 1.0 date 10-08-92
c
c copyright (cl 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MB, Eindhoven, The Netherlands"
c
c ***********_.******.*** *************.****************.************
c
c This subroutine is called when performing input checking
c
c .******************************************.**********.*****.*********
c
subroutine loopcklnsurf,ncurve,nuspnt,isurf,ncsf,icurve)
implicit double precision (a-h, o-zl
integer nuspnt,ncurve,nsurf,icurve,isurf,ncsf
dimension icurve(*),lsurf(15,30),ncsf(*)
c
c * _************************* *.* *************************.*****
c input/output
c
c nuspnt number of user points
c
c ncurve number of curves
c
c nsurf number of surfaces
c
c icurve arrav contains node number of curve ends
c
c isurf i arrav contains each surface's curve number in such a wav
c that outsurface counterclock wav, inner surface are addressed
c bV accessing lines to inner surface
c
c ncsf i each surfaces' total curve number
c
c at output the errors are reported
c

c
do 100 i=l,nsurf
ih=isurfli.l)

c lh each surface's first curve number


c iflrst. isecnd: this curve's ends point number

lflrst = icurve(2 * abslih)-l )


lsecnd = icurve(2 * abs(ih))
if(ih.lt.O) then

c ih <0 curve is not CCW


c after swap, it became CCW

ih=ifirst
ifirst =isecnd
isecnd =ih
endit
do 200 k = 2,ncsf(l)
=
Ie isurf(l,k)
ip 1 = icurve(2 * abslic)-')
ip2 = icurvel2 abs(ic))
if(ic.lt.OI then
ih=ipl
ipl =ip2
ip2=ih
endif
if(isecnd.ne.ip11 call
v ermess(O:loopck:surface curve number wrong')
isecnd=ip2
200 continue
100 continue

*._.*.**.--*-* .. _.. _-----_ .. _-* . _. *-_ .... **---


end
c ** - _
c
c programmer Xie Gaohong
c version 1.0 date 1008-92
c
c copvright (c11992 "WPA Dept. of Mechanical Engineering,
c Eindhoven Universitv of TEchnologv,
c 5600 MB. Eindhoven, The Netherlands
c
c ************** ******************.*********************************
c
subroutine h1ine(ichois,xy,vl,v2,dv)
implicit double precisionla-h,o-zl
dimension xyl*l,vl ("I,v2(")
common/const! pi,tol
integer ichois
c
c Purpose: determine whether a point is to the left of, right of,
c or on a directed line parallel to a line through given points.
c
C xy,v' ,v2 - vertex coordinates; the directed line is from vl to v2.
c (x,y) is the vertex for which the position relative to the directed
c line is to be determined
c
c ichois '" + 1, 0, -1 point is on the right of, on, left of
c the directed line (0 if line degenerates to a point)
c dv is the distance of point XV to line Iv1, v2)
C
dx "'v2111-vl (1)
dy .. v2(2)-v1 121
dxu '" xy(1 l-v1 (1)
dyu = xy(2)-v1 121
tolabs = tol* max(abs(dx),abs(dy),abs(dxu),abs(dyu))
t = dy* dxu-dx" dyu
ichois =intlsign(1.0dO,t))
if(abs(t).Ie.tolabs) ichois =0
iflichois.ne.OI then
ds = sqrt(dx*dx + dy"dy)
dv=abs(t)/ds
endif
end
c **************************************************************** ***
c *
c" subroutine to move a array to the bottom for stack operation
c "
c ******************_.****************.**********-*.*******.*************
c"
c " programmer Xie Gaohong
c " version 1.0 date 08-09-92
c"
c .. copyright (c) 1992 "WPA, Dept. of Mechanical Engineering
c " Eindhoven University of Technology
c .. 5600 MB, Eindhoven, The Netherlands.
c ..
c **********.******************************************.********.**.*****
c *
subroutine mvbotm(iarray,length,ipbot,iptopl
implicit double precision (a-h,o-z)
dimension larray(")
integer iarray,ipbot,iptop,length,i

if(ipbot.le.length) return
iptop=O
do 100 i =length,l,-l
iptop =iptop + 1
iarraylipbot-iptop + 1) = iarrayli)
100 continue
iptop =ipbot-iptop
return
end
c*******************_********************** *********
c
c programmer Xie Gaohong
c version 1.0 date 10-08-92
c
c copyright (c) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MB, Eindhoven, The Netherlands"
c
c *** ** *****.*** ** ** ** * ** ***.****.**.******.
c
c subroutine to check one point and close triangle
o
c * *** **.********** ***.***** *****.*.* ********** ***********
c
subroutine nbpcls(ipoint.nelem.nptemp.nnadj.
v neadj,ntadj.rinput)
implicit double precision (a-h, o-z)
integer ipoint,nptemp,nelem,nnadj,ntadj,neadj
integer ip.ifirst.ilast
dimension neadj( * l, ntadj( *) ,rinput( '"
dimension vl (2),v2(2),v3(2).nnadj(SOO,3)
c
c * ** * * ** * * * ***** *.********.********
c
call findip(ipoint,ip,nptemp.nnadj)
ifirst = nnadjlip. 2l
ilast = nnadjlip.3)
call getcr(ifirst, vl.rinputl
call getcrCipoint,v2,rinput)
call getcr(ilast,v3,rinput)
call dotvec(v2,vl,v3,cosvec,outp.s12.s23)
if(outp.le.O.or.cosvec.le.O) return
if(cosvec.ge.-O.OS} then
call closepCip,ifirst,ipoint,ilast,
v nelem,nptemp,nnadj.neadj,ntadj)
endit
end
c***********************************************************
c ..
c.. subroutine to build node-element adjacence list for quadrilateral
c ..
c ********.*.******** ** *.******.*******************************
c ..
c " programmer Xie Gaohong
c " version 1.0 date 09-09-92
c"
c .. copyright (c) 1992 "WPA, Dept. of Mechanical Engineering
c " Eindhoven University of Technology
c " 5600 MB, Eindhoven, The Netherlands.
c ..
c **********.***.**************.****** ******** **.**.*****************
c *
subroutine nebuld(nelem,npoint,nptot3,ntadj,neadj)
implicit double precision (a-h,o-z)
dimension neadj(*),ntadj(*)
integer nelem.npoint,nptot3,neadj,ntadj,ipoint,ie
integer il.i2.i3,i4,ie4.ip

do 500 ip=l,9*npoint
neadjlip) =0
500 continue
do 100 ipoint = l,npoint
icount=O
do 200 ie "" l,nelem
ie4=4*Cie-1)
i1 =ntadjlie4 + 1)
i2 =ntadjlie4 + 2)
i3 =ntadj(ie4 + 3)
i4 = ntadjlie4 + 4)
if(ipoint.eq.i 1) then
call neupdt(il,ie,neadj)
if(ipoint.gt.nptot3) then
icount""icount+ 1
if(icount.ge.4) go to 100
endif
go to 200
endil
iflipoint.eq.i2) then
call neupdtli2,ie,neadj)
if(jpoint.gt.nptot3) then
icount-icount+ 1
if(icount.ge.4) go to 100
endif
go to 200
endif
if(ipoint.eq.i3) then
call neupdt(i3,ie,neadj)
iflipoint.gt.nptot3) then
icount .. icount + 1
if(icount.ge.4) go to 100
endif
go to 200
endif
if(ipoint.eq.i4) then
call neupdt(i4,ie,neadj)
if(ipolnt.gt.nptot3) then
icount=icount+ 1
if(icount.ge.4) go to 100
endlf
endlf
200 continue
100 continue
return
end
c *** **************************.*** ****.**********.*****.***********
c ..
c .. programmer Xie Gaohong
c .. version 1.0 date 18-09-92
c ..
c" copyright (cl 1992 "WPA, Dept. of Mechanical Engineering
c .. Eindhoven University of Technology
c .. 5600 MB. Eindhoven, The Netherlands.
c ..
c ********.***.*.*** ********************.*************.***************
c ..
integer function netotHipoint,neadjl
implicit double precision (a-h,o-zl
dimension neadj(*l
integer ipoint.neadj
integer i,j
c
c return the total number of elements connected to lpoint
c
netotl =0
j = 9 (ipoint-1 )
do 100 i= 1,9
if(neadj(j + il .ne.O) netotl .. netot! + 1
100 continue
return
end
c ****** ********.*******.**********************************************
c ..
c" subroutine to add one element to node-element adjacence lists
0"
c ********************* *.**********.****.*.************ *.**********
0"
c .. programmer Xie Gaohong
o .. version 1.0 date 08-08-92
o
c" copyright (0) 1992 "WPA, Dept. of Mechanical Engineering
c .. Eindhoven University of Technology
c * 5600 MB, Eindhoven, The Netherlands.
o*
c ******.****.*.**.************************* ***********************.**
o
subroutine neupdtlipoint,nelem,neadj)
implicit double precision (s-h,o-zl
dimension neadj(*)
integer ipoint,nelem,neadj,iep,i

c ipoint: cuurent node point in consideration.


c nelem: current element number
c neadj: node-element adjacence list

i=l
, 00 continue
iep = 9 "(ipoint-')
if(neadj(iep +i).eq.nelem) return
ifCneadj(iep +i).eq.O) then
neadj(iep + i) =nelem
return
endif
i=i+l
if(i.gt.l1) call ermess(O:neupdt: bad element formed. The
v reason is the elements connected to one point more than 9.
v Reduce the difference of nodal spacing, try again')
go to 100
end
c .*.**.**** *.************* *****.******************.*********.*.
c
c programmer Xie Gaohong
c version 1.0 date 10-09-92
c
c copyright (c) 1992 DWPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MS, Eindhoven, The Netherlands
c
c *************.******************************************************
c
integer function npqout(ipoint,neadj)
implicit double precision (a-h,o-z)
integer ipoint,neadj("),i9,i,iem
c
c ***********************************************************************
c This function is called to identify out boundary points
c for each quadrilateral elements. if the point is on the out
c curve, then node adjacent element must be two
c ****.***************************** ***********************************
c
npqout=O
i9 = 9 *(ipoint-1)
iem=O
do 100i=1,9
if(neadjli9 + i).ne.O) iem = iem + 1
'00 continue
if(iem.eq.2) then
npqout= 1
return
endif
end
c .* ..... ** * *** * * ******* **** *
c ..
c" programmer Xie Gaohong
c .. version 1.0 date 08-08-92
c .
c . copyright (c) 1992 "WPA, Dept. of Mechanical Engineering
c .. Eindhoven University of Technology
c . 5600 MB, Eindhoven, The Netherlands.
c ..
c *.**** ******* *************.*.* **.******************************
cit
subroutine prtbnlnuspnt,ncurve,nelmcv,ibncv,rinput)
implicit double precision (a-h,o-z)
dimension ibncv(50,400),nelmcv(*),rinput(*)
integer ncurve,ibncv,nelmcv,nuspnt
integer ipt.ipx
common/iounit/ iore,iowr
ipt=O
do 20 icurv -, ,ncurve
ipt == ipt + nelmcv(icurv)l
ipx =nelmcv(icurv) + 1
write(iowr,10) icurv, (ibncv(icurv,j), j = l,ipx)
10 format(f, 'curve number',i3,2x,'node number',2x,10(i4,2x),/1
20 continue
do 30 i = l,ipt + nuspnt
write(iowr,40) j, rinput(2 *;'1 ),rinput(2 OJ)
40 tormat(/,'node .. ',i3,4x.'x .. ',n 0.5,5x,'y =' ,f1 0.5)
30 continue
return
end
c*********************************************** *.***
c
c programmer Xie Gaohong
c version 1.0 date 100892
c
e copyright (e) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5S00 MB, Eindhoven, The Netherlands"
c
c *.* ****************.*.*.******************** *.*****************
c
c subroutine to print triangles node and coordinates
c
c *****.*.*****.** *************.**.*.* *.****.**************
c
subroutine prtnec(ishape,nelem,npoint,neadj,ntadj,rinput)
implicit double precision (ah,o-z)
integer npoint,nelem,ntadj(*),neadj( * ),ishape
double precision rinput(*)
common liounitliore,iowr
integer iore,iowr,ip1,ip2,ip3,inelm
c
c .* . ** *** ** ****** **.****.******************
c
write(iowr,10)
10 format(f,'element No.',3x/node , ',3x/node 2',5x,'node 3'Ax,
v 'node 4',4x, 'node 5',4x,'node 6')
do , 00 inelm'" , ,nelem
iem =ishape (inelm-1)
ip 1 .. ntadjliem + 1 )
ip2 == ntadjliem + 2)
ip3 .. ntadj(iem + 3)
if(ishape.eq.3) then
write(iowr,30) inelm,ipl ,ip2,ip3
30 format(2x,i4,10x,i4,5x,i4,8x,i4)
endif
iflishape.eq.4) then
ip4 =ntadj(iem + 4)
write(iowr.4O) inelm,ipl ,ip2,ip3,ip4
40 format(2x,i4.10x,i4,5x,i4,8x,i4,8x,i4)
endif
if(ishape.eq.6} then
ip4 =ntadj(iem + 4)
ipS =ntadjliem + 5)
ip6 = ntadj(iem + 6)
write(iowr,50) inelm,ip l,ip2,ip3,ip4,ip5,ip6
50 tormatI2x,i4,8x.i4,6x,i4,Sx.i4,6x,i4,6x,i4,6x,i4)
endif
100 continue
write(iowr,SO)
60 formatl/,'nodal number: ,8x/x-coor' ,8x,'y-coor',n
do 200 ip 1 = 1 ,npoint
write(iowr,70) ipl,rinput(2 *ipl-1 },rinput(2*ipl)
70 format(2x,i4,12x,f11.6,5x, f11.S)
200 continue
write(iowr, *) 'node-element adjacence list'
do 300 ipl =l,npoint
j==9"(ipl-1I
write(iowr.20) ipl.(neadj(j+il.i == 1.91
20 formatI2x.i4,2x.9(i4.2x))
300 continue
return
end
c ************************************************.****.************
c"
c" Subroutine to find ratio point which divide line ab to ratio
c"
c *************.**********.*****.*.*******.*.****************************
c"
c .. programmer Xie Gaohong
c .. version 1.0 date 13-08-92
c ..
c .. copyright (c) 1992 "WPA. Dept. of Mechanical Engineering
c " Eindhoven University of Technology
c " 5600 MB. Eindhoven. The Netherlands.
c .,
c *****.****.*** *.****.****.*********** *******.*.********************
c .,
subroutine ratiop(ratio.a.b.pnt)
implicit double precision (ah.oz)
dimension a(*).b(").pnt(*)
c ..
c .. a.b Ii) : array of 2 contains coordinates of point a b
c ..
c" pnt (0) : array of 2 contains ratio point's coordinate
c "
c . ratio Ii) : the ratio equals line (a.pnt) to line (a.b)
c
c .************* *****.*********** *********** *********************

do 100 i=1.2
pnt(i} = ali) + ratio" (b(i)-a(i))
100 continue
return
end
c ************** *************.***********************************
c
c programmer Xie Gaohong
c version 1.0 date 100a-92
c
c copyright (c11992 "WPA Dept. of Mechanical Engineering.
c Eindhoven University of TEchnology.
c 5600 MB. Eindhoven. The Netherlands"
c *****.*.***********_ ****.*********.***********************.*******
c
c This subroutine is called to fetch data from input file
c
c fill array icurve(*' in the following way:
c
c icurve(p1.p2.p3.p4 )
c
c fill array isurf( * ) in the following way:
c
c isurf(l.ci). ci=cm . cn
c isurfI2.cil. ci=cm cn. ci are curve number close surface in CCW
c
c
c fill array rinput of the points in the following way:
c
c rinput(" rinput(2*nuspnt) coordinates of nodal points
c x y x y
c
c nuspnt 0 number of user points
c
c nsurf 0 number of surfaces
c
c isurf 0 array contains each surface's curve number in CCW
c
c icurve 0 array contains each curve's ends point number
c
c corase 0 array to be filled with user points corases
c
c rinput 0 array to be filled with user points coordinates
c********************************
o
subroutine rdmesh(nsurf,ncurve,nuspnt,isurf,icurve,
v ncsf,ishape,cunit,corase,rinput)
implicit double precision (a-h,o-z)
integer nuspnt,ncurva,nsurf,icurve,isurf,ncsf,ishape
commonliounitl iore,iowr
integer iore,iowr
common/control/nspint, fact,cascon,xycon
integer nspint
dimension cascon(20),xycon(40)
dimension isurf(15,30),ncsf(*),icurve( "),rinput(" I,corase(")
integer i,k
c
c*****************************.***** *******
c
c read total total number of surfaces, curves, user points
c
read (iore, *1 ishape,nsurf,ncurve,nuspnt
write(iowr, 10) ishape,nsurf,ncurve,nuspnt
10 format(/, 'shape of element',i3,l:total surface',
v i3,/:total curve' ,i3,I'totai user points' ,i3)
iflishape.ne.3.and.ishape.ne.4.and.ishape.ne.61 call
v ermess(O:the element shape number can only be 3.4,6')
if(nuspnt.lt.3.or .nuspnt.gt. 1OO.or .nsurf.lt. l.or .nsurf .gt. 15
v .or.ncurve.lt.3.or.ncurve.gt.50) call ermess(O:rdmesh:
v surface or curve or points numbers excess array bounds')
c
c read curve's two end point number, the curve direction is from first
c point to scond point, curve number then positive, else negative
c
read(iore, *' (icurvelil,i =1,2 *ncurve)
do 300 i =l,ncurve
write(iowr,30) i,icurve(2*i-1}, icurve(2 *i)
30 format(/:curve number=',i3,3x:1st point=',i3.3x,
v '2nd point=',i3)
300 continue
c
c read curve number of which composed surface
c
do 400 i =l,nsurf
ncsf(i) =0
k=l
420 continue
read(iore, *) isurf(i.k)
if(isurf(i,k).eq.O) go to 400
ncsHi) =k
k=k+l
go to 420
400 continue
do 450 i = 1.nsurf
do 450 j"" 1,ncsf(il
write(iowr,4O) i,isurfli,il
450 continue
40 format{/. surface=',i4.3x, 'curve number', i41
c
c olear array rinput
c
do 100 i=1,10000
100 rinput(i) =0.0
c
c read coraseness unit followed by each node's coraseness
c
read(iore, *) cunit, (corase(i),i "" l,nuspnt)
write(iowr, *) 'coarseness unit = ',cunit
write(iowr,50) (i,corase(i), i =1,nuspnt)
50 format(f, 'node=',i4,3x, 'coarse', f9.5)
c
c read each node's coordinates x,y, ...
c
read(iore, .) (rinput(2 *i-1),rinput(2 "il,i = 1 ,nuspnt)
write(iowr,60) (i,rinput(2 *i-1 ),rinput(2 "i), i =1,nuspnt)
60 format(/, 'node =' ,i4,2x,' coordinate x' ,2x,fl 0.S,2x,
v 'coordinate y',2x,flO.5)

read(iore, O') nspint


if(nspint.gt.20} call ermess(O,'rdmesh: number of control
v points maximum is 20')
if(nspint.gt.O) then
read(jore, *) fact,(cascon(i),i = 1,nspint)
write(iowr, *) 'local refine factor' ,fact
write(iowr, *) 'control point coarseness'
write(iowr,51) (i,cascon(i), i = 1 ,nspint)
51 format(/, 'control point-',i4,3x, 'corase', f9.S)
e
c read each control point's coordinates x,y, ...
e
readUore, *) (xycon(2 "i-l ),xycon(2 "il,i =1 ,nspint)
write(iowr,61) (i,xycon(2 *i-l ),xycon(2 "i), i = 1,nspint)
61 format(l,'control point = ',i4,2x,'coordinate x',2x,fl0.5,
v 2x/coordinate y',2x,f10.5)

do 71 i=l,nspint
71 cascon(i) =cascon(i)cunit
endif
close(iore)
end
c *** *** **.***.*** *.**************.*********
c
c subroutine to locally refine internal point area elements
c by splitting longest edges into two
c ..
c *.*_*_w _ _ _ __ _ _.* ... _.... ** __ *.w*** *.**._.
c
c programmer Xie Gaohong
c version 1.0 date 28-09-92
c ..
c .. copyright (c) 1992 "WPA, Dept. of Mechanical Engineering
c Eindhoven University of Technology
c .. 5600 MS, Eindhoven, The Netherlands.
c"
c -*-_ .. - _. _ _ * * **.-.*.*._-*** .... _*.
c "
subroutine refine(npoint,nelem,ishape,neadj,ntadj,rinput)
implicit double precision (a-h,o-z)
dimension neadj( '),ntadj( *),rinput( '),vl (2),v2/2),v3(2)
integer npoint,nelem,neadj,ntadj,ishape
integer il,i2,i3,ipl.ip2,ip3,ipa,iein,ieout,netotl
integer nspint
common/control/nspint,fact,cascon,xycon
dimension xycon(40),cascon(20)
c
if(nspint.eq.O) return
nelemd::: nelem
do 100 iein::: 1,nelemd
ie3 = 3 *(iein-l)
i1 =ntadj(ie3 + 1)
i2 = ntadj(ie3 + 2)
i3 = ntadj(ie3 + 3)
do 70 j 1,2
vl 0) = rinput(2 "(il-l) + j)
v2(j) =rinput(2 * (i2-1) + j)
v3(j) = rinput(2"(i3-1) + j)
70 continue
call doref(ichois,vl,v2,v3)
if(ichois.eq.O) go to 100
iref=2
if(ichois.eq.1) then
c
c splitting edge 01,i2) into two
c
if(netotl(i3,neadj).eq.9) go to 100
call sidenb(il,i2,iein,ieout,ipa,neadj,ntadj)
ifOeout.ne.iein) then
if(netotl(ipa,neadj).eq.9) go to 100
else
iref=l
endif
ipl =i1
ip2=i2
ip3-i3
go to 200
endif
if(ichois.eq.2) then
c
c splitting edge (i2,i3) into two
c
if(netotl(l1,neadj).eq.9} go to 100
call sidenb(i2,i3,iein,ieout,ipa,neadj,ntadj)
iflieout.ne.iein) then
if(netotl(ipa,neadj).eq.9} go to 100
else
iref= 1
endif
ipl =i2
ip2=i3
ip3=il
go to 200
endif
if(ichois.eq.3) then
c
c splitting edge Ci3,il) into two
c
if(netotlli2,neadj).eq.9) go to 100
call sidenbli3,il,iein,ieout,ipa,neadj,ntadj)
if(ieout.ne.iein) then
if(netotllipa,neadj).eq.9) go to 100
else
iref = 1
endif
ip1 =i3
ip2=il
ip3=i2
go to 200
endif
200 continue
c
c update total nodal point number and total element number
c
npoint =npoint + 1
nelem =nelem + 1
ntadjlie3 + 1) =ipl
ntadjlie3 + 2) ... npoint
ntadjlie3 + 3) =ip3
iemp ... 3 (nelem-l )
ntadj(iemp + 1 ) ... npoint
ntadj(iemp + 2) = ip2
ntadjliemp + 3) ... ip3
c
c update node-element list
c
call neupdt(ip3.nelem,neadjl
call neupdt(npoint,netem,neadjl
call neupdt(npoint,iein,neadj)
call remvnd(ip2.iein,neadjl
call neupdt{ip2.nelem.neadjl
c
c update coordinates of npoint
c
xy-rinput(2*Cipl-l I + 1) + rinput(2 * (ip2-1) + 11
rinput(2* (npoint-lI + 11 =xy/2.0
xy=rinput(2*(ipl-1) + 2) + rinput(2(ip2-1) + 2)
rinput(2 (npoint-l) + 2) = xy/2.0

if(iref.eq.2) then
itp = 3 (isout-')
ntadj(itp + 1 ) = ip 1
ntadjlitp + 2) =ipa
ntadjlitp + 3)- npoint
nelem= nelem + 1
iemp=3*Cnelem-l)
ntadjliemp + ,) = npoint
ntadj(iemp + 2) == ipa
ntadj(iemp + 3) = ip2
c
c update node-element list
c
call neupdtlipa,nelem.neadj)
call neupdtCnpoint.nelem.neadj)
call neupdt(npoint.ieout.neadj)
call remvnd(ip2.ieout.neadj)
call neupdtlip2.nelem.neadj)
endif
if(npoint.ge.5000) go to 300
if(nelem.ge.6000) go to 300
iflnelem.ge.2000.and.ishape.eq.41 go to 300
if(nelem.ge.4000.and.ishape.eq.61 go to 300
100 continue
300 return
end
c ** * * * *_ ... _- ....... * *** * * ***
e *
c * subroutine to remove one element from node-element adjacence list
c *
c .** * * * *.* _* * -**** ** _.*.
c *
c * programmer Xie Gaohong
c * version 1.0 date 08-09-92
c
C * copyright (e) 1992 "WPA, Dept. of Mechanical Engineering
c * Eindhoven University of Technology
c * 5600 MB, Eindhoven, The Netherlands.
c *
c ** _.** _**-*-*.***._ ***.**.**.**.**** -***.*****_ _._*.****
c
subroutine remvndlip.ielem.neadj)
implicit double precision (a-h,o-zl
dimension neadj(*)
integer ip,ielem,neadj,i9.i,iemp,ibot
c
iemp=-'
i9=9(ip-ll
ibot=10
do 100 i=1,9
iflneadjli9 + il.eq.ielem) iemp =i
if(neadjli9 + i).eq.O) then
ibot=i
go to 200
end if
100 continue
200 continue
if(iemp.eq.-1 I call ermess(O:remvnd: element suppose
v to be removed not exist in the list')
if{ibot.le.2) call ermess{O.'remvnd: only one element
v in the list while you try to removed'}
naadj09 + iamp) ,.. needjli9 + ibot-'}
needjn9 + ibot-l) = 0
c -_
and
-.*._-_ ...... _. __ . _-**._*-*-*** __ .* * 4_*.*_**

e"
c subroutine to find one edge's neibouring element and sustain node
cc --._.*.*.-._*._ .. *--. __ ..... _._._._ ....... _.... *_._.**_._* ... _-_ ..... _-
c"
c programmer Xie Gaohong
c version 1.0 date 08-09-92
c"
c copyright (e) 1992 "WPA, Dept. of Mechanical Engineering
c Eindhoven University of Technology
c * 5600 MB, Eindhoven, The Netherlands.
c
c__*_*_*_-_-_._-_ .... _.. - *.
c
subroutine sidenb(ip l,ip2,iein,ieout,ip,neadj, ntadj)
implicit double precision (a-h,o-z)
dimension neadj("I,ntadj(")
integer ip l,ip2,iein,ieout,ip,neadj,ntadj
integer i.j.k,jj,iee 1 ,iee2

ieout=iein
do 100 i=l,9
ieel = neadj(9 "(ipl') +i)
ifliee 1 .eq.iein) go to '00
if(ieel.eq.O) go to 400
do 200 j=1,9
iee2 = neadj(9" (ip2-1) + j)
if(iee2.eq.iee 1) ieout = iee2
ifliee2.eq.0) go to 100
200 continue
100 continue
400 continue
do 300 k=l,3
jj =ntadj(3 " lieout-' } + k)
if(jj.ne.ip 1.and.jj.ne.ip21 ip = jj
300 continue
return
end

c
c programmer Xie Gaohong
c version 1.0 date 02-09-92
c
c copyright (c) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MB, Eindhoven, The Netherlands"
c
c *.*_ _ _ *_ .......... _... -.... -... -*._ . -_ .. ****
c
c This subroutine is called to calculate node spacing of internal
c point (x,yl from all user given points and control points
c
c************************* *******.*****
c
c nuspnt : total user points, nspint: total control points
c usnspl*l: user points updated spacing; cascon: control
c nodal points spacing; xycon: control point's coordinates
c
subroutine spnintlicont,nuspnt,usnsp,spave,xy.rinput)
implicit double precision (a-h,o-z)
double precision dtotal,dsp,dx,dy,dxy
integer nuspnt,nspint,ip,icont
dimension xyl *),usnsp(*),rinput( *)
common/controllnspint,fact,cascon,xycon
dimension xycon(40),cascon(20)
c
c **** ****.****.******.*********************************************
c
dtotal =0
dsp=O
do 100 ip = l,nuspnt
dx = rinput(2 *ip-l )-xyll)
dy = rinputt2 "ip)-xyt2)
dxy=sqrt(dx*dx +dy"dyl
if(dxy.le.l06041 dxy= 1 Oe-4
dxy= 1.0/dxy
dtotal = dtotal + dxy
dsp =dsp +dxy"usnsp(ip)
100 continue
if(nspint.ge.l) then
do 200 ip = l,nspint
dx = xycon(2"ip-ll-xy(l )
dy = xycon(2 *ip)-xy(2)
dxy = sqrt(dx" dx + dy" dy)
if(dxy.le.10e-4) dxy= 10604
dxy = 1 .O/dxy
dtotal = dtotal + dxy
dsp =dsp +dxy*casconOp)
200 continue
endif
icont=O
stmp =dsp/dtotal
stmp = stmp/spave
if(stmp.gt.1.1) icont = 1
if(stmp.lt.0.9) icont=-1
end
c **************************************************.********************
c"
c" subroutine to swap edge if circumcircle rule is not applied
c "
c ***********************************************************************
c"
c " programmer Xie Gaohong
c " version 1.0 date 08-09-92
c "
c" copyright (c) 1992 "WPA, Dept. of Mechanical Engineering
c " Eindhoven University of Technology
c " 5600 MB, Eindhoven, The Netherlands.
c"
c ***.*****************************.*.***********************************
c "
subroutine swaped(nelem,neadj,ntadj,rinput)
implicit double precision (a-h,o-zl
dimension neadj( "I,nta<ij("),rinput( "),vl (2),v2(2),v3(2)
integer nelem,neadj,ntadj,itimes,netotl
integer i l,i2,i3,ip l,ip2,ip3,ip4,iein,ieout,idia.j

do 700 itimes .. 1,2


do 100 iein=l.nelem
ie3 = 3" Ciein-ll
il =ntadj(ie3 + 1)
i2 = ntadjlie3 + 21
i3 = ntadj(ie3 + 3)
do 70 j=l,2
vl Ii) =rinput!2 *0 1-1) + j)
v2(j) = rinpuU2*(i2-11 + j)
v3(j) =rinput(2 *(i3-11 + jl
70 continue
call dotvec(v3,v2,v1,cosvec,outp,sl,s2)
if(cosvec.lt.-0.08) then
call sidenb(i l,i2,iein,ieout,ip4,neadj,ntadjl
if(ieout.ne.ieinl then
ipl =i1
ip2=i2
ip3=i3
go to 200
endit
endif
call dotveo(vl.v3.v2.oosveo,outp,sl,s2}
if(oosvec.lt.-O.08) then
call sidenbli2.i3,iein,ieout.ip4,neadj,ntadj}
if(ieout.ne.iein) then
ipl ... i2
ip2==i3
ip3=il
go to 200
endit
endit
oall dotveo(v2.vl.v3.cosvec.outp.sl.s2)
if(oosvec.lt.-0.08} then
call sidenb(i3.i 1.iein.ieout,ip4,neadj,ntadj}
if(ieout.ne.iein) then
ipl =i3
ip2=il
ip3=i2
go to 200
endif
endif
go to 100
200 continue
x4 == rinput(2 *ip4-1)
y4", rinput(2 .. ip4)
idia ==idiadg(v2(1 ).v2(2),v3(1 ),v3(2I,vl (1),v1 (2),x4,y4)
c
e swap edge (ipl,ip2) to (ip3,ip4) if (ip3.ip4) is better positioned
o
if{idla.eq.-l) then
if(netotl(ip3,neadj).eq.91 go to 100
it(netotl(ip4,neadj).eq.9) go to 100

lemp == 3 .. lieout-l )
c
c update element list
c
ntadj(ie3 + 1) =ipl
ntadj(ie3 + 2) ==ip4
ntadj(ie3 + 3) == ip3
ntadjllemp + 1) = ip2
ntadj(iemp + 2) '" ip3
ntadj(iemp + 3) == ip4
e
c update node-element list
c
call neupdtlip3.ieout,neadj)
call neupdUlp4.ieln,neadj)
call remvnd(ipl .ieout.neadj)
call remvnd(ip2,iein,neadj)
endif
100 continue
700 continue
return
end
c .**.*** **.*** ** ** ********.** **************************
c ..
0" subroutine to updete adjacence lists when new triangle is formed
c ..
c .*_ .. ** * _*.*_.-.- .. _... * * _* *._*.* *_.*_.- * -
c ..
c .. programmer Xie Gaohong
c .. version 1.0 date 08-08-92
c ..
c .. copyright (c) 1992 "WPA. Dept. of Mechanical Engineering
c Eindhoven University of Technology
c .. 5600 MB, Eindhoven, The Netherlands.
e ..
c .*******.*** * **.**.*** ***********.*********** ********
c ..
subroutine tform(icase,ifirst,ipoint,ilast,nelem,npoint,
v nptemp,nnadj,neadj,ntadj)
implicit double precision (a-h,o-z)
dimension nnadj(800,3),neadj("),ntadj(")
integer ipoint,ifirst,i1ast,nelem,npoint,nnadj,neadj,ntadj
integer nptemp,ipw ,ipnew ,ii,j,ip2,ip3 ,icase

c ipoint: cuurent point in consideration.


c ifrist: backwerd point, ilast: forward point
c nelem: current element number, npoint: current node number
c nnadj: node-node adjacence list, neadj: node-element adjacence list
c ntradj: element-node adjacence list

c update total node points

npoint=npoint+ 1

if(icase.eq.2) then
ip2=ipoint
ip3=ilast
else
ip2 =ifirst
ip3 =ipoint
endif

c update element-node adjacence list

call update(nelem,npoint,ip2,ip3,neadj,ntadj)

c update node-node adjacence list

ipw=ip3
call findip(ipw,ipnew,nptemp,nnadj)
nnadj(ipnew,2) =npoint
ipw=ip2
call findip(ipw,ipnew,nptemp,nnadjl
nnadj(ipnew,3) =npoint
do 100 j "',nptemp + 1
if(nnadj(j. l).le.O) then
ii=j
if(iLge.nptemp) then
ii = nptemp + 1
nptemp == nptemp + 1
endif
nnadj(ii, 11 = npoint
nnadjlii,2) =ip2
nnadjlii,3) =ip3
return
endif
1 00 continue
end
c * ***** * **.--.*.***.*.*.**_ *** **** *** ********.****
c ..
c .. subroutine to generate 4-node quadrilateral elements out of 3-node ones
c ..
c *****.*******.**.*.*.*** ***.***************.***********.*************
c ..
c .. programmer Xie Gaohong
c .. version 1.0 date 09-09-92
c "
c " copyright (c) 1992 WPA, Dept. of Mechanical Engineering
c " Eindhoven University of Technology
c * 5600 MB, Eindhoven, The Netherlands.
c "
c ******* **************************.* ****** *******************.****
c "
subroutine trans4(nelem,npoint,neadj,ntadj,rinput)
implicit double precision (a-h,o-z)
dimension neadj(*I,ntadj(*I,rinput{*),nctmp(20001
integer nelem,npoint,neadj,ntad;,nptot3
integer i1,i2,i3,iein,ieout,ienew,ie3
integer length,ipbot,iptop

if(nelem.gt.20001 call ermess(0,'trans4: the maximum number


v of base triangle elements is 2000, increase nodal spacing')
nptot3 '" npoint
c
c first move array ntad; to the bottom for stack operation
c
ipbot =24000
length =3 .. nelem
call mvbotm(ntadj,length,ipbot,iptop)

do 100 iein =l,nelem


ienew = 6 .. (iein-1 )
ie3 = iptop + 3 * (iein-1 )
i1 =ntadj(ie3 + 1)
i2 =ntadjlie3 + 2)
i3 =ntadj(ie3 + 3)
ntadj(ienew + 11 = i 1
ntadj(ienew + 2) = i2
ntadjlienew + 3) =i3

call sidenblil,i2,iein,ieout,ip4,neadj,ntadj)
if(iein.le.ieout) then
call upnode(4,il,i2,iein,npoint,ntadj,rinput)
else
call findmn(ieout,i l,i2,ipm,ntadj)
ntadj(ienew+4) =ipm
endif

call sidenb(i2,i3,iein,ieout,ip4,neadj,ntadj)
if(iein.le.ieout) then
call upnode(5,i2,i3,iein,npoint,ntadj,rinputl
else
call findmnlieout,i2,i3,ipm,ntadj)
ntadj(ienew + 51 = ipm
endif

call sidenb(i3,il ,iein,ieout,ip4,neadj,ntadj)


if(iein.Je.ieout) then
call upnode(6,i3,il,iein,npoint,ntadj,rinput)
else
call findmn(ieout,i3,il,ipm,ntadj)
ntadj(ienew + 6) =ipm
endif

npoint = npoint + 1
if(npoint.gt.5000) call ermess(0,'trans4: maximum node
v point number over array limit 5000, increase node spacing')
nctmpliein) = npoint
xy=rinput(2*il-l1 + rinputl2*i2-' ) +rinput(2*i3-1)
rinput(2 "npoint-l) =xy/3.0
xy = rinput(2 *ill + rinput{2 *i2) + rinput{2 "i3)
rinput(2 "npoint) =xy/3.0
100 continue
c
c use array neadj for tempary swap, later build array neadj
c
do 200 j = l,nelem
ie6= 6 *lj-1)
i1 =ntadj{ie6+ 1)
i2 '" ntadj(ie6 + 2)
i3 = ntadj(ie6 + 3)
i4 '" ntadj(ie6 + 4)
i5 = ntadjlie6 + 51
i6 = ntadj(ie6 + 6)
i7 '" nctmp(j)
c
c first quadrilateral element
c
newem=3"(j-11 + 1
ie4 = 4" (newem-l )
neadj(ie4+ 1)=i1
neadjUe4 + 2) '" i4
neadj(ie4+3)=i7
neadj(ie4 + 4) "" i6
c
c second quadrilateral element
c
newem =3*(j-1) + 2
ie4 = 4 .. (newem-1 )
neadj(ie4+ 1) -i2
neadj(ie4+ 2) -i5
neadj(je4 + 3) =i7
neadjlie4 + 4) = i4
c
c third quadrilateral element
c
newem=3 *(j-1) + 3
ie4 =4 * (newem-lI
neadj(ie4 + 1) - i3
neadj!ie4 + 21 = i6
neadj(ie4 + 31 =i7
neadj(ie4 + 4) =is
200 continue
c
c copy array neadj back to array ntadj and build neadj
c
nelem '" 3" nelem
do 300 j=l,4"nelem
ntadjlj) = neadj(j)
300 continue
call nebuld(nelem,npoint,nptot3,ntadj,neadj)
return
end
c *******.***************************************************************
c ..
c" subroutine to generate a-node triangle element out of 3-node ones
c *
c *********** ******.******************.***********************.*******
c ..
c .. programmer Xie Gaohong
c .. version 1.0 date 09-09-92
c ..
c .. copyright (el 1992 ftWPA, Dept_ of Mechanical Engineering
c * Eindhoven University of Technology
c .. 5600 MS, Eindhoven, The Netherlands.
c ..
c .**********.******* *****.***************************.*************.*.
c ..
subroutine trans6(nelem,npoint,neadj,ntadj,rinput)
implicit double precision (a-h,o-z)
dimension neadj(*),ntadjl*),rinputl*I,ntemp(4500)
integer nelem,npoint,neadj,ntadj
integer i1,i2,i3,iein,ieout,ienew,ie3,ietmp
integer length,ipbot,iptop,ipm

if(nelem.gt.40001 call ermess(O:trans6: the maximum number


v of quadratic triangle is 4000, increase nodal spacing')
c
c first move array ntadj to the bottom for stack operation
c
ipbot =24000
length = 3 * nelem
if(nelem.le.25001 then
call mvbotm(ntadj,length,ipbot,iptop)
else
do 10 i =7500 + 1 ,length
ntemp(i-7500) = ntadj(i)
10 continue
length = 7 500
call mvbotm(ntadj,length,ipbot,iptop)
endif

do 100 iein=l,nelem
if(iein.gt.2500) then
ietmp = 3 *(iein-2500-1)
i 1 = ntemp(ietmp + 1 )
i2 = ntemp(ietmp + 21
i3 = ntemp(ietmp + 3)
else
ie3 =iptop +3"(iein-l)
i1 = ntadj(ie3 + 1)
i2 = ntadj(ie3 + 2)
i3 =ntadj(ie3 + 3)
endif
ienew=6*Oein-l)
ntadj(ienew + 11 =i1
ntadj(ienew + 2) =i2
ntadj(ienew + 3) = i3

call sidenbli l,i2,iein,ieout,ip4,neadj.ntadj)


if(iein.gt.ieout) then
call findmn(ieout,il ,i2,ipm.ntadj)
ntadj(ienew + 4) = ipm
else
call upnode(4,il,i2.iein,npoint.ntadj,rinputl
call neupdt(npoint.iein,neadj)
if(iein.ne.ieoutl call neupdt(npoint,ieout.neadjl
endif

call sidenb!i2.i3.iein,ieout,ip4.neadi.ntadj)
if(iein.gt.ieout) then
call findmn(ieout.i2,i3,ipm,ntadj)
ntadjlienew + 5) = ipm
else
call upnode(5,i2,i3.iein,npoint,ntadj,rinput)
call neupdt(npoint,iein,neadj)
if(iein.ne.ieout) call neupdt(npoint,ieout,neadj)
end if

call sidenb(i3,il ,iein.ieout,ip4,neadj,ntadj)


if(iein.gt.ieoutl then
call findmn(ieout,i3,il,ipm,ntadj)
ntadj(ienew+6) =ipm
else
call upnodel6,i3,il ,iein,npoint,ntadj.rinput)
call neupdt(npoint,iein,neadj)
if(iein.ne.ieout) call neupdtlnpoint,ieout,neadj)
endif
if(npoint.gt.5000) call ermess(0,'trans6: maximum node
v out of array limit 5000, increase node spacing')
100 continue
return
end
c
c*******************************************************.**.****.** _.
c
subroutine transc(x, y.xmin, ymin,xfact, yfact, fact)
double precision x,v,yfact,xfact,xmin,ymin,fact
c
c*_**_***-*-_****-*_-**-* .. _.**
c
c programmer Xie Gaohong
c version 1.0 date 26-08-92
c
c copyright (c) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MS, Eindhoven, The Netherlandsft
c
c *._-*-_.**-*_._ .... *-_ .......... *- -._ * **---*.* *****-
c
c This routine is only for the plotting purpose, can be droped
c transform user coordinates to plot coordinates
c
x = (x-xminl/xfact
y = (y-yminl/yfact/fact
return
end
c _.** *-* ****_ *_ _*--**.* ** _ _.*_.-*.* .....
*.*****.
c *
c * subroutine to find right hand vertice of triangle refer to
c * base cl (1 to c2(*)
c *
c * -.-*.* .. -._-_ ... _._._-*._._-_._***_.** ..... ****_ * ** * ***.*
c *
c * programmer Xie Gaohong
eversion 1.0 date 08-08-92
c *
c * copyright (c) 1992 wWPA, Dept. of Mechanical Engineering
c * Eindhoven University of Technology
c * 5600 MB, Eindhoven, The Netherlands.
c *
c --*._ _***._-*--*-**_ .. **---*-*****-_.-_.*-**-*.-.-* .... *.**** ****
0*
subroutine tsolxy(icont,ishort,cl,02.xy,sqlenl
implicit double precision (a-h,o-zl
dimension xy(*I,cl (*),c2(*),xym(2),xydI2)
common/const/ pi,tol
integer icont,i,ishort

do 100i=1,2
xym(i) =0.5*(c1 (i) +02(1)
xyd(i) = 02(i)-0 1 (i)
100 continue
sqlen=xydl1l*xyd(l) + xyd(2)*xyd(2)
s1 =0.866sqlen
if(icont.eq.l) sl = 1.2*s1
if(icont.eq.-1J s1 =O.S*sl
if(ishort.eq.1) sl =0.8 sl
s2 =c2(1)"c1 (2)-01 (1} c2(2) + sl
d0200i=l,2
xym(i) = xymlil"xyd(i)
200 continue
stmp = xym( 1 ) + xym(2)
xyl1) = (stmp *xyd(1 )-xyd(2) *s2l1sqlen
xy(2} = (stmp "xyd(2} + xyd( 1) "s2)/sqlen

o return the length of side

sqlen =sqrt(sqlenl
return
end
c********************************************** _ _ _ *.
c
c programmer Xie Gaohong
c version 1.0 date 20-09-92
c
c copyright (c) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MB, Eindhoven, The Netherlands"
c
c _.-._.- -._ _._ _._ *._.* .. _._ *_._--* *_.-
c
c subroutine to update one triangle information
c
c *_ __ * _ ---*_ *-----_._.
c
subroutine update(nelem.ip 1.ip2.ip3.neadj.ntadj)
integer nelem,neadj( *).ntadj()
integer ipl ,ip2.ip3
c
nelem = nelem + 1
ie3 =3*(nelem-l I
=
ntadj(ie3 + 1 I ip 1
ntadj(ie3 + 2) = ip2
ntadj(ie3 +3) =ip3
call neupdt(ipl,nelem.neadj)
call neupdt(ip2,nelem.neadj)
call neupdtlip3,nelem,neadjl
end
c *************************.*.******* ********.*** ******.*** ****
c ..
c" subroutine to update one middle point's coordinate and number
c ..
c *** *****************************.* **.*.*.*******************.****
c"
c " programmer Xie Gaohong
c .. version 1.0 date 08-09-92
c"
c " copyright (c) 1992 "WPA, Dept. of Mechanical Engineering
c " Eindhoven University of Technology
c " 5600 MS, Eindhoven, The Netherlands.
c ..
c ******* **** ***.*.****.***.*********************.***************
c"
subroutine upnodeCipos,ip1,ip2,ienow,npoint,ntadj,rinput)
implicit double precision (8-h,o-z)
dimension ntadj(" ),rinput!')
integer npoint,ntadj,ipos,ipl ,ip2,ienow
c
npoint = npoi nt + 1
ntadj(G Cienow-ll + ipos) = npoint
rinput(2 "npoint-l} =0.5 * (rinput(2 *ipl-1) + rinput(2 *ip2-1)}
rinput(2 "npoint) =0.5 *(rinput(2 *ipl) + rinput(2 *ip211
end
c ******************.*.*.********* ********.*********** *************
c"
c .. programmer Xie Gaohong
c .. version 1.0 date 15-09-92
c"
c " copyright (c) 1992 "WPA, Dept. of Mechanical Engineering
c " Eindhoven University of Technology
C .. 5600 MB. Eindhoven. The Netherlands.
c "
c ***************.*******************************************************
c"
c re-define nodal spacing after boundary line elements generated
c
subroutine upnsp(ip,usnsp,sp)
integer ip
common/const/ pi,tol
double precision sp,usnsp("),pi,tol

if(usnsp(ip).le.tol} then
usnsp(ip) = sp
else
usnsp(ip) =0.5 "(usnsp(ip) + sp)
endif
end
c
c**********************************************************************.*
c
subroutine pltcv(ishepe,nuspnt,nelem,ntadj,rinputl
implicit double precision (e-h,o-z)
integer nuspnt,nelem,ntadj("),ichois,ishape
integer ipl,ip2,ip3,ip4
double precision x,y,rinput(*I,x1,yl
double precision plotf,yfact,xfact,fact
double precision xmin,xmax,ymin,ymax
c
c ******** *********.**.** ********** *.*********************
c
c programmer Xie Gaohong
c version 1.0 date 11-08-92
c
c copyright (c) 1992 "WPA Dept. of Mechanical Engineering,
c Eindhoven University of TEchnology,
c 5600 MB, Eindhoven, The Netherlands"
c
c * ******************* ******************************************
c
c this routine is machine dependent for making plot files
c set plot parameters
c
plotf=20
call dmi nmx(nuspnt,rinput,xmin,xmax, ymin. ymax)
xfact = (xmax-xmin)/plotf
yfact;: (ymax-yminl/plotf
fact = (xmax-xminl!(ymaxymin)

c ichois = 1 open plot, x = 1 small paper

call plafp6(l,l dO.20dO)

do 10 i=l,nelem
ie=3*li1)
if(ishape.eq.6) ie = 6' 1i-1)
if(ishape.eq.4} ie=4*(j-1)
ip 1 =ntadj(ie + 1)
ip2;: ntadj(le + 2)
ip3 = ntadj(ie + 31
iflishape.eq.4) ip4 = ntadj(ie + 41
xl = rinput(2 *ip 1-1)
yl = rinput(2 *ip 1 )
call transclxl.y1,xmin.ymin.xfact.yfact,fact)
c
c ichois=2 pen down to (x,y), ichois=3 pen up to (x,y)
c
call plafp6(3,xl,yl)
x=rinput{2*ip21 )
y=rinput(2*ip2)
call transc(x. y.xmin, ymin.xfact. yfact. fact)
ichois=2
call plafp6(ichois,x,y)
x = rinput(2 *ip3-11
y;: rinput(2 "ip3)
call transc(x, y.xmin, ymin,xfact. yfact, fact)
call plafp6(ichois,x,y)
if(ishape.eq.41 then
x;: rinput(2 .. ip4-1 )
y=rinputI2*ip41
call transclx, y.xmin, ymin, xfact, yfact. fact)
call plafp6(ichois,x,y)
endif
call plafp6lichois,xl,y1)
10 continue
c
c ichois ;: 5 close plot dataset
c
ichois=5
call plafp6(ichois,OdO,OdO)
return
end

Anda mungkin juga menyukai