14 integer(kind=kint),
parameter :: DEBUG = 0
21 integer(kind=kint),
intent(in) :: n
22 integer(kind=kint),
intent(in) :: indexl(0:), indexu(0:)
23 integer(kind=kint),
intent(in) :: iteml(:), itemu(:)
24 integer(kind=kint),
intent(out) :: perm(:), iperm(:)
25 integer(kind=kint),
parameter :: nminmax = 5
26 integer(kind=kint) :: i, nmin
27 integer(kind=kint) :: mins(nminmax)
28 integer(kind=kint),
allocatable :: degs(:)
29 integer(kind=kint),
allocatable :: nlevel(:)
30 integer(kind=kint),
allocatable :: lv_index(:,:), lv_item(:,:)
31 integer(kind=kint) :: nlevel_max, max_id
33 call count_degrees(n, indexl, indexu, itemu, degs)
34 call find_minimum_degrees(n, degs, nminmax, nmin, mins)
35 allocate(nlevel(nmin), lv_index(0:n,nmin), lv_item(n,nmin))
41 call ordering_cm_inner(n, indexl, iteml, indexu, itemu, degs, mins(i), &
42 nlevel(i), lv_index(:,i), lv_item(:,i))
43 if (debug > 0)
write(*,*)
'DEBUG:: hecmw_matrix_ordering_CM: i, nstart, nlevel = ', i, mins(i), nlevel(i)
49 nlevel_max = nlevel(1)
52 if (nlevel(i) > nlevel_max)
then
53 nlevel_max = nlevel(i)
57 if (debug > 0)
write(*,*)
'DEBUG:: hecmw_matrix_ordering_CM: chose ordering',max_id
59 perm(i) = lv_item(i,max_id)
62 deallocate(nlevel, lv_index, lv_item)
68 integer(kind=kint),
intent(in) :: n
69 integer(kind=kint),
intent(in) :: indexl(0:), indexu(0:)
70 integer(kind=kint),
intent(in) :: iteml(:), itemu(:)
71 integer(kind=kint),
intent(out) :: perm(:), iperm(:)
73 call reverse_ordering(n, perm, iperm)
75 call write_nonzero_profile(n, indexl, iteml, indexu, itemu, perm, iperm)
76 call write_perm(n, perm, iperm)
80 subroutine ordering_cm_inner(N, indexL, itemL, indexU, itemU, degs, nstart, &
81 nlevel, lv_index, lv_item)
83 integer(kind=kint),
intent(in) :: n
84 integer(kind=kint),
intent(in) :: indexl(0:), indexu(0:)
85 integer(kind=kint),
intent(in) :: iteml(:), itemu(:)
86 integer(kind=kint),
intent(in) :: degs(:)
87 integer(kind=kint),
intent(in) :: nstart
88 integer(kind=kint),
intent(out) :: nlevel
89 integer(kind=kint),
intent(out) :: lv_index(0:)
90 integer(kind=kint),
intent(out) :: lv_item(:)
91 integer(kind=kint),
allocatable :: iwk(:)
92 integer(kind=kint) :: level, cntall, cnt, j, jnode, k, knode
105 prlv:
do j = lv_index(level-2)+1, lv_index(level-1)
108 do k = indexl(jnode-1)+1, indexl(jnode)
110 if (iwk(knode) == 0)
then
114 lv_item(cntall) = knode
118 do k = indexu(jnode-1)+1, indexu(jnode)
121 if (iwk(knode) == 0)
then
125 lv_item(cntall) = knode
131 if (debug > 0)
write(*,*)
'DEBUG: choose any uncolored node..'
133 if (iwk(knode) == 0)
then
137 lv_item(cntall) = knode
142 lv_index(level) = cntall
143 call sort_nodes_by_degree(lv_item, lv_index(level-1)+1, lv_index(level), degs)
144 if (cntall == n)
then
153 if (jnode <= 0 .or. jnode > n) stop
'ERROR: ordering_CM_inner: out of range'
154 if (iwk(jnode) < 0) stop
'ERROR: ordering_CM_inner: duplicated node found'
155 if (iwk(jnode) < level) stop
'ERROR: ordering_CM_inner: not in level order'
160 if (iwk(j) /= -1) stop
'ERROR: ordering_CM_inner: non-numbered node found'
164 end subroutine ordering_cm_inner
166 subroutine count_degrees(N, indexL, indexU, itemU, degs)
168 integer(kind=kint),
intent(in) :: n
169 integer(kind=kint),
intent(in) :: indexl(0:), indexu(0:)
170 integer(kind=kint),
intent(in) :: itemu(:)
171 integer(kind=kint),
intent(out) :: degs(:)
172 integer(kind=kint) :: i, j
174 degs(i) = indexl(i) - indexl(i-1)
175 do j = indexu(i-1)+1, indexu(i)
176 if (itemu(j) <= n) degs(i) = degs(i) + 1
179 end subroutine count_degrees
181 subroutine find_minimum_degrees(N, degs, nminmax, nmin, mins)
183 integer(kind=kint),
intent(in) :: n
184 integer(kind=kint),
intent(in) :: degs(:)
185 integer(kind=kint),
intent(in) :: nminmax
186 integer(kind=kint),
intent(out) :: nmin
187 integer(kind=kint),
intent(out) :: mins(nminmax)
188 integer(kind=kint) :: degmin, i, j
193 if (degs(i) == 0) cycle
194 if (degs(i) < degmin)
then
198 else if (degs(i) == degmin)
then
200 if (nmin <= nminmax) mins(nmin) = i
203 if (debug > 0)
write(*,*)
'DEBUG:: find_minimum_degrees: nmin, deg = ', nmin, degmin
204 if (nmin > nminmax) nmin = nminmax
205 end subroutine find_minimum_degrees
207 recursive subroutine sort_nodes_by_degree(lv_item, istart, iend, degs)
209 integer(kind=kint),
intent(inout) :: lv_item(:)
210 integer(kind=kint),
intent(in) :: istart, iend
211 integer(kind=kint),
intent(in) :: degs(:)
212 integer(kind=kint) :: pivot, left, right, itmp
213 if (istart >= iend)
return
214 pivot = degs(lv_item((istart + iend) / 2))
218 do while (degs(lv_item(left)) < pivot)
221 do while (pivot < degs(lv_item(right)))
224 if (left >= right)
exit
226 lv_item(left) = lv_item(right)
227 lv_item(right) = itmp
231 call sort_nodes_by_degree(lv_item, istart, left-1, degs)
232 call sort_nodes_by_degree(lv_item, right+1, iend, degs)
233 end subroutine sort_nodes_by_degree
235 subroutine reverse_ordering(N, perm, iperm)
237 integer(kind=kint),
intent(in) :: n
238 integer(kind=kint),
intent(inout) :: perm(:), iperm(:)
239 integer(kind=kint) :: i, n1
242 iperm(i) = n1 - iperm(i)
245 end subroutine reverse_ordering
247 subroutine write_nonzero_profile(N, indexL, itemL, indexU, itemU, perm, iperm)
249 integer(kind=kint),
intent(in) :: n
250 integer(kind=kint),
intent(in) :: indexl(0:), indexu(0:)
251 integer(kind=kint),
intent(in) :: iteml(:), itemu(:)
252 integer(kind=kint),
intent(in) :: perm(:), iperm(:)
253 integer(kind=kint),
parameter :: f_org = 901
254 integer(kind=kint),
parameter :: f_new = 902
255 integer(kind=kint) :: i, j, irow, jcol
256 open(f_org, file=
'nzprof_org.txt', status=
'replace')
259 do j = indexl(i-1)+1, indexl(i)
261 write(f_org,*) irow, jcol
263 do j = indexu(i-1)+1, indexu(i)
266 write(f_org,*) irow, jcol
270 open(f_new, file=
'nzprof_new.txt', status=
'replace')
273 do j = indexl(i-1)+1, indexl(i)
275 write(f_new,*) irow, iperm(jcol)
277 do j = indexu(i-1)+1, indexu(i)
280 write(f_new,*) irow, iperm(jcol)
284 end subroutine write_nonzero_profile
286 subroutine write_perm(N, perm, iperm)
288 integer(kind=kint),
intent(in) :: n
289 integer(kind=kint),
intent(in) :: perm(:), iperm(:)
290 integer(kind=kint),
parameter :: f_perm = 903
291 integer(kind=kint) :: i
292 open(f_perm, file=
'perm_iperm.txt', status=
'replace')
294 write(f_perm,*) i, perm(i), iperm(i)
297 end subroutine write_perm