⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bc_swff.f90

📁 Spectral Element Method for wave propagation and rupture dynamics.
💻 F90
📖 第 1 页 / 共 2 页
字号:
!    v(bc%bc1%node,1) = -sign( max( abs(bc%Tt0)+bc%MU*bc%Tn0, 0d0), bc%Tt0 ) &!                         / (2670d0*3464d0)!    if (two_sides) v(bc%bc2%node,1) = -v(bc%bc1%node,1)!  else ! P-SV!! WARNING: not implemented yet!  endif! Output arrays  bc%OutputIFir = max(bc%OutputIFir, 1)  bc%OutputILas = min(bc%OutputILas, npoin)  bc%OutputNpoin = (bc%OutputILas-bc%OutputIFir)/bc%OutputILag +1  allocate(bc%Tt(bc%OutputNpoin))  allocate(bc%Tn(bc%OutputNpoin))  bc%Tt=bc%Tt0(bc%OutputIFir:bc%OutputILas:bc%OutputILag)  bc%Tn=bc%Tn0(bc%OutputIFir:bc%OutputILas:bc%OutputILag)  if (size(bc%Tn0(bc%OutputIFir:bc%OutputILas:bc%OutputILag))/=bc%OutputNpoin) &    stop 'couille avec npoin'!-- Open output files -----! Set output parameters! NOTE: file names limited to tags(1)<100  write(OutputFileName,'("Flt",I2.2,"_sem2d.dat")') tags(1)  bc%OutputUnit = IO_new_unit()  open(bc%OutputUnit,file=OutputFileName,status='replace',form='unformatted') ! adjust output timestep to the nearest multiple of dt:  if (bc%OutputDt==0d0) then    bc%OutputNdt=1  else    bc%OutputNdt = nint(bc%OutputDt/time%dt)  endif  bc%OutputDt = time%dt * bc%OutputNdt  bc%OutputNextTime = nint(bc%OutputT1/time%dt) ! HEADER FILE FORMAT: !      Name            FltXX_sem2d.hdr where XX=tags(1) of the BC_SWFFLT !                      input block, the tag of the first side of the fault. !      Line 1          Name of size/other variables !      Line 2          Value of size/other variables !      Line 3          Name of data fields, separated by ":" !      Line 4          Name of coordinate axis !      Line 5:end      Two column table of nodes coordinates ! ! OUTPUT FILE FORMAT: !      At each time (lag DELT, total NSAMP), NDAT data lines with !      NPTS columns, one per fault node, are written. !      Stress fields are relative to initial values and !      the first NDAT lines contain the initial conditions. ! ! NOTE: when the binary file is written one line at a time !      a record tag is also written at the beginning and end of line, !      => number of columns in output file = nb of data columns +2 !  write(HdrFileName,'("Flt",I2.2,"_sem2d")') tags(1)  NDAT = 5  NSAMP = (time%nt -bc%OutputNextTime)/bc%OutputNdt +1  HdrUnit = IO_new_unit()  open(HdrUnit,file=trim(HdrFileName)//'.hdr',status='replace')  write(HdrUnit,*) 'NPTS NDAT NSAMP DELT'  write(HdrUnit,*) bc%OutputNpoin,NDAT,NSAMP,bc%OutputDt                    write(HdrUnit,*) 'Slip:Slip Rate:Shear Stress:Normal Stress:Friction'  write(HdrUnit,*) 'XPTS ZPTS'  do i=bc%OutputIFir,bc%OutputILas,bc%OutputILag    write(HdrUnit,*) FltCoord(:,i)  enddo  close(HdrUnit)  deallocate(FltCoord)! Sample SU script subset|b2a ! NOTE: how to convert to a human-readable ASCII table !      the Slip at time 10*DELT (assuming first output at t=0),  !      using Seismic Unix's subset and b2a : !              subset <Flt05_sem2d.hdr n1=(NPTS+2) n2=NDAT n3=NSAMP \ !              if1s=1 n1s=NPTS ix2s=0 ix3s=10 \ !              | b2a n1=NPTS > slip_t10.tab !  open(HdrUnit,file=trim(HdrFileName)//'.csh',status='replace')  write(HdrUnit,*) '#!/bin/csh -f'  write(HdrUnit,*) '#USAGE: '//trim(HdrFileName)//'.csh node field'  write(HdrUnit,*) '@ ifs = $2 - 1'  write(HdrUnit,'(A,I0,A,I0,A,I0,A)') 'subset <'//trim(HdrFileName)//'.dat n1=',bc%OutputNpoin+2, &    ' n2=',NDAT,' n3=',NSAMP,' ix1s=$1 ix2s=$ifs | b2a n1=1 > '//trim(HdrFileName)//'.$1.$ifs.tab'  close(HdrUnit)  end subroutine BC_SWFF_init!=====================================================================! Computes the boundary term B*T with T satisfying a friction law!! Convention:   T = sigma*n1!               D = d2-d1! => T and D have same sign!! NOTE: this is an EXPLICIT scheme FOR FRICTION, !       we use the displacement at the PREVIOUS timestep !       to compute the friction coefficient!! NOTE: possible periodicity does not need to be enforced at this level!       because it is assumed that MxA and D are already periodic!  subroutine BC_SWFF_set(bc,MxA,V,D)  type(bc_swff_type) :: bc  double precision, intent(in) :: V(:,:),D(:,:)  double precision, intent(inout) :: MxA(:,:)  if (size(V,2) == 1) then    call BC_SWFF_set_SH(bc,MxA(:,1),V(:,1),D(:,1))  else    call BC_SWFF_set_PSV(bc,MxA,V,D)  endif  end subroutine BC_SWFF_set!---------------------------------------------------------------------  subroutine BC_SWFF_set_SH(bc,MxA,V,D)  type(bc_swff_type) :: bc  double precision, intent(in) :: V(:),D(:)  double precision, intent(inout) :: MxA(:)  double precision, dimension(bc%bc1%npoin) :: T,dD  integer, pointer :: i1(:),i2(:)  logical :: two_sides  two_sides = associated(bc%bc2)  i1 => bc%bc1%node! A test traction is computed as if the fault was sticking at n+1 (no slip rate)!           = Z * SlipRateFree !	    = Z * (SlipRate_predicted + coef*SlipAccelFree)! where: !   Z = fault impedance matrix (diagonal)!   SlipRateFree, SlipAccelFree = slip velocity and acceleration !     				  as if the fault was stress free!   coef = depends on the time integration scheme!  if (two_sides) then    i2 => bc%bc2%node    T = bc%Z* ( V(i2)-V(i1) + bc%CoefA2V*( bc%invM2*MxA(i2)-bc%invM1*MxA(i1) ))    dD = D(i2) - D(i1)  else    T  = -2d0*bc%Z* ( V(i1) + bc%CoefA2V * bc%invM1*MxA(i1) )    dD = -2d0*D(i1)  endif! Update slip weakening (only for leapfrog scheme)  if (bc%UpdateFrictionFirst) bc%MU = friction(dD,bc%MuStatic,bc%MuDynamic,bc%Dc)! Coulomb friction, applied to the absolute stress  T = T + bc%Tt0  T = sign( min(abs(T), -bc%Tn0*bc%MU), T)  T = T - bc%Tt0! Add boundary term B*T to M*a  MxA(i1) = MxA(i1) + bc%B*T  if (two_sides) MxA(i2) = MxA(i2) - bc%B*T! Store relative tractions for output  bc%Tt = T(bc%OutputIFir:bc%OutputILas:bc%OutputILag)  bc%Tn = 0d0! Newmark scheme: update friction for next time step! Introduces a delay of dt, but keeps the friction solver fully explicit  if (.not. bc%UpdateFrictionFirst) then    if (two_sides) then      dD = dD + bc%CoefA2D *( bc%invM2*MxA(i2)-bc%invM1*MxA(i1) )    else      dD = dD -2d0*bc%CoefA2D * bc%invM1*MxA(i1)    endif    bc%MU = friction(dD, bc%MuStatic, bc%MuDynamic, bc%Dc)  endif  end subroutine BC_SWFF_set_SH!---------------------------------------------------------------------! WARNING: the opening conditions are incomplete!          there can be a problem if the fault opens and closes again  subroutine BC_SWFF_set_PSV(bc,MxA,V,D)  type(bc_swff_type) :: bc  double precision, intent(in) :: V(:,:),D(:,:)  double precision, intent(inout) :: MxA(:,:)  double precision, dimension(bc%bc1%npoin) :: Slip,Tt,Tn  double precision, dimension(bc%bc1%npoin,2) :: BxT,T_Stick,dD,dA  integer, pointer :: i1(:),i2(:)  logical :: two_sides  two_sides = associated(bc%bc2)! Test traction  i1 => bc%bc1%node  if (two_sides) then    i2 => bc%bc2%node    dD = D(i2,:) - D(i1,:)    dA(:,1) = bc%invM2*MxA(i2,1) - bc%invM1*MxA(i1,1)    dA(:,2) = bc%invM2*MxA(i2,2) - bc%invM1*MxA(i1,2)    T_Stick = V(i2,:)-V(i1,:) + bc%CoefA2V * dA  else    dD = - 2d0*D(i1,:) ! used only to compute tangential discontinuity (slip)    dA(:,1) = - 2d0*bc%invM1*MxA(i1,1)    dA(:,2) = - 2d0*bc%invM1*MxA(i1,2)    T_Stick = -2d0*V(i1,:) + bc%CoefA2V * dA  endif  T_Stick(:,1) = bc%Z * T_Stick(:,1)  T_Stick(:,2) = bc%Z * T_Stick(:,2) ! Update slip weakening:!WARNING: there should be no update if there is opening, !         if (Norm>0) return!         should be implemented here if required (unlikely)!  Slip = bc%n1(:,2)*dD(:,1) - bc%n1(:,1)*dD(:,2)  bc%MU = friction(Slip, bc%MuStatic, bc%MuDynamic, bc%Dc)! Rotate tractions to fault frame (Tt,Tn)  Tt = bc%n1(:,2)*T_Stick(:,1) - bc%n1(:,1)*T_Stick(:,2)  if (two_sides) then    Tn = bc%n1(:,1)*T_Stick(:,1) + bc%n1(:,2)*T_Stick(:,2)  else    Tn = 0d0    ! if symmetry: costant normal stress  endif! Add initial stress  Tt = Tt +bc%Tt0  Tn = Tn +bc%Tn0 !Opening-->free stress  Tn = min(Tn,0.d0) ! negative normal stress is compressive !Coulomb friction  Tt = sign( min(abs(Tt),-Tn*bc%MU), Tt)! Subtract initial stress  Tt = Tt -bc%Tt0  Tn = Tn -bc%Tn0! Rotate tractions back to (x,z) frame and apply boundary weights  BxT(:,1) = bc%B*(  bc%n1(:,2)*Tt + bc%n1(:,1)*Tn )  BxT(:,2) = bc%B*( -bc%n1(:,1)*Tt + bc%n1(:,2)*Tn )! Add boundary term B*T to M*a  MxA(i1,:) = MxA(i1,:) + BxT  if (two_sides) MxA(i2,:) = MxA(i2,:) - BxT! Store tractions for output  bc%Tt = Tt(bc%OutputIFir:bc%OutputILas:bc%OutputILag)  bc%Tn = Tn(bc%OutputIFir:bc%OutputILas:bc%OutputILag)  end subroutine BC_SWFF_set_PSV!=====================================================================! OUTPUT FORMAT: at each time, 5 data lines, one column per fault node! 1: Slip! 2: Slip rate! 3: Shear stress ! 4: Normal stress ! 5: Friction coefficient!  subroutine BC_SWFF_write(bc,displ,veloc,itime)  type(bc_swff_type) :: bc  double precision, intent(in) :: Veloc(:,:),Displ(:,:)  integer, intent(in) :: itime  double precision, pointer :: n1(:,:)  integer, pointer :: i1(:),i2(:)  if (itime<bc%OutputNextTime) return  bc%OutputNextTime = bc%OutputNextTime + bc%OutputNdt  if (associated(bc%bc2)) then    i1 => bc%bc1%node(bc%OutputIFir:bc%OutputILas:bc%OutputILag)    i2 => bc%bc2%node(bc%OutputIFir:bc%OutputILas:bc%OutputILag)    if ( size(displ,2)==1 ) then      write(bc%OutputUnit) real(displ(i2,1)-displ(i1,1))      write(bc%OutputUnit) real(veloc(i2,1)-veloc(i1,1))    else      n1 => bc%n1(bc%OutputIFir:bc%OutputILas:bc%OutputILag,:)      write(bc%OutputUnit) real( n1(:,2)*(displ(i2,1)-displ(i1,1)) &                               - n1(:,1)*(displ(i2,2)-displ(i1,2)) )      write(bc%OutputUnit) real( n1(:,2)*(veloc(i2,1)-veloc(i1,1)) &                               - n1(:,1)*(veloc(i2,2)-veloc(i1,2)) )    endif  else    i1 => bc%bc1%node(bc%OutputIFir:bc%OutputILas:bc%OutputILag)    if ( size(displ,2)==1 ) then      write(bc%OutputUnit) -real(2d0*displ(i1,1))      write(bc%OutputUnit) -real(2d0*veloc(i1,1))    else      n1 => bc%n1(bc%OutputIFir:bc%OutputILas:bc%OutputILag,:)      write(bc%OutputUnit) -2.0*real( n1(:,2)*displ(i1,1) &                                - n1(:,1)*displ(i1,2) )      write(bc%OutputUnit) -2.0*real( n1(:,2)*veloc(i1,1) &                                - n1(:,1)*veloc(i1,2) )    endif  endif  write(bc%OutputUnit) real( bc%Tt )  write(bc%OutputUnit) real( bc%Tn )  write(bc%OutputUnit) real( bc%MU(bc%OutputIFir:bc%OutputILas:bc%OutputILag) )  end subroutine BC_SWFF_write!===================================================================== !-- linear slip weakening:  function friction(s,mus,mud,dc) result(mu)  double precision, dimension(:), intent(in) :: s,mus,mud,dc  double precision :: mu(size(s))  mu = mus -(mus-mud)/dc *abs(s)  mu = max( mu, mud)  end function friction!--------------------------------------------------------------------- !-- exponential slip weakening:  function friction_exponential(s,mus,mud,dc) result(mu)  double precision, dimension(:), intent(in) :: s,mus,mud,dc  double precision :: mu(size(s))  mu = mus -(mus-mud)*exp(-abs(s)/dc)  end function friction_exponential  end module bc_swff

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -