t_fBase Derived Type

type, public :: t_fBase


Inherited by

type~~t_fbase~~InheritedByGraph type~t_fbase t_fBase type~t_base t_base type~t_base->type~t_fbase f type~t_hmap_axisnb t_hmap_axisNB type~t_hmap_axisnb->type~t_fbase fb_hat type~t_newton_root1d_fdf_pest t_newton_Root1D_FdF_pest type~t_newton_root1d_fdf_pest->type~t_fbase LA_fbase_in type~t_newton_root2d_boozer t_newton_Root2D_boozer type~t_newton_root2d_boozer->type~t_fbase AB_fbase_in type~t_sfl_boozer t_sfl_boozer type~t_sfl_boozer->type~t_fbase nu_fbase type~t_transform_sfl t_transform_sfl type~t_transform_sfl->type~t_base X1sfl_base, X2sfl_base, GZ_base, GZsfl_base type~t_transform_sfl->type~t_sfl_boozer booz

Components

Type Visibility Attributes Name Initial
integer, public :: mn_max(2)

input parameter: maximum number of fourier modes: m_max=mn_max(1),n_max=mn_max(2)

integer, public :: mn_nyq(2)

number of equidistant integration points (trapezoidal rule) in m and n

integer, public :: mn_IP

=mn_nyq(1)*mn_nyq(2)

integer, public :: nfp

number of field periods (toroidal repetition after 2pi/nfp)

integer, public :: sin_cos

can be either only sine: SIN or only cosine COS or full: SINCOS

logical, public :: exclude_mn_zero

=true: exclude m=n=0 mode in the basis (only important if cos is in basis)

integer, public :: modes

total(global) number of modes in basis (depends if only sin/cos or sin & cos are used)

integer, public :: modes_str

local range of modes, when distributed over MPI subdomains

integer, public :: modes_end

local range of modes, when distributed over MPI subdomains

integer, public, ALLOCATABLE :: offset_modes(:)

allocated (0:nRanks), gives range on each rank: modes_str:modes_end=offset_modes(myRank)+1:offset_modes(myRank+1)

integer, public, ALLOCATABLE :: whichRank(:)

know the MPI rank for each mode

logical, public :: initialized = .FALSE.

set to true in init, set to false in free

integer, public :: sin_range(2)

sin_range(1)+1:sin_range(2) is range with sine bases

integer, public :: cos_range(2)

sin_range(1)+1:sin_range(2) is range with cosine bases

integer, public :: mn_zero_mode

points to m=0,n=0 mode in mode array (1:mn_modes) (only one can exist for cosine, else =-1)

real(kind=wp), public :: d_thet

integration weight in theta direction: =2pi/mn_nyq(1)

real(kind=wp), public :: d_zeta

integration weight in zeta direction : =nfp(2pi/nfp)/mn_nyq(2)=2pi/mn_nyq(2)

integer, public, ALLOCATABLE :: Xmn(:,:)

mode number (m,n*nfp) for each iMode=1,modes, size(2,modes)

integer, public, ALLOCATABLE :: zero_odd_even(:)

=0 for m=n=0 mode, =1 for m= odd mode, =2 for m=even mode size(modes)

real(kind=wp), public, ALLOCATABLE :: x_IP(:,:)

(theta,zeta)position of interpolation points theta [0,2pi]x[0,2pi/nfp]size(2,mn_IP)

real(kind=wp), public, ALLOCATABLE :: thet_IP(:)

1d theta position of interpolation points theta [0,2pi] size(mn_nyq(1))

real(kind=wp), public, ALLOCATABLE :: zeta_IP(:)

1d zeta position of interpolation points theta [0,2pi/nfp] size(mn_nyq(2))

real(kind=wp), public, ALLOCATABLE :: base_IP(:,:)

basis functions, size(1:mn_IP,1:modes)

real(kind=wp), public, ALLOCATABLE :: base_dthet_IP(:,:)

dthet derivative of basis functions, (1:mn_IP,1:modes)

