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 // supcond.cc 00031 // 00032 // J. Zmuidzinas 11/30/88 Translated to C/C++ 9/15/97 J.Z. 00033 // 00034 // 8/30/99: improved the match between tabulated and analytic in gap_supcond() 00035 // 7/7/99: changed gap_supcond() to use an analytic extension at low T/Tc 00036 // 7/16/99: major mods to use integrate.h, and to make it look more like "C++" 00037 // *********************************************************************** 00038 00039 #include <math.h> 00040 #include "units.h" 00041 #include "supcond.h" 00042 #include "integrate.h" 00043 00044 00045 // Some variables we need to pass to integrand functions: 00046 // 00047 // Omega - reduced frequency, h*freq/e*DELTA(T) (h=Planck's const; e= 00048 // electron charge) 00049 // tau - reduced temperature, k*T/e*DELTA(T) (k = Boltzmann's const) 00050 00051 static struct { double tau; double Omega; } lparms; 00052 00053 // Integrand function declarations. static so we don't pollute the global 00054 // namespace. 00055 static double sig11_supcond(double); 00056 static double sig12_supcond(double); 00057 static double sig21_supcond(double); 00058 static double sig22_supcond(double); 00059 00060 // additional function declarations: 00061 inline double fermi_supcond(double, double); 00062 inline double g_supcond(double, double); 00063 static double gap_supcond(double); 00064 00065 00066 // *********************************************************************** 00067 // supcond(): 00068 00069 complex supcond(double freq, double T, double Vgap, double Tc) 00070 { 00071 if(Vgap < 0. || Tc < 0. || T > Tc) 00072 // check for unreasonable or nonsuperconducting conditions 00073 // and return normal-state conductivity if they exist: 00074 return(complex(1.0)); 00075 00076 double DELTA = 0.5*Vgap; // gap parameter 00077 double dratio = gap_supcond(T/Tc); // reduced gap at T: DELTA(T)/DELTA(0) 00078 00079 // Normalize frequency and temperature to gap energy: 00080 lparms.Omega = (freq/VoltToFreq)/(DELTA*dratio); 00081 lparms.tau = BoltzK*T/(hPlanck*VoltToFreq*DELTA*dratio); 00082 // lparms.tau = 0.086170837*T/(DELTA*dratio) 00083 00084 double S1, S2; // real and imaginary parts of conductivity 00085 static integrator<double> Int; // static so it only gets constructed once 00086 00087 // Calculate real part: 00088 00089 double S11, S12; 00090 00091 S11 = Int.sqrtlower()(sig11_supcond, 1.0, 2.0) 00092 + Int.exp()(sig11_supcond, 2.0, 1000); 00093 S11 *= 2.0/lparms.Omega; 00094 00095 if(lparms.Omega <= 2.) { 00096 S12 = 0. ; 00097 } 00098 else { 00099 S12 = Int.sqrtlower()(sig12_supcond, 1.0, lparms.Omega/2.0) 00100 + Int.sqrtupper()(sig12_supcond, lparms.Omega/2.0, lparms.Omega-1.0); 00101 S12 /= lparms.Omega; 00102 } 00103 00104 // Note following "-" sign on S12. This is correct. 00105 // Whitaker et al. (1988), eqn. 14a, has the incorrect sign. 00106 // Kautz (1978), eq. 2.9, has the correct sign. 00107 00108 S1 = S11-S12 ; 00109 00110 // Calculate imaginary part: 00111 00112 if(lparms.Omega <= 2.) { 00113 if(lparms.Omega <= 1.) { 00114 S2 = Int.sqrtlower()(sig21_supcond, 1.0-lparms.Omega, 1.0-lparms.Omega/2) 00115 + Int.sqrtupper()(sig21_supcond, 1.0-lparms.Omega/2, 1.0); 00116 } 00117 else { 00118 S2 = Int.sqrtupper()(sig22_supcond, 0, lparms.Omega-1.0) 00119 + Int.sqrtlower()(sig21_supcond, 0, 1.0-lparms.Omega/2.0) 00120 + Int.sqrtupper()(sig21_supcond, 1.0-lparms.Omega/2.0, 1.0); 00121 } 00122 } 00123 else { 00124 S2 = Int.sqrtupper()(sig22_supcond, 0, 1.0) 00125 + Int.sqrtupper()(sig21_supcond, 0, 1.0) ; 00126 } 00127 S2 /= lparms.Omega ; 00128 00129 return(complex(S1, -S2)); // note minus sign on imaginary part 00130 // this corresponds to exp(+ j omega t) 00131 } // supcond() 00132 00133 00134 // *********************************************************************** 00135 // the integrand functions declared previously: 00136 00137 static double sig11_supcond(double x) 00138 { 00139 double xO = x+lparms.Omega; // we'll use this a couple of times... 00140 00141 double result = fermi_supcond(x,lparms.tau) - fermi_supcond(xO,lparms.tau); 00142 result *= g_supcond(x,lparms.Omega); 00143 result /= sqrt(x*x - 1) * sqrt(xO*xO - 1); 00144 return result; 00145 } 00146 00147 00148 static double sig12_supcond(double x) 00149 { 00150 x *= -1; 00151 double xO = x+lparms.Omega; // we'll use this a couple of times... 00152 00153 double result = 1 - 2.0*fermi_supcond(xO,lparms.tau); 00154 result *= g_supcond(x,lparms.Omega) ; 00155 result /= sqrt(x*x - 1) * sqrt(xO*xO - 1) ; 00156 return result; 00157 } 00158 00159 00160 static double sig21_supcond(double x) 00161 { 00162 double xO = x+lparms.Omega; // we'll use this a couple of times... 00163 00164 double result = 1 - 2.0*fermi_supcond(xO,lparms.tau); 00165 result *= g_supcond(x,lparms.Omega) ; 00166 result /= sqrt(1 - x*x) * sqrt(xO*xO - 1) ; 00167 return result; 00168 } 00169 00170 00171 static double sig22_supcond(double x) 00172 { 00173 x *= -1; 00174 double xO = x+lparms.Omega; // we'll use this a couple of times... 00175 00176 double result = 1 - 2.0*fermi_supcond(xO,lparms.tau); 00177 result *= g_supcond(x,lparms.Omega) ; 00178 result /= sqrt(1 - x*x) * sqrt(xO*xO - 1) ; 00179 return result; 00180 } 00181 00182 00183 // *********************************************************************** 00184 // additional functions: 00185 00186 inline double fermi_supcond(double x, double tau) 00187 { 00188 double y = exp(-x/tau); 00189 return y / (1.0 + y) ; 00190 } 00191 00192 inline double g_supcond(double x, double Omega) 00193 { return 1.0 + x*(x + Omega); } 00194 00195 // ----------------------------------------------------------------------- 00196 // Table of reduced energy gap vs. T/Tc, from Muhlschlegel (1959). 00197 // Table starts at x = T/Tc = 0.18, and goes in steps of dx = 0.02 00198 00199 static double ratio[42] = { 00200 1.0, 0.9999, 0.9997, 0.9994, 0.9989, 00201 0.9982, 0.9971, 0.9957, 0.9938, 0.9915, 00202 0.9885, 0.985, 0.9809, 0.976, 0.9704, 00203 0.9641, 0.9569, 0.9488, 0.9399, 0.9299, 00204 0.919, 0.907, 0.8939, 0.8796, 0.864, 00205 0.8471, 0.8288, 0.8089, 0.7874, 0.764, 00206 0.7386, 0.711, 0.681, 0.648, 0.6117, 00207 0.5715, 0.5263, 0.4749, 0.4148, 0.3416, 00208 0.2436, 0.0 00209 } ; 00210 00211 00212 // ----------------------------------------------------------------------- 00213 // uses ratio[] to calculate superconducting energy gap as a function of temp: 00214 00215 static double gap_supcond(double x) 00216 { 00217 // the argument x = T/Tc; check if x is physical 00218 if(x < 0. || x >= 1.) return(0.0); // return gap of zero 00219 00220 // if T/Tc < 0.04, reduced energy gap is 1.0, to better than 1 part in 10^22 00221 if(x < 0.04) return(1.0); // return gap of 1.0 00222 00223 // if T/Tc <= xmatch, we use an analytic expression to extend the gap table; 00224 // ( which uses k Tc ~= Delta(0)/1.764; c.f. Tinkham ) 00225 00226 static const double xmatch = 0.32; // xmatch must be a multiple of 0.02, >= 0.18 00227 static const double ymatch = exp(-sqrt(3.562*xmatch)*exp(-1.764/xmatch)); 00228 if(x <= xmatch) return(exp(-sqrt(3.562*x)*exp(-1.764/x))); // 3.562==2*Pi/1.764 00229 00230 // if we get here, we interpolate between data points to calculate gap, taking 00231 // sqrt(1 - T/Tc) dependence near the gap into account. 00232 00233 int index = (int) floor((x-0.18)/0.02); // index into ratio[] 00234 double xl = index*0.02 + 0.18, 00235 xu = xl + 0.02, 00236 yl = ((xl > xmatch) ? ratio[index] : ymatch)/sqrt(1.-xl), 00237 yu = (index < 40) ? ratio[index+1]/sqrt(1.-xu) : 1.74; 00238 // Behavior near Tc - see Tinkham, eqn. 2-54. 00239 00240 return sqrt(1 - x) * (yl + (yu-yl)*(x-xl)/(xu-xl)); // linear interp into ratio[] 00241 } 00242 00243 00244 00245
Please direct comments and corrections to
supermix@submm.caltech.edu
Go to the supermix home page
Generated by
1.2.7