晶体的单晶声速


晶体的单晶声速计算公式

Christoffel’s equation relates acoustic velocitics to crystallo-graphic direction and elastic constants.
$$
det|C_{ijkl}n_{l}n_{j}-\rho v^{2}\delta_{ik}|=0 \
det|F_{ik}n_{l}n_{j}-\rho v^{2}\delta_{ik}|=0 \
i,j,k,l=1,2,3; \
when\ i=k; then\ \delta=1; others\ \delta=0
$$
So, the Kelvin-Christoffel stiffness $\Gamma_{ik}$ is:
$$
\Gamma_{ik}=\sum_{j,l=1}^{n=3} C_{ijkl}n_{j}n_{l},\ i,k=1,2,3 \
\Gamma = \begin{bmatrix} \Gamma_{11} & \Gamma_{12} & \Gamma_{13} \ \Gamma_{12} & \Gamma_{22} & \Gamma_{23} \ \Gamma_{13} & \Gamma_{23} & \Gamma_{33}\end{bmatrix}
$$
For $n_{j}(\phi,\theta,\chi),n_{l}(\phi,\theta,\chi)$ :
$$
n_1=cos(\phi)cos(\theta)cos(\chi)-sin(\phi)sin(\chi) \
n_2=-cos(\phi)cos(\theta)sin(\chi)-sin(\phi)cos(\chi) \
n_3=-cos(\phi)sin(\theta)
$$
then, we can calculate the eigenvalues of matrix equation ($\lambda_i,i=1,2,3$).
$$
\lambda_1=\rho v_l^2 \
\lambda_2=\rho v_{s1}^2 \
\lambda_3=\rho v_{s2}^2
$$

Reference:

Sound velocity and elasticity of single-crystal forsterite to 16 GPa; DOI: 10.1029/96JB01266


The fortran code:

