Skip to content

Instantly share code, notes, and snippets.

@capnfabs
Created April 22, 2020 15:29
Show Gist options
  • Save capnfabs/218416d3a630ed35de0c646cecf4acbd to your computer and use it in GitHub Desktop.
Save capnfabs/218416d3a630ed35de0c646cecf4acbd to your computer and use it in GitHub Desktop.
A super quick example of running a Sensitivity Analysis
PerturbAndObserveRunner<Complex> runner = new PerturbAndObserveRunner<Complex>(new OpenDSSSimulator());
runner.NetworkFilename = "network.dss";
//adjust everything for single phase/3-phase
var numphases = Phase != 0 ? 1 : 3;
var phases = Phase != 0 ? ("."+Phase+".0"): "";
// The {0}, {1}... arguments here will be populated with values from PerturbElementValuesSelector.
runner.PerturbCommands = new String[] { "new Generator.{0} bus1={1}"+phases+" phases="+numphases+" model=1 status=fixed kV={2} Vminpu=0.5 Vmaxpu=2 kW={3} kvAR=0" };
if (Phase == 0)
runner.PerturbElementSelector = network => network.Buses.Values;
else //ensure we're using the phase.
runner.PerturbElementSelector = network => network.Buses.Values.Where(bus => bus.ConnectedToPhased.ContainsKey(Phase));
var perturbation = 1; // in kVA
// First, let's perturb by adding kW generation to the network and see what happens
runner.PerturbElementValuesSelector = elem => { Bus b = (Bus)elem; return new Object[] { "gg-" + b.ID, b.ID, b.BaseVoltage * (Phase == 0 ? Math.Sqrt(3) : 1) / 1000, perturbation }; };
runner.PerturbValuesToRecord = x => x[3];
runner.ObserveElementSelector = network => network.Buses.Values;
if (Phase == 0)
runner.ObserveElementValuesSelector = elem => ((Bus)elem).Voltage;
else
runner.ObserveElementValuesSelector = elem => ((Bus)elem).VoltagePhased[Phase];
runner.RunPerturbAndObserve();
SensitivityGenerator<Complex> generatorMagnitude = new SensitivityGenerator<Complex>();
generatorMagnitude.RecordedPerturbationSelector = x => x;
generatorMagnitude.ResultSelector = x => x.Magnitude;
SensitivityGenerator<Complex> generatorPhase = new SensitivityGenerator<Complex>();
generatorPhase.RecordedPerturbationSelector = x => x;
generatorPhase.ResultSelector = x => x.Phase;
var sensitivitiesPV = generatorMagnitude.GenerateSensitivities(runner);
var sensitivitiesPd = generatorPhase.GenerateSensitivities(runner);
// Second, let's perturb by adding kVAr instead of kW.
runner.PerturbCommands = new String[] { "new Generator.{0} bus1={1}" + phases + " phases=" + numphases + " model=1 status=fixed kV={2} Vminpu=0.5 Vmaxpu=2 kW=0 kvAR={3}" };
runner.RunPerturbAndObserve();
var sensitivitiesQV = generatorMagnitude.GenerateSensitivities(runner);
var sensitivitiesQd = generatorPhase.GenerateSensitivities(runner);
//merge the tables.
// All of your sensitivity data will be in `table` by the end of this section.
SensitivityTable table = new SensitivityTable();
{
foreach (var kvpX in sensitivitiesPV.MapX)
foreach(var kvpY in kvpX.Value)
{
var thingy = new VoltageSensitivityToPQDataSet();
thingy.dV_dP = kvpY.Value;
thingy.dV_dQ = sensitivitiesQV.MapX[kvpX.Key][kvpY.Key];
thingy.dd_dP = sensitivitiesPd.MapX[kvpX.Key][kvpY.Key];
thingy.dd_dQ = sensitivitiesQd.MapX[kvpX.Key][kvpY.Key];
table.Add(kvpX.Key, kvpY.Key, thingy);
}
}
_Sensitivities = table;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment