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

mixer.h

Go to the documentation of this file.
00001 // SuperMix version 1.0  C++ source file
00002 //
00003 // Copyright (c) 1999 California Institute of Technology.
00004 // All rights reserved.
00005 //
00006 // Redistribution and use in source and binary forms for noncommercial
00007 // purposes are permitted provided that the above copyright notice and
00008 // this paragraph are duplicated in all such forms and that any
00009 // documentation and other materials related to such distribution and
00010 // use acknowledge that the software was developed by California
00011 // Institute of Technology. Redistribution and/or use in source or
00012 // binary forms is not permitted for any commercial purpose. Use of
00013 // this software does not include a permitted use of the Institute's
00014 // name or trademark for any purpose.
00015 //
00016 // DISCLAIMER:
00017 // THIS SOFTWARE AND/OR RELATED MATERIALS ARE PROVIDED "AS-IS" WITHOUT
00018 // WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR
00019 // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE (AS SET
00020 // FORTH IN UCC 23212-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
00021 // LICENSED PRODUCT, HOWEVER USED.  IN NO EVENT SHALL CALTECH/JPL BE
00022 // LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING BUT NOT LIMITED TO
00023 // INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, INCLUDING ECONOMIC
00024 // DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF
00025 // WHETHER CALTECH/JPL SHALL BE ADVISED, HAVE REASON TO KNOW, OR IN
00026 // FACT SHALL KNOW OF THE POSSIBILITY.  THE USER BEARS ALL RISK
00027 // RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE AND/OR RELATED
00028 // MATERIALS.
00029 //
00030 // ********************************************************************
00031 // mixer.h
00032 //
00033 // mixer.h holds the classes used to build up a full mixer device
00034 // from separate linear circuits and nonlinear junctions.
00035 //
00036 // Includes the following classes: mixer; mixer_currents
00037 //
00038 // 3/16/99:  Added mixer::freq()
00039 // 12/28/99: Reduced default max iteration count in balance()
00040 // 7/27/99:  Changed mixer_currents to be a data_ptr_nport
00041 // 7/22/99:  Changed reference to newt_raph.h to newton.h
00042 // 12/29/98: Added mixer::get_term_data().
00043 // 12/17/98: Use new mixer::analyzer class for small signal calculations.
00044 //           mixer is now derived from data_ptr_nport
00045 // 12/15/98: Split out definition of mixer::balancer to mixer_helper.h
00046 // 10/5/98:  Adding code for smart rebuilding of data structures in
00047 //           balancer
00048 // 9/14/98:  Improved auto_balance(), added initialize_mode().
00049 //           Implemented copy constructor and operator =.
00050 // 9/9/98:   removed check of LO from flag_mixer_incomplete()
00051 // 9/4/98:   Fixed a nasty bug: added const to mixer::get_last_data()
00052 // 8/28/98:  Fixed mixer::port() so it always uses IF circuit (not bias
00053 //           circuit if device::f == 0, as it did before); added size().
00054 // 8/27/98:  Added mixer_currents
00055 // 8/27/98:  mixer::set_LO can now shadow a parameter
00056 // 7/27/98:  Added I_junc() and V_junc(); LO freq is now a parameter
00057 // 7/22/98:  Added the balancer class to mixer; implemented in balance.cc
00058 // 7/21/98:  changed flag_balance_invalid() to flag_state_invalid();
00059 //           adding full balance() routines
00060 // 7/20/98:  Minor interface refinements.
00061 // 7/17/98:  Added private LO_saved; more large signal functions.
00062 // 7/15/98:  Many changes to the interface and the private variables
00063 //
00064 // F. Rice 7/9/98
00065 //
00066 // ********************************************************************
00067 
00068 #ifndef MIXER_H
00069 #define MIXER_H
00070 
00071 #include "circuit.h"
00072 #include "sources.h"
00073 #include "junction.h"
00074 
00075 
00076 // ********************************************************************
00077 // mixer
00078 //
00079 // A basic device which can perform harmonic balance and small signal
00080 // analysis of a multijunction mixer circuit.
00081 //
00082 // This mixer can only handle junction::Y_type nonlinear elements.
00083 //
00084 // The IF frequency for the small signal analysis should be set in
00085 // device::f. The device performs the small signal analysis when asked
00086 // to return its device parameters as an nport; the resulting sdata
00087 // holds the small signal response of the mixer.
00088 //
00089 // Note that this object will never return a nonzero source vector
00090 // in its small signal analysis result.  
00091 //
00092 // F. Rice 7/9/98
00093 //
00094 // ********************************************************************
00095 
00096 #include <vector>
00097 #include <pair.h>
00098 #include "newton.h"
00099 
00100 class mixer : public data_ptr_nport
00101 {
00102 
00103   // The results of the small signal mixer analysis are returned as S
00104   // parameters using class data_ptr_nport's get_data(), etc., functions,
00105   // so a mixer acts like just another circuit element.
00106 
00107 public:
00108 
00109   // Constructor: it only reserves space in its internal tables for the
00110   // fundamental USB and LSB. Call harmonics() to include more harmonics
00111   // in the analysis.
00112 
00113   mixer();
00114 
00115   // Copy constructor and operator =: Since the target and source mixers will
00116   // use the same junction devices following these operations, you should call
00117   // auto_balance(mixer::Always) to ensure that the junctions will be balanced
00118   // appropriately. It is also recommended that you call initialize_mode(1) to
00119   // make harmonic balance calculations more robust.
00120 
00121   mixer(const mixer &);
00122   mixer & operator = (const mixer &);
00123 
00124 
00125   // Flags which indicate the readiness of the mixer to perform accurate
00126   // calculations. A NONZERO RETURN VALUE IS BAD; A ZERO RETURN VALUE IS GOOD.
00127 
00128   // a fatal error if set when attempting a mixer calculation:
00129 
00130   int flag_mixer_incomplete() const;   // all required elements haven't been set,
00131                                        // or they don't have enough ports.
00132 
00133   // a fatal error during small signal analysis if auto balance is inactive:
00134 
00135   int flag_state_invalid() const;      // at least one junction has an invalid
00136                                        // operating state.
00137 
00138   // would indicate that any small signal calculations are inaccurate:
00139 
00140   int flag_balance_inaccurate() const; // something major changed since the last
00141                                        // balance: circuit references, LO freq,
00142                                        // or initialize_operating_state() was done.
00143 
00144 
00145   // Set or read the maximum number of harmonics to be used by the mixer.
00146 
00147   mixer & harmonics (int);     // set maximum harmonic number (1 is LO frequency)
00148 
00149   int harmonics() const { return max_harmonics; }
00150 
00151 
00152   // Manipulate the junctions attached to the mixer. The first junction added
00153   // will be connected to each of the RF, IF and DC circuits' port 1; the next
00154   // junction to the circuits' port 2, etc. Externally available ports of the RF
00155   // and IF circuits are through port numbers greater than the total number of
00156   // junctions in the mixer. Refer to the description of port().
00157 
00158   mixer & add_junction( junction & );  // add another junction device.
00159 
00160   int junctions() const { return num_junctions; }  // junctions added so far
00161 
00162   mixer & void_junctions();     // remove all previously attached junctions
00163 
00164 
00165   // Set the Local Oscillator frequency and the linear circuit elements:
00166 
00167   parameter LO;                 // the public variable which holds the LO
00168                                 // frequency for the mixer. If LO's value is
00169                                 // currently different from the value used at the
00170                                 // time of the last operating state calc, then
00171                                 // flag_balance_inaccurate() will be set.
00172 
00173   mixer & set_LO( double f ) { LO = f; return *this; }     // set LO frequency
00174 
00175   mixer & set_LO( abstract_real_parameter * pf ) { LO = pf; return *this; }
00176                                 // set LO frequency to shadow a parameter.
00177 
00178   mixer & set_bias( nport & );  // set the DC bias circuit. It must have the same
00179                                 // number of ports as the number of junctions to
00180                                 // be used.
00181 
00182   mixer & set_if( nport & );    // set the IF circuit. It must have more ports
00183                                 // than the number of junctions to be used.
00184 
00185   mixer & set_rf( nport & );    // set the RF circuit. It must have more ports
00186                                 // than the number of junctions to be used.
00187                                 // Setting a new RF circuit erases any previous
00188                                 // balance terminator settings.
00189 
00190   mixer & set_balance_terminator( nport &, int );  // provide a terminator for a
00191                                 // port of the RF circuit to be used during
00192                                 // harmonic balance. This is usually an LO power
00193                                 // source. The int argument gives the port index
00194                                 // on the RF circuit. The default is a device::Z0
00195                                 // termination. Warns the user if the RF circuit
00196                                 // hasn't been set, or the port doesn't exist.
00197                                 // Balance terminator assignments may be cleared
00198                                 // by setting the RF circuit using set_rf().
00199 
00200 
00201   // The mixer constructs a composite circuit of all linear and junction elements
00202   // during the small signal analysis. The following functions provide a map of
00203   // the ports of the individual linear elements to the resulting ports of the
00204   // final mixer circuit.
00205   // Port ordering is:
00206   //  (1) all open IF circuit ports
00207   //  (2) RF circuit at harmonic = 1: first open port at USB, then at LSB
00208   //  (3) all succeeding RF circuit open ports, USB then LSB at each port
00209   //  (4) same as (2) and (3) at harmonic = 2
00210   //  (5) continue for all higher harmonics
00211 
00212   int port( int p, int h );     // returns the mixer port index for port p of the
00213                                 // circuit at harmonic h.  h = 0 is the IF
00214                                 // circuit, h > 0 are upper sidebands of the RF
00215                                 // circuit, h < 0 are lower sidebands. returns 0
00216                                 // if the port p doesn't exist or is already
00217                                 // connected to a nonlinear junction.
00218 
00219   double freq( int port );      // returns the frequency associated with the port
00220                                 // of the mixer. If the port is associated with
00221                                 // harmonic h, returns: fabs(device::f + h*LO)
00222 
00223   int size();                   // since mixer is an nport, it must calculate its
00224                                 // size. This is the size of the small-signal
00225                                 // object. returns 0 if the mixer is incomplete.
00226 
00227 
00228   // The functions to control the harmonic balance of the mixer circuit. These
00229   // functions control how the operating states of the junctions are set.
00230 
00231   mixer & initialize_operating_state();  // Just set a rough operating state for
00232                                 // the junctions assuming the junctions behave as
00233                                 // open circuits when calculating the input
00234                                 // voltages. No harmonic balance iterations are
00235                                 // performed. Will not correct
00236                                 // flag_balance_inaccurate().
00237 
00238   int balance()                 // perform a harmonic balance, determining the
00239   { return balance_(); }        // operating states of all junctions.
00240                                 // Returns 0 if successful, 1 if a balance could
00241                                 // not be achieved. Will correct
00242                                 // flag_balance_inaccurate() if successful.
00243 
00244   mixer & initialize_mode(int f);  // If set to 0 (default), then balance() uses
00245                                 // the current junction operating states as the
00246                                 // initial guess for the nonlinear routine. If
00247                                 // set to nonzero, then balance() will first
00248                                 // call initialize_operating_state() before
00249                                 // executing the nonlinear routine.
00250 
00251   mixer & initialize_operating_state(const Matrix & V);  // Use the values in V
00252                                 // to set the operating states of the junctions.
00253                                 // V must have Index_C in both axes, with each
00254                                 // row providing the state vector for
00255                                 // call_large_signal() for its junction. The 1st
00256                                 // junction added is addressed by row 0, etc.
00257                                 // Uses the current LO frequency, and harmonics
00258                                 // equal to the larger of harmonics() or
00259                                 // V.Rmaxindex(). If V contains enough data to
00260                                 // set all junctions, then this routine will
00261                                 // correct flag_balance_inaccurate().
00262 
00263   mixer & save_operating_state(Matrix & V);  // saves the state vector of each
00264                                 // junction into the matrix V, in a form suitable
00265                                 // for use as an argument to
00266                                 // initialize_operating_state().
00267 
00268   mixer & auto_balance(int f);  // Set auto balance mode (default 0 - Off). 
00269                                 // If set to a value different from 0, then
00270                                 // get_data() may attempt to balance the mixer
00271                                 // before returning the small-signal response.
00272                                 // See the following enumeration for valid values
00273                                 // and their effects. If f is not 0, 1, or 2, then
00274                                 // the auto balance mode is left unchanged.
00275 
00276   enum { Off   = 0,             // Turn off auto balance feature (default).
00277          Always = 1,            // get_data() always rebalances the mixer. 
00278          Smart  = 2             // get_data() only rebalances the mixer if
00279   };                            // flag_state_invalid() or flag_balance_inaccurate()
00280 
00281 
00282   mixer & balance_parameters(   // control parameters for the harmonic balance
00283                                 // nonlinear solver (defaults in parentheses). The
00284                                 // defaults should be adequate.
00285     int max_iterations,   // maximum number of balance iterations (100)
00286     double tol_1,         // max absolute error of any individual voltage (1.0e-6)
00287     double tol_m,         // max sum of squares of all junction voltages (1.0e-8)
00288     double tol_x,         // single step relative change convergence test (1.0e-7)
00289     double alpha          // relative convergence speed minimum value (1.0e-4)
00290     );
00291 
00292 
00293   int balance_iterations()     // the number of iterations required by the most
00294   { return balance_.iterations(); }  // recent harmonic balance.
00295 
00296 
00297   // Results of the operating state calculations. The values returned are
00298   // obtained by calling the junctions' I() and V() member functions.  They
00299   // may not be accurate if flag_state_invalid() or flag_balance_inaccurate()
00300   // are set.
00301 
00302   Vector I_junc(int m);         // the currents through the junctions at
00303                                 // harmonic m of the LO frequency (0 is DC, 1 is
00304                                 // the LO freq). The index into the vector
00305                                 // selects the junction: 1 is the first junction
00306                                 // added to the mixer, etc. m must be nonnegative.
00307 
00308   Vector V_junc(int m);         // like I_junc(), except return the voltages
00309                                 // at harmonic m.
00310 
00311 
00312   // The normal small signal analysis results are returned by calling get_data() for
00313   // a mixer object. In addition, the following function is provided to aid in Y-factor
00314   // determinations:
00315 
00316   const sdata & get_term_data(); // Terminate the RF circuit using supplied balance
00317                                  // terminators and/or default Z0 terminations, then
00318                                  // perform the small signal analysis. The sdata result
00319                                  // will connect the open IF ports at the frequency 
00320                                  // given by device::f. The source vector of the result
00321                                  // will always be all 0's, even if there are embedded
00322                                  // sources in the circuits or terminators.
00323 
00324 
00325 
00326   // Bring in the private members and member class definitions:
00327 
00328 #include "mixer_helper.h"
00329 
00330 }; // mixer
00331 
00332 // ********************************************************************
00333 // mixer_currents
00334 //
00335 // mixer_currents is used to construct an equivalent nport device
00336 // representing current sinks, one per junction in the mixer
00337 // circuit, which can be used with an inst_circuit object (c.f.
00338 // instrument.h) to determine the voltages or currents in the linear
00339 // circuitry of the mixer.
00340 //
00341 // F. Rice 8/27/98
00342 //
00343 // ********************************************************************
00344 
00345 #include "sources.h"
00346 #include "parameter/scaled_real_parameter.h"
00347 
00348 class mixer_currents : public data_ptr_nport
00349 {
00350 public:
00351   // the constructor requires that the number of junctions to be
00352   // modeled be incuded, as well as the mixer object itself:
00353 
00354   mixer_currents(mixer & m, int num_junctions);
00355 
00356   // specify the harmonic of the LO to use; the mixer_currents
00357   // source frequency will be set to shadow this number times the mixer
00358   // object's LO frequency parameter.  The default is 0 (DC bias).
00359 
00360   mixer_currents & set_harmonic(int h);
00361 
00362 
00363   // the nport interface:
00364 
00365   inline int size() { return n; }
00366 
00367 private:
00368   mixer & mix;
00369   int n, h;
00370   std::vector <current_sink> junctions;
00371   scaled_real_parameter freq;
00372   circuit c;
00373 
00374   void recalc();
00375 
00376 };
00377 
00378 #endif /* MIXER_H */

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