//public double psiM2 { get; set; } public override IDictionary <string, object> BuildResultsForDisplay() { var dict = base.BuildResultsForDisplay(); dict.Add("Bdelta", Bdelta); dict.Add("phiD", phiD); dict.Add("gammaM", gammaM); dict.Add("phiM", phiM); dict.Add("phib", phib); dict.Add("phiFe", phiFe); dict.Add("FM", FM); dict.Add("BM", BM); dict.Add("HM", HM); dict.Add("PC", pc); dict.Add("Fz", Fz); dict.Add("Fy", Fy); dict.Add("Bz", Bz); dict.Add("By", By); dict.Add("kPMz", kPMz); dict.Add("kPMy", kPMy); dict.Add("wd", wd); dict.Add("psiM (max)", psiM); //dict.Add("psiM2", psiM2); dict.Add("Ld", Ld); dict.Add("Lq", Lq); dict.Add("LL", LL); dict.Add("R", R); dict.Add("psiM/Ld", psiM / Ld);//maximum Stator3Phase stator = Analyser.Motor.Stator as Stator3Phase; if (stator != null) { double Jrequired = psiM / Ld / (stator.WireDiameter * stator.WireDiameter / 4 * Math.PI) / Math.Sqrt(2); dict.Add("psiM/Ld/Swire (rms)", Jrequired); dict.Add("length_one_turn", stator.wirelength_oneturn); } dict.Add("Ikm", Ikm); dict.Add("L1", L1); dict.Add("L2", L2); dict.Add("dmin", dmin); dict.Add("dmax", dmax); double b1 = Bdelta * 4 / Math.PI * Math.Sin(gammaM * Math.PI / 180 / 2); double b3 = Bdelta * 4 / (Math.PI * 3) * Math.Sin(3 * gammaM * Math.PI / 180 / 2); dict.Add("Bd_1", b1); dict.Add("Bd_3", b3); return(dict); }
private void analyzeOne(DQCurrentPointData p) { PMTransientAnalyser analyser = new PMTransientAnalyser(); Stator3Phase stator = this.Motor.Stator as Stator3Phase; double id = p.idq.d; double iq = p.idq.q; analyser.Motor = this.Motor; analyser.OutputPath = this.Path_ToAnalysisVariant; analyser.Path_OriginalFEMFile = this.Path_OriginalFEMFile; analyser.AnalysisName = string.Format("{0},{1}", p.index_d, p.index_q); analyser.StepCount = StepCount; double endtime = 1 / (BaseSpeed / 60 * Motor.Rotor.p); analyser.EndTime = endtime; analyser.RotorSpeed = BaseSpeed; double beta = (id != 0) ? Math.Atan(iq / id) : Math.PI / 2; if (beta <= 0) { beta = beta + Math.PI; } double omega = BaseSpeed / 60 * 2 * Math.PI * Motor.Rotor.p; double II = Math.Sqrt(id * id + iq * iq); analyser.StartAngle = stator.VectorMMFAngle - 360.0 / (Motor.Rotor.p * 2.0) / 2.0; analyser.IA = string.Format("{0}*sin({1}*time+{2})", II, omega, beta); analyser.IB = string.Format("{0}*sin({1}*time+{2}-2*pi/3)", II, omega, beta); analyser.IC = string.Format("{0}*sin({1}*time+{2}+2*pi/3)", II, omega, beta); analyser.RunAnalysis(); p.transientResult = analyser.Results as PMTransientResults; // release memory ocupied by coreloss p.transientResult.RotorCoreLossResults = null; p.transientResult.StatorCoreLossResults = null; p.transientResult.Analyser = null; GC.Collect(); }
private void measureData(FEMM femm) { Stator3Phase stator = Motor.Stator as Stator3Phase; PM_ACAnalysisResults Results = this.Results as PM_ACAnalysisResults; //select block double r = (stator.xD + stator.xE) / 2; foreach (Stator3Phase.Coil sci in stator.coils) { int i = stator.coils.IndexOf(sci); //angle go clockwise from 3 o'clock (=0 degree in decarter), shift +pi/Q (to match rotor) int nn = stator.Q / (2 * Motor.Rotor.p); double aa = -2 * Math.PI * i / stator.Q + (nn % 2 == 0 ? Math.PI / stator.Q : 0); double x = r * Math.Cos(aa); double y = r * Math.Sin(aa); if (aa > -Motor.Rotor.alpha || aa < -2 * Math.PI + Motor.Rotor.alpha) { femm.mo_selectblock(x, y); } } double r2 = (stator.xF2 + stator.RGap) / 2; femm.mo_selectblock(r2, 0); // measure data double lossMagnetic = femm.mo_blockintegral(FEMM.BlockIntegralType.Losses_Hysteresis); double lossResistive = femm.mo_blockintegral(FEMM.BlockIntegralType.Losses_Resistive); Results.coefficient_lossMagnetic = lossMagnetic / (Current * Current * Freq * Freq); Results.coefficient_lossResistive = lossResistive / (Current * Current);//=3/2*R Results.freq = Freq; Results.current = Current; }
public override void RunAnalysis() { int len = Barray.Length; // table phid-fz Vector <double> Fz_vector = mybuilder.Dense(len, i => Harray[i] * lz); Vector <double> phid_Fz_vector = mybuilder.Dense(len, i => Barray[i] * Sz + Fz_vector[i] * Pslot); // table phid-fy Vector <double> Fy_vector = mybuilder.Dense(len, i => Harray[i] * ly); Vector <double> phid_Fy_vector = mybuilder.Dense(len, i => Barray[i] * Sy); // reshape phid-fy, using interpolation to create new vector corresponding with phid_fy = phid_fz Vector <double> phid_vector = mybuilder.DenseOfVector(phid_Fz_vector);//same phid table for all LinearSpline ls = LinearSpline.Interpolate(phid_Fy_vector.ToArray(), Fy_vector.ToArray()); Vector <double> eqvFy_vector = mybuilder.Dense(len, i => ls.Interpolate(phid_vector[i])); // table f_phid Vector <double> f_phid = mybuilder.Dense(len, i => phid_vector[i] / Pd + Fz_vector[i] + eqvFy_vector[i] - (phiR - phiHFe - phid_vector[i]) / (PM + PFe + Pb)); var Results = new PMAnalyticalResults(); Results.Analyser = this; this.Results = Results; // calc phiD ls = LinearSpline.Interpolate(f_phid.ToArray(), phid_vector.ToArray()); double phiD = ls.Interpolate(0); double FM = (phiR - phiHFe - phiD) / (PM + PFe + Pb); double phib = FM * Pb; double phiFe = phiHFe + FM * PFe; double phiM = phiD + phib + phiFe; ls = LinearSpline.Interpolate(phid_vector.ToArray(), Fz_vector.ToArray()); double Fz = ls.Interpolate(phiD); ls = LinearSpline.Interpolate(phid_vector.ToArray(), eqvFy_vector.ToArray()); double Fy = ls.Interpolate(phiD); double Bdelta = phiD / (L * wd * 1e-6); double BM = phiM / (L * wm * 1e-6); double HM = FM / (lm * 1e-3); double pc = phiM / (PM * FM); double Bz = phiD / Sz; double By = phiD / Sy; double Vz = Sz * lz; double Vy = Sy * ly; double ro_ = 7800;//kg/m^3 - specific weight double kPMz = 1.3 * Bz * Bz * ro_ * Vz; double kPMy = 1.3 * By * By * ro_ * Vy; Results.kPMz = kPMz; Results.kPMy = kPMy; // assign results Results.phiD = phiD; Results.Bdelta = Bdelta; Results.phiM = phiM; Results.BM = BM; Results.FM = FM; Results.HM = HM; Results.pc = pc; Results.phib = phib; Results.phiFe = phiFe; Results.Fz = Fz; Results.Fy = Fy; Results.Bz = Bz; Results.By = By; Results.wd = wd; Results.gammaM = gammaM; int q = Q / 3 / p / 2; double kp = Math.Sin(Math.PI / (2 * 3)) / (q * Math.Sin(Math.PI / (2 * 3 * q))); //Results.psiM = phiD * Nstrand * p * q * kp /*4 / Math.PI * Math.Sin(gammaM / 2 * Math.PI / 180)*/; // Ld, Lq //double In = 3;//Ampe whatever //double Fmm = q * kp * Nstrand * In; //double phidelta = (Fmm) / (1 / PMd + Fz / phiD + Fy / phiD) / 2;//2time,PMd=PM+Pdelta //double psi = phidelta * q * kp * Nstrand; //double LL = p * psi / In; //Results.LL = LL; //Results.Ld = 1.5 * LL;//M=-1/2L //phidelta = (Fmm) / (1 / PMq + Fz / phiD + Fy / phiD) / 2;// //psi = phidelta * q * kp * Nstrand; //LL = p * psi / In; //Results.Lq = 1.5 * LL; // Resistant Stator3Phase stator = Motor.Stator as Stator3Phase; Results.R = stator.resistancePhase; double delta2 = delta * 1.1; double ns = 4 / Math.PI * kp * stator.NStrands * q; double dmin = delta2; double alphaM = Motor.Rotor is VPMRotor ? (Motor.Rotor as VPMRotor).alphaM : 180; //double dmax = delta2 + lm / Math.Sin(alphaM); double dmax = delta2 + Constants.mu_0 * L * wd * 1e-3 * (1 / (PM + PFe + Pb) + Fy / phiD + Fz / phiD);//* wd / wm2 * ((VPMRotor)Motor.Rotor).mu_M; //double dmax = L * wd * 1e-3 * Constants.mu_0 / PMd; //double dmin2 = 1 / Math.PI * ((180 - gammaM) * dmin + gammaM * dmax) * Math.PI / 180 - 2 / Math.PI * Math.Sin(gammaM * Math.PI / 180) * (dmax - dmin); //double dmax2 = 1 / Math.PI * ((180 - gammaM) * dmin + gammaM * dmax) * Math.PI / 180 + 2 / Math.PI * Math.Sin(gammaM * Math.PI / 180) * (dmax - dmin); //double a1 = 0.5 * (1 / dmin2 + 1 / dmax2) * 1e3; //double a2 = 0.5 * (1 / dmin2 - 1 / dmax2) * 1e3; //double a1 = 0.5 * (dmin + dmax) / (dmin * dmax) * 1e3; //double a2 = 0.5 * (dmax - dmin) / (dmin * dmax) * 1e3; // test override double gm = gammaM * Math.PI / 180; double a1 = 1 / Math.PI * (gm / dmax + (Math.PI - gm) / dmin) * 1e3; double a2 = -2 / Math.PI * Math.Sin(gm) * (1 / dmax - 1 / dmin) * 1e3; double L1 = (ns / 2) * (ns / 2) * Math.PI * Motor.Rotor.RGap * Motor.GeneralParams.MotorLength * 1e-6 * a1 * 4 * Math.PI * 1e-7; double L2 = 0.5 * (ns / 2) * (ns / 2) * Math.PI * Motor.Rotor.RGap * Motor.GeneralParams.MotorLength * 1e-6 * a2 * 4 * Math.PI * 1e-7; Results.dmin = dmin; Results.dmax = dmax; Results.L1 = L1; Results.L2 = L2; Results.Ld = 1.5 * (L1 - L2); Results.Lq = 1.5 * (L1 + L2); double psim = 2 * Math.Sin(gammaM * Math.PI / 180 / 2) * ns * Bdelta * Motor.Rotor.RGap * Motor.GeneralParams.MotorLength * 1e-6; Results.psiM = psim; // current demagnetizing //Results.Ikm = 2 * phiR / PM / (kp * Nstrand * q); //old double hck = Motor.Rotor is VPMRotor ? (Motor.Rotor as VPMRotor).Hck : 0; Results.Ikm = Math.PI * (hck - HM) * lm * 1e-3 / (2 * q * Nstrand * kp); dataValid = (Results.Ld > 0 && Results.Lq > 0 && Results.psiM >= 0 && gm > 0); }
protected override void measureInOpenedFem(FEMM femm) { // Begin to measure FEMM.LineIntegralResult lir = new FEMM.LineIntegralResult(); VPMMotor Motor = this.Motor as VPMMotor; VPMRotor Rotor = Motor.Rotor; Stator3Phase Stator = Motor.Stator; GeneralParameters GeneralParams = Motor.GeneralParams; AirgapNormal Airgap = Motor.Airgap; PMStaticResults Results = this.Results as PMStaticResults; double xS = Rotor.Rrotor * Math.Cos(Rotor.alpha * 0.9999); double yS = Rotor.Rrotor * Math.Sin(Rotor.alpha * 0.9999); // get phiD femm.mo_addcontour(xS, yS); //femm.mo_selectpoint(Rotor.xR, Rotor.yR); femm.mo_addcontour(xS, -yS); femm.mo_bendcontour(-360 / (2 * Rotor.p), 1); lir = femm.mo_lineintegral_full(); Results.phiD = Math.Abs(lir.totalBn); // get phiM femm.mo_clearcontour(); femm.mo_selectpoint(Rotor.xD, Rotor.yD); femm.mo_selectpoint(Rotor.xG, Rotor.yG); FEMM.LineIntegralResult rr = femm.mo_lineintegral(FEMM.LineIntegralType.Bn); Results.phiM = Math.Abs(rr.totalBn * 2); // get phib femm.mo_clearcontour(); femm.mo_selectpoint(Rotor.xH, Rotor.yH); femm.mo_selectpoint(Rotor.xH, -Rotor.yH); rr = femm.mo_lineintegral(FEMM.LineIntegralType.Bn); Results.phib = Math.Abs(rr.totalBn); femm.mo_clearcontour(); femm.mo_selectpoint(Rotor.xE, Rotor.yE); femm.mo_selectpoint(Rotor.xA, Rotor.yA); rr = femm.mo_lineintegral(FEMM.LineIntegralType.Bn); Results.phib += Math.Abs(rr.totalBn * 2); // get phisigmaFe femm.mo_clearcontour(); femm.mo_addcontour(Rotor.xA, Rotor.yA); femm.mo_addcontour(xS, yS); rr = femm.mo_lineintegral(FEMM.LineIntegralType.Bn); Results.phiFe = Math.Abs(rr.totalBn * 2); // get phisigmaS double xZ = (Stator.Rinstator + 5) * Math.Cos(2 * Math.PI / (4 * Rotor.p) - 2 * Math.PI / 180); double yZ = (Stator.Rinstator + 5) * Math.Sin(2 * Math.PI / (4 * Rotor.p) - 2 * Math.PI / 180); femm.mo_clearcontour(); femm.mo_selectpoint(Rotor.xS, Rotor.yS); femm.mo_selectpoint(xZ, yZ); rr = femm.mo_lineintegral(FEMM.LineIntegralType.Bn); Results.phisigmaS = Math.Abs(rr.totalBn * 2); // get FM femm.mo_clearcontour(); femm.mo_addcontour((Rotor.xI + Rotor.xF) / 2, (Rotor.yI + Rotor.yF) / 2); femm.mo_addcontour((Rotor.xD + Rotor.xG) / 2, (Rotor.yD + Rotor.yG) / 2); rr = femm.mo_lineintegral(FEMM.LineIntegralType.Ht); Results.FM = Math.Abs(rr.totalHt); // get B_airgap int n = 128; Results.Bairgap = new PointD[n * 2]; double RR = (Rotor.Rrotor + Stator.Rinstator) / 2; for (int i = 0; i < n; i++) { double a = -(i - n / 2.0) / n * 2 * Rotor.alpha; double px = RR * Math.Cos(a); double py = RR * Math.Sin(a); FEMM.PointValues pv = femm.mo_getpointvalues(px, py); Results.Bairgap[i].X = 2 * Rotor.alpha * RR * i / n; Results.Bairgap[i].Y = pv.B1 * Math.Cos(a) + pv.B2 * Math.Sin(a); if (double.IsNaN(Results.Bairgap[i].Y)) { Results.Bairgap[i].Y = 0; } if (Results.Bdelta_max < Math.Abs(Results.Bairgap[i].Y)) { Results.Bdelta_max = Math.Abs(Results.Bairgap[i].Y); } } // make a mirror (odd function) double dd = 2 * Rotor.alpha * RR; for (int i = 0; i < n; i++) { Results.Bairgap[i + n].X = Results.Bairgap[i].X + dd; Results.Bairgap[i + n].Y = -Results.Bairgap[i].Y; } double wd = Rotor.gammaMedeg / 180 * (Rotor.Rrotor + Airgap.delta / 2) * 2 * Math.PI / (2 * Rotor.p); Results.Bdelta = Results.phiD / (GeneralParams.MotorLength * wd * 1e-6); // psiM Dictionary <String, FEMM.CircuitProperties> cps = Stator.getCircuitsPropertiesInAns(femm); if (cps.ContainsKey("A") && cps.ContainsKey("B") && cps.ContainsKey("C")) { Fdq fdq = ParkTransform.abc_dq(cps["A"].fluxlinkage, cps["B"].fluxlinkage, cps["C"].fluxlinkage, 0); Results.psiM = fdq.Magnitude; } else { Results.psiM = double.NaN; } femm.mo_close(); }
protected override void DoMeasureData(TransientStepArgs args, FEMM femm) { // measure base data base.DoMeasureData(args, femm); // measure only one, not all those for skew angle if (args.skewAngleAdded != 0) { return; } // measure loss // other processes need to wait for the first to finish this block of code lock (lock_first) { if (allElements == null) { Stator3Phase stator = Motor.Stator as Stator3Phase; int rotor_steel_group = -1; int rotor_magnet_group = -1; double rotor_Keddy = 0; double rotor_Kh = 0; double rotor_ro = 0; if (Motor.Rotor is SPMRotor) { var rotor = Motor.Rotor as SPMRotor; rotor_steel_group = rotor.Group_BlockLabel_Steel; rotor_magnet_group = rotor.Group_BlockLabel_Magnet_Air; rotor_Keddy = rotor.P_eddy_10_50; rotor_Kh = rotor.P_hysteresis_10_50; rotor_ro = rotor.Steel_ro; } else if (Motor.Rotor is VPMRotor) { var rotor = Motor.Rotor as VPMRotor; rotor_steel_group = rotor.Group_BlockLabel_Steel; rotor_magnet_group = rotor.Group_BlockLabel_Magnet_Air; rotor_Keddy = rotor.P_eddy_10_50; rotor_Kh = rotor.P_hysteresis_10_50; rotor_ro = rotor.Steel_ro; } List <PointD> nodes = new List <PointD>(); int n = femm.mo_numnodes(); for (int i = 1; i <= n; i++) { var p = femm.mo_getnode(i); nodes.Add(p); } allElements = new List <FEMM.Element>(); n = femm.mo_numelements(); for (int i = 1; i <= n; i++) // start from 1 { var e = femm.mo_getelement(i); for (int j = 0; j < e.nodes.Length; j++) { e.nodes[j]--;//convert from 1-base index to 0-base index } allElements.Add(e); } var statorElements = allElements.Where(e => e.group == stator.Group_BlockLabel_Steel).ToList(); statorLoss = new CoreLoss(this, nodes, statorElements); statorLoss.name = "Stator_"; statorLoss.ro = stator.Steel_ro; statorLoss.Keddy = stator.P_eddy_10_50; statorLoss.Kh = stator.P_hysteresis_10_50; var rotorElements = allElements.Where(e => e.group == rotor_steel_group || e.group == rotor_magnet_group).ToList(); // convert coordinates of elements back to 0 degree rotor angle // hashset of node to mark rotated node HashSet <int> rotatedNodes = new HashSet <int>(); // angle to rotate back double a = Motor.GetNormalizedRotorAngle(args.RotorAngle) * Math.PI / 180; // for each element foreach (var e in rotorElements) { double xx = e.center.X; double yy = e.center.Y; e.center.X = xx * Math.Cos(-a) - yy * Math.Sin(-a); e.center.Y = xx * Math.Sin(-a) + yy * Math.Cos(-a); // rotate nodes of this element also for (int i = 0; i < e.nodes.Length; i++) { int node_index = e.nodes[i]; // if already rotated if (rotatedNodes.Contains(node_index)) { continue; } xx = nodes[node_index].X; yy = nodes[node_index].Y; nodes[node_index] = new PointD() { X = xx * Math.Cos(-a) - yy * Math.Sin(-a), Y = xx * Math.Sin(-a) + yy * Math.Cos(-a), }; // mark as rotated rotatedNodes.Add(node_index); } } rotorLoss = new CoreLoss(this, nodes, rotorElements); rotorLoss.name = "Rotor_"; rotorLoss.isRotor = true; rotorLoss.Keddy = rotor_Keddy; rotorLoss.Kh = rotor_Kh; rotorLoss.ro = rotor_ro; } }// lock(..) statorLoss.GatherData(args, femm); rotorLoss.GatherData(args, femm); }
public static SPMMotor GetSampleMotor() { ////// all length is in mm ////// SPMMotor m = new SPMMotor(); // general information GeneralParameters gp = new GeneralParameters(); gp.MotorLength = 125; gp.FullBuildFEMModel = false; m.GeneralParams = gp; // materials //steel PointBH[] BH = JSON.ToObject <List <PointBH> >(Properties.Resources.bhsample).ToArray(); //stator Stator3Phase sp = new Stator3Phase(); sp.Q = 36; sp.DiaYoke = 191; sp.DiaGap = 126; sp.HS0 = 0.5; sp.HS1 = 1; sp.HS2 = 13.3; sp.BS0 = 3; sp.BS1 = 5; sp.BS2 = 8.2; sp.RS = 0.5; sp.Kfill = 0.8; sp.WindingsConfig = "A:1-7,12-18,13-19,24-30,25-31,36-6;B:8-14,9-15,20-26,21-27,32-2,33-3;C:4-10,5-11,16-22,17-23,28-34,29-35"; sp.NStrands = 10; //wire sp.WireConduct = 58; sp.WireType = FEMM.WireType.MagnetWire; sp.WireDiameter = 1.2; sp.Copper_ro = 8930; //steel sp.Lam_fill = 0.98; sp.Lam_d = 0.635; sp.BH = BH; sp.Steel_ro = 7650; sp.P_eddy_10_50 = 2.5; sp.P_hysteresis_10_50 = 0; m.Stator = sp; //airgap AirgapNormal airgap = new AirgapNormal(); airgap.Kc = 1.1; m.Airgap = airgap; //rotor SPMRotor rotor = new SPMRotor(); // steel rotor.BH = BH; rotor.Lam_fill = 0.98; rotor.Lam_d = 0.635; rotor.Steel_ro = 7650; //magnet rotor.Hc = 883310; rotor.mu_M = 1.045; rotor.Magnet_ro = 7500; rotor.ThickMag = 6; // magnet length rotor.GammaM = 133; rotor.DiaYoke = 32; rotor.p = 3; // pair poles rotor.DiaGap = 126 - 2; // airgap rotor.Poletype = SPMRotor.PoleType.Normal; rotor.PreRotateAngle = 0; m.Rotor = rotor; return(m); }