FE-Project
Loading...
Searching...
No Matches
scale_multigrid_smoother_base.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
2!> module FElib / Multigrid / Smoother base
3!!
4!! @par Description
5!! A module to provide derived type to manage multigrid smoother
6!!
7!! @author Yuta Kawai, Team SCALE
8!<
9!-------------------------------------------------------------------------------
10#include "scaleFElib.h"
12 !-----------------------------------------------------------------------------
13 !
14 !++ used modules
15 !
16 !
17 use scale_precision
18 use scale_io
19 use scale_prc, only: prc_abort
20
21 use scale_sparsemat, only: sparsemat
22
25
32
33 use scale_meshfield_base, only: &
38 !-----------------------------------------------------------------------------
39 implicit none
40 private
41
42 !-----------------------------------------------------------------------------
43 !
44 !++ Public type & procedure
45 !
46 integer, public, parameter :: mgsmoother_pre_id = 1 !< ID to represent pre-smoothing
47 integer, public, parameter :: mgsmoother_post_id = 2 !< ID to represent post-smoothing
48
49 !> Base type for multigrid smoother
50 type, public :: mgsmootherbase
51 integer :: itration !< Current smoothing iteration
52 integer :: num_smooth_itr_max !< Maximum number of smoothing iterations
53
54 real(rp) :: threshold_ratio_residual_l2 !< Threshold of decreasing ratio of residual for smoothing (L2 norm)
55 real(rp) :: threshold_residual_l2 !< Residual threshold for smoothing (L2 norm)
56 real(rp) :: threshold_residual_max !< Residual threshold for smoothing (max norm)
57
58 integer :: history_residual_step !< Step recording residual history
59 integer :: history_residual_rstep !< Remaining step to record residual history
60 integer :: history_residual_count !< Count of recorded residuals
61 real(rp), allocatable :: history_residual_l2(:) !< Residual history of L2 norm
62 real(rp) :: history_residual_l2_initial !< Initial residual L2 norm
63 real(rp), allocatable :: history_residual_max(:) !< Residual history of max norm
64 real(rp) :: history_residual_max_initial !< Initial residual max norm
65 contains
66 procedure :: set_smoothing_param => mgsmootherbase_set_smoothing_param
67 procedure :: output_residual_history => mgsmootherbase_output_residual_history
68 procedure :: is_converged => mgsmootherbase_is_converged
69 procedure :: get_initial_residual_statistics => mgsmootherbase_get_initial_residual_statistics
70 procedure :: get_current_residual_statistics => mgsmootherbase_get_current_residual_statistics
71 procedure, private :: is_residual_check_step => mgsmootherbase_is_residual_check_step
72 procedure, private :: eval_global_statistic => mgsmootherbase_eval_global_statistic
73
74 end type mgsmootherbase
75 public :: mgsmootherbase_init
76 public :: mgsmootherbase_final
79
80 integer, public, parameter :: mgsmoother_default_num_smooth_ite_max = 10
81 real(rp), public, parameter :: mgsmoother_default_threshold_ratio_residual_l2 = 1.0e-3_rp
82 real(rp), public, parameter :: mgsmoother_default_threshold_residual_l2 = 1.0e-3_rp
83 real(rp), public, parameter :: mgsmoother_default_threshold_residual_max = 1.0e-3_rp
84
85
86 !> Derived type for 2D multigrid smoother
87 type, abstract, extends(mgsmootherbase), public :: mgsmootherbase2d
88 contains
89 procedure :: do_smoothing => mgsmootherbase2d_do_smoothing
90 procedure(mgsmootherbase2d_advance_itr_1step), deferred :: advance_itr_1step
91 procedure :: eval_residual_statistic => mgsmootherbase2d_eval_residual_statistic
92 procedure :: set_initial_residual => mgsmootherbase2d_set_initial_residual
93 procedure, private :: put_residual => mgsmootherbase2d_put_residual
94 end type mgsmootherbase2d
95 public :: mgsmootherbase2d_init
97
98 abstract interface
99 subroutine mgsmootherbase2d_advance_itr_1step( this, q, res, &
100 f, aux_var, itr, var_comm, aux_comm, Dx, Dy, Lift, mesh2D, &
101 cal_res_flag, zero_initial_guess, mg_p_level, mg_h_level, &
102 pre_or_post_smooth )
103 import meshbase2d
104 import :: meshfield2d
105 import meshfieldcommbase
106 import sparsemat
107 import :: mgsmootherbase2d
108 class(mgsmootherbase2d), intent(inout) :: this
109 type(meshfield2d), intent(inout), target :: q
110 type(meshfield2d), intent(inout) :: res
111 type(meshfield2d), intent(in) :: f
112 type(meshfield2d), intent(inout), target :: aux_var(:)
113 integer, intent(in) :: itr
114 class(meshfieldcommbase), intent(inout) :: var_comm
115 class(meshfieldcommbase), intent(inout) :: aux_comm
116 type(sparsemat), intent(in) :: Dx
117 type(sparsemat), intent(in) :: Dy
118 type(sparsemat), intent(in) :: Lift
119 class(meshbase2d), intent(in), target :: mesh2D
120 logical, intent(in) :: cal_res_flag
121 logical, intent(in) :: zero_initial_guess
122 integer, intent(in) :: mg_p_level
123 integer, intent(in) :: mg_h_level
124 integer, intent(in) :: pre_or_post_smooth
126 end interface
127
128 !> Derived type for 3D multigrid smoother
129 type, abstract, extends(mgsmootherbase), public :: mgsmootherbase3d
130 contains
131 procedure, public :: do_smoothing => mgsmootherbase3d_do_smoothing
132 procedure(mgsmootherbase3d_advance_itr_1step), deferred :: advance_itr_1step
133 procedure :: eval_residual_statistic => mgsmootherbase3d_eval_residual_statistic
134 procedure :: set_initial_residual => mgsmootherbase3d_set_initial_residual
135 procedure, private :: put_residual => mgsmootherbase3d_put_residual
136 end type mgsmootherbase3d
137 public :: mgsmootherbase3d_init
138 public :: mgsmootherbase3d_final
139
140 abstract interface
141 subroutine mgsmootherbase3d_advance_itr_1step( this, q, res, &
142 f, aux_var, itr, var_comm, aux_comm, Dx, Dy, Dz, Lift, mesh3D, &
143 cal_res_flag, zero_initial_guess, mg_p_level, mg_h_level, &
144 pre_or_post_smooth )
145 import meshbase3d
146 import :: meshfield3d
147 import meshfieldcommbase
148 import sparsemat
149 import :: mgsmootherbase3d
150 class(mgsmootherbase3d), intent(inout) :: this
151 type(meshfield3d), intent(inout), target :: q
152 type(meshfield3d), intent(inout) :: res
153 type(meshfield3d), intent(in) :: f
154 type(meshfield3d), intent(inout), target :: aux_var(:)
155 integer, intent(in) :: itr
156 class(meshfieldcommbase), intent(inout) :: var_comm
157 class(meshfieldcommbase), intent(inout) :: aux_comm
158 type(sparsemat), intent(in) :: Dx
159 type(sparsemat), intent(in) :: Dy
160 type(sparsemat), intent(in) :: Dz
161 type(sparsemat), intent(in) :: Lift
162 class(meshbase3d), intent(in), target :: mesh3D
163 logical, intent(in) :: cal_res_flag
164 logical, intent(in) :: zero_initial_guess
165 integer, intent(in) :: mg_p_level
166 integer, intent(in) :: mg_h_level
167 integer, intent(in) :: pre_or_post_smooth
169 end interface
170
171contains
172!-- Base
173!OCL SERIAL
174 subroutine mgsmootherbase_init(this)
175 implicit none
176 class(mgsmootherbase), intent(inout) :: this
177 !---------------------------------
178 this%num_smooth_itr_max = mgsmoother_default_num_smooth_ite_max
179 this%threshold_ratio_residual_l2 = mgsmoother_default_threshold_ratio_residual_l2
180 this%threshold_residual_l2 = mgsmoother_default_threshold_residual_l2
181 this%threshold_residual_max = mgsmoother_default_threshold_residual_max
182 return
183 end subroutine mgsmootherbase_init
184
185!OCL SERIAL
186 subroutine mgsmootherbase_final(this)
187 implicit none
188 class(mgsmootherbase), intent(inout) :: this
189 !---------------------------------
190 return
191 end subroutine mgsmootherbase_final
192
193 !> Set smoothing parameters
194!OCL SERIAL
195 subroutine mgsmootherbase_set_smoothing_param( this, &
196 num_smooth_itr_max, &
197 threshold_ratio_residual_l2, &
198 threshold_residual_l2, &
199 threshold_residual_max, &
200 history_residual_step )
201 implicit none
202 class(mgsmootherbase), intent(inout) :: this
203 integer, intent(in) :: num_smooth_itr_max !< Maximum number of smoothing iterations
204 real(rp), intent(in) :: threshold_ratio_residual_l2 !< Threshold of decreasing ratio of residual for smoothing (L2 norm)
205 real(rp), intent(in) :: threshold_residual_l2 !< Residual threshold for smoothing (L2 norm)
206 real(rp), intent(in) :: threshold_residual_max !< Residual threshold for smoothing (max norm)
207 integer, intent(in) :: history_residual_step !< Step recording residual history
208
209 integer :: num_history_residual
210 !---------------------------------
211
212 this%num_smooth_itr_max = num_smooth_itr_max
213 this%threshold_ratio_residual_l2 = threshold_ratio_residual_l2
214 this%threshold_residual_l2 = threshold_residual_l2
215 this%threshold_residual_max = threshold_residual_max
216
217 !-
218 this%history_residual_step = history_residual_step
219 num_history_residual = this%num_smooth_itr_max / this%history_residual_step + 1
220
221 allocate( this%history_residual_l2(num_history_residual) )
222 allocate( this%history_residual_max(num_history_residual) )
223
224 log_info( 'MGSmootherBase_set_smoothing_param',* ) " Smoothing parameters set:"
225 log_info( 'MGSmootherBase_set_smoothing_param',* ) " num_smooth_itr_max =", this%num_smooth_itr_max
226 log_info( 'MGSmootherBase_set_smoothing_param',* ) " threshold_ratio_residual_l2 =", this%threshold_ratio_residual_l2
227 log_info( 'MGSmootherBase_set_smoothing_param',* ) " threshold_residual_l2 =", this%threshold_residual_l2
228 log_info( 'MGSmootherBase_set_smoothing_param',* ) " threshold_residual_max =", this%threshold_residual_max
229 log_info( 'MGSmootherBase_set_smoothing_param',* ) " history_residual_step =", this%history_residual_step
230 log_info( 'MGSmootherBase_set_smoothing_param',* ) " num of history residual =", num_history_residual
231 log_info( 'MGSmootherBase_set_smoothing_param',* ) "----------------------------------------"
232 return
233 end subroutine mgsmootherbase_set_smoothing_param
234
235!OCL SERIAL
236 function mgsmootherbase_is_residual_check_step( this ) result( is_check_step )
237 implicit none
238 class(mgsmootherbase), intent(in) :: this
239 logical :: is_check_step
240 !---------------------------------
241
242 if ( this%history_residual_rstep == 1 ) then
243 is_check_step = .true.
244 else
245 is_check_step = .false.
246 end if
247 return
248 end function mgsmootherbase_is_residual_check_step
249
250!OCL SERIAL
251 subroutine mgsmootherbase_get_initial_residual_statistics( this, res_l2_init, res_max_init )
252 implicit none
253 class(mgsmootherbase), intent(in) :: this
254 real(rp), intent(out) :: res_l2_init
255 real(rp), intent(out) :: res_max_init
256 !---------------------------------
257
258 res_l2_init = this%history_residual_l2_initial
259 res_max_init = this%history_residual_max_initial
260 return
261 end subroutine mgsmootherbase_get_initial_residual_statistics
262
263!OCL SERIAL
264 subroutine mgsmootherbase_get_current_residual_statistics( this, res_l2, res_max )
265 implicit none
266 class(mgsmootherbase), intent(in) :: this
267 real(rp), intent(out) :: res_l2
268 real(rp), intent(out) :: res_max
269 !---------------------------------
270
271 res_l2 = this%history_residual_l2( this%history_residual_count )
272 res_max = this%history_residual_max( this%history_residual_count )
273 return
274 end subroutine mgsmootherbase_get_current_residual_statistics
275
276!OCL SERIAL
277 function mgsmootherbase_is_converged( this, is_Vcycle_end ) result( conv_flag )
278 implicit none
279 class(mgsmootherbase), intent(in) :: this
280 logical, intent(in) :: is_vcycle_end
281 logical :: conv_flag
282
283 real(rp) :: res_l2, res_max
284 !---------------------------------
285
286 call this%Get_current_residual_statistics( res_l2, res_max )
287
288 conv_flag = .false.
289 if ( is_vcycle_end ) then
290 if ( ( res_l2 < this%threshold_residual_l2 &
291 .and. res_max < this%threshold_residual_max ) ) then
292 conv_flag = .true.
293 end if
294 else
295 if ( ( res_l2 / this%history_residual_l2_initial < this%threshold_ratio_residual_l2 ) &
296 .or. ( res_l2 < this%threshold_residual_l2 &
297 .and. res_max < this%threshold_residual_max ) ) then
298 conv_flag = .true.
299 end if
300 end if
301 return
302 end function mgsmootherbase_is_converged
303
304!OCL SERIAL
305 subroutine mgsmootherbase_output_residual_history( this )
306 implicit none
307 class(mgsmootherbase), intent(in) :: this
308
309 integer :: i
310 !---------------------------------
311
312 log_info( 'MGSmootherBase_output_residual_history','(A,2ES12.4)') "Smoothing residual history (ini, L2 norm, Max norm) : ", this%history_residual_l2_initial, this%history_residual_max_initial
313 log_info( 'MGSmootherBase_output_residual_history',*) "Smoothing residual history (itr, L2 norm, Max norm) : "
314 do i=1, this%history_residual_count
315 log_info( 'MGSmootherBase_output_residual_history', '(I8, 2ES12.4)' ) i*this%history_residual_step, &
316 this%history_residual_l2(i), this%history_residual_max(i)
317 end do
318 return
319 end subroutine mgsmootherbase_output_residual_history
320
321!-- 2D -----------------------------------------
322
323!OCL SERIAL
324 subroutine mgsmootherbase2d_init(this)
325 implicit none
326 class(mgsmootherbase2d), intent(inout) :: this
327 !---------------------------------
328 call mgsmootherbase_init( this )
329 return
330 end subroutine mgsmootherbase2d_init
331
332!OCL SERIAL
333 subroutine mgsmootherbase2d_final(this)
334 implicit none
335 class(mgsmootherbase2d), intent(inout) :: this
336 !---------------------------------
337 call mgsmootherbase_final( this )
338 return
339 end subroutine mgsmootherbase2d_final
340
341!OCL SERIAL
342 subroutine mgsmootherbase2d_do_smoothing( this, q, res, &
343 f, aux_var, var_comm, aux_comm, Dx, Dy, Lift, mesh2D, &
344 mg_p_level, mg_h_level, &
345 pre_or_post_smooth )
346 implicit none
347 class(mgsmootherbase2d), intent(inout) :: this
348 type(meshfield2d), intent(inout), target :: q
349 type(meshfield2d), intent(inout) :: res
350 type(meshfield2d), intent(in) :: f
351 type(meshfield2d), intent(inout), target :: aux_var(:)
352 class(meshfieldcommbase), intent(inout) :: var_comm
353 class(meshfieldcommbase), intent(inout) :: aux_comm
354 type(sparsemat), intent(in) :: dx
355 type(sparsemat), intent(in) :: dy
356 type(sparsemat), intent(in) :: lift
357 class(meshbase2d), intent(in), target :: mesh2d
358 integer, intent(in) :: mg_p_level
359 integer, intent(in) :: mg_h_level
360 integer, intent(in) :: pre_or_post_smooth
361
362 integer :: itr
363 logical :: zero_initial_guess
364 logical :: cal_res_flag
365 logical :: conv_flag
366 !--------------------------------------
367
368 this%history_residual_count = 0
369 this%history_residual_rstep = this%history_residual_step
370
371 do itr=1, this%num_smooth_itr_max
372 zero_initial_guess = ( pre_or_post_smooth == mgsmoother_pre_id .and. mg_p_level /= 1 .and. itr == 1 )
373 cal_res_flag = this%Is_residual_check_step()
374
375 call this%Advance_itr_1step( q, res, &
376 f, aux_var, itr, var_comm, aux_comm, dx, dy, lift, mesh2d, &
377 cal_res_flag, zero_initial_guess, mg_p_level, mg_h_level, &
378 pre_or_post_smooth )
379
380 call this%put_residual( res, conv_flag )
381 if ( cal_res_flag ) then
382 if ( conv_flag ) then
383 exit
384 else if ( itr == this%num_smooth_itr_max ) then
385 log_info( 'MGSmootherBase2D_Do_smoothing',*) "Smoothing did not converge in the maximum number of iterations.."
386 log_info( 'MGSmootherBase2D_Do_smoothing',*) "Residual L2, max norm : ", this%history_residual_l2(this%history_residual_count), this%history_residual_max(this%history_residual_count)
387 exit
388 end if
389 end if
390 end do
391 return
392 end subroutine mgsmootherbase2d_do_smoothing
393
394!OCL SERIAL
395 subroutine mgsmootherbase2d_eval_residual_statistic( this, res, &
396 res_l2, res_max )
397 implicit none
398 class(mgsmootherbase2d), intent(in) :: this
399 type(meshfield2d), intent(in), target :: res
400 real(rp), intent(out) :: res_l2
401 real(rp), intent(out) :: res_max
402
403 integer :: ldom
404 class(meshbase2d), pointer :: mesh2d
405 class(localmesh2d), pointer :: lmesh2d
406
407 real(rp) :: res_l2_lc, res_max_lc
408 !---------------------------------
409
410 mesh2d => res%mesh
411 res_l2_lc = 0.0_rp; res_max_lc = 0.0_rp
412
413 do ldom=1, mesh2d%LOCAL_MESH_NUM
414 lmesh2d => mesh2d%lcmesh_list(ldom)
415 call mgsmootherbase_get_statistic_lc( res_l2_lc, res_max_lc, &
416 res%local(ldom)%val, lmesh2d, mesh2d%refElem2D )
417 end do
418 call this%Eval_global_statistic( res_l2, res_max, &
419 res_l2_lc, res_max_lc )
420 return
421 end subroutine mgsmootherbase2d_eval_residual_statistic
422
423!OCL SERIAL
424 subroutine mgsmootherbase2d_set_initial_residual( this, res )
425 implicit none
426 class(mgsmootherbase2d), intent(inout) :: this
427 type(meshfield2d), intent(in) :: res
428 !----------------------------------------
429 call this%Eval_residual_statistic( res, & ! (in)
430 this%history_residual_l2_initial, & ! (out)
431 this%history_residual_max_initial ) ! (out)
432 return
433 end subroutine mgsmootherbase2d_set_initial_residual
434
435 !> Put residual history for 2D smoother.
436 !! To update internal counters, this subroutine should be called after each smoothing iteration
437 !! even when the evaluation of residual is not performed.
438!OCL SERIAL
439 subroutine mgsmootherbase2d_put_residual( this, res, conv_flag)
440 implicit none
441 class(mgsmootherbase2d), intent(inout) :: this
442 type(meshfield2d), intent(in), target :: res !< Residual field
443 logical, intent(out) :: conv_flag
444
445 real(rp) :: res_l2, res_max
446 logical :: is_residual_check_step
447 !---------------------------------
448
449 is_residual_check_step = this%Is_residual_check_step()
450 if ( is_residual_check_step ) then
451 call this%Eval_residual_statistic( res, & ! (in)
452 res_l2, res_max ) ! (out)
453 end if
455 conv_flag, & ! (out)
456 is_residual_check_step, res_l2, res_max ) ! (in)
457 return
458 end subroutine mgsmootherbase2d_put_residual
459
460!-- 3D -----------------------------------------
461
462!OCL SERIAL
463 subroutine mgsmootherbase3d_init(this)
464 implicit none
465 class(mgsmootherbase3d), intent(inout) :: this
466 !---------------------------------
467 call mgsmootherbase_init( this )
468 return
469 end subroutine mgsmootherbase3d_init
470
471!OCL SERIAL
472 subroutine mgsmootherbase3d_final(this)
473 implicit none
474 class(mgsmootherbase3d), intent(inout) :: this
475 !---------------------------------
476 call mgsmootherbase_final( this )
477 return
478 end subroutine mgsmootherbase3d_final
479
480!OCL SERIAL
481 subroutine mgsmootherbase3d_do_smoothing( this, q, res, &
482 f, aux_var, var_comm, aux_comm, Dx, Dy, Dz, Lift, mesh3D, &
483 mg_p_level, mg_h_level, &
484 pre_or_post_smooth )
485 implicit none
486 class(mgsmootherbase3d), intent(inout) :: this
487 type(meshfield3d), intent(inout), target :: q
488 type(meshfield3d), intent(inout) :: res
489 type(meshfield3d), intent(in) :: f
490 type(meshfield3d), intent(inout), target :: aux_var(:)
491 class(meshfieldcommbase), intent(inout) :: var_comm
492 class(meshfieldcommbase), intent(inout) :: aux_comm
493 type(sparsemat), intent(in) :: dx
494 type(sparsemat), intent(in) :: dy
495 type(sparsemat), intent(in) :: dz
496 type(sparsemat), intent(in) :: lift
497 class(meshbase3d), intent(in), target :: mesh3d
498 integer, intent(in) :: mg_p_level
499 integer, intent(in) :: mg_h_level
500 integer, intent(in) :: pre_or_post_smooth
501
502 integer :: itr
503 logical :: zero_initial_guess
504 logical :: cal_res_flag
505 logical :: conv_flag
506 !--------------------------------------
507
508 this%history_residual_count = 0
509 this%history_residual_rstep = this%history_residual_step
510
511 do itr=1, this%num_smooth_itr_max
512 cal_res_flag = this%Is_residual_check_step()
513 zero_initial_guess = ( pre_or_post_smooth == mgsmoother_pre_id .and. mg_p_level /= 1 .and. itr == 1 )
514
515 call this%Advance_itr_1step( q, res, &
516 f, aux_var, itr, var_comm, aux_comm, dx, dy, dz, lift, mesh3d, &
517 cal_res_flag, zero_initial_guess, mg_p_level, mg_h_level, &
518 pre_or_post_smooth )
519
520 call this%put_residual( res, conv_flag )
521 if ( cal_res_flag ) then
522 if ( conv_flag ) then
523 exit
524 else if ( itr == this%num_smooth_itr_max ) then
525 log_info( 'MGSmootherBase3D_Do_smoothing',*) "Smoothing did not converge in the maximum number of iterations.."
526 log_info( 'MGSmootherBase3D_Do_smoothing',*) "Residual L2, max norm : ", this%history_residual_l2(this%history_residual_count), this%history_residual_max(this%history_residual_count)
527 exit
528 end if
529 end if
530 end do
531 return
532 end subroutine mgsmootherbase3d_do_smoothing
533
534!OCL SERIAL
535 subroutine mgsmootherbase3d_eval_residual_statistic( this, res, &
536 res_l2, res_max )
537 implicit none
538 class(mgsmootherbase3d), intent(in) :: this
539 type(meshfield3d), intent(in) :: res
540 real(rp), intent(out) :: res_l2
541 real(rp), intent(out) :: res_max
542
543 integer :: ldom
544 class(meshbase3d), pointer :: mesh3d
545 class(localmesh3d), pointer :: lmesh3d
546
547 real(rp) :: res_l2_lc, res_max_lc
548 !---------------------------------
549
550 mesh3d => res%mesh
551 res_l2_lc = 0.0_rp; res_max_lc = 0.0_rp
552
553 do ldom=1, mesh3d%LOCAL_MESH_NUM
554 lmesh3d => mesh3d%lcmesh_list(ldom)
555 call mgsmootherbase_get_statistic_lc( res_l2_lc, res_max_lc, &
556 res%local(ldom)%val, lmesh3d, mesh3d%refElem3D )
557 end do
558 call this%Eval_global_statistic( res_l2, res_max, &
559 res_l2_lc, res_max_lc )
560 return
561 end subroutine mgsmootherbase3d_eval_residual_statistic
562
563!OCL SERIAL
564 subroutine mgsmootherbase3d_set_initial_residual( this, res )
565 implicit none
566 class(mgsmootherbase3d), intent(inout) :: this
567 type(meshfield3d), intent(in) :: res
568 !----------------------------------------
569 call this%Eval_residual_statistic( res, & ! (in)
570 this%history_residual_l2_initial, & ! (out)
571 this%history_residual_max_initial ) ! (out)
572 return
573 end subroutine mgsmootherbase3d_set_initial_residual
574
575!OCL SERIAL
576 subroutine mgsmootherbase3d_put_residual( this, res, conv_flag )
577 implicit none
578 class(mgsmootherbase3d), intent(inout) :: this
579 type(meshfield3d), intent(in), target :: res
580 logical, intent(out) :: conv_flag
581
582 real(rp) :: res_l2, res_max
583 logical :: is_residual_check_step
584 !---------------------------------
585
586 is_residual_check_step = this%Is_residual_check_step()
587 if ( is_residual_check_step ) then
588 call this%Eval_residual_statistic( res, & ! (in)
589 res_l2, res_max ) ! (out)
590 end if
592 conv_flag, & ! (out)
593 is_residual_check_step, res_l2, res_max ) ! (in)
594 return
595 end subroutine mgsmootherbase3d_put_residual
596
597!-- private subroutines ----------------------------------------------------
598
599 !> Put residual history and evaluate whether convergence is achieved.
600 !! This subroutine also updates internal counters.
601!OCL SERIAL
602 subroutine mgsmootherbase_put_residual_history( this, conv_flag, &
603 is_residual_check_step, res_l2, res_max )
604 implicit none
605 class(mgsmootherbase), intent(inout) :: this
606 logical, intent(out) :: conv_flag
607 logical, intent(in) :: is_residual_check_step
608 real(rp), intent(in) :: res_l2
609 real(rp), intent(in) :: res_max
610 !---------------------------------
611
612 if ( is_residual_check_step ) then
613 !- Store the statistics of residual to history
614 this%history_residual_count = this%history_residual_count + 1
615 this%history_residual_l2 (this%history_residual_count) = res_l2
616 this%history_residual_max(this%history_residual_count) = res_max
617
618 !- Reset remaining step
619 this%history_residual_rstep = this%history_residual_step
620
621 !- Evaluate convergence
622 conv_flag = this%Is_converged( .false. )
623 else
624 this%history_residual_rstep = this%history_residual_rstep - 1
625 conv_flag = .false.
626 end if
627 return
629
630 !> Get residual statistics on local mesh
631!OCL SERIAL
632 subroutine mgsmootherbase_get_statistic_lc( res_l2_lc, res_max_lc, &
633 res_lc, lmesh, elem )
636 implicit none
637 class(localmeshbase), intent(in), target :: lmesh
638 class(elementbase), intent(in), target :: elem
639 real(rp), intent(inout) :: res_l2_lc
640 real(rp), intent(inout) :: res_max_lc
641 real(rp), intent(in) :: res_lc(elem%np,lmesh%nea)
642
643 integer :: ke
644 real(rp) :: res_(elem%np)
645 !---------------------------------
646
647 !$omp parallel do private(ke,res_) reduction(+:res_l2_lc) reduction(max:res_max_lc)
648 do ke=lmesh%NeS, lmesh%NeE
649 res_(:) = res_lc(:,ke)
650 res_l2_lc = res_l2_lc + sum( res_(:)**2 )
651 res_max_lc = max(res_max_lc, maxval( abs(res_(:)) ))
652 end do
653 return
655
656!OCL SERIAL
657 subroutine mgsmootherbase_eval_global_statistic( this, res_l2_global, res_max_global, &
658 res_l2_lc, res_max_lc)
659 use mpi
660 use scale_prc, only: &
661 prc_local_comm_world
662 implicit none
663 class(mgsmootherbase), intent(in) :: this
664 real(rp), intent(out) :: res_l2_global
665 real(rp), intent(out) :: res_max_global
666 real(rp), intent(in) :: res_l2_lc
667 real(rp), intent(in) :: res_max_lc
668
669 integer :: ierr
670 !---------------------------------
671
672 !- Gather L2 residual from all processes
673 call mpi_allreduce( res_l2_lc, res_l2_global, &
674 1, mpi_double_precision, mpi_sum, prc_local_comm_world, ierr )
675
676 res_l2_global = sqrt( res_l2_global )
677
678 !- Gather max residual from all processes
679 call mpi_allreduce( res_max_lc, res_max_global, &
680 1, mpi_double_precision, mpi_max, prc_local_comm_world, ierr )
681 return
682 end subroutine mgsmootherbase_eval_global_statistic
683
module FElib / Element / Base
module FElib / Element / hexahedron
module FElib / Element / Quadrilateral
module FElib / Mesh / Local 2D
module FElib / Mesh / Local 3D
module FElib / Mesh / Local, Base
module FElib / Mesh / Base 2D
module FElib / Mesh / Base 3D
module FElib / Mesh / Cubic 3D domain
module FElib / Mesh / Rectangle 2D domain
module FElib / Data / base
module FElib / Data / Communication base
module FElib / Data / Communication 3D cubic domain
module FElib / Data / Communication 2D rectangle domain
module FElib / Multigrid / Smoother base
real(rp), parameter, public mgsmoother_default_threshold_residual_max
integer, parameter, public mgsmoother_pre_id
ID to represent pre-smoothing.
real(rp), parameter, public mgsmoother_default_threshold_residual_l2
integer, parameter, public mgsmoother_post_id
ID to represent post-smoothing.
subroutine, public mgsmootherbase_get_statistic_lc(res_l2_lc, res_max_lc, res_lc, lmesh, elem)
Get residual statistics on local mesh.
subroutine, public mgsmootherbase_put_residual_history(this, conv_flag, is_residual_check_step, res_l2, res_max)
Put residual history and evaluate whether convergence is achieved. This subroutine also updates inter...
integer, parameter, public mgsmoother_default_num_smooth_ite_max
real(rp), parameter, public mgsmoother_default_threshold_ratio_residual_l2
Module common / sparsemat.
Derived type representing an arbitrary finite element.
Derived type representing a hexahedral element.
Derived type representing a quadrilateral element.
Derived type representing a local mesh for 2D domain.
Derived type to manage a local 3D computational domain.
Derived type to manage a local computational domain (base type)
Derived type to manage a computational mesh (base type for 2D domain)
Derived type to manage a computational mesh (base type for 3D domain)
Derived type to manage a cubic 3D computational domain.
Derived type to manage a rectangular 2D computational domain.
Derived type representing a field with 2D mesh.
Derived type representing a field with 3D mesh.
Base derived type to manage data communication.
Base derived type to manage data communication with 3D cubic domain.
Base derived type to manage data communication with 2D rectangle domain.
Derived type to manage a sparse matrix.