initialize the type hmap_axisNB and read "G-frame" from netcdf
transform from full period cartesian coordinates to one-field period "hat" cartesian coordinates, by rotating around the zaxis with the local angle zeta, with the sign given by which direction xyz(zeta=0) rotates to xyz(zeta=2pi/nfp) INVERSION OF: x=cos(zeta)xhat - sgn_rotsin(zeta)yhat, y=cos(zeta)yhat + sgn_rotsin(zeta)xhat, z <=> zhat ==> xhat=cos(zeta)x+sgn_rotsin(zeta)y, yhat=cos(zeta)y-sgn_rotsin(zeta)x, check that all points on full period are the same in the xhat,yhat,zhat coordinates NOTE THIS FUNCTION IS USING sinz=sin(zeta),cosz=cos(zeta) and sgn_rot computed above!!!!
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | ncfile |
netcdf file containing the group "axis" from which to read the G-frame |
||
| integer, | intent(in) | :: | nvisu |
number of visualization points for G-Frame per field period, -1: no visualization |
self
FUNCTION hmap_axisNB_init_params(ncfile,nvisu) RESULT(sf) ! MODULES USE MODgvec_fbase ,ONLY: t_fBase USE MODgvec_io_netcdf ,ONLY: ncfile_init USE MODgvec_MPI ,ONLY: par_BCast,par_barrier IMPLICIT NONE !----------------------------------------------------------------------------------------------------------------------------------- ! INPUT VARIABLES CHARACTER(LEN=*),INTENT(IN) :: ncfile !! netcdf file containing the group "axis" from which to read the G-frame INTEGER ,INTENT(IN) :: nvisu !! number of visualization points for G-Frame per field period, -1: no visualization !----------------------------------------------------------------------------------------------------------------------------------- ! OUTPUT VARIABLES TYPE(t_hmap_axisNB) :: sf !! self !----------------------------------------------------------------------------------------------------------------------------------- ! LOCAL VARIABLES INTEGER :: i INTEGER :: error_nfp REAL(wp),ALLOCATABLE :: cosz(:),sinz(:) !=================================================================================================================================== CALL par_Barrier(beforeScreenOut='INIT HMAP :: axisNB FRAME OF A CLOSED CURVE ...') sf%ncfile=ncfile IF(MPIroot)THEN ! read axis from netcdf CALL ncfile_init(sf%nc,sf%ncfile,"r") CALL ReadNETCDF(sf) sf%sgn_rot=1 IF(sf%nfp.GT.2)THEN !no need to check for nfp=1 and nfp=2 is either a positive or negative rotation by pi IF(SUM((sf%xyz(:,1+sf%nzeta) - rodrigues(sf%xyz(:,1),TWOPI/REAL(sf%nfp,wp)))**2).LT.1.0e-12)THEN sf%sgn_rot=1 ELSEIF(SUM((sf%xyz(:,1+sf%nzeta) - rodrigues(sf%xyz(:,1),-TWOPI/REAL(sf%nfp,wp)))**2).LT.1.0e-12)THEN sf%sgn_rot=-1 ELSE CALL abort(__STAMP__, & 'problem with check of field period rotation: point at zeta=0 does not rotate to point at zeta= +/-2pi/nfp.', & TypeInfo="InitializationError") END IF END IF WRITE(UNIT_stdOut,'(4X,A,I2)')'INFO: sign of the rotation from zeta=0 to zeta=2pi/nfp is: ',sf%sgn_rot sf%n_max=(sf%nzeta-1)/2 ! maximum mode number on a field period END IF !MPIroot CALL par_BCast(sf%nzeta,0) CALL par_BCast(sf%nfp,0) CALL par_BCast(sf%n_max,0) CALL par_Bcast(sf%sgn_rot,0) IF(.NOT.MPIroot) CALL allocate_readin_vars(sf) CALL par_Bcast(sf%zeta,0) CALL par_Bcast(sf%xyz,0) CALL par_Bcast(sf%Nxyz,0) CALL par_Bcast(sf%Bxyz,0) !Fourier 1D base on one field period for "hat" coordinates sf%fb_hat = t_fBase((/0,sf%n_max/),(/1,sf%nzeta/),sf%nfp,"_sincos_",.FALSE.) ALLOCATE(sf%xyz_hat_modes( 3,sf%fb_hat%modes),& sf%Nxyz_hat_modes(3,sf%fb_hat%modes),& sf%Bxyz_hat_modes(3,sf%fb_hat%modes)) IF(MPIroot)THEN ALLOCATE(cosz(sf%nzeta*sf%nfp),sinz(sf%nzeta*sf%nfp)) !build cos(zeta),sin(zeta) on full torus DO i=1,sf%nfp cosz(sf%nzeta*(i-1)+1:sf%nzeta*i)=COS(sf%zeta(1:sf%nzeta)+TWOPI*(REAL(i-1,wp)/REAL(sf%nfp,wp))) sinz(sf%nzeta*(i-1)+1:sf%nzeta*i)=SIN(sf%zeta(1:sf%nzeta)+TWOPI*(REAL(i-1,wp)/REAL(sf%nfp,wp))) END DO sf%xyz_hat_modes =transform_to_hat(sf%xyz, "xyz to xyzhat" ) sf%Nxyz_hat_modes=transform_to_hat(sf%Nxyz,"Nxyz to Nxyzhat") sf%Bxyz_hat_modes=transform_to_hat(sf%Bxyz,"Bxyz to Bxyzhat") DEALLOCATE(cosz,sinz) IF(nvisu.GT.0) CALL Visu_axisNB(sf,nvisu*sf%nfp) CALL CheckFieldPeriodicity(sf,sf%sgn_rot,error_nfp) IF(error_nfp.LT.0) & CALL abort(__STAMP__, & "hmap_axisNB check Field Periodicity failed!", & TypeInfo="InitializationError") END IF !MPIroot CALL par_BCast(sf%xyz_hat_modes,0) CALL par_BCast(sf%Nxyz_hat_modes,0) CALL par_BCast(sf%Bxyz_hat_modes,0) sf%initialized=.TRUE. CALL par_barrier(afterScreenOut='...DONE') IF(.NOT.test_called) CALL hmap_axisNB_test(sf) !------------------ CONTAINS !------------------ !! transform from full period cartesian coordinates to one-field period "hat" cartesian coordinates, !! by rotating around the zaxis with the local angle zeta, !! with the sign given by which direction xyz(zeta=0) rotates to xyz(zeta=2pi/nfp) !! INVERSION OF: x=cos(zeta)*xhat - sgn_rot*sin(zeta)*yhat, !! y=cos(zeta)*yhat + sgn_rot*sin(zeta)*xhat, z <=> zhat !! ==> xhat=cos(zeta)x+sgn_rot*sin(zeta)y, !! yhat=cos(zeta)y-sgn_rot*sin(zeta)x, !! check that all points on full period are the same in the xhat,yhat,zhat coordinates !! NOTE THIS FUNCTION IS USING sinz=sin(zeta),cosz=cos(zeta) and sgn_rot computed above!!!! FUNCTION transform_to_hat(xyz_in,msg) RESULT(to_hat_modes) IMPLICIT NONE REAL(wp),INTENT(IN) :: xyz_in(3,sf%nzeta*sf%nfp) CHARACTER(*),INTENT(IN) :: msg REAL(wp) :: to_hat_modes(3,sf%fb_hat%modes) !------------------ REAL(wp) :: to_hat(3,sf%nzeta*sf%nfp) REAL(wp) :: check_xhat(1:3,2:sf%nfp) !------------------ to_hat(1,:)=xyz_in(1,:)*cosz(:)+sf%sgn_rot*xyz_in(2,:)*sinz(:) to_hat(2,:)=xyz_in(2,:)*cosz(:)-sf%sgn_rot*xyz_in(1,:)*sinz(:) to_hat(3,:)=xyz_in(3,:) !check periodicity for remaining nfp DO i=2,sf%nfp check_xhat(1,i)=MAXVAL(ABS(to_hat(1,1:sf%nzeta)-to_hat(1,sf%nzeta*(i-1)+1:sf%nzeta*i))) check_xhat(2,i)=MAXVAL(ABS(to_hat(2,1:sf%nzeta)-to_hat(2,sf%nzeta*(i-1)+1:sf%nzeta*i))) check_xhat(3,i)=MAXVAL(ABS(to_hat(3,1:sf%nzeta)-to_hat(3,sf%nzeta*(i-1)+1:sf%nzeta*i))) END DO IF(ANY(check_xhat.GT.1.0e-12))THEN DO i=2,sf%nfp WRITE(UNIT_stdout,'(A,I4,A,3E9.2)')'fp=1 vs fp=',i,', check_xyz=',check_xhat(1:3,i) END DO CALL abort(__STAMP__,& "transform from cartesian to hat coordinates"//TRIM(msg)//" yields non-field periodic data!", & TypeInfo="InitializationError") END IF DO i=1,3 to_hat_modes(i,:)=sf%fb_hat%initDOF(to_hat(i,1:sf%nzeta),thet_zeta_start=(/0.,sf%zeta(1)/)) END DO END FUNCTION transform_to_hat END FUNCTION hmap_axisNB_init_params