📄 rcm.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.! module rcmlib! Reverse Cuthill-McKee reordering! Subroutines by John Burkardt! http://www.csit.fsu.edu/~burkardt/f_src/rcm/rcm.html implicit none private public :: genrcm,perm_inverse containssubroutine degree ( root, adj_num, adj_row, adj, mask, deg, iccsze, ls, & node_num )!*******************************************************************************!!! DEGREE computes the degrees of the nodes in the connected component.!! Discussion:!! The connected component is specified by MASK and ROOT.! Nodes for which MASK is zero are ignored.!! Modified:!! 05 January 2003!! Reference:!! Alan George and J W Liu,! Computer Solution of Large Sparse Positive Definite Systems,! Prentice Hall, 1981.!! Parameters:!! Input, integer ROOT, the node that defines the connected component.!! Input, integer ADJ_NUM, the number of adjacency entries.!! Input, integer ADJ_ROW(NODE_NUM+1). Information about row I is stored! in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.!! Input, integer ADJ(ADJ_NUM), the adjacency structure.! For each row, it contains the column indices of the nonzero entries.!! Input, integer MASK(NODE_NUM), is nonzero for those nodes which are! to be considered.!! Output, integer DEG(NODE_NUM), contains, for each node in the connected! component, its degree.!! Output, integer ICCSIZE, the number of nodes in the connected component.!! Output, integer LS(NODE_NUM), stores in entries 1 through ICCSIZE the nodes! in the connected component, starting with ROOT, and proceeding ! by levels.!! Input, integer NODE_NUM, the number of nodes.! implicit none integer adj_num integer node_num integer adj(adj_num) integer adj_row(node_num+1) integer deg(node_num) integer i integer iccsze integer ideg integer j integer jstop integer jstrt integer lbegin integer ls(node_num) integer lvlend integer lvsize integer mask(node_num) integer nbr integer node integer root!! The sign of ADJ_ROW(I) is used to indicate if node I has been considered.! ls(1) = root adj_row(root) = -adj_row(root) lvlend = 0 iccsze = 1!! LBEGIN is the pointer to the beginning of the current level, and! LVLEND points to the end of this level.! do lbegin = lvlend + 1 lvlend = iccsze!! Find the degrees of nodes in the current level,! and at the same time, generate the next level.! do i = lbegin, lvlend node = ls(i) jstrt = -adj_row(node) jstop = abs ( adj_row(node+1) ) - 1 ideg = 0 do j = jstrt, jstop nbr = adj(j) if ( mask(nbr) /= 0 ) then ideg = ideg + 1 if ( 0 <= adj_row(nbr) ) then adj_row(nbr) = -adj_row(nbr) iccsze = iccsze + 1 ls(iccsze) = nbr end if end if end do deg(node) = ideg end do!! Compute the current level width.! lvsize = iccsze - lvlend!! If the current level width is nonzero, generate another level.! if ( lvsize == 0 ) then exit end if end do!! Reset ADJ_ROW to its correct sign and return.! do i = 1, iccsze node = ls(i) adj_row(node) = -adj_row(node) end do returnend subroutine degree subroutine genrcm ( node_num, adj_num, adj_row, adj, perm )!*******************************************************************************!!! GENRCM finds the reverse Cuthill-Mckee ordering for a general graph.!! Discussion:!! For each connected component in the graph, the routine obtains! an ordering by calling RCM.!! Modified:!! 04 January 2003!! Reference:!! Alan George and J W Liu,! Computer Solution of Large Sparse Positive Definite Systems,! Prentice Hall, 1981.!! Parameters:!! Input, integer NODE_NUM, the number of nodes.!! Input, integer ADJ_NUM, the number of adjacency entries.!! Input, integer ADJ_ROW(NODE_NUM+1). Information about row I is stored! in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.!! Input, integer ADJ(ADJ_NUM), the adjacency structure.! For each row, it contains the column indices of the nonzero entries.!! Output, integer PERM(NODE_NUM), the RCM ordering.!! Local Parameters:!! Local, integer LEVEL_ROW(NODE_NUM+1), the index vector for a level! structure. The level structure is stored in the currently unused ! spaces in the permutation vector PERM.!! Local, integer MASK(NODE_NUM), marks variables that have been numbered.! implicit none integer adj_num integer node_num integer adj(adj_num) integer adj_row(node_num+1) integer i integer iccsze integer mask(node_num) integer level_num integer level_row(node_num+1) integer num integer perm(node_num) integer root mask(1:node_num) = 1 num = 1 do i = 1, node_num!! For each masked connected component...! if ( mask(i) /= 0 ) then root = i!! Find a pseudo-peripheral node ROOT. The level structure found by! ROOT_FIND is stored starting at PERM(NUM).! call root_find ( root, adj_num, adj_row, adj, mask, level_num, & level_row, perm(num), node_num )!! RCM orders the component using ROOT as the starting node.! call rcm ( root, adj_num, adj_row, adj, mask, perm(num), iccsze, & node_num ) num = num + iccsze!! We can stop once every node is in one of the connected components.! if ( node_num < num ) then return end if end if end do returnend subroutine genrcm subroutine i_swap ( i, j )!*******************************************************************************!!! I_SWAP swaps two integer values.!! Modified:!! 30 November 1998!! Author:!! John Burkardt!! Parameters:!! Input/output, integer I, J. On output, the values of I and! J have been interchanged.! implicit none integer i integer j integer k k = i i = j j = k returnend subroutine i_swap subroutine ivec_reverse ( n, a )!*******************************************************************************!!! IVEC_REVERSE reverses the elements of an integer vector.!! Example:!! Input:!! N = 5,! A = ( 11, 12, 13, 14, 15 ).!! Output:!! A = ( 15, 14, 13, 12, 11 ).!! Modified:!! 26 July 1999!! Author:!! John Burkardt!! Parameters:!! Input, integer N, the number of entries in the array.!! Input/output, integer A(N), the array to be reversed.! implicit none integer n integer a(n) integer i do i = 1, n/2 call i_swap ( a(i), a(n+1-i) ) end do returnend subroutine ivec_reverse subroutine level_set ( root, adj_num, adj_row, adj, mask, level_num, & level_row, level, node_num )!*******************************************************************************!!! LEVEL_SET generates the connected level structure rooted at a given node.!! Discussion:!! Only nodes for which MASK is nonzero will be considered.!! The root node chosen by the user is assigned level 1, and masked.! All (unmasked) nodes reachable from a node in level 1 are! assigned level 2 and masked. The process continues until there! are no unmasked nodes adjacent to any node in the current level.! The number of levels may vary between 2 and NODE_NUM.!! Modified:!! 28 October 2003!! Reference:!! Alan George and J W Liu,! Computer Solution of Large Sparse Positive Definite Systems,! Prentice Hall, 1981.!! Parameters:!! Input, integer ROOT, the node at which the level structure! is to be rooted.!! Input, integer ADJ_NUM, the number of adjacency entries.!! Input, integer ADJ_ROW(NODE_NUM+1). Information about row I is stored! in entries ADJ_ROW(I) through ADJ_ROW(I+1)-1 of ADJ.!! Input, integer ADJ(ADJ_NUM), the adjacency structure.! For each row, it contains the column indices of the nonzero entries.!! Input/output, integer MASK(NODE_NUM). On input, only nodes with nonzero! MASK are to be processed. On output, those nodes which were included! in the level set have MASK set to 1.!! Output, integer LEVEL_NUM, the number of levels in the level! structure. ROOT is in level 1. The neighbors of ROOT! are in level 2, and so on.!! Output, integer LEVEL_ROW(NODE_NUM+1), LEVEL(NODE_NUM), the rooted ! level structure.!! Input, integer NODE_NUM, the number of nodes.! implicit none integer adj_num integer node_num integer adj(adj_num) integer adj_row(node_num+1) integer i integer iccsze integer j integer jstop integer jstrt integer lbegin integer level_num integer level_row(node_num+1) integer level(node_num) integer lvlend integer lvsize integer mask(node_num) integer nbr integer node integer root mask(root) = 0 level(1) = root level_num = 0 lvlend = 0 iccsze = 1!! LBEGIN is the pointer to the beginning of the current level, and! LVLEND points to the end of this level.!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -