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

📄 generic_list.f90

📁 Spectral Element Method for wave propagation and rupture dynamics.
💻 F90
字号:
! 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.! ! From: Roger Young and Peter McGavin, "A generic list implementation"!       ACM SIGPLAN Fortran Forum, Volume 20, Issue 1 (April 2001), Pages 16-20! (available online)! See original source for more info and sample at:!       http://www.fortran.com/fortran/gen_ll.f90       !!*** WARNING: USES A NON STANDARD FEATURE OF THE transfer INTRINSIC ***! Search the COMP-FORTRAN-90 mailing list archives for more info.! The problem is how to treat generic lists in Fortran 90. ! Lists can be (1) homogeneous (elements all of the same type) or ! (2) heterogeneous.! ! (1) Often there is a need to work with many (homogeneous) lists which! may be of different types. Patrice Lignelet has shown how generic list! properties may be logically treated in Fortran 90. However it still! appears that the list operations (initialization, addition/removal of! elements etc) must be separately defined for each list type, which! leads to considerable duplication of code.! ! (2) Jean Vezina has shown how to handle a heterogeneous list by employing the ! F90 TRANSFER() function. ! ! Peter McGavin at Industrial Research Limited (p.mcgavin@irl.cri.nz)! has constructed a species of generic list for Fortran 90. The method! is based on 2 ideas: the properties of the TRANSFER() function, and! the fact that a pointer to a derived data type also points to the! *first field* within the data type (and conversely). ! ! Since the TRANSFER() function does not accept pointer arguments the! method requires the introduction of 2 auxilliary data types which! contain the pointers, one in the generic list module and one for each! list type in the calling program (the same construction is adopted! when defining "arrays of pointers"). In spite of this complication the! method represents a big saving, both conceptually and practically, when! many lists of different types are involved.! ! To make clear the method we present a simple generic list module! together with a calling program. The list module defines a! uni-directional linked list with a few sample operations, but! obviously more complicated generic lists could be substituted in its! place (eg include back pointers).! ! Roger Young! Peter McGavin! ! .........................................................................MODULE Generic_List! Defines a generic uni-directional linked list IMPLICIT NONEPRIVATEPUBLIC :: &     Link_Type,        &! Put a Link_Type field first in your structure     Link_Ptr_Type,    &! Mold this to and from your type ptr with TRANSFER     List_Type          ! You should declare a List_Type variablePUBLIC :: &      LI_Init_List,        &! Initialise the List_Type variable before      LI_Get_Head,         &! Returns the first Link in the list     LI_Get_Next,         &! Return the next Link after a given one     LI_Add_To_Head,      &! Add a Link to the head of the list     LI_Remove_Head,      &! Remove the first Link and return it     LI_Get_Len,          &! Compute list length     LI_Associated,       &! Check if list member is associated     LI_Nullify,          &! Resets a Link pointer to null     LI_Check_List,       &! Aborts program if list is invalid or corrupt     LI_Remove_Next        ! Remove next Link from list and return itTYPE Link_Type  PRIVATE  TYPE(Link_Type), POINTER :: NextEND TYPE Link_Type! Auxilliary data type required for the transfer function TYPE Link_Ptr_Type       ! Use TRANSFER() function to mold Link_Ptr_Type  PRIVATE                ! to your pointer type and vice versa  TYPE(Link_Type), POINTER :: PEND TYPE Link_Ptr_TypeTYPE List_Type               PRIVATE  TYPE(Link_Type) :: Head   ! Dummy Link always at head of listEND TYPE List_TypeCONTAINS!-----------------------------------------------------------------------SUBROUTINE Abort(Message)IMPLICIT NONECHARACTER *(*) MessageWRITE(6,*) MessageWRITE(6,*) 'Program aborted'STOPEND SUBROUTINE Abort!-----------------------------------------------------------------------SUBROUTINE LI_Check_List(List,Message)IMPLICIT NONETYPE(List_Type) ListCHARACTER *(*) MessageIF(.NOT.ASSOCIATED(List%Head%Next))THEN   WRITE(6,*) Message   CALL Abort('List is not initialised in call to LI_Check_List()')ENDIFEND SUBROUTINE LI_Check_List!-----------------------------------------------------------------------SUBROUTINE LI_Init_List(List)  IMPLICIT NONE  TYPE(List_Type),INTENT(INOUT),TARGET :: List  NULLIFY(List%Head%Next)  RETURNEND SUBROUTINE LI_Init_List!-----------------------------------------------------------------------SUBROUTINE LI_Add_To_Head(Link,List)  IMPLICIT NONE  TYPE(List_Type)    ,INTENT(INOUT) :: List  TYPE(Link_Ptr_Type),INTENT(INOUT) :: Link  Link%P%Next    => List%Head%Next  List%Head%Next => Link%P  RETURNEND SUBROUTINE LI_Add_To_Head!-----------------------------------------------------------------------INTEGER FUNCTION LI_Get_Len(List)  IMPLICIT NONE  TYPE(List_Type), INTENT(IN),TARGET :: LIST  TYPE(Link_Ptr_Type) :: Link  INTEGER N  Link%P => List%Head  N = 0  DO WHILE(ASSOCIATED(Link%P%Next))     Link%P => Link%P%Next     N = N+1  ENDDO  LI_Get_Len = N  RETURNEND FUNCTION LI_Get_Len!-----------------------------------------------------------------------FUNCTION LI_Associated(Link)  IMPLICIT NONE  LOGICAL :: LI_Associated  TYPE(Link_Ptr_Type),INTENT(IN) :: Link  LI_Associated = .FALSE.  IF(ASSOCIATED(Link%P))LI_Associated=.TRUE.  RETURNEND FUNCTION LI_Associated!-----------------------------------------------------------------------subroutine LI_Nullify(Link)  TYPE(Link_Ptr_Type),INTENT(OUT) :: Link  nullify(Link%P)  RETURNEND subroutine LI_Nullify!-----------------------------------------------------------------------FUNCTION LI_Get_Next(Link)  IMPLICIT NONE  Type(Link_Ptr_Type)           :: LI_Get_Next  TYPE(Link_Ptr_Type),INTENT(IN) :: Link  IF(.NOT.ASSOCIATED(Link%P%Next))THEN     NULLIFY(LI_Get_Next%P)  ELSE        LI_Get_Next%P => Link%P%Next  ENDIF  RETURNEND FUNCTION LI_Get_Next!-----------------------------------------------------------------------FUNCTION LI_Get_Head(List)  IMPLICIT NONE  TYPE(Link_Ptr_Type)               :: LI_Get_Head  TYPE(List_Type),INTENT(IN),TARGET :: List  LI_Get_Head%P => List%Head%Next  RETURNEND FUNCTION LI_Get_Head!-----------------------------------------------------------------------FUNCTION LI_Remove_Head(List)  IMPLICIT NONE  TYPE(Link_Ptr_Type)                  :: LI_Remove_Head  TYPE(List_Type),INTENT(INOUT),TARGET :: List  TYPE(Link_Ptr_Type) :: Link  Link%P => List%Head%Next  IF(ASSOCIATED(Link%P))THEN     List%Head%Next => Link%P%Next     NULLIFY(Link%P%Next)  ENDIF     LI_Remove_Head%P => Link%P  RETURNEND FUNCTION LI_Remove_Head!-----------------------------------------------------------------------function LI_Remove_Next(Link,List)  TYPE(Link_Ptr_Type) :: Link  TYPE(List_Type),INTENT(INOUT),TARGET :: List  TYPE(Link_Ptr_Type) :: Link_Dummy,LI_Remove_Next    if (Associated(Link%P)) then    Link_Dummy%P => Link%P%Next    if (Associated(Link_Dummy%P)) then      Link%P%Next => Link_Dummy%P%Next      nullify(Link_Dummy%P%Next)    endif    LI_Remove_Next%P => Link_Dummy%P    else    LI_Remove_Next = LI_Remove_Head(List)  endifend function LI_Remove_NextEND MODULE Generic_List

⌨️ 快捷键说明

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