Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

rfmatch.annotated.cc

Go to the documentation of this file.
00001 // rfmatch.cc
00002 
00003 // This program performs a modest analysis of an SIS receiver using
00004 // purely linear circuit analysis in the same way as earlier tools
00005 // like pcircuit. It simulates superconducting microstrip RF
00006 // circuitry and evaluates its matching characteristics into a fixed
00007 // load representing the SIS junction:
00008 
00009 // Create the RF circuit for 1/2 of a twinslot, quasioptical SIS
00010 // mixer. Analyze its frequency response for matching into an SIS
00011 // junction with specified physical characteristics.
00012 //
00013 // The circuit will be modelled as follows:
00014 //
00015 // RF     ---     ---     ---     ---   branch    ---     ---      short
00016 // IN o--|   |---|   |---|   |---|   |-----+-----|   |---|   |---+   to
00017 //        ---     ---     ---     ---      |      ---     ---    | ground
00018 //      antenna   rf_1    rf_2   tune_2    o    sis_cap  tune_1  V
00019 //                                        OUT
00020 //                                    (into SIS Rn)
00021 //
00022 // Below each element is the name of the object representing it in the
00023 // program code below. The SIS junction is represented in a purely linear
00024 // fashion as a parallel RC combination. The power coupled into the R of
00025 // the RC is what we determine in this program.
00026 
00027 #include "supermix.h"
00028 
00029 // ==========================================================================
00030 // THE PHYSICAL SPECIFICATIONS OF THE RF CIRCUIT:
00031 
00032 // THE CHARACTERISTICS OF THE SUPERCONDUCTING FILMS
00033 //   Here we just create a new class to hold the relevant physical
00034 //   parameters needed. We immediately declare two objects of the
00035 //   class, holding the relevant numbers for Noibium and NbTiN.
00036 //
00037 //   The member variables of the class are of type parameter, so
00038 //   they could be controlled by the optimizer, if desired. See
00039 //   lna/lna_opt.cc for details.
00040 //
00041 //   Notice how we can initialize the member variables in simple
00042 //   classes like this one.
00043 struct sc_material { parameter Vgap, Tc, rho_normal; }
00044   nb    = { 2.9*mVolt,  9.20*Kelvin,  5.0*Micro*Ohm*Centi*Meter },
00045   nbtin = { 5.0*mVolt, 15.75*Kelvin, 30.0*Micro*Ohm*Centi*Meter };
00046 
00047 // THE WIDTHS AND LENGTHS OF THE MICROSTRIPS
00048 //   Another newly-created class, this time to hold the dimensions
00049 //   of the individual microstrip circuit elements.
00050 struct wl { parameter width, length; }
00051   RF1  = { 5.8*Micron, 11.2*Micron },   // transformer section 1 (nearest antenna)
00052   RF2  = { 3.3*Micron, 15.0*Micron },   // transformer section 2
00053   L1   = { 5.0*Micron,  6.9*Micron/2 }, // tuning inductor from SIS to virtual ground
00054   L2   = { 5.0*Micron,  2.5*Micron };   // tuning inductor between transformer and SIS
00055 
00056 //   We don't need new classes to hold the remaining info; we'll
00057 //   just use parameters.
00058 
00059 // THE LAYER THICKNESSES
00060 parameter
00061   GP_THICKNESS   = 3000.*Angstrom,      // ground plane superconductor thickness
00062   TOP_THICKNESS  = 3000.*Angstrom,      // top strip superconductor thickness
00063   SIO_THICKNESS  = 4500.*Angstrom,      // SiO layer generally
00064   TUNE_THICKNESS = 2500.*Angstrom;      // SiO in tuning inductor
00065 
00066 // SIS JUNCTION PARAMETERS
00067 parameter
00068   RNA  = 21.8*Ohm*Micron*Micron,        // normal resistance - area product
00069   SCAP = 82.0*fFarad/Micron/Micron,     // specific capacitance (per area)
00070   AREA = 1.2*1.2*Micron*Micron;         // effective junction area
00071 
00072 // THE FILE NAME FOR THE ANTENNA IMPEDANCE INFORMATION
00073 const char * const ANT_FILE = "Zslot.750";
00074 
00075 
00076 // ==========================================================================
00077 // CLASSES WHICH ACTUALLY CALCULATE THE SIS RN AND CAPACITANCE:
00078 
00079 //   The SIS junction objects in supermix want to know the actual normal
00080 //   resistance and capacitance of a junction. Since the SIS objects hold
00081 //   this information in parameters, they can be set to shadow other
00082 //   parameter-like variables (objects of type abstract_real_parameter).
00083 //   See parameter/real_parameter.h and parameter/abstract_real_parameter.h
00084 //   for further details. Here we create two objects each with their own
00085 //   unique class. Each one will act just like a double in equations, with
00086 //   the additional feature of being shadowable by other parameters.
00087 //
00088 //   To qualify as an abstract_real_parameter, an object must define the get()
00089 //   member function, which returns its value.
00090 //
00091 //   Note that we use "struct" instead of "class" in the type definitions. This
00092 //   just ensures that all members of a class object are public (accessible). 
00093 
00094 // Rn, THE NORMAL RESISTANCE:
00095 struct calc_Rn : public abstract_real_parameter {
00096   double get() const { return RNA/AREA; }
00097 } Rn;
00098 
00099 // Cap, THE JUNCTION CAPACITANCE:
00100 struct calc_Cap : public abstract_real_parameter {
00101   double get() const { return SCAP*AREA; }
00102 } Cap;
00103 
00104 
00105 // ==========================================================================
00106 // With the global definitions out of the way, we start the main routine:
00107 int main()
00108 {
00109   // SET THE GLOBAL TEMPERATURE AND NORMALIZATION IMPEDANCE
00110   //   See how we use our newly created type calc_Rn. device::Z0 is of type
00111   //   parameter, so it can "shadow" another parameter-like variable if
00112   //   assigned its address (the purpose of the '&'). When device::Z0 is
00113   //   asked for its value, it in turn asks Rn's value by calling Rn.get().
00114   //   Rn then asks RNA and AREA for their values before calculating their
00115   //   ratio. Consequently, if the program changes either RNA or AREA,
00116   //   subsequent accesses of device::Z0 will return a different result.
00117   //   Since device::Z0 determines the normalizing impedance for S matrix
00118   //   calculations, changes to RNA or AREA will have wide-ranging effects.
00119   device::T  = 4.2*Kelvin;
00120   device::Z0 = & Rn;       // we use the SIS Rn as our normalizing impedance
00121 
00122 
00123   // CREATE THE SUPERCONDUCTING FILMS AND THE DIELECTRIC MATERIALS
00124   //   See surfaceZ.h for a description of super_film, which is derived from
00125   //   type surfimp. super_film will calculate its surface impedance by
00126   //   first building an interpolation table, greatly speeding up repeated
00127   //   accesses. The interpolation table is dynamically extended in range
00128   //   as required, so its use is transparent to the user.
00129   //
00130   //   Dielectrics are defined in trlines.h. We use type const_diel, which
00131   //   uses two parameters to hold its characteristics: a dielectric constant
00132   //   and a loss tangent.
00133 
00134   // The top film is Niobium.
00135   super_film top;
00136     top.Vgap       = & nb.Vgap;
00137     top.Tc         = & nb.Tc; 
00138     top.rho_normal = & nb.rho_normal;
00139     top.Thick      = & TOP_THICKNESS;
00140 
00141   // The groundplane is NbTiN.
00142   super_film gp;
00143     gp.Vgap        = & nbtin.Vgap;
00144     gp.Tc          = & nbtin.Tc; 
00145     gp.rho_normal  = & nbtin.rho_normal;
00146     gp.Thick       = & GP_THICKNESS;
00147 
00148   // Air is the dielectric above the microstrips; we just treat it as vacuum.
00149   const_diel air;
00150     air.eps  = 1.0;
00151     air.tand = 0.0;
00152 
00153   // SiO is the dielectric between the strip and the groundplane.
00154   const_diel sio;
00155     sio.eps  = 5.6;
00156     sio.tand = 0.0;
00157 
00158 
00159   // CREATE THE MICROSTRIPS USING THE ABOVE MATERIALS
00160   //   class microstrip is defined in trlines.h. It requires materials,
00161   //   dimensions, and the dielectric layer thickness.
00162 
00163   // For convenience, we first create a generic microstrip using our materials.
00164   microstrip ms;
00165     ms.ground_plane(gp);
00166     ms.substrate(sio);
00167     ms.top_strip(top);
00168     ms.superstrate(air);
00169 
00170   // Now the ones we actually use, copying the generic one. We must assign
00171   // dimensions as well.
00172 
00173   // rf_1 and rf_2 make up the matching transformer between the antenna and
00174   // the SIS junction. rf_1 will be connected to the antenna.
00175   microstrip rf_1(ms);
00176     rf_1.width     = & RF1.width;
00177     rf_1.length    = & RF1.length;
00178     rf_1.sub_thick = & SIO_THICKNESS;
00179   microstrip rf_2(ms);
00180     rf_2.width     = & RF2.width;
00181     rf_2.length    = & RF2.length;
00182     rf_2.sub_thick = & SIO_THICKNESS;
00183 
00184   // tune_1 is the inductance which tunes out the SIS junction capacitance.
00185   // Since there is a virtual ground midway between the two halves of the
00186   // twinslot receiver, we use only 1/2 of the total tuning length. tune_2
00187   // is the bit between the SIS and the RF matching transformer.
00188   microstrip tune_1(ms);
00189     tune_1.width     = & L1.width;
00190     tune_1.length    = & L1.length;
00191     tune_1.sub_thick = & TUNE_THICKNESS;
00192   microstrip tune_2(ms);
00193     tune_2.width     = & L2.width;
00194     tune_2.length    = & L2.length;
00195     tune_2.sub_thick = & TUNE_THICKNESS;
00196 
00197 
00198   // CREATE THE ANTENNA
00199   //   The antenna will be modelled as a transformer, transforming the
00200   //   normalizing impedance device::Z0 to the antenna embedding impedance
00201   //   given by the file named in ANT_FILE. We use an interpolation of the
00202   //   file's complex impedance vs. frequency data, employing a variable of
00203   //   type complex_interp (defined in complex_interp.h). The interpolation
00204   //   will return the complex impedance at the current frequency stored in
00205   //   the global frequency variable device::f. We also must supply the
00206   //   units used in the file (GHz and Ohm). 
00207   //
00208   //   The definition of a transformer is in transformer.h. We set the
00209   //   impedance of port 2 (Z2) to shadow the interpolation of the
00210   //   antenna impedance. The other port's impedance will shadow device::Z0
00211   //   by default. This shadowing works because the transformer's impedances
00212   //   are held in variables of type complex_parameter
00213   //   (parameter/complex_parameter.h) and a complex_interp is derived from
00214   //   abstract_complex_parameter. Shadowing works the same way as for the
00215   //   real_parameter types.
00216   complex_interp Z_ant(device::f, ANT_FILE, GHz, Ohm);
00217   transformer antenna;
00218     antenna.Z2 = & Z_ant;
00219 
00220 
00221   // A CAPACITOR TO MODEL THE SIS JUNCTION
00222   //   The SIS junction's capacitance is modelled here using a lumped-element
00223   //   capacitor (see elements.h) with a value calculated using the special
00224   //   calc_Cap class we defined previously.
00225   capacitor sis_cap;
00226     sis_cap.parallel();
00227     sis_cap.C = & Cap;   // shadows our junction capacitance calculator
00228 
00229 
00230   // BUILD THE COMPLETE RF CIRCUIT MODEL
00231   //   We'll create the branch and short that we need as well (see elements.h).
00232   //   Refer to the comments in filter/filter.annotated.cc for a description of
00233   //   code similar to that below.
00234 
00235   branch tee;
00236   short_term ground;
00237 
00238   circuit rf;
00239     rf.connect( antenna, 2,  rf_1,    1 );
00240     rf.connect( rf_1,    2,  rf_2,    1 );
00241     rf.connect( rf_2,    2,  tune_2,  1 );
00242     rf.connect( tune_2,  2,  tee,     1 );
00243     rf.connect( tee,     2,  sis_cap, 1 );
00244     rf.connect( sis_cap, 2,  tune_1,  1 );
00245     rf.connect( tune_1,  2,  ground,  1 );
00246 
00247   int input  = rf.add_port( antenna, 1 );    // RF power input to antenna
00248   int output = rf.add_port( tee,     3 );    // power output into SIS resistance
00249 
00250 
00251   // ==========================================================================
00252   // PERFORM THE CALCULATION AND OUTPUT THE RESULTS
00253 
00254   // Again refer to the comments in filter/filter.annotated.cc for a description.
00255 
00256   cout << fixed << setprecision(3);
00257   cout << "# 750 GHz Twinslot RF Match, antenna -> SIS" << endl;
00258   cout << "# SIS Rn (Ohm): " << Rn/Ohm << " ; SIS Cap (fF): " << Cap/fFarad << endl;
00259   cout << "#" << endl;
00260   cout << "# F(THz)" << "\t" << "S21" << "\t" << "Phase" << endl;
00261 
00262   complex::out_degree();
00263   complex::out_separator("\t");
00264   
00265   for(double f = 300.0; f <= 1500.0; f += 1.0)  {
00266     device::f = f*GHz;
00267     sdata response = rf.get_data();
00268     complex S21 = response.S[output][input];
00269     cout << "   " << device::f/(1000*GHz)<< "\t" << S21 << endl;
00270   }
00271 
00272 }

Please direct comments and corrections to supermix@submm.caltech.edu
Go to the supermix home page
Generated by doxygen1.2.7