### Install distopf using pip Source: https://github.com/gridappsd/distopf/blob/main/README.md Install the DistOPF package using pip. This is the standard installation method for most users. ```bash pip install distopf ``` -------------------------------- ### Build Your Own OPF Example Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md Construct a custom optimal power flow model using Pyomo. This example is useful for advanced users who need to define specific objectives and constraints. ```shell uv run examples/pyomo/build_your_own_opf.py ``` -------------------------------- ### Import CIM Data Example Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md Demonstrates how to import network data using the CIM format. This is essential for integrating with existing grid models. ```shell uv run examples/data_import/cim_example.py ``` -------------------------------- ### Run Simple Power Flow Example Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md Execute a basic power flow analysis on a network. This is a fundamental step for understanding network behavior. ```shell uv run examples/tutorials/01_simple_power_flow.py ``` -------------------------------- ### Install distopf with CIM support Source: https://github.com/gridappsd/distopf/blob/main/README.md Install DistOPF with the 'cim' extra to enable CIM XML file import support. This requires pre-release packages. ```bash pip install distopf[cim] ``` -------------------------------- ### Install distopf from GitHub (Editable Mode) Source: https://github.com/gridappsd/distopf/blob/main/README.md Install the latest version of DistOPF from GitHub in editable mode. This allows for direct code changes to be reflected without reinstallation. ```bash git clone https://github.com/nathantgray/distopf.git ``` ```bash pip install -e . ``` -------------------------------- ### Run Power Flow using Lower-Level API Source: https://github.com/gridappsd/distopf/blob/main/examples/basics/basic_power_flow_examples.html This example shows how to use the lower-level API for power flow analysis. It initializes a LinDistModel with case data, solves it using cvxpy with a curtailment objective, and then plots the resulting voltages, apparent power flows, and generator power outputs. ```python case = opf.Case(data_path="ieee123_30der", gen_mult=10, control_variable="P") model = opf.LinDistModel( branch_data=case.branch_data, bus_data=case.bus_data, gen_data=case.gen_data, cap_data=case.cap_data, reg_data=case.reg_data ) # Solve model using provided objective function # result = opf.lp_solve(model, np.zeros(model.n_x)) result = opf.cvxpy_solve(model, opf.cp_obj_curtail) print(result.fun) v = model.get_voltages(result.x) s = model.get_apparent_power_flows(result.x) p_gens = model.get_p_gens(result.x) q_gens = model.get_q_gens(result.x) opf.plot_network(model, v, s, p_gen=p_gens, q_gen=q_gens).show() opf.plot_voltages(v).show() opf.plot_power_flows(s).show() ``` -------------------------------- ### Load CIM XML Case Source: https://github.com/gridappsd/distopf/blob/main/README.md Use the `create_case` function from the distopf library to load a power system model from a CIM XML file. Ensure the 'cim' extra is installed. ```python import distopf as opf case = opf.create_case(data_path="path/to/model.xml") ``` -------------------------------- ### Install distopf with CIM support from GitHub (Editable Mode) Source: https://github.com/gridappsd/distopf/blob/main/README.md Install DistOPF from GitHub in editable mode with the optional CIM extra. This enables CIM XML file import support and allows for direct code changes. ```bash pip install -e ".[cim]" ``` -------------------------------- ### Basic Pyomo Model with Constraints and Loss Objective Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md A Python script for a basic Pyomo model setup, including constraint configuration and a loss minimization objective. It demonstrates `equality_only=True` for constraint handling. ```python from gridappes.api import create_case, build_pyomo_model from pyomo.environ import Objective, minimize # Load a standard test case case = create_case("ieee_123_30der") # Build the Pyomo model with specific configurations model = build_pyomo_model( case, formulation="matpower", # Example formulation equality_only=True, # Only equality constraints # Add other configurations as needed ) # Define a loss minimization objective def loss_objective(model): # This is a placeholder; actual loss calculation depends on the model formulation return sum(model.p_inj[i]**2 for i in model.line) # Example: sum of squared power injections model.objective = Objective(expr=loss_objective(model), sense=minimize) # Solve the model (requires a Pyomo solver to be installed and configured) # results = model.solve() print("Pyomo model built with loss objective and equality constraints.") ``` -------------------------------- ### ImportError for CIM Support Source: https://github.com/gridappsd/distopf/blob/main/README.md This error occurs if the 'cim' extra is not installed when attempting to load a CIM XML file. The message provides instructions on how to install the required dependencies. ```python ImportError: CIM file support requires optional dependencies. Install them with: pip install distopf[cim] ``` -------------------------------- ### Import distopf Library Source: https://github.com/gridappsd/distopf/blob/main/examples/basics/basic_power_flow_examples.html Import the distopf library for power flow analysis. This is a common first step in using the library. ```python import distopf as opf ``` -------------------------------- ### Build Modular Pyomo OPF (24h Multiperiod) Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md A Marimo notebook demonstrating the construction of a modular Pyomo OPF model for a 24-hour multiperiod scenario. It includes features like `create_lindist_model()`, `add_*_constraints()`, custom objectives, and battery modeling. ```python import marimo as mo from gridappes.api import create_lindist_model from pyomo.environ import Objective, Constraint, NonNegativeReals # Placeholder for Marimo UI and model building logic # This notebook would typically involve defining network topology, # creating a Pyomo model using create_lindist_model(), adding constraints # for power balance, voltage limits, generator limits, and potentially # battery charge/discharge dynamics over 24 hours. # Example of adding a custom objective: # model.objective = Objective(expr=sum(model.p_inj[t, i] for t in model.time for i in model.line), sense=minimize) # Example of adding battery constraints: # model.soc = Var(model.time, model.battery, domain=NonNegativeReals) # model.charge_rate = Var(model.time, model.battery, domain=Reals) # model.discharge_rate = Var(model.time, model.battery, domain=Reals) # model.soc[t, b] == model.soc[t-1, b] + model.charge_rate[t, b] - model.discharge_rate[t, b] # Simplified SOC update mo.md("This Marimo notebook guides users through building a modular, 24-hour multiperiod Pyomo OPF model. It covers creating the model structure, defining various constraints (e.g., power balance, voltage, generator limits), and incorporating custom objectives and battery energy storage system dynamics.") ``` -------------------------------- ### Create and Run a Power Flow Case Source: https://github.com/gridappsd/distopf/blob/main/README.md Use `create_case()` to set up a power flow case with specified configurations or data paths. Subsequently, call `run_pf()` or `run_opf()` to execute the power flow or optimal power flow calculation and obtain results. ```python import distopf as opf case = opf.create_case( config="path/to/your_config.json", # or # data_path="path/to/your_data_directory/", # or # data_path="ieee13", output_dir="output", branch_data=None, bus_data=None, gen_data=None, cap_data=None, reg_data=None, v_swing=1.0, v_min=0.9, v_max=1.1, gen_mult=1.0, load_mult=1.0, cvr_p=1.0, cvr_q=1.0, control_variable="P", objective_function="gen_max", show_plots=False, save_results=False, save_plots=False, save_inputs=False ) # To run power flow: # pf_results = opf.run_pf(case) # To run optimal power flow: # opf_results = opf.run_opf(case) ``` -------------------------------- ### Compare Linear Pyomo vs Nonlinear BranchFlow Solves Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md This script compares the performance and results of linear Pyomo formulations against nonlinear BranchFlow solves. It highlights the use of `wrapper="pyomo"` versus `formulation="branchflow"` and FBS initialization. ```python from gridappes.api import create_case, run_opf # Load a standard test case case = create_case("ieee_123_30der") # Run OPF using Pyomo wrapper results_pyomo = run_opf(case, "loss_min", wrapper="pyomo") # Run OPF using BranchFlow formulation (nonlinear) # Note: FBS initialization might be implicitly used or explicitly configured results_branchflow = run_opf(case, "loss_min", formulation="branchflow") # Compare results (e.g., objective values, voltages, run times) print("Pyomo Wrapper Results:") print(f" Objective: {results_pyomo.objective_value}") print("BranchFlow Results:") print(f" Objective: {results_branchflow.objective_value}") # Further analysis and comparison can be added here ``` -------------------------------- ### Load DSS Case and Solve with Pyomo Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md This script demonstrates loading a network model from a Distributed System Simulator (DSS) file and solving it using a Pyomo formulation. It utilizes `create_lindist_model()` and includes a loss objective. ```python from gridappes.api import create_lindist_model from pyomo.environ import Objective, minimize # Path to your DSS file dss_file_path = "path/to/your/network.dss" # Create a linear distribution model from the DSS file # This function parses the DSS file and prepares it for Pyomo model = create_lindist_model(dss_file_path) # Define a loss minimization objective def loss_objective(model): # Placeholder for loss calculation based on model variables return sum(model.p_inj[i]**2 for i in model.line) # Example model.objective = Objective(expr=loss_objective(model), sense=minimize) # Solve the Pyomo model # results = model.solve() print(f"Successfully loaded DSS file '{dss_file_path}' and configured Pyomo model with loss objective.") ``` -------------------------------- ### Nonlinear OPF with Optional FBS Initialization Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md This script performs a nonlinear optimal power flow using the BranchFlow formulation. It supports optional Forward-Backward Sweep (FBS) initialization and can utilize solvers like IPOPT or Bonmin. It also handles discrete control for regulators and capacitors. ```python from gridappes.api import create_case, run_opf # Load a standard test case case = create_case("ieee_123_30der") # Run nonlinear OPF using BranchFlow formulation # Specify solver and initialization options results = run_opf( case, "loss_min", formulation="branchflow", solver_options={'solver': 'ipopt'}, # Example: Use IPOPT solver # fbs_init=True, # Uncomment to enable FBS initialization # discrete_control=True # Uncomment to enable discrete control logic ) print("Nonlinear OPF with BranchFlow formulation executed.") print(f"Objective value: {results.objective_value}") ``` -------------------------------- ### Basic Power Flow Script Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md A Python script demonstrating basic power flow analysis using the `create_case()` and `run_pf()` functions. ```python from gridappsd import GridAPPSD from gridappes.api import create_case, run_pf # Load a standard test case case = create_case("ieee_123_30der") # Run power flow results = run_pf(case) # Print results (e.g., voltages) print(results.voltages) ``` -------------------------------- ### Build Static Single-Step Modular Pyomo OPF Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md A Marimo notebook for building a static, single-step modular Pyomo OPF model. It focuses on Pyomo constraints, penalized objectives, and network visualization. ```python import marimo as mo from gridappes.api import create_lindist_model, plot_network from pyomo.environ import Objective, Constraint, minimize # Placeholder for Marimo UI and model building logic # This notebook would involve creating a Pyomo model for a single time step, # defining constraints like power balance and limits, and setting up a penalized objective. # Example of a penalized objective: # model.penalty_term = Var(initialize=0) # model.objective = Objective(expr=sum(model.p_inj[i] for i in model.line) + model.penalty_term, sense=minimize) # model.penalty_constraint = Constraint(expr=model.penalty_term >= 0) mo.md("This Marimo notebook demonstrates building a static, single-step modular Pyomo OPF model. It highlights the use of Pyomo constraints, the implementation of penalized objectives for handling infeasibilities or specific goals, and includes network visualization capabilities.") ``` -------------------------------- ### Enable Discrete Controls with MINLP Solvers Source: https://github.com/gridappsd/distopf/blob/main/README.md Use this snippet to enable regulator tap optimization and capacitor switching when using MINLP solvers. Ensure a MINLP-compatible solver like Gurobi is specified. ```python import distopf as opf case = opf.create_case(opf.CASES_DIR / "csv" / "ieee123") result = case.run_opf( wrapper="pyomo", model_type="branchflow", objective="loss", control_regulators=True, # Enable regulator tap control control_capacitors=True, # Enable capacitor switching initialize="fbs", # Recommended for discrete controls solver="gurobi", # MINLP compatible solver ) ``` -------------------------------- ### Run Loss Minimization OPF with Pyomo (BranchFlow - IPOPT) Source: https://github.com/gridappsd/distopf/blob/main/README.md Solve for loss minimization using the Pyomo wrapper with the BranchFlow model type and the IPOPT solver. This uses nonlinear power flow equations for higher accuracy. ```python import distopf as opf case = opf.create_case(opf.CASES_DIR / "csv" / "ieee123_30der") result = case.run_opf( model_type="branchflow", objective="loss", solver="ipopt", ) ``` -------------------------------- ### Run Power Flow with OpenDSS Model Source: https://github.com/gridappsd/distopf/blob/main/README.md Initialize a case using an existing OpenDSS model file. This method allows leveraging pre-defined network configurations from OpenDSS. ```python import distopf as opf case = opf.create_case( data_path="path/to/your_model_directory/model.dss", ) ``` -------------------------------- ### Multi-Period Optimization with Matrix BESS Wrapper Source: https://github.com/gridappsd/distopf/blob/main/README.md This snippet demonstrates how to perform multi-period (time-series) optimization with battery energy storage using the `matrix_bess` wrapper. The shorthand `wrapper="matrix_bess"` is also supported. ```python import distopf as opf case = opf.create_case(opf.CASES_DIR / "csv" / "ieee123_30der_batt") result = case.run_opf(wrapper="matrix_bess", objective="loss") ``` -------------------------------- ### Benchmark Matrix vs Pyomo Solver Performance Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md This script benchmarks the performance of matrix-based OPF solvers against Pyomo-based solvers. It profiles the build and solve times for `matrix_bess` and Pyomo formulations. ```python import time from gridappes.api import create_case, run_opf # Load a standard test case case = create_case("ieee_123_30der") # --- Matrix-based solver benchmark --- start_time = time.time() # Assuming 'matrix_bess' is a direct function or method call # results_matrix = run_opf(case, "loss_min", formulation="matrix_bess") # Example syntax end_time = time.time() matrix_build_solve_time = end_time - start_time # --- Pyomo-based solver benchmark --- start_time = time.time() results_pyomo = run_opf(case, "loss_min", wrapper="pyomo") end_time = time.time() pyomo_build_solve_time = end_time - start_time print(f"Matrix-based solver build/solve time: {matrix_build_solve_time:.4f} seconds") print(f"Pyomo solver build/solve time: {pyomo_build_solve_time:.4f} seconds") # Further analysis can compare objective values and solution quality ``` -------------------------------- ### Marimo Notebook: PF and OPF on IEEE Networks Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md An interactive Marimo notebook showcasing power flow and optimal power flow on IEEE networks. It utilizes `create_case()`, `run_pf()`, `run_opf()`, and `plot_network()`. ```python import marimo as mo from gridappes.api import create_case, run_pf, run_opf, plot_network # Define UI elements for network selection and OPF objective network_selector = mo.ui.Dropdown(options=["ieee_123_30der", "other_network"]) opf_objective = mo.ui.Dropdown(options=["loss_min", "voltage_control"]) # Function to run analysis based on UI selections def run_analysis(network_name, objective): case = create_case(network_name) pf_results = run_pf(case) opf_results = run_opf(case, objective) return pf_results, opf_results # Display results and plots @mo.capture def display_results(network_name, objective): pf_results, opf_results = run_analysis(network_name, objective) st = mo.hstack([ mo.vstack([mo.md("# Power Flow Results"), pf_results.voltages]), mo.vstack([mo.md("# OPF Results"), opf_results.voltages]) ]) plot_network(opf_results) return st # Layout the Marimo app app_layout = mo.ui.vstack([ network_selector, opf_objective, mo.ui.button(label="Run Analysis", on_click=display_results.run) ]) app_layout ``` -------------------------------- ### Run Loss Minimization OPF with Pyomo (LinDistFlow) Source: https://github.com/gridappsd/distopf/blob/main/README.md Use the default Pyomo wrapper with the LinDistFlow model to solve for loss minimization. This model is a linear approximation suitable for fast calculations. ```python import distopf as opf case = opf.create_case(opf.CASES_DIR / "csv" / "ieee123_30der") result = case.run_opf(wrapper="pyomo", objective="loss") # model_type="lindist" is the default ``` -------------------------------- ### 24-Hour Multiperiod Optimization with Batteries Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md This script demonstrates a 24-hour multiperiod optimization problem incorporating battery energy storage systems (BESS). It includes constraints for battery state of charge (SOC) and energy limits, enabling time-series scheduling. ```python from gridappes.api import create_case, build_pyomo_model from pyomo.environ import Objective, Constraint, Var, NonNegativeReals, Reals, minimize # Load a standard test case case = create_case("ieee_123_30der") # Build the Pyomo model for multiperiod optimization # This would typically involve specifying the time periods (e.g., 24 hours) model = build_pyomo_model( case, time_periods=24, # Specify 24 time periods # Add configurations for batteries if not default ) # Define battery variables (example) # model.soc = Var(model.time, model.battery, domain=NonNegativeReals) # model.charge_rate = Var(model.time, model.battery, domain=Reals) # model.discharge_rate = Var(model.time, model.battery, domain=Reals) # Add battery constraints (example - simplified SOC update) # def soc_update_rule(model, t, b): # if t == model.time.first(): # return model.soc[t, b] == model.initial_soc[b] + model.charge_rate[t, b] - model.discharge_rate[t, b] # else: # prev_t = model.time.prev(t) # return model.soc[t, b] == model.soc[prev_t, b] + model.charge_rate[t, b] - model.discharge_rate[t, b] # model.soc_update = Constraint(model.time, model.battery, rule=soc_update_rule) # Define an objective (e.g., minimize operating cost) # model.objective = Objective(expr=sum(...), sense=minimize) # Solve the model # results = model.solve() print("24-hour multiperiod optimization model with batteries configured.") ``` -------------------------------- ### Basic Optimal Power Flow Script Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md A Python script for running a basic optimal power flow with loss minimization and visualizing the results. ```python from gridappsd import GridAPPSD from gridappes.api import create_case, run_opf # Load a standard test case case = create_case("ieee_123_30der") # Run OPF with loss minimization objective results = run_opf(case, "loss_min") # Plot network results (voltages, power flows, generators) results.plot_network() ``` -------------------------------- ### create_case and run_pf/run_opf Source: https://github.com/gridappsd/distopf/blob/main/README.md This function creates a power system case from various data inputs and can then be used to run power flow or optimal power flow analysis. It accepts configurations, data paths, and overrides for system parameters. ```APIDOC ## create_case and run_pf/run_opf ### Description Creates and runs a power system case using specified configuration or data. Supports running power flow or optimal power flow with various control and objective functions. ### Method Python function calls ### Parameters #### `create_case` Parameters - **config** (str or dict) - Path to JSON config or dictionary with parameters to create case. Alternative to using **config. - **data_path** (str or pathlib.Path) - Path to the directory containing the data CSVs or path to OpenDSS model. Will also accept names of cases include in package e.g. "ieee13", "ieee34", "ieee123". - **output_dir** (str or pathlib.Path) - (default: "output") Directory to save results. - **branch_data** (pd.DataFrame or None) - DataFrame containing branch data (r and x values, limits). Overrides data found from data_path. - **bus_data** (pd.DataFrame or None) - DataFrame containing bus data (loads, voltages, limits). Overrides data found from data_path. - **gen_data** (pd.DataFrame or None) - DataFrame containing generator/DER data. Overrides data found from data_path. - **cap_data** (pd.DataFrame or None) - DataFrame containing capacitor data. Overrides data found from data_path. - **reg_data** (pd.DataFrame or None) - DataFrame containing regulator data. Overrides data found from data_path. - **v_swing** (Number or size-3 array) - Override substation voltage. Scalar or 3-phase array. Per Unit. - **v_min** (Number) - Override all voltage minimum limits. Per Unit. - **v_max** (Number) - Override all voltage maximum limits. Per Unit. - **gen_mult** (Number) - Scale all generator outputs and ratings. Per Unit. - **load_mult** (Number) - Scale all loads. - **cvr_p** (Number) - CVR factor for voltage dependent loads. Active power component. cvr_p = (dP/P)/(dV/V). To convert from ZIP parameters, kz, ki, kp: cvr_p = 2kz + 1ki - **cvr_q** (Number) - CVR factor for voltage dependent loads. Reactive power component. cvr_q = (dQ/Q)/(dV/V). To convert from ZIP parameters, kz, ki, kp: cvr_q = 2kz + 1ki - **control_variable** (str) - Control variable for optimization. Options (case-insensitive): None, "P", "Q". - **objective_function** (str or Callable) - Objective function for optimization. Options (case-insensitive): "gen_max", "load_min", "loss_min", "curtail_min", "target_p_3ph", "target_q_3ph", "target_p_total", "target_q_total". - **show_plots** (bool) - (default False) If true, renders plots in browser. - **save_results** (bool) - (default False) If true, saves result data to CSVs in output_dir. - **save_plots** (bool) - (default False) If true, saves interactive plots as html to output folder. - **save_inputs** (bool) - (default False) If true, saves model CSV and other input parameters. ### Usage Example ```python import distopf as opf # Create case from CSVs in a directory case = opf.create_case(data_path="path/to/data/directory") # Run power flow results = opf.run_pf(case) # Create case from OpenDSS model case_dss = opf.create_case( data_path="path/to/your_model_directory/model.dss" ) # Run optimal power flow with loss minimization opf_results = opf.run_opf(case_dss, objective_function="loss_min") ``` ``` -------------------------------- ### Run Unconstrained Power Flow Source: https://github.com/gridappsd/distopf/blob/main/README.md Create a case from a CSV file and run an unconstrained power flow calculation. The network can then be visualized in a browser. ```python import distopf as opf case = opf.create_case(opf.CASES_DIR / "csv" / "ieee123") result = case.run_pf() result.plot_network().show(renderer="browser") ``` -------------------------------- ### Load Custom Model from Directory Source: https://github.com/gridappsd/distopf/blob/main/README.md Use this snippet to load a custom grid model by specifying the path to a directory containing CSV files for branch, bus, generator, capacitor, regulator, and battery data. Ensure CSV names match exactly. ```python import distopf as opf case = opf.create_case( data_path="path/to/your_model_directory", ) ``` -------------------------------- ### Marimo: Modify Generators and Run OPF Source: https://github.com/gridappsd/distopf/blob/main/examples/README.md An interactive Marimo notebook demonstrating how to modify generator parameters and re-run OPF. Key features include `case.modify()`, `gen_mult`, `control_variable`, and `curtail_min`. ```python import marimo as mo from gridappes.api import create_case, run_opf # Load a base case case = create_case("ieee_123_30der") # UI elements for generator modification # Example: Modify generator 'G1' parameters # gen_mult_slider = mo.ui.Slider(start=0.5, end=1.5, label="Generator Multiplier (G1)") # control_var_dropdown = mo.ui.Dropdown(options=["P", "PQ"], label="Control Variable (G1)") # curtail_min_input = mo.ui.Number(value=0.1, label="Min Curtailment (G1)") # Placeholder for actual modification logic # def modify_and_run(gen_mult, control_var, curtail_min): # modified_case = case.modify(generators=[ # {"name": "G1", "gen_mult": gen_mult, "control_variable": control_var, "curtail_min": curtail_min} # ]) # results = run_opf(modified_case, "loss_min") # return results.voltages # Placeholder for Marimo UI and execution flow # app_layout = mo.ui.vstack([ # gen_mult_slider, # control_var_dropdown, # curtail_min_input, # mo.ui.button(label="Run OPF", on_click=modify_and_run.run) # ]) # app_layout # Simplified example output for demonstration mo.md("This Marimo notebook allows interactive modification of generator parameters like `gen_mult`, `control_variable`, and `curtail_min` before running an OPF.") ``` -------------------------------- ### Run DER Curtailment Minimization OPF Source: https://github.com/gridappsd/distopf/blob/main/README.md Create a case with distributed energy resources (DERs) and run an optimal power flow to minimize curtailment. This allows for control of real or reactive power injections. ```python import distopf as opf case = opf.create_case(opf.CASES_DIR / "csv" / "ieee123_30der") result = case.run_opf(objective="curtail_min", control_variable="P", v_max=1.05, v_min=0.95, gen_mult=10) result.plot_network().show(renderer="browser") ``` -------------------------------- ### Load Custom Model from DataFrames Source: https://github.com/gridappsd/distopf/blob/main/README.md This snippet shows how to load a custom grid model by creating pandas DataFrames for each data type (branch, bus, gen, cap, reg, bat) and passing them to the `opf.Case` constructor. Optional `schedules` DataFrame can be used for multi-period cases. ```python import distopf as opf import pandas as pd branch_data = pd.read_csv("path/to/your_model_directory/branch_data.csv", header=0) bus_data = pd.read_csv("path/to/your_model_directory/bus_data.csv", header=0) gen_data = pd.read_csv("path/to/your_model_directory/gen_data.csv", header=0) cap_data = pd.read_csv("path/to/your_model_directory/cap_data.csv", header=0) reg_data = pd.read_csv("path/to/your_model_directory/reg_data.csv", header=0) bat_data = pd.read_csv("path/to/your_model_directory/bat_data.csv", header=0) schedules = pd.read_csv("path/to/your_model_directory/schedules.csv", header=0) # Optional for multi-period cases case = opf.Case( branch_data=branch_data, bus_data=bus_data, gen_data=gen_data, cap_data=cap_data, reg_data=reg_data, bat_data=bat_data, schedules=schedules ) ``` -------------------------------- ### Run Power Flow with DERs and Curtailment Minimization Source: https://github.com/gridappsd/distopf/blob/main/examples/basics/basic_power_flow_examples.html Simulates power flow on the IEEE 123 bus system with Distributed Energy Resources (DERs) on 30 buses. It uses a 10x power multiplier for DERs and employs curtailment minimization to ensure voltages remain within bounds. The network and voltages are then plotted. ```python case = opf.Case(data_path="ieee123_30der", control_variable="P", objective_function="curtail_min", gen_mult=10) case.run_pf() case.plot_network(v_max=1.05, v_min=0.95) ``` ```python case.plot_voltages() ``` -------------------------------- ### Run Power Flow Calculation Source: https://github.com/gridappsd/distopf/blob/main/examples/basics/basic_power_flow_examples.html Executes a power flow calculation using the specified case file. Ensure the case file is accessible. ```python from gridappsdclient import GridAPPSDClient client = GridAPPSDClient(url="ws://localhost:61613") client.connect() # Get the results of a power flow calculation results = client.get_power_flow_results(case_file="/cases/ieee_14_bus/case.json") # Print the results print(results) ```