Skip to content

Commit

Permalink
Merge pull request #11 from ProjectTorreyPines/format
Browse files Browse the repository at this point in the history
Adds a format check using a configuration file and a GitHub Action to check format on push and PR with master and dev branches. The configuration file `.JuliaFormatter.toml` and the github workflow file `.github/workflows/format_check.yml` can be copied as it is to any other GitHub repo to recreate the same functionality.
  • Loading branch information
anchal-physics authored Sep 21, 2023
2 parents b31810e + 0c7036c commit b9e5372
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 102 deletions.
27 changes: 27 additions & 0 deletions .JuliaFormatter.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
align_assignment = true
align_conditional = true
align_matrix = true
align_pair_arrow = true
align_struct_field = true
always_for_in = true
always_use_return = true
annotate_untyped_fields_with_any = false
conditional_to_if = true
for_in_replacement = ""
format_docstrings = true
import_to_using = true
indent = 4
indent_submodule = true
join_lines_based_on_source = true
long_to_short_function_def = true
margin = 88
normalize_line_endings = "unix"
pipe_to_function_call = true
remove_extra_newlines = true
separate_kwargs_with_semicolon = true
surround_whereop_typeparameters = true
trailing_comma = true
whitespace_in_kwargs = false
whitespace_ops_in_indices = false
whitespace_typedefs = true
yas_style_nesting = true
36 changes: 36 additions & 0 deletions .github/workflows/format_check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Format Check

on:
push:
branches: ["master", "dev", "format"]
pull_request:
branches: ["master", "dev"]
jobs:
check:
runs-on: ${{ matrix.os }}
strategy:
matrix:
julia-version: [1.9.3]
julia-arch: [x86]
os: [ubuntu-latest]
steps:
- uses: julia-actions/setup-julia@latest
with:
version: ${{ matrix.julia-version }}

- uses: actions/checkout@v1
- name: Install JuliaFormatter and format
run: |
julia -e 'using Pkg; Pkg.add(PackageSpec(name="JuliaFormatter"))'
julia -e 'using JuliaFormatter; format(".", verbose=true)'
- name: Format check
run: |
julia -e '
out = Cmd(`git diff --name-only`) |> read |> String
if out == ""
exit(0)
else
@error "Some files have not been formatted !!!"
write(stdout, out)
exit(1)
end'
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# GGDUtils

