00001 // makeiv.cc 00002 // Generate a simulated SIS DC IV curve suitable for use with supermix. 00003 // The output IV curve will be normalized such that Vgap = Rn = 1. 00004 // The output will be written to the standard output stream. 00005 00006 #include "supermix.h" 00007 #include "numerical.h" 00008 00009 // --------------------------------------------------------------------------- 00010 // Function to print a usage prompt, with definitions of the parameters 00011 00012 const int cmd_line_params = 4; // the expected number of command line params 00013 00014 void prompt(const char *const *const argv) 00015 { 00016 cerr << argv[0] << ": construct a simulated, normalized SIS IV curve for" 00017 << endl << "use with SuperMix." << endl << endl; 00018 cerr << "Usage: " << argv[0] << " R_subgap Gap_width I_leakage I_defect" 00019 << endl << endl; 00020 00021 cerr << "Where:" << endl 00022 << " Parameter Description Valid Range \n" 00023 << " --------- --------------------------------- ----------- \n" 00024 << " R_subgap Subgap/Normal resistance ratio > 1.0 \n" 00025 << " Gap_width Width of the gap relative to Vgap 0.0 - 1.0 \n" 00026 << " I_leakage Leakage current just above V = 0 0.0 - 1.0 \n" 00027 << " I_defect Current defect just above gap 0.0 - 1.0 \n" 00028 << endl 00029 << " The output is normalized so that Vgap = Rn = 1.0. \n" 00030 << " Currents (I_leakage and I_defect) are normalized to Vgap/Rn. \n" 00031 << " I_defect is the amount that the current just above Vgap \n" 00032 << " falls short of being equal to V/Rn. It rerpesents a constant \n" 00033 << " offset below the I=V/Rn line for all currents with V>Vgap. \n" 00034 << endl 00035 << " Typical values for a fairly good SIS might be: \n" 00036 << " R_subgap = 20 \n" 00037 << " Gap_width = 0.02 \n" 00038 << " I_leakage = 0.01 \n" 00039 << " I_defect = 0.1 \n" 00040 << endl; 00041 } 00042 00043 // --------------------------------------------------------------------------- 00044 // Global parameters: 00045 00046 double G_subgap; // Subgap/Normal conductance ratio (0.0 - 1.0) 00047 double Gap_width; // Relative width of the gap (0.0 - 1.0) 00048 double I_leakage; // Leakage current/(Vgap/Rn) (0.0 - 1.0) 00049 double I_defect; // Current defect above gap (0.0 - 1.0) 00050 00051 // Set the comment prefix string to be used in the output header: 00052 const char *comment = "#"; 00053 00054 // --------------------------------------------------------------------------- 00055 // Functions used to simulate a simple SIS dc IV response: 00056 00057 // output a straight line fit: y = mx+b: 00058 inline double line(double x, double m, double b) { return m*x + b; } 00059 00060 // a hyperbolic tangent step function with some parameter checking 00061 double sym_step(double x, double w) 00062 { 00063 if (w > 0.0) return tanh(x/w); 00064 else { 00065 if (x < 0.0) return -1.0; 00066 else if (x == 0.0) return 0.0; 00067 else return 1.0; 00068 } 00069 } 00070 00071 // output a finite-width generalization of the Heaviside step function: 00072 inline double step(double x, double w) { return 0.5*(sym_step(x,w)+1.0); } 00073 00074 // the full simulation of the iv curve, using the curve parameters: 00075 // (this function will be passed to the adaptive interpolator fill algorithm) 00076 double f(double v) 00077 { 00078 double av = fabs(v); 00079 double i_sg = line(av, G_subgap, I_leakage * sym_step(v, sqrt(Gap_width))); 00080 double i_ag = line(av, 1.0, -I_defect) * sym_step(v, Gap_width); 00081 double weight = step(av - 1.0, Gap_width); 00082 return weight*i_ag + (1.0-weight)*i_sg; 00083 } 00084 00085 // --------------------------------------------------------------------------- 00086 // Here is the main program: 00087 00088 int main(int argc, char ** argv) // we'll be using command line arguments 00089 { 00090 // Input command line parameters; print a usage prompt if needed 00091 bool bad_param = false; 00092 if (argc != 1+cmd_line_params) bad_param = true; 00093 else { 00094 Gap_width = atof(argv[2]); 00095 G_subgap = 1/atof(argv[1]); 00096 I_leakage = atof(argv[3]); 00097 I_defect = atof(argv[4]); 00098 00099 // check the reasonableness of the parameters 00100 if (Gap_width <= 0.0 || Gap_width > 1.0) bad_param = true; 00101 if (G_subgap < 0.0 || G_subgap > 1.0) bad_param = true; 00102 if (I_leakage < 0.0 || I_leakage > 1.0) bad_param = true; 00103 if (I_defect < 0.0 || I_defect > 1.0) bad_param = true; 00104 } 00105 00106 if (bad_param) { 00107 prompt(argv); 00108 return 1; 00109 } 00110 00111 00112 // Adaptively fill an interpolator with simulated IV curve points. We use 00113 // an interpolator here, since the SuperMix class ivcurve does. We want to 00114 // ensure that the points we output will allow an interpolator to accurately 00115 // match the desired IV curve response. See interpolate.h and adaptive.h 00116 00117 // We build an interpolator object to hold the calculated IV points. This allows 00118 // us to use an adaptive fill algorithm to only include just enough points to 00119 // ensure that interpolation will meet our accuracy requirements. 00120 00121 // Class interpolator<> is defined in interpolate.h and is a templated class. 00122 // To construct an interpolator object we must specify the data type of the 00123 // dependent (y) variable. The independent (x) variable is always of type double. 00124 // The default is to use cubic spline interpolation, which is what we'll use. 00125 00126 interpolator<double> idc; 00127 00128 // Now we fill the interpolator with y(x) data points using an adaptive algoithm. 00129 // The function adaptive_fill() is defined in adaptive.h. It is a special 00130 // numerical routine not normally included by supermix.h, so we bring in its 00131 // definition using numerical.h, in the list of #include's at the beginning of 00132 // this program. 00133 00134 // The adaptive fill algorithm works by first sprinkling the interpolator with a 00135 // few uniformly-spaced points from the function to be interpolated. It then 00136 // evaluates the accuracy of the interpolation between each pair of points and 00137 // adds additional points recursively until it thinks it has met the accuracy 00138 // target. The resulting interpolator is filled with a set of unevenly-spaced 00139 // points. 00140 00141 adaptive_fill(idc, f, 0, 2, .0001, .01); 00142 00143 // In the above function call, 00144 // idc : the interpolator to be filled 00145 // f : the function object to be interpolated such that y = f(x) 00146 // 0 : the lower limit on the domain of the interpolation 00147 // 2 : the upper limit on the domain of the interpolation 00148 // .0001 : the absolute error target for the interpolation 00149 // .01 : the relative error target for the interpolation 00150 // 00151 // We don't set the error targets too high since we're just simulating 00152 // real iv curves here; these values will give us a nice smooth spline. 00153 00154 00155 // Now to output the (V,I) points in the interpolator. 00156 00157 // First we set the output number format: 00158 cout << fixed << setprecision(10); 00159 00160 // Then let's print a header recording the parameter values used. Note that 00161 // we prefix a comment identifier to each header line. 00162 cout << comment << " Normalized simulated SIS DC IV characteristic curve" << endl; 00163 cout << comment << " Parameter values used in the simulation:" << endl; 00164 cout << comment << " Gap Width = " << Gap_width << endl; 00165 cout << comment << " Subgap Resistance Ratio = " << 1/G_subgap << endl; 00166 cout << comment << " Subgap Current Leakage = " << I_leakage << endl; 00167 cout << comment << " Normal Current Defect = " << I_defect << endl; 00168 cout << comment << endl; 00169 cout << comment << " V: " << "\t" << "I:" << endl; 00170 00171 // Now we print out the points actually used in the interpolator. The size() 00172 // member function of the interpolator tells us how many points there are. 00173 00174 for(unsigned i = 0; i < idc.size(); ++i) 00175 00176 // The x(i) member function gives us the x value of the ith point; the points 00177 // are sorted by x value with the lowest x value associated with point 0. 00178 // The indexing operation [i] on an interpolator gives the y value of the ith 00179 // point, just like with a C-style array. 00180 00181 cout << idc.x(i) << "\t" << idc[i] << endl; 00182 } 00183
Please direct comments and corrections to
supermix@submm.caltech.edu
Go to the supermix home page
Generated by
1.2.7