Skip to content

Commit 33b337f

Browse files
author
Othman Abujazar
committed
improve gmsh for electrostatic simulation. Add equ circuit figure
1 parent 7d60341 commit 33b337f

9 files changed

Lines changed: 257 additions & 40 deletions

femmt/component.py

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,7 +1317,7 @@ def simulate(self):
13171317
gmsh.fltk.run()
13181318
else:
13191319
self.onelab_client.runSubClient("myGetDP", getdp_filepath + " " + solver_freq + " -msh " + \
1320-
self.file_data.e_m_mesh_file + " -solve Analysis -v2 " + verbose + to_file_str)
1320+
self.file_data.e_m_mesh_file + " -solve Analysis -v2" + verbose + to_file_str)
13211321
if self.simulation_type == SimulationType.TimeDomain:
13221322
if self.visualization_mode == VisualizationMode.Stream:
13231323
# 1) Start GUI
@@ -1331,12 +1331,23 @@ def simulate(self):
13311331
else:
13321332
# the two commands work but some changes should be done in fields_time.pro
13331333
self.onelab_client.runSubClient("myGetDP", getdp_filepath + " " + solver_time + " -msh " + self.file_data.e_m_mesh_file + \
1334-
" -solve Analysis -pos Map_local " + verbose + to_file_str)
1335-
# self.onelab_client.runSubClient("myGetDP", getdp_filepath + " " + solver + " -msh " + self.file_data.e_m_mesh_file +
1336-
# " -solve Analysis -v2 " + verbose) # freeing solutions
1334+
" -solve Analysis -pos Map_local " + verbose + to_file_str)
13371335
if self.simulation_type == SimulationType.ElectroStatic:
1338-
self.onelab_client.runSubClient("myGetDP", getdp_filepath + " " + solver_electrostatic + " -msh " + \
1339-
self.file_data.e_m_mesh_file + " -solve EleSta_v -v2 " + verbose + to_file_str)
1336+
if self.visualization_mode == VisualizationMode.Stream:
1337+
if not gmsh.isInitialized():
1338+
gmsh.initialize()
1339+
if '-nopopup' not in sys.argv:
1340+
gmsh.fltk.initialize()
1341+
gmsh.onelab.run("myGetDP", getdp_filepath + " " + solver_electrostatic + " -msh " + \
1342+
self.file_data.e_m_mesh_file + " -solve EleSta_v -pos Get_global" + verbose + to_file_str)
1343+
gmsh.fltk.run()
1344+
elif self.visualization_mode == VisualizationMode.Post:
1345+
gmsh.onelab.run("myGetDP", getdp_filepath + " " + solver_electrostatic + " -msh " + \
1346+
self.file_data.e_m_mesh_file + " -solve EleSta_v -v2" + verbose + to_file_str)
1347+
gmsh.fltk.run()
1348+
else:
1349+
self.onelab_client.runSubClient("myGetDP", getdp_filepath + " " + solver_electrostatic + " -msh " + \
1350+
self.file_data.e_m_mesh_file + " -solve EleSta_v -v2" + verbose + to_file_str)
13401351

