46 #include <Xyce_config.h>
55 #include <N_LAS_Matrix.h>
56 #include <N_LAS_Vector.h>
57 #include <N_UTL_Expression.h>
58 #include <N_UTL_FeatureTest.h>
59 #include <N_UTL_LogStream.h>
60 #include <N_UTL_Math.h>
88 .setDescription(
"Capacitance")
89 .setAnalyticSensitivityAvailable(
true)
90 .setSensitivityFunctor(&
capSens);
96 .setDescription(
"Semiconductor capacitor width");
99 .setDescription(
"Semiconductor capacitor length");
102 .setDescription(
"Age of capacitor");
104 .setDescription(
"Age degradation coefficient");
108 .setDescription(
"Device temperature");
113 .setDescription(
"Linear Temperature Coefficient");
117 .setDescription(
"Quadratic Temperature Coefficient");
142 .setDescription(
"Capacitance multiplier");
145 .setDescription(
"Junction bottom capacitance");
148 .setDescription(
"Junction sidewall capacitance");
151 .setDescription(
"Default device width");
154 .setDescription(
"Narrowing due to side etching");
201 UserError0(*
this) <<
"Age defined, but no base capacitance given. Can't use age-aware with semiconductor capacitor options";
212 UserError0(*
this) <<
"Could find neither C parameter or L in instance.";
218 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
220 dout() <<
"Semiconductor capacitor " <<
getName()
223 <<
"cj = " <<
model_.
cj << std::endl
225 <<
"width = " <<
width << std::endl
226 <<
"length = " <<
length << std::endl
269 bool bsuccess =
true;
270 double difference, factor;
279 dout() <<
"Capacitor " <<
getName() <<
" updateTemperature()"
282 <<
"C = " <<
C << std::endl
283 <<
"temp = " <<
temp << std::endl
284 <<
"temp_tmp = " << temp_tmp << std::endl
286 <<
"difference = " << difference << std::endl
289 <<
"baseCap = " <<
baseCap << std::endl
291 <<
"factor = " << factor << std::endl;
320 :
DeviceInstance(instance_block, configuration.getInstanceParameters(), factory_block),
325 temp(getDeviceOptions().temp.getImmutableValue<double>()),
329 tempCoeff1Given(false),
330 tempCoeff2Given(false),
338 APosEquPosNodeOffset(-1),
339 ANegEquPosNodeOffset(-1),
340 APosEquNegNodeOffset(-1),
341 ANegEquNegNodeOffset(-1),
342 APosEquBraNodeOffset(-1),
343 ANegEquBraNodeOffset(-1),
344 ABraEquBraNodeOffset(-1),
345 ABraEquPosNodeOffset(-1),
346 ABraEquNegNodeOffset(-1),
349 qPosEquPosNodePtr(0),
350 qNegEquPosNodePtr(0),
351 qPosEquNegNodePtr(0),
352 qNegEquNegNodePtr(0),
353 fPosEquBraNodePtr(0),
354 fNegEquBraNodePtr(0),
355 fBraEquBraNodePtr(0),
356 fBraEquPosNodePtr(0),
357 fBraEquNegNodePtr(0),
524 std::vector<Depend>::const_iterator d;
528 for (d=begin; d!=end; ++d)
532 UserError0(*
this) <<
"Solution-variable-dependent parameter other than C detected";
547 if (
expPtr->getNumDdt() != 0)
549 UserError0(*
this) <<
"Solution-variable-dependent expression contains time derivatives";
552 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
554 dout() <<
"Capacitor " <<
getName()
555 <<
": Found solution-dependent parameter C depending on " <<
expNumVars <<
" variables" << std::endl;
556 if (
expPtr->isTimeDependent())
558 dout() <<
" " <<
"Expression is time-dependent." << std::endl;
562 dout() <<
" " <<
"Expression is not time-dependent." << std::endl;
564 dout() <<
" " <<
"Expression depends on " <<
expPtr->num_vars() <<
" quantity, of which " <<
expPtr->num_vars()-
expNumVars <<
" are not solution vars. " << std::endl;
656 const std::vector<int> & extLIDVecRef)
679 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
681 dout() <<
"Capacitor " <<
getName() <<
" Instance::registerLIDs"
684 <<
"li_Pos_ = " <<
li_Pos << std::endl
685 <<
"li_Neg_ = " <<
li_Neg << std::endl;
688 dout() <<
"li_Bra = "<<
li_Bra<< std::endl;
941 int depVarsBaseIndex = 2;
957 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
959 dout() <<
"Capacitor " <<
getName() <<
" Instance::registerJacLIDs"
1018 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1094 double v_pos = solVec[
li_Pos];
1095 double v_neg = solVec[
li_Neg];
1097 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1099 dout() <<
" ----------------------------------" << std::endl;
1100 dout() <<
"Instance::updatePrimaryState:" << std::endl;
1154 q0 += 0.5*(oldC+
C)*(
vcap-oldVcap);
1158 dout() <<
" Derivatives of C w.r.t variables: " << std::endl;
1161 dout() <<
" expVarDerivs[ "<< i <<
" ] = " <<
expVarDerivs[i] << std::endl;
1345 bool bsuccess =
true;
1386 v_tmp= (Vpos-Vneg-
IC);
1573 Vneg = currSolVector[
li_Neg];
1576 currSolVector[
li_Pos] = Vpos;
1577 nextSolVector[
li_Pos] = Vpos;
1578 currSolVector[
li_Neg] = -Vpos;
1579 nextSolVector[
li_Neg] = -Vpos;
1597 varTypeVec.resize(1);
1598 varTypeVec[0] =
'I';
1652 std::vector<Instance*>::iterator iter;
1656 for (iter=first; iter!=last; ++iter)
1658 (*iter)->processParams();
1686 :
DeviceModel(model_block, configuration.getModelParameters(), factory_block),
1687 capacitanceMultiplier(1.0),
1694 tnom(getDeviceOptions().tnom),
1728 std::vector<Instance*>::iterator iter;
1732 for (iter=first; iter!=last; ++iter)
1750 std::vector<Instance*>::const_iterator iter;
1758 os <<
"Number of capacitor instances: " << isize << std::endl;
1759 os <<
" name\t\tmodelName\tParameters" << std::endl;
1761 for (i = 0, iter = first; iter != last; ++iter, ++i)
1763 os <<
" " << i <<
": " << (*iter)->getName() <<
"\t";
1765 os <<
"\t\tC = " << (*iter)->C;
1766 os <<
"\tIC = " << (*iter)->IC;
1791 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1836 double v_pos = solVec[ci.
li_Pos];
1837 double v_neg = solVec[ci.
li_Neg];
1838 ci.
vcap = v_pos-v_neg;
1890 bool Master::loadDAEVectors (
double * solVec,
double * fVec,
double *qVec,
double * bVec,
double * storeLeadF,
double * storeLeadQ,
double * leadF,
double * leadQ,
double * junctionV)
1893 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1895 dout() <<
" ----------------------------------" << std::endl;
1896 dout() <<
" Master::loadDAEVectors: " << std::endl;
1904 double Vpos (0.0), Vneg (0.0), v_tmp (0.0);
1909 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1911 dout() <<
" loading dcop F vector for cap " << ci.
getName() <<
":" << std::endl;
1915 Vpos = solVec[ci.
li_Pos];
1916 Vneg = solVec[ci.
li_Neg];
1935 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1937 dout() <<
" f[ " << ci.
li_Pos <<
" ] += " << solVec[ci.
li_Bra]<< std::endl;
1938 dout() <<
" f[ " << ci.
li_Neg <<
" ] += " << -solVec[ci.
li_Bra] << std::endl;
1941 v_tmp= (Vpos-Vneg-ci.
IC);
1945 fVec[ci.
li_Bra] += v_tmp;
1949 dout() <<
" f[ " << ci.
li_Bra <<
" ] += " << v_tmp << std::endl;
1966 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1968 dout() <<
" loading Q vector for cap " << ci.
getName() <<
":" << std::endl;
1969 dout() <<
" q[ " << ci.
li_Pos <<
" ] += " << ci.
q0 << std::endl;
1970 dout() <<
" q[ " << ci.
li_Neg <<
" ] += " << -ci.
q0 << std::endl;
2006 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
2008 dout() <<
" ----------------------------------" << std::endl;
2009 dout() <<
" Master::loadDAEMatrices: " << std::endl;
2018 dout() <<
" loads for capacitor " << ci.
getName() << std::endl;
2024 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
2040 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
2050 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
2113 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
2119 << expVarDerivs[i] << std::endl;
2178 .registerDevice(
"c", 1)
2179 .registerModelType(
"c", 1)
2180 .registerModelType(
"cap", 1);
2193 const std::string & name,
2194 std::vector<double> & dfdp,
2195 std::vector<double> & dqdp,
2196 std::vector<double> & dbdp,
2197 std::vector<int> & Findices,
2198 std::vector<int> & Qindices,
2199 std::vector<int> & Bindices
2206 double v_pos = solVec[in->
li_Pos];
2207 double v_neg = solVec[in->
li_Neg];
2208 double vcap = v_pos-v_neg;
2210 double dqdpLoc = vcap;
2217 Qindices[0] = in->
li_Pos;
2218 Qindices[1] = in->
li_Neg;
const InstanceName & getName() const
double * nextLeadCurrQCompRawPtr
bool loadDAEdQdx()
Load the DAE the derivative of the Q vector with respect to the solution vector x, dFdx.
bool updateDependentParameters()
virtual bool updateState(double *solVec, double *staVec, double *stoVec)
Update state for all capacitor instances, regardless of model.
const DeviceOptions & deviceOptions_
Descriptor & addPar(const char *parName, T default_value, T U::*varPtr)
Adds the parameter description to the parameter map.
double * daeQVectorRawPtr
bool processParams()
Process model parameters.
Linear::Vector * nextSolVectorPtr
std::vector< int > devConMap
bool given(const std::string ¶meter_name) const
double * fBraEquNegNodePtr
Pure virtual class to augment a linear system.
Parameter may be specified as time dependent expression from netlist.
bool loadDAEQVector()
Load the DAE Q vector.
void addInternalNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
std::vector< Instance * > instanceContainer
double * currStaVectorRawPtr
double * fBraEquPosNodePtr
bool processInstanceParams()
Process the instance parameters of instance owned by this model.
double baseCap
the baseline capacitance before aging
void setNumStoreVars(int num_store_vars)
void registerDevice()
Define how to use the device in a netlist.
void addBranchDataNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
void makeVector(const std::string &cname, int len)
Allows the parameter to be specified as a vector.
InstanceVector::const_iterator getInstanceEnd() const
Returns an iterator to the ending of the vector of all instances created for this device...
Base class for all parameters.
const std::vector< Depend > & getDependentParams()
virtual bool loadDAEVectors(double *solVec, double *fVec, double *qVec, double *bVec, double *storeLeadF, double *storeLeadQ, double *leadF, double *leadQ, double *junctionV)
Load DAE vectors of all capacitor instances, regardless of model.
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
Instance(const Configuration &configuration, const InstanceBlock &instance_block, Model &model, const FactoryBlock &factory_block)
Construct a Capacitor model from a "model block" that was created by the netlist parser.
void registerStoreLIDs(const std::vector< int > &stoLIDVecRef)
Register the local store IDs.
double * nextJunctionVCompRawPtr
double capacitanceMultiplier
bool updatePrimaryState()
Update the state variables.
double * storeLeadCurrQCompRawPtr
double * fNegEquBraNodePtr
std::vector< int > ANegEquDepVarOffsets
int getNumStoreVars() const
InstanceVector::const_iterator getInstanceBegin() const
Returns an iterator to the beginning of the vector of all instances created for this device...
std::vector< Param > params
Parameters from the line.
double * qPosEquPosNodePtr
void setParams(const std::vector< Param > ¶ms)
const std::string & getName() const
double * daeFVectorRawPtr
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
Create a new instance of the Capacitor device.
Util::Expression * expPtr
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
Register the local state IDs.
virtual void operator()(const ParameterBase &entity, const std::string &name, std::vector< double > &dfdp, std::vector< double > &dqdp, std::vector< double > &dbdp, std::vector< int > &Findices, std::vector< int > &Qindices, std::vector< int > &Bindices) const
const DeviceOptions & getDeviceOptions() const
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
Loads the parameter definition into the instance parameter map.
bool loadDAEdFdx()
Load the DAE the derivative of the F vector with respect to the solution vector x, dFdx.
static void loadModelParameters(ParametricData< Model > &model_parameters)
Loads the parameter definition into the model parameter map.
double * nextStoVectorRawPtr
double * fBraEquBraNodePtr
std::vector< int > li_dCdXState
int numBranchDataVarsIfAllocated
std::vector< int > li_dQdXState
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
static capSensitivity capSens
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
double * qNegEquNegNodePtr
Linear::Matrix * dFdxMatrixPtr
double * fPosEquBraNodePtr
The Device class is an interface for device implementations.
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
const SolverState & solverState_
double q0
charge in the capacitor
int li_Bra
for the "voltage source" when IC is specified
Class Configuration contains device configuration data.
std::vector< int > APosEquDepVarOffsets
bool processParams()
Process parameters.
std::vector< double > expVarDerivs
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
Register the Jacobian local IDs.
std::vector< double * > qPosEquDepVarsPtrs
const std::vector< std::vector< int > > & jacobianStamp() const
Return Jacobian stamp that informs topology of the layout of the resistor jacobian.
const SolverState & getSolverState() const
double * nextLeadCurrFCompRawPtr
bool updateTemperature(const double &temp_tmp)
Update the parameters that depend on the temperature of the device.
void setNumBranchDataVars(int num_branch_data_vars)
virtual std::ostream & printOutInstances(std::ostream &os) const
double * nextStaVectorRawPtr
#define Xyce_NONPOINTER_MATRIX_LOAD
std::vector< std::vector< int > > jacStamp_IC
std::vector< std::vector< int > > jacStamp
std::vector< double * > qNegEquDepVarsPtrs
double * qPosEquNegNodePtr
double * currSolVectorRawPtr
const ExternData & extData
void setupPointers()
Setup direct access pointer to solution matrix and vectors.
ModelBlock represents a .MODEL line from the netlist.
Parameter may be specified as a solution dependent expression from netlist.
Manages parameter binding for class C.
InstanceBlock represent a device instance line from the netlist.
bool loadDAEFVector()
Load the DAE F vector.
double ageCoef
degradation coeficient.
std::vector< Param > params
void registerBranchDataLIDs(const std::vector< int > &branchLIDVecRef)
Register the local store IDs.
Linear::Matrix * dQdxMatrixPtr
int li_branch_data
Index for lead current and junction voltage (for power calculations)
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
Register local IDs.
int getNumBranchDataVars() const
double * qNegEquPosNodePtr
const SolverState & getSolverState() const
Returns the solver state given during device construction.
void setModParams(const std::vector< Param > ¶ms)
double * nextSolVectorRawPtr
int numLeadCurrentStoreVars
virtual bool loadDAEMatrices(Linear::Matrix &dFdx, Linear::Matrix &dQdx)
Load DAE matrices for all capacitor instances, regardless of model.
void varTypes(std::vector< char > &varTypeVec)