real(kind=wp), public, ALLOCATABLE :: base_dzeta_IP(:,:)

dzeta derivative of basis functions, (1:mn_IP,1:modes)

real(kind=wp), public, ALLOCATABLE :: snorm_base(:)

1/norm of each basis function, size(1:modes), norm=int_0^2pi int_0^pi (base_mn(thet,zeta))^2 dthet dzeta

integer, public :: mTotal1D

mTotal1D =mn_max(1)+1 for sin or cos base, and mTotal=2*(mn_max(1)+1) for sin&cos base

real(kind=wp), public, ALLOCATABLE :: base1D_IPthet(:,:,:)

1D basis, size(1:mn_nyq(1),1:2,1:mTotal1D), if sin(m t-n z): sin(m t), -cos(m t) and if cos(m t-n z): cos(m t),sin(m t)

real(kind=wp), public, ALLOCATABLE :: base1D_dthet_IPthet(:,:,:)

derivative of 1D basis, size(1:mn_nyq(1),1:2,1:mTotal1D) if sin(m t-n z): m cos(m t),m sin(m t) and if cos(m t-n z): -m sin(m t),m cos(m t)

real(kind=wp), public, ALLOCATABLE :: base1D_IPzeta(:,:,:)

1D basis functions, size(1:2,-mn_max(2):mn_max(2),1:mn_nyq(2)) for sin/cos(m t-n z): cos(n z),sin(n z)

real(kind=wp), public, ALLOCATABLE :: base1D_dzeta_IPzeta(:,:,:)

derivative of 1D basis functions, size(1:2,-mn_max(2):mn_max(2),1:mn_nyq(2)) for sin/cos(m t-n z): -n sin(n z),n cos(n z)


Type-Bound Procedures

procedure, public :: init => fBase_init

  • private subroutine fBase_init(sf, mn_max_in, mn_nyq_in, nfp_in, sin_cos_in, exclude_mn_zero_in)

    initialize the type fBase maximum mode numbers, number of integration points, type of basis (sin/cos or sin and cos)

    Read more…

    Arguments

    Type IntentOptional Attributes Name
    class(t_fBase), intent(inout) :: sf

    self

    integer, intent(in) :: mn_max_in(2)

    maximum mode in m and n

    integer, intent(in) :: mn_nyq_in(2)

    number of integration points

    integer, intent(in) :: nfp_in

    number of field periods

    character(len=8), intent(in) :: sin_cos_in

    can be either only sine: " sin" only cosine: " cos" or full: "sin_cos"

    logical, intent(in) :: exclude_mn_zero_in

    =true: exclude m=n=0 mode in the basis (only important if cos is in basis)

procedure, public :: free => fBase_free

  • private subroutine fBase_free(sf)

    finalize the type fBase

    Arguments

    Type IntentOptional Attributes Name
    class(t_fBase), intent(inout) :: sf

    self

procedure, public :: copy => fBase_copy

  • private subroutine fBase_copy(sf, tocopy)

    copy the type fBase

    Arguments

    Type IntentOptional Attributes Name
    class(t_fBase), intent(inout) :: sf

    self

    class(t_fBase), intent(in) :: tocopy

procedure, public :: compare => fBase_compare

  • private subroutine fBase_compare(sf, tocompare, is_same, cond_out)

    compare sf with the input type fBase

    Arguments

    Type IntentOptional Attributes Name
    class(t_fBase), intent(in) :: sf

    self

    type(t_fBase), intent(in) :: tocompare
    logical, intent(out), optional :: is_same
    logical, intent(out), optional :: cond_out(:)

procedure, public :: change_base => fBase_change_base

  • private subroutine fBase_change_base(sf, old_fBase, iterDim, old_data, sf_data)

    change data from oldBase to self. Forier modes are directly copied so, if new mode space is smaller, its like a Fourier cut-off. if new modes do not match old ones, they are set to zero. Note that a change of nfp is not possible· as well as a change from sine to cosine

    Arguments

    Type IntentOptional Attributes Name
    class(t_fBase), intent(in) :: sf

    self

    class(t_fBase), intent(in) :: old_fBase

    base of old_data

    integer, intent(in) :: iterDim

    iterate on first or second dimension or old_data/sf_data

    real(kind=wp), intent(in) :: old_data(:,:)
    real(kind=wp), intent(out) :: sf_data(:,:)

