Source code for VeraGridEngine.Templates.Rms.pv_load_template

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0

from VeraGridEngine.Devices.Dynamic.var_factory import VarFactory
from VeraGridEngine.enumerations import ParamPowerFlowReferenceType, VarPowerFlowReferenceType, DeviceType
from VeraGridEngine.Devices.Dynamic.rms_template import RmsModelTemplate
from VeraGridEngine.Utils.Symbolic.block import Block
import VeraGridEngine.Utils.Symbolic.symbolic as sym


[docs] def PVLoadBuild(vfactory: VarFactory, name: str = "", Pg0_val=1.0, Vg0_val=1.0) -> RmsModelTemplate: """ Builds an RMS model template for a PV load with reactive power limits. The PV load model represents a load/generator with constant active power (P) and reactive power limited between Qmin and Qmax. When reactive power is within limits, the voltage is held at the reference value V0. When reactive power hits a limit, the voltage is allowed to vary. Equations: P = Pg0 (constant active power) Qh = Qg Qg = Qmax_G if Qh >= Qmax_G Vh = Vg0 if Qmax_G < Qh < Qmin_G Qg = Qmin_G if Qh <= Qmin_G Args: vfactory: VarFactory instance for creating variables name (str): Name of the PV load model Pg0 (float): Initial active power (pu) Qg0 (float): Initial reactive power (pu) Returns: RmsModelTemplate: Configured RMS model template for PV load simulation """ templ = RmsModelTemplate() templ.tpe = DeviceType.LoadDevice # Input: Vm (voltage magnitude) Vm = vfactory.add_var("Vm_" + name) inputs = [Vm] # Variables P = vfactory.add_var('P') Q = vfactory.add_var('Q') # Parameters Pg0 = vfactory.add_var('Pg0') Vg0 = vfactory.add_var('Vg0') Qmax_G = vfactory.add_var('Qmax_G') Qmin_G = vfactory.add_var('Qmin_G') # Event dictionary with default values event_dict = { Pg0: vfactory.add_const(Pg0_val), Vg0: vfactory.add_const(None), Qmax_G: vfactory.add_const(1.0), Qmin_G: vfactory.add_const(-1.0), } # Initialize Q to Qg0 init_eqs = { P: Pg0, Vg0: Vm, } within_limits = ((Qmax_G - Q)>=0).to_expression() * (0 <= (Q - Qmin_G)).to_expression() # # Implementation using saturation: # Qg = max(Qmin, min(Qh, Qmax)) Q_sat = sym.max(Qmin_G, sym.min(Q, Qmax_G)) templ.block = Block( algebraic_eqs=[ P - Pg0, (Vm - Vg0) * within_limits + (Q - Q_sat)*(1 - within_limits), ], algebraic_vars=[P, Q], init_eqs=init_eqs, event_dict=event_dict, ) templ.block.name = 'PV Load' templ.block.external_mapping = { VarPowerFlowReferenceType.P: P, VarPowerFlowReferenceType.Q: Q, VarPowerFlowReferenceType.Vm: inputs[0], } templ.block.api_obj_mapping = { ParamPowerFlowReferenceType.Pl0: Pg0, } templ.block.in_vars = inputs return templ