47 #include <Xyce_config.h>
52 #include <N_UTL_Math.h>
63 #include <N_ERH_ErrorMgr.h>
64 #include <N_IO_mmio.h>
65 #include <N_LAS_Matrix.h>
66 #include <N_LAS_Vector.h>
67 #include <N_UTL_Expression.h>
68 #include <N_UTL_FeatureTest.h>
70 #include <Teuchos_BLAS.hpp>
71 #include <Teuchos_Utils.hpp>
72 #include <Teuchos_LAPACK.hpp>
77 #undef HAVE_INTTYPES_H
80 #include <Trilinos_Util.h>
96 .setDescription(
"length of line");
105 .setDescription(
"Resistance per unit length");
111 .setDescription(
"Inductance per unit length");
117 .setDescription(
"Conductance per unit length");
123 .setDescription(
"Capacitance per unit length");
183 Model & TransLineiter,
185 :
DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
186 model_(TransLineiter),
190 numLumpsGiven(false),
192 L(0.0),C(0.0),
G(0.0),R(0.0)
224 if (isActive(Diag::DEVICE_PARAMETERS))
226 std::cout <<
"model_.resist = " <<
model_.
resist <<std::endl;
227 std::cout <<
"model_.capac = " <<
model_.
capac <<std::endl;
228 std::cout <<
"model_.induct = " <<
model_.
induct <<std::endl;
230 std::cout <<
"R = " <<
R <<std::endl;
231 std::cout <<
"G = " <<
G <<std::endl;
232 std::cout <<
"C = " <<
C <<std::endl;
233 std::cout <<
"L = " <<
L <<std::endl;
237 std::cout <<
"RLC line" <<std::endl;
241 std::cout <<
"LC line" <<std::endl;
269 for (
int lump=0;lump<
numLumps;++lump)
272 lumpVec[lump].indexV1 = lump*varsPerLump;
273 lumpVec[lump].indexV2 = lump*varsPerLump+1;
274 lumpVec[lump].indexI = lump*varsPerLump+2;
275 lumpVec[lump].indexV3 = (lump+1)*varsPerLump;
280 if (isActive(Diag::DEVICE_PARAMETERS))
282 std::cout <<
"lumps = " << numLumps <<std::endl;
283 for (
int lump=0;lump<
numLumps;++lump)
285 std::cout <<
"lumpVec["<<lump<<
"]: v1 = " <<
lumpVec[lump].indexV1;
286 std::cout <<
" v2 = " <<
lumpVec[lump].indexV2;
287 std::cout <<
" i = " <<
lumpVec[lump].indexI ;
288 std::cout <<
" v3 = " <<
lumpVec[lump].indexV3;
289 std::cout << std::endl;
300 for (
int lump=0;lump<
numLumps;++lump)
309 lumpVec[numLumps-1].indexV3 = 1;
314 if (isActive(Diag::DEVICE_PARAMETERS))
316 std::cout <<
"lumps = " << numLumps <<std::endl;
317 for (
int lump=0;lump<
numLumps;++lump)
319 std::cout <<
"lumpVec["<<lump<<
"]: v1 = " <<
lumpVec[lump].indexV1;
320 std::cout <<
" v2 = " <<
lumpVec[lump].indexV2;
321 std::cout <<
" i = " <<
lumpVec[lump].indexI ;
322 std::cout <<
" v3 = " <<
lumpVec[lump].indexV3;
323 std::cout << std::endl;
334 int n1 =
lumpVec[lump].indexV1;
335 int n2 =
lumpVec[lump].indexV2;
337 int n3 =
lumpVec[lump].indexV3;
361 int n1 =
lumpVec[lump].indexV1;
362 int n2 =
lumpVec[lump].indexV2;
364 int n3 =
lumpVec[lump].indexV3;
388 for (
int lump=1;lump<numLumps-1;++lump)
390 int n1 =
lumpVec[lump].indexV1;
391 int n2 =
lumpVec[lump].indexV2;
393 int n3 =
lumpVec[lump].indexV3;
431 for (
int lump=0;lump<
numLumps;++lump)
434 lumpVec[lump].indexV1 = lump*varsPerLump;
435 lumpVec[lump].indexI = lump*varsPerLump+1;
436 lumpVec[lump].indexV2 = (lump+1)*varsPerLump;
441 if (isActive(Diag::DEVICE_PARAMETERS))
443 std::cout <<
"lumps = " << numLumps <<std::endl;
444 for (
int lump=0;lump<
numLumps;++lump)
446 std::cout <<
"lumpVec["<<lump<<
"]: v1 = " <<
lumpVec[lump].indexV1;
447 std::cout <<
" i = " <<
lumpVec[lump].indexI ;
448 std::cout <<
" v2 = " <<
lumpVec[lump].indexV2;
449 std::cout << std::endl;
460 for (
int lump=0;lump<
numLumps;++lump)
468 lumpVec[numLumps-1].indexV2 = 1;
473 if (isActive(Diag::DEVICE_PARAMETERS))
475 std::cout <<
"lumps = " << numLumps <<std::endl;
476 for (
int lump=0;lump<
numLumps;++lump)
478 std::cout <<
"lumpVec["<<lump<<
"]: v1 = " <<
lumpVec[lump].indexV1;
479 std::cout <<
" i = " <<
lumpVec[lump].indexI ;
480 std::cout <<
" v2 = " <<
lumpVec[lump].indexV2;
481 std::cout << std::endl;
492 int n1 =
lumpVec[lump].indexV1;
493 int n2 =
lumpVec[lump].indexV2;
515 int n1 =
lumpVec[lump].indexV1;
516 int n2 =
lumpVec[lump].indexV2;
535 for (
int lump=1;lump<numLumps-1;++lump)
537 int n1 =
lumpVec[lump].indexV1;
538 int n2 =
lumpVec[lump].indexV2;
555 if (isActive(Diag::DEVICE_PARAMETERS))
558 for (
int i=0; i<size; ++i)
561 for (
int j=0;j<sizeJ;++j)
563 std::cout <<
"jacStamp["<<i<<
"]["<<j<<
"] = " <<
jacStamp[i][j];
564 std::cout << std::endl;
596 const std::vector<int> & extLIDVecRef)
613 lumpVec[0].li_V2 = intLIDVec[lid++];
614 lumpVec[0].li_I = intLIDVec[lid++];
620 lumpVec[i].li_V1 = intLIDVec[lid++];
621 lumpVec[i].li_V2 = intLIDVec[lid++];
622 lumpVec[i].li_I = intLIDVec[lid++];
625 lumpVec[numLumps-1].li_V1 = intLIDVec[lid++];
626 lumpVec[numLumps-1].li_V2 = intLIDVec[lid++];
627 lumpVec[numLumps-1].li_I = intLIDVec[lid++];
629 for (
int i=0;i<numLumps-1;++i)
641 lumpVec[0].li_I = intLIDVec[lid++];
647 lumpVec[i].li_V1 = intLIDVec[lid++];
648 lumpVec[i].li_I = intLIDVec[lid++];
651 lumpVec[numLumps-1].li_V1 = intLIDVec[lid++];
652 lumpVec[numLumps-1].li_I = intLIDVec[lid++];
654 for (
int i=0;i<numLumps-1;++i)
663 if (isActive(Diag::DEVICE_PARAMETERS))
667 std::cout <<
"intLIDVec["<<i<<
"] = " << intLIDVec[i] << std::endl;
674 std::cout <<
"lumpVec["<<i<<
"].li_V1 = " <<
lumpVec[i].li_V1 <<std::endl;
675 std::cout <<
"lumpVec["<<i<<
"].li_V2 = " <<
lumpVec[i].li_V2 <<std::endl;
676 std::cout <<
"lumpVec["<<i<<
"].li_I = " <<
lumpVec[i].li_I <<std::endl;
677 std::cout <<
"lumpVec["<<i<<
"].li_V3 = " <<
lumpVec[i].li_V3 <<std::endl;
684 std::cout <<
"lumpVec["<<i<<
"].li_V1 = " <<
lumpVec[i].li_V1 <<std::endl;
685 std::cout <<
"lumpVec["<<i<<
"].li_I = " <<
lumpVec[i].li_I <<std::endl;
686 std::cout <<
"lumpVec["<<i<<
"].li_V2 = " <<
lumpVec[i].li_V2 <<std::endl;
769 int n1 =
lumpVec[lump].indexV1;
770 int n2 =
lumpVec[lump].indexV2;
772 int n3 =
lumpVec[lump].indexV3;
774 lumpVec[lump].offset_v1_ii = jacLIDVec[n1][0];
776 lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][0];
777 lumpVec[lump].offset_v2_ii = jacLIDVec[n2][1];
778 lumpVec[lump].offset_v2_v3 = jacLIDVec[n2][2];
780 lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
781 lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][1];
782 lumpVec[lump].offset_ii_ii = jacLIDVec[ii][2];
786 lumpVec[lump].offset_v3_v2 = jacLIDVec[n3][0];
787 lumpVec[lump].offset_v3_v3 = jacLIDVec[n3][1];
794 int n1 =
lumpVec[lump].indexV1;
795 int n2 =
lumpVec[lump].indexV2;
797 int n3 =
lumpVec[lump].indexV3;
799 lumpVec[lump].offset_v1_v2m1 = jacLIDVec[n1][0];
800 lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
801 lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
803 lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][0];
804 lumpVec[lump].offset_v2_ii = jacLIDVec[n2][1];
805 lumpVec[lump].offset_v2_v3 = jacLIDVec[n2][2];
807 lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
808 lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][1];
809 lumpVec[lump].offset_ii_ii = jacLIDVec[ii][2];
811 lumpVec[lump].offset_v3_v2 = jacLIDVec[n3][0];
812 lumpVec[lump].offset_v3_v3 = jacLIDVec[n3][1];
816 for (
int lump=1;lump<
numLumps-1;++lump)
818 int n1 =
lumpVec[lump].indexV1;
819 int n2 =
lumpVec[lump].indexV2;
821 int n3 =
lumpVec[lump].indexV3;
823 lumpVec[lump].offset_v1_v2m1 = jacLIDVec[n1][0];
824 lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
825 lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
827 lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][0];
828 lumpVec[lump].offset_v2_ii = jacLIDVec[n2][1];
829 lumpVec[lump].offset_v2_v3 = jacLIDVec[n2][2];
831 lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
832 lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][1];
833 lumpVec[lump].offset_ii_ii = jacLIDVec[ii][2];
837 for (
int lump=0; lump<numLumps-1; ++lump)
848 int n1 =
lumpVec[lump].indexV1;
849 int n2 =
lumpVec[lump].indexV2;
852 lumpVec[lump].offset_v1_ii = jacLIDVec[n1][0];
854 lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
855 lumpVec[lump].offset_ii_ii = jacLIDVec[ii][1];
856 lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][2];
860 lumpVec[lump].offset_v2_ii = jacLIDVec[n2][0];
861 lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][1];
868 int n1 =
lumpVec[lump].indexV1;
869 int n2 =
lumpVec[lump].indexV2;
872 lumpVec[lump].offset_v1_iim1 = jacLIDVec[n1][0];
873 lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
874 lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
876 lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
877 lumpVec[lump].offset_ii_ii = jacLIDVec[ii][1];
878 lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][2];
880 lumpVec[lump].offset_v2_ii = jacLIDVec[n2][0];
881 lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][1];
885 for (
int lump=1;lump<
numLumps-1;++lump)
887 int n1 =
lumpVec[lump].indexV1;
888 int n2 =
lumpVec[lump].indexV2;
891 lumpVec[lump].offset_v1_iim1 = jacLIDVec[n1][0];
892 lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
893 lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
895 lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
896 lumpVec[lump].offset_ii_ii = jacLIDVec[ii][1];
897 lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][2];
901 for (
int lump=0; lump<numLumps-1; ++lump)
911 if (isActive(Diag::DEVICE_PARAMETERS))
917 std::cout <<
"lump = " << i <<std::endl;
919 std::cout <<
"offset_v1_v2m1 = " <<
lumpVec[i].offset_v1_v2m1 << std::endl;
920 std::cout <<
"offset_v1_v1 = " <<
lumpVec[i].offset_v1_v1 << std::endl;
921 std::cout <<
"offset_v1_ii = " <<
lumpVec[i].offset_v1_ii << std::endl;
924 std::cout <<
"offset_v2_v2 = " <<
lumpVec[i].offset_v2_v2 << std::endl;
925 std::cout <<
"offset_v2_ii = " <<
lumpVec[i].offset_v2_ii << std::endl;
926 std::cout <<
"offset_v2_v3 = " <<
lumpVec[i].offset_v2_v3 << std::endl;
929 std::cout <<
"offset_ii_v1 = " <<
lumpVec[i].offset_ii_v1 << std::endl;
930 std::cout <<
"offset_ii_v2 = " <<
lumpVec[i].offset_ii_v2 << std::endl;
931 std::cout <<
"offset_ii_ii = " <<
lumpVec[i].offset_ii_ii << std::endl;
933 std::cout <<
"offset_v3_v2 = " <<
lumpVec[i].offset_v3_v2 << std::endl;
934 std::cout <<
"offset_v3_v3 = " <<
lumpVec[i].offset_v3_v3 << std::endl;
941 std::cout <<
"lump = " << i <<std::endl;
943 std::cout <<
"offset_v1_iim1 = " <<
lumpVec[i].offset_v1_iim1 << std::endl;
944 std::cout <<
"offset_v1_v1 = " <<
lumpVec[i].offset_v1_v1 << std::endl;
945 std::cout <<
"offset_v1_ii = " <<
lumpVec[i].offset_v1_ii << std::endl;
947 std::cout <<
"offset_ii_v1 = " <<
lumpVec[i].offset_ii_v1 << std::endl;
948 std::cout <<
"offset_ii_ii = " <<
lumpVec[i].offset_ii_ii << std::endl;
949 std::cout <<
"offset_ii_v2 = " <<
lumpVec[i].offset_ii_v2 << std::endl;
951 std::cout <<
"offset_v2_ii = " <<
lumpVec[i].offset_v2_ii << std::endl;
952 std::cout <<
"offset_v2_v2 = " <<
lumpVec[i].offset_v2_v2 << std::endl;
970 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
990 double current = solVec[
lumpVec[i].li_I];
991 double v_pos = solVec[lumpVec[i].li_V1];
992 double v_neg = solVec[lumpVec[i].li_V2];
993 double vind = v_pos-v_neg;
994 lumpVec[i].i0_ind = current;
995 lumpVec[i].f0_ind =
L*current;
996 lumpVec[i].coef_ind = -vind;
999 v_pos = solVec[lumpVec[i].li_V2];
1000 v_neg = solVec[lumpVec[i].li_V3];
1001 lumpVec[i].i0_res = (v_pos-v_neg)*
G;
1004 double vcap = solVec[lumpVec[i].li_V3];
1005 lumpVec[i].q0_cap =
C*vcap;
1013 double current = solVec[
lumpVec[i].li_I];
1014 double v_pos = solVec[lumpVec[i].li_V1];
1015 double v_neg = solVec[lumpVec[i].li_V2];
1016 double vind = v_pos-v_neg;
1017 lumpVec[i].i0_ind = current;
1018 lumpVec[i].f0_ind =
L*current;
1019 lumpVec[i].coef_ind = -vind;
1022 double vcap = solVec[lumpVec[i].li_V2];
1023 lumpVec[i].q0_cap =
C*vcap;
1067 qVec[
lumpVec[i].li_I] += lumpVec[i].f0_ind;
1068 qVec[lumpVec[i].li_V3] += lumpVec[i].q0_cap;
1075 qVec[
lumpVec[i].li_I] += lumpVec[i].f0_ind;
1076 qVec[lumpVec[i].li_V2] += lumpVec[i].q0_cap;
1103 fVec[
lumpVec[i].li_V1] += lumpVec[i].i0_ind;
1104 fVec[lumpVec[i].li_V2] += -lumpVec[i].i0_ind;
1105 fVec[lumpVec[i].li_I ] += lumpVec[i].coef_ind;
1108 fVec[lumpVec[i].li_V2] += lumpVec[i].i0_res;
1109 fVec[lumpVec[i].li_V3] -= lumpVec[i].i0_res;
1117 fVec[
lumpVec[i].li_V1] += lumpVec[i].i0_ind;
1118 fVec[lumpVec[i].li_V2] += -lumpVec[i].i0_ind;
1119 fVec[lumpVec[i].li_I ] += lumpVec[i].coef_ind;
1152 dQdx[lumpVec[i].li_V3][lumpVec[i].offset_v3_v3] +=
C;
1163 dQdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_v2] +=
C;
1192 dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_ii] -= 1.0;
1193 dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v1] -= 1.0;
1194 dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v2] += 1.0;
1197 dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_v2] +=
G;
1198 dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_v3] -=
G;
1199 dFdx[lumpVec[i].li_V3][lumpVec[i].offset_v3_v2] -=
G;
1200 dFdx[lumpVec[i].li_V3][lumpVec[i].offset_v3_v3] +=
G;
1209 dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_ii] -= 1.0;
1210 dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v1] -= 1.0;
1211 dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v2] += 1.0;
1256 std::vector<Instance*>::iterator iter;
1260 for (iter=first; iter!=last; ++iter)
1262 (*iter)->processParams();
1281 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
1288 elevNumberGiven(false),
1291 conductGiven(false),
1320 std::vector<Instance*>::iterator iter;
1324 for (iter=first; iter!=last; ++iter)
1342 std::vector<Instance*>::const_iterator iter;
1350 os <<
"Number of TransLine instances: " << isize << std::endl;
1351 os <<
" name\t\tmodelName\tParameters" << std::endl;
1353 for (i = 0, iter = first; iter != last; ++iter, ++i)
1355 os <<
" " << i <<
": " << (*iter)->getName() <<
"\t";
1381 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1396 .registerDevice(
"transline", 1)
1397 .registerModelType(
"transline", 1);
const InstanceName & getName() const
bool updateTemperature(const double &temp_tmp)
virtual std::ostream & printOutInstances(std::ostream &os) const
bool updateDependentParameters()
const SolverState & solverState_
void varTypes(std::vector< char > &varTypeVec)
Descriptor & addPar(const char *parName, T default_value, T U::*varPtr)
Adds the parameter description to the parameter map.
double * daeQVectorRawPtr
bool updatePrimaryState()
void G(const ScalarT &V1, const ScalarT &V2, const ScalarT &Ap, const ScalarT &An, ScalarT &Vp, ScalarT &Vn, ScalarT &fval)
Pure virtual class to augment a linear system.
const std::vector< std::vector< int > > & jacobianStamp() const
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
void addInternalNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
bool processInstanceParams()
processInstanceParams
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
bool updateIntermediateVars()
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
static void loadModelParameters(ParametricData< Model > &model_parameters)
std::vector< Param > params
Parameters from the line.
void setParams(const std::vector< Param > ¶ms)
const std::string & getName() const
double * daeFVectorRawPtr
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
std::vector< std::vector< int > > jacStamp
const DeviceOptions & deviceOptions_
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
Linear::Matrix * dFdxMatrixPtr
bool processParams()
processParams
The Device class is an interface for device implementations.
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &Citer, const FactoryBlock &factory_block)
std::vector< Instance * > instanceContainer
Class Configuration contains device configuration data.
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
std::vector< lumpData > lumpVec
const ExternData & extData
ModelBlock represents a .MODEL line from the netlist.
Manages parameter binding for class C.
InstanceBlock represent a device instance line from the netlist.
std::vector< Param > params
Linear::Matrix * dQdxMatrixPtr
void setModParams(const std::vector< Param > ¶ms)
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
double * nextSolVectorRawPtr