13411352
def write_simulation_parameters_to_pro_files(self):
13421353
"""
@@ -1594,9 +1605,9 @@ def electrostatic_simulation(self, voltage: list[list[float]] = None, charge: li
15941605
ff.json_to_excel(json_file_path, output_excel_path)
15951606
logger.info(f"Data has been successfully written to {output_excel_path}")
15961607
logging_time = time.time() - start_time
1597-
1598-
if show_fem_simulation_results:
1599-
self.visualize()
1608+
if self.visualization_mode == VisualizationMode.Final:
1609+
if show_fem_simulation_results:
1610+
self.visualize()
16001611

16011612
return generate_electro_magnetic_mesh_time, prepare_simulation_time, real_simulation_time, logging_time
16021613
else:
@@ -1613,8 +1624,9 @@ def electrostatic_simulation(self, voltage: list[list[float]] = None, charge: li
16131624
ff.json_to_excel(json_file_path, output_excel_path)
16141625
logger.info(f"Data has been successfully written to {output_excel_path}")
16151626

1616-
if show_fem_simulation_results:
1617-
self.visualize()
1627+
if self.visualization_mode == VisualizationMode.Final:
1628+
if show_fem_simulation_results:
1629+
self.visualize()
16181630

16191631
logger.info(f"The electrostatic results are stored here: {self.file_data.electrostatic_results_log_path}")
16201632

@@ -2957,8 +2969,9 @@ def get_inductance_from_reluctance(self):
29572969

29582970
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
29592971
# Post-Processing --- Capacitance extraction---
2960-
def get_capacitance_of_inductor_component(self, freq_for_mesh: float = 0.0, show_visual_outputs: bool = False, plot_interpolation: bool = False,
2961-
show_fem_simulation_results: bool = False, benchmark: bool = False, save_to_excel: bool = False):
2972+
def get_capacitance_of_inductor_component(self, freq_for_mesh: float = 0.0, show_visual_outputs: bool = False, show_equivalent_circuit: bool = False,
2973+
plot_interpolation: bool = False, show_fem_simulation_results: bool = False, benchmark: bool = False,
2974+
save_to_excel: bool = False):
29622975
"""
29632976
Needed for finding parasitic capacitance of an inductor. A represent the first turn, B represents the last turn. e represents the core.
29642977
@@ -2978,6 +2991,8 @@ def get_capacitance_of_inductor_component(self, freq_for_mesh: float = 0.0, show
29782991
:type freq_for_mesh: float = 0.0
29792992
:param show_visual_outputs: show the electrostatic model before simulation
29802993
:type show_visual_outputs: bool, optional
2994+
:param show_equivalent_circuit: show the equivalent circuit of inductor
2995+
:type show_equivalent_circuit: bool
29812996
:param plot_interpolation: if True, plot the interpolation between the provided values for the material.
29822997
:type plot_interpolation: bool
29832998
:param show_fem_simulation_results: if True, show the simulation results after the simulation has finished
@@ -3031,6 +3046,14 @@ def get_capacitance_of_inductor_component(self, freq_for_mesh: float = 0.0, show
30313046
c_ab_stray = c_ab + (c_ae * c_be) / (c_ae + c_be)
30323047
logger.info(f"→ C_AB (incl. parasitic): {c_ab_stray:.4e} F")
30333048

3049+
if show_equivalent_circuit:
3050+
d = ff.draw_capacitive_equivalent_circuit_of_inductor(c_vec)
3051+
d.draw()
3052+
os.makedirs(self.file_data.e_m_values_folder_path, exist_ok=True)
3053+
figure_path = os.path.join(self.file_data.e_m_values_folder_path, "capacitive_equivalent_circuit_of_inductor.pdf")
3054+
d.save(figure_path)
3055+
logger.info(f"Equivalent circuit saved to {figure_path}")
3056+
30343057
return c_vec
30353058

30363059
def get_stray_capacitance_of_inductor_component(self, freq_for_mesh: float = 0.0, show_visual_outputs: bool = False, plot_interpolation: bool = False,
@@ -3098,9 +3121,9 @@ def get_stray_capacitance_of_inductor_component(self, freq_for_mesh: float = 0.0
30983121

30993122
def get_capacitance_of_transformer(self, freq_for_mesh: float = 0.0, c_meas_open: float | None = None,
31003123
c_meas_short: float | None = None, measured_capacitances: tuple | list | None = None,
3101-
flip_the_sec_terminal: bool = False, show_visual_outputs: bool = False, plot_interpolation: bool = False,
3102-
show_fem_simulation_results: bool = False, benchmark: bool = False, save_to_excel: bool = False,
3103-
show_plot_comparison: bool = True):
3124+
flip_the_sec_terminal: bool = False, show_visual_outputs: bool = False, show_equivalent_circuit: bool = False,
3125+
plot_interpolation: bool = False, show_fem_simulation_results: bool = False, benchmark: bool = False,
3126+
save_to_excel: bool = False, show_plot_comparison: bool = True):
31043127
r"""
31053128
Get 10 parasitic capacitance of a transformer.
31063129
@@ -3132,6 +3155,8 @@ def get_capacitance_of_transformer(self, freq_for_mesh: float = 0.0, c_meas_open
31323155
:type flip_the_sec_terminal: bool
31333156
:param show_visual_outputs: show the electrostatic model before simulation
31343157
:type show_visual_outputs: bool, optional
3158+
:param show_equivalent_circuit: show the equivalent circuit of transformer
3159+
:type show_equivalent_circuit: bool
31353160
:param plot_interpolation: if True, plot the interpolation between the provided values for the material.
31363161
:type plot_interpolation: bool
31373162
:param show_fem_simulation_results: if True, show the simulation results after the simulation has finished
@@ -3202,6 +3227,15 @@ def get_capacitance_of_transformer(self, freq_for_mesh: float = 0.0, c_meas_open
32023227
if show_plot_comparison and (c_meas_open is not None or c_meas_short is not None):
32033228
ff.plot_open_and_short_comparison(c_sim_open, c_sim_short, c_meas_open, c_meas_short)
32043229

3230+
# show equivalent circuit
3231+
if show_equivalent_circuit:
3232+
d = ff.draw_capacitive_equivalent_circuit_of_transformer(c_vec)
3233+
d.draw()
3234+
os.makedirs(self.file_data.e_m_values_folder_path, exist_ok=True)
3235+
figure_path = os.path.join(self.file_data.e_m_values_folder_path, "capacitive_equivalent_circuit_of_transformer.pdf")
3236+
d.save(figure_path)
3237+
logger.info(f"Equivalent circuit saved to {figure_path}")
3238+
32053239
return c_vec
32063240

32073241
def get_inductances(self, I0: float, op_frequency: float = 0, skin_mesh_factor: float = 1,
@@ -3666,6 +3700,11 @@ def write_electro_static_parameter_pro(self):
36663700

36673701
text_file.write("Flag_Static = 1;\n")
36683702

3703+
if self.visualization_mode == VisualizationMode.Stream or self.visualization_mode == VisualizationMode.Post:
3704+
text_file.write("Flag_Stream_Visualization = 1;\n")
3705+
else:
3706+
text_file.write("Flag_Stream_Visualization = 0;\n")
3707+
36693708
# Airgap number
36703709
text_file.write("n_airgaps = {};\n".format(len(self.air_gaps.midpoints)))
36713710

femmt/electro_magnetic/fields_electrostatic.pro

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,39 @@ PostOperation Map_local UsingPost EleSta {
33
// Potentials for the entire domain
44
ExtGmsh = ".pos";
55
Print[ u0, OnElementsOf Region[{Domain}], Name "Potential / V", File StrCat[DirResFields, "Potential", ExtGmsh], LastTimeStepOnly ] ;
6-
Print[ u0, OnElementsOf Region[{Core}], Name "Average Potential on Core / V", File StrCat[DirResFields, "Voltage_Core_Map", ExtGmsh], LastTimeStepOnly ];
6+
If (!Flag_Stream_Visualization)
7+
Print[ u0, OnElementsOf Region[{Core}], Name "Average Potential on Core / V", File StrCat[DirResFields, "Voltage_Core_Map", ExtGmsh], LastTimeStepOnly ];
8+
EndIf
79

810
// Electric Field vector in the entire domain
9-
Print[ e, OnElementsOf Region[{Domain}], Name "Electric Field", File StrCat[DirResFields, "Efield", ExtGmsh], LastTimeStepOnly ] ;
10-
//Print[ Welocal, OnElementsOf Region[{Domain}], Name "Stored Energy", File StrCat[DirResFields, "We", ExtGmsh], LastTimeStepOnly ] ;
11+
// Print[ e, OnElementsOf Region[{Domain}], Name "Electric Field", File StrCat[DirResFields, "Efield", ExtGmsh], LastTimeStepOnly ] ;
12+
If (Flag_Stream_Visualization)
13+
Print[ Welocal, OnElementsOf Region[{Domain}], Name "Stored Energy", File StrCat[DirResFields, "We", ExtGmsh], LastTimeStepOnly ] ;
14+
EndIf
1115
Print[ MagE, OnElementsOf Region[{Domain}], Name "Magnitude Electric Field / V/m", File StrCat[DirResFields, "MagE", ExtGmsh], LastTimeStepOnly ] ;
1216

1317
// Displacement Field vector in the entire domain
14-
Print[ d, OnElementsOf Region[{Domain}], Name "Electric Field Density", File StrCat[DirResFields, "Dfield", ExtGmsh], LastTimeStepOnly ] ;
18+
// Print[ d, OnElementsOf Region[{Domain}], Name "Electric Field Density", File StrCat[DirResFields, "Dfield", ExtGmsh], LastTimeStepOnly ] ;
1519
Print[ MagD, OnElementsOf Region[{Domain}], Name "Magnitude Electric Field Density / C/m^2", File StrCat[DirResFields, "MagD", ExtGmsh], LastTimeStepOnly ] ;
1620

1721

1822
// Settings for visualization output (optional)
19-
Echo[ Str["View[PostProcessing.NbViews-1].Light=0;
20-
View[PostProcessing.NbViews-1].LineWidth = 2;
21-
View[PostProcessing.NbViews-1].RangeType=3;
22-
View[PostProcessing.NbViews-1].IntervalsType=1;
23-
View[PostProcessing.NbViews-1].NbIso = 25;"],
24-
File OptionPos];
23+
// The electric field and electric field density are shown in linear
24+
If (Flag_Stream_Visualization)
25+
Echo[ Str[
26+
"For k In {0:PostProcessing.NbViews-1}",
27+
" View[k].RangeType = 3;", // per timestep
28+
" View[k].NbIso = 40;",
29+
" View[k].IntervalsType= 3;",
30+
" View[k].AutoPosition = 3;",
31+
" If (!StrCmp(View[k].Name, 'Magnitude Electric Field / V/m'))",
32+
" View[k].ScaleType = 1;",
33+
" EndIf",
34+
" If (!StrCmp(View[k].Name, 'Magnitude Electric Field Density / C/m^2'))",
35+
" View[k].ScaleType = 1;",
36+
" EndIf",
37+
"EndFor"
38+
], File "option.pos"];
39+
EndIf
40+
2541
}

femmt/electro_magnetic/values_electrostatic.pro

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
PostOperation Get_global UsingPost EleSta {
22
// energy stored in air
3-
Print[ energy[Domain], OnGlobal, Format TimeTable, File > StrCat[DirResVals,"Energy_Stored_Component.dat"], LastTimeStepOnly, StoreInVariable $energy_Component];
4-
Print[ energy[Air], OnGlobal, Format TimeTable, File > StrCat[DirResVals,"Energy_Stored_Air.dat"], LastTimeStepOnly, StoreInVariable $energy_Air];
5-
Print[ energy[Core], OnGlobal, Format TimeTable, File > StrCat[DirResVals,"Energy_Stored_Core.dat"], LastTimeStepOnly, StoreInVariable $energy_Core];
3+
Print[ energy[Domain], OnGlobal, Format TimeTable, File > StrCat[DirResVals,"Energy_Stored_Component.dat"], LastTimeStepOnly, StoreInVariable $energy_Component
4+
, SendToServer StrCat[po,"10Total energy [J]"], Color "LightYellow"];
5+
Print[ energy[Air], OnGlobal, Format TimeTable, File > StrCat[DirResVals,"Energy_Stored_Air.dat"], LastTimeStepOnly, StoreInVariable $energy_Air
6+
, SendToServer StrCat[po,"11Energy (Air) [J]"], Color "LightYellow"];
7+
Print[ energy[Core], OnGlobal, Format TimeTable, File > StrCat[DirResVals,"Energy_Stored_Core.dat"], LastTimeStepOnly, StoreInVariable $energy_Core
8+
, SendToServer StrCat[po,"12Energy (Core) [J]"], Color "LightYellow"];
69
// Print[ energy[Insulation_bobbin], OnGlobal, Format TimeTable, File > StrCat[DirResVals,"Energy_Stored_bobbin.dat"], LastTimeStepOnly, StoreInVariable $energy_bobbin];
710
// Print[ energy[Insulation_cond], OnGlobal, Format TimeTable, File > StrCat[DirResVals,"Energy_Stored_Cond_insulation.dat"], LastTimeStepOnly, StoreInVariable $energy_cond_insulation];
811

912
// average voltage of the core
10-
Print[ Avg_Voltage_Core[Core], OnGlobal, Format TimeTable, File > StrCat[DirResCirc,"Avg_Core_voltage.dat"], LastTimeStepOnly, StoreInVariable $Avg_Voltage_Core];
13+
Print[ Avg_Voltage_Core[Core], OnGlobal, Format TimeTable, File > StrCat[DirResCirc,"Avg_Core_voltage.dat"], LastTimeStepOnly, StoreInVariable $Avg_Voltage_Core
14+
, SendToServer StrCat[po,"13Average Voltage on Core[V]"], Color "LightYellow"];
1115

1216
// Charges
13-
Print[ Charge[Air], OnGlobal, Format TimeTable, File > StrCat[DirResVals,"charge_Air.dat"], LastTimeStepOnly, StoreInVariable $Charge_Air];
14-
Print[ Charge[Core], OnGlobal, Format TimeTable, File > StrCat[DirResVals,"charge_Core.dat"], LastTimeStepOnly, StoreInVariable $Charge_Core];
17+
Print[ Charge[Air], OnGlobal, Format TimeTable, File > StrCat[DirResVals,"charge_Air.dat"], LastTimeStepOnly, StoreInVariable $Charge_Air
18+
, SendToServer StrCat[po,"14Charge (Air) [C]"], Color "LightYellow"];
19+
Print[ Charge[Core], OnGlobal, Format TimeTable, File > StrCat[DirResVals,"charge_Core.dat"], LastTimeStepOnly, StoreInVariable $Charge_Core
20+
, SendToServer StrCat[po,"15Charge (Core) [C]"], Color "LightYellow"];
1521
// voltage and charges on windings
1622
For n In {1:n_windings}
1723
Print[ U, OnRegion Winding~{n}, Format TimeTable, File > Sprintf[StrCat[DirResCirc,"U_%g.dat"], n] , LastTimeStepOnly];
@@ -28,9 +34,11 @@ PostOperation Get_global UsingPost EleSta {
2834
// Print charge for each turn in the winding
2935
For turn_number In {1:nbturns~{winding_number}}
3036
Print[ U, OnRegion Turn~{winding_number}~{turn_number}, Format TimeTable,
31-
File > Sprintf[StrCat[DirResCirc, "U_%g_%g.dat"], winding_number, turn_number], LastTimeStepOnly];
37+
File > Sprintf[StrCat[DirResCirc, "U_%g_%g.dat"], winding_number, turn_number], LastTimeStepOnly,
38+
SendToServer Sprintf[StrCat[po,"16U (Winding_%g_Turn_%g) [V]"], winding_number, turn_number], Color "LightYellow"];
3239
Print[ Q, OnRegion Turn~{winding_number}~{turn_number}, Format TimeTable,
33-
File > Sprintf[StrCat[DirResCirc, "Q_%g_%g.dat"], winding_number, turn_number], LastTimeStepOnly];
40+
File > Sprintf[StrCat[DirResCirc, "Q_%g_%g.dat"], winding_number, turn_number], LastTimeStepOnly,
41+
SendToServer Sprintf[StrCat[po,"17Q (Winding_%g_Turn_%g) [C]"], winding_number, turn_number], Color "LightYellow"];
3442
EndFor
3543
EndFor
3644

femmt/examples/basic_inductor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ def example_thermal_simulation(show_thermal_visual_outputs: bool = True, flag_in
185185
# example_thermal_simulation(show_visual_outputs, flag_insulation=True)
186186

187187
# Extract the capacitance of inductor component
188-
# geo.get_capacitance_of_inductor_component(show_fem_simulation_results=False)
188+
# geo.get_capacitance_of_inductor_component(show_equivalent_circuit=True)
189189
# geo.get_inductor_stray_capacitance(show_visual_outputs=True)
190190

191191

femmt/examples/basic_inductor_electrostatic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def basic_example_inductor_electrostatic(onelab_folder: str = None, show_visual_
3737

3838
# 1. chose simulation type
3939
geo = fmt.MagneticComponent(simulation_type=fmt.SimulationType.ElectroStatic, component_type=fmt.ComponentType.Inductor,
40-
working_directory=working_directory, is_gui=is_test)
40+
working_directory=working_directory, is_gui=is_test, visualization_mode=fmt.VisualizationMode.Final)
4141

4242
# This line is for automated pytest running on GitHub only. Please ignore this line!
4343
if onelab_folder is not None:

femmt/examples/basic_transformer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ def example_thermal_simulation(show_thermal_visual_outputs: bool = True, flag_in
171171
example_thermal_simulation(show_visual_outputs, flag_insulation=True)
172172
# geo.get_inductances(I0=10, op_frequency=100000, skin_mesh_factor=0.5)
173173
# Extract capacitance of transformer component
174-
# geo.get_capacitance_of_transformer()
174+
# geo.get_capacitance_of_transformer(show_equivalent_circuit=True)
175175

176176

177177
if __name__ == "__main__":

femmt/examples/basic_transformer_electrostatic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def basic_example_transformer_electrostatic(onelab_folder: str = None, show_visu
3636

3737
# 1. chose simulation type
3838
geo = fmt.MagneticComponent(simulation_type=fmt.SimulationType.ElectroStatic, component_type=fmt.ComponentType.Transformer,
39-
working_directory=working_directory, is_gui=is_test)
39+
working_directory=working_directory, is_gui=is_test, visualization_mode=fmt.VisualizationMode.Final)
4040

4141
# This line is for automated pytest running on GitHub only. Please ignore this line!
4242
if onelab_folder is not None:

0 commit comments

Comments
 (0)