Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
Generation of graded triangular and quadrilateral mesh
Citation for published version (APA):Xie, G. (1992). Generation of graded triangular and quadrilateral mesh. (TH Eindhoven. Afd.Werktuigbouwkunde, Vakgroep Produktietechnologie : WPB; Vol. WPA1409,WPA1417). Technische UniversiteitEindhoven.
Document status and date:Published: 01/01/1992
Document Version:Publisher’s PDF, also known as Version of Record (includes final page, issue and volume numbers)
Please check the document version of this publication:
• A submitted manuscript is the version of the article upon submission and before peer-review. There can beimportant differences between the submitted version and the official published version of record. Peopleinterested in the research are advised to contact the author for the final version of the publication, or visit theDOI to the publisher's website.• The final author version and the galley proof are versions of the publication after peer review.• The final published version features the final layout of the paper including the volume, issue and pagenumbers.Link to publication
General rightsCopyright and moral rights for the publications made accessible in the public portal are retained by the authors and/or other copyright ownersand it is a condition of accessing publications that users recognise and abide by the legal requirements associated with these rights.
• Users may download and print one copy of any publication from the public portal for the purpose of private study or research. • You may not further distribute the material or use it for any profit-making activity or commercial gain • You may freely distribute the URL identifying the publication in the public portal.
If the publication is distributed under the terms of Article 25fa of the Dutch Copyright Act, indicated by the “Taverne” license above, pleasefollow below link for the End User Agreement:www.tue.nl/taverne
Take down policyIf you believe that this document breaches copyright please contact us at:[email protected] details and we will investigate your claim.
Download date: 13. Apr. 2021
Generation of Graded Triangular and Quadrilateral Mesh
Appendix: Source Codes Listing
Oct. 1992
TUE-Research Report Gaohong Xie
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 related 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 checking 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 compiler 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 nsurf I ncurve I nuspnt I nspint I lcurve I
3/6 1/15 3/50 3/100 1/20 6/100
I I I I I I
Element type number (3,4,6) Total number of surfaces Total number of curves (including inner opennings) Total number of user points (numbered from 1 to nuspnt) Total number of internal control points 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 con troll 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 c c
programmer version 1.0
Xie Gaohong date 20-08-92
c copyright (c) 1992 "WPA Dept. of Mechanical Engineering, c Eindhoven University of TEchnology, c 5600 MB, Eindhoven, The Netherlands" c 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 This part purely for the interface of sepren
call start(O, 1 ,1 ,n c**********************************************************************
c c initialise some constants c
c
c
tolin = lOe-6 call initcb(tolin)
namere = 'meshln' namewr = 'meshout' open (unit=iore, file=namere) open (unit =iowr, file = namewr)
c read all necessary information on mesh region, perform check c get time routine gtime is machine dependent, FTN77 compiler only c
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 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
c
writeliowr, *) 'CPU time in initia is' ,tt2 call cklimt(nsurf ,isurf, ncsf ,nelmcv}
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
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 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
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 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 o c
programmer version 1.0
Xie Gaohong date 17-08-92
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 c c
programmer version 1.0
Xie Gaohong date 10-08-92
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
o
subroutine chkfin(nptemp,nnadj) implicit double precision (a-h, o-z) integer nptemp,nnadj,jj,iaot dimension nnadj(800,3)
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 c c
programmer version 1.0
Xie Gaohong date 16-08-92
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
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 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
c
iflichois.eq.1) go to 100 if(ishape.eq.4) then
if(npqout(ip,neadj).eq.l) go to 100 endif
c stotal = 0, xylil = 0 c
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 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)
1 00 continue 900 continue
end c····*·********************************************************************
c c c c
Programmer Version 1.0
Xie Gaohong date 11-08-92
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
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 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 = 1 dO/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 c c
programmer version 1.0
Xie Gaohong date 20-09-92
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
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
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)
c
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 added a point in the middle of (ip1.ip2) three triagnles formed c
c
if(cosl.ge.OdO.and.cos2.ge.OdO) then
if(sp.le.O.4*(sl + sf)) return idid=l
c added a middla point of Up 1.ip2) and form three triangles c
c
opoint = npoint + 1 rinput(2* npoint-1) =O.S"(vl (1) +v2(1)) rinput(2 "npoint) =O.S"lvl (2) +v2(2))
c three triangles (ifl.ip 1.npoint) (ifl.npoint.il2) (iI2.npoint,ip2) c
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 update nnadj list c
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 two triangles (ifl.ipl.ip2) lifl,ip2,il2) c
c
call update(nelem,if1.ip 1.ip2.neadj.ntadj) call update(nelem.ifl,ip2.iI2.neadj.ntadj)
c update nnadj list c
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 two traingles (ip2,U2.ipl) (if1.ipl.il2) c
c
call update(nelem,ip2,iI2,ipl,neadj,ntadj) call update(nelem,ifl,ip 1.iI2,neadi,ntadj)
c update nnadj list c
nnadjlifdex.31 =il2 nnadjlildex.2) =if1 nnadj(indexl.21 = ip2
c
nnadjlindex2.3) -ip1 return
endif if(cos2.1t.0.and.cos1.1t.0) then
idid - 1
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 c c
programmer version 1.0
Xie Gaohong date 10-09-92
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
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(*)
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 c c
programmer version 1.0
Xie Gaohong date 02-09-92
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
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 *******************************.**********************._*_ •• * ••••• ** 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 1 00 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 **************************************** •• *******.****.*.*** ••••••• _* ••
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 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 c c
programmer version 1.0
Xie Gaohong date 10-08-92
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 c
string name of the calling routine
coat output the error message was printed and program was stoped c c **._ ••••••••••••• *.*.***_ ••••••• _** •• _**.*** ••• _** ••• * ••••••• *.** •••• *
c
c»
subroutine ermess(ichois,string) charaoter*!*) string integer iore, iowr,ichois commonliounitl iore,iowr
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
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
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" 0"
c c " c " 0 c *
programmer Xie Gaohong version 1.0 date 20-08-92
copyright (c) 1992 ·WPA, Dept. of Mechanical Engineering Eindhoven University of Technology 5600 MB, Eindhoven, The Netherlands.
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" c· c·
Eindhoven University of Technology 5600 MB, Eindhoven, The Netherlands.
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 c c
programmer version 1.0
Xie Gaohong date 10-08-92
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
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 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
c
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 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
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 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
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"npoint·1) = 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"npoint·l) =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 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)
v
else call nbpcls(ilast,nelem,nptemp,nnadj,
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)
v
else call nbpcls(ilast,nelem,nptemp,nnadj,
endif endif
endif
neadj,ntadj,rinput)
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 c c
programmer version 1.0
Xie Gaohong date 10-08-92
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
c
subroutine getcr(ipoint,xy,rinput) implicit double precision (a-h, o-z) dimension rinput(*),xy(*) integer ipoint
xy(1)" rinput(2 *ipoint-1) xy(2) .. rinput(2*ipoint) end
c ****************************.********* •• ****.***********************
c
c c c
programmer version 1.0
Xie Gaohong date 10-08-92
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 c c
programmer version 1.0
xie gaohong date 17-08-92
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 cOif four vertices are cocircular c
c
integer function idiadg(xO,yO,xl ,yl,x2.y2,x3,y3) implicit double precision (a-h,o-z) common/const/pi, tol
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
endif end
idiadg=l else
idisdg=O endif
c··*·_··········_····_···_*_·_·····***-_·-·_··***··_*·*************** e c c c
programmer version 1.0
Xie Gaohong date 17-08-92
e copyright (c) 1992 "WPA Dept. of Mechanical Engineering, c Eindhoven University of TEchnology, c 5600 MB, Eindhoven, The Netherlands" c 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 * ••• * •••• __ •••• _._. __ ._-_ •• _ •• -** ••• - •••••• **-_._--_ .. ****.***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 if this curve is inner boundary, if not then it is out boundary c --**_ •••••••••• _. __ •••• _._. __ ••• _ ••• _--*--_._. __ .. -.. -.. _.* ••••...... _. 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 e c
programmer version 1.0
Xie Gaohong date 14-08-92
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
c
commonliounitl iore,iowr integer iore,iowr common Iconst/pi,tol double precision pi.tol double precision tolin,eps,epsp 1 save Iconst/,liounit/
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, 1 OO.ODO*eps) 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 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 c c
programmer version 1.0
Xie Gaohong date 10-08-92
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
c
subroutine innerclnsurf,isurf,ncsf,ncurve,innerl implicit double precision (a-h, o-z) integer nsurf,isurf(15,30),ncsf( "I,inner!·)
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 *
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 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
c
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 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
c
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 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 c c
programmer version 1.0
Xie Gaohong date 10-08-92
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
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 input/output c c nuspnt number of user points c c ncurve number of curves c c nsurf number of surfaces c c c
icurve arrav contains node number of curve ends
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
v
200 100
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
ermess(O:loopck:surface curve number wrong') isecnd=ip2 continue continue
end c ** •• - •••• _ •••• *._.*.**.--*-* .. _ ••..• _-----_ .. _-* .• _ .•••• *-_ .... **---c c c c
programmer version 1.0
Xie Gaohong date 10·08-92
c copvright (c11992 "WPA Dept. of Mechanical Engineering, c Eindhoven Universitv of TEchnologv, c 5600 MB. Eindhoven, The Netherlands· c
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 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 c c
programmer version 1.0
Xie Gaohong date 10-08-92
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
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 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 ..
c
integer function netotHipoint,neadjl implicit double precision (a-h,o-zl dimension neadj(*l integer ipoint.neadj integer i,j
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 c c
programmer version 1.0
Xie Gaohong date 10-09-92
c copyright (c) 1992 DWPA Dept. of Mechanical Engineering, c Eindhoven University of TEchnology, c 5600 MS, Eindhoven, The Netherlands· c c *************.******************************************************
c
c
integer function npqout(ipoint,neadj) implicit double precision (a-h,o-z) integer ipoint,neadj("),i9,i,iem
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" c .. c .. c .. c .. c .. c ..
programmer Xie Gaohong version 1.0 date 08-08-92
copyright (c) 1992 "WPA, Dept. of Mechanical Engineering Eindhoven University of Technology 5600 MB, Eindhoven, The Netherlands.
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 c c
programmer version 1.0
Xie Gaohong date 10·08·92
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
c
subroutine prtnec(ishape,nelem,npoint,neadj,ntadj,rinput) implicit double precision (a·h,o-z) integer npoint,nelem,ntadj(*),neadj( * ),ishape double precision rinput(*) common liounitliore,iowr integer iore,iowr,ip1,ip2,ip3,inelm
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 .,
c ..
c .. c .. c" c " c .. c
subroutine ratiop(ratio.a.b.pnt) implicit double precision (a·h.o·z) dimension a(*).b(").pnt(*)
a.b Ii) : array of 2 contains coordinates of point a b
pnt (0) : array of 2 contains ratio point's coordinate
ratio Ii) : the ratio equals line (a.pnt) to line (a.b)
c .************* •••• *****.*********** •• *********** •• *********************
do 100 i=1.2 pnt(i} = ali) + ratio" (b(i)-a(i))
1 00 continue return end
c •• ************** ••• *************.***********************************
c c c c
programmer version 1.0
Xie Gaohong date 10·0a-92
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 c c c c c c c
icurve(p1.p2.p3.p4 ••••• )
fill array isurf( * •• ) in the following way:
isurf(l.ci). ci=cm •. cn isurfI2.cil. ci=cm •• cn. ci are curve number close surface in CCW
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
c
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 read total total number of surfaces, curves, user points c
read (iore, *1 ishape,nsurf,ncurve,nuspnt write(iowr, 1 0) ishape,nsurf,ncurve,nuspnt
10 format(/, 'shape of element',i3,l:total surface',
c
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. 1 OO.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 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 "
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)
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
c
call doref(ichois,vl,v2,v3) if(ichois.eq.O) go to 100 iref=2 if(ichois.eq.1) then
c splitting edge 01,i2) into two c
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 splitting edge (i2,i3) into two c
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 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
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 update node-element list c
call neupdt(ip3.nelem,neadjl call neupdt(npoint,netem,neadjl call neupdt(npoint,iein,neadj)
c
call remvnd(ip2.iein,neadjl call neupdt{ip2.nelem.neadjl
c update coordinates of npoint c
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 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·
c
subroutine remvndlip.ielem.neadj) implicit double precision (a-h,o-zl dimension neadj(*) integer ip,ielem,neadj,i9.i,iemp,ibot
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 and
c -_ ••• -.*._-_ ......•• _. __ .•• _-**._*-*-*** •••• __ .* ••• * ••••••••••• 4_*.*_**
e " c· subroutine to find one edge's neibouring element and sustain node
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 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
c c c c
return end
programmer version 1.0
Xie Gaohong date 02-09-92
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
c
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)
e swap edge (ipl,ip2) to (ip3,ip4) if (ip3.ip4) is better positioned o
c
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 update element list c
e
ntadj(ie3 + 1) =ipl ntadj(ie3 + 2) ==ip4 ntadj(ie3 + 3) == ip3 ntadjllemp + 1) = ip2 ntadj(iemp + 2) '" ip3 ntadj(iemp + 3) == ip4
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)
c
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 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
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 second quadrilateral element c
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 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 ..
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 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»
c
subroutine transc(x, y.xmin, ymin,xfact, yfact, fact) double precision x,v,yfact,xfact,xmin,ymin,fact
c·*·_*····*·_**·····*-*-······_·*·***-*··_············-**-* .. _.** •••• c c c c
programmer version 1.0
Xie Gaohong date 26-08-92
c copyright (c) 1992 "WPA Dept. of Mechanical Engineering,
c c c
Eindhoven University of TEchnology, 5600 MS, Eindhoven, The Netherlandsft
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.866·sqlen 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 c c
programmer version 1.0
Xie Gaohong date 20-09-92
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
c
subroutine update(nelem.ip 1.ip2.ip3.neadj.ntadj) integer nelem,neadj( *).ntadj(·) integer ipl ,ip2.ip3
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"
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
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
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» 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
c
double precision x,y,rinput(*I,x1,yl double precision plotf,yfact,xfact,fact double precision xmin,xmax,ymin,ymax
c •••••• ******** •• *********.**.** •• ********** •• *.*********************
c c c c
programmer version 1.0
Xie Gaohong date 11-08-92
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!(ymax·ymin)
c ichois = 1 open plot, x = 1 small paper
call plafp6(l,l dO.20dO)
do 10 i=l,nelem ie=3*li·1) 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*ip2·1 ) 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