! DOUG - Domain decomposition On Unstructured Grids ! Copyright (C) 1998-2006 Faculty of Computer Science, University of Tartu and ! Department of Mathematics, University of Bath ! ! This library is free software; you can redistribute it and/or ! modify it under the terms of the GNU Lesser General Public ! License as published by the Free Software Foundation; either ! version 2.1 of the License, or (at your option) any later version. ! ! This library is distributed in the hope that it will be useful, ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! Lesser General Public License for more details. ! ! You should have received a copy of the GNU Lesser General Public ! License along with this library; if not, write to the Free Software ! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ! or contact the authors (University of Tartu, Faculty of Computer Science, Chair ! of Distributed Systems, Liivi 2, 50409 Tartu, Estonia, http://dougdevel.org, ! mailto:info(at)dougdevel.org) !> Main program for running DOUG with input files in assembled form. !> \section aggregation_running Running the aggregation-based DOUG code: (example) !> mpirun -np 3 doug_aggr -f doug.ctl !> where \c doug.ctl may contain the following fields !> \subsection example Input-file example: !> \code !> solver 2 !> solve_maxiters 300 !> method 1 !> coarse_method 1 !> levels 2 !> overlap -1 !> smoothers 0 !> input_type 2 !> symmstruct T !> symmnumeric T !> # ################### !> # aggregate level 1: !> radius1 5 !> strong1 0.67e0 !> minasize1 2 !> #maxasize1 19 !> # aggregate level 2: !> radius2 35 !> strong2 0.67e0 !> minasize2 2 !> #maxasize2 96 !> # ################### !> matrix_type 1 !> number_of_blocks 1 !> initial_guess 2 !> start_vec_file ./NOT.DEFINED.start_vec_file !> start_vec_type 2 !> solve_tolerance 1.0e-12 !> solution_format 2 !> solution_file ./solution.file !> #debug -5 !> debug 0 !> verbose 0 !> plotting 1 !> assembled_mtx_file Hetero32.txt !> \endcode program main_aggr use doug use Distribution_mod use Partitioning_mod use Mesh_class use Mesh_plot_mod use SpMtx_mods use Vect_mod use DenseMtx_mod use solvers_mod use Aggregate_mod use Aggregate_utils_mod use CoarseMtx_mod use CoarseAllgathers use RobustCoarseMtx_mod use pcgRobust_mod implicit none #include #ifdef D_COMPLEX #define float complex #else #define float real #endif type(SpMtx) :: AC !< coarse matrix type(SpMtx) :: Restrict !< Restriction matrix (for operation) type(SumOfInversedSubMtx) :: B_RCS !< B matrix for the Robust Coarse Spaces !type(SpMtx) :: Rest_cmb !< Restriction matrix (for coarse matrix build) float(kind=rk), dimension(:), pointer :: xl !< local solution vector float(kind=rk), dimension(:), pointer :: x !< global solution on master float(kind=rk), dimension(:), pointer :: sol, rhs !< for testing solver real(kind=rk), pointer :: rhs_1(:), g(:) ! Partitioning integer :: nparts !< number of partitons to partition a mesh integer, dimension(6) :: part_opts = (/0,0,0,0,0,0/) type(ConvInf) :: resStat real(kind=rk) :: t,t1 integer :: i,j,k,it,ol float(kind=rk), dimension(:), pointer :: r, y character :: str character(len=40) :: frm float(kind=rk) :: cond_num,nrm integer,allocatable :: nodes(:), inds(:) type(Distribution) :: D !< mesh and matrix distribution type(Decomposition) :: DD !< domains type(Partitionings) :: P !< fine and coarse aggregates type(RobustPreconditionMtx) :: C type(CoarseSpace) :: CS ! Parallel coarse level !type(CoarseData) :: cdat -- moved into the module itself... ! Init DOUG call DOUG_Init() ! Master participates in calculations as well nparts = numprocs D = Distribution_NewInit(sctls%input_type,nparts,part_opts) if (sctls%levels>1.or.(numprocs==1.and.sctls%levels==1)) then !todo remove P = Partitionings_New() call Partitionings_CreateFine(P,D) ! profile info if(pstream/=0) then write(pstream, "(I0,':fine aggregates:',I0)") myrank, P%fAggr%inner%nagr end if !if (sctls%plotting>=2) then ! call SpMtx_writeLogicalValues(A, D%A%strong, 'strong.txt') !end if call Mesh_printInfo(D%mesh) if (numprocs==1.and.sctls%plotting==2.and.D%mesh%nell>0) then call Mesh_pl2D_plotAggregate(P%fAggr%inner,D%mesh,& D%A%strong_rowstart,D%A%strong_colnrs,& mctls%assembled_mtx_file, & INIT_CONT_END=D_PLPLOT_INIT) !D_PLPLOT_END) endif ! Testing coarse matrix and aggregation through it: if (numprocs>1) then call SpMtx_find_strong(A=D%A,alpha=P%strong_conn1,A_ghost=D%A_ghost) call SpMtx_exchange_strong(D%A,D%A_ghost,D%mesh) call SpMtx_symm_strong(D%A,D%A_ghost,.false.) call SpMtx_unscale(D%A) call IntRestBuild(D%A,P%fAggr%inner,Restrict,D%A_ghost) CS = CoarseSpace_Init(Restrict) call CoarseData_Copy(cdat,cdat_vec) call CoarseSpace_Expand(CS,Restrict,D%mesh,cdat) call CoarseMtxBuild(D%A,cdat%LAC,Restrict,D%mesh%ninner,D%A_ghost) call KeepGivenRowIndeces(Restrict, (/(i,i=1,P%fAggr%inner%nagr)/)) if (sctls%verbose>3.and.cdat%LAC%nnz<400) then write(stream,*)'Restrict (local) is:==================' call SpMtx_printRaw(A=Restrict) write(stream,*)'A coarse (local) is:==================' call SpMtx_printRaw(A=cdat%LAC) endif else ! non-parallel call IntRestBuild(D%A,P%fAggr%inner,Restrict) if (sctls%coarse_method<=1) then ! if not specified or ==1 call CoarseMtxBuild(D%A,AC,Restrict,D%mesh%ninner) else if (sctls%coarse_method==2) then ! use the Robust Coarse Spaces algorithm B_RCS = CoarseProjectionMtxsBuild(D%A,Restrict,P%fAggr%inner%nagr) allocate(rhs_1(D%A%nrows)) allocate(g(D%A%ncols)) rhs_1 = 1.0 call pcg_forRCS(B_RCS,rhs_1,g) if(sctls%verbose>5) then write (stream, *) "Solution g = ", g end if call RobustRestrictMtxBuild(B_RCS,g,Restrict) call CoarseMtxBuild(D%A,AC,Restrict,D%mesh%ninner) else write(stream,'(A," ",I2)') 'Wrong coarse method', sctls%coarse_method call DOUG_abort('Error in aggr', -1) endif if (sctls%verbose>3.and.AC%nnz<400) then write(stream,*)'A coarse is:==================' call SpMtx_printRaw(A=AC) endif endif ! coarse aggregates if (numprocs==1) then call Partitionings_CreateCoarse(P,D,AC) !call Aggrs_readFile_coarse(P%cAggr, "aggregates.txt") ! profile info if(pstream/=0) then write(pstream, "(I0,':coarse aggregates:',I0)") myrank, P%cAggr%inner%nagr end if if (sctls%plotting==2) then call Aggr_writeFile(P%fAggr%inner, 'aggr2.txt', P%cAggr%inner) end if if (sctls%plotting==2.and.D%mesh%nell>0) then !print *,'press Key' !read *,str call Mesh_pl2D_plotAggregate(P%fAggr%inner,D%mesh,& D%A%strong_rowstart,D%A%strong_colnrs,& mctls%assembled_mtx_file, & caggrnum=P%cAggr%inner%num, & INIT_CONT_END=D_PLPLOT_END)!, & !INIT_CONT_END=D_PLPLOT_CONT)!, & ! D_PLPLOT_END) endif write(stream,*)'# coarse aggregates:',P%cAggr%inner%nagr endif endif ! overlap for subdomains if (sctls%overlap<0) then ! autom. overlap from smoothing ol = max(sctls%smoothers,0) else ol = sctls%overlap endif if (numprocs==1) then DD = Decomposition_from_aggrs(D%A, P%cAggr%full, P%fAggr%full, ol) call AggrInfo_Destroy(P%cAggr) call AggrInfo_Destroy(P%fAggr) else DD = Decomposition_full(D%A,D%A_ghost,D%mesh%ninner,ol) ! call Aggrs_writeFile(M, P%fAggr, cdat, "aggregates.txt") if (sctls%levels>1) call AggrInfo_Destroy(P%fAggr) end if ! Testing UMFPACK: allocate(sol(D%A%nrows)) allocate(rhs(D%A%ncols)) ! Solve the system allocate(xl(D%mesh%nlf)) xl = 0.0_rk select case(sctls%solver) case (DCTL_SOLVE_CG) ! Conjugate gradient call cg(D%A, D%rhs, xl, D%mesh, solinf=resStat, resvects_=.true.) !call cg(A, b, xl, M, solinf=resStat) case (DCTL_SOLVE_PCG) ! Preconditioned conjugate gradient t1 = MPI_WTIME() if (sctls%levels==2) then write(stream,*)'calling pcg_weigs with coarse matrix' call pcg_weigs(A=D%A,b=D%rhs,x=xl,Msh=D%mesh,DomDec=DD,it=it,cond_num=cond_num, & A_interf_=D%A_ghost, & CoarseMtx_=AC,Restrict=Restrict, & refactor_=.true.) else write(stream,*)'calling pcg_weigs' call pcg_weigs(D%A, D%rhs, xl, D%mesh,DD,it,cond_num, & A_interf_=D%A_ghost, refactor_=.true.) endif t=MPI_WTIME()-t1 write(stream,*) 'time spent in pcg():',t t1=total_setup_time() write(stream,*) ' ...of which setup:',t1 write(stream,*) ' ...of which factorisation:', & total_factorisation_time() write(stream,*) 'solve time without setup:',t-t1 case default call DOUG_abort('[DOUG main] : Wrong solution method specified', -1) end select if (numprocs>1) then ! Assemble result on master if (ismaster()) then print *, "freedoms", D%mesh%ngf allocate(x(D%mesh%ngf)); x = 0.0_rk end if call Vect_Gather(xl, x, D%mesh) if (ismaster().and.sctls%verbose>2.and.(size(x) <= 100)) & call Vect_Print(x, 'sol > ') if (ismaster()) then call WriteSolutionToFile(x) end if else if (sctls%verbose>2.and.size(xl)<=100) then call Vect_Print(xl, 'sol > ') endif call WriteSolutionToFile(xl) endif ! Destroy objects call Mesh_Destroy(D%mesh) call SpMtx_Destroy(D%A) call ConvInf_Destroy(resStat) if (associated(xl)) deallocate(xl) if (associated(x)) deallocate(x) if (associated(sol)) deallocate(sol) call DOUG_Finalize() end program main_aggr