!------------------------------------------------------------------------------| !------------------------------------------------------------------------------| ! | ! ||===\\ | ! || \\ | ! || || //==\\ || || //==|| ||/==\\ | ! || || || || || || || || || || | ! || // || || || || || || || | ! ||===// \\==// \\==\\ \\==\\ || | ! | !------------------------------------------------------------------------------| !------------------------------------------------------------------------------| ! | ! CREATE_SURF May. 2008 | ! | !------------------------------------------------------------------------------| !------------------------------------------------------------------------------| subroutine create_surf(surface,is,debug) !------------------------------------------------------------------------------| !(((((((((((((((( Purpose of the routine )))))))))))))))))))))))))))))))))))))) !------------------------------------------------------------------------------| ! for a given surfaces passed as argument, this routine computes ! the 8 fields x,y,z,xn,yn,zn,r,s for each point of the surface ! according to its type and levelt, and the triangulation !------------------------------------------------------------------------------| !(((((((((((((((( declaration of the subroutine arguments )))))))))))))))))))) !------------------------------------------------------------------------------| use constants use definitions !use mpi use randomodule implicit none include 'mpif.h' type (sheet) :: surface integer is integer debug !------------------------------------------------------------------------------| !(((((((((((((((( declaration of the subroutine internal variables ))))))))))))) !------------------------------------------------------------------------------| integer :: levelt,surface_type,nproc,iproc,ierr,i,j,seed,indix integer :: err,ntmax,nhmax,npmax,nmax,nmode,nvmax,nnpnmax,nh,nohalt_hull,loc integer :: dmode,nt,nhull,icircles,irect integer,dimension(:), allocatable :: hulltriangles,vis_tlist,vis_elist integer,dimension(:), allocatable :: add_tlist integer,dimension(:,:),allocatable :: vertices,neighbour logical*1,dimension(:),allocatable :: lt_work,ln_work double precision :: sp01,sp02,sp03,sp04,sp05,sp06,sp07,sp08,sp09,sp10,sp11,sp12 double precision :: sp13,sp14,sp15 double precision :: delta,eps,epsil,delta_angle,delta_radius,angle double precision :: xx,yy,xini,xend,yini,yend,dx,dy,dist double precision,dimension(:), allocatable :: field double precision,dimension(:,:),allocatable :: points,centres logical clockwise character ch character*72 :: shift integer nnn(1),nnlist(1),ntrilist(1) !------------------------------------------------------------------------------| !------------------------------------------------------------------------------| call mpi_comm_size (mpi_comm_world,nproc,ierr) call mpi_comm_rank (mpi_comm_world,iproc,ierr) shift=' ' if (surface%surface_type.lt.0) then !--------------------------------- ! reading surface from ascii file !--------------------------------- if (iproc.eq.0) then write (ch,'(i1)') -surface%surface_type write(*,*) shift//'surface-'//ch//'.txt' open(71,file='surface-'//ch//'.txt',status='old') read(71,*) surface%nsurface,surface%nt write(*,*) shift//'-> nb of points :',surface%nsurface write(*,*) shift//'-> nb of triangles:',surface%nt end if call mpi_bcast (surface%nsurface,1,mpi_integer,0,mpi_comm_world,ierr) call mpi_bcast (surface%nt,1,mpi_integer,0,mpi_comm_world,ierr) deallocate (surface%x,surface%y,surface%z) deallocate (surface%xn,surface%yn,surface%zn) deallocate (surface%r,surface%s) deallocate (surface%icon) allocate (surface%x(surface%nsurface),surface%y(surface%nsurface),surface%z(surface%nsurface)) allocate (surface%xn(surface%nsurface),surface%yn(surface%nsurface),surface%zn(surface%nsurface)) allocate (surface%r(surface%nsurface),surface%s(surface%nsurface)) allocate (surface%icon(3,surface%nt)) if (iproc.eq.0) then write(*,*) surface%nsurface,surface%nt do i=1,surface%nsurface read (71,*) surface%x(i),surface%y(i),surface%z(i),surface%xn(i),surface%yn(i),surface%zn(i) surface%r(i)=surface%x(i) surface%s(i)=surface%y(i) if (surface%x(i)<0 .or. surface%x(i)>1 .or. surface%y(i)<0 .or. surface%y(i)>1 .or. surface%z(i)<0 .or. surface%z(i)>1 & .and. iproc.eq.0) & print *,surface%x(i),surface%y(i),surface%z(i) enddo do i=1,surface%nt read (71,*) (surface%icon(j,i),j=1,3) enddo close (71) endif call mpi_bcast(surface%x,surface%nsurface,mpi_double_precision,0,mpi_comm_world,ierr) call mpi_bcast(surface%y,surface%nsurface,mpi_double_precision,0,mpi_comm_world,ierr) call mpi_bcast(surface%z,surface%nsurface,mpi_double_precision,0,mpi_comm_world,ierr) call mpi_bcast(surface%xn,surface%nsurface,mpi_double_precision,0,mpi_comm_world,ierr) call mpi_bcast(surface%yn,surface%nsurface,mpi_double_precision,0,mpi_comm_world,ierr) call mpi_bcast(surface%zn,surface%nsurface,mpi_double_precision,0,mpi_comm_world,ierr) call mpi_bcast(surface%r,surface%nsurface,mpi_double_precision,0,mpi_comm_world,ierr) call mpi_bcast(surface%s,surface%nsurface,mpi_double_precision,0,mpi_comm_world,ierr) call mpi_bcast(surface%icon,surface%nt*3,mpi_integer,0,mpi_comm_world,ierr) else !---------------- ! create surface !---------------- seed=1234567 sp01=surface%sp01 sp02=surface%sp02 sp03=surface%sp03 sp04=surface%sp04 sp05=surface%sp05 sp06=surface%sp06 sp07=surface%sp07 sp08=surface%sp08 sp09=surface%sp09 sp10=surface%sp10 sp11=surface%sp11 sp12=surface%sp12 sp13=surface%sp13 sp14=surface%sp14 sp15=surface%sp15 surface_type=surface%surface_type levelt=surface%levelt ! delta=2.d0**(-levelt) ! spacing between points on hull delta=1.d0 / (2.d0**levelt +1) ! opla epsil=(surface%stretch-1)/2.d0 if (iproc.eq.0) write(8,*) 'create_surfaces: delta=',delta if (iproc.eq.0) write(8,*) 'create_surfaces: epsilon=',epsil !-----building the surface------------- ! type 1 : flat surface ! type 2 : rectangular emboss ! type 3 : convex spherical emboss ! type 4 : concave spherical emboss ! type 5 : double rectangular emboss ! type 6 : sinus ! type 7 : noisy surface ! type 8 : double sinus ! type 9 : cosinus sinus ! type 10 : slope ! type 11 : 2D hill ! type 12 : rectangular emboss with specified slope ! type 13 : slope with 2 kinks ! type 14 : slope with 2 kinks, one rounded select case(surface_type) case (1,2,5,6,7,8,9,10,11,12,13,14,15) ! if (surface%rand) then indix=1 ! convex hull do i=1,2**levelt +1 surface%x(indix)=dble(i-1)*delta surface%y(indix)=0.d0 indix=indix+1 end do do i=1,2**levelt +1 surface%x(indix)=1.d0 surface%y(indix)=dble(i-1)*delta indix=indix+1 end do do i=1,2**levelt +1 surface%x(indix)=1.d0-dble(i-1)*delta surface%y(indix)=1.d0 indix=indix+1 end do do i=1,2**levelt +1 surface%x(indix)=0.d0 surface%y(indix)=1.d0-dble(i-1)*delta indix=indix+1 end do !interior nodes if(surface%rand) then call random_number (surface%x(indix:surface%nsurface)) call random_number (surface%y(indix:surface%nsurface)) else surface%x(indix:surface%nsurface)=0.5d0 surface%y(indix:surface%nsurface)=0.5d0 end if do j=2,2**levelt +1 do i=2,2**levelt +1 surface%x(indix)=(((surface%x(indix)-0.5d0)*2.d0)*epsil+dble(i-1))*delta surface%y(indix)=(((surface%y(indix)-0.5d0)*2.d0)*epsil+dble(j-1))*delta indix=indix+1 enddo enddo ! else ! ! regular grid of points ! indix=1 ! do j=1,2**levelt+1 ! do i=1,2**levelt+1 ! surface%x(indix)=float(i-1)*delta ! surface%y(indix)=float(j-1)*delta ! indix=indix+1 ! end do ! end do ! end if case (22) if (surface%rand) then indix=1 ! convex hull do i=1,2**levelt surface%x(indix)=(i-1)*delta surface%y(indix)=0.d0 indix=indix+1 end do do i=1,2**levelt surface%x(indix)=1.d0 surface%y(indix)=(i-1)*delta indix=indix+1 end do do i=1,2**levelt surface%x(indix)=1.d0-(i-1)*delta surface%y(indix)=1.d0 indix=indix+1 end do do i=1,2**levelt surface%x(indix)=0.d0 surface%y(indix)=1.d0-(i-1)*delta indix=indix+1 end do if (iproc.eq.0) write(8,*) 'nhull=',indix-1,'for surface ',is ! placing rows of points outside, on and outside the rectangle eps=0.001 do irect=-5,3,2 xini=sp02+irect*eps xend=sp03-irect*eps yini=sp04+irect*eps yend=sp05-irect*eps dx=(xend-xini)/2**levelt dy=(yend-yini)/2**levelt do i=1,2**levelt xx=xini+(i-1)*dx yy=yini if (xx.ge.0 .and. xx.le.1 .and. yy.ge.0 .and. yy.le.1) then surface%x(indix)=xx surface%y(indix)=yy indix=indix+1 end if end do do i=1,2**levelt xx=xend yy=yini+(i-1)*dy if (xx.ge.0 .and. xx.le.1 .and. yy.ge.0 .and. yy.le.1) then surface%x(indix)=xx surface%y(indix)=yy indix=indix+1 end if end do do i=1,2**levelt xx=xend-(i-1)*dx yy=yend if (xx.ge.0 .and. xx.le.1 .and. yy.ge.0 .and. yy.le.1) then surface%x(indix)=xx surface%y(indix)=yy indix=indix+1 end if end do do i=1,2**levelt xx=xini yy=yend-(i-1)*dy if (xx.ge.0 .and. xx.le.1 .and. yy.ge.0 .and. yy.le.1) then surface%x(indix)=xx surface%y(indix)=yy indix=indix+1 end if end do end do ! throwing remaining points at random do while (indix.le.surface%nsurface) xx=ran(seed) yy=ran(seed) if ((xx<sp02-10*eps .or. xx>sp03+10*eps .or. yy<sp04-10*eps .or. yy>sp05+10*eps) .or. & (xx>sp02+10*eps .and. xx<sp03-10*eps .and. yy>sp04+10*eps .and. yy<sp05-10*eps)) then surface%x(indix)=xx surface%y(indix)=yy indix=indix+1 end if end do else ! regular grid of points indix=1 do j=1,2**levelt+1 do i=1,2**levelt+1 surface%x(indix)=float(i-1)*delta surface%y(indix)=float(j-1)*delta indix=indix+1 end do end do end if case (3,4) if (surface%rand) then ! convex hull indix=1 do i=1,2**levelt surface%x(indix)=(i-1)*delta surface%y(indix)=0.d0 indix=indix+1 end do do i=1,2**levelt surface%x(indix)=1.d0 surface%y(indix)=(i-1)*delta indix=indix+1 end do do i=1,2**levelt surface%x(indix)=1.d0-(i-1)*delta surface%y(indix)=1.d0 indix=indix+1 end do do i=1,2**levelt surface%x(indix)=0.d0 surface%y(indix)=1.d0-(i-1)*delta indix=indix+1 end do nhull=indix-1 if (iproc.eq.0) write(8,*) 'nhull=',nhull,'on surface ',is ! placing rows of nhull points outside, in, and inside the circle delta_angle=2.d0*pi/nhull delta_radius=0.0025d0*sp04 do icircles=-4,2 do i=0,nhull-1 angle=i*delta_angle surface%x(indix)=sp02+(sp04+icircles*delta_radius)*cos(angle) surface%y(indix)=sp03+(sp04+icircles*delta_radius)*sin(angle) indix=indix+1 end do end do ! throwing the rest of the points at random provided they are not ! too close to the concentric circles so that it does not disturb ! the regular triangulation do while (indix.le.surface%nsurface) xx=ran(seed) yy=ran(seed) dist=sqrt((xx-sp02)**2+(yy-sp03)**2) if (dist>(sp04+10*delta_radius) .or. dist<(sp04-10*delta_radius)) then surface%x(indix)=xx surface%y(indix)=yy indix=indix+1 end if end do else ! regular grid of points indix=1 do j=1,2**levelt+1 do i=1,2**levelt+1 surface%x(indix)=float(i-1)*delta surface%y(indix)=float(j-1)*delta indix=indix+1 end do end do end if case default call stop_run ('surface type not defined$') end select !-------------------------------------------| !-----building icon array-------------------| !-------------------------------------------| ! we use the NN library to compute the triangulation ! of points for the surface ntmax=surface%nsurface*3 nhmax=surface%nsurface npmax=surface%nsurface nnpnmax=100 nmax=3*ntmax+npmax nvmax=ntmax allocate (points(2,surface%nsurface),stat=err) ; if (err.ne.0) call stop_run ('Error alloc points in create_surface$') allocate (field(surface%nsurface),stat=err) ; if (err.ne.0) call stop_run ('Error alloc field in create_surface$') allocate (vertices(3,ntmax),stat=err) ; if (err.ne.0) call stop_run ('Error alloc vertices in create_surface$') allocate (centres(3,ntmax),stat=err) ; if (err.ne.0) call stop_run ('Error alloc centress in create_surface$') allocate (neighbour(3,ntmax),stat=err) ; if (err.ne.0) call stop_run ('Error alloc neighbour in create_surface$') allocate (hulltriangles(nhmax),stat=err) ; if (err.ne.0) call stop_run ('Error alloc hulltriangles in create_surface$') allocate (vis_tlist(nvmax),stat=err) ; if (err.ne.0) call stop_run ('Error alloc vis_tlist in create_surface$') allocate (vis_elist(nvmax),stat=err) ; if (err.ne.0) call stop_run ('Error alloc vis_elist in create_surface$') allocate (add_tlist(nvmax),stat=err) ; if (err.ne.0) call stop_run ('Error alloc add_tlist in icreate_surface$') allocate (lt_work(ntmax),stat=err) ; if (err.ne.0) call stop_run ('Error alloc lt_work in create_surface$') allocate (ln_work(surface%nsurface),stat=err) ; if (err.ne.0) call stop_run ('Error alloc ln_work in create_surface$') points(1,:)=surface%x points(2,:)=surface%y dmode=-2 nmode=0 loc=1 nohalt_hull=0 clockwise=.true. eps=1.d-8 call nn2d_setup (surface%nsurface,ntmax,nhmax,npmax,nnpnmax,nmax, & points,dmode,nmode,clockwise,field,nt,vertices, & centres,neighbour,nh,hulltriangles,nohalt_hull, & loc,nnn,nnlist,ntrilist, & eps,nvmax,vis_tlist,vis_elist,add_tlist, & lt_work,ln_work) if (iproc.eq.0) write (8,*) 'surface ',is,' has ',nt,' triangles' surface%icon(1:3,1:surface%nt)=vertices(1:3,1:nt) deallocate (points) deallocate (field) deallocate (vertices) deallocate (centres) deallocate (neighbour) deallocate (hulltriangles) deallocate (vis_tlist) deallocate (vis_elist) deallocate (add_tlist) deallocate (lt_work) deallocate (ln_work) !----------------------------------------------| !----computing z coordinate--------------------| !----------------------------------------------| call zpoints (surface%nsurface,surface%x,surface%y,surface%z,surface_type, & sp01,sp02,sp03,sp04,sp05,sp06,sp07,sp08,sp09,sp10,sp11,sp12, & sp13,sp14,sp15) !----------------------------------------------| !----computing the normals---------------------| !----------------------------------------------| call compute_normals (surface%nsurface,surface%x,surface%y,surface%z, & surface%nt,surface%icon,surface%xn,surface%yn,surface%zn) if (debug>=2) call output_surf (surface,is,'init',-1,-1) end if end subroutine create_surf !------------------------------------------------------------------------------| !------------------------------------------------------------------------------| subroutine zpoints (ns,x,y,z,surface_type,sp01,sp02,sp03,sp04,sp05,sp06,sp07, & sp08,sp09,sp10,sp11,sp12,sp13,sp14,sp15) !------------------------------------------------------------------------------| !(((((((((((((((( Purpose of the routine )))))))))))))))))))))))))))))))))))))) !------------------------------------------------------------------------------| ! knowing the two-dimensional spatial distribution of points on the plane (x,y) ! this routine computes the z-coordinate accordingly to the surface type. ! ns is the number of points ! x,y,z are the coordinates of the points ! surface_type is the type of surface under consideration ! sp01..sp15 are the surface parameters (not all are necessarily used) !------------------------------------------------------------------------------| !(((((((((((((((( declaration of the subroutine arguments )))))))))))))))))))) !------------------------------------------------------------------------------| use constants implicit none integer ns double precision x(ns),y(ns),z(ns) integer surface_type double precision sp01,sp02,sp03,sp04,sp05,sp06,sp07,sp08,sp09,sp10,sp11,sp12 double precision sp13,sp14,sp15 !------------------------------------------------------------------------------| !(((((((((((((((( declaration of the subroutine internal variables ))))))))))))) !------------------------------------------------------------------------------| integer :: i,iproc double precision :: dist,ran,m,x1a,x1b,x2a,x2b,y1a,y1b,y2a,y2b,zx,xsym double precision :: psi,theta1,theta2,theta1s,theta2s,psis,y0s,y1s,y2s,x0,y0w double precision :: y0a,y0b,y0,y1,y2,a1,b1,bb1,c1,m1,a2,b2,bb2,c2,m2,a3,b3,bb3 double precision :: c3,m3,a4,b4,bb4,c4,m4,eps,psi2,psi2s,psi3,psi3s,dz1,dz2,dz3 double precision :: dz4,psi1,psi1s,y0u,y0l,y1u,y1l,y2u,y2l,x0ut double precision :: x0ub,x0lt,x0lb,x1ut,x1ub,x1lt,x1lb,x2ut,x2ub,x2lt,x2lb,y12mt double precision :: y12mb,y2as,y2bs,y2au,y2al,y2bu,y2bl,x2aut,x2aub,x2alt,x2alb double precision :: x2but,x2blt,x2bub,x2blb,y2rad !------------------------------------------------------------------------------| !------------------------------------------------------------------------------| eps=1.d-10 iproc=0 select case(surface_type) case (1) ! a flat surface, ! sp01 is the z level z=sp01 case (2) ! rectangular emboss, ! sp01 is the z level ! sp02 and 03 are x1,x2 ! sp04 and 05 are y1,y2 ! sp06 is the thickness do i=1,ns if ((x(i)-sp02)*(x(i)-sp03).le.0.d0 .and. (y(i)-sp04)*(y(i)-sp05).le.0.d0) then z(i)=sp01-sp06 else z(i)=sp01 end if end do case (3) ! convex spherical emboss, ! sp01 is the z level ! sp02 and 03 are x0,y0 ! sp04 is the radius do i=1,ns dist=sqrt((x(i)-sp02)**2+(y(i)-sp03)**2) if (dist.le.sp04) then z(i)=sp01+sp04*sin(acos(dist/sp04)) else z(i)=sp01 endif end do case (4) ! convex spherical emboss, ! sp01 is the z level ! sp02 and 03 are x0,y0 ! sp04 is the radius do i=1,ns dist=sqrt((x(i)-sp02)**2+(y(i)-sp03)**2) if (dist.le.sp04) then z(i)=sp01-sp04*sin(acos(dist/sp04)) else z(i)=sp01 endif end do case (5) ! double rectangular emboss, ! sp01 is the z level ! sp02 and 03 are x1,x2 ! sp04 and 05 are x3,x4 ! sp06 and 07 are y1,y2 ! sp08 and 09 are y3,y4 ! sp10 is the thickness z=sp01 do i=1,ns if ((x(i)-sp02)*(x(i)-sp03).le.0.d0 .and. (y(i)-sp06)*(y(i)-sp07).le.0.d0) then z(i)=z(i)-sp10 endif if ((x(i)-sp04)*(x(i)-sp05).le.0.d0 .and. (y(i)-sp08)*(y(i)-sp09).le.0.d0) then z(i)=z(i)-sp10 endif end do case (6) ! a sinus, ! sp01 is the z level ! sp02 is the wavelength ! sp03 is the amplitude ! sp04 is the phase do i=1,ns z(i)=sp01+sp03*sin(2.d0*pi*(x(i)/sp02+sp04)) end do case (7) ! a noisy surface, ! sp01 is the z level ! sp02 is the noise amplitude do i=1,ns call random_number (ran) z(i)=sp01+ran*sp02 end do case (8) ! a double sinus. ! sp01 is the z level ! sp02 is the x-wavelength ! sp03 is the x-amplitude ! sp04 is the y-wavelength ! sp05 is the y-amplitude do i=1,ns z(i)=sp01+sp03*sin(x(i)*2.*pi/sp02)+sp05*sin(y(i)*2.*pi/sp04) end do case (9) ! a cosinus, ! sp01 is the z level ! sp02 is the wavelength ! sp03 is the amplitude ! sp04 is the phase do i=1,ns z(i)=sp01+sp03*cos(2.d0*pi*(x(i)/sp02+sp04)) end do case (10) ! a 2D embankment ! sp01 is z0 ! sp02 is y0 ! sp03 is psi ! sp04 is the thickness do i=1,ns if (y(i)<sp02) then z(i)=sp01 else z(i)=sp01+min((y(i)-sp02)*tan(sp03*pi/180.d0),sp04) end if end do case (11) ! a 2D hill ! sp01 is z level ! sp02 height ! sp03 is y0 ! sp04 is width do i=1,ns if (y(i)>sp03-sp04/2.d0 .and. y(i)<sp03+sp04/2.d0) then z(i)=sp01+sp02*(sin(pi*((y(i)-sp03)/sp04+0.5d0)))**2 else z(i)=sp01 end if end do case (12) ! rectangular emboss with specified slope ! sp01 is the z level ! sp02 and 03 are x1,x2 ! sp04 and 05 are y1,y2 ! sp06 is the thickness ! sp07 is the slope m=tan(sp07*pi/180.d0) x1a=sp02+(sp06/(2.d0*m)) x1b=sp02-(sp06/(2.d0*m)) x2a=sp03+(sp06/(2.d0*m)) x2b=sp03-(sp06/(2.d0*m)) y1a=sp04+(sp06/(2.d0*m)) y1b=sp04-(sp06/(2.d0*m)) y2a=sp05+(sp06/(2.d0*m)) y2b=sp05-(sp06/(2.d0*m)) do i=1,ns if (x(i).le.x1a) then zx=sp01 elseif (x(i).le.x1b) then zx=sp01-(((x(i)-x1a)/(-sp06/m))*sp06) elseif (x(i).le.x2a) then zx=sp01-sp06 elseif (x(i).le.x2b) then zx=sp01-((1.d0-((x(i)-x2a)/(-sp06/m)))*sp06) !zx=sp01-((1.d0-((x(i)-x2a)/(sp06/m)))*sp06) else zx=sp01 endif if (y(i).le.y1a) then z(i)=sp01 elseif (y(i).le.y1b) then z(i)=min(sp01-(((y(i)-y1a)/(-sp06/m))*sp06),zx) elseif (y(i).le.y2a) then z(i)=min(sp01-sp06,zx) elseif (y(i).le.y2b) then z(i)=min(sp01-((1.d0-((y(i)-y2a)/(-sp06/m)))*sp06),zx) else z(i)=sp01 endif end do case (13) ! a 3D embankment of finite length and with 2 kinks ! sp01 is the z level ! sp02 is the z level 2 ! sp03 is slope angle (psi) ! sp04 is x value for the center of the slope (x0) ! sp05 is the x width of the narrow end of the plateau (y0w) ! sp06 is the y position for the start of the slope (y0) ! sp07 is the y position of the first kink (y1) ! sp08 is the angle of the first kink (theta1) ! sp09 is the y position of the second kink (y2) ! sp10 is the angle of the second kink (theta2) ! sp11 is the reference elevation (elevation of the lower outer dip change) ! sp12 is the dip angle of the lower outer dip panel ! sp13 is the reference elevation (elevation of the upper outer flat) ! sp14 is the dip angle of the upper outer dip panel dz1=sp02-sp01 !dz2=sp01-sp11 dz2=sp01-sp11 dz3=sp01-sp13 dz4=dz3-dz2 psi=sp03*pi/180.d0 !psi2=sp12*pi/180.d0 psi2=sp12*pi/180.d0 psi3=sp14*pi/180.d0 theta1=sp08*pi/180.d0 theta2=sp10*pi/180.d0 psis=sign(tan(psi),dz1) psi2s=sign(tan(psi2),dz2) psi3s=sign(tan(psi3),dz3) theta1s=tan(theta1) theta2s=tan(theta2) y0s=1.d0 y1s=tan(theta1/2.d0) y2s=tan((theta1+theta2)/2.d0) x0=sp04 y0w=sp05+dz1/(2.d0*psis) y0=sp06+dz1/(2.d0*psis) y0a=y0+dz1/(2.d0*psis) y0b=y0-dz1/(2.d0*psis) y1=sp07+(dz1/(2.d0*psis))*y1s y2=sp09+(dz1/(2.d0*psis))*y2s m1=((y2+(dz1/(2.d0*psis))*y1s)-(y1+(dz1/(2.d0*psis))*y1s))/& ((x0-y0w-(y1-y2)*theta1s-(dz1/(2.d0*psis)))-(x0-y0w-(dz1/(2.d0*psis)))) bb1=(y1+(dz1/(2.d0*psis))*y1s)-m1*(x0-y0w-(dz1/(2.d0*psis))) a1=-m1 b1=1 c1=-bb1 m2=((y2-(dz1/(2.d0*psis))*y1s)-(y1-(dz1/(2.d0*psis))*y1s))/& ((x0-y0w-(y1-y2)*theta1s+(dz1/(2.d0*psis)))-(x0-y0w+(dz1/(2.d0*psis)))) bb2=(y1-(dz1/(2.d0*psis))*y1s)-m1*(x0-y0w+(dz1/(2.d0*psis))) a2=-m2 b2=1 c2=-bb2 m3=((y2-(dz1/(2.d0*psis))*y1s)-(y1-(dz1/(2.d0*psis))*y1s))/& ((x0+y0w+(y1-y2)*theta1s-(dz1/(2.d0*psis)))-(x0+y0w-(dz1/(2.d0*psis)))) bb3=(y1-(dz1/(2.d0*psis))*y1s)-m3*(x0+y0w-(dz1/(2.d0*psis))) a3=-m3 b3=1 c3=-bb3 m4=((y2+(dz1/(2.d0*psis))*y1s)-(y1+(dz1/(2.d0*psis))*y1s))/& ((x0+y0w+(y1-y2)*theta1s+(dz1/(2.d0*psis)))-(x0+y0w+(dz1/(2.d0*psis)))) bb4=(y1+(dz1/(2.d0*psis))*y1s)-m3*(x0+y0w+(dz1/(2.d0*psis))) a4=-m4 b4=1 c4=-bb4 do i=1,ns z(i)=sp01 if (y(i).ge.-y0s*x(i)+(y0+(x0-y0w)) .and. y(i).ge.y0s*x(i)+(y0-(x0+y0w))) then if (y(i).ge.y0a) then if (y(i).ge.y0a+(dz2/psi2s)) then if (abs(dz4).gt.eps) then if (dz4.gt.eps) then z(i)=max(sp01-dz2-psi3s*(y(i)-(y0a+(dz2/psi2s))),sp13) else z(i)=min(sp01-dz2-psi3s*(y(i)-(y0a+(dz2/psi2s))),sp13) endif else z(i)=sp13 endif else z(i)=sp01-psi2s*(y(i)-y0a) endif ! if (dz2.gt.eps) then ! z(i)=max(sp01-psi2s*(y(i)-y0a),sp11) ! else ! z(i)=min(sp01-psi2s*(y(i)-y0a),sp11) ! endif elseif (y(i).ge.y0b) then z(i)=sp01+psis*(y0a-y(i)) elseif (y(i).lt.y0b) then z(i)=sp02 endif elseif (y(i).ge.-y1s*x(i)+(y1s*(x0-y0w)+y1) .and. y(i).ge.y1s*x(i)+(-y1s*(x0+y0w)+y1)) then if (x(i).lt.((x0-y0w)-(dz1/(2.d0*psis)))) then if (x(i).lt.((x0-y0w)-(dz1/(2.d0*psis)))-(dz2/psi2s)) then if (abs(dz4).gt.eps) then if (dz4.gt.eps) then z(i)=max(sp01-dz2-psi3s*(((x0-y0w)-(dz2/psi2s))-x(i)),sp13) else z(i)=min(sp01-dz2-psi3s*(((x0-y0w)-(dz2/psi2s))-x(i)),sp13) endif else z(i)=sp13 endif else z(i)=sp01-psi2s*(((x0-y0w)-(dz1/(2.d0*psis)))-x(i)) endif ! if ((dz2).gt.eps) then ! z(i)=max(sp01-psi2s*(((x0-y0w)-(dz1/(2.d0*psis)))-x(i)),sp11) ! else ! z(i)=min(sp01-psi2s*(((x0-y0w)-(dz1/(2.d0*psis)))-x(i)),sp11) ! endif elseif (x(i).ge.((x0-y0w)-(dz1/(2.d0*psis))) .and. x(i).lt.((x0-y0w)+(dz1/(2.d0*psis)))) then z(i)=sp01+psis*(x(i)-((x0-y0w)-(dz1/(2.d0*psis)))) elseif (x(i).ge.((x0-y0w)+(dz1/(2.d0*psis))) .and. x(i).lt.((x0+y0w)-(dz1/(2.d0*psis)))) then z(i)=sp02 elseif (x(i).ge.((x0+y0w)-(dz1/(2.d0*psis))) .and. x(i).lt.((x0+y0w)+(dz1/(2.d0*psis)))) then z(i)=sp01-psis*(x(i)-((x0+y0w)+(dz1/(2.d0*psis)))) else if (x(i).lt.((x0+y0w)+(dz1/(2.d0*psis)))+(dz2/psi2s)) then z(i)=sp01-psi2s*(x(i)-((x0+y0w)+(dz1/(2.d0*psis)))) else if (abs(dz4).gt.eps) then if (dz4.gt.eps) then z(i)=max(sp01-dz2-psi3s*(x(i)-((x0+y0w)+(dz2/psi2s))),sp13) else z(i)=min(sp01-dz2-psi3s*(x(i)-((x0+y0w)+(dz2/psi2s))),sp13) endif else z(i)=sp13 endif endif ! if ((dz2).gt.eps) then ! z(i)=max(sp01-psi2s*(x(i)-((x0+y0w)+(dz1/(2.d0*psis)))),sp11) ! else ! z(i)=min(sp01-psi2s*(x(i)-((x0+y0w)+(dz1/(2.d0*psis)))),sp11) ! endif endif elseif (y(i).ge.-y2s*x(i)+(y2s*(x0-y0w-(y1-y2)*theta1s)+y2) .and. y(i).ge.y2s*x(i)+(-y2s*(x0+y0w+(y1-y2)*theta1s)+y2)) then if (y(i).ge.m1*x(i)+bb1) then dist=abs(a1*x(i)+b1*y(i)+c1)/sqrt(a1**2.d0+b1**2.d0) if (dist.lt.(dz2/psi2s)) then z(i)=sp01-psi2s*dist else if (abs(dz4).gt.eps) then if (dz4.gt.eps) then z(i)=max(sp01-dz2-psi3s*(dist-(dz2/psi2s)),sp13) else z(i)=min(sp01-dz2-psi3s*(dist-(dz2/psi2s)),sp13) endif else z(i)=sp13 endif endif ! if ((dz2).gt.eps) then ! z(i)=max(sp01-psi2s*dist,sp11) ! else ! z(i)=min(sp01-psi2s*dist,sp11) ! endif elseif (y(i).ge.m2*x(i)+bb2 .and. y(i).lt.m1*x(i)+bb1) then dist=abs(a1*x(i)+b1*y(i)+c1)/sqrt(a1**2.d0+b1**2.d0) z(i)=sp01+dist*psis elseif (y(i).lt.m2*x(i)+bb2 .and. y(i).lt.m3*x(i)+bb3) then z(i)=sp02 elseif (y(i).ge.m3*x(i)+bb3 .and. y(i).lt.m4*x(i)+bb4) then dist=abs(a4*x(i)+b4*y(i)+c4)/sqrt(a4**2.d0+b4**2.d0) z(i)=sp01+dist*psis else dist=abs(a4*x(i)+b4*y(i)+c4)/sqrt(a4**2.d0+b4**2.d0) if (dist.lt.(dz2/psi2s)) then z(i)=sp01-psi2s*dist else if (abs(dz4).gt.eps) then if (dz4.gt.eps) then z(i)=max(sp01-dz2-psi3s*(dist-(dz2/psi2s)),sp13) else z(i)=min(sp01-dz2-psi3s*(dist-(dz2/psi2s)),sp13) endif else z(i)=sp13 endif endif ! if ((dz2).gt.eps) then ! z(i)=max(sp01-psi2s*dist,sp11) ! else ! z(i)=min(sp01-psi2s*dist,sp11) ! endif endif elseif (x(i).lt.x0-y0w-(y1-y2)*theta1s-dz1/(2.d0*psis)) then if (x(i).lt.x0-y0w-(y1-y2)*theta1s-dz1/(2.d0*psis)-(dz2/psi2s)) then if (abs(dz4).gt.eps) then if (dz4.gt.eps) then z(i)=max(sp01-dz2-psi3s*(((x0-y0w)-(y1-y2)*theta1s-(dz2/psi2s))-x(i)),sp13) !z(i)=sp13 else z(i)=min(sp01-dz2-psi3s*(((x0-y0w)-(y1-y2)*theta1s-(dz2/psi2s))-x(i)),sp13) !z(i)=sp13 endif else z(i)=sp13 endif else z(i)=sp01-psi2s*((x0-y0w-(y1-y2)*theta1s-dz1/(2.d0*psis))-x(i)) !z(i)=sp13 endif ! if ((dz2).gt.eps) then ! z(i)=max(sp01-psi2s*((x0-y0w-(y1-y2)*theta1s-dz1/(2.d0*psis))-x(i)),sp11) ! else ! z(i)=min(sp01-psi2s*((x0-y0w-(y1-y2)*theta1s-dz1/(2.d0*psis))-x(i)),sp11) ! endif elseif (x(i).ge.((x0-y0w-(y1-y2)*theta1s)-(dz1/(2.d0*psis))) .and. x(i).lt.((x0-y0w-(y1-y2)*theta1s)+(dz1/(2.d0*psis)))) then z(i)=sp01+psis*(x(i)-((x0-y0w-(y1-y2)*theta1s)-(dz1/(2.d0*psis)))) elseif (x(i).ge.((x0-y0w-(y1-y2)*theta1s)+(abs(dz1)/(2.d0*psis))) .and. x(i).lt.((x0+y0w+(y1-y2)*theta1s)-(abs(dz1)/(2.d0*psis)))) then z(i)=sp02 elseif (x(i).ge.((x0+y0w+(y1-y2)*theta1s)-(abs(dz1)/(2.d0*psis))) .and. x(i).lt.((x0+y0w+(y1-y2)*theta1s)+(abs(dz1)/(2.d0*psis)))) then z(i)=sp01-psis*(x(i)-((x0+y0w+(y1-y2)*theta1s)+(dz1/(2.d0*psis)))) else if (x(i).gt.x0+y0w+(y1-y2)*theta1s-dz1/(2.d0*psis)+(dz2/psi2s)) then if (abs(dz4).gt.eps) then if (dz4.gt.eps) then z(i)=max(sp01-dz2-psi3s*(x(i)-(x0+y0w+(y1-y2)*theta1s+(dz2/psi2s))),sp13) else z(i)=min(sp01-dz2-psi3s*(x(i)-(x0+y0w+(y1-y2)*theta1s+(dz2/psi2s))),sp13) endif else z(i)=sp13 endif else !z(i)=sp01-psi2s*(x(i)-(x0-y0w-(y1-y2)*theta1s-dz1/(2.d0*psis))) z(i)=sp01-psi2s*(x(i)-(x0+y0w+(y1-y2)*theta1s+dz1/(2.d0*psis))) endif ! if ((dz2).gt.eps) then ! z(i)=max(sp01-psi2s*(x(i)-(x0-y0w-(y1-y2)*theta1s-dz1/(2.d0*psis))),sp11) ! else ! z(i)=min(sp01-psi2s*(x(i)-(x0-y0w-(y1-y2)*theta1s-dz1/(2.d0*psis))),sp11) ! endif endif enddo case (14) ! a 3D embankment of finite length and with rounded 2 kinks ! sp01 is the z level ! sp02 is the z level 2 ! sp03 is slope angle (psi) ! sp04 is x value for the center of the slope (xsym) ! sp05 is the x width of the narrow end of the plateau (y0w) ! sp06 is the y position for the start of the slope (y0) ! sp07 is the y position of the first kink (y1) ! sp08 is the angle of the first kink (theta1) ! sp09 is the y position of the second kink (y2) ! sp10 is the angle of the second kink (theta2) ! sp11 is the reference elevation (elevation of the lower outer dip change) ! sp12 is the dip angle of the lower outer dip panel ! sp13 is the reference elevation (elevation of the upper outer flat) ! sp14 is the dip angle of the upper outer dip panel ! sp15 is the radius used for rounding the second kink dz1=sp02-sp01 dz2=sp01-sp11 dz3=sp01-sp13 dz4=dz3-dz2 psi1=sp03*pi/180.d0 psi2=sp12*pi/180.d0 psi3=sp14*pi/180.d0 theta1=sp08*pi/180.d0 theta2=sp10*pi/180.d0 y2rad=sp15 psi1s=sign(tan(psi1),dz1) psi2s=sign(tan(psi2),dz2) psi3s=sign(tan(psi3),dz3) theta1s=tan(theta1) theta2s=tan(theta2) y0s=1.d0 y1s=tan(theta1/2.d0) y2s=tan((theta1+theta2)/2.d0) xsym=sp04 y0w=sp05 y0=sp06 y1=sp07 y2=sp09 y0u=y0 y0l=y0+dz1/psi1s y1u=y1 y1l=y1+(dz1/psi1s)*y1s y2u=y2 y2l=y2+(dz1/psi1s)*y2s ! if (iproc == 0) write (*,*) 'y0u: ',y0u ! if (iproc == 0) write (*,*) 'y0l: ',y0l ! if (iproc == 0) write (*,*) 'y1u: ',y1u ! if (iproc == 0) write (*,*) 'y1l: ',y1l ! if (iproc == 0) write (*,*) 'y2u: ',y2u ! if (iproc == 0) write (*,*) 'y2l: ',y2l ! if (iproc == 0) write (*,*) 'y2rad: ',y2rad x0ut=xsym+y0w x0lt=xsym+y0w+dz1/psi1s x0ub=xsym-y0w x0lb=xsym-y0w-dz1/psi1s x1ut=x0ut x1lt=x0lt x1ub=x0ub x1lb=x0lb x2ut=x1ut+(y1-y2)*theta1s x2lt=x1lt+(y1-y2)*theta1s x2ub=x1ub-(y1-y2)*theta1s x2lb=x1lb-(y1-y2)*theta1s ! if (iproc == 0) write (*,*) 'x0ut: ',x0ut ! if (iproc == 0) write (*,*) 'x0lt: ',x0lt ! if (iproc == 0) write (*,*) 'x0ub: ',x0ub ! if (iproc == 0) write (*,*) 'x0lb: ',x0lb ! if (iproc == 0) write (*,*) 'x1ut: ',x1ut ! if (iproc == 0) write (*,*) 'x1lt: ',x1lt ! if (iproc == 0) write (*,*) 'x1ub: ',x1ub ! if (iproc == 0) write (*,*) 'x1lb: ',x1lb ! if (iproc == 0) write (*,*) 'x2ut: ',x2ut ! if (iproc == 0) write (*,*) 'x2lt: ',x2lt ! if (iproc == 0) write (*,*) 'x2ub: ',x2ub ! if (iproc == 0) write (*,*) 'x2lb: ',x2lb y12mt=(y2u-y1u)/(x2ut-x1ut) y12mb=(y2u-y1u)/(x2ub-x1ub) ! if (iproc == 0) write (*,*) 'y12mt: ',y12mt ! if (iproc == 0) write (*,*) 'y12mb: ',y12mb if (abs(theta1).gt.eps) then y2as=tan(pi/2.d0-theta1) else y2as=1.d0 endif if (abs(theta2).gt.eps) then y2bs=tan(pi/2.d0-theta2) else y2bs=1.d0 endif ! if (iproc == 0) write (*,*) 'y2as: ',y2as ! if (iproc == 0) write (*,*) 'y2bs: ',y2bs y2au=y2u+(y2rad*tan((theta1-theta2)/2.d0))*cos(theta1) if (abs(theta1).gt.eps) then y2al=y2u+(dz1/psi1s*y2as)+(y2rad*tan((theta1-theta2)/2.d0))*cos(theta1) else y2al=y2au endif y2bu=y2u-y2rad*tan((theta1-theta2)/2.d0) ! if (abs(theta2).gt.eps) then ! y2bl=y2u-(dz1/psi1s*y2as)-(y2rad*tan((theta1-theta2)/2.d0)) ! else y2bl=y2bu ! endif ! SHOULD THE y12mb's BELOW BE sin(theta1)'s INSTEAD????????? x2aut=x2ut-(y2rad*tan((theta1-theta2)/2.d0))*y12mb if (abs(theta1).gt.eps) then x2alt=x2ut+(dz1/psi1s*(1.d0/y2as))-(y2rad*tan((theta1-theta2)/2.d0))*y12mb else x2alt=x2ut+dz1/psi1s-(y2rad*tan((theta1-theta2)/2.d0))*y12mb endif x2but=x2ut x2blt=x2lt x2aub=x2ub+(y2rad*tan((theta1-theta2)/2.d0))*y12mb if (abs(theta2).gt.eps) then x2alb=x2ub-(dz1/psi1s*(1.d0/y2as))+(y2rad*tan((theta1-theta2)/2.d0))*y12mb else x2alb=x2ub-dz1/psi1s+(y2rad*tan((theta1-theta2)/2.d0))*y12mb endif x2bub=x2ub x2blb=x2lb ! if (iproc == 0) write (*,*) 'y2au: ',y2au ! if (iproc == 0) write (*,*) 'y2al: ',y2al ! if (iproc == 0) write (*,*) 'y2bu: ',y2bu ! if (iproc == 0) write (*,*) 'y2bl: ',y2bl ! if (iproc == 0) write (*,*) 'x2aut: ',x2aut ! if (iproc == 0) write (*,*) 'x2alt: ',x2alt ! if (iproc == 0) write (*,*) 'x2but: ',x2but ! if (iproc == 0) write (*,*) 'x2blt: ',x2blt ! if (iproc == 0) write (*,*) 'x2aub: ',x2aub ! if (iproc == 0) write (*,*) 'x2alb: ',x2alb ! if (iproc == 0) write (*,*) 'x2bub: ',x2bub ! if (iproc == 0) write (*,*) 'x2blb: ',x2blb m1=(y2l-y1l)/(x2lb-x1lb) !bb1=(y1l+(dz1/psi1s)*y1s)-m1*(x1lb-(dz1/psi1s)) bb1=y1l-m1*x1lb a1=-m1 b1=1 c1=-bb1 m2=(y2u-y1u)/(x2ub-x1ub) bb2=y1u-m2*x1ub a2=-m2 b2=1 c2=-bb2 m3=(y2u-y1u)/(x2ut-x1ut) bb3=y1u-m3*x1ut a3=-m3 b3=1 c3=-bb3 m4=(y2l-y1l)/(x2lt-x1lt) bb4=(y1l+(dz1/psi1s)*y1s)-m4*(x1lt+dz1/psi1s) a4=-m4 b4=1 c4=-bb4 do i=1,ns z(i)=sp01 if (y(i).ge.-y0s*x(i)+(y0u+x0ub) .and. y(i).ge.y0s*x(i)+(y0u-x0ut)) then if (y(i).ge.y0l) then if (y(i).ge.y0l+(dz2/psi2s)) then if (abs(dz4).gt.eps) then if (dz4.gt.eps) then z(i)=max(sp01-dz2-psi3s*(y(i)-(y0l+(dz2/psi2s))),sp13) else z(i)=min(sp01-dz2-psi3s*(y(i)-(y0l+(dz2/psi2s))),sp13) endif else z(i)=sp13 endif else z(i)=sp01-psi2s*(y(i)-y0l) endif elseif (y(i).ge.y0u) then z(i)=sp01+psi1s*(y0l-y(i)) elseif (y(i).lt.y0u) then z(i)=sp02 endif elseif (y(i).ge.-y1s*x(i)+(y1s*x1ub+y1u) .and. y(i).ge.y1s*x(i)+(-y1s*x1ut+y1u)) then if (x(i).lt.x1lb) then if (x(i).lt.x1lb-dz2/psi2s) then if (abs(dz4).gt.eps) then if (dz4.gt.eps) then z(i)=max(sp01-dz2-psi3s*(x1ub-dz2/psi2s)-x(i),sp13) else z(i)=min(sp01-dz2-psi3s*(x1ub-dz2/psi2s)-x(i),sp13) endif else z(i)=sp13 endif else z(i)=sp01-psi2s*(x1lb-x(i)) endif elseif (x(i).ge.x1lb .and. x(i).lt.x1ub) then z(i)=sp01+psi1s*(x(i)-x1lb) elseif (x(i).ge.x1ub .and. x(i).lt.x1ut) then z(i)=sp02 elseif (x(i).ge.x1ut .and. x(i).lt.x1lt) then z(i)=sp01-psi1s*(x(i)-x1lt) else if (x(i).lt.x1lt+(dz2/psi2s)) then z(i)=sp01-psi2s*(x(i)-x1lt) else if (abs(dz4).gt.eps) then if (dz4.gt.eps) then z(i)=max(sp01-dz2-psi3s*(x(i)-x1lt),sp13) else z(i)=min(sp01-dz2-psi3s*(x(i)-x1lt),sp13) endif else z(i)=sp13 endif endif endif elseif (y(i).ge.-y2as*x(i)+(y2as*x2aub+y2au) .and. y(i).ge.y2as*x(i)+(-y2as*x2aut+y2au)) then ! elseif (y(i).ge.-y2s*x(i)+(y2s*x2ub+y2u) .and. y(i).ge.y2s*x(i)+(-y2s*x2ut+y2u)) then ! z(i)=0.13d0 if (y(i).ge.m1*x(i)+bb1) then dist=abs(a1*x(i)+b1*y(i)+c1)/sqrt(a1**2.d0+b1**2.d0) if (dist.lt.(dz2/psi2s)) then z(i)=sp01-psi2s*dist else if (abs(dz4).gt.eps) then if (dz4.gt.eps) then z(i)=max(sp01-dz2-psi3s*(dist-(dz2/psi2s)),sp13) else z(i)=min(sp01-dz2-psi3s*(dist-(dz2/psi2s)),sp13) endif else z(i)=sp13 endif endif elseif (y(i).ge.m2*x(i)+bb2 .and. y(i).lt.m1*x(i)+bb1) then dist=abs(a1*x(i)+b1*y(i)+c1)/sqrt(a1**2.d0+b1**2.d0) z(i)=sp01+dist*psi1s elseif (y(i).lt.m2*x(i)+bb2 .and. y(i).lt.m3*x(i)+bb3) then z(i)=sp02 elseif (y(i).ge.m3*x(i)+bb3 .and. y(i).lt.m4*x(i)+bb4) then dist=abs(a4*x(i)+b4*y(i)+c4)/sqrt(a4**2.d0+b4**2.d0) z(i)=sp01+dist*psi1s else dist=abs(a4*x(i)+b4*y(i)+c4)/sqrt(a4**2.d0+b4**2.d0) if (dist.lt.(dz2/psi2s)) then z(i)=sp01-psi2s*dist else if (abs(dz4).gt.eps) then if (dz4.gt.eps) then z(i)=max(sp01-dz2-psi3s*(dist-(dz2/psi2s)),sp13) else z(i)=min(sp01-dz2-psi3s*(dist-(dz2/psi2s)),sp13) endif else z(i)=sp13 endif endif endif !elseif (y(i).ge.-y2as*x(i)+(y2as*x2aub+y2au) .and. y(i).ge.y2as*x(i)+(-y2as*x2aut+y2au)) then elseif (y(i).ge.y2bu) then dist=sqrt((x(i)-(x2bub+y2rad))**2.d0+(y(i)-y2bu)**2.d0) if (dist <= y2rad) then z(i)=sp02 elseif (dist <= y2rad+dz1/psi1s) then z(i)=sp01+((y2rad+dz1/psi1s)-dist)*psi1s elseif (dist <= y2rad+dz1/psi1s+dz2/psi2s) then z(i)=sp01-psi2s*(dist-(y2rad+dz1/psi1s)) else if (abs(dz4) > eps) then if (dz4 > eps) then z(i)=max(sp01-dz2-psi3s*((y2rad+dz1/psi1s+dz2/psi2s+dz3/psi3s)-dist),sp13) else z(i)=min(sp01-dz2-psi3s*((y2rad+dz1/psi1s+dz2/psi2s+dz3/psi3s)-dist),sp13) endif else z(i)=sp13 endif endif elseif (x(i) < x2lb) then if (x(i) < x2lb-(dz2/psi2s)) then if (abs(dz4).gt.eps) then if (dz4.gt.eps) then z(i)=max(sp01-dz2-psi3s*(x2lb-(dz2/psi2s)-x(i)),sp13) else z(i)=min(sp01-dz2-psi3s*(x2lb-(dz2/psi2s)-x(i)),sp13) endif else z(i)=sp13 endif else z(i)=sp01-psi2s*(x2lb-x(i)) endif elseif (x(i).ge.x2lb .and. x(i).lt.x2ub) then z(i)=sp01+psi1s*(x(i)-x2lb) elseif (x(i).ge.x2ub .and. x(i).lt.x2ut) then z(i)=sp02 elseif (x(i).ge.x2ut .and. x(i).lt.x2lt) then z(i)=sp01+psi1s*(x2lb-x(i)) else if (x(i) > x2ut+(dz2/psi2s)) then if (abs(dz4).gt.eps) then if (dz4.gt.eps) then z(i)=max(sp01-dz2-psi3s*(x(i)-(x2ut+(dz2/psi2s))),sp13) else z(i)=min(sp01-dz2-psi3s*(x(i)-(x2ut+(dz2/psi2s))),sp13) endif else z(i)=sp13 endif else z(i)=sp01-psi2s*(x(i)-x2lt) endif endif enddo case (15) ! sp01 is the z base level (z0) ! sp02 is the x position of the peak (x0) ! sp03 is the y position of the peak (y0) ! sp04 is the elevation of the peak above base level (h) ! sp05 is the x radius (distance from peak to base) (rx) ! sp06 is the y width (distance from base to base) (ry) ! negative values create a cylinder of length -ry ! sp07 is the angle of slope in x-direction at the base in degree (phi) ! note that for ry<rx the slope at the base will be steeper in y direction ! also ensure that rx > h/tan(phi) ! phi<0 creates a dome unscaled in z-direction (doesn't force angle) ! sp08 is a radial offset from the specified surface (for spherical shells) !spherical shells need sphere radius to calculate adjusted values for h, rx and ry !do loop again with new values !checking validity of input values a1=sp04/tan(sp07*pi/180.d0) if (sp05<=2.d0*a1) then if (iproc.eq.0) then write(*,*) 'WARNING: overconstrained surface values, ignoring set angle phi' endif sp07=-1.d0 endif if (sp07>0.d0) then !Radius of spere unscaled in z direction b1=sp05*(sp05-a1)/sqrt(sp05*(sp05-2.d0*a1)) !scaling factor for z-direction c1 = sp04/(b1-sqrt(b1**2-sp05**2)) else !Radius of unscaled sphere cutting through (x0,z0+h) and (x0+xr,z0) b1=(sp04**2+sp05**2)/(2.d0*sp04) c1=1.d0 endif !z-value of sphere center zx=sp01+sp04-b1*c1; !adjust radius for shell offset b1 = b1 + sp08/c1 do i=1,ns if (sp06>0.d0) then !distance from center + squeezing in y-direction dist=sqrt((x(i)-sp02)**2+((y(i)-sp03)*2.d0*sp05/sp06)**2) z(i)=max(sp01,zx+c1*sqrt(b1**2-dist**2)) else !distance from center in x-direction dist=abs((x(i)-sp02)) if (dist>sp05 .or. abs(y(i)-sp03)>(-0.53d0*sp06)) then !outside rotating cylinder z(i)=sp01 elseif (abs(y(i)-sp03)<(-0.5d0*sp06)) then !inside rotating cylinder z(i)=zx+c1*sqrt(b1**2-dist**2) else !transition zone (3% of wy on both sides) z(i)= sp01-(abs(y(i)-sp03)+0.53e0*sp06)/(-0.03e0*sp06)*(zx+c1*sqrt(b1**2-dist**2)-sp01) endif endif enddo case default call stop_run ('surface type not defined$') end select return end