diff --git a/pyEPR/_config_user.py b/pyEPR/_config_user.py index 0ed2961..932bcd9 100644 --- a/pyEPR/_config_user.py +++ b/pyEPR/_config_user.py @@ -49,6 +49,22 @@ # units: unitless, since this is tan(delta) tan_delta_surf=1e-3, + ################################################## + # Surface object specific dielectric properties. + # These will override ones above when applicable + dielectric_surfaces=Dict( + trace=Dict( + tan_delta_surf=0.001, + th=5e-9, + eps_r=10 + ), + gap=Dict( + tan_delta_surf=0.001, + th=2e-9, + eps_r=10 + ) + ), + ################################################## # Thin-film surface loss # units: Ohms diff --git a/pyEPR/core_distributed_analysis.py b/pyEPR/core_distributed_analysis.py index ab3f7b1..2013210 100644 --- a/pyEPR/core_distributed_analysis.py +++ b/pyEPR/core_distributed_analysis.py @@ -878,13 +878,11 @@ def get_Qdielectric(self, dielectric, mode, variation, U_E=None): 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+'_' + - str(mode)] = 1/(p_dielectric*config.dissipation.tan_delta_sapp) - print('p_dielectric'+'_'+dielectric+'_' + - str(mode)+' = ' + str(p_dielectric)) + Qdielectric['Qdielectric_' + dielectric] = 1/(p_dielectric*config.dissipation.tan_delta_sapp) + print('p_dielectric'+'_'+dielectric+'_' + str(mode) + ' = ' + str(p_dielectric)) return pd.Series(Qdielectric) - def get_Qsurface(self, mode, variation, name, U_E=None): + def get_Qsurface(self, mode, variation, name, U_E=None, material_properties=None): ''' Calculate the contribution to Q of a dielectric layer of dirt on a given surface. Set the dirt thickness and loss tangent in the config file @@ -892,10 +890,15 @@ def get_Qsurface(self, mode, variation, name, U_E=None): ''' if U_E is None: U_E = self.calc_energy_electric(variation) + if material_properties is None: + material_properties = {} + th = material_properties.get('th', config.dissipation.th) + eps_r = material_properties.get('eps_r', config.dissipation.eps_r) + tan_delta_surf = material_properties.get('tan_delta_surf', config.dissipation.tan_delta_surf) + lv = self._get_lv(variation) Qsurf = OrderedDict() - print('Calculating Qsurface for mode ' + str(mode) + - ' (' + str(mode) + '/' + str(self.n_modes-1) + ')') + print(f'Calculating Qsurface {name} for mode ({mode}/{self.n_modes-1})') calcobject = CalcObject([], self.setup) vecE = calcobject.getQty("E") A = vecE @@ -904,11 +907,10 @@ def get_Qsurface(self, mode, variation, name, U_E=None): A = A.real() A = A.integrate_surf(name=name) U_surf = A.evaluate(lv=lv) - U_surf *= config.dissipation.th*epsilon_0*config.dissipation.eps_r + U_surf *= th * epsilon_0 * eps_r p_surf = U_surf/U_E - Qsurf['Qsurf_'+str(mode)] = 1 / \ - (p_surf*config.dissipation.tan_delta_surf) - print('p_surf'+'_'+str(mode)+' = ' + str(p_surf)) + Qsurf[f'Qsurf_{name}'] = 1 / (p_surf * tan_delta_surf) + print(f'p_surf_{name}_{mode} = {p_surf}') return pd.Series(Qsurf) def get_Qsurface_all(self, mode, variation, U_E=None): @@ -1308,17 +1310,15 @@ def do_EPR_analysis(self, dielectric, mode, variation, self.U_E)) # get Q surface - if self.pinfo.dissipative['resistive_surfaces']: - if self.pinfo.dissipative['resistive_surfaces'] == 'all': + if self.pinfo.dissipative['dielectric_surfaces']: + if self.pinfo.dissipative['dielectric_surfaces'] == 'all': sol = sol.append( self.get_Qsurface_all(mode, variation, self.U_E)) else: - raise NotImplementedError( - "Join the team, by helping contribute this piece of code.") - - if self.pinfo.dissipative['resistive_surfaces'] is not None: - raise NotImplementedError( - "Join the team, by helping contribute this piece of code.") + for surface, properties in self.pinfo.dissipative['dielectric_surfaces'].items(): + sol = sol.append( + self.get_Qsurface(mode, variation, surface, self.U_E, properties) + ) SOL[mode] = sol diff --git a/pyEPR/core_quantum_analysis.py b/pyEPR/core_quantum_analysis.py index 9adc18b..3b9b5af 100644 --- a/pyEPR/core_quantum_analysis.py +++ b/pyEPR/core_quantum_analysis.py @@ -52,7 +52,7 @@ class HamiltonianResultsContainer(OrderedDict): def __init__(self, dict_file=None, data_dir=None): """ input: - dict file - 1. ethier None to create an empty results hamiltonian as + dict file - 1. either None to create an empty results hamiltonian as as was done in the original code 2. or a string with the name of the file where the file of the @@ -711,12 +711,15 @@ def analyze_variation(self, try: result['Q_coupling'] = self.Qm_coupling[variation][self.Qm_coupling[variation].columns[junctions]][modes]#TODO change the columns to junctions except: - result['Q_coupling'] = self.Qm_coupling[variation] + result['Q_coupling'] = self.Qm_coupling[variation] try: result['Qs'] = self.Qs[variation][self.PM[variation].columns[junctions]][modes] #TODO change the columns to junctions except: - result['Qs'] = self.Qs[variation][modes] + result['Qs'] = self.Qs[variation][modes] + + result['sol'] = self.sols[variation] + result['fock_trunc'] = fock_trunc result['cos_trunc'] = cos_trunc @@ -733,7 +736,8 @@ def analyze_variation(self, def full_report_variations(self, var_list: list=None): """see full_variation_report""" - if var_list is None: var_list =self.variations + if var_list is None: + var_list = self.variations for variation in var_list: self.full_variation_report(variation) diff --git a/pyEPR/project_info.py b/pyEPR/project_info.py index 3d20395..f6757dd 100644 --- a/pyEPR/project_info.py +++ b/pyEPR/project_info.py @@ -120,10 +120,12 @@ def __setitem__(self, key, value): # --- check valid inputs --- if not (key in diss_opt or key == 'pinfo'): raise ValueError(f"No such parameter {key}") - if key != 'pinfo' and (not isinstance(value, list) or \ + if key != 'pinfo' and (not isinstance(value, (list, dict)) or \ not all(isinstance(x, str) for x in value)) and (value != None): raise ValueError(f'dissipative[\'{key}\'] must be a list of strings ' \ - 'containing names of models in the project!') + 'containing names of models in the project or dictionary of strings of models containing ' \ + 'material loss properties!' + ) if key != 'pinfo' and hasattr(self['pinfo'], 'design'): for x in value: if x not in self['pinfo'].get_all_object_names():