source: src/main/geom.F90 @ e083829

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

Get rid of CoarseMtx_ and Restrict in pcg.

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