45 #include <Xyce_config.h>
48 #include <N_UTL_Misc.h>
67 #include <N_ERH_ErrorMgr.h>
69 #include <N_LAS_Vector.h>
70 #include <N_LAS_Matrix.h>
72 #include <N_UTL_Expression.h>
100 APosEquBraVarOffset(-1),
101 ANegEquBraVarOffset(-1),
102 ABraEquPosNodeOffset(-1),
103 ABraEquNegNodeOffset(-1),
104 ABraEquBraVarOffset(-1),
110 f_PosEquBraVarPtr(0),
111 f_NegEquBraVarPtr(0),
112 f_BraEquPosNodePtr(0),
113 f_BraEquNegNodePtr(0),
114 f_BraEquBraVarPtr(0),
119 q_PosEquBraVarPtr(0),
120 q_NegEquBraVarPtr(0),
121 q_BraEquPosNodePtr(0),
122 q_BraEquNegNodePtr(0),
123 q_BraEquBraVarPtr(0),
131 namespace MutIndLin {
186 :
DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
190 mutualCupGiven(false),
192 temp(getDeviceOptions().temp.getImmutableValue<double>()),
257 int indexInductorOne = -1;
258 int indexInductorTwo = -1;
263 indexInductorOne = j;
267 indexInductorTwo = j;
269 if( indexInductorOne != -1 && indexInductorTwo != -1 )
294 #ifdef Xyce_DEBUG_DEVICE
297 Xyce::dout() <<
"mutualCouplingCoef: " << std::endl;
304 Xyce::dout() << std::endl;
310 dIdt.resize( numInductors );
313 LOI.resize( numInductors );
314 LO.resize( numInductors );
317 LO[i].resize( numInductors );
360 jacStamp.resize( 3 * numInductors );
365 jacStamp[2*numInductors + i].resize(numInductors + 2);
367 jacStamp[2*i ][0] = 2*numInductors + i;
368 jacStamp[2*i+1][0] = 2*numInductors + i;
369 jacStamp[2*numInductors + i][0] = 2*i;
370 jacStamp[2*numInductors + i][1] = 2*i + 1;
373 jacStamp[2*numInductors + i][j+2] = 2*numInductors + j;
382 std::vector<sDepend>::iterator d;
386 for (d=begin; d != end; ++d)
389 if (d->name ==
"COUPLING" && d->vectorIndex != -1)
399 expPtrs[d->vectorIndex] = d->expr;
402 int indexInductorOne =
indexPairs[d->vectorIndex].first;
403 int indexInductorTwo =
indexPairs[d->vectorIndex].second;
406 int inductorOneBranchSize =
jacStamp[2*numInductors+
407 indexInductorOne].size();
408 int inductorTwoBranchSize =
jacStamp[2*numInductors+
409 indexInductorTwo].size();
410 jacStamp[2*numInductors+indexInductorOne].resize(inductorOneBranchSize+
412 jacStamp[2*numInductors+indexInductorTwo].resize(inductorTwoBranchSize+
414 for (
int i=0; i<d->n_vars; i++)
416 jacStamp[2*numInductors+indexInductorOne][inductorOneBranchSize+i]
418 jacStamp[2*numInductors+indexInductorTwo][inductorTwoBranchSize+i]
428 std::pair<int,int>(d->vectorIndex,i));
430 std::pair<int,int>(d->vectorIndex,i));
436 std::string msg=
"Error in mutual inductor constructor for ";
438 msg +=
": Found a dependent parameter that fails sanity check.";
439 msg +=
"Name:" + d->name +
" ";
440 msg +=
"Value: " + (d->expr)->get_expression() +
" ";
441 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
453 #ifdef Xyce_DEBUG_DEVICE
456 Xyce::dout() <<
"Instance::Instance-----------------" << std::endl;
457 Xyce::dout() <<
"numExtVars = " <<
numExtVars << std::endl
460 <<
"numInductors = " << numInductors << std::endl
461 <<
"jacStamp = " << std::endl;
462 for(
int i = 0; i<
jacStamp.size(); ++i )
464 Xyce::dout() <<
"jacStamp[ " << i <<
" ] = { ";
465 for(
int j=0; j<
jacStamp[i].size(); ++j)
468 if( j != (
jacStamp[i].size() -1 ) )
470 Xyce::dout() <<
", ";
473 Xyce::dout() <<
" }" << std::endl;
490 std::vector< InductorInstanceData* >::iterator currentInductor =
instanceData.begin();
491 std::vector< InductorInstanceData* >::iterator endInductor =
instanceData.end();
492 for ( ; currentInductor != endInductor ; ++currentInductor)
494 delete *currentInductor;
507 const std::vector<int> & extLIDVecRef)
520 std::vector< InductorInstanceData* >::iterator currentInductor =
instanceData.begin();
521 std::vector< InductorInstanceData* >::iterator endInductor =
instanceData.end();
524 while( currentInductor != endInductor )
526 (*currentInductor)->li_Pos =
extLIDVec[ i++ ];
527 (*currentInductor)->li_Neg =
extLIDVec[ i++ ];
528 (*currentInductor)->li_Branch = intLIDVec[ j++ ];
532 #ifdef Xyce_DEBUG_DEVICE
535 Xyce::dout() <<
"Instance::registerLIDs----------------------------" << std::endl;
538 while( currentInductor != endInductor )
540 Xyce::dout() <<
"Inductor [ " << i++ <<
" ] "
541 <<
" li_Pos = " << (*currentInductor)->li_Pos
542 <<
" li_Neg = " << (*currentInductor)->li_Neg
543 <<
" li_Branch = " << (*currentInductor)->li_Branch << std::endl;
628 #ifdef Xyce_DEBUG_DEVICE
631 Xyce::dout() <<
"Instance::registerJacLIDs ----------------------------" << std::endl;
634 std::vector< InductorInstanceData* >::iterator currentInductor =
instanceData.begin();
635 std::vector< InductorInstanceData* >::iterator endInductor =
instanceData.end();
637 while( currentInductor != endInductor )
639 (*currentInductor)->APosEquBraVarOffset = jacLIDVec[ 2*i ][ 0 ];
640 (*currentInductor)->ANegEquBraVarOffset = jacLIDVec[ 2*i + 1 ][ 0 ];
641 (*currentInductor)->ABraEquPosNodeOffset = jacLIDVec[ 2*
numInductors + i ][ 0 ];
642 (*currentInductor)->ABraEquNegNodeOffset = jacLIDVec[ 2*
numInductors + i ][ 1 ];
647 (*currentInductor)->ABraEquBraVarOffset = jacLIDVec[ 2*numInductors + i ][ j + 2 ];
649 (*currentInductor)->inductorCurrentOffsets[ j ] = jacLIDVec[ 2*numInductors + i ][ j + 2 ];
652 int numdepvars=(*currentInductor)->depVarPairs.size();
653 (*currentInductor)->ABraEquDepVarOffsets.resize(numdepvars);
654 for (
int j = 0; j < numdepvars; ++j)
656 (*currentInductor)->ABraEquDepVarOffsets[j] =
657 jacLIDVec[2*numInductors+i][numInductors+2+j];
663 #ifdef Xyce_DEBUG_DEVICE
666 Xyce::dout() <<
"Instance::registerJacLIDs--------------------------" << std::endl;
669 while( currentInductor != endInductor )
671 Xyce::dout() <<
"Inductor [ " << i <<
" ] " << (*currentInductor)->name
672 <<
" APosEquBraVarOffset = " << (*currentInductor)->APosEquBraVarOffset
673 <<
" ANegEquBraVarOffset = " << (*currentInductor)->ANegEquBraVarOffset
674 <<
" ABraEquPosNodeOffset = " << (*currentInductor)->ABraEquPosNodeOffset
675 <<
" ABraEquNegNodeOffset = " << (*currentInductor)->ABraEquNegNodeOffset
676 <<
" ABraEquBraVarOffset = " << (*currentInductor)->ABraEquBraVarOffset << std::endl;
677 Xyce::dout() <<
"\tInductor branch offsets = { ";
680 Xyce::dout() << (*currentInductor)->inductorCurrentOffsets[ j ] <<
", ";
682 Xyce::dout() <<
"} " << std::endl;
700 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
704 std::vector< InductorInstanceData* >::iterator currentInductor =
instanceData.begin();
705 std::vector< InductorInstanceData* >::iterator endInductor =
instanceData.end();
707 while( currentInductor != endInductor )
710 (*currentInductor)->f_PosEquBraVarPtr =
711 &(dFdx[((*currentInductor)->li_Pos)] [((*currentInductor)->APosEquBraVarOffset)] );
713 (*currentInductor)->f_NegEquBraVarPtr =
714 &(dFdx[((*currentInductor)->li_Neg)] [((*currentInductor)->ANegEquBraVarOffset)] );
716 (*currentInductor)->f_BraEquPosNodePtr =
717 &(dFdx[((*currentInductor)->li_Branch)][((*currentInductor)->ABraEquPosNodeOffset)] );
719 (*currentInductor)->f_BraEquNegNodePtr =
720 &(dFdx[((*currentInductor)->li_Branch)][((*currentInductor)->ABraEquNegNodeOffset)] );
730 (*currentInductor)->f_inductorCurrentPtrs[ j ] =
731 &(dFdx[((*currentInductor)->li_Branch)][(*currentInductor)->inductorCurrentOffsets[j]] );
734 int numdepvars=(*currentInductor)->depVarPairs.size();
735 (*currentInductor)->f_BraEquDepVarPtrs.resize(numdepvars);
737 for (
int j = 0; j < numdepvars; ++j)
739 (*currentInductor)->f_BraEquDepVarPtrs[j] =
740 &(dFdx[((*currentInductor)->li_Branch)][(*currentInductor)->ABraEquDepVarOffsets[j]] );
745 (*currentInductor)->q_PosEquBraVarPtr =
746 &(dQdx[((*currentInductor)->li_Pos)] [((*currentInductor)->APosEquBraVarOffset)] );
748 (*currentInductor)->q_NegEquBraVarPtr =
749 &(dQdx[((*currentInductor)->li_Neg)] [((*currentInductor)->ANegEquBraVarOffset)] );
751 (*currentInductor)->q_BraEquPosNodePtr =
752 &(dQdx[((*currentInductor)->li_Branch)][((*currentInductor)->ABraEquPosNodeOffset)] );
754 (*currentInductor)->q_BraEquNegNodePtr =
755 &(dQdx[((*currentInductor)->li_Branch)][((*currentInductor)->ABraEquNegNodeOffset)] );
765 (*currentInductor)->q_inductorCurrentPtrs[ j ] =
766 &(dQdx[((*currentInductor)->li_Branch)][(*currentInductor)->inductorCurrentOffsets[j]] );
769 numdepvars=(*currentInductor)->depVarPairs.size();
770 (*currentInductor)->q_BraEquDepVarPtrs.resize(numdepvars);
772 for (
int j = 0; j < numdepvars; ++j)
774 (*currentInductor)->q_BraEquDepVarPtrs[j] =
775 &(dQdx[((*currentInductor)->li_Branch)][(*currentInductor)->ABraEquDepVarOffsets[j]] );
804 for( i=0; i<j ; ++i )
819 #ifdef Xyce_DEBUG_DEVICE
822 Xyce::dout() <<
"processParams: mutualCouplingCoef: " << std::endl;
829 Xyce::dout() << std::endl;
850 bool bsuccess =
true;
855 std::vector< InductorInstanceData* >::iterator currentData =
instanceData.begin();
860 (*currentData)->L = ((*currentData)->baseL)*factor;
880 bool bsuccess =
true;
901 std::vector< InductorInstanceData* >::iterator
903 std::vector< InductorInstanceData* >::iterator
908 while( currentInductor != endInductor )
938 #ifdef Xyce_DEBUG_DEVICE
941 Xyce::dout() <<
"Instance::updatePrimaryState------------------" << std::endl
942 <<
"\tname = " <<
getName() << std::endl;
951 for (
int i=0; i<ncoupcoef; ++i)
961 std::vector< InductorInstanceData* >::iterator
963 std::vector< InductorInstanceData* >::iterator
966 while( currentInductor != endInductor )
968 if( (
getSolverState().dcopFlag) && ((*currentInductor)->ICGiven) )
998 bool returnVal=
false;
999 #ifndef Xyce_NO_MUTINDLIN_MASK
1002 std::vector< InductorInstanceData* >::iterator currentInductor =
instanceData.begin();
1003 std::vector< InductorInstanceData* >::iterator endInductor =
instanceData.end();
1004 while( currentInductor != endInductor )
1006 (*maskVectorPtr)[((*currentInductor)->li_Branch)] = 0.0;
1031 #ifdef Xyce_DEBUG_DEVICE
1034 Xyce::dout() <<
"Instance::loadDAEQVector---------------------------" << std::endl
1035 <<
"\tname = " <<
getName() << std::endl;
1059 std::vector< InductorInstanceData* >::iterator currentInductor =
instanceData.begin();
1060 std::vector< InductorInstanceData* >::iterator endInductor =
instanceData.end();
1062 while( currentInductor != endInductor )
1064 qVec[(*currentInductor)->li_Branch] +=
LOI[ i ];
1086 #ifdef Xyce_DEBUG_DEVICE
1089 Xyce::dout() <<
"Instance::loadDAEFVector---------------------------" << std::endl
1090 <<
"\tname = " <<
getName() << std::endl;
1098 std::vector< InductorInstanceData* >::iterator currentInductor =
instanceData.begin();
1099 std::vector< InductorInstanceData* >::iterator endInductor =
instanceData.end();
1102 while( currentInductor != endInductor )
1104 double current = solVec[(*currentInductor)->li_Branch];
1105 double vNodePos = solVec[(*currentInductor)->li_Pos];
1106 double vNodeNeg = solVec[(*currentInductor)->li_Neg];
1107 fVec[((*currentInductor)->li_Pos)] +=
scalingRHS * current;
1108 fVec[((*currentInductor)->li_Neg)] += -
scalingRHS * current;
1109 fVec[((*currentInductor)->li_Branch)] += -(vNodePos - vNodeNeg);
1111 #ifdef Xyce_DEBUG_DEVICE
1114 Xyce::dout() <<
" Inductor = " << (*currentInductor)->name
1115 <<
"\tcurrent = " << current
1116 <<
"\tvNodePos = " << vNodePos
1117 <<
"\tvNodeNeg = " << vNodeNeg
1140 #ifdef Xyce_DEBUG_DEVICE
1143 Xyce::dout() <<
"Instance::loadDAEdQdx--------------------------" << std::endl
1144 <<
"\tname = " <<
getName() << std::endl;
1155 std::vector< InductorInstanceData* >::iterator currentInductor =
instanceData.begin();
1156 std::vector< InductorInstanceData* >::iterator endInductor =
instanceData.end();
1158 while( currentInductor != endInductor )
1162 dQdx[((*currentInductor)->li_Branch)]
1166 int numdepterms=(*currentInductor)->depVarPairs.size();
1167 for (
int j=0 ; j<numdepterms; ++j)
1169 int coefficientNumber=(*currentInductor)->depVarPairs[j].first;
1170 int depVarNumber=(*currentInductor)->depVarPairs[j].second;
1179 otherInductor=
indexPairs[coefficientNumber].second;
1181 otherInductor=
indexPairs[coefficientNumber].first;
1183 dQdx[((*currentInductor)->li_Branch)][(*currentInductor)->ABraEquDepVarOffsets[j]] +=
1213 std::vector< InductorInstanceData* >::iterator currentInductor =
instanceData.begin();
1214 std::vector< InductorInstanceData* >::iterator endInductor =
instanceData.end();
1215 while( currentInductor != endInductor )
1217 dFdx[((*currentInductor)->li_Pos)] [((*currentInductor)->APosEquBraVarOffset)] +=
scalingRHS;
1218 dFdx[((*currentInductor)->li_Neg)] [((*currentInductor)->ANegEquBraVarOffset)] += -
scalingRHS;
1219 dFdx[((*currentInductor)->li_Branch)][((*currentInductor)->ABraEquPosNodeOffset)] += -1.0;
1220 dFdx[((*currentInductor)->li_Branch)][((*currentInductor)->ABraEquNegNodeOffset)] += 1.0;
1241 bool bsuccess =
true;
1258 varTypeVec[i] =
'I';
1285 std::vector<Instance*>::iterator iter;
1289 for (iter=first; iter!=last; ++iter)
1291 (*iter)->processParams();
1309 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
1312 tnom(getDeviceOptions().tnom)
1342 std::vector<Instance*>::iterator iter;
1346 for (iter=first; iter!=last; ++iter)
1365 std::vector<Instance*>::const_iterator iter;
1373 os <<
"Number of MutIndLin instances: " << isize << std::endl;
1374 os <<
" name=\t\tmodelName\tParameters" << std::endl;
1375 for (i=0, iter=first; iter!=last; ++iter, ++i)
1377 os <<
" " << i <<
": " << (*iter)->getName() <<
"\t";
1403 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1427 for (
int i=0; i<ncoupcoef; ++i)
1437 std::vector< InductorInstanceData* >::iterator
1439 std::vector< InductorInstanceData* >::iterator
1443 while( currentInductor != endInductor )
1445 if( (
getSolverState().dcopFlag) && ((*currentInductor)->ICGiven) )
1478 std::vector< InductorInstanceData* >::iterator currentInductor = inst.
instanceData.begin();
1479 std::vector< InductorInstanceData* >::iterator endInductor = inst.
instanceData.end();
1481 while( currentInductor != endInductor )
1483 double current = solVec[(*currentInductor)->li_Branch];
1484 double vNodePos = solVec[(*currentInductor)->li_Pos];
1485 double vNodeNeg = solVec[(*currentInductor)->li_Neg];
1487 fVec[((*currentInductor)->li_Pos)] += inst.
scalingRHS * current;
1488 fVec[((*currentInductor)->li_Neg)] += -inst.
scalingRHS * current;
1489 fVec[((*currentInductor)->li_Branch)] += -(vNodePos - vNodeNeg);
1506 inst.
LOI[ i ] = 0.0;
1517 while( currentInductor != endInductor )
1519 qVec[(*currentInductor)->li_Branch] += inst.
LOI[ li ];
1527 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1542 std::vector< InductorInstanceData* >::iterator currentInductor = inst.
instanceData.begin();
1543 std::vector< InductorInstanceData* >::iterator endInductor = inst.
instanceData.end();
1544 while( currentInductor != endInductor )
1546 *((*currentInductor)->f_PosEquBraVarPtr) += inst.
scalingRHS;
1547 *((*currentInductor)->f_NegEquBraVarPtr) += -inst.
scalingRHS;
1548 *((*currentInductor)->f_BraEquPosNodePtr) += -1.0;
1549 *((*currentInductor)->f_BraEquNegNodePtr) += 1.0;
1562 while( currentInductor != endInductor )
1566 *((*currentInductor)->q_inductorCurrentPtrs[j]) += inst.
mutualCouplingCoef[li][j] * inst.
LO[li][j];
1569 int numdepterms=(*currentInductor)->depVarPairs.size();
1570 for (
int j=0 ; j<numdepterms; ++j)
1572 int coefficientNumber=(*currentInductor)->depVarPairs[j].first;
1573 int depVarNumber=(*currentInductor)->depVarPairs[j].second;
1581 if (li==inst.
indexPairs[coefficientNumber].first)
1582 otherInductor=inst.
indexPairs[coefficientNumber].second;
1584 otherInductor=inst.
indexPairs[coefficientNumber].second;
1586 *((*currentInductor)->q_BraEquDepVarPtrs[j]) +=
1611 int sizeInstances = instanceContainer_.size();
1612 for (
int i=0; i<sizeInstances; ++i)
1614 Instance & inst = *(instanceContainer_.at(i));
1616 std::vector< InductorInstanceData* >::iterator currentInductor = inst.
instanceData.begin();
1617 std::vector< InductorInstanceData* >::iterator endInductor = inst.
instanceData.end();
1618 while( currentInductor != endInductor )
1620 dFdx[((*currentInductor)->li_Pos)] [((*currentInductor)->APosEquBraVarOffset)] += inst.
scalingRHS;
1621 dFdx[((*currentInductor)->li_Neg)] [((*currentInductor)->ANegEquBraVarOffset)] += -inst.
scalingRHS;
1622 dFdx[((*currentInductor)->li_Branch)][((*currentInductor)->ABraEquPosNodeOffset)] += -1.0;
1623 dFdx[((*currentInductor)->li_Branch)][((*currentInductor)->ABraEquNegNodeOffset)] += 1.0;
1636 while( currentInductor != endInductor )
1640 dQdx[((*currentInductor)->li_Branch)]
1641 [(*currentInductor)->inductorCurrentOffsets[j]] += inst.
mutualCouplingCoef[i][j] * inst.
LO[i][j];
1644 int numdepterms=(*currentInductor)->depVarPairs.size();
1645 for (
int j=0 ; j<numdepterms; ++j)
1647 int coefficientNumber=(*currentInductor)->depVarPairs[j].first;
1648 int depVarNumber=(*currentInductor)->depVarPairs[j].second;
1656 if (i==inst.
indexPairs[coefficientNumber].first)
1657 otherInductor=inst.
indexPairs[coefficientNumber].second;
1659 otherInductor=inst.
indexPairs[coefficientNumber].second;
1661 dQdx[((*currentInductor)->li_Branch)][(*currentInductor)->ABraEquDepVarOffsets[j]] +=
1684 .registerDevice(
"mil", 1)
1685 .registerModelType(
"mil", 1);