Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion applications/sopflow_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ int main(int argc, char **argv) {
SOPFLOW sopflow;
char file[PETSC_MAX_PATH_LEN];
char scenfile[PETSC_MAX_PATH_LEN];
char loadfile[PETSC_MAX_PATH_LEN];
Comment on lines 12 to +13
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why are load files and scenario files different? Shouldn't there be single scenario file format including generation and load?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes, the loadfile variable name is not necessary actually. A single name is fine. I did not want to touch the variable name in the first implementation. I will drop the loadfile and use scenfile only.

Regarding Load and Generator together: It can be done but will require little bit more modification. The first cut focused on changing Load P and Q values. But I see I can use the same template to have different forecast types. Will try to submit the changes.

char outputdir[PETSC_MAX_PATH_LEN];
PetscBool outputdir_set;
PetscBool flg = PETSC_FALSE, flgscen = PETSC_FALSE;
PetscBool flg = PETSC_FALSE, flgscen = PETSC_FALSE, flgload = PETSC_FALSE;
PetscBool print_output = PETSC_FALSE, save_output = PETSC_FALSE;
PetscLogStage stages[3];
char appname[] = "sopflow";
Expand Down Expand Up @@ -54,6 +55,11 @@ int main(int argc, char **argv) {
PETSC_MAX_PATH_LEN, &flgscen);
CHKERRQ(ierr);

/* Get load data file from command line */
ierr = PetscOptionsGetString(NULL, NULL, "-loadfile", loadfile,
PETSC_MAX_PATH_LEN, &flgload);
CHKERRQ(ierr);

/* Stage 1 - Application creation and reading data */
ierr = PetscLogStagePush(stages[0]);
CHKERRQ(ierr);
Expand All @@ -78,6 +84,13 @@ int main(int argc, char **argv) {
CHKERRQ(ierr);
}

/* Set Load Data file */
if (flgload) {
ierr = SOPFLOWSetScenarioData(sopflow, SOPFLOW_NATIVE_SINGLEPERIOD, LOAD,
loadfile);
CHKERRQ(ierr);
}

/* Set a subset of scenarios to be selected. Can use the option -sopflow_Ns
* instead */
/* ierr = SOPFLOWSetNumScenarios(sopflow,2);CHKERRQ(ierr); */
Expand Down
11 changes: 11 additions & 0 deletions datafiles/case9/10_scenarios_9bus_load.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
scenario_nr,weight,kv_list
1,0.101,8_Load_1_185.0_1000,6_Load_1_105.5_2000
2,0.102,6_Load_1_105.0_10
3,0.103,8_Load_1_75.0_20
Comment on lines +1 to +4
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is somewhat strange string format. Can't we use simple csv?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Okay, the issue is similar to the argument for CSR type of file format.

For example, say we have a test case, where we want to add a large load to each bus and say we have 30k eligible buses. So we have 30k such scenarios.

In old format, we need to have 30k columns for each CSV file, and all will have original model values except 1 column for each scenario of the existing CSV format.

In this new format, we are just keeping the bus which need to be changes.

But I agree the format is a bit strange and I am open to suggestions for input format. We can rewrite the parser accordingly.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

How about we use JSON format?

@PhilipFackler, please chime in.

4,0.104,6_Load_1_95.0_30
5,0.105,8_Load_1_115.0_40
6,0.106,6_Load_1_65.0_50
7,0.107,8_Load_1_33.0_60
8,0.108,6_Load_1_125.0_70
9,0.109,8_Load_1_55.0_80
10,0.1110,6_Load_1_250.0_90
2 changes: 1 addition & 1 deletion include/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ typedef enum {
typedef enum {
FORECAST_WIND = 1,
FORECAST_LOAD_P = 2,
FORECAST_LOAD_Q = 3
FORECAST_LOAD_PQ = 3
Comment on lines 23 to +24
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why is FORECAST_LOAD_Q changed into FORECAST_LOAD_PQ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I wanted to have the ability to change PQ value as a set. In later iterations, we can drop FORECAST_LOAD_P and use just FORECAST_GEN (after renaming FORECAST_WIND) and and FORECAST_LOAD.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't see why one would want to change P and Q as a set. They can and they occasionally do change separately.

@hambrickjc and @tsybinae: please chime in.

} ForecastType;

/**
Expand Down
1 change: 1 addition & 0 deletions include/opflow.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ namespace OPFLOWOptions {
const auto model = ExaGOStringOption("-opflow_model", "OPFLOW model name",
"POWER_BALANCE_POLAR",
{
"DCOPF",
#ifdef EXAGO_ENABLE_HIOP
"POWER_BALANCE_HIOP",
"PBPOLRAJAHIOP",
Expand Down
3 changes: 2 additions & 1 deletion include/private/psimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,8 @@ struct _p_PS {

PetscBool setupcalled; /* Is setup called on PS? */

PetscLogDouble solve_real_time;
PetscLogDouble solve_real_time; /* Solve time */
PetscInt numits; /* Number of solver iterations */
};

extern PetscErrorCode PSCheckTopology(PS);
Expand Down
3 changes: 2 additions & 1 deletion include/private/scenariolist.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ struct _p_Forecast {
PetscInt nele; /* Number of devices/elements involved in this forecast */
PetscInt *buses; /* Bus numbers */
char **id; /* Device ids */
PetscScalar *val; /* forecast values */
PetscScalar *val1 = nullptr; /* forecast values */
PetscScalar *val2 = nullptr; /* 2nd set of forecast values */
Comment on lines +21 to +22
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What are forecast values and "2nd set of forecast values"? This is somewhat counterintuitive.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

In current format, Forecast have a single value. But for a load, we want to change P and Q values simultaneously. So, either we can change the data type of val, or we can add add a second list of values. I used the second list here.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I am not sure we want to change P & Q simultaneously. They often change together but sometimes they don't as far as I know.

};

typedef struct _p_Forecast Forecast;
Expand Down
1 change: 1 addition & 0 deletions src/opflow/interface/opflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3196,6 +3196,7 @@ PetscErrorCode OPFLOWSetSummaryStats(OPFLOW opflow) {
CHKERRQ(ierr);

ps->solve_real_time = opflow->solve_real_time;
ps->numits = opflow->numits;

PetscFunctionReturn(0);
}
Expand Down
31 changes: 30 additions & 1 deletion src/ps/ps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1609,6 +1609,7 @@ PetscErrorCode PSApplyScenario(PS ps, Scenario scenario) {
PetscInt i, j;
Forecast *forecast;
PSGEN gen;
PSLOAD load;
PetscErrorCode ierr;

PetscFunctionBegin;
Expand All @@ -1621,7 +1622,7 @@ PetscErrorCode PSApplyScenario(PS ps, Scenario scenario) {
CHKERRQ(ierr);
if (gen) {
gen->pg = gen->pt =
forecast->val[j] /
forecast->val1[j] /
ps->MVAbase; /* Set real power generation. Note that
Pg upper limit is also set to the forecast value. This allows
the wind generator to be dispatched at its limit */
Expand All @@ -1638,6 +1639,34 @@ PetscErrorCode PSApplyScenario(PS ps, Scenario scenario) {
forecast->buses[j], forecast->id[j]);
}
}
} else if (forecast->type == FORECAST_LOAD_P) {
/* Load forecast */
for (j = 0; j < forecast->nele; j++) {
ierr = PSGetLoad(ps, forecast->buses[j], forecast->id[j], &load);
CHKERRQ(ierr);
if (load) {
load->pl = forecast->val1[j] / ps->MVAbase; /* Set real power load. */
} else {
printf("No load on bus %d with id %s. Cannot apply the "
"requested scenario\n",
forecast->buses[j], forecast->id[j]);
}
}
} else if (forecast->type == FORECAST_LOAD_PQ) {
/* Load forecast */
for (j = 0; j < forecast->nele; j++) {
ierr = PSGetLoad(ps, forecast->buses[j], forecast->id[j], &load);
CHKERRQ(ierr);
if (load) {
load->pl = forecast->val1[j] / ps->MVAbase; /* Set real power load. */
load->ql =
forecast->val2[j] / ps->MVAbase; /* Set reactive power load. */
} else {
printf("No load on bus %d with id %s. Cannot apply the "
"requested scenario\n",
forecast->buses[j], forecast->id[j]);
}
}
}
}

