Developer Guide#
These pages contain development guidelines and useful resources for developing GVEC.
Contact#
GVEC is mainly being developed in the department of Numerical Methods in Plasma Physics (NMPP) led by Prof. Eric Sonnendruecker at the Max Planck Institute for Plasma Physics in Garching, Germany. Outside contributions are of course very welcome!
If you have questions you can contact the maintainers (Florian) directly or join the matrix-chat channel.
Development Workflow#
GVEC is hosted on two git repositories:
the main development repository on MPCDF-GitLab: Issues, Merge Requests, CI-Pipelines
Benefit: in-house support, unlimited CI/CD budget
Drawback: requires an MPCDF account for contributions → contact the maintainers to obtain a guest account
a public repository on GitHub for visibility and public contributions
New contributors#
Contributions are always welcome!
If you already have a GitHub account, just open an issue on GitHub if you want to report a bug or have a question.
If you want to contribute, it is easiest to submit a Pull Request on GitHub for your proposed changes. The Maintainers will then mirror your branch back to GitLab to run all the testing pipelines. For larger contributions, you can contact the maintainers to obtain a guest account for the MPCDF-GitLab.
You can also join the matrix-chat channel for questions and discussions.
Remarks / Guidelines#
developis the main development branchuse feature branches, merge to
developearly and oftenuse GitLab merge requests to document the changes and code review
update with
developbefore merging → resolve conflicts in the feature branch
prefer merging over rebasing
automatic testing in GitLab: add tests for new features
mainpoints to the latest release / tagreleases (with corresponding tags) are created within GitLab
associate milestones with the releases to document progress
tags/releases (mostly) follow semantic versioning
fixes should be added to
develop/ a feature branch and can be cherry-picked back to older releases if necessarya release branch (e.g.
v1.3.x) can be setup to track the history of a release which has branched away fromdevelop
on readthedocs, multiple versions of the documentation are available:
in the version switcher (top-left):
latest→main,develop, and other selected releasesin the readthedocs panel (bottom-right): additional branches, configured in the readthedocs settings
configure readthedocs here: https://app.readthedocs.org/projects/gvec/
in repo:
.readthedocs.yaml&docs/static/version-switcher.json
use pre-commit hooks (python formatting, notebook cleaning, etc.)
pip install pre-commit&pre-commit installuse ruff for python formatting & linting
split your work into small commits
don’t commit large binary data (use pre-commit!)
Repository structure#
src/- the main fortran sourcespyproject.toml- configuration for thegvecpython packagepython/gvec/- thegvecpython package (pyGVEC) with bindings to fortranpython/examples/- example notebooks and configurationspython/kind_map.py&python/class_names.py- auxiliary files for the python bindings with f90wrapCMakeLists.txt,CMakePresets.json,cmake/- configuration of CMakeCI_setup/- scripts to load modules for different clusters & CI runnerstest-CI/- testcases and test logic usingpytest.gitlab-ci.yml&CI_templates- configuration of the GitLab CI Pipelines (see <dev/pipeline>)docs/&.readthedocs.yaml- configuration and static content for the documentation, built with sphinx and ford.gitignore- file patterns to be ignored by git.mailmap- cleaning git authors forgit blametemplate/- a structural template for fortran sourcestools/
Object-Oriented Programming in FORTRAN#
Here is a recommendation for a tutorial on how to program in an object-oriented way with polymorphism in fortran.
Useful VSCode extensions#
Modern Fortran
CMake Tools
Git Graph
GitLab Workflow
GitLens (Premium/Students)
GitHub Copilot (AI, Premium/Students)
Codeium (AI)
Jupyter
MyST-Markdown
Python
Pylance
Ruff (Python Linter & Formatter)
Todo Tree
Vim
YAML
netCDF Preview
Contents#
Developer Guide
- Testing
- Continuous Integration
- Documentation
- pyGVEC
- Fortran-only
- Derivations for computable Quantities
- Contributors
API
- gvec.core.state
StateState.bind()State.compute()State.evaluate()State.evaluate_base_list_rtz_all()State.evaluate_base_list_tz()State.evaluate_base_list_tz_all()State.evaluate_base_tens()State.evaluate_base_tens_all()State.evaluate_boozer_list_tz_all()State.evaluate_hmap()State.evaluate_hmap_derivs()State.evaluate_hmap_only()State.evaluate_jac_h_derivs()State.evaluate_metric_derivs()State.evaluate_profile()State.evaluate_rho2_profile()State.evaluate_sfl()State.get_boozer()State.get_boozer_angles()State.get_integration_points()State.get_mn_max()State.get_pest_angles()State.nameState.new()State.nfpState.plot_3d_surface()State.plot_fourier_on_surface()State.plot_on_axis()State.plot_on_flux_surface()State.plot_poloidal_plane()State.plot_radial_profile()State.rundirState.stdoutState.unbind()
find_state()find_states()load_state()
- gvec.core.run
- gvec.core.compute
- gvec.quantities
A_surface()B()B_contra_t_B()B_contra_t_P()B_contra_z_B()B_rho_B()B_rho_P()B_theta_B()B_theta_P()B_theta_avg()B_zeta_B()B_zeta_P()B_zeta_avg()D_Merc()F()F_r_avg()II_tt()II_tt_B()II_tt_P()II_tz()II_tz_B()II_tz_P()II_zz()II_zz_B()II_zz_P()I_pol()I_tor()J()J_contra_t_B()J_contra_t_P()J_contra_z_B()J_rho_B()J_rho_P()J_theta_B()J_theta_P()J_zeta_B()J_zeta_P()Jac()Jac_B()Jac_P()Jac_h()LA()L_axis()L_gradB()N_FP()Phi()Phi_edge()V()W_MHD()X1()X2()aspect_ratio()beta_avg()chi()dA()dB_dr()dB_dt()dB_dz()dB_theta_avg_dr()dI_tor_dr()dNU_B_dt()dNU_B_dz()dPhi_dr()dPhi_drr()dV_dPhi_n()dV_dPhi_n2()dchi_dr()dchi_drr()diota_dr()diota_drr()dmod_B_dr_B()dmod_B_dt_B()dmod_B_dz_B()dp_dr()dp_drr()e_rho()e_rho_B()e_rho_P()e_theta()e_theta_B()e_theta_P()e_zeta()e_zeta_B()e_zeta_P()elongation()g_rr()g_rr_B()g_rr_P()g_rt()g_rt_B()g_rt_P()g_rz()g_rz_B()g_rz_P()g_tt()g_tt_B()g_tt_P()g_tz()g_tz_B()g_tz_P()g_zz()g_zz_B()g_zz_P()gamma()grad_mod_B()grad_rho()grad_theta()grad_theta_B()grad_theta_P()grad_zeta()grad_zeta_B()iota()iota_0()iota_avg()iota_avg2()iota_curr()iota_curr_0()k_rr()k_rt()k_rz()k_tt()k_tz()k_zz()mirror_ratio()mu0()normal()p()r_major()r_minor()shear()shear_avg()shear_avg2()theta_P()vacuum_magnetic_well_depth()xyz()
- gvec.fourier
- gvec.surface
- gvec.util
CaseInsensitiveDictadapt_parameter_file()axis_from_boundary()boundary_generator()boundary_generator_cases()bspl2gvec()chdir()check_boundary_direction()compute_FD()compute_boundary_perturbation()effective_minor_radius()ellipse_circumference_factor()evaluate_axis()evaluate_boundary()flatten_parameters()flip_boundary_theta()flip_boundary_zeta()flip_parameters_theta()flip_parameters_zeta()get_compile_options()linking_number()logging_setup()parameters_from_vmec()read_parameter_file_ini()read_parameters()shift_boundary_theta_pi()signed_cross_sectional_area()solid_angle_between_segments()stack_parameters()stringify_mn_parameters()unstringify_mn_parameters()version_info()write_parameter_file_ini()write_parameters()writhe_from_polygon()
- gvec.vtk
- gvec.gframe
check_field_periodicity()construct_gframe_from_surface()cut_surf()eval_curve()eval_distance_to_curve()eval_distance_to_plane()find_zeta_cuts()frenet_frame()frenet_frame_evaluate()get_X0_N_B()get_xyz_cut()minimal_modes()plot_cross_section_comparison()read_Gframe_ncfile()rodrigues()to_RZ()to_axis()to_surface()twist_of_ribbon()write_Gframe_ncfile()writhe()xyz_hat_to_xyz()xyz_to_xyz_hat()
- gvec.plotting.plots1d
- gvec.plotting.plots2d
- gvec.plotting.plots3d
- gvec.coils
- gvec.scripts.main
- gvec.scripts.run
- gvec.scripts.cas3d
- gvec.scripts.gist
- gvec.scripts.quasr
- gvec.lib
Modgvec_BiotsavartModgvec_FbaseModgvec_Fbase.change_base()Modgvec_Fbase.compare()Modgvec_Fbase.copy()Modgvec_Fbase.eval()Modgvec_Fbase.eval_xn()Modgvec_Fbase.evaldof_ip()Modgvec_Fbase.evaldof_x()Modgvec_Fbase.evaldof_xn()Modgvec_Fbase.evaldof_xn_tens()Modgvec_Fbase.get_array_sin_cos_map()Modgvec_Fbase.init()Modgvec_Fbase.initdof()Modgvec_Fbase.projectiptodof()Modgvec_Fbase.projectxntodof()Modgvec_Fbase.set_array_sin_cos_map()Modgvec_Fbase.sin_cos_mapModgvec_Fbase.t_fBaseModgvec_Fbase.t_fBase.base1d_dthet_ipthetModgvec_Fbase.t_fBase.base1d_dzeta_ipzetaModgvec_Fbase.t_fBase.base1d_ipthetModgvec_Fbase.t_fBase.base1d_ipzetaModgvec_Fbase.t_fBase.base_dthet_ipModgvec_Fbase.t_fBase.base_dzeta_ipModgvec_Fbase.t_fBase.base_ipModgvec_Fbase.t_fBase.change_base()Modgvec_Fbase.t_fBase.compare()Modgvec_Fbase.t_fBase.copy()Modgvec_Fbase.t_fBase.cos_rangeModgvec_Fbase.t_fBase.d_thetModgvec_Fbase.t_fBase.d_zetaModgvec_Fbase.t_fBase.eval()Modgvec_Fbase.t_fBase.eval_xn()Modgvec_Fbase.t_fBase.evaldof_ip()Modgvec_Fbase.t_fBase.evaldof_x()Modgvec_Fbase.t_fBase.evaldof_xn()Modgvec_Fbase.t_fBase.evaldof_xn_tens()Modgvec_Fbase.t_fBase.exclude_mn_zeroModgvec_Fbase.t_fBase.init()Modgvec_Fbase.t_fBase.initdof()Modgvec_Fbase.t_fBase.initializedModgvec_Fbase.t_fBase.mn_ipModgvec_Fbase.t_fBase.mn_maxModgvec_Fbase.t_fBase.mn_nyqModgvec_Fbase.t_fBase.mn_zero_modeModgvec_Fbase.t_fBase.modesModgvec_Fbase.t_fBase.modes_endModgvec_Fbase.t_fBase.modes_strModgvec_Fbase.t_fBase.mtotal1dModgvec_Fbase.t_fBase.nfpModgvec_Fbase.t_fBase.offset_modesModgvec_Fbase.t_fBase.projectiptodof()Modgvec_Fbase.t_fBase.projectxntodof()Modgvec_Fbase.t_fBase.sin_cosModgvec_Fbase.t_fBase.sin_rangeModgvec_Fbase.t_fBase.snorm_baseModgvec_Fbase.t_fBase.thet_ipModgvec_Fbase.t_fBase.whichrankModgvec_Fbase.t_fBase.x_ipModgvec_Fbase.t_fBase.xmnModgvec_Fbase.t_fBase.zero_odd_evenModgvec_Fbase.t_fBase.zeta_ip
Modgvec_NewtonModgvec_Newton.FR()Modgvec_Newton.FRdFR()Modgvec_Newton.c_newton_Min1DModgvec_Newton.c_newton_Min2DModgvec_Newton.c_newton_Root1DModgvec_Newton.c_newton_Root1D_FdFModgvec_Newton.c_newton_Root2DModgvec_Newton.dFR()Modgvec_Newton.ddFR()Modgvec_Newton.dfr()Modgvec_Newton.fr()Modgvec_Newton.newtonmin1d()Modgvec_Newton.newtonmin2d()Modgvec_Newton.newtonroot1d()Modgvec_Newton.newtonroot1d_fdf()Modgvec_Newton.newtonroot2d()Modgvec_Newton.t_newton_Root1D_wrap_Min1D
Modgvec_Py_BindingModgvec_Py_RunModgvec_Py_StateModgvec_Py_State.evaluate_base_list_stz_all()Modgvec_Py_State.evaluate_base_list_tz()Modgvec_Py_State.evaluate_base_list_tz_all()Modgvec_Py_State.evaluate_base_tens()Modgvec_Py_State.evaluate_base_tens_all()Modgvec_Py_State.evaluate_boozer_list_tz_all()Modgvec_Py_State.evaluate_hmap()Modgvec_Py_State.evaluate_hmap_derivs()Modgvec_Py_State.evaluate_hmap_only()Modgvec_Py_State.evaluate_hmap_only_pw()Modgvec_Py_State.evaluate_hmap_pw()Modgvec_Py_State.evaluate_jac_h_derivs()Modgvec_Py_State.evaluate_jac_h_derivs_pw()Modgvec_Py_State.evaluate_metric_derivs()Modgvec_Py_State.evaluate_profile()Modgvec_Py_State.evaluate_rho2_profile()Modgvec_Py_State.finalize()Modgvec_Py_State.find_pest_angles_2d()Modgvec_Py_State.get_boozer()Modgvec_Py_State.get_initialized()Modgvec_Py_State.get_integration_points()Modgvec_Py_State.get_integration_points_num()Modgvec_Py_State.get_mn_ip()Modgvec_Py_State.get_mn_max()Modgvec_Py_State.get_modes()Modgvec_Py_State.get_nfp()Modgvec_Py_State.get_s_ip()Modgvec_Py_State.get_s_nbase()Modgvec_Py_State.init()Modgvec_Py_State.init_boozer()Modgvec_Py_State.initializedModgvec_Py_State.initsolution()Modgvec_Py_State.minimize()Modgvec_Py_State.nfpModgvec_Py_State.readstate()Modgvec_Py_State.set_initialized()Modgvec_Py_State.set_nfp()
Modgvec_Rprofile_BaseModgvec_Rprofile_Base.antiderivative()Modgvec_Rprofile_Base.c_rProfileModgvec_Rprofile_Base.c_rProfile.antiderivative()Modgvec_Rprofile_Base.c_rProfile.coefsModgvec_Rprofile_Base.c_rProfile.eval_at_rho()Modgvec_Rprofile_Base.c_rProfile.eval_at_rho2()Modgvec_Rprofile_Base.c_rProfile.n_coefsModgvec_Rprofile_Base.c_rProfile.rprofile_drho2()Modgvec_Rprofile_Base.c_rProfile.rprofile_drho3()Modgvec_Rprofile_Base.c_rProfile.rprofile_drho4()
Modgvec_Rprofile_Base.eval_at_rho()Modgvec_Rprofile_Base.eval_at_rho2()Modgvec_Rprofile_Base.poly_derivative_prefactor()Modgvec_Rprofile_Base.rho2_derivative()Modgvec_Rprofile_Base.rprofile_drho2()Modgvec_Rprofile_Base.rprofile_drho3()Modgvec_Rprofile_Base.rprofile_drho4()
Modgvec_Rprofile_BsplModgvec_Rprofile_Bspl.antiderivative()Modgvec_Rprofile_Bspl.eval_at_rho()Modgvec_Rprofile_Bspl.eval_at_rho2()Modgvec_Rprofile_Bspl.rprofile_drho2()Modgvec_Rprofile_Bspl.rprofile_drho3()Modgvec_Rprofile_Bspl.rprofile_drho4()Modgvec_Rprofile_Bspl.t_rProfile_bsplModgvec_Rprofile_Bspl.t_rProfile_bspl.antiderivative()Modgvec_Rprofile_Bspl.t_rProfile_bspl.degModgvec_Rprofile_Bspl.t_rProfile_bspl.eval_at_rho()Modgvec_Rprofile_Bspl.t_rProfile_bspl.eval_at_rho2()Modgvec_Rprofile_Bspl.t_rProfile_bspl.knotsModgvec_Rprofile_Bspl.t_rProfile_bspl.n_knotsModgvec_Rprofile_Bspl.t_rProfile_bspl.rprofile_drho2()Modgvec_Rprofile_Bspl.t_rProfile_bspl.rprofile_drho3()Modgvec_Rprofile_Bspl.t_rProfile_bspl.rprofile_drho4()
Modgvec_Rprofile_PolyModgvec_Rprofile_Poly.antiderivative()Modgvec_Rprofile_Poly.eval_at_rho()Modgvec_Rprofile_Poly.eval_at_rho2()Modgvec_Rprofile_Poly.rprofile_drho2()Modgvec_Rprofile_Poly.rprofile_drho3()Modgvec_Rprofile_Poly.rprofile_drho4()Modgvec_Rprofile_Poly.t_rProfile_polyModgvec_Rprofile_Poly.t_rProfile_poly.antiderivative()Modgvec_Rprofile_Poly.t_rProfile_poly.degModgvec_Rprofile_Poly.t_rProfile_poly.eval_at_rho()Modgvec_Rprofile_Poly.t_rProfile_poly.eval_at_rho2()Modgvec_Rprofile_Poly.t_rProfile_poly.rprofile_drho2()Modgvec_Rprofile_Poly.t_rProfile_poly.rprofile_drho3()Modgvec_Rprofile_Poly.t_rProfile_poly.rprofile_drho4()
Modgvec_Sfl_BoozerModgvec_Sfl_Boozer.find_angles()Modgvec_Sfl_Boozer.find_angles_irho()Modgvec_Sfl_Boozer.find_boozer_angles()Modgvec_Sfl_Boozer.t_sfl_boozerModgvec_Sfl_Boozer.t_sfl_boozer.find_angles()Modgvec_Sfl_Boozer.t_sfl_boozer.find_angles_irho()Modgvec_Sfl_Boozer.t_sfl_boozer.initializedModgvec_Sfl_Boozer.t_sfl_boozer.iotaModgvec_Sfl_Boozer.t_sfl_boozer.lambda_Modgvec_Sfl_Boozer.t_sfl_boozer.nrhoModgvec_Sfl_Boozer.t_sfl_boozer.nuModgvec_Sfl_Boozer.t_sfl_boozer.nu_fbaseModgvec_Sfl_Boozer.t_sfl_boozer.phiprimeModgvec_Sfl_Boozer.t_sfl_boozer.relambdaModgvec_Sfl_Boozer.t_sfl_boozer.rho_pos