46 #include <Xyce_config.h>
50 #include <N_UTL_Expression.h>
51 #include <N_UTL_Misc.h>
52 #include <N_UTL_Math.h>
53 #include <N_UTL_LogStream.h>
62 #include <N_LAS_Vector.h>
63 #include <N_LAS_Matrix.h>
93 .setDescription(
"Capacitance")
94 .setAnalyticSensitivityAvailable(
true)
95 .setSensitivityFunctor(&
capSens);
101 .setDescription(
"Semiconductor capacitor width");
104 .setDescription(
"Semiconductor capacitor length");
107 .setDescription(
"Age of capacitor");
109 .setDescription(
"Age degradation coefficient");
113 .setDescription(
"Device temperature");
118 .setDescription(
"Linear Temperature Coefficient");
122 .setDescription(
"Quadratic Temperature Coefficient");
147 .setDescription(
"Capacitance multiplier");
150 .setDescription(
"Junction bottom capacitance");
153 .setDescription(
"Junction sidewall capacitance");
156 .setDescription(
"Default device width");
159 .setDescription(
"Narrowing due to side etching");
205 UserError0(*
this) <<
"Age defined, but no base capacitance given. Can't use age-aware with semiconductor capacitor options";
216 UserError0(*
this) <<
"Could find neither C parameter or L in instance.";
224 dout() <<
"Semiconductor capacitor " <<
getName()
227 <<
"cj = " <<
model_.
cj << std::endl
229 <<
"width = " <<
width << std::endl
230 <<
"length = " <<
length << std::endl
273 bool bsuccess =
true;
274 double difference, factor;
283 dout() <<
"Capacitor " <<
getName() <<
" updateTemperature()"
286 <<
"C = " <<
C << std::endl
287 <<
"temp = " <<
temp << std::endl
288 <<
"temp_tmp = " << temp_tmp << std::endl
290 <<
"difference = " << difference << std::endl
293 <<
"baseCap = " <<
baseCap << std::endl
295 <<
"factor = " << factor << std::endl;
324 :
DeviceInstance(instance_block, configuration.getInstanceParameters(), factory_block),
329 temp(getDeviceOptions().temp.getImmutableValue<double>()),
333 tempCoeff1Given(false),
334 tempCoeff2Given(false),
341 APosEquPosNodeOffset(-1),
342 ANegEquPosNodeOffset(-1),
343 APosEquNegNodeOffset(-1),
344 ANegEquNegNodeOffset(-1),
345 APosEquBraNodeOffset(-1),
346 ANegEquBraNodeOffset(-1),
347 ABraEquBraNodeOffset(-1),
348 ABraEquPosNodeOffset(-1),
349 ABraEquNegNodeOffset(-1),
352 qPosEquPosNodePtr(0),
353 qNegEquPosNodePtr(0),
354 qPosEquNegNodePtr(0),
355 qNegEquNegNodePtr(0),
356 fPosEquBraNodePtr(0),
357 fNegEquBraNodePtr(0),
358 fBraEquBraNodePtr(0),
359 fBraEquPosNodePtr(0),
360 fBraEquNegNodePtr(0),
525 std::vector<Depend>::const_iterator d;
529 for (d=begin; d!=end; ++d)
533 UserError0(*
this) <<
"Solution-variable-dependent parameter other than C detected";
548 if (
expPtr->getNumDdt() != 0)
550 UserError0(*
this) <<
"Solution-variable-dependent expression contains time derivatives";
555 dout() <<
"Capacitor " <<
getName()
556 <<
": Found solution-dependent parameter C depending on " <<
expNumVars <<
" variables" << std::endl;
557 if (
expPtr->isTimeDependent())
559 dout() <<
" " <<
"Expression is time-dependent." << std::endl;
563 dout() <<
" " <<
"Expression is not time-dependent." << std::endl;
565 dout() <<
" " <<
"Expression depends on " <<
expPtr->num_vars() <<
" quantity, of which " <<
expPtr->num_vars()-
expNumVars <<
" are not solution vars. " << std::endl;
657 const std::vector<int> & extLIDVecRef)
682 dout() <<
"Capacitor " <<
getName() <<
" Instance::registerLIDs"
685 <<
"li_Pos_ = " <<
li_Pos << std::endl
686 <<
"li_Neg_ = " <<
li_Neg << std::endl;
689 dout() <<
"li_Bra = "<<
li_Bra<< std::endl;
952 int depVarsBaseIndex = 2;
970 dout() <<
"Capacitor " <<
getName() <<
" Instance::registerJacLIDs"
1029 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1105 double v_pos = solVec[
li_Pos];
1106 double v_neg = solVec[
li_Neg];
1110 dout() <<
" ----------------------------------" << std::endl;
1111 dout() <<
"Instance::updatePrimaryState:" << std::endl;
1165 q0 += 0.5*(oldC+
C)*(
vcap-oldVcap);
1169 dout() <<
" Derivatives of C w.r.t variables: " << std::endl;
1172 dout() <<
" expVarDerivs[ "<< i <<
" ] = " <<
expVarDerivs[i] << std::endl;
1347 bool bsuccess =
true;
1375 v_tmp= (Vpos-Vneg-
IC);
1562 Vneg = currSolVector[
li_Neg];
1565 currSolVector[
li_Pos] = Vpos;
1566 nextSolVector[
li_Pos] = Vpos;
1567 currSolVector[
li_Neg] = -Vpos;
1568 nextSolVector[
li_Neg] = -Vpos;
1586 varTypeVec.resize(1);
1587 varTypeVec[0] =
'I';
1643 std::vector<Instance*>::iterator iter;
1647 for (iter=first; iter!=last; ++iter)
1649 (*iter)->processParams();
1677 :
DeviceModel(model_block, configuration.getModelParameters(), factory_block),
1678 capacitanceMultiplier(1.0),
1685 tnom(getDeviceOptions().tnom),
1719 std::vector<Instance*>::iterator iter;
1723 for (iter=first; iter!=last; ++iter)
1741 std::vector<Instance*>::const_iterator iter;
1749 os <<
"Number of capacitor instances: " << isize << std::endl;
1750 os <<
" name\t\tmodelName\tParameters" << std::endl;
1752 for (i = 0, iter = first; iter != last; ++iter, ++i)
1754 os <<
" " << i <<
": " << (*iter)->getName() <<
"\t";
1756 os <<
"\t\tC = " << (*iter)->C;
1757 os <<
"\tIC = " << (*iter)->IC;
1782 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1827 double v_pos = solVec[ci.
li_Pos];
1828 double v_neg = solVec[ci.
li_Neg];
1829 ci.
vcap = v_pos-v_neg;
1881 bool Master::loadDAEVectors (
double * solVec,
double * fVec,
double *qVec,
double * bVec,
double * storeLeadF,
double * storeLeadQ)
1886 dout() <<
" ----------------------------------" << std::endl;
1887 dout() <<
" Master::loadDAEVectors: " << std::endl;
1895 double Vpos (0.0), Vneg (0.0), v_tmp (0.0);
1902 dout() <<
" loading dcop F vector for cap " << ci.
getName() <<
":" << std::endl;
1906 Vpos = solVec[ci.
li_Pos];
1907 Vneg = solVec[ci.
li_Neg];
1928 dout() <<
" f[ " << ci.
li_Pos <<
" ] += " << solVec[ci.
li_Bra]<< std::endl;
1929 dout() <<
" f[ " << ci.
li_Neg <<
" ] += " << -solVec[ci.
li_Bra] << std::endl;
1932 v_tmp= (Vpos-Vneg-ci.
IC);
1936 fVec[ci.
li_Bra] += v_tmp;
1940 dout() <<
" f[ " << ci.
li_Bra <<
" ] += " << v_tmp << std::endl;
1967 dout() <<
" loading Q vector for cap " << ci.
getName() <<
":" << std::endl;
1968 dout() <<
" q[ " << ci.
li_Pos <<
" ] += " << ci.
q0 << std::endl;
1969 dout() <<
" q[ " << ci.
li_Neg <<
" ] += " << -ci.
q0 << std::endl;
2007 dout() <<
" ----------------------------------" << std::endl;
2008 dout() <<
" Master::loadDAEMatrices: " << std::endl;
2017 dout() <<
" loads for capacitor " << ci.
getName() << std::endl;
2023 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
2039 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
2049 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
2118 << expVarDerivs[i] << std::endl;
2177 .registerDevice(
"c", 1)
2178 .registerModelType(
"c", 1)
2179 .registerModelType(
"cap", 1);
2192 const std::string & name,
2193 std::vector<double> & dfdp,
2194 std::vector<double> & dqdp,
2195 std::vector<double> & dbdp,
2196 std::vector<int> & Findices,
2197 std::vector<int> & Qindices,
2198 std::vector<int> & Bindices
2205 double v_pos = solVec[in->
li_Pos];
2206 double v_neg = solVec[in->
li_Neg];
2207 double vcap = v_pos-v_neg;
2209 double dqdpLoc = vcap;
2216 Qindices[0] = in->
li_Pos;
2217 Qindices[1] = in->
li_Neg;