Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asaf branch #55

Merged
merged 12 commits into from
Oct 23, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@
}
],
"source": [
"ℰ_total = eprh.calc_energy_electric(volume='AllObjects')\n",
"ℰ_substr = eprh.calc_energy_electric(volume='substrate')\n",
"ℰ_total = eprh.calc_energy_electric(obj='AllObjects')\n",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good change

"ℰ_substr = eprh.calc_energy_electric(obj='substrate')\n",
"print(f'Energy in substrate = {100*ℰ_substr/ℰ_total:.1f}%')"
]
},
Expand Down Expand Up @@ -513,4 +513,4 @@
},
"nbformat": 4,
"nbformat_minor": 4
}
}
102 changes: 67 additions & 35 deletions pyEPR/core_distributed_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,18 +233,18 @@ def setup_data(self):
if not self.data_dir.is_dir():
self.data_dir.mkdir(parents=True, exist_ok=True)

def calc_p_junction_single(self, mode, variation, U_E = None, U_H = None):
def calc_p_junction_single(self, mode, variation, U_E=None, U_H=None):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good formatting

'''
This function is used in the case of a single junction only.
For multiple junctions, see `calc_p_junction`.

Assumes no lumped capacitive elements.
'''
if U_E == None:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good check update

if U_E is None:
U_E = self.calc_energy_electric(variation)
if U_H == None:
if U_H is None:
U_H = self.calc_energy_magnetic(variation)

pj = OrderedDict()
pj_val = (U_E-U_H)/U_E
pj['pj_'+str(mode)] = np.abs(pj_val)
Expand Down Expand Up @@ -445,7 +445,7 @@ def get_nominal_variation_index(self):
"""
try:
return str(self._list_variations.index(self._nominal_variation))
except:
except Exception:
print('WARNING: Unsure of the index, returning 0')
return '0'

Expand Down Expand Up @@ -555,8 +555,10 @@ def get_variable_vs_variations(self, variable: str, convert: bool = True):

def calc_energy_electric(self,
variation: str = None,
volume: str = 'AllObjects',
smooth: bool = False):
obj: str = 'AllObjects',
volume: str = 'Deprecated',
smooth: bool = False,
obj_dims: int = 3):
r'''
Calculates two times the peak electric energy, or 4 times the RMS,
:math:`4*\mathcal{E}_{\mathrm{elec}}`
Expand All @@ -568,20 +570,24 @@ def calc_energy_electric(self,
Args:
variation (str): A string identifier of the variation,
such as '0', '1', ...
volume (string | 'AllObjects'): Name of the volume to integrate over
obj (string | 'AllObjects'): Name of the object to integrate over
smooth (bool | False) : Smooth the electric field or not when performing calculation
obj_dims (int | 3) : 1 - line, 2 - surface, 3 - volume. Default volume

Example:
Example use to calcualte the energy participation ratio (EPR) of a substrate

.. code-block:: python
:linenos:

ℰ_total = epr_hfss.calc_energy_electric(volume='AllObjects')
ℰ_substr = epr_hfss.calc_energy_electric(volume='Box1')
ℰ_total = epr_hfss.calc_energy_electric(obj='AllObjects')
ℰ_substr = epr_hfss.calc_energy_electric(obj='Box1')
print(f'Energy in substrate = {100*ℰ_substr/ℰ_total:.1f}%')

'''
if volume != 'Deprecated':
logger.warning('The use of the "volume" argument is deprecated... use "obj" instead')
obj = volume

calcobject = CalcObject([], self.setup)

Expand All @@ -592,15 +598,26 @@ def calc_energy_electric(self,
B = vecE.conj()
A = A.dot(B)
A = A.real()
A = A.integrate_vol(name=volume)

if obj_dims == 1:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice

A = A.integrate_line(name=obj)
elif obj_dims == 2:
A = A.integrate_surf(name=obj)
elif obj_dims == 3:
A = A.integrate_vol(name=obj)
else:
logger.warning('Invalid object dimensions %s, using default of 3 (volume)' % obj_dims)
A = A.integrate_vol(name=obj)

lv = self._get_lv(variation)
return A.evaluate(lv=lv)

def calc_energy_magnetic(self,
variation=None,
volume='AllObjects',
smooth=True):
variation: str = None,
obj: str = 'AllObjects',
volume: str = 'Deprecated',
smooth: bool = False,
obj_dims: int = 3):
'''
See calc_energy_electric.

Expand All @@ -609,7 +626,11 @@ def calc_energy_magnetic(self,
such as '0', '1', ...
volume (string | 'AllObjects'): Name of the volume to integrate over
smooth (bool | False) : Smooth the electric field or not when performing calculation
obj_dims (int | 3) : 1 - line, 2 - surface, 3 - volume. Default volume
'''
if volume != 'Deprecated':
logger.warning('The use of the "volume" argument is deprecated... use "obj" instead')
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice

obj = volume

calcobject = CalcObject([], self.setup)

Expand All @@ -620,7 +641,16 @@ def calc_energy_magnetic(self,
B = vecH.conj()
A = A.dot(B)
A = A.real()
A = A.integrate_vol(name=volume)

if obj_dims == 1:
A = A.integrate_line(name=obj)
elif obj_dims == 2:
A = A.integrate_surf(name=obj)
elif obj_dims == 3:
A = A.integrate_vol(name=obj)
else:
logger.warn(f'Invalid object dimensions {obj_dims}, using default of 3 (volume)')
A = A.integrate_vol(name=obj)

lv = self._get_lv(variation)
return A.evaluate(lv=lv)
Expand All @@ -647,12 +677,12 @@ def calc_p_electric_volume(self,

if E_total is None:
logger.debug('Calculating ℰ_total')
ℰ_total = self.calc_energy_electric(volume=relative_to)
ℰ_total = self.calc_energy_electric(obj=relative_to)
else:
ℰ_total = E_total

logger.debug('Calculating ℰ_object')
ℰ_object = self.calc_energy_electric(volume=name_dielectric3D)
ℰ_object = self.calc_energy_electric(obj=name_dielectric3D)

return ℰ_object/ℰ_total, (ℰ_object, ℰ_total)

Expand Down Expand Up @@ -694,7 +724,8 @@ def calc_avg_current_J_surf_mag(self, variation: str, junc_rect: str, junc_line)
# self.design.Clear_Field_Clac_Stack()
return I

def calc_current_using_line_voltage(self, variation: str, junc_line_name: str, junc_L_Henries: float, Cj_Farads: float = None):
def calc_current_using_line_voltage(self, variation: str, junc_line_name: str,
junc_L_Henries: float, Cj_Farads: float = None):
'''
Peak current I_max for prespecified mode calculating line voltage across junction.

Expand Down Expand Up @@ -766,20 +797,22 @@ def get_junc_len_dir(self, variation: str, junc_line):
uj = [float(u[0]/jl), float(u[1]/jl), float(u[2]/jl)]
return jl, uj

def get_Qseam(self, seam, mode, variation, U_H = None):
def get_Qseam(self, seam, mode, variation, U_H=None):
r'''
Caculate the contribution to Q of a seam, by integrating the current in
the seam with finite conductance: set in the config file
ref: http://arxiv.org/pdf/1509.01119.pdf
'''
if U_H == None:

if U_H is None:
U_H = self.calc_energy_magnetic(variation)


_, freqs_bare_vals = self.get_freqs_bare(variation)
self.omega = 2*np.pi*freqs_bare_vals[mode]

lv = self._get_lv(variation)
Qseam = OrderedDict()
print('Calculating Qseam_' + seam + ' for mode ' + str(mode) +
' (' + str(mode) + '/' + str(self.n_modes-1) + ')')
print(f'Calculating Qseam_{seam} for mode {mode} ({mode}/{self.n_modes-1})')
# overestimating the loss by taking norm2 of j, rather than jperp**2
j_2_norm = self.fields.Vector_Jsurf.norm_2()
int_j_2 = j_2_norm.integrate_line(seam)
Expand All @@ -789,22 +822,21 @@ def get_Qseam(self, seam, mode, variation, U_H = None):
Qseam['Qseam_'+seam+'_' +
str(mode)] = config.dissipation.gseam/yseam

print('Qseam_' + seam + '_' + str(mode) + str(' = ') +
str(config.dissipation.gseam/config.dissipation.yseam))
print('Qseam_' + seam + '_' + str(mode), '=', str(config.dissipation.gseam/yseam))

return pd.Series(Qseam)

def get_Qseam_sweep(self, seam, mode, variation, variable, values, unit, U_H = None, pltresult=True):
def get_Qseam_sweep(self, seam, mode, variation, variable, values, unit, U_H=None, pltresult=True):
"""
Q due to seam loss.

