bff_convert_to_modes Subroutine

private subroutine bff_convert_to_modes(sf, x1_fbase_in, x2_fbase_in, X1_b, X2_b, scale_minor_radius)

Uses

  • proc~~bff_convert_to_modes~~UsesGraph proc~bff_convert_to_modes t_boundaryFromFile%bff_convert_to_modes module~modgvec_fbase MODgvec_fBase proc~bff_convert_to_modes->module~modgvec_fbase module~modgvec_globals MODgvec_Globals module~modgvec_fbase->module~modgvec_globals iso_fortran_env iso_fortran_env module~modgvec_globals->iso_fortran_env

convert from interpolation points X=> X1_b, Y=> X2_b to fourier modes, given from the input fbase convert to maximum allowable number of modes (ntheta>=2m_max+1, nzeta>=2n_max+1) the final m_max/n_max can be smaller or larger. If larger, a change of base is necessary

Type Bound

t_boundaryFromFile

Arguments

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

self

type(t_fBase), intent(in) :: x1_fbase_in
type(t_fBase), intent(in) :: x2_fbase_in
real(kind=wp), intent(inout) :: X1_b(x1_fbase_in%modes)
real(kind=wp), intent(inout) :: X2_b(x2_fbase_in%modes)
real(kind=wp), intent(in) :: scale_minor_radius

Calls

proc~~bff_convert_to_modes~~CallsGraph proc~bff_convert_to_modes t_boundaryFromFile%bff_convert_to_modes proc~fbase_change_base t_fBase%fBase_change_base proc~bff_convert_to_modes->proc~fbase_change_base proc~fbase_evaldof_xn t_fBase%fBase_evalDOF_xn proc~bff_convert_to_modes->proc~fbase_evaldof_xn proc~fbase_initdof t_fBase%fBase_initDOF proc~bff_convert_to_modes->proc~fbase_initdof proc~fbase_new fBase_new proc~bff_convert_to_modes->proc~fbase_new proc~fbase_compare t_fBase%fBase_compare proc~fbase_change_base->proc~fbase_compare __matvec_n __matvec_n proc~fbase_evaldof_xn->__matvec_n proc~fbase_eval_xn t_fBase%fBase_eval_xn proc~fbase_evaldof_xn->proc~fbase_eval_xn proc~fbase_projectiptodof_tens t_fBase%fBase_projectIPtoDOF_tens proc~fbase_initdof->proc~fbase_projectiptodof_tens proc~fbase_projectxntodof t_fBase%fBase_projectxntoDOF proc~fbase_initdof->proc~fbase_projectxntodof __perfoff __perfoff proc~fbase_new->__perfoff __perfon __perfon proc~fbase_new->__perfon proc~fbase_init t_fBase%fBase_init proc~fbase_new->proc~fbase_init proc~fbase_alloc fBase_alloc proc~fbase_init->proc~fbase_alloc proc~fbase_test fBase_test proc~fbase_init->proc~fbase_test swrite swrite proc~fbase_init->swrite __adgemm_tn __adgemm_tn proc~fbase_projectiptodof_tens->__adgemm_tn __dgemm_nt __dgemm_nt proc~fbase_projectiptodof_tens->__dgemm_nt proc~fbase_projectxntodof->proc~fbase_eval_xn __pamatvec_t __pamatvec_t proc~fbase_projectxntodof->__pamatvec_t proc~fbase_test->proc~fbase_change_base proc~fbase_test->proc~fbase_evaldof_xn proc~fbase_test->proc~fbase_initdof proc~fbase_test->proc~fbase_compare proc~fbase_test->proc~fbase_init proc~fbase_test->swrite proc~fbase_evaldof_ip_tens t_fBase%fBase_evalDOF_IP_tens proc~fbase_test->proc~fbase_evaldof_ip_tens proc~fbase_evaldof_x t_fBase%fBase_evalDOF_x proc~fbase_test->proc~fbase_evaldof_x proc~fbase_evaldof_xn_tens t_fBase%fBase_evalDOF_xn_tens proc~fbase_test->proc~fbase_evaldof_xn_tens proc~fbase_evaldof_ip_tens->proc~fbase_evaldof_xn __dgemm_nn __dgemm_nn proc~fbase_evaldof_ip_tens->__dgemm_nn proc~fbase_eval t_fBase%fBase_eval proc~fbase_evaldof_x->proc~fbase_eval proc~fbase_evaldof_xn_tens->__dgemm_nn proc~fbase_eval1d_thet fBase_eval1d_thet proc~fbase_evaldof_xn_tens->proc~fbase_eval1d_thet proc~fbase_eval1d_zeta fBase_eval1d_zeta proc~fbase_evaldof_xn_tens->proc~fbase_eval1d_zeta proc~fbase_eval->proc~fbase_eval_xn

