| 1 | module Aggregate_utils_mod |
|---|
| 2 | use Aggregate_mod |
|---|
| 3 | use CoarseAllgathers |
|---|
| 4 | implicit none |
|---|
| 5 | |
|---|
| 6 | contains |
|---|
| 7 | |
|---|
| 8 | !> Write out aggregates to the specified file. |
|---|
| 9 | !! If coarse aggregates are specified then it used to map fine aggregates to |
|---|
| 10 | !! coarse aggregates and write coarse aggregate numbers to file. |
|---|
| 11 | subroutine Aggr_writeFile(aggr, filename, caggr) |
|---|
| 12 | type(Aggrs), intent(in) :: aggr !< fine aggregates |
|---|
| 13 | character(*) :: filename |
|---|
| 14 | type(Aggrs), intent(in), optional :: caggr !< coarse aggregates |
|---|
| 15 | integer :: i |
|---|
| 16 | |
|---|
| 17 | open(78, file=filename) |
|---|
| 18 | if (.NOT.present(caggr)) then |
|---|
| 19 | write (78,*) aggr%nagr, size(aggr%num) |
|---|
| 20 | do i=1,size(aggr%num) |
|---|
| 21 | write (78,*) aggr%num(i) |
|---|
| 22 | end do |
|---|
| 23 | else |
|---|
| 24 | write (78,*) caggr%nagr, size(aggr%num) |
|---|
| 25 | do i=1,size(aggr%num) |
|---|
| 26 | write (78,*) caggr%num(aggr%num(i)) |
|---|
| 27 | end do |
|---|
| 28 | end if |
|---|
| 29 | close(78) |
|---|
| 30 | end subroutine Aggr_writeFile |
|---|
| 31 | |
|---|
| 32 | !> Write all aggregates to file for testing with non-paralel case. |
|---|
| 33 | subroutine Aggrs_writeFile(M, fAggr, cdata, filename) |
|---|
| 34 | type(Mesh), intent(in) :: M |
|---|
| 35 | type(AggrInfo), intent(in) :: fAggr |
|---|
| 36 | type(CoarseData), intent(in) :: cdata |
|---|
| 37 | character(*), intent(in) :: filename |
|---|
| 38 | |
|---|
| 39 | integer :: ierr, i, fd, k, l |
|---|
| 40 | integer, allocatable :: sizes(:), disps(:), nodes(:), locs(:), allnodes(:) |
|---|
| 41 | integer :: nnodes |
|---|
| 42 | |
|---|
| 43 | fd = 79 |
|---|
| 44 | if (ismaster()) then |
|---|
| 45 | open(fd, file=filename) |
|---|
| 46 | allocate(sizes(numprocs)) |
|---|
| 47 | end if |
|---|
| 48 | |
|---|
| 49 | call MPI_Gather(size(fAggr%inner%num), 1, MPI_INTEGER, sizes, 1, MPI_INTEGER, & |
|---|
| 50 | 0, MPI_COMM_WORLD, ierr) |
|---|
| 51 | |
|---|
| 52 | if (ismaster()) then |
|---|
| 53 | nnodes = sum(sizes) |
|---|
| 54 | write(fd,*) nnodes |
|---|
| 55 | allocate(nodes(nnodes)) |
|---|
| 56 | allocate(locs(nnodes)) |
|---|
| 57 | allocate(disps(numprocs)) |
|---|
| 58 | |
|---|
| 59 | ! scan |
|---|
| 60 | disps(1) = 0 |
|---|
| 61 | do i=2,numprocs |
|---|
| 62 | disps(i) = disps(i-1)+sizes(i-1) |
|---|
| 63 | end do |
|---|
| 64 | end if |
|---|
| 65 | |
|---|
| 66 | call MPI_Gatherv(M%lg_fmap, M%ninner, MPI_INTEGER, & |
|---|
| 67 | locs, sizes, disps, MPI_INTEGER, & |
|---|
| 68 | 0, MPI_COMM_WORLD, ierr) |
|---|
| 69 | call MPI_Gatherv(cdat%lg_cfmap(fAggr%inner%num), size(fAggr%inner%num), MPI_INTEGER, & |
|---|
| 70 | nodes, sizes, disps, MPI_INTEGER, & |
|---|
| 71 | 0, MPI_COMM_WORLD, ierr) |
|---|
| 72 | |
|---|
| 73 | if (ismaster()) then |
|---|
| 74 | allocate(allnodes(nnodes)) |
|---|
| 75 | do i=1,numprocs |
|---|
| 76 | allnodes(locs) = nodes |
|---|
| 77 | end do |
|---|
| 78 | write(fd,*) allnodes |
|---|
| 79 | end if |
|---|
| 80 | |
|---|
| 81 | ! write coarse aggregate info |
|---|
| 82 | call MPI_Gather(fAggr%inner%nagr, 1, MPI_INTEGER, sizes, 1, MPI_INTEGER, & |
|---|
| 83 | 0, MPI_COMM_WORLD, ierr) |
|---|
| 84 | |
|---|
| 85 | k = 0 |
|---|
| 86 | if (ismaster()) then |
|---|
| 87 | write(fd,*) sum(sizes) |
|---|
| 88 | ! assume that coarse aggregates are numbered by process |
|---|
| 89 | do i=1,numprocs |
|---|
| 90 | write(fd,*) (/(i, l=1,k+sizes(i))/) |
|---|
| 91 | k = k+sizes(i) |
|---|
| 92 | end do |
|---|
| 93 | |
|---|
| 94 | deallocate(sizes, disps, nodes) |
|---|
| 95 | end if |
|---|
| 96 | |
|---|
| 97 | end subroutine Aggrs_writeFile |
|---|
| 98 | |
|---|
| 99 | !> Read fine aggregates from file for testing with non-paralel case. |
|---|
| 100 | subroutine Aggrs_readFile_fine(aggr, filename) |
|---|
| 101 | type(AggrInfo), intent(inout) :: aggr |
|---|
| 102 | character(*), intent(in) :: filename |
|---|
| 103 | |
|---|
| 104 | integer :: fd, nnodes, nagr |
|---|
| 105 | integer, allocatable :: nodes(:) |
|---|
| 106 | |
|---|
| 107 | fd = 79 |
|---|
| 108 | open(fd, file=filename, status='OLD') |
|---|
| 109 | |
|---|
| 110 | read(fd,*) nnodes |
|---|
| 111 | allocate(nodes(nnodes)) |
|---|
| 112 | read(fd,*) nodes |
|---|
| 113 | nagr = maxval(nodes) |
|---|
| 114 | call Form_Aggr(aggr%inner, nagr, nnodes, 2, 0, nodes) |
|---|
| 115 | call Form_Aggr(aggr%full, nagr, nnodes, 2, 0, nodes) |
|---|
| 116 | |
|---|
| 117 | end subroutine Aggrs_readFile_fine |
|---|
| 118 | |
|---|
| 119 | !> Read coarse aggregates from file for testing with non-paralel case. |
|---|
| 120 | subroutine Aggrs_readFile_coarse(aggr, filename) |
|---|
| 121 | type(AggrInfo), intent(inout) :: aggr |
|---|
| 122 | character(*), intent(in) :: filename |
|---|
| 123 | |
|---|
| 124 | integer :: fd, nnodes, nagr |
|---|
| 125 | integer, allocatable :: nodes(:) |
|---|
| 126 | |
|---|
| 127 | fd = 79 |
|---|
| 128 | |
|---|
| 129 | read(fd,*) nnodes |
|---|
| 130 | allocate(nodes(nnodes)) |
|---|
| 131 | read(fd,*) nodes |
|---|
| 132 | nagr = maxval(nodes) |
|---|
| 133 | call Form_Aggr(aggr%inner, nagr, nnodes, 2, 0, nodes) |
|---|
| 134 | call Form_Aggr(aggr%full, nagr, nnodes, 2, 0, nodes) |
|---|
| 135 | |
|---|
| 136 | close(fd) |
|---|
| 137 | end subroutine Aggrs_readFile_coarse |
|---|
| 138 | |
|---|
| 139 | end module Aggregate_utils_mod |
|---|