"""MotorCAD fixed parameter templates with Chinese names, categories and descriptions. Used to populate AI-generated simulation plans with comprehensive fixed parameters. Parameters that are also scan variables are automatically excluded. This file is the single source of truth for the fixed-parameter template. AI plan generation populates ALL parameters here (template-driven), so the frontend can reliably render a complete, balanced fixed-parameter table. """ from typing import Dict, Any, List from .bc_fields import normalize_bc # Category Chinese names (8 motor-engineering categories) CATEGORY_CN = { "Geometry": "\u51e0\u4f55\u5c3a\u5bf8", "Stator": "\u5b9a\u5b50\u53c2\u6570", "Rotor": "\u8f6c\u5b50\u53c2\u6570", "Performance": "\u6027\u80fd\u89c4\u683c", "Winding": "\u7ed5\u7ec4\u53c2\u6570", "Material": "\u6750\u6599\u5c5e\u6027", "Thermal": "\u70ed\u4e0e\u51b7\u5374", "Simulation": "\u4eff\u771f\u8bbe\u7f6e", "System": "\u4eff\u771f\u8bbe\u7f6e", "Mechanical": "\u5176\u4ed6", "Electrical": "\u6027\u80fd\u89c4\u683c", "General": "\u5176\u4ed6", } # Fixed parameter templates: name -> {display_name, name_cn, unit, value, category, category_cn, description, description_cn} # Note: params marked "\u9700\u786e\u8ba4" in description_cn may need Motor-CAD variable name verification. FIXED_PARAM_TEMPLATES = [ # ===== Geometry \u51e0\u4f55\u5c3a\u5bf8 ===== { "name": "Outer_Rotor_Diameter", "motorcad_var": "RotorOuterDiameter", "display_name": "Outer Rotor Diameter", "name_cn": "\u8f6c\u5b50\u5916\u5f84", "unit": "mm", "value": 130.0, "category": "Geometry", "description": "Outer diameter of rotor back iron", "description_cn": "\u8f6c\u5b50\u80cc\u94c1\u5916\u5f84", }, { "name": "Inner_Rotor_Diameter", "motorcad_var": None, "display_name": "Inner Rotor Diameter", "name_cn": "\u8f6c\u5b50\u5185\u5f84", "unit": "mm", "value": 120.0, "category": "Geometry", "description": "Inner diameter of rotor back iron", "description_cn": "\u8f6c\u5b50\u80cc\u94c1\u5185\u5f84", }, { "name": "Stator_Outer_Diameter", "motorcad_var": "Stator_Lam_Dia", "display_name": "Stator Outer Diameter", "name_cn": "\u5b9a\u5b50\u5916\u5f84", "unit": "mm", "value": 76.0, "category": "Geometry", "description": "Outer diameter of stator lamination", "description_cn": "\u5b9a\u5b50\u51b2\u7247\u5916\u5f84", }, { "name": "Stator_Inner_Diameter", "motorcad_var": "Stator_Bore", "display_name": "Stator Inner Diameter", "name_cn": "\u5b9a\u5b50\u5185\u5f84", "unit": "mm", "value": 50.0, "category": "Geometry", "description": "Inner diameter of stator lamination", "description_cn": "\u5b9a\u5b50\u51b2\u7247\u5185\u5f84", }, { "name": "Airgap", "motorcad_var": "Airgap", "display_name": "Airgap Length", "name_cn": "\u6c14\u9699\u957f\u5ea6", "unit": "mm", "value": 1.0, "category": "Geometry", "description": "Mechanical airgap between stator and rotor", "description_cn": "\u5b9a\u8f6c\u5b50\u4e4b\u95f4\u6c14\u9699", }, # ===== Stator \u5b9a\u5b50\u53c2\u6570 ===== { "name": "Stator_Yoke_Thickness", "motorcad_var": None, "display_name": "Stator Yoke Thickness", "name_cn": "\u5b9a\u5b50\u8f6f\u539a", "unit": "mm", "value": 10.0, "category": "Stator", "description": "Radial thickness of stator yoke", "description_cn": "\u5b9a\u5b50\u8f6f\u90e8\u5f84\u5411\u539a\u5ea6", }, { "name": "Slot_Depth", "motorcad_var": "Slot_Depth", "display_name": "Slot Depth", "name_cn": "\u69fd\u6df1", "unit": "mm", "value": 7.0, "category": "Stator", "description": "Depth of stator slot", "description_cn": "\u5b9a\u5b50\u69fd\u6df1\u5ea6", }, { "name": "Slot_Width", "motorcad_var": "Slot_Width", "display_name": "Slot Width", "name_cn": "\u69fd\u5bbd", "unit": "mm", "value": 8.5, "category": "Stator", "description": "Width of stator slot opening", "description_cn": "\u5b9a\u5b50\u69fd\u53e3\u5bbd\u5ea6", }, { "name": "Tooth_Width", "motorcad_var": "Tooth_Width", "display_name": "Tooth Width", "name_cn": "\u9f7f\u5bbd", "unit": "mm", "value": 7.0, "category": "Stator", "description": "Width of stator tooth", "description_cn": "\u5b9a\u5b50\u9f7f\u5bbd\u5ea6", }, { "name": "Number_of_Slots", "motorcad_var": "Slot_Number", "display_name": "Number of Slots", "name_cn": "\u69fd\u6570", "unit": "", "value": 12, "category": "Stator", "description": "Total number of stator slots", "description_cn": "\u5b9a\u5b50\u603b\u69fd\u6570", }, # ===== Rotor \u8f6c\u5b50\u53c2\u6570 ===== { "name": "Rotor_Back_Iron_Thickness", "motorcad_var": "Back_Iron_Thickness", "display_name": "Rotor Back Iron Thickness", "name_cn": "\u8f6c\u5b50\u80cc\u94c1\u539a", "unit": "mm", "value": 5.0, "category": "Rotor", "description": "Radial thickness of rotor back iron", "description_cn": "\u8f6c\u5b50\u80cc\u94c1\u5f84\u5411\u539a\u5ea6", }, { "name": "Magnet_Length", "motorcad_var": "Magnet_Length", "display_name": "Magnet Axial Thickness", "name_cn": "\u78c1\u94a2\u8f74\u5411\u957f\u5ea6", "unit": "mm", "value": 3.0, "category": "Rotor", "description": "Axial thickness of permanent magnet", "description_cn": "\u6c38\u78c1\u4f53\u8f74\u5411\u539a\u5ea6", }, { "name": "Magnet_Thickness", "motorcad_var": "Magnet_Thickness", "display_name": "Magnet Radial Depth", "name_cn": "\u78c1\u94a2\u5f84\u5411\u539a\u5ea6", "unit": "mm", "value": 13.0, "category": "Rotor", "description": "Magnet ring radial depth", "description_cn": "\u78c1\u94a2\u73af\u5f84\u5411\u539a\u5ea6", }, { "name": "Magnet_Arc_[ED]", "motorcad_var": "Magnet_Arc_[ED]", "display_name": "Magnet Pole Arc", "name_cn": "\u78c1\u94a2\u6781\u5f27\u89d2", "unit": "deg", "value": 121.0, "category": "Rotor", "description": "Magnet pole arc in electrical degrees", "description_cn": "\u78c1\u94a2\u6781\u5f27\u89d2\u5ea6(\u7535\u89d2\u5ea6)", }, { "name": "Number_of_Poles", "motorcad_var": "Pole_Number", "display_name": "Number of Poles", "name_cn": "\u6781\u6570", "unit": "", "value": 10, "category": "Rotor", "description": "Total number of magnetic poles", "description_cn": "\u7535\u673a\u603b\u6781\u6570", }, # ===== Performance \u6027\u80fd\u89c4\u683c ===== { "name": "Current_Advance_Angle", "motorcad_var": "PhaseAdvance", "display_name": "Current Advance Angle", "name_cn": "\u7535\u6d41\u8d85\u524d\u89d2", "unit": "deg", "value": 0.0, "category": "Performance", "description": "Current advance angle for field weakening", "description_cn": "\u5f31\u78c1\u63a7\u5236\u7535\u6d41\u8d85\u524d\u89d2", }, { "name": "DC_Link_Voltage", "motorcad_var": "DCBusVoltage", "display_name": "DC Link Voltage", "name_cn": "\u6bcd\u7ebf\u7535\u538b", "unit": "V", "value": 13.5, "category": "Performance", "description": "DC bus voltage", "description_cn": "\u76f4\u6d41\u6bcd\u7ebf\u7535\u538b", }, { "name": "RMSCurrent", "motorcad_var": "RMSCurrent", "display_name": "RMS Phase Current", "name_cn": "\u989d\u5b9a\u7535\u6d41", "unit": "A", "value": 21.0, "category": "Performance", "description": "RMS phase current (CurrentDefinition=1)", "description_cn": "\u989d\u5b9a\u76f8\u7535\u6d41(RMS)", }, { "name": "Shaft_Speed", "motorcad_var": "Shaft_Speed", "display_name": "Shaft Speed", "name_cn": "\u989d\u5b9a\u8f6c\u901f", "unit": "rpm", "value": 5000.0, "category": "Performance", "description": "Rotational shaft speed", "description_cn": "\u7535\u673a\u989d\u5b9a\u8f6c\u901f", }, { "name": "Max_Speed", "motorcad_var": "WindageGraph_MaxSpeed", "display_name": "Max Speed", "name_cn": "\u6700\u9ad8\u8f6c\u901f", "unit": "rpm", "value": 7500.0, "category": "Performance", "description": "Maximum rotational speed (variable name may need Motor-CAD verification)", "description_cn": "\u7535\u673a\u6700\u9ad8\u8f6c\u901f\uff08\u53d8\u91cf\u540d\u9700\u786e\u8ba4\uff09", }, # ===== Winding \u7ed5\u7ec4\u53c2\u6570 ===== { "name": "Turns_per_Coil", "motorcad_var": "ConductorsPerSlot", "display_name": "Turns per Coil", "name_cn": "\u6bcf\u7ebf\u5708\u53a9\u6570", "unit": "", "value": 20, "category": "Winding", "description": "Number of turns per coil", "description_cn": "\u6bcf\u4e2a\u7ebf\u5708\u7684\u53a9\u6570", }, { "name": "Parallel_Paths", "motorcad_var": "ParallelPaths", "display_name": "Parallel Paths", "name_cn": "\u5e76\u8054\u652f\u8def\u6570", "unit": "", "value": 1, "category": "Winding", "description": "Number of parallel winding paths", "description_cn": "\u7ed5\u7ec4\u5e76\u8054\u652f\u8def\u6570", }, { "name": "Copper_Fill_Factor", "motorcad_var": "Slot_Fill", "display_name": "Copper Fill Factor", "name_cn": "\u69fd\u6ee1\u7387", "unit": "", "value": 0.45, "category": "Winding", "description": "Copper area to slot area ratio", "description_cn": "\u94dc\u7ebf\u9762\u79ef\u4e0e\u69fd\u9762\u79ef\u4e4b\u6bd4", }, { "name": "Wire_Diameter", "motorcad_var": "Wire_Diameter", "display_name": "Wire Diameter", "name_cn": "\u7ebf\u5f84", "unit": "mm", "value": 1.63, "category": "Winding", "description": "Diameter of magnet wire", "description_cn": "\u6f06\u5305\u7ebf\u76f4\u5f84", }, { "name": "Winding_Connection", "motorcad_var": "WindingConnection", "display_name": "Winding Connection", "name_cn": "\u7ed5\u7ec4\u8fde\u63a5\u65b9\u5f0f", "unit": "", "value": "Star", "category": "Winding", "description": "Winding connection (Star/Delta) - variable name may need verification", "description_cn": "\u7ed5\u7ec4\u8fde\u63a5\u65b9\u5f0f(\u661f/\u4e09\u89d2)\uff08\u53d8\u91cf\u540d\u9700\u786e\u8ba4\uff09", }, { "name": "Current_Density", "motorcad_var": None, "display_name": "Current Density", "name_cn": "\u7535\u6d41\u5bc6\u5ea6", "unit": "A/mm2", "value": 6.0, "category": "Winding", "description": "Winding current density - variable name may need verification", "description_cn": "\u7ed5\u7ec4\u7535\u6d41\u5bc6\u5ea6\uff08\u53d8\u91cf\u540d\u9700\u786e\u8ba4\uff09", }, # ===== Material \u6750\u6599\u5c5e\u6027 ===== { "name": "Magnet_Material", "motorcad_var": "Material_Magnet", "display_name": "Magnet Material", "name_cn": "\u78c1\u94a2\u6750\u6599", "unit": "", "value": "N42UH", "category": "Material", "description": "Permanent magnet material grade", "description_cn": "\u6c38\u78c1\u4f53\u6750\u6599\u724c\u53f7", }, { "name": "Steel_Grade", "motorcad_var": None, "display_name": "Steel Grade", "name_cn": "\u7845\u94a2\u7247\u724c\u53f7", "unit": "", "value": "M19_24G", "category": "Material", "description": "Electrical steel lamination grade", "description_cn": "\u7535\u5de5\u7845\u94a2\u7247\u724c\u53f7", }, { "name": "Magnet_Temperature", "motorcad_var": "InitialMagnetTemperature", "display_name": "Magnet Temperature", "name_cn": "\u78c1\u94a2\u6e29\u5ea6", "unit": "C", "value": 40.0, "category": "Material", "description": "Operating temperature of magnets", "description_cn": "\u78c1\u94a2\u5de5\u4f5c\u6e29\u5ea6", }, { "name": "Magnet_Remanence", "motorcad_var": "Magnet_Br_at_RefTemp", "display_name": "Magnet Remanence", "name_cn": "\u5269\u78c1", "unit": "T", "value": 1.31, "category": "Material", "description": "Permanent magnet remanence flux density - variable name may need verification", "description_cn": "\u6c38\u78c1\u4f53\u5269\u78c1\u5bc6\u5ea6\uff08\u53d8\u91cf\u540d\u9700\u786e\u8ba4\uff09", }, # ===== Thermal \u70ed\u4e0e\u51b7\u5374 ===== { "name": "Ambient_Temperature", "motorcad_var": "Ambient_Temperature", "display_name": "Ambient Temperature", "name_cn": "\u73af\u5883\u6e29\u5ea6", "unit": "C", "value": 40.0, "category": "Thermal", "description": "Ambient air temperature", "description_cn": "\u73af\u5883\u7a7a\u6c14\u6e29\u5ea6", }, { "name": "Cooling_Method", "motorcad_var": "Cooling_Type", "display_name": "Cooling Method", "name_cn": "\u51b7\u5374\u65b9\u5f0f", "unit": "", "value": "Natural", "category": "Thermal", "description": "Cooling method (Natural/ForcedAir/WaterJacket)", "description_cn": "\u51b7\u5374\u65b9\u5f0f(\u81ea\u7136/\u5f3a\u8feb\u98ce\u51b7/\u6c34\u51b7)", }, { "name": "Insulation_Class", "motorcad_var": None, "display_name": "Insulation Class", "name_cn": "\u7edd\u7f18\u7b49\u7ea7", "unit": "", "value": "F", "category": "Thermal", "description": "Insulation class (A/E/B/F/H) - variable name may need verification", "description_cn": "\u7edd\u7f18\u7b49\u7ea7(A/E/B/F/H)\uff08\u53d8\u91cf\u540d\u9700\u786e\u8ba4\uff09", }, # ===== Simulation \u4eff\u771f\u8bbe\u7f6e ===== { "name": "TorquePointsPerCycle", "motorcad_var": "TorquePointsPerCycle", "display_name": "Torque Points Per Cycle", "name_cn": "\u6bcf\u5468\u671f\u8f6c\u77e9\u91c7\u6837\u70b9", "unit": "", "value": 30, "category": "Simulation", "description": "Number of torque calculation points per electrical cycle", "description_cn": "\u6bcf\u7535\u5468\u671f\u8f6c\u77e9\u8ba1\u7b97\u91c7\u6837\u70b9\u6570", }, { "name": "CurrentDefinition", "motorcad_var": "CurrentDefinition", "display_name": "Current Definition", "name_cn": "\u7535\u6d41\u5b9a\u4e49\u65b9\u5f0f", "unit": "", "value": 1.0, "category": "Simulation", "description": "1=RMS, 2=Peak current definition", "description_cn": "1=\u6709\u6548\u503c, 2=\u5cf0\u503c\u7535\u6d41\u5b9a\u4e49", }, { "name": "AirgapMeshPoints_mesh", "motorcad_var": "AirgapMeshPoints_mesh", "display_name": "Airgap Mesh Points", "name_cn": "\u6c14\u9699\u7f51\u683c\u70b9\u6570", "unit": "", "value": 600.0, "category": "Simulation", "description": "Number of airgap mesh points (FE mesh refinement)", "description_cn": "\u6c14\u9699\u7f51\u683c\u70b9\u6570(\u663e\u5f0f\u6c42\u89e3\u7f51\u683c\u52a0\u5bc6)", }, { "name": "MessageDisplayState", "motorcad_var": "MessageDisplayState", "display_name": "Message Display", "name_cn": "\u6d88\u606f\u663e\u793a", "unit": "", "value": 2.0, "category": "Simulation", "description": "Suppress popup dialogs during scripting", "description_cn": "\u811a\u672c\u8fd0\u884c\u65f6\u6291\u5236\u5f39\u7a97", }, ] def get_fixed_param_template(name: str) -> Dict[str, Any]: """Get a fixed parameter template by name (case-insensitive).""" lower = name.lower() for p in FIXED_PARAM_TEMPLATES: if p["name"].lower() == lower: return dict(p) return {} def build_default_fixed_params( scan_variable_names: List[str], boundary_conditions: Dict[str, Any] = None, ) -> List[Dict[str, Any]]: """Build default fixed parameter list, excluding variables that are being scanned. Args: scan_variable_names: List of variable names used as scan variables. boundary_conditions: Project boundary conditions for value inference. Returns: List of fixed parameter dicts. """ # Normalize the incoming boundary conditions through the single-source BC # catalog (bc_fields.normalize_bc): legacy aliases (rated_*, slot_count, # dc_link_voltage_v, cooling_method, ...) are mapped to the canonical keys # (current_a, speed_rpm, slots, voltage_v, cooling_type, ...) read below. # This replaces the previous local alias bridge and keeps all BC-key # handling in one place (P1-1). bc = normalize_bc(boundary_conditions or {}) scan_names = {n.lower() for n in scan_variable_names} params = [] for tmpl in FIXED_PARAM_TEMPLATES: # Skip if this parameter is already a scan variable if tmpl["name"].lower() in scan_names: continue p = dict(tmpl) p["category_cn"] = CATEGORY_CN.get(p["category"], p["category"]) # Infer values from boundary conditions if tmpl["name"] == "Outer_Rotor_Diameter" and bc.get("outer_diameter_mm"): p["value"] = float(bc["outer_diameter_mm"]) elif tmpl["name"] == "Stator_Outer_Diameter" and bc.get("outer_diameter_mm"): p["value"] = float(bc["outer_diameter_mm"]) - 2.0 elif tmpl["name"] == "Inner_Rotor_Diameter" and bc.get("inner_diameter_mm"): p["value"] = float(bc["inner_diameter_mm"]) elif tmpl["name"] == "Stator_Inner_Diameter" and bc.get("inner_diameter_mm"): p["value"] = float(bc["inner_diameter_mm"]) + 2.0 elif tmpl["name"] == "Airgap" and bc.get("airgap_mm"): p["value"] = float(bc["airgap_mm"]) elif tmpl["name"] == "Number_of_Poles" and bc.get("pole_pairs"): p["value"] = int(bc["pole_pairs"]) * 2 elif tmpl["name"] == "Number_of_Slots" and bc.get("slots"): p["value"] = int(bc["slots"]) elif tmpl["name"] == "RMSCurrent" and bc.get("current_a"): p["value"] = float(bc["current_a"]) elif tmpl["name"] == "Shaft_Speed" and bc.get("speed_rpm"): p["value"] = float(bc["speed_rpm"]) elif tmpl["name"] == "Max_Speed" and bc.get("max_speed_rpm"): p["value"] = float(bc["max_speed_rpm"]) elif tmpl["name"] == "DC_Link_Voltage" and bc.get("voltage_v"): p["value"] = float(bc["voltage_v"]) elif tmpl["name"] == "Magnet_Material" and bc.get("magnet_material"): p["value"] = bc["magnet_material"] elif tmpl["name"] == "Steel_Grade" and bc.get("steel_grade"): p["value"] = bc["steel_grade"] elif tmpl["name"] == "Cooling_Method" and bc.get("cooling_type"): p["value"] = bc["cooling_type"] elif tmpl["name"] == "Turns_per_Coil" and bc.get("turns_per_coil"): p["value"] = int(bc["turns_per_coil"]) elif tmpl["name"] == "Parallel_Paths" and bc.get("parallel_paths"): p["value"] = int(bc["parallel_paths"]) elif tmpl["name"] == "Magnet_Length" and bc.get("magnet_length_mm"): p["value"] = float(bc["magnet_length_mm"]) elif tmpl["name"] == "Magnet_Thickness" and bc.get("magnet_thickness_mm"): p["value"] = float(bc["magnet_thickness_mm"]) elif tmpl["name"] == "Magnet_Arc_[ED]" and bc.get("magnet_arc_deg"): p["value"] = float(bc["magnet_arc_deg"]) elif tmpl["name"] == "Current_Density" and bc.get("current_density_a_mm2"): p["value"] = float(bc["current_density_a_mm2"]) elif tmpl["name"] == "Magnet_Remanence" and bc.get("magnet_remanence_t"): p["value"] = float(bc["magnet_remanence_t"]) elif tmpl["name"] == "Ambient_Temperature" and bc.get("ambient_temp_c"): p["value"] = float(bc["ambient_temp_c"]) elif tmpl["name"] == "Magnet_Temperature" and bc.get("magnet_temp_c"): p["value"] = float(bc["magnet_temp_c"]) elif tmpl["name"] == "Insulation_Class" and bc.get("insulation_class"): p["value"] = bc["insulation_class"] params.append(p) return params