pydynamicestimator.tests.test_inverter_lcl_static ================================================= .. py:module:: pydynamicestimator.tests.test_inverter_lcl_static .. autoapi-nested-parse:: Phase 5: validate the quasi-static LCL_static filter (filter quantities as device-private algebraics) against the dynamic LCL filter. LCL_static is NOT byte-identical to dynamic LCL -- it is a singular-perturbation reduction that removes the fast LCL dynamics. So the validation is: 1. **Self-consistency / machinery (rigorous):** LCL_static runs as a DAE (line_dyn=False), initializes, and is exactly reproducible. This proves the algebraic-port plumbing (var_sym + DAE integration + the init routing the algebraic filter values into dae.yinit) is correct, with no reference to the dynamic model. LCL_static supports BOTH init methods (sequential default and joint) and they reach the same operating point -- checked here. 2. **Quasi-static reduction (physics):** comparing slow quantities between LCL_static and dynamic LCL (same static network), they are machine-identical BEFORE a disturbance and re-converge AFTER the fast transient settles; they differ only during the fast transient (a few % for a fault, negligible for a gentle load step). Validated for both a bus fault and a small load step. Attributes ---------- .. autoapisummary:: pydynamicestimator.tests.test_inverter_lcl_static.TS pydynamicestimator.tests.test_inverter_lcl_static.T_END pydynamicestimator.tests.test_inverter_lcl_static.SLOW Functions --------- .. autoapisummary:: pydynamicestimator.tests.test_inverter_lcl_static._build_fixture pydynamicestimator.tests.test_inverter_lcl_static._run pydynamicestimator.tests.test_inverter_lcl_static._dev_state pydynamicestimator.tests.test_inverter_lcl_static.test_lcl_static_self_consistent pydynamicestimator.tests.test_inverter_lcl_static.test_lcl_static_both_init_methods_agree pydynamicestimator.tests.test_inverter_lcl_static.test_lcl_static_quasi_static_reduction Module Contents --------------- .. py:data:: TS :value: 0.005 .. py:data:: T_END :value: 5.0 .. py:data:: SLOW :value: [('GFMI4', 'Pc_tilde'), ('GFMI4', 'delta_c'), ('GFMI4', 'Qc_tilde'), ('GFLI7', 'Pc_tilde'),... .. py:function:: _build_fixture(root, filter_name, disturbance) Copy the inverter fixture into ``root``, select ``filter_name`` on every converter, and set the disturbance (``"fault"`` keeps the bus fault at t=4.0; ``"load"`` replaces it with a small load step at t=2.0 on a load bus). .. py:function:: _run(root, filter_name, disturbance) .. py:function:: _dev_state(sim, idx, state) Trajectory of a named state for the device with the given idx. .. py:function:: test_lcl_static_self_consistent(tmp_path) LCL_static runs as a DAE, initializes (sequential by default), and is exactly reproducible (the algebraic-port machinery is correct). .. py:function:: test_lcl_static_both_init_methods_agree(tmp_path, monkeypatch) LCL_static initializes correctly under BOTH the sequential init (routing the algebraic filter values into dae.yinit) and the joint init (solving them as private-algebraic unknowns); both reach the same operating point. .. py:function:: test_lcl_static_quasi_static_reduction(tmp_path, disturbance, t_dist, after_atol) The slow quantities of LCL_static and dynamic LCL (same static network) are machine-identical before the disturbance and re-converge after the fast transient settles -- they differ only during the fast transient.