module singal_sound_velocity
    contains
    subroutine sing_sound_velocity(Celas, theta, phi, chi,  V_sing)
            ! Celas: elastic constants
            implicit none
            real(kind=8) :: theta, phi ,chi, Celas(6,6)
            real(kind=8) :: V_sing(3,3)
            real(kind=8) :: n1,n2,n3
            real(kind=8) :: f(3,3), Fv(3,3),E(3,3), namda(3,3)
            integer :: n=3 
            real(kind=8) :: err
            integer :: i,j

            n1=cosd(theta)*cosd(phi)*cosd(chi)-sind(phi)*sind(chi)
            n2=-cosd(theta)*cosd(phi)*sind(chi)-sind(phi)*cosd(chi)
            n3=sind(theta)*cosd(phi)

            f(1,1)=n1*n1*Celas(1,1)+n1*n2*Celas(1,6)+n1*n3*Celas(1,5) &
                  +n2*n1*Celas(6,1)+n2*n2*Celas(6,6)+n2*n3*Celas(6,5) &
                  +n3*n1*Celas(5,1)+n3*n2*Celas(5,6)+n3*n3*Celas(5,5)

            f(2,2)=n1*n1*Celas(6,6)+n1*n2*Celas(6,2)+n1*n3*Celas(6,4) &
                  +n2*n1*Celas(2,6)+n2*n2*Celas(2,2)+n2*n3*Celas(2,4) &
                  +n3*n1*Celas(4,6)+n3*n2*Celas(4,2)+n3*n3*Celas(4,4)


            f(3,3)=n1*n1*Celas(5,5)+n1*n2*Celas(5,4)+n1*n3*Celas(5,3) &
                  +n2*n1*Celas(4,5)+n2*n2*Celas(4,4)+n2*n3*Celas(4,3) &
                  +n3*n1*Celas(3,5)+n3*n2*Celas(3,4)+n3*n3*Celas(3,3)

            f(1,2)=n1*n1*Celas(1,6)+n1*n2*Celas(1,2)+n1*n3*Celas(1,4) &
                  +n2*n1*Celas(6,6)+n2*n2*Celas(6,2)+n2*n3*Celas(6,4) &
                  +n3*n1*Celas(5,6)+n3*n2*Celas(5,2)+n3*n3*Celas(5,4)

            f(1,3)=n1*n1*Celas(1,5)+n1*n2*Celas(1,4)+n1*n3*Celas(1,3) &
                  +n2*n1*Celas(6,5)+n2*n2*Celas(6,4)+n2*n3*Celas(6,3) &
                  +n3*n1*Celas(5,5)+n3*n2*Celas(5,4)+n3*n3*Celas(5,3)

            f(2,3)=n1*n1*Celas(6,5)+n1*n2*Celas(6,4)+n1*n3*Celas(6,3) &
                  +n2*n1*Celas(2,5)+n2*n2*Celas(2,4)+n2*n3*Celas(2,3) &
                  +n3*n1*Celas(4,5)+n3*n2*Celas(4,4)+n3*n3*Celas(4,3)

            Fv(1,1)=f(1,1)
            Fv(2,2)=f(2,2)
            Fv(3,3)=f(3,3)
            Fv(1,2)=f(1,2)
            Fv(1,3)=f(1,3)
            Fv(2,1)=f(1,2)
            Fv(3,1)=f(1,3)
            Fv(2,3)=f(2,3)
            Fv(3,2)=f(2,3)

            err=1.0d-8

            call eigenvector_calc(Fv,3,namda,err)

            V_sing=namda

            open(unit=89,file="velocity.out")
            do i=1,3
               write(89,*) (namda(i,j),j=1,3)
            enddo

            do i=1,3
               write(89,*) (Fv(i,j),j=1,3)
            enddo

    end subroutine sing_sound_velocity

    subroutine eigenvector_calc(a,n,e,eps)
        !==============================================================
        ! Compute all eigenvalues: real symmetric matrix a(n,n,)
        ! a*x = lambda*x 
        ! method: the basic QR method
        ! Alex G. (January 2010)
        !--------------------------------------------------------------
        ! input ...
        ! a(n,n) - array of coefficients for matrix A
        ! n      - dimension
        ! eps    - convergence tolerance
        ! output ...
        ! e(n)   - eigenvalues
        ! iter   - number of iterations to achieve the tolerance
        ! comments ...
        ! kmax   - max number of allowed iterations
        !==============================================================
        implicit none
        integer :: n ,iter
        real(kind=8) :: a(n,n), e(n,n), eps
        real(kind=8) :: q(n,n), r(n,n), w(n), an, Ajnorm, sum, e0,e1 
        integer :: k, i, j, m
        integer, parameter::kmax=1000

        ! initialization
        q = 0.0
        r = 0.0
        e0 = 0.0

        do k=1,kmax              ! iterations

        ! step 1: compute Q(n,n) and R(n,n)
        ! column 1
          an = Ajnorm(a,n,1)
          r(1,1) = an
          do i=1,n
            q(i,1) = a(i,1)/an
          end do
        ! columns 2,...,n
          do j=2,n
            w = 0.0
            do m=1,j-1
        ! product q^T*a result = scalar
              sum = 0.0
              do i=1,n
                sum = sum + q(i,m)*a(i,j)
              end do
              r(m,j) = sum
        ! product (q^T*a)*q  result = vector w(n)
              do i=1,n
                w(i) = w(i) + sum*q(i,m)
              end do
            end do
        ! new a'(j)
            do i =1,n
              a(i,j) = a(i,j) - w(i)
            end do
        ! evaluate the norm for a'(j)
            an = Ajnorm(a,n,j)
            r(j,j) = an
        ! vector q(j)
            do i=1,n
              q(i,j) = a(i,j)/an
            end do
          end do

        ! step 2: compute A=R(n,n)*Q(n,n)
          a = matmul(r,q)
        ! egenvalues and the average eigenvale
          sum = 0.0
          do i=1,n
            e(i,i) = a(i,i)
            sum = sum+e(i,i)*e(i,i)
          end do  
          e1 = sqrt(sum)

        ! print here eigenvalues
        !  write (*,201)  (e(i),i=1,n)
        !201 format (6f12.6)

        ! check for convergence
          if (abs(e1-e0) < eps) exit
        ! prepare for the next iteration
          e0 = e1  
        end do

        iter = k
        if(k == kmax) write (*,*)'The eigenvlue failed to converge'

    end subroutine eigenvector_calc
end module

function Ajnorm(a,n,j)
    implicit none
    integer n, j, i
    real(kind=8) :: a(n,n), Ajnorm
    real(kind=8) :: sum

    sum = 0.0
    do i=1,n
      sum = sum + a(i,j)*a(i,j)
    end do
    Ajnorm = sqrt(sum)
end function Ajnorm

文章作者: 天帝君豪
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 天帝君豪 !
  目录