From 5a7587a66288e6deaab55e4f70d50d91d64f17ef Mon Sep 17 00:00:00 2001 From: Maksudul Alam Date: Thu, 9 Apr 2026 20:11:03 +0000 Subject: [PATCH 01/15] Adding Support for Load Scenarios --- applications/sopflow_main.cpp | 17 +- src/ps/ps.cpp | 16 ++ src/sopflow/interface/sopflowscen.cpp | 390 ++++++++++++++++++++++++++ 3 files changed, 422 insertions(+), 1 deletion(-) diff --git a/applications/sopflow_main.cpp b/applications/sopflow_main.cpp index df98dcc7..9f588ce2 100644 --- a/applications/sopflow_main.cpp +++ b/applications/sopflow_main.cpp @@ -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]; 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"; @@ -54,6 +55,13 @@ 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); @@ -78,6 +86,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); */ diff --git a/src/ps/ps.cpp b/src/ps/ps.cpp index 15a7c3d7..fb9d66f9 100644 --- a/src/ps/ps.cpp +++ b/src/ps/ps.cpp @@ -1609,6 +1609,7 @@ PetscErrorCode PSApplyScenario(PS ps, Scenario scenario) { PetscInt i, j; Forecast *forecast; PSGEN gen; + PSLOAD load; PetscErrorCode ierr; PetscFunctionBegin; @@ -1638,6 +1639,21 @@ 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->val[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]); + } + } } } diff --git a/src/sopflow/interface/sopflowscen.cpp b/src/sopflow/interface/sopflowscen.cpp index df0d642b..e2620dc7 100644 --- a/src/sopflow/interface/sopflowscen.cpp +++ b/src/sopflow/interface/sopflowscen.cpp @@ -4,6 +4,9 @@ #include #include +#include +using namespace std; + extern void clean2Char(char *); extern char **blankTokenizer(const char *str, int *numtok, int maxtokens, int maxchar); @@ -35,6 +38,389 @@ PetscErrorCode SOPFLOWSetScenarioData(SOPFLOW sopflow, PetscFunctionReturn(0); } +/* + SOPFLOWReadScenarioData_Load_SinglePeriod - Reads the load data and populates +the scenario list Input Parameters ++ sopflow - SOPFLOW object +. loadprofile - load profile file + + Note: This function reads the load scenario data for "single period" format +files. +*/ +PetscErrorCode +SOPFLOWReadScenarioData_Load_SinglePeriod(SOPFLOW sopflow, + const char windgenprofile[]) { + PetscErrorCode ierr; + FILE *fp; + char line[MAXLINE]; + char *out; + PetscInt ngenwind, nw = 0; + char *tok, *tok2; + char sep[] = ",", sep2[] = "_"; + PetscReal pg, weight; + int scen_num = 0; + int genid; + int windgenbus[1000]; + char windgenid[1000][3]; + int i; + ScenarioList *scenlist = &sopflow->scenlist; + Scenario *scenario; + Forecast *forecast; + + PetscFunctionBegin; + + ngenwind = 1000; // This should be increased for larger cases (?) + fp = fopen(windgenprofile, "r"); + if (fp == NULL) { + SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, + "Cannot open wind generation profile file %s", windgenprofile); + } + + /* First line -- has the bus numbers */ + out = fgets(line, MAXLINE, fp); + /* Parse wind generator numbers */ + tok = strtok(line, sep); + tok = strtok(NULL, sep); /* Skip first token */ + while (tok != NULL) { + if (strcmp(tok, "weight") == 0 || strcmp(tok, "weight\n") == 0 || + strcmp(tok, "weight\r\n") == 0) { + tok = strtok(NULL, sep); + continue; + } + /* Parse generator info */ + tok2 = strsep(&tok, sep2); + sscanf(tok2, "%d", &windgenbus[nw]); + tok2 = strsep(&tok, sep2); + tok2 = strsep(&tok, sep2); /* Skip string "Wind" */ + sscanf(tok2, "%d", &genid); + if (nw == ngenwind) + SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, + "Exceeded max. number of wind generators=%d\n", ngenwind); + snprintf(windgenid[nw], 3, "%-2d", genid); + + nw++; + tok = strtok(NULL, sep); + } + + while ((out = fgets(line, MAXLINE, fp)) != NULL) { + if (strcmp(line, "\r\n") == 0 || strcmp(line, "\n") == 0) { + continue; /* Skip blank lines */ + } + + tok = strtok(line, sep); + sscanf(tok, "%d", &scen_num); /* Scenario number */ + scen_num -= 1; /* Scenario numbers start with 1 in the file, convert to + zero-based start */ + + if (scen_num < scenlist->Nscen || scen_num == sopflow->Ns) { + fclose(fp); + PetscFunctionReturn(0); + } + + scenario = &scenlist->scen[scen_num]; + forecast = &scenario->forecastlist[scenario->nforecast]; + forecast->num = scen_num; + forecast->type = FORECAST_LOAD_P; + forecast->nele = nw; + ierr = PetscCalloc1(forecast->nele, &forecast->buses); + CHKERRQ(ierr); + ierr = PetscCalloc1(forecast->nele, &forecast->id); + CHKERRQ(ierr); + for (i = 0; i < forecast->nele; i++) { + ierr = PetscCalloc1(3, &forecast->id[i]); + } + ierr = PetscCalloc1(forecast->nele, &forecast->val); + CHKERRQ(ierr); + + tok = strtok(NULL, sep); + for (i = 0; i < nw; i++) { + forecast->buses[i] = windgenbus[i]; + ierr = PetscStrcpy(forecast->id[i], windgenid[i]); + CHKERRQ(ierr); + sscanf(tok, "%lf", &pg); + forecast->val[i] = pg; + tok = strtok(NULL, sep); + } + + /* Read scenario weight */ + sscanf(tok, "%lf", &weight); + scenario->prob = weight; + + scenario->nforecast++; + scenlist->Nscen++; + } + PetscFunctionReturn(0); +} + +// Need to implementa a separate type of scenario data reader +PetscErrorCode +SOPFLOWReadScenarioData_GenLoad_SinglePeriod(SOPFLOW sopflow, + const char windgenprofile[]) { + + //printf("I am being called\n"); + PetscErrorCode ierr; + FILE *fp; + char line[MAXLINE]; + char *out; + PetscInt ngenwind, nw = 0; + char *tok, *tok2, *tok3, *tok4, *tok5; + char sep_comma[] = ",", sep2_dash[] = "_"; + PetscReal pg, weight; + int scen_num = 0; + int genid; + int bus[1000]; + char genids[1000][3]; + int i; + ScenarioList *scenlist = &sopflow->scenlist; + Scenario *scenario; + Forecast *forecast; + + PetscFunctionBegin; + + ngenwind = 1000; // This should be increased for larger cases (?) + fp = fopen(windgenprofile, "r"); + if (fp == NULL) { + SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, + "Cannot open wind generation profile file %s", windgenprofile); + } + + /* First line -- has the bus numbers */ + out = fgets(line, MAXLINE, fp); + /* Parse wind generator numbers */ + tok = strtok(line, sep_comma); + tok = strtok(NULL, sep_comma); /* Skip first token */ + while (tok != NULL) { + if (strcmp(tok, "weight") == 0 || strcmp(tok, "weight\n") == 0 || + strcmp(tok, "weight\r\n") == 0) { + tok = strtok(NULL, sep_comma); + continue; + } + + // sscanf(tok2, "%d", &genid); + // if (nw == ngenwind) + // SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, + // "Exceeded max. number of wind generators=%d\n", ngenwind); + // snprintf(genids[nw], 3, "%-2d", genid); + + // nw++; + tok = strtok(NULL, sep_comma); + } + + printf("Done Parsing Header. nw = %d\n", nw); + + // Body + while ((out = fgets(line, MAXLINE, fp)) != NULL) { + if (strcmp(line, "\r\n") == 0 || strcmp(line, "\n") == 0) { + continue; /* Skip blank lines */ + } + + tok = strtok(line, sep_comma); + sscanf(tok, "%d", &scen_num); /* Scenario number */ + scen_num -= 1; /* Scenario numbers start with 1 in the file, convert to + zero-based start */ + + printf("Parsing scenario number %d\n", scen_num); + + tok2 = strsep(&tok, sep2_dash); // Bus Number + + // sscanf(tok2, "%d", &bus[nw]); + // tok3 = strsep(&tok, sep2_dash); // Wind + // tok4 = strsep(&tok, sep2_dash); // Gen ID + // tok5 = strsep(&tok, sep2_dash); // Value + + if (scen_num < scenlist->Nscen || scen_num == sopflow->Ns) { + fclose(fp); + PetscFunctionReturn(0); + } + + struct GenData { + int busnum; + PetscReal value; + char id[3]; + }; + + vector gendata; + + tok = strtok(NULL, sep_comma); + sscanf(tok, "%lf", &weight); + + // printf("Scenario weight = %lf\n", weight); + + tok = strtok(NULL, sep_comma); + while (tok != NULL) { + + // printf("## tok = %s\n", tok); + + GenData gd; + + /* Parse generator info */ + tok2 = strsep(&tok, sep2_dash); // Bus Number + sscanf(tok2, "%d", &gd.busnum); + tok3 = strsep(&tok, sep2_dash); // Wind + tok4 = strsep(&tok, sep2_dash); // Gen ID + sscanf(tok4, "%d", &genid); + snprintf(gd.id, 3, "%-2d", genid); + tok5 = strsep(&tok, sep2_dash); // Value + sscanf(tok5, "%lf", &gd.value); + + gendata.push_back(gd); + + // printf("## gd = %d, %s, %lf\n", gd.busnum, gd.id, gd.value); + + // printf("!Token = %s\n", gendata.back()); + tok = strtok(NULL, sep_comma); + } + // printf("Done Parsing Tokens\n"); + scenario = &scenlist->scen[scen_num]; + forecast = &scenario->forecastlist[scenario->nforecast]; + forecast->num = scen_num; + forecast->type = FORECAST_LOAD_P; + forecast->nele = gendata.size(); + ierr = PetscCalloc1(forecast->nele, &forecast->buses); + CHKERRQ(ierr); + ierr = PetscCalloc1(forecast->nele, &forecast->id); + CHKERRQ(ierr); + for (i = 0; i < forecast->nele; i++) { + ierr = PetscCalloc1(3, &forecast->id[i]); + } + ierr = PetscCalloc1(forecast->nele, &forecast->val); + CHKERRQ(ierr); + + // tok = strtok(NULL, sep_comma); + + for (i = 0; i < gendata.size(); i++) { + forecast->buses[i] = gendata[i].busnum; + ierr = PetscStrcpy(forecast->id[i], gendata[i].id); + CHKERRQ(ierr); + // sscanf(tok, "%lf", &pg); + forecast->val[i] = gendata[i].value; + // tok = strtok(NULL, sep_comma); + } + + // /* Read scenario weight */ + // sscanf(tok, "%lf", &weight); + scenario->prob = weight; + + scenario->nforecast++; + scenlist->Nscen++; + } + PetscFunctionReturn(0); +} + +/* + SOPFLOWReadScenarioData_Wind_SinglePeriod - Reads the wind data and populates +the scenario list Input Parameters ++ sopflow - SOPFLOW object +. windgenprofile - wind generator profile file + + Note: This function reads the wind scenario data for "single period" format +files. +*/ +PetscErrorCode +SOPFLOWReadScenarioData_Wind_SinglePeriod_2(SOPFLOW sopflow, + const char windgenprofile[]) { + PetscErrorCode ierr; + FILE *fp; + char line[MAXLINE]; + char *out; + PetscInt ngenwind, nw = 0; + char *tok, *tok2; + char sep[] = ",", sep2[] = "_"; + PetscReal pg, weight; + int scen_num = 0; + int genid; + int windgenbus[1000]; + char windgenid[1000][3]; + int i; + ScenarioList *scenlist = &sopflow->scenlist; + Scenario *scenario; + Forecast *forecast; + + PetscFunctionBegin; + + ngenwind = 1000; // This should be increased for larger cases (?) + fp = fopen(windgenprofile, "r"); + if (fp == NULL) { + SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, + "Cannot open wind generation profile file %s", windgenprofile); + } + + /* First line -- has the bus numbers */ + out = fgets(line, MAXLINE, fp); + /* Parse wind generator numbers */ + tok = strtok(line, sep); + tok = strtok(NULL, sep); /* Skip first token */ + while (tok != NULL) { + if (strcmp(tok, "weight") == 0 || strcmp(tok, "weight\n") == 0 || + strcmp(tok, "weight\r\n") == 0) { + tok = strtok(NULL, sep); + continue; + } + /* Parse generator info */ + tok2 = strsep(&tok, sep2); + sscanf(tok2, "%d", &windgenbus[nw]); + tok2 = strsep(&tok, sep2); + tok2 = strsep(&tok, sep2); /* Skip string "Wind" */ + sscanf(tok2, "%d", &genid); + if (nw == ngenwind) + SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, + "Exceeded max. number of wind generators=%d\n", ngenwind); + snprintf(windgenid[nw], 3, "%-2d", genid); + + nw++; + tok = strtok(NULL, sep); + } + + while ((out = fgets(line, MAXLINE, fp)) != NULL) { + if (strcmp(line, "\r\n") == 0 || strcmp(line, "\n") == 0) { + continue; /* Skip blank lines */ + } + + tok = strtok(line, sep); + sscanf(tok, "%d", &scen_num); /* Scenario number */ + scen_num -= 1; /* Scenario numbers start with 1 in the file, convert to + zero-based start */ + + if (scen_num < scenlist->Nscen || scen_num == sopflow->Ns) { + fclose(fp); + PetscFunctionReturn(0); + } + + scenario = &scenlist->scen[scen_num]; + forecast = &scenario->forecastlist[scenario->nforecast]; + forecast->num = scen_num; + forecast->type = FORECAST_WIND; + forecast->nele = nw; + ierr = PetscCalloc1(forecast->nele, &forecast->buses); + CHKERRQ(ierr); + ierr = PetscCalloc1(forecast->nele, &forecast->id); + CHKERRQ(ierr); + for (i = 0; i < forecast->nele; i++) { + ierr = PetscCalloc1(3, &forecast->id[i]); + } + ierr = PetscCalloc1(forecast->nele, &forecast->val); + CHKERRQ(ierr); + + tok = strtok(NULL, sep); + for (i = 0; i < nw; i++) { + forecast->buses[i] = windgenbus[i]; + ierr = PetscStrcpy(forecast->id[i], windgenid[i]); + CHKERRQ(ierr); + sscanf(tok, "%lf", &pg); + forecast->val[i] = pg; + tok = strtok(NULL, sep); + } + + /* Read scenario weight */ + sscanf(tok, "%lf", &weight); + scenario->prob = weight; + + scenario->nforecast++; + scenlist->Nscen++; + } + PetscFunctionReturn(0); +} + /* SOPFLOWReadScenarioData_Wind_SinglePeriod - Reads the wind data and populates the scenario list Input Parameters @@ -284,6 +670,10 @@ PetscErrorCode SOPFLOWReadScenarioData(SOPFLOW sopflow, ierr = SOPFLOWReadScenarioData_Wind_MultiPeriod(sopflow, scenfile); CHKERRQ(ierr); } + } else if (sopflow->scenunctype == LOAD) { + //ierr = SOPFLOWReadScenarioData_Load_SinglePeriod(sopflow, scenfile); + ierr = SOPFLOWReadScenarioData_GenLoad_SinglePeriod(sopflow, scenfile); + CHKERRQ(ierr); } PetscFunctionReturn(0); From 818f9a231120b219b3a6c28261161689b06124ed Mon Sep 17 00:00:00 2001 From: Maksudul Alam Date: Thu, 9 Apr 2026 20:16:13 +0000 Subject: [PATCH 02/15] Adding a sample load scenario --- datafiles/case9/10_scenarios_9bus_load.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 datafiles/case9/10_scenarios_9bus_load.txt diff --git a/datafiles/case9/10_scenarios_9bus_load.txt b/datafiles/case9/10_scenarios_9bus_load.txt new file mode 100644 index 00000000..819760f3 --- /dev/null +++ b/datafiles/case9/10_scenarios_9bus_load.txt @@ -0,0 +1,11 @@ +scenario_nr,weight,kv_list +1,0.1,8_Load_1_185.0,6_Load_1_105.5 +2,0.1,6_Load_1_105.0 +3,0.1,8_Load_1_75.0 +4,0.1,6_Load_1_95.0 +5,0.1,8_Load_1_115.0 +6,0.1,6_Load_1_65.0 +7,0.1,8_Load_1_33.0 +8,0.1,6_Load_1_125.0 +9,0.1,8_Load_1_55.0 +10,0.1,6_Load_1_250.0 From 6a1449b8ae83adba56b50e40e9e61635111995aa Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Thu, 26 Feb 2026 13:32:22 -0500 Subject: [PATCH 03/15] Print total scopflow_Nc and distinguish with nc on rank 0. --- src/scopflow/interface/scopflow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scopflow/interface/scopflow.cpp b/src/scopflow/interface/scopflow.cpp index dcf45fce..83a84b1b 100644 --- a/src/scopflow/interface/scopflow.cpp +++ b/src/scopflow/interface/scopflow.cpp @@ -652,8 +652,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) { From 525daa2f51c45f834591d1fe689643d95a912bab Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Fri, 27 Feb 2026 11:16:07 -0500 Subject: [PATCH 04/15] Don't create scopflow vectors if solver is not IPOPT. --- src/scopflow/interface/scopflow.cpp | 70 ++++++++++++++++------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/src/scopflow/interface/scopflow.cpp b/src/scopflow/interface/scopflow.cpp index 83a84b1b..772d63b9 100644 --- a/src/scopflow/interface/scopflow.cpp +++ b/src/scopflow/interface/scopflow.cpp @@ -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]; @@ -935,40 +936,49 @@ 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) { @@ -1007,10 +1017,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"); From 17073621f0efe55b515c318f4834d4baa1e93d40 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Fri, 27 Feb 2026 05:46:51 -0500 Subject: [PATCH 05/15] Fixes to run scopflow with DCOPF? --- include/opflow.h | 1 + src/scopflow/interface/scopflow.cpp | 12 +++++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/opflow.h b/include/opflow.h index bce416c8..a778568b 100644 --- a/include/opflow.h +++ b/include/opflow.h @@ -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", diff --git a/src/scopflow/interface/scopflow.cpp b/src/scopflow/interface/scopflow.cpp index 772d63b9..afa319e4 100644 --- a/src/scopflow/interface/scopflow.cpp +++ b/src/scopflow/interface/scopflow.cpp @@ -695,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); @@ -801,7 +799,7 @@ 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); CHKERRQ(ierr); @@ -810,9 +808,9 @@ PetscErrorCode SCOPFLOWSetUp(SCOPFLOW scopflow) { } 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); From 0fb78c5d0f9fca78df2b7496eaf75eba560998b6 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Wed, 4 Mar 2026 11:36:23 -0500 Subject: [PATCH 06/15] Missing change to scopflow->subproblem_solver --- src/scopflow/interface/scopflow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scopflow/interface/scopflow.cpp b/src/scopflow/interface/scopflow.cpp index afa319e4..95cca557 100644 --- a/src/scopflow/interface/scopflow.cpp +++ b/src/scopflow/interface/scopflow.cpp @@ -801,7 +801,7 @@ PetscErrorCode SCOPFLOWSetUp(SCOPFLOW scopflow) { if (scopflow->cstart + c == 0) { /* First stage */ 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); From 542ef69f03286df98cb7eadb5d05203a8b9c7e3f Mon Sep 17 00:00:00 2001 From: nkoukpaizan Date: Wed, 4 Mar 2026 16:42:42 +0000 Subject: [PATCH 07/15] Apply pre-commmit fixes --- include/opflow.h | 2 +- src/scopflow/interface/scopflow.cpp | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/opflow.h b/include/opflow.h index a778568b..f46bc3a1 100644 --- a/include/opflow.h +++ b/include/opflow.h @@ -65,7 +65,7 @@ namespace OPFLOWOptions { const auto model = ExaGOStringOption("-opflow_model", "OPFLOW model name", "POWER_BALANCE_POLAR", { - "DCOPF", + "DCOPF", #ifdef EXAGO_ENABLE_HIOP "POWER_BALANCE_HIOP", "PBPOLRAJAHIOP", diff --git a/src/scopflow/interface/scopflow.cpp b/src/scopflow/interface/scopflow.cpp index 95cca557..35346192 100644 --- a/src/scopflow/interface/scopflow.cpp +++ b/src/scopflow/interface/scopflow.cpp @@ -801,7 +801,8 @@ PetscErrorCode SCOPFLOWSetUp(SCOPFLOW scopflow) { if (scopflow->cstart + c == 0) { /* First stage */ ierr = OPFLOWSetModel(scopflow->opflows[c], scopflow->subproblem_model); CHKERRQ(ierr); - ierr = OPFLOWSetSolver(scopflow->opflows[c], scopflow->subproblem_solver); + ierr = + OPFLOWSetSolver(scopflow->opflows[c], scopflow->subproblem_solver); CHKERRQ(ierr); ierr = OPFLOWSetObjectiveType(scopflow->opflows[c], MIN_GEN_COST); CHKERRQ(ierr); @@ -810,7 +811,8 @@ PetscErrorCode SCOPFLOWSetUp(SCOPFLOW scopflow) { CHKERRQ(ierr); /* Activates ramping variables */ ierr = OPFLOWSetModel(scopflow->opflows[c], scopflow->subproblem_model); CHKERRQ(ierr); - ierr = OPFLOWSetSolver(scopflow->opflows[c], scopflow->subproblem_solver); + ierr = + OPFLOWSetSolver(scopflow->opflows[c], scopflow->subproblem_solver); CHKERRQ(ierr); // ierr = OPFLOWSetObjectiveType(scopflow->opflows[c], NO_OBJ); CHKERRQ(ierr); @@ -936,8 +938,7 @@ PetscErrorCode SCOPFLOWSetUp(SCOPFLOW scopflow) { ierr = PetscStrcmp(scopflow->solvername.c_str(), "IPOPT", &issolver_ipopt); CHKERRQ(ierr); - if (issolver_ipopt) - { + if (issolver_ipopt) { /* Create vector X */ ierr = VecCreate(scopflow->comm->type, &scopflow->X); CHKERRQ(ierr); From f6beca1d3bafc1aace1319d13a5644f3f83381e2 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Wed, 25 Mar 2026 09:46:36 -0400 Subject: [PATCH 08/15] Decrease max_lazy_iter to get answers in finite time without diverging. --- src/opflow/interface/opflow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opflow/interface/opflow.cpp b/src/opflow/interface/opflow.cpp index 64c7ed60..06438480 100644 --- a/src/opflow/interface/opflow.cpp +++ b/src/opflow/interface/opflow.cpp @@ -2119,7 +2119,7 @@ PetscErrorCode OPFLOWSolve(OPFLOW opflow) { OPFLOW opflow2; PetscBool has_overload = PETSC_FALSE; PetscInt lazy_iter = 0; - PetscInt max_lazy_iter = 10; + PetscInt max_lazy_iter = 2; PetscInt nlines_overloaded; PetscInt *lines_overloaded; From 99450126416e878b767e8105e36329bd37484ed6 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Wed, 25 Mar 2026 12:52:34 -0400 Subject: [PATCH 09/15] Revert "Decrease max_lazy_iter to get answers in finite time without diverging." This reverts commit e61b89b548c321e84d10fd462c8ac58c90843eec. --- src/opflow/interface/opflow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opflow/interface/opflow.cpp b/src/opflow/interface/opflow.cpp index 06438480..64c7ed60 100644 --- a/src/opflow/interface/opflow.cpp +++ b/src/opflow/interface/opflow.cpp @@ -2119,7 +2119,7 @@ PetscErrorCode OPFLOWSolve(OPFLOW opflow) { OPFLOW opflow2; PetscBool has_overload = PETSC_FALSE; PetscInt lazy_iter = 0; - PetscInt max_lazy_iter = 2; + PetscInt max_lazy_iter = 10; PetscInt nlines_overloaded; PetscInt *lines_overloaded; From ef220e1b4c7cb875cf81cd2a0719967f49074823 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 30 Mar 2026 19:38:43 -0400 Subject: [PATCH 10/15] Save numits. --- include/private/psimpl.h | 3 ++- src/opflow/interface/opflow.cpp | 1 + src/ps/psoutput.cpp | 7 ++++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/private/psimpl.h b/include/private/psimpl.h index 225a67cf..fc1d859f 100644 --- a/include/private/psimpl.h +++ b/include/private/psimpl.h @@ -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); diff --git a/src/opflow/interface/opflow.cpp b/src/opflow/interface/opflow.cpp index 64c7ed60..9c42ef36 100644 --- a/src/opflow/interface/opflow.cpp +++ b/src/opflow/interface/opflow.cpp @@ -3196,6 +3196,7 @@ PetscErrorCode OPFLOWSetSummaryStats(OPFLOW opflow) { CHKERRQ(ierr); ps->solve_real_time = opflow->solve_real_time; + ps->numits = opflow->numits; PetscFunctionReturn(0); } diff --git a/src/ps/psoutput.cpp b/src/ps/psoutput.cpp index a7f3f7e7..d2642fba 100644 --- a/src/ps/psoutput.cpp +++ b/src/ps/psoutput.cpp @@ -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); } @@ -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 @@ -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); From 42ced776bfd17cee9ccaffffd94dcf8553777048 Mon Sep 17 00:00:00 2001 From: Maksudul Alam Date: Thu, 16 Apr 2026 18:39:03 +0000 Subject: [PATCH 11/15] Updating to include PQ Loads --- datafiles/case9/10_scenarios_9bus_load.txt | 20 +-- include/common.h | 2 +- include/private/scenariolist.h | 3 +- src/ps/ps.cpp | 20 ++- src/sopflow/interface/sopflow.cpp | 4 +- src/sopflow/interface/sopflowscen.cpp | 194 +++++---------------- 6 files changed, 75 insertions(+), 168 deletions(-) diff --git a/datafiles/case9/10_scenarios_9bus_load.txt b/datafiles/case9/10_scenarios_9bus_load.txt index 819760f3..a9374ae4 100644 --- a/datafiles/case9/10_scenarios_9bus_load.txt +++ b/datafiles/case9/10_scenarios_9bus_load.txt @@ -1,11 +1,11 @@ scenario_nr,weight,kv_list -1,0.1,8_Load_1_185.0,6_Load_1_105.5 -2,0.1,6_Load_1_105.0 -3,0.1,8_Load_1_75.0 -4,0.1,6_Load_1_95.0 -5,0.1,8_Load_1_115.0 -6,0.1,6_Load_1_65.0 -7,0.1,8_Load_1_33.0 -8,0.1,6_Load_1_125.0 -9,0.1,8_Load_1_55.0 -10,0.1,6_Load_1_250.0 +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 +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 diff --git a/include/common.h b/include/common.h index 357a2e58..b906419f 100644 --- a/include/common.h +++ b/include/common.h @@ -21,7 +21,7 @@ typedef enum { typedef enum { FORECAST_WIND = 1, FORECAST_LOAD_P = 2, - FORECAST_LOAD_Q = 3 + FORECAST_LOAD_PQ = 3 } ForecastType; /** diff --git a/include/private/scenariolist.h b/include/private/scenariolist.h index 4e6bae44..f1ddb687 100644 --- a/include/private/scenariolist.h +++ b/include/private/scenariolist.h @@ -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 */ }; typedef struct _p_Forecast Forecast; diff --git a/src/ps/ps.cpp b/src/ps/ps.cpp index fb9d66f9..ca363a73 100644 --- a/src/ps/ps.cpp +++ b/src/ps/ps.cpp @@ -1622,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 */ @@ -1645,9 +1645,21 @@ PetscErrorCode PSApplyScenario(PS ps, Scenario scenario) { ierr = PSGetLoad(ps, forecast->buses[j], forecast->id[j], &load); CHKERRQ(ierr); if (load) { - load->pl = - forecast->val[j] / - ps->MVAbase; /* Set real power 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", diff --git a/src/sopflow/interface/sopflow.cpp b/src/sopflow/interface/sopflow.cpp index dfdbc745..7c00f8ad 100644 --- a/src/sopflow/interface/sopflow.cpp +++ b/src/sopflow/interface/sopflow.cpp @@ -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); } } diff --git a/src/sopflow/interface/sopflowscen.cpp b/src/sopflow/interface/sopflowscen.cpp index e2620dc7..e426c469 100644 --- a/src/sopflow/interface/sopflowscen.cpp +++ b/src/sopflow/interface/sopflowscen.cpp @@ -39,7 +39,7 @@ PetscErrorCode SOPFLOWSetScenarioData(SOPFLOW sopflow, } /* - SOPFLOWReadScenarioData_Load_SinglePeriod - Reads the load data and populates + SOPFLOWReadScenarioData_LoadPQ_SinglePeriod - Reads the load data and populates the scenario list Input Parameters + sopflow - SOPFLOW object . loadprofile - load profile file @@ -48,124 +48,18 @@ the scenario list Input Parameters files. */ PetscErrorCode -SOPFLOWReadScenarioData_Load_SinglePeriod(SOPFLOW sopflow, - const char windgenprofile[]) { - PetscErrorCode ierr; - FILE *fp; - char line[MAXLINE]; - char *out; - PetscInt ngenwind, nw = 0; - char *tok, *tok2; - char sep[] = ",", sep2[] = "_"; - PetscReal pg, weight; - int scen_num = 0; - int genid; - int windgenbus[1000]; - char windgenid[1000][3]; - int i; - ScenarioList *scenlist = &sopflow->scenlist; - Scenario *scenario; - Forecast *forecast; - - PetscFunctionBegin; - - ngenwind = 1000; // This should be increased for larger cases (?) - fp = fopen(windgenprofile, "r"); - if (fp == NULL) { - SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, - "Cannot open wind generation profile file %s", windgenprofile); - } - - /* First line -- has the bus numbers */ - out = fgets(line, MAXLINE, fp); - /* Parse wind generator numbers */ - tok = strtok(line, sep); - tok = strtok(NULL, sep); /* Skip first token */ - while (tok != NULL) { - if (strcmp(tok, "weight") == 0 || strcmp(tok, "weight\n") == 0 || - strcmp(tok, "weight\r\n") == 0) { - tok = strtok(NULL, sep); - continue; - } - /* Parse generator info */ - tok2 = strsep(&tok, sep2); - sscanf(tok2, "%d", &windgenbus[nw]); - tok2 = strsep(&tok, sep2); - tok2 = strsep(&tok, sep2); /* Skip string "Wind" */ - sscanf(tok2, "%d", &genid); - if (nw == ngenwind) - SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, - "Exceeded max. number of wind generators=%d\n", ngenwind); - snprintf(windgenid[nw], 3, "%-2d", genid); - - nw++; - tok = strtok(NULL, sep); - } - - while ((out = fgets(line, MAXLINE, fp)) != NULL) { - if (strcmp(line, "\r\n") == 0 || strcmp(line, "\n") == 0) { - continue; /* Skip blank lines */ - } - - tok = strtok(line, sep); - sscanf(tok, "%d", &scen_num); /* Scenario number */ - scen_num -= 1; /* Scenario numbers start with 1 in the file, convert to - zero-based start */ - - if (scen_num < scenlist->Nscen || scen_num == sopflow->Ns) { - fclose(fp); - PetscFunctionReturn(0); - } - - scenario = &scenlist->scen[scen_num]; - forecast = &scenario->forecastlist[scenario->nforecast]; - forecast->num = scen_num; - forecast->type = FORECAST_LOAD_P; - forecast->nele = nw; - ierr = PetscCalloc1(forecast->nele, &forecast->buses); - CHKERRQ(ierr); - ierr = PetscCalloc1(forecast->nele, &forecast->id); - CHKERRQ(ierr); - for (i = 0; i < forecast->nele; i++) { - ierr = PetscCalloc1(3, &forecast->id[i]); - } - ierr = PetscCalloc1(forecast->nele, &forecast->val); - CHKERRQ(ierr); - - tok = strtok(NULL, sep); - for (i = 0; i < nw; i++) { - forecast->buses[i] = windgenbus[i]; - ierr = PetscStrcpy(forecast->id[i], windgenid[i]); - CHKERRQ(ierr); - sscanf(tok, "%lf", &pg); - forecast->val[i] = pg; - tok = strtok(NULL, sep); - } - - /* Read scenario weight */ - sscanf(tok, "%lf", &weight); - scenario->prob = weight; - - scenario->nforecast++; - scenlist->Nscen++; - } - PetscFunctionReturn(0); -} - -// Need to implementa a separate type of scenario data reader -PetscErrorCode -SOPFLOWReadScenarioData_GenLoad_SinglePeriod(SOPFLOW sopflow, +SOPFLOWReadScenarioData_LoadPQ_SinglePeriod(SOPFLOW sopflow, const char windgenprofile[]) { - //printf("I am being called\n"); + // printf("I am being called\n"); PetscErrorCode ierr; FILE *fp; char line[MAXLINE]; char *out; PetscInt ngenwind, nw = 0; - char *tok, *tok2, *tok3, *tok4, *tok5; + char *tok, *tok2, *tok3, *tok4, *tok5, *tok6; char sep_comma[] = ",", sep2_dash[] = "_"; - PetscReal pg, weight; + PetscReal pl, ql, weight; int scen_num = 0; int genid; int bus[1000]; @@ -187,28 +81,11 @@ SOPFLOWReadScenarioData_GenLoad_SinglePeriod(SOPFLOW sopflow, /* First line -- has the bus numbers */ out = fgets(line, MAXLINE, fp); /* Parse wind generator numbers */ - tok = strtok(line, sep_comma); - tok = strtok(NULL, sep_comma); /* Skip first token */ - while (tok != NULL) { - if (strcmp(tok, "weight") == 0 || strcmp(tok, "weight\n") == 0 || - strcmp(tok, "weight\r\n") == 0) { - tok = strtok(NULL, sep_comma); - continue; - } - - // sscanf(tok2, "%d", &genid); - // if (nw == ngenwind) - // SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, - // "Exceeded max. number of wind generators=%d\n", ngenwind); - // snprintf(genids[nw], 3, "%-2d", genid); - - // nw++; - tok = strtok(NULL, sep_comma); - } printf("Done Parsing Header. nw = %d\n", nw); - // Body + // Body Example + // 1,0.1,8_Load_1_185.0_10,6_Load_1_105.5_20 while ((out = fgets(line, MAXLINE, fp)) != NULL) { if (strcmp(line, "\r\n") == 0 || strcmp(line, "\n") == 0) { continue; /* Skip blank lines */ @@ -221,7 +98,7 @@ SOPFLOWReadScenarioData_GenLoad_SinglePeriod(SOPFLOW sopflow, printf("Parsing scenario number %d\n", scen_num); - tok2 = strsep(&tok, sep2_dash); // Bus Number + // tok2 = strsep(&tok, sep2_dash); // Bus Number // sscanf(tok2, "%d", &bus[nw]); // tok3 = strsep(&tok, sep2_dash); // Wind @@ -235,7 +112,8 @@ SOPFLOWReadScenarioData_GenLoad_SinglePeriod(SOPFLOW sopflow, struct GenData { int busnum; - PetscReal value; + PetscReal value1; + PetscReal value2; char id[3]; }; @@ -244,7 +122,7 @@ SOPFLOWReadScenarioData_GenLoad_SinglePeriod(SOPFLOW sopflow, tok = strtok(NULL, sep_comma); sscanf(tok, "%lf", &weight); - // printf("Scenario weight = %lf\n", weight); + printf("Scenario weight = %lf\n", weight); tok = strtok(NULL, sep_comma); while (tok != NULL) { @@ -256,25 +134,35 @@ SOPFLOWReadScenarioData_GenLoad_SinglePeriod(SOPFLOW sopflow, /* Parse generator info */ tok2 = strsep(&tok, sep2_dash); // Bus Number sscanf(tok2, "%d", &gd.busnum); - tok3 = strsep(&tok, sep2_dash); // Wind - tok4 = strsep(&tok, sep2_dash); // Gen ID + printf("Bus number = %d\n", gd.busnum); + tok3 = strsep(&tok, sep2_dash); // Type (Load or Gen) + tok4 = strsep(&tok, sep2_dash); // CKT sscanf(tok4, "%d", &genid); snprintf(gd.id, 3, "%-2d", genid); - tok5 = strsep(&tok, sep2_dash); // Value - sscanf(tok5, "%lf", &gd.value); + printf("Gen ID = %s\n", gd.id); + tok5 = strsep(&tok, sep2_dash); // Value1 + sscanf(tok5, "%lf", &gd.value1); + printf("Value1 = %lf\n", gd.value1); + tok6 = strsep(&tok, sep2_dash); // Value2 + sscanf(tok6, "%lf", &gd.value2); + printf("Value2 = %lf\n", gd.value2); gendata.push_back(gd); - // printf("## gd = %d, %s, %lf\n", gd.busnum, gd.id, gd.value); + printf("## gd = %d, %s, %lf, %lf\n", gd.busnum, gd.id, gd.value1, + gd.value2); // printf("!Token = %s\n", gendata.back()); tok = strtok(NULL, sep_comma); + + printf("## tok = %s\n", tok); } - // printf("Done Parsing Tokens\n"); + + printf("Done Parsing 1 line of Tokens\n"); scenario = &scenlist->scen[scen_num]; forecast = &scenario->forecastlist[scenario->nforecast]; forecast->num = scen_num; - forecast->type = FORECAST_LOAD_P; + forecast->type = FORECAST_LOAD_PQ; forecast->nele = gendata.size(); ierr = PetscCalloc1(forecast->nele, &forecast->buses); CHKERRQ(ierr); @@ -282,9 +170,13 @@ SOPFLOWReadScenarioData_GenLoad_SinglePeriod(SOPFLOW sopflow, CHKERRQ(ierr); for (i = 0; i < forecast->nele; i++) { ierr = PetscCalloc1(3, &forecast->id[i]); + CHKERRQ(ierr); } - ierr = PetscCalloc1(forecast->nele, &forecast->val); + ierr = PetscCalloc1(forecast->nele, &forecast->val1); CHKERRQ(ierr); + ierr = PetscCalloc1(forecast->nele, &forecast->val2); + CHKERRQ(ierr); + // tok = strtok(NULL, sep_comma); @@ -293,7 +185,8 @@ SOPFLOWReadScenarioData_GenLoad_SinglePeriod(SOPFLOW sopflow, ierr = PetscStrcpy(forecast->id[i], gendata[i].id); CHKERRQ(ierr); // sscanf(tok, "%lf", &pg); - forecast->val[i] = gendata[i].value; + forecast->val1[i] = gendata[i].value1; + forecast->val2[i] = gendata[i].value2; // tok = strtok(NULL, sep_comma); } @@ -318,7 +211,7 @@ files. */ PetscErrorCode SOPFLOWReadScenarioData_Wind_SinglePeriod_2(SOPFLOW sopflow, - const char windgenprofile[]) { + const char windgenprofile[]) { PetscErrorCode ierr; FILE *fp; char line[MAXLINE]; @@ -398,7 +291,7 @@ SOPFLOWReadScenarioData_Wind_SinglePeriod_2(SOPFLOW sopflow, for (i = 0; i < forecast->nele; i++) { ierr = PetscCalloc1(3, &forecast->id[i]); } - ierr = PetscCalloc1(forecast->nele, &forecast->val); + ierr = PetscCalloc1(forecast->nele, &forecast->val1); CHKERRQ(ierr); tok = strtok(NULL, sep); @@ -407,7 +300,7 @@ SOPFLOWReadScenarioData_Wind_SinglePeriod_2(SOPFLOW sopflow, ierr = PetscStrcpy(forecast->id[i], windgenid[i]); CHKERRQ(ierr); sscanf(tok, "%lf", &pg); - forecast->val[i] = pg; + forecast->val1[i] = pg; tok = strtok(NULL, sep); } @@ -512,7 +405,7 @@ SOPFLOWReadScenarioData_Wind_SinglePeriod(SOPFLOW sopflow, for (i = 0; i < forecast->nele; i++) { ierr = PetscCalloc1(3, &forecast->id[i]); } - ierr = PetscCalloc1(forecast->nele, &forecast->val); + ierr = PetscCalloc1(forecast->nele, &forecast->val1); CHKERRQ(ierr); tok = strtok(NULL, sep); @@ -521,7 +414,7 @@ SOPFLOWReadScenarioData_Wind_SinglePeriod(SOPFLOW sopflow, ierr = PetscStrcpy(forecast->id[i], windgenid[i]); CHKERRQ(ierr); sscanf(tok, "%lf", &pg); - forecast->val[i] = pg; + forecast->val1[i] = pg; tok = strtok(NULL, sep); } @@ -624,7 +517,7 @@ SOPFLOWReadScenarioData_Wind_MultiPeriod(SOPFLOW sopflow, for (i = 0; i < forecast->nele; i++) { ierr = PetscCalloc1(3, &forecast->id[i]); } - ierr = PetscCalloc1(forecast->nele, &forecast->val); + ierr = PetscCalloc1(forecast->nele, &forecast->val1); CHKERRQ(ierr); for (i = 0; i < nw; i++) { @@ -637,7 +530,7 @@ SOPFLOWReadScenarioData_Wind_MultiPeriod(SOPFLOW sopflow, nw = 0; while (tok != NULL) { sscanf(tok, "%lf", &pg); - forecast->val[nw] = pg; + forecast->val1[nw] = pg; nw++; tok = strtok(NULL, sep); } @@ -671,8 +564,7 @@ PetscErrorCode SOPFLOWReadScenarioData(SOPFLOW sopflow, CHKERRQ(ierr); } } else if (sopflow->scenunctype == LOAD) { - //ierr = SOPFLOWReadScenarioData_Load_SinglePeriod(sopflow, scenfile); - ierr = SOPFLOWReadScenarioData_GenLoad_SinglePeriod(sopflow, scenfile); + ierr = SOPFLOWReadScenarioData_LoadPQ_SinglePeriod(sopflow, scenfile); CHKERRQ(ierr); } From 97dfc85ebf6005c1569d563418120f6e580cea45 Mon Sep 17 00:00:00 2001 From: Maksudul Alam Date: Thu, 16 Apr 2026 18:40:28 +0000 Subject: [PATCH 12/15] Commenting out printfs --- src/sopflow/interface/sopflowscen.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/sopflow/interface/sopflowscen.cpp b/src/sopflow/interface/sopflowscen.cpp index e426c469..4b06fb30 100644 --- a/src/sopflow/interface/sopflowscen.cpp +++ b/src/sopflow/interface/sopflowscen.cpp @@ -82,7 +82,7 @@ SOPFLOWReadScenarioData_LoadPQ_SinglePeriod(SOPFLOW sopflow, out = fgets(line, MAXLINE, fp); /* Parse wind generator numbers */ - printf("Done Parsing Header. nw = %d\n", nw); + // printf("Done Parsing Header. nw = %d\n", nw); // Body Example // 1,0.1,8_Load_1_185.0_10,6_Load_1_105.5_20 @@ -96,7 +96,7 @@ SOPFLOWReadScenarioData_LoadPQ_SinglePeriod(SOPFLOW sopflow, scen_num -= 1; /* Scenario numbers start with 1 in the file, convert to zero-based start */ - printf("Parsing scenario number %d\n", scen_num); + // printf("Parsing scenario number %d\n", scen_num); // tok2 = strsep(&tok, sep2_dash); // Bus Number @@ -122,7 +122,7 @@ SOPFLOWReadScenarioData_LoadPQ_SinglePeriod(SOPFLOW sopflow, tok = strtok(NULL, sep_comma); sscanf(tok, "%lf", &weight); - printf("Scenario weight = %lf\n", weight); + // printf("Scenario weight = %lf\n", weight); tok = strtok(NULL, sep_comma); while (tok != NULL) { @@ -134,31 +134,31 @@ SOPFLOWReadScenarioData_LoadPQ_SinglePeriod(SOPFLOW sopflow, /* Parse generator info */ tok2 = strsep(&tok, sep2_dash); // Bus Number sscanf(tok2, "%d", &gd.busnum); - printf("Bus number = %d\n", gd.busnum); + // printf("Bus number = %d\n", gd.busnum); tok3 = strsep(&tok, sep2_dash); // Type (Load or Gen) tok4 = strsep(&tok, sep2_dash); // CKT sscanf(tok4, "%d", &genid); snprintf(gd.id, 3, "%-2d", genid); - printf("Gen ID = %s\n", gd.id); + // printf("Gen ID = %s\n", gd.id); tok5 = strsep(&tok, sep2_dash); // Value1 sscanf(tok5, "%lf", &gd.value1); - printf("Value1 = %lf\n", gd.value1); + // printf("Value1 = %lf\n", gd.value1); tok6 = strsep(&tok, sep2_dash); // Value2 sscanf(tok6, "%lf", &gd.value2); - printf("Value2 = %lf\n", gd.value2); + // printf("Value2 = %lf\n", gd.value2); gendata.push_back(gd); - printf("## gd = %d, %s, %lf, %lf\n", gd.busnum, gd.id, gd.value1, - gd.value2); + // printf("## gd = %d, %s, %lf, %lf\n", gd.busnum, gd.id, gd.value1, + // gd.value2); // printf("!Token = %s\n", gendata.back()); tok = strtok(NULL, sep_comma); - printf("## tok = %s\n", tok); + // printf("## tok = %s\n", tok); } - printf("Done Parsing 1 line of Tokens\n"); + // printf("Done Parsing 1 line of Tokens\n"); scenario = &scenlist->scen[scen_num]; forecast = &scenario->forecastlist[scenario->nforecast]; forecast->num = scen_num; From 85b54b0a0b1bb1fd398323a14dc661b1bc95bfe9 Mon Sep 17 00:00:00 2001 From: Maksudul Alam Date: Thu, 23 Apr 2026 17:10:36 +0000 Subject: [PATCH 13/15] Adds CTest --- src/sopflow/interface/sopflowscen.cpp | 145 ------------------ tests/functionality/sopflow/selfcheck.cpp | 24 ++- .../sopflow/sopflow_multiscenario.toml | 10 ++ 3 files changed, 29 insertions(+), 150 deletions(-) diff --git a/src/sopflow/interface/sopflowscen.cpp b/src/sopflow/interface/sopflowscen.cpp index 4b06fb30..c99dccc3 100644 --- a/src/sopflow/interface/sopflowscen.cpp +++ b/src/sopflow/interface/sopflowscen.cpp @@ -51,7 +51,6 @@ PetscErrorCode SOPFLOWReadScenarioData_LoadPQ_SinglePeriod(SOPFLOW sopflow, const char windgenprofile[]) { - // printf("I am being called\n"); PetscErrorCode ierr; FILE *fp; char line[MAXLINE]; @@ -96,15 +95,6 @@ SOPFLOWReadScenarioData_LoadPQ_SinglePeriod(SOPFLOW sopflow, scen_num -= 1; /* Scenario numbers start with 1 in the file, convert to zero-based start */ - // printf("Parsing scenario number %d\n", scen_num); - - // tok2 = strsep(&tok, sep2_dash); // Bus Number - - // sscanf(tok2, "%d", &bus[nw]); - // tok3 = strsep(&tok, sep2_dash); // Wind - // tok4 = strsep(&tok, sep2_dash); // Gen ID - // tok5 = strsep(&tok, sep2_dash); // Value - if (scen_num < scenlist->Nscen || scen_num == sopflow->Ns) { fclose(fp); PetscFunctionReturn(0); @@ -122,43 +112,28 @@ SOPFLOWReadScenarioData_LoadPQ_SinglePeriod(SOPFLOW sopflow, tok = strtok(NULL, sep_comma); sscanf(tok, "%lf", &weight); - // printf("Scenario weight = %lf\n", weight); - tok = strtok(NULL, sep_comma); while (tok != NULL) { - // printf("## tok = %s\n", tok); - GenData gd; /* Parse generator info */ tok2 = strsep(&tok, sep2_dash); // Bus Number sscanf(tok2, "%d", &gd.busnum); - // printf("Bus number = %d\n", gd.busnum); tok3 = strsep(&tok, sep2_dash); // Type (Load or Gen) tok4 = strsep(&tok, sep2_dash); // CKT sscanf(tok4, "%d", &genid); snprintf(gd.id, 3, "%-2d", genid); - // printf("Gen ID = %s\n", gd.id); tok5 = strsep(&tok, sep2_dash); // Value1 sscanf(tok5, "%lf", &gd.value1); - // printf("Value1 = %lf\n", gd.value1); tok6 = strsep(&tok, sep2_dash); // Value2 sscanf(tok6, "%lf", &gd.value2); - // printf("Value2 = %lf\n", gd.value2); gendata.push_back(gd); - // printf("## gd = %d, %s, %lf, %lf\n", gd.busnum, gd.id, gd.value1, - // gd.value2); - - // printf("!Token = %s\n", gendata.back()); tok = strtok(NULL, sep_comma); - - // printf("## tok = %s\n", tok); } - // printf("Done Parsing 1 line of Tokens\n"); scenario = &scenlist->scen[scen_num]; forecast = &scenario->forecastlist[scenario->nforecast]; forecast->num = scen_num; @@ -177,135 +152,15 @@ SOPFLOWReadScenarioData_LoadPQ_SinglePeriod(SOPFLOW sopflow, ierr = PetscCalloc1(forecast->nele, &forecast->val2); CHKERRQ(ierr); - - // tok = strtok(NULL, sep_comma); - for (i = 0; i < gendata.size(); i++) { forecast->buses[i] = gendata[i].busnum; ierr = PetscStrcpy(forecast->id[i], gendata[i].id); CHKERRQ(ierr); - // sscanf(tok, "%lf", &pg); forecast->val1[i] = gendata[i].value1; forecast->val2[i] = gendata[i].value2; - // tok = strtok(NULL, sep_comma); } // /* Read scenario weight */ - // sscanf(tok, "%lf", &weight); - scenario->prob = weight; - - scenario->nforecast++; - scenlist->Nscen++; - } - PetscFunctionReturn(0); -} - -/* - SOPFLOWReadScenarioData_Wind_SinglePeriod - Reads the wind data and populates -the scenario list Input Parameters -+ sopflow - SOPFLOW object -. windgenprofile - wind generator profile file - - Note: This function reads the wind scenario data for "single period" format -files. -*/ -PetscErrorCode -SOPFLOWReadScenarioData_Wind_SinglePeriod_2(SOPFLOW sopflow, - const char windgenprofile[]) { - PetscErrorCode ierr; - FILE *fp; - char line[MAXLINE]; - char *out; - PetscInt ngenwind, nw = 0; - char *tok, *tok2; - char sep[] = ",", sep2[] = "_"; - PetscReal pg, weight; - int scen_num = 0; - int genid; - int windgenbus[1000]; - char windgenid[1000][3]; - int i; - ScenarioList *scenlist = &sopflow->scenlist; - Scenario *scenario; - Forecast *forecast; - - PetscFunctionBegin; - - ngenwind = 1000; // This should be increased for larger cases (?) - fp = fopen(windgenprofile, "r"); - if (fp == NULL) { - SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, - "Cannot open wind generation profile file %s", windgenprofile); - } - - /* First line -- has the bus numbers */ - out = fgets(line, MAXLINE, fp); - /* Parse wind generator numbers */ - tok = strtok(line, sep); - tok = strtok(NULL, sep); /* Skip first token */ - while (tok != NULL) { - if (strcmp(tok, "weight") == 0 || strcmp(tok, "weight\n") == 0 || - strcmp(tok, "weight\r\n") == 0) { - tok = strtok(NULL, sep); - continue; - } - /* Parse generator info */ - tok2 = strsep(&tok, sep2); - sscanf(tok2, "%d", &windgenbus[nw]); - tok2 = strsep(&tok, sep2); - tok2 = strsep(&tok, sep2); /* Skip string "Wind" */ - sscanf(tok2, "%d", &genid); - if (nw == ngenwind) - SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, - "Exceeded max. number of wind generators=%d\n", ngenwind); - snprintf(windgenid[nw], 3, "%-2d", genid); - - nw++; - tok = strtok(NULL, sep); - } - - while ((out = fgets(line, MAXLINE, fp)) != NULL) { - if (strcmp(line, "\r\n") == 0 || strcmp(line, "\n") == 0) { - continue; /* Skip blank lines */ - } - - tok = strtok(line, sep); - sscanf(tok, "%d", &scen_num); /* Scenario number */ - scen_num -= 1; /* Scenario numbers start with 1 in the file, convert to - zero-based start */ - - if (scen_num < scenlist->Nscen || scen_num == sopflow->Ns) { - fclose(fp); - PetscFunctionReturn(0); - } - - scenario = &scenlist->scen[scen_num]; - forecast = &scenario->forecastlist[scenario->nforecast]; - forecast->num = scen_num; - forecast->type = FORECAST_WIND; - forecast->nele = nw; - ierr = PetscCalloc1(forecast->nele, &forecast->buses); - CHKERRQ(ierr); - ierr = PetscCalloc1(forecast->nele, &forecast->id); - CHKERRQ(ierr); - for (i = 0; i < forecast->nele; i++) { - ierr = PetscCalloc1(3, &forecast->id[i]); - } - ierr = PetscCalloc1(forecast->nele, &forecast->val1); - CHKERRQ(ierr); - - tok = strtok(NULL, sep); - for (i = 0; i < nw; i++) { - forecast->buses[i] = windgenbus[i]; - ierr = PetscStrcpy(forecast->id[i], windgenid[i]); - CHKERRQ(ierr); - sscanf(tok, "%lf", &pg); - forecast->val1[i] = pg; - tok = strtok(NULL, sep); - } - - /* Read scenario weight */ - sscanf(tok, "%lf", &weight); scenario->prob = weight; scenario->nforecast++; diff --git a/tests/functionality/sopflow/selfcheck.cpp b/tests/functionality/sopflow/selfcheck.cpp index 924779b8..bb6ab50a 100644 --- a/tests/functionality/sopflow/selfcheck.cpp +++ b/tests/functionality/sopflow/selfcheck.cpp @@ -9,6 +9,7 @@ struct SopflowFunctionalityTestParameters { std::string solver = ""; std::string network = ""; std::string scenfile = ""; + std::string loadfile = ""; std::string contingencies = ""; std::string pload = ""; std::string qload = ""; @@ -54,6 +55,7 @@ struct SopflowFunctionalityTestParameters { set_if_found(solver, values, "solver"); set_if_found(network, values, "network"); set_if_found(scenfile, values, "scenfile"); + set_if_found(loadfile, values, "loadfile"); set_if_found(num_scenarios, values, "num_scenarios"); set_if_found(tolerance, values, "tolerance"); set_if_found(warning_tolerance, values, "warning_tolerance"); @@ -139,7 +141,7 @@ struct SopflowFunctionalityTests }; for (const auto &opt : - {"solver", "network", "scenfile", "num_scenarios", "tolerance"}) + {"solver", "network", "num_scenarios", "tolerance"}) ensure_option_available(opt); bool is_multicontingency = false; @@ -171,7 +173,10 @@ struct SopflowFunctionalityTests testcase["description"] = params.description; testcase["solver"] = params.solver; testcase["network"] = params.network; - testcase["scenfile"] = params.scenfile; + if (params.loadfile != "") + testcase["loadfile"] = params.loadfile; + else if (params.scenfile != "") + testcase["scenfile"] = params.scenfile; testcase["num_scenarios"] = params.num_scenarios; testcase["initialization_type"] = params.initialization_type; @@ -231,10 +236,19 @@ struct SopflowFunctionalityTests ExaGOCheckError(ierr); // Prepend installation directory to scenario data - resolve_datafiles_path(params.scenfile); - ierr = SOPFLOWSetScenarioData(sopflow, SOPFLOW_NATIVE_SINGLEPERIOD, WIND, + if (params.loadfile != ""){ + std::cout << "Network: " << params.network << " Using Load File: " << params.loadfile << std::endl; + resolve_datafiles_path(params.loadfile); + ierr = SOPFLOWSetScenarioData(sopflow, SOPFLOW_NATIVE_SINGLEPERIOD, LOAD, + params.loadfile.c_str()); + ExaGOCheckError(ierr); + } else if (params.scenfile != ""){ + std::cout << "Network: " << params.network << " Using Scenario File: " << params.scenfile << std::endl; + resolve_datafiles_path(params.scenfile); + ierr = SOPFLOWSetScenarioData(sopflow, SOPFLOW_NATIVE_SINGLEPERIOD, WIND, params.scenfile.c_str()); - ExaGOCheckError(ierr); + ExaGOCheckError(ierr); + } ierr = SOPFLOWSetInitializationType(sopflow, params.initialization_type); ExaGOCheckError(ierr); diff --git a/tests/functionality/sopflow/sopflow_multiscenario.toml b/tests/functionality/sopflow/sopflow_multiscenario.toml index 6beb2e6b..39c4ddc5 100644 --- a/tests/functionality/sopflow/sopflow_multiscenario.toml +++ b/tests/functionality/sopflow/sopflow_multiscenario.toml @@ -53,3 +53,13 @@ solver = 'EMPAR' num_scenarios = 3 num_iters = 0 obj_value = 14316.630954933302 + +[[testcase]] +description = 'LoadTest' +tolerance = 1e-3 +network = 'datafiles/case9/case9mod.m' +loadfile = 'datafiles/case9/10_scenarios_9bus_load.txt' +solver = 'EMPAR' +num_scenarios = 3 +num_iters = 0 +obj_value = 722.106958693 From 32e1cbdaa47572f30ad3db081db6da0f8fb65b8e Mon Sep 17 00:00:00 2001 From: maksud Date: Thu, 23 Apr 2026 17:20:28 +0000 Subject: [PATCH 14/15] Apply pre-commmit fixes --- applications/sopflow_main.cpp | 2 -- include/private/psimpl.h | 2 +- include/private/scenariolist.h | 4 ++-- src/ps/ps.cpp | 3 ++- src/sopflow/interface/sopflowscen.cpp | 6 +++--- tests/functionality/sopflow/selfcheck.cpp | 17 +++++++++-------- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/applications/sopflow_main.cpp b/applications/sopflow_main.cpp index 9f588ce2..b3240000 100644 --- a/applications/sopflow_main.cpp +++ b/applications/sopflow_main.cpp @@ -55,13 +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); diff --git a/include/private/psimpl.h b/include/private/psimpl.h index fc1d859f..fc091a70 100644 --- a/include/private/psimpl.h +++ b/include/private/psimpl.h @@ -498,7 +498,7 @@ struct _p_PS { PetscBool setupcalled; /* Is setup called on PS? */ PetscLogDouble solve_real_time; /* Solve time */ - PetscInt numits; /* Number of solver iterations */ + PetscInt numits; /* Number of solver iterations */ }; extern PetscErrorCode PSCheckTopology(PS); diff --git a/include/private/scenariolist.h b/include/private/scenariolist.h index f1ddb687..5e07cc81 100644 --- a/include/private/scenariolist.h +++ b/include/private/scenariolist.h @@ -18,8 +18,8 @@ struct _p_Forecast { PetscInt nele; /* Number of devices/elements involved in this forecast */ PetscInt *buses; /* Bus numbers */ char **id; /* Device ids */ - PetscScalar *val1 = nullptr; /* forecast values */ - PetscScalar *val2 = nullptr; /* 2nd set of forecast values */ + PetscScalar *val1 = nullptr; /* forecast values */ + PetscScalar *val2 = nullptr; /* 2nd set of forecast values */ }; typedef struct _p_Forecast Forecast; diff --git a/src/ps/ps.cpp b/src/ps/ps.cpp index ca363a73..2053afcf 100644 --- a/src/ps/ps.cpp +++ b/src/ps/ps.cpp @@ -1659,7 +1659,8 @@ PetscErrorCode PSApplyScenario(PS ps, Scenario scenario) { 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. */ + 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", diff --git a/src/sopflow/interface/sopflowscen.cpp b/src/sopflow/interface/sopflowscen.cpp index c99dccc3..2f72f116 100644 --- a/src/sopflow/interface/sopflowscen.cpp +++ b/src/sopflow/interface/sopflowscen.cpp @@ -39,8 +39,8 @@ PetscErrorCode SOPFLOWSetScenarioData(SOPFLOW sopflow, } /* - SOPFLOWReadScenarioData_LoadPQ_SinglePeriod - Reads the load data and populates -the scenario list Input Parameters + SOPFLOWReadScenarioData_LoadPQ_SinglePeriod - Reads the load data and +populates the scenario list Input Parameters + sopflow - SOPFLOW object . loadprofile - load profile file @@ -49,7 +49,7 @@ files. */ PetscErrorCode SOPFLOWReadScenarioData_LoadPQ_SinglePeriod(SOPFLOW sopflow, - const char windgenprofile[]) { + const char windgenprofile[]) { PetscErrorCode ierr; FILE *fp; diff --git a/tests/functionality/sopflow/selfcheck.cpp b/tests/functionality/sopflow/selfcheck.cpp index bb6ab50a..8eb1d22a 100644 --- a/tests/functionality/sopflow/selfcheck.cpp +++ b/tests/functionality/sopflow/selfcheck.cpp @@ -140,8 +140,7 @@ struct SopflowFunctionalityTests } }; - for (const auto &opt : - {"solver", "network", "num_scenarios", "tolerance"}) + for (const auto &opt : {"solver", "network", "num_scenarios", "tolerance"}) ensure_option_available(opt); bool is_multicontingency = false; @@ -236,17 +235,19 @@ struct SopflowFunctionalityTests ExaGOCheckError(ierr); // Prepend installation directory to scenario data - if (params.loadfile != ""){ - std::cout << "Network: " << params.network << " Using Load File: " << params.loadfile << std::endl; + if (params.loadfile != "") { + std::cout << "Network: " << params.network + << " Using Load File: " << params.loadfile << std::endl; resolve_datafiles_path(params.loadfile); ierr = SOPFLOWSetScenarioData(sopflow, SOPFLOW_NATIVE_SINGLEPERIOD, LOAD, - params.loadfile.c_str()); + params.loadfile.c_str()); ExaGOCheckError(ierr); - } else if (params.scenfile != ""){ - std::cout << "Network: " << params.network << " Using Scenario File: " << params.scenfile << std::endl; + } else if (params.scenfile != "") { + std::cout << "Network: " << params.network + << " Using Scenario File: " << params.scenfile << std::endl; resolve_datafiles_path(params.scenfile); ierr = SOPFLOWSetScenarioData(sopflow, SOPFLOW_NATIVE_SINGLEPERIOD, WIND, - params.scenfile.c_str()); + params.scenfile.c_str()); ExaGOCheckError(ierr); } From f6738ca8c0929bf5516d3456f0245cec06570e5b Mon Sep 17 00:00:00 2001 From: Maksudul Alam Date: Thu, 30 Apr 2026 20:16:41 +0000 Subject: [PATCH 15/15] Changing the parser --- src/sopflow/interface/sopflowscen.cpp | 29 ++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/sopflow/interface/sopflowscen.cpp b/src/sopflow/interface/sopflowscen.cpp index 2f72f116..52e6d635 100644 --- a/src/sopflow/interface/sopflowscen.cpp +++ b/src/sopflow/interface/sopflowscen.cpp @@ -100,14 +100,15 @@ SOPFLOWReadScenarioData_LoadPQ_SinglePeriod(SOPFLOW sopflow, PetscFunctionReturn(0); } - struct GenData { + struct ForecastData { int busnum; + char type[16]; PetscReal value1; PetscReal value2; char id[3]; }; - vector gendata; + vector gendata; tok = strtok(NULL, sep_comma); sscanf(tok, "%lf", &weight); @@ -115,19 +116,30 @@ SOPFLOWReadScenarioData_LoadPQ_SinglePeriod(SOPFLOW sopflow, tok = strtok(NULL, sep_comma); while (tok != NULL) { - GenData gd; + ForecastData gd; /* Parse generator info */ tok2 = strsep(&tok, sep2_dash); // Bus Number sscanf(tok2, "%d", &gd.busnum); + tok3 = strsep(&tok, sep2_dash); // Type (Load or Gen) + sscanf(tok3, "%s", gd.type); + tok4 = strsep(&tok, sep2_dash); // CKT sscanf(tok4, "%d", &genid); snprintf(gd.id, 3, "%-2d", genid); - tok5 = strsep(&tok, sep2_dash); // Value1 - sscanf(tok5, "%lf", &gd.value1); - tok6 = strsep(&tok, sep2_dash); // Value2 - sscanf(tok6, "%lf", &gd.value2); + + if (strcmp(gd.type, "Load") == 0) { + /* Load forecast */ + tok5 = strsep(&tok, sep2_dash); // Value1 + sscanf(tok5, "%lf", &gd.value1); + tok6 = strsep(&tok, sep2_dash); // Value2 + sscanf(tok6, "%lf", &gd.value2); + } else if (strcmp(gd.type, "Gen") == 0) { + /* Gen forecast */ + tok5 = strsep(&tok, sep2_dash); // Value1 + sscanf(tok5, "%lf", &gd.value1); + } gendata.push_back(gd); @@ -135,6 +147,9 @@ SOPFLOWReadScenarioData_LoadPQ_SinglePeriod(SOPFLOW sopflow, } scenario = &scenlist->scen[scen_num]; + + printf("scenario %d has %d forecasts\n", scen_num, scenario->nforecast); + forecast = &scenario->forecastlist[scenario->nforecast]; forecast->num = scen_num; forecast->type = FORECAST_LOAD_PQ;