FE-Project
Loading...
Searching...
No Matches
scale_multigrid_solver_2d.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module FElib / Multigrid / Solver 2D
3!!
4!! @par Description
5!! Manage a multigrid solver for 2D domain
6!!
7!! @author Yuta Kawai, Team SCALE
8!<
9!-------------------------------------------------------------------------------
10#include "scaleFElib.h"
12
13 !-----------------------------------------------------------------------------
14 !
15 !++ used modules
16 !
17 !
18 use scale_precision
19 use scale_io
20 use scale_prc, only: prc_abort
21
22 use scale_sparsemat, only: sparsemat
23
26
30
33
34 use scale_mesh_hierarchy_base, only: &
35 pmg_finest_level => mesh_hierarchy_pmg_finest_level, &
36 hmg_finest_level => mesh_hierarchy_hmg_finest_level, &
39 use scale_mesh_hierarchy_2d, only: &
43
49
50 !-----------------------------------------------------------------------------
51 implicit none
52 private
53
54 !-----------------------------------------------------------------------------
55 !
56 !++ Public type & procedure
57 !
58
59 !> Derived type for multigrid solver in 2D domain
60 type, extends(multigridsolverbase), public :: multigridsolver2d
61 type(meshhierarchy2d), pointer :: mesh_hierarchy_ptr !< Pointer to an object to manage 2D mesh hierarchy
62 class(mgsmootherbase2d), pointer :: mg_smoother_ptr !< Pointer to an object to manage 2D MG smoother
63
64 type(mgfieldset2d), allocatable :: fields_h(:) !< Array of objects to manage MG field sets for h-MG
65 type(mgfieldset2d), allocatable :: fields_p(:) !< Array of objects to manage MG field sets for p-MG
66 contains
67 procedure :: init => multigridsolver2d_init
68 procedure :: final => multigridsolver2d_final
69 procedure :: solve => multigridsolver2d_solve
70 procedure :: do_vcycle => multigridsolver2d_do_vcycle
71 !-
72 procedure :: do_hmg_vcycle => multigridsolver2d_do_hmg_vcycle
73 procedure :: operate_pmg_restriction => multigridsolver2d_operate_pmg_restriction
74 procedure :: operate_pmg_correction => multigridsolver2d_operate_pmg_correction
75 procedure :: operate_hmg_restriction => multigridsolver2d_operate_hmg_restriction
76 procedure :: operate_hmg_correction => multigridsolver2d_operate_hmg_correction
77 end type multigridsolver2d
78
79 !-----------------------------------------------------------------------------
80 !
81 !++ Public parameters & variables
82 !
83
84 !-----------------------------------------------------------------------------
85 !
86 !++ Private procedure
87 !
88
89 !-----------------------------------------------------------------------------
90 !
91 !++ Private parameters & variables
92 !
93contains
94 !> Initialize an object for multigrid solver in 2D domain
95!OCL SERIAL
96 subroutine multigridsolver2d_init( this, &
97 mesh_hierarchy, mg_smoother, &
98 aux_var_num, aux_vec_num )
99
101 implicit none
102 class(multigridsolver2d), intent(inout) :: this
103 class(meshhierarchy2d), intent(in), target :: mesh_hierarchy
104 class(mgsmootherbase2d), intent(in), target :: mg_smoother
105 integer, intent(in) :: aux_var_num
106 integer, intent(in) :: aux_vec_num
107
108 integer :: lev_p
109 integer :: lev_h
110 !-------------------------------------------------------------
111
112 call multigridsolverbase_init( this, mesh_hierarchy )
113
114 this%mesh_hierarchy_ptr => mesh_hierarchy
115 this%mg_smoother_ptr => mg_smoother
116
117 !- Prepare p-MG field sets
118 allocate( this%fields_p( mesh_hierarchy%NUM_pMG_LEVEL ) )
119 do lev_p=1, mesh_hierarchy%NUM_pMG_LEVEL
120 call this%fields_p(lev_p)%Init( mesh_hierarchy%p_mesh_list(lev_p)%ptr, &
121 aux_var_num, aux_vec_num, lev_p )
122 end do
123
124 !- Prepare h-MG field sets
125 allocate( this%fields_h( mesh_hierarchy%NUM_hMG_LEVEL ) )
126 do lev_h=1, mesh_hierarchy%NUM_hMG_LEVEL
127 call this%fields_h(lev_h)%Init( mesh_hierarchy%h_mesh_list(lev_h)%ptr, &
128 aux_var_num, aux_vec_num, lev_h )
129 end do
130 return
131 end subroutine multigridsolver2d_init
132
133 !> Finalize an object for multigrid solver in 2D domain
134!OCL SERIAL
135 subroutine multigridsolver2d_final(this)
137 implicit none
138 class(multigridsolver2d), intent(inout) :: this
139
140 integer :: lev_p
141 integer :: lev_h
142 !-------------------------------------------------------------
143
144 call multigridsolverbase_final( this )
145
146 if ( allocated(this%fields_p) ) then
147 do lev_p=1, size(this%fields_p)
148 call this%fields_p(lev_p)%Final()
149 end do
150 end if
151 deallocate( this%fields_p )
152
153 if ( allocated(this%fields_h) ) then
154 do lev_h=1, size(this%fields_h)
155 call this%fields_h(lev_h)%Final()
156 end do
157 end if
158 deallocate( this%fields_h )
159
160 return
161 end subroutine multigridsolver2d_final
162
163 !> Solve a linear system using multigrid method in 2D domain
164!OCL SERIAL
165 subroutine multigridsolver2d_solve(this, q, &
166 f )
167 implicit none
168 class(multigridsolver2d), intent(inout) :: this
169
170 class(meshfield2d), intent(inout), target :: q
171 class(meshfield2d), intent(inout) :: f
172
173 integer :: vcyc_itr
174
175 class(localmesh2d), pointer :: lmesh
176 integer :: ldomID
177 integer :: ke
178 !-------------------------------------------------------------
179
180 do ldomid=1, q%mesh%LOCAL_MESH_NUM
181 lmesh => q%mesh%lcmesh_list(ldomid)
182 do ke=lmesh%NeS, lmesh%NeE
183 this%fields_p(pmg_finest_level)%dq%local(ldomid)%val(:,ke) = q%local(ldomid)%val(:,ke)
184 end do
185 end do
186
187 this%current_p_lev = pmg_finest_level-1
188 this%current_h_lev = hmg_finest_level-1
189
190 !-
191 do vcyc_itr=1, this%vcyc_num_max
192 log_info("MultiGridSolver2D_solve",*) "V-cycle iteration:", vcyc_itr
193
194 call this%do_Vcycle( pmg_finest_level, f, vcyc_itr )
195 if ( this%Is_converged(this%mg_smoother_ptr) ) then
196 log_info("MultiGridSolver2D_solve",*) "V-cycle converged: vcyc_itr=", vcyc_itr
197 exit
198 end if
199 end do
200
201 !-
202 do ldomid=1, q%mesh%LOCAL_MESH_NUM
203 lmesh => q%mesh%lcmesh_list(ldomid)
204 do ke=lmesh%NeS, lmesh%NeE
205 q%local(ldomid)%val(:,ke) = this%fields_p(pmg_finest_level)%dq%local(ldomid)%val(:,ke)
206 end do
207 end do
208 return
209 end subroutine multigridsolver2d_solve
210
211 !> Do a V-cycle in 2D domain
212!OCL SERIAL
213 recursive subroutine multigridsolver2d_do_vcycle(this, mg_level, f_in, vcyc_itr)
214 implicit none
215 class(multigridsolver2d), intent(inout), target :: this
216 integer, intent(in) :: mg_level
217 type(meshfield2d), intent(inout) :: f_in
218 integer, intent(in) :: vcyc_itr
219 logical :: invoke_hMG
220
221 class(mgfieldset2d), pointer :: fs_p
222 class(meshhierarchy2d), pointer :: mesh_hierarchy
223 !---------------------------------------------------------------------
224
225 this%current_p_lev = this%current_p_lev + 1
226
227 mesh_hierarchy => this%mesh_hierarchy_ptr
228 fs_p => this%fields_p(mg_level)
229
230 log_info("MultiGridSolver2D_do_Vcycle",*) "Start: p_level=", this%current_p_lev
231
232 !- Pre-relaxation
233 call this%mg_smoother_ptr%Do_smoothing( fs_p%dq, fs_p%res, &
234 f_in, fs_p%aux_var, fs_p%var_comm_ptr, fs_p%aux_comm_ptr, &
235 fs_p%Dx, fs_p%Dy, fs_p%Lift, mesh_hierarchy%p_mesh_list(mg_level)%ptr, &
236 this%current_p_lev, this%current_h_lev, mgsmoother_pre_id )
237
238 if ( vcyc_itr == 1 .and. this%current_p_lev == pmg_finest_level ) then
239 call this%mg_smoother_ptr%Get_initial_residual_statistics( &
240 this%history_residual_l2_initial, this%history_residual_max_initial )
241 end if
242 call this%mg_smoother_ptr%Output_residual_history()
243
244 if ( mg_level == mesh_hierarchy%NUM_pMG_LEVEL .and. mesh_hierarchy%NUM_hMG_LEVEL == 0 ) then
245 log_info("MultiGridSolver2D_do_Vcycle",*) "End: p_level=", this%current_p_lev
246 this%current_p_lev = this%current_p_lev - 1
247 return
248 end if
249
250 !-
251 invoke_hmg = ( mg_level+1 >= mesh_hierarchy%NUM_pMG_LEVEL .and. mesh_hierarchy%NUM_hMG_LEVEL > 0 )
252
253 if ( invoke_hmg ) then
254 !- Restriction
255 call this%Operate_pMG_restriction( this%fields_h(hmg_finest_level)%f, &
256 this%fields_p(mg_level)%res, mg_level )
257
258 !- Advance node in the V-cycle
259 call this%do_hMG_Vcycle( hmg_finest_level, this%fields_h(hmg_finest_level)%f )
260
261 !- Correction
262 call this%Operate_pMG_correction( this%fields_p(mg_level)%dq, &
263 this%fields_h(hmg_finest_level)%dq, mg_level )
264 else
265 !- Restriction
266 call this%Operate_pMG_restriction( this%fields_p(mg_level+1)%f, &
267 this%fields_p(mg_level)%res, mg_level )
268
269 !- Advance node in the V-cycle
270 call this%do_Vcycle( mg_level+1, this%fields_p(mg_level+1)%f, vcyc_itr )
271
272 !- Correction
273 call this%Operate_pMG_correction( this%fields_p(mg_level)%dq, &
274 this%fields_p(mg_level+1)%dq, mg_level )
275 end if
276
277 !- Post-relaxation
278 call this%mg_smoother_ptr%Do_smoothing( fs_p%dq, fs_p%res, &
279 f_in, fs_p%aux_var, fs_p%var_comm_ptr, fs_p%aux_comm_ptr, &
280 fs_p%Dx, fs_p%Dy, fs_p%Lift, mesh_hierarchy%p_mesh_list(mg_level)%ptr, &
281 this%current_p_lev, this%current_h_lev, mgsmoother_post_id )
282
283 call this%mg_smoother_ptr%Output_residual_history()
284 log_info("MultiGridSolver2D_do_Vcycle",*) "End: p_level=", this%current_p_lev
285
286 this%current_p_lev = this%current_p_lev - 1
287 return
288 end subroutine multigridsolver2d_do_vcycle
289
290!OCL SERIAL
291 recursive subroutine multigridsolver2d_do_hmg_vcycle( this, mg_level, f_in )
292 implicit none
293 class(multigridsolver2d), intent(inout), target :: this
294 integer, intent(in) :: mg_level
295 type(meshfield2d), intent(inout) :: f_in
296
297 class(meshhierarchy2d), pointer :: mesh_hierarchy
298 class(mgfieldset2d), pointer :: fs_h
299 !----------------------------------------------
300
301 mesh_hierarchy => this%mesh_hierarchy_ptr
302 fs_h => this%fields_h(mg_level)
303
304 this%current_h_lev = this%current_h_lev + 1
305
306 log_info("MultiGridSolver2D_do_hMG_Vcycle",*) "Start: h_level=", this%current_h_lev
307
308 if ( mg_level == mesh_hierarchy%NUM_hMG_LEVEL ) then
309 ! It should be replaced with a direct solver
310 call this%mg_smoother_ptr%Do_smoothing( fs_h%dq, fs_h%res, &
311 f_in, fs_h%aux_var, fs_h%var_comm_ptr, fs_h%aux_comm_ptr, &
312 fs_h%Dx, fs_h%Dy, fs_h%Lift, mesh_hierarchy%h_mesh_list(mg_level)%ptr, &
313 this%current_p_lev, this%current_h_lev, mgsmoother_pre_id )
314
315 call this%mg_smoother_ptr%Output_residual_history()
316
317 log_info("MultiGridSolver2D_do_hMG_Vcycle",*) "End: h_level=", this%current_h_lev
318 this%current_h_lev = this%current_h_lev - 1
319 return
320 end if
321
322 !- Pre-relaxation
323 call this%mg_smoother_ptr%Do_smoothing( fs_h%dq, fs_h%res, &
324 f_in, fs_h%aux_var, fs_h%var_comm_ptr, fs_h%aux_comm_ptr, &
325 fs_h%Dx, fs_h%Dy, fs_h%Lift, mesh_hierarchy%h_mesh_list(mg_level)%ptr, &
326 this%current_p_lev, this%current_h_lev, mgsmoother_pre_id )
327
328 !- Restriction
329 call this%Operate_hMG_restriction( this%fields_h(mg_level+1)%f, &
330 this%fields_h(mg_level)%res, mg_level )
331
332 !- Advance node in the V-cycle
333 call this%do_hMG_Vcycle( mg_level+1, this%fields_h(mg_level+1)%f )
334
335 !- Correction
336 call this%Operate_hMG_correction( this%fields_h(mg_level)%dq, &
337 this%fields_h(mg_level+1)%dq, mg_level )
338
339 !- Post-relaxation
340 call this%mg_smoother_ptr%Do_smoothing( fs_h%dq, fs_h%res, &
341 f_in, fs_h%aux_var, fs_h%var_comm_ptr, fs_h%aux_comm_ptr, &
342 fs_h%Dx, fs_h%Dy, fs_h%Lift, mesh_hierarchy%h_mesh_list(mg_level)%ptr, &
343 this%current_p_lev, this%current_h_lev, mgsmoother_post_id )
344
345 log_info("MultiGridSolver2D_do_hMG_Vcycle",*) "End: h_level=", this%current_h_lev
346 this%current_h_lev = this%current_h_lev - 1
347 return
348 end subroutine multigridsolver2d_do_hmg_vcycle
349
350!--
351!OCL SERIAL
352 subroutine multigridsolver2d_operate_pmg_restriction( this, res_c, &
353 res, p_lev )
354 implicit none
355 class(multigridsolver2d), intent(in), target :: this
356 class(meshfield2d), intent(inout) :: res_c
357 class(meshfield2d), intent(in) :: res
358 integer, intent(in) :: p_lev
359
360 class(meshhierarchy2d), pointer :: hierarchy
361 integer :: ldomID
362 class(meshbase2d), pointer :: mesh2D
363 !------------------------------------------------
364
365 if ( this%mesh_hierarchy_ptr%NUM_pMG_LEVEL < p_lev+1 ) then
366 call prc_abort()
367 end if
368
369 hierarchy => this%mesh_hierarchy_ptr
370 mesh2d => hierarchy%p_mesh_list(p_lev)%ptr
371 do ldomid=1, mesh2d%LOCAL_MESH_NUM
372 call multigridsolver2d_pmg_operation( res_c%local(ldomid)%val, &
373 res%local(ldomid)%val, &
374 hierarchy%elem2D_list(p_lev), hierarchy%elem2D_list(p_lev+1), &
375 mesh2d%lcmesh_list(ldomid), hierarchy%p_level(p_lev)%pMat1D_f2c, &
376 .false. )
377 end do
378 return
379 end subroutine multigridsolver2d_operate_pmg_restriction
380
381!OCL SERIAL
382 subroutine multigridsolver2d_operate_pmg_correction( this, dq, &
383 cor_c, p_lev )
384 implicit none
385 class(multigridsolver2d), intent(in), target :: this
386 class(meshfield2d), intent(inout) :: dq
387 class(meshfield2d), intent(in) :: cor_c
388 integer, intent(in) :: p_lev
389
390 class(meshhierarchy2d), pointer :: hierarchy
391
392 integer :: ldomID
393 class(meshbase2d), pointer :: mesh2D
394 !------------------------------------------------
395
396 hierarchy => this%mesh_hierarchy_ptr
397 mesh2d => hierarchy%p_mesh_list(p_lev)%ptr
398
399 do ldomid=1, mesh2d%LOCAL_MESH_NUM
400 call multigridsolver2d_pmg_operation( dq%local(ldomid)%val, &
401 cor_c%local(ldomid)%val, &
402 hierarchy%elem2D_list(p_lev+1), hierarchy%elem2D_list(p_lev), &
403 mesh2d%lcmesh_list(ldomid), hierarchy%p_level(p_lev)%pMat1D_c2f, &
404 .true. )
405 end do
406 return
407 end subroutine multigridsolver2d_operate_pmg_correction
408
409!OCL SERIAL
410 subroutine multigridsolver2d_operate_hmg_restriction( this, res_c, &
411 res, h_lev )
413 implicit none
414 class(multigridsolver2d), intent(in), target :: this
415 class(meshfield2d), intent(inout) :: res_c
416 class(meshfield2d), intent(in) :: res
417 integer, intent(in) :: h_lev
418
419 class(meshhierarchy2d), pointer :: hierarchy
420
421 integer :: ldomID
422 class(meshbase2d), pointer :: mesh2D
423 class(meshbase2d), pointer :: mesh2D_c
424 !------------------------------------------------
425
426 hierarchy => this%mesh_hierarchy_ptr
427 mesh2d => hierarchy%h_mesh_list(h_lev)%ptr
428 mesh2d_c => hierarchy%h_mesh_list(h_lev+1)%ptr
429
430 do ldomid=1, mesh2d%LOCAL_MESH_NUM
431 call multigridsolver2d_hmg_restriction_core( res_c%local(ldomid)%val, &
432 res%local(ldomid)%val, &
433 hierarchy%h_level(h_lev)%mg_local(ldomid), mesh2d%lcmesh_list(ldomid), &
434 hierarchy%elem2D_list(hierarchy%NUM_pMG_LEVEL), mesh2d_c%lcmesh_list(ldomid) )
435 end do
436 return
437 end subroutine multigridsolver2d_operate_hmg_restriction
438
439!OCL SERIAL
440 subroutine multigridsolver2d_operate_hmg_correction( this, dq, &
441 cor_c, h_lev )
443 implicit none
444 class(multigridsolver2d), intent(in), target :: this
445 class(meshfield2d), intent(inout) :: dq
446 class(meshfield2d), intent(in) :: cor_c
447 integer, intent(in) :: h_lev
448
449 integer :: ldomID
450 class(meshbase2d), pointer :: mesh2D
451 class(meshhierarchy2d), pointer :: hierarchy
452 !------------------------------------------------
453
454 hierarchy => this%mesh_hierarchy_ptr
455 mesh2d => hierarchy%h_mesh_list(h_lev)%ptr
456
457 do ldomid=1, mesh2d%LOCAL_MESH_NUM
458 call multigridsolver2d_hmg_correction_core( dq%local(ldomid)%val, &
459 cor_c%local(ldomid)%val, hierarchy%h_level(h_lev)%mg_local(ldomid), &
460 mesh2d%lcmesh_list(ldomid), mesh2d%refElem2D )
461 end do
462 return
463 end subroutine multigridsolver2d_operate_hmg_correction
464
465!-- private --------------------------------------------------------------
466
467
468!OCL SERIAL
469 subroutine multigridsolver2d_hmg_restriction_core( res_c_lc, &
470 res_lc, mg_local, lmesh, elem, lmesh_c )
471 implicit none
472 class(localmesh2d), intent(in) :: lmesh
473 class(elementbase2d), intent(in) :: elem
474 class(localmesh2d), intent(in) :: lmesh_c
475 real(RP), intent(out) :: res_c_lc(elem%Np,lmesh_c%NeA)
476 real(RP), intent(in) :: res_lc(elem%Np,lmesh%NeA)
477 class(meshhierarchylocalmgdata2d), intent(in) :: mg_local
478
479 integer :: k, ke, ke_c
480 real(RP) :: Ic2fT_lc(4,4)
481 real(RP) :: tmp_c(elem%Np)
482 real(RP) :: tmp2(elem%Np)
483
484 real(RP) :: int_tmp(lmesh_c%Ne)
485 real(RP) :: res_cor
486 !-----------------------------------------
487
488 !$omp parallel private(ke, ke_c, tmp2, tmp_c, Ic2fT_lc)
489 !$omp do
490 do ke_c=lmesh_c%NeS, lmesh_c%NeE
491
492 tmp_c(:) = 0.0_rp
493 do k=1, 4
494 ke = mg_local%If2c_emap(k,ke_c)
495
496 tmp2(:) = matmul( elem%M, res_lc(:,ke) )
497 ! tmp2(:) = res_lc(:,ke)
498 ic2ft_lc(:,:) = transpose( mg_local%Ic2f(:,:,ke) )
499 tmp_c(:) = tmp_c(:) + matmul( ic2ft_lc, tmp2(:) )
500 end do
501
502 res_c_lc(:,ke_c) = matmul(lmesh_c%refElem2D%invM, tmp_c(:)) * 0.25_rp
503 ! res_c_lc(:,ke_c) = tmp_c(:) * 0.25_RP
504 end do
505 !$omp end parallel
506 return
507 end subroutine multigridsolver2d_hmg_restriction_core
508
509!OCL SERIAL
510 subroutine multigridsolver2d_hmg_correction_core( dq_lc, &
511 dq_c_lc, mg_local, lmesh, elem )
512 implicit none
513 class(localmesh2d), intent(in) :: lmesh
514 class(elementbase2d), intent(in) :: elem
515 real(RP), intent(out) :: dq_lc(elem%Np,lmesh%NeA)
516 real(RP), intent(in) :: dq_c_lc(elem%Np,lmesh%NeA)
517 class(meshhierarchylocalmgdata2d), intent(in) :: mg_local
518
519 integer :: k, ke, ke_c
520 !-----------------------------------------
521
522 !$omp parallel do private(ke, ke_c)
523 do ke=lmesh%NeS, lmesh%NeE
524 ke_c = mg_local%Ic2f_emap(ke)
525 dq_lc(:,ke) = dq_lc(:,ke) + &
526 matmul( mg_local%Ic2f(:,:,ke), dq_c_lc(:,ke_c) )
527 end do
528 return
529 end subroutine multigridsolver2d_hmg_correction_core
530
531!OCL SERIAL
532 subroutine multigridsolver2d_pmg_operation( q_o, &
533 q_i, elem2D_i, elem2D_o, lcmesh, pMat1D, is_added )
534 implicit none
535 class(elementbase2d), intent(in) :: elem2D_i
536 class(elementbase2d), intent(in) :: elem2D_o
537 class(localmesh2d), intent(in) :: lcmesh
538 real(RP), intent(inout) :: q_o(elem2D_o%Nfp,elem2D_o%Nfp,lcmesh%NeA)
539 real(RP), intent(in) :: q_i(elem2D_i%Nfp,elem2D_i%Nfp,lcmesh%NeA)
540 real(RP), intent(in) :: pMat1D(elem2D_o%Nfp,elem2D_i%Nfp)
541 logical, intent(in) :: is_added
542
543 integer :: ke
544
545 integer :: px, py
546 integer :: pxx, pyy
547 real(RP) :: tmp1
548 real(RP) :: tmp2(elem2D_o%Nfp,elem2D_i%Nfp)
549 real(RP) :: tmp3(elem2D_o%Nfp)
550
551 real(RP) :: mat_tr(elem2D_i%Nfp,elem2D_o%Nfp)
552 !-------------------------------------------
553
554 mat_tr(:,:) = transpose(pmat1d)
555
556 !$omp parallel do private(tmp1, tmp2, tmp3)
557 do ke=lcmesh%NeS, lcmesh%NeE
558 do py=1, elem2d_i%Nfp
559 do pxx=1, elem2d_o%Nfp
560 tmp1 = 0.0_rp
561 do px=1, elem2d_i%Nfp
562 tmp1 = tmp1 + mat_tr(px,pxx) * q_i(px,py,ke)
563 end do
564 tmp2(pxx,py) = tmp1
565 end do
566 end do
567
568 if ( is_added ) then
569 do pyy=1, elem2d_o%Nfp
570 tmp3(:) = 0.0_rp
571 do py=1, elem2d_i%Nfp
572 do px=1, elem2d_o%Nfp
573 tmp3(px) = tmp3(px) + mat_tr(py,pyy) * tmp2(px,py)
574 end do
575 end do
576 q_o(:,pyy,ke) = q_o(:,pyy,ke) + tmp3(:)
577 end do
578 else
579 do pyy=1, elem2d_o%Nfp
580 tmp3(:) = 0.0_rp
581 do py=1, elem2d_i%Nfp
582 do px=1, elem2d_o%Nfp
583 tmp3(px) = tmp3(px) + mat_tr(py,pyy) * tmp2(px,py)
584 end do
585 end do
586 q_o(:,pyy,ke) = tmp3(:)
587 end do
588 end if
589 end do
590 return
591 end subroutine multigridsolver2d_pmg_operation
module FElib / Element / Base
module FElib / Element / Quadrilateral
module FElib / Mesh / Local 2D
module FElib / Mesh / Base 2D
module FElib / Mesh / 2D domain
module FElib / Mesh / Hierarchy base
integer, parameter, public mesh_hierarchy_type_pmg
Type ID of mesh hierarchy: p-MG.
integer, parameter, public mesh_hierarchy_hmg_finest_level
Finest level index in h-MG.
integer, parameter, public mesh_hierarchy_type_hmg
Type ID of mesh hierarchy: h-MG.
integer, parameter, public mesh_hierarchy_pmg_finest_level
Finest level index in p-MG.
module FElib / Mesh / Rectangle 2D domain
module FElib / Data / base
module FElib / Data / Communication 2D rectangle domain
module FElib / Multigrid / Field set base
module FElib / Multigrid / Smoother base
integer, parameter, public mgsmoother_pre_id
ID to represent pre-smoothing.
integer, parameter, public mgsmoother_post_id
ID to represent post-smoothing.
module FElib / Multigrid / Solver 2D
subroutine multigridsolver2d_init(this, mesh_hierarchy, mg_smoother, aux_var_num, aux_vec_num)
Initialize an object for multigrid solver in 2D domain.
module FElib / Multigrid / Solver base
subroutine, public multigridsolverbase_final(this)
Finalize a base object for multigrid solver.
subroutine, public multigridsolverbase_init(this, mesh_hierarchy)
Initialize a base object for multigrid solver.
Module common / sparsemat.
Derived type representing a 2D reference element.
Derived type representing a quadrilateral element.
Derived type representing a local mesh for 2D domain.
Derived type to manage a computational mesh (base type for 2D domain)
Derived type for mesh hierarchy in 2D domain.
Derived type to represent mesh hierarchy level in 2D domain.
Derived type to manage 2D local mesh data for multigrid.
Derived type to manage a rectangular 2D computational domain.
Derived type representing a field with 2D mesh.
Base derived type to manage data communication with 2D rectangle domain.
Derived type for multigrid solver in 2D domain.
Derived type to manage a sparse matrix.