diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml
index 1b6411b1..7f54c8e3 100644
--- a/.github/workflows/docker-build.yml
+++ b/.github/workflows/docker-build.yml
@@ -74,9 +74,11 @@ jobs:
images: pnnl/gridpack
tags: |
type=ref,event=branch
- type=semver,pattern={{version}}
- type=semver,pattern={{major}}.{{minor}}
- type=raw,value=latest,enable={{is_default_branch}}
+ type=semver,pattern=v{{version}}
+ type=semver,pattern=v{{major}}.{{minor}}
+ type=semver,pattern=v{{major}}
+ type=ref,event=tag
+ type=raw,value=latest,enable=${{ github.event_name == 'release' || github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
type=raw,value=${{ inputs.tag || 'dev' }},enable=${{ github.event_name == 'workflow_dispatch' }}
- name: Extract primary tag
diff --git a/.github/workflows/docker-readme.yml b/.github/workflows/docker-readme.yml
new file mode 100644
index 00000000..d91b615e
--- /dev/null
+++ b/.github/workflows/docker-readme.yml
@@ -0,0 +1,25 @@
+name: Sync Docker Hub README
+
+on:
+ push:
+ branches: [ develop ]
+
+jobs:
+ sync-readme:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v5
+
+ - name: Login to Docker Hub
+ uses: docker/login-action@v4
+ with:
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
+
+ - name: Update Docker Hub repo description
+ uses: peter-evans/dockerhub-description@v5
+ with:
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
+ repository: pnnl/gridpack
+ readme-filepath: ./README.md
diff --git a/README.md b/README.md
index 1b679023..4a0b75a6 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,11 @@
# GridPACKTM-->
# GridPACK: High-Performance Electric Grid Simulation
+* Repo: https://github.com/gridoptics/gridpack
+* Issues: https://github.com/GridOPTICS/GridPACK/issues
+* Releases: https://github.com/GridOPTICS/GridPACK/releases
+## About
GridPACK is an open-source high-performance (HPC) package for simulation of large-scale electrical grids. Powered by distributed (parallel) computing and high-performance numerical solvers, GridPACK offers several applications forfast simulation of electrical transmission systems. GridPACK includes a number of prebuilt applications that can be directly used. The most commonly used and well-developed are:
- AC Power Flow
- Dynamics Simulation
@@ -28,6 +32,9 @@ docker pull pnnl/gridpack:latest
# Run with your files (container starts in /app/workspace)
docker run -it --rm -v $(pwd):/app/workspace pnnl/gridpack:latest bash
+
+# Run a specific semantic version
+docker run -it --rm -v $(pwd):/app/workspace pnnl/gridpack:v3.6 bash
```
The Docker image supports both AMD64 and ARM64 architectures. See the [Docker usage guide](https://gridpack.readthedocs.io/en/latest/Section2-Docker.html) for more examples.
diff --git a/src/applications/modules/dynamic_simulation_full_y/dsf_components.cpp b/src/applications/modules/dynamic_simulation_full_y/dsf_components.cpp
index 6abddbc6..1e453e23 100644
--- a/src/applications/modules/dynamic_simulation_full_y/dsf_components.cpp
+++ b/src/applications/modules/dynamic_simulation_full_y/dsf_components.cpp
@@ -226,8 +226,12 @@ bool gridpack::dynamic_simulation::DSFullBus::matrixDiagValues(ComplexType *valu
if (p_ngen > 0) {
for (int i = 0; i < p_ngen; i++) {
if(!p_gstatus[i]) continue;
-
- if (p_pg[i] < 0) {
+
+ // Only convert PG<0 generators to impedance load if they
+ // do NOT have a dynamic model. Generators with dynamic models
+ // (including motoring generators with PG<0) contribute via
+ // Norton current injection, not as impedance loads.
+ if (p_pg[i] < 0 && p_gen_nodynmodel[i]) {
p_ybusr = p_ybusr+(-p_pg[i])/(p_voltage*p_voltage);
p_ybusi = p_ybusi+p_qg[i]/(p_voltage*p_voltage);
gridpack::ComplexType ret(p_ybusr, p_ybusi);
@@ -241,14 +245,6 @@ bool gridpack::dynamic_simulation::DSFullBus::matrixDiagValues(ComplexType *valu
gridpack::ComplexType u(p_ybusr, p_ybusi);
values[0] = u;
}
- if (p_negngen > 0) {
- for (int i = 0; i < p_negngen; i++) {
- p_ybusr = p_ybusr+(-p_negpg[i])/(p_voltage*p_voltage);
- p_ybusi = p_ybusi+p_negqg[i]/(p_voltage*p_voltage);
- gridpack::ComplexType ret(p_ybusr, p_ybusi);
- values[0] = ret;
- }
- }
for (int i = 0; i < p_ngen; i++) {
if(p_gen_nodynmodel[i]) {
p_ybusr = p_ybusr+(-p_genpg_nodynmodel[i])/(p_voltage*p_voltage);
@@ -978,7 +974,7 @@ void gridpack::dynamic_simulation::DSFullBus::load(
p_gpmax.push_back(pmax);
std::string model;
- if (data->getValue(GENERATOR_MODEL, &model, i) && pg >= 0.0) {
+ if (data->getValue(GENERATOR_MODEL, &model, i)) {
BaseGeneratorModel *generator
= genFactory.createGeneratorModel(model);
@@ -1127,7 +1123,7 @@ void gridpack::dynamic_simulation::DSFullBus::load(
model.c_str(), idx);
}
- } else if (!data->getValue(GENERATOR_MODEL, &model, i) && pg >= 0.0){
+ } else if (!data->getValue(GENERATOR_MODEL, &model, i)){
// handle the generators having no dynamic model, need to convert to negative load
BaseGeneratorModel *generator = new gridpack::dynamic_simulation::BaseGeneratorModel;
boost::shared_ptr basegen;
@@ -1138,10 +1134,6 @@ void gridpack::dynamic_simulation::DSFullBus::load(
p_genpg_nodynmodel[i] = pg;
p_genqg_nodynmodel[i] = qg;
p_ngen_nodynmodel++;
- } else if (pg < 0.0) {
- p_negpg.push_back(pg);
- p_negqg.push_back(qg);
- p_negngen++;
}
icnt++;
}
diff --git a/src/applications/modules/dynamic_simulation_full_y/model_classes/classical.cpp b/src/applications/modules/dynamic_simulation_full_y/model_classes/classical.cpp
index 3a3b536d..ce4725a2 100644
--- a/src/applications/modules/dynamic_simulation_full_y/model_classes/classical.cpp
+++ b/src/applications/modules/dynamic_simulation_full_y/model_classes/classical.cpp
@@ -163,7 +163,7 @@ void gridpack::dynamic_simulation::ClassicalGenerator::init(double mag,
p_eqprime = gridpack::ComplexType(abs(p_eprime_s0),0.0);
//printf("eqprime = %f\n", p_eqprime);
// pmech
- p_pmech = gridpack::ComplexType(abs(p_pelect),0.0);
+ p_pmech = gridpack::ComplexType(real(p_pelect),0.0);
//printf("mech = %f\n", p_pmech);
//printf("mva = %f\n", p_mva);
//printf("d0 = %f\n", p_d0);