MOM6
regrid_interp.F90
Go to the documentation of this file.
2 
3 use mom_error_handler, only : mom_error, fatal
5 
9 
13 
16 
17 implicit none ; private
18 
19 type, public :: interp_cs_type
20  private
21 
22  !> The following parameter is only relevant when used with the target
23  !! interface densities regridding scheme. It indicates which interpolation
24  !! to use to determine the grid.
25  integer :: interpolation_scheme = -1
26 
27  !> Indicate whether high-order boundary extrapolation should be used within
28  !! boundary cells
29  logical :: boundary_extrapolation
30 end type interp_cs_type
31 
35 
36 ! List of interpolation schemes
37 integer, parameter :: interpolation_p1m_h2 = 0 !< O(h^2)
38 integer, parameter :: interpolation_p1m_h4 = 1 !< O(h^2)
39 integer, parameter :: interpolation_p1m_ih4 = 2 !< O(h^2)
40 integer, parameter :: interpolation_plm = 3 !< O(h^2)
41 integer, parameter :: interpolation_ppm_h4 = 4 !< O(h^3)
42 integer, parameter :: interpolation_ppm_ih4 = 5 !< O(h^3)
43 integer, parameter :: interpolation_p3m_ih4ih3 = 6 !< O(h^4)
44 integer, parameter :: interpolation_p3m_ih6ih5 = 7 !< O(h^4)
45 integer, parameter :: interpolation_pqm_ih4ih3 = 8 !< O(h^4)
46 integer, parameter :: interpolation_pqm_ih6ih5 = 9 !< O(h^5)
47 
48 !> List of interpolant degrees
49 integer, parameter :: degree_1 = 1, degree_2 = 2, degree_3 = 3, degree_4 = 4
50 integer, public, parameter :: degree_max = 5
51 
52 !> When the N-R algorithm produces an estimate that lies outside [0,1], the
53 !! estimate is set to be equal to the boundary location, 0 or 1, plus or minus
54 !! an offset, respectively, when the derivative is zero at the boundary.
55 real, public, parameter :: nr_offset = 1e-6
56 !> Maximum number of Newton-Raphson iterations. Newton-Raphson iterations are
57 !! used to build the new grid by finding the coordinates associated with
58 !! target densities and interpolations of degree larger than 1.
59 integer, public, parameter :: nr_iterations = 8
60 !> Tolerance for Newton-Raphson iterations (stop when increment falls below this)
61 real, public, parameter :: nr_tolerance = 1e-12
62 
63 contains
64 
65 !> Given the set of target values and cell densities, this routine
66 !! builds an interpolated profile for the densities within each grid cell.
67 !! It may happen that, given a high-order interpolator, the number of
68 !! available layers is insufficient (e.g., there are two available layers for
69 !! a third-order PPM ih4 scheme). In these cases, we resort to the simplest
70 !! continuous linear scheme (P1M h2).
71 subroutine regridding_set_ppolys(CS, densities, n0, h0, ppoly0_E, ppoly0_S, &
72  ppoly0_coefficients, degree)
73  type(interp_cs_type),intent(in) :: CS !< Interpolation control structure
74  real, dimension(:), intent(in) :: densities !< Actual cell densities
75  integer, intent(in) :: n0 !< Number of cells on source grid
76  real, dimension(:), intent(in) :: h0 !< cell widths on source grid
77  real, dimension(:,:),intent(inout) :: ppoly0_E !< Edge value of polynomial
78  real, dimension(:,:),intent(inout) :: ppoly0_S !< Edge slope of polynomial
79  real, dimension(:,:),intent(inout) :: ppoly0_coefficients !< Coefficients of polynomial
80  integer, intent(inout) :: degree !< The degree of the polynomials
81 
82  logical :: extrapolate
83 
84  ! Reset piecewise polynomials
85  ppoly0_e(:,:) = 0.0
86  ppoly0_s(:,:) = 0.0
87  ppoly0_coefficients(:,:) = 0.0
88 
89  extrapolate = cs%boundary_extrapolation
90 
91  ! Compute the interpolated profile of the density field and build grid
92  select case (cs%interpolation_scheme)
93 
94  case ( interpolation_p1m_h2 )
95  degree = degree_1
96  call edge_values_explicit_h2( n0, h0, densities, ppoly0_e )
97  call p1m_interpolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
98  if (extrapolate) then
99  call p1m_boundary_extrapolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
100  end if
101 
102  case ( interpolation_p1m_h4 )
103  degree = degree_1
104  if ( n0 >= 4 ) then
105  call edge_values_explicit_h4( n0, h0, densities, ppoly0_e )
106  else
107  call edge_values_explicit_h2( n0, h0, densities, ppoly0_e )
108  end if
109  call p1m_interpolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
110  if (extrapolate) then
111  call p1m_boundary_extrapolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
112  end if
113 
114  case ( interpolation_p1m_ih4 )
115  degree = degree_1
116  if ( n0 >= 4 ) then
117  call edge_values_implicit_h4( n0, h0, densities, ppoly0_e )
118  else
119  call edge_values_explicit_h2( n0, h0, densities, ppoly0_e )
120  end if
121  call p1m_interpolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
122  if (extrapolate) then
123  call p1m_boundary_extrapolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
124  end if
125 
126  case ( interpolation_plm )
127  degree = degree_1
128  call plm_reconstruction( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
129  if (extrapolate) then
130  call plm_boundary_extrapolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
131  end if
132 
133  case ( interpolation_ppm_h4 )
134  if ( n0 >= 4 ) then
135  degree = degree_2
136  call edge_values_explicit_h4( n0, h0, densities, ppoly0_e )
137  call ppm_reconstruction( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
138  if (extrapolate) then
139  call ppm_boundary_extrapolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
140  end if
141  else
142  degree = degree_1
143  call edge_values_explicit_h2( n0, h0, densities, ppoly0_e )
144  call p1m_interpolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
145  if (extrapolate) then
146  call p1m_boundary_extrapolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
147  end if
148  end if
149 
150  case ( interpolation_ppm_ih4 )
151  if ( n0 >= 4 ) then
152  degree = degree_2
153  call edge_values_implicit_h4( n0, h0, densities, ppoly0_e )
154  call ppm_reconstruction( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
155  if (extrapolate) then
156  call ppm_boundary_extrapolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
157  end if
158  else
159  degree = degree_1
160  call edge_values_explicit_h2( n0, h0, densities, ppoly0_e )
161  call p1m_interpolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
162  if (extrapolate) then
163  call p1m_boundary_extrapolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
164  end if
165  end if
166 
167  case ( interpolation_p3m_ih4ih3 )
168  if ( n0 >= 4 ) then
169  degree = degree_3
170  call edge_values_implicit_h4( n0, h0, densities, ppoly0_e )
171  call edge_slopes_implicit_h3( n0, h0, densities, ppoly0_s )
172  call p3m_interpolation( n0, h0, densities, ppoly0_e, ppoly0_s, ppoly0_coefficients )
173  if (extrapolate) then
174  call p3m_boundary_extrapolation( n0, h0, densities, ppoly0_e, ppoly0_s, ppoly0_coefficients )
175  end if
176  else
177  degree = degree_1
178  call edge_values_explicit_h2( n0, h0, densities, ppoly0_e )
179  call p1m_interpolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
180  if (extrapolate) then
181  call p1m_boundary_extrapolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
182  end if
183  end if
184 
185  case ( interpolation_p3m_ih6ih5 )
186  if ( n0 >= 6 ) then
187  degree = degree_3
188  call edge_values_implicit_h6( n0, h0, densities, ppoly0_e )
189  call edge_slopes_implicit_h5( n0, h0, densities, ppoly0_s )
190  call p3m_interpolation( n0, h0, densities, ppoly0_e, ppoly0_s, ppoly0_coefficients )
191  if (extrapolate) then
192  call p3m_boundary_extrapolation( n0, h0, densities, ppoly0_e, ppoly0_s, ppoly0_coefficients )
193  end if
194  else
195  degree = degree_1
196  call edge_values_explicit_h2( n0, h0, densities, ppoly0_e )
197  call p1m_interpolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
198  if (extrapolate) then
199  call p1m_boundary_extrapolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
200  end if
201  end if
202 
203  case ( interpolation_pqm_ih4ih3 )
204  if ( n0 >= 4 ) then
205  degree = degree_4
206  call edge_values_implicit_h4( n0, h0, densities, ppoly0_e )
207  call edge_slopes_implicit_h3( n0, h0, densities, ppoly0_s )
208  call pqm_reconstruction( n0, h0, densities, ppoly0_e, ppoly0_s, ppoly0_coefficients )
209  if (extrapolate) then
210  call pqm_boundary_extrapolation_v1( n0, h0, densities, ppoly0_e, ppoly0_s, ppoly0_coefficients )
211  end if
212  else
213  degree = degree_1
214  call edge_values_explicit_h2( n0, h0, densities, ppoly0_e )
215  call p1m_interpolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
216  if (extrapolate) then
217  call p1m_boundary_extrapolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
218  end if
219  end if
220 
221  case ( interpolation_pqm_ih6ih5 )
222  if ( n0 >= 6 ) then
223  degree = degree_4
224  call edge_values_implicit_h6( n0, h0, densities, ppoly0_e )
225  call edge_slopes_implicit_h5( n0, h0, densities, ppoly0_s )
226  call pqm_reconstruction( n0, h0, densities, ppoly0_e, ppoly0_s, ppoly0_coefficients )
227  if (extrapolate) then
228  call pqm_boundary_extrapolation_v1( n0, h0, densities, ppoly0_e, ppoly0_s, ppoly0_coefficients )
229  end if
230  else
231  degree = degree_1
232  call edge_values_explicit_h2( n0, h0, densities, ppoly0_e )
233  call p1m_interpolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
234  if (extrapolate) then
235  call p1m_boundary_extrapolation( n0, h0, densities, ppoly0_e, ppoly0_coefficients )
236  end if
237  end if
238  end select
239 end subroutine regridding_set_ppolys
240 
241 !> Given target values (e.g., density), build new grid based on polynomial
242 !!
243 !! Given the grid 'grid0' and the piecewise polynomial interpolant
244 !! 'ppoly0' (possibly discontinuous), the coordinates of the new grid 'grid1'
245 !! are determined by finding the corresponding target interface densities.
246 subroutine interpolate_grid( n0, h0, x0, ppoly0_E, ppoly0_coefficients, target_values, degree, n1, h1, x1 )
247  ! Arguments
248  integer, intent(in) :: n0 !< Number of points on source grid
249  real, dimension(:), intent(in) :: h0 !< Thicknesses of source grid cells
250  real, dimension(:), intent(in) :: x0 !< Source interface positions
251  real, dimension(:,:), intent(in) :: ppoly0_E !< Edge values of interpolating polynomials
252  real, dimension(:,:), intent(in) :: ppoly0_coefficients !< Coefficients of interpolating polynomials
253  real, dimension(:), intent(in) :: target_values !< Target values of interfaces
254  integer, intent(in) :: degree !< Degree of interpolating polynomials
255  integer, intent(in) :: n1 !< Number of points on target grid
256  real, dimension(:), intent(inout) :: h1 !< Thicknesses of target grid cells
257  real, dimension(:), intent(inout) :: x1 !< Target interface positions
258 
259  ! Local variables
260  integer :: k ! loop index
261  real :: t ! current interface target density
262 
263  ! Make sure boundary coordinates of new grid coincide with boundary
264  ! coordinates of previous grid
265  x1(1) = x0(1)
266  x1(n1+1) = x0(n0+1)
267 
268  ! Find coordinates for interior target values
269  do k = 2,n1
270  t = target_values(k)
271  x1(k) = get_polynomial_coordinate( n0, h0, x0, ppoly0_e, ppoly0_coefficients, t, degree )
272  h1(k-1) = x1(k) - x1(k-1)
273  end do
274  h1(n1) = x1(n1+1) - x1(n1)
275 
276 end subroutine interpolate_grid
277 
278 subroutine build_and_interpolate_grid(CS, densities, n0, h0, x0, target_values, n1, h1, x1)
279  type(interp_cs_type), intent(in) :: CS
280  real, dimension(:), intent(in) :: densities, target_values
281  integer, intent(in) :: n0, n1
282  real, dimension(:), intent(in) :: h0, x0
283  real, dimension(:), intent(inout) :: h1, x1
284 
285  real, dimension(n0,2) :: ppoly0_E, ppoly0_S
286  real, dimension(n0,DEGREE_MAX+1) :: ppoly0_C
287  integer :: degree
288 
289  call regridding_set_ppolys(cs, densities, n0, h0, ppoly0_e, ppoly0_s, ppoly0_c, &
290  degree)
291  call interpolate_grid(n0, h0, x0, ppoly0_e, ppoly0_c, target_values, degree, &
292  n1, h1, x1)
293 end subroutine build_and_interpolate_grid
294 
295 !> Given a target value, find corresponding coordinate for given polynomial
296 !!
297 !! Here, 'ppoly' is assumed to be a piecewise discontinuous polynomial of degree
298 !! 'degree' throughout the domain defined by 'grid'. A target value is given
299 !! and we need to determine the corresponding grid coordinate to define the
300 !! new grid.
301 !!
302 !! If the target value is out of range, the grid coordinate is simply set to
303 !! be equal to one of the boundary coordinates, which results in vanished layers
304 !! near the boundaries.
305 !!
306 !! IT IS ASSUMED THAT THE PIECEWISE POLYNOMIAL IS MONOTONICALLY INCREASING.
307 !! IF THIS IS NOT THE CASE, THE NEW GRID MAY BE ILL-DEFINED.
308 !!
309 !! It is assumed that the number of cells defining 'grid' and 'ppoly' are the
310 !! same.
311 function get_polynomial_coordinate ( N, h, x_g, ppoly_E, ppoly_coefficients, &
312  target_value, degree ) result ( x_tgt )
313  ! Arguments
314  integer, intent(in) :: N !< Number of grid cells
315  real, dimension(:), intent(in) :: h !< Grid cell thicknesses
316  real, dimension(:), intent(in) :: x_g !< Grid interface locations
317  real, dimension(:,:), intent(in) :: ppoly_E !< Edge values of interpolating polynomials
318  real, dimension(:,:), intent(in) :: ppoly_coefficients !< Coefficients of interpolating polynomials
319  real, intent(in) :: target_value !< Target value to find position for
320  integer, intent(in) :: degree !< Degree of the interpolating polynomials
321 
322  real :: x_tgt !< The position of x_g at which target_value is found.
323 
324  ! Local variables
325  integer :: i, k ! loop indices
326  integer :: k_found ! index of target cell
327  integer :: iter
328  real :: xi0 ! normalized target coordinate
329  real, dimension(DEGREE_MAX) :: a ! polynomial coefficients
330  real :: numerator
331  real :: denominator
332  real :: delta ! Newton-Raphson increment
333  real :: x ! global target coordinate
334  real :: eps ! offset used to get away from
335  ! boundaries
336  real :: grad ! gradient during N-R iterations
337 
338  eps = nr_offset
339  k_found = -1
340 
341  ! If the target value is outside the range of all values, we
342  ! force the target coordinate to be equal to the lowest or
343  ! largest value, depending on which bound is overtaken
344  if ( target_value <= ppoly_e(1,1) ) then
345  x_tgt = x_g(1)
346  return ! return because there is no need to look further
347  end if
348 
349  ! Since discontinuous edge values are allowed, we check whether the target
350  ! value lies between two discontinuous edge values at interior interfaces
351  do k = 2,n
352  if ( ( target_value >= ppoly_e(k-1,2) ) .AND. &
353  ( target_value <= ppoly_e(k,1) ) ) then
354  x_tgt = x_g(k)
355  return ! return because there is no need to look further
356  exit
357  end if
358  end do
359 
360  ! If the target value is outside the range of all values, we
361  ! force the target coordinate to be equal to the lowest or
362  ! largest value, depending on which bound is overtaken
363  if ( target_value >= ppoly_e(n,2) ) then
364  x_tgt = x_g(n+1)
365  return ! return because there is no need to look further
366  end if
367 
368  ! At this point, we know that the target value is bounded and does not
369  ! lie between discontinuous, monotonic edge values. Therefore,
370  ! there is a unique solution. We loop on all cells and find which one
371  ! contains the target value. The variable k_found holds the index value
372  ! of the cell where the taregt value lies.
373  do k = 1,n
374  if ( ( target_value > ppoly_e(k,1) ) .AND. &
375  ( target_value < ppoly_e(k,2) ) ) then
376  k_found = k
377  exit
378  end if
379  end do
380 
381  ! At this point, 'k_found' should be strictly positive. If not, this is
382  ! a major failure because it means we could not find any target cell
383  ! despite the fact that the target value lies between the extremes. It
384  ! means there is a major problem with the interpolant. This needs to be
385  ! reported.
386  if ( k_found == -1 ) then
387  write(*,*) target_value, ppoly_e(1,1), ppoly_e(n,2)
388  write(*,*) 'Could not find target coordinate in ' //&
389  '"get_polynomial_coordinate". This is caused by an '//&
390  'inconsistent interpolant (perhaps not monotonically '//&
391  'increasing)'
392  call mom_error( fatal, 'Aborting execution' )
393  end if
394 
395  ! Reset all polynomial coefficients to 0 and copy those pertaining to
396  ! the found cell
397  a(:) = 0.0
398  do i = 1,degree+1
399  a(i) = ppoly_coefficients(k_found,i)
400  end do
401 
402  ! Guess value to start Newton-Raphson iterations (middle of cell)
403  xi0 = 0.5
404  iter = 1
405  delta = 1e10
406 
407  ! Newton-Raphson iterations
408  do
409  ! break if converged or too many iterations taken
410  if ( ( iter > nr_iterations ) .OR. &
411  ( abs(delta) < nr_tolerance ) ) then
412  exit
413  end if
414 
415  numerator = a(1) + a(2)*xi0 + a(3)*xi0*xi0 + a(4)*xi0*xi0*xi0 + &
416  a(5)*xi0*xi0*xi0*xi0 - target_value
417 
418  denominator = a(2) + 2*a(3)*xi0 + 3*a(4)*xi0*xi0 + 4*a(5)*xi0*xi0*xi0
419 
420  delta = -numerator / denominator
421 
422  xi0 = xi0 + delta
423 
424  ! Check whether new estimate is out of bounds. If the new estimate is
425  ! indeed out of bounds, we manually set it to be equal to the overtaken
426  ! bound with a small offset towards the interior when the gradient of
427  ! the function at the boundary is zero (in which case, the Newton-Raphson
428  ! algorithm does not converge).
429  if ( xi0 < 0.0 ) then
430  xi0 = 0.0
431  grad = a(2)
432  if ( grad == 0.0 ) xi0 = xi0 + eps
433  end if
434 
435  if ( xi0 > 1.0 ) then
436  xi0 = 1.0
437  grad = a(2) + 2*a(3) + 3*a(4) + 4*a(5)
438  if ( grad == 0.0 ) xi0 = xi0 - eps
439  end if
440 
441  iter = iter + 1
442  end do ! end Newton-Raphson iterations
443 
444  x_tgt = x_g(k_found) + xi0 * h(k_found)
445 end function get_polynomial_coordinate
446 
447 !> Numeric value of interpolation_scheme corresponding to scheme name
448 integer function interpolation_scheme(interp_scheme)
449  character(len=*), intent(in) :: interp_scheme !< Name of interpolation scheme
450 
451  select case ( uppercase(trim(interp_scheme)) )
452  case ("P1M_H2"); interpolation_scheme = interpolation_p1m_h2
453  case ("P1M_H4"); interpolation_scheme = interpolation_p1m_h4
454  case ("P1M_IH2"); interpolation_scheme = interpolation_p1m_ih4
456  case ("PPM_H4"); interpolation_scheme = interpolation_ppm_h4
457  case ("PPM_IH4"); interpolation_scheme = interpolation_ppm_ih4
458  case ("P3M_IH4IH3"); interpolation_scheme = interpolation_p3m_ih4ih3
459  case ("P3M_IH6IH5"); interpolation_scheme = interpolation_p3m_ih6ih5
460  case ("PQM_IH4IH3"); interpolation_scheme = interpolation_pqm_ih4ih3
461  case ("PQM_IH6IH5"); interpolation_scheme = interpolation_pqm_ih6ih5
462  case default ; call mom_error(fatal, "regrid_interp: "//&
463  "Unrecognized choice for INTERPOLATION_SCHEME ("//trim(interp_scheme)//").")
464  end select
465 end function interpolation_scheme
466 
467 subroutine set_interp_scheme(CS, interp_scheme)
468  type(interp_cs_type), intent(inout) :: CS
469  character(len=*), intent(in) :: interp_scheme
470 
471  cs%interpolation_scheme = interpolation_scheme(interp_scheme)
472 end subroutine set_interp_scheme
473 
474 subroutine set_interp_extrap(CS, extrapolation)
475  type(interp_cs_type), intent(inout) :: CS
476  logical, intent(in) :: extrapolation
477 
478  cs%boundary_extrapolation = extrapolation
479 end subroutine set_interp_extrap
480 
481 end module regrid_interp
subroutine, public edge_values_implicit_h6(N, h, u, edge_values)
subroutine, public edge_values_implicit_h4(N, h, u, edge_values)
integer function interpolation_scheme(interp_scheme)
Numeric value of interpolation_scheme corresponding to scheme name.
integer, parameter interpolation_p3m_ih6ih5
O(h^4)
integer, parameter degree_3
integer, parameter interpolation_p1m_ih4
O(h^2)
integer, parameter interpolation_p1m_h4
O(h^2)
subroutine, public pqm_boundary_extrapolation_v1(N, h, u, ppoly_E, ppoly_S, ppoly_coefficients)
subroutine, public set_interp_scheme(CS, interp_scheme)
subroutine, public p1m_boundary_extrapolation(N, h, u, ppoly_E, ppoly_coefficients)
integer, parameter interpolation_plm
O(h^2)
subroutine, public pqm_reconstruction(N, h, u, ppoly_E, ppoly_S, ppoly_coefficients)
Provides functions used with the Piecewise-Parabolic-Method in the vertical ALE algorithm.
integer, parameter interpolation_p1m_h2
O(h^2)
integer, parameter degree_1
List of interpolant degrees.
subroutine, public build_and_interpolate_grid(CS, densities, n0, h0, x0, target_values, n1, h1, x1)
integer, parameter interpolation_ppm_h4
O(h^3)
integer, parameter degree_2
subroutine, public p1m_interpolation(N, h, u, ppoly_E, ppoly_coefficients)
subroutine, public regridding_set_ppolys(CS, densities, n0, h0, ppoly0_E, ppoly0_S, ppoly0_coefficients, degree)
Given the set of target values and cell densities, this routine builds an interpolated profile for th...
subroutine, public ppm_reconstruction(N, h, u, ppoly_E, ppoly_coefficients)
Builds quadratic polynomials coefficients from cell mean and edge values.
character(len=len(input_string)) function, public uppercase(input_string)
subroutine, public edge_slopes_implicit_h3(N, h, u, edge_slopes)
subroutine, public p3m_interpolation(N, h, u, ppoly_E, ppoly_S, ppoly_coefficients)
integer, parameter, public nr_iterations
Maximum number of Newton-Raphson iterations. Newton-Raphson iterations are used to build the new grid...
integer, parameter degree_4
subroutine, public edge_slopes_implicit_h5(N, h, u, edge_slopes)
subroutine, public interpolate_grid(n0, h0, x0, ppoly0_E, ppoly0_coefficients, target_values, degree, n1, h1, x1)
Given target values (e.g., density), build new grid based on polynomial.
subroutine, public edge_values_explicit_h2(N, h, u, edge_values)
subroutine, public plm_boundary_extrapolation(N, h, u, ppoly_E, ppoly_coefficients)
subroutine, public plm_reconstruction(N, h, u, ppoly_E, ppoly_coefficients)
integer, parameter interpolation_pqm_ih6ih5
O(h^5)
integer, parameter interpolation_ppm_ih4
O(h^3)
integer, parameter, public degree_max
real, parameter, public nr_tolerance
Tolerance for Newton-Raphson iterations (stop when increment falls below this)
subroutine, public ppm_boundary_extrapolation(N, h, u, ppoly_E, ppoly_coefficients)
integer, parameter interpolation_p3m_ih4ih3
O(h^4)
real function get_polynomial_coordinate(N, h, x_g, ppoly_E, ppoly_coefficients, target_value, degree)
Given a target value, find corresponding coordinate for given polynomial.
subroutine, public mom_error(level, message, all_print)
real, parameter, public nr_offset
When the N-R algorithm produces an estimate that lies outside [0,1], the estimate is set to be equal ...
subroutine, public set_interp_extrap(CS, extrapolation)
subroutine, public p3m_boundary_extrapolation(N, h, u, ppoly_E, ppoly_S, ppoly_coefficients)
subroutine, public edge_values_explicit_h4(N, h, u, edge_values)
integer, parameter interpolation_pqm_ih4ih3
O(h^4)