Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new tests for seven modules. Include GH workflow. #563

Merged
merged 12 commits into from
Nov 13, 2023
69 changes: 69 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: CI

on:
pull_request:
push:
branches: [main, develop]
tags: ['*']

jobs:
test:
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name}}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
version:
- "1.6" # LTS (64-bit Linux)
- "1.7"
- "1.8"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be good to ensure we're testing on 1.9 (though I guess this is covered by 1 for "latest"?)

There's some new features in 1.9 that might motivate us to stop supporting older versions in GenX v0.4.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, '1' ensures we're testing on the latest stable release. We could also keep only the current stable release ('1'), and the long-term support (LTS) release (right now, v1.6.7) as other packages do.

- '1.9' # latest stable Julia release (Linux)
os:
- ubuntu-latest
arch:
- x64
include: # additional tests [Julia-nightly] (Linux)
- os: ubuntu-latest
version: 'nightly'
arch: x64
allow_failure: true
steps:
- uses: actions/checkout@v3
- name: Create a new branch and pull test logs from repo # only push logs if PR is not from a fork
if: ${{ ! github.event.pull_request.head.repo.fork }}
run: |
git checkout -b ${GITHUB_REF#refs/heads/}-testlogs
mkdir test/Logs; cd test/Logs
git config --global init.defaultBranch main
git init
git config --local user.name GenXProject
git config --local user.email "[email protected]"
git remote add testlog https://[email protected]/GenXProject/GenX-testlog.git
git pull testlog main
if [ -d Logs_v${{ matrix.version }} ]; then
mv Logs_v${{ matrix.version }}/*.log .
else
mkdir Logs_v${{ matrix.version }}
fi
env:
LOG_TOKEN: ${{ secrets.LOG_TOKEN }}
- uses: julia-actions/setup-julia@v1
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: julia-actions/cache@v1
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
- name: Commit logs and push back to repo # only push logs if PR is not from a fork
if: ${{ ! github.event.pull_request.head.repo.fork }}
run: |
cd ${GITHUB_WORKSPACE}/test/Logs
mv *.log Logs_v${{ matrix.version }}
git add -f Logs_v${{ matrix.version }}
git commit -m "Update test logs for Julia v${{ matrix.version }}"
git pull --rebase testlog main # pull again to avoid conflicts from other versions
git push testlog main
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v3
with:
file: lcov.info
15 changes: 0 additions & 15 deletions .github/workflows/ci_test.yml

This file was deleted.

6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ gurobi.log
cplex.log
Highs.log

test/Logs

/docs/build/

# Microsoft office temporary files
Expand All @@ -42,3 +44,7 @@ Example_Systems/SmallNewEngland/ThreeZones_full/*

Example_Systems/SmallNewEngland/ThreeZones_MultiStage/Inputs/*
test_get_retirement_period.jl

# Test files
test/TDR/TDR_Results_test
test/MethodofMorris/morris.csv
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add PR template (#516)
- Validation ensures that resource flags (THERM, HYDRO, LDS etc) are self-consistent (#513).
- Maintenance formulation for thermal-commit plants (#556).
- Add new tests for GenX: three-zone, multi-stage, electrolyzer, VRE+storage,
piecewise_fuel+CO2, TDR, and Method of Morris (#563).


### Fixed
- Set MUST_RUN=1 for RealSystemExample/small_hydro plants (#517).
Expand Down
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ YAML = "0.4.7"
julia = "1"

[extras]
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
LoggingExtras = "e6f89c97-d47a-5376-807f-9c37f3926c36"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "Logging"]
test = ["Test", "JLD2", "Logging", "LoggingExtras"]
1 change: 1 addition & 0 deletions src/GenX.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export choose_output_dir
export run_ddp
export configure_multi_stage_inputs
export load_inputs_multi_stage
export compute_cumulative_min_retirements!
export write_multi_stage_outputs
export run_genx_case!
export run_timedomainreduction!
Expand Down
13 changes: 9 additions & 4 deletions src/additional_tools/method_of_morris.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
const SEED = 1234


@doc raw"""
morris(EP::Model, path::AbstractString, setup::Dict, inputs::Dict, outpath::AbstractString, OPTIMIZER)

Expand All @@ -14,6 +17,7 @@ struct MorrisResult{T1,T2}
variances::T1
elementary_effects::T2
end

function generate_design_matrix(p_range, p_steps, rng;len_design_mat,groups)
ps = [range(p_range[i][1], stop=p_range[i][2], length=p_steps[i]) for i in 1:length(p_range)]
indices = [rand(rng, 1:i) for i in p_steps]
Expand Down Expand Up @@ -74,8 +78,9 @@ function sample_matrices(p_range,p_steps, rng;num_trajectory,total_num_trajector
reduce(hcat,matrices)
end

function my_gsa(f, p_steps, num_trajectory, total_num_trajectory, p_range::AbstractVector,len_design_mat,groups)
function my_gsa(f, p_steps, num_trajectory, total_num_trajectory, p_range::AbstractVector, len_design_mat, groups, random)
rng = Random.default_rng()
if !random; Random.seed!(SEED); end
design_matrices_original = sample_matrices(p_range, p_steps, rng;num_trajectory,
total_num_trajectory,len_design_mat,groups)
println(design_matrices_original)
Expand Down Expand Up @@ -158,7 +163,7 @@ function my_gsa(f, p_steps, num_trajectory, total_num_trajectory, p_range::Abstr
end
MorrisResult(reduce(hcat, means),reduce(hcat, means_star),reduce(hcat, variances),effects)
end
function morris(EP::Model, path::AbstractString, setup::Dict, inputs::Dict, outpath::AbstractString, OPTIMIZER)
function morris(EP::Model, path::AbstractString, setup::Dict, inputs::Dict, outpath::AbstractString, OPTIMIZER; random=true)

# Reading the input parameters
Morris_range = load_dataframe(joinpath(path, "Method_of_morris_range.csv"))
Expand Down Expand Up @@ -197,7 +202,7 @@ function morris(EP::Model, path::AbstractString, setup::Dict, inputs::Dict, outp
end

# Perform the method of morris analysis
m = my_gsa(f1,p_steps,num_trajectory,total_num_trajectory,p_range,len_design_mat,groups)
m = my_gsa(f1,p_steps,num_trajectory,total_num_trajectory,p_range,len_design_mat,groups,random)
println(m.means)
println(DataFrame(m.means', :auto))
#save the mean effect of each uncertain variable on the objective fucntion
Expand All @@ -207,5 +212,5 @@ function morris(EP::Model, path::AbstractString, setup::Dict, inputs::Dict, outp
Morris_range[!,:variance] = DataFrame(m.variances', :auto)[!,:x1]

CSV.write(joinpath(outpath, "morris.csv"), Morris_range)

return Morris_range
end
21 changes: 13 additions & 8 deletions src/time_domain_reduction/time_domain_reduction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ using Distances
using CSV
using GenX


const SEED = 1234

@doc raw"""
rmse_score(y_true, y_pred)

Expand Down Expand Up @@ -202,7 +205,7 @@ function get_worst_period_idx(R)
end

@doc raw"""
cluster(ClusterMethod, ClusteringInputDF, NClusters, nIters)
cluster(ClusterMethod, ClusteringInputDF, NClusters, nIters, v=false, random=true)

Get representative periods using cluster centers from kmeans or kmedoids.

Expand All @@ -212,12 +215,13 @@ https://juliastats.org/Clustering.jl/dev/kmeans.html
K-Medoids:
https://juliastats.org/Clustering.jl/stable/kmedoids.html
"""
function cluster(ClusterMethod, ClusteringInputDF, NClusters, nIters, v=false)
function cluster(ClusterMethod, ClusteringInputDF, NClusters, nIters, v=false, random=true)
if ClusterMethod == "kmeans"
DistMatrix = pairwise(Euclidean(), Matrix(ClusteringInputDF), dims=2)
R = kmeans(Matrix(ClusteringInputDF), NClusters, init=:kmcen)

for i in 1:nIters
if !random; Random.seed!(SEED); end
R_i = kmeans(Matrix(ClusteringInputDF), NClusters)

if R_i.totalcost < R.totalcost
Expand All @@ -243,6 +247,7 @@ function cluster(ClusterMethod, ClusteringInputDF, NClusters, nIters, v=false)
R = kmedoids(DistMatrix, NClusters, init=:kmcen)

for i in 1:nIters
if !random; Random.seed!(SEED); end
R_i = kmedoids(DistMatrix, NClusters)
if R_i.totalcost < R.totalcost
R = R_i
Expand All @@ -257,7 +262,7 @@ function cluster(ClusterMethod, ClusteringInputDF, NClusters, nIters, v=false)
M = R.medoids # get the cluster centers - M for Medoids
else
println("INVALID ClusterMethod. Select kmeans or kmedoids. Running kmeans instead.")
return cluster("kmeans", ClusteringInputDF, NClusters, nIters)
return cluster("kmeans", ClusteringInputDF, NClusters, nIters, v, random)
end
return [R, A, W, M, DistMatrix]
end
Expand Down Expand Up @@ -485,7 +490,7 @@ end


@doc raw"""
cluster_inputs(inpath, settings_path, v=false, norm_plot=false, silh_plot=false, res_plots=false, indiv_plots=false, pair_plots=false)
cluster_inputs(inpath, settings_path, mysetup, stage_id=-99, v=false; random=true)

Use kmeans or kmedoids to cluster raw demand profiles and resource capacity factor profiles
into representative periods. Use Extreme Periods to capture noteworthy periods or
Expand Down Expand Up @@ -538,7 +543,7 @@ to separate Vre_and_stor_solar_variability.csv and Vre_and_stor_wind_variability
and wind profiles for co-located resources will be separated into different CSV files to be read by loading the inputs
after the clustering of the inputs has occurred.
"""
function cluster_inputs(inpath, settings_path, mysetup, stage_id=-99, v=false)
function cluster_inputs(inpath, settings_path, mysetup, stage_id=-99, v=false; random=true)
if v println(now()) end

##### Step 0: Load in settings and data
Expand Down Expand Up @@ -781,7 +786,7 @@ function cluster_inputs(inpath, settings_path, mysetup, stage_id=-99, v=false)
cluster_results = []

# Cluster once regardless of iteration decisions
push!(cluster_results, cluster(ClusterMethod, ClusteringInputDF, NClusters, nReps, v))
push!(cluster_results, cluster(ClusterMethod, ClusteringInputDF, NClusters, nReps, v, random))

# Iteratively add worst periods as extreme periods OR increment number of clusters k
# until threshold is met or maximum periods are added (If chosen in inputs)
Expand All @@ -790,15 +795,15 @@ function cluster_inputs(inpath, settings_path, mysetup, stage_id=-99, v=false)
if IterateMethod == "cluster"
if v println("Adding a new Cluster! ") end
NClusters += 1
push!(cluster_results, cluster(ClusterMethod, ClusteringInputDF, NClusters, nReps, v))
push!(cluster_results, cluster(ClusterMethod, ClusteringInputDF, NClusters, nReps, v, random))
elseif (IterateMethod == "extreme") & (UseExtremePeriods == 1)
if v println("Adding a new Extreme Period! ") end
worst_period_idx = get_worst_period_idx(last(cluster_results)[1])
removed_period = string(names(ClusteringInputDF)[worst_period_idx])
select!(ClusteringInputDF, Not(worst_period_idx))
push!(ExtremeWksList, parse(Int, removed_period))
if v println(worst_period_idx, " (", removed_period, ") ", ExtremeWksList) end
push!(cluster_results, cluster(ClusterMethod, ClusteringInputDF, NClusters, nReps, v))
push!(cluster_results, cluster(ClusterMethod, ClusteringInputDF, NClusters, nReps, v, random))
elseif IterateMethod == "extreme"
println("INVALID IterateMethod ", IterateMethod, " because UseExtremePeriods is off. Set to 1 if you wish to add extreme periods.")
break
Expand Down
Loading