program BallGeometry implicit none integer level,i,j,nrad,nz,nradp,ip integer i1,i2,i3,i4,ij,k,np double precision x1,x2,x3,y1,y2,y3,z1,z2,z3 double precision xne,yne,zne,xyzn integer nnode,nnode0,nxt,nxb,nnodemax,nelem,nelemmax,nnodep double precision xc,yc,zc,rad,radp,phi,theta double precision x,y,z,xsp,dist,pi double precision, dimension(:),allocatable::xp,yp,zp,xn,yn,zn integer,dimension(:,:),allocatable::icon pi=atan(1.)*4. ! xc yc zc is the centre of the ball ! rad is radius xc=.501d0 yc=.501d0 zc=.495d0 xc=.5d0 yc=.5d0 ! zc=.9d0 rad=.025d0 ! reference size rad=.05d0 level=9 nz=int(2.d0**level*rad*pi)+1 if ((nz/2)*2.eq.nz) nz=nz+1 nnodemax=nz*nz*2 nelemmax=nnodemax*3 allocate (xp(nnodemax),yp(nnodemax),zp(nnodemax)) allocate (xn(nnodemax),yn(nnodemax),zn(nnodemax)) allocate (icon(3,nelemmax)) nnode=0 nelem=0 ip=1 do j=1,nz theta=-pi/2.+pi*float(j-1)/float(nz-1) radp=rad*cos(theta) z=rad*sin(theta) nrad=1+int(radp*pi*2.d0*2.d0**level) print*,nz,nrad do i=1,nrad phi=2.d0*pi*float(i-1)/float(nrad) x=radp*sin(phi) y=radp*cos(phi) call add_point (nnode,x,y,z,xp,yp,zp,nnodemax) ! bottom half if (j.ne.1.and.j.le.nz/2+1) then i1=nnode i2=nnode+1 if (i.eq.nrad) i2=nnodep+nradp+1 i3=nnodep+int((i*nradp)/nrad)+1 ip=nnodep+int(((i-1)*nradp)/nrad)+1 if (i3.ge.nnodep+nradp+1) i3=nnodep+1 call add_element (nelem,icon,i1,i2,i3,nelemmax) if (i3.ne.ip) call add_element (nelem,icon,i1,i3,ip,nelemmax) ip=i3 ! top half (minus very top) elseif (j.ne.1.and.j.ne.nz) then i1=nnode i2=nnode+1 if (i.eq.nrad) i2=nnode-nrad+1 i3=nnodep+int((i*nradp)/nrad)+1 if (i.eq.1) i3=nnodep+2 np=1 if (i.ne.1) np=i3-ip do k=1,np call add_element (nelem,icon,i3-k,i1,i3-k+1,nelemmax) enddo if (i.eq.nrad) call add_element (nelem,icon,i2,nnodep+1,nnode-nrad,nelemmax) call add_element (nelem,icon,i1,i2,i3,nelemmax) ip=i3 ! very top elseif (j.eq.nz) then do k=1,nradp i1=nnodep+k i2=i1+1 if (i2.eq.nnode) i2=nnodep+1 i3=nnode call add_element (nelem,icon,i1,i3,i2,nelemmax) enddo endif enddo nradp=nrad nnodep=nnode-nrad enddo print*,nnode,nelem !add normals 112 continue do i=1,nelem i1=icon(1,i) i2=icon(2,i) i3=icon(3,i) if (i1.eq.i2 .or. i2.eq.i3 .or. i3.eq.i1)then print*,'element ',i,' collapsed: ',icon(:,i) do j=i+1,nelem icon(:,j-1)=icon(:,j) enddo nelem=nelem-1 goto 112 endif x1=xp(i1) x2=xp(i2) x3=xp(i3) y1=yp(i1) y2=yp(i2) y3=yp(i3) z1=zp(i1) z2=zp(i2) z3=zp(i3) xne=(y2-y1)*(z3-z1)-(y3-y1)*(z2-z1) yne=(z2-z1)*(x3-x1)-(z3-z1)*(x2-x1) zne=(x2-x1)*(y3-y1)-(x3-x1)*(y2-y1) xyzn=sqrt(xne**2+yne**2+zne**2) xne=xne/xyzn yne=yne/xyzn zne=zne/xyzn do j=1,3 ij=icon(j,i) xn(ij)=xn(ij)+xne yn(ij)=yn(ij)+yne zn(ij)=zn(ij)+zne enddo enddo do i=1,nnode xyzn=sqrt(xn(i)**2+yn(i)**2+zn(i)**2) xn(i)=xn(i)/xyzn yn(i)=yn(i)/xyzn zn(i)=zn(i)/xyzn enddo xp=xp+xc yp=yp+yc zp=zp+zc open (71,file='surface-1.txt',status='unknown') write (71,*) nnode,nelem do i=1,nnode write (71,*) xp(i),yp(i),zp(i),xn(i),yn(i),zn(i) enddo do i=1,nelem write (71,*) (icon(j,i),j=1,3) enddo close (71) open(unit=30,file='Mesh.vtk') write(30,'(a)')'# vtk DataFile Version 3.0' write(30,'(a)')'surface' write(30,'(a)')'ASCII' write(30,'(a)')'DATASET UNSTRUCTURED_GRID' write(30,'(a7,i10,a6)')'POINTS ',nnode,' float' do i=1,nnode write(30,'(3f16.11)') xp(i),yp(i),zp(i) enddo write(30,'(A6, 2I10)') 'CELLS ',nelem,4*nelem do i=1,nelem write(30,'(9I10)')3,icon(1:3,i)-1 enddo write(30,'(A11, I10)') 'CELL_TYPES ',nelem do i=1,nelem write(30,'(I2)')5 ! octree (8 nodes) enddo write(30,'(a11,i10)')'POINT_DATA ',nnode write(30,'(a)')'VECTORS norm float' do i=1,nnode write(30,'(3f18.13)')xn(i),yn(i),zn(i) enddo close(30) deallocate (xp,yp,zp,icon) end !-------- subroutine add_point (nnode,x,y,z,xp,yp,zp,nnodemax) double precision xp(nnodemax),yp(nnodemax),zp(nnodemax) double precision x,y,z nnode=nnode+1 if (nnode.gt.nnodemax) then print*,nnode,nnodemax stop 'needs to increase nnodemax' endif xp(nnode)=x yp(nnode)=y zp(nnode)=z return end !---------- subroutine add_element (nelem,icon,i1,i2,i3,nelemmax) integer nelem,nelemmax,icon(3,nelemmax),i1,i2,i3 nelem=nelem+1 if (nelem.gt.nelemmax) then print*,nelem,nelemmax stop 'nelemmax needs to be increased' endif icon(1,nelem)=i1 icon(2,nelem)=i2 icon(3,nelem)=i3 return end