13 #include "sll_memory.h"
14 #include "sll_working_precision.h"
69 sll_int32,
private :: bc_type
70 sll_real64,
dimension(:),
pointer :: coeffs
88 #define MAKE_GET_SLOT_FUNCTION( fname, datatype, slot, ret_type ) \
89 function fname(spline_obj)
result(val); \
90 type(datatype),
pointer :: spline_obj; \
92 val = spline_obj%slot; \
109 sll_int32,
intent(in) :: bc_type
131 sll_real64,
dimension(:),
target,
intent(in) ::
data
132 sll_int32,
intent(in) :: deg
136 select case (spline%bc_type)
137 case (sll_p_dirichlet)
139 call spline%compute_coeff_box_spline_2d_diri(
data, deg)
140 case (sll_p_periodic)
142 call spline%compute_coeff_box_spline_2d_prdc(
data, deg)
145 call spline%compute_coeff_box_spline_2d_neum(
data, deg)
147 print *,
'ERROR: compute_coeff_box_spline_2d(): ', &
148 'did not recognize given boundary condition combination.'
163 sll_real64,
dimension(:),
intent(in),
target ::
data
164 sll_int32,
intent(in) :: deg
166 sll_int32 :: num_pts_tot
167 sll_int32 :: k1_ref, k2_ref
172 sll_int32 :: num_pts_radius
174 sll_real64,
allocatable,
dimension(:) :: filter_array
176 num_pts_tot = spline%mesh%num_pts_tot
179 num_pts_radius = 3*deg*(deg + 1) + 1
193 do i = 1, num_pts_tot
195 spline%coeffs(i) = real(0, f64)
196 k1_ref = spline%mesh%global_to_hex1(i)
197 k2_ref = spline%mesh%global_to_hex2(i)
201 do k = 1, num_pts_radius
202 filter = filter_array(k)
203 nei = spline%mesh%local_hex_to_global(k1_ref, k2_ref, k)
204 if ((nei .le. num_pts_tot) .and. (nei .gt. 0))
then
205 spline%coeffs(i) = spline%coeffs(i) +
data(nei)*filter
209 spline%coeffs(i) = spline%coeffs(i)
225 sll_int32,
intent(in) :: deg
226 sll_real64,
dimension(:),
intent(in),
target ::
data
228 sll_int32 :: num_pts_tot
231 print *,
' WARNING : BOUNDARY CONDITIONS PERIODIC NOT &
232 & YET IMPLEMENTED', deg
233 num_pts_tot = spline%mesh%num_pts_tot
234 do i = 1, num_pts_tot
235 spline%coeffs(i) = real(0, f64)*
data(i)
249 sll_real64,
dimension(:),
intent(in),
target ::
data
250 sll_int32,
intent(in) :: deg
252 sll_int32 :: num_pts_tot
255 print *,
' WARNING : BOUNDARY CONDITIONS PERIODIC NOT &
256 & YET IMPLEMENTED', deg
257 num_pts_tot = spline%mesh%num_pts_tot
258 do i = 1, num_pts_tot
259 spline%coeffs(i) = real(0, f64)*
data(i)
271 sll_int32,
intent(in) :: n
272 sll_int32,
intent(in) :: k
276 else if (n .lt. k)
then
299 sll_real64,
intent(in) :: x1_in
300 sll_real64,
intent(in) :: x2_in
301 sll_int32,
intent(in) :: deg
339 do k = -deg, ceiling(u) - 1
340 if ((x1_in .eq. 0._f64) .and. (x2_in .eq. 0.8_f64))
then
343 do l = -deg, ceiling(v) - 1
344 if ((x1_in .eq. 0._f64) .and. (x2_in .eq. 0.8_f64))
then
347 do i = 0, min(deg + k, deg + l)
348 if ((x1_in .eq. 0._f64) .and. (x2_in .eq. 0.8_f64))
then
351 coeff = (-1.0_f64)**(k + l + i)* &
355 if ((x1_in .eq. 0._f64) .and. (x2_in .eq. 0.8_f64))
then
359 if ((x1_in .eq. 0._f64) .and. (x2_in .eq. 0.8_f64))
then
362 aux = abs(v - real(l, f64) - u + real(k, f64))
363 aux2 = (u - real(k, f64) + v - real(l, f64) - aux)/2._f64
364 if (aux2 .lt. 0._f64)
then
367 val = val + coeff*
choose(deg - 1 + d, d) &
370 *aux**(deg - 1 - d) &
371 *aux2**(2*deg - 1 + d)
372 if ((x1_in .eq. 0._f64) .and. (x2_in .eq. 0.8_f64))
then
402 if (v .gt. 2._f64)
then
404 else if (v .lt. 1._f64)
then
406 ((5._f64/3._f64 - v/8.0_f64)*v - 3.0_f64)*v*v/4.0_f64 + &
407 ((1._f64 - v/4._f64)*v + g*g/6._f64 - 1._f64)*g*g
408 else if (u .gt. 1._f64)
then
409 val = (v - 2._f64)*(v - 2._f64)*(v - 2._f64)*(g - 1._f64)/6.0_f64
411 val = 5._f64/6._f64 + &
412 ((1._f64 + (1._f64/3._f64 - v/8._f64)*v)*v/4._f64 - 1._f64)*v + &
413 ((1._f64 - v/4._f64)*v + g*g/6.0_f64 - 1._f64)*g*g
430 sll_real64,
intent(in) :: x1
431 sll_real64,
intent(in) :: x2
432 sll_int32,
intent(in) :: deg
434 sll_real64 :: x1_basis
435 sll_real64 :: x2_basis
454 sll_real64,
intent(in) :: x1
455 sll_real64,
intent(in) :: x2
456 sll_real64 :: delta_q
457 sll_real64 :: k1_basis
458 sll_real64 :: k2_basis
459 sll_real64 :: x1_basis
460 sll_real64 :: inv_delta_q
461 sll_real64 :: q11, q12
462 sll_real64 :: q21, q22
463 sll_real64 :: r11, r12
464 sll_real64 :: r21, r22
473 q11 = spline%mesh%r1_x1
474 q12 = spline%mesh%r1_x2
475 q21 = spline%mesh%r2_x1
476 q22 = spline%mesh%r2_x2
479 delta_q = q11*q22 - q12*q21
480 inv_delta_q = 1._f64/delta_q
481 k1_basis = inv_delta_q*(q22*x1 - q21*x2)
482 k2_basis = inv_delta_q*(q11*x2 - q12*x1)
483 x1_basis = r11*k1_basis + r21*k2_basis
498 sll_real64,
intent(in) :: x1
499 sll_real64,
intent(in) :: x2
500 sll_real64 :: delta_q
501 sll_real64 :: inv_delta_q
502 sll_real64 :: k1_basis
503 sll_real64 :: k2_basis
504 sll_real64 :: x2_basis
505 sll_real64 :: q11, q12
506 sll_real64 :: q21, q22
507 sll_real64 :: r11, r12
508 sll_real64 :: r21, r22
518 q11 = spline%mesh%r1_x1
519 q12 = spline%mesh%r1_x2
520 q21 = spline%mesh%r2_x1
521 q22 = spline%mesh%r2_x2
524 delta_q = q11*q22 - q12*q21
525 inv_delta_q = 1._f64/delta_q
526 k1_basis = inv_delta_q*(q22*x1 - q21*x2)
527 k2_basis = inv_delta_q*(q11*x2 - q12*x1)
528 x2_basis = r12*k1_basis + r22*k2_basis
545 sll_int32,
intent(in) :: deg
546 sll_real64,
intent(in) :: x1, x2
547 sll_real64 :: xm1, xm2
548 sll_real64 :: x1_spl, x2_spl
549 sll_real64 :: r11, r12
550 sll_real64 :: r21, r22
551 sll_real64 :: r31, r32
552 sll_int32 :: k1_asso, k2_asso
555 sll_int32 :: num_pts_tot
556 sll_int32 :: num_cells
557 sll_int32 :: distance
563 r11 = mesh_geom%r1_x1
564 r12 = mesh_geom%r1_x2
565 r21 = mesh_geom%r2_x1
566 r22 = mesh_geom%r2_x2
567 r31 = mesh_geom%r3_x1
568 r32 = mesh_geom%r3_x2
570 num_pts_tot = mesh_geom%num_pts_tot
571 num_cells = spline%mesh%num_cells
588 if (distance .le. num_cells)
then
590 ind = spline%mesh%hex_to_global(k1, k2)
595 xm1 = x1 - r11*real(k1_asso, f64) - r21*real(k2_asso, f64) &
596 - real(ki, f64)*r11 - real(kj, f64)*r21
597 xm2 = x2 - r12*real(k1_asso, f64) - r22*real(k2_asso, f64) &
598 - real(ki, f64)*r12 - real(kj, f64)*r22
604 val = val + spline%coeffs(ind)* &
609 if (spline%bc_type .eq. sll_p_dirichlet)
then
611 ind = spline%mesh%hex_to_global(k1_asso, k2_asso)
613 print *,
"Error : Boundary condition type not yet implemented"
634 sll_int32,
intent(in) :: deg
635 sll_int32,
intent(in) :: cell_index
636 sll_int32 :: index_nz(3*deg*deg)
638 sll_int32 :: nei_point
639 sll_int32 :: non_zero
640 sll_int32 :: distance
641 sll_int32 :: edge1, edge2, edge3
646 sll_int32 :: last_point
647 sll_int32 :: current_nz
651 index_nz(1:non_zero) = -1
654 call mesh%cell_type(cell_index, type)
658 mesh%center_cartesian_coord(2, cell_index), &
666 if (
type .eq. 2) then
677 do distance = 1, deg - 1
678 first = 1 + (distance - 1)*(distance - 1)*3
679 last = distance*distance*3
681 last_point = index_nz(i)
682 if (last_point .eq. -1)
then
683 print *,
"ERROR in non_zero_splines: wrong index, i=", i
687 if ((nei_point .ne. -1) .and. (.not. (any(index_nz == nei_point))))
then
688 index_nz(current_nz) = nei_point
689 current_nz = current_nz + 1
704 sll_int32,
intent(in) :: deg
705 sll_real64,
intent(in) :: x1
706 sll_real64,
intent(in) :: x2
723 val = (-fp2h + 8._f64*fp1h - 8._f64*fm1h + fm2h)/12._f64/h
735 sll_int32,
intent(in) :: deg
736 sll_real64,
intent(in) :: x1
737 sll_real64,
intent(in) :: x2
754 val = 0.25_f64/3._f64/h*(-fp2h + 8._f64*fp1h - 8._f64*fm1h + fm2h)
769 sll_int32,
intent(in) :: deg
770 sll_int32,
intent(in) :: nderiv1
771 sll_int32,
intent(in) :: nderiv2
772 sll_real64,
intent(in) :: x1
773 sll_real64,
intent(in) :: x2
775 sll_real64 :: x1_basis
776 sll_real64 :: x2_basis
788 if (nderiv1 .eq. 0)
then
789 if (nderiv2 .eq. 0)
then
792 else if (nderiv2 .eq. 1)
then
796 print *,
"Error in sll_f_boxspline_val_der : cannot compute this derivative"
798 else if (nderiv1 .eq. 1)
then
800 if (nderiv2 .eq. 0)
then
803 print *,
"Error in sll_f_boxspline_val_der : cannot compute this derivative"
807 sll_deallocate_array(spline%coeffs, ierr)
808 sll_deallocate(spline, ierr)
821 sll_int32,
intent(in) :: deg
822 sll_int32 :: out_unit
823 character(len=28),
parameter :: name =
"boxsplines_connectivity.txt"
824 sll_int32 :: nz_indices(3*deg*deg)
827 sll_int32 :: non_zero
839 open (file=name, status=
"replace", form=
"formatted", newunit=out_unit)
842 write (out_unit,
"(i6)") mesh%num_triangles
844 do num_ele = 1, mesh%num_triangles
848 write (out_unit,
"(i6)") non_zero
853 write (out_unit,
"(i6)", advance=
"no") val
854 write (out_unit,
"(a)", advance=
"no")
","
856 write (out_unit,
"(a)")
""
870 if (.not.
associated(spline))
then
871 print *,
'delete_box_spline_2D(): passed spline is not associated'
875 sll_deallocate(spline%coeffs, ierr)
876 sll_deallocate(spline, ierr)
Generic sub-routine defined for 2D box spline types. Deallocates the memory associated with the given...
Describe different boundary conditions.
Provides capabilities for values and derivatives interpolation with box splines on hexagonal meshes.
subroutine, public sll_s_write_connectivity(mesh, deg)
Writes connectivity for CAID / DJANGO.
real(kind=f64) function, public sll_f_boxspline_val_der(x1, x2, deg, nderiv1, nderiv2)
Computes the values or derivatives of box splines.
real(kind=f64) function change_basis_x2(spline, x1, x2)
2nd coo. of (x1, x2) in reference hex-mesh coo.
real(kind=f64) function, public sll_f_hex_interpolate_value(mesh_geom, x1, x2, spline, deg)
Interpolates on point of cartesian coordinates (x1, x2)
function chi_gen_val(x1_in, x2_in, deg)
Computes the box spline of degree deg on (x1, x2)
real(kind=f64) function change_basis_x1(spline, x1, x2)
1st coo. of (x1, x2) in reference hex-mesh coo.
subroutine compute_coeff_box_spline_2d_diri(spline, data, deg)
Computes box splines coefficients for dirichlet BC.
subroutine delete_box_spline_2d(spline)
Generic sub-routine defined for 2D box spline types. Deallocates the memory associated with the given...
subroutine compute_coeff_box_spline_2d_prdc(spline, data, deg)
Computes box splines coefficients with periodic BC.
subroutine compute_coeff_box_spline_2d(spline, data, deg)
Computes box splines coefficients.
subroutine compute_coeff_box_spline_2d_neum(spline, data, deg)
Computes box splines coefficients with neumann BC.
integer(kind=i32) function, dimension(3 *deg *deg) non_zeros_splines(mesh, cell_index, deg)
Computes indices of non null splines on a given cell.
function choose(n, k)
Computes the binomial coefficient (n, k)
real(kind=f64) function, public sll_f_boxspline_x2_derivative(x1, x2, deg)
Computes y-derivative on (x,y)
type(sll_t_box_spline_2d) function, pointer, public sll_f_new_box_spline_2d(mesh, bc_type)
Creates a box spline element.
real(kind=f64) function, public sll_f_compute_box_spline(spline, x1, x2, deg)
Computes the value of a box spline.
real(kind=f64) function, public sll_f_boxspline_x1_derivative(x1, x2, deg)
Computes x-derivative on (x,y)
Fortran module where set some physical and mathematical constants.
real(kind=f64), parameter, public sll_p_sqrt3
real(kind=f64), parameter, public sll_p_epsilon_0
Pre-filter for box-splines quasi interpolation.
subroutine, public sll_s_pre_filter_pfir(mesh, deg, weight_tab)
Pre-filter PFIR to compute the box splines coefficients.
real(kind=f64) function, public sll_f_pre_filter_piir2(mesh, local_index, deg)
Pre-filter PIIR2 to compute the box splines coefficients.
real(kind=f64) function, public sll_f_pre_filter_int(mesh, local_index, deg)
Pre-filter PINT to compute the box splines coefficients.
real(kind=f64) function, public sll_f_pre_filter_piir1(mesh, local_index, deg)
Pre-filter PIIR1 to compute the box splines coefficients.
function, public sll_f_local_to_global(mesh, ref_index, local)
Transforms local index in a given reference local indexation to a global index from the mesh.
function, public sll_f_change_elements_notation(mesh, i_elmt_old)
Function that allows to change from the current element notation to one more intuitive.
integer(kind=i32) function, public sll_f_cells_to_origin(k1, k2)
Computes the number of cell from point to origin.
function, public sll_f_cart_to_hex2(mesh, x1, x2)
Transform cartesian coordinates to 2ndst hexagonal coordinates.
subroutine, public sll_s_write_caid_files(mesh, transf, spline_deg)
Writes files for CAID.
function, public sll_f_cart_to_hex1(mesh, x1, x2)
Transform cartesian coordinates to 1st hexagonal coordinates.
subroutine, public sll_s_get_cell_vertices_index(x, y, mesh, s1, s2, s3)
Returns indices of the edges of a given cell.
type(sll_t_hex_mesh_2d) function, pointer, public sll_f_new_hex_mesh_2d(num_cells, center_x1, center_x2, r11, r12, r21, r22, r31, r32, radius, EXTRA_TABLES)
Creates and initializes a new hexagonal mesh.
Some common numerical utilities.
Basic type for 2 dimensional box splines.