11 #include "sll_assert.h"
12 #include "sll_errors.h"
13 #include "sll_memory.h"
14 #include "sll_working_precision.h"
57 sll_real64 :: cell_size
59 sll_real64,
pointer :: positions(:)
60 sll_real64,
pointer :: quadrature_points(:)
61 sll_real64,
pointer :: quadrature_inv_diffs(:, :)
62 sll_real64,
pointer :: quadrature_weights(:)
63 sll_real64,
pointer :: quadrature_inv_weights(:)
64 sll_real64,
pointer :: weights1(:, :)
65 sll_real64,
pointer :: weights2(:, :)
73 sll_int32,
intent(in) :: n_cells
74 sll_int32,
intent(in) :: degree
75 sll_real64,
intent(in) :: x_min
76 sll_real64,
intent(in) :: x_max
77 sll_int32,
intent(in) ::
type !< descriptor telling
if gauss-lobatto, gauss-legendre or uniform points shall be used as points within the cells
79 sll_int32 :: ierr, j, i
81 self%n_cells = n_cells
83 self%n_total = n_cells*degree
85 sll_allocate(self%positions(self%n_total), ierr)
86 sll_allocate(self%quadrature_points(self%degree), ierr)
87 sll_allocate(self%quadrature_weights(self%degree), ierr)
88 sll_allocate(self%quadrature_inv_weights(self%degree), ierr)
89 sll_allocate(self%weights1(self%degree, self%degree), ierr)
90 sll_allocate(self%weights2(self%degree, self%degree), ierr)
91 sll_allocate(self%quadrature_inv_diffs(self%degree, self%degree), ierr)
103 do j = 1, self%degree
104 self%quadrature_points(j) = real(j - 1, f64)/real(self%degree - 1, f64)
106 self%quadrature_weights = 1.0_f64/(self%degree - 1)
107 self%quadrature_weights(1) = 0.5_f64/(self%degree - 1)
108 self%quadrature_weights(self%degree) = self%quadrature_weights(1)
110 sll_error(
'sll_s_dg_interpolator_1d_init',
'Wrong type of points.')
114 self%cell_size = (x_max - x_min)/n_cells
117 self%positions(1 + (j - 1)*degree:j*degree) = x_min + &
118 (real(j - 1, f64) + self%quadrature_points)*self%cell_size
123 do i = 1, self%degree
124 do j = 1, self%degree
126 self%quadrature_inv_diffs(j, i) = 1.0_f64/(self%quadrature_points(i) - self%quadrature_points(j))
129 self%quadrature_inv_diffs(j, i) = 1.0_f64
136 do i = 1, self%degree
137 self%quadrature_inv_weights(i) = 1.0_f64/self%quadrature_weights(i)
146 sll_deallocate(self%positions, ierr)
147 sll_deallocate(self%quadrature_points, ierr)
148 sll_deallocate(self%quadrature_inv_diffs, ierr)
149 sll_deallocate(self%quadrature_weights, ierr)
150 sll_deallocate(self%quadrature_inv_weights, ierr)
151 sll_deallocate(self%weights1, ierr)
152 sll_deallocate(self%weights2, ierr)
158 sll_int32,
intent(in) :: num_pts
159 sll_real64,
intent(in) :: alpha
160 sll_real64,
dimension(:),
intent(in) ::
data
161 sll_real64,
dimension(num_pts),
intent(out) :: output_array
163 sll_int32 :: i, j, k, r, q, ind1, ind2, degree, n_cells
164 sll_real64 :: beta, alph
165 sll_real64,
pointer :: quadrature_points(:)
166 sll_real64,
pointer :: quadrature_weights(:)
167 sll_real64,
pointer :: quadrature_inv_weights(:)
168 sll_real64,
pointer :: weights1(:, :)
169 sll_real64,
pointer :: weights2(:, :)
170 sll_real64,
pointer :: quadrature_inv_diffs(:, :)
172 sll_assert(num_pts == self%n_total)
175 beta = alpha/self%cell_size
177 alph = beta - real(q, f64)
181 n_cells = self%n_cells
182 quadrature_points => self%quadrature_points
183 quadrature_inv_diffs => self%quadrature_inv_diffs
184 quadrature_weights => self%quadrature_weights
185 quadrature_inv_weights => self%quadrature_inv_weights
186 weights1 => self%weights1
187 weights2 => self%weights2
214 weights1(:, :) = 0.0_f64
218 weights1(k, j) = weights1(k, j) + quadrature_weights(r)* &
219 lagrange_poly_opt(quadrature_points, quadrature_inv_diffs, degree, k, alph + (1.0_f64 - alph)*quadrature_points(r))* &
220 lagrange_poly_opt(quadrature_points, quadrature_inv_diffs, degree, j, (1.0_f64 - alph)*quadrature_points(r))
222 weights1(k, j) = weights1(k, j)*(1.0_f64 - alph)
226 weights2(:, :) = 0.0_f64
230 weights2(k, j) = weights2(k, j) + quadrature_weights(r)* &
231 lagrange_poly_opt(quadrature_points, quadrature_inv_diffs, degree, k, alph*quadrature_points(r))* &
232 lagrange_poly_opt(quadrature_points, quadrature_inv_diffs, degree, j, alph*(quadrature_points(r) - 1.0_f64) + 1.0_f64)
234 weights2(k, j) = weights2(k, j)*alph
239 output_array(:) = 0.0_f64
243 ind1 = modulo(i - 1 + q, self%n_cells)*degree
244 ind2 = modulo(i + q, self%n_cells)*degree
246 output_array((i - 1)*degree + j) = output_array((i - 1)*degree + j) + &
247 data(ind1 + k)*weights1(k, j) +
data(ind2 + k)*weights2(k, j)
250 output_array((i - 1)*degree + j) = output_array((i - 1)*degree + j)*quadrature_inv_weights(j)
259 sll_real64,
intent(in) :: alpha
260 sll_real64,
intent(in) ::
data(:)
261 sll_real64,
intent(inout) :: weights1(self%degree, self%degree)
262 sll_real64,
intent(inout) :: weights2(self%degree, self%degree)
263 sll_real64,
intent(inout) :: output_array(self%n_total)
265 sll_int32 :: i, j, k, r, q, ind1, ind2, num_pts, degree, n_cells
267 sll_real64,
pointer :: quadrature_points(:)
268 sll_real64,
pointer :: quadrature_weights(:)
269 sll_real64,
pointer :: quadrature_inv_weights(:)
270 sll_real64,
pointer :: quadrature_inv_diffs(:, :)
273 n_cells = self%n_cells
275 quadrature_points => self%quadrature_points
276 quadrature_weights => self%quadrature_weights
277 quadrature_inv_weights => self%quadrature_inv_weights
278 quadrature_inv_diffs => self%quadrature_inv_diffs
316 weights1(:, :) = 0.0_f64
320 weights1(k, j) = weights1(k, j) + quadrature_weights(r)* &
321 lagrange_poly_opt(quadrature_points, quadrature_inv_diffs, degree, k, alph + (1.0_f64 - alph)*quadrature_points(r))* &
322 lagrange_poly_opt(quadrature_points, quadrature_inv_diffs, degree, j, (1.0_f64 - alph)*quadrature_points(r))
324 weights1(k, j) = weights1(k, j)*(1.0_f64 - alph)
328 weights2(:, :) = 0.0_f64
332 weights2(k, j) = weights2(k, j) + quadrature_weights(r)* &
333 lagrange_poly_opt(quadrature_points, quadrature_inv_diffs, degree, k, alph*quadrature_points(r))* &
334 lagrange_poly_opt(quadrature_points, quadrature_inv_diffs, degree, j, alph*(quadrature_points(r) - 1.0_f64) + 1.0_f64)
336 weights2(k, j) = weights2(k, j)*alph
341 output_array(:) = 0.0_f64
344 ind1 = (i - 1)*degree
352 output_array((i - 1)*degree + j) = output_array((i - 1)*degree + j) + &
353 data(ind1 + k)*weights1(k, j) +
data(ind2 + k)*weights2(k, j)
356 output_array((i - 1)*degree + j) = output_array((i - 1)*degree + j)*quadrature_inv_weights(j)
363 sll_int32,
intent(in) :: npoints
364 sll_real64,
intent(out) :: output_array(:, :)
366 sll_int32 :: j, idx, degree
368 sll_real64,
pointer :: quadrature_points(:)
369 sll_real64,
pointer :: quadrature_inv_diffs(:, :)
371 delta = 1.0_f64/real(npoints - 1, f64);
373 quadrature_points => self%quadrature_points
374 quadrature_inv_diffs => self%quadrature_inv_diffs
379 output_array(idx, j) =
lagrange_poly_opt(quadrature_points, quadrature_inv_diffs, degree, idx, real(j - 1, f64)*delta)
386 sll_int32,
intent(in) :: npoints
387 sll_real64,
intent(out) :: output_array(:, :)
389 sll_int32 :: j, idx, degree
391 sll_real64,
pointer :: quadrature_points(:)
392 sll_real64,
pointer :: quadrature_inv_diffs(:, :)
394 delta = 1.0_f64/real(npoints, f64);
396 quadrature_points => self%quadrature_points
397 quadrature_inv_diffs => self%quadrature_inv_diffs
402 output_array(idx, j) =
lagrange_poly_opt(quadrature_points, quadrature_inv_diffs, degree, idx, (real(j - 1, f64) + 0.5_f64)*delta)
412 sll_int32,
intent(in) :: idx
413 sll_real64,
intent(in) :: x
419 do j = 1, self%degree
421 r = r*(x - self%quadrature_points(j))/(self%quadrature_points(idx) - self%quadrature_points(j))
429 sll_real64,
intent(in) :: quadrature_points(:)
430 sll_real64,
intent(in) :: quadrature_inv_diffs(:, :)
431 sll_int32,
intent(in) :: degree
432 sll_int32,
intent(in) :: idx
433 sll_real64,
intent(in) :: x
441 r = r*(x - quadrature_points(j))*quadrature_inv_diffs(j, idx)
Describe different boundary conditions.
Interpolator 1d using dg interpolation.
real(kind=f64) function lagrange_poly_opt(quadrature_points, quadrature_inv_diffs, degree, idx, x)
Evaluate Lagrange polynomial, optimized version.
subroutine, public sll_s_dg_interpolator_1d_interpolate_array_disp_halo(self, data, alpha, weights1, weights2, output_array)
Interpolation routine with halo cells.
subroutine, public sll_s_dg_interpolator_1d_dg_to_equi_cell_staggered(self, npoints, output_array)
subroutine, public sll_s_dg_interpolator_1d_interpolate_array_disp_periodic(self, num_pts, data, alpha, output_array)
subroutine, public sll_s_dg_interpolator_1d_dg_to_equi_cell(self, npoints, output_array)
integer(kind=i32), parameter, public sll_p_dg_gauss_lobatto
subroutine, public sll_s_dg_interpolator_1d_init(self, n_cells, degree, x_min, x_max, type)
subroutine, public sll_s_dg_interpolator_1d_free(self)
integer(kind=i32), parameter, public sll_p_dg_uniform
real(kind=f64) function lagrange_poly(self, idx, x)
Evaluate Lagrange polynomial, original version. Suffers from repeated dereferencing,...
integer(kind=i32), parameter, public sll_p_dg_gauss_legendre
Gauss-Legendre integration.
real(kind=f64) function, dimension(1:npoints), public sll_f_gauss_legendre_points(npoints, a, b)
real(kind=f64) function, dimension(1:npoints), public sll_f_gauss_legendre_weights(npoints, a, b)
Gauss-Lobatto integration.
real(kind=f64) function, dimension(n), public sll_f_gauss_lobatto_points(n, a, b)
Returns a 1d array of size (n) containing gauss-lobatto points in the interval [a,...
real(kind=f64) function, dimension(n), public sll_f_gauss_lobatto_weights(n, a, b)
Returns a 1d array of size (n) containing gauss-lobatto weights in the interval [a,...
Module for 1D interpolation and reconstruction.
Abstract class for 1D interpolation and reconstruction.