-
Notifications
You must be signed in to change notification settings - Fork 7
Fix ramp parsing and GENRAMP indexing in TCOPFLOW #62
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
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| #include <private/psimpl.h> | ||
|
|
||
| #include <utils.h> | ||
| /* | ||
| PSReadPSSERawData - Reads the PSSE raw data file and populates the PS object | ||
|
|
||
|
|
@@ -1040,6 +1040,8 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { | |
| loadcosti++; | ||
| } | ||
|
|
||
| PetscScalar fuel_ramp_min; | ||
|
|
||
| /* Read generator fuel data */ | ||
| if (i >= genfuel_start_line && i < genfuel_end_line) { | ||
| if (strcmp(line, "\n") == 0 || strcmp(line, "\r\n") == 0) | ||
|
|
@@ -1050,15 +1052,11 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { | |
| } | ||
| if (strstr(line, "coal") != NULL) { | ||
| Gen[genfueli].genfuel_type = GENFUEL_COAL; | ||
| Gen[genfueli].ramp_rate_min = GENRAMPRATE_COAL / ps->MVAbase; | ||
| Gen[genfueli].ramp_rate_10min = Gen[genfueli].ramp_rate_min * 10; | ||
| Gen[genfueli].ramp_rate_30min = Gen[genfueli].ramp_rate_min * 30; | ||
| fuel_ramp_min = GENRAMPRATE_COAL; | ||
| ps->ngencoal++; | ||
| } else if (strstr(line, "wind") != NULL) { | ||
| Gen[genfueli].genfuel_type = GENFUEL_WIND; | ||
| Gen[genfueli].ramp_rate_min = GENRAMPRATE_WIND / ps->MVAbase; | ||
| Gen[genfueli].ramp_rate_10min = Gen[genfueli].ramp_rate_min * 10; | ||
| Gen[genfueli].ramp_rate_30min = Gen[genfueli].ramp_rate_min * 30; | ||
| fuel_ramp_min = GENRAMPRATE_WIND; | ||
| Gen[genfueli].pb = 0.0; /* Set lower Pg limit to 0.0 so that power | ||
| can be curtailed if need be */ | ||
|
|
||
|
|
@@ -1067,41 +1065,36 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { | |
| Gen[genfueli].isrenewable = PETSC_TRUE; | ||
| } else if (strstr(line, "ng") != NULL) { | ||
| Gen[genfueli].genfuel_type = GENFUEL_NG; | ||
| Gen[genfueli].ramp_rate_min = GENRAMPRATE_NG / ps->MVAbase; | ||
| Gen[genfueli].ramp_rate_10min = Gen[genfueli].ramp_rate_min * 10; | ||
| Gen[genfueli].ramp_rate_30min = Gen[genfueli].ramp_rate_min * 30; | ||
| fuel_ramp_min = GENRAMPRATE_NG; | ||
| ps->ngenng++; | ||
|
Comment on lines
+1068
to
1069
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this fuel_ramp_min = GENRAMPRATE_NG;and not fuel_ramp_min = GENRAMPRATE_NG / ps->MVAbase;? What are the units of Same applies to other fuel types for generators. |
||
| } else if (strstr(line, "solar") != NULL) { | ||
| Gen[genfueli].genfuel_type = GENFUEL_SOLAR; | ||
| Gen[genfueli].ramp_rate_min = GENRAMPRATE_SOLAR / ps->MVAbase; | ||
| Gen[genfueli].ramp_rate_10min = Gen[genfueli].ramp_rate_min * 10; | ||
| Gen[genfueli].ramp_rate_30min = Gen[genfueli].ramp_rate_min * 30; | ||
| fuel_ramp_min = GENRAMPRATE_SOLAR; | ||
| Gen[genfueli].pb = 0.0; /* Set lower Pg limit to 0.0 so that power | ||
| can be curtailed if need be */ | ||
| ps->ngensolar++; | ||
| ps->ngenrenew++; | ||
| Gen[genfueli].isrenewable = PETSC_TRUE; | ||
| } else if (strstr(line, "nuclear") != NULL) { | ||
| Gen[genfueli].genfuel_type = GENFUEL_NUCLEAR; | ||
| Gen[genfueli].ramp_rate_min = GENRAMPRATE_NUCLEAR / ps->MVAbase; | ||
| Gen[genfueli].ramp_rate_10min = Gen[genfueli].ramp_rate_min * 10; | ||
| Gen[genfueli].ramp_rate_30min = Gen[genfueli].ramp_rate_min * 30; | ||
| fuel_ramp_min = GENRAMPRATE_NUCLEAR; | ||
| ps->ngennuclear++; | ||
| } else if (strstr(line, "hydro") != NULL) { | ||
| Gen[genfueli].genfuel_type = GENFUEL_HYDRO; | ||
| Gen[genfueli].ramp_rate_min = GENRAMPRATE_HYDRO / ps->MVAbase; | ||
| Gen[genfueli].ramp_rate_10min = Gen[genfueli].ramp_rate_min * 10; | ||
| Gen[genfueli].ramp_rate_30min = Gen[genfueli].ramp_rate_min * 30; | ||
| fuel_ramp_min = GENRAMPRATE_HYDRO; | ||
| ps->ngenhydro++; | ||
| ps->ngenrenew++; | ||
| Gen[genfueli].isrenewable = PETSC_TRUE; | ||
| } else { | ||
| Gen[genfueli].genfuel_type = GENFUEL_UNDEFINED; | ||
| Gen[genfueli].ramp_rate_min = | ||
| GENRAMPRATE_COAL / ps->MVAbase; /* Defaults to COAL ramp rate */ | ||
| fuel_ramp_min = GENRAMPRATE_COAL; /* Defaults to COAL ramp rate */ | ||
| ps->ngenundefined++; | ||
| } | ||
| double ramp_rate_min_error = 0.0; | ||
| if (IsEqual(Gen[genfueli].ramp_rate_min, 0.0, 1e-12, ramp_rate_min_error)) { | ||
| Gen[genfueli].ramp_rate_min = fuel_ramp_min / ps->MVAbase; | ||
| Gen[genfueli].ramp_rate_10min = Gen[genfueli].ramp_rate_min * 10; | ||
| Gen[genfueli].ramp_rate_30min = Gen[genfueli].ramp_rate_min * 30; | ||
| ps->ngenundefined++; | ||
| } | ||
| genfueli++; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -119,6 +119,7 @@ PetscErrorCode TCOPFLOWSetConstraintBounds_GENRAMP(TCOPFLOW tcopflow, Vec Gl, | |
| /* Ramp constraints */ | ||
| gli[opflow->ncon + ctr] = -gen->ramp_rate_min * tcopflow->dT; | ||
| gui[opflow->ncon + ctr] = gen->ramp_rate_min * tcopflow->dT; | ||
|
|
||
| ctr++; | ||
| } | ||
| } | ||
|
|
@@ -205,7 +206,7 @@ PetscErrorCode TCOPFLOWComputeJacobian_GENRAMP(TCOPFLOW tcopflow, Vec X, | |
| PetscInt roffset, coffset; | ||
| PetscInt nrow, ncol; | ||
| PetscScalar *xi, *x; | ||
| PetscInt i, j, k, loc, loctpre, xtpreloc, xiloc; | ||
| PetscInt i, j, k, ctr, xtpreloc, xiloc; | ||
| PS ps, pstpre; | ||
| PSBUS bus, bustpre; | ||
| PSGEN gen, gentpre; | ||
|
|
@@ -280,47 +281,48 @@ PetscErrorCode TCOPFLOWComputeJacobian_GENRAMP(TCOPFLOW tcopflow, Vec X, | |
| CHKERRQ(ierr); | ||
|
|
||
| if (tcopflow->nconineqcoup[i]) { | ||
| ctr = 0; | ||
| ps = opflow->ps; | ||
| pstpre = opflowtpre->ps; | ||
|
|
||
|
Comment on lines
283
to
+287
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The following code should be documented with comments in code. |
||
| for (j = 0; j < ps->nbus; j++) { | ||
| bus = &ps->bus[j]; | ||
| bustpre = &pstpre->bus[j]; | ||
| ierr = PSBUSGetVariableLocation(bus, &loc); | ||
| CHKERRQ(ierr); | ||
| ierr = PSBUSGetVariableLocation(bustpre, &loctpre); | ||
| CHKERRQ(ierr); | ||
|
|
||
| for (k = 0; k < bus->ngen; k++) { | ||
| ierr = PSBUSGetGen(bus, k, &gen); | ||
| CHKERRQ(ierr); | ||
| ierr = PSBUSGetGen(bustpre, k, &gentpre); | ||
| CHKERRQ(ierr); | ||
|
|
||
| if (!gen->status) { | ||
| if (gentpre->status) | ||
| loctpre += 2; | ||
| if (!gen->status || !gentpre->status) | ||
| continue; | ||
| } else { | ||
| loc += 2; | ||
| if (!gentpre->status) | ||
| continue; | ||
| loctpre += 2; | ||
| } | ||
|
|
||
| xtpreloc = tcopflow->xstarti[i - 1] + loctpre; | ||
| xiloc = tcopflow->xstarti[i] + loc; | ||
| row = roffset; | ||
|
|
||
| row = roffset + ctr; | ||
|
|
||
| xtpreloc = tcopflow->xstarti[i - 1] + gentpre->startxpowlocglob; | ||
| xiloc = tcopflow->xstarti[i] + gen->startxpowlocglob; | ||
|
|
||
| col = xtpreloc; | ||
| val = -1.; | ||
| ierr = MatSetValues(J, 1, &row, 1, &col, &val, INSERT_VALUES); | ||
| CHKERRQ(ierr); | ||
|
|
||
| col = xiloc; | ||
| val = 1.; | ||
| ierr = MatSetValues(J, 1, &row, 1, &col, &val, INSERT_VALUES); | ||
| CHKERRQ(ierr); | ||
|
|
||
| roffset += 1; | ||
| ctr++; | ||
| } | ||
| } | ||
|
|
||
| if (ctr != tcopflow->nconineqcoup[i]) { | ||
| SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, | ||
| "GENRAMP Jacobian coupling constraint count mismatch"); | ||
| } | ||
|
|
||
| roffset += ctr; | ||
| } | ||
|
|
||
| opflowtpre = opflow; | ||
|
|
@@ -341,7 +343,7 @@ PetscErrorCode TCOPFLOWComputeConstraints_GENRAMP(TCOPFLOW tcopflow, Vec X, | |
| Vec G) { | ||
| PetscErrorCode ierr; | ||
| OPFLOW opflowtpre, opflow; | ||
| PetscInt i, j, k, loc, loctpre, ctr; | ||
| PetscInt i, j, k, ctr; | ||
| PetscScalar *xtpre, *x, *xi, *g, *gi; | ||
| PS ps, pstpre; | ||
| PSBUS bus, bustpre; | ||
|
|
@@ -389,36 +391,32 @@ PetscErrorCode TCOPFLOWComputeConstraints_GENRAMP(TCOPFLOW tcopflow, Vec X, | |
| ctr = 0; | ||
| ps = opflow->ps; | ||
| pstpre = opflowtpre->ps; | ||
|
|
||
| for (j = 0; j < ps->nbus; j++) { | ||
| bus = &ps->bus[j]; | ||
| bustpre = &pstpre->bus[j]; | ||
| ierr = PSBUSGetVariableLocation(bus, &loc); | ||
| CHKERRQ(ierr); | ||
| ierr = PSBUSGetVariableLocation(bustpre, &loctpre); | ||
| CHKERRQ(ierr); | ||
|
|
||
| for (k = 0; k < bus->ngen; k++) { | ||
| ierr = PSBUSGetGen(bus, k, &gen); | ||
| CHKERRQ(ierr); | ||
| ierr = PSBUSGetGen(bustpre, k, &gentpre); | ||
| CHKERRQ(ierr); | ||
|
|
||
| if (!gen->status) { | ||
| if (gentpre->status) | ||
| loctpre += 2; | ||
| if (!gen->status || !gentpre->status) | ||
| continue; | ||
| } else { | ||
| loc += 2; | ||
| if (!gentpre->status) | ||
| continue; | ||
| loctpre += 2; | ||
| } | ||
|
|
||
| gi[ctr] = xi[loc] - xtpre[loctpre]; /* PG(t) - PG(t-dT) */ | ||
|
|
||
| gi[ctr] = | ||
| xi[gen->startxpowloc] - xtpre[gentpre->startxpowloc]; | ||
|
|
||
| ctr++; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (ctr != tcopflow->nconineqcoup[i]) { | ||
| SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, | ||
| "GENRAMP value coupling constraint count mismatch"); | ||
| } | ||
| } | ||
|
|
||
| ierr = VecResetArray(opflow->X); | ||
| CHKERRQ(ierr); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code block and the logic inside it should be explained in more detail in code comments.