Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_scalar_field_2d.F90
Go to the documentation of this file.
1 
5 
6 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 #include "sll_assert.h"
8 #include "sll_errors.h"
9 #include "sll_memory.h"
10 #include "sll_working_precision.h"
11 
12  use sll_m_cartesian_meshes, only: &
14 
17 
18  use sll_m_gnuplot, only: &
20 
21  use sll_m_interpolators_2d_base, only: &
23 
24  use sll_m_scalar_field_2d_base, only: &
26 
27  use sll_m_utilities, only: &
30 
31  use sll_m_xdmf, only: &
33 
34  implicit none
35 
36  public :: &
39  sll_o_delete, &
44 
45  private
46 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
47 
49 
50  private
51  type(sll_t_cartesian_mesh_2d), pointer :: mesh
52  procedure(sll_i_two_var_parametrizable_function), pointer, nopass :: func
53  procedure(sll_i_two_var_parametrizable_function), pointer, nopass :: first_deriv_eta1
54  procedure(sll_i_two_var_parametrizable_function), pointer, nopass :: first_deriv_eta2
55 
56  sll_real64, dimension(:), allocatable :: params
57  character(len=64) :: name
59 
60  sll_int32 :: bc1_min
61  sll_int32 :: bc1_max
62  sll_int32 :: bc2_min
63  sll_int32 :: bc2_max
64  logical :: present_deriv_eta1_int
65  logical :: present_deriv_eta2_int
66 
67  contains
68 
69  procedure, pass(field) :: init => initialize_scalar_field_2d_analytic
70  procedure, pass(field) :: get_transformation => get_transformation_analytic
71  procedure, pass(field) :: get_cartesian_mesh => get_cartesian_mesh_2d_analytic
72  procedure, pass(field) :: get_jacobian_matrix => get_jacobian_matrix_analytic
73  procedure, pass(field) :: value_at_point => value_at_pt_analytic
74  procedure, pass(field) :: value_at_indices => value_at_index_analytic
75  procedure, pass(field) :: first_deriv_eta1_value_at_point => &
77  procedure, pass(field) :: first_deriv_eta2_value_at_point => &
79  procedure, pass(field) :: first_deriv_eta1_value_at_indices => &
81  procedure, pass(field) :: first_deriv_eta2_value_at_indices => &
83  procedure, pass(field) :: set_field_data => set_field_data_analytic_2d
84  procedure, pass(field) :: update_interpolation_coefficients => &
86  procedure, pass(field) :: write_to_file => write_to_file_analytic_2d
87  procedure, pass(field) :: free => delete_field_2d_analytic
88 
90 
92 
93  type(sll_t_cartesian_mesh_2d), pointer :: mesh
94  sll_real64, dimension(:, :), pointer :: values => null()
95  logical :: owns_memory = .true.
96  character(len=64) :: name
97 
99  class(sll_c_interpolator_2d), pointer :: interp_2d
100 
101  sll_real64, dimension(:), pointer :: point1_1d
102  sll_real64, dimension(:), pointer :: point2_1d
103 
104  sll_int32 :: bc1_min
105  sll_int32 :: bc1_max
106  sll_int32 :: bc2_min
107  sll_int32 :: bc2_max
108 
109  contains
110 
111  procedure, pass(field) :: init => initialize_scalar_field_2d_discrete
112  procedure, pass(field) :: update_interpolation_coefficients => &
114  procedure, pass(field) :: get_transformation => get_transformation_discrete
115  procedure, pass(field) :: get_cartesian_mesh => get_cartesian_mesh_2d_discrete
116  procedure, pass(field) :: get_jacobian_matrix => get_jacobian_matrix_discrete
117  procedure, pass(field) :: value_at_point => value_at_pt_discrete
118  procedure, pass(field) :: value_at_indices => value_at_index_discrete
119  procedure, pass(field) :: first_deriv_eta1_value_at_point => &
121  procedure, pass(field) :: first_deriv_eta2_value_at_point => &
123  procedure, pass(field) :: first_deriv_eta1_value_at_indices => &
125  procedure, pass(field) :: first_deriv_eta2_value_at_indices => &
127  procedure, pass(field) :: set_field_data => set_field_data_discrete_2d
128  procedure, pass(field) :: free_internal_data_copy => free_data_discrete_2d
129  procedure, pass(field) :: reset_data_pointer => reset_ptr_discrete_2d
130  procedure, pass(field) :: get_data_pointer => get_data_ptr_discrete_2d
131  procedure, pass(field) :: write_to_file => write_to_file_discrete_2d
132  procedure, pass(field) :: free => delete_field_2d_discrete
133 
135 
137  type(sll_t_scalar_field_2d_discrete), pointer :: f
139 
140  abstract interface
141 
142  function sll_i_two_var_parametrizable_function(eta1, eta2, params)
145  sll_real64, intent(in) :: eta1
146  sll_real64, intent(in) :: eta2
147  sll_real64, dimension(:), intent(in) :: params
149 
150  end interface
151 
152  abstract interface
153 
154  function scalar_function_2d(eta1, eta2)
156  sll_real64 :: scalar_function_2d
157  sll_real64, intent(in) :: eta1
158  sll_real64, intent(in) :: eta2
159  end function scalar_function_2d
160 
161  end interface
162 
163  interface sll_o_delete
165  end interface sll_o_delete
166 
167 contains
168 
169 ! **************************************************************************
170 !
171 ! ANALYTIC CASE
172 !
173 ! **************************************************************************
174 
175  function value_at_pt_analytic(field, eta1, eta2)
176 
177  class(sll_t_scalar_field_2d_analytic), intent(in) :: field
178  sll_real64, intent(in) :: eta1
179  sll_real64, intent(in) :: eta2
180  sll_real64 :: value_at_pt_analytic
181 
182  value_at_pt_analytic = field%func(eta1, eta2, field%params)
183 
184  end function value_at_pt_analytic
185 
186  function value_at_index_analytic(field, i, j)
187 
188  class(sll_t_scalar_field_2d_analytic), intent(in) :: field
189  sll_int32, intent(in) :: i
190  sll_int32, intent(in) :: j
191  type(sll_t_cartesian_mesh_2d), pointer :: lm
192  sll_real64 :: eta1
193  sll_real64 :: eta2
194  sll_real64 :: value_at_index_analytic
195 
196  lm => field%T%mesh
197  eta1 = lm%eta1_min + (i - 1)*lm%delta_eta1
198  eta2 = lm%eta2_min + (j - 1)*lm%delta_eta2
199  value_at_index_analytic = field%func(eta1, eta2, field%params)
200 
201  end function value_at_index_analytic
202 
203  function first_deriv_eta1_value_at_pt_analytic(field, eta1, eta2)
204 
205  class(sll_t_scalar_field_2d_analytic), intent(in) :: field
206  sll_real64, intent(in) :: eta1
207  sll_real64, intent(in) :: eta2
208 
210 
211  character(len=128) :: err_msg
212  character(len=*), parameter :: this_fun_name = &
213  'first_deriv_eta1_value_at_pt_analytic'
214 
215  if (field%present_deriv_eta1_int) then
217  field%first_deriv_eta1(eta1, eta2, field%params)
218  else
220  err_msg = "In "//field%name// &
221  ": first derivative in eta1 not given in the initialization."
222  sll_error(this_fun_name, err_msg)
223  end if
224 
226 
227  function first_deriv_eta2_value_at_pt_analytic(field, eta1, eta2)
228 
229  class(sll_t_scalar_field_2d_analytic), intent(in) :: field
230  sll_real64, intent(in) :: eta1
231  sll_real64, intent(in) :: eta2
232 
234 
235  character(len=128) :: err_msg
236  character(len=*), parameter :: this_fun_name = &
237  'first_deriv_eta2_value_at_pt_analytic'
238 
239  if (field%present_deriv_eta2_int) then
241  field%first_deriv_eta2(eta1, eta2, field%params)
242  else
244  err_msg = "In "//field%name// &
245  ": first derivative in eta2 &
246  & not given in the initialization."
247  sll_error(this_fun_name, err_msg)
248  end if
249 
251 
253 
254  class(sll_t_scalar_field_2d_analytic), intent(in) :: field
255  sll_int32, intent(in) :: i
256  sll_int32, intent(in) :: j
257  sll_real64 :: eta1
258  sll_real64 :: eta2
259  type(sll_t_cartesian_mesh_2d), pointer :: lm
260 
262 
263  lm => field%T%mesh
264  eta1 = lm%eta1_min + real(i - 1, f64)*lm%delta_eta1
265  eta2 = lm%eta2_min + real(j - 1, f64)*lm%delta_eta2
266 
267  if (field%present_deriv_eta1_int) then
269  field%first_deriv_eta1(eta1, eta2, field%params)
270  else
272  print *, field%name, &
273  'first_deriv_eta1_value_at_index_analytic(): ERROR, ', &
274  'first derivative in eta1 is not given in the initialization'
275  end if
276 
278 
280 
281  class(sll_t_scalar_field_2d_analytic), intent(in) :: field
282  sll_int32, intent(in) :: i
283  sll_int32, intent(in) :: j
284  sll_real64 :: eta1
285  sll_real64 :: eta2
286  type(sll_t_cartesian_mesh_2d), pointer :: lm
287 
289 
290  lm => field%T%mesh
291  eta1 = lm%eta1_min + real(i - 1, f64)*lm%delta_eta1
292  eta2 = lm%eta2_min + real(j - 1, f64)*lm%delta_eta2
293 
294  if (field%present_deriv_eta2_int) then
296  field%first_deriv_eta2(eta1, eta2, field%params)
297  else
298  print *, ' first derivative in eta2 is not given in the initialization'
299  end if
300 
302 
304  field_name, &
305  transformation, &
306  bc1_min, &
307  bc1_max, &
308  bc2_min, &
309  bc2_max, &
310  func_params, &
311  first_deriv_eta1, &
312  first_deriv_eta2) result(obj)
313 
314  type(sll_t_scalar_field_2d_analytic), pointer :: obj
315  procedure(sll_i_two_var_parametrizable_function) :: func
316  character(len=*), intent(in) :: field_name
317  class(sll_c_coordinate_transformation_2d_base), target :: transformation
318  sll_int32, intent(in) :: bc1_min
319  sll_int32, intent(in) :: bc1_max
320  sll_int32, intent(in) :: bc2_min
321  sll_int32, intent(in) :: bc2_max
322  sll_real64, dimension(:), intent(in) :: func_params
323  procedure(sll_i_two_var_parametrizable_function), optional :: first_deriv_eta1
324  procedure(sll_i_two_var_parametrizable_function), optional :: first_deriv_eta2
325  sll_int32 :: ierr
326 
327  sll_warning("sll_f_new_scalar_field_2d_analytic", "This function is deprecated, use init subroutine instead")
328  sll_allocate(obj, ierr)
329 
330  call obj%init(func, &
331  & field_name, &
332  & transformation, &
333  & bc1_min, &
334  & bc1_max, &
335  & bc2_min, &
336  & bc2_max, &
337  & func_params, &
338  & first_deriv_eta1, &
339  & first_deriv_eta2)
340 
342 
343  subroutine set_field_data_analytic_2d(field, values)
344 
345  class(sll_t_scalar_field_2d_analytic), intent(inout) :: field
346  sll_real64, dimension(:, :), intent(in) :: values
347 
348  print *, 'WARNING: set_field_data_analytic_2d(): it is useless to ', &
349  'call this function on an analytic scalar field.'
350  sll_assert(associated(field%mesh))
351  sll_assert(size(values, 1) > 0)
352 
353  end subroutine set_field_data_analytic_2d
354 
356 
357  class(sll_t_scalar_field_2d_analytic), intent(inout) :: field
358  print *, 'WARNING: update_interpolation_coefficients_2d_analytic(): ', &
359  ' it is useless to call this function on an analytic scalar field.'
360  sll_assert(associated(field%mesh))
361 
363 
364  subroutine delete_field_2d_analytic(field)
365 
366  class(sll_t_scalar_field_2d_analytic), intent(inout) :: field
367 ! nothing internal do deallocate, just nullify pointers. Can't call
368 ! delete on them because the field does not 'own' these data.
369  if (associated(field%func)) nullify (field%func)
370  if (associated(field%T)) nullify (field%T)
371  if (allocated(field%params)) deallocate (field%params)
372 
373  end subroutine delete_field_2d_analytic
374 
375 ! For those cases in which handling pointers to field structures is not
376 ! convenient, we offer the following initialization.
378  & func, &
379  & field_name, &
380  & transformation, &
381  & bc1_min, &
382  & bc1_max, &
383  & bc2_min, &
384  & bc2_max, &
385  & func_params, &
386  & first_deriv_eta1, &
387  & first_deriv_eta2)
388 
389  class(sll_t_scalar_field_2d_analytic), intent(out) :: field
390  procedure(sll_i_two_var_parametrizable_function) :: func
391  character(len=*), intent(in) :: field_name
392  class(sll_c_coordinate_transformation_2d_base), target :: transformation
393  sll_int32, intent(in) :: bc1_min
394  sll_int32, intent(in) :: bc1_max
395  sll_int32, intent(in) :: bc2_min
396  sll_int32, intent(in) :: bc2_max
397  sll_real64, dimension(:), intent(in) :: func_params
398  procedure(sll_i_two_var_parametrizable_function), optional :: first_deriv_eta1
399  procedure(sll_i_two_var_parametrizable_function), optional :: first_deriv_eta2
400  sll_int32 :: ierr
401 
402  sll_allocate(field%params(size(func_params)), ierr)
403 
404  field%params(:) = func_params
405  field%T => transformation
406  field%func => func
407  field%name = trim(field_name)
408  field%bc1_min = bc1_min
409  field%bc1_max = bc1_max
410  field%bc2_min = bc2_min
411  field%bc2_max = bc2_max
412 
413  if (present(first_deriv_eta1)) then
414  field%first_deriv_eta1 => first_deriv_eta1
415  field%present_deriv_eta1_int = .true.
416  end if
417  if (present(first_deriv_eta2)) then
418  field%first_deriv_eta2 => first_deriv_eta2
419  field%present_deriv_eta2_int = .true.
420  end if
421 
423 
424 ! The following pair of subroutines are tricky. We want them as general
425 ! services by the fields, hence we need this subroutine interface, yet
426 ! we would also like a flexibility in how the derivatives are computed.
427 ! A general interpolator interface would cover most of the cases, maybe
428 ! all. It could be that a finite difference scheme would also work, if
429 ! we ignore some of the interpolator services, like the ability to return
430 ! values anywhere instead of at the nodes.
431 ! For now, this interface would permit to have multiple implementations.
432 !!$ subroutine compute_eta1_derivative_on_col( field2d, ith_col, deriv_out )
433 !!$ type(scalar_field_2d), intent(in) :: field2d
434 !!$ sll_int32, intent(in) :: ith_col
435 !!$ sll_real64, dimension(:),intent(out) :: deriv_out
436 !!$ end subroutine compute_eta1_derivative_on_col
437 
438  function get_transformation_analytic(field) result(res)
439 
440  class(sll_t_scalar_field_2d_analytic), intent(in) :: field
441  class(sll_c_coordinate_transformation_2d_base), pointer :: res
442  res => field%T
443 
444  end function get_transformation_analytic
445 
446  function get_cartesian_mesh_2d_analytic(field) result(res)
447 
448  class(sll_t_scalar_field_2d_analytic), intent(in) :: field
449  class(sll_t_cartesian_mesh_2d), pointer :: res
450  res => field%T%get_cartesian_mesh()
451 
452  end function get_cartesian_mesh_2d_analytic
453 
454  function get_jacobian_matrix_analytic(field, eta1, eta2) result(res)
455 
456  class(sll_t_scalar_field_2d_analytic), intent(in) :: field
457  sll_real64, intent(in) :: eta1
458  sll_real64, intent(in) :: eta2
459  sll_real64, dimension(2, 2) :: res
460  res = (field%T%jacobian_matrix(eta1, eta2))
461 
462  end function get_jacobian_matrix_analytic
463 
464  subroutine write_to_file_analytic_2d(field, tag)
465 
466  class(sll_t_scalar_field_2d_analytic), intent(in) :: field
467  sll_int32, intent(in) :: tag
468  sll_int32 :: nptsx1
469  sll_int32 :: nptsx2
470  sll_real64, dimension(:, :), allocatable :: x1coords
471  sll_real64, dimension(:, :), allocatable :: x2coords
472  sll_real64, dimension(:, :), allocatable :: values
473  sll_real64 :: eta1
474  sll_real64 :: eta2
475  class(sll_c_coordinate_transformation_2d_base), pointer :: T
476  class(sll_t_cartesian_mesh_2d), pointer :: mesh
477  sll_int32 :: i
478  sll_int32 :: j
479  sll_int32 :: ierr
480 
481 ! use the logical mesh information to find out the extent of the
482 ! domain and allocate the arrays for the plotter.
483  t => field%get_transformation()
484  mesh => field%get_cartesian_mesh()
485  nptsx1 = mesh%num_cells1 + 1
486  nptsx2 = mesh%num_cells2 + 1
487  sll_allocate(x1coords(nptsx1, nptsx2), ierr)
488  sll_allocate(x2coords(nptsx1, nptsx2), ierr)
489  sll_allocate(values(nptsx1, nptsx2), ierr)
490 
491 ! Fill the arrays with the needed information.
492  do j = 1, nptsx2
493  eta2 = mesh%eta2_min + (j - 1)*mesh%delta_eta2
494  do i = 1, nptsx1
495  eta1 = mesh%eta1_min + (i - 1)*mesh%delta_eta1
496  x1coords(i, j) = t%x1(eta1, eta2)
497  x2coords(i, j) = t%x2(eta1, eta2)
498  values(i, j) = field%value_at_point(eta1, eta2)
499  end do
500  end do
501 
502  call sll_o_gnuplot_2d(nptsx1, &
503  & nptsx2, &
504  & x1coords, &
505  & x2coords, &
506  & values, &
507  & trim(field%name), &
508  & tag, &
509  & ierr)
510 
511  sll_deallocate_array(x1coords, ierr)
512  sll_deallocate_array(x2coords, ierr)
513  sll_deallocate_array(values, ierr)
514 
515  end subroutine write_to_file_analytic_2d
516 
517 ! **************************************************************************
518 !
519 ! DISCRETE CASE
520 !
521 ! **************************************************************************
522 
523  function sll_f_new_scalar_field_2d_discrete(field_name, &
524  interpolator_2d, &
525  transformation, &
526  bc1_min, &
527  bc1_max, &
528  bc2_min, &
529  bc2_max, &
530  point1_1d, &
531  sz_point1, &
532  point2_1d, &
533  sz_point2) result(obj)
534 
535  type(sll_t_scalar_field_2d_discrete), pointer :: obj
536  character(len=*), intent(in) :: field_name
537  class(sll_c_interpolator_2d), target :: interpolator_2d
538  class(sll_c_coordinate_transformation_2d_base) :: transformation
539  sll_int32, intent(in) :: bc1_min
540  sll_int32, intent(in) :: bc1_max
541  sll_int32, intent(in) :: bc2_min
542  sll_int32, intent(in) :: bc2_max
543  sll_real64, dimension(:), optional :: point1_1d
544  sll_real64, dimension(:), optional :: point2_1d
545  sll_int32, optional :: sz_point1
546  sll_int32, optional :: sz_point2
547  sll_int32 :: ierr
548 
549  sll_warning("sll_f_new_scalar_field_2d_discrete", "is deprectated, use init subroutine instead")
550 
551  sll_allocate(obj, ierr)
552 
553  call obj%init(field_name, &
554  interpolator_2d, &
555  transformation, &
556  bc1_min, &
557  bc1_max, &
558  bc2_min, &
559  bc2_max, &
560  point1_1d, &
561  sz_point1, &
562  point2_1d, &
563  sz_point2)
564 
566 
568  & field_name, &
569  & interpolator_2d, &
570  & transformation, &
571  & bc1_min, &
572  & bc1_max, &
573  & bc2_min, &
574  & bc2_max, &
575  & point1_1d, &
576  & sz_point1, &
577  & point2_1d, &
578  & sz_point2)
579 
580  class(sll_t_scalar_field_2d_discrete), intent(inout) :: field
581  character(len=*), intent(in) :: field_name
582  class(sll_c_interpolator_2d), target :: interpolator_2d
583  class(sll_c_coordinate_transformation_2d_base), target :: transformation
584  sll_int32, intent(in) :: bc1_min
585  sll_int32, intent(in) :: bc1_max
586  sll_int32, intent(in) :: bc2_min
587  sll_int32, intent(in) :: bc2_max
588  sll_real64, dimension(:), optional :: point1_1d
589  sll_real64, dimension(:), optional :: point2_1d
590  sll_int32, optional :: sz_point1
591  sll_int32, optional :: sz_point2
592 
593  sll_int32 :: num_cells1
594  sll_int32 :: num_cells2
595  sll_int32 :: ierr
596 
597  field%T => transformation
598 
599  field%interp_2d => interpolator_2d
600 
601  field%name = trim(field_name)
602  field%bc1_min = bc1_min
603  field%bc1_max = bc1_max
604  field%bc2_min = bc2_min
605  field%bc2_max = bc2_max
606 
607  num_cells1 = transformation%mesh%num_cells1
608  num_cells2 = transformation%mesh%num_cells2
609 
610 ! Allocate internal array to store locally a copy of the data.
611  sll_allocate(field%values(num_cells1 + 1, num_cells2 + 1), ierr)
612 
613  return
614  sll_assert(present(point1_1d))
615  sll_assert(present(point2_1d))
616  sll_assert(present(sz_point1))
617  sll_assert(present(sz_point2))
618 
620 
621 ! need to do something about deallocating the field proper, when allocated
622 ! in the heap...
623  subroutine delete_field_2d_discrete(field)
624  class(sll_t_scalar_field_2d_discrete), intent(inout) :: field
625  sll_int32 :: ierr
626  if (field%owns_memory) then
627  if (associated(field%values)) sll_deallocate(field%values, ierr)
628  end if
629  if (associated(field%T)) nullify (field%T)
630  if (associated(field%interp_2d)) nullify (field%interp_2d)
631  if (associated(field%point1_1d)) nullify (field%point1_1d)
632  if (associated(field%point2_1d)) nullify (field%point2_1d)
633  end subroutine delete_field_2d_discrete
634 
635  subroutine set_field_data_discrete_2d(field, values)
636  class(sll_t_scalar_field_2d_discrete), intent(inout) :: field
637  sll_real64, dimension(:, :), intent(in) :: values
638  class(sll_t_cartesian_mesh_2d), pointer :: m
639 
640  m => field%get_cartesian_mesh()
641  if ((size(values, 1) < m%num_cells1) .or. &
642  (size(values, 2) < m%num_cells2)) then
643  print *, 'WARNING, set_field_data_discrete_2d(), passed array ', &
644  'is smaller than the size of data originally declared for ', &
645  'this field. Size of values in first dimension:', size(values, 1), &
646  ' Size of mesh: ', m%num_cells1, ' Size of values in second ', &
647  'dimension:', size(values, 2), 'Size of mesh: ', m%num_cells2
648  end if
649  field%values(:, :) = values(:, :)
650  end subroutine set_field_data_discrete_2d
651 
652 ! There is a bit of background history to the existence of the
653 ! free_data_discrete_2d() and reset_ptr_discrete_2d() routines. By request
654 ! of a user, the default behavior of the field is to manage its own copy
655 ! of the data. Thus upon creation, the object allocates the necessary
656 ! memory to store nodal values. However, it may be desired that the object
657 ! DOES NOT manage its own memory, but rather that it only points to some
658 ! external block of memory. To permit the change of the behavior of the
659 ! field from its default, is the role of these functions. The first
660 ! deallocates the memory and sets the flag which indicates that the field
661 ! no longer owns its memory. The second permits to reset the data pointer
662 ! to whatever is desired.
663  subroutine free_data_discrete_2d(field)
664  class(sll_t_scalar_field_2d_discrete), intent(inout) :: field
665  sll_int32 :: ierr
666 
667  if (.not. associated(field%values)) then
668  print *, 'ERROR, free_data_discrete_2d(): the internal copy of the ', &
669  'data has been already freed or never allocated.'
670  end if
671  sll_deallocate(field%values, ierr)
672  field%owns_memory = .false.
673  end subroutine free_data_discrete_2d
674 
675  subroutine reset_ptr_discrete_2d(field, values)
676  class(sll_t_scalar_field_2d_discrete), intent(inout) :: field
677  sll_real64, dimension(:, :), target :: values
678  if (field%owns_memory .eqv. .true.) then
679  print *, 'ERROR, reset_ptr_discrete_2d(): the data pointer can not ', &
680  'be reset without a previous call to free_internal_data_copy().', &
681  'This object is not being used properly. A memory leak has ', &
682  'occurred. Continue at your peril.'
683  end if
684  field%values => values
685  end subroutine reset_ptr_discrete_2d
686 
687  function get_data_ptr_discrete_2d(field) result(ptr)
688 
689  sll_real64, dimension(:, :), pointer :: ptr
690  class(sll_t_scalar_field_2d_discrete), intent(inout) :: field
691  sll_assert(associated(field%values))
692 
693  ptr => field%values
694 
695  end function get_data_ptr_discrete_2d
696 
698  class(sll_t_scalar_field_2d_discrete), intent(inout) :: field
699  call field%interp_2d%compute_interpolants(field%values)
700  end subroutine update_interp_coeffs_2d_discrete
701 
702  function get_transformation_discrete(field) result(res)
703 
704  class(sll_t_scalar_field_2d_discrete), intent(in) :: field
705  class(sll_c_coordinate_transformation_2d_base), pointer :: res
706 
707  res => field%T
708 
709  end function get_transformation_discrete
710 
711  function get_cartesian_mesh_2d_discrete(field) result(res)
712 
713  class(sll_t_scalar_field_2d_discrete), intent(in) :: field
714  class(sll_t_cartesian_mesh_2d), pointer :: res
715  class(sll_c_coordinate_transformation_2d_base), pointer :: transf
716 
717  transf => field%T
718  res => transf%get_cartesian_mesh()
719 
720  end function get_cartesian_mesh_2d_discrete
721 
722  function get_jacobian_matrix_discrete(field, eta1, eta2) result(res)
723 
724  class(sll_t_scalar_field_2d_discrete), intent(in) :: field
725  sll_real64, intent(in) :: eta1
726  sll_real64, intent(in) :: eta2
727  sll_real64, dimension(2, 2) :: res
728 
729  res(:, :) = field%T%jacobian_matrix(eta1, eta2)
730 
731  end function get_jacobian_matrix_discrete
732 
733  function value_at_pt_discrete(field, eta1, eta2)
734 
735  class(sll_t_scalar_field_2d_discrete), intent(in) :: field
736  sll_real64, intent(in) :: eta1
737  sll_real64, intent(in) :: eta2
738  sll_real64 :: value_at_pt_discrete
739 
740  value_at_pt_discrete = field%interp_2d%interpolate_from_interpolant_value(eta1, eta2)
741 
742  end function value_at_pt_discrete
743 
744  function value_at_index_discrete(field, i, j)
745  class(sll_t_scalar_field_2d_discrete), intent(in) :: field
746  sll_int32, intent(in) :: i
747  sll_int32, intent(in) :: j
748  sll_real64 :: eta1
749  sll_real64 :: eta2
750  class(sll_t_cartesian_mesh_2d), pointer :: lm
751  sll_real64 :: value_at_index_discrete
752 
753  lm => field%get_cartesian_mesh()
754  eta1 = lm%eta1_min + real(i - 1, f64)*lm%delta_eta1
755  eta2 = lm%eta2_min + real(j - 1, f64)*lm%delta_eta2
756  value_at_index_discrete = field%interp_2d%interpolate_from_interpolant_value(eta1, eta2)
757  end function value_at_index_discrete
758 
759  function first_deriv_eta1_value_at_pt_discrete(field, eta1, eta2)
760  class(sll_t_scalar_field_2d_discrete), intent(in) :: field
761  sll_real64, intent(in) :: eta1
762  sll_real64, intent(in) :: eta2
764 
766  field%interp_2d%interpolate_from_interpolant_derivative_eta1(eta1, eta2)
768 
769  function first_deriv_eta2_value_at_pt_discrete(field, eta1, eta2)
770  class(sll_t_scalar_field_2d_discrete), intent(in) :: field
771  sll_real64, intent(in) :: eta1
772  sll_real64, intent(in) :: eta2
774 
776  field%interp_2d%interpolate_from_interpolant_derivative_eta2(eta1, eta2)
778 
780  class(sll_t_scalar_field_2d_discrete), intent(in) :: field
781  sll_int32, intent(in) :: i
782  sll_int32, intent(in) :: j
783  sll_real64 :: eta1
784  sll_real64 :: eta2
785  class(sll_t_cartesian_mesh_2d), pointer :: lm
787 
788  lm => field%get_cartesian_mesh()
789  eta1 = lm%eta1_min + real(i - 1, f64)*lm%delta_eta1
790  eta2 = lm%eta2_min + real(j - 1, f64)*lm%delta_eta2
792  field%interp_2d%interpolate_from_interpolant_derivative_eta1(eta1, eta2)
793 
795 
797  class(sll_t_scalar_field_2d_discrete), intent(in) :: field
798  sll_int32, intent(in) :: i
799  sll_int32, intent(in) :: j
800  sll_real64 :: eta1
801  sll_real64 :: eta2
802  class(sll_t_cartesian_mesh_2d), pointer :: lm
804 
805  lm => field%get_cartesian_mesh()
806  eta1 = lm%eta1_min + real(i - 1, f64)*lm%delta_eta1
807  eta2 = lm%eta2_min + real(j - 1, f64)*lm%delta_eta2
809  field%interp_2d%interpolate_from_interpolant_derivative_eta2(eta1, eta2)
811 
812  subroutine write_to_file_discrete_2d(field, tag)
813 
814  class(sll_t_scalar_field_2d_discrete), intent(in) :: field
815  sll_int32, intent(in) :: tag
816  sll_int32 :: nptsx1
817  sll_int32 :: nptsx2
818  sll_real64, dimension(:, :), allocatable :: x1coords
819  sll_real64, dimension(:, :), allocatable :: x2coords
820  sll_real64, dimension(:, :), allocatable :: values
821  sll_real64 :: eta1
822  sll_real64 :: eta2
823  class(sll_c_coordinate_transformation_2d_base), pointer :: T
824  class(sll_t_cartesian_mesh_2d), pointer :: mesh
825  sll_int32 :: i
826  sll_int32 :: j
827  sll_int32 :: ierr
828  character(len=4) :: ctag
829 
830 ! use the logical mesh information to find out the extent of the
831 ! domain and allocate the arrays for the plotter.
832  t => field%get_transformation()
833  mesh => field%get_cartesian_mesh()
834  nptsx1 = mesh%num_cells1 + 1
835  nptsx2 = mesh%num_cells2 + 1
836  sll_allocate(x1coords(nptsx1, nptsx2), ierr)
837  sll_allocate(x2coords(nptsx1, nptsx2), ierr)
838  sll_allocate(values(nptsx1, nptsx2), ierr)
839 
840 ! Fill the arrays with the needed information.
841  do j = 1, nptsx2
842  eta2 = mesh%eta2_min + (j - 1)*mesh%delta_eta2
843  do i = 1, nptsx1
844  eta1 = mesh%eta1_min + (i - 1)*mesh%delta_eta1
845  x1coords(i, j) = field%T%x1(eta1, eta2)
846  x2coords(i, j) = field%T%x2(eta1, eta2)
847  values(i, j) = field%value_at_point(eta1, eta2)
848  end do
849  end do
850 
851  call sll_o_gnuplot_2d(nptsx1, &
852  & nptsx2, &
853  & x1coords, &
854  & x2coords, &
855  & values, &
856  & trim(field%name), &
857  & tag, &
858  & ierr)
859 
860  call sll_s_int2string(tag, ctag)
861  call sll_s_xdmf_curv2d_nodes(trim(field%name)//ctag, &
862  values, "values", x1coords, x2coords, "HDF5")
863 
864  sll_deallocate_array(x1coords, ierr)
865  sll_deallocate_array(x2coords, ierr)
866  sll_deallocate_array(values, ierr)
867 
868  end subroutine write_to_file_discrete_2d
869 
870 end module sll_m_scalar_field_2d
Write file for gnuplot to display 2d field.
Cartesian mesh basic types.
Abstract class for coordinate transformations.
Implements the functions to write data file plotable by GNUplot.
abstract data type for 2d interpolation
Implements the field descriptor types.
subroutine write_to_file_discrete_2d(field, tag)
type(sll_t_scalar_field_2d_discrete) function, pointer, public sll_f_new_scalar_field_2d_discrete(field_name, interpolator_2d, transformation, bc1_min, bc1_max, bc2_min, bc2_max, point1_1d, sz_point1, point2_1d, sz_point2)
real(kind=f64) function first_deriv_eta2_value_at_pt_analytic(field, eta1, eta2)
function first_deriv_eta1_value_at_pt_discrete(field, eta1, eta2)
function first_deriv_eta2_value_at_pt_discrete(field, eta1, eta2)
type(sll_t_scalar_field_2d_analytic) function, pointer, public sll_f_new_scalar_field_2d_analytic(func, field_name, transformation, bc1_min, bc1_max, bc2_min, bc2_max, func_params, first_deriv_eta1, first_deriv_eta2)
subroutine update_interpolation_coefficients_2d_analytic(field)
class(sll_c_coordinate_transformation_2d_base) function, pointer get_transformation_analytic(field)
function first_deriv_eta1_value_at_index_discrete(field, i, j)
real(kind=f64) function value_at_index_analytic(field, i, j)
pointer get_data_ptr_discrete_2d(field)
subroutine initialize_scalar_field_2d_discrete(field, field_name, interpolator_2d, transformation, bc1_min, bc1_max, bc2_min, bc2_max, point1_1d, sz_point1, point2_1d, sz_point2)
subroutine delete_field_2d_analytic(field)
class(sll_c_coordinate_transformation_2d_base) function, pointer get_transformation_discrete(field)
subroutine set_field_data_discrete_2d(field, values)
real(kind=f64) function value_at_pt_analytic(field, eta1, eta2)
subroutine reset_ptr_discrete_2d(field, values)
subroutine initialize_scalar_field_2d_analytic(field, func, field_name, transformation, bc1_min, bc1_max, bc2_min, bc2_max, func_params, first_deriv_eta1, first_deriv_eta2)
function first_deriv_eta2_value_at_index_discrete(field, i, j)
real(kind=f64) function first_deriv_eta1_value_at_pt_analytic(field, eta1, eta2)
function value_at_pt_discrete(field, eta1, eta2)
subroutine delete_field_2d_discrete(field)
subroutine write_to_file_analytic_2d(field, tag)
real(kind=f64) function first_deriv_eta1_value_at_index_analytic(field, i, j)
class(sll_t_cartesian_mesh_2d) function, pointer get_cartesian_mesh_2d_discrete(field)
real(kind=f64) function first_deriv_eta2_value_at_index_analytic(field, i, j)
subroutine free_data_discrete_2d(field)
subroutine update_interp_coeffs_2d_discrete(field)
function value_at_index_discrete(field, i, j)
dimension(2, 2) get_jacobian_matrix_discrete(field, eta1, eta2)
dimension(2, 2) get_jacobian_matrix_analytic(field, eta1, eta2)
subroutine set_field_data_analytic_2d(field, values)
class(sll_t_cartesian_mesh_2d) function, pointer get_cartesian_mesh_2d_analytic(field)
Some common numerical utilities.
subroutine, public sll_s_int2string(istep, cstep)
Convert an integer < 9999 to a 4 characters string.
subroutine, public sll_s_new_file_id(file_id, error)
Get a file unit number free before creating a file.
Module to select the kind parameter.
Implements the functions to write xdmf file plotable by VisIt.
Definition: sll_m_xdmf.F90:24
subroutine, public sll_s_xdmf_curv2d_nodes(file_name, array, array_name, eta1, eta2, file_format, iplot)
Subroutine to write a 2D array in xdmf format. The field is describe on a cartesian mesh....
Definition: sll_m_xdmf.F90:635
Base class/basic interface for 2D interpolators.
    Report Typos and Errors