From ad08d4a6eebea2a509045f039b8ddb6d87fdc2e6 Mon Sep 17 00:00:00 2001 From: Marvin Tollnitsch Date: Wed, 28 Feb 2024 15:15:37 +0100 Subject: [PATCH] Added defining equations Signed-off-by: Marvin Tollnitsch --- .../EMT/EMT_Ph3_SynchronGenerator4OrderSSN.h | 10 ++++- .../EMT_Ph3_SynchronGenerator4OrderSSN.cpp | 38 +++++++++++++++++-- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/dpsim-models/include/dpsim-models/EMT/EMT_Ph3_SynchronGenerator4OrderSSN.h b/dpsim-models/include/dpsim-models/EMT/EMT_Ph3_SynchronGenerator4OrderSSN.h index 24250b1429..ec5c2a523a 100644 --- a/dpsim-models/include/dpsim-models/EMT/EMT_Ph3_SynchronGenerator4OrderSSN.h +++ b/dpsim-models/include/dpsim-models/EMT/EMT_Ph3_SynchronGenerator4OrderSSN.h @@ -59,7 +59,15 @@ class SynchronGenerator4OrderSSN: double omega_old; private: - + //constants + const double C_d = (mTimeStep*X_D)/(2.*T_d0*X_D+mTimeStep*X_d); + const double C_dd = (mTimeStep*(X_d-X_D))/(2.*T_d0*X_D+mTimeStep*X_d); + const double C_0dd = (2.*T_d0*X_D-mTimeStep*X_d)/(2.*T_d0*X_D+mTimeStep*X_d); + const double C_qq = (mTimeStep*(X_q-X_Q))/(2.*T_q0*X_Q+mTimeStep*X_q); + const double C_0qq = (2.*T_q0*X_Q-mTimeStep*X_q)/(2.*T_q0*X_Q+mTimeStep*X_q); + const double C_wbq = (mTimeStep*mTimeStep*omega_base)/(4.*H*X_Q); + const double C_wbd = (mTimeStep*mTimeStep*omega_base)/(4.*H*X_D); + const double C_wb = (mTimeStep*mTimeStep*omega_base)/(8.*H); } } } diff --git a/dpsim-models/src/EMT/EMT_Ph3_SynchronGenerator4OrderSSN.cpp b/dpsim-models/src/EMT/EMT_Ph3_SynchronGenerator4OrderSSN.cpp index 95e3823e83..e8f57e2f94 100644 --- a/dpsim-models/src/EMT/EMT_Ph3_SynchronGenerator4OrderSSN.cpp +++ b/dpsim-models/src/EMT/EMT_Ph3_SynchronGenerator4OrderSSN.cpp @@ -20,6 +20,7 @@ void CPS::EMT::Ph3::SynchronGenerator4OrderSSN::calculateNonlinearFunctionResult **intfCurrent(1,0) = ((Eq-Vq)/Xd)*cos(theta - (2*M_PI/3)) - ((Vd-Ed)/Xq)*sin(theta - (2*M_PI/3)); **intfCurrent(2,0) = ((Eq-Vq)/Xd)*cos(theta + (2*M_PI/3)) - ((Vd-Ed)/Xq)*sin(theta + (2*M_PI/3)); + ///FIXME: f_theta instead of theta theta = ((mTimeStep*mTimeStep*omega_base)/(8.*H))*P_mech - ((mTimeStep*mTimeStep*omega_base)/(8.*H))*((Vd*Vd)/Xq_dash) +((mTimeStep*mTimeStep*omega_base)/(8.*H))*((Vd)/Xq_dash)*( ((mTimeStep*(Xq-Xq_dash))/(2*Tq0_dash*Xq_dash+mTimeStep*Xq))*Vd+((mTimeStep*(Xq-Xq_dash))/(2.*Tq0_dash*Xq_dash+mTimeStep*Xq))*Vd_old @@ -100,7 +101,7 @@ void CPS::EMT::Ph3::SynchronGenerator4OrderSSN::mnaCompApplySystemMatrixStamp(Ma Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 2), matrixNodeIndex(0, 1), -Jacobian(2, 1)); Math::addToMatrixElement(systemMatrix, matrixNodeIndex(1, 2), matrixNodeIndex(0, 2), -Jacobian(2, 2)); } - //Internal Voltages are v1-v0: Positive for Terminal 1, negative for terminal 0 (Thus also the signs for Jacobian(2, 3) above). + //Internal Voltages are v1-v0: Positive for Terminal 1, negative for terminal 0 //Theta is not a difference: We only have one "virtual terminal" for it. Math::addToMatrixElement(systemMatrix, mVirtualNodes[0]->matrixNodeIndex(PhaseType::Single), matrixNodeIndex(0, 0) ,-Jacobian(3, 0)); @@ -119,16 +120,26 @@ void CPS::EMT::Ph3::SynchronGenerator4OrderSSN::mnaCompApplySystemMatrixStamp(Ma void CPS::EMT::Ph3::SynchronGenerator4OrderSSN::mnaCompInitialize(Real omega, Real timeStep, Attribute::Ptr leftVector) { updateMatrixNodeIndices(); - - } void CPS::EMT::Ph3::SynchronGenerator4OrderSSN::mnaCompApplyRightSideVectorStamp(Matrix& rightVector) { + //Phase current output equations do not contain constant history terms + + //Math::setVectorElement(rightVector, matrixNodeIndex(0, PhaseType::A), 0.); + //Math::setVectorElement(rightVector, matrixNodeIndex(0, PhaseType::B), 0.); + //Math::setVectorElement(rightVector, matrixNodeIndex(0, PhaseType::C), 0.); + + //Math::setVectorElement(rightVector, matrixNodeIndex(0, PhaseType::A), 0.); + //Math::setVectorElement(rightVector, matrixNodeIndex(0, PhaseType::B), 0.); + //Math::setVectorElement(rightVector, matrixNodeIndex(0, PhaseType::C), 0.); + + //Equation for theta does contain constant history terms: + double linear_theta_hist = -C_wb*(P_mech_old-(V_d_old*V_d_old/X_Q)+(V_d_old*E_d_old/X_Q)-(V_q_old*E_q_old/X_D)+(V_q*V_q/X_D))-(0.5*timeStep*omega_old)-(0.5*timeStep*omega_base(omega_old-2.))-omega_old-1.; + Math::setVectorElement(rightVector, mVirtualNodes[0]->matrixNodeIndex(PhaseType::Single), linear_theta_hist); } void CPS::EMT::Ph3::SynchronGenerator4OrderSSN::mnaCompAddPreStepDependencies(AttributeBase::List &prevStepDependencies, AttributeBase::List &attributeDependencies, AttributeBase::List &modifiedAttributes) { - // actually depends on C, but then we'd have to modify the system matrix anyway modifiedAttributes.push_back(mRightVector); prevStepDependencies.push_back(mIntfCurrent); prevStepDependencies.push_back(mIntfVoltage); @@ -178,8 +189,27 @@ void CPS::EMT::Ph3::SynchronGenerator4OrderSSN::iterationUpdate(const Matrix& le void CPS::EMT::Ph3::SynchronGenerator4OrderSSN::updateJacobian() { + Jacobian(0,0)=(cos(theta)*sin(theta)*(1.-C_dd)/X_D)-(cos(theta)*sin(theta)*(1.-C_qq)/X_Q); + Jacobian(0,1)=(cos(theta)*sin(theta-(2.*M_PI/3.))*(1.-C_dd)/X_D)-(cos(theta-(2.*M_PI/3.))*sin(theta)*(1.-C_qq)/X_Q); + Jacobian(0,2)=(cos(theta)*sin(theta+(2.*M_PI/3.))*(1.-C_dd)/X_D)-(cos(theta+(2.*M_PI/3.))*sin(theta)*(1.-C_qq)/X_Q); + Jacobian(0,3)=(cos(theta)/X_D)*(V_a*cos(theta)+V_b*cos(theta-(2.*M_PI/3.))+V_c*cos(theta+(2.*M_PI/3.)))*(1.-C_dd)-(sin(theta)/X_D)*(E_q-V_q)+(sin(theta)/X_Q)*(V_a*sin(theta)+V_b*sin(theta-(2.*M_PI/3.))+V_c*sin(theta+(2.*M_PI/3.)))*(1.-C_qq)+(cos(theta)/X_Q)*(E_d-V_d); + Jacobian(1,0)=(cos(theta-(2.*M_PI/3.))*sin(theta)*(1.-C_dd)/X_D)-(cos(theta)*sin(theta-(2.*M_PI/3.))*(1.-C_qq)/X_Q); + Jacobian(1,1)=(cos(theta-(2.*M_PI/3.))*sin(theta-(2.*M_PI/3.))*(1.-C_dd)/X_D)-(cos(theta-(2.*M_PI/3.))*sin(theta-(2.*M_PI/3.))*(1.-C_qq)/X_Q); + Jacobian(1,2)=(cos(theta-(2.*M_PI/3.))*sin(theta+(2.*M_PI/3.))*(1.-C_dd)/X_D)-(cos(theta+(2.*M_PI/3.))*sin(theta-(2.*M_PI/3.))*(1.-C_qq)/X_Q); + Jacobian(1,3)=(cos(theta-(2.*M_PI/3.))/X_D)*(V_a*cos(theta)+V_b*cos(theta-(2.*M_PI/3.))+V_c*cos(theta+(2.*M_PI/3.)))*(1.-C_dd)-(sin(theta-(2.*M_PI/3.))/X_D)*(E_q-V_q)+(sin(theta-(2.*M_PI/3.))/X_Q)*(V_a*sin(theta)+V_b*sin(theta-(2.*M_PI/3.))+V_c*sin(theta+(2.*M_PI/3.)))*(1.-C_qq)+(cos(theta-(2.*M_PI/3.))/X_Q)*(E_d-V_d); + Jacobian(2,0)=(cos(theta+(2.*M_PI/3.))*sin(theta)*(1.-C_dd)/X_D)-(cos(theta)*sin(theta+(2.*M_PI/3.))*(1.-C_qq)/X_Q); + Jacobian(2,1)=(cos(theta+(2.*M_PI/3.))*sin(theta-(2.*M_PI/3.))*(1.-C_dd)/X_D)-(cos(theta-(2.*M_PI/3.))*sin(theta+(2.*M_PI/3.))*(1.-C_qq)/X_Q); + Jacobian(2,2)=(cos(theta+(2.*M_PI/3.))*sin(theta+(2.*M_PI/3.))*(1.-C_dd)/X_D)-(cos(theta+(2.*M_PI/3.))*sin(theta+(2.*M_PI/3.))*(1.-C_qq)/X_Q); + Jacobian(2,3)=(cos(theta+(2.*M_PI/3.))/X_D)*(V_a*cos(theta)+V_b*cos(theta-(2.*M_PI/3.))+V_c*cos(theta+(2.*M_PI/3.)))*(1.-C_dd)-(sin(theta+(2.*M_PI/3.))/X_D)*(E_q-V_q)+(sin(theta+(2.*M_PI/3.))/X_Q)*(V_a*sin(theta)+V_b*sin(theta-(2.*M_PI/3.))+V_c*sin(theta+(2.*M_PI/3.)))*(1.-C_qq)+(cos(theta+(2.*M_PI/3.))/X_Q)*(E_d-V_d); + Jacobian(3,0)=C_wbq*V_d*cos(theta)*(1.-C_qq)-0.5*C_wbq*cos(theta)*(C_qq*V_d_old+C_0qq*E_d_old)-C_wbd*V_q*sin(theta)*(C_dd-1.)-0.5*C_wbd*sin(theta)*(C_d*(E_f+E_f_old)+C_0dd*E_q_old+C_dd*V_q_old); + Jacobian(3,1)=C_wbq*V_d*cos(theta-(2.*M_PI/3.))*(1.-C_qq)-0.5*C_wbq*cos(theta-(2.*M_PI/3.))*(C_qq*V_d_old+C_0qq*E_d_old)-C_wbd*V_q*sin(theta-(2.*M_PI/3.))*(C_dd-1.)-0.5*C_wbd*sin(theta-(2.*M_PI/3.))*(C_d*(E_f+E_f_old)+C_0dd*E_q_old+C_dd*V_q_old); + Jacobian(3,2)=C_wbq*V_d*cos(theta+(2.*M_PI/3.))*(1.-C_qq)-0.5*C_wbq*cos(theta+(2.*M_PI/3.))*(C_qq*V_d_old+C_0qq*E_d_old)-C_wbd*V_q*sin(theta+(2.*M_PI/3.))*(C_dd-1.)-0.5*C_wbd*sin(theta+(2.*M_PI/3.))*(C_d*(E_f+E_f_old)+C_0dd*E_q_old+C_dd*V_q_old); + Jacobian(3,3)=C_wbq*V_d*(V_a*sin(theta)+V_b*sin(theta-(2.*M_PI/3.))+V_c*sin(theta+(2.*M_PI/3.)))*(1.-C_qq)-0.5*C_wbq*(V_a*sin(theta)+V_b*sin(theta-(2.*M_PI/3.))+V_c*sin(theta+(2.*M_PI/3.)))*(C_qq*V_d_old+C_0qq*E_d_old)+C_wbd*V_q*(V_a*cos(theta)+V_b*cos(theta-(2.*M_PI/3.))+V_c*cos(theta+(2.*M_PI/3.)))*(C_dd-1.)+0.5*C_wbd*(V_a*cos(theta)+V_b*cos(theta-(2.*M_PI/3.))+V_c*cos(theta+(2.*M_PI/3.)))*(C_d*(E_f+E_f_old)+C_0dd*E_q_old+C_dd*V_q_old)-1.; } void CPS::EMT::Ph3::SynchronGenerator4OrderSSN::updateStates() { + E_d = C_qq*(V_d+V_d_old)+C_0qq*E_d_old; + E_q = C_dd*(V_q+V_q_old)+C_d*(E_f+E_f_old)+C_0dd*E_q_old; + omega = C_h*(P_mech-(V_d*V_d/X_Q)+(V_d*E_d/X_Q)-(V_q*E_q/X_d)+(V_q*V_q/X_D))+C_h*(P_mech_old-(V_d_old*V_d_old/X_Q)+(V_d_old*E_d_old/X_Q)-(V_q_old*E_q_old/X_D)+(V_q_old*V_q_old/X_D))+omega_old; }