|
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 00023 module Partitioning_aggr_mod 00024 use Partitioning_mod 00025 00026 implicit none 00027 00028 private 00029 public :: Partitionings_aggr_InitFine, Partitionings_aggr_InitCoarse 00030 contains 00031 00032 ! Create fine partitionings using aggregate method. 00033 subroutine Partitionings_aggr_InitFine(P,D) 00034 use SpMtx_class 00035 use Distribution_base_mod 00036 use Aggregate_utils_mod 00037 use SpMtx_aggregation 00038 00039 type(Distribution),intent(inout) :: D !< mesh and data distribution 00040 type(Partitionings),intent(inout) :: P !< output 00041 00042 type(SpMtx) :: LA !< matrix without outer nodes 00043 integer :: plotting 00044 integer :: min_asize1 00045 integer :: nnodes 00046 00047 00048 ! ------- Create fine aggregates 00049 if (P%levels<1) then 00050 P%levels = 1 00051 00052 if (sctls%strong1/=0.0_rk) then 00053 P%strong_conn1=sctls%strong1 00054 else 00055 P%strong_conn1=0.67_rk 00056 endif 00057 if (sctls%radius1>0) then 00058 P%aggr_radius1=sctls%radius1 00059 else 00060 P%aggr_radius1=2 00061 endif 00062 if (sctls%minasize1>0) then 00063 min_asize1=sctls%minasize1 00064 else 00065 ! Changes R. Scheichl 21/06/05 00066 ! min_asize1=2*aggr_radius1+1 00067 min_asize1=0.5_rk*(2*P%aggr_radius1+1)**2 00068 endif 00069 if (sctls%maxasize1>0) then 00070 P%max_asize1=sctls%maxasize1 00071 else 00072 P%max_asize1=(2*P%aggr_radius1+1)**2 00073 endif 00074 if (numprocs>1) then 00075 plotting=0 00076 else 00077 plotting=sctls%plotting 00078 endif 00079 00080 ! find fine aggregates 00081 if (numprocs > 1) then 00082 ! we need to create aggregates only on inner nodes, so use local matrix LA 00083 ! instead of expanded (to overlap) local matrix A 00084 LA = getLocal(D%A,D%mesh) 00085 call SpMtx_find_strong(A=LA,alpha=P%strong_conn1) 00086 call SpMtx_aggregate(LA,P%fAggr,P%aggr_radius1, & 00087 minaggrsize=min_asize1, & 00088 maxaggrsize=P%max_asize1, & 00089 alpha=p%strong_conn1, & 00090 M=D%mesh, & 00091 plotting=plotting) 00092 call SpMtx_unscale(LA) 00093 else 00094 ! non-parallel case use the whole matrix 00095 call SpMtx_find_strong(A=D%A,alpha=P%strong_conn1) 00096 call SpMtx_aggregate(D%A,P%fAggr,P%aggr_radius1, & 00097 minaggrsize=min_asize1, & 00098 maxaggrsize=P%max_asize1, & 00099 alpha=P%strong_conn1, & 00100 M=D%mesh, & 00101 plotting=plotting) 00102 call SpMtx_unscale(D%A) 00103 !call Aggrs_readFile_fine(D%A%aggr, "aggregates.txt") 00104 end if 00105 00106 ! set partitions 00107 P%fPart%nnodes = D%mesh%ninner 00108 P%fPart%nparts = P%fAggr%full%nagr 00109 allocate(P%fPart%starts(P%fPart%nparts+1)) 00110 allocate(P%fPart%nodes(P%fPart%nnodes)) 00111 00112 p%fPart%starts = P%fAggr%full%starts 00113 p%fPart%nodes = P%fAggr%full%nodes 00114 00115 end if 00116 00117 end subroutine Partitionings_aggr_InitFine 00118 00119 ! Create fine partitionings using aggregate method. 00120 subroutine Partitionings_aggr_InitCoarse(P,D,AC) 00121 use SpMtx_class 00122 use Distribution_base_mod 00123 use Aggregate_utils_mod 00124 use SpMtx_aggregation 00125 00126 type(Partitionings),intent(inout) :: P !< output 00127 type(Distribution),intent(inout) :: D !< mesh and data distribution 00128 type(SpMtx),intent(inout) :: AC !< Coarse matrix 00129 00130 integer :: n, cAggr, nnodes, start, end 00131 integer,allocatable :: nodes(:) 00132 integer :: aggr_radius2, min_asize2, max_asize2 00133 00134 call Partitionings_aggr_InitFine(P,D) 00135 00136 ! Create coarse aggregates 00137 if (P%levels<2) then 00138 P%levels = 2 00139 00140 if (sctls%strong2>0) then 00141 P%strong_conn2=sctls%strong2 00142 else 00143 P%strong_conn2=P%strong_conn1/2.0_rk 00144 endif 00145 call SpMtx_find_strong(AC,P%strong_conn2) 00146 00147 if (sctls%radius2>0) then 00148 aggr_radius2=sctls%radius2 00149 else 00150 n=sqrt(1.0_rk*D%A%nrows) 00151 aggr_radius2=nint(3*sqrt(dble(n))/(2*P%aggr_radius1+1)-1) 00152 write (stream,*) 'Coarse aggregation radius aggr_radius2 =',aggr_radius2 00153 endif 00154 if (sctls%minasize2>0) then 00155 min_asize2=sctls%minasize2 00156 elseif (sctls%radius2>0) then 00157 min_asize2=2*sctls%radius2+1 00158 else 00159 min_asize2=0.5_rk*(2*aggr_radius2+1)**2 00160 endif 00161 if (sctls%maxasize2>0) then 00162 max_asize2=sctls%maxasize2 00163 else 00164 !max_asize2=max_asize1 00165 max_asize2=(2*aggr_radius2+1)**2 00166 endif 00167 call SpMtx_aggregate(AC,P%cAggr,aggr_radius2, & 00168 minaggrsize=min_asize2, & 00169 maxaggrsize=max_asize2, & 00170 alpha=P%strong_conn2, & 00171 aggr_fine=P%fAggr) 00172 call SpMtx_unscale(AC) 00173 00174 ! set partitions 00175 P%cPart%nnodes = D%mesh%ninner 00176 P%cPart%nparts = P%cAggr%full%nagr 00177 allocate(P%cPart%starts(P%cPart%nparts+1)) 00178 allocate(P%cPart%nodes(P%cPart%nnodes)) 00179 00180 allocate(nodes(P%cPart%nnodes)) 00181 P%cPart%starts(1) = 1 00182 do cAggr=1,P%cAggr%full%nagr ! loop over coarse aggregates 00183 call Get_aggregate_nodes(cAggr,P%cAggr%full,P%fAggr%full,P%cPart%nnodes,nodes,nnodes) 00184 start = P%cPart%starts(cAggr) 00185 end = start+nnodes 00186 P%cPart%starts(cAggr+1) = end 00187 P%cPart%nodes(start:end-1) = nodes(1:nnodes) 00188 end do 00189 deallocate(nodes) 00190 00191 end if 00192 00193 end subroutine Partitionings_aggr_InitCoarse 00194 00195 end module Partitioning_aggr_mod
1.7.3-20110217