Skip to content
Snippets Groups Projects
define_bc_rot_sub_init.f90 12.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • !------------------------------------------------------------------------------|
    !------------------------------------------------------------------------------|
    !                                                                              |
    !              ||===\\                                                         | 
    !              ||    \\                                                        |
    !              ||     ||   //==\\   ||  ||   //==||  ||/==\\                   |
    !              ||     ||  ||    ||  ||  ||  ||   ||  ||    ||                  |
    !              ||    //   ||    ||  ||  ||  ||   ||  ||                        |
    !              ||===//     \\==//    \\==\\  \\==\\  ||                        |
    !                                                                              |
    !------------------------------------------------------------------------------|
    !------------------------------------------------------------------------------|
    !                                                                              |
    !              DEFINE_BC_SEGMENTED_S_LINE   Feb. 2009                          |
    !                                                                              |
    !------------------------------------------------------------------------------|
    !------------------------------------------------------------------------------|
    
    subroutine define_bc_rot_sub_init(params,osolve,vo,bcdef,nest)
    
    !------------------------------------------------------------------------------|
    !((((((((((((((((  Purpose of the routine  )))))))))))))))))))))))))))))))))))))
    !------------------------------------------------------------------------------|
    ! This routine assigns the velocity boundary conditions for the rotational     |
    ! subduction geometry                                                          |
    !------------------------------------------------------------------------------|
    !((((((((((((((((  declaration of the subroutine arguments  ))))))))))))))))))))
    !------------------------------------------------------------------------------|
    
    use definitions
    !use mpi
    
    implicit none
    
    include 'mpif.h' 
    
    type (parameters) params
    type (octreesolve) osolve
    type (void) vo
    type (bc_definition) bcdef
    type (nest_info) nest
    
    !------------------------------------------------------------------------------|
    !(((((((((((((((( declaration of the subroutine internal variables )))))))))))))
    !------------------------------------------------------------------------------|
    
    integer i,iproc,nproc,ierr,tempcase,fixdomain
    double precision :: eps,pi,y0,h,rx,wy,vin,vtop,vback,nelemx,nelemz,dxy,dz
    double precision :: rmain,zmain,omega,theta,phi,distmain,distrot,distz0plane
    double precision :: distzonerad,distzoney,distzone,distedge
    double precision :: xedge,xminedge,xmaxedge,yfix_xedge, yedge,yminedge,ymaxedge
    double precision :: zedge,zminedge,zmaxedge, ustart,ustart2,uend,uend2
    double precision :: wstart,wstart2,wend,tempstart,tempstart2,tempend
    double precision :: nl_heat,hr,depth,ztemp
    
    !------------------------------------------------------------------------------|
    !------------------------------------------------------------------------------|
    
    call mpi_comm_size (mpi_comm_world,nproc,ierr)
    call mpi_comm_rank (mpi_comm_world,iproc,ierr)
    
    !basic constants
    eps=1.d-10
    pi=atan(1.d0)*4.d0
    
    !set fixed to 0 everywhere
    osolve%kfix=0
    osolve%kfixt=0
    
    
    !parameters from input file 
    y0=bcdef%bc_parameters(1)
    h=bcdef%bc_parameters(2)
    rx=bcdef%bc_parameters(3)
    wy=bcdef%bc_parameters(4)
    vin=bcdef%bc_parameters(5)
    vtop=bcdef%bc_parameters(6)
    vback=-bcdef%bc_parameters(7) !change in orientation
    nelemx=bcdef%bc_parameters(8)
    nelemz=bcdef%bc_parameters(9)
    tempcase=idint(bcdef%bc_parameters(10))
    nl_heat=bcdef%bc_parameters(11)/params%tempscale
    hr=bcdef%bc_parameters(12)
    fixdomain=idint(bcdef%bc_parameters(13))    
    
    dxy=nelemx/2.d0**(params%levelmax_oct+1.d0) !0.5*transition width in xy
    dz=nelemz*params%vex/2.d0**(params%levelmax_oct+1.d0) !0.5*transition width in z
    
    ztemp = params%ztemp*params%vex
    
    !Derived parameters from input values
    rmain=(h**2+rx**2)/(2.d0*h)
    zmain=h-rmain
    omega=vin/rmain
    
    !rotating element is sphere
    
    do i=1,osolve%nnode
    
    !distance from center of sphere
    distmain=sqrt(osolve%x(i)**2+((osolve%y(i)-y0)*rx/(0.5d0*wy))**2 + &
                  (osolve%z(i)*params%vex-zmain)**2)
    !distance from axis of rotation
    distrot=sqrt(osolve%x(i)**2+(osolve%z(i)*params%vex-zmain)**2)
    
    !setting velocity in indenter
    if (distmain<rmain) then
        theta=asin(osolve%x(i)/distrot)
        osolve%kfix((i-1)*3+1)=1
        osolve%u(i)=distrot*omega*cos(theta)
        osolve%kfix((i-1)*3+2)=1
        osolve%v(i)=0.d0
        osolve%kfix((i-1)*3+3)=1
        osolve%w(i)=-osolve%x(i)*omega
    elseif (distmain > rmain+2.d0*dz .AND. fixdomain > 0) then
        osolve%kfix((i-1)*3+1)=1
        osolve%u(i)=0.d0
        osolve%kfix((i-1)*3+2)=1
        osolve%v(i)=0.d0
        osolve%kfix((i-1)*3+3)=1
        osolve%w(i)=0.d0
    end if
    
    !y=0 face free slip 
    if (osolve%y(i)<eps) then
        !no flux through face
        osolve%kfix((i-1)*3+2)=1 ; osolve%v(i)=0.d0
    
        !flow fixed to (vback, 0 0)
        osolve%kfix((i-1)*3+1)=1 ; osolve%u(i)=vback
        osolve%kfix((i-1)*3+3)=1 ; osolve%w(i)=0.d0
        
        !rotating sphere cuts y=0 face
        if (y0-0.5d0*wy < 0.d0) then
            !calculate geometry for face
            distedge = sqrt(max(0.0d0, rmain**2 - ((-y0)*rx/(0.5d0*wy))**2))
            distzonerad = max(0.d0,min(1.d0,(distrot-distedge+dz)/(2*dz)))
            
            !Setting velocities for inside and tranistion
            !angle of rotation
            theta=asin(osolve%x(i)/distrot)
            !inside rotating cylinder
            if (distzonerad < eps) then
                !set x velocity
                osolve%kfix((i-1)*3+1)=1
                osolve%u(i)=distrot*omega*cos(theta)
                !set z velocity
                osolve%kfix((i-1)*3+3)=1
                osolve%w(i)=-osolve%x(i)*omega
            !in transition zone
            else if (distzonerad < 1.d0) then
                xminedge = osolve%x(i)*(distedge-dz)/distrot
                !set x velocity
                ustart=(distedge-dz)*omega*cos(theta)
                uend=vback
                osolve%u(i)=ustart+distzonerad*(uend-ustart)
                !set z velocity
                wstart=-xminedge*omega
                wend=0.d0
                osolve%w(i)=wstart+distzonerad*(wend-wstart)
            end if
        end if
    end if
    
    !y=1 face free slip
    if (osolve%y(i)>(1.d0-eps)) then
        !no flux through face
        osolve%kfix((i-1)*3+2)=1 ; osolve%v(i)=0.d0
    
        !flow fixed to (vback, 0 0)
        osolve%kfix((i-1)*3+1)=1 ; osolve%u(i)=vback
        osolve%kfix((i-1)*3+3)=1 ; osolve%w(i)=0.d0
        
        !rotating sphere cuts y=1 face
        if (y0+0.5d0*wy > 1.d0) then
            !calculate geometry for face
            distedge = sqrt(max(0.0d0, rmain**2 - ((1.d0-y0)*rx/(0.5d0*wy))**2))
            distzonerad = max(0.d0,min(1.d0,(distrot-distedge+dz)/(2*dz)))
            
            !Setting velocities for inside and transition
            !angle of rotation
            theta=asin(osolve%x(i)/distrot)
            !inside rotating cylinder
            if (distzonerad < eps) then
                !set x velocity
                osolve%kfix((i-1)*3+1)=1
                osolve%u(i)=distrot*omega*cos(theta)
                !set z velocity
                osolve%kfix((i-1)*3+3)=1
                osolve%w(i)=-osolve%x(i)*omega
            !in transition zone
            else if (distzonerad < 1.d0) then
                xminedge = osolve%x(i)*(distedge-dz)/distrot
                !set x velocity
                ustart=(distedge-dz)*omega*cos(theta)
                uend=vback
                osolve%u(i)=ustart+distzonerad*(uend-ustart)
                !set z velocity
                wstart=-xminedge*omega
                wend=0.d0
                osolve%w(i)=wstart+distzonerad*(wend-wstart)
            end if
        end if
    end if
    
    !x=0 face
    if (osolve%x(i)<eps) then
        !set y and z velocity
        osolve%kfix((i-1)*3+1)=1 !x-direction fixed
        osolve%kfix((i-1)*3+2)=1 ; osolve%v(i)=0.d0 !y-direction
        osolve%kfix((i-1)*3+3)=1 ; osolve%w(i)=0.d0 !z-direction
        
        !outline of indenter
        zedge = max(0.d0, zmain+sqrt(max(0.d0,rmain**2-((osolve%y(i)-y0)*rx/(0.5d0*wy))**2)))
        zminedge = max(0.d0,zedge-dz)
        zmaxedge = max(0.d0,zedge+dz)
        
        !position relative to radial and y transition zones
        !    (0 inside, 1 outside, linear transition in zone)
        distzonerad = max(0.d0,min(1.d0,(osolve%z(i)*params%vex-zminedge)/(zmaxedge-zminedge+eps)))
        distzoney=min(1.d0,max(0.d0,(abs(osolve%y(i)-y0)-0.5d0*wy+dxy)/(2.d0*dxy)))
        
        !outside rotating sphere radially
        if (distzonerad > 1.d0-eps) then
            ustart = vtop
            uend = vback
            osolve%u(i)=ustart+distzoney*(uend-ustart)
        !within rotating sphere radially
        elseif (distzonerad < eps) then
            osolve%u(i)=omega*(osolve%z(i)*params%vex-zmain)
        !inside transition zone radially
        else
            !uend depends on upper gradient (see distzonerad > 1)
            ustart2=vtop
            uend2=vback
            uend=ustart2+distzoney*(uend2-ustart2)
            !ustart is gradient from urot to uback
            ustart2 = omega*(osolve%z(i)*params%vex-zmain)
            uend2=vback
            ustart=ustart2+distzoney*(uend2-ustart2)
            osolve%u(i)=ustart+distzonerad*(uend-ustart)
        end if
    
        !set temperature
        osolve%kfixt(i) = 1
    
        depth = ztemp - osolve%z(i)*params%vex
        select case (tempcase)
            case (1)
            !"typical isotherm taken from R.Bendicks simulation
            !nl_heat is scaled nonlinear heat component hr^2*S_o/k_T
                osolve%temp(i) = (depth/ztemp) + & 
                    nl_heat*((1.d0-exp(-depth/hr))-(1.d0-exp(-ztemp/hr))*depth/ztemp)
            case default
                osolve%temp(i) = depth/ztemp
        end select
    
    end if
    
    !z=0 face
    if (osolve%z(i) < eps) then
        !fix all velocities and temp, set v to 0
        osolve%kfix((i-1)*3+1)=1 
        osolve%kfix((i-1)*3+2)=1 ; osolve%v(i)=0.d0 !y-direction
        osolve%kfix((i-1)*3+3)=1
        
        !calculating radial transition zone: radial belt of width 2dxy at indenter edge,
        !circle origin is (x0, y0, 0)
        !finding intersections with indenter edge radial direction
        distz0plane = sqrt(osolve%x(i)**2+((osolve%y(i)-y0)*rx/(0.5d0*wy))**2)
        if (distz0plane < eps) then
            xedge = rx
            yedge = y0
        else
            xedge = osolve%x(i)*rx/distz0plane 
            yedge = y0+(osolve%y(i)-y0)*rx/distz0plane
        end if
        !finding intersection with indenter edge for given x in y direction
        yfix_xedge=sqrt(max(0.d0,rmain**2-((osolve%y(i)-y0)*rx/(0.5d0*wy))**2-zmain**2))
        !start of transition zone radially
        xminedge = xedge-dxy*xedge/sqrt(xedge**2+(yedge-y0)**2)
        yminedge = yedge-dxy*(yedge-y0)/sqrt(xedge**2+(yedge-y0)**2)
    
        !transition zone in radial >1 for outside, <0 for inside
        distzonerad=(sqrt((osolve%y(i)-y0)**2+osolve%x(i)**2) - &
                  sqrt((yminedge-y0)**2+(xminedge)**2))/(2.d0*dxy)
    
        !outside rotating sphere radially
        if (distzonerad > 1.d0) then
            !velocity
            osolve%u(i) = vback
            osolve%w(i) = 0.d0
            !temperature
            osolve%temp(i)=1.d0
            osolve%kfixt(i)=1 
        !within rotating sphere radially
        elseif (distzonerad < 0.d0) then
            distrot = sqrt(osolve%x(i)**2+zmain**2)
            theta = asin(osolve%x(i)/distrot)
            !set x velocity
            osolve%u(i) = distrot*omega*cos(theta)
            !set z velocity
            osolve%w(i) = -osolve%x(i)*omega
            
            !don't set temperature
    
        !transition zone radially
        else
            !start value at inner edge of transition zone 
            distrot = sqrt(xminedge**2+zmain**2)
            theta = asin(xminedge/distrot)
            ustart = distrot*omega*cos(theta)
            uend = vback
            wstart = -xminedge*omega
            wend = 0.d0
            !setting velocities
            osolve%u(i)=ustart+distzonerad*(uend-ustart)
            osolve%w(i)=wstart+distzonerad*(wend-wstart)
            
            !don't set temperature
    
        end if      
    end if
    
    !x=1 face with influx vback
    if (osolve%x(i)>1.d0-eps) then
        osolve%kfix((i-1)*3+1)=1 ; osolve%u(i)=vback
        osolve%kfix((i-1)*3+2)=1 ; osolve%v(i)=0.d0
        osolve%kfix((i-1)*3+3)=1 ; osolve%w(i)=0.d0
    end if
    
    !z=1 face 
    if (osolve%z(i) > 1.d0-eps) then
        osolve%kfix((i-1)*3+1)=1 ; osolve%u(i)=0.d0 !x-direction
        osolve%kfix((i-1)*3+2)=1 ; osolve%v(i)=0.d0 !y-direction
        osolve%kfix((i-1)*3+3)=1 ; osolve%w(i)=0.d0 !z-direction
        osolve%kfixt(i)=1 ; osolve%temp(i)=0.d0
    end if
    
    if (.not.vo%influid(i)) then
       osolve%kfixt(i)=1
       osolve%temp(i)=0.d0
    endif
    
    end do
    
    end
    
    !------------------------------------------------------------------------------|