11#include "scaleFElib.h"
19 use scale_prc,
only: &
20 prc_ismaster, prc_abort
50 integer :: log_step_interval
52 logical :: output_error_first
56 integer :: polyordererrorcheck
59 real(rp),
allocatable :: intrpmat(:,:)
60 real(rp),
allocatable :: intw_intrp(:)
61 real(rp),
allocatable :: epos_intrp(:,:)
65 procedure :: init_base => meshfield_analysis_numerror_base_init
66 generic :: init => init_base
67 procedure :: final => meshfield_analysis_numerror_base_final
68 procedure :: regist => meshfield_analysis_numerror_base_regist
69 procedure :: evaluate_base => meshfield_analysis_numerror_base_evaluate
71 procedure :: evaluate_error_lc => meshfield_analysis_numerror_base_evaluate_error_lc
72 procedure :: evaluate_covariance_lc => meshfield_analysis_numerror_base_evaluate_covariance_lc
86 num_error_l1_lc_, num_error_l2_lc_, num_error_linf_lc_, &
87 numsol_mean, exactsol_mean )
91 real(RP),
intent(in) :: tsec
92 real(RP),
intent(inout) :: num_error_l1_lc_(this_%var_num)
93 real(RP),
intent(inout) :: num_error_l2_lc_(this_%var_num)
94 real(RP),
intent(inout) :: num_error_linf_lc_(this_%var_num)
95 real(RP),
intent(inout) :: numsol_mean(this_%var_num)
96 real(RP),
intent(inout) :: exactsol_mean(this_%var_num)
99 subroutine calc_covariance_interface( this_, tsec, &
100 cov_numsol_numsol_lc, cov_numsol_exactsol_lc, cov_exactsol_exactsol_lc, &
101 numsol_mean, exactsol_mean )
105 real(RP),
intent(in) :: tsec
106 real(RP),
intent(inout) :: cov_numsol_numsol_lc(this_%var_num)
107 real(RP),
intent(inout) :: cov_numsol_exactsol_lc(this_%var_num)
108 real(RP),
intent(inout) :: cov_exactsol_exactsol_lc(this_%var_num)
109 real(RP),
intent(in) :: numsol_mean(this_%var_num)
110 real(RP),
intent(in) :: exactsol_mean(this_%var_num)
111 end subroutine calc_covariance_interface
114 private :: numerror_do_step
126 subroutine meshfield_analysis_numerror_base_init( this, &
127 porder_error_check, ndim, np, intrp_np, log_fname_base, log_step_interval, &
128 mesh, numerror_analysis_info )
131 integer,
intent(in) :: porder_error_check
132 integer,
intent(in) :: ndim
133 integer,
intent(in) :: np
134 integer,
intent(in) :: intrp_np
135 character(len=*),
intent(in) :: log_fname_base
136 integer,
intent(in) :: log_step_interval
137 class(
meshbase),
intent(in),
target :: mesh
140 character(len=H_MID) :: fname
146 this%log_step_interval = log_step_interval
147 this%log_rstep = log_step_interval
149 this%output_error_first = .true.
152 if ( prc_ismaster )
then
153 this%log_fid = io_get_available_fid()
154 fname = trim(log_fname_base)//
".peall"
155 open( unit = this%log_fid, &
157 form =
'formatted', &
159 if ( ierr /= 0 )
then
160 log_error(
'MeshField_NumErrorAnalysis_Init',*)
'File open error! :', trim(fname)
166 this%PolyOrderErrorCheck = porder_error_check
167 this%intrp_np = intrp_np
169 allocate( this%IntrpMat(this%intrp_np,np) )
170 allocate( this%intw_intrp(this%intrp_np) )
171 allocate( this%epos_intrp(this%intrp_np,this%ndim) )
173 this%info => numerror_analysis_info
176 end subroutine meshfield_analysis_numerror_base_init
181 subroutine meshfield_analysis_numerror_base_final( this )
186 deallocate( this%IntrpMat, this%intw_intrp, this%epos_intrp )
188 close( this%log_fid )
194 end subroutine meshfield_analysis_numerror_base_final
198 subroutine meshfield_analysis_numerror_base_regist( this, varname, unit, varid )
201 character(len=*),
intent(in) :: varname
202 character(len=*),
intent(in) :: unit
203 integer,
intent(out) :: varid
206 this%var_num = this%var_num + 1
209 if ( prc_ismaster )
then
210 write(this%log_fid,
'(A25)',advance=
'no')
'L1_error ('//trim(varname)//
')'
211 write(this%log_fid,
'(A25)',advance=
'no')
'L2_error ('//trim(varname)//
')'
212 write(this%log_fid,
'(A25)',advance=
'no')
'Linf_error ('//trim(varname)//
')'
213 write(this%log_fid,
'(A25)',advance=
'no')
'Ediss ('//trim(varname)//
')'
214 write(this%log_fid,
'(A25)',advance=
'no')
'Edisp ('//trim(varname)//
')'
217 end subroutine meshfield_analysis_numerror_base_regist
221 subroutine meshfield_analysis_numerror_base_evaluate( &
222 this, tstep, tsec, dom_vol, evaluate_error, calc_covariance )
224 use scale_prc,
only: &
228 integer,
intent(in) :: tstep
230 real(RP),
intent(in) :: dom_vol
232 procedure(calc_covariance_interface) :: calc_covariance
234 logical :: do_check_numerror
236 integer,
parameter :: SUM_BUF_L1_ID = 1
237 integer,
parameter :: SUM_BUF_L2_ID = 2
238 integer,
parameter :: SUM_BUF_MEAN_NUMSOL_ID = 3
239 integer,
parameter :: SUM_BUF_MEAN_EXACTSOL_ID = 4
240 integer,
parameter :: SUM_BUF_NUM = 4
242 real(RP) :: num_error_linf_lc(this%var_num)
243 real(RP) :: sum_buf_lc(this%var_num,SUM_BUF_NUM)
244 real(RP) :: num_error_linf(this%var_num)
245 real(RP) :: sum_buf(this%var_num,SUM_BUF_NUM)
247 real(RP) :: covariance_lc(this%var_num,3)
248 real(RP) :: covariance(this%var_num,3)
249 real(RP) :: Ediss(this%var_num), Edisp(this%var_num)
255 if ( this%var_num == 0 )
return
257 if ( this%output_error_first )
then
258 if ( prc_ismaster )
write(this%log_fid,*)
259 this%output_error_first = .false.
262 do_check_numerror = numerror_do_step( this, tstep )
263 if ( .not. do_check_numerror )
then
269 num_error_linf_lc(:) = 0.0_rp
270 sum_buf_lc(:,:) = 0.0_rp
272 call evaluate_error( this, tsec, &
273 sum_buf_lc(:,sum_buf_l1_id), sum_buf_lc(:,sum_buf_l2_id), num_error_linf_lc(:), &
274 sum_buf_lc(:,sum_buf_mean_numsol_id), sum_buf_lc(:,sum_buf_mean_exactsol_id) )
276 call mpi_allreduce( sum_buf_lc(:,:), sum_buf(:,:), &
277 this%var_num * sum_buf_num, &
278 mpi_double_precision, &
280 prc_local_comm_world, &
282 call mpi_allreduce( num_error_linf_lc(:), num_error_linf(:), &
284 mpi_double_precision, &
286 prc_local_comm_world, &
289 sum_buf(:,sum_buf_mean_numsol_id) = sum_buf(:,sum_buf_mean_numsol_id) / dom_vol
290 sum_buf(:,sum_buf_mean_exactsol_id) = sum_buf(:,sum_buf_mean_exactsol_id) / dom_vol
293 covariance_lc(:,:) = 0.0_rp
295 call calc_covariance( this, tsec, &
296 covariance_lc(:,1), covariance_lc(:,2), covariance_lc(:,3), &
297 sum_buf(:,sum_buf_mean_numsol_id), sum_buf(:,sum_buf_mean_exactsol_id) )
299 call mpi_allreduce( covariance_lc(:,:), covariance(:,:), &
301 mpi_double_precision, &
303 prc_local_comm_world, &
306 if ( prc_ismaster )
then
308 ediss(:) = ( sqrt(covariance(:,1) / dom_vol) - sqrt(covariance(:,3) / dom_vol) )**2 &
309 + ( sum_buf(:,sum_buf_mean_numsol_id) - sum_buf(:,sum_buf_mean_exactsol_id) )**2
311 edisp(:) = 2.0_rp * ( sqrt( covariance(:,1) * covariance(:,3) ) &
312 - covariance(:,2) ) / dom_vol
314 write(this%log_fid,
'(A,ES18.8)',advance=
'no')
'tsec=', tsec
315 do iv=1, this%var_num
316 write(this%log_fid,
'(A,ES18.8)',advance=
'no')
' ', sum_buf(iv,sum_buf_l1_id) / dom_vol
317 write(this%log_fid,
'(A,ES18.8)',advance=
'no')
' ', sqrt(sum_buf(iv,sum_buf_l2_id) / dom_vol)
318 write(this%log_fid,
'(A,ES18.8)',advance=
'no')
' ', num_error_linf(iv)
319 write(this%log_fid,
'(A,ES18.8)',advance=
'no')
' ', ediss(iv)
320 write(this%log_fid,
'(A,ES18.8)',advance=
'no')
' ', edisp(iv)
322 write(this%log_fid,*)
328 end subroutine meshfield_analysis_numerror_base_evaluate
332 subroutine meshfield_analysis_numerror_base_evaluate_error_lc( base, &
333 num_error_l1_lc, num_error_l2_lc, num_error_linf_lc, &
334 numsol_mean_lc, exactsol_mean_lc, &
335 q, qexact, qexact_intrp, lcmesh, elem )
340 real(RP),
intent(inout) :: num_error_l1_lc(base%var_num)
341 real(RP),
intent(inout) :: num_error_l2_lc(base%var_num)
342 real(RP),
intent(inout) :: num_error_linf_lc(base%var_num)
343 real(RP),
intent(inout) :: numsol_mean_lc(base%var_num)
344 real(RP),
intent(inout) :: exactsol_mean_lc(base%var_num)
345 real(RP),
intent(in) :: q(elem%Np,lcmesh%Ne,base%var_num)
346 real(RP),
intent(in) :: qexact(elem%Np,lcmesh%Ne,base%var_num)
347 real(RP),
intent(in) :: qexact_intrp(base%intrp_np,lcmesh%Ne,base%var_num)
352 real(RP) :: linf_max_tmp(lcmesh%Ne,base%var_num)
353 real(RP) :: q_intrp(base%intrp_np)
354 real(RP) :: JGsqrtxIntw_intrp(base%intrp_np)
357 do iv=1, base%var_num
359 do ke=lcmesh%NeS, lcmesh%NeE
360 q_intrp(:) = matmul( base%IntrpMat, q(:,ke,iv) )
361 jgsqrtxintw_intrp(:) = matmul( base%IntrpMat, lcmesh%J(:,ke) * lcmesh%Gsqrt(:,ke) )
362 jgsqrtxintw_intrp(:) = jgsqrtxintw_intrp(:) * base%intw_intrp(:)
364 num_error_l1_lc(iv) = num_error_l1_lc(iv) + sum( jgsqrtxintw_intrp(:) * abs( q_intrp(:) - qexact_intrp(:,ke,iv) ) )
365 num_error_l2_lc(iv) = num_error_l2_lc(iv) + sum( jgsqrtxintw_intrp(:) * ( q_intrp(:) - qexact_intrp(:,ke,iv) )**2 )
366 linf_max_tmp(ke,iv) = maxval(abs(q(:,ke,iv) - qexact(:,ke,iv)))
368 numsol_mean_lc(iv) = numsol_mean_lc(iv) + sum( jgsqrtxintw_intrp(:) * q_intrp(:) )
369 exactsol_mean_lc(iv) = exactsol_mean_lc(iv) + sum( jgsqrtxintw_intrp(:) * qexact_intrp(:,ke,iv) )
372 num_error_linf_lc(iv) = max( num_error_linf_lc(iv), maxval( linf_max_tmp(:,iv) ) )
376 end subroutine meshfield_analysis_numerror_base_evaluate_error_lc
380 subroutine meshfield_analysis_numerror_base_evaluate_covariance_lc( base, &
381 cov_numsol_numsol_lc, cov_numsol_exactsol_lc, cov_exactsol_exactsol_lc, &
382 q, qexact, qexact_intrp, numsol_mean, exactsol_mean, &
389 real(RP),
intent(inout) :: cov_numsol_numsol_lc(base%var_num)
390 real(RP),
intent(inout) :: cov_numsol_exactsol_lc(base%var_num)
391 real(RP),
intent(inout) :: cov_exactsol_exactsol_lc(base%var_num)
392 real(RP),
intent(in) :: q(elem%Np,lcmesh%Ne,base%var_num)
393 real(RP),
intent(in) :: qexact(elem%Np,lcmesh%Ne,base%var_num)
394 real(RP),
intent(in) :: qexact_intrp(base%intrp_np,lcmesh%Ne,base%var_num)
395 real(RP),
intent(in) :: numsol_mean(base%var_num)
396 real(RP),
intent(in) :: exactsol_mean(base%var_num)
401 real(RP) :: dq_intrp(base%intrp_np)
402 real(RP) :: JGsqrtxIntw_intrp(base%intrp_np)
403 real(RP) :: dq_exact_intrp(base%intrp_np)
406 do iv=1, base%var_num
408 do ke=lcmesh%NeS, lcmesh%NeE
409 dq_intrp(:) = matmul( base%IntrpMat, q(:,ke,iv) ) - numsol_mean(iv)
410 dq_exact_intrp(:) = qexact_intrp(:,ke,iv)- exactsol_mean(iv)
411 jgsqrtxintw_intrp(:) = matmul( base%IntrpMat, lcmesh%J(:,ke) * lcmesh%Gsqrt(:,ke) )
412 jgsqrtxintw_intrp(:) = jgsqrtxintw_intrp(:) * base%intw_intrp(:)
414 cov_numsol_numsol_lc(iv) = cov_numsol_numsol_lc(iv) + sum( jgsqrtxintw_intrp(:) * dq_intrp(:) * dq_intrp(:) )
415 cov_numsol_exactsol_lc(iv) = cov_numsol_exactsol_lc(iv) + sum( jgsqrtxintw_intrp(:) * dq_intrp(:) * dq_exact_intrp(:) )
416 cov_exactsol_exactsol_lc(iv) = cov_exactsol_exactsol_lc(iv) + sum( jgsqrtxintw_intrp(:) * dq_exact_intrp(:) * dq_exact_intrp(:) )
421 end subroutine meshfield_analysis_numerror_base_evaluate_covariance_lc
428 function numerror_do_step( this, step )
result(do_flag)
432 integer,
intent(in) :: step
436 if ( step == 1 .or. time_nstep < step )
then
441 this%log_rstep = this%log_rstep - 1
442 if ( this%log_rstep == 0 )
then
444 this%log_rstep = this%log_step_interval
450 end function numerror_do_step
module FElib / Element / Base
module FElib / Element / hexahedron
module FElib / Element / line
module FElib / Element / Quadrilateral
module FElib / Mesh / Local, Base
module FElib / Data / base
module FElib / Mesh / Base
module FElib / Data / Statistics / numerical error
module FElib / Data / base
Derived type representing an arbitrary finite element.
Derived type representing a hexahedral element.
Derived type representing a line element.
Derived type representing a quadrilateral element.
Derived type to manage a local computational domain (base type)
Derived type representing a field with local mesh (base type)
Base type to manage a computational mesh.
Base type for numerical error analysis of mesh field.
Derived type saving information for numerical error analysis.
Derived type representing a field (base type)