/// <summary> /// Make a femm model using parameters /// This will check if file existed and use parameters the same to this one or not. /// If not, build new one /// </summary> /// <param name="outfile">Output femm model</param> /// <param name="original">The original femm model to insert into</param> /// <param name="forcebuild">True if build even file existed</param> /// <returns>0-OK,1-File existed, analyzed,-1-ERROR</returns> public virtual void BuildFEMModel(String outfile, FEMM femm = null) { // make sure coordinates were calculated if (!isPointsCoordCalculated) { throw new InvalidOperationException("Points must be calculated before make FEM model."); } if (femm == null) { femm = FEMM.DefaultFEMM; } femm.newdocument(FEMM.DocumentType.Magnetic); // setup problems params femm.mi_probdef(0, FEMM.UnitsType.millimeters, FEMM.ProblemType.planar, 1e-8, GeneralParams.MotorLength, 7, FEMM.ACSolverType.Succ_Approx); // build a rotor in femm Rotor.BuildInFEMM(femm); // build a stator in femm Stator.BuildInFEMM(femm); // build airgap (put label) Airgap.BuildInFEMM(femm); // clear selected, refresh, and go to natural zoom femm.mi_clearselected(); femm.mi_zoomnatural(); femm.mi_saveas(outfile); femm.mi_close(); // write md5 to it FEMM.mi_modifyFEMMComment(outfile, GetMD5String()); }
/// <summary> /// Make a femm model using parameters from rotor creation process /// </summary> /// <param name="outfile">Output femm model</param> /// <param name="original">The original femm model to insert into</param> public void MakeAFEMMModelFile(String outfile, String original = "") { if (!isPointsCoordCalculated) { CalcPointsCoordinates(); } // create new or open an exist if (original == "") { FEMM.newdocument(FEMM.DocumentType.Magnetic); } else { FEMM.open(original); } // double Rrotor = RotorParams.Rrotor; double alpha = 2 * Math.PI / (4 * RotorParams.p); double alphaM = RotorParams.alphaM; int p = RotorParams.p; ///// Build 1 poles // point far right of rotors double xI = Rrotor; double yI = 0; // segments (magnet) FEMM.mi_addSegmentEx(xA, yA, xB, yB, Group_Lines); //AB FEMM.mi_addSegmentEx(xA, yA, xF, yF, Group_Lines); //AF FEMM.mi_addSegmentEx(xA, yA, xD, yD, Group_Lines); //AD FEMM.mi_addSegmentEx(xB, yB, xC, yC, Group_Lines); //BC FEMM.mi_addSegmentEx(xC, yC, xD, yD, Group_Lines); //CD // mirrored segments (magnet) FEMM.mi_addSegmentEx(xA, -yA, xB, -yB, Group_Lines); //AB FEMM.mi_addSegmentEx(xA, -yA, xF, -yF, Group_Lines); //AF FEMM.mi_addSegmentEx(xA, -yA, xD, -yD, Group_Lines); //AD FEMM.mi_addSegmentEx(xB, -yB, xC, -yC, Group_Lines); //BC FEMM.mi_addSegmentEx(xC, -yC, xD, -yD, Group_Lines); //CD // barrier segments FEMM.mi_addSegmentEx(xC, yC, xC, -yC, Group_Lines); //AB FEMM.mi_addSegmentEx(xD, yD, xD, -yD, Group_Lines); //AF // arcsegments double a = (Math.Atan(yF / xF) - Math.Atan(yB / xB)) * 180 / Math.PI; FEMM.mi_addArcEx(xB, yB, xF, yF, a, 1, Group_Lines); FEMM.mi_addArcEx(xF, -yF, xB, -yB, a, 1, Group_Lines); // arcsegments rotor FEMM.mi_addArcEx(xI, yI, xG, yG, alpha * 180 / Math.PI, 1, Group_Lines); FEMM.mi_addArcEx(xG, -yG, xI, yI, alpha * 180 / Math.PI, 1, Group_Lines); // blocks // air block label double air1X = (xA + xB + xF) / 3; double air1Y = (yA + yB + yF) / 3; FEMM.mi_addBlockLabelEx(air1X, air1Y, AirBlockName, Group_Label); FEMM.mi_addBlockLabelEx(air1X, -air1Y, AirBlockName, Group_Label); FEMM.mi_addBlockLabelEx((xC + xD) / 2, 0, AirBlockName, Group_Label); // magnet block label double magBlockLabelX = (xA + xC) / 2; double magBlockLabelY = (yA + yC) / 2; FEMM.mi_addBlockLabelEx(magBlockLabelX, magBlockLabelY, MagnetBlockName, Group_Label, alphaM * 180 / Math.PI - 90 + 180);//+180 but set back later FEMM.mi_addBlockLabelEx(magBlockLabelX, -magBlockLabelY, MagnetBlockName, Group_Label, 90 - alphaM * 180 / Math.PI + 180); ///// Build 2 poles FEMM.mi_clearselected(); FEMM.mi_selectgroup(Group_Lines); FEMM.mi_selectgroup(Group_Label); FEMM.mi_copyrotate(0, 0, 360 / (2 * p), 1, FEMM.EditMode.group); // rotate the magnet direction FEMM.mi_clearselected(); FEMM.mi_selectlabel(magBlockLabelX, magBlockLabelY); FEMM.mi_setblockprop(MagnetBlockName, true, 0, "", alphaM * 180 / Math.PI - 90, Group_Label, 0); FEMM.mi_clearselected(); FEMM.mi_selectlabel(magBlockLabelX, -magBlockLabelY); FEMM.mi_setblockprop(MagnetBlockName, true, 0, "", 90 - alphaM * 180 / Math.PI, Group_Label, 0); ///// Build p-1 pair of poles remaining FEMM.mi_clearselected(); FEMM.mi_selectgroup(Group_Lines); FEMM.mi_selectgroup(Group_Label); FEMM.mi_copyrotate(0, 0, 360 / p, p - 1, FEMM.EditMode.group); FEMM.mi_addBlockLabelEx(0, 0, SteelBlockName, Group_Rotor_Steel); // clear selected, refresh, and go to natural zoom FEMM.mi_clearselected(); FEMM.mi_zoomnatural(); // save as if (Path.GetDirectoryName(outfile) == "") { outfile = Path.GetDirectoryName(original) + "\\" + outfile; } FEMM.mi_saveas(outfile); FEMM.mi_close(); }