source: src/main/geom.F90 @ 93cc7c7

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

Refactor: create 'Distribution' component.

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