13 use plm_functions,
only : plm_reconstruction, plm_boundary_extrapolation
14 use ppm_functions,
only : ppm_reconstruction, ppm_boundary_extrapolation
15 use pqm_functions,
only : pqm_reconstruction, pqm_boundary_extrapolation_v1
17 use iso_fortran_env,
only : stdout=>output_unit, stderr=>error_unit
19 implicit none ;
private 21 #include <MOM_memory.h> 27 integer :: remapping_scheme = -911
31 logical :: boundary_extrapolation = .true.
33 logical :: check_reconstruction = .false.
35 logical :: check_remapping = .false.
37 logical :: force_bounds_in_subcell = .false.
39 logical :: answers_2018 = .true.
43 public remapping_core_h, remapping_core_w
44 public initialize_remapping, end_remapping, remapping_set_param, extract_member_remapping_cs
45 public remapping_unit_tests, build_reconstructions_1d, average_value_ppoly
49 integer,
parameter :: remapping_pcm = 0
50 integer,
parameter :: remapping_plm = 1
51 integer,
parameter :: remapping_ppm_h4 = 2
52 integer,
parameter :: remapping_ppm_ih4 = 3
53 integer,
parameter :: remapping_pqm_ih4ih3 = 4
54 integer,
parameter :: remapping_pqm_ih6ih5 = 5
56 integer,
parameter :: integration_pcm = 0
57 integer,
parameter :: integration_plm = 1
58 integer,
parameter :: integration_ppm = 3
59 integer,
parameter :: integration_pqm = 5
61 character(len=40) :: mdl =
"MOM_remapping" 64 character(len=256),
public :: remappingschemesdoc = &
65 "PCM (1st-order accurate)\n"//&
66 "PLM (2nd-order accurate)\n"//&
67 "PPM_H4 (3rd-order accurate)\n"//&
68 "PPM_IH4 (3rd-order accurate)\n"//&
69 "PQM_IH4IH3 (4th-order accurate)\n"//&
70 "PQM_IH6IH5 (5th-order accurate)\n" 71 character(len=3),
public :: remappingdefaultscheme =
"PLM" 76 #define __USE_ROUNDOFF_SAFE_ADJUSTMENTS__ 78 real,
parameter :: hneglect_dflt = 1.e-30
83 logical,
parameter :: old_algorithm = .false.
90 subroutine remapping_set_param(CS, remapping_scheme, boundary_extrapolation, &
91 check_reconstruction, check_remapping, force_bounds_in_subcell, answers_2018)
93 character(len=*),
optional,
intent(in) :: remapping_scheme
94 logical,
optional,
intent(in) :: boundary_extrapolation
95 logical,
optional,
intent(in) :: check_reconstruction
96 logical,
optional,
intent(in) :: check_remapping
97 logical,
optional,
intent(in) :: force_bounds_in_subcell
98 logical,
optional,
intent(in) :: answers_2018
100 if (
present(remapping_scheme))
then 101 call setreconstructiontype( remapping_scheme, cs )
103 if (
present(boundary_extrapolation))
then 104 cs%boundary_extrapolation = boundary_extrapolation
106 if (
present(check_reconstruction))
then 107 cs%check_reconstruction = check_reconstruction
109 if (
present(check_remapping))
then 110 cs%check_remapping = check_remapping
112 if (
present(force_bounds_in_subcell))
then 113 cs%force_bounds_in_subcell = force_bounds_in_subcell
115 if (
present(answers_2018))
then 116 cs%answers_2018 = answers_2018
118 end subroutine remapping_set_param
120 subroutine extract_member_remapping_cs(CS, remapping_scheme, degree, boundary_extrapolation, check_reconstruction, &
121 check_remapping, force_bounds_in_subcell)
123 integer,
optional,
intent(out) :: remapping_scheme
124 integer,
optional,
intent(out) :: degree
125 logical,
optional,
intent(out) :: boundary_extrapolation
126 logical,
optional,
intent(out) :: check_reconstruction
127 logical,
optional,
intent(out) :: check_remapping
129 logical,
optional,
intent(out) :: force_bounds_in_subcell
132 if (
present(remapping_scheme)) remapping_scheme = cs%remapping_scheme
133 if (
present(degree)) degree = cs%degree
134 if (
present(boundary_extrapolation)) boundary_extrapolation = cs%boundary_extrapolation
135 if (
present(check_reconstruction)) check_reconstruction = cs%check_reconstruction
136 if (
present(check_remapping)) check_remapping = cs%check_remapping
137 if (
present(force_bounds_in_subcell)) force_bounds_in_subcell = cs%force_bounds_in_subcell
139 end subroutine extract_member_remapping_cs
141 subroutine buildgridfromh(nz, h, x)
142 integer,
intent(in) :: nz
143 real,
dimension(nz),
intent(in) :: h
144 real,
dimension(nz+1),
intent(inout) :: x
153 end subroutine buildgridfromh
163 function ispossumerrsignificant(n1, sum1, n2, sum2)
164 integer,
intent(in) :: n1
165 integer,
intent(in) :: n2
166 real,
intent(in) :: sum1
167 real,
intent(in) :: sum2
168 logical :: ispossumerrsignificant
170 real :: sumerr, allowederr, eps
172 if (sum1<0.)
call mom_error(fatal,
'isPosSumErrSignificant: sum1<0 is not allowed!')
173 if (sum2<0.)
call mom_error(fatal,
'isPosSumErrSignificant: sum2<0 is not allowed!')
174 sumerr = abs(sum1-sum2)
176 allowederr = eps*0.5*(real(n1-1)*sum1+real(n2-1)*sum2)
177 if (sumerr>allowederr)
then 178 write(0,*)
'isPosSumErrSignificant: sum1,sum2=',sum1,sum2
179 write(0,*)
'isPosSumErrSignificant: eps=',eps
180 write(0,*)
'isPosSumErrSignificant: err,n*eps=',sumerr,allowederr
181 write(0,*)
'isPosSumErrSignificant: err/eps,n1,n2,n1+n2=',sumerr/eps,n1,n2,n1+n2
182 ispossumerrsignificant = .true.
184 ispossumerrsignificant = .false.
186 end function ispossumerrsignificant
189 subroutine remapping_core_h(CS, n0, h0, u0, n1, h1, u1, h_neglect, h_neglect_edge)
191 integer,
intent(in) :: n0
192 real,
dimension(n0),
intent(in) :: h0
193 real,
dimension(n0),
intent(in) :: u0
194 integer,
intent(in) :: n1
195 real,
dimension(n1),
intent(in) :: h1
196 real,
dimension(n1),
intent(out) :: u1
197 real,
optional,
intent(in) :: h_neglect
200 real,
optional,
intent(in) :: h_neglect_edge
205 real,
dimension(n0,2) :: ppoly_r_e
206 real,
dimension(n0,2) :: ppoly_r_s
207 real,
dimension(n0,CS%degree+1) :: ppoly_r_coefs
209 real :: eps, h0tot, h0err, h1tot, h1err, u0tot, u0err, u0min, u0max, u1tot, u1err, u1min, u1max, uh_err
210 real :: hneglect, hneglect_edge
212 hneglect = 1.0e-30 ;
if (
present(h_neglect)) hneglect = h_neglect
213 hneglect_edge = 1.0e-10 ;
if (
present(h_neglect_edge)) hneglect_edge = h_neglect_edge
215 call build_reconstructions_1d( cs, n0, h0, u0, ppoly_r_coefs, ppoly_r_e, ppoly_r_s, imethod, &
216 hneglect, hneglect_edge )
218 if (cs%check_reconstruction)
call check_reconstructions_1d(n0, h0, u0, cs%degree, &
219 cs%boundary_extrapolation, ppoly_r_coefs, ppoly_r_e, ppoly_r_s)
222 call remap_via_sub_cells( n0, h0, u0, ppoly_r_e, ppoly_r_coefs, n1, h1, imethod, &
223 cs%force_bounds_in_subcell, u1, uh_err )
225 if (cs%check_remapping)
then 227 call measure_input_bounds( n0, h0, u0, ppoly_r_e, h0tot, h0err, u0tot, u0err, u0min, u0max )
228 call measure_output_bounds( n1, h1, u1, h1tot, h1err, u1tot, u1err, u1min, u1max )
230 if ( (abs(u1tot-u0tot)>(u0err+u1err)+uh_err .and. abs(h1tot-h0tot)<h0err+h1err) &
231 .or. (u1min<u0min .or. u1max>u0max) )
then 232 write(0,*)
'iMethod = ',imethod
233 write(0,*)
'H: h0tot=',h0tot,
'h1tot=',h1tot,
'dh=',h1tot-h0tot,
'h0err=',h0err,
'h1err=',h1err
234 if (abs(h1tot-h0tot)>h0err+h1err) &
235 write(0,*)
'H non-conservation difference=',h1tot-h0tot,
'allowed err=',h0err+h1err,
' <-----!' 236 write(0,*)
'UH: u0tot=',u0tot,
'u1tot=',u1tot,
'duh=',u1tot-u0tot,
'u0err=',u0err,
'u1err=',u1err,
'uh_err=',uh_err
237 if (abs(u1tot-u0tot)>(u0err+u1err)+uh_err) &
238 write(0,*)
'U non-conservation difference=',u1tot-u0tot,
'allowed err=',u0err+u1err+uh_err,
' <-----!' 239 write(0,*)
'U: u0min=',u0min,
'u1min=',u1min
240 if (u1min<u0min)
write(0,*)
'U minimum overshoot=',u1min-u0min,
' <-----!' 241 write(0,*)
'U: u0max=',u0max,
'u1max=',u1max
242 if (u1max>u0max)
write(0,*)
'U maximum overshoot=',u1max-u0max,
' <-----!' 243 write(0,
'(a3,6a24)')
'k',
'h0',
'left edge',
'u0',
'right edge',
'h1',
'u1' 245 if (k<=min(n0,n1))
then 246 write(0,
'(i3,1p6e24.16)') k,h0(k),ppoly_r_e(k,1),u0(k),ppoly_r_e(k,2),h1(k),u1(k)
248 write(0,
'(i3,96x,1p2e24.16)') k,h1(k),u1(k)
250 write(0,
'(i3,1p4e24.16)') k,h0(k),ppoly_r_e(k,1),u0(k),ppoly_r_e(k,2)
253 write(0,
'(a3,2a24)')
'k',
'u0',
'Polynomial coefficients' 255 write(0,
'(i3,1p6e24.16)') k,u0(k),ppoly_r_coefs(k,:)
257 call mom_error( fatal,
'MOM_remapping, remapping_core_h: '//&
258 'Remapping result is inconsistent!' )
263 end subroutine remapping_core_h
267 subroutine remapping_core_w( CS, n0, h0, u0, n1, dx, u1, h_neglect, h_neglect_edge )
269 integer,
intent(in) :: n0
270 real,
dimension(n0),
intent(in) :: h0
271 real,
dimension(n0),
intent(in) :: u0
272 integer,
intent(in) :: n1
273 real,
dimension(n1+1),
intent(in) :: dx
274 real,
dimension(n1),
intent(out) :: u1
275 real,
optional,
intent(in) :: h_neglect
278 real,
optional,
intent(in) :: h_neglect_edge
283 real,
dimension(n0,2) :: ppoly_r_e
284 real,
dimension(n0,2) :: ppoly_r_s
285 real,
dimension(n0,CS%degree+1) :: ppoly_r_coefs
287 real :: eps, h0tot, h0err, h1tot, h1err
288 real :: u0tot, u0err, u0min, u0max, u1tot, u1err, u1min, u1max, uh_err
289 real,
dimension(n1) :: h1
290 real :: hneglect, hneglect_edge
292 hneglect = 1.0e-30 ;
if (
present(h_neglect)) hneglect = h_neglect
293 hneglect_edge = 1.0e-10 ;
if (
present(h_neglect_edge)) hneglect_edge = h_neglect_edge
295 call build_reconstructions_1d( cs, n0, h0, u0, ppoly_r_coefs, ppoly_r_e, ppoly_r_s, imethod,&
296 hneglect, hneglect_edge )
298 if (cs%check_reconstruction)
call check_reconstructions_1d(n0, h0, u0, cs%degree, &
299 cs%boundary_extrapolation, ppoly_r_coefs, ppoly_r_e, ppoly_r_s)
304 h1(k) = max( 0., h0(k) + ( dx(k+1) - dx(k) ) )
306 h1(k) = max( 0., dx(k+1) - dx(k) )
309 call remap_via_sub_cells( n0, h0, u0, ppoly_r_e, ppoly_r_coefs, n1, h1, imethod, &
310 cs%force_bounds_in_subcell,u1, uh_err )
314 if (cs%check_remapping)
then 316 call measure_input_bounds( n0, h0, u0, ppoly_r_e, h0tot, h0err, u0tot, u0err, u0min, u0max )
317 call measure_output_bounds( n1, h1, u1, h1tot, h1err, u1tot, u1err, u1min, u1max )
319 if ( (abs(u1tot-u0tot)>(u0err+u1err)+uh_err .and. abs(h1tot-h0tot)<h0err+h1err) &
320 .or. (u1min<u0min .or. u1max>u0max) )
then 321 write(0,*)
'iMethod = ',imethod
322 write(0,*)
'H: h0tot=',h0tot,
'h1tot=',h1tot,
'dh=',h1tot-h0tot,
'h0err=',h0err,
'h1err=',h1err
323 if (abs(h1tot-h0tot)>h0err+h1err) &
324 write(0,*)
'H non-conservation difference=',h1tot-h0tot,
'allowed err=',h0err+h1err,
' <-----!' 325 write(0,*)
'UH: u0tot=',u0tot,
'u1tot=',u1tot,
'duh=',u1tot-u0tot,
'u0err=',u0err,
'u1err=',u1err,
'uh_err=',uh_err
326 if (abs(u1tot-u0tot)>(u0err+u1err)+uh_err) &
327 write(0,*)
'U non-conservation difference=',u1tot-u0tot,
'allowed err=',u0err+u1err+uh_err,
' <-----!' 328 write(0,*)
'U: u0min=',u0min,
'u1min=',u1min
329 if (u1min<u0min)
write(0,*)
'U minimum overshoot=',u1min-u0min,
' <-----!' 330 write(0,*)
'U: u0max=',u0max,
'u1max=',u1max
331 if (u1max>u0max)
write(0,*)
'U maximum overshoot=',u1max-u0max,
' <-----!' 332 write(0,
'(a3,6a24)')
'k',
'h0',
'left edge',
'u0',
'right edge',
'h1',
'u1' 334 if (k<=min(n0,n1))
then 335 write(0,
'(i3,1p6e24.16)') k,h0(k),ppoly_r_e(k,1),u0(k),ppoly_r_e(k,2),h1(k),u1(k)
337 write(0,
'(i3,96x,1p2e24.16)') k,h1(k),u1(k)
339 write(0,
'(i3,1p4e24.16)') k,h0(k),ppoly_r_e(k,1),u0(k),ppoly_r_e(k,2)
342 write(0,
'(a3,2a24)')
'k',
'u0',
'Polynomial coefficients' 344 write(0,
'(i3,1p6e24.16)') k,u0(k),ppoly_r_coefs(k,:)
346 call mom_error( fatal,
'MOM_remapping, remapping_core_w: '//&
347 'Remapping result is inconsistent!' )
352 end subroutine remapping_core_w
355 subroutine build_reconstructions_1d( CS, n0, h0, u0, ppoly_r_coefs, &
356 ppoly_r_E, ppoly_r_S, iMethod, h_neglect, &
359 integer,
intent(in) :: n0
360 real,
dimension(n0),
intent(in) :: h0
361 real,
dimension(n0),
intent(in) :: u0
362 real,
dimension(n0,CS%degree+1), &
363 intent(out) :: ppoly_r_coefs
364 real,
dimension(n0,2),
intent(out) :: ppoly_r_e
365 real,
dimension(n0,2),
intent(out) :: ppoly_r_s
366 integer,
intent(out) :: imethod
367 real,
optional,
intent(in) :: h_neglect
370 real,
optional,
intent(in) :: h_neglect_edge
374 integer :: local_remapping_scheme
375 integer :: remapping_scheme
376 logical :: boundary_extrapolation
381 ppoly_r_coefs(:,:) = 0.0
384 local_remapping_scheme = cs%remapping_scheme
386 local_remapping_scheme = remapping_pcm
388 local_remapping_scheme = min( local_remapping_scheme, remapping_plm )
390 local_remapping_scheme = min( local_remapping_scheme, remapping_ppm_h4 )
392 select case ( local_remapping_scheme )
393 case ( remapping_pcm )
394 call pcm_reconstruction( n0, u0, ppoly_r_e, ppoly_r_coefs)
395 imethod = integration_pcm
396 case ( remapping_plm )
397 call plm_reconstruction( n0, h0, u0, ppoly_r_e, ppoly_r_coefs, h_neglect )
398 if ( cs%boundary_extrapolation )
then 399 call plm_boundary_extrapolation( n0, h0, u0, ppoly_r_e, ppoly_r_coefs, h_neglect)
401 imethod = integration_plm
402 case ( remapping_ppm_h4 )
403 call edge_values_explicit_h4( n0, h0, u0, ppoly_r_e, h_neglect_edge, answers_2018=cs%answers_2018 )
404 call ppm_reconstruction( n0, h0, u0, ppoly_r_e, ppoly_r_coefs, h_neglect, answers_2018=cs%answers_2018 )
405 if ( cs%boundary_extrapolation )
then 406 call ppm_boundary_extrapolation( n0, h0, u0, ppoly_r_e, ppoly_r_coefs, h_neglect )
408 imethod = integration_ppm
409 case ( remapping_ppm_ih4 )
410 call edge_values_implicit_h4( n0, h0, u0, ppoly_r_e, h_neglect_edge, answers_2018=cs%answers_2018 )
411 call ppm_reconstruction( n0, h0, u0, ppoly_r_e, ppoly_r_coefs, h_neglect, answers_2018=cs%answers_2018 )
412 if ( cs%boundary_extrapolation )
then 413 call ppm_boundary_extrapolation( n0, h0, u0, ppoly_r_e, ppoly_r_coefs, h_neglect )
415 imethod = integration_ppm
416 case ( remapping_pqm_ih4ih3 )
417 call edge_values_implicit_h4( n0, h0, u0, ppoly_r_e, h_neglect_edge, answers_2018=cs%answers_2018 )
418 call edge_slopes_implicit_h3( n0, h0, u0, ppoly_r_s, h_neglect, answers_2018=cs%answers_2018 )
419 call pqm_reconstruction( n0, h0, u0, ppoly_r_e, ppoly_r_s, ppoly_r_coefs, h_neglect, &
420 answers_2018=cs%answers_2018 )
421 if ( cs%boundary_extrapolation )
then 422 call pqm_boundary_extrapolation_v1( n0, h0, u0, ppoly_r_e, ppoly_r_s, &
423 ppoly_r_coefs, h_neglect )
425 imethod = integration_pqm
426 case ( remapping_pqm_ih6ih5 )
427 call edge_values_implicit_h6( n0, h0, u0, ppoly_r_e, h_neglect_edge, answers_2018=cs%answers_2018 )
428 call edge_slopes_implicit_h5( n0, h0, u0, ppoly_r_s, h_neglect, answers_2018=cs%answers_2018 )
429 call pqm_reconstruction( n0, h0, u0, ppoly_r_e, ppoly_r_s, ppoly_r_coefs, h_neglect, &
430 answers_2018=cs%answers_2018 )
431 if ( cs%boundary_extrapolation )
then 432 call pqm_boundary_extrapolation_v1( n0, h0, u0, ppoly_r_e, ppoly_r_s, &
433 ppoly_r_coefs, h_neglect )
435 imethod = integration_pqm
437 call mom_error( fatal,
'MOM_remapping, build_reconstructions_1d: '//&
438 'The selected remapping method is invalid' )
441 end subroutine build_reconstructions_1d
444 subroutine check_reconstructions_1d(n0, h0, u0, deg, boundary_extrapolation, &
445 ppoly_r_coefs, ppoly_r_E, ppoly_r_S)
446 integer,
intent(in) :: n0
447 real,
dimension(n0),
intent(in) :: h0
448 real,
dimension(n0),
intent(in) :: u0
449 integer,
intent(in) :: deg
450 logical,
intent(in) :: boundary_extrapolation
451 real,
dimension(n0,deg+1),
intent(out) :: ppoly_r_coefs
452 real,
dimension(n0,2),
intent(out) :: ppoly_r_E
453 real,
dimension(n0,2),
intent(out) :: ppoly_r_S
456 real :: u_l, u_c, u_r
458 logical :: problem_detected
460 problem_detected = .false.
462 u_l = u0(max(1,i0-1))
464 u_r = u0(min(n0,i0+1))
465 if (i0 > 1 .or. .not. boundary_extrapolation)
then 466 u_min = min(u_l, u_c)
467 u_max = max(u_l, u_c)
468 if (ppoly_r_e(i0,1) < u_min)
then 469 write(0,
'(a,i4,5(x,a,1pe24.16))')
'Left edge undershoot at',i0,
'u(i0-1)=',u_l,
'u(i0)=',u_c, &
470 'edge=',ppoly_r_e(i0,1),
'err=',ppoly_r_e(i0,1)-u_min
471 problem_detected = .true.
473 if (ppoly_r_e(i0,1) > u_max)
then 474 write(0,
'(a,i4,5(x,a,1pe24.16))')
'Left edge overshoot at',i0,
'u(i0-1)=',u_l,
'u(i0)=',u_c, &
475 'edge=',ppoly_r_e(i0,1),
'err=',ppoly_r_e(i0,1)-u_max
476 problem_detected = .true.
479 if (i0 < n0 .or. .not. boundary_extrapolation)
then 480 u_min = min(u_c, u_r)
481 u_max = max(u_c, u_r)
482 if (ppoly_r_e(i0,2) < u_min)
then 483 write(0,
'(a,i4,5(x,a,1pe24.16))')
'Right edge undershoot at',i0,
'u(i0)=',u_c,
'u(i0+1)=',u_r, &
484 'edge=',ppoly_r_e(i0,2),
'err=',ppoly_r_e(i0,2)-u_min
485 problem_detected = .true.
487 if (ppoly_r_e(i0,2) > u_max)
then 488 write(0,
'(a,i4,5(x,a,1pe24.16))')
'Right edge overshoot at',i0,
'u(i0)=',u_c,
'u(i0+1)=',u_r, &
489 'edge=',ppoly_r_e(i0,2),
'err=',ppoly_r_e(i0,2)-u_max
490 problem_detected = .true.
494 if ( (u_c-u_l)*(ppoly_r_e(i0,1)-ppoly_r_e(i0-1,2)) < 0.)
then 495 write(0,
'(a,i4,5(x,a,1pe24.16))')
'Non-monotonic edges at',i0,
'u(i0-1)=',u_l,
'u(i0)=',u_c, &
496 'right edge=',ppoly_r_e(i0-1,2),
'left edge=',ppoly_r_e(i0,1)
497 write(0,
'(5(a,1pe24.16,x))')
'u(i0)-u(i0-1)',u_c-u_l,
'edge diff=',ppoly_r_e(i0,1)-ppoly_r_e(i0-1,2)
498 problem_detected = .true.
501 if (problem_detected)
then 502 write(0,
'(a,1p9e24.16)')
'Polynomial coeffs:',ppoly_r_coefs(i0,:)
503 write(0,
'(3(a,1pe24.16,x))')
'u_l=',u_l,
'u_c=',u_c,
'u_r=',u_r
504 write(0,
'(a4,10a24)')
'i0',
'h0(i0)',
'u0(i0)',
'left edge',
'right edge',
'Polynomial coefficients' 506 write(0,
'(i4,1p10e24.16)') n,h0(n),u0(n),ppoly_r_e(n,1),ppoly_r_e(n,2),ppoly_r_coefs(n,:)
508 call mom_error(fatal,
'MOM_remapping, check_reconstructions_1d: '// &
509 'Edge values or polynomial coefficients were inconsistent!')
513 end subroutine check_reconstructions_1d
518 subroutine remap_via_sub_cells( n0, h0, u0, ppoly0_E, ppoly0_coefs, n1, h1, method, &
519 force_bounds_in_subcell, u1, uh_err, ah_sub, aisub_src, aiss, aise )
520 integer,
intent(in) :: n0
521 real,
intent(in) :: h0(n0)
522 real,
intent(in) :: u0(n0)
523 real,
intent(in) :: ppoly0_E(n0,2)
524 real,
intent(in) :: ppoly0_coefs(:,:)
525 integer,
intent(in) :: n1
526 real,
intent(in) :: h1(n1)
527 integer,
intent(in) :: method
528 logical,
intent(in) :: force_bounds_in_subcell
529 real,
intent(out) :: u1(n1)
530 real,
intent(out) :: uh_err
531 real,
optional,
intent(out) :: ah_sub(n0+n1+1)
532 integer,
optional,
intent(out) :: aisub_src(n0+n1+1)
533 integer,
optional,
intent(out) :: aiss(n0)
534 integer,
optional,
intent(out) :: aise(n0)
543 real,
dimension(n0+n1+1) :: h_sub
544 real,
dimension(n0+n1+1) :: uh_sub
545 real,
dimension(n0+n1+1) :: u_sub
546 integer,
dimension(n0+n1+1) :: isub_src
547 integer,
dimension(n0) :: isrc_start
548 integer,
dimension(n0) :: isrc_end
549 integer,
dimension(n0) :: isrc_max
550 real,
dimension(n0) :: h0_eff
551 real,
dimension(n0) :: u0_min
552 real,
dimension(n0) :: u0_max
553 integer,
dimension(n1) :: itgt_start
554 integer,
dimension(n1) :: itgt_end
556 real :: h0_supply, h1_supply
561 logical,
parameter :: force_bounds_in_target = .true.
562 logical,
parameter :: adjust_thickest_subcell = .true.
563 logical,
parameter :: debug_bounds = .false.
564 integer :: k, i0_last_thick_cell
565 real :: h0tot, h0err, h1tot, h1err, h2tot, h2err, u02_err
566 real :: u0tot, u0err, u0min, u0max, u1tot, u1err, u1min, u1max, u2tot, u2err, u2min, u2max, u_orig
567 logical :: src_has_volume
568 logical :: tgt_has_volume
570 if (old_algorithm) isrc_max(:)=1
572 i0_last_thick_cell = 0
574 u0_min(i0) = min(ppoly0_e(i0,1), ppoly0_e(i0,2))
575 u0_max(i0) = max(ppoly0_e(i0,1), ppoly0_e(i0,2))
576 if (h0(i0)>0.) i0_last_thick_cell = i0
582 src_has_volume = .true.
583 tgt_has_volume = .true.
585 i_start0 = 1 ; i_start1 = 1
598 do i_sub = 2, n0+n1+1
602 dh = min(h0_supply, h1_supply)
607 dh0_eff = dh0_eff + min(dh, h0_supply)
616 if (dh >= dh_max)
then 623 if (h0_supply <= h1_supply .and. src_has_volume)
then 626 h1_supply = h1_supply - dh
629 isrc_start(i0) = i_start0
639 if (old_algorithm)
then 640 if (i0 < i0_last_thick_cell)
then 644 do while (h0_supply==0. .and. i0<i0_last_thick_cell)
659 src_has_volume = .false.
662 elseif (h0_supply >= h1_supply .and. tgt_has_volume)
then 665 h0_supply = h0_supply - dh
668 itgt_start(i1) = i_start1
676 if (old_algorithm)
then 680 tgt_has_volume = .false.
683 elseif (src_has_volume)
then 685 h_sub(i_sub) = h0_supply
687 isrc_start(i0) = i_start0
702 src_has_volume = .false.
704 elseif (tgt_has_volume)
then 706 h_sub(i_sub) = h1_supply
708 itgt_start(i1) = i_start1
717 tgt_has_volume = .false.
720 stop
'remap_via_sub_cells: THIS SHOULD NEVER HAPPEN!' 729 u_sub(1) = ppoly0_e(1,1)
742 dh0_eff = dh0_eff + dh
743 if (h0_eff(i0)>0.)
then 744 xb = dh0_eff / h0_eff(i0)
746 u_sub(i_sub) = average_value_ppoly( n0, u0, ppoly0_e, ppoly0_coefs, method, i0, xa, xb)
749 u_sub(i_sub) = u0(i0)
751 if (debug_bounds)
then 752 if (method<5 .and.(u_sub(i_sub)<u0_min(i0) .or. u_sub(i_sub)>u0_max(i0)))
then 753 write(0,*)
'Sub cell average is out of bounds',i_sub,
'method=',method
754 write(0,*)
'xa,xb: ',xa,xb
755 write(0,*)
'Edge values: ',ppoly0_e(i0,:),
'mean',u0(i0)
756 write(0,*)
'a_c: ',(u0(i0)-ppoly0_e(i0,1))+(u0(i0)-ppoly0_e(i0,2))
757 write(0,*)
'Polynomial coeffs: ',ppoly0_coefs(i0,:)
758 write(0,*)
'Bounds min=',u0_min(i0),
'max=',u0_max(i0)
759 write(0,*)
'Average: ',u_sub(i_sub),
'rel to min=',u_sub(i_sub)-u0_min(i0),
'rel to max=',u_sub(i_sub)-u0_max(i0)
760 call mom_error( fatal,
'MOM_remapping, remap_via_sub_cells: '//&
761 'Sub-cell average is out of bounds!' )
764 if (force_bounds_in_subcell)
then 768 u_orig = u_sub(i_sub)
769 u_sub(i_sub) = max( u_sub(i_sub), u0_min(i0) )
770 u_sub(i_sub) = min( u_sub(i_sub), u0_max(i0) )
771 u02_err = u02_err + dh*abs( u_sub(i_sub) - u_orig )
773 uh_sub(i_sub) = dh * u_sub(i_sub)
775 if (isub_src(i_sub+1) /= i0)
then 784 u_sub(n0+n1+1) = ppoly0_e(n0,2)
785 uh_sub(n0+n1+1) = ppoly0_e(n0,2) * h_sub(n0+n1+1)
787 if (adjust_thickest_subcell)
then 791 do i0 = 1, i0_last_thick_cell
793 dh_max = h_sub(i_max)
794 if (dh_max > 0.)
then 797 do i_sub = isrc_start(i0), isrc_end(i0)
798 if (i_sub /= i_max) duh = duh + uh_sub(i_sub)
800 uh_sub(i_max) = u0(i0)*h0(i0) - duh
801 u02_err = u02_err + max( abs(uh_sub(i_max)), abs(u0(i0)*h0(i0)), abs(duh) )
809 if (h1(i1) > 0.)
then 811 i_sub = itgt_start(i1)
812 if (force_bounds_in_target)
then 816 do i_sub = itgt_start(i1), itgt_end(i1)
817 if (force_bounds_in_target)
then 818 u1min = min(u1min, u_sub(i_sub))
819 u1max = max(u1max, u_sub(i_sub))
821 dh = dh + h_sub(i_sub)
822 duh = duh + uh_sub(i_sub)
824 uh_err = uh_err + max(abs(duh),abs(uh_sub(i_sub)))*epsilon(duh)
828 uh_err = uh_err + abs(duh)*epsilon(duh)
829 if (force_bounds_in_target)
then 831 u1(i1) = max(u1min, min(u1max, u1(i1)))
833 uh_err = uh_err + dh*abs( u1(i1)-u_orig )
836 u1(i1) = u_sub(itgt_start(i1))
841 if (debug_bounds)
then 842 call measure_input_bounds( n0, h0, u0, ppoly0_e, h0tot, h0err, u0tot, u0err, u0min, u0max )
843 call measure_output_bounds( n1, h1, u1, h1tot, h1err, u1tot, u1err, u1min, u1max )
844 call measure_output_bounds( n0+n1+1, h_sub, u_sub, h2tot, h2err, u2tot, u2err, u2min, u2max )
846 if ( (abs(u1tot-u0tot)>(u0err+u1err)+uh_err+u02_err .and. abs(h1tot-h0tot)<h0err+h1err) &
847 .or. (abs(u2tot-u0tot)>u0err+u2err+u02_err .and. abs(h2tot-h0tot)<h0err+h2err) &
848 .or. (u1min<u0min .or. u1max>u0max) )
then 849 write(0,*)
'method = ',method
850 write(0,*)
'Source to sub-cells:' 851 write(0,*)
'H: h0tot=',h0tot,
'h2tot=',h2tot,
'dh=',h2tot-h0tot,
'h0err=',h0err,
'h2err=',h2err
852 if (abs(h2tot-h0tot)>h0err+h2err) &
853 write(0,*)
'H non-conservation difference=',h2tot-h0tot,
'allowed err=',h0err+h2err,
' <-----!' 854 write(0,*)
'UH: u0tot=',u0tot,
'u2tot=',u2tot,
'duh=',u2tot-u0tot,
'u0err=',u0err,
'u2err=',u2err,&
855 'adjustment err=',u02_err
856 if (abs(u2tot-u0tot)>u0err+u2err) &
857 write(0,*)
'U non-conservation difference=',u2tot-u0tot,
'allowed err=',u0err+u2err,
' <-----!' 858 write(0,*)
'Sub-cells to target:' 859 write(0,*)
'H: h2tot=',h2tot,
'h1tot=',h1tot,
'dh=',h1tot-h2tot,
'h2err=',h2err,
'h1err=',h1err
860 if (abs(h1tot-h2tot)>h2err+h1err) &
861 write(0,*)
'H non-conservation difference=',h1tot-h2tot,
'allowed err=',h2err+h1err,
' <-----!' 862 write(0,*)
'UH: u2tot=',u2tot,
'u1tot=',u1tot,
'duh=',u1tot-u2tot,
'u2err=',u2err,
'u1err=',u1err,
'uh_err=',uh_err
863 if (abs(u1tot-u2tot)>u2err+u1err) &
864 write(0,*)
'U non-conservation difference=',u1tot-u2tot,
'allowed err=',u2err+u1err,
' <-----!' 865 write(0,*)
'Source to target:' 866 write(0,*)
'H: h0tot=',h0tot,
'h1tot=',h1tot,
'dh=',h1tot-h0tot,
'h0err=',h0err,
'h1err=',h1err
867 if (abs(h1tot-h0tot)>h0err+h1err) &
868 write(0,*)
'H non-conservation difference=',h1tot-h0tot,
'allowed err=',h0err+h1err,
' <-----!' 869 write(0,*)
'UH: u0tot=',u0tot,
'u1tot=',u1tot,
'duh=',u1tot-u0tot,
'u0err=',u0err,
'u1err=',u1err,
'uh_err=',uh_err
870 if (abs(u1tot-u0tot)>(u0err+u1err)+uh_err) &
871 write(0,*)
'U non-conservation difference=',u1tot-u0tot,
'allowed err=',u0err+u1err+uh_err,
' <-----!' 872 write(0,*)
'U: u0min=',u0min,
'u1min=',u1min,
'u2min=',u2min
873 if (u1min<u0min)
write(0,*)
'U minimum overshoot=',u1min-u0min,
' <-----!' 874 if (u2min<u0min)
write(0,*)
'U2 minimum overshoot=',u2min-u0min,
' <-----!' 875 write(0,*)
'U: u0max=',u0max,
'u1max=',u1max,
'u2max=',u2max
876 if (u1max>u0max)
write(0,*)
'U maximum overshoot=',u1max-u0max,
' <-----!' 877 if (u2max>u0max)
write(0,*)
'U2 maximum overshoot=',u2max-u0max,
' <-----!' 878 write(0,
'(a3,6a24,2a3)')
'k',
'h0',
'left edge',
'u0',
'right edge',
'h1',
'u1',
'is',
'ie' 880 if (k<=min(n0,n1))
then 881 write(0,
'(i3,1p6e24.16,2i3)') k,h0(k),ppoly0_e(k,1),u0(k),ppoly0_e(k,2),h1(k),u1(k),itgt_start(k),itgt_end(k)
883 write(0,
'(i3,96x,1p2e24.16,2i3)') k,h1(k),u1(k),itgt_start(k),itgt_end(k)
885 write(0,
'(i3,1p4e24.16)') k,h0(k),ppoly0_e(k,1),u0(k),ppoly0_e(k,2)
888 write(0,
'(a3,2a24)')
'k',
'u0',
'Polynomial coefficients' 890 write(0,
'(i3,1p6e24.16)') k,u0(k),ppoly0_coefs(k,:)
892 write(0,
'(a3,3a24,a3,2a24)')
'k',
'Sub-cell h',
'Sub-cell u',
'Sub-cell hu',
'i0',
'xa',
'xb' 898 dh0_eff = dh0_eff + dh
899 xb = dh0_eff / h0_eff(i0)
901 write(0,
'(i3,1p3e24.16,i3,1p2e24.16)') k,h_sub(k),u_sub(k),uh_sub(k),i0,xa,xb
903 if (isub_src(k+1) /= i0)
then 904 dh0_eff = 0.; xa = 0.
910 call mom_error( fatal,
'MOM_remapping, remap_via_sub_cells: '//&
911 'Remapping result is inconsistent!' )
917 uh_err = uh_err + u02_err
919 if (
present(ah_sub)) ah_sub(1:n0+n1+1) = h_sub(1:n0+n1+1)
920 if (
present(aisub_src)) aisub_src(1:n0+n1+1) = isub_src(1:n0+n1+1)
921 if (
present(aiss)) aiss(1:n0) = isrc_start(1:n0)
922 if (
present(aise)) aise(1:n0) = isrc_end(1:n0)
924 end subroutine remap_via_sub_cells
929 real function average_value_ppoly( n0, u0, ppoly0_E, ppoly0_coefs, method, i0, xa, xb)
930 integer,
intent(in) :: n0
931 real,
intent(in) :: u0(:)
932 real,
intent(in) :: ppoly0_e(:,:)
933 real,
intent(in) :: ppoly0_coefs(:,:)
934 integer,
intent(in) :: method
935 integer,
intent(in) :: i0
936 real,
intent(in) :: xa
937 real,
intent(in) :: xb
939 real :: u_ave, xa_2, xb_2, xa2pxb2, xapxb
940 real,
parameter :: r_3 = 1.0/3.0
942 real :: mx, a_l, a_r, u_c, ya, yb, my, xa2b2ab, ya2b2ab, a_c
945 select case ( method )
946 case ( integration_pcm )
948 case ( integration_plm )
951 + ppoly0_coefs(i0,2) * 0.5 * ( xb + xa ) )
952 case ( integration_ppm )
953 mx = 0.5 * ( xa + xb )
954 a_l = ppoly0_e(i0, 1)
955 a_r = ppoly0_e(i0, 2)
957 a_c = 0.5 * ( ( u_c - a_l ) + ( u_c - a_r ) )
960 xa2b2ab = (xa*xa+xb*xb)+xa*xb
961 u_ave = a_l + ( ( a_r - a_l ) * mx &
962 + a_c * ( 3. * ( xb + xa ) - 2.*xa2b2ab ) )
967 my = 0.5 * ( ya + yb )
968 ya2b2ab = (ya*ya+yb*yb)+ya*yb
969 u_ave = a_r + ( ( a_l - a_r ) * my &
970 + a_c * ( 3. * ( yb + ya ) - 2.*ya2b2ab ) )
972 case ( integration_pqm )
975 xa2pxb2 = xa_2 + xb_2
979 + ( ppoly0_coefs(i0,2) * 0.5 * ( xapxb ) &
980 + ( ppoly0_coefs(i0,3) * r_3 * ( xa2pxb2 + xa*xb ) &
981 + ( ppoly0_coefs(i0,4) * 0.25* ( xa2pxb2 * xapxb ) &
982 + ppoly0_coefs(i0,5) * 0.2 * ( ( xb*xb_2 + xa*xa_2 ) * xapxb + xa_2*xb_2 ) ) ) ) )
984 call mom_error( fatal,
'The selected integration method is invalid' )
987 select case ( method )
988 case ( integration_pcm )
989 u_ave = ppoly0_coefs(i0,1)
990 case ( integration_plm )
993 a_l = ppoly0_e(i0, 1)
994 a_r = ppoly0_e(i0, 2)
997 u_ave = a_l + xa * ( a_r - a_l )
999 u_ave = a_r + ya * ( a_l - a_r )
1001 case ( integration_ppm )
1005 a_l = ppoly0_e(i0, 1)
1006 a_r = ppoly0_e(i0, 2)
1008 a_c = 3. * ( ( u_c - a_l ) + ( u_c - a_r ) )
1011 u_ave = a_l + xa * ( ( a_r - a_l ) + a_c * ya )
1013 u_ave = a_r + ya * ( ( a_l - a_r ) + a_c * xa )
1015 case ( integration_pqm )
1016 u_ave = ppoly0_coefs(i0,1) &
1017 + xa * ( ppoly0_coefs(i0,2) &
1018 + xa * ( ppoly0_coefs(i0,3) &
1019 + xa * ( ppoly0_coefs(i0,4) &
1020 + xa * ppoly0_coefs(i0,5) ) ) )
1022 call mom_error( fatal,
'The selected integration method is invalid' )
1025 average_value_ppoly = u_ave
1027 end function average_value_ppoly
1030 subroutine measure_input_bounds( n0, h0, u0, edge_values, h0tot, h0err, u0tot, u0err, u0min, u0max )
1031 integer,
intent(in) :: n0
1032 real,
dimension(n0),
intent(in) :: h0
1033 real,
dimension(n0),
intent(in) :: u0
1034 real,
dimension(n0,2),
intent(in) :: edge_values
1035 real,
intent(out) :: h0tot
1036 real,
intent(out) :: h0err
1037 real,
intent(out) :: u0tot
1038 real,
intent(out) :: u0err
1039 real,
intent(out) :: u0min
1040 real,
intent(out) :: u0max
1045 eps = epsilon(h0(1))
1048 u0tot = h0(1) * u0(1)
1050 u0min = min( edge_values(1,1), edge_values(1,2) )
1051 u0max = max( edge_values(1,1), edge_values(1,2) )
1053 h0tot = h0tot + h0(k)
1054 h0err = h0err + eps * max(h0tot, h0(k))
1055 u0tot = u0tot + h0(k) * u0(k)
1056 u0err = u0err + eps * max(abs(u0tot), abs(h0(k) * u0(k)))
1057 u0min = min( u0min, edge_values(k,1), edge_values(k,2) )
1058 u0max = max( u0max, edge_values(k,1), edge_values(k,2) )
1061 end subroutine measure_input_bounds
1064 subroutine measure_output_bounds( n1, h1, u1, h1tot, h1err, u1tot, u1err, u1min, u1max )
1065 integer,
intent(in) :: n1
1066 real,
dimension(n1),
intent(in) :: h1
1067 real,
dimension(n1),
intent(in) :: u1
1068 real,
intent(out) :: h1tot
1069 real,
intent(out) :: h1err
1070 real,
intent(out) :: u1tot
1071 real,
intent(out) :: u1err
1072 real,
intent(out) :: u1min
1073 real,
intent(out) :: u1max
1078 eps = epsilon(h1(1))
1081 u1tot = h1(1) * u1(1)
1086 h1tot = h1tot + h1(k)
1087 h1err = h1err + eps * max(h1tot, h1(k))
1088 u1tot = u1tot + h1(k) * u1(k)
1089 u1err = u1err + eps * max(abs(u1tot), abs(h1(k) * u1(k)))
1090 u1min = min(u1min, u1(k))
1091 u1max = max(u1max, u1(k))
1094 end subroutine measure_output_bounds
1098 subroutine remapbyprojection( n0, h0, u0, ppoly0_E, ppoly0_coefs, &
1099 n1, h1, method, u1, h_neglect )
1100 integer,
intent(in) :: n0
1101 real,
intent(in) :: h0(:)
1102 real,
intent(in) :: u0(:)
1103 real,
intent(in) :: ppoly0_E(:,:)
1104 real,
intent(in) :: ppoly0_coefs(:,:)
1105 integer,
intent(in) :: n1
1106 real,
intent(in) :: h1(:)
1107 integer,
intent(in) :: method
1108 real,
intent(out) :: u1(:)
1109 real,
optional,
intent(in) :: h_neglect
1127 xr = xl + h1(itarget)
1129 call integraterecononinterval( n0, h0, u0, ppoly0_e, ppoly0_coefs, method, &
1130 xl, xr, h1(itarget), u1(itarget), jstart, xstart, h_neglect )
1134 end subroutine remapbyprojection
1146 subroutine remapbydeltaz( n0, h0, u0, ppoly0_E, ppoly0_coefs, n1, dx1, &
1147 method, u1, h1, h_neglect )
1148 integer,
intent(in) :: n0
1149 real,
dimension(:),
intent(in) :: h0
1150 real,
dimension(:),
intent(in) :: u0
1151 real,
dimension(:,:),
intent(in) :: ppoly0_E
1152 real,
dimension(:,:),
intent(in) :: ppoly0_coefs
1153 integer,
intent(in) :: n1
1154 real,
dimension(:),
intent(in) :: dx1
1155 integer,
intent(in) :: method
1156 real,
dimension(:),
intent(out) :: u1
1157 real,
dimension(:), &
1158 optional,
intent(out) :: h1
1159 real,
optional,
intent(in) :: h_neglect
1165 real :: xOld, hOld, uOld
1166 real :: xNew, hNew, h_err
1167 real :: uhNew, hFlux, uAve, fluxL, fluxR
1183 if (itarget == 0)
then 1187 elseif (itarget <= n0)
then 1188 xold = xold + h0(itarget)
1191 h_err = h_err + epsilon(hold) * max(hold, xold)
1196 xnew = xold + dx1(itarget+1)
1197 xl = min( xold, xnew )
1198 xr = max( xold, xnew )
1201 hflux = abs(dx1(itarget+1))
1202 call integraterecononinterval( n0, h0, u0, ppoly0_e, ppoly0_coefs, method, &
1203 xl, xr, hflux, uave, jstart, xstart )
1205 fluxr = dx1(itarget+1)*uave
1208 hnew = hold + ( dx1(itarget+1) - dx1(itarget) )
1209 hnew = max( 0., hnew )
1210 uhnew = ( uold * hold ) + ( fluxr - fluxl )
1212 u1(itarget) = uhnew / hnew
1216 if (
present(h1)) h1(itarget) = hnew
1221 end subroutine remapbydeltaz
1225 subroutine integraterecononinterval( n0, h0, u0, ppoly0_E, ppoly0_coefs, method, &
1226 xL, xR, hC, uAve, jStart, xStart, h_neglect )
1227 integer,
intent(in) :: n0
1228 real,
dimension(:),
intent(in) :: h0
1229 real,
dimension(:),
intent(in) :: u0
1230 real,
dimension(:,:),
intent(in) :: ppoly0_E
1231 real,
dimension(:,:),
intent(in) :: ppoly0_coefs
1232 integer,
intent(in) :: method
1233 real,
intent(in) :: xL
1234 real,
intent(in) :: xR
1235 real,
intent(in) :: hC
1236 real,
intent(out) :: uAve
1237 integer,
intent(inout) :: jStart
1239 real,
intent(inout) :: xStart
1241 real,
optional,
intent(in) :: h_neglect
1251 real :: x0jLl, x0jLr
1252 real :: x0jRl, x0jRr
1255 real :: x0_2, x1_2, x02px12, x0px1
1257 real,
parameter :: r_3 = 1.0/3.0
1259 hneglect = hneglect_dflt ;
if (
present(h_neglect)) hneglect = h_neglect
1270 x0jlr = x0jll + h0(j)
1272 if ( ( xl >= x0jll ) .AND. ( xl <= x0jlr ) )
then 1288 if ( jl == -1 )
call mom_error(fatal, &
1289 'MOM_remapping, integrateReconOnInterval: '//&
1290 'The location of the left-most cell could not be found')
1302 if ( abs(xr - xl) == 0.0 )
then 1308 if ( h0(jl) == 0.0 )
then 1309 uave = 0.5 * ( ppoly0_e(jl,1) + ppoly0_e(jl,2) )
1312 xi0 = xl / ( h0(jl) + hneglect ) - x0jll / ( h0(jl) + hneglect )
1314 select case ( method )
1315 case ( integration_pcm )
1316 uave = ppoly0_coefs(jl,1)
1317 case ( integration_plm )
1318 uave = ppoly0_coefs(jl,1) &
1319 + xi0 * ppoly0_coefs(jl,2)
1320 case ( integration_ppm )
1321 uave = ppoly0_coefs(jl,1) &
1322 + xi0 * ( ppoly0_coefs(jl,2) &
1323 + xi0 * ppoly0_coefs(jl,3) )
1324 case ( integration_pqm )
1325 uave = ppoly0_coefs(jl,1) &
1326 + xi0 * ( ppoly0_coefs(jl,2) &
1327 + xi0 * ( ppoly0_coefs(jl,3) &
1328 + xi0 * ( ppoly0_coefs(jl,4) &
1329 + xi0 * ppoly0_coefs(jl,5) ) ) )
1331 call mom_error( fatal,
'The selected integration method is invalid' )
1344 x0jrr = x0jrl + h0(j)
1346 if ( ( xr >= x0jrl ) .AND. ( xr <= x0jrr ) )
then 1355 if (xr>x0jrr) jr = n0
1361 if ( jl == jr )
then 1370 #ifdef __USE_ROUNDOFF_SAFE_ADJUSTMENTS__ 1371 xi0 = max( 0., min( 1., ( xl - x0jll ) / ( h0(jl) + hneglect ) ) )
1372 xi1 = max( 0., min( 1., ( xr - x0jll ) / ( h0(jl) + hneglect ) ) )
1374 xi0 = xl / h0(jl) - x0jll / ( h0(jl) + hneglect )
1375 xi1 = xr / h0(jl) - x0jll / ( h0(jl) + hneglect )
1378 hact = h0(jl) * ( xi1 - xi0 )
1383 select case ( method )
1384 case ( integration_pcm )
1385 q = ( xr - xl ) * ppoly0_coefs(jl,1)
1386 case ( integration_plm )
1387 q = ( xr - xl ) * ( &
1388 ppoly0_coefs(jl,1) &
1389 + ppoly0_coefs(jl,2) * 0.5 * ( xi1 + xi0 ) )
1390 case ( integration_ppm )
1391 q = ( xr - xl ) * ( &
1392 ppoly0_coefs(jl,1) &
1393 + ( ppoly0_coefs(jl,2) * 0.5 * ( xi1 + xi0 ) &
1394 + ppoly0_coefs(jl,3) * r_3 * ( ( xi1*xi1 + xi0*xi0 ) + xi0*xi1 ) ) )
1395 case ( integration_pqm )
1398 x02px12 = x0_2 + x1_2
1400 q = ( xr - xl ) * ( &
1401 ppoly0_coefs(jl,1) &
1402 + ( ppoly0_coefs(jl,2) * 0.5 * ( xi1 + xi0 ) &
1403 + ( ppoly0_coefs(jl,3) * r_3 * ( x02px12 + xi0*xi1 ) &
1404 + ppoly0_coefs(jl,4) * 0.25* ( x02px12 * x0px1 ) &
1405 + ppoly0_coefs(jl,5) * 0.2 * ( ( xi1*x1_2 + xi0*x0_2 ) * x0px1 + x0_2*x1_2 ) ) ) )
1407 call mom_error( fatal,
'The selected integration method is invalid' )
1426 #ifdef __USE_ROUNDOFF_SAFE_ADJUSTMENTS__ 1427 xi0 = max( 0., min( 1., ( xl - x0jll ) / ( h0(jl) + hneglect ) ) )
1429 xi0 = (xl - x0jll) / ( h0(jl) + hneglect )
1433 hact = h0(jl) * ( xi1 - xi0 )
1435 select case ( method )
1436 case ( integration_pcm )
1437 q = q + ( x0jlr - xl ) * ppoly0_coefs(jl,1)
1438 case ( integration_plm )
1439 q = q + ( x0jlr - xl ) * ( &
1440 ppoly0_coefs(jl,1) &
1441 + ppoly0_coefs(jl,2) * 0.5 * ( xi1 + xi0 ) )
1442 case ( integration_ppm )
1443 q = q + ( x0jlr - xl ) * ( &
1444 ppoly0_coefs(jl,1) &
1445 + ( ppoly0_coefs(jl,2) * 0.5 * ( xi1 + xi0 ) &
1446 + ppoly0_coefs(jl,3) * r_3 * ( ( xi1*xi1 + xi0*xi0 ) + xi0*xi1 ) ) )
1447 case ( integration_pqm )
1450 x02px12 = x0_2 + x1_2
1452 q = q + ( x0jlr - xl ) * ( &
1453 ppoly0_coefs(jl,1) &
1454 + ( ppoly0_coefs(jl,2) * 0.5 * ( xi1 + xi0 ) &
1455 + ( ppoly0_coefs(jl,3) * r_3 * ( x02px12 + xi0*xi1 ) &
1456 + ppoly0_coefs(jl,4) * 0.25* ( x02px12 * x0px1 ) &
1457 + ppoly0_coefs(jl,5) * 0.2 * ( ( xi1*x1_2 + xi0*x0_2 ) * x0px1 + x0_2*x1_2 ) ) ) )
1459 call mom_error( fatal,
'The selected integration method is invalid' )
1463 if ( jr > (jl+1) )
then 1465 q = q + h0(k) * u0(k)
1472 #ifdef __USE_ROUNDOFF_SAFE_ADJUSTMENTS__ 1473 xi1 = max( 0., min( 1., ( xr - x0jrl ) / ( h0(jr) + hneglect ) ) )
1475 xi1 = (xr - x0jrl) / ( h0(jr) + hneglect )
1478 hact = hact + h0(jr) * ( xi1 - xi0 )
1480 select case ( method )
1481 case ( integration_pcm )
1482 q = q + ( xr - x0jrl ) * ppoly0_coefs(jr,1)
1483 case ( integration_plm )
1484 q = q + ( xr - x0jrl ) * ( &
1485 ppoly0_coefs(jr,1) &
1486 + ppoly0_coefs(jr,2) * 0.5 * ( xi1 + xi0 ) )
1487 case ( integration_ppm )
1488 q = q + ( xr - x0jrl ) * ( &
1489 ppoly0_coefs(jr,1) &
1490 + ( ppoly0_coefs(jr,2) * 0.5 * ( xi1 + xi0 ) &
1491 + ppoly0_coefs(jr,3) * r_3 * ( ( xi1*xi1 + xi0*xi0 ) + xi0*xi1 ) ) )
1492 case ( integration_pqm )
1495 x02px12 = x0_2 + x1_2
1497 q = q + ( xr - x0jrl ) * ( &
1498 ppoly0_coefs(jr,1) &
1499 + ( ppoly0_coefs(jr,2) * 0.5 * ( xi1 + xi0 ) &
1500 + ( ppoly0_coefs(jr,3) * r_3 * ( x02px12 + xi0*xi1 ) &
1501 + ppoly0_coefs(jr,4) * 0.25* ( x02px12 * x0px1 ) &
1502 + ppoly0_coefs(jr,5) * 0.2 * ( ( xi1*x1_2 + xi0*x0_2 ) * x0px1 + x0_2*x1_2 ) ) ) )
1504 call mom_error( fatal,
'The selected integration method is invalid' )
1510 #ifdef __USE_ROUNDOFF_SAFE_ADJUSTMENTS__ 1512 uave = ppoly0_coefs(jl,1)
1522 end subroutine integraterecononinterval
1525 subroutine dzfromh1h2( n1, h1, n2, h2, dx )
1526 integer,
intent(in) :: n1
1527 real,
dimension(:),
intent(in) :: h1
1528 integer,
intent(in) :: n2
1529 real,
dimension(:),
intent(in) :: h2
1530 real,
dimension(:),
intent(out) :: dx
1538 do k = 1, max(n1,n2)
1539 if (k <= n1) x1 = x1 + h1(k)
1546 end subroutine dzfromh1h2
1549 subroutine initialize_remapping( CS, remapping_scheme, boundary_extrapolation, &
1550 check_reconstruction, check_remapping, force_bounds_in_subcell, answers_2018)
1553 character(len=*),
intent(in) :: remapping_scheme
1554 logical,
optional,
intent(in) :: boundary_extrapolation
1555 logical,
optional,
intent(in) :: check_reconstruction
1556 logical,
optional,
intent(in) :: check_remapping
1557 logical,
optional,
intent(in) :: force_bounds_in_subcell
1558 logical,
optional,
intent(in) :: answers_2018
1561 call remapping_set_param(cs, remapping_scheme=remapping_scheme, boundary_extrapolation=boundary_extrapolation, &
1562 check_reconstruction=check_reconstruction, check_remapping=check_remapping, &
1563 force_bounds_in_subcell=force_bounds_in_subcell, answers_2018=answers_2018)
1565 end subroutine initialize_remapping
1571 subroutine setreconstructiontype(string,CS)
1572 character(len=*),
intent(in) :: string
1577 select case ( uppercase(trim(string)) )
1579 cs%remapping_scheme = remapping_pcm
1582 cs%remapping_scheme = remapping_plm
1585 cs%remapping_scheme = remapping_ppm_h4
1588 cs%remapping_scheme = remapping_ppm_ih4
1591 cs%remapping_scheme = remapping_pqm_ih4ih3
1594 cs%remapping_scheme = remapping_pqm_ih6ih5
1597 call mom_error(fatal,
"setReconstructionType: "//&
1598 "Unrecognized choice for REMAPPING_SCHEME ("//trim(string)//
").")
1603 end subroutine setreconstructiontype
1606 subroutine end_remapping(CS)
1611 end subroutine end_remapping
1616 logical function remapping_unit_tests(verbose)
1617 logical,
intent(in) :: verbose
1619 integer,
parameter :: n0 = 4, n1 = 3, n2 = 6
1620 real :: h0(n0), x0(n0+1), u0(n0)
1621 real :: h1(n1), x1(n1+1), u1(n1), hn1(n1), dx1(n1+1)
1622 real :: h2(n2), x2(n2+1), u2(n2), hn2(n2), dx2(n2+1)
1623 data u0 /9., 3., -3., -9./
1628 real,
allocatable,
dimension(:,:) :: ppoly0_e, ppoly0_s, ppoly0_coefs
1629 logical :: answers_2018
1631 real :: err, h_neglect, h_neglect_edge
1632 logical :: thistest, v
1635 answers_2018 = .false.
1636 h_neglect = hneglect_dflt
1637 h_neglect_edge = hneglect_dflt ;
if (answers_2018) h_neglect_edge = 1.0e-10
1639 write(*,*)
'==== MOM_remapping: remapping_unit_tests =================' 1640 remapping_unit_tests = .false.
1643 call buildgridfromh(n0, h0, x0)
1645 err=x0(i)-0.75*real(i-1)
1646 if (abs(err)>real(i-1)*epsilon(err)) thistest = .true.
1648 if (thistest)
write(*,*)
'remapping_unit_tests: Failed buildGridFromH() 1' 1649 remapping_unit_tests = remapping_unit_tests .or. thistest
1650 call buildgridfromh(n1, h1, x1)
1653 if (abs(err)>real(i-1)*epsilon(err)) thistest = .true.
1655 if (thistest)
write(*,*)
'remapping_unit_tests: Failed buildGridFromH() 2' 1656 remapping_unit_tests = remapping_unit_tests .or. thistest
1659 call initialize_remapping(cs,
'PPM_H4', answers_2018=answers_2018)
1660 if (verbose)
write(*,*)
'h0 (test data)' 1661 if (verbose)
call dumpgrid(n0,h0,x0,u0)
1663 call dzfromh1h2( n0, h0, n1, h1, dx1 )
1664 call remapping_core_w( cs, n0, h0, u0, n1, dx1, u1, h_neglect, h_neglect_edge)
1666 err=u1(i)-8.*(0.5*real(1+n1)-real(i))
1667 if (abs(err)>real(n1-1)*epsilon(err)) thistest = .true.
1669 if (verbose)
write(*,*)
'h1 (by projection)' 1670 if (verbose)
call dumpgrid(n1,h1,x1,u1)
1671 if (thistest)
write(*,*)
'remapping_unit_tests: Failed remapping_core_w()' 1672 remapping_unit_tests = remapping_unit_tests .or. thistest
1675 allocate(ppoly0_e(n0,2))
1676 allocate(ppoly0_s(n0,2))
1677 allocate(ppoly0_coefs(n0,cs%degree+1))
1681 ppoly0_coefs(:,:) = 0.0
1683 call edge_values_explicit_h4( n0, h0, u0, ppoly0_e, h_neglect=1e-10, answers_2018=answers_2018 )
1684 call ppm_reconstruction( n0, h0, u0, ppoly0_e, ppoly0_coefs, h_neglect, answers_2018=answers_2018 )
1685 call ppm_boundary_extrapolation( n0, h0, u0, ppoly0_e, ppoly0_coefs, h_neglect )
1687 call remapbyprojection( n0, h0, u0, ppoly0_e, ppoly0_coefs, &
1688 n1, h1, integration_ppm, u1, h_neglect )
1690 err=u1(i)-8.*(0.5*real(1+n1)-real(i))
1691 if (abs(err)>2.*epsilon(err)) thistest = .true.
1693 if (thistest)
write(*,*)
'remapping_unit_tests: Failed remapByProjection()' 1694 remapping_unit_tests = remapping_unit_tests .or. thistest
1698 call remapbydeltaz( n0, h0, u0, ppoly0_e, ppoly0_coefs, &
1699 n1, x1-x0(1:n1+1), &
1700 integration_ppm, u1, hn1, h_neglect )
1701 if (verbose)
write(*,*)
'h1 (by delta)' 1702 if (verbose)
call dumpgrid(n1,h1,x1,u1)
1705 err=u1(i)-8.*(0.5*real(1+n1)-real(i))
1706 if (abs(err)>2.*epsilon(err)) thistest = .true.
1708 if (thistest)
write(*,*)
'remapping_unit_tests: Failed remapByDeltaZ() 1' 1709 remapping_unit_tests = remapping_unit_tests .or. thistest
1712 call buildgridfromh(n2, h2, x2)
1713 dx2(1:n0+1) = x2(1:n0+1) - x0
1714 dx2(n0+2:n2+1) = x2(n0+2:n2+1) - x0(n0+1)
1715 call remapbydeltaz( n0, h0, u0, ppoly0_e, ppoly0_coefs, &
1717 integration_ppm, u2, hn2, h_neglect )
1718 if (verbose)
write(*,*)
'h2' 1719 if (verbose)
call dumpgrid(n2,h2,x2,u2)
1720 if (verbose)
write(*,*)
'hn2' 1721 if (verbose)
call dumpgrid(n2,hn2,x2,u2)
1724 err=u2(i)-8./2.*(0.5*real(1+n2)-real(i))
1725 if (abs(err)>2.*epsilon(err)) thistest = .true.
1727 if (thistest)
write(*,*)
'remapping_unit_tests: Failed remapByDeltaZ() 2' 1728 remapping_unit_tests = remapping_unit_tests .or. thistest
1730 if (verbose)
write(*,*)
'Via sub-cells' 1732 call remap_via_sub_cells( n0, h0, u0, ppoly0_e, ppoly0_coefs, &
1733 n2, h2, integration_ppm, .false., u2, err )
1734 if (verbose)
call dumpgrid(n2,h2,x2,u2)
1737 err=u2(i)-8./2.*(0.5*real(1+n2)-real(i))
1738 if (abs(err)>2.*epsilon(err)) thistest = .true.
1740 if (thistest)
write(*,*)
'remapping_unit_tests: Failed remap_via_sub_cells() 2' 1741 remapping_unit_tests = remapping_unit_tests .or. thistest
1743 call remap_via_sub_cells( n0, h0, u0, ppoly0_e, ppoly0_coefs, &
1744 6, (/.125,.125,.125,.125,.125,.125/), integration_ppm, .false., u2, err )
1745 if (verbose)
call dumpgrid(6,h2,x2,u2)
1747 call remap_via_sub_cells( n0, h0, u0, ppoly0_e, ppoly0_coefs, &
1748 3, (/2.25,1.5,1./), integration_ppm, .false., u2, err )
1749 if (verbose)
call dumpgrid(3,h2,x2,u2)
1751 if (.not. remapping_unit_tests)
write(*,*)
'Pass' 1753 write(*,*)
'===== MOM_remapping: new remapping_unit_tests ==================' 1755 deallocate(ppoly0_e, ppoly0_s, ppoly0_coefs)
1756 allocate(ppoly0_coefs(5,6))
1757 allocate(ppoly0_e(5,2))
1758 allocate(ppoly0_s(5,2))
1760 call pcm_reconstruction(3, (/1.,2.,4./), ppoly0_e(1:3,:), &
1761 ppoly0_coefs(1:3,:) )
1762 remapping_unit_tests = remapping_unit_tests .or. &
1763 test_answer(v, 3, ppoly0_e(:,1), (/1.,2.,4./),
'PCM: left edges')
1764 remapping_unit_tests = remapping_unit_tests .or. &
1765 test_answer(v, 3, ppoly0_e(:,2), (/1.,2.,4./),
'PCM: right edges')
1766 remapping_unit_tests = remapping_unit_tests .or. &
1767 test_answer(v, 3, ppoly0_coefs(:,1), (/1.,2.,4./),
'PCM: P0')
1769 call plm_reconstruction(3, (/1.,1.,1./), (/1.,3.,5./), ppoly0_e(1:3,:), &
1770 ppoly0_coefs(1:3,:), h_neglect )
1771 remapping_unit_tests = remapping_unit_tests .or. &
1772 test_answer(v, 3, ppoly0_e(:,1), (/1.,2.,5./),
'Unlim PLM: left edges')
1773 remapping_unit_tests = remapping_unit_tests .or. &
1774 test_answer(v, 3, ppoly0_e(:,2), (/1.,4.,5./),
'Unlim PLM: right edges')
1775 remapping_unit_tests = remapping_unit_tests .or. &
1776 test_answer(v, 3, ppoly0_coefs(:,1), (/1.,2.,5./),
'Unlim PLM: P0')
1777 remapping_unit_tests = remapping_unit_tests .or. &
1778 test_answer(v, 3, ppoly0_coefs(:,2), (/0.,2.,0./),
'Unlim PLM: P1')
1780 call plm_reconstruction(3, (/1.,1.,1./), (/1.,2.,7./), ppoly0_e(1:3,:), &
1781 ppoly0_coefs(1:3,:), h_neglect )
1782 remapping_unit_tests = remapping_unit_tests .or. &
1783 test_answer(v, 3, ppoly0_e(:,1), (/1.,1.,7./),
'Left lim PLM: left edges')
1784 remapping_unit_tests = remapping_unit_tests .or. &
1785 test_answer(v, 3, ppoly0_e(:,2), (/1.,3.,7./),
'Left lim PLM: right edges')
1786 remapping_unit_tests = remapping_unit_tests .or. &
1787 test_answer(v, 3, ppoly0_coefs(:,1), (/1.,1.,7./),
'Left lim PLM: P0')
1788 remapping_unit_tests = remapping_unit_tests .or. &
1789 test_answer(v, 3, ppoly0_coefs(:,2), (/0.,2.,0./),
'Left lim PLM: P1')
1791 call plm_reconstruction(3, (/1.,1.,1./), (/1.,6.,7./), ppoly0_e(1:3,:), &
1792 ppoly0_coefs(1:3,:), h_neglect )
1793 remapping_unit_tests = remapping_unit_tests .or. &
1794 test_answer(v, 3, ppoly0_e(:,1), (/1.,5.,7./),
'Right lim PLM: left edges')
1795 remapping_unit_tests = remapping_unit_tests .or. &
1796 test_answer(v, 3, ppoly0_e(:,2), (/1.,7.,7./),
'Right lim PLM: right edges')
1797 remapping_unit_tests = remapping_unit_tests .or. &
1798 test_answer(v, 3, ppoly0_coefs(:,1), (/1.,5.,7./),
'Right lim PLM: P0')
1799 remapping_unit_tests = remapping_unit_tests .or. &
1800 test_answer(v, 3, ppoly0_coefs(:,2), (/0.,2.,0./),
'Right lim PLM: P1')
1802 call plm_reconstruction(3, (/1.,2.,3./), (/1.,4.,9./), ppoly0_e(1:3,:), &
1803 ppoly0_coefs(1:3,:), h_neglect )
1804 remapping_unit_tests = remapping_unit_tests .or. &
1805 test_answer(v, 3, ppoly0_e(:,1), (/1.,2.,9./),
'Non-uniform line PLM: left edges')
1806 remapping_unit_tests = remapping_unit_tests .or. &
1807 test_answer(v, 3, ppoly0_e(:,2), (/1.,6.,9./),
'Non-uniform line PLM: right edges')
1808 remapping_unit_tests = remapping_unit_tests .or. &
1809 test_answer(v, 3, ppoly0_coefs(:,1), (/1.,2.,9./),
'Non-uniform line PLM: P0')
1810 remapping_unit_tests = remapping_unit_tests .or. &
1811 test_answer(v, 3, ppoly0_coefs(:,2), (/0.,4.,0./),
'Non-uniform line PLM: P1')
1813 call edge_values_explicit_h4( 5, (/1.,1.,1.,1.,1./), (/1.,3.,5.,7.,9./), ppoly0_e, &
1814 h_neglect=1e-10, answers_2018=answers_2018 )
1816 thistest = test_answer(v, 5, ppoly0_e(:,1), (/0.,2.,4.,6.,8./),
'Line H4: left edges', tol=8.0e-15)
1817 remapping_unit_tests = remapping_unit_tests .or. thistest
1818 thistest = test_answer(v, 5, ppoly0_e(:,2), (/2.,4.,6.,8.,10./),
'Line H4: right edges', tol=1.0e-14)
1819 remapping_unit_tests = remapping_unit_tests .or. thistest
1820 ppoly0_e(:,1) = (/0.,2.,4.,6.,8./)
1821 ppoly0_e(:,2) = (/2.,4.,6.,8.,10./)
1822 call ppm_reconstruction(5, (/1.,1.,1.,1.,1./), (/1.,3.,5.,7.,9./), ppoly0_e(1:5,:), &
1823 ppoly0_coefs(1:5,:), h_neglect, answers_2018=answers_2018 )
1824 remapping_unit_tests = remapping_unit_tests .or. &
1825 test_answer(v, 5, ppoly0_coefs(:,1), (/1.,2.,4.,6.,9./),
'Line PPM: P0')
1826 remapping_unit_tests = remapping_unit_tests .or. &
1827 test_answer(v, 5, ppoly0_coefs(:,2), (/0.,2.,2.,2.,0./),
'Line PPM: P1')
1828 remapping_unit_tests = remapping_unit_tests .or. &
1829 test_answer(v, 5, ppoly0_coefs(:,3), (/0.,0.,0.,0.,0./),
'Line PPM: P2')
1831 call edge_values_explicit_h4( 5, (/1.,1.,1.,1.,1./), (/1.,1.,7.,19.,37./), ppoly0_e, &
1832 h_neglect=1e-10, answers_2018=answers_2018 )
1834 thistest = test_answer(v, 5, ppoly0_e(:,1), (/3.,0.,3.,12.,27./),
'Parabola H4: left edges', tol=2.7e-14)
1835 remapping_unit_tests = remapping_unit_tests .or. thistest
1836 thistest = test_answer(v, 5, ppoly0_e(:,2), (/0.,3.,12.,27.,48./),
'Parabola H4: right edges', tol=4.8e-14)
1837 remapping_unit_tests = remapping_unit_tests .or. thistest
1838 ppoly0_e(:,1) = (/0.,0.,3.,12.,27./)
1839 ppoly0_e(:,2) = (/0.,3.,12.,27.,48./)
1840 call ppm_reconstruction(5, (/1.,1.,1.,1.,1./), (/0.,1.,7.,19.,37./), ppoly0_e(1:5,:), &
1841 ppoly0_coefs(1:5,:), h_neglect, answers_2018=answers_2018 )
1842 remapping_unit_tests = remapping_unit_tests .or. &
1843 test_answer(v, 5, ppoly0_e(:,1), (/0.,0.,3.,12.,37./),
'Parabola PPM: left edges')
1844 remapping_unit_tests = remapping_unit_tests .or. &
1845 test_answer(v, 5, ppoly0_e(:,2), (/0.,3.,12.,27.,37./),
'Parabola PPM: right edges')
1846 remapping_unit_tests = remapping_unit_tests .or. &
1847 test_answer(v, 5, ppoly0_coefs(:,1), (/0.,0.,3.,12.,37./),
'Parabola PPM: P0')
1848 remapping_unit_tests = remapping_unit_tests .or. &
1849 test_answer(v, 5, ppoly0_coefs(:,2), (/0.,0.,6.,12.,0./),
'Parabola PPM: P1')
1850 remapping_unit_tests = remapping_unit_tests .or. &
1851 test_answer(v, 5, ppoly0_coefs(:,3), (/0.,3.,3.,3.,0./),
'Parabola PPM: P2')
1853 ppoly0_e(:,1) = (/0.,0.,6.,10.,15./)
1854 ppoly0_e(:,2) = (/0.,6.,12.,17.,15./)
1855 call ppm_reconstruction(5, (/1.,1.,1.,1.,1./), (/0.,5.,7.,16.,15./), ppoly0_e(1:5,:), &
1856 ppoly0_coefs(1:5,:), h_neglect, answers_2018=answers_2018 )
1857 remapping_unit_tests = remapping_unit_tests .or. &
1858 test_answer(v, 5, ppoly0_e(:,1), (/0.,3.,6.,16.,15./),
'Limits PPM: left edges')
1859 remapping_unit_tests = remapping_unit_tests .or. &
1860 test_answer(v, 5, ppoly0_e(:,2), (/0.,6.,9.,16.,15./),
'Limits PPM: right edges')
1861 remapping_unit_tests = remapping_unit_tests .or. &
1862 test_answer(v, 5, ppoly0_coefs(:,1), (/0.,3.,6.,16.,15./),
'Limits PPM: P0')
1863 remapping_unit_tests = remapping_unit_tests .or. &
1864 test_answer(v, 5, ppoly0_coefs(:,2), (/0.,6.,0.,0.,0./),
'Limits PPM: P1')
1865 remapping_unit_tests = remapping_unit_tests .or. &
1866 test_answer(v, 5, ppoly0_coefs(:,3), (/0.,-3.,3.,0.,0./),
'Limits PPM: P2')
1868 call plm_reconstruction(4, (/0.,1.,1.,0./), (/5.,4.,2.,1./), ppoly0_e(1:4,:), &
1869 ppoly0_coefs(1:4,:), h_neglect )
1870 remapping_unit_tests = remapping_unit_tests .or. &
1871 test_answer(v, 4, ppoly0_e(1:4,1), (/5.,5.,3.,1./),
'PPM: left edges h=0110')
1872 remapping_unit_tests = remapping_unit_tests .or. &
1873 test_answer(v, 4, ppoly0_e(1:4,2), (/5.,3.,1.,1./),
'PPM: right edges h=0110')
1874 call remap_via_sub_cells( 4, (/0.,1.,1.,0./), (/5.,4.,2.,1./), ppoly0_e(1:4,:), &
1875 ppoly0_coefs(1:4,:), &
1876 2, (/1.,1./), integration_plm, .false., u2, err )
1877 remapping_unit_tests = remapping_unit_tests .or. &
1878 test_answer(v, 2, u2, (/4.,2./),
'PLM: remapped h=0110->h=11')
1880 deallocate(ppoly0_e, ppoly0_s, ppoly0_coefs)
1882 if (.not. remapping_unit_tests)
write(*,*)
'Pass' 1884 end function remapping_unit_tests
1887 logical function test_answer(verbose, n, u, u_true, label, tol)
1888 logical,
intent(in) :: verbose
1889 integer,
intent(in) :: n
1890 real,
dimension(n),
intent(in) :: u
1891 real,
dimension(n),
intent(in) :: u_true
1892 character(len=*),
intent(in) :: label
1893 real,
optional,
intent(in) :: tol
1898 tolerance = 0.0 ;
if (
present(tol)) tolerance = tol
1899 test_answer = .false.
1901 if (abs(u(k) - u_true(k)) > tolerance) test_answer = .true.
1903 if (test_answer .or. verbose)
then 1904 write(stdout,
'(a4,2a24,x,a)')
'k',
'Calculated value',
'Correct value',label
1906 if (abs(u(k) - u_true(k)) > tolerance)
then 1907 write(stdout,
'(i4,1p2e24.16,a,1pe24.16,a)') k,u(k),u_true(k),
' err=',u(k)-u_true(k),
' < wrong' 1908 write(stderr,
'(i4,1p2e24.16,a,1pe24.16,a)') k,u(k),u_true(k),
' err=',u(k)-u_true(k),
' < wrong' 1910 write(stdout,
'(i4,1p2e24.16)') k,u(k),u_true(k)
1915 end function test_answer
1918 subroutine dumpgrid(n,h,x,u)
1919 integer,
intent(in) :: n
1920 real,
dimension(:),
intent(in) :: h
1921 real,
dimension(:),
intent(in) :: x
1922 real,
dimension(:),
intent(in) :: u
1924 write(stdout,
'("i=",20i10)') (i,i=1,n+1)
1925 write(stdout,
'("x=",20es10.2)') (x(i),i=1,n+1)
1926 write(stdout,
'("i=",5x,20i10)') (i,i=1,n)
1927 write(stdout,
'("h=",5x,20es10.2)') (h(i),i=1,n)
1928 write(stdout,
'("u=",5x,20es10.2)') (u(i),i=1,n)
1929 end subroutine dumpgrid
Piecewise quartic reconstruction functions.
Provides column-wise vertical remapping functions.
Provides functions used with the Piecewise-Parabolic-Method in the vertical ALE algorithm.
Container for remapping parameters.
Piecewise constant reconstruction functions.
Piecewise linear reconstruction functions.
Routines for error handling and I/O management.
Edge value estimation for high-order resconstruction.
Handy functions for manipulating strings.