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

📄 utils.f90

📁 Spectral Element Method for wave propagation and rupture dynamics.
💻 F90
📖 第 1 页 / 共 2 页
字号:
! SEM2DPACK version 2.2.11 -- A Spectral Element Method for 2D wave propagation and fracture dynamics,!                             with emphasis on computational seismology and earthquake source dynamics.! ! Copyright (C) 2003-2007 Jean-Paul Ampuero! All Rights Reserved! ! Jean-Paul Ampuero! ! ETH Zurich (Swiss Federal Institute of Technology)! Institute of Geophysics! Seismology and Geodynamics Group! ETH H鰊ggerberg HPP O 13.1! CH-8093 Z黵ich! Switzerland! ! ampuero@erdw.ethz.ch! +41 44 633 2197 (office)! +41 44 633 1065 (fax)! ! http://www.sg.geophys.ethz.ch/geodynamics/ampuero/! ! ! This software is freely available for scientific research purposes. ! If you use this software in writing scientific papers include proper ! attributions to its author, Jean-Paul Ampuero.! ! This program is free software; you can redistribute it and/or! modify it under the terms of the GNU General Public License! as published by the Free Software Foundation; either version 2! of the License, or (at your option) any later version.! ! This program is distributed in the hope that it will be useful,! but WITHOUT ANY WARRANTY; without even the implied warranty of! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the! GNU General Public License for more details.! ! You should have received a copy of the GNU General Public License! along with this program; if not, write to the Free Software! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.! ! This is a set of basic tools, adapted from different open sourcesmodule utils  implicit none  private  public :: invert2,drank,dsort,hunt,sub2ind,sub2ind_b,spline,splintcontains!----------------------------------------------------------------------!-- inversion of a 2 x 2 matrix  function invert2(A) result(B)  use stdio, only : IO_abort  double precision, intent(in) :: A(2,2)  double precision :: B(2,2)  double precision :: determinant  determinant = A(1,1)*A(2,2) - A(1,2)*A(2,1)  if (determinant <= 0d0) call IO_abort('SE_InverseJacobian: undefined Jacobian')  B(1,1) =   A(2,2)  B(2,1) = - A(2,1)  B(1,2) = - A(1,2)  B(2,2) =   A(1,1)  B = B/determinant  end function invert2!=====================================================================! subscript (i,j) to index (iglob)! numbering conventions :!   i=1:n !   j=1:p!   iglob = 1:integer function sub2ind(i,j,n)  integer, intent(in) :: i,j,n  sub2ind = (j-1)*n + iend function sub2ind!--------------------------------------------------------------------- ! returns 0 if out of boxinteger function sub2ind_b(i,j,n,p)  integer, intent(in) :: i,j,n,p  if (i<=n .and. i>=1 .and. j<=p .and. j>=1) then     sub2ind_b= (j-1)*n + i  else    sub2ind_b=0   endifend function sub2ind_b!-----------------------------------------------------------------------!From Michel Olagnon's ORDERPACK 2.0!http://www.fortran-2000.com/rank/index.html!!Subroutine D_mrgrnk (XDONT, IRNGT)Subroutine drank(XDONT, IRNGT)! __________________________________________________________!   MRGRNK = Merge-sort ranking of an array!   For performance reasons, the first 2 passes are taken!   out of the standard loop, and use dedicated coding.! __________________________________________________________! __________________________________________________________!      Real (kind=kdp), Dimension (:), Intent (In) :: XDONT      double precision, Dimension (:), Intent (In) :: XDONT !jpampuero      Integer, Dimension (:), Intent (Out) :: IRNGT! __________________________________________________________!      Real (kind=kdp) :: XVALA, XVALB      double precision :: XVALA, XVALB !jpampuero!      Integer, Dimension (SIZE(IRNGT)) :: JWRKT      Integer :: LMTNA, LMTNC, IRNG1, IRNG2      Integer :: NVAL, IIND, IWRKD, IWRK, IWRKF, JINDA, IINDA, IINDB!      NVAL = Min (SIZE(XDONT), SIZE(IRNGT))      Select Case (NVAL)      Case (:0)         Return      Case (1)         IRNGT (1) = 1         Return      Case Default         Continue      End Select!!  Fill-in the index array, creating ordered couples!      Do IIND = 2, NVAL, 2         If (XDONT(IIND-1) <= XDONT(IIND)) Then            IRNGT (IIND-1) = IIND - 1            IRNGT (IIND) = IIND         Else            IRNGT (IIND-1) = IIND            IRNGT (IIND) = IIND - 1         End If      End Do      If (Modulo(NVAL, 2) /= 0) Then         IRNGT (NVAL) = NVAL      End If!!  We will now have ordered subsets A - B - A - B - ...!  and merge A and B couples into     C   -   C   - ...!      LMTNA = 2      LMTNC = 4!!  First iteration. The length of the ordered subsets goes from 2 to 4!      Do         If (NVAL <= 2) Exit!!   Loop on merges of A and B into C!         Do IWRKD = 0, NVAL - 1, 4            If ((IWRKD+4) > NVAL) Then               If ((IWRKD+2) >= NVAL) Exit!!   1 2 3!               If (XDONT(IRNGT(IWRKD+2)) <= XDONT(IRNGT(IWRKD+3))) Exit!!   1 3 2!               If (XDONT(IRNGT(IWRKD+1)) <= XDONT(IRNGT(IWRKD+3))) Then                  IRNG2 = IRNGT (IWRKD+2)                  IRNGT (IWRKD+2) = IRNGT (IWRKD+3)                  IRNGT (IWRKD+3) = IRNG2!!   3 1 2!               Else                  IRNG1 = IRNGT (IWRKD+1)                  IRNGT (IWRKD+1) = IRNGT (IWRKD+3)                  IRNGT (IWRKD+3) = IRNGT (IWRKD+2)                  IRNGT (IWRKD+2) = IRNG1               End If               Exit            End If!!   1 2 3 4!            If (XDONT(IRNGT(IWRKD+2)) <= XDONT(IRNGT(IWRKD+3))) Cycle!!   1 3 x x!            If (XDONT(IRNGT(IWRKD+1)) <= XDONT(IRNGT(IWRKD+3))) Then               IRNG2 = IRNGT (IWRKD+2)               IRNGT (IWRKD+2) = IRNGT (IWRKD+3)               If (XDONT(IRNG2) <= XDONT(IRNGT(IWRKD+4))) Then!   1 3 2 4                  IRNGT (IWRKD+3) = IRNG2               Else!   1 3 4 2                  IRNGT (IWRKD+3) = IRNGT (IWRKD+4)                  IRNGT (IWRKD+4) = IRNG2               End If!!   3 x x x!            Else               IRNG1 = IRNGT (IWRKD+1)               IRNG2 = IRNGT (IWRKD+2)               IRNGT (IWRKD+1) = IRNGT (IWRKD+3)               If (XDONT(IRNG1) <= XDONT(IRNGT(IWRKD+4))) Then                  IRNGT (IWRKD+2) = IRNG1                  If (XDONT(IRNG2) <= XDONT(IRNGT(IWRKD+4))) Then!   3 1 2 4                     IRNGT (IWRKD+3) = IRNG2                  Else!   3 1 4 2                     IRNGT (IWRKD+3) = IRNGT (IWRKD+4)                     IRNGT (IWRKD+4) = IRNG2                  End If               Else!   3 4 1 2                  IRNGT (IWRKD+2) = IRNGT (IWRKD+4)                  IRNGT (IWRKD+3) = IRNG1                  IRNGT (IWRKD+4) = IRNG2               End If            End If         End Do!!  The Cs become As and Bs!         LMTNA = 4         Exit      End Do!!  Iteration loop. Each time, the length of the ordered subsets!  is doubled.!      Do         If (LMTNA >= NVAL) Exit         IWRKF = 0         LMTNC = 2 * LMTNC!!   Loop on merges of A and B into C!         Do            IWRK = IWRKF            IWRKD = IWRKF + 1            JINDA = IWRKF + LMTNA            IWRKF = IWRKF + LMTNC            If (IWRKF >= NVAL) Then               If (JINDA >= NVAL) Exit               IWRKF = NVAL            End If            IINDA = 1            IINDB = JINDA + 1!!   Shortcut for the case when the max of A is smaller!   than the min of B. This line may be activated when the!   initial set is already close to sorted.!!          IF (XDONT(IRNGT(JINDA)) <= XDONT(IRNGT(IINDB))) CYCLE!!  One steps in the C subset, that we build in the final rank array!!  Make a copy of the rank array for the merge iteration!            JWRKT (1:LMTNA) = IRNGT (IWRKD:JINDA)!            XVALA = XDONT (JWRKT(IINDA))            XVALB = XDONT (IRNGT(IINDB))!            Do               IWRK = IWRK + 1!!  We still have unprocessed values in both A and B!               If (XVALA > XVALB) Then                  IRNGT (IWRK) = IRNGT (IINDB)                  IINDB = IINDB + 1                  If (IINDB > IWRKF) Then!  Only A still with unprocessed values                     IRNGT (IWRK+1:IWRKF) = JWRKT (IINDA:LMTNA)                     Exit                  End If                  XVALB = XDONT (IRNGT(IINDB))               Else                  IRNGT (IWRK) = JWRKT (IINDA)                  IINDA = IINDA + 1                  If (IINDA > LMTNA) Exit! Only B still with unprocessed values                  XVALA = XDONT (JWRKT(IINDA))               End If!            End Do         End Do!!  The Cs become As and Bs!         LMTNA = 2 * LMTNA      End Do!      Return!!End Subroutine D_mrgrnkEnd Subroutine drank!-----------------------------------------------------------------------! DSORT adapted from SLATEC! Converted to f90 using f2f.perl! Modified:     + to be used always with DY!               + only increasing order!               + no checks / error messages! Jean-Paul Ampuero     dim oct 19 17:15:29 EDT 2003! ECK DSORT!    SUBROUTINE DSORT (DX, DY, N, KFLAG)    SUBROUTINE DSORT (DX, DY)!***BEGIN PROLOGUE  DSORT!***PURPOSE  Sort an array and optionally make the same interchanges in! an auxiliary array.  The array may be sorted in increasing! or decreasing order.  A slightly modified QUICKSORT! algorithm is used.!***LIBRARY   SLATEC!***CATEGORY  N6A2B!***TYPE      DOUBLE PRECISION (SSORT-S, DSORT-D, ISORT-I)!***KEYWORDS  SINGLETON QUICKSORT, SORT, SORTING!***AUTHOR  Jones, R. E., (SNLA)! Wisniewski, J. A., (SNLA)!***DESCRIPTION

⌨️ 快捷键说明

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