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); }