diff --git a/applications/scopflow_main.cpp b/applications/scopflow_main.cpp index 578f83a49..31581c331 100644 --- a/applications/scopflow_main.cpp +++ b/applications/scopflow_main.cpp @@ -9,9 +9,10 @@ int main(int argc, char **argv) { SCOPFLOW scopflow; char file[PETSC_MAX_PATH_LEN]; char ctgcfile[PETSC_MAX_PATH_LEN]; + char gicfile[PETSC_MAX_PATH_LEN]; char outputdir[PETSC_MAX_PATH_LEN]; PetscBool outputdir_set; - PetscBool flg = PETSC_FALSE, flgctgc = PETSC_FALSE; + PetscBool flg = PETSC_FALSE, flgctgc = PETSC_FALSE, flggic = PETSC_FALSE; PetscBool print_output = PETSC_FALSE, save_output = PETSC_FALSE; PetscLogStage stages[3]; char appname[] = "scopflow"; @@ -53,6 +54,11 @@ int main(int argc, char **argv) { PETSC_MAX_PATH_LEN, &flgctgc); CHKERRQ(ierr); + /* Get gic data file from command line */ + ierr = PetscOptionsGetString(NULL, NULL, "-gicfile", gicfile, + PETSC_MAX_PATH_LEN, &flggic); + ExaGOCheckError(ierr); + /* Stage 1 - Application creation and reading data */ ierr = PetscLogStagePush(stages[0]); CHKERRQ(ierr); @@ -86,6 +92,12 @@ int main(int argc, char **argv) { CHKERRQ(ierr); } + /* Set gicdata */ + if (flggic) { + ierr = SCOPFLOWSetGICData(scopflow, gicfile); + ExaGOCheckError(ierr); + } + /* Set a subset of contingencies to be selected. Can use the option * -scopflow_Nc instead */ /* ierr = SCOPFLOWSetNumContingencies(scopflow,2);CHKERRQ(ierr); */ diff --git a/datafiles/case9/case9_dcline.m b/datafiles/case9/case9_dcline.m new file mode 100644 index 000000000..0f4bdb3e1 --- /dev/null +++ b/datafiles/case9/case9_dcline.m @@ -0,0 +1,80 @@ +function mpc = case9_dcline +%T_CASE9_DCLINE Same as T_CASE9_OPFV2 with addition of DC line data. +% Please see CASEFORMAT for details on the case file format. +% +% See also: TOGGLE_DCLINE, IDX_DCLINE. + +% MATPOWER + +%% MATPOWER Case Format : Version 2 +mpc.version = '2'; + +%%----- Power Flow Data -----%% +%% system MVA base +mpc.baseMVA = 100; + +%% bus data +% bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin +mpc.bus = [ + 1 3 0 0 0 0 1 1 0 345 1 1.1 0.9; + 2 2 0 0 0 0 1 1 0 345 1 1.1 0.9; + 30 2 0 0 0 0 1 1 0 345 1 1.1 0.9; + 4 1 0 0 0 0 1 1 0 345 1 1.1 0.9; + 5 1 90 30 0 0 1 1 0 345 1 1.1 0.9; + 6 1 0 0 0 0 1 1 0 345 1 1.1 0.9; + 7 1 100 35 0 0 1 1 0 345 1 1.1 0.9; + 8 1 0 0 0 0 1 1 0 345 1 1.1 0.9; + 9 1 125 50 0 0 1 1 0 345 1 1.1 0.9; +]; + +%% generator data +% bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf +mpc.gen = [ + 1 0 0 300 -300 1 100 1 250 90 0 0 0 0 0 0 0 0 0 0 0; + 2 163 0 300 -300 1 100 1 300 10 0 200 -20 20 -10 10 0 0 0 0 0; + 30 85 0 300 -300 1 100 1 270 10 0 200 -30 30 -15 15 0 0 0 0 0; +]; + +%% branch data +% fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax +mpc.branch = [ + 1 4 0 0.0576 0 0 250 250 0 0 1 -360 2.48; + 4 5 0.017 0.092 0.158 0 250 250 0 0 1 -360 360; + 5 6 0.039 0.17 0.358 150 150 150 0 0 1 -360 360; + 30 6 0 0.0586 0 0 300 300 0 0 1 -360 360; + 6 7 0.0119 0.1008 0.209 40 150 150 0 0 1 -360 360; + 7 8 0.0085 0.072 0.149 250 250 250 0 0 1 -360 360; + 8 2 0 0.0625 0 250 250 250 0 0 1 -360 360; + 8 9 0.032 0.161 0.306 250 250 250 0 0 1 -360 360; + 9 4 0.01 0.085 0.176 250 250 250 0 0 1 -2 360; +]; + +%%----- OPF Data -----%% +%% generator cost data +% 1 startup shutdown n x1 y1 ... xn yn +% 2 startup shutdown n c(n-1) ... c0 +mpc.gencost = [ + 2 1500.00 0.00 3 0.11 5 150; + 2 2000.00 0.00 3 0.085 1.2 600; + 2 3000 0 3 0.1225 1 335; +]; + +%%----- DC Line Data ----- +%% Change 30-4 Vf to 1.0 from 1.01 to match with gen set-point voltage +% fbus tbus status Pf Pt Qf Qt Vf Vt Pmin Pmax QminF QmaxF QminT QmaxT loss0 loss1 +mpc.dcline = [ + 30 4 1 10 8.9 0 0 1 1 1 10 -10 10 -10 10 1 0.01; + 7 9 1 2 1.96 0 0 1 0.98 2 10 0 0 0 0 0 0; + 5 8 1 0 0 0 0 1 1 1 10 -10 10 -10 10 0 0; + 5 9 1 10 9.5 0 0 1 0.98 0 10 -10 10 -10 10 0 0.05; +]; + +%% DC line cost data +% 1 startup shutdown n x1 y1 ... xn yn +% 2 startup shutdown n c(n-1) ... c0 +mpc.dclinecost = [ + 2 0 0 2 0 0 0 0 0 0 0 0 0 0; + 2 0 0 2 0 0 0 0 0 0 0 0 0 0; + 2 0 0 2 0 0 0 0 0 0 0 0 0 0; + 2 0 0 2 7.3 0 0 0 0 0 0 0 0 0; +]; diff --git a/include/constants.h b/include/constants.h index e1a27f3d1..621c955d2 100644 --- a/include/constants.h +++ b/include/constants.h @@ -18,7 +18,8 @@ */ #define NLOAD_AT_BUS_MAX 32 /**< Maximum number of loads allowed at a bus */ #define NPHASE 1 /**< Per-phase analysis */ -#define MAX_KV_LEVELS 20 /**< Maximum KV levels */ +#define MAX_KV_LEVELS \ + 200 /**< Maximum KV (voltage) levels allowed in input file */ /* Fuel types for generators */ #define GENFUEL_COAL 0 /* Coal */ diff --git a/include/opflow.h b/include/opflow.h index 6ce41a276..3b790c3ac 100644 --- a/include/opflow.h +++ b/include/opflow.h @@ -134,6 +134,9 @@ const auto tolerance = const auto ignore_lineflow_constraints = ExaGOBoolOption("-opflow_ignore_lineflow_constraints", "Ignore line flow constraints?", PETSC_FALSE); +const auto lazy_lineflow_constraints = + ExaGOBoolOption("-opflow_lazy_lineflow_constraints", + "Apply line flow constraints lazily?", PETSC_FALSE); const auto allow_lineflow_violation = ExaGOBoolOption("-opflow_allow_lineflow_violation", "Allow line flow limit violation?", PETSC_FALSE); @@ -152,6 +155,9 @@ const auto include_powerimbalance_variables = const auto powerimbalance_penalty = ExaGORealOption( "-opflow_powerimbalance_penalty", "Power imbalance penalty", 1e4); +const auto load_scaling_factor = ExaGORealOption("-opflow_load_scaling_factor", + "Scale factor for load", 1.0); + #ifdef EXAGO_ENABLE_HIOP const auto hiop_compute_mode = ExaGOStringOption("-hiop_compute_mode", "Set compute mode for HiOp solver", @@ -263,6 +269,8 @@ OPFLOWGetInitializationType(OPFLOW, OPFLOWInitializationType *); PETSC_EXTERN PetscErrorCode OPFLOWIgnoreLineflowConstraints(OPFLOW, PetscBool); PETSC_EXTERN PetscErrorCode OPFLOWGetIgnoreLineflowConstraints(OPFLOW, PetscBool *); +PETSC_EXTERN PetscErrorCode OPFLOWGetLineOverloads(OPFLOW, PetscInt *, + PetscInt **, PetscBool *); PETSC_EXTERN PetscErrorCode OPFLOWAllowLineflowViolation(OPFLOW, PetscBool); PETSC_EXTERN PetscErrorCode OPFLOWGetAllowLineflowViolation(OPFLOW, PetscBool *); @@ -277,6 +285,7 @@ PETSC_EXTERN PetscErrorCode OPFLOWSetBusPowerImbalancePenalty(OPFLOW, PetscReal); PETSC_EXTERN PetscErrorCode OPFLOWGetBusPowerImbalancePenalty(OPFLOW, PetscReal *); +PETSC_EXTERN PetscErrorCode OPFLOWSetLoadScalingFactor(OPFLOW, PetscReal); PETSC_EXTERN PetscErrorCode OPFLOWSetWeight(OPFLOW, PetscScalar); PETSC_EXTERN PetscErrorCode OPFLOWSkipOptions(OPFLOW, PetscBool); @@ -333,12 +342,16 @@ PETSC_EXTERN PetscErrorCode OPFLOWSolutionToPS(OPFLOW); Input Parameter: + opflow - OPFLOW object -. nkvlevels - Number of kvlevels to monitor (Use -1 to monitor all kvlevels) -. kvlevels - line kvlevels to monitor -- monitorfile - File with list of lines to monitor. +. mon_mode - Monitor Mode (0 = Input lines, 1 = KV levels, 2 = from file) +. nlinesmon - Number of lines to be monitored (active when mon_mode = 0) +. linesmon - List of lines to be monitored (active with mon_mode = 0) +. nkvlevels - Number of kvlevels to monitor (active with mon_mode = 1, use -1 +to monitor all kvlevels) . kvlevels - line kvlevels to monitor (active with +mon_mode = 1) +- monitorfile - File with list of lines to monitor (active with mon_mode = 2) Notes: - The lines to monitor are either specified through a file OR by + The lines to monitor are either specified via API, through a file OR by kvlevels, but not both. Use NULL for monitorfile if file is not set. If monitorfile is given then the kvlevels are ignored. @@ -347,7 +360,8 @@ PETSC_EXTERN PetscErrorCode OPFLOWSolutionToPS(OPFLOW); This function should be called after OPFLOWSetupPS() is called */ -PETSC_EXTERN PetscErrorCode OPFLOWSetLinesMonitored(OPFLOW, PetscInt, +PETSC_EXTERN PetscErrorCode OPFLOWSetLinesMonitored(OPFLOW, PetscInt, PetscInt, + PetscInt *, PetscInt, const PetscScalar *, const char *); @@ -365,4 +379,15 @@ PETSC_EXTERN PetscErrorCode OPFLOWSetAuxillaryObjective( PETSC_EXTERN PetscErrorCode OPFLOWSetUpdateVariableBoundsFunction( OPFLOW, PetscErrorCode (*)(OPFLOW, Vec, Vec, void *), void *); +/* + OPFLOWCheckConstraints - Displays information about OPFLOW constraints + + Input Parameters: +. opflow - the OPFLOW oject + + Notes: This is called by OPFLOWSolutionToPS. If called exterenally then +OPFLOWSolutionToPS() needs to be called first. +*/ +PETSC_EXTERN PetscErrorCode OPFLOWCheckConstraints(OPFLOW opflow); + #endif diff --git a/include/private/contingencylist.h b/include/private/contingencylist.h index 6ca7f6fd5..cc134538c 100644 --- a/include/private/contingencylist.h +++ b/include/private/contingencylist.h @@ -16,7 +16,7 @@ typedef enum { LOAD_OUTAGE = 4 } OutageType; -#define MAX_SIMULTANEOUS_OUTAGES 5 +#define MAX_SIMULTANEOUS_OUTAGES 250 #define MAX_CONTINGENCIES 20000 struct _p_Outage { diff --git a/include/private/opflowimpl.h b/include/private/opflowimpl.h index c584f8dd5..6dc6310d6 100644 --- a/include/private/opflowimpl.h +++ b/include/private/opflowimpl.h @@ -67,6 +67,8 @@ struct _p_OPFLOWModelOps { PetscErrorCode (*computeinequalityconstraintsarray)( OPFLOW, const double *, double *); /* Set equality constraints */ PetscErrorCode (*computeconstraints)(OPFLOW, Vec, Vec); + PetscErrorCode (*checkconstraints)( + OPFLOW); /* Check and display constraints info */ PetscErrorCode (*computeconstraintsarray)( OPFLOW, double *, double *); /* Array version of compute constraints */ PetscErrorCode (*computeequalityconstraintjacobian)(OPFLOW, Vec, Mat); @@ -234,7 +236,8 @@ struct _p_OPFLOW { PetscBool OPFLOWSolverRegisterAllCalled; PetscBool ignore_lineflow_constraints; /* Ignore line flow constraints */ - PetscBool allow_lineflow_violation; /* Allow line flow violation */ + PetscBool lazy_lineflow_constraints; /* Apply line flow constraints lazily */ + PetscBool allow_lineflow_violation; /* Allow line flow violation */ PetscReal lineflowviolation_penalty; /* Penalty for exceeding line flow limits */ @@ -245,6 +248,8 @@ struct _p_OPFLOW { imbalance */ PetscReal powerimbalance_penalty; + PetscReal load_scaling_factor; /* scaling factor for load */ + PetscBool has_powersetpoint; /* Use real power set-point */ PetscInt numits; /* Number of solver iterations */ @@ -306,6 +311,9 @@ struct _p_OPFLOW { /** @brief user provided data struct for auxillary objective */ void *userctx; + OPFLOW + *address; /* Address for this OPFLOW object, used with lazy constraints */ + PetscBool skip_options; /* Skip run-time options */ PetscScalar weight; /* Weight for this system condition (0,1) */ diff --git a/include/private/psimpl.h b/include/private/psimpl.h index fea18eb73..225a67cfa 100644 --- a/include/private/psimpl.h +++ b/include/private/psimpl.h @@ -24,7 +24,7 @@ /** * @brief A bogus value for load loss cost */ -#define BOGUSLOSSCOST -1234.0 +#define BOGUSLOSSCOST 12345.0 /** * @brief private bus data struct @@ -298,8 +298,29 @@ struct _p_PSLINE { PetscScalar kvlevel; /* Kv level for lines, for transformers uses the HV side voltage */ + PetscInt areaf, areat; /**< Areas for from and to buses */ + PetscInt zonef, zonet; /**< Zones for from and to buses */ + PSBUS connbuses[2]; /**< From and to buses */ + /****** For DC lines **********/ + PetscBool isdcline; /**< Is line a DC line? */ + PetscScalar pmin; /**< lower limit on PF (MW flow at "from" end) */ + PetscScalar pmax; /**< upper limit on PF (MW flow at "from" end) */ + PetscScalar Vf; /**(kvlevels.size()), &tmp[0], NULL); + w.opf, 1, NULL, NULL, static_cast(kvlevels.size()), + &tmp[0], NULL); ExaGOCheckError(ierr); }) @@ -361,7 +362,8 @@ void init_exago_opflow(pybind11::module &m) { [](OPFLOW_wrapper &w, const int &nkvlevels, const std::string &monitorfile) { PetscErrorCode ierr; - ierr = OPFLOWSetLinesMonitored(w.opf, (PetscInt)nkvlevels, NULL, + ierr = OPFLOWSetLinesMonitored(w.opf, 1, NULL, NULL, + (PetscInt)nkvlevels, NULL, monitorfile.c_str()); ExaGOCheckError(ierr); }) diff --git a/src/opflow/CMakeLists.txt b/src/opflow/CMakeLists.txt index b4dd9e0b2..d05536575 100644 --- a/src/opflow/CMakeLists.txt +++ b/src/opflow/CMakeLists.txt @@ -30,8 +30,8 @@ set(OPFLOW_SOLVER_SRC ) set(OPFLOW_SRC - interface/opflow.cpp interface/opflowregi.cpp interface/opflowoutput.cpp - ${OPFLOW_FORM_SRC} ${OPFLOW_SOLVER_SRC} + interface/opflow.cpp interface/opflow2.cpp interface/opflowregi.cpp + interface/opflowoutput.cpp ${OPFLOW_FORM_SRC} ${OPFLOW_SOLVER_SRC} ) set_source_files_properties(${OPFLOW_SRC} PROPERTIES LANGUAGE CXX) diff --git a/src/opflow/interface/opflow.cpp b/src/opflow/interface/opflow.cpp index 2729f26b7..fb954f59b 100644 --- a/src/opflow/interface/opflow.cpp +++ b/src/opflow/interface/opflow.cpp @@ -71,7 +71,7 @@ PetscErrorCode OPFLOWGetLinesMonitored(OPFLOW opflow) { PetscFunctionBegin; if (opflow->nlinesmon) { - /* Number of lines monitored already set through file. */ + /* Number of lines monitored already set through input list or file. */ PetscFunctionReturn(0); } if (opflow->nlinekvmon == -1) { @@ -272,6 +272,23 @@ PetscErrorCode OPFLOWSetBusPowerImbalancePenalty(OPFLOW opflow, PetscFunctionReturn(0); } +/* + OPFLOWSetLoadScalingFactor - Set load scaling factor + + Input Parameters: ++ opflow - OPFLOW object +- penalty - load scaling factor (same for all loads) + + Command-line option: -opflow_load_scaling_factor + Notes: Should be called before OPFLOWSetUp + +*/ +PetscErrorCode OPFLOWSetLoadScalingFactor(OPFLOW opflow, PetscReal factor) { + PetscFunctionBegin; + opflow->load_scaling_factor = factor; + PetscFunctionReturn(0); +} + /* OPFLOWGetBusPowerImbalancePenalty - Get bus power imbalance penalty @@ -467,63 +484,83 @@ PetscErrorCode OPFLOWGetVariableOrdering(OPFLOW opflow, int **ordering) { } /* - OPFLOWInitializeDCOPF - DCOPF initialization of OPFLOW + OPFLOWCopyOptions - Copies options */ -PetscErrorCode OPFLOWInitializeDCOPF(OPFLOW opflow, PetscBool *converged) { +PetscErrorCode OPFLOWCopyOptions(OPFLOW opflow, OPFLOW opflowout) { PetscErrorCode ierr; - OPFLOW dcopflow; // DCOPF object PetscFunctionBegin; - ierr = OPFLOWCreate(opflow->comm->type, &dcopflow); + /* Set options */ + ierr = OPFLOWHasLoadLoss(opflowout, opflow->include_loadloss_variables); CHKERRQ(ierr); - ierr = OPFLOWReadMatPowerData(dcopflow, opflow->ps->net_file_name); + ierr = OPFLOWSetLoadLossPenalty(opflowout, opflow->loadloss_penalty); CHKERRQ(ierr); - ierr = OPFLOWSetModel(dcopflow, OPFLOWMODEL_DCOPF); + ierr = OPFLOWSetLoadScalingFactor(opflowout, opflow->load_scaling_factor); CHKERRQ(ierr); -#if defined(EXAGO_ENABLE_IPOPT) - ierr = OPFLOWSetSolver(dcopflow, OPFLOWSOLVER_IPOPT); + ierr = OPFLOWHasBusPowerImbalance(opflowout, + opflow->include_powerimbalance_variables); CHKERRQ(ierr); -#else - ierr = OPFLOWSetSolver(dcopflow, OPFLOWSOLVER_HIOPSPARSE); + ierr = OPFLOWSetBusPowerImbalancePenalty(opflowout, + opflow->powerimbalance_penalty); CHKERRQ(ierr); -#endif - /* Set options */ - ierr = OPFLOWHasLoadLoss(dcopflow, opflow->include_loadloss_variables); + ierr = OPFLOWHasGenSetPoint(opflowout, opflow->has_gensetpoint); CHKERRQ(ierr); - ierr = OPFLOWSetLoadLossPenalty(dcopflow, opflow->loadloss_penalty); + + ierr = OPFLOWUseAGC(opflowout, opflow->use_agc); CHKERRQ(ierr); - ierr = OPFLOWHasBusPowerImbalance(dcopflow, - opflow->include_powerimbalance_variables); + ierr = OPFLOWIgnoreLineflowConstraints(opflowout, + opflow->ignore_lineflow_constraints); CHKERRQ(ierr); - ierr = OPFLOWSetBusPowerImbalancePenalty(dcopflow, - opflow->powerimbalance_penalty); + ierr = + OPFLOWAllowLineflowViolation(opflowout, opflow->allow_lineflow_violation); CHKERRQ(ierr); - ierr = OPFLOWHasGenSetPoint(dcopflow, opflow->has_gensetpoint); + ierr = OPFLOWSetTolerance(opflowout, opflow->tolerance); CHKERRQ(ierr); - ierr = OPFLOWUseAGC(dcopflow, opflow->use_agc); + ierr = OPFLOWSetObjectiveType(opflowout, opflow->objectivetype); CHKERRQ(ierr); - ierr = OPFLOWIgnoreLineflowConstraints(dcopflow, - opflow->ignore_lineflow_constraints); + PetscFunctionReturn(0); +} + +/* + OPFLOWInitializeDCOPF - DCOPF initialization of OPFLOW +*/ +PetscErrorCode OPFLOWInitializeDCOPF(OPFLOW opflow, PetscBool *converged) { + PetscErrorCode ierr; + OPFLOW dcopflow; // DCOPF object + + PetscFunctionBegin; + + ierr = OPFLOWCreate(opflow->comm->type, &dcopflow); CHKERRQ(ierr); - ierr = - OPFLOWAllowLineflowViolation(dcopflow, opflow->allow_lineflow_violation); + + ierr = OPFLOWReadMatPowerData(dcopflow, opflow->ps->net_file_name); + CHKERRQ(ierr); + + ierr = OPFLOWSetModel(dcopflow, OPFLOWMODEL_DCOPF); CHKERRQ(ierr); - ierr = OPFLOWSetTolerance(dcopflow, opflow->tolerance); +#if defined(EXAGO_ENABLE_IPOPT) + ierr = OPFLOWSetSolver(dcopflow, OPFLOWSOLVER_IPOPT); + CHKERRQ(ierr); +#else + ierr = OPFLOWSetSolver(dcopflow, OPFLOWSOLVER_HIOPSPARSE); CHKERRQ(ierr); +#endif - ierr = OPFLOWSetObjectiveType(dcopflow, opflow->objectivetype); + /* Copy options */ + ierr = OPFLOWCopyOptions(opflow, dcopflow); CHKERRQ(ierr); + /* Skip setting options again */ ierr = OPFLOWSkipOptions(dcopflow, PETSC_TRUE); CHKERRQ(ierr); @@ -814,6 +851,8 @@ PetscErrorCode OPFLOWCreate(MPI_Comm mpicomm, OPFLOW *opflowout) { /* Run-time options */ opflow->ignore_lineflow_constraints = OPFLOWOptions::ignore_lineflow_constraints.default_value; + opflow->lazy_lineflow_constraints = + OPFLOWOptions::lazy_lineflow_constraints.default_value; opflow->allow_lineflow_violation = OPFLOWOptions::allow_lineflow_violation.default_value; opflow->lineflowviolation_penalty = @@ -822,6 +861,8 @@ PetscErrorCode OPFLOWCreate(MPI_Comm mpicomm, OPFLOW *opflowout) { OPFLOWOptions::include_loadloss_variables.default_value; opflow->include_powerimbalance_variables = OPFLOWOptions::include_powerimbalance_variables.default_value; + opflow->load_scaling_factor = + OPFLOWOptions::load_scaling_factor.default_value; opflow->loadloss_penalty = OPFLOWOptions::loadloss_penalty.default_value; opflow->powerimbalance_penalty = @@ -845,6 +886,8 @@ PetscErrorCode OPFLOWCreate(MPI_Comm mpicomm, OPFLOW *opflowout) { *opflowout = opflow; + opflow->address = opflowout; + // ierr = PetscPrintf(opflow->comm->type,"OPFLOW: Application created\n"); PetscFunctionReturn(0); } @@ -1127,6 +1170,7 @@ PetscErrorCode OPFLOWSetModel(OPFLOW opflow, const std::string modelname) { opflow->modelops.setinitialguessarray = 0; opflow->modelops.computeequalityconstraints = 0; opflow->modelops.computeequalityconstraintsarray = 0; + opflow->modelops.checkconstraints = 0; opflow->modelops.computeinequalityconstraints = 0; opflow->modelops.computeinequalityconstraintsarray = 0; opflow->modelops.computeconstraints = 0; @@ -1537,6 +1581,18 @@ PetscErrorCode OPFLOWSetUp(OPFLOW opflow) { &opflow->ignore_lineflow_constraints, NULL); CHKERRQ(ierr); + /* Lazy line flow constraints? */ + ierr = + PetscOptionsBool(OPFLOWOptions::lazy_lineflow_constraints.opt.c_str(), + OPFLOWOptions::lazy_lineflow_constraints.desc.c_str(), + "", opflow->lazy_lineflow_constraints, + &opflow->lazy_lineflow_constraints, NULL); + CHKERRQ(ierr); + + if (opflow->lazy_lineflow_constraints) { + opflow->ignore_lineflow_constraints = PETSC_TRUE; + } + /* Allow line flow violations ? */ ierr = PetscOptionsBool(OPFLOWOptions::allow_lineflow_violation.opt.c_str(), @@ -1563,6 +1619,13 @@ PetscErrorCode OPFLOWSetUp(OPFLOW opflow) { opflow->loadloss_penalty, &opflow->loadloss_penalty, NULL); CHKERRQ(ierr); + + ierr = PetscOptionsReal(OPFLOWOptions::load_scaling_factor.opt.c_str(), + OPFLOWOptions::load_scaling_factor.desc.c_str(), "", + opflow->load_scaling_factor, + &opflow->load_scaling_factor, NULL); + CHKERRQ(ierr); + ierr = PetscOptionsBool( OPFLOWOptions::include_powerimbalance_variables.opt.c_str(), OPFLOWOptions::include_powerimbalance_variables.desc.c_str(), "", @@ -1645,13 +1708,21 @@ PetscErrorCode OPFLOWSetUp(OPFLOW opflow) { CHKERRQ(ierr); } + /* Scaling of load (note by default load scaling factor is 1.0 */ + for (int i = 0; i < ps->nbus; i++) { + PSBUS bus = &(ps->bus[i]); + for (int l = 0; l < bus->nload; l++) { + PSLOAD load; + ierr = PSBUSGetLoad(bus, l, &load); + CHKERRQ(ierr); + load->pl *= opflow->load_scaling_factor; + load->ql *= opflow->load_scaling_factor; + } + } + /* Set individual load cost parameters to the blanket values if they were not read from the input network */ if (opflow->include_loadloss_variables) { - PS ps; - ierr = OPFLOWGetPS(opflow, &ps); - CHKERRQ(ierr); - if (!ps->read_load_cost) { for (int i = 0; i < ps->nbus; i++) { PSBUS bus = &(ps->bus[i]); @@ -1659,7 +1730,11 @@ PetscErrorCode OPFLOWSetUp(OPFLOW opflow) { PSLOAD load; ierr = PSBUSGetLoad(bus, l, &load); CHKERRQ(ierr); - load->loss_frac = 1.0; + if (load->pl < 0.0 || load->ql < 0.0) { + load->loss_frac = 0.0; + } else { + load->loss_frac = 1.0; + } load->loss_cost = opflow->loadloss_penalty; } } @@ -2001,6 +2076,8 @@ PetscErrorCode OPFLOWSolve(OPFLOW opflow) { PetscErrorCode ierr; PetscLogDouble real1 = 0.0, real2 = 0.0; PetscLogDouble cpu1 = 0.0, cpu2 = 0.0; + PetscBool conv_status; + OPFLOW *opflowaddr = opflow->address; PetscFunctionBegin; ierr = PetscTime(&real1); @@ -2021,6 +2098,88 @@ PetscErrorCode OPFLOWSolve(OPFLOW opflow) { CHKERRQ(ierr); // ierr = VecView(opflow->X,0);CHKERRQ(ierr); + if (opflow->lazy_lineflow_constraints) { + OPFLOW opflow2; + PetscBool has_overload = PETSC_FALSE; + PetscInt lazy_iter = 0; + PetscInt max_lazy_iter = 10; + PetscInt nlines_overloaded; + PetscInt *lines_overloaded; + + ierr = OPFLOWSolutionToPS(opflow); + CHKERRQ(ierr); + + /* Get Line overloads */ + ierr = OPFLOWGetLineOverloads(opflow, &opflow->ps->nlines_overloaded, + &opflow->ps->lines_overloaded, + &opflow->ps->has_overloaded_lines); + CHKERRQ(ierr); + + has_overload = opflow->ps->has_overloaded_lines; + + while ((lazy_iter++ < max_lazy_iter) && (has_overload)) { + nlines_overloaded = opflow->ps->nlines_overloaded; + lines_overloaded = opflow->ps->lines_overloaded; + + /* Get convergence status */ + ierr = OPFLOWGetConvergenceStatus(opflow, &conv_status); + + ierr = PetscPrintf(opflow->comm->type, "%d lines overloaded\n", + nlines_overloaded); + CHKERRQ(ierr); + + /* Display constraints information */ + ierr = OPFLOWCheckConstraints(opflow); + CHKERRQ(ierr); + + /* Create new OPFLOW */ + ierr = OPFLOWCreate(opflow->comm->type, &opflow2); + CHKERRQ(ierr); + + ierr = OPFLOWReadMatPowerData(opflow2, opflow->ps->net_file_name); + CHKERRQ(ierr); + + ierr = OPFLOWSetModel(opflow2, opflow->modelname); + CHKERRQ(ierr); + + ierr = OPFLOWSetSolver(opflow2, opflow->solvername); + CHKERRQ(ierr); + + ierr = OPFLOWCopyOptions(opflow, opflow2); + CHKERRQ(ierr); + + ierr = OPFLOWSkipOptions(opflow2, PETSC_TRUE); + CHKERRQ(ierr); + + opflow2->lazy_lineflow_constraints = PETSC_FALSE; + opflow2->ignore_lineflow_constraints = PETSC_TRUE; + + ierr = OPFLOWSetLinesMonitored(opflow2, 0, nlines_overloaded, + lines_overloaded, 0, NULL, NULL); + CHKERRQ(ierr); + + ierr = OPFLOWSolve(opflow2); + CHKERRQ(ierr); + + opflow2->lazy_lineflow_constraints = opflow->lazy_lineflow_constraints; + opflow2->ignore_lineflow_constraints = + opflow->ignore_lineflow_constraints; + + ierr = OPFLOWDestroy(&opflow); + CHKERRQ(ierr); + + *opflowaddr = opflow2; + opflow = opflow2; + + /* Get Line overloads */ + ierr = OPFLOWGetLineOverloads(opflow, &opflow->ps->nlines_overloaded, + &opflow->ps->lines_overloaded, + &opflow->ps->has_overloaded_lines); + CHKERRQ(ierr); + + has_overload = opflow->ps->has_overloaded_lines; + } + } ierr = PetscTime(&real2); CHKERRQ(ierr); @@ -2029,6 +2188,14 @@ PetscErrorCode OPFLOWSolve(OPFLOW opflow) { opflow->solve_real_time = real2 - real1; + /* Get convergence status */ + ierr = OPFLOWGetConvergenceStatus(opflow, &conv_status); + + if (!conv_status || opflow->ignore_lineflow_constraints) { + /* Display constraints information */ + ierr = OPFLOWCheckConstraints(opflow); + } + PetscFunctionReturn(0); } @@ -2762,6 +2929,7 @@ PetscErrorCode OPFLOWSetUpPS(OPFLOW opflow) { PetscFunctionBegin; ierr = PSSetUp(opflow->ps); CHKERRQ(ierr); + /* set individual load costs if necessary */ PetscFunctionReturn(0); @@ -2854,6 +3022,73 @@ PetscErrorCode OPFLOWIgnoreLineflowConstraints(OPFLOW opflow, PetscBool set) { PetscFunctionReturn(0); } +/* + OPFLOWSetLinesMonitored - List of lines to monitor. The flows for these lines + are included as inequality constraints in OPFLOW + + Input Parameter: ++ opflow - OPFLOW object +. mon_mode - - Monitor Mode (0 = Input lines, 1 = KV levels, 2 = From file) +. nlinesmon - Number of lines to be monitored (active with mon_mode = 0) +. linesmon - List of lines to be monitored (active with mon_mode = 0) +. nkvlevels - Number of kvlevels to monitor (active with mon_mode = 1,Use -1 +to monitor all kvlevels) . kvlevels - line kvlevels to monitor (active with +mon_mode = 1) +- monitorfile - File with list of lines to monitor (active with mon_mode = 2) + + Notes: + The lines to monitor are either specified via API, through a file OR by + kvlevels, Use NULL for monitorfile if file is not set. + +*/ +PetscErrorCode OPFLOWSetLinesMonitored(OPFLOW opflow, PetscInt mon_mode, + PetscInt nlinesmon, PetscInt *linesmon, + PetscInt nkvlevels, + const PetscScalar *kvlevels, + const char *monitorfile) { + PetscErrorCode ierr; + + PetscFunctionBegin; + + if (mon_mode < 0 || mon_mode > 2) { + SETERRQ1(opflow->comm->type, PETSC_ERR_SUP, + "mon_mode input for OPFLOWSetLinesMonitored should \ + be either 0 (list of given lines), 1 (list of KV levels), 2 (list from input file. Incorrect \ + mon_mode = %d given", + mon_mode); + } + + if (mon_mode == 0) { + opflow->nlinesmon = nlinesmon; + ierr = PetscMalloc1(opflow->nlinesmon, &opflow->linesmon); + CHKERRQ(ierr); + ierr = PetscMemcpy(opflow->linesmon, linesmon, + opflow->nlinesmon * sizeof(PetscInt)); + CHKERRQ(ierr); + } else if (mon_mode == 1) { + if (nkvlevels < 0) { + opflow->nlinekvmon = opflow->ps->nkvlevels; + ierr = PetscMemcpy(opflow->linekvmon, opflow->ps->kvlevels, + opflow->nlinekvmon * sizeof(PetscScalar)); + } else if (nkvlevels == 0) { + opflow->ignore_lineflow_constraints = PETSC_TRUE; + opflow->nlinekvmon = 0; + opflow->linesmon = NULL; + } else { + opflow->nlinekvmon = nkvlevels; + ierr = PetscMemcpy(opflow->linekvmon, kvlevels, + nkvlevels * sizeof(PetscScalar)); + } + } else { + if (monitorfile != NULL) { + SETERRQ(opflow->comm->type, PETSC_ERR_SUP, + "Providing line list via file not yet supported"); + } + } + + PetscFunctionReturn(0); +} + /** * @brief Gets ignore_lineflow_constraints * @@ -2923,52 +3158,6 @@ PetscErrorCode OPFLOWGetLineFlowViolationPenalty(OPFLOW opflow, PetscFunctionReturn(0); } -/* - OPFLOWMonitorLines - List of lines to monitor. The flows for these lines - are included as inequality constraints in OPFLOW - - Input Parameter: -+ opflow - OPFLOW object -. nkvlevels - Number of kvlevels to monitor (Use -1 to monitor all kvlevels) -. kvlevels - line kvlevels to monitor -- monitorfile - File with list of lines to monitor. - - Notes: - The lines to monitor are either specified through a file OR by - kvlevels, but not both. Use NULL for monitorfile if file is not set. - If monitorfile is given then the kvlevels are ignored. - -*/ -PetscErrorCode OPFLOWSetLinesMonitored(OPFLOW opflow, PetscInt nkvlevels, - const PetscScalar *kvlevels, - const char *monitorfile) { - PetscErrorCode ierr = 0; - PetscFunctionBegin; - - if (monitorfile != NULL) { - SETERRQ(opflow->comm->type, PETSC_ERR_SUP, - "Providing line list via file not yet supported"); - } - - if (nkvlevels < 0) { - opflow->nlinekvmon = opflow->ps->nkvlevels; - ierr = PetscMemcpy(opflow->linekvmon, opflow->ps->kvlevels, - opflow->nlinekvmon * sizeof(PetscScalar)); - ExaGOCheckError(ierr); - } else if (nkvlevels == 0) { - opflow->ignore_lineflow_constraints = PETSC_TRUE; - opflow->nlinekvmon = 0; - opflow->linesmon = NULL; - } else { - opflow->nlinekvmon = nkvlevels; - ierr = PetscMemcpy(opflow->linekvmon, kvlevels, - nkvlevels * sizeof(PetscScalar)); - ExaGOCheckError(ierr); - } - - PetscFunctionReturn(ierr); -} - /* OPFLOWSetSummaryStats - Sets the summary stats for the OPFLOW run @@ -3074,3 +3263,36 @@ PetscErrorCode OPFLOWCheckModelSolverCompatibility(OPFLOW opflow) { #endif // HIOP PetscFunctionReturn(0); } + +/* + OPFLOWGetLineOverloads - Gets overloaded lines and returns the indices (line +numbers) for overloaded lines + + Input Parameters: +. opflow - OPFLOW object + + Output Parameters: ++ nodlines - number of overloaded line +. odlines - Indices for overloaded lines +- has_overload - True if any line is overloaded + + Notes: Should be called after OPFLOWSolutionToPS has been called +*/ +PetscErrorCode OPFLOWGetLineOverloads(OPFLOW opflow, PetscInt *nodlines, + PetscInt **odlines, + PetscBool *has_overload) { + PetscErrorCode ierr; + + PetscFunctionBegin; + + if (!opflow->solutiontops) { + SETERRQ( + opflow->comm->type, 0, + "Must call OPFLOWSolutioToPS before calling OPLOWCheckLineOverloads"); + } + + ierr = PSGetLineOverloads(opflow->ps, nodlines, odlines, has_overload); + CHKERRQ(ierr); + + PetscFunctionReturn(0); +} diff --git a/src/opflow/interface/opflow2.cpp b/src/opflow/interface/opflow2.cpp new file mode 100644 index 000000000..ccbcfce6d --- /dev/null +++ b/src/opflow/interface/opflow2.cpp @@ -0,0 +1,37 @@ +#include +#include +#include +#include + +/* + OPFLOWCheckConstraints - Displays information about OPFLOW constraints + + Input Parameters: +. opflow - the OPFLOW oject + + Notes: This is called by OPFLOWSolutionToPS. If called exterenally then +OPFLOWSolutionToPS() needs to be called first. +*/ +PetscErrorCode OPFLOWCheckConstraints(OPFLOW opflow) { + PetscErrorCode ierr; + PS ps = opflow->ps; + PSBUS bus; + PSLINE line; + PSGEN gen; + PSLOAD load; + PetscInt i, j; + + PetscFunctionBegin; + + if (!opflow->solutiontops) { + ierr = OPFLOWSolutionToPS(opflow); + CHKERRQ(ierr); + } + + if (opflow->modelops.checkconstraints) { + ierr = (*opflow->modelops.checkconstraints)(opflow); + CHKERRQ(ierr); + } + + PetscFunctionReturn(0); +} diff --git a/src/opflow/model/dcopf/dcopf.cpp b/src/opflow/model/dcopf/dcopf.cpp index 827bbadc6..fd08d9fc2 100644 --- a/src/opflow/model/dcopf/dcopf.cpp +++ b/src/opflow/model/dcopf/dcopf.cpp @@ -18,6 +18,7 @@ PetscErrorCode OPFLOWSetVariableBounds_DCOPF(OPFLOW opflow, Vec Xl, Vec Xu) { PetscScalar *xl, *xu; PetscInt i; PSBUS bus; + PSLINE line; PSGEN gen; PetscInt loc; @@ -29,6 +30,18 @@ PetscErrorCode OPFLOWSetVariableBounds_DCOPF(OPFLOW opflow, Vec Xl, Vec Xu) { ierr = VecGetArray(Xu, &xu); CHKERRQ(ierr); + for (i = 0; i < opflow->nlinesmon; i++) { + line = &ps->line[opflow->linesmon[i]]; + + if (line->isdcline) { + loc = line->startxdcloc; + + // Bounds on PF + xl[loc] = line->pmin; + xu[loc] = line->pmax; + } + } + for (i = 0; i < ps->nbus; i++) { PetscInt k; @@ -173,12 +186,10 @@ PetscErrorCode OPFLOWSetConstraintBounds_DCOPF(OPFLOW opflow, Vec Gl, Vec Gu) { } } /* Line flow constraint bounds */ - if (!opflow->ignore_lineflow_constraints) { - for (i = 0; i < ps->nline; i++) { - line = &ps->line[i]; - if (!line->status || line->rateA > 1e5) - continue; + for (i = 0; i < opflow->nlinesmon; i++) { + line = &ps->line[opflow->linesmon[i]]; + if (!line->isdcline) { gloc = line->startineqloc; /* Line flow inequality constraints */ gl[gloc] = gl[gloc + 1] = -(line->rateA / ps->MVAbase); @@ -214,10 +225,11 @@ PetscErrorCode OPFLOWSetInitialGuess_DCOPF(OPFLOW opflow, Vec X, Vec Lambda) { PetscErrorCode ierr; PS ps = opflow->ps; const PetscScalar *xl, *xu; - PetscScalar *x; + PetscScalar *x, *lambda; PetscInt i; PSBUS bus; - PetscInt loc; + PSLINE line; + PetscInt loc, gloc; PetscFunctionBegin; @@ -228,6 +240,8 @@ PetscErrorCode OPFLOWSetInitialGuess_DCOPF(OPFLOW opflow, Vec X, Vec Lambda) { CHKERRQ(ierr); ierr = VecGetArrayRead(opflow->Xu, &xu); CHKERRQ(ierr); + ierr = VecGetArray(Lambda, &lambda); + CHKERRQ(ierr); for (i = 0; i < ps->nbus; i++) { PetscInt k; @@ -299,6 +313,26 @@ PetscErrorCode OPFLOWSetInitialGuess_DCOPF(OPFLOW opflow, Vec X, Vec Lambda) { x[loc] = 0.0; } } + + gloc = bus->starteqloc; + lambda[gloc] = bus->mult_pmis; + } + + for (i = 0; i < opflow->nlinesmon; i++) { + line = &ps->line[opflow->linesmon[i]]; + + if (line->isdcline) { + loc = line->startxdcloc; + + if (opflow->initializationtype == OPFLOWINIT_MIDPOINT || + opflow->initializationtype == OPFLOWINIT_FLATSTART) { + x[loc] = 0.5 * (xl[loc] + xu[loc]); + } else if (opflow->initializationtype == OPFLOWINIT_FROMFILE || + opflow->initializationtype == OPFLOWINIT_ACPF || + opflow->initializationtype == OPFLOWINIT_DCOPF) { + x[loc] = PetscMax(line->pmin, PetscMin(line->pf, line->pmax)); + } + } } ierr = VecRestoreArray(X, &x); @@ -307,6 +341,8 @@ PetscErrorCode OPFLOWSetInitialGuess_DCOPF(OPFLOW opflow, Vec X, Vec Lambda) { CHKERRQ(ierr); ierr = VecRestoreArrayRead(opflow->Xu, &xu); CHKERRQ(ierr); + ierr = VecRestoreArray(Lambda, &lambda); + CHKERRQ(ierr); PetscFunctionReturn(0); } @@ -425,31 +461,45 @@ PetscErrorCode OPFLOWComputeEqualityConstraints_DCOPF(OPFLOW opflow, Vec X, busf = connbuses[0]; bust = connbuses[1]; - xlocf = busf->startxVloc; - xloct = bust->startxVloc; + if (!line->isdcline) { + xlocf = busf->startxVloc; + xloct = bust->startxVloc; - thetaf = x[xlocf]; - thetat = x[xloct]; - thetaft = thetaf - thetat; - thetatf = thetat - thetaf; + thetaf = x[xlocf]; + thetat = x[xloct]; + thetaft = thetaf - thetat; + thetatf = thetat - thetaf; - if (bus == busf) { - Pf = Bdc * thetaft + Pshift; + if (bus == busf) { + Pf = Bdc * thetaft + Pshift; - val[0] = Pf; + val[0] = Pf; - ierr = VecSetValues(Ge, 1, row, val, ADD_VALUES); - CHKERRQ(ierr); + ierr = VecSetValues(Ge, 1, row, val, ADD_VALUES); + CHKERRQ(ierr); - flps += 1.0; - } else { - Pt = Bdc * thetatf - Pshift; + flps += 2.0; + } else { + Pt = Bdc * thetatf - Pshift; - val[0] = Pt; + val[0] = Pt; + ierr = VecSetValues(Ge, 1, row, val, ADD_VALUES); + CHKERRQ(ierr); + flps += 2.0; + } + } else if (line->isdcline) { + Pf = x[line->startxdcloc]; + + if (bus == busf) { + val[0] = Pf; + } else { + Pt = Pf - (line->loss0 + line->loss1 * Pf); + val[0] = -Pf; + flps += 3.0; + } ierr = VecSetValues(Ge, 1, row, val, ADD_VALUES); CHKERRQ(ierr); - flps += 1.0; } } @@ -586,10 +636,9 @@ PetscErrorCode OPFLOWComputeEqualityConstraintJacobian_DCOPF(OPFLOW opflow, for (k = 0; k < nconnlines; k++) { line = connlines[k]; + if (!line->status) continue; - Bdc = line->bdc; - // Pshift = line->pshift; /* Get the connected buses to this line */ ierr = PSLINEGetConnectedBuses(line, &connbuses); @@ -597,41 +646,47 @@ PetscErrorCode OPFLOWComputeEqualityConstraintJacobian_DCOPF(OPFLOW opflow, busf = connbuses[0]; bust = connbuses[1]; - // locf = busf->startxVloc; - // loct = bust->startxVloc; - - locglobf = busf->startxVlocglob; - locglobt = bust->startxVlocglob; + if (!line->isdcline) { + locglobf = busf->startxVlocglob; + locglobt = bust->startxVlocglob; - // thetaf = xarr[locf]; - // thetat = xarr[loct]; - // thetaft = thetaf - thetat; - // thetatf = thetat - thetaf; + Bdc = line->bdc; - if (bus == busf) { - col[0] = locglobf; - col[1] = locglobt; - /* dPf_dthetaf */ - val[0] = Bdc; - /*dPf_dthetat */ - val[1] = -Bdc; + if (bus == busf) { + col[0] = locglobf; + col[1] = locglobt; + /* dPf_dthetaf */ + val[0] = Bdc; + /*dPf_dthetat */ + val[1] = -Bdc; - ierr = MatSetValues(Je, 1, row, 2, col, val, ADD_VALUES); - CHKERRQ(ierr); - } else { - col[0] = locglobt; - col[1] = locglobf; + ierr = MatSetValues(Je, 1, row, 2, col, val, ADD_VALUES); + CHKERRQ(ierr); + } else { + col[0] = locglobt; + col[1] = locglobf; - /* dPt_dthetat */ - val[0] = Bdc; - /* dPt_dthetaf */ - val[1] = -Bdc; + /* dPt_dthetat */ + val[0] = Bdc; + /* dPt_dthetaf */ + val[1] = -Bdc; - ierr = MatSetValues(Je, 1, row, 2, col, val, ADD_VALUES); - CHKERRQ(ierr); + ierr = MatSetValues(Je, 1, row, 2, col, val, ADD_VALUES); + CHKERRQ(ierr); + } + } else if (line->isdcline) { + if (bus == busf) { + col[0] = line->startxdcloc; + val[0] = 1.0; + ierr = MatSetValues(Je, 1, row, 1, col, val, ADD_VALUES); + } else { + col[0] = line->startxdcloc; + val[0] = -(1.0 - line->loss1); + ierr = MatSetValues(Je, 1, row, 1, col, val, ADD_VALUES); + flps += 2.0; + } } } - flps += nconnlines * 2; if (opflow->has_gensetpoint) { ierr = PSBUSGetVariableGlobalLocation(bus, &locglob); @@ -741,36 +796,36 @@ PetscErrorCode OPFLOWComputeInequalityConstraints_DCOPF(OPFLOW opflow, Vec X, } if (!opflow->ignore_lineflow_constraints) { - for (i = 0; i < ps->nline; i++) { - line = &ps->line[i]; - if (!line->status || line->rateA > 1e5) - continue; + for (i = 0; i < opflow->nlinesmon; i++) { + line = &ps->line[opflow->linesmon[i]]; - gloc = line->startineqloc; + if (!line->isdcline) { + gloc = line->startineqloc; - Bdc = line->bdc; - Pshift = line->pshift; + Bdc = line->bdc; + Pshift = line->pshift; - ierr = PSLINEGetConnectedBuses(line, &connbuses); - CHKERRQ(ierr); - busf = connbuses[0]; - bust = connbuses[1]; + ierr = PSLINEGetConnectedBuses(line, &connbuses); + CHKERRQ(ierr); + busf = connbuses[0]; + bust = connbuses[1]; - xlocf = busf->startxVloc; - xloct = bust->startxVloc; + xlocf = busf->startxVloc; + xloct = bust->startxVloc; - thetaf = x[xlocf]; - thetat = x[xloct]; - thetaft = thetaf - thetat; - thetatf = thetat - thetaf; + thetaf = x[xlocf]; + thetat = x[xloct]; + thetaft = thetaf - thetat; + thetatf = thetat - thetaf; - Pf = Bdc * thetaft + Pshift; - Pt = Bdc * thetatf - Pshift; + Pf = Bdc * thetaft + Pshift; + Pt = Bdc * thetatf - Pshift; - g[gloc] = Pf; - g[gloc + 1] = Pt; + g[gloc] = Pf; + g[gloc + 1] = Pt; - flps += 4.0; + flps += 4.0; + } } } @@ -859,54 +914,48 @@ PetscErrorCode OPFLOWComputeInequalityConstraintJacobian_DCOPF(OPFLOW opflow, } if (!opflow->ignore_lineflow_constraints) { - for (i = 0; i < ps->nline; i++) { - line = &ps->line[i]; - if (!line->status || line->rateA > 1e5) - continue; - - gloc = line->startineqloc; + for (i = 0; i < opflow->nlinesmon; i++) { + line = &ps->line[opflow->linesmon[i]]; - Bdc = line->bdc; - // Pshift = line->pshift; + if (!line->isdcline) { + gloc = line->startineqloc; - ierr = PSLINEGetConnectedBuses(line, &connbuses); - CHKERRQ(ierr); - busf = connbuses[0]; - bust = connbuses[1]; + Bdc = line->bdc; - xlocf = busf->startxVloc; - xloct = bust->startxVloc; + ierr = PSLINEGetConnectedBuses(line, &connbuses); + CHKERRQ(ierr); + busf = connbuses[0]; + bust = connbuses[1]; - // thetaf = x[xlocf]; - // thetat = x[xloct]; - // thetaft = thetaf - thetat; - // thetatf = thetat - thetaf; + xlocf = busf->startxVloc; + xloct = bust->startxVloc; - dPf_dthetaf = Bdc; - dPf_dthetat = -Bdc; + dPf_dthetaf = Bdc; + dPf_dthetat = -Bdc; - dPt_dthetat = Bdc; - dPt_dthetaf = -Bdc; + dPt_dthetat = Bdc; + dPt_dthetaf = -Bdc; - row[0] = gloc; - col[0] = xlocf; - col[1] = xloct; + row[0] = gloc; + col[0] = xlocf; + col[1] = xloct; - val[0] = dPf_dthetaf; - val[1] = dPf_dthetat; + val[0] = dPf_dthetaf; + val[1] = dPf_dthetat; - ierr = MatSetValues(Ji, 1, row, 2, col, val, ADD_VALUES); - CHKERRQ(ierr); + ierr = MatSetValues(Ji, 1, row, 2, col, val, ADD_VALUES); + CHKERRQ(ierr); - row[0] = gloc + 1; - col[0] = xloct; - col[1] = xlocf; + row[0] = gloc + 1; + col[0] = xloct; + col[1] = xlocf; - val[0] = dPt_dthetat; - val[1] = dPt_dthetaf; + val[0] = dPt_dthetat; + val[1] = dPt_dthetaf; - ierr = MatSetValues(Ji, 1, row, 2, col, val, ADD_VALUES); - CHKERRQ(ierr); + ierr = MatSetValues(Ji, 1, row, 2, col, val, ADD_VALUES); + CHKERRQ(ierr); + } } flps += ps->nline * 2; } @@ -1112,15 +1161,22 @@ PetscErrorCode OPFLOWModelSetNumVariables_DCOPF(OPFLOW opflow, PSLINE line; PetscErrorCode ierr; PetscBool isghost; + PetscInt monidx; PetscFunctionBegin; *nx = 0; - /* No variables for the branches */ - for (i = 0; i < ps->nline; i++) { - line = &ps->line[i]; - branchnvar[i] = line->nx = 0; - *nx += branchnvar[i]; + /* Variables for the branches */ + for (i = 0; i < opflow->nlinesmon; i++) { + monidx = opflow->linesmon[i]; + line = &ps->line[opflow->linesmon[i]]; + + if (line->isdcline) { + branchnvar[monidx] = line->nx = 1; + } else { + branchnvar[monidx] = line->nx = 0; + } + *nx += branchnvar[monidx]; } /* Variables for the buses */ @@ -1243,12 +1299,14 @@ PetscErrorCode OPFLOWModelSetNumConstraints_DCOPF(OPFLOW opflow, } if (!opflow->ignore_lineflow_constraints) { - for (i = 0; i < ps->nline; i++) { - line = &ps->line[i]; - if (line->status && line->rateA < 1e5) { + for (i = 0; i < opflow->nlinesmon; i++) { + line = &ps->line[opflow->linesmon[i]]; + if (!line->isdcline) { *nconineq += 2; /* Real power flow line constraint (from and to bus) */ line->nconineq = 2; line->nconeq = 0; + } else if (line->isdcline) { + line->nconeq = line->nconineq = 0; } } } @@ -1555,35 +1613,49 @@ PetscErrorCode OPFLOWSolutionToPS_DCOPF(OPFLOW opflow) { continue; } - Bdc = line->bdc; - Pshift = line->pshift; + if (!line->isdcline) { + Bdc = line->bdc; + Pshift = line->pshift; - ierr = PSLINEGetConnectedBuses(line, &connbuses); - CHKERRQ(ierr); - busf = connbuses[0]; - bust = connbuses[1]; + ierr = PSLINEGetConnectedBuses(line, &connbuses); + CHKERRQ(ierr); + busf = connbuses[0]; + bust = connbuses[1]; - xlocf = busf->startxVloc; - xloct = bust->startxVloc; + xlocf = busf->startxVloc; + xloct = bust->startxVloc; - thetaf = x[xlocf]; - thetat = x[xloct]; - thetaft = thetaf - thetat; - thetatf = thetat - thetaf; + thetaf = x[xlocf]; + thetat = x[xloct]; + thetaft = thetaf - thetat; + thetatf = thetat - thetaf; - Pf = Bdc * thetaft + Pshift; - Pt = Bdc * thetatf - Pshift; + Pf = Bdc * thetaft + Pshift; + Pt = Bdc * thetatf - Pshift; - line->pf = Pf; - line->qf = 0.0; - line->pt = Pt; - line->qt = 0.0; - line->sf = Pf; - line->st = Pt; + line->pf = Pf; + line->qf = 0.0; + line->pt = Pt; + line->qt = 0.0; + line->sf = Pf; + line->st = Pt; + } else if (line->isdcline) { + Pf = x[line->startxdcloc]; + + Pt = Pf - (line->loss0 + line->loss1 * Pf); + + line->pf = Pf; + line->qf = 0.0; + line->pt = Pt; + line->qt = 0.0; + line->sf = Pf; + line->st = Pt; + } + } - if (opflow->ignore_lineflow_constraints || line->rateA > 1e5) { - line->mult_sf = line->mult_st = 0.0; - } else { + for (i = 0; i < opflow->nlinesmon; i++) { + line = &ps->line[opflow->linesmon[i]]; + if (!line->isdcline) { gloc = line->startineqloc; line->mult_sf = lambdai[gloc]; line->mult_st = lambdai[gloc + 1]; @@ -1697,11 +1769,16 @@ PetscErrorCode OPFLOWModelSetUp_DCOPF(OPFLOW opflow) { } } - for (i = 0; i < ps->nline; i++) { - line = &ps->line[i]; - if (line->status && line->rateA < 1e5) { + for (i = 0; i < opflow->nlinesmon; i++) { + line = &ps->line[opflow->linesmon[i]]; + + if (!line->isdcline) { line->startineqloc = ineqloc; ineqloc += line->nconineq; + } else if (line->isdcline) { + ierr = PSLINEGetVariableLocation(line, &loc); + CHKERRQ(ierr); + line->startxdcloc = loc; } } diff --git a/src/opflow/model/power_bal_polar/pbpol.cpp b/src/opflow/model/power_bal_polar/pbpol.cpp index 2f6bfb9a6..0a26bf349 100644 --- a/src/opflow/model/power_bal_polar/pbpol.cpp +++ b/src/opflow/model/power_bal_polar/pbpol.cpp @@ -1,7 +1,6 @@ #include "pbpol.h" #include "exago_config.h" #include -/* Testing Orestis's permission to commit. */ PetscErrorCode OPFLOWModelDestroy_PBPOL(OPFLOW opflow) { PetscErrorCode ierr; @@ -31,13 +30,32 @@ PetscErrorCode OPFLOWSetVariableBounds_PBPOL(OPFLOW opflow, Vec Xl, Vec Xu) { ierr = VecGetArray(Xu, &xu); CHKERRQ(ierr); - for (i = 0; i < opflow->nlinesmon; i++) { - line = &ps->line[opflow->linesmon[i]]; - if (opflow->allow_lineflow_violation) { - /* Bounds on slack variables */ - loc = line->startxslackloc; - xl[loc] = xl[loc + 1] = 0.0; - xu[loc] = xu[loc + 1] = PETSC_INFINITY; + for (i = 0; i < ps->nline; i++) { + line = &ps->line[i]; + if (!line->status) + continue; + + if (!line->isdcline) { + if (opflow->allow_lineflow_violation) { + /* Bounds on slack variables */ + loc = line->startxslackloc; + xl[loc] = xl[loc + 1] = 0.0; + xu[loc] = xu[loc + 1] = PETSC_INFINITY; + } + } else { + loc = line->startxdcloc; + + // Bounds on PF + xl[loc] = line->pmin; + xu[loc] = line->pmax; + + // Bounds on QF + xl[loc + 1] = line->qminf; + xu[loc + 1] = line->qmaxf; + + // Bounds on QT + xl[loc + 2] = line->qmint; + xu[loc + 2] = line->qmaxt; } } @@ -53,8 +71,15 @@ PetscErrorCode OPFLOWSetVariableBounds_PBPOL(OPFLOW opflow, Vec Xl, Vec Xu) { xu[loc] = PETSC_INFINITY; if (opflow->genbusvoltagetype == VARIABLE_WITHIN_BOUNDS) { - xl[loc + 1] = bus->Vmin; - xu[loc + 1] = bus->Vmax; + if (bus->ngenON && (bus->ide == REF_BUS || bus->ide == PV_BUS)) { + // bus->Vmin = 0.98*bus->vm; + // bus->Vmax = 1.02*bus->vm; + xl[loc + 1] = bus->Vmin; + xu[loc + 1] = bus->Vmax; + } else { + xl[loc + 1] = bus->Vmin; + xu[loc + 1] = bus->Vmax; + } } else if (opflow->genbusvoltagetype == FIXED_WITHIN_QBOUNDS) { if (bus->ide == REF_BUS || bus->ide == PV_BUS) { xl[loc + 1] = 0.0; @@ -97,8 +122,23 @@ PetscErrorCode OPFLOWSetVariableBounds_PBPOL(OPFLOW opflow, Vec Xl, Vec Xu) { loc = gen->startxpowloc; - xl[loc] = gen->pb; /* PGmin */ - xu[loc] = gen->pt; /* PGmax */ + /* If generator is renewable then set the lower + bound to 0 so that it can be curtailed if needed + Note: Do this only if we have positive Pmax (pt) + */ + if (gen->isrenewable && (gen->pt > 0)) { + xl[loc] = 0.0; + xu[loc] = gen->pt; /* PGmax */ + } else { + if (gen->pt > gen->pb || (PetscAbsScalar(gen->pt - gen->pb) < 1e-6)) { + xl[loc] = gen->pb; /* PGmin */ + xu[loc] = gen->pt; /* PGmax */ + } else { + xu[loc] = gen->pb; /* PGmin */ + xl[loc] = gen->pt; /* PGmax */ + } + } + xl[loc + 1] = gen->qb; /* QGmin */ xu[loc + 1] = gen->qt; /* QGmax */ /* pb, pt, qb, qt are converted in p.u. in ps.c */ @@ -232,11 +272,13 @@ PetscErrorCode OPFLOWSetConstraintBounds_PBPOL(OPFLOW opflow, Vec Gl, Vec Gu) { for (i = 0; i < opflow->nlinesmon; i++) { line = &ps->line[opflow->linesmon[i]]; - gloc = line->startineqloc; - /* Line flow inequality constraints */ - gl[gloc] = gl[gloc + 1] = 0.0; - gu[gloc] = gu[gloc + 1] = - (line->rateA / ps->MVAbase) * (line->rateA / ps->MVAbase); + if (!line->isdcline) { + gloc = line->startineqloc; + /* Line flow inequality constraints */ + gl[gloc] = gl[gloc + 1] = PETSC_NINFINITY; + gu[gloc] = gu[gloc + 1] = + (line->rateA / ps->MVAbase) * (line->rateA / ps->MVAbase); + } } ierr = VecRestoreArray(Gl, &gl); @@ -298,7 +340,11 @@ PetscErrorCode OPFLOWSetInitialGuess_PBPOL(OPFLOW opflow, Vec X, Vec Lambda) { if (opflow->initializationtype == OPFLOWINIT_MIDPOINT) { /* Initial guess for voltage angles and bounds on voltage magnitudes */ x[loc] = (xl[loc] + xu[loc]) / 2.0; - x[loc + 1] = (xl[loc + 1] + xu[loc + 1]) / 2.0; + if (bus->ngenON && (bus->ide == REF_BUS || bus->ide == PV_BUS)) { + x[loc + 1] = (bus->Vmin + bus->Vmax) / 2.0; // bus->vm; + } else { + x[loc + 1] = (bus->Vmin + bus->Vmax) / 2.0; + } } else if (opflow->initializationtype == OPFLOWINIT_FROMFILE || opflow->initializationtype == OPFLOWINIT_ACPF || opflow->initializationtype == OPFLOWINIT_DCOPF) { @@ -380,23 +426,49 @@ PetscErrorCode OPFLOWSetInitialGuess_PBPOL(OPFLOW opflow, Vec X, Vec Lambda) { } gloc = bus->starteqloc; - lambda[gloc] = bus->mult_pmis; - lambda[gloc + 1] = bus->mult_qmis; + lambda[gloc] = bus->mult_pmis * ps->MVAbase; + lambda[gloc + 1] = bus->mult_qmis * ps->MVAbase; } PetscScalar *lambdai = lambda + opflow->nconeq; - for (i = 0; i < opflow->nlinesmon; i++) { line = &ps->line[opflow->linesmon[i]]; + gloc = line->startineqloc; + lambdai[gloc] = + line->mult_sf * ps->MVAbase * ps->MVAbase / (2 * line->rateA); + lambdai[gloc + 1] = + line->mult_st * ps->MVAbase * ps->MVAbase / (2 * line->rateA); + } - if (opflow->allow_lineflow_violation) { - loc = line->startxslackloc; - /* Initialize slacks for line flow violations */ - x[loc] = x[loc + 1] = 0.0; + for (i = 0; i < ps->nline; i++) { + line = &ps->line[i]; + if (!line->status) + continue; + + if (!line->isdcline) { + if (opflow->allow_lineflow_violation) { + loc = line->startxslackloc; + /* Initialize slacks for line flow violations */ + x[loc] = x[loc + 1] = 0.0; + } + + } else if (line->isdcline) { + loc = line->startxdcloc; + + if (opflow->initializationtype == OPFLOWINIT_MIDPOINT || + opflow->initializationtype == OPFLOWINIT_FLATSTART) { + x[loc] = 0.5 * (xl[loc] + xu[loc]); + x[loc + 1] = 0.5 * (xl[loc + 1] + xu[loc + 1]); + x[loc + 2] = 0.5 * (xl[loc + 2] + xu[loc + 2]); + + } else if (opflow->initializationtype == OPFLOWINIT_FROMFILE || + opflow->initializationtype == OPFLOWINIT_ACPF || + opflow->initializationtype == OPFLOWINIT_DCOPF) { + x[loc] = PetscMax(line->pmin, PetscMin(line->pf, line->pmax)); + x[loc + 1] = PetscMax(line->qminf, PetscMin(line->qf, line->qmaxf)); + x[loc + 2] = PetscMax(line->qmint, PetscMin(line->qt, line->qmaxt)); + } } - gloc = line->startineqloc; - lambdai[gloc] = line->mult_sf; - lambdai[gloc + 1] = line->mult_st; } ierr = VecRestoreArray(X, &x); @@ -405,6 +477,8 @@ PetscErrorCode OPFLOWSetInitialGuess_PBPOL(OPFLOW opflow, Vec X, Vec Lambda) { CHKERRQ(ierr); ierr = VecRestoreArrayRead(opflow->Xu, &xu); CHKERRQ(ierr); + ierr = VecRestoreArray(Lambda, &lambda); + CHKERRQ(ierr); PetscFunctionReturn(0); } @@ -415,10 +489,10 @@ PetscErrorCode OPFLOWComputeEqualityConstraints_PBPOL(OPFLOW opflow, Vec X, PetscInt i, k, nconnlines; PetscInt gloc, row[2]; PetscInt xloc, xlocf, xloct; - PetscScalar val[2]; PetscScalar Pg, Qg, Pd, Qd; PetscScalar Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt; PetscScalar Vmf, Vmt, thetaf, thetat, thetaft, thetatf; + PetscScalar sin_thetaft, cos_thetaft, sin_thetatf, cos_thetatf; PetscScalar Pf, Qf, Pt, Qt; PetscScalar theta, Vm; PS ps = opflow->ps; @@ -429,6 +503,7 @@ PetscErrorCode OPFLOWComputeEqualityConstraints_PBPOL(OPFLOW opflow, Vec X, const PSBUS *connbuses; const PSLINE *connlines; const PetscScalar *x; + PetscScalar *ge; double flps = 0.0; PetscFunctionBegin; @@ -438,6 +513,9 @@ PetscErrorCode OPFLOWComputeEqualityConstraints_PBPOL(OPFLOW opflow, Vec X, ierr = VecGetArrayRead(X, &x); CHKERRQ(ierr); + ierr = VecGetArray(Ge, &ge); + CHKERRQ(ierr); + for (i = 0; i < ps->nbus; i++) { bus = &ps->bus[i]; @@ -452,20 +530,14 @@ PetscErrorCode OPFLOWComputeEqualityConstraints_PBPOL(OPFLOW opflow, Vec X, Vm = x[xloc + 1]; if (bus->ide == ISOLATED_BUS) { - row[0] = gloc; - row[1] = row[0] + 1; - val[0] = theta - bus->va; - val[1] = Vm - bus->vm; - ierr = VecSetValues(Ge, 2, row, val, ADD_VALUES); - CHKERRQ(ierr); + ge[row[0]] += theta - bus->va; + ge[row[1]] += Vm - bus->vm; continue; } /* Shunt injections */ - val[0] = Vm * Vm * bus->gl; - val[1] = -Vm * Vm * bus->bl; - ierr = VecSetValues(Ge, 2, row, val, ADD_VALUES); - CHKERRQ(ierr); + ge[row[0]] += Vm * Vm * bus->gl; + ge[row[1]] += -Vm * Vm * bus->bl; flps += 5.0; @@ -480,10 +552,8 @@ PetscErrorCode OPFLOWComputeEqualityConstraints_PBPOL(OPFLOW opflow, Vec X, Pimb = Pimbplus - Pimbminus; Qimb = Qimbplus - Qimbminus; - val[0] = Pimb; - val[1] = Qimb; - ierr = VecSetValues(Ge, 2, row, val, ADD_VALUES); - CHKERRQ(ierr); + ge[row[0]] += Pimb; + ge[row[1]] += Qimb; flps += 2.0; } @@ -499,10 +569,8 @@ PetscErrorCode OPFLOWComputeEqualityConstraints_PBPOL(OPFLOW opflow, Vec X, Pg = x[xloc]; Qg = x[xloc + 1]; - val[0] = -Pg; - val[1] = -Qg; - ierr = VecSetValues(Ge, 2, row, val, ADD_VALUES); - CHKERRQ(ierr); + ge[row[0]] += -Pg; + ge[row[1]] += -Qg; flps += 2.0; } @@ -520,10 +588,9 @@ PetscErrorCode OPFLOWComputeEqualityConstraints_PBPOL(OPFLOW opflow, Vec X, Qd = load->ql; } - val[0] = Pd; - val[1] = Qd; - ierr = VecSetValues(Ge, 2, row, val, ADD_VALUES); - CHKERRQ(ierr); + ge[row[0]] += Pd; + ge[row[1]] += Qd; + flps += 2.0; } @@ -534,53 +601,69 @@ PetscErrorCode OPFLOWComputeEqualityConstraints_PBPOL(OPFLOW opflow, Vec X, if (!line->status) continue; - Gff = line->yff[0]; - Bff = line->yff[1]; - Gft = line->yft[0]; - Bft = line->yft[1]; - Gtf = line->ytf[0]; - Btf = line->ytf[1]; - Gtt = line->ytt[0]; - Btt = line->ytt[1]; - ierr = PSLINEGetConnectedBuses(line, &connbuses); CHKERRQ(ierr); busf = connbuses[0]; bust = connbuses[1]; - xlocf = busf->startxVloc; - xloct = bust->startxVloc; - - thetaf = x[xlocf]; - Vmf = x[xlocf + 1]; - thetat = x[xloct]; - Vmt = x[xloct + 1]; - thetaft = thetaf - thetat; - thetatf = thetat - thetaf; - - if (bus == busf) { - Pf = Gff * Vmf * Vmf + - Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - Qf = -Bff * Vmf * Vmf + - Vmf * Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); - - val[0] = Pf; - val[1] = Qf; - ierr = VecSetValues(Ge, 2, row, val, ADD_VALUES); - CHKERRQ(ierr); - - flps += 78.0; - } else { - Pt = Gtt * Vmt * Vmt + - Vmt * Vmf * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - Qt = -Btt * Vmt * Vmt + - Vmt * Vmf * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - - val[0] = Pt; - val[1] = Qt; - ierr = VecSetValues(Ge, 2, row, val, ADD_VALUES); - CHKERRQ(ierr); - flps += 78.0; + if (!line->isdcline) { + Gff = line->yff[0]; + Bff = line->yff[1]; + Gft = line->yft[0]; + Bft = line->yft[1]; + Gtf = line->ytf[0]; + Btf = line->ytf[1]; + Gtt = line->ytt[0]; + Btt = line->ytt[1]; + + xlocf = busf->startxVloc; + xloct = bust->startxVloc; + + thetaf = x[xlocf]; + Vmf = x[xlocf + 1]; + thetat = x[xloct]; + Vmt = x[xloct + 1]; + thetaft = thetaf - thetat; + thetatf = thetat - thetaf; + sin_thetaft = sin(thetaft); + cos_thetaft = cos(thetaft); + sin_thetatf = sin(thetatf); + cos_thetatf = cos(thetatf); + + if (bus == busf) { + Pf = Gff * Vmf * Vmf + + Vmf * Vmt * (Gft * cos_thetaft + Bft * sin_thetaft); + Qf = -Bff * Vmf * Vmf + + Vmf * Vmt * (-Bft * cos_thetaft + Gft * sin_thetaft); + + ge[row[0]] += Pf; + ge[row[1]] += Qf; + + flps += 78.0; + } else { + Pt = Gtt * Vmt * Vmt + + Vmt * Vmf * (Gtf * cos_thetatf + Btf * sin_thetatf); + Qt = -Btt * Vmt * Vmt + + Vmt * Vmf * (-Btf * cos_thetatf + Gtf * sin_thetatf); + + ge[row[0]] += Pt; + ge[row[1]] += Qt; + + flps += 78.0; + } + } else if (line->isdcline) { + Pf = x[line->startxdcloc]; + Qf = x[line->startxdcloc + 1]; + Qt = x[line->startxdcloc + 2]; + + if (bus == busf) { + ge[row[0]] += Pf; + ge[row[1]] += Qf; + } else { + Pt = Pf - (line->loss0 + line->loss1 * Pf); + ge[row[0]] += -Pt; + ge[row[1]] += -Qt; + } } } @@ -600,24 +683,17 @@ PetscErrorCode OPFLOWComputeEqualityConstraints_PBPOL(OPFLOW opflow, Vec X, gloc = gen->starteqloc; row[0] = gloc; - val[0] = Pgset + delPg - Pg; - - ierr = VecSetValues(Ge, 1, row, val, ADD_VALUES); - CHKERRQ(ierr); + ge[row[0]] += Pgset + delPg - Pg; row[0] = gloc + 1; - val[0] = Pgset - gen->pgs; - - ierr = VecSetValues(Ge, 1, row, val, ADD_VALUES); - CHKERRQ(ierr); + ge[row[0]] += Pgset - gen->pgs; flps += 3.0; } } } - ierr = VecAssemblyBegin(Ge); - CHKERRQ(ierr); - ierr = VecAssemblyEnd(Ge); + + ierr = VecRestoreArray(Ge, &ge); CHKERRQ(ierr); ierr = VecRestoreArrayRead(X, &x); @@ -634,6 +710,7 @@ PetscErrorCode OPFLOWComputeEqualityConstraintJacobian_PBPOL(OPFLOW opflow, PetscInt nconnlines, locglob, loc, locglobf, locglobt, locf, loct; PetscScalar Vm, val[8], Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt; PetscScalar thetaf, thetat, Vmf, Vmt, thetaft, thetatf; + PetscScalar sin_thetaft, cos_thetaft, sin_thetatf, cos_thetatf; PS ps = opflow->ps; PSBUS bus; PSLINE line; @@ -744,14 +821,6 @@ PetscErrorCode OPFLOWComputeEqualityConstraintJacobian_PBPOL(OPFLOW opflow, line = connlines[k]; if (!line->status) continue; - Gff = line->yff[0]; - Bff = line->yff[1]; - Gft = line->yft[0]; - Bft = line->yft[1]; - Gtf = line->ytf[0]; - Btf = line->ytf[1]; - Gtt = line->ytt[0]; - Btt = line->ytt[1]; /* Get the connected buses to this line */ ierr = PSLINEGetConnectedBuses(line, &connbuses); @@ -759,71 +828,104 @@ PetscErrorCode OPFLOWComputeEqualityConstraintJacobian_PBPOL(OPFLOW opflow, busf = connbuses[0]; bust = connbuses[1]; - locf = busf->startxVloc; - loct = bust->startxVloc; - - locglobf = busf->startxVlocglob; - locglobt = bust->startxVlocglob; - - thetaf = xarr[locf]; - Vmf = xarr[locf + 1]; - thetat = xarr[loct]; - Vmt = xarr[loct + 1]; - thetaft = thetaf - thetat; - thetatf = thetat - thetaf; - - if (bus == busf) { - col[0] = locglobf; - col[1] = locglobf + 1; - col[2] = locglobt; - col[3] = locglobt + 1; - /* dPf_dthetaf */ - val[0] = Vmf * Vmt * (-Gft * sin(thetaft) + Bft * cos(thetaft)); - /*dPf_dVmf */ - val[1] = - 2 * Gff * Vmf + Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - /*dPf_dthetat */ - val[2] = Vmf * Vmt * (Gft * sin(thetaft) - Bft * cos(thetaft)); - /* dPf_dVmt */ - val[3] = Vmf * (Gft * cos(thetaft) + Bft * sin(thetaft)); - - /* dQf_dthetaf */ - val[4] = Vmf * Vmt * (Bft * sin(thetaft) + Gft * cos(thetaft)); - /* dQf_dVmf */ - val[5] = - -2 * Bff * Vmf + Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); - /* dQf_dthetat */ - val[6] = Vmf * Vmt * (-Bft * sin(thetaft) - Gft * cos(thetaft)); - /* dQf_dVmt */ - val[7] = Vmf * (-Bft * cos(thetaft) + Gft * sin(thetaft)); - ierr = MatSetValues(Je, 2, row, 4, col, val, ADD_VALUES); - CHKERRQ(ierr); - } else { - col[0] = locglobt; - col[1] = locglobt + 1; - col[2] = locglobf; - col[3] = locglobf + 1; - /* dPt_dthetat */ - val[0] = Vmt * Vmf * (-Gtf * sin(thetatf) + Btf * cos(thetatf)); - /* dPt_dVmt */ - val[1] = - 2 * Gtt * Vmt + Vmf * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - /* dPt_dthetaf */ - val[2] = Vmt * Vmf * (Gtf * sin(thetatf) - Btf * cos(thetatf)); - /* dPt_dVmf */ - val[3] = Vmt * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - - /* dQt_dthetat */ - val[4] = Vmt * Vmf * (Btf * sin(thetatf) + Gtf * cos(thetatf)); - /* dQt_dVmt */ - val[5] = - -2 * Btt * Vmt + Vmf * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - /* dQt_dthetaf */ - val[6] = Vmt * Vmf * (-Btf * sin(thetatf) - Gtf * cos(thetatf)); - /* dQt_dVmf */ - val[7] = Vmt * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - ierr = MatSetValues(Je, 2, row, 4, col, val, ADD_VALUES); - CHKERRQ(ierr); + if (!line->isdcline) { + Gff = line->yff[0]; + Bff = line->yff[1]; + Gft = line->yft[0]; + Bft = line->yft[1]; + Gtf = line->ytf[0]; + Btf = line->ytf[1]; + Gtt = line->ytt[0]; + Btt = line->ytt[1]; + + locf = busf->startxVloc; + loct = bust->startxVloc; + + locglobf = busf->startxVlocglob; + locglobt = bust->startxVlocglob; + + thetaf = xarr[locf]; + Vmf = xarr[locf + 1]; + thetat = xarr[loct]; + Vmt = xarr[loct + 1]; + thetaft = thetaf - thetat; + thetatf = thetat - thetaf; + sin_thetaft = sin(thetaft); + cos_thetaft = cos(thetaft); + sin_thetatf = sin(thetatf); + cos_thetatf = cos(thetatf); + + if (bus == busf) { + col[0] = locglobf; + col[1] = locglobf + 1; + col[2] = locglobt; + col[3] = locglobt + 1; + /* dPf_dthetaf */ + val[0] = Vmf * Vmt * (-Gft * sin_thetaft + Bft * cos_thetaft); + /*dPf_dVmf */ + val[1] = + 2 * Gff * Vmf + Vmt * (Gft * cos_thetaft + Bft * sin_thetaft); + /*dPf_dthetat */ + val[2] = Vmf * Vmt * (Gft * sin_thetaft - Bft * cos_thetaft); + /* dPf_dVmt */ + val[3] = Vmf * (Gft * cos_thetaft + Bft * sin_thetaft); + + /* dQf_dthetaf */ + val[4] = Vmf * Vmt * (Bft * sin_thetaft + Gft * cos_thetaft); + /* dQf_dVmf */ + val[5] = + -2 * Bff * Vmf + Vmt * (-Bft * cos_thetaft + Gft * sin_thetaft); + /* dQf_dthetat */ + val[6] = Vmf * Vmt * (-Bft * sin_thetaft - Gft * cos_thetaft); + /* dQf_dVmt */ + val[7] = Vmf * (-Bft * cos_thetaft + Gft * sin_thetaft); + ierr = MatSetValues(Je, 2, row, 4, col, val, ADD_VALUES); + CHKERRQ(ierr); + } else { + col[0] = locglobt; + col[1] = locglobt + 1; + col[2] = locglobf; + col[3] = locglobf + 1; + /* dPt_dthetat */ + val[0] = Vmt * Vmf * (-Gtf * sin_thetatf + Btf * cos_thetatf); + /* dPt_dVmt */ + val[1] = + 2 * Gtt * Vmt + Vmf * (Gtf * cos_thetatf + Btf * sin_thetatf); + /* dPt_dthetaf */ + val[2] = Vmt * Vmf * (Gtf * sin_thetatf - Btf * cos_thetatf); + /* dPt_dVmf */ + val[3] = Vmt * (Gtf * cos_thetatf + Btf * sin_thetatf); + + /* dQt_dthetat */ + val[4] = Vmt * Vmf * (Btf * sin_thetatf + Gtf * cos_thetatf); + /* dQt_dVmt */ + val[5] = + -2 * Btt * Vmt + Vmf * (-Btf * cos_thetatf + Gtf * sin_thetatf); + /* dQt_dthetaf */ + val[6] = Vmt * Vmf * (-Btf * sin_thetatf - Gtf * cos_thetatf); + /* dQt_dVmf */ + val[7] = Vmt * (-Btf * cos_thetatf + Gtf * sin_thetatf); + ierr = MatSetValues(Je, 2, row, 4, col, val, ADD_VALUES); + CHKERRQ(ierr); + } + } else if (line->isdcline) { + if (bus == busf) { + col[0] = line->startxdcloc; + val[0] = 1.0; + ierr = MatSetValues(Je, 1, row, 1, col, val, ADD_VALUES); + + col[0] = line->startxdcloc + 1; + val[0] = 1.0; + ierr = MatSetValues(Je, 1, row + 1, 1, col, val, ADD_VALUES); + } else { + col[0] = line->startxdcloc; + val[0] = -(1.0 - line->loss1); + ierr = MatSetValues(Je, 1, row, 1, col, val, ADD_VALUES); + + col[0] = line->startxdcloc + 2; + val[0] = -1.0; + ierr = MatSetValues(Je, 1, row + 1, 1, col, val, ADD_VALUES); + } } } flps += nconnlines * @@ -891,6 +993,7 @@ PetscErrorCode OPFLOWComputeInequalityConstraints_PBPOL(OPFLOW opflow, Vec X, PetscScalar *g; PetscScalar Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt; PetscScalar Vmf, Vmt, thetaf, thetat, thetaft, thetatf; + PetscScalar sin_thetaft, cos_thetaft, sin_thetatf, cos_thetatf; PetscScalar Pf, Qf, Pt, Qt, Sf2, St2; PS ps = opflow->ps; PSLINE line; @@ -972,66 +1075,68 @@ PetscErrorCode OPFLOWComputeInequalityConstraints_PBPOL(OPFLOW opflow, Vec X, } } - if (!opflow->ignore_lineflow_constraints) { - for (i = 0; i < opflow->nlinesmon; i++) { - line = &ps->line[opflow->linesmon[i]]; + for (i = 0; i < opflow->nlinesmon; i++) { + line = &ps->line[opflow->linesmon[i]]; - gloc = line->startineqloc; + if (line->isdcline) + continue; - Gff = line->yff[0]; - Bff = line->yff[1]; - Gft = line->yft[0]; - Bft = line->yft[1]; - Gtf = line->ytf[0]; - Btf = line->ytf[1]; - Gtt = line->ytt[0]; - Btt = line->ytt[1]; + gloc = line->startineqloc; - ierr = PSLINEGetConnectedBuses(line, &connbuses); - CHKERRQ(ierr); - busf = connbuses[0]; - bust = connbuses[1]; + Gff = line->yff[0]; + Bff = line->yff[1]; + Gft = line->yft[0]; + Bft = line->yft[1]; + Gtf = line->ytf[0]; + Btf = line->ytf[1]; + Gtt = line->ytt[0]; + Btt = line->ytt[1]; - xlocf = busf->startxVloc; - xloct = bust->startxVloc; + ierr = PSLINEGetConnectedBuses(line, &connbuses); + CHKERRQ(ierr); + busf = connbuses[0]; + bust = connbuses[1]; - thetaf = x[xlocf]; - Vmf = x[xlocf + 1]; - thetat = x[xloct]; - Vmt = x[xloct + 1]; - thetaft = thetaf - thetat; - thetatf = thetat - thetaf; + xlocf = busf->startxVloc; + xloct = bust->startxVloc; - Pf = Gff * Vmf * Vmf + - Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - Qf = -Bff * Vmf * Vmf + - Vmf * Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); + thetaf = x[xlocf]; + Vmf = x[xlocf + 1]; + thetat = x[xloct]; + Vmt = x[xloct + 1]; + thetaft = thetaf - thetat; + thetatf = thetat - thetaf; + sin_thetaft = sin(thetaft); + cos_thetaft = cos(thetaft); + sin_thetatf = sin(thetatf); + cos_thetatf = cos(thetatf); - Pt = Gtt * Vmt * Vmt + - Vmt * Vmf * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - Qt = -Btt * Vmt * Vmt + - Vmt * Vmf * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); + Pf = Gff * Vmf * Vmf + Vmf * Vmt * (Gft * cos_thetaft + Bft * sin_thetaft); + Qf = + -Bff * Vmf * Vmf + Vmf * Vmt * (-Bft * cos_thetaft + Gft * sin_thetaft); - Sf2 = Pf * Pf + Qf * Qf; - St2 = Pt * Pt + Qt * Qt; + Pt = Gtt * Vmt * Vmt + Vmt * Vmf * (Gtf * cos_thetatf + Btf * sin_thetatf); + Qt = + -Btt * Vmt * Vmt + Vmt * Vmf * (-Btf * cos_thetatf + Gtf * sin_thetatf); - g[gloc] = Sf2; - g[gloc + 1] = St2; + Sf2 = Pf * Pf + Qf * Qf; + St2 = Pt * Pt + Qt * Qt; - if (opflow->allow_lineflow_violation) { - PetscInt loc; - PetscScalar xsft_slack = 0.0, xstf_slack = 0.0; - loc = line->startxslackloc; - // Slack variables for from and to side - xsft_slack = x[loc]; - xstf_slack = x[loc + 1]; + g[gloc] = Sf2; + g[gloc + 1] = St2; - g[gloc] -= xsft_slack; - g[gloc + 1] -= xstf_slack; - } + if (opflow->allow_lineflow_violation) { + PetscInt loc; + PetscScalar xsft_slack = 0.0, xstf_slack = 0.0; + loc = line->startxslackloc; + // Slack variables for from and to side + xsft_slack = x[loc]; + xstf_slack = x[loc + 1]; - flps += 160.0; + g[gloc] -= xsft_slack; + g[gloc + 1] -= xstf_slack; } + flps += 160.0; } ierr = VecRestoreArrayRead(X, &x); @@ -1053,6 +1158,7 @@ PetscErrorCode OPFLOWComputeInequalityConstraintJacobian_PBPOL(OPFLOW opflow, PetscScalar val[4]; PetscScalar Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt; PetscScalar Vmf, Vmt, thetaf, thetat, thetaft, thetatf; + PetscScalar sin_thetaft, cos_thetaft, sin_thetatf, cos_thetatf; PetscScalar Pf, Qf, Pt, Qt; PetscScalar dSf2_dPf, dSf2_dQf, dSt2_dPt, dSt2_dQt; PetscScalar dPf_dthetaf, dPf_dVmf, dPf_dthetat, dPf_dVmt; @@ -1171,129 +1277,129 @@ PetscErrorCode OPFLOWComputeInequalityConstraintJacobian_PBPOL(OPFLOW opflow, } } - if (!opflow->ignore_lineflow_constraints) { - for (i = 0; i < opflow->nlinesmon; i++) { - line = &ps->line[opflow->linesmon[i]]; + for (i = 0; i < opflow->nlinesmon; i++) { + line = &ps->line[opflow->linesmon[i]]; - gloc = line->startineqloc; + if (line->isdcline) + continue; - Gff = line->yff[0]; - Bff = line->yff[1]; - Gft = line->yft[0]; - Bft = line->yft[1]; - Gtf = line->ytf[0]; - Btf = line->ytf[1]; - Gtt = line->ytt[0]; - Btt = line->ytt[1]; + gloc = line->startineqloc; - ierr = PSLINEGetConnectedBuses(line, &connbuses); - CHKERRQ(ierr); - busf = connbuses[0]; - bust = connbuses[1]; + Gff = line->yff[0]; + Bff = line->yff[1]; + Gft = line->yft[0]; + Bft = line->yft[1]; + Gtf = line->ytf[0]; + Btf = line->ytf[1]; + Gtt = line->ytt[0]; + Btt = line->ytt[1]; - xlocf = busf->startxVloc; - xloct = bust->startxVloc; + ierr = PSLINEGetConnectedBuses(line, &connbuses); + CHKERRQ(ierr); + busf = connbuses[0]; + bust = connbuses[1]; - thetaf = x[xlocf]; - Vmf = x[xlocf + 1]; - thetat = x[xloct]; - Vmt = x[xloct + 1]; - thetaft = thetaf - thetat; - thetatf = thetat - thetaf; + xlocf = busf->startxVloc; + xloct = bust->startxVloc; - Pf = Gff * Vmf * Vmf + - Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - Qf = -Bff * Vmf * Vmf + - Vmf * Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); + thetaf = x[xlocf]; + Vmf = x[xlocf + 1]; + thetat = x[xloct]; + Vmt = x[xloct + 1]; + thetaft = thetaf - thetat; + thetatf = thetat - thetaf; + sin_thetaft = sin(thetaft); + cos_thetaft = cos(thetaft); + sin_thetatf = sin(thetatf); + cos_thetatf = cos(thetatf); + + Pf = Gff * Vmf * Vmf + Vmf * Vmt * (Gft * cos_thetaft + Bft * sin_thetaft); + Qf = + -Bff * Vmf * Vmf + Vmf * Vmt * (-Bft * cos_thetaft + Gft * sin_thetaft); + + Pt = Gtt * Vmt * Vmt + Vmt * Vmf * (Gtf * cos_thetatf + Btf * sin_thetatf); + Qt = + -Btt * Vmt * Vmt + Vmt * Vmf * (-Btf * cos_thetatf + Gtf * sin_thetatf); + + dSf2_dPf = 2 * Pf; + dSf2_dQf = 2 * Qf; + dSt2_dPt = 2 * Pt; + dSt2_dQt = 2 * Qt; + + dPf_dthetaf = Vmf * Vmt * (-Gft * sin_thetaft + Bft * cos_thetaft); + dPf_dVmf = 2 * Gff * Vmf + Vmt * (Gft * cos_thetaft + Bft * sin_thetaft); + dPf_dthetat = Vmf * Vmt * (Gft * sin_thetaft - Bft * cos_thetaft); + dPf_dVmt = Vmf * (Gft * cos_thetaft + Bft * sin_thetaft); + + dQf_dthetaf = Vmf * Vmt * (Bft * sin_thetaft + Gft * cos_thetaft); + dQf_dVmf = -2 * Bff * Vmf + Vmt * (-Bft * cos_thetaft + Gft * sin_thetaft); + dQf_dthetat = Vmf * Vmt * (-Bft * sin_thetaft - Gft * cos_thetaft); + dQf_dVmt = Vmf * (-Bft * cos_thetaft + Gft * sin_thetaft); + + dPt_dthetat = Vmt * Vmf * (-Gtf * sin_thetatf + Btf * cos_thetatf); + dPt_dVmt = 2 * Gtt * Vmt + Vmf * (Gtf * cos_thetatf + Btf * sin_thetatf); + dPt_dthetaf = Vmt * Vmf * (Gtf * sin_thetatf - Btf * cos_thetatf); + dPt_dVmf = Vmt * (Gtf * cos_thetatf + Btf * sin_thetatf); + + dQt_dthetat = Vmt * Vmf * (Btf * sin_thetatf + Gtf * cos_thetatf); + dQt_dVmt = -2 * Btt * Vmt + Vmf * (-Btf * cos_thetatf + Gtf * sin_thetatf); + dQt_dthetaf = Vmt * Vmf * (-Btf * sin_thetatf - Gtf * cos_thetatf); + dQt_dVmf = Vmt * (-Btf * cos_thetatf + Gtf * sin_thetatf); + + dSf2_dthetaf = dSf2_dPf * dPf_dthetaf + dSf2_dQf * dQf_dthetaf; + dSf2_dthetat = dSf2_dPf * dPf_dthetat + dSf2_dQf * dQf_dthetat; + dSf2_dVmf = dSf2_dPf * dPf_dVmf + dSf2_dQf * dQf_dVmf; + dSf2_dVmt = dSf2_dPf * dPf_dVmt + dSf2_dQf * dQf_dVmt; - Pt = Gtt * Vmt * Vmt + - Vmt * Vmf * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - Qt = -Btt * Vmt * Vmt + - Vmt * Vmf * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - - dSf2_dPf = 2 * Pf; - dSf2_dQf = 2 * Qf; - dSt2_dPt = 2 * Pt; - dSt2_dQt = 2 * Qt; - - dPf_dthetaf = Vmf * Vmt * (-Gft * sin(thetaft) + Bft * cos(thetaft)); - dPf_dVmf = - 2 * Gff * Vmf + Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - dPf_dthetat = Vmf * Vmt * (Gft * sin(thetaft) - Bft * cos(thetaft)); - dPf_dVmt = Vmf * (Gft * cos(thetaft) + Bft * sin(thetaft)); - - dQf_dthetaf = Vmf * Vmt * (Bft * sin(thetaft) + Gft * cos(thetaft)); - dQf_dVmf = - -2 * Bff * Vmf + Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); - dQf_dthetat = Vmf * Vmt * (-Bft * sin(thetaft) - Gft * cos(thetaft)); - dQf_dVmt = Vmf * (-Bft * cos(thetaft) + Gft * sin(thetaft)); - - dPt_dthetat = Vmt * Vmf * (-Gtf * sin(thetatf) + Btf * cos(thetatf)); - dPt_dVmt = - 2 * Gtt * Vmt + Vmf * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - dPt_dthetaf = Vmt * Vmf * (Gtf * sin(thetatf) - Btf * cos(thetatf)); - dPt_dVmf = Vmt * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - - dQt_dthetat = Vmt * Vmf * (Btf * sin(thetatf) + Gtf * cos(thetatf)); - dQt_dVmt = - -2 * Btt * Vmt + Vmf * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - dQt_dthetaf = Vmt * Vmf * (-Btf * sin(thetatf) - Gtf * cos(thetatf)); - dQt_dVmf = Vmt * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - - dSf2_dthetaf = dSf2_dPf * dPf_dthetaf + dSf2_dQf * dQf_dthetaf; - dSf2_dthetat = dSf2_dPf * dPf_dthetat + dSf2_dQf * dQf_dthetat; - dSf2_dVmf = dSf2_dPf * dPf_dVmf + dSf2_dQf * dQf_dVmf; - dSf2_dVmt = dSf2_dPf * dPf_dVmt + dSf2_dQf * dQf_dVmt; + row[0] = gloc; + col[0] = xlocf; + col[1] = xlocf + 1; + col[2] = xloct; + col[3] = xloct + 1; + val[0] = dSf2_dthetaf; + val[1] = dSf2_dVmf; + val[2] = dSf2_dthetat; + val[3] = dSf2_dVmt; + ierr = MatSetValues(Ji, 1, row, 4, col, val, ADD_VALUES); + CHKERRQ(ierr); - row[0] = gloc; - col[0] = xlocf; - col[1] = xlocf + 1; - col[2] = xloct; - col[3] = xloct + 1; - val[0] = dSf2_dthetaf; - val[1] = dSf2_dVmf; - val[2] = dSf2_dthetat; - val[3] = dSf2_dVmt; - ierr = MatSetValues(Ji, 1, row, 4, col, val, ADD_VALUES); - CHKERRQ(ierr); + dSt2_dthetaf = dSt2_dPt * dPt_dthetaf + dSt2_dQt * dQt_dthetaf; + dSt2_dthetat = dSt2_dPt * dPt_dthetat + dSt2_dQt * dQt_dthetat; + dSt2_dVmf = dSt2_dPt * dPt_dVmf + dSt2_dQt * dQt_dVmf; + dSt2_dVmt = dSt2_dPt * dPt_dVmt + dSt2_dQt * dQt_dVmt; + + row[0] = gloc + 1; + col[0] = xloct; + col[1] = xloct + 1; + col[2] = xlocf; + col[3] = xlocf + 1; + val[0] = dSt2_dthetat; + val[1] = dSt2_dVmt; + val[2] = dSt2_dthetaf; + val[3] = dSt2_dVmf; + ierr = MatSetValues(Ji, 1, row, 4, col, val, ADD_VALUES); + CHKERRQ(ierr); - dSt2_dthetaf = dSt2_dPt * dPt_dthetaf + dSt2_dQt * dQt_dthetaf; - dSt2_dthetat = dSt2_dPt * dPt_dthetat + dSt2_dQt * dQt_dthetat; - dSt2_dVmf = dSt2_dPt * dPt_dVmf + dSt2_dQt * dQt_dVmf; - dSt2_dVmt = dSt2_dPt * dPt_dVmt + dSt2_dQt * dQt_dVmt; + if (!line->isdcline && opflow->allow_lineflow_violation) { + loc = line->startxslackloc; + row[0] = gloc; + col[0] = loc; + val[0] = -1.0; - row[0] = gloc + 1; - col[0] = xloct; - col[1] = xloct + 1; - col[2] = xlocf; - col[3] = xlocf + 1; - val[0] = dSt2_dthetat; - val[1] = dSt2_dVmt; - val[2] = dSt2_dthetaf; - val[3] = dSt2_dVmf; - ierr = MatSetValues(Ji, 1, row, 4, col, val, ADD_VALUES); + ierr = MatSetValues(Ji, 1, row, 1, col, val, ADD_VALUES); CHKERRQ(ierr); - if (opflow->allow_lineflow_violation) { - loc = line->startxslackloc; - row[0] = gloc; - col[0] = loc; - val[0] = -1.0; - - ierr = MatSetValues(Ji, 1, row, 1, col, val, ADD_VALUES); - CHKERRQ(ierr); - - row[0] = gloc + 1; - col[0] = loc + 1; - val[0] = -1.0; + row[0] = gloc + 1; + col[0] = loc + 1; + val[0] = -1.0; - ierr = MatSetValues(Ji, 1, row, 1, col, val, ADD_VALUES); - CHKERRQ(ierr); - } + ierr = MatSetValues(Ji, 1, row, 1, col, val, ADD_VALUES); + CHKERRQ(ierr); } - flps += opflow->nlinesmon * - (160 + (20 * EXAGO_FLOPS_SINOP) + (20 * EXAGO_FLOPS_COSOP)); } + flps += opflow->nlinesmon * + (160 + (20 * EXAGO_FLOPS_SINOP) + (20 * EXAGO_FLOPS_COSOP)); + ierr = VecRestoreArrayRead(X, &x); CHKERRQ(ierr); @@ -1337,8 +1443,13 @@ PetscErrorCode OPFLOWComputeObjective_PBPOL(OPFLOW opflow, Vec X, *obj = 0.0; - for (i = 0; i < opflow->nlinesmon; i++) { - line = &ps->line[opflow->linesmon[i]]; + for (i = 0; i < ps->nline; i++) { + line = &ps->line[i]; + if (!line->status) + continue; + + if (line->isdcline) + continue; if (opflow->allow_lineflow_violation) { loc = line->startxslackloc; // Slack variables for from and to side @@ -1377,6 +1488,7 @@ PetscErrorCode OPFLOWComputeObjective_PBPOL(OPFLOW opflow, Vec X, if (opflow->objectivetype == MIN_GEN_COST) { loc = gen->startxpowloc; Pg = x[loc] * ps->MVAbase; + *obj += gen->cost_alpha * Pg * Pg + gen->cost_beta * Pg + gen->cost_gamma; flps += 7.0; @@ -1436,15 +1548,17 @@ PetscErrorCode OPFLOWComputeGradient_PBPOL(OPFLOW opflow, Vec X, Vec grad) { ierr = VecGetArray(grad, &df); CHKERRQ(ierr); - for (i = 0; i < opflow->nlinesmon; i++) { - line = &ps->line[opflow->linesmon[i]]; + for (i = 0; i < ps->nline; i++) { + line = &ps->line[i]; + if (!line->status) + continue; + + if (line->isdcline) + continue; if (opflow->allow_lineflow_violation) { loc = line->startxslackloc; - // ADD GRADIENT HERE df[loc] = opflow->lineflowviolation_penalty; df[loc + 1] = opflow->lineflowviolation_penalty; - - flps += 0.0; } } @@ -1537,24 +1651,31 @@ PetscErrorCode OPFLOWModelSetNumVariables_PBPOL(OPFLOW opflow, PSLINE line; PetscErrorCode ierr; PetscBool isghost; - PetscInt idx; PetscFunctionBegin; *nx = 0; - /* No variables for the branches */ - for (i = 0; i < opflow->nlinesmon; i++) { - idx = opflow->linesmon[i]; - line = &ps->line[idx]; - branchnvar[idx] = line->nx = 0; - if (opflow->allow_lineflow_violation) { - /* Two variables for line flow slacks - - From side flow (Sft) and To side flow (Stf) - */ - branchnvar[idx] += 2; - line->nx += 2; + + /* Variables for the lines */ + for (i = 0; i < ps->nline; i++) { + line = &ps->line[i]; + if (!line->status) + continue; + + if (line->isdcline) { + branchnvar[i] = line->nx = 3; + } else { + branchnvar[i] = line->nx = 0; + if (opflow->allow_lineflow_violation) { + /* Two variables for line flow slacks + - From side flow (Sft) and To side flow (Stf) + */ + branchnvar[i] += 2; + line->nx += 2; + } } - *nx += branchnvar[idx]; + + *nx += branchnvar[i]; } /* Variables for the buses */ @@ -1682,13 +1803,15 @@ PetscErrorCode OPFLOWModelSetNumConstraints_PBPOL(OPFLOW opflow, } } - if (!opflow->ignore_lineflow_constraints) { - for (i = 0; i < opflow->nlinesmon; i++) { - line = &ps->line[opflow->linesmon[i]]; + for (i = 0; i < opflow->nlinesmon; i++) { + line = &ps->line[opflow->linesmon[i]]; + if (!line->isdcline) { *nconineq += 2; /* Number of line flow constraints */ line->nconineq = 2; line->nconeq = 0; + } else if (line->isdcline) { + line->nconeq = line->nconineq = 0; } } @@ -1726,6 +1849,7 @@ PetscErrorCode OPFLOWComputeEqualityConstraintsHessian_PBPOL(OPFLOW opflow, PetscInt gloc; PetscInt row[16], col[16]; PetscScalar val[16]; + PetscScalar lambda_gloc, lambda_gloc1; PetscFunctionBegin; @@ -1745,7 +1869,10 @@ PetscErrorCode OPFLOWComputeEqualityConstraintsHessian_PBPOL(OPFLOW opflow, row[0] = xloc + 1; col[0] = xloc + 1; - val[0] = lambda[gloc] * 2 * bus->gl + lambda[gloc + 1] * (-2 * bus->bl); + lambda_gloc = lambda[gloc]; + lambda_gloc1 = lambda[gloc + 1]; + + val[0] = lambda_gloc * 2 * bus->gl + lambda_gloc1 * (-2 * bus->bl); ierr = MatSetValues(H, 1, row, 1, col, val, ADD_VALUES); CHKERRQ(ierr); @@ -1777,6 +1904,7 @@ PetscErrorCode OPFLOWComputeEqualityConstraintsHessian_PBPOL(OPFLOW opflow, xloct = bust->startxVloc; PetscScalar Vmf, Vmt, thetaf, thetat, thetaft, thetatf; + PetscScalar sin_thetaft, cos_thetaft, sin_thetatf, cos_thetatf; thetaf = x[xlocf]; Vmf = x[xlocf + 1]; @@ -1784,6 +1912,10 @@ PetscErrorCode OPFLOWComputeEqualityConstraintsHessian_PBPOL(OPFLOW opflow, Vmt = x[xloct + 1]; thetaft = thetaf - thetat; thetatf = thetat - thetaf; + sin_thetaft = sin(thetaft); + cos_thetaft = cos(thetaft); + sin_thetatf = sin(thetatf); + cos_thetatf = cos(thetatf); if (bus == busf) { @@ -1796,32 +1928,32 @@ PetscErrorCode OPFLOWComputeEqualityConstraintsHessian_PBPOL(OPFLOW opflow, PetscScalar dPf_dVmt_dthetaf, dPf_dVmt_dVmf, dPf_dVmt_dthetat, dPf_dVmt_dVmt; - /* dPf_dthetaf = Vmf*Vmt*(-Gft*sin(thetaft) + Bft*cos(thetaft)); */ + /* dPf_dthetaf = Vmf*Vmt*(-Gft*sin_thetaft + Bft*cos_thetaft); */ dPf_dthetaf_dthetaf = - -Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - dPf_dthetaf_dVmf = Vmt * (-Gft * sin(thetaft) + Bft * cos(thetaft)); + -Vmf * Vmt * (Gft * cos_thetaft + Bft * sin_thetaft); + dPf_dthetaf_dVmf = Vmt * (-Gft * sin_thetaft + Bft * cos_thetaft); dPf_dthetaf_dthetat = - Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - dPf_dthetaf_dVmt = Vmf * (-Gft * sin(thetaft) + Bft * cos(thetaft)); + Vmf * Vmt * (Gft * cos_thetaft + Bft * sin_thetaft); + dPf_dthetaf_dVmt = Vmf * (-Gft * sin_thetaft + Bft * cos_thetaft); - /* dPf_Vmf = 2*Gff*Vmf + Vmt*(Gft*cos(thetaft) + Bft*sin(thetaft)); */ - dPf_dVmf_dthetaf = Vmt * (-Gft * sin(thetaft) + Bft * cos(thetaft)); + /* dPf_Vmf = 2*Gff*Vmf + Vmt*(Gft*cos_thetaft + Bft*sin_thetaft); */ + dPf_dVmf_dthetaf = Vmt * (-Gft * sin_thetaft + Bft * cos_thetaft); dPf_dVmf_dVmf = 2 * Gff; - dPf_dVmf_dthetat = Vmt * (Gft * sin(thetaft) - Bft * cos(thetaft)); - dPf_dVmf_dVmt = (Gft * cos(thetaft) + Bft * sin(thetaft)); + dPf_dVmf_dthetat = Vmt * (Gft * sin_thetaft - Bft * cos_thetaft); + dPf_dVmf_dVmt = (Gft * cos_thetaft + Bft * sin_thetaft); - /* dPf_dthetat = Vmf*Vmt*(Gft*sin(thetaft) - Bft*cos(thetaft)); */ + /* dPf_dthetat = Vmf*Vmt*(Gft*sin_thetaft - Bft*cos_thetaft); */ dPf_dthetat_dthetaf = - Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - dPf_dthetat_dVmf = Vmt * (Gft * sin(thetaft) - Bft * cos(thetaft)); + Vmf * Vmt * (Gft * cos_thetaft + Bft * sin_thetaft); + dPf_dthetat_dVmf = Vmt * (Gft * sin_thetaft - Bft * cos_thetaft); dPf_dthetat_dthetat = - Vmf * Vmt * (-Gft * cos(thetaft) - Bft * sin(thetaft)); - dPf_dthetat_dVmt = Vmf * (Gft * sin(thetaft) - Bft * cos(thetaft)); + Vmf * Vmt * (-Gft * cos_thetaft - Bft * sin_thetaft); + dPf_dthetat_dVmt = Vmf * (Gft * sin_thetaft - Bft * cos_thetaft); - /* dPf_dVmt = Vmf*(Gft*cos(thetaft) + Bft*sin(thetaft)); */ - dPf_dVmt_dthetaf = Vmf * (-Gft * sin(thetaft) + Bft * cos(thetaft)); - dPf_dVmt_dVmf = (Gft * cos(thetaft) + Bft * sin(thetaft)); - dPf_dVmt_dthetat = Vmf * (Gft * sin(thetaft) - Bft * cos(thetaft)); + /* dPf_dVmt = Vmf*(Gft*cos_thetaft + Bft*sin_thetaft); */ + dPf_dVmt_dthetaf = Vmf * (-Gft * sin_thetaft + Bft * cos_thetaft); + dPf_dVmt_dVmf = (Gft * cos_thetaft + Bft * sin_thetaft); + dPf_dVmt_dthetat = Vmf * (Gft * sin_thetaft - Bft * cos_thetaft); dPf_dVmt_dVmt = 0.0; PetscScalar dQf_dthetaf_dthetaf, dQf_dthetaf_dVmf, dQf_dthetaf_dthetat, @@ -1833,33 +1965,33 @@ PetscErrorCode OPFLOWComputeEqualityConstraintsHessian_PBPOL(OPFLOW opflow, PetscScalar dQf_dVmt_dthetaf, dQf_dVmt_dVmf, dQf_dVmt_dthetat, dQf_dVmt_dVmt; - /* dQf_dthetaf = Vmf*Vmt*(Bft*sin(thetaft) + Gft*cos(thetaft)); */ + /* dQf_dthetaf = Vmf*Vmt*(Bft*sin_thetaft + Gft*cos_thetaft); */ dQf_dthetaf_dthetaf = - Vmf * Vmt * (Bft * cos(thetaft) - Gft * sin(thetaft)); - dQf_dthetaf_dVmf = Vmt * (Bft * sin(thetaft) + Gft * cos(thetaft)); + Vmf * Vmt * (Bft * cos_thetaft - Gft * sin_thetaft); + dQf_dthetaf_dVmf = Vmt * (Bft * sin_thetaft + Gft * cos_thetaft); dQf_dthetaf_dthetat = - Vmf * Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); - dQf_dthetaf_dVmt = Vmf * (Bft * sin(thetaft) + Gft * cos(thetaft)); + Vmf * Vmt * (-Bft * cos_thetaft + Gft * sin_thetaft); + dQf_dthetaf_dVmt = Vmf * (Bft * sin_thetaft + Gft * cos_thetaft); - /* dQf_dVmf = -2*Bff*Vmf + Vmt*(-Bft*cos(thetaft) + Gft*sin(thetaft)); + /* dQf_dVmf = -2*Bff*Vmf + Vmt*(-Bft*cos_thetaft + Gft*sin_thetaft); */ - dQf_dVmf_dthetaf = Vmt * (Bft * sin(thetaft) + Gft * cos(thetaft)); + dQf_dVmf_dthetaf = Vmt * (Bft * sin_thetaft + Gft * cos_thetaft); dQf_dVmf_dVmf = -2 * Bff; - dQf_dVmf_dthetat = Vmt * (-Bft * sin(thetaft) - Gft * cos(thetaft)); - dQf_dVmf_dVmt = (-Bft * cos(thetaft) + Gft * sin(thetaft)); + dQf_dVmf_dthetat = Vmt * (-Bft * sin_thetaft - Gft * cos_thetaft); + dQf_dVmf_dVmt = (-Bft * cos_thetaft + Gft * sin_thetaft); - /* dQf_dthetat = Vmf*Vmt*(-Bft*sin(thetaft) - Gft*cos(thetaft)); */ + /* dQf_dthetat = Vmf*Vmt*(-Bft*sin_thetaft - Gft*cos_thetaft); */ dQf_dthetat_dthetaf = - Vmf * Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); - dQf_dthetat_dVmf = Vmt * (-Bft * sin(thetaft) - Gft * cos(thetaft)); + Vmf * Vmt * (-Bft * cos_thetaft + Gft * sin_thetaft); + dQf_dthetat_dVmf = Vmt * (-Bft * sin_thetaft - Gft * cos_thetaft); dQf_dthetat_dthetat = - Vmf * Vmt * (Bft * cos(thetaft) - Gft * sin(thetaft)); - dQf_dthetat_dVmt = Vmf * (-Bft * sin(thetaft) - Gft * cos(thetaft)); + Vmf * Vmt * (Bft * cos_thetaft - Gft * sin_thetaft); + dQf_dthetat_dVmt = Vmf * (-Bft * sin_thetaft - Gft * cos_thetaft); - /* dQf_dVmt = Vmf*(-Bft*cos(thetaft) + Gft*sin(thetaft)); */ - dQf_dVmt_dthetaf = Vmf * (Bft * sin(thetaft) + Gft * cos(thetaft)); - dQf_dVmt_dVmf = (-Bft * cos(thetaft) + Gft * sin(thetaft)); - dQf_dVmt_dthetat = Vmf * (-Bft * sin(thetaft) - Gft * cos(thetaft)); + /* dQf_dVmt = Vmf*(-Bft*cos_thetaft + Gft*sin_thetaft); */ + dQf_dVmt_dthetaf = Vmf * (Bft * sin_thetaft + Gft * cos_thetaft); + dQf_dVmt_dVmf = (-Bft * cos_thetaft + Gft * sin_thetaft); + dQf_dVmt_dthetat = Vmf * (-Bft * sin_thetaft - Gft * cos_thetaft); dQf_dVmt_dVmt = 0.0; row[0] = xlocf; @@ -1872,23 +2004,21 @@ PetscErrorCode OPFLOWComputeEqualityConstraintsHessian_PBPOL(OPFLOW opflow, val[0] = val[1] = val[2] = val[3] = val[4] = val[5] = val[6] = val[7] = 0.0; - val[0] = lambda[gloc] * dPf_dthetaf_dthetaf + - lambda[gloc + 1] * dQf_dthetaf_dthetaf; - val[1] = lambda[gloc] * dPf_dthetaf_dVmf + - lambda[gloc + 1] * dQf_dthetaf_dVmf; - val[2] = lambda[gloc] * dPf_dthetaf_dthetat + - lambda[gloc + 1] * dQf_dthetaf_dthetat; - val[3] = lambda[gloc] * dPf_dthetaf_dVmt + - lambda[gloc + 1] * dQf_dthetaf_dVmt; - - val[4] = lambda[gloc] * dPf_dVmf_dthetaf + - lambda[gloc + 1] * dQf_dVmf_dthetaf; - val[5] = - lambda[gloc] * dPf_dVmf_dVmf + lambda[gloc + 1] * dQf_dVmf_dVmf; - val[6] = lambda[gloc] * dPf_dVmf_dthetat + - lambda[gloc + 1] * dQf_dVmf_dthetat; - val[7] = - lambda[gloc] * dPf_dVmf_dVmt + lambda[gloc + 1] * dQf_dVmf_dVmt; + val[0] = lambda_gloc * dPf_dthetaf_dthetaf + + lambda_gloc1 * dQf_dthetaf_dthetaf; + val[1] = + lambda_gloc * dPf_dthetaf_dVmf + lambda_gloc1 * dQf_dthetaf_dVmf; + val[2] = lambda_gloc * dPf_dthetaf_dthetat + + lambda_gloc1 * dQf_dthetaf_dthetat; + val[3] = + lambda_gloc * dPf_dthetaf_dVmt + lambda_gloc1 * dQf_dthetaf_dVmt; + + val[4] = + lambda_gloc * dPf_dVmf_dthetaf + lambda_gloc1 * dQf_dVmf_dthetaf; + val[5] = lambda_gloc * dPf_dVmf_dVmf + lambda_gloc1 * dQf_dVmf_dVmf; + val[6] = + lambda_gloc * dPf_dVmf_dthetat + lambda_gloc1 * dQf_dVmf_dthetat; + val[7] = lambda_gloc * dPf_dVmf_dVmt + lambda_gloc1 * dQf_dVmf_dVmt; ierr = MatSetValues(H, 2, row, 4, col, val, ADD_VALUES); CHKERRQ(ierr); @@ -1903,23 +2033,21 @@ PetscErrorCode OPFLOWComputeEqualityConstraintsHessian_PBPOL(OPFLOW opflow, val[0] = val[1] = val[2] = val[3] = val[4] = val[5] = val[6] = val[7] = 0.0; - val[0] = lambda[gloc] * dPf_dthetat_dthetaf + - lambda[gloc + 1] * dQf_dthetat_dthetaf; - val[1] = lambda[gloc] * dPf_dthetat_dVmf + - lambda[gloc + 1] * dQf_dthetat_dVmf; - val[2] = lambda[gloc] * dPf_dthetat_dthetat + - lambda[gloc + 1] * dQf_dthetat_dthetat; - val[3] = lambda[gloc] * dPf_dthetat_dVmt + - lambda[gloc + 1] * dQf_dthetat_dVmt; - - val[4] = lambda[gloc] * dPf_dVmt_dthetaf + - lambda[gloc + 1] * dQf_dVmt_dthetaf; - val[5] = - lambda[gloc] * dPf_dVmt_dVmf + lambda[gloc + 1] * dQf_dVmt_dVmf; - val[6] = lambda[gloc] * dPf_dVmt_dthetat + - lambda[gloc + 1] * dQf_dVmt_dthetat; - val[7] = - lambda[gloc] * dPf_dVmt_dVmt + lambda[gloc + 1] * dQf_dVmt_dVmt; + val[0] = lambda_gloc * dPf_dthetat_dthetaf + + lambda_gloc1 * dQf_dthetat_dthetaf; + val[1] = + lambda_gloc * dPf_dthetat_dVmf + lambda_gloc1 * dQf_dthetat_dVmf; + val[2] = lambda_gloc * dPf_dthetat_dthetat + + lambda_gloc1 * dQf_dthetat_dthetat; + val[3] = + lambda_gloc * dPf_dthetat_dVmt + lambda_gloc1 * dQf_dthetat_dVmt; + + val[4] = + lambda_gloc * dPf_dVmt_dthetaf + lambda_gloc1 * dQf_dVmt_dthetaf; + val[5] = lambda_gloc * dPf_dVmt_dVmf + lambda_gloc1 * dQf_dVmt_dVmf; + val[6] = + lambda_gloc * dPf_dVmt_dthetat + lambda_gloc1 * dQf_dVmt_dthetat; + val[7] = lambda_gloc * dPf_dVmt_dVmt + lambda_gloc1 * dQf_dVmt_dVmt; ierr = MatSetValues(H, 2, row, 4, col, val, ADD_VALUES); CHKERRQ(ierr); @@ -1935,32 +2063,32 @@ PetscErrorCode OPFLOWComputeEqualityConstraintsHessian_PBPOL(OPFLOW opflow, PetscScalar dPt_dVmf_dthetat, dPt_dVmf_dVmt, dPt_dVmf_dthetaf, dPt_dVmf_dVmf; - /* dPt_dthetat = Vmf*Vmt*(-Gtf*sin(thetatf) + Btf*cos(thetatf)); */ + /* dPt_dthetat = Vmf*Vmt*(-Gtf*sin_thetatf + Btf*cos_thetatf); */ dPt_dthetat_dthetat = - Vmf * Vmt * (-Gtf * cos(thetatf) - Btf * sin(thetatf)); - dPt_dthetat_dVmt = Vmf * (-Gtf * sin(thetatf) + Btf * cos(thetatf)); + Vmf * Vmt * (-Gtf * cos_thetatf - Btf * sin_thetatf); + dPt_dthetat_dVmt = Vmf * (-Gtf * sin_thetatf + Btf * cos_thetatf); dPt_dthetat_dthetaf = - Vmf * Vmt * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - dPt_dthetat_dVmf = Vmt * (-Gtf * sin(thetatf) + Btf * cos(thetatf)); + Vmf * Vmt * (Gtf * cos_thetatf + Btf * sin_thetatf); + dPt_dthetat_dVmf = Vmt * (-Gtf * sin_thetatf + Btf * cos_thetatf); - /* dPt_Vmt = 2*Gtt*Vmt + Vmf*(Gtf*cos(thetatf) + Btf*sin(thetatf)); */ - dPt_dVmt_dthetat = Vmf * (-Gtf * sin(thetatf) + Bft * cos(thetatf)); + /* dPt_Vmt = 2*Gtt*Vmt + Vmf*(Gtf*cos_thetatf + Btf*sin_thetatf); */ + dPt_dVmt_dthetat = Vmf * (-Gtf * sin_thetatf + Bft * cos_thetatf); dPt_dVmt_dVmt = 2 * Gtt; - dPt_dVmt_dthetaf = Vmf * (Gtf * sin(thetatf) - Btf * cos(thetatf)); - dPt_dVmt_dVmf = (Gtf * cos(thetatf) + Btf * sin(thetatf)); + dPt_dVmt_dthetaf = Vmf * (Gtf * sin_thetatf - Btf * cos_thetatf); + dPt_dVmt_dVmf = (Gtf * cos_thetatf + Btf * sin_thetatf); - /* dPt_dthetaf = Vmf*Vmt*(Gtf*sin(thetatf) - Btf*cos(thetatf)); */ + /* dPt_dthetaf = Vmf*Vmt*(Gtf*sin_thetatf - Btf*cos_thetatf); */ dPt_dthetaf_dthetat = - Vmf * Vmt * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - dPt_dthetaf_dVmt = Vmf * (Gtf * sin(thetatf) - Btf * cos(thetatf)); + Vmf * Vmt * (Gtf * cos_thetatf + Btf * sin_thetatf); + dPt_dthetaf_dVmt = Vmf * (Gtf * sin_thetatf - Btf * cos_thetatf); dPt_dthetaf_dthetaf = - Vmf * Vmt * (-Gtf * cos(thetatf) - Btf * sin(thetatf)); - dPt_dthetaf_dVmf = Vmt * (Gtf * sin(thetatf) - Btf * cos(thetatf)); + Vmf * Vmt * (-Gtf * cos_thetatf - Btf * sin_thetatf); + dPt_dthetaf_dVmf = Vmt * (Gtf * sin_thetatf - Btf * cos_thetatf); - /* dPt_dVmf = Vmt*(Gtf*cos(thetatf) + Btf*sin(thetatf)); */ - dPt_dVmf_dthetat = Vmt * (-Gtf * sin(thetatf) + Btf * cos(thetatf)); - dPt_dVmf_dVmt = (Gtf * cos(thetatf) + Btf * sin(thetatf)); - dPt_dVmf_dthetaf = Vmt * (Gtf * sin(thetatf) - Btf * cos(thetatf)); + /* dPt_dVmf = Vmt*(Gtf*cos_thetatf + Btf*sin_thetatf); */ + dPt_dVmf_dthetat = Vmt * (-Gtf * sin_thetatf + Btf * cos_thetatf); + dPt_dVmf_dVmt = (Gtf * cos_thetatf + Btf * sin_thetatf); + dPt_dVmf_dthetaf = Vmt * (Gtf * sin_thetatf - Btf * cos_thetatf); dPt_dVmf_dVmf = 0.0; PetscScalar dQt_dthetaf_dthetaf, dQt_dthetaf_dVmf, dQt_dthetaf_dthetat, @@ -1972,33 +2100,33 @@ PetscErrorCode OPFLOWComputeEqualityConstraintsHessian_PBPOL(OPFLOW opflow, PetscScalar dQt_dVmt_dthetaf, dQt_dVmt_dVmf, dQt_dVmt_dthetat, dQt_dVmt_dVmt; - /* dQt_dthetat = Vmf*Vmt*(Btf*sin(thetatf) + Gtf*cos(thetatf)); */ + /* dQt_dthetat = Vmf*Vmt*(Btf*sin_thetatf + Gtf*cos_thetatf); */ dQt_dthetat_dthetat = - Vmf * Vmt * (Btf * cos(thetatf) - Gtf * sin(thetatf)); - dQt_dthetat_dVmt = Vmf * (Btf * sin(thetatf) + Gtf * cos(thetatf)); + Vmf * Vmt * (Btf * cos_thetatf - Gtf * sin_thetatf); + dQt_dthetat_dVmt = Vmf * (Btf * sin_thetatf + Gtf * cos_thetatf); dQt_dthetat_dthetaf = - Vmf * Vmt * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - dQt_dthetat_dVmf = Vmf * (Btf * sin(thetatf) + Gtf * cos(thetatf)); + Vmf * Vmt * (-Btf * cos_thetatf + Gtf * sin_thetatf); + dQt_dthetat_dVmf = Vmf * (Btf * sin_thetatf + Gtf * cos_thetatf); - /* dQt_dVmt = -2*Btt*Vmt + Vmf*(-Btf*cos(thetatf) + Gtf*sin(thetatf)); + /* dQt_dVmt = -2*Btt*Vmt + Vmf*(-Btf*cos_thetatf + Gtf*sin_thetatf); */ - dQt_dVmt_dthetat = Vmf * (Btf * sin(thetatf) + Gtf * cos(thetatf)); + dQt_dVmt_dthetat = Vmf * (Btf * sin_thetatf + Gtf * cos_thetatf); dQt_dVmt_dVmt = -2 * Btt; - dQt_dVmt_dthetaf = Vmf * (-Btf * sin(thetatf) + Gtf * cos(thetatf)); - dQt_dVmt_dVmf = (-Btf * cos(thetatf) + Gtf * sin(thetatf)); + dQt_dVmt_dthetaf = Vmf * (-Btf * sin_thetatf + Gtf * cos_thetatf); + dQt_dVmt_dVmf = (-Btf * cos_thetatf + Gtf * sin_thetatf); - /* dQt_dthetaf = Vmf*Vmt*(-Btf*sin(thetatf) - Gtf*cos(thetatf)); */ + /* dQt_dthetaf = Vmf*Vmt*(-Btf*sin_thetatf - Gtf*cos_thetatf); */ dQt_dthetaf_dthetat = - Vmf * Vmt * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - dQt_dthetaf_dVmt = Vmf * (-Btf * sin(thetatf) - Gtf * cos(thetatf)); + Vmf * Vmt * (-Btf * cos_thetatf + Gtf * sin_thetatf); + dQt_dthetaf_dVmt = Vmf * (-Btf * sin_thetatf - Gtf * cos_thetatf); dQt_dthetaf_dthetaf = - Vmf * Vmt * (Btf * cos(thetatf) - Gtf * sin(thetatf)); - dQt_dthetaf_dVmf = Vmt * (-Btf * sin(thetatf) - Gtf * cos(thetatf)); + Vmf * Vmt * (Btf * cos_thetatf - Gtf * sin_thetatf); + dQt_dthetaf_dVmf = Vmt * (-Btf * sin_thetatf - Gtf * cos_thetatf); - /* dQt_dVmf = Vmt*(-Btf*cos(thetatf) + Gtf*sin(thetatf)); */ - dQt_dVmf_dthetat = Vmt * (Btf * sin(thetatf) + Gtf * cos(thetatf)); - dQt_dVmf_dVmt = (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - dQt_dVmf_dthetaf = Vmt * (-Btf * sin(thetatf) - Gtf * cos(thetatf)); + /* dQt_dVmf = Vmt*(-Btf*cos_thetatf + Gtf*sin_thetatf); */ + dQt_dVmf_dthetat = Vmt * (Btf * sin_thetatf + Gtf * cos_thetatf); + dQt_dVmf_dVmt = (-Btf * cos_thetatf + Gtf * sin_thetatf); + dQt_dVmf_dthetaf = Vmt * (-Btf * sin_thetatf - Gtf * cos_thetatf); dQt_dVmf_dVmf = 0.0; row[0] = xloct; @@ -2011,23 +2139,21 @@ PetscErrorCode OPFLOWComputeEqualityConstraintsHessian_PBPOL(OPFLOW opflow, val[0] = val[1] = val[2] = val[3] = val[4] = val[5] = val[6] = val[7] = 0.0; - val[0] = lambda[gloc] * dPt_dthetat_dthetat + - lambda[gloc + 1] * dQt_dthetat_dthetat; - val[1] = lambda[gloc] * dPt_dthetat_dVmt + - lambda[gloc + 1] * dQt_dthetat_dVmt; - val[2] = lambda[gloc] * dPt_dthetat_dthetaf + - lambda[gloc + 1] * dQt_dthetat_dthetaf; - val[3] = lambda[gloc] * dPt_dthetat_dVmf + - lambda[gloc + 1] * dQt_dthetat_dVmf; - - val[4] = lambda[gloc] * dPt_dVmt_dthetat + - lambda[gloc + 1] * dQt_dVmt_dthetat; - val[5] = - lambda[gloc] * dPt_dVmt_dVmt + lambda[gloc + 1] * dQt_dVmt_dVmt; - val[6] = lambda[gloc] * dPt_dVmt_dthetaf + - lambda[gloc + 1] * dQt_dVmt_dthetaf; - val[7] = - lambda[gloc] * dPt_dVmt_dVmf + lambda[gloc + 1] * dQt_dVmt_dVmf; + val[0] = lambda_gloc * dPt_dthetat_dthetat + + lambda_gloc1 * dQt_dthetat_dthetat; + val[1] = + lambda_gloc * dPt_dthetat_dVmt + lambda_gloc1 * dQt_dthetat_dVmt; + val[2] = lambda_gloc * dPt_dthetat_dthetaf + + lambda_gloc1 * dQt_dthetat_dthetaf; + val[3] = + lambda_gloc * dPt_dthetat_dVmf + lambda_gloc1 * dQt_dthetat_dVmf; + + val[4] = + lambda_gloc * dPt_dVmt_dthetat + lambda_gloc1 * dQt_dVmt_dthetat; + val[5] = lambda_gloc * dPt_dVmt_dVmt + lambda_gloc1 * dQt_dVmt_dVmt; + val[6] = + lambda_gloc * dPt_dVmt_dthetaf + lambda_gloc1 * dQt_dVmt_dthetaf; + val[7] = lambda_gloc * dPt_dVmt_dVmf + lambda_gloc1 * dQt_dVmt_dVmf; ierr = MatSetValues(H, 2, row, 4, col, val, ADD_VALUES); CHKERRQ(ierr); @@ -2042,23 +2168,21 @@ PetscErrorCode OPFLOWComputeEqualityConstraintsHessian_PBPOL(OPFLOW opflow, val[0] = val[1] = val[2] = val[3] = val[4] = val[5] = val[6] = val[7] = 0.0; - val[0] = lambda[gloc] * dPt_dthetaf_dthetat + - lambda[gloc + 1] * dQt_dthetaf_dthetat; - val[1] = lambda[gloc] * dPt_dthetaf_dVmt + - lambda[gloc + 1] * dQt_dthetaf_dVmt; - val[2] = lambda[gloc] * dPt_dthetaf_dthetaf + - lambda[gloc + 1] * dQt_dthetaf_dthetaf; - val[3] = lambda[gloc] * dPt_dthetaf_dVmf + - lambda[gloc + 1] * dQt_dthetaf_dVmf; - - val[4] = lambda[gloc] * dPt_dVmf_dthetat + - lambda[gloc + 1] * dQt_dVmf_dthetat; - val[5] = - lambda[gloc] * dPt_dVmf_dVmt + lambda[gloc + 1] * dQt_dVmf_dVmt; - val[6] = lambda[gloc] * dPt_dVmf_dthetaf + - lambda[gloc + 1] * dQt_dVmf_dthetaf; - val[7] = - lambda[gloc] * dPt_dVmf_dVmf + lambda[gloc + 1] * dQt_dVmf_dVmf; + val[0] = lambda_gloc * dPt_dthetaf_dthetat + + lambda_gloc1 * dQt_dthetaf_dthetat; + val[1] = + lambda_gloc * dPt_dthetaf_dVmt + lambda_gloc1 * dQt_dthetaf_dVmt; + val[2] = lambda_gloc * dPt_dthetaf_dthetaf + + lambda_gloc1 * dQt_dthetaf_dthetaf; + val[3] = + lambda_gloc * dPt_dthetaf_dVmf + lambda_gloc1 * dQt_dthetaf_dVmf; + + val[4] = + lambda_gloc * dPt_dVmf_dthetat + lambda_gloc1 * dQt_dVmf_dthetat; + val[5] = lambda_gloc * dPt_dVmf_dVmt + lambda_gloc1 * dQt_dVmf_dVmt; + val[6] = + lambda_gloc * dPt_dVmf_dthetaf + lambda_gloc1 * dQt_dVmf_dthetaf; + val[7] = lambda_gloc * dPt_dVmf_dVmf + lambda_gloc1 * dQt_dVmf_dVmf; ierr = MatSetValues(H, 2, row, 4, col, val, ADD_VALUES); CHKERRQ(ierr); @@ -2111,6 +2235,7 @@ PetscErrorCode OPFLOWComputeInequalityConstraintsHessian_PBPOL(OPFLOW opflow, PSGEN gen; PetscInt loc; PetscScalar Q, Qmax, Qmin, Qg; + PetscScalar lambda_gloc, lambda_gloc1; PetscFunctionBegin; @@ -2140,27 +2265,30 @@ PetscErrorCode OPFLOWComputeInequalityConstraintsHessian_PBPOL(OPFLOW opflow, row[0] = gen->startxpowloc; + lambda_gloc = lambda[gloc]; + lambda_gloc1 = lambda[gloc + 1]; + col[0] = gen->startxpowloc; col[1] = gen->startxpdevloc; col[2] = ps->startxloc; val[0] = 0.0; - val[1] = -lambda[gloc] - lambda[gloc + 1]; - val[2] = gen->apf * (lambda[gloc] + lambda[gloc + 1]); + val[1] = -lambda_gloc - lambda_gloc1; + val[2] = gen->apf * (lambda_gloc + lambda_gloc1); ierr = MatSetValues(H, 1, row, 3, col, val, ADD_VALUES); // df1_ddelPg = -(Pg - gen->pt); // df2_ddelPg = gen->pb - Pg; row[0] = gen->startxpdevloc; - val[0] = -lambda[gloc] - lambda[gloc + 1]; + val[0] = -lambda_gloc - lambda_gloc1; ierr = MatSetValues(H, 1, row, 1, col, val, ADD_VALUES); CHKERRQ(ierr); // df1_ddelP = gen->apf*(Pg - gen->pt); // df2_ddelP = -gen->apf*(gen->pb - Pg); row[0] = ps->startxloc; - val[0] = gen->apf * (lambda[gloc] + lambda[gloc + 1]); + val[0] = gen->apf * (lambda_gloc + lambda_gloc1); ierr = MatSetValues(H, 1, row, 1, col, val, ADD_VALUES); CHKERRQ(ierr); } @@ -2177,6 +2305,9 @@ PetscErrorCode OPFLOWComputeInequalityConstraintsHessian_PBPOL(OPFLOW opflow, // xlocglob = bus->startxVlocglob; // V = x[xloc + 1]; + lambda_gloc = lambda[gloc]; + lambda_gloc1 = lambda[gloc + 1]; + Q = 0; Qmax = 0; Qmin = 0; @@ -2194,16 +2325,16 @@ PetscErrorCode OPFLOWComputeInequalityConstraintsHessian_PBPOL(OPFLOW opflow, row[0] = loc + 1; col[0] = xloc + 1; - val[0] = -( - lambda[gloc] + - lambda[gloc + 1]); // lam_eq1*d2eq1_dQg_dV + lam_eq2*d2eq2_dQg_dV + val[0] = + -(lambda_gloc + + lambda_gloc1); // lam_eq1*d2eq1_dQg_dV + lam_eq2*d2eq2_dQg_dV ierr = MatSetValues(H, 1, row, 1, col, val, ADD_VALUES); CHKERRQ(ierr); row[0] = xloc + 1; col[0] = loc + 1; - val[0] = -( - lambda[gloc] + - lambda[gloc + 1]); // lam_eq1* d2eq1_dQg_dV + lam_eq2*d2eq2_dV_dQg + val[0] = + -(lambda_gloc + + lambda_gloc1); // lam_eq1* d2eq1_dQg_dV + lam_eq2*d2eq2_dV_dQg ierr = MatSetValues(H, 1, row, 1, col, val, ADD_VALUES); CHKERRQ(ierr); } @@ -2212,429 +2343,412 @@ PetscErrorCode OPFLOWComputeInequalityConstraintsHessian_PBPOL(OPFLOW opflow, } // for the part of line constraints - if (!opflow->ignore_lineflow_constraints) { - for (i = 0; i < opflow->nlinesmon; i++) { - line = &ps->line[opflow->linesmon[i]]; - - PetscScalar Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt; - Gff = line->yff[0]; - Bff = line->yff[1]; - Gft = line->yft[0]; - Bft = line->yft[1]; - Gtf = line->ytf[0]; - Btf = line->ytf[1]; - Gtt = line->ytt[0]; - Btt = line->ytt[1]; - - ierr = PSLINEGetConnectedBuses(line, &connbuses); - CHKERRQ(ierr); - busf = connbuses[0]; - bust = connbuses[1]; + for (i = 0; i < opflow->nlinesmon; i++) { + line = &ps->line[opflow->linesmon[i]]; - gloc = line->startineqloc; + if (line->isdcline) + continue; - xlocf = busf->startxVloc; - xloct = bust->startxVloc; - xlocglobf = busf->startxVlocglob; - xlocglobt = bust->startxVlocglob; + PetscScalar Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt; + Gff = line->yff[0]; + Bff = line->yff[1]; + Gft = line->yft[0]; + Bft = line->yft[1]; + Gtf = line->ytf[0]; + Btf = line->ytf[1]; + Gtt = line->ytt[0]; + Btt = line->ytt[1]; - PetscScalar Vmf, Vmt, thetaf, thetat, thetaft, thetatf; + ierr = PSLINEGetConnectedBuses(line, &connbuses); + CHKERRQ(ierr); + busf = connbuses[0]; + bust = connbuses[1]; - thetaf = x[xlocf]; - Vmf = x[xlocf + 1]; - thetat = x[xloct]; - Vmt = x[xloct + 1]; - thetaft = thetaf - thetat; - thetatf = thetat - thetaf; + gloc = line->startineqloc; - // Sf2 and St2 are the constraints - PetscScalar Pf, Qf, Pt, Qt; + xlocf = busf->startxVloc; + xloct = bust->startxVloc; + xlocglobf = busf->startxVlocglob; + xlocglobt = bust->startxVlocglob; - Pf = Gff * Vmf * Vmf + - Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - Qf = -Bff * Vmf * Vmf + - Vmf * Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); + PetscScalar Vmf, Vmt, thetaf, thetat, thetaft, thetatf; + PetscScalar sin_thetaft, cos_thetaft, sin_thetatf, cos_thetatf; - Pt = Gtt * Vmt * Vmt + - Vmt * Vmf * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - Qt = -Btt * Vmt * Vmt + - Vmt * Vmf * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - - PetscScalar dSf2_dPf, dSf2_dQf, dSt2_dPt, dSt2_dQt; - - dSf2_dPf = 2. * Pf; - dSf2_dQf = 2. * Qf; - dSt2_dPt = 2. * Pt; - dSt2_dQt = 2. * Qt; - - PetscScalar dPf_dthetaf, dPf_dVmf, dPf_dthetat, dPf_dVmt; - PetscScalar dQf_dthetaf, dQf_dVmf, dQf_dthetat, dQf_dVmt; - PetscScalar dPt_dthetaf, dPt_dVmf, dPt_dthetat, dPt_dVmt; - PetscScalar dQt_dthetaf, dQt_dVmf, dQt_dthetat, dQt_dVmt; - - dPf_dthetaf = Vmf * Vmt * (-Gft * sin(thetaft) + Bft * cos(thetaft)); - dPf_dVmf = - 2. * Gff * Vmf + Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - dPf_dthetat = Vmf * Vmt * (Gft * sin(thetaft) - Bft * cos(thetaft)); - dPf_dVmt = Vmf * (Gft * cos(thetaft) + Bft * sin(thetaft)); - - dQf_dthetaf = Vmf * Vmt * (Bft * sin(thetaft) + Gft * cos(thetaft)); - dQf_dVmf = - -2. * Bff * Vmf + Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); - dQf_dthetat = Vmf * Vmt * (-Bft * sin(thetaft) - Gft * cos(thetaft)); - dQf_dVmt = Vmf * (-Bft * cos(thetaft) + Gft * sin(thetaft)); - - dPt_dthetat = Vmt * Vmf * (-Gtf * sin(thetatf) + Btf * cos(thetatf)); - dPt_dVmt = - 2. * Gtt * Vmt + Vmf * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - dPt_dthetaf = Vmt * Vmf * (Gtf * sin(thetatf) - Btf * cos(thetatf)); - dPt_dVmf = Vmt * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - - dQt_dthetat = Vmt * Vmf * (Btf * sin(thetatf) + Gtf * cos(thetatf)); - dQt_dVmt = - -2. * Btt * Vmt + Vmf * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - dQt_dthetaf = Vmt * Vmf * (-Btf * sin(thetatf) - Gtf * cos(thetatf)); - dQt_dVmf = Vmt * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - - PetscScalar d2Pf_dthetaf_dthetaf, d2Pf_dthetaf_dVmf, d2Pf_dthetaf_dthetat, - d2Pf_dthetaf_dVmt; - PetscScalar d2Pf_dVmf_dthetaf, d2Pf_dVmf_dVmf, d2Pf_dVmf_dthetat, - d2Pf_dVmf_dVmt; - PetscScalar d2Pf_dthetat_dthetaf, d2Pf_dthetat_dVmf, d2Pf_dthetat_dthetat, - d2Pf_dthetat_dVmt; - PetscScalar d2Pf_dVmt_dthetaf, d2Pf_dVmt_dVmf, d2Pf_dVmt_dthetat, - d2Pf_dVmt_dVmt; - - /* dPf_dthetaf = Vmf*Vmt*(-Gft*sin(thetaft) + Bft*cos(thetaft)); */ - d2Pf_dthetaf_dthetaf = - -Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - d2Pf_dthetaf_dVmf = Vmt * (-Gft * sin(thetaft) + Bft * cos(thetaft)); - d2Pf_dthetaf_dthetat = - Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - d2Pf_dthetaf_dVmt = Vmf * (-Gft * sin(thetaft) + Bft * cos(thetaft)); - - /* dPf_Vmf = 2*Gff*Vmf + Vmt*(Gft*cos(thetaft) + Bft*sin(thetaft)); */ - d2Pf_dVmf_dthetaf = Vmt * (-Gft * sin(thetaft) + Bft * cos(thetaft)); - d2Pf_dVmf_dVmf = 2 * Gff; - d2Pf_dVmf_dthetat = Vmt * (Gft * sin(thetaft) - Bft * cos(thetaft)); - d2Pf_dVmf_dVmt = (Gft * cos(thetaft) + Bft * sin(thetaft)); - - /* dPf_dthetat = Vmf*Vmt*(Gft*sin(thetaft) - Bft*cos(thetaft)); */ - d2Pf_dthetat_dthetaf = - Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - d2Pf_dthetat_dVmf = Vmt * (Gft * sin(thetaft) - Bft * cos(thetaft)); - d2Pf_dthetat_dthetat = - Vmf * Vmt * (-Gft * cos(thetaft) - Bft * sin(thetaft)); - d2Pf_dthetat_dVmt = Vmf * (Gft * sin(thetaft) - Bft * cos(thetaft)); - - /* dPf_dVmt = Vmf*(Gft*cos(thetaft) + Bft*sin(thetaft)); */ - d2Pf_dVmt_dthetaf = Vmf * (-Gft * sin(thetaft) + Bft * cos(thetaft)); - d2Pf_dVmt_dVmf = (Gft * cos(thetaft) + Bft * sin(thetaft)); - d2Pf_dVmt_dthetat = Vmf * (Gft * sin(thetaft) - Bft * cos(thetaft)); - d2Pf_dVmt_dVmt = 0.0; - - PetscScalar d2Qf_dthetaf_dthetaf, d2Qf_dthetaf_dVmf, d2Qf_dthetaf_dthetat, - d2Qf_dthetaf_dVmt; - PetscScalar d2Qf_dVmf_dthetaf, d2Qf_dVmf_dVmf, d2Qf_dVmf_dthetat, - d2Qf_dVmf_dVmt; - PetscScalar d2Qf_dthetat_dthetaf, d2Qf_dthetat_dVmf, d2Qf_dthetat_dthetat, - d2Qf_dthetat_dVmt; - PetscScalar d2Qf_dVmt_dthetaf, d2Qf_dVmt_dVmf, d2Qf_dVmt_dthetat, - d2Qf_dVmt_dVmt; - - /* dQf_dthetaf = Vmf*Vmt*(Bft*sin(thetaft) + Gft*cos(thetaft)); */ - d2Qf_dthetaf_dthetaf = - Vmf * Vmt * (Bft * cos(thetaft) - Gft * sin(thetaft)); - d2Qf_dthetaf_dVmf = Vmt * (Bft * sin(thetaft) + Gft * cos(thetaft)); - d2Qf_dthetaf_dthetat = - Vmf * Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); - d2Qf_dthetaf_dVmt = Vmf * (Bft * sin(thetaft) + Gft * cos(thetaft)); - - /* dQf_dVmf = -2*Bff*Vmf + Vmt*(-Bft*cos(thetaft) + Gft*sin(thetaft)); */ - d2Qf_dVmf_dthetaf = Vmt * (Bft * sin(thetaft) + Gft * cos(thetaft)); - d2Qf_dVmf_dVmf = -2 * Bff; - d2Qf_dVmf_dthetat = Vmt * (-Bft * sin(thetaft) - Gft * cos(thetaft)); - d2Qf_dVmf_dVmt = (-Bft * cos(thetaft) + Gft * sin(thetaft)); - - /* dQf_dthetat = Vmf*Vmt*(-Bft*sin(thetaft) - Gft*cos(thetaft)); */ - d2Qf_dthetat_dthetaf = - Vmf * Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); - d2Qf_dthetat_dVmf = Vmt * (-Bft * sin(thetaft) - Gft * cos(thetaft)); - d2Qf_dthetat_dthetat = - Vmf * Vmt * (Bft * cos(thetaft) - Gft * sin(thetaft)); - d2Qf_dthetat_dVmt = Vmf * (-Bft * sin(thetaft) - Gft * cos(thetaft)); - - /* dQf_dVmt = Vmf*(-Bft*cos(thetaft) + Gft*sin(thetaft)); */ - d2Qf_dVmt_dthetaf = Vmf * (Bft * sin(thetaft) + Gft * cos(thetaft)); - d2Qf_dVmt_dVmf = (-Bft * cos(thetaft) + Gft * sin(thetaft)); - d2Qf_dVmt_dthetat = Vmf * (-Bft * sin(thetaft) - Gft * cos(thetaft)); - d2Qf_dVmt_dVmt = 0.0; - - PetscScalar d2Pt_dthetat_dthetat, d2Pt_dthetat_dVmt, d2Pt_dthetat_dthetaf, - d2Pt_dthetat_dVmf; - PetscScalar d2Pt_dVmt_dthetat, d2Pt_dVmt_dVmt, d2Pt_dVmt_dthetaf, - d2Pt_dVmt_dVmf; - PetscScalar d2Pt_dthetaf_dthetat, d2Pt_dthetaf_dVmt, d2Pt_dthetaf_dthetaf, - d2Pt_dthetaf_dVmf; - PetscScalar d2Pt_dVmf_dthetat, d2Pt_dVmf_dVmt, d2Pt_dVmf_dthetaf, - d2Pt_dVmf_dVmf; - - /* dPt_dthetat = Vmf*Vmt*(-Gtf*sin(thetatf) + Btf*cos(thetatf)); */ - d2Pt_dthetat_dthetat = - Vmf * Vmt * (-Gtf * cos(thetatf) - Btf * sin(thetatf)); - d2Pt_dthetat_dVmt = Vmf * (-Gtf * sin(thetatf) + Btf * cos(thetatf)); - d2Pt_dthetat_dthetaf = - Vmf * Vmt * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - d2Pt_dthetat_dVmf = Vmt * (-Gtf * sin(thetatf) + Btf * cos(thetatf)); - - /* dPt_Vmt = 2*Gtt*Vmt + Vmf*(Gtf*cos(thetatf) + Btf*sin(thetatf)); */ - d2Pt_dVmt_dthetat = Vmf * (-Gtf * sin(thetatf) + Bft * cos(thetatf)); - d2Pt_dVmt_dVmt = 2 * Gtt; - d2Pt_dVmt_dthetaf = Vmf * (Gtf * sin(thetatf) - Btf * cos(thetatf)); - d2Pt_dVmt_dVmf = (Gtf * cos(thetatf) + Btf * sin(thetatf)); - - /* dPt_dthetaf = Vmf*Vmt*(Gtf*sin(thetatf) - Btf*cos(thetatf)); */ - d2Pt_dthetaf_dthetat = - Vmf * Vmt * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - d2Pt_dthetaf_dVmt = Vmf * (Gtf * sin(thetatf) - Btf * cos(thetatf)); - d2Pt_dthetaf_dthetaf = - Vmf * Vmt * (-Gtf * cos(thetatf) - Btf * sin(thetatf)); - d2Pt_dthetaf_dVmf = Vmt * (Gtf * sin(thetatf) - Btf * cos(thetatf)); - - /* dPt_dVmf = Vmt*(Gtf*cos(thetatf) + Btf*sin(thetatf)); */ - d2Pt_dVmf_dthetat = Vmt * (-Gtf * sin(thetatf) + Btf * cos(thetatf)); - d2Pt_dVmf_dVmt = (Gtf * cos(thetatf) + Btf * sin(thetatf)); - d2Pt_dVmf_dthetaf = Vmt * (Gtf * sin(thetatf) - Btf * cos(thetatf)); - d2Pt_dVmf_dVmf = 0.0; - - PetscScalar d2Qt_dthetaf_dthetaf, d2Qt_dthetaf_dVmf, d2Qt_dthetaf_dthetat, - d2Qt_dthetaf_dVmt; - PetscScalar d2Qt_dVmf_dthetaf, d2Qt_dVmf_dVmf, d2Qt_dVmf_dthetat, - d2Qt_dVmf_dVmt; - PetscScalar d2Qt_dthetat_dthetaf, d2Qt_dthetat_dVmf, d2Qt_dthetat_dthetat, - d2Qt_dthetat_dVmt; - PetscScalar d2Qt_dVmt_dthetaf, d2Qt_dVmt_dVmf, d2Qt_dVmt_dthetat, - d2Qt_dVmt_dVmt; - - /* dQt_dthetat = Vmf*Vmt*(Btf*sin(thetatf) + Gtf*cos(thetatf)); */ - d2Qt_dthetat_dthetat = - Vmf * Vmt * (Btf * cos(thetatf) - Gtf * sin(thetatf)); - d2Qt_dthetat_dVmt = Vmf * (Btf * sin(thetatf) + Gtf * cos(thetatf)); - d2Qt_dthetat_dthetaf = - Vmf * Vmt * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - d2Qt_dthetat_dVmf = Vmf * (Btf * sin(thetatf) + Gtf * cos(thetatf)); - - /* dQt_dVmt = -2*Btt*Vmt + Vmf*(-Btf*cos(thetatf) + Gtf*sin(thetatf)); */ - d2Qt_dVmt_dthetat = Vmf * (Btf * sin(thetatf) + Gtf * cos(thetatf)); - d2Qt_dVmt_dVmt = -2 * Btt; - d2Qt_dVmt_dthetaf = Vmf * (-Btf * sin(thetatf) + Gtf * cos(thetatf)); - d2Qt_dVmt_dVmf = (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - - /* dQt_dthetaf = Vmf*Vmt*(-Btf*sin(thetatf) - Gtf*cos(thetatf)); */ - d2Qt_dthetaf_dthetat = - Vmf * Vmt * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - d2Qt_dthetaf_dVmt = Vmf * (-Btf * sin(thetatf) - Gtf * cos(thetatf)); - d2Qt_dthetaf_dthetaf = - Vmf * Vmt * (Btf * cos(thetatf) - Gtf * sin(thetatf)); - d2Qt_dthetaf_dVmf = Vmt * (-Btf * sin(thetatf) - Gtf * cos(thetatf)); - - /* dQt_dVmf = Vmt*(-Btf*cos(thetatf) + Gtf*sin(thetatf)); */ - d2Qt_dVmf_dthetat = Vmt * (Btf * sin(thetatf) + Gtf * cos(thetatf)); - d2Qt_dVmf_dVmt = (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - d2Qt_dVmf_dthetaf = Vmt * (-Btf * sin(thetatf) - Gtf * cos(thetatf)); - d2Qt_dVmf_dVmf = 0.0; - - PetscScalar d2Sf2_dthetaf_dthetaf = 0.0, d2Sf2_dthetaf_dVmf = 0.0, - d2Sf2_dthetaf_dthetat = 0.0, d2Sf2_dthetaf_dVmt = 0.0; - PetscScalar d2St2_dthetaf_dthetaf = 0.0, d2St2_dthetaf_dVmf = 0.0, - d2St2_dthetaf_dthetat = 0.0, d2St2_dthetaf_dVmt = 0.0; - - d2Sf2_dthetaf_dthetaf = - 2 * dPf_dthetaf * dPf_dthetaf + dSf2_dPf * d2Pf_dthetaf_dthetaf + - 2 * dQf_dthetaf * dQf_dthetaf + dSf2_dQf * d2Qf_dthetaf_dthetaf; - d2Sf2_dthetaf_dVmf = - 2 * dPf_dVmf * dPf_dthetaf + dSf2_dPf * d2Pf_dthetaf_dVmf + - 2 * dQf_dVmf * dQf_dthetaf + dSf2_dQf * d2Qf_dthetaf_dVmf; - d2Sf2_dthetaf_dthetat = - 2 * dPf_dthetat * dPf_dthetaf + dSf2_dPf * d2Pf_dthetaf_dthetat + - 2 * dQf_dthetat * dQf_dthetaf + dSf2_dQf * d2Qf_dthetaf_dthetat; - d2Sf2_dthetaf_dVmt = - 2 * dPf_dVmt * dPf_dthetaf + dSf2_dPf * d2Pf_dthetaf_dVmt + - 2 * dQf_dVmt * dQf_dthetaf + dSf2_dQf * d2Qf_dthetaf_dVmt; - - d2St2_dthetaf_dthetaf = - 2 * dPt_dthetaf * dPt_dthetaf + dSt2_dPt * d2Pt_dthetaf_dthetaf + - 2 * dQt_dthetaf * dQt_dthetaf + dSt2_dQt * d2Qt_dthetaf_dthetaf; - d2St2_dthetaf_dVmf = - 2 * dPt_dVmf * dPt_dthetaf + dSt2_dPt * d2Pt_dthetaf_dVmf + - 2 * dQt_dVmf * dQt_dthetaf + dSt2_dQt * d2Qt_dthetaf_dVmf; - d2St2_dthetaf_dthetat = - 2 * dPt_dthetat * dPt_dthetaf + dSt2_dPt * d2Pt_dthetaf_dthetat + - 2 * dQt_dthetat * dQt_dthetaf + dSt2_dQt * d2Qt_dthetaf_dthetat; - d2St2_dthetaf_dVmt = - 2 * dPt_dVmt * dPt_dthetaf + dSt2_dPt * d2Pt_dthetaf_dVmt + - 2 * dQt_dVmt * dQt_dthetaf + dSt2_dQt * d2Qt_dthetaf_dVmt; - - val[0] = val[1] = val[2] = val[3] = 0.0; - col[0] = xlocglobf; - col[1] = xlocglobf + 1; - col[2] = xlocglobt; - col[3] = xlocglobt + 1; - row[0] = xlocglobf; - val[0] = lambda[gloc] * d2Sf2_dthetaf_dthetaf + - lambda[gloc + 1] * d2St2_dthetaf_dthetaf; - val[1] = lambda[gloc] * d2Sf2_dthetaf_dVmf + - lambda[gloc + 1] * d2St2_dthetaf_dVmf; - val[2] = lambda[gloc] * d2Sf2_dthetaf_dthetat + - lambda[gloc + 1] * d2St2_dthetaf_dthetat; - val[3] = lambda[gloc] * d2Sf2_dthetaf_dVmt + - lambda[gloc + 1] * d2St2_dthetaf_dVmt; - - ierr = MatSetValues(H, 1, row, 4, col, val, ADD_VALUES); - CHKERRQ(ierr); + thetaf = x[xlocf]; + Vmf = x[xlocf + 1]; + thetat = x[xloct]; + Vmt = x[xloct + 1]; + thetaft = thetaf - thetat; + thetatf = thetat - thetaf; + sin_thetaft = sin(thetaft); + cos_thetaft = cos(thetaft); + sin_thetatf = sin(thetatf); + cos_thetatf = cos(thetatf); + + // Sf2 and St2 are the constraints + PetscScalar Pf, Qf, Pt, Qt; + + Pf = Gff * Vmf * Vmf + Vmf * Vmt * (Gft * cos_thetaft + Bft * sin_thetaft); + Qf = + -Bff * Vmf * Vmf + Vmf * Vmt * (-Bft * cos_thetaft + Gft * sin_thetaft); + + Pt = Gtt * Vmt * Vmt + Vmt * Vmf * (Gtf * cos_thetatf + Btf * sin_thetatf); + Qt = + -Btt * Vmt * Vmt + Vmt * Vmf * (-Btf * cos_thetatf + Gtf * sin_thetatf); + + PetscScalar dSf2_dPf, dSf2_dQf, dSt2_dPt, dSt2_dQt; + + dSf2_dPf = 2. * Pf; + dSf2_dQf = 2. * Qf; + dSt2_dPt = 2. * Pt; + dSt2_dQt = 2. * Qt; + + PetscScalar dPf_dthetaf, dPf_dVmf, dPf_dthetat, dPf_dVmt; + PetscScalar dQf_dthetaf, dQf_dVmf, dQf_dthetat, dQf_dVmt; + PetscScalar dPt_dthetaf, dPt_dVmf, dPt_dthetat, dPt_dVmt; + PetscScalar dQt_dthetaf, dQt_dVmf, dQt_dthetat, dQt_dVmt; + + dPf_dthetaf = Vmf * Vmt * (-Gft * sin_thetaft + Bft * cos_thetaft); + dPf_dVmf = 2. * Gff * Vmf + Vmt * (Gft * cos_thetaft + Bft * sin_thetaft); + dPf_dthetat = Vmf * Vmt * (Gft * sin_thetaft - Bft * cos_thetaft); + dPf_dVmt = Vmf * (Gft * cos_thetaft + Bft * sin_thetaft); + + dQf_dthetaf = Vmf * Vmt * (Bft * sin_thetaft + Gft * cos_thetaft); + dQf_dVmf = -2. * Bff * Vmf + Vmt * (-Bft * cos_thetaft + Gft * sin_thetaft); + dQf_dthetat = Vmf * Vmt * (-Bft * sin_thetaft - Gft * cos_thetaft); + dQf_dVmt = Vmf * (-Bft * cos_thetaft + Gft * sin_thetaft); + + dPt_dthetat = Vmt * Vmf * (-Gtf * sin_thetatf + Btf * cos_thetatf); + dPt_dVmt = 2. * Gtt * Vmt + Vmf * (Gtf * cos_thetatf + Btf * sin_thetatf); + dPt_dthetaf = Vmt * Vmf * (Gtf * sin_thetatf - Btf * cos_thetatf); + dPt_dVmf = Vmt * (Gtf * cos_thetatf + Btf * sin_thetatf); + + dQt_dthetat = Vmt * Vmf * (Btf * sin_thetatf + Gtf * cos_thetatf); + dQt_dVmt = -2. * Btt * Vmt + Vmf * (-Btf * cos_thetatf + Gtf * sin_thetatf); + dQt_dthetaf = Vmt * Vmf * (-Btf * sin_thetatf - Gtf * cos_thetatf); + dQt_dVmf = Vmt * (-Btf * cos_thetatf + Gtf * sin_thetatf); + + PetscScalar d2Pf_dthetaf_dthetaf, d2Pf_dthetaf_dVmf, d2Pf_dthetaf_dthetat, + d2Pf_dthetaf_dVmt; + PetscScalar d2Pf_dVmf_dthetaf, d2Pf_dVmf_dVmf, d2Pf_dVmf_dthetat, + d2Pf_dVmf_dVmt; + PetscScalar d2Pf_dthetat_dthetaf, d2Pf_dthetat_dVmf, d2Pf_dthetat_dthetat, + d2Pf_dthetat_dVmt; + PetscScalar d2Pf_dVmt_dthetaf, d2Pf_dVmt_dVmf, d2Pf_dVmt_dthetat, + d2Pf_dVmt_dVmt; + + /* dPf_dthetaf = Vmf*Vmt*(-Gft*sin_thetaft + Bft*cos_thetaft); */ + d2Pf_dthetaf_dthetaf = -Vmf * Vmt * (Gft * cos_thetaft + Bft * sin_thetaft); + d2Pf_dthetaf_dVmf = Vmt * (-Gft * sin_thetaft + Bft * cos_thetaft); + d2Pf_dthetaf_dthetat = Vmf * Vmt * (Gft * cos_thetaft + Bft * sin_thetaft); + d2Pf_dthetaf_dVmt = Vmf * (-Gft * sin_thetaft + Bft * cos_thetaft); + + /* dPf_Vmf = 2*Gff*Vmf + Vmt*(Gft*cos_thetaft + Bft*sin_thetaft); */ + d2Pf_dVmf_dthetaf = Vmt * (-Gft * sin_thetaft + Bft * cos_thetaft); + d2Pf_dVmf_dVmf = 2 * Gff; + d2Pf_dVmf_dthetat = Vmt * (Gft * sin_thetaft - Bft * cos_thetaft); + d2Pf_dVmf_dVmt = (Gft * cos_thetaft + Bft * sin_thetaft); + + /* dPf_dthetat = Vmf*Vmt*(Gft*sin_thetaft - Bft*cos_thetaft); */ + d2Pf_dthetat_dthetaf = Vmf * Vmt * (Gft * cos_thetaft + Bft * sin_thetaft); + d2Pf_dthetat_dVmf = Vmt * (Gft * sin_thetaft - Bft * cos_thetaft); + d2Pf_dthetat_dthetat = Vmf * Vmt * (-Gft * cos_thetaft - Bft * sin_thetaft); + d2Pf_dthetat_dVmt = Vmf * (Gft * sin_thetaft - Bft * cos_thetaft); + + /* dPf_dVmt = Vmf*(Gft*cos_thetaft + Bft*sin_thetaft); */ + d2Pf_dVmt_dthetaf = Vmf * (-Gft * sin_thetaft + Bft * cos_thetaft); + d2Pf_dVmt_dVmf = (Gft * cos_thetaft + Bft * sin_thetaft); + d2Pf_dVmt_dthetat = Vmf * (Gft * sin_thetaft - Bft * cos_thetaft); + d2Pf_dVmt_dVmt = 0.0; + + PetscScalar d2Qf_dthetaf_dthetaf, d2Qf_dthetaf_dVmf, d2Qf_dthetaf_dthetat, + d2Qf_dthetaf_dVmt; + PetscScalar d2Qf_dVmf_dthetaf, d2Qf_dVmf_dVmf, d2Qf_dVmf_dthetat, + d2Qf_dVmf_dVmt; + PetscScalar d2Qf_dthetat_dthetaf, d2Qf_dthetat_dVmf, d2Qf_dthetat_dthetat, + d2Qf_dthetat_dVmt; + PetscScalar d2Qf_dVmt_dthetaf, d2Qf_dVmt_dVmf, d2Qf_dVmt_dthetat, + d2Qf_dVmt_dVmt; + + /* dQf_dthetaf = Vmf*Vmt*(Bft*sin_thetaft + Gft*cos_thetaft); */ + d2Qf_dthetaf_dthetaf = Vmf * Vmt * (Bft * cos_thetaft - Gft * sin_thetaft); + d2Qf_dthetaf_dVmf = Vmt * (Bft * sin_thetaft + Gft * cos_thetaft); + d2Qf_dthetaf_dthetat = Vmf * Vmt * (-Bft * cos_thetaft + Gft * sin_thetaft); + d2Qf_dthetaf_dVmt = Vmf * (Bft * sin_thetaft + Gft * cos_thetaft); + + /* dQf_dVmf = -2*Bff*Vmf + Vmt*(-Bft*cos_thetaft + Gft*sin_thetaft); */ + d2Qf_dVmf_dthetaf = Vmt * (Bft * sin_thetaft + Gft * cos_thetaft); + d2Qf_dVmf_dVmf = -2 * Bff; + d2Qf_dVmf_dthetat = Vmt * (-Bft * sin_thetaft - Gft * cos_thetaft); + d2Qf_dVmf_dVmt = (-Bft * cos_thetaft + Gft * sin_thetaft); + + /* dQf_dthetat = Vmf*Vmt*(-Bft*sin_thetaft - Gft*cos_thetaft); */ + d2Qf_dthetat_dthetaf = Vmf * Vmt * (-Bft * cos_thetaft + Gft * sin_thetaft); + d2Qf_dthetat_dVmf = Vmt * (-Bft * sin_thetaft - Gft * cos_thetaft); + d2Qf_dthetat_dthetat = Vmf * Vmt * (Bft * cos_thetaft - Gft * sin_thetaft); + d2Qf_dthetat_dVmt = Vmf * (-Bft * sin_thetaft - Gft * cos_thetaft); + + /* dQf_dVmt = Vmf*(-Bft*cos_thetaft + Gft*sin_thetaft); */ + d2Qf_dVmt_dthetaf = Vmf * (Bft * sin_thetaft + Gft * cos_thetaft); + d2Qf_dVmt_dVmf = (-Bft * cos_thetaft + Gft * sin_thetaft); + d2Qf_dVmt_dthetat = Vmf * (-Bft * sin_thetaft - Gft * cos_thetaft); + d2Qf_dVmt_dVmt = 0.0; + + PetscScalar d2Pt_dthetat_dthetat, d2Pt_dthetat_dVmt, d2Pt_dthetat_dthetaf, + d2Pt_dthetat_dVmf; + PetscScalar d2Pt_dVmt_dthetat, d2Pt_dVmt_dVmt, d2Pt_dVmt_dthetaf, + d2Pt_dVmt_dVmf; + PetscScalar d2Pt_dthetaf_dthetat, d2Pt_dthetaf_dVmt, d2Pt_dthetaf_dthetaf, + d2Pt_dthetaf_dVmf; + PetscScalar d2Pt_dVmf_dthetat, d2Pt_dVmf_dVmt, d2Pt_dVmf_dthetaf, + d2Pt_dVmf_dVmf; + + /* dPt_dthetat = Vmf*Vmt*(-Gtf*sin_thetatf + Btf*cos_thetatf); */ + d2Pt_dthetat_dthetat = Vmf * Vmt * (-Gtf * cos_thetatf - Btf * sin_thetatf); + d2Pt_dthetat_dVmt = Vmf * (-Gtf * sin_thetatf + Btf * cos_thetatf); + d2Pt_dthetat_dthetaf = Vmf * Vmt * (Gtf * cos_thetatf + Btf * sin_thetatf); + d2Pt_dthetat_dVmf = Vmt * (-Gtf * sin_thetatf + Btf * cos_thetatf); + + /* dPt_Vmt = 2*Gtt*Vmt + Vmf*(Gtf*cos_thetatf + Btf*sin_thetatf); */ + d2Pt_dVmt_dthetat = Vmf * (-Gtf * sin_thetatf + Bft * cos_thetatf); + d2Pt_dVmt_dVmt = 2 * Gtt; + d2Pt_dVmt_dthetaf = Vmf * (Gtf * sin_thetatf - Btf * cos_thetatf); + d2Pt_dVmt_dVmf = (Gtf * cos_thetatf + Btf * sin_thetatf); + + /* dPt_dthetaf = Vmf*Vmt*(Gtf*sin_thetatf - Btf*cos_thetatf); */ + d2Pt_dthetaf_dthetat = Vmf * Vmt * (Gtf * cos_thetatf + Btf * sin_thetatf); + d2Pt_dthetaf_dVmt = Vmf * (Gtf * sin_thetatf - Btf * cos_thetatf); + d2Pt_dthetaf_dthetaf = Vmf * Vmt * (-Gtf * cos_thetatf - Btf * sin_thetatf); + d2Pt_dthetaf_dVmf = Vmt * (Gtf * sin_thetatf - Btf * cos_thetatf); + + /* dPt_dVmf = Vmt*(Gtf*cos_thetatf + Btf*sin_thetatf); */ + d2Pt_dVmf_dthetat = Vmt * (-Gtf * sin_thetatf + Btf * cos_thetatf); + d2Pt_dVmf_dVmt = (Gtf * cos_thetatf + Btf * sin_thetatf); + d2Pt_dVmf_dthetaf = Vmt * (Gtf * sin_thetatf - Btf * cos_thetatf); + d2Pt_dVmf_dVmf = 0.0; + + PetscScalar d2Qt_dthetaf_dthetaf, d2Qt_dthetaf_dVmf, d2Qt_dthetaf_dthetat, + d2Qt_dthetaf_dVmt; + PetscScalar d2Qt_dVmf_dthetaf, d2Qt_dVmf_dVmf, d2Qt_dVmf_dthetat, + d2Qt_dVmf_dVmt; + PetscScalar d2Qt_dthetat_dthetaf, d2Qt_dthetat_dVmf, d2Qt_dthetat_dthetat, + d2Qt_dthetat_dVmt; + PetscScalar d2Qt_dVmt_dthetaf, d2Qt_dVmt_dVmf, d2Qt_dVmt_dthetat, + d2Qt_dVmt_dVmt; + + /* dQt_dthetat = Vmf*Vmt*(Btf*sin_thetatf + Gtf*cos_thetatf); */ + d2Qt_dthetat_dthetat = Vmf * Vmt * (Btf * cos_thetatf - Gtf * sin_thetatf); + d2Qt_dthetat_dVmt = Vmf * (Btf * sin_thetatf + Gtf * cos_thetatf); + d2Qt_dthetat_dthetaf = Vmf * Vmt * (-Btf * cos_thetatf + Gtf * sin_thetatf); + d2Qt_dthetat_dVmf = Vmf * (Btf * sin_thetatf + Gtf * cos_thetatf); + + /* dQt_dVmt = -2*Btt*Vmt + Vmf*(-Btf*cos_thetatf + Gtf*sin_thetatf); */ + d2Qt_dVmt_dthetat = Vmf * (Btf * sin_thetatf + Gtf * cos_thetatf); + d2Qt_dVmt_dVmt = -2 * Btt; + d2Qt_dVmt_dthetaf = Vmf * (-Btf * sin_thetatf + Gtf * cos_thetatf); + d2Qt_dVmt_dVmf = (-Btf * cos_thetatf + Gtf * sin_thetatf); + + /* dQt_dthetaf = Vmf*Vmt*(-Btf*sin_thetatf - Gtf*cos_thetatf); */ + d2Qt_dthetaf_dthetat = Vmf * Vmt * (-Btf * cos_thetatf + Gtf * sin_thetatf); + d2Qt_dthetaf_dVmt = Vmf * (-Btf * sin_thetatf - Gtf * cos_thetatf); + d2Qt_dthetaf_dthetaf = Vmf * Vmt * (Btf * cos_thetatf - Gtf * sin_thetatf); + d2Qt_dthetaf_dVmf = Vmt * (-Btf * sin_thetatf - Gtf * cos_thetatf); + + /* dQt_dVmf = Vmt*(-Btf*cos_thetatf + Gtf*sin_thetatf); */ + d2Qt_dVmf_dthetat = Vmt * (Btf * sin_thetatf + Gtf * cos_thetatf); + d2Qt_dVmf_dVmt = (-Btf * cos_thetatf + Gtf * sin_thetatf); + d2Qt_dVmf_dthetaf = Vmt * (-Btf * sin_thetatf - Gtf * cos_thetatf); + d2Qt_dVmf_dVmf = 0.0; + + PetscScalar d2Sf2_dthetaf_dthetaf = 0.0, d2Sf2_dthetaf_dVmf = 0.0, + d2Sf2_dthetaf_dthetat = 0.0, d2Sf2_dthetaf_dVmt = 0.0; + PetscScalar d2St2_dthetaf_dthetaf = 0.0, d2St2_dthetaf_dVmf = 0.0, + d2St2_dthetaf_dthetat = 0.0, d2St2_dthetaf_dVmt = 0.0; + + d2Sf2_dthetaf_dthetaf = + 2 * dPf_dthetaf * dPf_dthetaf + dSf2_dPf * d2Pf_dthetaf_dthetaf + + 2 * dQf_dthetaf * dQf_dthetaf + dSf2_dQf * d2Qf_dthetaf_dthetaf; + d2Sf2_dthetaf_dVmf = + 2 * dPf_dVmf * dPf_dthetaf + dSf2_dPf * d2Pf_dthetaf_dVmf + + 2 * dQf_dVmf * dQf_dthetaf + dSf2_dQf * d2Qf_dthetaf_dVmf; + d2Sf2_dthetaf_dthetat = + 2 * dPf_dthetat * dPf_dthetaf + dSf2_dPf * d2Pf_dthetaf_dthetat + + 2 * dQf_dthetat * dQf_dthetaf + dSf2_dQf * d2Qf_dthetaf_dthetat; + d2Sf2_dthetaf_dVmt = + 2 * dPf_dVmt * dPf_dthetaf + dSf2_dPf * d2Pf_dthetaf_dVmt + + 2 * dQf_dVmt * dQf_dthetaf + dSf2_dQf * d2Qf_dthetaf_dVmt; + + d2St2_dthetaf_dthetaf = + 2 * dPt_dthetaf * dPt_dthetaf + dSt2_dPt * d2Pt_dthetaf_dthetaf + + 2 * dQt_dthetaf * dQt_dthetaf + dSt2_dQt * d2Qt_dthetaf_dthetaf; + d2St2_dthetaf_dVmf = + 2 * dPt_dVmf * dPt_dthetaf + dSt2_dPt * d2Pt_dthetaf_dVmf + + 2 * dQt_dVmf * dQt_dthetaf + dSt2_dQt * d2Qt_dthetaf_dVmf; + d2St2_dthetaf_dthetat = + 2 * dPt_dthetat * dPt_dthetaf + dSt2_dPt * d2Pt_dthetaf_dthetat + + 2 * dQt_dthetat * dQt_dthetaf + dSt2_dQt * d2Qt_dthetaf_dthetat; + d2St2_dthetaf_dVmt = + 2 * dPt_dVmt * dPt_dthetaf + dSt2_dPt * d2Pt_dthetaf_dVmt + + 2 * dQt_dVmt * dQt_dthetaf + dSt2_dQt * d2Qt_dthetaf_dVmt; + + lambda_gloc = lambda[gloc]; + lambda_gloc1 = lambda[gloc + 1]; + + val[0] = val[1] = val[2] = val[3] = 0.0; + col[0] = xlocglobf; + col[1] = xlocglobf + 1; + col[2] = xlocglobt; + col[3] = xlocglobt + 1; + row[0] = xlocglobf; + val[0] = lambda_gloc * d2Sf2_dthetaf_dthetaf + + lambda_gloc1 * d2St2_dthetaf_dthetaf; + val[1] = + lambda_gloc * d2Sf2_dthetaf_dVmf + lambda_gloc1 * d2St2_dthetaf_dVmf; + val[2] = lambda_gloc * d2Sf2_dthetaf_dthetat + + lambda_gloc1 * d2St2_dthetaf_dthetat; + val[3] = + lambda_gloc * d2Sf2_dthetaf_dVmt + lambda_gloc1 * d2St2_dthetaf_dVmt; + + ierr = MatSetValues(H, 1, row, 4, col, val, ADD_VALUES); + CHKERRQ(ierr); - PetscScalar d2Sf2_dVmf_dthetaf, d2Sf2_dVmf_dVmf, d2Sf2_dVmf_dthetat, - d2Sf2_dVmf_dVmt; - PetscScalar d2St2_dVmf_dthetaf, d2St2_dVmf_dVmf, d2St2_dVmf_dthetat, - d2St2_dVmf_dVmt; - - d2Sf2_dVmf_dthetaf = - 2 * dPf_dthetaf * dPf_dVmf + dSf2_dPf * d2Pf_dVmf_dthetaf + - 2 * dQf_dthetaf * dQf_dVmf + dSf2_dQf * d2Qf_dVmf_dthetaf; - d2Sf2_dVmf_dVmf = 2 * dPf_dVmf * dPf_dVmf + dSf2_dPf * d2Pf_dVmf_dVmf + - 2 * dQf_dVmf * dQf_dVmf + dSf2_dQf * d2Qf_dVmf_dVmf; - d2Sf2_dVmf_dthetat = - 2 * dPf_dthetat * dPf_dVmf + dSf2_dPf * d2Pf_dVmf_dthetat + - 2 * dQf_dthetat * dQf_dVmf + dSf2_dQf * d2Qf_dVmf_dthetat; - d2Sf2_dVmf_dVmt = 2 * dPf_dVmt * dPf_dVmf + dSf2_dPf * d2Pf_dVmf_dVmt + - 2 * dQf_dVmt * dQf_dVmf + dSf2_dQf * d2Qf_dVmf_dVmt; - - d2St2_dVmf_dthetaf = - 2 * dPt_dthetaf * dPt_dVmf + dSt2_dPt * d2Pt_dVmf_dthetaf + - 2 * dQt_dthetaf * dQt_dVmf + dSt2_dQt * d2Qt_dVmf_dthetaf; - d2St2_dVmf_dVmf = 2 * dPt_dVmf * dPt_dVmf + dSt2_dPt * d2Pt_dVmf_dVmf + - 2 * dQt_dVmf * dQt_dVmf + dSt2_dQt * d2Qt_dVmf_dVmf; - d2St2_dVmf_dthetat = - 2 * dPt_dthetat * dPt_dVmf + dSt2_dPt * d2Pt_dVmf_dthetat + - 2 * dQt_dthetat * dQt_dVmf + dSt2_dQt * d2Qt_dVmf_dthetat; - d2St2_dVmf_dVmt = 2 * dPt_dVmt * dPt_dVmf + dSt2_dPt * d2Pt_dVmf_dVmt + - 2 * dQt_dVmt * dQt_dVmf + dSt2_dQt * d2Qt_dVmf_dVmt; - - val[0] = val[1] = val[2] = val[3] = 0.0; - col[0] = xlocglobf; - col[1] = xlocglobf + 1; - col[2] = xlocglobt; - col[3] = xlocglobt + 1; - row[0] = xlocglobf + 1; - val[0] = lambda[gloc] * d2Sf2_dVmf_dthetaf + - lambda[gloc + 1] * d2St2_dVmf_dthetaf; - val[1] = - lambda[gloc] * d2Sf2_dVmf_dVmf + lambda[gloc + 1] * d2St2_dVmf_dVmf; - val[2] = lambda[gloc] * d2Sf2_dVmf_dthetat + - lambda[gloc + 1] * d2St2_dVmf_dthetat; - val[3] = - lambda[gloc] * d2Sf2_dVmf_dVmt + lambda[gloc + 1] * d2St2_dVmf_dVmt; - ierr = MatSetValues(H, 1, row, 4, col, val, ADD_VALUES); - CHKERRQ(ierr); + PetscScalar d2Sf2_dVmf_dthetaf, d2Sf2_dVmf_dVmf, d2Sf2_dVmf_dthetat, + d2Sf2_dVmf_dVmt; + PetscScalar d2St2_dVmf_dthetaf, d2St2_dVmf_dVmf, d2St2_dVmf_dthetat, + d2St2_dVmf_dVmt; + + d2Sf2_dVmf_dthetaf = + 2 * dPf_dthetaf * dPf_dVmf + dSf2_dPf * d2Pf_dVmf_dthetaf + + 2 * dQf_dthetaf * dQf_dVmf + dSf2_dQf * d2Qf_dVmf_dthetaf; + d2Sf2_dVmf_dVmf = 2 * dPf_dVmf * dPf_dVmf + dSf2_dPf * d2Pf_dVmf_dVmf + + 2 * dQf_dVmf * dQf_dVmf + dSf2_dQf * d2Qf_dVmf_dVmf; + d2Sf2_dVmf_dthetat = + 2 * dPf_dthetat * dPf_dVmf + dSf2_dPf * d2Pf_dVmf_dthetat + + 2 * dQf_dthetat * dQf_dVmf + dSf2_dQf * d2Qf_dVmf_dthetat; + d2Sf2_dVmf_dVmt = 2 * dPf_dVmt * dPf_dVmf + dSf2_dPf * d2Pf_dVmf_dVmt + + 2 * dQf_dVmt * dQf_dVmf + dSf2_dQf * d2Qf_dVmf_dVmt; + + d2St2_dVmf_dthetaf = + 2 * dPt_dthetaf * dPt_dVmf + dSt2_dPt * d2Pt_dVmf_dthetaf + + 2 * dQt_dthetaf * dQt_dVmf + dSt2_dQt * d2Qt_dVmf_dthetaf; + d2St2_dVmf_dVmf = 2 * dPt_dVmf * dPt_dVmf + dSt2_dPt * d2Pt_dVmf_dVmf + + 2 * dQt_dVmf * dQt_dVmf + dSt2_dQt * d2Qt_dVmf_dVmf; + d2St2_dVmf_dthetat = + 2 * dPt_dthetat * dPt_dVmf + dSt2_dPt * d2Pt_dVmf_dthetat + + 2 * dQt_dthetat * dQt_dVmf + dSt2_dQt * d2Qt_dVmf_dthetat; + d2St2_dVmf_dVmt = 2 * dPt_dVmt * dPt_dVmf + dSt2_dPt * d2Pt_dVmf_dVmt + + 2 * dQt_dVmt * dQt_dVmf + dSt2_dQt * d2Qt_dVmf_dVmt; + + val[0] = val[1] = val[2] = val[3] = 0.0; + col[0] = xlocglobf; + col[1] = xlocglobf + 1; + col[2] = xlocglobt; + col[3] = xlocglobt + 1; + row[0] = xlocglobf + 1; + val[0] = + lambda_gloc * d2Sf2_dVmf_dthetaf + lambda_gloc1 * d2St2_dVmf_dthetaf; + val[1] = lambda_gloc * d2Sf2_dVmf_dVmf + lambda_gloc1 * d2St2_dVmf_dVmf; + val[2] = + lambda_gloc * d2Sf2_dVmf_dthetat + lambda_gloc1 * d2St2_dVmf_dthetat; + val[3] = lambda_gloc * d2Sf2_dVmf_dVmt + lambda_gloc1 * d2St2_dVmf_dVmt; + ierr = MatSetValues(H, 1, row, 4, col, val, ADD_VALUES); + CHKERRQ(ierr); - PetscScalar d2Sf2_dthetat_dthetaf, d2Sf2_dthetat_dVmf, - d2Sf2_dthetat_dthetat, d2Sf2_dthetat_dVmt; - PetscScalar d2St2_dthetat_dthetaf, d2St2_dthetat_dVmf, - d2St2_dthetat_dthetat, d2St2_dthetat_dVmt; - - d2Sf2_dthetat_dthetaf = - 2 * dPf_dthetaf * dPf_dthetat + dSf2_dPf * d2Pf_dthetat_dthetaf + - 2 * dQf_dthetat * dQf_dthetaf + dSf2_dQf * d2Qf_dthetat_dthetaf; - d2Sf2_dthetat_dVmf = - 2 * dPf_dVmf * dPf_dthetat + dSf2_dPf * d2Pf_dthetat_dVmf + - 2 * dQf_dthetat * dQf_dVmf + dSf2_dQf * d2Qf_dthetat_dVmf; - d2Sf2_dthetat_dthetat = - 2 * dPf_dthetat * dPf_dthetat + dSf2_dPf * d2Pf_dthetat_dthetat + - 2 * dQf_dthetat * dQf_dthetat + dSf2_dQf * d2Qf_dthetat_dthetat; - d2Sf2_dthetat_dVmt = - 2 * dPf_dVmt * dPf_dthetat + dSf2_dPf * d2Pf_dthetat_dVmt + - 2 * dQf_dthetat * dQf_dVmt + dSf2_dQf * d2Qf_dthetat_dVmt; - - d2St2_dthetat_dthetaf = - 2 * dPt_dthetaf * dPt_dthetat + dSt2_dPt * d2Pt_dthetat_dthetaf + - 2 * dQt_dthetaf * dQt_dthetat + dSt2_dQt * d2Qt_dthetat_dthetaf; - d2St2_dthetat_dVmf = - 2 * dPt_dVmf * dPt_dthetat + dSt2_dPt * d2Pt_dthetat_dVmf + - 2 * dQt_dVmf * dQt_dthetat + dSt2_dQt * d2Qt_dthetat_dVmf; - d2St2_dthetat_dthetat = - 2 * dPt_dthetat * dPt_dthetat + dSt2_dPt * d2Pt_dthetat_dthetat + - 2 * dQt_dthetat * dQt_dthetat + dSt2_dQt * d2Qt_dthetat_dthetat; - d2St2_dthetat_dVmt = - 2 * dPt_dVmt * dPt_dthetat + dSt2_dPt * d2Pt_dthetat_dVmt + - 2 * dQt_dVmt * dQt_dthetat + dSt2_dQt * d2Qt_dthetat_dVmt; - - val[0] = val[1] = val[2] = val[3] = 0.0; - col[0] = xlocglobf; - col[1] = xlocglobf + 1; - col[2] = xlocglobt; - col[3] = xlocglobt + 1; - row[0] = xlocglobt; - - val[0] = lambda[gloc] * d2Sf2_dthetat_dthetaf + - lambda[gloc + 1] * d2St2_dthetat_dthetaf; - val[1] = lambda[gloc] * d2Sf2_dthetat_dVmf + - lambda[gloc + 1] * d2St2_dthetat_dVmf; - val[2] = lambda[gloc] * d2Sf2_dthetat_dthetat + - lambda[gloc + 1] * d2St2_dthetat_dthetat; - val[3] = lambda[gloc] * d2Sf2_dthetat_dVmt + - lambda[gloc + 1] * d2St2_dthetat_dVmt; - - ierr = MatSetValues(H, 1, row, 4, col, val, ADD_VALUES); - CHKERRQ(ierr); + PetscScalar d2Sf2_dthetat_dthetaf, d2Sf2_dthetat_dVmf, + d2Sf2_dthetat_dthetat, d2Sf2_dthetat_dVmt; + PetscScalar d2St2_dthetat_dthetaf, d2St2_dthetat_dVmf, + d2St2_dthetat_dthetat, d2St2_dthetat_dVmt; + + d2Sf2_dthetat_dthetaf = + 2 * dPf_dthetaf * dPf_dthetat + dSf2_dPf * d2Pf_dthetat_dthetaf + + 2 * dQf_dthetat * dQf_dthetaf + dSf2_dQf * d2Qf_dthetat_dthetaf; + d2Sf2_dthetat_dVmf = + 2 * dPf_dVmf * dPf_dthetat + dSf2_dPf * d2Pf_dthetat_dVmf + + 2 * dQf_dthetat * dQf_dVmf + dSf2_dQf * d2Qf_dthetat_dVmf; + d2Sf2_dthetat_dthetat = + 2 * dPf_dthetat * dPf_dthetat + dSf2_dPf * d2Pf_dthetat_dthetat + + 2 * dQf_dthetat * dQf_dthetat + dSf2_dQf * d2Qf_dthetat_dthetat; + d2Sf2_dthetat_dVmt = + 2 * dPf_dVmt * dPf_dthetat + dSf2_dPf * d2Pf_dthetat_dVmt + + 2 * dQf_dthetat * dQf_dVmt + dSf2_dQf * d2Qf_dthetat_dVmt; + + d2St2_dthetat_dthetaf = + 2 * dPt_dthetaf * dPt_dthetat + dSt2_dPt * d2Pt_dthetat_dthetaf + + 2 * dQt_dthetaf * dQt_dthetat + dSt2_dQt * d2Qt_dthetat_dthetaf; + d2St2_dthetat_dVmf = + 2 * dPt_dVmf * dPt_dthetat + dSt2_dPt * d2Pt_dthetat_dVmf + + 2 * dQt_dVmf * dQt_dthetat + dSt2_dQt * d2Qt_dthetat_dVmf; + d2St2_dthetat_dthetat = + 2 * dPt_dthetat * dPt_dthetat + dSt2_dPt * d2Pt_dthetat_dthetat + + 2 * dQt_dthetat * dQt_dthetat + dSt2_dQt * d2Qt_dthetat_dthetat; + d2St2_dthetat_dVmt = + 2 * dPt_dVmt * dPt_dthetat + dSt2_dPt * d2Pt_dthetat_dVmt + + 2 * dQt_dVmt * dQt_dthetat + dSt2_dQt * d2Qt_dthetat_dVmt; + + val[0] = val[1] = val[2] = val[3] = 0.0; + col[0] = xlocglobf; + col[1] = xlocglobf + 1; + col[2] = xlocglobt; + col[3] = xlocglobt + 1; + row[0] = xlocglobt; + + val[0] = lambda_gloc * d2Sf2_dthetat_dthetaf + + lambda_gloc1 * d2St2_dthetat_dthetaf; + val[1] = + lambda_gloc * d2Sf2_dthetat_dVmf + lambda_gloc1 * d2St2_dthetat_dVmf; + val[2] = lambda_gloc * d2Sf2_dthetat_dthetat + + lambda_gloc1 * d2St2_dthetat_dthetat; + val[3] = + lambda_gloc * d2Sf2_dthetat_dVmt + lambda_gloc1 * d2St2_dthetat_dVmt; + + ierr = MatSetValues(H, 1, row, 4, col, val, ADD_VALUES); + CHKERRQ(ierr); - PetscScalar d2Sf2_dVmt_dthetaf, d2Sf2_dVmt_dVmf, d2Sf2_dVmt_dthetat, - d2Sf2_dVmt_dVmt; - PetscScalar d2St2_dVmt_dthetaf, d2St2_dVmt_dVmf, d2St2_dVmt_dthetat, - d2St2_dVmt_dVmt; - - d2Sf2_dVmt_dthetaf = - 2 * dPf_dthetaf * dPf_dVmt + dSf2_dPf * d2Pf_dVmt_dthetaf + - 2 * dQf_dthetaf * dQf_dVmt + dSf2_dQf * d2Qf_dVmt_dthetaf; - d2Sf2_dVmt_dVmf = 2 * dPf_dVmf * dPf_dVmt + dSf2_dPf * d2Pf_dVmt_dVmf + - 2 * dQf_dVmf * dQf_dVmt + dSf2_dQf * d2Qf_dVmt_dVmf; - d2Sf2_dVmt_dthetat = - 2 * dPf_dthetat * dPf_dVmt + dSf2_dPf * d2Pf_dVmt_dthetat + - 2 * dQf_dthetat * dQf_dVmt + dSf2_dQf * d2Qf_dVmt_dthetat; - d2Sf2_dVmt_dVmt = 2 * dPf_dVmt * dPf_dVmt + dSf2_dPf * d2Pf_dVmt_dVmt + - 2 * dQf_dVmt * dQf_dVmt + dSf2_dQf * d2Qf_dVmt_dVmt; - - d2St2_dVmt_dthetaf = - 2 * dPt_dthetaf * dPt_dVmt + dSt2_dPt * d2Pt_dVmt_dthetaf + - 2 * dQt_dthetaf * dQt_dVmt + dSt2_dQt * d2Qt_dVmt_dthetaf; - d2St2_dVmt_dVmf = 2 * dPt_dVmf * dPt_dVmt + dSt2_dPt * d2Pt_dVmt_dVmf + - 2 * dQt_dVmf * dQt_dVmt + dSt2_dQt * d2Qt_dVmt_dVmf; - d2St2_dVmt_dthetat = - 2 * dPt_dthetat * dPt_dVmt + dSt2_dPt * d2Pt_dVmt_dthetat + - 2 * dQt_dthetat * dQt_dVmt + dSt2_dQt * d2Qt_dVmt_dthetat; - d2St2_dVmt_dVmt = 2 * dPt_dVmt * dPt_dVmt + dSt2_dPt * d2Pt_dVmt_dVmt + - 2 * dQt_dVmt * dQt_dVmt + dSt2_dQt * d2Qt_dVmt_dVmt; - - val[0] = val[1] = val[2] = val[3] = 0.0; - col[0] = xlocglobf; - col[1] = xlocglobf + 1; - col[2] = xlocglobt; - col[3] = xlocglobt + 1; - row[0] = xlocglobt + 1; - - val[0] = lambda[gloc] * d2Sf2_dVmt_dthetaf + - lambda[gloc + 1] * d2St2_dVmt_dthetaf; - val[1] = - lambda[gloc] * d2Sf2_dVmt_dVmf + lambda[gloc + 1] * d2St2_dVmt_dVmf; - val[2] = lambda[gloc] * d2Sf2_dVmt_dthetat + - lambda[gloc + 1] * d2St2_dVmt_dthetat; - val[3] = - lambda[gloc] * d2Sf2_dVmt_dVmt + lambda[gloc + 1] * d2St2_dVmt_dVmt; - - ierr = MatSetValues(H, 1, row, 4, col, val, ADD_VALUES); - CHKERRQ(ierr); - // Must be inside for loop since there's a continue condition - flps += (185 + (16 * EXAGO_FLOPS_SINOP) + (16 * EXAGO_FLOPS_COSOP)); - } + PetscScalar d2Sf2_dVmt_dthetaf, d2Sf2_dVmt_dVmf, d2Sf2_dVmt_dthetat, + d2Sf2_dVmt_dVmt; + PetscScalar d2St2_dVmt_dthetaf, d2St2_dVmt_dVmf, d2St2_dVmt_dthetat, + d2St2_dVmt_dVmt; + + d2Sf2_dVmt_dthetaf = + 2 * dPf_dthetaf * dPf_dVmt + dSf2_dPf * d2Pf_dVmt_dthetaf + + 2 * dQf_dthetaf * dQf_dVmt + dSf2_dQf * d2Qf_dVmt_dthetaf; + d2Sf2_dVmt_dVmf = 2 * dPf_dVmf * dPf_dVmt + dSf2_dPf * d2Pf_dVmt_dVmf + + 2 * dQf_dVmf * dQf_dVmt + dSf2_dQf * d2Qf_dVmt_dVmf; + d2Sf2_dVmt_dthetat = + 2 * dPf_dthetat * dPf_dVmt + dSf2_dPf * d2Pf_dVmt_dthetat + + 2 * dQf_dthetat * dQf_dVmt + dSf2_dQf * d2Qf_dVmt_dthetat; + d2Sf2_dVmt_dVmt = 2 * dPf_dVmt * dPf_dVmt + dSf2_dPf * d2Pf_dVmt_dVmt + + 2 * dQf_dVmt * dQf_dVmt + dSf2_dQf * d2Qf_dVmt_dVmt; + + d2St2_dVmt_dthetaf = + 2 * dPt_dthetaf * dPt_dVmt + dSt2_dPt * d2Pt_dVmt_dthetaf + + 2 * dQt_dthetaf * dQt_dVmt + dSt2_dQt * d2Qt_dVmt_dthetaf; + d2St2_dVmt_dVmf = 2 * dPt_dVmf * dPt_dVmt + dSt2_dPt * d2Pt_dVmt_dVmf + + 2 * dQt_dVmf * dQt_dVmt + dSt2_dQt * d2Qt_dVmt_dVmf; + d2St2_dVmt_dthetat = + 2 * dPt_dthetat * dPt_dVmt + dSt2_dPt * d2Pt_dVmt_dthetat + + 2 * dQt_dthetat * dQt_dVmt + dSt2_dQt * d2Qt_dVmt_dthetat; + d2St2_dVmt_dVmt = 2 * dPt_dVmt * dPt_dVmt + dSt2_dPt * d2Pt_dVmt_dVmt + + 2 * dQt_dVmt * dQt_dVmt + dSt2_dQt * d2Qt_dVmt_dVmt; + + val[0] = val[1] = val[2] = val[3] = 0.0; + col[0] = xlocglobf; + col[1] = xlocglobf + 1; + col[2] = xlocglobt; + col[3] = xlocglobt + 1; + row[0] = xlocglobt + 1; + + val[0] = + lambda_gloc * d2Sf2_dVmt_dthetaf + lambda_gloc1 * d2St2_dVmt_dthetaf; + val[1] = lambda_gloc * d2Sf2_dVmt_dVmf + lambda_gloc1 * d2St2_dVmt_dVmf; + val[2] = + lambda_gloc * d2Sf2_dVmt_dthetat + lambda_gloc1 * d2St2_dVmt_dthetat; + val[3] = lambda_gloc * d2Sf2_dVmt_dVmt + lambda_gloc1 * d2St2_dVmt_dVmt; + + ierr = MatSetValues(H, 1, row, 4, col, val, ADD_VALUES); + CHKERRQ(ierr); + // Must be inside for loop since there's a continue condition + flps += (185 + (16 * EXAGO_FLOPS_SINOP) + (16 * EXAGO_FLOPS_COSOP)); } ierr = VecRestoreArrayRead(X, &x); @@ -2804,6 +2918,7 @@ PetscErrorCode OPFLOWSolutionToPS_PBPOL(OPFLOW opflow) { PetscInt loc, gloc = 0; PetscScalar Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt; PetscScalar Vmf, Vmt, thetaf, thetat, thetaft, thetatf; + PetscScalar sin_thetaft, cos_thetaft, sin_thetatf, cos_thetatf; PetscScalar Pf, Qf, Pt, Qt; PSBUS busf, bust; const PSBUS *connbuses; @@ -2834,8 +2949,8 @@ PetscErrorCode OPFLOWSolutionToPS_PBPOL(OPFLOW opflow) { bus->vm = x[loc + 1]; gloc = bus->starteqloc; - bus->mult_pmis = lambdae[gloc]; - bus->mult_qmis = lambdae[gloc + 1]; + bus->mult_pmis = lambdae[gloc] / ps->MVAbase; + bus->mult_qmis = lambdae[gloc + 1] / ps->MVAbase; if (opflow->include_powerimbalance_variables) { loc = bus->startxpimbloc; @@ -2879,40 +2994,51 @@ PetscErrorCode OPFLOWSolutionToPS_PBPOL(OPFLOW opflow) { continue; } - Gff = line->yff[0]; - Bff = line->yff[1]; - Gft = line->yft[0]; - Bft = line->yft[1]; - Gtf = line->ytf[0]; - Btf = line->ytf[1]; - Gtt = line->ytt[0]; - Btt = line->ytt[1]; + if (!line->isdcline) { + Gff = line->yff[0]; + Bff = line->yff[1]; + Gft = line->yft[0]; + Bft = line->yft[1]; + Gtf = line->ytf[0]; + Btf = line->ytf[1]; + Gtt = line->ytt[0]; + Btt = line->ytt[1]; - ierr = PSLINEGetConnectedBuses(line, &connbuses); - CHKERRQ(ierr); - busf = connbuses[0]; - bust = connbuses[1]; + ierr = PSLINEGetConnectedBuses(line, &connbuses); + CHKERRQ(ierr); + busf = connbuses[0]; + bust = connbuses[1]; - xlocf = busf->startxVloc; - xloct = bust->startxVloc; + xlocf = busf->startxVloc; + xloct = bust->startxVloc; - thetaf = x[xlocf]; - Vmf = x[xlocf + 1]; - thetat = x[xloct]; - Vmt = x[xloct + 1]; - thetaft = thetaf - thetat; - thetatf = thetat - thetaf; + thetaf = x[xlocf]; + Vmf = x[xlocf + 1]; + thetat = x[xloct]; + Vmt = x[xloct + 1]; + thetaft = thetaf - thetat; + thetatf = thetat - thetaf; + sin_thetaft = sin(thetaft); + cos_thetaft = cos(thetaft); + sin_thetatf = sin(thetatf); + cos_thetatf = cos(thetatf); - Pf = - Gff * Vmf * Vmf + Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - Qf = -Bff * Vmf * Vmf + - Vmf * Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); + Pf = + Gff * Vmf * Vmf + Vmf * Vmt * (Gft * cos_thetaft + Bft * sin_thetaft); + Qf = -Bff * Vmf * Vmf + + Vmf * Vmt * (-Bft * cos_thetaft + Gft * sin_thetaft); - Pt = - Gtt * Vmt * Vmt + Vmt * Vmf * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - Qt = -Btt * Vmt * Vmt + - Vmt * Vmf * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); + Pt = + Gtt * Vmt * Vmt + Vmt * Vmf * (Gtf * cos_thetatf + Btf * sin_thetatf); + Qt = -Btt * Vmt * Vmt + + Vmt * Vmf * (-Btf * cos_thetatf + Gtf * sin_thetatf); + } else if (line->isdcline) { + Pf = x[line->startxdcloc]; + Qf = x[line->startxdcloc + 1]; + Qt = -x[line->startxdcloc + 2]; + Pt = -1 * (Pf - (line->loss0 + line->loss1 * Pf)); + } line->pf = Pf; line->qf = Qf; line->pt = Pt; @@ -2923,9 +3049,13 @@ PetscErrorCode OPFLOWSolutionToPS_PBPOL(OPFLOW opflow) { for (i = 0; i < opflow->nlinesmon; i++) { line = &ps->line[opflow->linesmon[i]]; + if (line->isdcline) + continue; gloc = line->startineqloc; - line->mult_sf = lambdai[gloc]; - line->mult_st = lambdai[gloc + 1]; + line->mult_sf = + (2 * lambdai[gloc] * line->rateA / ps->MVAbase) / ps->MVAbase; + line->mult_st = + (2 * lambdai[gloc + 1] * line->rateA / ps->MVAbase) / ps->MVAbase; } ierr = VecRestoreArrayRead(X, &x); @@ -3035,18 +3165,200 @@ PetscErrorCode OPFLOWModelSetUp_PBPOL(OPFLOW opflow) { } } - for (i = 0; i < opflow->nlinesmon; i++) { - line = &ps->line[opflow->linesmon[i]]; + for (i = 0; i < ps->nline; i++) { + line = &ps->line[i]; + if (!line->status) + continue; + + if (!line->isdcline) { + /* Set starting location for slack variable */ + if (opflow->allow_lineflow_violation) { + line->startxslackloc = loc; + } + line->startineqloc = ineqloc; + ineqloc += line->nconineq; + } else if (line->isdcline) { + ierr = PSLINEGetVariableLocation(line, &loc); + CHKERRQ(ierr); + line->startxdcloc = loc; + } + } + + PetscFunctionReturn(0); +} + +PetscErrorCode OPFLOWCheckConstraints_PBPOL(OPFLOW opflow) { + PetscErrorCode ierr; + PS ps = opflow->ps; + PSBUS bus; + PSLINE line; + PSGEN gen; + PSLOAD load; + PetscInt i, j; + + PetscFunctionBegin; + + for (i = 0; i < ps->nbus; i++) { + + bus = &ps->bus[i]; + + // Check for bus voltage bounds + if (bus->vm < bus->Vmin) { + ierr = PetscPrintf(PETSC_COMM_SELF, + "Bus %d voltage lower bound not satisfied: Vm = " + "%10.8f < Vmin = %10.8f\n", + bus->bus_i, bus->vm, bus->Vmin); + CHKERRQ(ierr); + } else if (bus->vm > bus->Vmax) { + ierr = PetscPrintf(PETSC_COMM_SELF, + "Bus %d voltage upper bound not satisfied: Vm = " + "%10.8f > Vmax = %10.8f\n", + bus->bus_i, bus->vm, bus->Vmax); + CHKERRQ(ierr); + } + + // Check for real and reactive power generator bounds + for (j = 0; j < bus->ngen; j++) { + ierr = PSBUSGetGen(bus, j, &gen); + CHKERRQ(ierr); + if (!gen->status) + continue; - ierr = PSLINEGetVariableLocation(line, &loc); + PetscScalar pgmin = gen->pb; + if (gen->isrenewable && gen->pt > 0) { + pgmin = 0.0; + } + + if (gen->pg < pgmin) { + ierr = PetscPrintf(PETSC_COMM_SELF, + "Generator %s on bus %d real power lower bound not " + "satisfied: Pg = %10.8f < Pgmin = %10.8f\n", + gen->id, bus->bus_i, gen->pg, pgmin); + CHKERRQ(ierr); + } else if (gen->pg > gen->pt) { + ierr = PetscPrintf(PETSC_COMM_SELF, + "Generator %s on bus %d real power uper bound not " + "satisfied: Pg = %10.8f > Pgmax = %10.8f\n", + gen->id, bus->bus_i, gen->pg, gen->pt); + CHKERRQ(ierr); + } + + if (gen->qg < gen->qb) { + ierr = PetscPrintf(PETSC_COMM_SELF, + "Generator %s on bus %d reactive power lower bound " + "not satisfied: Qg = %10.8f < Qgmin = %10.8f\n", + gen->id, bus->bus_i, gen->qg, gen->qb); + CHKERRQ(ierr); + } else if (gen->qg > gen->qt) { + ierr = PetscPrintf(PETSC_COMM_SELF, + "Generator %s on bus %d reactive power bound not " + "satisfied: Qg = %10.8f > Qgmax = %10.8f\n", + gen->id, bus->bus_i, gen->qg, gen->qt); + CHKERRQ(ierr); + } + } + + /* Equality constraints */ + PetscScalar misp = 0.0, misq = 0.0; + + misp += bus->vm * bus->vm * bus->gl; + misq += -bus->vm * bus->vm * bus->bl; + + if (opflow->include_powerimbalance_variables) { + misp += bus->pimb; + misq += bus->qimb; + } + + for (j = 0; j < bus->ngen; j++) { + ierr = PSBUSGetGen(bus, j, &gen); + CHKERRQ(ierr); + if (!gen->status) + continue; + + misp += -gen->pg; + misq += -gen->qg; + } + + for (j = 0; j < bus->nload; j++) { + ierr = PSBUSGetLoad(bus, j, &load); + CHKERRQ(ierr); + if (!load->status) + continue; + + misp += load->pl; + misq += load->ql; + + if (opflow->include_loadloss_variables) { + misp -= load->pl_loss; + misq -= load->ql_loss; + } + } + + PetscInt nconnlines; + const PSLINE *connlines; + PSBUS busf; + const PSBUS *connbuses; + + ierr = PSBUSGetSupportingLines(bus, &nconnlines, &connlines); CHKERRQ(ierr); - /* Set starting location for slack variable */ - if (opflow->allow_lineflow_violation) { - line->startxslackloc = loc; + for (j = 0; j < nconnlines; j++) { + line = connlines[j]; + if (!line->status) + continue; + + ierr = PSLINEGetConnectedBuses(line, &connbuses); + CHKERRQ(ierr); + busf = connbuses[0]; + + if (bus == busf) { + misp += line->pf; + misq += line->qf; + } else { + misp += line->pt; + misq += line->qt; + } } - line->startineqloc = ineqloc; - ineqloc += line->nconineq; + if (PetscAbsScalar(misp) > 1.0) { + ierr = PetscPrintf(PETSC_COMM_SELF, + "Bus %d real power balance mismatch: %10.8f\n", + bus->bus_i, misp); + CHKERRQ(ierr); + } else if (PetscAbsScalar(misq) > 1.0) { + ierr = PetscPrintf(PETSC_COMM_SELF, + "Bus %d reactive power balance mismatch: %10.8f\n", + bus->bus_i, misq); + CHKERRQ(ierr); + } + } + + /* Check for line limit violations */ + for (i = 0; i < ps->nline; i++) { + line = &ps->line[i]; + + if (!line->status || line->isdcline) + continue; + + PetscScalar Sft, Stf; + + Sft = ps->MVAbase * + PetscSqrtScalar(line->pf * line->pf + line->qf * line->qf); + Stf = ps->MVAbase * + PetscSqrtScalar(line->pt * line->pt + line->qt * line->qt); + + if (Sft > line->rateA) { + ierr = PetscPrintf(PETSC_COMM_SELF, + "Line %d -- %d with id %s from flow bound not " + "satisfied: Sft = %10.8f > SrateA = %10.8f\n", + line->fbus, line->tbus, line->ckt, Sft, line->rateA); + CHKERRQ(ierr); + } else if (Stf > line->rateA) { + ierr = PetscPrintf(PETSC_COMM_SELF, + "Line %d -- %d with id %s from flow bound not " + "satisfied: Stf = %10.8f > SrateA = %10.8f\n", + line->fbus, line->tbus, line->ckt, Stf, line->rateA); + CHKERRQ(ierr); + } } PetscFunctionReturn(0); @@ -3077,6 +3389,7 @@ PetscErrorCode OPFLOWModelCreate_PBPOL(OPFLOW opflow) { OPFLOWComputeEqualityConstraints_PBPOL; opflow->modelops.computeinequalityconstraints = OPFLOWComputeInequalityConstraints_PBPOL; + opflow->modelops.checkconstraints = OPFLOWCheckConstraints_PBPOL; opflow->modelops.computeequalityconstraintjacobian = OPFLOWComputeEqualityConstraintJacobian_PBPOL; opflow->modelops.computeinequalityconstraintjacobian = diff --git a/src/opflow/solver/ipopt/opflow_ipopt.cpp b/src/opflow/solver/ipopt/opflow_ipopt.cpp index 82ea7cb6b..1b566d613 100644 --- a/src/opflow/solver/ipopt/opflow_ipopt.cpp +++ b/src/opflow/solver/ipopt/opflow_ipopt.cpp @@ -543,6 +543,9 @@ PetscErrorCode OPFLOWSolverSetUp_IPOPT(OPFLOW opflow) { { AddIpoptNumOption(ipopt->nlp, (char *)"tol", opflow->tolerance); AddIpoptIntOption(ipopt->nlp, (char *)"max_iter", 5000); + AddIpoptStrOption(ipopt->nlp, (char *)"nlp_scaling_method", + (char *)"gradient-based"); + /* AddIpoptStrOption(ipopt->nlp, (char *)"mu_strategy", (char *)"monotone"); AddIpoptStrOption(ipopt->nlp, (char *)"fixed_variable_treatment", (char *)"relax_bounds"); @@ -551,6 +554,7 @@ PetscErrorCode OPFLOWSolverSetUp_IPOPT(OPFLOW opflow) { AddIpoptNumOption(ipopt->nlp, (char *)"residual_ratio_max", 1e3); AddIpoptNumOption(ipopt->nlp, (char *)"residual_ratio_singular", 1e4); AddIpoptNumOption(ipopt->nlp, (char *)"bound_relax_factor", 1e-6); + */ } /* Add intermediate callback function to get the solver info diff --git a/src/pflow/pflow.cpp b/src/pflow/pflow.cpp index a1d58defb..bc34b9c40 100644 --- a/src/pflow/pflow.cpp +++ b/src/pflow/pflow.cpp @@ -178,7 +178,7 @@ PetscErrorCode PFLOWJacobian(SNES snes, Vec X, Mat J, Mat Jpre, void *ctx) { Vec localX; const PetscScalar *xarr; PetscBool ghostbus; - PetscInt i, k; + PetscInt i, j, k; PetscInt flps = 0; PetscFunctionBegin; @@ -233,13 +233,22 @@ PetscErrorCode PFLOWJacobian(SNES snes, Vec X, Mat J, Mat Jpre, void *ctx) { val[0] = 0.0; val[1] = 2 * Vm * bus->gl; val[2] = 0.0; + val[3] = 0.0; flps += 2; if (bus->ide != PV_BUS) { val[3] = -2 * Vm * bus->bl; /* Partial derivative for shunt contribution */ flps += 2; - } else - val[3] = 1.0; /* Partial derivative of voltage magnitude constraint */ + } else { + for (j = 0; j < bus->ngen; j++) { + PSGEN gen; + ierr = PSBUSGetGen(bus, j, &gen); + CHKERRQ(ierr); + if (gen->status) + val[3] += + 1.0; /* Partial derivative of voltage magnitude constraint */ + } + } ierr = MatSetValues(J, 2, row, 2, col, val, ADD_VALUES); CHKERRQ(ierr); } @@ -257,16 +266,6 @@ PetscErrorCode PFLOWJacobian(SNES snes, Vec X, Mat J, Mat Jpre, void *ctx) { line = connlines[k]; if (!line->status) continue; - PetscScalar Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt; - Gff = line->yff[0]; - Bff = line->yff[1]; - Gft = line->yft[0]; - Bft = line->yft[1]; - Gtf = line->ytf[0]; - Btf = line->ytf[1]; - Gtt = line->ytt[0]; - Btt = line->ytt[1]; - const PSBUS *connbuses; PSBUS busf, bust; PetscInt locglobf, locglobt, locf, loct; @@ -296,62 +295,89 @@ PetscErrorCode PFLOWJacobian(SNES snes, Vec X, Mat J, Mat Jpre, void *ctx) { thetatf = thetat - thetaf; flps += 2; - if (bus == busf) { - if (bus->ide != REF_BUS) { - row[0] = locglobf; - col[0] = locglobf; - col[1] = locglobf + 1; - col[2] = locglobt; - col[3] = locglobt + 1; - val[0] = Vmf * Vmt * (-Gft * sin(thetaft) + Bft * cos(thetaft)); - val[1] = - 2 * Gff * Vmf + Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - val[2] = Vmf * Vmt * (Gft * sin(thetaft) - Bft * cos(thetaft)); - val[3] = Vmf * (Gft * cos(thetaft) + Bft * sin(thetaft)); - flps += 21 + (4 * EXAGO_FLOPS_SINOP) + (4 * EXAGO_FLOPS_COSOP); - ierr = MatSetValues(J, 1, row, 4, col, val, ADD_VALUES); - CHKERRQ(ierr); - - if (bus->ide != PV_BUS) { - row[0] = locglobf + 1; - val[0] = Vmf * Vmt * (Bft * sin(thetaft) + Gft * cos(thetaft)); - val[1] = -2 * Bff * Vmf + - Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); - val[2] = Vmf * Vmt * (-Bft * sin(thetaft) - Gft * cos(thetaft)); - val[3] = Vmf * (-Bft * cos(thetaft) + Gft * sin(thetaft)); + if (!line->isdcline) { + PetscScalar Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt; + Gff = line->yff[0]; + Bff = line->yff[1]; + Gft = line->yft[0]; + Bft = line->yft[1]; + Gtf = line->ytf[0]; + Btf = line->ytf[1]; + Gtt = line->ytt[0]; + Btt = line->ytt[1]; + + if (bus == busf) { + if (bus->ide != REF_BUS) { + row[0] = locglobf; + col[0] = locglobf; + col[1] = locglobf + 1; + col[2] = locglobt; + col[3] = locglobt + 1; + val[0] = Vmf * Vmt * (-Gft * sin(thetaft) + Bft * cos(thetaft)); + val[1] = + 2 * Gff * Vmf + Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); + val[2] = Vmf * Vmt * (Gft * sin(thetaft) - Bft * cos(thetaft)); + val[3] = Vmf * (Gft * cos(thetaft) + Bft * sin(thetaft)); flps += 21 + (4 * EXAGO_FLOPS_SINOP) + (4 * EXAGO_FLOPS_COSOP); ierr = MatSetValues(J, 1, row, 4, col, val, ADD_VALUES); CHKERRQ(ierr); - } - } - } else { - if (bus->ide != REF_BUS) { - row[0] = locglobt; - col[0] = locglobt; - col[1] = locglobt + 1; - col[2] = locglobf; - col[3] = locglobf + 1; - val[0] = Vmt * Vmf * (-Gtf * sin(thetatf) + Btf * cos(thetatf)); - val[1] = - 2 * Gtt * Vmt + Vmf * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - val[2] = Vmt * Vmf * (Gtf * sin(thetatf) - Btf * cos(thetatf)); - val[3] = Vmt * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - flps += 21 + (4 * EXAGO_FLOPS_SINOP) + (4 * EXAGO_FLOPS_COSOP); - ierr = MatSetValues(J, 1, row, 4, col, val, ADD_VALUES); - CHKERRQ(ierr); - if (bus->ide != PV_BUS) { - row[0] = locglobt + 1; - val[0] = Vmt * Vmf * (Btf * sin(thetatf) + Gtf * cos(thetatf)); - val[1] = -2 * Btt * Vmt + - Vmf * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - val[2] = Vmt * Vmf * (-Btf * sin(thetatf) - Gtf * cos(thetatf)); - val[3] = Vmt * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); + if (bus->ide != PV_BUS) { + row[0] = locglobf + 1; + val[0] = Vmf * Vmt * (Bft * sin(thetaft) + Gft * cos(thetaft)); + val[1] = -2 * Bff * Vmf + + Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); + val[2] = Vmf * Vmt * (-Bft * sin(thetaft) - Gft * cos(thetaft)); + val[3] = Vmf * (-Bft * cos(thetaft) + Gft * sin(thetaft)); + flps += 21 + (4 * EXAGO_FLOPS_SINOP) + (4 * EXAGO_FLOPS_COSOP); + ierr = MatSetValues(J, 1, row, 4, col, val, ADD_VALUES); + CHKERRQ(ierr); + } + } + } else { + if (bus->ide != REF_BUS) { + row[0] = locglobt; + col[0] = locglobt; + col[1] = locglobt + 1; + col[2] = locglobf; + col[3] = locglobf + 1; + val[0] = Vmt * Vmf * (-Gtf * sin(thetatf) + Btf * cos(thetatf)); + val[1] = + 2 * Gtt * Vmt + Vmf * (Gtf * cos(thetatf) + Btf * sin(thetatf)); + val[2] = Vmt * Vmf * (Gtf * sin(thetatf) - Btf * cos(thetatf)); + val[3] = Vmt * (Gtf * cos(thetatf) + Btf * sin(thetatf)); flps += 21 + (4 * EXAGO_FLOPS_SINOP) + (4 * EXAGO_FLOPS_COSOP); ierr = MatSetValues(J, 1, row, 4, col, val, ADD_VALUES); CHKERRQ(ierr); + + if (bus->ide != PV_BUS) { + row[0] = locglobt + 1; + val[0] = Vmt * Vmf * (Btf * sin(thetatf) + Gtf * cos(thetatf)); + val[1] = -2 * Btt * Vmt + + Vmf * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); + val[2] = Vmt * Vmf * (-Btf * sin(thetatf) - Gtf * cos(thetatf)); + val[3] = Vmt * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); + flps += 21 + (4 * EXAGO_FLOPS_SINOP) + (4 * EXAGO_FLOPS_COSOP); + ierr = MatSetValues(J, 1, row, 4, col, val, ADD_VALUES); + CHKERRQ(ierr); + } } } + } else if (line->isdcline) { + /* DC line */ + if (bus == busf) { + row[0] = locglobf + 1; + col[0] = locglobf + 1; + val[0] = 1.0; + ierr = MatSetValues(J, 1, row, 1, col, val, ADD_VALUES); + CHKERRQ(ierr); + } else { + row[0] = locglobt + 1; + col[0] = locglobt + 1; + val[0] = 1.0; + ierr = MatSetValues(J, 1, row, 1, col, val, ADD_VALUES); + CHKERRQ(ierr); + } } } } @@ -460,7 +486,7 @@ PetscErrorCode PFLOWFunction(SNES snes, Vec X, Vec F, void *ctx) { farr[loc] -= gen->pg; flps += 1; if (bus->ide == PV_BUS) { - farr[loc + 1] = Vm - gen->vs; + farr[loc + 1] += Vm - gen->vs; flps += 1; } else { farr[loc + 1] -= gen->qg; @@ -496,27 +522,18 @@ PetscErrorCode PFLOWFunction(SNES snes, Vec X, Vec F, void *ctx) { line = connlines[k]; if (!line->status) continue; - PetscScalar Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt; - Gff = line->yff[0]; - Bff = line->yff[1]; - Gft = line->yft[0]; - Bft = line->yft[1]; - Gtf = line->ytf[0]; - Btf = line->ytf[1]; - Gtt = line->ytt[0]; - Btt = line->ytt[1]; const PSBUS *connbuses; PSBUS busf, bust; - PetscInt locf, loct; - PetscScalar thetaf, Vmf, thetat, Vmt, thetaft, thetatf; - /* Get the connected buses to this line */ ierr = PSLINEGetConnectedBuses(line, &connbuses); CHKERRQ(ierr); busf = connbuses[0]; bust = connbuses[1]; + PetscInt locf, loct; + PetscScalar thetaf, Vmf, thetat, Vmt, thetaft, thetatf; + ierr = PSBUSGetVariableLocation(busf, &locf); CHKERRQ(ierr); ierr = PSBUSGetVariableLocation(bust, &loct); @@ -525,36 +542,62 @@ PetscErrorCode PFLOWFunction(SNES snes, Vec X, Vec F, void *ctx) { Vmf = xarr[locf + 1]; thetat = xarr[loct]; Vmt = xarr[loct + 1]; - thetaft = thetaf - thetat; - thetatf = thetat - thetaf; - if (bus == busf) { - if (busf->ide != REF_BUS) { - farr[locf] += Gff * Vmf * Vmf + - Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - flps += 9 + EXAGO_FLOPS_SINOP + EXAGO_FLOPS_COSOP; - } - if (busf->ide != PV_BUS && busf->ide != REF_BUS) { - farr[locf + 1] += - -Bff * Vmf * Vmf + - Vmf * Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); - flps += 9 + EXAGO_FLOPS_SINOP + EXAGO_FLOPS_COSOP; - } - } else { - if (bust->ide != REF_BUS) { - farr[loct] += Gtt * Vmt * Vmt + - Vmt * Vmf * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - flps += 9 + EXAGO_FLOPS_SINOP + EXAGO_FLOPS_COSOP; + if (!line->isdcline) { + PetscScalar Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt; + Gff = line->yff[0]; + Bff = line->yff[1]; + Gft = line->yft[0]; + Bft = line->yft[1]; + Gtf = line->ytf[0]; + Btf = line->ytf[1]; + Gtt = line->ytt[0]; + Btt = line->ytt[1]; + + thetaft = thetaf - thetat; + thetatf = thetat - thetaf; + + if (bus == busf) { + if (busf->ide != REF_BUS) { + farr[locf] += Gff * Vmf * Vmf + + Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); + flps += 9 + EXAGO_FLOPS_SINOP + EXAGO_FLOPS_COSOP; + } + if (busf->ide != PV_BUS && busf->ide != REF_BUS) { + farr[locf + 1] += + -Bff * Vmf * Vmf + + Vmf * Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); + flps += 9 + EXAGO_FLOPS_SINOP + EXAGO_FLOPS_COSOP; + } + } else { + if (bust->ide != REF_BUS) { + farr[loct] += Gtt * Vmt * Vmt + + Vmt * Vmf * (Gtf * cos(thetatf) + Btf * sin(thetatf)); + flps += 9 + EXAGO_FLOPS_SINOP + EXAGO_FLOPS_COSOP; + } + if (bust->ide != PV_BUS && bust->ide != REF_BUS) { + farr[loct + 1] += + -Btt * Vmt * Vmt + + Vmt * Vmf * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); + flps += 9 + EXAGO_FLOPS_SINOP + EXAGO_FLOPS_COSOP; + } } - if (bust->ide != PV_BUS && bust->ide != REF_BUS) { - farr[loct + 1] += - -Btt * Vmt * Vmt + - Vmt * Vmf * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - flps += 9 + EXAGO_FLOPS_SINOP + EXAGO_FLOPS_COSOP; + } else if (line->isdcline) { + /* DC line */ + if (bus == busf) { /* From bus */ + farr[locf] += line->pf; + farr[locf + 1] += Vmf - line->Vf; + flps += 3; + } else { + /* To bus */ + double loss; + loss = line->loss0 + line->loss1 * line->pf; + farr[loct] -= line->pf - loss; + farr[loct + 1] += Vmt - line->Vt; + flps += 6; } } } - flps += 2 * nconnlines; // for the two flops line: 447,448 } ierr = VecRestoreArrayRead(localX, &xarr); @@ -794,7 +837,9 @@ PetscErrorCode PFLOWSolutionToPS(PFLOW pflow) { for (i = 0; i < ps->nline; i++) { line = &ps->line[i]; - line->pf = line->qf = line->pt = line->qt = 0.0; + if (!line->isdcline) { + line->pf = line->qf = line->pt = line->qt = 0.0; + } } for (i = 0; i < ps->nbus; i++) { @@ -860,15 +905,6 @@ PetscErrorCode PFLOWSolutionToPS(PFLOW pflow) { line = connlines[k]; if (!line->status) continue; - PetscScalar Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt; - Gff = line->yff[0]; - Bff = line->yff[1]; - Gft = line->yft[0]; - Bft = line->yft[1]; - Gtf = line->ytf[0]; - Btf = line->ytf[1]; - Gtt = line->ytt[0]; - Btt = line->ytt[1]; const PSBUS *connbuses; PSBUS busf, bust; @@ -892,22 +928,44 @@ PetscErrorCode PFLOWSolutionToPS(PFLOW pflow) { thetaft = thetaf - thetat; thetatf = thetat - thetaf; - if (bus == busf) { - line->pf = Gff * Vmf * Vmf + - Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); - line->qf = -Bff * Vmf * Vmf + - Vmf * Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); - Pnet += line->pf; - Qnet += line->qf; - } else { - line->pt = Gtt * Vmt * Vmt + - Vmt * Vmf * (Gtf * cos(thetatf) + Btf * sin(thetatf)); - line->qt = -Btt * Vmt * Vmt + - Vmt * Vmf * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); - Pnet += line->pt; - Qnet += line->qt; + if (!line->isdcline) { + PetscScalar Gff, Bff, Gft, Bft, Gtf, Btf, Gtt, Btt; + Gff = line->yff[0]; + Bff = line->yff[1]; + Gft = line->yft[0]; + Bft = line->yft[1]; + Gtf = line->ytf[0]; + Btf = line->ytf[1]; + Gtt = line->ytt[0]; + Btt = line->ytt[1]; + + if (bus == busf) { + line->pf = Gff * Vmf * Vmf + + Vmf * Vmt * (Gft * cos(thetaft) + Bft * sin(thetaft)); + line->qf = -Bff * Vmf * Vmf + + Vmf * Vmt * (-Bft * cos(thetaft) + Gft * sin(thetaft)); + Pnet += line->pf; + Qnet += line->qf; + } else { + line->pt = Gtt * Vmt * Vmt + + Vmt * Vmf * (Gtf * cos(thetatf) + Btf * sin(thetatf)); + line->qt = -Btt * Vmt * Vmt + + Vmt * Vmf * (-Btf * cos(thetatf) + Gtf * sin(thetatf)); + Pnet += line->pt; + Qnet += line->qt; + } + flps += 18 + 2 * (EXAGO_FLOPS_SINOP + EXAGO_FLOPS_COSOP); + } else if (line->isdcline) { + if (bus == busf) { + Pnet += line->pf; + } else { + double loss; + loss = line->loss0 + line->loss1 * line->pf; + line->pt = (line->pf - loss); + + Pnet += line->pt; + } } - flps += 18 + 2 * (EXAGO_FLOPS_SINOP + EXAGO_FLOPS_COSOP); } flps += 2 * nconnlines; diff --git a/src/ps/ps.cpp b/src/ps/ps.cpp index 4a89bac85..513d555b1 100644 --- a/src/ps/ps.cpp +++ b/src/ps/ps.cpp @@ -772,8 +772,11 @@ PetscErrorCode PSCreate(MPI_Comm mpicomm, PS *psout) { ps->Ngen = -1; ps->NgenON = -1; ps->Nline = -1; + ps->Ndcline = -1; ps->nlineON = -1; + ps->ndclineON = -1; ps->NlineON = -1; + ps->NdclineON = -1; ps->Nload = -1; ps->refct = 0; ps->app = NULL; @@ -784,6 +787,9 @@ PetscErrorCode PSCreate(MPI_Comm mpicomm, PS *psout) { ps->ngencoal = ps->ngenwind = ps->ngensolar = 0; ps->ngenng = ps->ngennuclear = ps->ngenundefined = 0; + ps->nlines_overloaded = 0; + ps->has_overloaded_lines = PETSC_FALSE; + ps->nkvlevels = 0; ierr = PetscMalloc1(MAX_KV_LEVELS, &ps->kvlevels); CHKERRQ(ierr); @@ -846,6 +852,18 @@ PetscErrorCode PSDestroy(PS *ps) { ierr = PetscFree((*ps)->kvlevels); CHKERRQ(ierr); + + if ((*ps)->nlines_overloaded) { + ierr = PetscFree((*ps)->lines_overloaded); + CHKERRQ(ierr); + } + + ierr = PetscFree((*ps)->zones); + CHKERRQ(ierr); + + ierr = PetscFree((*ps)->areas); + CHKERRQ(ierr); + ierr = PetscFree((*ps)->busext2intmap); CHKERRQ(ierr); ierr = DMDestroy(&(*ps)->networkdm); @@ -972,11 +990,25 @@ PetscErrorCode PSSetUp(PS ps) { CHKERRQ(ierr); /* Set up edge connectivity */ - + /* Edges include true edges + dummy edges set up for isolated buses + These edges for isolated buses are inserted so that DMNetwork + correctly knows the number of vertices. DMNetwork filters out + any nodes that do not have edges and so this messes up our network + data layout that has these isolated buses. So, we create dummy + edges connecting these isolated buses. These are only used here + for the DMNetwork business, not anywhere else + */ ierr = PetscCalloc1(2 * Nlines, &lineconn[0]); CHKERRQ(ierr); ierr = PSGetLineConnectivity(ps, Nlines, lineconn[0]); CHKERRQ(ierr); + /* Insert dummy edges for isolated_buses */ + // for(i=0; i < ps->nisolated_buses; i++) { + /* Each dummy line is connected between bus 0 and the isolated bus */ + // lineconn[0][2 * (Nlines+i) ] = ps->isolated_buses[i]; + // lineconn[0][2 * (Nlines+i) + 1] = 0; + // } + // ierr = PetscFree(ps->isolated_buses); /* Set sizes for the network and provide edge connectivity information */ ierr = DMNetworkSetNumSubNetworks(networkdm, PETSC_DECIDE, 1); @@ -1068,9 +1100,10 @@ PetscErrorCode PSSetUp(PS ps) { CHKERRQ(ierr); } - /* Broadcast global Nbus,Ngen,Nbranch, Nload,and maxbusnum to all processors + /* Broadcast global Nbus,Ngen,Nbranch, Nload,Ndcline, and maxbusnum to all + * processors */ - PetscInt temp[8]; + PetscInt temp[9]; /* Pack variables */ temp[0] = ps->Nbus; temp[1] = ps->Ngen; @@ -1080,6 +1113,7 @@ PetscErrorCode PSSetUp(PS ps) { temp[5] = ps->NgenON; temp[6] = ps->NlineON; temp[7] = ps->Nref; + temp[8] = ps->Ndcline; ierr = MPI_Bcast(temp, 8, MPI_INT, 0, ps->comm->type); CHKERRQ(ierr); /* Unpack */ @@ -1091,6 +1125,7 @@ PetscErrorCode PSSetUp(PS ps) { ps->NgenON = temp[5]; ps->NlineON = temp[6]; ps->Nref = temp[7]; + ps->Ndcline = temp[8]; /* Recreate busext2intmap..this will map the local bus numbers to external * numbers */ @@ -1099,7 +1134,8 @@ PetscErrorCode PSSetUp(PS ps) { for (i = 0; i < ps->maxbusnum + 1; i++) ps->busext2intmap[i] = -1; - ps->ngen = ps->nload = ps->ngenON = ps->nlineON = 0; + ps->ngen = ps->nload = ps->ndcline = ps->ngenON = ps->nlineON = + ps->ndclineON = 0; /* Get the local number of gens and loads */ for (i = 0; i < nv; i++) { ierr = DMNetworkGetNumComponents(ps->networkdm, vtx[i], &numComponents); @@ -1133,6 +1169,10 @@ PetscErrorCode PSSetUp(PS ps) { ierr = PetscMemcpy(&ps->line[i], component, sizeof(struct _p_PSLINE)); CHKERRQ(ierr); ps->nlineON += ps->line[i].status; + if (ps->line[i].isdcline) { + ps->ndcline++; + ps->ndclineON += ps->line[i].status; + } } PetscInt genj = 0, loadj = 0; PetscInt genctr, loadctr; @@ -1170,6 +1210,7 @@ PetscErrorCode PSSetUp(PS ps) { ps->nload = ps->Nload; ps->ngenON = ps->NgenON; ps->nlineON = ps->NlineON; + ps->ndclineON = ps->NdclineON; } /* Set up @@ -1178,8 +1219,9 @@ PetscErrorCode PSSetUp(PS ps) { (c) incident generators at bus (d) incident loads at bus (e) kv levels for lines - (e) sets the starting location for the variables for this bus in the given + (f) sets the starting location for the variables for this bus in the given application state vector + (g) marks from and to buses for DC lines (ON) as PV buses */ PetscInt eStart, eEnd, vStart, vEnd; PetscInt nlines, k; @@ -1279,6 +1321,42 @@ PetscErrorCode PSSetUp(PS ps) { /* Get KV levels */ ierr = PSGetKVLevels(ps, &ps->nkvlevels, (const PetscScalar **)&ps->kvlevels); CHKERRQ(ierr); + + PSLINE line; + /* Set up for lines + - Turn off lines that are connected to isolated buses (if they are not OFF + already) + - Mark DC line ends as PV buses */ + for (i = 0; i < ps->nline; i++) { + line = &ps->line[i]; + + const PSBUS *connbuses; + PSBUS busf, bust; + /* Get the connected buses */ + ierr = PSLINEGetConnectedBuses(line, &connbuses); + CHKERRQ(ierr); + busf = connbuses[0]; + bust = connbuses[1]; + + if (busf->ide == ISOLATED_BUS || bust->ide == ISOLATED_BUS) { + /* Switch off lines connected to isolated buses */ + if (line->status) { + line->status = 0; + ps->nlineON--; + } + } + + if (!line->isdcline) + continue; + if (!line->status) + continue; + + if (busf->ide != REF_BUS || busf->ide != PV_BUS) + busf->ide = PV_BUS; + if (bust->ide != REF_BUS || bust->ide != PV_BUS) + bust->ide = PV_BUS; + } + // ierr = PetscPrintf(PETSC_COMM_SELF,"Rank %d Came // here\n",ps->comm->rank);CHKERRQ(ierr); ps->setupcalled = PETSC_TRUE; @@ -1541,16 +1619,24 @@ PetscErrorCode PSApplyScenario(PS ps, Scenario scenario) { for (j = 0; j < forecast->nele; j++) { ierr = PSGetGen(ps, forecast->buses[j], forecast->id[j], &gen); CHKERRQ(ierr); - gen->pg = gen->pt = - forecast->val[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 */ - gen->pgs = gen->pb; /* Set-point set to lower bound. This is good for + if (gen) { + gen->pg = gen->pt = + forecast->val[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 */ + gen->pgs = gen->pb; /* Set-point set to lower bound. This is good for optimization */ - if (PetscAbsScalar(gen->pg) < 1e-6) - gen->status = - 0; /* Generation value is zero, so switch off the generator */ + if (PetscAbsScalar(gen->pg) < 1e-6) + gen->status = + 0; /* Generation value is zero, so switch off the generator */ + // else gen->status = 1; /* Switch on generator (it may be off in + //the input file) */ + } else { + printf("No generator on bus %d with id %s. Cannot apply the " + "requested scenario\n", + forecast->buses[j], forecast->id[j]); + } } } } @@ -1964,3 +2050,78 @@ PetscErrorCode PSComputeSummaryStats(PS ps) { PetscFunctionReturn(0); } + +/* + PSGetLineOverloads - Get overloaded lines and returns the indices (line +numbers) for overloaded lines + + Input Parameters: +. ps - PS object + + Output Parameters: ++ nodlines - number of overloaded line +. odlines - Indices for overloaded lines +- has_overload - True if any line is overloaded + +*/ +PetscErrorCode PSGetLineOverloads(PS ps, PetscInt *nodlines, PetscInt **odlines, + PetscBool *has_overload) { + PetscErrorCode ierr; + PetscInt i; + PSLINE line; + PetscInt idx = 0; + PetscInt *odlines_temp; + PetscBool hasoverload_temp = PETSC_TRUE; + + PetscFunctionBegin; + + /* Crete buffer to store overloaded lines */ + ierr = PetscMalloc1(ps->nlineON, &odlines_temp); + + for (i = 0; i < ps->nline; i++) { + line = &ps->line[i]; + if (!line->status) + continue; + + /* Check which lines are overloaded */ + if (line->sf > (line->rateA / ps->MVAbase) || + line->st > (line->rateA / ps->MVAbase)) { + odlines_temp[idx++] = i; + } + } + + if (!idx) { + /* No overloaded lines */ + ierr = PetscFree(odlines_temp); + CHKERRQ(ierr); + hasoverload_temp = PETSC_FALSE; + ps->has_overloaded_lines = PETSC_FALSE; + *has_overload = PETSC_FALSE; + *nodlines = 0; + PetscFunctionReturn(0); + } else { + /* Some lines are overloaded */ + if (ps->nlines_overloaded) { + /* GetLineOverloads called previously, so re-allocate lines_overloaded + * array */ + ierr = PetscFree(ps->lines_overloaded); + CHKERRQ(ierr); + } + ps->nlines_overloaded = idx; + ps->has_overloaded_lines = PETSC_TRUE; + ierr = PetscMalloc1(ps->nlines_overloaded, &ps->lines_overloaded); + CHKERRQ(ierr); + /* Copy values to ps->lines_overloaded array */ + ierr = + PetscMemcpy(ps->lines_overloaded, odlines_temp, idx * sizeof(PetscInt)); + CHKERRQ(ierr); + + ierr = PetscFree(odlines_temp); + CHKERRQ(ierr); + } + *nodlines = ps->nlines_overloaded; + *odlines = ps->lines_overloaded; + *has_overload = ps->has_overloaded_lines; + + PetscFunctionReturn(0); +} diff --git a/src/ps/psoutput.cpp b/src/ps/psoutput.cpp index eab377751..3628c61f4 100644 --- a/src/ps/psoutput.cpp +++ b/src/ps/psoutput.cpp @@ -443,6 +443,23 @@ static void PrintJSONArray(FILE *fd, const char *name, int nvals, PrintJSONArrayEnd(fd, trail_comma); } +static void PrintJSONArrayInt(FILE *fd, int value, bool trail_comma) { + std::string str = trail_comma ? "," : ""; + fprintf(fd, "%s%d%s\n", tabstring, value, str.c_str()); +} + +static void PrintJSONIntArray(FILE *fd, const char *name, int nvals, + int *values, bool trail_comma) { + PrintJSONArrayBegin(fd, name); + + for (int i = 0; i < nvals - 1; i++) { + PrintJSONArrayInt(fd, values[i], true); + } + PrintJSONArrayInt(fd, values[nvals - 1], false); + + PrintJSONArrayEnd(fd, trail_comma); +} + static void PrintGenData(FILE *fd, PSBUS bus, bool trail_comma, PetscScalar MVAbase) { PSGEN gen; @@ -522,6 +539,19 @@ static void PrintLineData(FILE *fd, PSLINE line, bool trail_comma, PrintJSONDouble(fd, "RATE_A", (line->rateA > 1e5) ? 10000 : line->rateA, true); + // Zones for from and to bus + // Zone from bus + PrintJSONInt(fd, "ZONE_FBUS", line->zonef, true); + + // Zone to bus + PrintJSONInt(fd, "ZONE_TBUS", line->zonet, true); + + // Area from bus + PrintJSONInt(fd, "AREA_FBUS", line->areaf, true); + + // Zone to bus + PrintJSONInt(fd, "AREA_TBUS", line->areat, true); + // PF,QF, PT, QT PrintJSONDouble(fd, "PF", line->pf * MVAbase, true); PrintJSONDouble(fd, "QF", line->qf * MVAbase, true); @@ -573,6 +603,12 @@ static void PrintBusData(FILE *fd, PSSUBST subst, bool trail_comma, // Base KV PrintJSONDouble(fd, "BASE_KV", bus->basekV, true); + // Zone + PrintJSONInt(fd, "ZONE", bus->zone, true); + + // Area + PrintJSONInt(fd, "AREA", bus->area, true); + // PD if (bus->nload) { PSBUSGetLoad(bus, 0, &load); @@ -665,6 +701,8 @@ PetscErrorCode PSSaveSolution_JSON(PS ps, const char outfile[]) { snprintf(subst->name, 64, "%d", ps->bus[i].bus_i); subst->nbus = 1; subst->nkvlevels = 1; + subst->zone = ps->bus[i].zone; + subst->area = ps->bus[i].area; /* Circular distribution of lats and long from some location with .5 * degrees deviation. This is completely random baseless lat/long creation */ @@ -714,6 +752,12 @@ PetscErrorCode PSSaveSolution_JSON(PS ps, const char outfile[]) { PrintJSONString(fd, "gicfile", "not given", true); } + /* Print number of zones */ + PrintJSONInt(fd, "nzones", ps->nzones, true); + + /* Print number of zones */ + PrintJSONInt(fd, "nareas", ps->nareas, true); + /* Print number of lines */ PrintJSONInt(fd, "nbranch", ps->Nline, true); @@ -723,6 +767,12 @@ PetscErrorCode PSSaveSolution_JSON(PS ps, const char outfile[]) { /* Print Number of bus */ PrintJSONInt(fd, "nbus", ps->Nbus, true); + /* Print zones */ + PrintJSONIntArray(fd, "zones", ps->nzones, ps->zones, true); + + /* Print areas */ + PrintJSONIntArray(fd, "areas", ps->nareas, ps->areas, true); + /* Print KV levels */ PrintJSONArray(fd, "KVlevels", ps->nkvlevels, ps->kvlevels, true); @@ -757,6 +807,12 @@ PetscErrorCode PSSaveSolution_JSON(PS ps, const char outfile[]) { // Name PrintJSONString(fd, "NAME", ps->substations[i].name, true); + // Zone number + PrintJSONInt(fd, "zone", ps->substations[i].zone, true); + + // Area number + PrintJSONInt(fd, "area", ps->substations[i].area, true); + // Number of buses PrintJSONInt(fd, "nbus", ps->substations[i].nbus, true); @@ -827,7 +883,7 @@ 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, true); + PrintJSONDouble(fd, "SolveRealTime", ps->solve_real_time, false); PrintJSONObjectEnd(fd, false); // System summary object end @@ -883,6 +939,8 @@ 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, "\tNzones: %d\n", ps->nzones); + fprintf(fd, "\tNareas: %d\n", ps->nareas); fclose(fd); diff --git a/src/ps/psreaddata.cpp b/src/ps/psreaddata.cpp index 5c4405b5d..3b63ec5b8 100644 --- a/src/ps/psreaddata.cpp +++ b/src/ps/psreaddata.cpp @@ -136,7 +136,7 @@ PetscErrorCode PSReadPSSERawData(PS ps, const char netfile[]) { ps->Ngen = ps->ngen = Ngenerator; ps->Nline = ps->nline = Nline + Ntransformer; ps->NgenON = 0; - ps->NlineON = 0; + ps->nlineON = ps->NlineON = 0; #if defined DEBUGPS ierr = PetscPrintf( @@ -480,6 +480,20 @@ PetscErrorCode PSReadPSSERawData(PS ps, const char netfile[]) { PetscFunctionReturn(0); } +/* Returns true if busum is in the isolated_buses list */ +PetscBool BusIsIsolated(PetscInt busnum, PetscInt nisolated_buses, + PetscInt *isolated_buses) { + PetscInt i; + + for (i = 0; i < nisolated_buses; i++) { + if (isolated_buses[i] == busnum) { + return PETSC_TRUE; + } + } + + return PETSC_FALSE; +} + /* PSReadMatPowerData - Reads the MATPOWER data file and populates the PS object @@ -502,13 +516,20 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { -1; /* xx_end_line points to the next line after the record ends */ PetscInt gen_start_line = -1, gen_end_line = -1; PetscInt br_start_line = -1, br_end_line = -1; + PetscInt dcline_start_line = -1, dcline_end_line = -1; PetscInt gencost_start_line = -1, gencost_end_line = -1; PetscInt genfuel_start_line = -1, genfuel_end_line = -1; PetscInt loadcost_start_line = -1, loadcost_end_line = -1; + + /* Number of lines for each data */ + PetscInt bus_numlines, gen_numlines, br_numlines, dcline_numlines; + PetscInt load_numlines = 0; /* Number of blank lines in bus, gen, br, gencost, and genfuel branch arrays */ PetscInt bus_nblank_lines = 0, gen_nblank_lines = 0; PetscInt br_nblank_lines = 0; + PetscInt dcline_nblank_lines = 0; + char line[MAXLINE]; PetscInt loadi = 0, geni = 0, bri = 0, busi = 0, gencosti = 0, genfueli = 0, loadcosti = 0, i; @@ -517,14 +538,25 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { PetscInt intbusnum; char *str; char *out; + PetscInt buff_num = 1; + PetscInt + *temp_buff; /* buffer to hold 10 isolated buses, gets resized later */ + PetscBool bad_data = PETSC_FALSE; + const char bad_data_str[] = "Input Data Error: "; + PetscInt num_max_cost_coeffs = + 3; // Max. number of cost-coefficients for any generator PetscFunctionBegin; if (ps->comm->type != PETSC_COMM_SELF && ps->comm->rank != 0) { - ps->Nline = ps->Nbus = ps->Ngen = ps->Nload = 0; + ps->Nline = ps->Nbus = ps->Ngen = ps->Nload = ps->Ndcline = 0; PetscFunctionReturn(0); } + ps->nisolated_buses = 0; + ierr = PetscCalloc1(10, &ps->isolated_buses); + CHKERRQ(ierr); + fp = fopen(netfile, "r"); /* Check for valid file */ if (fp == NULL) { @@ -540,6 +572,12 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { ps->Nload = 0; ps->maxbusnum = -1; ps->read_load_cost = PETSC_FALSE; + + ps->nzones = ps->nareas = 0; + ierr = PetscCalloc1(500, &ps->zones); + CHKERRQ(ierr); + ierr = PetscCalloc1(500, &ps->areas); + CHKERRQ(ierr); while ((out = fgets(line, MAXLINE, fp)) != NULL) { if (strstr(line, "mpc.baseMVA")) { /* Read base MVA */ @@ -554,6 +592,9 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { line_counter + 1; /* Generator data starts from next line */ if (strstr(line, "mpc.branch") != NULL) br_start_line = line_counter + 1; /* Branch data starts from next line */ + if (strstr(line, "mpc.dcline") != NULL && dcline_start_line == -1) + dcline_start_line = + line_counter + 1; /* DC line data starts from next line */ if (strstr(line, "mpc.gencost") != NULL) gencost_start_line = line_counter + 1; /* Gen cost data starts from next line */ @@ -580,6 +621,8 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { gen_end_line = line_counter; if (br_start_line != -1 && br_end_line == -1) br_end_line = line_counter; + if (dcline_start_line != -1 && dcline_end_line == -1) + dcline_end_line = line_counter; if (gencost_start_line != -1 && gencost_end_line == -1) gencost_end_line = line_counter; if (loadcost_start_line != -1 && loadcost_end_line == -1) @@ -588,59 +631,90 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { if (bus_start_line != -1 && bus_end_line == -1) { if (strcmp(line, "\n") == 0 || strcmp(line, "\r\n") == 0) - bus_nblank_lines++; + bus_nblank_lines = bus_nblank_lines + 1; } if (gen_start_line != -1 && gen_end_line == -1) { if (strcmp(line, "\n") == 0 || strcmp(line, "\r\n") == 0) - gen_nblank_lines++; + gen_nblank_lines = gen_nblank_lines + 1; } if (br_start_line != -1 && br_end_line == -1) { if (strcmp(line, "\n") == 0 || strcmp(line, "\r\n") == 0) - br_nblank_lines++; + br_nblank_lines = br_nblank_lines + 1; + } + + if (dcline_start_line != -1 && dcline_end_line == -1) { + if (strcmp(line, "\n") == 0 || strcmp(line, "\r\n") == 0) + dcline_nblank_lines = dcline_nblank_lines + 1; } /* Count the number of pq loads */ if (bus_start_line != -1 && line_counter >= bus_start_line && bus_end_line == -1) { sscanf(line, "%d %d %lf %lf", &extbusnum, &bustype_i, &Pd, &Qd); + if (bustype_i == ISOLATED_BUS) { /* Isolated bus */ + /* put it in the isolated_buses array for later work */ + ps->isolated_buses[ps->nisolated_buses++] = extbusnum; + if (ps->nisolated_buses == buff_num * 10) { + /* Reached buffer max, need to allocate more size */ + buff_num++; + ierr = PetscCalloc1(buff_num * 10, &temp_buff); + CHKERRQ(ierr); + /* Copy over isolated_buses to temp_buff */ + ierr = PetscMemcpy(temp_buff, ps->isolated_buses, + (buff_num - 1) * 10 * sizeof(PetscInt)); + ierr = PetscFree(ps->isolated_buses); + CHKERRQ(ierr); + /* Updated pointer to isolated_buses */ + ps->isolated_buses = temp_buff; + } + } + if (!((Pd == 0.0) && (Qd == 0.0))) - ps->Nload++; + load_numlines++; if (extbusnum > ps->maxbusnum) ps->maxbusnum = extbusnum; } + + /* Count the number of cost-coefficients */ + if (gencost_start_line != -1 && line_counter >= gencost_start_line && + gencost_end_line == -1) { + PetscInt gencost_model, num_cost_coeffs; + PetscScalar cost_startup, cost_shutdown; + sscanf(line, "%d %lf %lf %d", &gencost_model, &cost_startup, + &cost_shutdown, &num_cost_coeffs); + if (num_cost_coeffs > num_max_cost_coeffs) + num_max_cost_coeffs = num_cost_coeffs; + } + line_counter++; } fclose(fp); - ps->Nbus = ps->nbus = bus_end_line - bus_start_line - bus_nblank_lines; - ps->Ngen = ps->ngen = gen_end_line - gen_start_line - gen_nblank_lines; - ps->Nline = ps->nline = br_end_line - br_start_line - br_nblank_lines; - ps->nload = ps->Nload; + bus_numlines = bus_end_line - bus_start_line - bus_nblank_lines; + gen_numlines = gen_end_line - gen_start_line - gen_nblank_lines; + br_numlines = br_end_line - br_start_line - br_nblank_lines; + dcline_numlines = dcline_end_line - dcline_start_line - dcline_nblank_lines; + ps->NgenON = 0; - ps->NlineON = 0; + ps->nlineON = ps->NlineON = 0; + ps->ndclineON = ps->NdclineON = 0; -#if defined DEBUGPS - ierr = PetscPrintf( - PETSC_COMM_SELF, - "System summary : Nbuses = %d, Ngen = %d, Nload = %d, Nbranch = %d\n", - ps->Nbus, ps->Ngen, ps->Nload, ps->Nline); + ierr = PetscCalloc1(bus_numlines, &ps->bus); CHKERRQ(ierr); -#endif - ierr = PetscCalloc1(ps->Nbus, &ps->bus); + ierr = PetscCalloc1(gen_numlines, &ps->gen); CHKERRQ(ierr); - ierr = PetscCalloc1(ps->Ngen, &ps->gen); - CHKERRQ(ierr); - ierr = PetscCalloc1(ps->Nload, &ps->load); + ierr = PetscCalloc1(load_numlines, &ps->load); CHKERRQ(ierr); - ierr = PetscCalloc1(ps->Nline, &ps->line); + ierr = PetscCalloc1(br_numlines + dcline_numlines, + &ps->line); /* Includes space for DC lines */ CHKERRQ(ierr); Bus = ps->bus; Gen = ps->gen; Load = ps->load; Branch = ps->line; - for (i = 0; i < ps->Nbus; i++) { + for (i = 0; i < bus_numlines; i++) { ps->bus[i].ngen = ps->bus[i].nload = ps->bus[i].ngenON = ps->bus[i].nshunt = 0; ps->bus[i].qrange = ps->bus[i].qmintot = ps->bus[i].Pgtot = @@ -658,6 +732,23 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { for (i = 0; i < ps->maxbusnum + 1; i++) busext2intmap[i] = -1; + ps->Nbus = ps->nbus = 0; + ps->Nline = ps->nline = 0; + ps->Nload = ps->nload = 0; + ps->Ngen = ps->ngen = 0; + ps->Ndcline = ps->ndcline = 0; + + /* Create a temp array to store the locations in mpc.gen (generators) + connected to isolated buses. This is used later in ignoring these + generators in gencost data + */ + PetscInt + temp_geni[200]; // Assume there are max 200 generators at an isolated node + for (i = 0; i < 200; i++) + temp_geni[i] = line_counter + 1; // initialize + + PetscInt i_idx = -1, isol_idx = 0, isol_idx2 = 0, isol_idx3 = 0; + fp = fopen(netfile, "r"); /* Reading data */ for (i = 0; i < line_counter; i++) { @@ -673,8 +764,43 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { &Bus[busi].basekV, &Bus[busi].zone, &Bus[busi].Vmax, &Bus[busi].Vmin); + if (Bus[busi].ide == ISOLATED_BUS) + continue; /* Skip isolated bus */ + + ps->nbus++; + ps->Nbus++; + + /* Save zone and area information to PS struct */ + int area_found = 0; + for (int num = 0; num < ps->nareas; num++) { + if (Bus[busi].area == ps->areas[num]) { + area_found = 1; + break; + } + } + if (!area_found) + ps->areas[ps->nareas++] = Bus[busi].area; + + int zone_found = 0; + for (int num = 0; num < ps->nzones; num++) { + if (Bus[busi].zone == ps->zones[num]) { + zone_found = 1; + break; + } + } + if (!zone_found) + ps->zones[ps->nzones++] = Bus[busi].zone; + Bus[busi].Vmax = Bus[busi].Vmax == 0 ? 1.1 : Bus[busi].Vmax; Bus[busi].Vmin = Bus[busi].Vmin == 0 ? 0.9 : Bus[busi].Vmin; + /* Sanity check for voltage limits */ + if ((Bus[busi].Vmax < Bus[busi].Vmin)) { + bad_data = PETSC_TRUE; + ierr = PetscPrintf( + ps->comm->type, + "%sVmax = %4.3f at bus %d is less than Vmin = %4.3f\n", + bad_data_str, Bus[busi].Vmax, Bus[busi].bus_i, Bus[busi].Vmin); + } // Convert angle to radians Bus[busi].va *= PETSC_PI / 180.0; @@ -689,12 +815,19 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { Bus[busi].nshunt++; if (!((Pd == 0.0) && (Qd == 0.0))) { + ps->nload++; + ps->Nload++; + Load[loadi].bus_i = Bus[busi].bus_i; Load[loadi].status = 1; Load[loadi].pl = Pd / ps->MVAbase; Load[loadi].ql = Qd / ps->MVAbase; /* Some defaults for load shed */ - Load[loadi].loss_frac = 1.0; + if (Pd < 0.0 || Qd <= 0.0) { + Load[loadi].loss_frac = 0.0; + } else { + Load[loadi].loss_frac = 1.0; + } Load[loadi].loss_cost = BOGUSLOSSCOST; Load[loadi].area = Bus[busi].area; Load[loadi].internal_i = busi; @@ -710,13 +843,16 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { "Exceeded maximum number of loads allowed at bus"); loadi++; } + Bus[busi].nconnlines = 0; busi++; } /* Read generator data */ if (i >= gen_start_line && i < gen_end_line) { + i_idx += 1; if (strcmp(line, "\n") == 0 || strcmp(line, "\r\n") == 0) continue; + sscanf(line, "%d %lf %lf %lf %lf %lf %lf %d %lf %lf %lf %lf %lf %lf %lf %lf " "%lf %lf %lf %lf %lf", @@ -728,6 +864,19 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { &Gen[geni].ramp_rate_10min, &Gen[geni].ramp_rate_30min, &Gen[geni].ramp_rate_min_mvar, &Gen[geni].apf); + if (BusIsIsolated(Gen[geni].bus_i, ps->nisolated_buses, + ps->isolated_buses)) { + if (isol_idx == 200) { + SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, + "Total number of generators at isolated buses greater than " + "max. allowed = 200\n"); + } + temp_geni[isol_idx++] = i_idx; + continue; /* Skip generator at isolated bus */ + } + ps->ngen++; + ps->Ngen++; + intbusnum = busext2intmap[Gen[geni].bus_i]; Gen[geni].qt = Gen[geni].qt > 1e10 ? PETSC_INFINITY : Gen[geni].qt; @@ -767,8 +916,8 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { Gen[geni].genfuel_type = GENFUEL_UNDEFINED; Gen[geni].ramp_rate_min = GENRAMPRATE_COAL / ps->MVAbase; /* Defaults to COAL ramp rate */ - Gen[geni].ramp_rate_10min = Gen[genfueli].ramp_rate_min * 10; - Gen[geni].ramp_rate_30min = Gen[genfueli].ramp_rate_min * 30; + Gen[geni].ramp_rate_10min = Gen[geni].ramp_rate_min * 10; + Gen[geni].ramp_rate_30min = Gen[geni].ramp_rate_min * 30; } if (Gen[geni].status) { @@ -788,6 +937,26 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { */ snprintf(Gen[geni].id, 3, "%-2d", 1 + Bus[intbusnum].ngen); + /* Sanity check for real power limits */ + if (Gen[geni].pt < Gen[geni].pb) { + bad_data = PETSC_TRUE; + ierr = PetscPrintf(ps->comm->type, + "%sPmax = %4.3f for generator with id %s at bus %d " + "is less than Pmin = %4.3f\n", + bad_data_str, Gen[geni].pt, Gen[geni].id, + Gen[geni].bus_i, Gen[geni].pb); + } + + /* Sanity check for reactive power limits */ + if (Gen[geni].qt < Gen[geni].qb) { + bad_data = PETSC_TRUE; + ierr = PetscPrintf(ps->comm->type, + "%sQmax = %4.3f for generator with id %s at bus %d " + "is less than Qmin = %4.3f\n", + bad_data_str, Gen[geni].qt, Gen[geni].id, + Gen[geni].bus_i, Gen[geni].qb); + } + Bus[intbusnum].gidx[Bus[intbusnum].ngen++] = geni; // Bus[intbusnum].vm = Gen[geni].vs; @@ -809,10 +978,51 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { if (i >= gencost_start_line && i < gencost_end_line) { if (strcmp(line, "\n") == 0 || strcmp(line, "\r\n") == 0) continue; - sscanf(line, "%d %lf %lf %d %lf %lf %lf", &Gen[gencosti].cost_model, - &Gen[gencosti].cost_startup, &Gen[gencosti].cost_shutdown, - &Gen[gencosti].cost_ncoeffs, &Gen[gencosti].cost_alpha, - &Gen[gencosti].cost_beta, &Gen[gencosti].cost_gamma); + + if (temp_geni[isol_idx2] == i - gencost_start_line) { + isol_idx2 += 1; + continue; + } + + if (num_max_cost_coeffs == 2) { + Gen[geni].cost_alpha = 0.0; + sscanf(line, "%d %lf %lf %d %lf %lf", &Gen[gencosti].cost_model, + &Gen[gencosti].cost_startup, &Gen[gencosti].cost_shutdown, + &Gen[gencosti].cost_ncoeffs, &Gen[gencosti].cost_beta, + &Gen[gencosti].cost_gamma); + } else if (num_max_cost_coeffs == 3) { + sscanf(line, "%d %lf %lf %d %lf %lf %lf", &Gen[gencosti].cost_model, + &Gen[gencosti].cost_startup, &Gen[gencosti].cost_shutdown, + &Gen[gencosti].cost_ncoeffs, &Gen[gencosti].cost_alpha, + &Gen[gencosti].cost_beta, &Gen[gencosti].cost_gamma); + } else if (num_max_cost_coeffs == 4) { + sscanf(line, "%d %lf %lf %d %*f %lf %lf %lf", &Gen[gencosti].cost_model, + &Gen[gencosti].cost_startup, &Gen[gencosti].cost_shutdown, + &Gen[gencosti].cost_ncoeffs, &Gen[gencosti].cost_alpha, + &Gen[gencosti].cost_beta, &Gen[gencosti].cost_gamma); + } else { + bad_data = PETSC_TRUE; + ierr = + PetscPrintf(ps->comm->type, + "%sExaGO can only read generator cost curves upto 3rd " + "order. More than 4 coefficients found for cost curve " + "of cost curve for generator with id %s at bus %d\n", + bad_data_str, Gen[gencosti].id, Gen[gencosti].bus_i); + CHKERRQ(ierr); + } + + /* Sanity check for generator cost function */ + if (Gen[gencosti].cost_model != 2) { + bad_data = PETSC_TRUE; + ierr = + PetscPrintf(ps->comm->type, + "%sExaGO only supports generator cost curves modeled " + "as quadratic function.. No quadratic cost curve " + "function found for generator with id %s at bus %d\n", + bad_data_str, Gen[gencosti].id, Gen[gencosti].bus_i); + CHKERRQ(ierr); + } + gencosti++; } @@ -830,6 +1040,10 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { if (i >= genfuel_start_line && i < genfuel_end_line) { if (strcmp(line, "\n") == 0 || strcmp(line, "\r\n") == 0) continue; + if (temp_geni[isol_idx3] == i - genfuel_start_line) { + isol_idx3 += 1; + continue; + } if (strstr(line, "coal") != NULL) { Gen[genfueli].genfuel_type = GENFUEL_COAL; Gen[genfueli].ramp_rate_min = GENRAMPRATE_COAL / ps->MVAbase; @@ -841,8 +1055,9 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { 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; - Gen[genfueli].pb = 0.0; /* Set lower Pg limit to 0.0 so that wind power + Gen[genfueli].pb = 0.0; /* Set lower Pg limit to 0.0 so that power can be curtailed if need be */ + ps->ngenwind++; ps->ngenrenew++; Gen[genfueli].isrenewable = PETSC_TRUE; @@ -895,8 +1110,20 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { &Branch[bri].x, &Branch[bri].b, &Branch[bri].rateA, &Branch[bri].rateB, &Branch[bri].rateC, &Branch[bri].tapratio, &Branch[bri].phaseshift, &Branch[bri].status); - if (Branch[bri].status) + + if ((BusIsIsolated(Branch[bri].fbus, ps->nisolated_buses, + ps->isolated_buses)) || + (BusIsIsolated(Branch[bri].tbus, ps->nisolated_buses, + ps->isolated_buses))) + continue; /* Skip branch connected to isolated bus */ + + ps->nline++; + ps->Nline++; + + if (Branch[bri].status) { + ps->nlineON++; ps->NlineON++; + } if (!Branch[bri].tapratio) Branch[bri].tapratio = 1.0; Branch[bri].phaseshift *= PETSC_PI / 180.0; @@ -922,6 +1149,10 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { intbusnum = busext2intmap[Branch[bri].tbus]; Branch[bri].internal_j = intbusnum; + /* Update number of connected lines for the from and to bus */ + Bus[Branch[bri].internal_i].nconnlines++; + Bus[Branch[bri].internal_j].nconnlines++; + PetscInt lineididx = 0; for (linenum = 0; linenum < bri - 1; linenum++) { if (Branch[bri].internal_i == Branch[linenum].internal_i && @@ -932,6 +1163,16 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { /* MatPower does not have ids for lines. Using bri+1 as the id */ snprintf(Branch[bri].ckt, 3, "%-2d", 1 + lineididx); + if (Branch[bri].rateA < 0.0) { + bad_data = PETSC_TRUE; + ierr = PetscPrintf( + ps->comm->type, + "%srateA = %4.3f for line %d -- %d with id %s is negative\n", + bad_data_str, Branch[bri].rateA, Branch[bri].fbus, Branch[bri].tbus, + Branch[bri].ckt); + CHKERRQ(ierr); + } + /* Compute self and transfer admittances */ PetscScalar R, X, Bc, B, G, Zm, tap, shift, tap2, tapr, tapi; R = Branch[bri].r; @@ -981,9 +1222,117 @@ PetscErrorCode PSReadMatPowerData(PS ps, const char netfile[]) { Branch[bri].bdc = (1 / X) / tap; Branch[bri].pshift = -(1 / X) * shift; } + Branch[bri].isdcline = PETSC_FALSE; + bri++; + } + + /* DC lines */ + if (i >= dcline_start_line && i < dcline_end_line) { + if (strcmp(line, "\n") == 0 || strcmp(line, "\r\n") == 0) + continue; + sscanf(line, + "%d %d %d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", + &Branch[bri].fbus, &Branch[bri].tbus, &Branch[bri].status, + &Branch[bri].pf, &Branch[bri].pt, &Branch[bri].qf, &Branch[bri].qt, + &Branch[bri].Vf, &Branch[bri].Vt, &Branch[bri].pmin, + &Branch[bri].pmax, &Branch[bri].qminf, &Branch[bri].qmaxf, + &Branch[bri].qmint, &Branch[bri].qmaxt, &Branch[bri].loss0, + &Branch[bri].loss1); + + if ((BusIsIsolated(Branch[bri].fbus, ps->nisolated_buses, + ps->isolated_buses)) || + (BusIsIsolated(Branch[bri].tbus, ps->nisolated_buses, + ps->isolated_buses))) + continue; /* Skip branch connected to isolated bus */ + ps->ndcline++; + ps->Ndcline++; + + Branch[bri].pf /= ps->MVAbase; + Branch[bri].pmin /= ps->MVAbase; + Branch[bri].pmax /= ps->MVAbase; + Branch[bri].qminf /= ps->MVAbase; + Branch[bri].qmaxf /= ps->MVAbase; + Branch[bri].qmint /= ps->MVAbase; + Branch[bri].qmaxt /= ps->MVAbase; + Branch[bri].loss0 /= ps->MVAbase; + + Branch[bri].isdcline = PETSC_TRUE; + ps->Nline++; + ps->nline++; + if (Branch[bri].status) { + ps->NlineON++; + ps->nlineON++; + ps->NdclineON++; + ps->ndclineON++; + } + + intbusnum = busext2intmap[Branch[bri].fbus]; + Branch[bri].internal_i = intbusnum; + + intbusnum = busext2intmap[Branch[bri].tbus]; + Branch[bri].internal_j = intbusnum; + + /* Update number of connected lines for the from and to bus */ + Bus[Branch[bri].internal_i].nconnlines++; + Bus[Branch[bri].internal_j].nconnlines++; + + /* Set from and to bus areas and zones for the line */ + Branch[bri].areaf = Bus[Branch[bri].internal_i].area; + Branch[bri].areat = Bus[Branch[bri].internal_j].area; + Branch[bri].zonef = Bus[Branch[bri].internal_i].zone; + Branch[bri].zonet = Bus[Branch[bri].internal_j].zone; + + PetscInt lineididx = 0; + for (linenum = 0; linenum < bri - 1; linenum++) { + if (Branch[bri].internal_i == Branch[linenum].internal_i && + Branch[bri].internal_j == Branch[linenum].internal_j) + lineididx += 1; + } + + /* MatPower does not have ids for lines. Using bri+1 as the id */ + snprintf(Branch[bri].ckt, 3, "%-2d", 1 + lineididx); + + if (Branch[bri].pmax < Branch[bri].pmin) { + bad_data = PETSC_TRUE; + ierr = PetscPrintf(ps->comm->type, + "%sPmax = %4.3f for DC line %d -- %d with id %s is " + "less than Pmin = %4.3f\n", + bad_data_str, Branch[bri].pmax, Branch[bri].fbus, + Branch[bri].tbus, Branch[bri].ckt, Branch[bri].pmin); + CHKERRQ(ierr); + } + + if (Branch[bri].qmaxf < Branch[bri].qminf) { + bad_data = PETSC_TRUE; + ierr = + PetscPrintf(ps->comm->type, + "%sQmaxf = %4.3f for DC line %d -- %d with id %s is " + "less than Qminf = %4.3f\n", + bad_data_str, Branch[bri].qmaxf, Branch[bri].fbus, + Branch[bri].tbus, Branch[bri].ckt, Branch[bri].qminf); + CHKERRQ(ierr); + } + + if (Branch[bri].qmaxt < Branch[bri].qmint) { + bad_data = PETSC_TRUE; + ierr = + PetscPrintf(ps->comm->type, + "%sQmaxt = %4.3f for DC line %d -- %d with id %s is " + "less than Qmint = %4.3f\n", + bad_data_str, Branch[bri].qmaxt, Branch[bri].fbus, + Branch[bri].tbus, Branch[bri].ckt, Branch[bri].qmint); + CHKERRQ(ierr); + } + bri++; } } + + if (bad_data) { + SETERRQ(ps->comm->type, 0, + "Found errors in input data. Please fix the suggested errors"); + } + fclose(fp); PetscFunctionReturn(0); @@ -1064,6 +1413,9 @@ PetscErrorCode PSReadGICData(PS ps) { bus = &ps->bus[ps->busext2intmap[bus_num]]; subst->bus[subst->nbus++] = bus; + subst->zone = bus->zone; + subst->area = bus->area; + for (int j = 0; j < subst->nkvlevels; j++) { if (PetscAbsScalar(bus->basekV - subst->kvlevels[j]) < 1e-6) { found = true; diff --git a/src/scopflow/interface/scopflow.cpp b/src/scopflow/interface/scopflow.cpp index f67b93c1e..dcf45fcec 100644 --- a/src/scopflow/interface/scopflow.cpp +++ b/src/scopflow/interface/scopflow.cpp @@ -72,6 +72,8 @@ PetscErrorCode SCOPFLOWCreate(MPI_Comm mpicomm, SCOPFLOW *scopflowout) { scopflow->ctgclist = NULL; scopflow->ctgcfileset = PETSC_FALSE; + scopflow->gicfileset = PETSC_FALSE; + /* Default subproblem model and solver */ #if 0 (void)std::strncpy(scopflow->subproblem_model, @@ -769,6 +771,12 @@ PetscErrorCode SCOPFLOWSetUp(SCOPFLOW scopflow) { CHKERRQ(ierr); } + /* Set any GIC file data */ + if (scopflow->gicfileset) { + ierr = OPFLOWSetGICData(scopflow->opflows[c], scopflow->gicfile); + CHKERRQ(ierr); + } + /* Set contingencies */ if (scopflow->ctgcfileset && scopflow->Nc > 1) { Contingency ctgc = scopflow->ctgclist->cont[scopflow->cstart + c]; @@ -1371,6 +1379,28 @@ SCOPFLOWSetContingencyData(SCOPFLOW scopflow, PetscFunctionReturn(0); } +/* + * @brief Set the gic data file for SCOPFLOW + * + * @param[in] scopflow application object + * @param[in] name of the gic file + * + * gicfile has the coordinates and the substation information. Used for + * visualization + */ +PetscErrorCode SCOPFLOWSetGICData(SCOPFLOW scopflow, const char gicfile[]) { + PetscErrorCode ierr; + + PetscFunctionBegin; + + ierr = PetscMemcpy(scopflow->gicfile, gicfile, + PETSC_MAX_PATH_LEN * sizeof(char)); + CHKERRQ(ierr); + scopflow->gicfileset = PETSC_TRUE; + + PetscFunctionReturn(0); +} + /* SCOPFLOWSetSubproblemModel - Set subproblem model diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index ac802c77d..880371e2d 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -44,7 +44,7 @@ else() "$<$,$>:SHELL:--compiler-options -Werror,-Wall,-Wextra>" ) set(CXX_COMPILE_OPTIONS - "$<$,$>:-Werror;-Wall;-Wextra;-Wpedantic>" + "$<$,$>:-Wall;-Wextra;-Wpedantic>" ) endif() diff --git a/tests/functionality/opflow/CMakeLists.txt b/tests/functionality/opflow/CMakeLists.txt index 70a3c445c..fc54fae77 100644 --- a/tests/functionality/opflow/CMakeLists.txt +++ b/tests/functionality/opflow/CMakeLists.txt @@ -163,6 +163,22 @@ if(EXAGO_INSTALL_TESTS) HIOP ) + exago_add_test( + NAME + OPFLOW_DCLINE_TEST + COMMAND + ${RUNCMD} + $ + -netfile + ${CMAKE_SOURCE_DIR}/datafiles/case9/case9_dcline.m + -opflow_solver + IPOPT + -opflow_model + POWER_BALANCE_POLAR + DEPENDS + IPOPT + ) + foreach(fmt "MATPOWER" "CSV" "JSON" "MINIMAL") set(tname "OPFLOW_SOLUTION_OUTPUT_${fmt}") exago_add_test( diff --git a/tests/functionality/opflow/ipopt_pbpol.toml b/tests/functionality/opflow/ipopt_pbpol.toml index 375fc9a6a..2ff3ac547 100644 --- a/tests/functionality/opflow/ipopt_pbpol.toml +++ b/tests/functionality/opflow/ipopt_pbpol.toml @@ -272,3 +272,11 @@ is_powerimb_active = true gen_bus_voltage_type = 'VARIABLE_WITHIN_BOUNDS' num_iters = 27 obj_value = 740032.301353 + +[[testcase]] +network = 'datafiles/case9/case9_dcline.m' +description = "Test for OPFLOW with DC line" +is_loadloss_active = false +is_powerimb_active = false +num_iters = 18 +obj_value = 5312.16147 diff --git a/viz/app.js b/viz/app.js index dc5c85975..46b05b661 100644 --- a/viz/app.js +++ b/viz/app.js @@ -40,7 +40,7 @@ import { LinearInterpolator, FlyToInterpolator } from 'deck.gl'; import { HeatmapLayer } from 'deck.gl'; import { InvertColorsOff, ShopTwoOutlined } from '@mui/icons-material'; -import { getCountyNodes, ExtractFirstTimeSlice, ExtractFlowData, getBarNet, getPoints, getGeneration, getLoad, getContours } from "./src/dataprocess"; +import { getCountyNodes, ExtractFirstTimeSlice, ExtractFlowData, getBarNet, getPoints, getGeneration, getLoad, getContours, getAreas, getZones } from "./src/dataprocess"; import { LineColor, FlowColor, FillColor, fillGenColumnColor, fillGenColumnColorCap, getVoltageFillColor } from "./src/color" import 'core-js/actual/structured-clone'; @@ -59,11 +59,12 @@ casedata = mod_casedata.get_casedata(); // Source data GeoJSON const geodata = casedata['geojsondata'] - +const style='pos'; const MAP_STYLE = { pos_no_label: 'https://basemaps.cartocdn.com/gl/positron-nolabels-gl-style/style.json', pos: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json', - dark: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json' + dark: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json', + none:'' }; @@ -72,8 +73,11 @@ var data = ExtractFirstTimeSlice(geodata); const countyloaddata = getCountyNodes(data); data = countyloaddata.updatedata; +const areas = getAreas(casedata); + +const zones = getZones(casedata); -var flowdata = ExtractFlowData(data); +const flowdata = ExtractFlowData(data); const Points = getPoints(data); const Voltages = Points.map(d => d.value); @@ -146,9 +150,15 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g const [busNameSelectItems, setBusNameSelectItems] = useState([]); const [busNameItems, setbusNameItems] = useState(data.features - .filter(f => f.geometry.type == "Point").map((f) => (f.properties.NAME))); + .filter(f => f.geometry.type == "Point").map((f) => (f.properties.NAME))); + + const [areaNameSelectItems, setAreaNameSelectItems] = useState([]); + + const [areaNameItems, setAreaNameItems] = useState(areas.features.map(f => f.properties.name)); + const [zoneNameSelectItems, setZoneNameSelectItems] = useState([]); + const [zoneNameItems, setZoneNameItems] = useState(zones.features.map(f => f.properties.name)); const [countyNameSelectItems, setCountyNameSelectItems] = useState([]); @@ -182,7 +192,7 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g const [netfiltervalue, setNetFilterValue] = useState([0, 800]); - const [flowfiltervalue, setFlowFilterValue] = useState([0, 800]); + const [flowfiltervalue, setFlowFilterValue] = useState([0, 120]); const [loadfiltervalue, setLoadFilterValue] = useState([0, countyloaddata.maxPd]); @@ -213,26 +223,32 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g lat: feature.geometry.coordinates[1] }) } else if (feature.geometry.type === "LineString" && lineNameSelectItems.includes(feature.properties.NAME)) { + var RATE_A; + if(feature.properties.RATE_A == 0) { + RATE_A = 10000; + } else { + RATE_A = feature.properties.RATE_A; + } + var loading = Math.abs(feature.properties.PF / RATE_A)*100; if (feature.properties.PF > 0) { const [origin, dest] = feature.properties.NAME.split(' -- ') flows.push({ origin: origin, dest: dest, - count: Math.abs(feature.properties.PF) + count: feature.properties.KV, + loading: loading }) } else { const [dest, origin] = feature.properties.NAME.split(' -- ') flows.push({ origin: origin, dest: dest, - count: Math.abs(feature.properties.PF) + count: feature.properties.KV, + loading: loading }) } - } - }) - } else if (busNameSelectItems.length > 0) { data.features.forEach(feature => { @@ -244,19 +260,29 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g lat: feature.geometry.coordinates[1] }) } else if (feature.geometry.type === "LineString" && feature.properties.NAME.split(' -- ').some(r => busNameSelectItems.includes(r))) { + var RATE_A; + if(feature.properties.RATE_A == 0) { + RATE_A = 10000; + } else { + RATE_A = feature.properties.RATE_A; + } + + var loading = Math.abs(feature.properties.PF / RATE_A)*100; if (feature.properties.PF > 0) { const [origin, dest] = feature.properties.NAME.split(' -- ') flows.push({ origin: origin, dest: dest, - count: Math.abs(feature.properties.PF) + count: feature.properties.KV, + loading: loading }) } else { const [dest, origin] = feature.properties.NAME.split(' -- ') flows.push({ origin: origin, dest: dest, - count: Math.abs(feature.properties.PF) + count: feature.properties.KV, + loading: loading }) } @@ -264,12 +290,10 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g }) } - else { + else { data.features.forEach(feature => { if (feature.geometry.type === "Point" && netfiltervalue[0] <= feature.properties.KVlevels[0] && - feature.properties.KVlevels[0] <= netfiltervalue[1] && - flowfiltervalue[0] <= feature.properties.KVlevels[0] && - feature.properties.KVlevels[0] <= flowfiltervalue[1]) { + feature.properties.KVlevels[0] <= netfiltervalue[1]) { locations.push({ id: feature.properties.NAME, name: feature.properties.NAME, @@ -277,30 +301,39 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g lat: feature.geometry.coordinates[1] }) } else if (feature.geometry.type === "LineString" && netfiltervalue[0] <= feature.properties.KV && - feature.properties.KV <= netfiltervalue[1] && - flowfiltervalue[0] <= feature.properties.KV && - feature.properties.KV <= flowfiltervalue[1]) { - if (feature.properties.PF > 0) { - const [origin, dest] = feature.properties.NAME.split(' -- ') - flows.push({ - origin: origin, - dest: dest, - count: Math.abs(feature.properties.PF) - }) - } else { - const [dest, origin] = feature.properties.NAME.split(' -- ') - flows.push({ - origin: origin, - dest: dest, - count: Math.abs(feature.properties.PF) - }) - } - + feature.properties.KV <= netfiltervalue[1]) { + var RATE_A; + if(feature.properties.RATE_A == 0) { + RATE_A = 10000; + } else { + RATE_A = feature.properties.RATE_A; + } + var loading = Math.abs(feature.properties.PF/RATE_A)*100.0; + + if(flowfiltervalue[0] <= loading && loading <= flowfiltervalue[1]) { + if (feature.properties.PF > 0) { + const [origin, dest] = feature.properties.NAME.split(' -- ') + flows.push({ + origin: origin, + dest: dest, + count: feature.properties.KV, + loading: loading + }) + } else { + const [dest, origin] = feature.properties.NAME.split(' -- ') + flows.push({ + origin: origin, + dest: dest, + count: feature.properties.KV, + loading: loading + }) + } + } } - }) - } - const newflowdata = { locations: locations, flows: flows } + } + + const newflowdata = { locations: locations, flows: flows, maxloading: 120 } setFlowData(newflowdata); }, [data, netfiltervalue, flowfiltervalue, lineNameSelectItems]); @@ -370,9 +403,10 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g popup.name = info.object.properties.NAME popup.info = "Substation Info" } else { - var popup = {}; - popup.name = info.object.properties.NAME - popup.info = "Line Info" + var popup = {}; + var loading = Math.abs(info.object.properties.PF / info.object.properties.RATE_A)*100.0; + popup.name = info.object.properties.NAME + popup.info = "KV: "+info.object.properties.KV.toFixed(2)+"KV \nLoading: "+loading.toFixed(2)+ "%"; } setShowPopup(showPopup => ({ ...showPopup, ...popup })); } else if (info.layer.id == "gen-column") { @@ -407,6 +441,54 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g }); + const zoomToAreaName = useCallback((filterareas,minLng, minLat, maxLng, maxLat) => { + var viewport = new WebMercatorViewport(INITIAL_VIEW_STATE); + + const { longitude, latitude, zoom } = viewport.fitBounds([[minLng, minLat], [maxLng, maxLat]]); + + setInitialViewState(viewState => ({ + ...viewState, + latitude: latitude, + longitude: longitude, + pitch: 50, + traansitionInterpolator: transitionFlyToInterpolator, + transitionDuration: 5000, + zoom: 7.5, + onTransitionEnd: activatePopup + })) + + var popup = { display: false, name: '', info: '' }; // Will be displayed after transition end only + popup.name = "Area " + filterareas.properties.name; +// popup.info = "Area: " + info.object.properties.name; + setShowPopup(showPopup => ({ ...showPopup, ...popup })); + + }); + + const zoomToZoneName = useCallback((filterzones,minLng, minLat, maxLng, maxLat) => { + var viewport = new WebMercatorViewport(INITIAL_VIEW_STATE); + + const { longitude, latitude, zoom } = viewport.fitBounds([[minLng, minLat], [maxLng, maxLat]]); + + setInitialViewState(viewState => ({ + ...viewState, + latitude: latitude, + longitude: longitude, + pitch: 50, + traansitionInterpolator: transitionFlyToInterpolator, + transitionDuration: 5000, + zoom: 7.5, + onTransitionEnd: activatePopup + })) + + var popup = { display: false, name: '', info: '' }; // Will be displayed after transition end only + popup.name = "Zone " + filterzones.properties.name; +// popup.info = "Zone: " + info.object.properties.name; + setShowPopup(showPopup => ({ ...showPopup, ...popup })); + + }); + + + const zoomToCounty = useCallback((info) => { if (!info) return null; @@ -433,7 +515,73 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g var popup = { display: false, name: '', info: '' }; // Will be displayed after transition end only popup.name = info.object.properties.NAME; - popup.info = "Load: " + info.object.properties.Pd.toFixed(2) + "MW"; + popup.info = "Load loss: " + info.object.properties.Pd.toFixed(2) + "MW"; + setShowPopup(showPopup => ({ ...showPopup, ...popup })); + + + } + }); + + const zoomToArea = useCallback((info) => { + if (!info) return null; + + if (info.layer.id == 'AreaLayer') { + var layer = info.layer; + var { viewport } = layer.context; + + var cbounds = bbox(info.object); + var c1 = [cbounds[0], cbounds[1]]; + var c2 = [cbounds[2], cbounds[3]]; + var areabounds = [c1, c2]; + const { longitude, latitude, zoom } = viewport.fitBounds(areabounds); + + setInitialViewState(viewState => ({ + ...viewState, + latitude: latitude, + longitude: longitude, + pitch: 50, + traansitionInterpolator: transitionFlyToInterpolator, + transitionDuration: 5000, + zoom: zoom - 0.25, + onTransitionEnd: activatePopup + })) + + var popup = { display: false, name: '', info: '' }; // Will be displayed after transition end only + popup.name = "Area " + info.object.properties.name; +// popup.info = "Area: " + info.object.properties.name; + setShowPopup(showPopup => ({ ...showPopup, ...popup })); + + + } + }); + + const zoomToZone = useCallback((info) => { + if (!info) return null; + + if (info.layer.id == 'ZoneLayer') { + var layer = info.layer; + var { viewport } = layer.context; + + var cbounds = bbox(info.object); + var c1 = [cbounds[0], cbounds[1]]; + var c2 = [cbounds[2], cbounds[3]]; + var zonebounds = [c1, c2]; + const { longitude, latitude, zoom } = viewport.fitBounds(zonebounds); + + setInitialViewState(viewState => ({ + ...viewState, + latitude: latitude, + longitude: longitude, + pitch: 50, + traansitionInterpolator: transitionFlyToInterpolator, + transitionDuration: 5000, + zoom: zoom - 0.25, + onTransitionEnd: activatePopup + })) + + var popup = { display: false, name: '', info: '' }; // Will be displayed after transition end only + popup.name = "Zone " + info.object.properties.name; +// popup.info = "Zone: " + info.object.properties.name; setShowPopup(showPopup => ({ ...showPopup, ...popup })); @@ -464,10 +612,9 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g const [genlayeractive, setGenLayerActive] = useState(false); const [genlayercapactive, setGenLayerCapActive] = useState(false); const [voltagelayeractive, setVoltageLayerActive] = useState(false); - - - - + const [zonelayeractive, setZoneLayerActive] = useState(false); + const [arealayeractive, setAreaLayerActive] = useState(false); + const handleUserInput = (inputText) => { console.log(`New message incoming! ${inputText}`); // Now send the message to GPT and get response @@ -554,8 +701,6 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g toggleMsgLoader(); // close loading }, [ouputMes]); - - const handleNetLayerChange = (event) => { setNetLayerActive(event.target.checked); setNetFilterValue([0, 800]); @@ -563,7 +708,8 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g const handleFlowLayerChange = (event) => { - setFlowLayerActive(event.target.checked); + setFlowLayerActive(event.target.checked); + setFlowFilterValue([0, 120]); }; const handleLoadLayerChange = (event) => { @@ -590,6 +736,31 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g }))) }; + const handleAreaLayerChange = (event) => { + setAreaLayerActive(event.target.checked); +// setVoltageFilterValue([0.89, 1.11]); + + event.target.checked && (setInitialViewState(viewState => ({ + ...viewState, + pitch: 40, + traansitionInterpolator: transitionFlyToInterpolator, + transitionDuration: 2000, + }))) + }; + + const handleZoneLayerChange = (event) => { + setZoneLayerActive(event.target.checked); +// setVoltageFilterValue([0.89, 1.11]); + + event.target.checked && (setInitialViewState(viewState => ({ + ...viewState, + pitch: 40, + traansitionInterpolator: transitionFlyToInterpolator, + transitionDuration: 2000, + }))) + }; + + const handleGenLayerChange = (event) => { setGenLayerActive(event.target.checked); setGenFilterValue([gendata.minPg, gendata.maxPg]); @@ -640,8 +811,21 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g if (netfiltervalue[0] <= KV && KV <= netfiltervalue[1]) return KV; } } else { - /* Line layer */ - return data.properties.KV; + if(data.geometry.type == 'LineString') { /* Line layer */ + /* Uncomment to activate flow-based filtering + var RATE_A; + if(data.properties.RATE_A == 0) { + RATE_A = 10000; + } else { + RATE_A = data.properties.RATE_A; + } + var loading = Math.abs(data.properties.PF / RATE_A)*100; + if(flowfiltervalue[0] <= loading && loading <= flowfiltervalue[1]) { + return data.properties.KV; + } + */ + return data.properties.KV; + } } } @@ -649,7 +833,7 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g } function getFlowFilterValue(data) { - console.log(data) + } function getGenFilterValue(data) { @@ -777,7 +961,7 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g extensions: [new DataFilterExtension({ filtersize: 1 })], updateTriggers: { - getFilterValue: [netfiltervalue, lineNameSelectItems, busNameSelectItems] + getFilterValue: [netfiltervalue, lineNameSelectItems, busNameSelectItems, flowfiltervalue] } }), @@ -875,6 +1059,59 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g }), */ + + new GeoJsonLayer({ + id: 'AreaLayer', + data: areas, + pickable: arealayeractive, + visible: arealayeractive, + stroked: true, + filled: true, + extruded: true, + wireframe: true, + lineWidthMinPixels: 1, + getPolygon: d => d.geometry.coordinates, + // getElevation: d => d.properties.Pd*5.0, + getFillColor: [255, 192, 203], + getLineColor: [80, 80, 80], + getLineWidth: d => 1, + opacity: 0.1, + onClick: zoomToArea, +// extensions: [new DataFilterExtension({ filtersize: 1 })], +// getFilterValue: getLoadFilterValue, +// filterRange: loadfiltervalue, + +// updateTriggers: { +// getFilterValue: [netfiltervalue, countyNameSelectItems] +// } + }), + + new GeoJsonLayer({ + id: 'ZoneLayer', + data: zones, + pickable: zonelayeractive, + visible: zonelayeractive, + stroked: true, + filled: true, + extruded: true, + wireframe: true, + lineWidthMinPixels: 1, + getPolygon: d => d.geometry.coordinates, + // getElevation: d => d.properties.Pd*5.0, + getFillColor: [252, 245, 95], + getLineColor: [80, 80, 80], + getLineWidth: d => 1, + opacity: 0.1, + onClick: zoomToZone, +// extensions: [new DataFilterExtension({ filtersize: 1 })], +// getFilterValue: getLoadFilterValue, +// filterRange: loadfiltervalue, + +// updateTriggers: { +// getFilterValue: [netfiltervalue, countyNameSelectItems] +// } + }), + new GeoJsonLayer({ id: 'PolygonLayerload', data: countyload, @@ -1069,6 +1306,56 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g } } + const handleAreaMultiselect = (selectItem, metadata) => { + + const selected = areaNameSelectItems.indexOf(metadata.dataItem) + console.log(selected); + if (selected >= 0) { //if is selected, remove + const newArray = [...areaNameSelectItems.slice(0, selected), ...areaNameSelectItems.slice(selected + 1)]; + setAreaNameSelectItems(newArray) + + } else { //add to array + setAreaNameSelectItems(areaNameSelectItems => ([...areaNameSelectItems, metadata.dataItem])) + const filterareas = areas.features.filter(area => area.properties.name === metadata.dataItem) + if (filterareas.length > 0) { + const longs = filterareas[0].geometry.coordinates[0].map(d => d[0]) + const lats = filterareas[0].geometry.coordinates[0].map(d => d[1]) + const minLng = Math.min(...longs) + const maxLng = Math.max(...longs) + const minLat = Math.min(...lats) + const maxLat = Math.max(...lats) + + zoomToAreaName(filterareas[0],minLng, minLat, maxLng, maxLat) + } + } + } + + const handleZoneMultiselect = (selectItem, metadata) => { + + const selected = zoneNameSelectItems.indexOf(metadata.dataItem) + console.log(selected); + if (selected >= 0) { //if is selected, remove + const newArray = [...zoneNameSelectItems.slice(0, selected), ...zoneNameSelectItems.slice(selected + 1)]; + setZoneNameSelectItems(newArray) + + } else { //add to array + setZoneNameSelectItems(zoneNameSelectItems => ([...zoneNameSelectItems, metadata.dataItem])) + const filterzones = zones.features.filter(area => area.properties.name === metadata.dataItem) + if (filterzones.length > 0) { + const longs = filterzones[0].geometry.coordinates[0].map(d => d[0]) + const lats = filterzones[0].geometry.coordinates[0].map(d => d[1]) + const minLng = Math.min(...longs) + const maxLng = Math.max(...longs) + const minLat = Math.min(...lats) + const maxLat = Math.max(...lats) + + zoomToZoneName(filterzones[0],minLng, minLat, maxLng, maxLat) + } + } + } + + + const renderItem = ({ id, name @@ -1194,7 +1481,7 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g @@ -1293,9 +1580,9 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g valueLabelDisplay="auto" onChange={handleFlowRangeFilterChange} getAriaValueText={valuetext} - step={100} + step={10} min={0} - max={800} + max={120} > ) } @@ -1375,7 +1662,7 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g }> - Load + Load loss @@ -1442,6 +1729,44 @@ export default function App({ refdata = data, refflowdata = flowdata, ggdata = g + + }> + + Show Areas + + + + + {arealayeractive && (
)} +
+
+
+ + + }> + + Show Zones + + + + + {zonelayeractive && (
)} +
+
+
+ {/*

*/} diff --git a/viz/geninputfile.py b/viz/geninputfile.py index 79d6ceb87..1d8beb189 100644 --- a/viz/geninputfile.py +++ b/viz/geninputfile.py @@ -12,6 +12,10 @@ f.write('\n') f.write('\t\t\t\tvar casedata0 = {};\n') f.write('\t\t\t\tcasedata0.geojsondata = {};\n') + f.write('\t\t\t\tcasedata0.nareas = inputcasedata.nareas;\n') + f.write('\t\t\t\tcasedata0.nzones = inputcasedata.nzones;\n') + f.write('\t\t\t\tcasedata0.areas = inputcasedata.areas;\n') + f.write('\t\t\t\tcasedata0.zones = inputcasedata.zones;\n') f.write('\t\t\t\tcasedata0.geojsondata.type = "FeatureCollection";\n') f.write( '\t\t\t\tcasedata0.geojsondata.features = [...inputcasedata.geojsondata.features];\n') diff --git a/viz/src/dataprocess.js b/viz/src/dataprocess.js index 511dc1f08..100b2bb27 100644 --- a/viz/src/dataprocess.js +++ b/viz/src/dataprocess.js @@ -35,7 +35,7 @@ function getCountyNodes(data) { countydata.features[j].properties.KVlevels = [...countydata.features[j].properties.KVlevels, ...data.features[i].properties.KVlevels]; for (var k = 0; k < nbus; k++) { var bus = subst.bus[k]; - countydata.features[j].properties.Pd += bus.PD; + countydata.features[j].properties.Pd += bus.PDloss; countydata.features[j].properties.Vm_avg += bus.VM; nbuscounty++; @@ -90,19 +90,28 @@ function ExtractFlowData(data) { lat: feature.geometry.coordinates[1] }) } else if (feature.geometry.type === "LineString") { + var RATE_A; + if(feature.properties.RATE_A == 0) { + RATE_A = 10000; + } else { + RATE_A = feature.properties.RATE_A; + } + var loading = Math.abs(feature.properties.PF / RATE_A)*100; if (feature.properties.PF > 0) { const [origin, dest] = feature.properties.NAME.split(' -- ') flows.push({ origin: origin, dest: dest, - count: feature.properties.KV + count: feature.properties.KV, + loading: loading }) } else { const [dest, origin] = feature.properties.NAME.split(' -- ') flows.push({ origin: origin, dest: dest, - count: feature.properties.KV + count: feature.properties.KV, + loading: loading }) } @@ -114,7 +123,7 @@ function ExtractFlowData(data) { const uniq = new Set(flows.map(e => JSON.stringify(e))); const res = Array.from(uniq).map(e => JSON.parse(e)); return ({ - locations: locations, flows: res + locations: locations, flows: res, maxloading: 120 }) } @@ -235,8 +244,8 @@ function getLoad(data) { var Qd = 0.0; for (j = 0; j < nbus; j++) { var bus = subst.bus[j]; - Pd += bus.PD; - Qd += bus.QD; + Pd += bus.PDloss; + Qd += bus.QDloss; } if (Pd > 0) { if (Pd <= minPd) minPd = Pd; @@ -261,4 +270,72 @@ function getContours() { return contours; } -export { getCountyNodes, ExtractFirstTimeSlice, ExtractFlowData, getBarNet, getPoints, getGeneration, getLoad, getContours }; +// Filter features with geometry type "Point" and properties area = area_num +function getArea(data,area_num) { + var filteredFeatures = data.features.filter(feature => + feature.geometry.type === "Point" && feature.properties.area === area_num + ); + + // Create a new GeoJSON object with filtered features + var filteredGeoJSON = { + type: "FeatureCollection", + features: filteredFeatures + }; + + var areahull = convex(filteredGeoJSON); + if(areahull) { + areahull.properties ={name: area_num}; + } + + return areahull; +} + +function getAreas(sysdata) { + + var areas = []; + + for(var i = 0; i < sysdata.nareas; i++) { + var area = getArea(sysdata.geojsondata,sysdata.areas[i]); + if(area) { + areas.push(area); + } + } + + return {type:"FeatureCollection", features:areas}; +} + +// Filter features with geometry type "Point" and properties zone = zone_num +function getZone(data,zone_num) { + var filteredFeatures = data.features.filter(feature => + feature.geometry.type === "Point" && feature.properties.zone === zone_num + ); + + // Create a new GeoJSON object with filtered features + var filteredGeoJSON = { + type: "FeatureCollection", + features: filteredFeatures + }; + + var zonehull = convex(filteredGeoJSON); + if(zonehull) { + zonehull.properties ={name: zone_num}; + } + + return zonehull; +} + +function getZones(sysdata) { + + var zones = []; + + for(var i = 0; i < sysdata.nzones; i++) { + var zone = getZone(sysdata.geojsondata,sysdata.zones[i]); + if(zone) { + zones.push(zone); + } + } + + return {type:"FeatureCollection", features:zones}; +} + +export { getCountyNodes, ExtractFirstTimeSlice, ExtractFlowData, getBarNet, getPoints, getGeneration, getLoad, getContours, getAreas, getZones };