values = ['5mm','6mm','7mm']
ref: http://arxiv.org/pdf/1509.01119.pdf
"""

if U_H == None:
if U_H is None:
U_H = self.calc_energy_(variation)

self.solutions.set_mode(mode+1, 0)
self.fields = self.setup.get_fields()
freqs_bare_dict, freqs_bare_vals = self.get_freqs_bare(variation)
Expand Down Expand Up @@ -838,14 +870,14 @@ def get_Qseam_sweep(self, seam, mode, variation, variable, values, unit, U_H = N

return Qseamsweep

def get_Qdielectric(self, dielectric, mode, variation, U_E = None):
if U_E == None:
def get_Qdielectric(self, dielectric, mode, variation, U_E=None):
if U_E is None:
U_E = self.calc_energy_electric(variation)
Qdielectric = OrderedDict()
print('Calculating Qdielectric_' + dielectric + ' for mode ' +
str(mode) + ' (' + str(mode) + '/' + str(self.n_modes-1) + ')')

U_dielectric = self.calc_energy_electric(variation, volume=dielectric)
U_dielectric = self.calc_energy_electric(variation, obj=dielectric)
p_dielectric = U_dielectric/U_E
# TODO: Update make p saved sep. and get Q for diff materials, indep. specify in pinfo
Qdielectric['Qdielectric_'+dielectric+'_' +
Expand All @@ -854,13 +886,13 @@ def get_Qdielectric(self, dielectric, mode, variation, U_E = None):
str(mode)+' = ' + str(p_dielectric))
return pd.Series(Qdielectric)

def get_Qsurface_all(self, mode, variation, U_E = None):
def get_Qsurface_all(self, mode, variation, U_E=None):
'''
caculate the contribution to Q of a dieletric layer of dirt on all surfaces
set the dirt thickness and loss tangent in the config file
ref: http://arxiv.org/pdf/1509.01854.pdf
'''
if U_E == None:
if U_E is None:
U_E = self.calc_energy_electric(variation)
lv = self._get_lv(variation)
Qsurf = OrderedDict()
Expand Down Expand Up @@ -893,7 +925,7 @@ def calc_Q_external(self, variation, freq_GHz, U_E = None):
variation (str): A string identifier of the variation,
such as '0', '1', ...
'''
if U_E == None:
if U_E is None:
U_E = self.calc_energy_electric(variation)
Qp = pd.Series({})

Expand Down
Loading