From dbe3b026e223a996dd9d7c0573946d70bfa76f44 Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Thu, 14 Nov 2024 21:54:06 +0000 Subject: [PATCH] build based on d81fa75 --- dev/.documenter-siteinfo.json | 2 +- dev/api/index.html | 4 +- dev/assets/documenter.js | 302 ++++++++++++++++++---------------- dev/index.html | 2 +- dev/license/index.html | 2 +- dev/notice/index.html | 2 +- 6 files changed, 166 insertions(+), 148 deletions(-) diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 4a4ecd6..a97f2a1 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.11.1","generation_timestamp":"2024-10-27T06:06:59","documenter_version":"1.7.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.11.1","generation_timestamp":"2024-11-14T21:54:01","documenter_version":"1.8.0"}} \ No newline at end of file diff --git a/dev/api/index.html b/dev/api/index.html index 152440d..8cb556a 100644 --- a/dev/api/index.html +++ b/dev/api/index.html @@ -3,6 +3,6 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-65D8V8C8VQ', {'page_path': location.pathname + location.search + location.hash}); -

API Reference

TJLF

TJLF.gauss_hermiteFunction
gauss_hermite(inputs::InputTJLF{T}) where T<:Real

parameters: inputs::InputTJLF{T} - InputTJLF struct constructed in tjlfreadinput.jl

outputs: OutputHermite(x,wx,h) - OutputHermite struct

description: computes abscisca's and weights for Gauss- Hermite integration adapted from Numerical Recipes in Fortran Pg.147 reversed order of roots so that x(m) is largest and x(1) is smallest only the positive roots are found and stored #––––––––––––––––––––––––––––––– initializes the hermite basis functions and ten point Gauss-Hermite integration with absissas x and weights w.

source
TJLF.get_ky_spectrumFunction
get_ky_spectrum(inputs::InputTJLF{T}, grad_r0::T)::Vector{T} where T<:Real

parameters: inputs::InputTJLF{T} - InputTJLF struct constructed in tjlfreadinput.jl gradr0::T - value from SaturationParameters struct from tjlfgeometry.jl

outputs: ky_spectrum::Vector{T} - array of floats that form the ky grid

description: the input file provides the type of kygrid to create (values 1 to 5) and this function creates it accordingly

source
TJLF.get_ky_spectrum_sizeFunction
get_ky_spectrum_size(nky::Int,kygrid_model::Int)::Int

parameters: nky::Int - nky from input file kygridmodel::Int - kygridmodel from input file

outputs: size of the ky_spectrum array

description: called before creation of InputTJLF struct to get the size of ky_spectrum

source
TJLF.get_sat_paramsFunction
get_sat_params(inputs::InputTJLF{T}; ms::Int=128) where T<:Real

parameters: inputs::InputTJLF{T} - InputTJLF struct constructed in tjlfreadinput.jl

outputs: SaturationParameters{Float64}() - SaturationParameters struct calculated

description: compute the geometric coefficients on the x-grid

location: tjlf_geometry.jl

source
TJLF.readInputFunction
readInput(baseDirectory::String)

