DOUG 0.2

Partitioning_aggr.F90

Go to the documentation of this file.
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