Skip to content

Commit

Permalink
Merge pull request #8 from idaholab/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
manoj1511 authored Mar 1, 2023
2 parents 0c68e4d + dd9b886 commit ea3e8ff
Show file tree
Hide file tree
Showing 13 changed files with 130 additions and 50 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ build/
#error files and output files
inputs/*error*
outputs/*.csv

CMakeSettings.json
.vs/
7 changes: 3 additions & 4 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
[submodule "extern/caldera_charge_icm"]
path = extern/caldera_charge_icm
url = https://hpcgitlab.hpc.inl.gov/caldera_charge/caldera_charge_icm.git
branch = main
[submodule "extern/Caldera_ICM"]
path = extern/Caldera_ICM
url = https://github.com/idaholab/Caldera_ICM.git
8 changes: 4 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.5)

project(Grid)

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# Check to see PROJECT cmake variable is set
if (NOT DEFINED PROJECT)
message(WARNING "PROJECT cmake variable not set defaulting to emosiac project")
Expand All @@ -13,9 +15,7 @@ if (NOT (${PROJECT} STREQUAL "eMosaic" OR ${PROJECT} STREQUAL "EVs_at_Risk" OR $
message(FATAL_ERROR "PROJECT cmake variable must be equal to eMosaic or EVs_at_Risk or DirectXFC")
endif()


# Find pybind11

find_package(pybind11 CONFIG)

# Update submodules
Expand All @@ -33,7 +33,7 @@ if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
endif()
endif()

if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/caldera_charge_icm/CMakeLists.txt")
if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/Caldera_ICM/CMakeLists.txt")
message(FATAL_ERROR "The submodules were not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again.")
endif()

Expand All @@ -43,4 +43,4 @@ SET(INSTALL_DIR ${PROJECT_SOURCE_DIR}/libs)

# Add subdirs to compile the necessary binaries
add_subdirectory(source/ES500)
add_subdirectory(extern/caldera_charge_icm)
add_subdirectory(extern/Caldera_ICM)
135 changes: 104 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,120 @@
# Caldera_Charge_Grid
# Caldera_Grid

Caldera and OpenDSS co-simulation platform using HELICS

## Overview
Caldera Grid enables modeling EV charging on the electric grid. Caldera Grid cosimulation platform is built using HELICS (Hierarchical Engine for Large Scale Infrastructure Co-simulation) and cosimulates Caldera ICM with OpenDSS. The platfrom also provides an interface to apply custom control strategies to EV charge events.
Caldera Grid enables modeling EV charging on the electric grid. Caldera Grid co-simulation platform is built using HELICS (Hierarchical Engine for Large Scale Infrastructure Co-simulation) and cosimulates Caldera ICM with OpenDSS. The platfrom also provides an interface to apply custom control strategies to EV charge events.

## Prerequisites

Caldera Grid depends on `C++ compiler`, `git`, `cmake`, `python` and `pybind11` to compile.

## Installation

Get a copy of Caldera ICM.
```
git clone https://hpcgitlab.hpc.inl.gov/caldera_charge/caldera_charge_grid.git
```
If you are interested in the most up to date version of Caldera ICM, the development version is available in the `develop` branch.
```
git switch develop
```
To install Caldera Grid using cmake
```
cd caldera_charge_grid
mkdir build
cmake -DPROJECT=<PROJECT_NAME> -DICM=<ON/OFF> ../
make
make install
```
If cmake cannot find C++ compiler, python or pybind11. They need to be pointed to its installed paths to find them. Refer to [pybind11](https://pybind11.readthedocs.io/en/stable/compiling.html#building-with-cmake) and [cmake](https://cmake.org/cmake/help/latest/guide/tutorial/index.html) documentations.


Caldera Grid compiles the Caldera ICM submodule and installs compiled python libraries in the `libs/` folder.

`-DPROJECT` flag is used to specify the project specific EV-EVSE models to be used. Options are `DirectXFC`, `eMosaic` and `EVs_at_Risk`. `-DICM` flag turns ON/OFF compiling `Caldera_ICM` lib. Please refer to Caldera ICM project for more information with respect to Caldera ICM compilation.
### Windows

The installation approach for windows is only a suggested approach which is well tested


#### Prerequisites

Caldera Grid has the following requirements to be able to compile on windows

1. Install git for windows
2. Install Anaconda
3. Install visual studio with C++ and cmake

#### Anaconda environment setup

1. Open anaconda prompt
2. Create a new conda environment
```
conda create -n Caldera python=3.9 # (recommended version >= 3.7.0)
```
3. Activate the new conda environment
```
conda activate Caldera
```
4. Install required python packages
```
conda install pybind11 # (recommended version >= 2.10)
conda install numpy # (recommended version >= 1.23.5)
conda install pandas # (recommended version >= 1.5.2)
conda install cvxopt # (recommended version >= 1.2.6)
pip install "OpenDSSDirect.py[extras]" # (recommended version >= 0.7.0)
pip install helics # (recommended version >= 3.4.0)
```

#### Download Caldera Grid

1. open git for windows
2. navigate to desired folder where you would like to download Caldera Grid
```
cd <path_to_desired_download_folder>
```
3. clone Caldera Grid from Github
```
git clone https://github.com/idaholab/Caldera_Grid.git
```
4. Swich to develop branch. Develop branch has the most recent updates and bug fixes for Caldera Grid
```
git switch develop
```

#### Compile Caldera Grid

1. Open the downloaded Caldera Grid folder in Visual Studio
```
File -> Open -> Folder -> <path_to_Caldera_Grid>
```
2. Open CMakeSettings.json
```
Project -> CMake Settings
```
3. Set flages for the cmake compilation process in the CMake command arguments test box
```
-DPROJECT=eMosaic -DICM=ON -DPYTHON_EXECUTABLE=<path_to_anaconda3>\envs\<env_name>\python.exe -Dpybind11_DIR=<path_to_anaconda3>\envs\<env_name>\Library\share\cmake\pybind11
```
- PROJECT - options are DirectXFC, eMosaic and EVs_at_Risk
- ICM - needs to be ON, Caldera_Grid needs ICM module
4. Configure CMake
- Saving CMakeSettings.json will kick off the configuration in the output tab
5. Build libraries
```
build -> build all
```
6. Install libraries
```
build -> Install Grid
```

#### Running Caldera Grid

1. Open Anaconda prompt
2. Navigate to project folder
```
cd <path_to_Caldera_Grid>
```
3. Activate Anaconda environment
```
conda activate Caldera
```
4. Run simulation
```
python start_execution.py
```

- `start_execution.py` is set up to run a simple example of EVs charging on the IEEE 34 node test feeder.


__NOTE :__ If the excution takes longer time to run, Try using release mode to build

## Usage
Please refer to [usage documentation](https://hpcgitlab.hpc.inl.gov/caldera_charge/caldera_charge_grid/-/raw/main/docs/Caldera-OpenDSS%20simulation%20platform.pptx) to learn on how to use the tool.

`start_execution.py` is set up to run a simple example of EVs charging on the IEEE 34 node test feeder.
## Citation
If you use Caldera Grid in your research, please cite:

Sundarrajan, Manoj Kumar Cebol, Scoffield, Don R, Rumsey, Paden D, & USDOE Office of Nuclear Energy. (2022, December 13). idaholab/Caldera_Grid [Computer software]. https://www.osti.gov//servlets/purl/1907411. https://doi.org/10.11578/dc.20230103.3


## Authors
1. Don Scoffield, Senior Research Engineer, Idaho National Laboratory
2. Manoj Sundarrajan, Research Software Developer, Idaho National Laboratory

## License
For open source projects, say how it is licensed.
1 change: 1 addition & 0 deletions extern/Caldera_ICM
Submodule Caldera_ICM added at d261da
1 change: 0 additions & 1 deletion extern/caldera_charge_icm
Submodule caldera_charge_icm deleted from 6ee477
2 changes: 1 addition & 1 deletion source/ES500/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
set(GLOBALS_DIR ${PROJECT_SOURCE_DIR}/extern/caldera_charge_icm/source/charging_models)
set(GLOBALS_DIR ${PROJECT_SOURCE_DIR}/extern/Caldera_ICM/source/charging_models)

pybind11_add_module(ES500_Aggregator_Helper ${GLOBALS_DIR}/datatypes_global.cpp
${GLOBALS_DIR}/${PROJECT}/datatypes_global_SE_EV_definitions.cpp
Expand Down
7 changes: 6 additions & 1 deletion source/ES500/ES500_aggregator_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ class ES500_aggregator_allocate_energy_to_PEVs
int index;
double charge_progression;

bool operator < (const SE_priority_element& rhs)
bool operator<(const SE_priority_element& rhs) const
{
return this->charge_progression < rhs.charge_progression;
}

bool operator<(SE_priority_element& rhs) const
{
return this->charge_progression < rhs.charge_progression;
}
Expand Down
2 changes: 1 addition & 1 deletion source/base/load_input_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ def __get_supply_equipment_data(self, SE_data_file_path):
if len(errors) == 0:
grid_node_id_col_name = elements[4].strip()
location_type_col_name = elements[6].strip()
df = pd.read_csv(SE_data_file_path, sep=',', header=0, dtype={grid_node_id_col_name:np.str, location_type_col_name:np.str})
df = pd.read_csv(SE_data_file_path, sep=',', header=0, dtype={grid_node_id_col_name:str, location_type_col_name:str})

if len(df.columns) != number_of_fields:
errors.append('NA, There must be {} columns in file.'.format(number_of_fields))
Expand Down
4 changes: 2 additions & 2 deletions source/federates/Caldera_ICM_federate.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ def caldera_ICM_federate(base_dir, json_config_file_name, simulation_time_constr
config_file_path = base_dir + "/source/helics_config/" + json_config_file_name
fed = h.helicsCreateCombinationFederateFromConfig(config_file_path)

sub_data_loaded = h.helicsFederateGetSubscription(fed, 'Load_Input_Files/data_loaded')
sub_dss_simulation_loaded = h.helicsFederateGetSubscription(fed, 'OpenDSS/dss_simulation_loaded')
sub_data_loaded = h.helicsFederateGetInputByTarget(fed, 'Load_Input_Files/data_loaded')
sub_dss_simulation_loaded = h.helicsFederateGetInputByTarget(fed, 'OpenDSS/dss_simulation_loaded')

input_datasets_endpoint_local = h.helicsFederateGetEndpoint(fed, "input_datasets_endpoint")
input_datasets_endpoint_remote = h.helicsEndpointGetDefaultDestination(input_datasets_endpoint_local)
Expand Down
2 changes: 1 addition & 1 deletion source/federates/OpenDSS_federate.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def open_dss_federate(base_dir, json_config_file_name, simulation_time_constrain
config_file_path = base_dir + "/source/helics_config/" + json_config_file_name
fed = h.helicsCreateCombinationFederateFromConfig(config_file_path)

sub_data_loaded = h.helicsFederateGetSubscription(fed, 'Load_Input_Files/data_loaded')
sub_data_loaded = h.helicsFederateGetInputByTarget(fed, 'Load_Input_Files/data_loaded')
pub_dss_simulation_loaded = h.helicsFederateGetPublication(fed, 'dss_simulation_loaded')

input_datasets_endpoint_local = h.helicsFederateGetEndpoint(fed, "input_datasets_endpoint")
Expand Down
4 changes: 2 additions & 2 deletions source/federates/typeA_control_federate.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def typeA_control_federate(base_dir, json_config_file_name, simulation_time_cons
config_file_path = base_dir + "/source/helics_config/" + json_config_file_name
fed = h.helicsCreateCombinationFederateFromConfig(config_file_path)

sub_data_loaded = h.helicsFederateGetSubscription(fed, 'Load_Input_Files/data_loaded')
sub_dss_simulation_loaded = h.helicsFederateGetSubscription(fed, 'OpenDSS/dss_simulation_loaded')
sub_data_loaded = h.helicsFederateGetInputByTarget(fed, 'Load_Input_Files/data_loaded')
sub_dss_simulation_loaded = h.helicsFederateGetInputByTarget(fed, 'OpenDSS/dss_simulation_loaded')

input_datasets_endpoint_local = h.helicsFederateGetEndpoint(fed, "input_datasets_endpoint")
input_datasets_endpoint_remote = h.helicsEndpointGetDefaultDestination(input_datasets_endpoint_local)
Expand Down
4 changes: 2 additions & 2 deletions source/federates/typeB_control_federate.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ def typeB_control_federate(base_dir, json_config_file_name, simulation_time_cons
config_file_path = base_dir + "/source/helics_config/" + json_config_file_name
fed = h.helicsCreateCombinationFederateFromConfig(config_file_path)

sub_data_loaded = h.helicsFederateGetSubscription(fed, 'Load_Input_Files/data_loaded')
sub_dss_simulation_loaded = h.helicsFederateGetSubscription(fed, 'OpenDSS/dss_simulation_loaded')
sub_data_loaded = h.helicsFederateGetInputByTarget(fed, 'Load_Input_Files/data_loaded')
sub_dss_simulation_loaded = h.helicsFederateGetInputByTarget(fed, 'OpenDSS/dss_simulation_loaded')

input_datasets_endpoint_local = h.helicsFederateGetEndpoint(fed, "input_datasets_endpoint")
input_datasets_endpoint_remote = h.helicsEndpointGetDefaultDestination(input_datasets_endpoint_local)
Expand Down

0 comments on commit ea3e8ff

Please sign in to comment.