From db40748a0f4a3bfed0334bdd8dc0729d770406ca Mon Sep 17 00:00:00 2001 From: Anchal Gupta Date: Tue, 17 Dec 2024 18:10:43 -0800 Subject: [PATCH] Adding back read_b2_boundary_parameters This function was removed in 0d2ef6bbc031f67875aaece81607481c64af681d to remove unregistered Fortran90Namelists dep. The usecase of reading the namelist was very specific, so this commit adds a small basic julia funciton to read the required parts of namelist and adds back this function. In future, if generic fortran namelist parser is available in Julia Registry, we will use that. --- Project.toml | 2 +- docs/src/index.md | 1 + src/parser.jl | 86 +++++++++++++++++++++++++++++++++++++++++++++-- test/runtests.jl | 40 +++++++++++----------- 4 files changed, 105 insertions(+), 24 deletions(-) diff --git a/Project.toml b/Project.toml index 7a0a832..32f6a4e 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "SOLPS2imas" uuid = "09becab6-0636-4c23-a92a-2b3723265c31" authors = ["David Eldon "] -version = "2.0.0" +version = "2.0.1" [deps] ArgParse = "c7e460c6-2fb9-53a9-8c5b-16f535851c63" diff --git a/docs/src/index.md b/docs/src/index.md index 2adb145..9c184f5 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -36,6 +36,7 @@ This module uses some parsing functions which can be used standalone as well read_b2_output read_b2mn_output read_b2time_output +read_b2_boundary_parameters ``` ## SOLPS Mesh Tools diff --git a/src/parser.jl b/src/parser.jl index 4bcd73b..505349b 100644 --- a/src/parser.jl +++ b/src/parser.jl @@ -1,4 +1,4 @@ -export read_b2_output, read_b2mn_output, read_b2time_output # , read_b2_boundary_parameters +export read_b2_output, read_b2mn_output, read_b2time_output, read_b2_boundary_parameters """ read_b2time_output(filename::String)::Dict{String, Dict{String, Any}} @@ -269,8 +269,8 @@ as well as particle fluxes. Returns a dictionary of interpreted results. """ function read_b2_boundary_parameters(filename::String)::Dict{String, Any} ret_dict = Dict{String, Any}() - namelist = readnml(filename) - nbc = namelist[:boundary][:nbc] + namelist = boundary_param_readnml(filename) + nbc = namelist[:boundary][:NBC] # Sources from core ret_dict["power_electrons"] = 0.0 # W @@ -347,3 +347,83 @@ function read_b2_boundary_parameters(filename::String)::Dict{String, Any} return ret_dict end + +""" + boundary_param_readnml(filename::String)::Dict{Symbol,Dict{Symbol,Any}} + +Parse fortran namelist of boundary parameters for a small subset of supported fields: +:NBC, :BCCHAR, :BCPOS, :BCSTART, :BCEND, :BCENE, :BCENI, :ENEPAR, :ENIPAR, :GAMMAE, :GAMMAI + +This function should be replaced with a generic fortran namelist parser if one becomes available in julia registry +""" +function boundary_param_readnml(filename::String)::Dict{Symbol, Dict{Symbol, Any}} + supported_fields = [ + :NBC, + :BCCHAR, + :BCPOS, + :BCSTART, + :BCEND, + :BCENE, + :BCENI, + :ENEPAR, + :ENIPAR, + :GAMMAE, + :GAMMAI, + ] + data = Dict{Symbol, Dict{Symbol, Any}}() + working_dict = data + open(filename, "r") do io + for line ∈ eachline(io) + # skip comments or empty lines + line = split(line, ";")[1] + line = split(line, "!")[1] + line = split(line, "#")[1] + line = strip(line) + if length(line) == 0 + continue + end + line = replace(line, "\$" => "&") + line = replace(line, r"^&$" => "/") + line = replace(line, "&end" => "/") + + # remove spaces + if startswith(line, '&') + sub_dir = Symbol(replace(line, "&" => "")) + data[sub_dir] = Dict{Symbol, Any}() + working_dict = data[sub_dir] + end + + if contains(line, "=") + key_values = split(line, "=") + key = Symbol(uppercase(strip(key_values[1]))) + if key in supported_fields + values = filter(e -> e != "", split(key_values[2], ",")) + if length(values) == 1 + working_dict[key] = fortran_parse(strip(values[1])) + else + working_dict[key] = + [fortran_parse(strip(value)) for value ∈ values] + end + end + end + end + end + return data +end + +""" + fortran_parse(str::AbstractString) + +Very basic and specific fortran parsing. +""" +fortran_parse(str::AbstractString) = + if contains(str, "'") + return split(str, "'")[2] + else + for types ∈ [Int64, Float64, Bool, String] + try + return parse(types, str) + catch + end + end + end diff --git a/test/runtests.jl b/test/runtests.jl index 76fca78..4d38d58 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,7 +3,7 @@ using Test using YAML: load_file as YAML_load_file using ArgParse: ArgParse using IMASdd: IMASdd -import SOLPS2imas: get_grid_subset # , read_b2_boundary_parameters +import SOLPS2imas: get_grid_subset, read_b2_boundary_parameters allowed_rtol = 1e-4 @@ -31,9 +31,9 @@ function parse_commandline() ["--fort"], Dict(:help => "Test triangular mesh generation from fort files", :action => :store_true), - # ["--namelist"], - # Dict(:help => "Test parsing of namelists", - # :action => :store_true), + ["--namelist"], + Dict(:help => "Test parsing of namelists", + :action => :store_true), ) args = ArgParse.parse_args(localARGS, s) if !any(values(args)) # If no flags are set, run all tests @@ -283,20 +283,20 @@ if args["fort"] end end -# if args["namelist"] -# @testset "Test parsing of namelists" begin -# # Basic parameters namelist parsing -# testfile = "$(@__DIR__)/../samples/b2.boundary.parameters" -# boundary_params = SOLPS2imas.read_b2_boundary_parameters(testfile) -# println(boundary_params) -# @test boundary_params["power_electrons"] > 0.0 -# @test boundary_params["power_ions"] > 0.0 -# @test boundary_params["number_of_boundaries"] > -# boundary_params["number_of_core_source_boundaries"] +if args["namelist"] + @testset "Test parsing of namelists" begin + # Basic parameters namelist parsing + testfile = "$(@__DIR__)/../samples/b2.boundary.parameters" + boundary_params = SOLPS2imas.read_b2_boundary_parameters(testfile) + println(boundary_params) + @test boundary_params["power_electrons"] > 0.0 + @test boundary_params["power_ions"] > 0.0 + @test boundary_params["number_of_boundaries"] > + boundary_params["number_of_core_source_boundaries"] -# # Using parameters namelist to populate summary data -# ids = IMASdd.dd() -# SOLPS2imas.load_summary_data!(ids, (testfile, "", "", "")) -# @test !(ismissing(ids.summary.heating_current_drive.power_ec, :value)) -# end -# end + # Using parameters namelist to populate summary data + ids = IMASdd.dd() + SOLPS2imas.load_summary_data!(ids, (testfile, "", "", "")) + @test !(ismissing(ids.summary.heating_current_drive.power_ec, :value)) + end +end