| 1 | ! DOUG - Domain decomposition On Unstructured Grids |
|---|
| 2 | ! Copyright (C) 1998-2006 Faculty of Computer Science, University of Tartu and |
|---|
| 3 | ! Department of Mathematics, University of Bath |
|---|
| 4 | ! |
|---|
| 5 | ! This library is free software; you can redistribute it and/or |
|---|
| 6 | ! modify it under the terms of the GNU Lesser General Public |
|---|
| 7 | ! License as published by the Free Software Foundation; either |
|---|
| 8 | ! version 2.1 of the License, or (at your option) any later version. |
|---|
| 9 | ! |
|---|
| 10 | ! This library is distributed in the hope that it will be useful, |
|---|
| 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 13 | ! Lesser General Public License for more details. |
|---|
| 14 | ! |
|---|
| 15 | ! You should have received a copy of the GNU Lesser General Public |
|---|
| 16 | ! License along with this library; if not, write to the Free Software |
|---|
| 17 | ! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|---|
| 18 | ! or contact the authors (University of Tartu, Faculty of Computer Science, Chair |
|---|
| 19 | ! of Distributed Systems, Liivi 2, 50409 Tartu, Estonia, http://dougdevel.org, |
|---|
| 20 | ! mailto:info(at)dougdevel.org) |
|---|
| 21 | |
|---|
| 22 | !> Main program for running DOUG with input files in assembled form. |
|---|
| 23 | !> \section aggregation_running Running the aggregation-based DOUG code: (example) |
|---|
| 24 | !> <tt>mpirun -np 3 doug_aggr -f doug.ctl</tt> |
|---|
| 25 | !> where \c doug.ctl may contain the following fields |
|---|
| 26 | !> \subsection example Input-file example: |
|---|
| 27 | !> \code |
|---|
| 28 | !> solver 2 |
|---|
| 29 | !> solve_maxiters 300 |
|---|
| 30 | !> method 1 |
|---|
| 31 | !> coarse_method 1 |
|---|
| 32 | !> levels 2 |
|---|
| 33 | !> overlap -1 |
|---|
| 34 | !> smoothers 0 |
|---|
| 35 | !> input_type 2 |
|---|
| 36 | !> symmstruct T |
|---|
| 37 | !> symmnumeric T |
|---|
| 38 | !> # ################### |
|---|
| 39 | !> # aggregate level 1: |
|---|
| 40 | !> radius1 5 |
|---|
| 41 | !> strong1 0.67e0 |
|---|
| 42 | !> minasize1 2 |
|---|
| 43 | !> #maxasize1 19 |
|---|
| 44 | !> # aggregate level 2: |
|---|
| 45 | !> radius2 35 |
|---|
| 46 | !> strong2 0.67e0 |
|---|
| 47 | !> minasize2 2 |
|---|
| 48 | !> #maxasize2 96 |
|---|
| 49 | !> # ################### |
|---|
| 50 | !> matrix_type 1 |
|---|
| 51 | !> number_of_blocks 1 |
|---|
| 52 | !> initial_guess 2 |
|---|
| 53 | !> start_vec_file ./NOT.DEFINED.start_vec_file |
|---|
| 54 | !> start_vec_type 2 |
|---|
| 55 | !> solve_tolerance 1.0e-12 |
|---|
| 56 | !> solution_format 2 |
|---|
| 57 | !> solution_file ./solution.file |
|---|
| 58 | !> #debug -5 |
|---|
| 59 | !> debug 0 |
|---|
| 60 | !> verbose 0 |
|---|
| 61 | !> plotting 1 |
|---|
| 62 | !> assembled_mtx_file Hetero32.txt |
|---|
| 63 | !> \endcode |
|---|
| 64 | program main_aggr |
|---|
| 65 | |
|---|
| 66 | use doug |
|---|
| 67 | use Distribution_mod |
|---|
| 68 | use Partitioning_mod |
|---|
| 69 | use Preconditioner_mod |
|---|
| 70 | use FinePreconditioner_complete_mod |
|---|
| 71 | use Mesh_class |
|---|
| 72 | use Mesh_plot_mod |
|---|
| 73 | use SpMtx_mods |
|---|
| 74 | use Vect_mod |
|---|
| 75 | use DenseMtx_mod |
|---|
| 76 | use solvers_mod |
|---|
| 77 | use Aggregate_mod |
|---|
| 78 | use Aggregate_utils_mod |
|---|
| 79 | use CoarseMtx_mod |
|---|
| 80 | use CoarseAllgathers |
|---|
| 81 | use RobustCoarseMtx_mod |
|---|
| 82 | use pcgRobust_mod |
|---|
| 83 | |
|---|
| 84 | implicit none |
|---|
| 85 | |
|---|
| 86 | #include<doug_config.h> |
|---|
| 87 | |
|---|
| 88 | #ifdef D_COMPLEX |
|---|
| 89 | #define float complex |
|---|
| 90 | #else |
|---|
| 91 | #define float real |
|---|
| 92 | #endif |
|---|
| 93 | |
|---|
| 94 | type(SumOfInversedSubMtx) :: B_RCS !< B matrix for the Robust Coarse Spaces |
|---|
| 95 | !type(SpMtx) :: Rest_cmb !< Restriction matrix (for coarse matrix build) |
|---|
| 96 | |
|---|
| 97 | float(kind=rk), dimension(:), pointer :: xl !< local solution vector |
|---|
| 98 | float(kind=rk), dimension(:), pointer :: x !< global solution on master |
|---|
| 99 | float(kind=rk), dimension(:), pointer :: sol, rhs !< for testing solver |
|---|
| 100 | real(kind=rk), pointer :: rhs_1(:), g(:) |
|---|
| 101 | |
|---|
| 102 | ! Partitioning |
|---|
| 103 | integer :: nparts !< number of partitons to partition a mesh |
|---|
| 104 | integer, dimension(6) :: part_opts = (/0,0,0,0,0,0/) |
|---|
| 105 | |
|---|
| 106 | type(ConvInf) :: resStat |
|---|
| 107 | |
|---|
| 108 | real(kind=rk) :: t,t1 |
|---|
| 109 | integer :: i,j,k,it,ol |
|---|
| 110 | float(kind=rk), dimension(:), pointer :: r, y |
|---|
| 111 | character :: str |
|---|
| 112 | character(len=40) :: frm |
|---|
| 113 | float(kind=rk) :: cond_num,nrm |
|---|
| 114 | integer,allocatable :: nodes(:), inds(:) |
|---|
| 115 | |
|---|
| 116 | type(Distribution) :: D !< mesh and matrix distribution |
|---|
| 117 | type(Partitionings) :: P !< fine and coarse aggregates |
|---|
| 118 | type(FinePreconditioner) :: FP |
|---|
| 119 | type(CoarsePreconditioner) :: CP |
|---|
| 120 | type(RobustPreconditionMtx) :: C |
|---|
| 121 | type(CoarseSpace) :: CS |
|---|
| 122 | integer,pointer :: aggrnum(:) |
|---|
| 123 | integer :: nagr |
|---|
| 124 | |
|---|
| 125 | ! Init DOUG |
|---|
| 126 | call DOUG_Init() |
|---|
| 127 | |
|---|
| 128 | ! Master participates in calculations as well |
|---|
| 129 | nparts = numprocs |
|---|
| 130 | |
|---|
| 131 | D = Distribution_NewInit(sctls%input_type,nparts,part_opts) |
|---|
| 132 | |
|---|
| 133 | if (sctls%levels>1.or.(numprocs==1.and.sctls%levels==1)) then !todo remove |
|---|
| 134 | P = Partitionings_New() |
|---|
| 135 | call Partitionings_CreateFine(P,D) |
|---|
| 136 | ! profile info |
|---|
| 137 | if(pstream/=0) then |
|---|
| 138 | write(pstream, "(I0,':fine aggregates:',I0)") myrank, P%fAggr%inner%nagr |
|---|
| 139 | end if |
|---|
| 140 | |
|---|
| 141 | !if (sctls%plotting>=2) then |
|---|
| 142 | ! call SpMtx_writeLogicalValues(A, D%A%strong, 'strong.txt') |
|---|
| 143 | !end if |
|---|
| 144 | |
|---|
| 145 | call Mesh_printInfo(D%mesh) |
|---|
| 146 | |
|---|
| 147 | if (numprocs==1.and.sctls%plotting==2.and.D%mesh%nell>0) then |
|---|
| 148 | call Mesh_pl2D_plotAggregate(P%fAggr%inner,D%mesh,& |
|---|
| 149 | D%A%strong_rowstart,D%A%strong_colnrs,& |
|---|
| 150 | mctls%assembled_mtx_file, & |
|---|
| 151 | INIT_CONT_END=D_PLPLOT_INIT) |
|---|
| 152 | !D_PLPLOT_END) |
|---|
| 153 | endif |
|---|
| 154 | |
|---|
| 155 | CP = CoarsePreconditioner_New() |
|---|
| 156 | ! Testing coarse matrix and aggregation through it: |
|---|
| 157 | if (numprocs>1) then |
|---|
| 158 | CP%type = COARSE_PRECONDITIONER_TYPE_SMOOTH |
|---|
| 159 | allocate(aggrnum(D%mesh%nlf)) |
|---|
| 160 | nagr = P%fAggr%inner%nagr |
|---|
| 161 | aggrnum = 0 |
|---|
| 162 | aggrnum(1:D%mesh%ninner) = P%fAggr%inner%num |
|---|
| 163 | call setup_aggr_cdat(CP%cdat, CP%cdat_vec, nagr, D%mesh%ninner,aggrnum,D%mesh) |
|---|
| 164 | |
|---|
| 165 | call SpMtx_find_strong(A=D%A,alpha=P%strong_conn1,A_ghost=D%A_ghost) |
|---|
| 166 | call SpMtx_exchange_strong(D%A,D%A_ghost,D%mesh) |
|---|
| 167 | call SpMtx_symm_strong(D%A,D%A_ghost,.false.) |
|---|
| 168 | call SpMtx_unscale(D%A) |
|---|
| 169 | |
|---|
| 170 | call IntRestBuild(D%A,P%fAggr%inner,CP%R,D%A_ghost) |
|---|
| 171 | CS = CoarseSpace_Init(CP%R) |
|---|
| 172 | call CoarseData_Copy(CP%cdat,CP%cdat_vec) |
|---|
| 173 | call CoarseSpace_Expand(CS,CP%R,D%mesh,CP%cdat) |
|---|
| 174 | call CoarseMtxBuild(D%A,CP%cdat%LAC,CP%R,D%mesh%ninner,D%A_ghost) |
|---|
| 175 | call KeepGivenRowIndeces(CP%R, (/(i,i=1,P%fAggr%inner%nagr)/)) |
|---|
| 176 | |
|---|
| 177 | if (sctls%verbose>3.and.CP%cdat%LAC%nnz<400) then |
|---|
| 178 | write(stream,*)'CP%R (local) is:==================' |
|---|
| 179 | call SpMtx_printRaw(A=CP%R) |
|---|
| 180 | write(stream,*)'A coarse (local) is:==================' |
|---|
| 181 | call SpMtx_printRaw(A=CP%cdat%LAC) |
|---|
| 182 | endif |
|---|
| 183 | |
|---|
| 184 | else |
|---|
| 185 | ! non-parallel |
|---|
| 186 | call IntRestBuild(D%A,P%fAggr%inner,CP%R) |
|---|
| 187 | |
|---|
| 188 | if (sctls%coarse_method<=1) then ! if not specified or ==1 |
|---|
| 189 | CP%type = COARSE_PRECONDITIONER_TYPE_SMOOTH |
|---|
| 190 | call CoarseMtxBuild(D%A,CP%AC,CP%R,D%mesh%ninner) |
|---|
| 191 | |
|---|
| 192 | else if (sctls%coarse_method==2) then |
|---|
| 193 | ! use the Robust Coarse Spaces algorithm |
|---|
| 194 | CP%type = COARSE_PRECONDITIONER_TYPE_ROBUST |
|---|
| 195 | |
|---|
| 196 | B_RCS = CoarseProjectionMtxsBuild(D%A,CP%R,P%fAggr%inner%nagr) |
|---|
| 197 | allocate(rhs_1(D%A%nrows)) |
|---|
| 198 | allocate(g(D%A%ncols)) |
|---|
| 199 | |
|---|
| 200 | rhs_1 = 1.0 |
|---|
| 201 | call pcg_forRCS(B_RCS,rhs_1,g) |
|---|
| 202 | |
|---|
| 203 | if(sctls%verbose>5) then |
|---|
| 204 | write (stream, *) "Solution g = ", g |
|---|
| 205 | end if |
|---|
| 206 | |
|---|
| 207 | call RobustRestrictMtxBuild(B_RCS,g,CP%R) |
|---|
| 208 | call CoarseMtxBuild(D%A,CP%AC,CP%R,D%mesh%ninner) |
|---|
| 209 | |
|---|
| 210 | else |
|---|
| 211 | write(stream,'(A," ",I2)') 'Wrong coarse method', sctls%coarse_method |
|---|
| 212 | call DOUG_abort('Error in aggr', -1) |
|---|
| 213 | endif |
|---|
| 214 | |
|---|
| 215 | if (sctls%verbose>3.and.CP%AC%nnz<400) then |
|---|
| 216 | write(stream,*)'A coarse is:==================' |
|---|
| 217 | call SpMtx_printRaw(A=CP%AC) |
|---|
| 218 | endif |
|---|
| 219 | endif |
|---|
| 220 | |
|---|
| 221 | ! coarse aggregates |
|---|
| 222 | if (numprocs==1) then |
|---|
| 223 | call Partitionings_CreateCoarse(P,D,CP%AC) |
|---|
| 224 | !call Aggrs_readFile_coarse(P%cAggr, "aggregates.txt") |
|---|
| 225 | |
|---|
| 226 | ! profile info |
|---|
| 227 | if(pstream/=0) then |
|---|
| 228 | write(pstream, "(I0,':coarse aggregates:',I0)") myrank, P%cAggr%inner%nagr |
|---|
| 229 | end if |
|---|
| 230 | |
|---|
| 231 | if (sctls%plotting==2) then |
|---|
| 232 | call Aggr_writeFile(P%fAggr%inner, 'aggr2.txt', P%cAggr%inner) |
|---|
| 233 | end if |
|---|
| 234 | if (sctls%plotting==2.and.D%mesh%nell>0) then |
|---|
| 235 | !print *,'press Key<Enter>' |
|---|
| 236 | !read *,str |
|---|
| 237 | call Mesh_pl2D_plotAggregate(P%fAggr%inner,D%mesh,& |
|---|
| 238 | D%A%strong_rowstart,D%A%strong_colnrs,& |
|---|
| 239 | mctls%assembled_mtx_file, & |
|---|
| 240 | caggrnum=P%cAggr%inner%num, & |
|---|
| 241 | INIT_CONT_END=D_PLPLOT_END)!, & |
|---|
| 242 | !INIT_CONT_END=D_PLPLOT_CONT)!, & |
|---|
| 243 | ! D_PLPLOT_END) |
|---|
| 244 | endif |
|---|
| 245 | write(stream,*)'# coarse aggregates:',P%cAggr%inner%nagr |
|---|
| 246 | |
|---|
| 247 | endif |
|---|
| 248 | endif |
|---|
| 249 | |
|---|
| 250 | ! overlap for subdomains |
|---|
| 251 | if (sctls%overlap<0) then ! autom. overlap from smoothing |
|---|
| 252 | ol = max(sctls%smoothers,0) |
|---|
| 253 | else |
|---|
| 254 | ol = sctls%overlap |
|---|
| 255 | endif |
|---|
| 256 | |
|---|
| 257 | FP = FinePreconditioner_New(D) |
|---|
| 258 | if (numprocs==1) then |
|---|
| 259 | call FinePreconditioner_InitAggrs(FP, D, P, ol) |
|---|
| 260 | call FinePreconditioner_complete_Init(FP) |
|---|
| 261 | call AggrInfo_Destroy(P%cAggr) |
|---|
| 262 | call AggrInfo_Destroy(P%fAggr) |
|---|
| 263 | else |
|---|
| 264 | call FinePreconditioner_InitFull(FP, D, ol) |
|---|
| 265 | call FinePreconditioner_complete_Init(FP) |
|---|
| 266 | ! call Aggrs_writeFile(M, P%fAggr, CP%cdat, "aggregates.txt") |
|---|
| 267 | if (sctls%levels>1) call AggrInfo_Destroy(P%fAggr) |
|---|
| 268 | end if |
|---|
| 269 | |
|---|
| 270 | ! Testing UMFPACK: |
|---|
| 271 | allocate(sol(D%A%nrows)) |
|---|
| 272 | allocate(rhs(D%A%ncols)) |
|---|
| 273 | |
|---|
| 274 | ! Solve the system |
|---|
| 275 | allocate(xl(D%mesh%nlf)) |
|---|
| 276 | xl = 0.0_rk |
|---|
| 277 | |
|---|
| 278 | select case(sctls%solver) |
|---|
| 279 | case (DCTL_SOLVE_CG) |
|---|
| 280 | ! Conjugate gradient |
|---|
| 281 | call cg(D%A, D%rhs, xl, D%mesh, solinf=resStat, resvects_=.true.) |
|---|
| 282 | !call cg(A, b, xl, M, solinf=resStat) |
|---|
| 283 | case (DCTL_SOLVE_PCG) |
|---|
| 284 | ! Preconditioned conjugate gradient |
|---|
| 285 | t1 = MPI_WTIME() |
|---|
| 286 | write(stream,*)'calling pcg_weigs' |
|---|
| 287 | call pcg_weigs(A=D%A,b=D%rhs,x=xl,Msh=D%mesh,& |
|---|
| 288 | finePrec=FP,coarsePrec=CP,& |
|---|
| 289 | it=it,cond_num=cond_num, A_interf_=D%A_ghost, & |
|---|
| 290 | refactor_=.true.) |
|---|
| 291 | t=MPI_WTIME()-t1 |
|---|
| 292 | write(stream,*) 'time spent in pcg():',t |
|---|
| 293 | t1=total_setup_time() |
|---|
| 294 | write(stream,*) ' ...of which setup:',t1 |
|---|
| 295 | write(stream,*) ' ...of which factorisation:', & |
|---|
| 296 | total_factorisation_time() |
|---|
| 297 | write(stream,*) 'solve time without setup:',t-t1 |
|---|
| 298 | case default |
|---|
| 299 | call DOUG_abort('[DOUG main] : Wrong solution method specified', -1) |
|---|
| 300 | end select |
|---|
| 301 | |
|---|
| 302 | if (numprocs>1) then |
|---|
| 303 | ! Assemble result on master |
|---|
| 304 | if (ismaster()) then |
|---|
| 305 | print *, "freedoms", D%mesh%ngf |
|---|
| 306 | allocate(x(D%mesh%ngf)); x = 0.0_rk |
|---|
| 307 | end if |
|---|
| 308 | call Vect_Gather(xl, x, D%mesh) |
|---|
| 309 | if (ismaster().and.sctls%verbose>2.and.(size(x) <= 100)) & |
|---|
| 310 | call Vect_Print(x, 'sol > ') |
|---|
| 311 | if (ismaster()) then |
|---|
| 312 | call WriteSolutionToFile(x) |
|---|
| 313 | end if |
|---|
| 314 | |
|---|
| 315 | else |
|---|
| 316 | if (sctls%verbose>2.and.size(xl)<=100) then |
|---|
| 317 | call Vect_Print(xl, 'sol > ') |
|---|
| 318 | endif |
|---|
| 319 | call WriteSolutionToFile(xl) |
|---|
| 320 | endif |
|---|
| 321 | |
|---|
| 322 | |
|---|
| 323 | ! Destroy objects |
|---|
| 324 | call Mesh_Destroy(D%mesh) |
|---|
| 325 | call SpMtx_Destroy(D%A) |
|---|
| 326 | call ConvInf_Destroy(resStat) |
|---|
| 327 | if (associated(xl)) deallocate(xl) |
|---|
| 328 | if (associated(x)) deallocate(x) |
|---|
| 329 | if (associated(sol)) deallocate(sol) |
|---|
| 330 | |
|---|
| 331 | call DOUG_Finalize() |
|---|
| 332 | |
|---|
| 333 | |
|---|
| 334 | end program main_aggr |
|---|