procedure, public :: eval => fBase_eval

  • private function fBase_eval(sf, deriv, x) result(base_x)

    evaluate all modes at specific given point in theta and zeta

    Arguments

    Type IntentOptional Attributes Name
    class(t_fBase), intent(in) :: sf

    self

    integer, intent(in) :: deriv

    =0: base, =2: dthet , =3: dzeta

    real(kind=wp), intent(in) :: x(2)

    theta,zeta point position

    Return Value real(kind=wp), (sf%modes)

procedure, public :: eval_xn => fBase_eval_xn

  • private function fBase_eval_xn(sf, deriv, np, xn) result(base_xn)

    evaluate all modes at a list of given points in theta and zeta

    Arguments

    Type IntentOptional Attributes Name
    class(t_fBase), intent(in) :: sf

    self

    integer, intent(in) :: deriv

    =0: base, =2: dthet , =3: dzeta

    integer, intent(in) :: np

    number of points in xn

    real(kind=wp), intent(in) :: xn(2,1:np)

    theta,zeta point positions

    Return Value real(kind=wp), (1:np,sf%modes)

procedure, public :: evalDOF_x => fBase_evalDOF_x

  • private function fBase_evalDOF_x(sf, x, deriv, DOFs) result(y)

    evaluate all modes at a given interpolation point

    Arguments

    Type IntentOptional Attributes Name
    class(t_fBase), intent(in) :: sf

    self

    real(kind=wp), intent(in) :: x(2)

    input coordinate theta,zeta in [0,2pi]^2

    integer, intent(in) :: deriv

    =0: base, =2: dthet , =3: dzeta

    real(kind=wp), intent(in) :: DOFs(:)

    array of all modes

    Return Value real(kind=wp)

procedure, public :: evalDOF_xn => fBase_evalDOF_xn

  • private function fBase_evalDOF_xn(sf, np, xn, deriv, DOFs) result(y)

    evaluate all modes at a list of interpolation points

    Arguments

    Type IntentOptional Attributes Name
    class(t_fBase), intent(in) :: sf

    self

    integer, intent(in) :: np

    number of points to be evaluated

    real(kind=wp), intent(in) :: xn(2,1:np)

    input coordinate theta,zeta in [0,2pi]^2

    integer, intent(in) :: deriv

    =0: base, =2: dthet , =3: dzeta

    real(kind=wp), intent(in) :: DOFs(:)

    array of all modes

    Return Value real(kind=wp), (1:np)