Called by

proc~~bff_convert_to_modes~~CalledByGraph proc~bff_convert_to_modes t_boundaryFromFile%bff_convert_to_modes proc~initmhd3d t_functional_mhd3d%InitMHD3D proc~initmhd3d->proc~bff_convert_to_modes

Source Code

SUBROUTINE bff_convert_to_modes(sf,x1_fbase_in,x2_fbase_in,X1_b,X2_b,scale_minor_radius)
! MODULES
  USE MODgvec_fbase  ,ONLY: t_fbase,fbase_new,sin_cos_map
  IMPLICIT NONE
  !-----------------------------------------------------------------------------------------------------------------------------------
  ! INPUT VARIABLES
  TYPE(t_fbase), INTENT(IN):: x1_fbase_in,x2_fbase_in
  REAL(wp), INTENT(IN)  :: scale_minor_radius
  !-----------------------------------------------------------------------------------------------------------------------------------
  ! OUTPUT VARIABLES
  REAL(wp), INTENT(INOUT)  :: X1_b(x1_fbase_in%modes),X2_b(x2_fbase_in%modes)
  CLASS(t_boundaryFromFile), INTENT(INOUT) :: sf !! self
  !-----------------------------------------------------------------------------------------------------------------------------------
  ! LOCAL VARIABLES
  TYPE(t_fBase),ALLOCATABLE        :: X_fbase,Y_fbase
  INTEGER                           :: i,nIP,mIP,mn_max_pts(2)
  REAL(wp)                          :: xn(2,sf%ntheta*sf%nzeta)
  REAL(wp),ALLOCATABLE              :: xydofs(:,:),X12dofs(:,:)
  !===================================================================================================================================
  WRITE(UNIT_stdOut,'(A)')'  CONVERT BOUNDARY FROM POINTS TO MODES:'

  IF(sf%nfp.NE.x1_fbase_in%nfp)CALL abort(__STAMP__,&
                 " error in convert boundary to modes, nfp from GVEC parameterfile does not match to nfp of boundary file")
  mn_max_pts(1:2)=(/(sf%ntheta-1)/2,(sf%nzeta-1)/2/)
  WRITE(UNIT_stdOut,'(6X,2(A,I4),2A)')' from X,Y(ntheta= ',sf%ntheta,', nzeta= ', &
                                               sf%nzeta, '), lasym=',MERGE("symmetric","asymetric",(sf%lasym.EQ.0))
  WRITE(UNIT_stdOut,'(6x,2(3A,2(2I4,A)))') ' => X1 ',sin_cos_map(x1_fbase_in%sin_cos), &
                                                   ', (m_max,n_max)= (',mn_max_pts,')=>(',x1_fbase_in%mn_max,')', &
                                            ' , X2 ',sin_cos_map(x2_fbase_in%sin_cos), &
                                                  ', (m_max,n_max)= (',mn_max_pts,')=>(',x2_fbase_in%mn_max,')'
  IF(ALL(x1_fbase_in%mn_max.LE.mn_max_pts))THEN  !X1_base is smaller/equal
    CALL fbase_new( X_fbase, x1_fbase_in%mn_max,  (/sf%ntheta,sf%nzeta/), &
                    sf%nfp, sin_cos_map(x1_fbase_in%sin_cos), x1_fbase_in%exclude_mn_zero)
    X1_b = X_fbase%initDOF(RESHAPE(sf%X*scale_minor_radius,(/sf%ntheta*sf%nzeta/)) ,thet_zeta_start=(/sf%theta(1),sf%zeta(1)/))
  ELSE
    CALL fbase_new( X_fbase, mn_max_pts,  (/sf%ntheta,sf%nzeta/), &
                    sf%nfp, sin_cos_map(x1_fbase_in%sin_cos), x1_fbase_in%exclude_mn_zero)
    ALLOCATE(xydofs(1,1:X_fbase%modes),X12dofs(1,1:x1_fbase_in%modes))
    xydofs(1,:) = X_fbase%initDOF(RESHAPE(sf%X*scale_minor_radius,(/sf%ntheta*sf%nzeta/)),thet_zeta_start=(/sf%theta(1),sf%zeta(1)/))
    CALL x1_fbase_in%change_base(X_fbase,1,xydofs,X12dofs)
    X1_b=X12dofs(1,:)
    DEALLOCATE(xydofs,X12dofs)
  END IF
  IF(ALL(x2_fbase_in%mn_max.LE.mn_max_pts))THEN  !X2_base is smaller/equal
    CALL fbase_new( Y_fbase, x2_fbase_in%mn_max,  (/sf%ntheta,sf%nzeta/), &
                    sf%nfp,  sin_cos_map(x2_fbase_in%sin_cos),  x2_fbase_in%exclude_mn_zero)
    X2_b = Y_fbase%initDOF(RESHAPE(sf%Y*scale_minor_radius,(/sf%ntheta*sf%nzeta/)) ,thet_zeta_start=(/sf%theta(1),sf%zeta(1)/))
  ELSE
    CALL fbase_new( Y_fbase, mn_max_pts,  (/sf%ntheta,sf%nzeta/), &
                    sf%nfp,  sin_cos_map(x2_fbase_in%sin_cos),  x2_fbase_in%exclude_mn_zero)
    ALLOCATE(xydofs(1,1:Y_fbase%modes),X12dofs(1,1:x2_fbase_in%modes))
    xydofs(1,:) = Y_fbase%initDOF(RESHAPE(sf%Y*scale_minor_radius,(/sf%ntheta*sf%nzeta/)),thet_zeta_start=(/sf%theta(1),sf%zeta(1)/))
    CALL x2_fbase_in%change_base(Y_fbase,1,xydofs,X12dofs)
    X2_b=X12dofs(1,:)
  END IF
  !evaluate at interpolation points and check the error
  i=0
  DO nIP=1,sf%nzeta
    DO mIP=1,sf%ntheta
      i=i+1
      xn(1,i)=sf%theta(mIP)
      xn(2,i)=sf%zeta(nIP)
    END DO !m
  END DO !n

  WRITE(UNIT_stdOut,'(6X,A)')      ' => APPROXIMATION ERROR COMPARED TO INPUT POINTS:'
  WRITE(UNIT_stdOut,'(6X,A,E11.3)')'     max(|X1_fourier-X_input|)=',&
                      MAXVAL(ABS(x1_fbase_in%evalDOF_xn(sf%ntheta*sf%nzeta,xn,0,X1_b)/scale_minor_radius &
                             -RESHAPE(sf%X,(/sf%ntheta*sf%nzeta/))))
  WRITE(UNIT_stdOut,'(6X,A,E11.3)')'     max(|X2_fourier-Y_input|)', &
                      MAXVAL(ABS(x2_fbase_in%evalDOF_xn(sf%ntheta*sf%nzeta,xn,0,X2_b)/scale_minor_radius &
                             -RESHAPE(sf%Y,(/sf%ntheta*sf%nzeta/))))


  CALL X_fbase%free()
  CALL Y_fbase%free()
  DEALLOCATE(X_fbase,Y_fbase)
  WRITE(UNIT_stdOut,'(A)')'  ... CONVERT BOUNDARY DONE.'
END SUBROUTINE bff_convert_to_modes