generation of graded triangular and quadrilateral mesh · isurf i 3/15 i curve number of each...

49
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 Universiteit Eindhoven. 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 be important differences between the submitted version and the official published version of record. People interested in the research are advised to contact the author for the final version of the publication, or visit the DOI 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 page numbers. Link to publication General rights Copyright and moral rights for the publications made accessible in the public portal are retained by the authors and/or other copyright owners and 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, please follow below link for the End User Agreement: www.tue.nl/taverne Take down policy If you believe that this document breaches copyright please contact us at: [email protected] providing details and we will investigate your claim. Download date: 13. Apr. 2021

Upload: others

Post on 28-Oct-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Generation of graded triangular and quadrilateral mesh · 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

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

Page 2: Generation of graded triangular and quadrilateral mesh · 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

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

Page 3: Generation of graded triangular and quadrilateral mesh · 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

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 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

Page 4: Generation of graded triangular and quadrilateral mesh · 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

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

Page 5: Generation of graded triangular and quadrilateral mesh · 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

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

Page 6: Generation of graded triangular and quadrilateral mesh · 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

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

Page 7: Generation of graded triangular and quadrilateral mesh · 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

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

Page 8: Generation of graded triangular and quadrilateral mesh · 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

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*

Page 9: Generation of graded triangular and quadrilateral mesh · 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

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

Page 10: Generation of graded triangular and quadrilateral mesh · 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

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

Page 11: Generation of graded triangular and quadrilateral mesh · 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

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

Page 12: Generation of graded triangular and quadrilateral mesh · 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

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)

Page 13: Generation of graded triangular and quadrilateral mesh · 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

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

Page 14: Generation of graded triangular and quadrilateral mesh · 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

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

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)

Page 15: Generation of graded triangular and quadrilateral mesh · 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

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.

Page 16: Generation of graded triangular and quadrilateral mesh · 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

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

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

Page 17: Generation of graded triangular and quadrilateral mesh · 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

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

Page 18: Generation of graded triangular and quadrilateral mesh · 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

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

Page 19: Generation of graded triangular and quadrilateral mesh · 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

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

Page 20: Generation of graded triangular and quadrilateral mesh · 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

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

Page 21: Generation of graded triangular and quadrilateral mesh · 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

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

Page 22: Generation of graded triangular and quadrilateral mesh · 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

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

Page 23: Generation of graded triangular and quadrilateral mesh · 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

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

Page 24: Generation of graded triangular and quadrilateral mesh · 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

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

Page 25: Generation of graded triangular and quadrilateral mesh · 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

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)

Page 26: Generation of graded triangular and quadrilateral mesh · 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

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

Page 27: Generation of graded triangular and quadrilateral mesh · 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

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

Page 28: Generation of graded triangular and quadrilateral mesh · 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

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

Page 29: Generation of graded triangular and quadrilateral mesh · 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

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

Page 30: Generation of graded triangular and quadrilateral mesh · 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

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

Page 31: Generation of graded triangular and quadrilateral mesh · 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

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

Page 32: Generation of graded triangular and quadrilateral mesh · 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

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(*)

Page 33: Generation of graded triangular and quadrilateral mesh · 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

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

Page 34: Generation of graded triangular and quadrilateral mesh · 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

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

Page 35: Generation of graded triangular and quadrilateral mesh · 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

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

Page 36: Generation of graded triangular and quadrilateral mesh · 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

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)

Page 37: Generation of graded triangular and quadrilateral mesh · 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

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

Page 38: Generation of graded triangular and quadrilateral mesh · 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

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)

Page 39: Generation of graded triangular and quadrilateral mesh · 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

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

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

Page 40: Generation of graded triangular and quadrilateral mesh · 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

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)

Page 41: Generation of graded triangular and quadrilateral mesh · 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

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

Page 42: Generation of graded triangular and quadrilateral mesh · 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

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 ..

Page 43: Generation of graded triangular and quadrilateral mesh · 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

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)

Page 44: Generation of graded triangular and quadrilateral mesh · 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

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)

Page 45: Generation of graded triangular and quadrilateral mesh · 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

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

Page 46: Generation of graded triangular and quadrilateral mesh · 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

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 c

programmer version 1.0

Xie Gaohong date 26-08-92

c copyright (c) 1992 "WPA Dept. of Mechanical Engineering,

Page 47: Generation of graded triangular and quadrilateral mesh · 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

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 •••••••••••• *_ ••••••• __ •••••••••• * ••• _ ••••••••• ---*_ •••••• *-----_._.

Page 48: Generation of graded triangular and quadrilateral mesh · 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

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

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

Page 49: Generation of graded triangular and quadrilateral mesh · 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

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