source: src/main/geom.F90 @ b378423

Revision b378423, 8.9 KB checked in by Oleg Batrashev <ogbash@…>, 2 years ago (diff)

Factor out Aggregates from sparse matrix structure.

  • Property mode set to 100644
Line 
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 elemental form.
23!> Running the code: (example)
24!>   <tt>mpirun -np 3 doug_geom -f doug.ctl</tt>
25!>     where \c doug.ctl may contain the following fields
26!!
27!! See \ref p_inputformat page for input description.
28
29program main_geom
30
31  use doug
32  use main_drivers
33  use Mesh_class
34  use SpMtx_mods
35  use Vect_mod
36  use DenseMtx_mod
37  use solvers_mod
38  use CoarseGrid_class
39  use TransmitCoarse
40  use CoarseAllgathers
41  use CreateCoarseGrid
42  use CoarseCreateRestrict
43  use CoarseMtx_mod
44
45  implicit none
46
47#include<doug_config.h>
48
49#ifdef D_COMPLEX
50#define float complex
51#else
52#define float real
53#endif
54
55  type(Mesh), target     :: M  !< Mesh
56
57  type(SpMtx)    :: A, A_interf  ! System matrix (parallel sparse matrix)
58  type(SpMtx)    :: AC  ! Coarse matrix
59  type(SpMtx)    :: Restrict ! Restriction matrix
60
61  float(kind=rk), dimension(:), pointer :: b  ! local RHS
62  float(kind=rk), dimension(:), pointer :: xl ! local solution vector
63  float(kind=rk), dimension(:), pointer :: x  ! global solution on master
64
65  ! Partitioning
66  integer               :: nparts ! number of partitons to partition a mesh
67  integer, dimension(6) :: part_opts = (/0,0,0,0,0,0/)
68
69  type(ConvInf) :: resStat
70
71  ! +
72  real(kind=rk) :: t1, time
73  integer :: i,it,ierr,ol
74  real(kind=rk) :: res_norm_local,res_norm,cond_num
75  real(kind=rk), dimension(:), pointer :: r, y
76  float(kind=rk), dimension(:), pointer :: yc, gyc, ybuf
77
78  type(Decomposition) :: DD !< domains
79
80  ! Aggregation
81  integer :: nagrs
82  integer, dimension(:), allocatable :: aggrnum
83  type(CoarseGrid) :: LC,C
84  integer, pointer :: glg_cfmap(:)
85  integer, allocatable :: cdisps(:),sends(:)
86  !type(CoarseData) :: cdat -- is defined now inside the module...
87
88  !DEBUG
89  integer :: k
90  real(kind=xyzk) :: mi(3),ma(3)
91
92  ! Init DOUG
93  call DOUG_Init()
94
95  time = MPI_WTime()
96
97  t1 = MPI_WTime()
98  ! Master participates in calculations as well
99  nparts = numprocs
100
101  call parallelDistributeInput(sctls%input_type,M,A,b,nparts,part_opts,A_interf)
102
103  if(pstream/=0) write(pstream, "(I0,':distribute time:',F0.3)") myrank, MPI_WTIME()-t1
104
105  ! create subdomains
106  if (sctls%overlap<0) then ! autom. overlap from smoothing
107    ol = max(sctls%smoothers,0)
108  else
109    ol = sctls%overlap
110  endif
111  DD = Decomposition_full(A,A_interf,M%ninner,ol)
112
113  ! conversion from elemental form to assembled matrix wanted?
114  if (mctls%dump_matrix_only.eqv..true.) then
115     call SpMtx_writeMatrix(A)
116     call DOUG_Finalize()
117     stop
118  end if
119  ! Geometric coarse grid processing
120  if (sctls%input_type==DCTL_INPUT_TYPE_ELEMENTAL .and. sctls%levels==2) then
121    t1 = MPI_WTime()
122    ! Init some mandatory values if they arent given
123    if (mctls%cutbal<=0) mctls%cutbal=1
124    if (mctls%maxnd==-1) mctls%maxnd=500
125    if (mctls%maxcie==-1) mctls%maxcie=75
126    if (mctls%center_type==-1) mctls%center_type=1 ! geometric
127    if (sctls%interpolation_type==-1) sctls%interpolation_type=1 ! multilinear
128    sctls%smoothers=0 ! only way it works
129
130    if (ismaster()) then
131      if (sctls%verbose>0) write (stream,*) "Building coarse grid"
132
133      call CreateCoarse(M,C)
134
135      if (sctls%plotting>0) then
136          call Mesh_pl2D_plotMesh(M,D_PLPLOT_INIT)
137          call CoarseGrid_pl2D_plotMesh(C,D_PLPLOT_END)
138      endif
139
140      if (sctls%verbose>1) &
141           write (stream,*) "Sending parts of the coarse grid to other threads"   
142      call SendCoarse(C,M,LC)
143
144!      if (sctls%verbose>1) write (stream,*) "Creating a local coarse grid"
145!      call CoarseGrid_Destroy(LC)
146!      call CreateLocalCoarse(C,M,LC)
147
148      ! deallocating coarse grid
149      nullify(C%coords) ! as LC uses that
150      call CoarseGrid_Destroy(C)
151
152    else
153      if (sctls%verbose>0) write (stream,*) "Recieving coarse grid data"
154      call  ReceiveCoarse(LC, M)
155    endif       
156      if (sctls%plotting>1 .and. ismaster()) call CoarseGrid_pl2D_plotMesh(LC)
157
158      if (sctls%verbose>0) write (stream,*) "Creating Restriction matrix"
159      call CreateRestrict(LC,M,Restrict)
160
161      if (sctls%verbose>1) write (stream,*) "Cleaning Restriction matrix"
162      call CleanCoarse(LC,Restrict,M)
163
164      if (sctls%verbose>0)  write (stream,*) "Building coarse matrix"
165      call CoarseMtxBuild(A,cdat%LAC,Restrict,M%ninner)
166
167      if (sctls%verbose>1) write (stream, *) "Stripping the restriction matrix"
168      call StripRestrict(M,Restrict)
169
170      if (sctls%verbose>0) write (stream,*) "Transmitting local-to-global maps"
171
172      allocate(cdat%cdisps(M%nparts+1))
173      cdat%send=SendData_New(M%nparts)
174      cdat%lg_cfmap=>LC%lg_fmap
175      cdat%gl_cfmap=>LC%gl_fmap
176      cdat%nprocs=M%nparts
177      cdat%ngfc=LC%ngfc
178      cdat%nlfc=LC%nlfc
179      cdat%active=.true.
180 
181      call AllSendCoarselgmap(LC%lg_fmap,LC%nlfc,M%nparts,&
182                              cdat%cdisps,cdat%glg_cfmap,cdat%send)
183      call AllRecvCoarselgmap(cdat%send)
184
185      if(pstream/=0) write(pstream, "(I0,':coarse time:',F0.3)") myrank, MPI_WTIME()-t1
186  endif
187
188  ! Solve the system
189  allocate(xl(M%nlf)); xl = 0.0_rk
190
191  select case(sctls%solver)
192  case (DCTL_SOLVE_CG)
193
194     ! Conjugate gradient
195     !call cg(A, b, xl, M, solinf=resStat, resvects_=.true.)
196     call cg(A, b, xl, M, solinf=resStat)
197
198  case (DCTL_SOLVE_PCG)
199
200     ! Preconditioned conjugate gradient
201     !call pcg(A, b, xl, M, solinf=resStat, resvects_in=.true.)
202
203     t1 = MPI_WTIME()
204
205     if (sctls%input_type==DCTL_INPUT_TYPE_ELEMENTAL .and. &
206                        sctls%levels==2) then
207       call pcg_weigs(A=A,b=b,x=xl,Msh=M,DomDec=DD,it=it,cond_num=cond_num, &
208                      A_interf_=A_interf,CoarseMtx_=AC,Restrict=Restrict, &
209                      refactor_=.true.)
210!                     refactor_=.true., cdat_=cdat)
211     else
212       call pcg_weigs(A=A,b=b,x=xl,Msh=M,DomDec=DD,it=it,cond_num=cond_num, &
213                        A_interf_=A_interf,refactor_=.true.)
214     endif
215
216     write(stream,*) 'time spent in pcg():',MPI_WTIME()-t1
217     if(pstream/=0) write(pstream, "(I0,':pcg time:',F0.3)") myrank, MPI_WTIME()-t1
218
219!call Vect_Print(xl,'xl: local solution')
220
221  case default
222     call DOUG_abort('[DOUG main] : Wrong solution method specified', -1)
223  end select
224
225  ! Calculate solution residual (in parallel)
226  allocate(r(size(xl)), y(size(xl)))
227  call SpMtx_pmvm(y, A, xl, M)
228  r = y - b
229  res_norm_local = Vect_dot_product(r, r)
230  deallocate(r, y)
231
232  ! Calculate global residual
233  call MPI_REDUCE(res_norm_local, res_norm, 1, MPI_fkind, MPI_SUM, D_MASTER, MPI_COMM_WORLD, ierr)
234
235  ! Assemble result on master and write it to screen and/or file
236  if (ismaster()) then
237     allocate(x(M%ngf)); x = 0.0_rk
238  end if
239  call Vect_Gather(xl, x, M)
240  if (ismaster().and.(size(x) <= 100).and.(D_MSGLVL > 0)) &
241       call Vect_Print(x, 'solution ')
242  if (ismaster()) then
243       write(stream,*) 'dsqrt(res_norm) =',dsqrt(res_norm)
244       call WriteSolutionToFile(x)
245  endif
246  if (ismaster()) then
247     deallocate(x)
248  end if
249
250!call MPI_BARRIER(MPI_COMM_WORLD,i)
251!call DOUG_abort('... testing ...',-1)
252
253
254
255!!$  if (ismaster()) then
256!!$     open(51, FILE='pcg.sol', FORM='UNFORMATTED')
257!!$     write(51) (x(i),i=1,size(x))
258!!$     allocate(xchk(size(x)), r(size(x)), y(size(x)))
259!!$     xchk = 0.0_rk; r = 0.0_rk; y = 0.0_rk
260!!$     read(51) (xchk(i),i=1,size(x))
261!!$     call SpMtx_mvm(A, xchk, y)
262!!$     r = b - y
263!!$     call Vect_Print(r,'residual :: ')
264!!$     write(stream,*) 'dsqrt(res_norm) =',dsqrt(dot_product(r,r))
265!!$     deallocate(xchk, r, y)
266!!$     close(51)
267!!$  end if
268
269  ! Destroy objects
270  call Mesh_Destroy(M)
271  call SpMtx_Destroy(A)
272
273  if (sctls%input_type==DCTL_INPUT_TYPE_ELEMENTAL .and. sctls%levels==2) then
274      call SpMtx_Destroy(AC)
275      call SpMtx_Destroy(Restrict)
276!      call SpMtx_Destroy(Res_aux)
277      call SendData_Destroy(cdat%send)
278
279      call CoarseGrid_Destroy(LC)
280  endif
281
282  call ConvInf_Destroy(resStat)
283  call Vect_cleanUp()
284  deallocate(b, xl)
285
286  if(pstream/=0) write(pstream, "(I0,':total time:',F0.3)") myrank, MPI_WTIME()-time
287
288  call DOUG_Finalize()
289
290end program main_geom
Note: See TracBrowser for help on using the repository browser.