10#include "scaleFElib.h"
19 use scale_prc,
only: prc_abort
52 integer :: num_smooth_itr_max
54 real(rp) :: threshold_ratio_residual_l2
55 real(rp) :: threshold_residual_l2
56 real(rp) :: threshold_residual_max
58 integer :: history_residual_step
59 integer :: history_residual_rstep
60 integer :: history_residual_count
61 real(rp),
allocatable :: history_residual_l2(:)
62 real(rp) :: history_residual_l2_initial
63 real(rp),
allocatable :: history_residual_max(:)
64 real(rp) :: history_residual_max_initial
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
89 procedure :: do_smoothing => mgsmootherbase2d_do_smoothing
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
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, &
112 type(
meshfield2d),
intent(inout),
target :: aux_var(:)
113 integer,
intent(in) :: itr
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
131 procedure,
public :: do_smoothing => mgsmootherbase3d_do_smoothing
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
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, &
154 type(
meshfield3d),
intent(inout),
target :: aux_var(:)
155 integer,
intent(in) :: itr
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
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 )
203 integer,
intent(in) :: num_smooth_itr_max
204 real(rp),
intent(in) :: threshold_ratio_residual_l2
205 real(rp),
intent(in) :: threshold_residual_l2
206 real(rp),
intent(in) :: threshold_residual_max
207 integer,
intent(in) :: history_residual_step
209 integer :: num_history_residual
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
218 this%history_residual_step = history_residual_step
219 num_history_residual = this%num_smooth_itr_max / this%history_residual_step + 1
221 allocate( this%history_residual_l2(num_history_residual) )
222 allocate( this%history_residual_max(num_history_residual) )
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',* )
"----------------------------------------"
233 end subroutine mgsmootherbase_set_smoothing_param
236 function mgsmootherbase_is_residual_check_step( this )
result( is_check_step )
239 logical :: is_check_step
242 if ( this%history_residual_rstep == 1 )
then
243 is_check_step = .true.
245 is_check_step = .false.
248 end function mgsmootherbase_is_residual_check_step
251 subroutine mgsmootherbase_get_initial_residual_statistics( this, res_l2_init, res_max_init )
254 real(rp),
intent(out) :: res_l2_init
255 real(rp),
intent(out) :: res_max_init
258 res_l2_init = this%history_residual_l2_initial
259 res_max_init = this%history_residual_max_initial
261 end subroutine mgsmootherbase_get_initial_residual_statistics
264 subroutine mgsmootherbase_get_current_residual_statistics( this, res_l2, res_max )
267 real(rp),
intent(out) :: res_l2
268 real(rp),
intent(out) :: res_max
271 res_l2 = this%history_residual_l2( this%history_residual_count )
272 res_max = this%history_residual_max( this%history_residual_count )
274 end subroutine mgsmootherbase_get_current_residual_statistics
277 function mgsmootherbase_is_converged( this, is_Vcycle_end )
result( conv_flag )
280 logical,
intent(in) :: is_vcycle_end
283 real(rp) :: res_l2, res_max
286 call this%Get_current_residual_statistics( res_l2, res_max )
289 if ( is_vcycle_end )
then
290 if ( ( res_l2 < this%threshold_residual_l2 &
291 .and. res_max < this%threshold_residual_max ) )
then
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
302 end function mgsmootherbase_is_converged
305 subroutine mgsmootherbase_output_residual_history( this )
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)
319 end subroutine mgsmootherbase_output_residual_history
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, &
351 type(
meshfield2d),
intent(inout),
target :: aux_var(:)
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
363 logical :: zero_initial_guess
364 logical :: cal_res_flag
368 this%history_residual_count = 0
369 this%history_residual_rstep = this%history_residual_step
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()
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, &
380 call this%put_residual( res, conv_flag )
381 if ( cal_res_flag )
then
382 if ( conv_flag )
then
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)
392 end subroutine mgsmootherbase2d_do_smoothing
395 subroutine mgsmootherbase2d_eval_residual_statistic( this, res, &
400 real(rp),
intent(out) :: res_l2
401 real(rp),
intent(out) :: res_max
407 real(rp) :: res_l2_lc, res_max_lc
411 res_l2_lc = 0.0_rp; res_max_lc = 0.0_rp
413 do ldom=1, mesh2d%LOCAL_MESH_NUM
414 lmesh2d => mesh2d%lcmesh_list(ldom)
416 res%local(ldom)%val, lmesh2d, mesh2d%refElem2D )
418 call this%Eval_global_statistic( res_l2, res_max, &
419 res_l2_lc, res_max_lc )
421 end subroutine mgsmootherbase2d_eval_residual_statistic
424 subroutine mgsmootherbase2d_set_initial_residual( this, res )
429 call this%Eval_residual_statistic( res, &
430 this%history_residual_l2_initial, &
431 this%history_residual_max_initial )
433 end subroutine mgsmootherbase2d_set_initial_residual
439 subroutine mgsmootherbase2d_put_residual( this, res, conv_flag)
443 logical,
intent(out) :: conv_flag
445 real(rp) :: res_l2, res_max
446 logical :: is_residual_check_step
449 is_residual_check_step = this%Is_residual_check_step()
450 if ( is_residual_check_step )
then
451 call this%Eval_residual_statistic( res, &
456 is_residual_check_step, res_l2, res_max )
458 end subroutine mgsmootherbase2d_put_residual
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, &
490 type(
meshfield3d),
intent(inout),
target :: aux_var(:)
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
503 logical :: zero_initial_guess
504 logical :: cal_res_flag
508 this%history_residual_count = 0
509 this%history_residual_rstep = this%history_residual_step
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 )
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, &
520 call this%put_residual( res, conv_flag )
521 if ( cal_res_flag )
then
522 if ( conv_flag )
then
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)
532 end subroutine mgsmootherbase3d_do_smoothing
535 subroutine mgsmootherbase3d_eval_residual_statistic( this, res, &
540 real(rp),
intent(out) :: res_l2
541 real(rp),
intent(out) :: res_max
547 real(rp) :: res_l2_lc, res_max_lc
551 res_l2_lc = 0.0_rp; res_max_lc = 0.0_rp
553 do ldom=1, mesh3d%LOCAL_MESH_NUM
554 lmesh3d => mesh3d%lcmesh_list(ldom)
556 res%local(ldom)%val, lmesh3d, mesh3d%refElem3D )
558 call this%Eval_global_statistic( res_l2, res_max, &
559 res_l2_lc, res_max_lc )
561 end subroutine mgsmootherbase3d_eval_residual_statistic
564 subroutine mgsmootherbase3d_set_initial_residual( this, res )
569 call this%Eval_residual_statistic( res, &
570 this%history_residual_l2_initial, &
571 this%history_residual_max_initial )
573 end subroutine mgsmootherbase3d_set_initial_residual
576 subroutine mgsmootherbase3d_put_residual( this, res, conv_flag )
580 logical,
intent(out) :: conv_flag
582 real(rp) :: res_l2, res_max
583 logical :: is_residual_check_step
586 is_residual_check_step = this%Is_residual_check_step()
587 if ( is_residual_check_step )
then
588 call this%Eval_residual_statistic( res, &
593 is_residual_check_step, res_l2, res_max )
595 end subroutine mgsmootherbase3d_put_residual
603 is_residual_check_step, res_l2, res_max )
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
612 if ( is_residual_check_step )
then
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
619 this%history_residual_rstep = this%history_residual_step
622 conv_flag = this%Is_converged( .false. )
624 this%history_residual_rstep = this%history_residual_rstep - 1
633 res_lc, lmesh, 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)
644 real(rp) :: res_(elem%np)
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_(:)) ))
657 subroutine mgsmootherbase_eval_global_statistic( this, res_l2_global, res_max_global, &
658 res_l2_lc, res_max_lc)
660 use scale_prc,
only: &
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
673 call mpi_allreduce( res_l2_lc, res_l2_global, &
674 1, mpi_double_precision, mpi_sum, prc_local_comm_world, ierr )
676 res_l2_global = sqrt( res_l2_global )
679 call mpi_allreduce( res_max_lc, res_max_global, &
680 1, mpi_double_precision, mpi_max, prc_local_comm_world, ierr )
682 end subroutine mgsmootherbase_eval_global_statistic
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
subroutine, public mgsmootherbase_final(this)
integer, parameter, public mgsmoother_pre_id
ID to represent pre-smoothing.
real(rp), parameter, public mgsmoother_default_threshold_residual_l2
subroutine, public mgsmootherbase2d_init(this)
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 mgsmootherbase3d_init(this)
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...
subroutine, public mgsmootherbase2d_final(this)
subroutine, public mgsmootherbase_init(this)
subroutine, public mgsmootherbase3d_final(this)
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 for 2D multigrid smoother.
Derived type for 3D multigrid smoother.
Base type for multigrid smoother.
Derived type to manage a sparse matrix.