![Format Check](https://github.com/ProjectTorreyPines/GGDUtils.jl/actions/workflows/format_check.yml/badge.svg)

Package holding utilities for Generalized Grid Description (GGD) objects in IMAS datastructure. Primary goals are interpolation and core profile extrapolation.
151 changes: 86 additions & 65 deletions src/GGDUtils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,60 @@ module GGDUtils
import NearestNeighbors: KDTree, knn
import StaticArrays: SVector
import Statistics: mean
import OMAS
using OMAS: OMAS
import SOLPS2IMAS: get_subset_space, get_grid_subset_with_index
using RecipesBase
import ColorSchemes
using ColorSchemes: ColorSchemes

export interp
export get_kdtree
export project_prop_on_subset!


include("recipes.jl")


function get_kdtree(space::OMAS.edge_profiles__grid_ggd___space)
grid_nodes = space.objects_per_dimension[1].object
grid_faces = space.objects_per_dimension[3].object
grid_faces = [cell for cell in grid_faces if length(cell.nodes) == 4]
grid_centers = [SVector{2}(mean([grid_nodes[node].geometry for node in cell.nodes])) for cell in grid_faces]
grid_faces = [cell for cell grid_faces if length(cell.nodes) == 4]
grid_centers = [
SVector{2}(mean([grid_nodes[node].geometry for node cell.nodes])) for
cell grid_faces
]
return KDTree(grid_centers; leafsize=10)
end


function interp(prop, kdtree::KDTree)
function get_interp_val(x::Number, y::Number)
nearest_indices, distances = knn(kdtree, Array([x, y]), 4)
v1, v2, v3, v4 = [prop.values[ii] for ii in nearest_indices]
v1, v2, v3, v4 = [prop.values[ii] for ii nearest_indices]
d1, d2, d3, d4 = distances
return ((v1 * d2 * d3 * d4 + d1 * v2 * d3 * d4
+ d1 * d2 * v3 * d4 + d1 * d2 * d3 * v4)
/
(d2 * d3 * d4 + d1 * d3 * d4
+ d1 * d2 * d4 + d1 * d2 * d3))
return (
(
v1 * d2 * d3 * d4 + d1 * v2 * d3 * d4
+ d1 * d2 * v3 * d4 + d1 * d2 * d3 * v4
)
/
(d2 * d3 * d4 + d1 * d3 * d4
+ d1 * d2 * d4 + d1 * d2 * d3)
)
end
function get_interp_val(x::Vector{Float64}, y::Vector{Float64})
if length(x) != length(y)
error("Length of the two axes are not equal")
else
return [get_interp_val(x[ii], y[ii]) for ii in eachindex(x)]
return [get_interp_val(x[ii], y[ii]) for ii eachindex(x)]
end
end
function get_interp_val(xy::Vector{Tuple{Float64, Float64}})
return [get_interp_val(xy[ii]...) for ii in eachindex(xy)]
return [get_interp_val(xy[ii]...) for ii eachindex(xy)]
end
return get_interp_val
end


function interp(prop, space::OMAS.edge_profiles__grid_ggd___space)
return interp(prop, get_kdtree(space))
end


"""
get_subset_centers(space::OMAS.edge_profiles__grid_ggd___space,
subset::OMAS.edge_profiles__grid_ggd___grid_subset)
Expand All @@ -66,50 +68,64 @@ function get_subset_centers(space::OMAS.edge_profiles__grid_ggd___space,
subset::OMAS.edge_profiles__grid_ggd___grid_subset)
subset_space = get_subset_space(space, subset.element)
grid_nodes = space.objects_per_dimension[1].object
return [Tuple(mean([grid_nodes[node].geometry for node in obj.nodes])) for obj in subset_space]
return [
Tuple(mean([grid_nodes[node].geometry for node obj.nodes])) for
obj subset_space
]
end


#! format: off
"""
project_prop_on_subset!(prop, from_subset::OMAS.edge_profiles__grid_ggd___grid_subset,
to_subset::OMAS.edge_profiles__grid_ggd___grid_subset;
space::OMAS.edge_profiles__grid_ggd___space)
project_prop_on_subset!(prop,
from_subset::OMAS.edge_profiles__grid_ggd___grid_subset,
to_subset::OMAS.edge_profiles__grid_ggd___grid_subset,
space::OMAS.edge_profiles__grid_ggd___space)
This function can be used to add another instance on a property vector representing the value
in a new subset that can be taken as a projection from an existing larger subset.
This function can be used to add another instance on a property vector representing the
value in a new subset that can be taken as a projection from an existing larger subset.
Arguments:
prop: A property like electrons.density that is a vector of objects with fields coefficients,
grid_index, grid_subset_index, and values. The different instances in the vector correspond
to different grid_subset for which the property is provided.
from_subset: grid_subset object which is already represented in the property instance. grid subset
with index 5 is populated in electrons.density already if the values for all cells are
present.
to_subset: grid_subset which is either a smaller part of from_subset (core, sol, idr, odr) but has
same dimensions as from_subset
prop: A property like electrons.density that is a vector of objects with fields
coefficients, grid_index, grid_subset_index, and values. The different instances
in the vector correspond to different grid_subset for which the property is
provided.
from_subset: grid_subset object which is already represented in the property instance.
grid subset with index 5 is populated in electrons.density already if the
values for all cells are present.
to_subset: grid_subset which is either a smaller part of from_subset (core, sol, idr,
odr) but has same dimensions as from_subset
OR
is smaller in dimension that goes through the from_subset (core_boundary, separatix etc.)
space: (optional) space object in grid_ggd is required only when from_subset is higher dimensional
than to_subset.
is smaller in dimension that goes through the from_subset (core_boundary,
separatix etc.)
space: (optional) space object in grid_ggd is required only when from_subset is
higher dimensional than to_subset.
Returns:
NOTE: This function ends in ! which means it updates prop argument in place. But for the additional
utility, this function also returns a tuple
to_subset_centers, to_prop.values (when from_subset dimension is greater than to_subset dimension)
to_subset_ele_obj_inds, to_prop.values (when from_subset dimension is same as to_subset dimension)
NOTE: This function ends in ! which means it updates prop argument in place. But for
the additional utility, this function also returns a tuple
(to_subset_centers, to_prop.values) when from_subset dimension is greater than
to_subset dimension
OR
(to_subset_ele_obj_inds, to_prop.values) when from_subset dimension is same as
to_subset dimension)
Descriptions:
to_subset_centers: center of cells or center of edges of the to_subset where property values are
defined and stored
to_subset_ele_obj_inds: Indices of the elements of to_subset where property values are deined and
stored
to_prop.values: The projected values of the properties added to prop object in a new instance
to_subset_centers: center of cells or center of edges of the to_subset where property
values are defined and stored
to_subset_ele_obj_inds: Indices of the elements of to_subset where property values are
defined and stored
to_prop.values: The projected values of the properties added to prop object in a new
instance
"""
function project_prop_on_subset!(prop, from_subset::OMAS.edge_profiles__grid_ggd___grid_subset,
to_subset::OMAS.edge_profiles__grid_ggd___grid_subset,
space::OMAS.edge_profiles__grid_ggd___space)
if from_subset.element[1].object[1].dimension == to_subset.element[1].object[1].dimension
#! format: on
function project_prop_on_subset!(prop,
from_subset::OMAS.edge_profiles__grid_ggd___grid_subset,
to_subset::OMAS.edge_profiles__grid_ggd___grid_subset,
space::OMAS.edge_profiles__grid_ggd___space)
if from_subset.element[1].object[1].dimension ==
to_subset.element[1].object[1].dimension
return project_prop_on_subset!(prop, from_subset, to_subset)
elseif from_subset.element[1].object[1].dimension > to_subset.element[1].object[1].dimension
elseif from_subset.element[1].object[1].dimension >
to_subset.element[1].object[1].dimension
from_prop = nothing
for p in prop
for p prop
if p.grid_subset_index == from_subset.identifier.index
from_prop = p
break
Expand All @@ -132,11 +148,11 @@ function project_prop_on_subset!(prop, from_subset::OMAS.edge_profiles__grid_ggd
end
end


function project_prop_on_subset!(prop, from_subset::OMAS.edge_profiles__grid_ggd___grid_subset,
to_subset::OMAS.edge_profiles__grid_ggd___grid_subset)
function project_prop_on_subset!(prop,
from_subset::OMAS.edge_profiles__grid_ggd___grid_subset,
to_subset::OMAS.edge_profiles__grid_ggd___grid_subset)
from_prop = nothing
for p in prop
for p prop
if p.grid_subset_index == from_subset.identifier.index
from_prop = p
break
Expand All @@ -145,34 +161,39 @@ function project_prop_on_subset!(prop, from_subset::OMAS.edge_profiles__grid_ggd
if isnothing(from_prop)
println("from_subset not represented in the property yet")
end
if from_subset.element[1].object[1].dimension == to_subset.element[1].object[1].dimension
if from_subset.element[1].object[1].dimension ==
to_subset.element[1].object[1].dimension
resize!(prop, length(prop) + 1)
to_prop = prop[end]
to_prop.grid_index = from_prop.grid_index
to_prop.grid_subset_index = to_subset.identifier.index
from_subset_ele_obj_inds = [ele.object[1].index for ele in from_subset.element]
to_subset_ele_obj_inds = [ele.object[1].index for ele in to_subset.element]
from_subset_ele_obj_inds = [ele.object[1].index for ele from_subset.element]
to_subset_ele_obj_inds = [ele.object[1].index for ele to_subset.element]
if to_subset_ele_obj_inds from_subset_ele_obj_inds
from_ele_inds = []
for to_ele_obj_ind in to_subset_ele_obj_inds
for (from_ele_ind, from_ele_obj_ind) in enumerate(from_subset_ele_obj_inds)
for to_ele_obj_ind to_subset_ele_obj_inds
for (from_ele_ind, from_ele_obj_ind)
enumerate(from_subset_ele_obj_inds)
if from_ele_obj_ind == to_ele_obj_ind
append!(from_ele_inds, from_ele_ind)
end
end
end
filtered_values = [from_prop.values[from_ele_ind] for from_ele_ind in from_ele_inds]
resize!(to_prop.values, length(filtered_values))
filtered_values =
[from_prop.values[from_ele_ind] for from_ele_ind from_ele_inds]
resize!(to_prop.values, length(filtered_values))
to_prop.values = filtered_values
return to_subset_ele_obj_inds, to_prop.values
else
error("to_subset does not lie entirely inside from_subset. Projection not possible.")
error("to_subset does not lie entirely inside from_subset. Projection ",
"not possible.",
)
end
else
error("Dimensions of from_subset and to_subset do not match. Provide keyword ",
"argument space if you want to project to a smaller dimension as space ",
"information is required for that. Use\n",
"project_prop_on_subset!(prop, from_subset, to_subset; space=space)")
"argument space if you want to project to a smaller dimension as space ",
"information is required for that. Use\n",
"project_prop_on_subset!(prop, from_subset, to_subset; space=space)")
end
end

Expand Down
Loading

0 comments on commit b9e5372

Please sign in to comment.