544{
545
548 auto data = bus->GetElectricalData();
549 data.stabVoltageVector.clear();
550 data.stabVoltageVector.shrink_to_fit();
551 data.stabFreqVector.clear();
552 data.stabFreqVector.shrink_to_fit();
553 data.stabFreq = m_systemFreq;
554 data.oldAngle = std::arg(data.voltage);
555 data.filteredAngle = 0.0;
556 data.dxt = 0.0;
557 data.filteredVelocity = 0.0;
558 data.ddw = 0.0;
559 bus->SetElectricalData(data);
560 }
561
563 auto dataPU = load->GetPUElectricalData(m_powerSystemBase);
564 auto data = load->GetElectricalData();
565
566 double activePower = dataPU.activePower;
567 double reactivePower = dataPU.reactivePower;
568
571 {
572 data.voltage = bus->GetElectricalData().voltage;
573 }
574 else {
575 load->SetOnline(false);
576 }
577
578 data.v0 = std::abs(data.voltage);
579 data.y0 = std::complex<double>(activePower, -reactivePower) / (data.v0 * data.v0);
580
581 if (data.loadType == CONST_IMPEDANCE) {
582 std::complex<double> s0 = std::complex<double>(activePower, -reactivePower) * (data.v0 * data.v0);
583 activePower = s0.real();
584 reactivePower = -s0.imag();
585 }
586
587 data.pz0 = (data.constImpedanceActive / 100.0) * activePower;
588 data.pi0 = (data.constCurrentActive / 100.0) * activePower;
589 data.pp0 = (data.constPowerActive / 100.0) * activePower;
590
591 data.qz0 = (data.constImpedanceReactive / 100.0) * reactivePower;
592 data.qi0 = (data.constCurrentReactive / 100.0) * reactivePower;
593 data.qp0 = (data.constPowerReactive / 100.0) * reactivePower;
594
595 data.voltageVector.clear();
596 data.voltageVector.shrink_to_fit();
597 data.electricalPowerVector.clear();
598 data.electricalPowerVector.shrink_to_fit();
599
600 if (load->IsOnline())
601 data.electricalPower = std::complex<double>(activePower, reactivePower);
602 else {
603 data.electricalPower = std::complex<double>(0.0, 0.0);
604 data.voltage = std::complex<double>(0.0, 0.0);
605 }
606
607 load->SetElectricalData(data);
608 }
609
612 auto dataPU = syncGenerator->GetPUElectricalData(m_powerSystemBase);
613 auto data = syncGenerator->GetElectricalData();
614 double k = 1.0;
615 if (data.useMachineBase) {
616 double oldBase = syncGenerator->GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
617 k = m_powerSystemBase / oldBase;
618 }
621 data.terminalVoltage = bus->GetElectricalData().voltage;
622 else
623 data.terminalVoltage = std::complex<double>(1.0, 0.0);
624
625 std::complex<double> conjS(dataPU.activePower, -dataPU.reactivePower);
626 std::complex<double> vt = data.terminalVoltage;
627 std::complex<double> ia = conjS / std::conj(vt);
628
629 double xd = data.syncXd * k;
630 double xq = data.syncXq * k;
631 double ra = data.armResistance * k;
632
633 if (data.model == Machines::SM_MODEL_1) {
634 xq = data.transXd * k;
635 xd = xq;
636 }
637 else if (data.syncXq == 0.0)
638 xq = data.syncXd * k;
639
640 double sd = 1.0;
641 double sq = 1.0;
642 double satF = 1.0;
643 double xp = data.potierReactance * k;
644 bool hasSaturation = false;
645 if (data.satFactor != 0.0) {
646 satF = (data.satFactor - 1.2) / std::pow(1.2, 7);
647 if (xp == 0.0) xp = 0.8 * (data.transXd * k);
648 hasSaturation = true;
649 }
650
651
652 std::complex<double> eq0 = vt + std::complex<double>(ra, xq) * ia;
653 double delta = std::arg(eq0);
654
655 double id0, iq0, vd0, vq0;
658
659
660 double xqs = xq;
661 double xds = xd;
662 if (hasSaturation) {
663 double oldDelta = 0;
664 bool exit = false;
665 int numIt = 0;
666 while (!exit) {
667 oldDelta = delta;
670
671
672 double epd = vd0 + ra * id0 + xp * iq0;
673
674 sq = 1.0 + satF * (xq / xd) * std::pow(epd, 6);
675 xqs = (xq - xp) / sq + xp;
676 eq0 = data.terminalVoltage + std::complex<double>(ra, xqs) * ia;
677 delta = std::arg(eq0);
678 if (std::abs(delta - oldDelta) < m_saturationTolerance) {
679 exit = true;
680 }
681 else if (numIt >= m_maxIterations) {
682 m_errorMsg = _("Error on initializate the saturation values of \"") + data.name + _("\".");
683 return false;
684 }
685 numIt++;
686 }
687
688 double epq = vq0 + ra * iq0 - xp * id0;
689 sd = 1.0 + satF * std::pow(epq, 6);
690 xds = (xd - xp) / sd + xp;
691 }
692
693 double ef0 = vq0 + ra * iq0 - xds * id0;
694
695 data.initialFieldVoltage = ef0 * sd;
696 data.fieldVoltage = data.initialFieldVoltage;
697 data.pm = std::real((data.terminalVoltage * std::conj(ia)) + (std::abs(ia) * std::abs(ia) * ra));
698 syncGenerator->
IsOnline() ? data.speed = 2.0 * M_PI * m_systemFreq : data.speed = 2.0 * M_PI * data.ocFrequency;
699 data.delta = delta;
700 data.pe = data.pm;
701 data.electricalPower = std::complex<double>(dataPU.activePower, dataPU.reactivePower);
702 if (!syncGenerator->
IsOnline()) data.electricalPower = std::complex<double>(0.0, 0.0);
703 data.sd = sd;
704 data.sq = sq;
705 data.id = id0;
706 data.iq = iq0;
707
708
709 data.oldIq = iq0;
710 data.oldId = id0;
711 data.oldPe = data.pe;
712 data.oldSd = sd;
713 data.oldSq = sq;
714
715 switch (data.model) {
716 case Machines::SM_MODEL_1: {
717 data.tranEq = std::abs(eq0);
718
719 data.tranEd = 0.0;
720 data.subEq = 0.0;
721 data.subEd = 0.0;
722 } break;
723 case Machines::SM_MODEL_2: {
724 double tranXd = data.transXd * k;
725
726 data.tranEq = ef0 + (xd - tranXd) * (id0 / sd);
727 data.tranEd = 0.0;
728 data.subEd = 0.0;
729 data.subEq = 0.0;
730 } break;
731 case Machines::SM_MODEL_3: {
732 double tranXd = data.transXd * k;
733 double tranXq = data.transXq * k;
734 if (tranXq == 0.0) tranXq = tranXd;
735
736 data.tranEq = ef0 + (xd - tranXd) * (id0 / sd);
737 data.tranEd = -(xq - tranXq) * (iq0 / sq);
738
739 data.subEd = 0.0;
740 data.subEq = 0.0;
741 } break;
742 case Machines::SM_MODEL_4: {
743 double tranXd = data.transXd * k;
744 double subXd = data.subXd * k;
745 double subXq = data.subXq * k;
746 if (subXd == 0.0) subXd = subXq;
747 if (subXq == 0.0) subXq = subXd;
748
749 data.tranEq = ef0 + (xd - tranXd) * (id0 / sd);
750 data.tranEd = 0.0;
751 data.subEq = data.tranEq + (tranXd - subXd) * (id0 / sd);
752 data.subEd = -(xq - subXq) * (iq0 / sq);
753 } break;
754 case Machines::SM_MODEL_5: {
755 double tranXd = data.transXd * k;
756 double tranXq = data.transXq * k;
757 double subXd = data.subXd * k;
758 double subXq = data.subXq * k;
759 if (subXd == 0.0) subXd = subXq;
760 if (subXq == 0.0) subXq = subXd;
761
762 data.tranEq = ef0 + (xd - tranXd) * (id0 / sd);
763 data.tranEd = -(xq - tranXq) * (iq0 / sq);
764 data.subEq = data.tranEq + (tranXd - subXd) * (id0 / sd);
765 data.subEd = data.tranEd - (tranXq - subXq) * (iq0 / sq);
766 } break;
767 default:
768 break;
769 }
770
771
772 if (data.useAVR) {
773
774
775
776 data.avrSolver = std::make_shared<ControlElementSolver>(data.avr, m_timeStep * m_ctrlTimeStepMultiplier, m_tolerance, m_parent);
777
778 data.avrSolver->SetSwitchStatus(syncGenerator->
IsOnline());
779 data.avrSolver->SetCurrentTime(m_currentTime);
780 data.avrSolver->SetTerminalVoltage(std::abs(data.terminalVoltage));
781 data.avrSolver->SetInitialTerminalVoltage(std::abs(data.terminalVoltage));
782 data.avrSolver->SetActivePower(dataPU.activePower);
783 data.avrSolver->SetReactivePower(dataPU.reactivePower);
784 data.avrSolver->SetVelocity(data.speed);
785 data.avrSolver->SetInitialVelocity(data.speed);
786 data.avrSolver->InitializeValues(false);
787 if (!data.avrSolver->IsOK()) {
788 m_errorMsg = _("Error on initializate the AVR of \"") + data.name + wxT("\".\n") +
789 data.avrSolver->GetErrorMessage();
790 syncGenerator->SetElectricalData(data);
791 return false;
792 }
793 }
794 if (data.useSpeedGovernor) {
795
796
797
798
799 data.speedGovSolver = std::make_shared<ControlElementSolver>(data.speedGov, m_timeStep * m_ctrlTimeStepMultiplier, m_tolerance, m_parent);
800 data.speedGovSolver->SetSwitchStatus(syncGenerator->
IsOnline());
801 data.speedGovSolver->SetCurrentTime(m_currentTime);
802 data.speedGovSolver->SetActivePower(dataPU.activePower);
803 data.speedGovSolver->SetReactivePower(dataPU.reactivePower);
804 data.speedGovSolver->SetVelocity(data.speed);
805 data.speedGovSolver->SetInitialVelocity(data.speed);
806 data.speedGovSolver->SetInitialMecPower(data.pm);
807 data.speedGovSolver->InitializeValues(false);
808 if (!data.speedGovSolver->IsOK()) {
809 m_errorMsg = _("Error on initializate the speed governor of \"") + data.name + wxT("\".\n") +
810 data.speedGovSolver->GetErrorMessage();
811 syncGenerator->SetElectricalData(data);
812 return false;
813 }
814 }
815
816
817
818
819
820 data.terminalVoltageVector.clear();
821 data.terminalVoltageVector.shrink_to_fit();
822 data.electricalPowerVector.clear();
823 data.electricalPowerVector.shrink_to_fit();
824 data.mechanicalPowerVector.clear();
825 data.mechanicalPowerVector.shrink_to_fit();
826 data.freqVector.clear();
827 data.freqVector.shrink_to_fit();
828 data.fieldVoltageVector.clear();
829 data.fieldVoltageVector.shrink_to_fit();
830 data.deltaVector.clear();
831 data.deltaVector.shrink_to_fit();
832
833 syncGenerator->SetElectricalData(data);
834 }
835
838 auto dataPU = indMotor->GetPUElectricalData(m_powerSystemBase);
839 auto data = indMotor->GetElectricalData();
840
842 if (connBus->GetElectricalData().number < 0) indMotor->
SetOnline(
false);
843
844 double w0 = 2.0 * M_PI * m_systemFreq;
845 std::complex<double> i1 = std::complex<double>(dataPU.activePower, -data.q0) / std::conj(data.terminalVoltage);
846 double ir = std::real(i1);
847 double im = std::imag(i1);
848 std::complex<double> e = data.terminalVoltage - std::complex<double>(data.r1t, data.x1t) * i1;
849 double te = std::real(e * std::conj(i1)) / w0;
850
851 double wi = w0 * (1 - data.s0);
852 data.as = te * (data.aw + (data.bw * w0) / wi + (data.cw * w0 * w0) / (wi * wi));
853 data.bs = te * ((data.bw * w0) / wi + (2.0 * data.cw * w0 * w0) / (wi * wi));
854 data.cs = (te * data.cw * w0 * w0) / (wi * wi);
855
856 data.aCalc = data.as;
857 data.bCalc = data.bs;
858 data.cCalc = data.cs;
859
861 std::complex<double> tranE =
862 (std::complex<double>(0, data.x0 - data.xt) * i1) / std::complex<double>(1.0, w0 * data.s0 * data.t0);
863
864 data.tranEr = std::real(tranE);
865 data.tranEm = std::imag(tranE);
866
867 data.slip = data.s0;
868 data.ir = ir;
869 data.im = im;
870 data.te = te;
871 }
872 else {
873 data.tranEr = 0.0;
874 data.tranEm = 0.0;
875 data.slip = 1.0 - 1e-7;
876 data.ir = 0.0;
877 data.im = 0.0;
878 data.te = 0.0;
879 }
880
881
882 data.oldTe = data.te;
883 data.oldIr = data.ir;
884 data.oldIm = data.im;
885
886
887 data.slipVector.clear();
888 data.slipVector.shrink_to_fit();
889 data.electricalTorqueVector.clear();
890 data.electricalTorqueVector.shrink_to_fit();
891 data.mechanicalTorqueVector.clear();
892 data.mechanicalTorqueVector.shrink_to_fit();
893 data.velocityVector.clear();
894 data.velocityVector.shrink_to_fit();
895 data.currentVector.clear();
896 data.currentVector.shrink_to_fit();
897 data.terminalVoltageVector.clear();
898 data.terminalVoltageVector.shrink_to_fit();
899 data.activePowerVector.clear();
900 data.activePowerVector.shrink_to_fit();
901 data.reactivePowerVector.clear();
902 data.reactivePowerVector.shrink_to_fit();
903
904 indMotor->SetElectricalData(data);
905 }
906 CalculateReferenceSpeed();
907 return true;
908}