|
DOUG 0.2
|
00001 ! DOUG - Domain decomposition On Unstructured Grids 00002 ! Copyright (C) 1998-2006 Faculty of Computer Science, University of Tartu and 00003 ! Department of Mathematics, University of Bath 00004 ! 00005 ! This library is free software; you can redistribute it and/or 00006 ! modify it under the terms of the GNU Lesser General Public 00007 ! License as published by the Free Software Foundation; either 00008 ! version 2.1 of the License, or (at your option) any later version. 00009 ! 00010 ! This library is distributed in the hope that it will be useful, 00011 ! but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 ! Lesser General Public License for more details. 00014 ! 00015 ! You should have received a copy of the GNU Lesser General Public 00016 ! License along with this library; if not, write to the Free Software 00017 ! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00018 ! or contact the authors (University of Tartu, Faculty of Computer Science, Chair 00019 ! of Distributed Systems, Liivi 2, 50409 Tartu, Estonia, http://dougdevel.org, 00020 ! mailto:info(at)dougdevel.org) 00021 00024 module Distribution_struct_mod 00025 use globals 00026 use Mesh_class 00027 use Distribution_base_mod 00028 use SpMtx_class 00029 use SpMtx_distribution_mod 00030 00031 implicit none 00032 00033 contains 00034 00036 function Distribution_struct_NewInit(n,ol) result(D) 00037 type(Distribution) :: D 00038 integer,intent(in) :: n !< number of nodes along each axis, total n*n 00039 integer,intent(in) :: ol !< overlap to other process regions 00040 00041 integer :: nrows !< number of sections along each axis 00042 integer,allocatable :: rowb(:) !< row bounds 00043 integer :: i,colblocks,irow,icol,ri,ci 00044 integer :: ri_s,ri_e,ci_s,ci_e,nnodes,nnz,mri 00045 00046 if (sctls%verbose>=1) write(stream,*) "INFO: Build structured distribution" 00047 00048 D = Distribution_New() 00049 call Mesh_Init(D%mesh, nell=n*n, ngf=n*n, nsd=-2, mfrelt=-3, nnode=n*n) 00050 D%mesh%parted = .true. 00051 D%mesh%nparts = numprocs 00052 00053 ! number of rows 00054 nrows = ceiling(sqrt(real(numprocs))) 00055 00056 ! row bounds, ie number of blocks in each row (index base 0) 00057 allocate(rowb(nrows+1)) 00058 do i=1,nrows+1 00059 rowb(i) = (i-1)*numprocs/nrows 00060 end do 00061 00062 ! load-balance the rows proportionally to the number of blocks in the row 00063 allocate(D%mesh%eptnmap(n*n)) 00064 do i=1,numprocs 00065 irow = (i-1)*nrows/numprocs + 1 00066 colblocks = rowb(irow+1)-rowb(irow) 00067 icol = (i-1)-rowb(irow) + 1 00068 if (sctls%verbose>=3) then 00069 write(stream,('(A,I0,A,I0,"-",I0,", ",I0,"-",I0)')) & 00070 "Block (process) ",i," rows and columns: ", & 00071 rowb(irow)*n/numprocs+1, rowb(irow+1)*n/numprocs, & 00072 (n*(icol-1)/colblocks)+1, n*icol/colblocks 00073 end if 00074 00075 ! mark nodes of each block 00076 ri_s = rowb(irow)*n/numprocs+1 00077 ri_e = rowb(irow+1)*n/numprocs 00078 ci_s = (n*(icol-1)/colblocks)+1 00079 ci_e = n*icol/colblocks 00080 do ri = ri_s,ri_e 00081 do ci = ci_s,ci_e 00082 D%mesh%eptnmap((ri-1)*n+ci) = i 00083 end do 00084 end do 00085 end do 00086 00087 ! generate local matrix with 2*ol expansion 00088 i = myrank+1 00089 irow = (i-1)*nrows/numprocs + 1 00090 colblocks = rowb(irow+1)-rowb(irow) 00091 icol = (i-1)-rowb(irow) + 1 00092 ri_s = rowb(irow)*n/numprocs+1 00093 ri_e = rowb(irow+1)*n/numprocs 00094 ci_s = (n*(icol-1)/colblocks)+1 00095 ci_e = n*icol/colblocks 00096 ri_s = max(1,ri_s-max(1,2*ol)) 00097 ri_e = min(n,ri_e+max(1,2*ol)) 00098 ci_s = max(1,ci_s-max(1,2*ol)) 00099 ci_e = min(n,ci_e+max(1,2*ol)) 00100 nnodes = (ri_e-ri_s+1)*(ci_e-ci_s+1) 00101 nnz = 5*nnodes-2*((ri_e-ri_s+1)+(ci_e-ci_s+1)) 00102 D%A = SpMtx_NewInit(nnz,nrows=n*n,ncols=n*n) ! specify nrows/ncols, otherwise arrange later fails 00103 nnz = 0 00104 do ri = ri_s,ri_e 00105 do ci = ci_s,ci_e 00106 mri = (ri-1)*n+ci ! matrix row index 00107 ! diagonal 00108 nnz = nnz+1 00109 D%A%indi(nnz) = mri 00110 D%A%indj(nnz) = mri 00111 D%A%val(nnz) = 4 00112 ! left 00113 if (ci>ci_s) then 00114 nnz = nnz+1 00115 D%A%indi(nnz) = mri 00116 D%A%indj(nnz) = mri-1 00117 D%A%val(nnz) = -1 00118 end if 00119 ! right 00120 if (ci<ci_e) then 00121 nnz = nnz+1 00122 D%A%indi(nnz) = mri 00123 D%A%indj(nnz) = mri+1 00124 D%A%val(nnz) = -1 00125 end if 00126 ! up 00127 if (ri>ri_s) then 00128 nnz = nnz+1 00129 D%A%indi(nnz) = mri 00130 D%A%indj(nnz) = mri-n 00131 D%A%val(nnz) = -1 00132 end if 00133 ! down 00134 if (ri<ri_e) then 00135 nnz = nnz+1 00136 D%A%indi(nnz) = mri 00137 D%A%indj(nnz) = mri+n 00138 D%A%val(nnz) = -1 00139 end if 00140 end do 00141 end do 00142 00143 ! localize matrix 00144 allocate(D%rhs(n*n)) 00145 D%rhs = -1 00146 call SpMtx_arrange(D%A, D_SpMtx_ARRNG_ROWS) 00147 call SpMtx_localize(D%A,D%A_ghost,D%rhs,D%mesh) 00148 end function Distribution_struct_NewInit 00149 end module Distribution_struct_mod
1.7.3-20110217