Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_polar_bsplines_2d.F90
Go to the documentation of this file.
1 ! Implements formulas in section 5.1 of https://doi.org/10.1016/j.jcp.2019.108889
3 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 #include "sll_assert.h"
5 
7 
9 
11 
13 
14  implicit none
15 
16  public :: sll_t_polar_bsplines_2d
17 
18  private
19 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20 
22  integer, parameter :: wp = f64
23 
26 
27  ! Pointer to discrete IGA mapping (private member)
28  type(sll_t_singular_mapping_discrete), pointer, private :: mapping => null()
29 
30  ! Pole of the singularity
31  real(wp) :: pole(2)
32 
33  ! Parameter to compute triangle vertices and barycentric coordinates
34  real(wp) :: tau
35 
36  ! Triangle vertices
37  real(wp) :: t0(2)
38  real(wp) :: t1(2)
39  real(wp) :: t2(2)
40 
41  ! New basis functions
42  type(sll_t_spline_2d) :: n0
43  type(sll_t_spline_2d) :: n1
44  type(sll_t_spline_2d) :: n2
45 
46  contains
47 
48  procedure :: init => s_polar_bsplines_2d__init
49  procedure :: eval_l0 => f_polar_bsplines_2d__eval_l0
50  procedure :: eval_l1 => f_polar_bsplines_2d__eval_l1
51  procedure :: eval_l2 => f_polar_bsplines_2d__eval_l2
52  procedure :: free => s_polar_bsplines_2d__free
53 
55 
56 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
57 contains
58 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
59 
60  subroutine s_polar_bsplines_2d__init(self, spline_basis_eta1, spline_basis_eta2, mapping)
61  class(sll_t_polar_bsplines_2d), intent(inout) :: self
62  class(sll_c_bsplines), intent(in) :: spline_basis_eta1
63  class(sll_c_bsplines), intent(in) :: spline_basis_eta2
64  type(sll_t_singular_mapping_discrete), target, intent(in) :: mapping ! mapping must be discrete
65 
66  real(wp) :: tau1, tau2, tau3
67  integer :: nb1, nb2
68 
69  ! Assign pointer to discrete IGA mapping
70  self%mapping => mapping
71 
72  ! Store pole
73  self%pole = mapping%pole()
74 
75  ! Store locally number of basis functions
76  nb1 = spline_basis_eta1%nbasis
77  nb2 = spline_basis_eta2%nbasis
78 
79  ! Compute tau from mapping control points
80  associate(x0 => self%pole(1), &
81  y0 => self%pole(2), &
82  c_x1 => mapping%spline_2d_x1%bcoef(2, 1:nb2), &
83  c_x2 => mapping%spline_2d_x2%bcoef(2, 1:nb2))
84 
85  tau1 = maxval(-2.0_wp*(c_x1 - x0))
86  tau2 = maxval(c_x1 - x0 - sqrt(3.0_wp)*(c_x2 - y0))
87  tau3 = maxval(c_x1 - x0 + sqrt(3.0_wp)*(c_x2 - y0))
88 
89  self%tau = max(tau1, tau2, tau3)
90 
91  ! Compute triangle vertices
92  self%T0(1) = x0 + self%tau
93  self%T0(2) = y0
94  self%T1(1) = x0 - self%tau*0.5_wp
95  self%T1(2) = y0 + self%tau*0.5_wp*sqrt(3.0_wp)
96  self%T2(1) = x0 - self%tau*0.5_wp
97  self%T2(2) = y0 - self%tau*0.5_wp*sqrt(3.0_wp)
98 
99  end associate
100 
101  ! Initialize new basis functions as 2D splines
102  call self%N0%init(spline_basis_eta1, spline_basis_eta2)
103  call self%N1%init(spline_basis_eta1, spline_basis_eta2)
104  call self%N2%init(spline_basis_eta1, spline_basis_eta2)
105 
106  ! Set to zero all coefficients
107  self%N0%bcoef(1:nb1, 1:nb2) = 0.0_wp
108  self%N1%bcoef(1:nb1, 1:nb2) = 0.0_wp
109  self%N2%bcoef(1:nb1, 1:nb2) = 0.0_wp
110 
111  ! Set coefficients e_0j (i=1)
112  self%N0%bcoef(1, 1:nb2) = 1.0_wp/3.0_wp
113  self%N1%bcoef(1, 1:nb2) = 1.0_wp/3.0_wp
114  self%N2%bcoef(1, 1:nb2) = 1.0_wp/3.0_wp
115 
116  ! Set coefficients e_1j (i=2)
117  associate(c_x1 => mapping%spline_2d_x1%bcoef(2, 1:nb2), &
118  c_x2 => mapping%spline_2d_x2%bcoef(2, 1:nb2))
119 
120  self%N0%bcoef(2, 1:nb2) = self%eval_l0(c_x1, c_x2)
121  self%N1%bcoef(2, 1:nb2) = self%eval_l1(c_x1, c_x2)
122  self%N2%bcoef(2, 1:nb2) = self%eval_l2(c_x1, c_x2)
123 
124  end associate
125 
126  end subroutine s_polar_bsplines_2d__init
127 
128  !-----------------------------------------------------------------------------
129  sll_pure elemental function f_polar_bsplines_2d__eval_l0(self, x, y) result(l0)
130  class(sll_t_polar_bsplines_2d), intent(in) :: self
131  real(wp), intent(in) :: x
132  real(wp), intent(in) :: y
133  real(wp) :: l0
134 
135  associate(x0 => self%pole(1), y0 => self%pole(2), tau => self%tau)
136 
137  l0 = 1.0_wp/3.0_wp + 2.0_wp*(x - x0)/(3.0_wp*tau)
138 
139  end associate
140 
141  end function f_polar_bsplines_2d__eval_l0
142 
143  !-----------------------------------------------------------------------------
144  sll_pure elemental function f_polar_bsplines_2d__eval_l1(self, x, y) result(l1)
145  class(sll_t_polar_bsplines_2d), intent(in) :: self
146  real(wp), intent(in) :: x
147  real(wp), intent(in) :: y
148  real(wp) :: l1
149 
150  associate(x0 => self%pole(1), y0 => self%pole(2), tau => self%tau)
151 
152  l1 = 1.0_wp/3.0_wp - (x - x0)/(3.0_wp*tau) + (y - y0)/(sqrt(3.0_wp)*tau)
153 
154  end associate
155 
156  end function f_polar_bsplines_2d__eval_l1
157 
158  !-----------------------------------------------------------------------------
159  sll_pure elemental function f_polar_bsplines_2d__eval_l2(self, x, y) result(l2)
160  class(sll_t_polar_bsplines_2d), intent(in) :: self
161  real(wp), intent(in) :: x
162  real(wp), intent(in) :: y
163  real(wp) :: l2
164 
165  associate(x0 => self%pole(1), y0 => self%pole(2), tau => self%tau)
166 
167  l2 = 1.0_wp/3.0_wp - (x - x0)/(3.0_wp*tau) - (y - y0)/(sqrt(3.0_wp)*tau)
168 
169  end associate
170 
171  end function f_polar_bsplines_2d__eval_l2
172 
173  !-----------------------------------------------------------------------------
174  subroutine s_polar_bsplines_2d__free(self)
175  class(sll_t_polar_bsplines_2d), intent(inout) :: self
176 
177  call self%N0%free()
178  call self%N1%free()
179  call self%N2%free()
180 
181  end subroutine s_polar_bsplines_2d__free
182 
183 end module sll_m_polar_bsplines_2d
Abstract class for B-splines of arbitrary degree.
subroutine s_polar_bsplines_2d__free(self)
integer, parameter wp
Working precision.
subroutine s_polar_bsplines_2d__init(self, spline_basis_eta1, spline_basis_eta2, mapping)
Module for tensor-product 2D splines.
Module to select the kind parameter.
integer, parameter, public f64
f64 is the kind type for 64-bit reals (double precision)
Type containing new 2D polar basis functions.
2D tensor-product spline
    Report Typos and Errors