Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_fekete_integration.F90
Go to the documentation of this file.
1 
10 
11 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 #include "sll_memory.h"
13 #include "sll_working_precision.h"
14 
15  use sll_m_hexagonal_meshes, only: &
19 
20  use sll_m_box_splines, only: &
23 
24  implicit none
25 
26  public :: &
31 
32  private
33 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
34 
35 #ifndef DOXYGEN_SHOULD_SKIP_THIS
36  abstract interface
37 
38  function function_2d(x, y)
39  use sll_m_working_precision ! can't pass a header file because the
40  ! preprocessor prevents double inclusion.
41  ! This is very rare.
42  sll_real64 :: function_2d
43  sll_real64, intent(in) :: x
44  sll_real64, intent(in) :: y
45  end function function_2d
46  end interface
47 #endif
48 
49 contains
50 
51  !--------------------------------------------------------------------
61  subroutine fekete_degree(rule, degree)
62  sll_int32, intent(in) :: rule
63  sll_int32, intent(out) :: degree
64 
65  if (rule == 1) then
66  degree = 3
67  else if (rule == 2) then
68  degree = 6
69  else if (rule == 3) then
70  degree = 9
71  else if (rule == 4) then
72  degree = 12
73  else if (rule == 5) then
74  degree = 12
75  else if (rule == 6) then
76  degree = 15
77  else if (rule == 7) then
78  degree = 18
79  else
80  degree = -1
81  print *, ""
82  print *, "In fekete_degree(): Fatal error"
83  print *, " Illegal RULE = ", rule
84  stop
85  end if
86  end subroutine fekete_degree
87 
88  !----------------------------------------------------------------------
99  subroutine sll_s_fekete_order_num(rule, order_num)
100  sll_int32, intent(in) :: rule
101  sll_int32, intent(out) :: order_num
102  sll_int32, allocatable, dimension(:) :: suborder
103  sll_int32 :: suborder_num
104  sll_int32 :: ierr
105 
106  call fekete_suborder_num(rule, suborder_num)
107 
108  sll_allocate(suborder(1:suborder_num), ierr)
109 
110  call fekete_suborder(rule, suborder_num, suborder)
111 
112  order_num = sum(suborder(1:suborder_num))
113 
114  sll_deallocate_array(suborder, ierr)
115  end subroutine sll_s_fekete_order_num
116 
117  !---------------------------------------------------------------------------
125  subroutine fekete_rule(rule, order_num, xy, w)
126  sll_int32, intent(in) :: rule
127  sll_int32, intent(in) :: order_num
128  sll_real64, intent(out) :: w(order_num)
129  sll_real64, intent(out) :: xy(2, order_num)
130  sll_int32, allocatable, dimension(:) :: suborder
131  sll_real64, allocatable, dimension(:) :: suborder_w
132  sll_real64, allocatable, dimension(:, :) :: suborder_xyz
133  sll_int32 :: suborder_num
134  sll_int32 :: k
135  sll_int32 :: o
136  sll_int32 :: s
137  sll_int32 :: ierr
138 
139  ! Get the suborder information.
140  call fekete_suborder_num(rule, suborder_num)
141 
142  sll_allocate(suborder(suborder_num), ierr)
143  sll_allocate(suborder_xyz(3, suborder_num), ierr)
144  sll_allocate(suborder_w(suborder_num), ierr)
145 
146  call fekete_suborder(rule, suborder_num, suborder)
147 
148  call fekete_subrule(rule, suborder_num, suborder_xyz, suborder_w)
149 
150  ! Expand the suborder information to a full order rule.
151  o = 0
152  do s = 1, suborder_num
153  if (suborder(s) == 1) then
154  o = o + 1
155  xy(1:2, o) = suborder_xyz(1:2, s)
156  w(o) = suborder_w(s)
157  else if (suborder(s) == 3) then
158  do k = 1, 3
159  o = o + 1
160  xy(1, o) = suborder_xyz(wrapping(k, 1, 3), s)
161  xy(2, o) = suborder_xyz(wrapping(k + 1, 1, 3), s)
162  w(o) = suborder_w(s)
163  end do
164  else if (suborder(s) == 6) then
165  do k = 1, 3
166  o = o + 1
167  xy(1, o) = suborder_xyz(wrapping(k, 1, 3), s)
168  xy(2, o) = suborder_xyz(wrapping(k + 1, 1, 3), s)
169  w(o) = suborder_w(s)
170  end do
171  do k = 1, 3
172  o = o + 1
173  xy(1, o) = suborder_xyz(wrapping(k + 1, 1, 3), s)
174  xy(2, o) = suborder_xyz(wrapping(k, 1, 3), s)
175  w(o) = suborder_w(s)
176  end do
177  else
178  print *, ""
179  print *, 'FEKETE_RULE - Fatal error!'
180  print *, ' Illegal SUBORDER(', s, ') = ', suborder(s)
181  stop
182  end if
183  end do
184 
185  sll_deallocate_array(suborder, ierr)
186  sll_deallocate_array(suborder_xyz, ierr)
187  sll_deallocate_array(suborder_w, ierr)
188  end subroutine fekete_rule
189 
190  !---------------------------------------------------------------------------
196  subroutine rearrange_fekete_rule(n, xy, w)
197  sll_int32, intent(in) :: n
198  sll_real64, intent(out) :: xy(2, n)
199  sll_real64, intent(out) :: w(n)
200  sll_real64, dimension(3, n) :: xyw_copy
201  sll_int32 :: i
202  sll_int32 :: low_left
203  !sll_real64 :: min_x
204 
205  ! we start by making a copy of the points
206  xyw_copy(1:2, 1:n) = xy(1:2, 1:n)
207  xyw_copy(3, 1:n) = w(1:n)
208  ! now we arrange by the x-coordinate
209  do i = 1, n
210  low_left = minloc(xyw_copy(1, :), 1)
211  xy(1:2, i) = xyw_copy(1:2, low_left)
212  w(i) = xyw_copy(3, low_left)
213  ! We put a value that we know will never be the lower left point
214  ! as all points are between 0 and 1
215  xyw_copy(1:3, low_left) = 10000._f64
216  end do
217 
218  ! we copy again the points
219  xyw_copy(1:2, 1:n) = xy(1:2, 1:n)
220  xyw_copy(3, 1:n) = w(1:n)
221  ! now we arrange by the y-coordinate
222  do i = 1, n
223  low_left = minloc(xyw_copy(2, :), 1)
224  xy(1:2, i) = xyw_copy(1:2, low_left)
225  w(i) = xyw_copy(3, low_left)
226  ! We put a value that we know will never be the lower left point
227  ! as all points are between 0 and 1
228  xyw_copy(1:3, low_left) = 10000._f64
229  end do
230  end subroutine rearrange_fekete_rule
231 
232  !---------------------------------------------------------------------------
237  subroutine fekete_rule_num(rule_num)
238  sll_int32, intent(out) :: rule_num
239 
240  rule_num = 7
241  end subroutine fekete_rule_num
242 
243  !---------------------------------------------------------------------------
250  subroutine fekete_suborder(rule, suborder_num, suborder)
251  sll_int32, intent(in) :: suborder_num
252  sll_int32, intent(in) :: rule
253  sll_int32, intent(out) :: suborder(suborder_num)
254 
255  if (rule == 1) then
256  suborder(1:suborder_num) = (/ &
257  1, 3, 6/)
258  else if (rule == 2) then
259  suborder(1:suborder_num) = (/ &
260  1, 3, 3, 3, 6, 6, 6/)
261  else if (rule == 3) then
262  suborder(1:suborder_num) = (/ &
263  1, 3, 3, 3, 3, 6, 6, 6, 6, 6, &
264  6, 6/)
265  else if (rule == 4) then
266  suborder(1:suborder_num) = (/ &
267  1, 3, 3, 3, 3, 3, 3, 6, 6, 6, &
268  6, 6, 6, 6, 6, 6, 6, 6, 6/)
269  else if (rule == 5) then
270  suborder(1:suborder_num) = (/ &
271  1, 3, 3, 3, 3, 3, 3, 3, 3, 3, &
272  3, 6, 6, 6, 6, 6, 6, 6, 6, 6, &
273  6/)
274  else if (rule == 6) then
275  suborder(1:suborder_num) = (/ &
276  1, 3, 3, 3, 3, 3, 3, 3, 3, 3, &
277  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, &
278  6, 6, 6, 6, 6, 6, 6, 6/)
279  else if (rule == 7) then
280  suborder(1:suborder_num) = (/ &
281  1, 3, 3, 3, 3, 3, 3, 3, 3, 3, &
282  3, 3, 6, 6, 6, 6, 6, 6, 6, 6, &
283  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, &
284  6, 6, 6, 6, 6, 6, 6, 6/)
285  else
286  print *, ""
287  print *, 'FEKETE_SUBORDER - Fatal error!'
288  write (*, '(a,i8)') ' Illegal RULE = ', rule
289  stop
290  end if
291  end subroutine fekete_suborder
292 
293  !---------------------------------------------------------------------------
299  subroutine fekete_suborder_num(rule, suborder_num)
300  sll_int32, intent(in) :: rule
301  sll_int32, intent(out) :: suborder_num
302 
303  if (rule == 1) then
304  suborder_num = 3
305  else if (rule == 2) then
306  suborder_num = 7
307  else if (rule == 3) then
308  suborder_num = 12
309  else if (rule == 4) then
310  suborder_num = 19
311  else if (rule == 5) then
312  suborder_num = 21
313  else if (rule == 6) then
314  suborder_num = 28
315  else if (rule == 7) then
316  suborder_num = 38
317  else
318  suborder_num = -1
319  print *, ""
320  print *, 'FEKETE_SUBORDER_NUM - Fatal error!'
321  write (*, '(a,i8)') ' Illegal RULE = ', rule
322  stop
323  end if
324  end subroutine fekete_suborder_num
325 
326  !---------------------------------------------------------------------------
339  subroutine fekete_subrule(rule, suborder_num, suborder_xyz, suborder_w)
340  sll_int32, intent(in) :: suborder_num
341  sll_int32, intent(in) :: rule
342  sll_real64, intent(out) :: suborder_w(suborder_num)
343  sll_real64, intent(out) :: suborder_xyz(3, suborder_num)
344  sll_int32 :: s
345 
346  if (rule == 1) then
347  suborder_xyz(1:3, 1:suborder_num) = reshape((/ &
348  1._f64/3._f64, 1._f64/3._f64, 1._f64/3._f64, &
349  1.0000000000_f64, 0.0000000000_f64, 0.0000000000_f64, &
350  0.0000000000_f64, 0.2763932023_f64, 0.7236067977_f64 &
351  /), (/3, suborder_num/))
352 
353  suborder_w(1:suborder_num) = (/ &
354  0.9000000000_f64, &
355  0.0333333333_f64, &
356  0.1666666667_f64/)
357 
358  else if (rule == 2) then
359 
360  suborder_xyz(1:3, 1:suborder_num) = reshape((/ &
361  1._f64/3._f64, 1._f64/3._f64, 0.3333333334_f64, &
362  0.1063354684_f64, 0.1063354684_f64, 0.7873290632_f64, &
363  0.5000000000_f64, 0.5000000000_f64, 0.0000000000_f64, &
364  1.0000000000_f64, 0.0000000000_f64, 0.0000000000_f64, &
365  0.1171809171_f64, 0.3162697959_f64, 0.5665492870_f64, &
366  0.0000000000_f64, 0.2655651402_f64, 0.7344348598_f64, &
367  0.0000000000_f64, 0.0848854223_f64, 0.9151145777_f64 &
368  /), (/3, suborder_num/))
369 
370  suborder_w(1:suborder_num) = (/ &
371  0.2178563571_f64, &
372  0.1104193374_f64, &
373  0.0358939762_f64, &
374  0.0004021278_f64, &
375  0.1771348660_f64, &
376  0.0272344079_f64, &
377  0.0192969460_f64/)
378 
379  else if (rule == 3) then
380 
381  suborder_xyz(1:3, 1:suborder_num) = reshape((/ &
382  1._f64/3._f64, 1._f64/3._f64, 0.3333333334_f64, &
383  0.1704318201_f64, 0.1704318201_f64, 0.6591363598_f64, &
384  0.0600824712_f64, 0.4699587644_f64, 0.4699587644_f64, &
385  0.0489345696_f64, 0.0489345696_f64, 0.9021308608_f64, &
386  0.0000000000_f64, 0.0000000000_f64, 1.0000000000_f64, &
387  0.1784337588_f64, 0.3252434900_f64, 0.4963227512_f64, &
388  0.0588564879_f64, 0.3010242110_f64, 0.6401193011_f64, &
389  0.0551758079_f64, 0.1543901944_f64, 0.7904339977_f64, &
390  0.0000000000_f64, 0.4173602935_f64, 0.5826397065_f64, &
391  0.0000000000_f64, 0.2610371960_f64, 0.7389628040_f64, &
392  0.0000000000_f64, 0.1306129092_f64, 0.8693870908_f64, &
393  0.0000000000_f64, 0.0402330070_f64, 0.9597669930_f64 &
394  /), (/3, suborder_num/))
395 
396  suborder_w(1:suborder_num) = (/ &
397  0.1096011288_f64, &
398  0.0767491008_f64, &
399  0.0646677819_f64, &
400  0.0276211659_f64, &
401  0.0013925011_f64, &
402  0.0933486453_f64, &
403  0.0619010169_f64, &
404  0.0437466450_f64, &
405  0.0114553907_f64, &
406  0.0093115568_f64, &
407  0.0078421987_f64, &
408  0.0022457501_f64/)
409 
410  else if (rule == 4) then
411 
412  suborder_xyz(1:3, 1:suborder_num) = reshape((/ &
413  1._f64/3._f64, 1._f64/3._f64, 0.3333333334_f64, &
414  0.1988883477_f64, 0.4005558262_f64, 0.4005558261_f64, &
415  0.2618405201_f64, 0.2618405201_f64, 0.4763189598_f64, &
416  0.0807386775_f64, 0.0807386775_f64, 0.8385226450_f64, &
417  0.0336975736_f64, 0.0336975736_f64, 0.9326048528_f64, &
418  0.0000000000_f64, 0.5000000000_f64, 0.5000000000_f64, &
419  0.0000000000_f64, 0.0000000000_f64, 1.0000000000_f64, &
420  0.1089969290_f64, 0.3837518758_f64, 0.5072511952_f64, &
421  0.1590834479_f64, 0.2454317980_f64, 0.5954847541_f64, &
422  0.0887037176_f64, 0.1697134458_f64, 0.7415828366_f64, &
423  0.0302317829_f64, 0.4071849276_f64, 0.5625832895_f64, &
424  0.0748751152_f64, 0.2874821712_f64, 0.6376427136_f64, &
425  0.0250122615_f64, 0.2489279690_f64, 0.7260597695_f64, &
426  0.0262645218_f64, 0.1206826354_f64, 0.8530528428_f64, &
427  0.0000000000_f64, 0.3753565349_f64, 0.6246434651_f64, &
428  0.0000000000_f64, 0.2585450895_f64, 0.7414549105_f64, &
429  0.0000000000_f64, 0.1569057655_f64, 0.8430942345_f64, &
430  0.0000000000_f64, 0.0768262177_f64, 0.9231737823_f64, &
431  0.0000000000_f64, 0.0233450767_f64, 0.9766549233_f64 &
432  /), (/3, suborder_num/))
433 
434  suborder_w(1:suborder_num) = (/ &
435  0.0626245179_f64, &
436  0.0571359417_f64, &
437  0.0545982307_f64, &
438  0.0172630326_f64, &
439  0.0142519606_f64, &
440  0.0030868485_f64, &
441  0.0004270742_f64, &
442  0.0455876390_f64, &
443  0.0496701966_f64, &
444  0.0387998322_f64, &
445  0.0335323983_f64, &
446  0.0268431561_f64, &
447  0.0237377452_f64, &
448  0.0177255972_f64, &
449  0.0043097313_f64, &
450  0.0028258057_f64, &
451  0.0030994935_f64, &
452  0.0023829062_f64, &
453  0.0009998683_f64/)
454 
455  else if (rule == 5) then
456 
457  suborder_xyz(1:3, 1:suborder_num) = reshape((/ &
458  1._f64/3._f64, 1._f64/3._f64, 0.3333333334_f64, &
459  0.2201371125_f64, 0.3169406831_f64, 0.4629222044_f64, &
460  0.2201371125_f64, 0.4629222044_f64, 0.3169406831_f64, &
461  0.1877171129_f64, 0.1877171129_f64, 0.6245657742_f64, &
462  0.1403402144_f64, 0.4298298928_f64, 0.4298298928_f64, &
463  0.0833252778_f64, 0.0833252778_f64, 0.8333494444_f64, &
464  0.0664674598_f64, 0.0252297247_f64, 0.9083028155_f64, &
465  0.0218884020_f64, 0.4890557990_f64, 0.4890557990_f64, &
466  0.0252297247_f64, 0.0664674598_f64, 0.9083028155_f64, &
467  0.0000000000_f64, 0.5000000000_f64, 0.5000000000_f64, &
468  0.0000000000_f64, 0.0000000000_f64, 1.0000000000_f64, &
469  0.1157463404_f64, 0.2842319093_f64, 0.6000217503_f64, &
470  0.0672850606_f64, 0.3971764400_f64, 0.5355384994_f64, &
471  0.0909839531_f64, 0.1779000668_f64, 0.7311159801_f64, &
472  0.0318311633_f64, 0.3025963402_f64, 0.6655724965_f64, &
473  0.0273518579_f64, 0.1733665506_f64, 0.7992815915_f64, &
474  0.0000000000_f64, 0.3753565349_f64, 0.6246434651_f64, &
475  0.0000000000_f64, 0.2585450895_f64, 0.7414549105_f64, &
476  0.0000000000_f64, 0.1569057655_f64, 0.8430942345_f64, &
477  0.0000000000_f64, 0.0768262177_f64, 0.9231737823_f64, &
478  0.0000000000_f64, 0.0233450767_f64, 0.9766549233_f64 &
479  /), (/3, suborder_num/))
480 
481  suborder_w(1:suborder_num) = (/ &
482  0.0485965670_f64, &
483  0.0602711576_f64, &
484  0.0602711576_f64, &
485  0.0476929767_f64, &
486  0.0453940802_f64, &
487  0.0258019417_f64, &
488  0.0122004614_f64, &
489  0.0230003812_f64, &
490  0.0122004614_f64, &
491  0.0018106475_f64, &
492  -0.0006601747_f64, &
493  0.0455413513_f64, &
494  0.0334182802_f64, &
495  0.0324896773_f64, &
496  0.0299402736_f64, &
497  0.0233477738_f64, &
498  0.0065962854_f64, &
499  0.0021485117_f64, &
500  0.0034785755_f64, &
501  0.0013990566_f64, &
502  0.0028825748_f64/)
503 
504  else if (rule == 6) then
505 
506  suborder_xyz(1:3, 1:suborder_num) = reshape((/ &
507  1._f64/3._f64, 1._f64/3._f64, 0.3333333334_f64, &
508  0.2379370518_f64, 0.3270403780_f64, 0.4350225702_f64, &
509  0.3270403780_f64, 0.2379370518_f64, 0.4350225702_f64, &
510  0.1586078048_f64, 0.4206960976_f64, 0.4206960976_f64, &
511  0.2260541354_f64, 0.2260541354_f64, 0.5478917292_f64, &
512  0.1186657611_f64, 0.1186657611_f64, 0.7626684778_f64, &
513  0.0477095725_f64, 0.4761452137_f64, 0.4761452138_f64, &
514  0.0531173538_f64, 0.0531173538_f64, 0.8937652924_f64, &
515  0.0219495841_f64, 0.0219495841_f64, 0.9561008318_f64, &
516  0.0000000000_f64, 0.0000000000_f64, 1.0000000000_f64, &
517  0.1585345951_f64, 0.3013819154_f64, 0.5400834895_f64, &
518  0.0972525649_f64, 0.3853507643_f64, 0.5173966708_f64, &
519  0.0875150140_f64, 0.2749910734_f64, 0.6374939126_f64, &
520  0.1339547708_f64, 0.1975591066_f64, 0.6684861226_f64, &
521  0.0475622627_f64, 0.3524012205_f64, 0.6000365168_f64, &
522  0.0596194677_f64, 0.1978887556_f64, 0.7424917767_f64, &
523  0.0534939782_f64, 0.1162464503_f64, 0.8302595715_f64, &
524  0.0157189888_f64, 0.4176001732_f64, 0.5666808380_f64, &
525  0.0196887324_f64, 0.2844332752_f64, 0.6958779924_f64, &
526  0.0180698489_f64, 0.1759511193_f64, 0.8059790318_f64, &
527  0.0171941515_f64, 0.0816639421_f64, 0.9011419064_f64, &
528  0.0000000000_f64, 0.4493368632_f64, 0.5506631368_f64, &
529  0.0000000000_f64, 0.3500847655_f64, 0.6499152345_f64, &
530  0.0000000000_f64, 0.2569702891_f64, 0.7430297109_f64, &
531  0.0000000000_f64, 0.1738056486_f64, 0.8261943514_f64, &
532  0.0000000000_f64, 0.1039958541_f64, 0.8960041459_f64, &
533  0.0000000000_f64, 0.0503997335_f64, 0.9496002665_f64, &
534  0.0000000000_f64, 0.0152159769_f64, 0.9847840231_f64 &
535  /), (/3, suborder_num/))
536 
537  suborder_w(1:suborder_num) = (/ &
538  0.0459710878_f64, &
539  0.0346650571_f64, &
540  0.0346650571_f64, &
541  0.0384470625_f64, &
542  0.0386013566_f64, &
543  0.0224308157_f64, &
544  0.0243531004_f64, &
545  0.0094392654_f64, &
546  0.0061105652_f64, &
547  0.0001283162_f64, &
548  0.0305412307_f64, &
549  0.0262101254_f64, &
550  0.0265367617_f64, &
551  0.0269859772_f64, &
552  0.0172635676_f64, &
553  0.0188795851_f64, &
554  0.0158224870_f64, &
555  0.0127170850_f64, &
556  0.0164489660_f64, &
557  0.0120018620_f64, &
558  0.0072268907_f64, &
559  0.0023599161_f64, &
560  0.0017624674_f64, &
561  0.0018648017_f64, &
562  0.0012975716_f64, &
563  0.0018506035_f64, &
564  0.0009919379_f64, &
565  0.0004893506_f64/)
566 
567  else if (rule == 7) then
568 
569  suborder_xyz(1:3, 1:suborder_num) = reshape((/ &
570  1._f64/3._f64, 1._f64/3._f64, 0.3333333334_f64, &
571  0.2515553103_f64, 0.3292984162_f64, 0.4191462735_f64, &
572  0.3292984162_f64, 0.2515553103_f64, 0.4191462735_f64, &
573  0.1801930996_f64, 0.4099034502_f64, 0.4099034502_f64, &
574  0.2438647767_f64, 0.2438647767_f64, 0.5122704466_f64, &
575  0.1512564554_f64, 0.1512564554_f64, 0.6974870892_f64, &
576  0.0810689493_f64, 0.4594655253_f64, 0.4594655254_f64, &
577  0.0832757649_f64, 0.0832757649_f64, 0.8334484702_f64, &
578  0.0369065587_f64, 0.0369065587_f64, 0.9261868826_f64, &
579  0.0149574850_f64, 0.0149574850_f64, 0.9700850300_f64, &
580  0.0000000000_f64, 0.5000000000_f64, 0.5000000000_f64, &
581  0.0000000000_f64, 0.0000000000_f64, 1.0000000000_f64, &
582  0.1821465920_f64, 0.3095465041_f64, 0.5083069039_f64, &
583  0.1246901255_f64, 0.3789288931_f64, 0.4963809814_f64, &
584  0.1179441386_f64, 0.2868915642_f64, 0.5951642972_f64, &
585  0.1639418454_f64, 0.2204868669_f64, 0.6155712877_f64, &
586  0.0742549663_f64, 0.3532533654_f64, 0.5724916683_f64, &
587  0.0937816771_f64, 0.2191980979_f64, 0.6870202250_f64, &
588  0.0890951387_f64, 0.1446273457_f64, 0.7662775156_f64, &
589  0.0409065243_f64, 0.4360543636_f64, 0.5230391121_f64, &
590  0.0488675890_f64, 0.2795984854_f64, 0.6715339256_f64, &
591  0.0460342127_f64, 0.2034211147_f64, 0.7505446726_f64, &
592  0.0420687187_f64, 0.1359040280_f64, 0.8220272533_f64, &
593  0.0116377940_f64, 0.4336892286_f64, 0.5546729774_f64, &
594  0.0299062187_f64, 0.3585587824_f64, 0.6115349989_f64, &
595  0.0132313129_f64, 0.2968103667_f64, 0.6899583204_f64, &
596  0.0136098469_f64, 0.2050279257_f64, 0.7813622274_f64, &
597  0.0124869684_f64, 0.1232146223_f64, 0.8642984093_f64, &
598  0.0365197797_f64, 0.0805854893_f64, 0.8828947310_f64, &
599  0.0118637765_f64, 0.0554881302_f64, 0.9326480933_f64, &
600  0.0000000000_f64, 0.4154069883_f64, 0.5845930117_f64, &
601  0.0000000000_f64, 0.3332475761_f64, 0.6667524239_f64, &
602  0.0000000000_f64, 0.2558853572_f64, 0.7441146428_f64, &
603  0.0000000000_f64, 0.1855459314_f64, 0.8144540686_f64, &
604  0.0000000000_f64, 0.1242528987_f64, 0.8757471013_f64, &
605  0.0000000000_f64, 0.0737697111_f64, 0.9262302889_f64, &
606  0.0000000000_f64, 0.0355492359_f64, 0.9644507641_f64, &
607  0.0000000000_f64, 0.0106941169_f64, 0.9893058831_f64 &
608  /), (/3, suborder_num/))
609 
610  suborder_w(1:suborder_num) = (/ &
611  0.0326079297_f64, &
612  0.0255331366_f64, &
613  0.0255331366_f64, &
614  0.0288093886_f64, &
615  0.0279490452_f64, &
616  0.0174438045_f64, &
617  0.0203594338_f64, &
618  0.0113349170_f64, &
619  0.0046614185_f64, &
620  0.0030346239_f64, &
621  0.0012508731_f64, &
622  0.0000782945_f64, &
623  0.0235716330_f64, &
624  0.0206304700_f64, &
625  0.0204028340_f64, &
626  0.0215105697_f64, &
627  0.0183482070_f64, &
628  0.0174161032_f64, &
629  0.0155972434_f64, &
630  0.0119269616_f64, &
631  0.0147074804_f64, &
632  0.0116182830_f64, &
633  0.0087639138_f64, &
634  0.0098563528_f64, &
635  0.0096342355_f64, &
636  0.0086477936_f64, &
637  0.0083868302_f64, &
638  0.0062576643_f64, &
639  0.0077839825_f64, &
640  0.0031415239_f64, &
641  0.0006513246_f64, &
642  0.0021137942_f64, &
643  0.0004393452_f64, &
644  0.0013662119_f64, &
645  0.0003331251_f64, &
646  0.0011613225_f64, &
647  0.0004342867_f64, &
648  0.0002031499_f64/)
649  else
650  print *, ""
651  print *, 'FEKETE_SUBRULE - Fatal error!'
652  write (*, '(a,i8)') ' Illegal RULE = ', rule
653  stop
654  end if
655 
656  ! The listed weights are twice what we want!.
657  do s = 1, suborder_num
658  suborder_w(s) = 0.5_f64*suborder_w(s)
659  end do
660  end subroutine fekete_subrule
661 
662  !---------------------------------------------------------
691  function wrapping(ival, ilo, ihi) result(res)
692  sll_int32, intent(in) :: ihi
693  sll_int32, intent(in) :: ilo
694  sll_int32, intent(in) :: ival
695  sll_int32 :: jhi
696  sll_int32 :: jlo
697  sll_int32 :: res
698  sll_int32 :: wide
699 
700  jlo = min(ilo, ihi)
701  jhi = max(ilo, ihi)
702 
703  wide = jhi - jlo + 1
704 
705  if (wide == 1) then
706  res = jlo
707  else
708  res = jlo + modulo(ival - jlo, wide)
709  end if
710  end function wrapping
711 
712  !---------------------------------------------------------------------------
748  subroutine reference_to_physical_t3(node_xy, n, ref, phy)
749  sll_int32, intent(in) :: n
750  sll_real64, intent(in) :: node_xy(2, 3)
751  sll_real64, intent(in) :: ref(2, n)
752  sll_real64, dimension(2, n), intent(out) :: phy
753  sll_int32 :: i
754 
755  do i = 1, 2
756  phy(i, 1:n) = node_xy(i, 1)*(1.0_f64 - ref(1, 1:n) - ref(2, 1:n)) &
757  + node_xy(i, 2)*ref(1, 1:n) &
758  + node_xy(i, 3)*ref(2, 1:n)
759  end do
760  end subroutine reference_to_physical_t3
761 
762  !---------------------------------------------------------
775  function sll_f_fekete_points_and_weights(node_xy2, rule) result(xyw)
776  sll_real64, dimension(2, 3), intent(in) :: node_xy2
777  sll_int32, intent(in) :: rule
778  !sll_int32 :: order
779  sll_int32 :: order_num
780  sll_int32 :: ierr
781  sll_real64, allocatable :: xy(:, :)
782  sll_real64, allocatable :: xy2(:, :)
783  sll_real64, allocatable :: w(:)
784  sll_real64, allocatable :: xyw(:, :)
785 
786  call sll_s_fekete_order_num(rule, order_num)
787 
788  sll_allocate(xy(1:2, 1:order_num), ierr)
789  sll_allocate(xy2(1:2, 1:order_num), ierr)
790  sll_allocate(w(1:order_num), ierr)
791  sll_allocate(xyw(1:3, 1:order_num), ierr)
792 
793  call fekete_rule(rule, order_num, xy, w)
794  call rearrange_fekete_rule(order_num, xy, w)
795  xyw(3, :) = w
796 
797  call reference_to_physical_t3(node_xy2, order_num, xy, xy2)
798  xyw(1:2, :) = xy2
799 
800  sll_deallocate_array(xy, ierr)
801  sll_deallocate_array(xy2, ierr)
802  sll_deallocate_array(w, ierr)
803 
805 
806  !---------------------------------------------------------------------------
816  function sll_f_fekete_integral(f, pxy)
817  sll_real64, dimension(2, 3), intent(in) :: pxy
818  sll_real64 :: sll_f_fekete_integral
819  procedure(function_2d) :: f
820  sll_real64, dimension(3, 10) :: xyw
821  sll_real64, dimension(2) :: v1
822  sll_real64, dimension(2) :: v2
823  sll_real64, dimension(2) :: v3
824  sll_real64 :: a
825  sll_real64 :: b
826  sll_real64 :: c
827  sll_real64 :: p
828  sll_real64 :: area
829  sll_int32 :: k
830  sll_int32 :: n
831 
832  ! Initialiting the fekete points and weigths ......
833  xyw(:, :) = 0._f64
834  xyw = sll_f_fekete_points_and_weights(pxy, 1)
835 
836  n = 10
837  sll_f_fekete_integral = 0._f64
838  do k = 1, n
839  sll_f_fekete_integral = sll_f_fekete_integral + f(xyw(1, k), xyw(2, k))*xyw(3, k)
840  end do
841 
842  ! Computing the area of the triangle
843  ! v1 = Vector(p1, p2)
844  v1(1) = pxy(1, 2) - pxy(1, 1)
845  v1(2) = pxy(2, 2) - pxy(2, 1)
846  a = sqrt(v1(1)*v1(1) + v1(2)*v1(2))
847  ! v2 = Vector(p1, p3)
848  v2(1) = pxy(1, 3) - pxy(1, 1)
849  v2(2) = pxy(2, 3) - pxy(2, 1)
850  b = sqrt(v2(1)*v2(1) + v2(2)*v2(2))
851  ! v3 = Vector(p2, p3)
852  v3(1) = pxy(1, 3) - pxy(1, 2)
853  v3(2) = pxy(2, 3) - pxy(2, 2)
854  c = sqrt(v3(1)*v3(1) + v3(2)*v3(2))
855  ! Computing demi-perimeter
856  p = 0.5_f64*(a + b + c)
857  ! area
858  area = sqrt(p*(p - a)*(p - b)*(p - c))
859 
861  end function sll_f_fekete_integral
862 
863  subroutine triangle_area(node_xy, area)
864  implicit none
865 
866  sll_real64 :: area
867  sll_real64 :: node_xy(2, 3)
868 
869  area = 0.5_f64*( &
870  node_xy(1, 1)*(node_xy(2, 2) - node_xy(2, 3)) &
871  + node_xy(1, 2)*(node_xy(2, 3) - node_xy(2, 1)) &
872  + node_xy(1, 3)*(node_xy(2, 1) - node_xy(2, 2)))
873 
874  return
875  end subroutine triangle_area
876 
877  !---------------------------------------------------------------------------
884  subroutine write_quadrature(rule)
885  sll_int32, intent(in) :: rule
886  sll_int32 :: out_unit
887  character(len=25), parameter :: name = "boxsplines_quadrature.txt"
888  sll_real64, dimension(2, 3) :: ref_pts
889  sll_real64, dimension(:, :), allocatable :: quad_pw
890  sll_int32 :: num_fek
891  sll_int32 :: i
892  sll_real64 :: x
893  sll_real64 :: y
894  sll_real64 :: w
895  sll_real64 :: volume
896  sll_int32 :: ierr
897  ! Definition of reference triangle, such that:
898  ! |
899  ! 1 3
900  ! | | \
901  ! | | \
902  ! | | X 2
903  ! | | /
904  ! | | /
905  ! 0 1
906  ! |
907  ! +--0-----1-->
908  ref_pts(:, 1) = (/0._f64, 0.0_f64/)
909  ! ref_pts(:,2) = (/ 1._f64, 0.0_f64 /)
910  ref_pts(:, 2) = (/sqrt(3._f64)*0.5_f64, 0.5_f64/)
911  ref_pts(:, 3) = (/0._f64, 1.0_f64/)
912 
913  call triangle_area(ref_pts, volume)
914  print *, "area triangle = ", volume
915 
916  ! Computing fekete points on that triangle
917  call sll_s_fekete_order_num(rule, num_fek)
918  sll_allocate(quad_pw(1:3, 1:num_fek), ierr)
919  quad_pw = sll_f_fekete_points_and_weights(ref_pts, rule)
920  ! For Gaussian quadrature rule:
921  ! num_fek = rule + 1
922  ! SLL_ALLOCATE(quad_pw(1:3, 1:num_fek), ierr)
923  ! quad_pw = gauss_triangle_points_and_weights(ref_pts, rule)
924 
925  open (file=name, status="replace", form="formatted", newunit=out_unit)
926 
927  write (out_unit, "(i6)") num_fek
928 
929  do i = 1, num_fek
930  x = quad_pw(1, i)
931  y = quad_pw(2, i)
932  w = quad_pw(3, i)*volume
933  write (out_unit, "(2(g25.17,a,1x),(g25.17))") x, ",", y, ",", w
934  end do
935  close (out_unit)
936  end subroutine write_quadrature
937 
938  !---------------------------------------------------------------------------
945  subroutine write_basis_values(deg, rule)
946  sll_int32, intent(in) :: deg
947  sll_int32, intent(in) :: rule
948  sll_real64, dimension(2, 3) :: ref_pts
949  sll_real64, dimension(:, :), allocatable :: quad_pw
950  sll_real64, dimension(:, :), allocatable :: disp_vec
951  sll_int32, parameter :: out_unit = 20
952  character(len=*), parameter :: name = "boxsplines_basis_values.txt"
953  sll_real64 :: x
954  sll_real64 :: y
955  sll_real64 :: val
956  sll_int32 :: ierr
957  sll_int32 :: nonzero
958  sll_int32 :: ind_nz
959  sll_int32 :: nderiv
960  sll_int32 :: idx, idy
961  sll_int32 :: num_fek
962  sll_int32 :: ind_fek
963  ! Definition of reference triangle, such that:
964  ! |
965  ! 1 3
966  ! | | \
967  ! | | \
968  ! | | \
969  ! | | \
970  ! | | _____\
971  ! 0 1 2
972  ! |
973  ! +--0-----1-->
974  ref_pts(:, 1) = (/0._f64, 0.0_f64/)
975  ! ref_pts(:,2) = (/ 1._f64, 0.0_f64 /)
976  ref_pts(:, 2) = (/sqrt(3._f64)/2._f64, 0.5_f64/)
977  ref_pts(:, 3) = (/0._f64, 1.0_f64/)
978 
979  ! Computing fekete points on the reference triangle
980  call sll_s_fekete_order_num(rule, num_fek)
981  sll_allocate(quad_pw(1:3, 1:num_fek), ierr)
982  quad_pw = sll_f_fekete_points_and_weights(ref_pts, rule)
983  ! ! For Gaussian qudrature:
984  ! num_fek = rule + 1
985  ! SLL_ALLOCATE(quad_pw(1:3, 1:num_fek), ierr)
986  ! quad_pw = gauss_triangle_points_and_weights(ref_pts, rule)
987 
988  nonzero = 3*deg*deg
989  nderiv = 1
990 
993  sll_allocate(disp_vec(2, nonzero), ierr)
994  disp_vec(:, 1) = 0._f64
995  disp_vec(:, 2) = ref_pts(:, 1) - ref_pts(:, 2)
996  disp_vec(:, 3) = ref_pts(:, 1) - ref_pts(:, 3)
997 
998  open (unit=out_unit, file=name, action="write", status="replace")
999 
1000  write (out_unit, "(i6)") deg
1001  write (out_unit, "(i6)") nderiv
1002 
1003  do ind_nz = 1, nonzero
1004  do ind_fek = 1, num_fek
1005  x = quad_pw(1, ind_fek) + disp_vec(1, ind_nz)
1006  y = quad_pw(2, ind_fek) + disp_vec(2, ind_nz)
1007  do idx = 0, nderiv
1008  do idy = 0, nderiv - idx
1009  val = sll_f_boxspline_val_der(x, y, deg, idx, idy)
1010  write (out_unit, "(1(g25.18))", advance='no') val
1011  if ((idx < nderiv) .or. (idy < nderiv - idx)) then
1012  write (out_unit, "(1(a,1x))", advance='no') ","
1013  end if
1014  end do
1015  end do
1016  write (out_unit, *) ""
1017  end do
1018  end do
1019 
1020  close (out_unit)
1021  sll_deallocate_array(disp_vec, ierr)
1022  sll_deallocate_array(quad_pw, ierr)
1023 
1024  end subroutine write_basis_values
1025 
1032  subroutine sll_s_write_all_django_files(num_cells, deg, rule, transf)
1033  sll_int32, intent(in) :: num_cells
1034  sll_int32, intent(in) :: deg
1035  sll_int32, intent(in) :: rule
1036  type(sll_t_hex_mesh_2d), pointer :: mesh
1037  character(len=*), intent(in) :: transf
1038 
1039  mesh => sll_f_new_hex_mesh_2d(num_cells, 0._f64, 0._f64, radius=1._f64)
1040 
1041  call sll_s_write_caid_files(mesh, transf, deg)
1042  call sll_s_write_connectivity(mesh, deg)
1043  call write_basis_values(deg, rule)
1044  call write_quadrature(rule)
1045 #ifdef DEBUG
1046  print *, 'sll_s_write_all_django_files rule=', rule
1047 #endif
1048 
1049  end subroutine sll_s_write_all_django_files
1050 
1051 end module sll_m_fekete_integration
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.
Fekete quadrature rules for a triangle.
integer(kind=i32) function wrapping(ival, ilo, ihi)
forces an I4 to lie between given limits by wrapping.
subroutine, public sll_s_fekete_order_num(rule, order_num)
returns the order of a Fekete rule for the triangle.
subroutine fekete_rule(rule, order_num, xy, w)
returns the points and weights of a Fekete rule.
subroutine triangle_area(node_xy, area)
subroutine fekete_rule_num(rule_num)
returns the number of Fekete rules available.
subroutine reference_to_physical_t3(node_xy, n, ref, phy)
maps T3 reference points to physical points.
subroutine fekete_subrule(rule, suborder_num, suborder_xyz, suborder_w)
returns a compressed Fekete rule
real(kind=f64) function, public sll_f_fekete_integral(f, pxy)
Fekete quadrature rule over a triangle.
subroutine fekete_suborder_num(rule, suborder_num)
returns the number of suborders for a Fekete rule.
subroutine rearrange_fekete_rule(n, xy, w)
Re arranges the order of the quadrature point to go from lower-left to top right.
subroutine fekete_suborder(rule, suborder_num, suborder)
returns the suborders for a Fekete rule.
subroutine write_basis_values(deg, rule)
Writes on a file values of boxsplines on fekete points.
subroutine write_quadrature(rule)
Writes fekete points coordinates of a hex-mesh reference triangle.
subroutine, public sll_s_write_all_django_files(num_cells, deg, rule, transf)
This function is supposed to write all django input files needed for a Django/Jorek simulation.
real(kind=f64) function, dimension(:, :), allocatable, public sll_f_fekete_points_and_weights(node_xy2, rule)
Gives the fekete points coordinates and associated weights for a certain rule in a given triangle.
subroutine fekete_degree(rule, degree)
returns the degree of a Fekete rule for the triangle.
subroutine, public sll_s_write_caid_files(mesh, transf, spline_deg)
Writes files for CAID.
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.
Module to select the kind parameter.
    Report Typos and Errors