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");
167 Model & TransLineiter,
169 :
DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
170 model_(TransLineiter),
174 numLumpsGiven(false),
176 L(0.0),C(0.0),G(0.0),R(0.0)
225 if (isActive(Diag::DEVICE_PARAMETERS))
227 std::cout <<
"model_.resist = " <<
model_.
resist <<std::endl;
228 std::cout <<
"model_.capac = " <<
model_.
capac <<std::endl;
229 std::cout <<
"model_.induct = " <<
model_.
induct <<std::endl;
231 std::cout <<
"R = " <<
R <<std::endl;
232 std::cout <<
"G = " <<
G <<std::endl;
233 std::cout <<
"C = " <<
C <<std::endl;
234 std::cout <<
"L = " <<
L <<std::endl;
238 std::cout <<
"RLC line" <<std::endl;
242 std::cout <<
"LC line" <<std::endl;
270 for (
int lump=0;lump<
numLumps;++lump)
273 lumpVec[lump].indexV1 = lump*varsPerLump;
274 lumpVec[lump].indexV2 = lump*varsPerLump+1;
275 lumpVec[lump].indexI = lump*varsPerLump+2;
276 lumpVec[lump].indexV3 = (lump+1)*varsPerLump;
281 if (isActive(Diag::DEVICE_PARAMETERS))
283 std::cout <<
"lumps = " << numLumps <<std::endl;
284 for (
int lump=0;lump<
numLumps;++lump)
286 std::cout <<
"lumpVec["<<lump<<
"]: v1 = " <<
lumpVec[lump].indexV1;
287 std::cout <<
" v2 = " <<
lumpVec[lump].indexV2;
288 std::cout <<
" i = " <<
lumpVec[lump].indexI ;
289 std::cout <<
" v3 = " <<
lumpVec[lump].indexV3;
290 std::cout << std::endl;
301 for (
int lump=0;lump<
numLumps;++lump)
310 lumpVec[numLumps-1].indexV3 = 1;
315 if (isActive(Diag::DEVICE_PARAMETERS))
317 std::cout <<
"lumps = " << numLumps <<std::endl;
318 for (
int lump=0;lump<
numLumps;++lump)
320 std::cout <<
"lumpVec["<<lump<<
"]: v1 = " <<
lumpVec[lump].indexV1;
321 std::cout <<
" v2 = " <<
lumpVec[lump].indexV2;
322 std::cout <<
" i = " <<
lumpVec[lump].indexI ;
323 std::cout <<
" v3 = " <<
lumpVec[lump].indexV3;
324 std::cout << std::endl;
335 int n1 =
lumpVec[lump].indexV1;
336 int n2 =
lumpVec[lump].indexV2;
338 int n3 =
lumpVec[lump].indexV3;
362 int n1 =
lumpVec[lump].indexV1;
363 int n2 =
lumpVec[lump].indexV2;
365 int n3 =
lumpVec[lump].indexV3;
389 for (
int lump=1;lump<numLumps-1;++lump)
391 int n1 =
lumpVec[lump].indexV1;
392 int n2 =
lumpVec[lump].indexV2;
394 int n3 =
lumpVec[lump].indexV3;
432 for (
int lump=0;lump<
numLumps;++lump)
435 lumpVec[lump].indexV1 = lump*varsPerLump;
436 lumpVec[lump].indexI = lump*varsPerLump+1;
437 lumpVec[lump].indexV2 = (lump+1)*varsPerLump;
442 if (isActive(Diag::DEVICE_PARAMETERS))
444 std::cout <<
"lumps = " << numLumps <<std::endl;
445 for (
int lump=0;lump<
numLumps;++lump)
447 std::cout <<
"lumpVec["<<lump<<
"]: v1 = " <<
lumpVec[lump].indexV1;
448 std::cout <<
" i = " <<
lumpVec[lump].indexI ;
449 std::cout <<
" v2 = " <<
lumpVec[lump].indexV2;
450 std::cout << std::endl;
461 for (
int lump=0;lump<
numLumps;++lump)
469 lumpVec[numLumps-1].indexV2 = 1;
474 if (isActive(Diag::DEVICE_PARAMETERS))
476 std::cout <<
"lumps = " << numLumps <<std::endl;
477 for (
int lump=0;lump<
numLumps;++lump)
479 std::cout <<
"lumpVec["<<lump<<
"]: v1 = " <<
lumpVec[lump].indexV1;
480 std::cout <<
" i = " <<
lumpVec[lump].indexI ;
481 std::cout <<
" v2 = " <<
lumpVec[lump].indexV2;
482 std::cout << std::endl;
493 int n1 =
lumpVec[lump].indexV1;
494 int n2 =
lumpVec[lump].indexV2;
516 int n1 =
lumpVec[lump].indexV1;
517 int n2 =
lumpVec[lump].indexV2;
536 for (
int lump=1;lump<numLumps-1;++lump)
538 int n1 =
lumpVec[lump].indexV1;
539 int n2 =
lumpVec[lump].indexV2;
556 if (isActive(Diag::DEVICE_PARAMETERS))
559 for (
int i=0; i<size; ++i)
562 for (
int j=0;j<sizeJ;++j)
564 std::cout <<
"jacStamp["<<i<<
"]["<<j<<
"] = " <<
jacStamp[i][j];
565 std::cout << std::endl;
597 const std::vector<int> & extLIDVecRef)
614 lumpVec[0].li_V2 = intLIDVec[lid++];
615 lumpVec[0].li_I = intLIDVec[lid++];
621 lumpVec[i].li_V1 = intLIDVec[lid++];
622 lumpVec[i].li_V2 = intLIDVec[lid++];
623 lumpVec[i].li_I = intLIDVec[lid++];
626 lumpVec[numLumps-1].li_V1 = intLIDVec[lid++];
627 lumpVec[numLumps-1].li_V2 = intLIDVec[lid++];
628 lumpVec[numLumps-1].li_I = intLIDVec[lid++];
630 for (
int i=0;i<numLumps-1;++i)
642 lumpVec[0].li_I = intLIDVec[lid++];
648 lumpVec[i].li_V1 = intLIDVec[lid++];
649 lumpVec[i].li_I = intLIDVec[lid++];
652 lumpVec[numLumps-1].li_V1 = intLIDVec[lid++];
653 lumpVec[numLumps-1].li_I = intLIDVec[lid++];
655 for (
int i=0;i<numLumps-1;++i)
664 if (isActive(Diag::DEVICE_PARAMETERS))
668 std::cout <<
"intLIDVec["<<i<<
"] = " << intLIDVec[i] << std::endl;
675 std::cout <<
"lumpVec["<<i<<
"].li_V1 = " <<
lumpVec[i].li_V1 <<std::endl;
676 std::cout <<
"lumpVec["<<i<<
"].li_V2 = " <<
lumpVec[i].li_V2 <<std::endl;
677 std::cout <<
"lumpVec["<<i<<
"].li_I = " <<
lumpVec[i].li_I <<std::endl;
678 std::cout <<
"lumpVec["<<i<<
"].li_V3 = " <<
lumpVec[i].li_V3 <<std::endl;
685 std::cout <<
"lumpVec["<<i<<
"].li_V1 = " <<
lumpVec[i].li_V1 <<std::endl;
686 std::cout <<
"lumpVec["<<i<<
"].li_I = " <<
lumpVec[i].li_I <<std::endl;
687 std::cout <<
"lumpVec["<<i<<
"].li_V2 = " <<
lumpVec[i].li_V2 <<std::endl;
770 int n1 =
lumpVec[lump].indexV1;
771 int n2 =
lumpVec[lump].indexV2;
773 int n3 =
lumpVec[lump].indexV3;
775 lumpVec[lump].offset_v1_ii = jacLIDVec[n1][0];
777 lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][0];
778 lumpVec[lump].offset_v2_ii = jacLIDVec[n2][1];
779 lumpVec[lump].offset_v2_v3 = jacLIDVec[n2][2];
781 lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
782 lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][1];
783 lumpVec[lump].offset_ii_ii = jacLIDVec[ii][2];
787 lumpVec[lump].offset_v3_v2 = jacLIDVec[n3][0];
788 lumpVec[lump].offset_v3_v3 = jacLIDVec[n3][1];
795 int n1 =
lumpVec[lump].indexV1;
796 int n2 =
lumpVec[lump].indexV2;
798 int n3 =
lumpVec[lump].indexV3;
800 lumpVec[lump].offset_v1_v2m1 = jacLIDVec[n1][0];
801 lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
802 lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
804 lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][0];
805 lumpVec[lump].offset_v2_ii = jacLIDVec[n2][1];
806 lumpVec[lump].offset_v2_v3 = jacLIDVec[n2][2];
808 lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
809 lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][1];
810 lumpVec[lump].offset_ii_ii = jacLIDVec[ii][2];
812 lumpVec[lump].offset_v3_v2 = jacLIDVec[n3][0];
813 lumpVec[lump].offset_v3_v3 = jacLIDVec[n3][1];
817 for (
int lump=1;lump<
numLumps-1;++lump)
819 int n1 =
lumpVec[lump].indexV1;
820 int n2 =
lumpVec[lump].indexV2;
822 int n3 =
lumpVec[lump].indexV3;
824 lumpVec[lump].offset_v1_v2m1 = jacLIDVec[n1][0];
825 lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
826 lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
828 lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][0];
829 lumpVec[lump].offset_v2_ii = jacLIDVec[n2][1];
830 lumpVec[lump].offset_v2_v3 = jacLIDVec[n2][2];
832 lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
833 lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][1];
834 lumpVec[lump].offset_ii_ii = jacLIDVec[ii][2];
838 for (
int lump=0; lump<numLumps-1; ++lump)
849 int n1 =
lumpVec[lump].indexV1;
850 int n2 =
lumpVec[lump].indexV2;
853 lumpVec[lump].offset_v1_ii = jacLIDVec[n1][0];
855 lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
856 lumpVec[lump].offset_ii_ii = jacLIDVec[ii][1];
857 lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][2];
861 lumpVec[lump].offset_v2_ii = jacLIDVec[n2][0];
862 lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][1];
869 int n1 =
lumpVec[lump].indexV1;
870 int n2 =
lumpVec[lump].indexV2;
873 lumpVec[lump].offset_v1_iim1 = jacLIDVec[n1][0];
874 lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
875 lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
877 lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
878 lumpVec[lump].offset_ii_ii = jacLIDVec[ii][1];
879 lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][2];
881 lumpVec[lump].offset_v2_ii = jacLIDVec[n2][0];
882 lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][1];
886 for (
int lump=1;lump<
numLumps-1;++lump)
888 int n1 =
lumpVec[lump].indexV1;
889 int n2 =
lumpVec[lump].indexV2;
892 lumpVec[lump].offset_v1_iim1 = jacLIDVec[n1][0];
893 lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
894 lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
896 lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
897 lumpVec[lump].offset_ii_ii = jacLIDVec[ii][1];
898 lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][2];
902 for (
int lump=0; lump<numLumps-1; ++lump)
912 if (isActive(Diag::DEVICE_PARAMETERS))
918 std::cout <<
"lump = " << i <<std::endl;
920 std::cout <<
"offset_v1_v2m1 = " <<
lumpVec[i].offset_v1_v2m1 << std::endl;
921 std::cout <<
"offset_v1_v1 = " <<
lumpVec[i].offset_v1_v1 << std::endl;
922 std::cout <<
"offset_v1_ii = " <<
lumpVec[i].offset_v1_ii << std::endl;
925 std::cout <<
"offset_v2_v2 = " <<
lumpVec[i].offset_v2_v2 << std::endl;
926 std::cout <<
"offset_v2_ii = " <<
lumpVec[i].offset_v2_ii << std::endl;
927 std::cout <<
"offset_v2_v3 = " <<
lumpVec[i].offset_v2_v3 << std::endl;
930 std::cout <<
"offset_ii_v1 = " <<
lumpVec[i].offset_ii_v1 << std::endl;
931 std::cout <<
"offset_ii_v2 = " <<
lumpVec[i].offset_ii_v2 << std::endl;
932 std::cout <<
"offset_ii_ii = " <<
lumpVec[i].offset_ii_ii << std::endl;
934 std::cout <<
"offset_v3_v2 = " <<
lumpVec[i].offset_v3_v2 << std::endl;
935 std::cout <<
"offset_v3_v3 = " <<
lumpVec[i].offset_v3_v3 << std::endl;
942 std::cout <<
"lump = " << i <<std::endl;
944 std::cout <<
"offset_v1_iim1 = " <<
lumpVec[i].offset_v1_iim1 << std::endl;
945 std::cout <<
"offset_v1_v1 = " <<
lumpVec[i].offset_v1_v1 << std::endl;
946 std::cout <<
"offset_v1_ii = " <<
lumpVec[i].offset_v1_ii << std::endl;
948 std::cout <<
"offset_ii_v1 = " <<
lumpVec[i].offset_ii_v1 << std::endl;
949 std::cout <<
"offset_ii_ii = " <<
lumpVec[i].offset_ii_ii << std::endl;
950 std::cout <<
"offset_ii_v2 = " <<
lumpVec[i].offset_ii_v2 << std::endl;
952 std::cout <<
"offset_v2_ii = " <<
lumpVec[i].offset_v2_ii << std::endl;
953 std::cout <<
"offset_v2_v2 = " <<
lumpVec[i].offset_v2_v2 << std::endl;
971 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
991 double current = solVec[
lumpVec[i].li_I];
992 double v_pos = solVec[lumpVec[i].li_V1];
993 double v_neg = solVec[lumpVec[i].li_V2];
994 double vind = v_pos-v_neg;
995 lumpVec[i].i0_ind = current;
996 lumpVec[i].f0_ind =
L*current;
997 lumpVec[i].coef_ind = -vind;
1000 v_pos = solVec[lumpVec[i].li_V2];
1001 v_neg = solVec[lumpVec[i].li_V3];
1002 lumpVec[i].i0_res = (v_pos-v_neg)*
G;
1005 double vcap = solVec[lumpVec[i].li_V3];
1006 lumpVec[i].q0_cap =
C*vcap;
1014 double current = solVec[
lumpVec[i].li_I];
1015 double v_pos = solVec[lumpVec[i].li_V1];
1016 double v_neg = solVec[lumpVec[i].li_V2];
1017 double vind = v_pos-v_neg;
1018 lumpVec[i].i0_ind = current;
1019 lumpVec[i].f0_ind =
L*current;
1020 lumpVec[i].coef_ind = -vind;
1023 double vcap = solVec[lumpVec[i].li_V2];
1024 lumpVec[i].q0_cap =
C*vcap;
1068 qVec[
lumpVec[i].li_I] += lumpVec[i].f0_ind;
1069 qVec[lumpVec[i].li_V3] += lumpVec[i].q0_cap;
1076 qVec[
lumpVec[i].li_I] += lumpVec[i].f0_ind;
1077 qVec[lumpVec[i].li_V2] += lumpVec[i].q0_cap;
1104 fVec[
lumpVec[i].li_V1] += lumpVec[i].i0_ind;
1105 fVec[lumpVec[i].li_V2] += -lumpVec[i].i0_ind;
1106 fVec[lumpVec[i].li_I ] += lumpVec[i].coef_ind;
1109 fVec[lumpVec[i].li_V2] += lumpVec[i].i0_res;
1110 fVec[lumpVec[i].li_V3] -= lumpVec[i].i0_res;
1118 fVec[
lumpVec[i].li_V1] += lumpVec[i].i0_ind;
1119 fVec[lumpVec[i].li_V2] += -lumpVec[i].i0_ind;
1120 fVec[lumpVec[i].li_I ] += lumpVec[i].coef_ind;
1153 dQdx[lumpVec[i].li_V3][lumpVec[i].offset_v3_v3] +=
C;
1164 dQdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_v2] +=
C;
1193 dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_ii] -= 1.0;
1194 dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v1] -= 1.0;
1195 dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v2] += 1.0;
1198 dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_v2] +=
G;
1199 dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_v3] -=
G;
1200 dFdx[lumpVec[i].li_V3][lumpVec[i].offset_v3_v2] -=
G;
1201 dFdx[lumpVec[i].li_V3][lumpVec[i].offset_v3_v3] +=
G;
1210 dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_ii] -= 1.0;
1211 dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v1] -= 1.0;
1212 dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v2] += 1.0;
1257 std::vector<Instance*>::iterator iter;
1261 for (iter=first; iter!=last; ++iter)
1263 (*iter)->processParams();
1282 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
1289 elevNumberGiven(false),
1292 conductGiven(false),
1321 std::vector<Instance*>::iterator iter;
1325 for (iter=first; iter!=last; ++iter)
1343 std::vector<Instance*>::const_iterator iter;
1351 os <<
"Number of TransLine instances: " << isize << std::endl;
1352 os <<
" name\t\tmodelName\tParameters" << std::endl;
1354 for (i = 0, iter = first; iter != last; ++iter, ++i)
1356 os <<
" " << i <<
": " << (*iter)->getName() <<
"\t";
1382 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1397 .registerDevice(
"transline", 1)
1398 .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()
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