parameter: baseDirectory::String - string of the directory (include a '\' at the end) of input.tglf (NOT input.tglf.gen)

return: inputTJLF::InputTJLF - return InputTJLF struct based off the input.tglf file

description: parse through a input.tglf file found in baseDirectory parameter, creates a inputTJLF struct and populates the fields based off the values in the file. has some check to make sure the file is written properly

source
TJLF.sum_ky_spectrumFunction
sum_ky_spectrum(inputs::InputTJLF{T},satParams::SaturationParameters{T},gamma_matrix::Matrix{T},QL::Array{T,5})where T <: Real

parameters: inputs - InputTJLF struct constructed using the input.TGLF file gammamatrix - matrix of gamma (mode, ky) QLweights - split into separate types of QL weights (field, species, mode, ky, type) type: (particle, energy, torodial stress, parallel stress, exchange) (optional) - a lot of optional parameters that I don't use -DSUN

outputs: QLfluxout - flux integral of the QL weights (field, species, type)

takes in the input.tglf file, ky values, gammas, quasilinear weights, calls
+

API Reference

TJLF

TJLF.gauss_hermiteFunction
gauss_hermite(inputs::InputTJLF{T}) where T<:Real

parameters: inputs::InputTJLF{T} - InputTJLF struct constructed in tjlfreadinput.jl

outputs: OutputHermite(x,wx,h) - OutputHermite struct

description: computes abscisca's and weights for Gauss- Hermite integration adapted from Numerical Recipes in Fortran Pg.147 reversed order of roots so that x(m) is largest and x(1) is smallest only the positive roots are found and stored #––––––––––––––––––––––––––––––– initializes the hermite basis functions and ten point Gauss-Hermite integration with absissas x and weights w.

source
TJLF.get_ky_spectrumFunction
get_ky_spectrum(inputs::InputTJLF{T}, grad_r0::T)::Vector{T} where T<:Real

parameters: inputs::InputTJLF{T} - InputTJLF struct constructed in tjlfreadinput.jl gradr0::T - value from SaturationParameters struct from tjlfgeometry.jl

outputs: ky_spectrum::Vector{T} - array of floats that form the ky grid

description: the input file provides the type of kygrid to create (values 1 to 5) and this function creates it accordingly

source
TJLF.get_ky_spectrum_sizeFunction
get_ky_spectrum_size(nky::Int,kygrid_model::Int)::Int

parameters: nky::Int - nky from input file kygridmodel::Int - kygridmodel from input file

outputs: size of the ky_spectrum array

description: called before creation of InputTJLF struct to get the size of ky_spectrum

source
TJLF.get_sat_paramsFunction
get_sat_params(inputs::InputTJLF{T}; ms::Int=128) where T<:Real

parameters: inputs::InputTJLF{T} - InputTJLF struct constructed in tjlfreadinput.jl

outputs: SaturationParameters{Float64}() - SaturationParameters struct calculated

description: compute the geometric coefficients on the x-grid

location: tjlf_geometry.jl

source
TJLF.readInputFunction
readInput(baseDirectory::String)

parameter: baseDirectory::String - string of the directory (include a '\' at the end) of input.tglf (NOT input.tglf.gen)

return: inputTJLF::InputTJLF - return InputTJLF struct based off the input.tglf file

description: parse through a input.tglf file found in baseDirectory parameter, creates a inputTJLF struct and populates the fields based off the values in the file. has some check to make sure the file is written properly

source
TJLF.sum_ky_spectrumFunction
sum_ky_spectrum(inputs::InputTJLF{T},satParams::SaturationParameters{T},gamma_matrix::Matrix{T},QL::Array{T,5})where T <: Real

parameters: inputs - InputTJLF struct constructed using the input.TGLF file gammamatrix - matrix of gamma (mode, ky) QLweights - split into separate types of QL weights (field, species, mode, ky, type) type: (particle, energy, torodial stress, parallel stress, exchange) (optional) - a lot of optional parameters that I don't use -DSUN

outputs: QLfluxout - flux integral of the QL weights (field, species, type)

takes in the input.tglf file, ky values, gammas, quasilinear weights, calls
 intensity_sat() which returns the QL intensity values, then calls
-flux_integrals() which numerically integrates the fluxes
source
TJLF.tjlf_TMFunction
tjlf_TM(inputs::InputTJLF{T},satParams::SaturationParameters{T},outputHermite::OutputHermite{T}) where T<:Real

parameters: inputs::InputTJLF{T} - InputTJLF struct constructed in tjlfreadinput.jl satParams::SaturationParameters{T} - SaturationParameters struct constructed in tjlfgeometry.jl outputHermite::OutputHermite{T} - OutputHermite struct constructed in tjlfhermite.jl

outputs: QLweights - 5d array of QL weights (field, species, mode, ky, type), type: (particle, energy, torodial stress, parallel stress, exchange) firstPasseigenvalue - 3d array of eigenvalues (mode, ky, type) type: (gamma, frequency)

description: Main transport model function. Calls linear TGLF over a spectrum of ky's and computes spectral integrals of field, intensity, and fluxes.

source
TJLF.xgrid_functions_geoFunction
xgrid_functions_geo(inputs::InputTJLF{T}, satParams::SaturationParameters{T}, gamma_matrix::Matrix{T};small::T=0.00000001)

parameters: inputs::InputTJLF{T} - InputTJLF struct constructed in tjlfreadinput.jl satParams::SaturationParameters{T} - SaturationParameters struct constructed in tjlfgeometry.jl gammamatrix::Vector{T} - growth rate eigenvalues for each mode

outputs: kx0e - value of kx0e for tge given gamma value

description: calculate kx0_e (spectral shift) given the growthrate used for the second pass of TM

location: tjlf_geometry.jl

source
xgrid_functions_geo(inputs::InputTJLF{T}, satParams::SaturationParameters{T}, outHermite::OutputHermite{T}, ky::T, ky_index::Int; kx0_e::T=NaN, ms::Int=128)

parameters: inputs::InputTJLF{T} - InputTJLF struct constructed in tjlfreadinput.jl satParams::SaturationParameters{T} - SaturationParameters struct constructed in tjlfgeometry.jl outputHermite::OutputHermite{T} - OutputHermite struct constructed in tjlfhermite.jl ky::T - ky value kyindex::Int - index used for multithreading kx0e::T=NaN - spectral shift provided for second pass

outputs: OutputGeometry{Float64}() - OutputGeometry struct for different WIDTHS value

description: create the OutputGeometry struct for the specific WIDTHS value used to calculate Ave structs (tjlf_matrix.jl) used in eigenmatrix population

location: tjlf_geometry.jl

source
+flux_integrals() which numerically integrates the fluxes
source
TJLF.tjlf_TMFunction
tjlf_TM(inputs::InputTJLF{T},satParams::SaturationParameters{T},outputHermite::OutputHermite{T}) where T<:Real

parameters: inputs::InputTJLF{T} - InputTJLF struct constructed in tjlfreadinput.jl satParams::SaturationParameters{T} - SaturationParameters struct constructed in tjlfgeometry.jl outputHermite::OutputHermite{T} - OutputHermite struct constructed in tjlfhermite.jl

outputs: QLweights - 5d array of QL weights (field, species, mode, ky, type), type: (particle, energy, torodial stress, parallel stress, exchange) firstPasseigenvalue - 3d array of eigenvalues (mode, ky, type) type: (gamma, frequency)

description: Main transport model function. Calls linear TGLF over a spectrum of ky's and computes spectral integrals of field, intensity, and fluxes.

source
TJLF.xgrid_functions_geoFunction
xgrid_functions_geo(inputs::InputTJLF{T}, satParams::SaturationParameters{T}, gamma_matrix::Matrix{T};small::T=0.00000001)

parameters: inputs::InputTJLF{T} - InputTJLF struct constructed in tjlfreadinput.jl satParams::SaturationParameters{T} - SaturationParameters struct constructed in tjlfgeometry.jl gammamatrix::Vector{T} - growth rate eigenvalues for each mode

outputs: kx0e - value of kx0e for tge given gamma value

description: calculate kx0_e (spectral shift) given the growthrate used for the second pass of TM

location: tjlf_geometry.jl

source
xgrid_functions_geo(inputs::InputTJLF{T}, satParams::SaturationParameters{T}, outHermite::OutputHermite{T}, ky::T, ky_index::Int; kx0_e::T=NaN, ms::Int=128)

parameters: inputs::InputTJLF{T} - InputTJLF struct constructed in tjlfreadinput.jl satParams::SaturationParameters{T} - SaturationParameters struct constructed in tjlfgeometry.jl outputHermite::OutputHermite{T} - OutputHermite struct constructed in tjlfhermite.jl ky::T - ky value kyindex::Int - index used for multithreading kx0e::T=NaN - spectral shift provided for second pass

outputs: OutputGeometry{Float64}() - OutputGeometry struct for different WIDTHS value

description: create the OutputGeometry struct for the specific WIDTHS value used to calculate Ave structs (tjlf_matrix.jl) used in eigenmatrix population

location: tjlf_geometry.jl

source
diff --git a/dev/assets/documenter.js b/dev/assets/documenter.js index 82252a1..7d68cd8 100644 --- a/dev/assets/documenter.js +++ b/dev/assets/documenter.js @@ -612,176 +612,194 @@ function worker_function(documenterSearchIndex, documenterBaseURL, filters) { }; } -// `worker = Threads.@spawn worker_function(documenterSearchIndex)`, but in JavaScript! -const filters = [ - ...new Set(documenterSearchIndex["docs"].map((x) => x.category)), -]; -const worker_str = - "(" + - worker_function.toString() + - ")(" + - JSON.stringify(documenterSearchIndex["docs"]) + - "," + - JSON.stringify(documenterBaseURL) + - "," + - JSON.stringify(filters) + - ")"; -const worker_blob = new Blob([worker_str], { type: "text/javascript" }); -const worker = new Worker(URL.createObjectURL(worker_blob)); - /////// SEARCH MAIN /////// -// Whether the worker is currently handling a search. This is a boolean -// as the worker only ever handles 1 or 0 searches at a time. -var worker_is_running = false; - -// The last search text that was sent to the worker. This is used to determine -// if the worker should be launched again when it reports back results. -var last_search_text = ""; - -// The results of the last search. This, in combination with the state of the filters -// in the DOM, is used compute the results to display on calls to update_search. -var unfiltered_results = []; - -// Which filter is currently selected -var selected_filter = ""; - -$(document).on("input", ".documenter-search-input", function (event) { - if (!worker_is_running) { - launch_search(); - } -}); - -function launch_search() { - worker_is_running = true; - last_search_text = $(".documenter-search-input").val(); - worker.postMessage(last_search_text); -} - -worker.onmessage = function (e) { - if (last_search_text !== $(".documenter-search-input").val()) { - launch_search(); - } else { - worker_is_running = false; - } - - unfiltered_results = e.data; - update_search(); -}; +function runSearchMainCode() { + // `worker = Threads.@spawn worker_function(documenterSearchIndex)`, but in JavaScript! + const filters = [ + ...new Set(documenterSearchIndex["docs"].map((x) => x.category)), + ]; + const worker_str = + "(" + + worker_function.toString() + + ")(" + + JSON.stringify(documenterSearchIndex["docs"]) + + "," + + JSON.stringify(documenterBaseURL) + + "," + + JSON.stringify(filters) + + ")"; + const worker_blob = new Blob([worker_str], { type: "text/javascript" }); + const worker = new Worker(URL.createObjectURL(worker_blob)); + + // Whether the worker is currently handling a search. This is a boolean + // as the worker only ever handles 1 or 0 searches at a time. + var worker_is_running = false; + + // The last search text that was sent to the worker. This is used to determine + // if the worker should be launched again when it reports back results. + var last_search_text = ""; + + // The results of the last search. This, in combination with the state of the filters + // in the DOM, is used compute the results to display on calls to update_search. + var unfiltered_results = []; + + // Which filter is currently selected + var selected_filter = ""; + + $(document).on("input", ".documenter-search-input", function (event) { + if (!worker_is_running) { + launch_search(); + } + }); -$(document).on("click", ".search-filter", function () { - if ($(this).hasClass("search-filter-selected")) { - selected_filter = ""; - } else { - selected_filter = $(this).text().toLowerCase(); + function launch_search() { + worker_is_running = true; + last_search_text = $(".documenter-search-input").val(); + worker.postMessage(last_search_text); } - // This updates search results and toggles classes for UI: - update_search(); -}); + worker.onmessage = function (e) { + if (last_search_text !== $(".documenter-search-input").val()) { + launch_search(); + } else { + worker_is_running = false; + } -/** - * Make/Update the search component - */ -function update_search() { - let querystring = $(".documenter-search-input").val(); + unfiltered_results = e.data; + update_search(); + }; - if (querystring.trim()) { - if (selected_filter == "") { - results = unfiltered_results; + $(document).on("click", ".search-filter", function () { + if ($(this).hasClass("search-filter-selected")) { + selected_filter = ""; } else { - results = unfiltered_results.filter((result) => { - return selected_filter == result.category.toLowerCase(); - }); + selected_filter = $(this).text().toLowerCase(); } - let search_result_container = ``; - let modal_filters = make_modal_body_filters(); - let search_divider = `
`; + // This updates search results and toggles classes for UI: + update_search(); + }); - if (results.length) { - let links = []; - let count = 0; - let search_results = ""; - - for (var i = 0, n = results.length; i < n && count < 200; ++i) { - let result = results[i]; - if (result.location && !links.includes(result.location)) { - search_results += result.div; - count++; - links.push(result.location); - } - } + /** + * Make/Update the search component + */ + function update_search() { + let querystring = $(".documenter-search-input").val(); - if (count == 1) { - count_str = "1 result"; - } else if (count == 200) { - count_str = "200+ results"; + if (querystring.trim()) { + if (selected_filter == "") { + results = unfiltered_results; } else { - count_str = count + " results"; + results = unfiltered_results.filter((result) => { + return selected_filter == result.category.toLowerCase(); + }); } - let result_count = `
${count_str}
`; - search_result_container = ` + let search_result_container = ``; + let modal_filters = make_modal_body_filters(); + let search_divider = `
`; + + if (results.length) { + let links = []; + let count = 0; + let search_results = ""; + + for (var i = 0, n = results.length; i < n && count < 200; ++i) { + let result = results[i]; + if (result.location && !links.includes(result.location)) { + search_results += result.div; + count++; + links.push(result.location); + } + } + + if (count == 1) { + count_str = "1 result"; + } else if (count == 200) { + count_str = "200+ results"; + } else { + count_str = count + " results"; + } + let result_count = `
${count_str}
`; + + search_result_container = ` +
+ ${modal_filters} + ${search_divider} + ${result_count} +
+ ${search_results} +
+
+ `; + } else { + search_result_container = `
${modal_filters} ${search_divider} - ${result_count} -
- ${search_results} -
-
+
0 result(s)
+ +
No result found!
`; - } else { - search_result_container = ` -
- ${modal_filters} - ${search_divider} -
0 result(s)
-
-
No result found!
- `; - } + } - if ($(".search-modal-card-body").hasClass("is-justify-content-center")) { - $(".search-modal-card-body").removeClass("is-justify-content-center"); - } + if ($(".search-modal-card-body").hasClass("is-justify-content-center")) { + $(".search-modal-card-body").removeClass("is-justify-content-center"); + } - $(".search-modal-card-body").html(search_result_container); - } else { - if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { - $(".search-modal-card-body").addClass("is-justify-content-center"); + $(".search-modal-card-body").html(search_result_container); + } else { + if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { + $(".search-modal-card-body").addClass("is-justify-content-center"); + } + + $(".search-modal-card-body").html(` +
Type something to get started!
+ `); } + } - $(".search-modal-card-body").html(` -
Type something to get started!
- `); + /** + * Make the modal filter html + * + * @returns string + */ + function make_modal_body_filters() { + let str = filters + .map((val) => { + if (selected_filter == val.toLowerCase()) { + return `${val}`; + } else { + return `${val}`; + } + }) + .join(""); + + return ` +
+ Filters: + ${str} +
`; } } -/** - * Make the modal filter html - * - * @returns string - */ -function make_modal_body_filters() { - let str = filters - .map((val) => { - if (selected_filter == val.toLowerCase()) { - return `${val}`; - } else { - return `${val}`; - } - }) - .join(""); - - return ` -
- Filters: - ${str} -
`; +function waitUntilSearchIndexAvailable() { + // It is possible that the documenter.js script runs before the page + // has finished loading and documenterSearchIndex gets defined. + // So we need to wait until the search index actually loads before setting + // up all the search-related stuff. + if (typeof documenterSearchIndex !== "undefined") { + runSearchMainCode(); + } else { + console.warn("Search Index not available, waiting"); + setTimeout(waitUntilSearchIndexAvailable, 1000); + } } +// The actual entry point to the search code +waitUntilSearchIndexAvailable(); + }) //////////////////////////////////////////////////////////////////////////////// require(['jquery'], function($) { diff --git a/dev/index.html b/dev/index.html index 33d23da..613b48e 100644 --- a/dev/index.html +++ b/dev/index.html @@ -17,4 +17,4 @@ | | gsev!() | TGLF | | | | | robust, | | | | | thread scales! | | -+--------------+---------+-----------------+-------------------+

To run top left, set the InputTJLF SMALL parameter = 0.0, set FINDEIGEN = False<br> To run mid left, use the default InputTJLF SMALL parameter = 1e-13<br> To run top right, set the InputTJLF SMALL parameter = 0.0, set FINDEIGEN = True<br>

Arpack.jl

NOTE, If you are getting:<br> <pre> Error: XYAUPD_Exception: Maximum number of iterations taken. All possible eigenvalues of OP has been found.<br> │ IPARAM(5) returns the number of wanted converged Ritz values.<br> │ info = 1</pre>

Make sure you are using Arpack v0.5.3 and NOT v0.5.4, the current version does not work. You might have to restart your Julia enviroment, activate TJLF, and build.

Also, Arpack.jl's eigs() is NOT thread safe. I have locks in the code to keep things safe. In the future, GenericArpack.jl should provide a pure Julia version of the Arpack algorithm that is thread safe, but it is still under development and seems to be a ways off.

Indices of Arrays

There are some 3D and 5D arrays where the indices are not obvious. They are specified in the function comments where they appear, but I will repeat them here:<br> <pre>QLweights::Array{5} - [field, species, mode, ky, type]<br> type: (particle, energy, torodial stress, parallel stress, exchange)</pre><br> <pre>fluxspectrum::Array{5} - [field, species, mode, ky, type]<br> type: (particle, energy, torodial stress, parallel stress, exchange)</pre><br> <pre>eigenvalue::Array{3} - [mode, ky, type]<br> type: (gamma, frequency)</pre><br> <pre>QLfluxout::Array{3} - [field, species, type]<br> type: (particle, energy, torodial stress, parallel stress, exchange)</pre><br> <pre>"Output of run_tjlf()"::Array{2} - [species, type]<br> type: (particle, energy, torodial stress, parallel stress, exchange)</pre><br> <pre>species: 1 = electron, 2+ = ions</pre><br> <pre>modes: 1 = most unstable</pre> The order of the indices try to take advantage of Julia's column major memory usage

Multithreading

If you are multithreading, make sure BLAS.setnumthreads(1) is set at some point.

Bash Folder

Wrote a Bash script for testing how number of threads affects speed. Currently it is testing on the seven radial points Tim gave me found in outputs/TIM_test/. You call the executable followed by command line arguements. If you give one number, it gives you the @btime with that number of threads. If you give two numbers, it gives you the @btime looping through those two numbers. If you give three or more numbers, it gives you the @btime for each number in the arguments. I currently don't have any implementation to test the threading speed on other test cases, but you can pretty easily copy my Julia script to meet whatever you need.

Other Notes from DSUN

For SAT0, TM() does not return the value of QLweights (aka "QLfluxspectrumout" in TGLF) and instead returns the value of what TGLF refers to as fluxspectrumout. This is because the saturation rule calculation is done in a different place (LS.jl instead of multiscalespectrum.jl), and otherwise, I would have to pass this extra Array through multiple functions just for SAT0 which is tedious and ugly. Plus SAT0 isn't really used apparently. So, if you are trying to compare the QLweights for a SAT0 run, make sure you keep this in mind.

The name of the SaturationParameters struct is probably not a great struct name since it doesn't really relate to the saturation rules at all and instead are more related to the Miller Geometry, not sure what a better name would be since OutputGeometry is already used.

Currently, InputTJLF's IFLUX parameter tells the code whether it is going to calculate eigenvectors. This is bad and I should probably change it into a local variable instead of a struct parameter. Ran into an issue multithreading with onePass() since it changes IFLUX in the middle of its function. The code is currently fixed with an extra "find_eigenvector" variable, but this should just be the standard IMO. I will try and implement this before I leave and delete the IFLUX parameter, but if this is still in the README I have not done it yet.

Online documentation

For more details, see the online documentation.

Docs

Citation

If this software contributes to an academic publication, please cite it as follows:

T.F. Neiser, D. Sun, B. Agnew, T. Slendebroek, O. Meneghini, B.C. Lyons, A. Ghiozzi, J. McClenaghan, G. Staebler and J. Candy, TJLF: The quasi-linear model of gyrokinetic transport TGLF translated to Julia, APS Meeting Abstracts (2024)

++--------------+---------+-----------------+-------------------+

To run top left, set the InputTJLF SMALL parameter = 0.0, set FINDEIGEN = False<br> To run mid left, use the default InputTJLF SMALL parameter = 1e-13<br> To run top right, set the InputTJLF SMALL parameter = 0.0, set FINDEIGEN = True<br>

Arpack.jl

NOTE, If you are getting:<br> <pre> Error: XYAUPD_Exception: Maximum number of iterations taken. All possible eigenvalues of OP has been found.<br> │ IPARAM(5) returns the number of wanted converged Ritz values.<br> │ info = 1</pre>

Make sure you are using Arpack v0.5.3 and NOT v0.5.4, the current version does not work. You might have to restart your Julia enviroment, activate TJLF, and build.

Also, Arpack.jl's eigs() is NOT thread safe. I have locks in the code to keep things safe. In the future, GenericArpack.jl should provide a pure Julia version of the Arpack algorithm that is thread safe, but it is still under development and seems to be a ways off.

Indices of Arrays

There are some 3D and 5D arrays where the indices are not obvious. They are specified in the function comments where they appear, but I will repeat them here:<br> <pre>QLweights::Array{5} - [field, species, mode, ky, type]<br> type: (particle, energy, torodial stress, parallel stress, exchange)</pre><br> <pre>fluxspectrum::Array{5} - [field, species, mode, ky, type]<br> type: (particle, energy, torodial stress, parallel stress, exchange)</pre><br> <pre>eigenvalue::Array{3} - [mode, ky, type]<br> type: (gamma, frequency)</pre><br> <pre>QLfluxout::Array{3} - [field, species, type]<br> type: (particle, energy, torodial stress, parallel stress, exchange)</pre><br> <pre>"Output of run_tjlf()"::Array{2} - [species, type]<br> type: (particle, energy, torodial stress, parallel stress, exchange)</pre><br> <pre>species: 1 = electron, 2+ = ions</pre><br> <pre>modes: 1 = most unstable</pre> The order of the indices try to take advantage of Julia's column major memory usage

Multithreading

If you are multithreading, make sure BLAS.setnumthreads(1) is set at some point.

Bash Folder

Wrote a Bash script for testing how number of threads affects speed. Currently it is testing on the seven radial points Tim gave me found in outputs/TIM_test/. You call the executable followed by command line arguements. If you give one number, it gives you the @btime with that number of threads. If you give two numbers, it gives you the @btime looping through those two numbers. If you give three or more numbers, it gives you the @btime for each number in the arguments. I currently don't have any implementation to test the threading speed on other test cases, but you can pretty easily copy my Julia script to meet whatever you need.

Other Notes from DSUN

For SAT0, TM() does not return the value of QLweights (aka "QLfluxspectrumout" in TGLF) and instead returns the value of what TGLF refers to as fluxspectrumout. This is because the saturation rule calculation is done in a different place (LS.jl instead of multiscalespectrum.jl), and otherwise, I would have to pass this extra Array through multiple functions just for SAT0 which is tedious and ugly. Plus SAT0 isn't really used apparently. So, if you are trying to compare the QLweights for a SAT0 run, make sure you keep this in mind.

The name of the SaturationParameters struct is probably not a great struct name since it doesn't really relate to the saturation rules at all and instead are more related to the Miller Geometry, not sure what a better name would be since OutputGeometry is already used.

Currently, InputTJLF's IFLUX parameter tells the code whether it is going to calculate eigenvectors. This is bad and I should probably change it into a local variable instead of a struct parameter. Ran into an issue multithreading with onePass() since it changes IFLUX in the middle of its function. The code is currently fixed with an extra "find_eigenvector" variable, but this should just be the standard IMO. I will try and implement this before I leave and delete the IFLUX parameter, but if this is still in the README I have not done it yet.

Online documentation

For more details, see the online documentation.

Docs

Citation

If this software contributes to an academic publication, please cite it as follows:

T.F. Neiser, D. Sun, B. Agnew, T. Slendebroek, O. Meneghini, B.C. Lyons, A. Ghiozzi, J. McClenaghan, G. Staebler and J. Candy, TJLF: The quasi-linear model of gyrokinetic transport TGLF translated to Julia, APS Meeting Abstracts (2024)

diff --git a/dev/license/index.html b/dev/license/index.html index ed3f16f..5d4792f 100644 --- a/dev/license/index.html +++ b/dev/license/index.html @@ -12,4 +12,4 @@ comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier - identification within third-party archives.

Copyright 2024 General Atomics

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

+ identification within third-party archives.

Copyright 2024 General Atomics

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

diff --git a/dev/notice/index.html b/dev/notice/index.html index 51b1158..0e06673 100644 --- a/dev/notice/index.html +++ b/dev/notice/index.html @@ -3,4 +3,4 @@ function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-65D8V8C8VQ', {'page_path': location.pathname + location.search + location.hash}); -

TJLF.jl Notice

The purpose of this NOTICE file is to provide legal notices and acknowledgments that must be displayed to users in any derivative works or distributions. This file does not alter the terms of the Apache 2.0 license that governs the use and distribution of the TJLF.jl package.

Development Attribution

TJLF.jl was originally developed under the GA Theory division of the Magnetic Fusion Energy group at General Atomics. This work is supported by the U.S. DOE under DE-FG02-95ER54309 (GA Theory) and the DOE Office of Workforce Development for Teachers and Scientists (WDTS) under the Science Undergraduate Laboratory Internships (SULI) program and used computational resources of NERSC (DOE-AC02-05CH11231).

Citation

If this software contributes to an academic publication, please cite it as follows:

T.F. Neiser, D. Sun, B. Agnew, T. Slendebroek, O. Meneghini, B.C. Lyons, A. Ghiozzi, J. McClenaghan, G. Staebler and J. Candy, TJLF: The quasi-linear model of gyrokinetic transport TGLF translated to Julia, APS Meeting Abstracts (2024)

Trademark Notice

The names "General Atomics", and any associated logos or images, are trademarks of General Atomics. Use of these trademarks without prior written consent from General Atomics is strictly prohibited. Users cannot imply endorsement by General Atomics or contributors to the project simply because the project is part of their work.

Copyright (c) 2024 General Atomics

Version

Version: v1.0

+

TJLF.jl Notice

The purpose of this NOTICE file is to provide legal notices and acknowledgments that must be displayed to users in any derivative works or distributions. This file does not alter the terms of the Apache 2.0 license that governs the use and distribution of the TJLF.jl package.

Development Attribution

TJLF.jl was originally developed under the GA Theory division of the Magnetic Fusion Energy group at General Atomics. This work is supported by the U.S. DOE under DE-FG02-95ER54309 (GA Theory) and the DOE Office of Workforce Development for Teachers and Scientists (WDTS) under the Science Undergraduate Laboratory Internships (SULI) program and used computational resources of NERSC (DOE-AC02-05CH11231).

Citation

If this software contributes to an academic publication, please cite it as follows:

T.F. Neiser, D. Sun, B. Agnew, T. Slendebroek, O. Meneghini, B.C. Lyons, A. Ghiozzi, J. McClenaghan, G. Staebler and J. Candy, TJLF: The quasi-linear model of gyrokinetic transport TGLF translated to Julia, APS Meeting Abstracts (2024)

Trademark Notice

The names "General Atomics", and any associated logos or images, are trademarks of General Atomics. Use of these trademarks without prior written consent from General Atomics is strictly prohibited. Users cannot imply endorsement by General Atomics or contributors to the project simply because the project is part of their work.

Copyright (c) 2024 General Atomics

Version

Version: v1.0