procedure, public :: evalDOF_xn_tens => fBase_evalDOF_xn_tens

  • private function fBase_evalDOF_xn_tens(sf, nthet, nzeta, thet, zeta, deriv, DOFs) result(y)

    evaluate all modes on a tensor-produc grid (t_i,z_j), making use of the tensor product in the fourier series: y_ij = DOFs_mn * SIN(mt_i - nz_j ) => SIN(mt_i) DOFs_mn COS(nz_j) -COS(mt_i) DOFs_mn SIN(nz_j) y_ij = DOFs_mn * COS(mt_i - nz_j ) => COS(mt_i) DOFs_mn COS(nz_j) +SIN(mt_i) DOFs_mn SIN(nz_j) => a1_im DOFs_mn b1_nj + a2_im DOFs_mn b2_nj can be written as 2 SPECIAL MATMAT operations: c(i,1,n)=a1(i,m) DOFs(m,n) , c(i,2,n) = a2(i,m) DOFs(m,n) => c(i,d,n) = DOT_PROD(a(i,d,1:mmax),DOFs(1:mmax,n)) y(i,j) = c(i,1,n) b1(n,j) + c(i,2,n) b2(n,j) = DOT_PROD(c(i,1:2,1:nmax),b(1:2,1:nmax,j) the 1D ordering in y does not neead a reshape, y(i,j) => y(1:mn_IP), 1D array data can be kept, as it is passed (with its start adress) to DGEMM.

    Arguments

    Type IntentOptional Attributes Name
    class(t_fBase), intent(in) :: sf

    self

    integer, intent(in) :: nthet

    number of points in theta

    integer, intent(in) :: nzeta

    number of points in zeta

    real(kind=wp), intent(in) :: thet(1:nthet)

    theta positions

    real(kind=wp), intent(in) :: zeta(1:nzeta)

    zeta positions

    integer, intent(in) :: deriv

    =0: base, =2: dthet , =3: dzeta

    real(kind=wp), intent(in) :: DOFs(:)

    array of all modes

    Return Value real(kind=wp), (1:nthet*nzeta)

    DOFS evaluated on tensor-product grid,

procedure, public :: evalDOF_IP => fBase_evalDOF_IP_tens

  • private function fBase_evalDOF_IP_tens(sf, deriv, DOFs) result(y_IP)

    evaluate all modes at all interpolation points, making use of the tensor product: y_ij = DOFs_mn * SIN(mt_i - nz_j ) => SIN(mt_i) DOFs_mn COS(nz_j) -COS(mt_i) DOFs_mn SIN(nz_j) y_ij = DOFs_mn * COS(mt_i - nz_j ) => COS(mt_i) DOFs_mn COS(nz_j) +SIN(mt_i) DOFs_mn SIN(nz_j) => a1_im DOFs_mn b1_nj + a2_im DOFs_mn b2_nj can be written as 2 SPECIAL MATMAT operations: c(i,1,n)=a1(i,m) DOFs(m,n) , c(i,2,n) = a2(i,m) DOFs(m,n) => c(i,d,n) = DOT_PROD(a(i,d,1:mmax),DOFs(1:mmax,n)) y(i,j) = c(i,1,n) b1(n,j) + c(i,2,n) b2(n,j) = DOT_PROD(c(i,1:2,1:nmax),b(1:2,1:nmax,j) the 1D ordering in y does not neead a reshape, y(i,j) => y(1:mn_IP), 1D array data can be kept, as it is passed (with its start adress) to DGEMM.

    Arguments

    Type IntentOptional Attributes Name
    class(t_fBase), intent(in) :: sf

    self

    integer, intent(in) :: deriv

    =0: base, =2: dthet , =3: dzeta

    real(kind=wp), intent(in) :: DOFs(:)

    array of all modes (sf%modes)

    Return Value real(kind=wp), (sf%mn_IP)

procedure, public :: projectIPtoDOF => fBase_projectIPtoDOF_tens

  • private subroutine fBase_projectIPtoDOF_tens(sf, add, factor, deriv, y_IP, DOFs)

    inverse of fBase_evalDOF_IP_tens

    Arguments

    Type IntentOptional Attributes Name
    class(t_fBase), intent(in) :: sf

    self

    logical, intent(in) :: add

    =F initialize DOFs , =T add to DOFs

    real(kind=wp), intent(in) :: factor

    scale result by factor, before adding to DOFs (should be =1.0_wp if not needed)

    integer, intent(in) :: deriv

    =0: base, =2: dthet , =3: dzeta

    real(kind=wp), intent(in) :: y_IP(:)

    point values (at sf%x_IP if x_IP_in not given)

    real(kind=wp), intent(inout) :: DOFs(1:sf%modes)

    array of all modes

procedure, public :: projectxntoDOF => fBase_projectxntoDOF

  • private subroutine fBase_projectxntoDOF(sf, add, factor, deriv, np, xn, yn, DOFs)

    project from any 2D set of interpolation points, at tensor-product of (theta,zeta) positions given by "xn", to all modes DOFs = addDOFs+ fac MATMUL(base_xn,yn)

    Arguments

    Type IntentOptional Attributes Name
    class(t_fBase), intent(in) :: sf

    self

    logical, intent(in) :: add

    =F initialize DOFs , =T add to DOFs

    real(kind=wp), intent(in) :: factor

    scale result by factor, before adding to DOFs (should be =1.0_wp if not needed)

    integer, intent(in) :: deriv

    =0: base, =2: dthet , =3: dzeta

    integer, intent(in) :: np

    total number of 2D interpolation points

    real(kind=wp), intent(in) :: xn(2,1:np)

    (theta=1,zeta=2) position of tensor-product interpolation points, [0,2pi]x[0,2pi/nfp],size(2,mn_IP)

    real(kind=wp), intent(in) :: yn(1:np)

    value at interpolation points

    real(kind=wp), intent(inout) :: DOFs(1:sf%modes)

    array of all modes

procedure, public :: initDOF => fBase_initDOF

  • private function fBase_initDOF(sf, g_IP, thet_zeta_start) result(DOFs)

    take values interpolated at sf%s_IP positions and project onto fourier basis by integration

    Arguments

    Type IntentOptional Attributes Name
    class(t_fBase), intent(in) :: sf

    self

    real(kind=wp), intent(in) :: g_IP(:)

    interpolation values at theta_IP zeta_IP positions

    real(kind=wp), intent(in), optional :: thet_zeta_start(2)

    Return Value real(kind=wp), (1:sf%modes)

    projection to fourier base

Source Code

TYPE :: t_fBase
  !---------------------------------------------------------------------------------------------------------------------------------
  !input parameters
  INTEGER              :: mn_max(2)   !! input parameter: maximum number of fourier modes: m_max=mn_max(1),n_max=mn_max(2)
  INTEGER              :: mn_nyq(2)   !! number of equidistant integration points (trapezoidal rule) in m and n
  INTEGER              :: mn_IP       !! =mn_nyq(1)*mn_nyq(2)
  INTEGER              :: nfp         !! number of field periods (toroidal repetition after 2pi/nfp)
  INTEGER              :: sin_cos     !! can be either only sine: _SIN_  or only cosine _COS_ or full: _SINCOS_
  !input parameters
  LOGICAL              :: exclude_mn_zero  !!  =true: exclude m=n=0 mode in the basis (only important if cos is in basis)
  !---------------------------------------------------------------------------------------------------------------------------------
  INTEGER              :: modes       !! total(global) number of modes in basis (depends if only sin/cos or sin & cos are used)
  INTEGER              :: modes_str, modes_end   !! local range of modes, when distributed over MPI subdomains
  INTEGER,ALLOCATABLE  :: offset_modes(:)        !! allocated (0:nRanks), gives range on each rank:
                                                 !!   modes_str:modes_end=offset_modes(myRank)+1:offset_modes(myRank+1)
  INTEGER,ALLOCATABLE  :: whichRank(:)           !! know the MPI rank for each mode
  !---------------------------------------------------------------------------------------------------------------------------------
  LOGICAL              :: initialized=.FALSE.      !! set to true in init, set to false in free
  !---------------------------------------------------------------------------------------------------------------------------------
  INTEGER              :: sin_range(2)        !! sin_range(1)+1:sin_range(2) is range with sine bases
  INTEGER              :: cos_range(2)        !! sin_range(1)+1:sin_range(2) is range with cosine bases
  INTEGER              :: mn_zero_mode        !! points to m=0,n=0 mode in mode array (1:mn_modes) (only one can exist for cosine, else =-1)
  REAL(wp)             :: d_thet              !! integration weight in theta direction: =2pi/mn_nyq(1)
  REAL(wp)             :: d_zeta              !! integration weight in zeta direction : =nfp*(2pi/nfp)/mn_nyq(2)=2*pi/mn_nyq(2)
  INTEGER,ALLOCATABLE  :: Xmn(:,:)            !! mode number (m,n*nfp) for each iMode=1,modes, size(2,modes)
  INTEGER,ALLOCATABLE  :: zero_odd_even(:)    !! =0 for m=n=0 mode, =1 for m= odd mode, =2 for m=even mode size(modes)
  REAL(wp),ALLOCATABLE :: x_IP(:,:)           !! (theta,zeta)position of interpolation points theta [0,2pi]x[0,2pi/nfp]size(2,mn_IP)
  REAL(wp),ALLOCATABLE :: thet_IP(:)           !! 1d theta position of interpolation points theta [0,2pi] size(mn_nyq(1))
  REAL(wp),ALLOCATABLE :: zeta_IP(:)           !! 1d zeta position of interpolation points theta [0,2pi/nfp] size(mn_nyq(2))
  REAL(wp),ALLOCATABLE :: base_IP(:,:)        !! basis functions,                 size(1:mn_IP,1:modes)
  REAL(wp),ALLOCATABLE :: base_dthet_IP(:,:)  !! dthet derivative of basis functions, (1:mn_IP,1:modes)
  REAL(wp),ALLOCATABLE :: base_dzeta_IP(:,:)  !! dzeta derivative of basis functions, (1:mn_IP,1:modes)

  REAL(wp),ALLOCATABLE :: snorm_base(:)       !! 1/norm of each basis function, size(1:modes), norm=int_0^2pi int_0^pi (base_mn(thet,zeta))^2 dthet dzeta
  INTEGER              :: mTotal1D            !! mTotal1D =mn_max(1)+1  for sin or cos base, and mTotal=2*(mn_max(1)+1) for sin&cos base
  REAL(wp),ALLOCATABLE :: base1D_IPthet(:,:,:) !! 1D basis,  size(1:mn_nyq(1),1:2,1:mTotal1D),
                                               !! if sin(m t-n z):   sin(m t), -cos(m t) and if cos(m t-n z): cos(m t),sin(m t)
  REAL(wp),ALLOCATABLE :: base1D_dthet_IPthet(:,:,:) !! derivative of 1D basis, size(1:mn_nyq(1),1:2,1:mTotal1D)
                                               !! if sin(m t-n z): m cos(m t),m sin(m t) and if cos(m t-n z): -m sin(m t),m cos(m t)
  REAL(wp),ALLOCATABLE :: base1D_IPzeta(:,:,:) !! 1D basis functions, size(1:2,-mn_max(2):mn_max(2),1:mn_nyq(2))
                                               !! for sin/cos(m t-n z): cos(n z),sin(n z)
  REAL(wp),ALLOCATABLE :: base1D_dzeta_IPzeta(:,:,:) !! derivative of 1D basis functions, size(1:2,-mn_max(2):mn_max(2),1:mn_nyq(2))
                                               !! for sin/cos(m t-n z): -n sin(n z),n cos(n z)

  CONTAINS

  PROCEDURE :: init             => fBase_init
  PROCEDURE :: free             => fBase_free
  PROCEDURE :: copy             => fBase_copy
  PROCEDURE :: compare          => fBase_compare
  PROCEDURE :: change_base      => fBase_change_base
  PROCEDURE :: eval             => fBase_eval
  PROCEDURE :: eval_xn          => fBase_eval_xn
  PROCEDURE :: evalDOF_x        => fBase_evalDOF_x
  PROCEDURE :: evalDOF_xn       => fBase_evalDOF_xn
  PROCEDURE :: evalDOF_xn_tens  => fBase_evalDOF_xn_tens
  ! PROCEDURE :: evalDOF_IP       => fBase_evalDOF_IP !use _tens instead!
  PROCEDURE :: evalDOF_IP       => fBase_evalDOF_IP_tens
  !  PROCEDURE :: projectIPtoDOF   => fBase_projectIPtoDOF
  PROCEDURE :: projectIPtoDOF   => fBase_projectIPtoDOF_tens
  PROCEDURE :: projectxntoDOF   => fBase_projectxntoDOF
  PROCEDURE :: initDOF          => fBase_initDOF

END TYPE t_fBase