class DC_Phase_ModModel(i3.CompactModel): parameters = [ 'length', 'n_eff', 'n_g', 'center_wavelength', 'VpiLpi', 'loss_dB_m' ] #VpiLpi = 1.2 V.cm states = [] terms = [ i3.OpticalTerm(name='in'), i3.OpticalTerm(name='out'), i3.ElectricalTerm(name='elec1'), i3.ElectricalTerm(name='elec2'), ] def calculate_smatrix(parameters, env, S): pass # reflexion def calculate_signals(parameters, env, output_signals, y, t, input_signals): v_diff = input_signals['elec2'] - input_signals['elec1'] dneff = -(parameters.n_g - parameters.n_eff) / parameters.center_wavelength n_eff_final = parameters.n_eff + (env.wavelength - parameters.center_wavelength) * dneff length_m = parameters.length * 1e-6 length_cm = parameters.length * 1e-4 # 1e-4: from um to cm phase = 2 * pi * n_eff_final / env.wavelength * parameters.length + pi * ( v_diff * length_cm) / parameters.VpiLpi amp = 10**(-parameters.loss_dB_m * length_m / 20.) output_signals['in'] = amp * exp(1j * phase) * input_signals['out'] output_signals['out'] = amp * exp(1j * phase) * input_signals['in']
class PhotoDetectorCompactModel(i3.CompactModel): """Simple photodetector model. """ parameters = ['R', 'BW', 'reflection_dB', 'dark_current'] terms = [ i3.OpticalTerm(name='in'), i3.ElectricalTerm(name='anode'), i3.ElectricalTerm(name='cathode') ] states = ['current'] def calculate_smatrix(parameters, env, S): S['in', 'in'] = 10.**(-parameters.reflection_dB / 20.) def calculate_signals(parameters, env, output_signals, y, t, input_signals): output_signals['anode'] = y['current'] + parameters.dark_current * 1e-9 output_signals['cathode'] = -output_signals['anode'] def calculate_dydt(parameters, env, dydt, y, t, input_signals): dydt['current'] = parameters.BW * 1e9 * ( parameters.R * (abs(input_signals['in'])**2) - y['current'])
def _generate_terms(self, terms): # Calling super() to inherit terms from non-connected subblocks (i.e., splitter optical input term and combiner optical output term) super(PlaceAndAutoRoute.Netlist, self)._generate_terms(terms) for i in range(5): terms['elec_left_{}'.format(i + 1)] = i3.ElectricalTerm( name='elec_left_{}'.format(i + 1)) terms['elec_right_{}'.format(i + 1)] = i3.ElectricalTerm( name='elec_right_{}'.format(i + 1)) return terms
class MZMLumpedCompactModel(i3.CompactModel): """Lumped model for a MZM with - Insertion Loss - VpiLpi Only 'elec_left_2' (bottom arm) and 'elect_left_4' (top arm) are taken into account for the electrical signals ! """ parameters = [ 'n_eff', 'delay', 'length', 'insertion_loss_dB', 'VpiLpi', ] terms = [ i3.OpticalTerm(name='in'), i3.OpticalTerm(name='out'), ] terms += [ i3.ElectricalTerm(name='elec_left_{}'.format(_ + 1)) for _ in range(5) ] terms += [ i3.ElectricalTerm(name='elec_right_{}'.format(_ + 1)) for _ in range(5) ] def calculate_smatrix(parameters, env, S): t = 10**(-parameters.insertion_loss_dB / 20.) delay_phase = parameters.n_eff * abs(parameters.delay) / env.wavelength S['in', 'out'] = S['out', 'in'] = t * exp(1j * delay_phase) def calculate_signals(parameters, env, output_signals, y, t, input_signals): t = 10**(-parameters.insertion_loss_dB / 20.) delay_phase = parameters.n_eff * abs(parameters.delay) / env.wavelength phase_arm1 = ( 2 * pi * (delay_phase if (parameters.delay < 0) else 0) + pi * (input_signals['elec_left_2'] * parameters.length * 1e-4) / parameters.VpiLpi) phase_arm2 = ( 2 * pi * (delay_phase if (parameters.delay > 0) else 0) + pi * (input_signals['elec_left_4'] * parameters.length * 1e-4) / parameters.VpiLpi) output_signals['out'] = t / 2. * input_signals['in'] * ( exp(1j * phase_arm1) + exp(1j * phase_arm2)) output_signals['in'] = t / 2. * input_signals['out'] * ( exp(1j * phase_arm1) + exp(1j * phase_arm2))
def _generate_terms(self, terms): terms += i3.ElectricalTerm(name='in') terms += i3.OpticalTerm(name='out') return terms