Expand Down
7 changes: 6 additions & 1 deletion src/ps/psoutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,9 @@ PetscErrorCode PSSaveSolution_MATPOWER(PS ps, const char outfile[]) {
fprintf(fd, "\n%%%% solve time\n");
fprintf(fd, "%ssolve_time = %.5g;\n", prefix, ps->solve_real_time);

fprintf(fd, "\n%%%% number of iterations\n");
fprintf(fd, "%snum_iter = %d;\n", prefix, ps->numits);

fclose(fd);
PetscFunctionReturn(0);
}
Expand Down Expand Up @@ -888,7 +891,8 @@ PetscErrorCode PSSaveSolution_JSON(PS ps, const char outfile[]) {
PrintJSONArray(fd, "LOAD", 2, &ps->sys_info.total_load[0], true);
PrintJSONArray(fd, "LOADSHED", 2, &ps->sys_info.total_loadshed[0], true);

PrintJSONDouble(fd, "SolveRealTime", ps->solve_real_time, false);
PrintJSONDouble(fd, "SolveRealTime", ps->solve_real_time, true);
PrintJSONInt(fd, "NumIter", ps->numits, false);

PrintJSONObjectEnd(fd, false); // System summary object end

Expand Down Expand Up @@ -944,6 +948,7 @@ PetscErrorCode PSSaveSolution_MINIMAL(PS ps, const char outfile[]) {
fprintf(fd, "\tTotal Load Shed P, Q: %9g, %9g\n",
ps->sys_info.total_loadshed[0], ps->sys_info.total_loadshed[1]);
fprintf(fd, "\tSolve Time: %5g\n", ps->solve_real_time);
fprintf(fd, "\tNumber of iterations: %d\n", ps->numits);
fprintf(fd, "\tNzones: %d\n", ps->nzones);
fprintf(fd, "\tNareas: %d\n", ps->nareas);

Expand Down
89 changes: 47 additions & 42 deletions src/scopflow/interface/scopflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ PetscErrorCode SCOPFLOWSetUp(SCOPFLOW scopflow) {
PetscInt c, i, j;
PS ps;
OPFLOW opflow;
PetscBool issolver_ipopt;

char ploadprofile[PETSC_MAX_PATH_LEN];
char qloadprofile[PETSC_MAX_PATH_LEN];
Expand Down Expand Up @@ -652,8 +653,8 @@ PetscErrorCode SCOPFLOWSetUp(SCOPFLOW scopflow) {

ExaGOLog(EXAGO_LOG_INFO,
"SCOPFLOW running with {:d} subproblems (base case + {:d} "
"contingencies)",
scopflow->nc, scopflow->nc - 1);
"contingencies) globally; {:d} subproblems locally",
scopflow->Nc, scopflow->Nc - 1, scopflow->nc);

/* Set model */
if (!scopflow->ismultiperiod) {
Expand Down Expand Up @@ -694,11 +695,9 @@ PetscErrorCode SCOPFLOWSetUp(SCOPFLOW scopflow) {
ierr = OPFLOWIgnoreLineflowConstraints(
scopflow->opflow0, scopflow->ignore_lineflow_constraints);
CHKERRQ(ierr);
/* Base-case problem model should be POWER_BALANCE_POLAR */
ierr = OPFLOWSetModel(scopflow->opflow0, OPFLOWMODEL_PBPOL);
ierr = OPFLOWSetModel(scopflow->opflow0, scopflow->subproblem_model);
CHKERRQ(ierr);
/* Base-case problem solver should be IPOPT */
ierr = OPFLOWSetSolver(scopflow->opflow0, OPFLOWSOLVER_IPOPT);
ierr = OPFLOWSetSolver(scopflow->opflow0, scopflow->subproblem_solver);
CHKERRQ(ierr);
ierr = OPFLOWReadMatPowerData(scopflow->opflow0, scopflow->netfile);
CHKERRQ(ierr);
Expand Down Expand Up @@ -800,18 +799,20 @@ PetscErrorCode SCOPFLOWSetUp(SCOPFLOW scopflow) {
}

if (scopflow->cstart + c == 0) { /* First stage */
ierr = OPFLOWSetModel(scopflow->opflows[c], OPFLOWMODEL_PBPOL);
ierr = OPFLOWSetModel(scopflow->opflows[c], scopflow->subproblem_model);
CHKERRQ(ierr);
ierr = OPFLOWSetSolver(scopflow->opflows[c], OPFLOWSOLVER_IPOPT);
ierr =
OPFLOWSetSolver(scopflow->opflows[c], scopflow->subproblem_solver);
CHKERRQ(ierr);
ierr = OPFLOWSetObjectiveType(scopflow->opflows[c], MIN_GEN_COST);
CHKERRQ(ierr);
} else { /* Second stages */
ierr = OPFLOWHasGenSetPoint(scopflow->opflows[c], PETSC_TRUE);
CHKERRQ(ierr); /* Activates ramping variables */
ierr = OPFLOWSetModel(scopflow->opflows[c], OPFLOWMODEL_PBPOL);
ierr = OPFLOWSetModel(scopflow->opflows[c], scopflow->subproblem_model);
CHKERRQ(ierr);
ierr = OPFLOWSetSolver(scopflow->opflows[c], OPFLOWSOLVER_IPOPT);
ierr =
OPFLOWSetSolver(scopflow->opflows[c], scopflow->subproblem_solver);
CHKERRQ(ierr);
// ierr = OPFLOWSetObjectiveType(scopflow->opflows[c], NO_OBJ);
CHKERRQ(ierr);
Expand Down Expand Up @@ -935,40 +936,48 @@ PetscErrorCode SCOPFLOWSetUp(SCOPFLOW scopflow) {
}
}

/* Create vector X */
ierr = VecCreate(scopflow->comm->type, &scopflow->X);
CHKERRQ(ierr);
ierr = VecSetSizes(scopflow->X, scopflow->nx, PETSC_DECIDE);
CHKERRQ(ierr);
ierr = VecSetFromOptions(scopflow->X);
CHKERRQ(ierr);
ierr = VecGetSize(scopflow->X, &scopflow->Nx);
ierr = PetscStrcmp(scopflow->solvername.c_str(), "IPOPT", &issolver_ipopt);
CHKERRQ(ierr);
if (issolver_ipopt) {
/* Create vector X */
ierr = VecCreate(scopflow->comm->type, &scopflow->X);
CHKERRQ(ierr);
ierr = VecSetSizes(scopflow->X, scopflow->nx, PETSC_DECIDE);
CHKERRQ(ierr);
ierr = VecSetFromOptions(scopflow->X);
CHKERRQ(ierr);
ierr = VecGetSize(scopflow->X, &scopflow->Nx);
CHKERRQ(ierr);

ierr = VecDuplicate(scopflow->X, &scopflow->Xl);
CHKERRQ(ierr);
ierr = VecDuplicate(scopflow->X, &scopflow->Xu);
CHKERRQ(ierr);
ierr = VecDuplicate(scopflow->X, &scopflow->gradobj);
CHKERRQ(ierr);
ierr = VecDuplicate(scopflow->X, &scopflow->Xl);
CHKERRQ(ierr);
ierr = VecDuplicate(scopflow->X, &scopflow->Xu);
CHKERRQ(ierr);
ierr = VecDuplicate(scopflow->X, &scopflow->gradobj);
CHKERRQ(ierr);

/* Vector for constraints */
ierr = VecCreate(scopflow->comm->type, &scopflow->G);
CHKERRQ(ierr);
ierr = VecSetSizes(scopflow->G, scopflow->ncon, PETSC_DECIDE);
CHKERRQ(ierr);
/* Vector for constraints */
ierr = VecCreate(scopflow->comm->type, &scopflow->G);
CHKERRQ(ierr);
ierr = VecSetSizes(scopflow->G, scopflow->ncon, PETSC_DECIDE);
CHKERRQ(ierr);

ierr = VecSetFromOptions(scopflow->G);
CHKERRQ(ierr);
ierr = VecSetFromOptions(scopflow->G);
CHKERRQ(ierr);

ierr = VecGetSize(scopflow->G, &scopflow->Ncon);
CHKERRQ(ierr);
ierr = VecGetSize(scopflow->G, &scopflow->Ncon);
CHKERRQ(ierr);

/* Constraint bounds vectors */
ierr = VecDuplicate(scopflow->G, &scopflow->Gl);
CHKERRQ(ierr);
ierr = VecDuplicate(scopflow->G, &scopflow->Gu);
CHKERRQ(ierr);
/* Constraint bounds vectors */
ierr = VecDuplicate(scopflow->G, &scopflow->Gl);
CHKERRQ(ierr);
ierr = VecDuplicate(scopflow->G, &scopflow->Gu);
CHKERRQ(ierr);

/* Lagrangian multipliers */
ierr = VecDuplicate(scopflow->G, &scopflow->Lambda);
CHKERRQ(ierr);
}

/* The matrices are not used in parallel, so we don't need to create them */
if (scopflow->comm->size == 1) {
Expand Down Expand Up @@ -1007,10 +1016,6 @@ PetscErrorCode SCOPFLOWSetUp(SCOPFLOW scopflow) {
CHKERRQ(ierr);
}

/* Lagrangian multipliers */
ierr = VecDuplicate(scopflow->G, &scopflow->Lambda);
CHKERRQ(ierr);

ierr = (*scopflow->solverops.setup)(scopflow);
CHKERRQ(ierr);
ExaGOLog(EXAGO_LOG_INFO, "{}", "SCOPFLOW: Setup completed");
Expand Down
4 changes: 3 additions & 1 deletion src/sopflow/interface/sopflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,9 @@ PetscErrorCode SOPFLOWDestroy(SOPFLOW *sopflow) {
}
ierr = PetscFree((*sopflow)->scenlist.scen[s].forecastlist[i].id);
CHKERRQ(ierr);
ierr = PetscFree((*sopflow)->scenlist.scen[s].forecastlist[i].val);
ierr = PetscFree((*sopflow)->scenlist.scen[s].forecastlist[i].val1);
CHKERRQ(ierr);
ierr = PetscFree((*sopflow)->scenlist.scen[s].forecastlist[i].val2);
CHKERRQ(ierr);
}
}
Expand Down
Loading
Loading