First KLU support of CIDER TWOD simulations
This commit is contained in:
parent
30d09c62ae
commit
8a8adfe451
|
|
@ -102,36 +102,61 @@ NUMD2admittance(TWOdevice *pDevice, double omega, SPcomplex *yd)
|
|||
}
|
||||
storeNewRhs(pDevice, pDevice->pLastContact);
|
||||
|
||||
spSetComplex(pDevice->matrix);
|
||||
for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {
|
||||
pElem = pDevice->elements[eIndex];
|
||||
if (pElem->elemType == SEMICON) {
|
||||
dxdy = 0.25 * pElem->dx * pElem->dy;
|
||||
for (index = 0; index <= 3; index++) {
|
||||
pNode = pElem->pNodes[index];
|
||||
if (pNode->nodeType != CONTACT) {
|
||||
if (!OneCarrier) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, 0.0, -dxdy * omega);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, 0.0, dxdy * omega);
|
||||
} else if (OneCarrier == N_TYPE) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, 0.0, -dxdy * omega);
|
||||
} else if (OneCarrier == P_TYPE) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, 0.0, dxdy * omega);
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
// Francesco Lannutti - To be completed
|
||||
pDevice->matrix->SMPkluMatrix->KLUmatrixIsComplex = CKTkluMatrixComplex ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
spSetComplex(pDevice->matrix->SPmatrix);
|
||||
|
||||
for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {
|
||||
pElem = pDevice->elements[eIndex];
|
||||
if (pElem->elemType == SEMICON) {
|
||||
dxdy = 0.25 * pElem->dx * pElem->dy;
|
||||
for (index = 0; index <= 3; index++) {
|
||||
pNode = pElem->pNodes[index];
|
||||
if (pNode->nodeType != CONTACT) {
|
||||
if (!OneCarrier) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, 0.0, -dxdy * omega);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, 0.0, dxdy * omega);
|
||||
} else if (OneCarrier == N_TYPE) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, 0.0, -dxdy * omega);
|
||||
} else if (OneCarrier == P_TYPE) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, 0.0, dxdy * omega);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KLU
|
||||
}
|
||||
#endif
|
||||
|
||||
pDevice->pStats->loadTime[STAT_AC] += SPfrontEnd->IFseconds() - startTime;
|
||||
|
||||
/* FACTOR */
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
spFactor(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
SMPluFacKLUforCIDER (pDevice->matrix) ;
|
||||
#else
|
||||
SMPcLUfac(pDevice->matrix, 0);
|
||||
#endif
|
||||
|
||||
pDevice->pStats->factorTime[STAT_AC] += SPfrontEnd->IFseconds() - startTime;
|
||||
|
||||
/* SOLVE */
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#else
|
||||
SMPcSolveForCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#endif
|
||||
|
||||
pDevice->pStats->solveTime[STAT_AC] += SPfrontEnd->IFseconds() - startTime;
|
||||
}
|
||||
/* MISC */
|
||||
|
|
@ -263,36 +288,61 @@ NBJT2admittance(TWOdevice *pDevice, double omega, SPcomplex *yIeVce,
|
|||
TWOPjacLoad(pDevice);
|
||||
}
|
||||
storeNewRhs(pDevice, pColContact);
|
||||
spSetComplex(pDevice->matrix);
|
||||
for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {
|
||||
pElem = pDevice->elements[eIndex];
|
||||
if (pElem->elemType == SEMICON) {
|
||||
dxdy = 0.25 * pElem->dx * pElem->dy;
|
||||
for (index = 0; index <= 3; index++) {
|
||||
pNode = pElem->pNodes[index];
|
||||
if (pNode->nodeType != CONTACT) {
|
||||
if (!OneCarrier) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, 0.0, -dxdy * omega);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, 0.0, dxdy * omega);
|
||||
} else if (OneCarrier == N_TYPE) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, 0.0, -dxdy * omega);
|
||||
} else if (OneCarrier == P_TYPE) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, 0.0, dxdy * omega);
|
||||
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
// Francesco Lannutti - To be completed
|
||||
pDevice->matrix->SMPkluMatrix->KLUmatrixIsComplex = CKTkluMatrixComplex ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
spSetComplex(pDevice->matrix->SPmatrix);
|
||||
for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {
|
||||
pElem = pDevice->elements[eIndex];
|
||||
if (pElem->elemType == SEMICON) {
|
||||
dxdy = 0.25 * pElem->dx * pElem->dy;
|
||||
for (index = 0; index <= 3; index++) {
|
||||
pNode = pElem->pNodes[index];
|
||||
if (pNode->nodeType != CONTACT) {
|
||||
if (!OneCarrier) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, 0.0, -dxdy * omega);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, 0.0, dxdy * omega);
|
||||
} else if (OneCarrier == N_TYPE) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, 0.0, -dxdy * omega);
|
||||
} else if (OneCarrier == P_TYPE) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, 0.0, dxdy * omega);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KLU
|
||||
}
|
||||
#endif
|
||||
|
||||
pDevice->pStats->loadTime[STAT_AC] += SPfrontEnd->IFseconds() - startTime;
|
||||
|
||||
/* FACTOR */
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
spFactor(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
SMPluFacKLUforCIDER (pDevice->matrix) ;
|
||||
#else
|
||||
SMPcLUfac(pDevice->matrix, 0);
|
||||
#endif
|
||||
|
||||
pDevice->pStats->factorTime[STAT_AC] += SPfrontEnd->IFseconds() - startTime;
|
||||
|
||||
/* SOLVE */
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#else
|
||||
SMPcSolveForCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#endif
|
||||
|
||||
pDevice->pStats->solveTime[STAT_AC] += SPfrontEnd->IFseconds() - startTime;
|
||||
|
||||
/* MISC */
|
||||
|
|
@ -317,7 +367,13 @@ NBJT2admittance(TWOdevice *pDevice, double omega, SPcomplex *yIeVce,
|
|||
|
||||
/* SOLVE */
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#else
|
||||
SMPcSolveForCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#endif
|
||||
|
||||
pDevice->pStats->solveTime[STAT_AC] += SPfrontEnd->IFseconds() - startTime;
|
||||
}
|
||||
/* MISC */
|
||||
|
|
@ -517,36 +573,62 @@ NUMOSadmittance(TWOdevice *pDevice, double omega, struct mosAdmittances *yAc)
|
|||
} else if (OneCarrier == P_TYPE) {
|
||||
TWOPjacLoad(pDevice);
|
||||
}
|
||||
spSetComplex(pDevice->matrix);
|
||||
for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {
|
||||
pElem = pDevice->elements[eIndex];
|
||||
if (pElem->elemType == SEMICON) {
|
||||
dxdy = 0.25 * pElem->dx * pElem->dy;
|
||||
for (index = 0; index <= 3; index++) {
|
||||
pNode = pElem->pNodes[index];
|
||||
if (pNode->nodeType != CONTACT) {
|
||||
if (!OneCarrier) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, 0.0, -dxdy * omega);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, 0.0, dxdy * omega);
|
||||
} else if (OneCarrier == N_TYPE) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, 0.0, -dxdy * omega);
|
||||
} else if (OneCarrier == P_TYPE) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, 0.0, dxdy * omega);
|
||||
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
// Francesco Lannutti - To be completed
|
||||
pDevice->matrix->SMPkluMatrix->KLUmatrixIsComplex = CKTkluMatrixComplex ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
spSetComplex(pDevice->matrix->SPmatrix);
|
||||
|
||||
for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {
|
||||
pElem = pDevice->elements[eIndex];
|
||||
if (pElem->elemType == SEMICON) {
|
||||
dxdy = 0.25 * pElem->dx * pElem->dy;
|
||||
for (index = 0; index <= 3; index++) {
|
||||
pNode = pElem->pNodes[index];
|
||||
if (pNode->nodeType != CONTACT) {
|
||||
if (!OneCarrier) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, 0.0, -dxdy * omega);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, 0.0, dxdy * omega);
|
||||
} else if (OneCarrier == N_TYPE) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, 0.0, -dxdy * omega);
|
||||
} else if (OneCarrier == P_TYPE) {
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, 0.0, dxdy * omega);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KLU
|
||||
}
|
||||
#endif
|
||||
|
||||
pDevice->pStats->loadTime[STAT_AC] += SPfrontEnd->IFseconds() - startTime;
|
||||
|
||||
/* FACTOR */
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
spFactor(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
SMPluFacKLUforCIDER (pDevice->matrix) ;
|
||||
#else
|
||||
SMPcLUfac(pDevice->matrix, 0);
|
||||
#endif
|
||||
|
||||
pDevice->pStats->factorTime[STAT_AC] += SPfrontEnd->IFseconds() - startTime;
|
||||
|
||||
/* SOLVE */
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#else
|
||||
SMPcSolveForCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#endif
|
||||
|
||||
pDevice->pStats->solveTime[STAT_AC] += SPfrontEnd->IFseconds() - startTime;
|
||||
|
||||
/* MISC */
|
||||
|
|
@ -574,7 +656,13 @@ NUMOSadmittance(TWOdevice *pDevice, double omega, struct mosAdmittances *yAc)
|
|||
|
||||
/* SOLVE */
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#else
|
||||
SMPcSolveForCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#endif
|
||||
|
||||
pDevice->pStats->solveTime[STAT_AC] += SPfrontEnd->IFseconds() - startTime;
|
||||
|
||||
/* MISC */
|
||||
|
|
@ -602,7 +690,13 @@ NUMOSadmittance(TWOdevice *pDevice, double omega, struct mosAdmittances *yAc)
|
|||
|
||||
/* SOLVE */
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#else
|
||||
SMPcSolveForCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#endif
|
||||
|
||||
pDevice->pStats->solveTime[STAT_AC] += SPfrontEnd->IFseconds() - startTime;
|
||||
}
|
||||
/* MISC */
|
||||
|
|
@ -687,7 +781,12 @@ TWOsorSolve(TWOdevice *pDevice, double *xReal, double *xImag,
|
|||
}
|
||||
|
||||
/* compute xReal(k+1). solution stored in rhsImag */
|
||||
spSolve(pDevice->matrix, rhsSOR, rhsSOR, NULL, NULL);
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhsSOR, rhsSOR, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolve(pDevice->matrix, rhsSOR, rhsSOR);
|
||||
#endif
|
||||
|
||||
/* modify solution when wRelax is not 1 */
|
||||
if (wRelax != 1) {
|
||||
for (index = 1; index <= numEqns; index++) {
|
||||
|
|
@ -729,7 +828,12 @@ TWOsorSolve(TWOdevice *pDevice, double *xReal, double *xImag,
|
|||
}
|
||||
}
|
||||
/* compute xImag(k+1) */
|
||||
spSolve(pDevice->matrix, rhsSOR, rhsSOR, NULL, NULL);
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhsSOR, rhsSOR, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolve(pDevice->matrix, rhsSOR, rhsSOR);
|
||||
#endif
|
||||
|
||||
/* modify solution when wRelax is not 1 */
|
||||
if (wRelax != 1) {
|
||||
for (index = 1; index <= numEqns; index++) {
|
||||
|
|
@ -1073,32 +1177,54 @@ NUMD2ys(TWOdevice *pDevice, SPcomplex *s, SPcomplex *yIn)
|
|||
}
|
||||
storeNewRhs(pDevice, pDevice->pLastContact);
|
||||
|
||||
spSetComplex(pDevice->matrix);
|
||||
for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {
|
||||
pElem = pDevice->elements[eIndex];
|
||||
if (pElem->elemType == SEMICON) {
|
||||
dxdy = 0.25 * pElem->dx * pElem->dy;
|
||||
for (index = 0; index <= 3; index++) {
|
||||
pNode = pElem->pNodes[index];
|
||||
if (pNode->nodeType != CONTACT) {
|
||||
if (!OneCarrier) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag);
|
||||
} else if (OneCarrier == N_TYPE) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag);
|
||||
} else if (OneCarrier == P_TYPE) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag);
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
// Francesco Lannutti - To be completed
|
||||
pDevice->matrix->SMPkluMatrix->KLUmatrixIsComplex = CKTkluMatrixComplex ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
spSetComplex(pDevice->matrix->SPmatrix);
|
||||
|
||||
for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {
|
||||
pElem = pDevice->elements[eIndex];
|
||||
if (pElem->elemType == SEMICON) {
|
||||
dxdy = 0.25 * pElem->dx * pElem->dy;
|
||||
for (index = 0; index <= 3; index++) {
|
||||
pNode = pElem->pNodes[index];
|
||||
if (pNode->nodeType != CONTACT) {
|
||||
if (!OneCarrier) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag);
|
||||
} else if (OneCarrier == N_TYPE) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag);
|
||||
} else if (OneCarrier == P_TYPE) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spFactor(pDevice->matrix);
|
||||
spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag);
|
||||
#ifdef KLU
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
SMPluFacKLUforCIDER (pDevice->matrix) ;
|
||||
#else
|
||||
SMPcLUfac(pDevice->matrix, 0);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#else
|
||||
SMPcSolveForCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#endif
|
||||
|
||||
y = contactAdmittance(pDevice, pDevice->pFirstContact, deltaVContact,
|
||||
solnReal, solnImag, &cOmega);
|
||||
CMPLX_ASSIGN_VALUE(yAc, y->real, y->imag);
|
||||
|
|
@ -1147,31 +1273,54 @@ NBJT2ys(TWOdevice *pDevice, SPcomplex *s, SPcomplex *yIeVce, SPcomplex *yIcVce,
|
|||
TWOPjacLoad(pDevice);
|
||||
}
|
||||
storeNewRhs(pDevice, pColContact);
|
||||
spSetComplex(pDevice->matrix);
|
||||
for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {
|
||||
pElem = pDevice->elements[eIndex];
|
||||
if (pElem->elemType == SEMICON) {
|
||||
dxdy = 0.25 * pElem->dx * pElem->dy;
|
||||
for (index = 0; index <= 3; index++) {
|
||||
pNode = pElem->pNodes[index];
|
||||
if (pNode->nodeType != CONTACT) {
|
||||
if (!OneCarrier) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag);
|
||||
} else if (OneCarrier == N_TYPE) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag);
|
||||
} else if (OneCarrier == P_TYPE) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag);
|
||||
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
// Francesco Lannutti - To be completed
|
||||
pDevice->matrix->SMPkluMatrix->KLUmatrixIsComplex = CKTkluMatrixComplex ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
spSetComplex(pDevice->matrix->SPmatrix);
|
||||
|
||||
for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {
|
||||
pElem = pDevice->elements[eIndex];
|
||||
if (pElem->elemType == SEMICON) {
|
||||
dxdy = 0.25 * pElem->dx * pElem->dy;
|
||||
for (index = 0; index <= 3; index++) {
|
||||
pNode = pElem->pNodes[index];
|
||||
if (pNode->nodeType != CONTACT) {
|
||||
if (!OneCarrier) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag);
|
||||
} else if (OneCarrier == N_TYPE) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag);
|
||||
} else if (OneCarrier == P_TYPE) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KLU
|
||||
}
|
||||
spFactor(pDevice->matrix);
|
||||
spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
SMPluFacKLUforCIDER (pDevice->matrix) ;
|
||||
#else
|
||||
SMPcLUfac(pDevice->matrix, 0);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#else
|
||||
SMPcSolveForCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#endif
|
||||
|
||||
y = contactAdmittance(pDevice, pEmitContact, FALSE,
|
||||
solnReal, solnImag, &cOmega);
|
||||
|
|
@ -1184,7 +1333,13 @@ NBJT2ys(TWOdevice *pDevice, SPcomplex *s, SPcomplex *yIeVce, SPcomplex *yIcVce,
|
|||
}
|
||||
storeNewRhs(pDevice, pBaseContact);
|
||||
/* don't need to LU factor the jacobian since it exists */
|
||||
spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#else
|
||||
SMPcSolveForCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#endif
|
||||
|
||||
y = contactAdmittance(pDevice, pEmitContact, FALSE,
|
||||
solnReal, solnImag, &cOmega);
|
||||
CMPLX_ASSIGN_VALUE(pIeVbe, y->real, y->imag);
|
||||
|
|
@ -1240,33 +1395,54 @@ NUMOSys(TWOdevice *pDevice, SPcomplex *s, struct mosAdmittances *yAc)
|
|||
TWOPjacLoad(pDevice);
|
||||
}
|
||||
storeNewRhs(pDevice, pDContact);
|
||||
spSetComplex(pDevice->matrix);
|
||||
|
||||
for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {
|
||||
pElem = pDevice->elements[eIndex];
|
||||
if (pElem->elemType == SEMICON) {
|
||||
dxdy = 0.25 * pElem->dx * pElem->dy;
|
||||
for (index = 0; index <= 3; index++) {
|
||||
pNode = pElem->pNodes[index];
|
||||
if (pNode->nodeType != CONTACT) {
|
||||
if (!OneCarrier) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag);
|
||||
} else if (OneCarrier == N_TYPE) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag);
|
||||
} else if (OneCarrier == P_TYPE) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag);
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
// Francesco Lannutti - To be completed
|
||||
pDevice->matrix->SMPkluMatrix->KLUmatrixIsComplex = CKTkluMatrixComplex ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
spSetComplex(pDevice->matrix->SPmatrix);
|
||||
|
||||
for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {
|
||||
pElem = pDevice->elements[eIndex];
|
||||
if (pElem->elemType == SEMICON) {
|
||||
dxdy = 0.25 * pElem->dx * pElem->dy;
|
||||
for (index = 0; index <= 3; index++) {
|
||||
pNode = pElem->pNodes[index];
|
||||
if (pNode->nodeType != CONTACT) {
|
||||
if (!OneCarrier) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag);
|
||||
} else if (OneCarrier == N_TYPE) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag);
|
||||
} else if (OneCarrier == P_TYPE) {
|
||||
CMPLX_MULT_SCALAR(temp, cOmega, dxdy);
|
||||
spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spFactor(pDevice->matrix);
|
||||
spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag);
|
||||
#ifdef KLU
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
SMPluFacKLUforCIDER (pDevice->matrix) ;
|
||||
#else
|
||||
SMPcLUfac(pDevice->matrix, 0);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#else
|
||||
SMPcSolveForCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#endif
|
||||
|
||||
y = contactAdmittance(pDevice, pDContact, TRUE,
|
||||
solnReal, solnImag, &cOmega);
|
||||
|
|
@ -1283,7 +1459,13 @@ NUMOSys(TWOdevice *pDevice, SPcomplex *s, struct mosAdmittances *yAc)
|
|||
}
|
||||
storeNewRhs(pDevice, pSContact);
|
||||
/* don't need to LU factor the jacobian since it exists */
|
||||
spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#else
|
||||
SMPcSolveForCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#endif
|
||||
|
||||
y = contactAdmittance(pDevice, pDContact, FALSE,
|
||||
solnReal, solnImag, &cOmega);
|
||||
CMPLX_ASSIGN_VALUE(yAc->yIdVsb, y->real, y->imag);
|
||||
|
|
@ -1297,7 +1479,13 @@ NUMOSys(TWOdevice *pDevice, SPcomplex *s, struct mosAdmittances *yAc)
|
|||
rhsImag[index] = 0.0;
|
||||
}
|
||||
storeNewRhs(pDevice, pGContact);
|
||||
spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#else
|
||||
SMPcSolveForCIDER (pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag) ;
|
||||
#endif
|
||||
|
||||
y = contactAdmittance(pDevice, pDContact, FALSE,
|
||||
solnReal, solnImag, &cOmega);
|
||||
CMPLX_ASSIGN_VALUE(yAc->yIdVgb, y->real, y->imag);
|
||||
|
|
|
|||
|
|
@ -30,8 +30,13 @@ void
|
|||
*/
|
||||
incVpn = pDevice->dcDeltaSolution;
|
||||
storeNewRhs( pDevice, pDevice->pLastContact );
|
||||
spSolve( pDevice->matrix, pDevice->rhs, incVpn, NULL, NULL);
|
||||
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, pDevice->rhs, incVpn, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolveForCIDER (pDevice->matrix, pDevice->rhs, incVpn) ;
|
||||
#endif
|
||||
|
||||
incVpn = pDevice->dcDeltaSolution;
|
||||
*gd = contactConductance( pDevice, pContact, deltaVContact, incVpn,
|
||||
tranAnalysis, intCoeff );
|
||||
|
|
@ -58,9 +63,20 @@ void
|
|||
incVce = pDevice->dcDeltaSolution;
|
||||
incVbe = pDevice->copiedSolution;
|
||||
storeNewRhs( pDevice, pColContact );
|
||||
spSolve( pDevice->matrix, pDevice->rhs, incVce, NULL, NULL);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, pDevice->rhs, incVce, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolveForCIDER (pDevice->matrix, pDevice->rhs, incVce) ;
|
||||
#endif
|
||||
|
||||
storeNewRhs( pDevice, pBaseContact );
|
||||
spSolve( pDevice->matrix, pDevice->rhs, incVbe, NULL, NULL);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, pDevice->rhs, incVbe, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolveForCIDER (pDevice->matrix, pDevice->rhs, incVbe) ;
|
||||
#endif
|
||||
|
||||
*dIeDVce = contactConductance( pDevice, pEmitContact, FALSE, incVce,
|
||||
tranAnalysis, intCoeff );
|
||||
|
|
@ -96,11 +112,28 @@ void
|
|||
incVsb = pDevice->copiedSolution;
|
||||
incVgb = pDevice->rhsImag;
|
||||
storeNewRhs( pDevice, pDContact );
|
||||
spSolve( pDevice->matrix, pDevice->rhs, incVdb, NULL, NULL);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, pDevice->rhs, incVdb, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolveForCIDER (pDevice->matrix, pDevice->rhs, incVdb) ;
|
||||
#endif
|
||||
|
||||
storeNewRhs( pDevice, pSContact );
|
||||
spSolve( pDevice->matrix, pDevice->rhs, incVsb, NULL, NULL);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, pDevice->rhs, incVsb, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolveForCIDER (pDevice->matrix, pDevice->rhs, incVsb) ;
|
||||
#endif
|
||||
|
||||
storeNewRhs( pDevice, pGContact );
|
||||
spSolve( pDevice->matrix, pDevice->rhs, incVgb, NULL, NULL);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, pDevice->rhs, incVgb, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolveForCIDER (pDevice->matrix, pDevice->rhs, incVgb) ;
|
||||
#endif
|
||||
|
||||
dIdV->dIdDVdb = contactConductance( pDevice, pDContact, TRUE,
|
||||
incVdb, tranAnalysis, intCoeff );
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -33,7 +33,13 @@ TWOdestroy(TWOdevice *pDevice)
|
|||
FREE( pDevice->copiedSolution );
|
||||
FREE( pDevice->rhs );
|
||||
FREE( pDevice->rhsImag );
|
||||
spDestroy( pDevice->matrix );
|
||||
|
||||
#ifdef KLU
|
||||
SMPdestroyKLUforCIDER (pDevice->matrix) ;
|
||||
#else
|
||||
SMPdestroy (pDevice->matrix) ;
|
||||
#endif
|
||||
|
||||
break;
|
||||
case SLV_EQUIL:
|
||||
/* free up the vectors allocated in the equilibrium solution */
|
||||
|
|
@ -41,7 +47,13 @@ TWOdestroy(TWOdevice *pDevice)
|
|||
FREE( pDevice->dcDeltaSolution );
|
||||
FREE( pDevice->copiedSolution );
|
||||
FREE( pDevice->rhs );
|
||||
spDestroy( pDevice->matrix );
|
||||
|
||||
#ifdef KLU
|
||||
SMPdestroyKLUforCIDER (pDevice->matrix) ;
|
||||
#else
|
||||
SMPdestroy (pDevice->matrix) ;
|
||||
#endif
|
||||
|
||||
break;
|
||||
case SLV_NONE:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -166,4 +166,11 @@ extern BOOLEAN TWOpsiDeltaConverged(TWOdevice *);
|
|||
extern double TWOnuNorm(TWOdevice *);
|
||||
extern void TWOjacCheck(TWOdevice *, BOOLEAN, TWOtranInfo *);
|
||||
|
||||
#ifdef KLU
|
||||
void TWObindCSC (TWOdevice *) ;
|
||||
void TWONbindCSC (TWOdevice *) ;
|
||||
void TWOPbindCSC (TWOdevice *) ;
|
||||
void TWOQbindCSC (TWOdevice *) ;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ Author: 1991 David A. Gates, U. C. Berkeley CAD Group
|
|||
#include "ngspice/cidersupt.h"
|
||||
#include "../../maths/misc/bernoull.h"
|
||||
|
||||
#ifdef KLU
|
||||
#include "ngspice/klu-binding.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Functions to setup and solve the continuity equations.
|
||||
|
|
@ -54,16 +57,41 @@ void
|
|||
pNode = pElem->pNodes[ nIndex ];
|
||||
/* get poisson-only pointer */
|
||||
psiEqn = pNode->psiEqn;
|
||||
pNode->fPsiPsi = spGetElement( matrix, psiEqn, psiEqn );
|
||||
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsi = SMPmakeEltKLUforCIDER (matrix, psiEqn, psiEqn) ;
|
||||
pNode->fPsiPsiBinding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsi = SMPmakeElt(matrix, psiEqn, psiEqn);
|
||||
#endif
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* get continuity-coupling terms */
|
||||
nEqn = pNode->nEqn;
|
||||
pNode->pEqn = 0; /* Throw pEqn number into garbage. */
|
||||
/* pointers for additional terms */
|
||||
pNode->fPsiN = spGetElement( matrix, psiEqn, nEqn );
|
||||
pNode->fNPsi = spGetElement( matrix, nEqn, psiEqn );
|
||||
pNode->fNN = spGetElement( matrix, nEqn, nEqn );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiN = SMPmakeEltKLUforCIDER (matrix, psiEqn, nEqn) ;
|
||||
pNode->fPsiNBinding = NULL ;
|
||||
#else
|
||||
pNode->fPsiN = SMPmakeElt(matrix, psiEqn, nEqn);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsi = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqn) ;
|
||||
pNode->fNPsiBinding = NULL ;
|
||||
#else
|
||||
pNode->fNPsi = SMPmakeElt(matrix, nEqn, psiEqn);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNN = SMPmakeEltKLUforCIDER (matrix, nEqn, nEqn) ;
|
||||
pNode->fNNBinding = NULL ;
|
||||
#else
|
||||
pNode->fNN = SMPmakeElt(matrix, nEqn, nEqn);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
nEqn = 0;
|
||||
}
|
||||
|
|
@ -92,66 +120,270 @@ void
|
|||
|
||||
/* now terms to couple to adjacent nodes */
|
||||
pNode = pElem->pTLNode;
|
||||
pNode->fPsiPsiiP1 = spGetElement(matrix, psiEqnTL, psiEqnTR );
|
||||
pNode->fPsiPsijP1 = spGetElement(matrix, psiEqnTL, psiEqnBL );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsiiP1 = SMPmakeEltKLUforCIDER (matrix, psiEqnTL, psiEqnTR) ;
|
||||
pNode->fPsiPsiiP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsiiP1 = SMPmakeElt(matrix, psiEqnTL, psiEqnTR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsijP1 = SMPmakeEltKLUforCIDER (matrix, psiEqnTL, psiEqnBL) ;
|
||||
pNode->fPsiPsijP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsijP1 = SMPmakeElt(matrix, psiEqnTL, psiEqnBL);
|
||||
#endif
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
pNode->fNPsiiP1 = spGetElement( matrix, nEqnTL, psiEqnTR );
|
||||
pNode->fNNiP1 = spGetElement( matrix, nEqnTL, nEqnTR );
|
||||
pNode->fNPsijP1 = spGetElement( matrix, nEqnTL, psiEqnBL );
|
||||
pNode->fNNjP1 = spGetElement( matrix, nEqnTL, nEqnBL );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiiP1 = SMPmakeEltKLUforCIDER (matrix, nEqnTL, psiEqnTR) ;
|
||||
pNode->fNPsiiP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiiP1 = SMPmakeElt(matrix, nEqnTL, psiEqnTR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNNiP1 = SMPmakeEltKLUforCIDER (matrix, nEqnTL, nEqnTR) ;
|
||||
pNode->fNNiP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNNiP1 = SMPmakeElt(matrix, nEqnTL, nEqnTR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsijP1 = SMPmakeEltKLUforCIDER (matrix, nEqnTL, psiEqnBL) ;
|
||||
pNode->fNPsijP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsijP1 = SMPmakeElt(matrix, nEqnTL, psiEqnBL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNNjP1 = SMPmakeEltKLUforCIDER (matrix, nEqnTL, nEqnBL) ;
|
||||
pNode->fNNjP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNNjP1 = SMPmakeElt(matrix, nEqnTL, nEqnBL);
|
||||
#endif
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
pNode->fNPsiiP1jP1 = spGetElement( matrix, nEqnTL, psiEqnBR );
|
||||
pNode->fNNiP1jP1 = spGetElement( matrix, nEqnTL, nEqnBR );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiiP1jP1 = SMPmakeEltKLUforCIDER (matrix, nEqnTL, psiEqnBR) ;
|
||||
pNode->fNPsiiP1jP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiiP1jP1 = SMPmakeElt(matrix, nEqnTL, psiEqnBR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNNiP1jP1 = SMPmakeEltKLUforCIDER (matrix, nEqnTL, nEqnBR) ;
|
||||
pNode->fNNiP1jP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNNiP1jP1 = SMPmakeElt(matrix, nEqnTL, nEqnBR);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pNode = pElem->pTRNode;
|
||||
pNode->fPsiPsiiM1 = spGetElement(matrix, psiEqnTR, psiEqnTL );
|
||||
pNode->fPsiPsijP1 = spGetElement(matrix, psiEqnTR, psiEqnBR );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsiiM1 = SMPmakeEltKLUforCIDER (matrix, psiEqnTR, psiEqnTL) ;
|
||||
pNode->fPsiPsiiM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsiiM1 = SMPmakeElt(matrix, psiEqnTR, psiEqnTL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsijP1 = SMPmakeEltKLUforCIDER (matrix, psiEqnTR, psiEqnBR) ;
|
||||
pNode->fPsiPsijP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsijP1 = SMPmakeElt(matrix, psiEqnTR, psiEqnBR);
|
||||
#endif
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
pNode->fNPsiiM1 = spGetElement( matrix, nEqnTR, psiEqnTL );
|
||||
pNode->fNNiM1 = spGetElement( matrix, nEqnTR, nEqnTL );
|
||||
pNode->fNPsijP1 = spGetElement( matrix, nEqnTR, psiEqnBR );
|
||||
pNode->fNNjP1 = spGetElement( matrix, nEqnTR, nEqnBR );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiiM1 = SMPmakeEltKLUforCIDER (matrix, nEqnTR, psiEqnTL) ;
|
||||
pNode->fNPsiiM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiiM1 = SMPmakeElt(matrix, nEqnTR, psiEqnTL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNNiM1 = SMPmakeEltKLUforCIDER (matrix, nEqnTR, nEqnTL) ;
|
||||
pNode->fNNiM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNNiM1 = SMPmakeElt(matrix, nEqnTR, nEqnTL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsijP1 = SMPmakeEltKLUforCIDER (matrix, nEqnTR, psiEqnBR) ;
|
||||
pNode->fNPsijP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsijP1 = SMPmakeElt(matrix, nEqnTR, psiEqnBR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNNjP1 = SMPmakeEltKLUforCIDER (matrix, nEqnTR, nEqnBR) ;
|
||||
pNode->fNNjP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNNjP1 = SMPmakeElt(matrix, nEqnTR, nEqnBR);
|
||||
#endif
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
pNode->fNPsiiM1jP1 = spGetElement( matrix, nEqnTR, psiEqnBL );
|
||||
pNode->fNNiM1jP1 = spGetElement( matrix, nEqnTR, nEqnBL );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiiM1jP1 = SMPmakeEltKLUforCIDER (matrix, nEqnTR, psiEqnBL) ;
|
||||
pNode->fNPsiiM1jP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiiM1jP1 = SMPmakeElt(matrix, nEqnTR, psiEqnBL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNNiM1jP1 = SMPmakeEltKLUforCIDER (matrix, nEqnTR, nEqnBL) ;
|
||||
pNode->fNNiM1jP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNNiM1jP1 = SMPmakeElt(matrix, nEqnTR, nEqnBL);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pNode = pElem->pBRNode;
|
||||
pNode->fPsiPsiiM1 = spGetElement(matrix, psiEqnBR, psiEqnBL );
|
||||
pNode->fPsiPsijM1 = spGetElement(matrix, psiEqnBR, psiEqnTR );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsiiM1 = SMPmakeEltKLUforCIDER (matrix, psiEqnBR, psiEqnBL) ;
|
||||
pNode->fPsiPsiiM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsiiM1 = SMPmakeElt(matrix, psiEqnBR, psiEqnBL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsijM1 = SMPmakeEltKLUforCIDER (matrix, psiEqnBR, psiEqnTR) ;
|
||||
pNode->fPsiPsijM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsijM1 = SMPmakeElt(matrix, psiEqnBR, psiEqnTR);
|
||||
#endif
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
pNode->fNPsiiM1 = spGetElement( matrix, nEqnBR, psiEqnBL );
|
||||
pNode->fNNiM1 = spGetElement( matrix, nEqnBR, nEqnBL );
|
||||
pNode->fNPsijM1 = spGetElement( matrix, nEqnBR, psiEqnTR );
|
||||
pNode->fNNjM1 = spGetElement( matrix, nEqnBR, nEqnTR );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiiM1 = SMPmakeEltKLUforCIDER (matrix, nEqnBR, psiEqnBL) ;
|
||||
pNode->fNPsiiM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiiM1 = SMPmakeElt(matrix, nEqnBR, psiEqnBL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNNiM1 = SMPmakeEltKLUforCIDER (matrix, nEqnBR, nEqnBL) ;
|
||||
pNode->fNNiM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNNiM1 = SMPmakeElt(matrix, nEqnBR, nEqnBL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsijM1 = SMPmakeEltKLUforCIDER (matrix, nEqnBR, psiEqnTR) ;
|
||||
pNode->fNPsijM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsijM1 = SMPmakeElt(matrix, nEqnBR, psiEqnTR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNNjM1 = SMPmakeEltKLUforCIDER (matrix, nEqnBR, nEqnTR) ;
|
||||
pNode->fNNjM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNNjM1 = SMPmakeElt(matrix, nEqnBR, nEqnTR);
|
||||
#endif
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
pNode->fNPsiiM1jM1 = spGetElement( matrix, nEqnBR, psiEqnTL );
|
||||
pNode->fNNiM1jM1 = spGetElement( matrix, nEqnBR, nEqnTL );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiiM1jM1 = SMPmakeEltKLUforCIDER (matrix, nEqnBR, psiEqnTL) ;
|
||||
pNode->fNPsiiM1jM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiiM1jM1 = SMPmakeElt(matrix, nEqnBR, psiEqnTL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNNiM1jM1 = SMPmakeEltKLUforCIDER (matrix, nEqnBR, nEqnTL) ;
|
||||
pNode->fNNiM1jM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNNiM1jM1 = SMPmakeElt(matrix, nEqnBR, nEqnTL);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pNode = pElem->pBLNode;
|
||||
pNode->fPsiPsiiP1 = spGetElement(matrix, psiEqnBL, psiEqnBR );
|
||||
pNode->fPsiPsijM1 = spGetElement(matrix, psiEqnBL, psiEqnTL );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsiiP1 = SMPmakeEltKLUforCIDER (matrix, psiEqnBL, psiEqnBR) ;
|
||||
pNode->fPsiPsiiP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsiiP1 = SMPmakeElt(matrix, psiEqnBL, psiEqnBR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsijM1 = SMPmakeEltKLUforCIDER (matrix, psiEqnBL, psiEqnTL) ;
|
||||
pNode->fPsiPsijM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsijM1 = SMPmakeElt(matrix, psiEqnBL, psiEqnTL);
|
||||
#endif
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
pNode->fNPsiiP1 = spGetElement( matrix, nEqnBL, psiEqnBR );
|
||||
pNode->fNNiP1 = spGetElement( matrix, nEqnBL, nEqnBR );
|
||||
pNode->fNPsijM1 = spGetElement( matrix, nEqnBL, psiEqnTL );
|
||||
pNode->fNNjM1 = spGetElement( matrix, nEqnBL, nEqnTL );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiiP1 = SMPmakeEltKLUforCIDER (matrix, nEqnBL, psiEqnBR) ;
|
||||
pNode->fNPsiiP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiiP1 = SMPmakeElt(matrix, nEqnBL, psiEqnBR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNNiP1 = SMPmakeEltKLUforCIDER (matrix, nEqnBL, nEqnBR) ;
|
||||
pNode->fNNiP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNNiP1 = SMPmakeElt(matrix, nEqnBL, nEqnBR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsijM1 = SMPmakeEltKLUforCIDER (matrix, nEqnBL, psiEqnTL) ;
|
||||
pNode->fNPsijM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsijM1 = SMPmakeElt(matrix, nEqnBL, psiEqnTL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNNjM1 = SMPmakeEltKLUforCIDER (matrix, nEqnBL, nEqnTL) ;
|
||||
pNode->fNNjM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNNjM1 = SMPmakeElt(matrix, nEqnBL, nEqnTL);
|
||||
#endif
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
pNode->fNPsiiP1jM1 = spGetElement( matrix, nEqnBL, psiEqnTR );
|
||||
pNode->fNNiP1jM1 = spGetElement( matrix, nEqnBL, nEqnTR );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiiP1jM1 = SMPmakeEltKLUforCIDER (matrix, nEqnBL, psiEqnTR) ;
|
||||
pNode->fNPsiiP1jM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiiP1jM1 = SMPmakeElt(matrix, nEqnBL, psiEqnTR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNNiP1jM1 = SMPmakeEltKLUforCIDER (matrix, nEqnBL, nEqnTR) ;
|
||||
pNode->fNNiP1jM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNNiP1jM1 = SMPmakeElt(matrix, nEqnBL, nEqnTR);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -200,27 +432,135 @@ void
|
|||
nEqn = pNode->nEqn;
|
||||
if ( pCh->type % 2 == 0 ) { /* Vertical Slice */
|
||||
if ( nIndex == 0 || nIndex == 3 ) { /* Left Side */
|
||||
pNode->fNPsiIn = spGetElement( matrix, nEqn, psiEqnInM );
|
||||
pNode->fNPsiInP1 = spGetElement( matrix, nEqn, psiEqnInP );
|
||||
pNode->fNPsiOx = spGetElement( matrix, nEqn, psiEqnOxM );
|
||||
pNode->fNPsiOxP1 = spGetElement( matrix, nEqn, psiEqnOxP );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiIn = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnInM) ;
|
||||
pNode->fNPsiInBinding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiIn = SMPmakeElt(matrix, nEqn, psiEqnInM);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiInP1 = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnInP) ;
|
||||
pNode->fNPsiInP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiInP1 = SMPmakeElt(matrix, nEqn, psiEqnInP);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiOx = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnOxM) ;
|
||||
pNode->fNPsiOxBinding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiOx = SMPmakeElt(matrix, nEqn, psiEqnOxM);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiOxP1 = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnOxP) ;
|
||||
pNode->fNPsiOxP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiOxP1 = SMPmakeElt(matrix, nEqn, psiEqnOxP);
|
||||
#endif
|
||||
|
||||
} else { /* Right Side */
|
||||
pNode->fNPsiInM1 = spGetElement( matrix, nEqn, psiEqnInM );
|
||||
pNode->fNPsiIn = spGetElement( matrix, nEqn, psiEqnInP );
|
||||
pNode->fNPsiOxM1 = spGetElement( matrix, nEqn, psiEqnOxM );
|
||||
pNode->fNPsiOx = spGetElement( matrix, nEqn, psiEqnOxP );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiInM1 = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnInM) ;
|
||||
pNode->fNPsiInM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiInM1 = SMPmakeElt(matrix, nEqn, psiEqnInM);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiIn = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnInP) ;
|
||||
pNode->fNPsiInBinding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiIn = SMPmakeElt(matrix, nEqn, psiEqnInP);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiOxM1 = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnOxM) ;
|
||||
pNode->fNPsiOxM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiOxM1 = SMPmakeElt(matrix, nEqn, psiEqnOxM);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiOx = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnOxP) ;
|
||||
pNode->fNPsiOxBinding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiOx = SMPmakeElt(matrix, nEqn, psiEqnOxP);
|
||||
#endif
|
||||
|
||||
}
|
||||
} else { /* Horizontal Slice */
|
||||
if ( nIndex == 0 || nIndex == 3 ) { /* Left (Top?) Side : bug 483 */
|
||||
pNode->fNPsiIn = spGetElement( matrix, nEqn, psiEqnInM );
|
||||
pNode->fNPsiInP1 = spGetElement( matrix, nEqn, psiEqnInP );
|
||||
pNode->fNPsiOx = spGetElement( matrix, nEqn, psiEqnOxM );
|
||||
pNode->fNPsiOxP1 = spGetElement( matrix, nEqn, psiEqnOxP );
|
||||
// <<<<<<< HEAD
|
||||
// if ( nIndex == 0 || nIndex == 3 ) { /* Left (Top?) Side : bug 483 */
|
||||
// pNode->fNPsiIn = spGetElement( matrix, nEqn, psiEqnInM );
|
||||
// pNode->fNPsiInP1 = spGetElement( matrix, nEqn, psiEqnInP );
|
||||
// pNode->fNPsiOx = spGetElement( matrix, nEqn, psiEqnOxM );
|
||||
// pNode->fNPsiOxP1 = spGetElement( matrix, nEqn, psiEqnOxP );
|
||||
// =======
|
||||
// if ( nIndex <= 1 ) { /* Top Side */
|
||||
//
|
||||
// #ifdef KLU
|
||||
// pNode->fNPsiIn = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnInM) ;
|
||||
// pNode->fNPsiInBinding = NULL ;
|
||||
// #else
|
||||
// pNode->fNPsiIn = SMPmakeElt(matrix, nEqn, psiEqnInM);
|
||||
// #endif
|
||||
//
|
||||
// #ifdef KLU
|
||||
// pNode->fNPsiInP1 = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnInP) ;
|
||||
// pNode->fNPsiInP1Binding = NULL ;
|
||||
// #else
|
||||
// pNode->fNPsiInP1 = SMPmakeElt(matrix, nEqn, psiEqnInP);
|
||||
// #endif
|
||||
//
|
||||
// #ifdef KLU
|
||||
// pNode->fNPsiOx = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnOxM) ;
|
||||
// pNode->fNPsiOxBinding = NULL ;
|
||||
// #else
|
||||
// pNode->fNPsiOx = SMPmakeElt(matrix, nEqn, psiEqnOxM);
|
||||
// #endif
|
||||
//
|
||||
// #ifdef KLU
|
||||
// pNode->fNPsiOxP1 = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnOxP) ;
|
||||
// pNode->fNPsiOxP1Binding = NULL ;
|
||||
// #else
|
||||
// pNode->fNPsiOxP1 = SMPmakeElt(matrix, nEqn, psiEqnOxP);
|
||||
// #endif
|
||||
//
|
||||
// >>>>>>> First KLU support of CIDER TWOD simulations
|
||||
} else { /* Bottom Side */
|
||||
pNode->fNPsiInM1 = spGetElement( matrix, nEqn, psiEqnInM );
|
||||
pNode->fNPsiIn = spGetElement( matrix, nEqn, psiEqnInP );
|
||||
pNode->fNPsiOxM1 = spGetElement( matrix, nEqn, psiEqnOxM );
|
||||
pNode->fNPsiOx = spGetElement( matrix, nEqn, psiEqnOxP );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiInM1 = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnInM) ;
|
||||
pNode->fNPsiInM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiInM1 = SMPmakeElt(matrix, nEqn, psiEqnInM);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiIn = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnInP) ;
|
||||
pNode->fNPsiInBinding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiIn = SMPmakeElt(matrix, nEqn, psiEqnInP);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiOxM1 = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnOxM) ;
|
||||
pNode->fNPsiOxM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiOxM1 = SMPmakeElt(matrix, nEqn, psiEqnOxM);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fNPsiOx = SMPmakeEltKLUforCIDER (matrix, nEqn, psiEqnOxP) ;
|
||||
pNode->fNPsiOxBinding = NULL ;
|
||||
#else
|
||||
pNode->fNPsiOx = SMPmakeElt(matrix, nEqn, psiEqnOxP);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
} /* endfor nIndex */
|
||||
|
|
@ -230,6 +570,256 @@ void
|
|||
} /* endif SurfaceMobility */
|
||||
}
|
||||
|
||||
#ifdef KLU
|
||||
void
|
||||
TWONbindCSC (TWOdevice *pDevice)
|
||||
{
|
||||
TWOelem *pElem;
|
||||
TWOnode *pNode;
|
||||
TWOchannel *pCh;
|
||||
BindKluElementCOO i, *matched, *BindStruct, *BindStructCSC ;
|
||||
int index ;
|
||||
size_t nz ;
|
||||
|
||||
int eIndex, nIndex;
|
||||
int nextIndex; /* index of node to find next element */
|
||||
int psiEqn, nEqn; /* scratch for deref'd eqn numbers */
|
||||
int psiEqnTL = 0, nEqnTL = 0;
|
||||
int psiEqnTR = 0, nEqnTR = 0;
|
||||
int psiEqnBR = 0, nEqnBR = 0;
|
||||
int psiEqnBL = 0, nEqnBL = 0;
|
||||
int psiEqnInM = 0, psiEqnInP = 0; /* scratch for deref'd surface eqns */
|
||||
int psiEqnOxM = 0, psiEqnOxP = 0; /* M= more negative, P= more positive */
|
||||
|
||||
BindStruct = pDevice->matrix->SMPkluMatrix->KLUmatrixBindStructCOO ;
|
||||
nz = pDevice->matrix->SMPkluMatrix->KLUmatrixNZ ;
|
||||
|
||||
BindStructCSC = (BindKluElementCOO *) malloc (nz * sizeof(BindKluElementCOO)) ;
|
||||
for (index = 0 ; index < (int)nz ; index++) {
|
||||
BindStructCSC [index] = BindStruct [index] ;
|
||||
}
|
||||
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
|
||||
/* first the self terms */
|
||||
for ( nIndex = 0; nIndex <= 3; nIndex++ ) {
|
||||
pNode = pElem->pNodes[ nIndex ];
|
||||
/* get poisson-only pointer */
|
||||
psiEqn = pNode->psiEqn;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsi, fPsiPsiBinding, psiEqn, psiEqn) ;
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* get continuity-coupling terms */
|
||||
nEqn = pNode->nEqn;
|
||||
pNode->pEqn = 0; /* Throw pEqn number into garbage. */
|
||||
/* pointers for additional terms */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiN, fPsiNBinding, psiEqn, nEqn) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsi, fNPsiBinding, nEqn, psiEqn) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNN, fNNBinding, nEqn, nEqn) ;
|
||||
|
||||
} else {
|
||||
nEqn = 0;
|
||||
}
|
||||
/* save equation indices */
|
||||
switch ( nIndex ) {
|
||||
case 0: /* TL Node */
|
||||
psiEqnTL = psiEqn;
|
||||
nEqnTL = nEqn;
|
||||
break;
|
||||
case 1: /* TR Node */
|
||||
psiEqnTR = psiEqn;
|
||||
nEqnTR = nEqn;
|
||||
break;
|
||||
case 2: /* BR Node */
|
||||
psiEqnBR = psiEqn;
|
||||
nEqnBR = nEqn;
|
||||
break;
|
||||
case 3: /* BL Node */
|
||||
psiEqnBL = psiEqn;
|
||||
nEqnBL = nEqn;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* now terms to couple to adjacent nodes */
|
||||
pNode = pElem->pTLNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsiiP1, fPsiPsiiP1Binding, psiEqnTL, psiEqnTR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsijP1, fPsiPsijP1Binding, psiEqnTL, psiEqnBL) ;
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiiP1, fNPsiiP1Binding, nEqnTL, psiEqnTR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNNiP1, fNNiP1Binding, nEqnTL, nEqnTR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsijP1, fNPsijP1Binding, nEqnTL, psiEqnBL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNNjP1, fNNjP1Binding, nEqnTL, nEqnBL) ;
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiiP1jP1, fNPsiiP1jP1Binding, nEqnTL, psiEqnBR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNNiP1jP1, fNNiP1jP1Binding, nEqnTL, nEqnBR) ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pNode = pElem->pTRNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsiiM1, fPsiPsiiM1Binding, psiEqnTR, psiEqnTL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsijP1, fPsiPsijP1Binding, psiEqnTR, psiEqnBR) ;
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiiM1, fNPsiiM1Binding, nEqnTR, psiEqnTL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNNiM1, fNNiM1Binding, nEqnTR, nEqnTL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsijP1, fNPsijP1Binding, nEqnTR, psiEqnBR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNNjP1, fNNjP1Binding, nEqnTR, nEqnBR) ;
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiiM1jP1, fNPsiiM1jP1Binding, nEqnTR, psiEqnBL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNNiM1jP1, fNNiM1jP1Binding, nEqnTR, nEqnBL) ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pNode = pElem->pBRNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsiiM1, fPsiPsiiM1Binding, psiEqnBR, psiEqnBL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsijM1, fPsiPsijM1Binding, psiEqnBR, psiEqnTR) ;
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiiM1, fNPsiiM1Binding, nEqnBR, psiEqnBL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNNiM1, fNNiM1Binding, nEqnBR, nEqnBL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsijM1, fNPsijM1Binding, nEqnBR, psiEqnTR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNNjM1, fNNjM1Binding, nEqnBR, nEqnTR) ;
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiiM1jM1, fNPsiiM1jM1Binding, nEqnBR, psiEqnTL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNNiM1jM1, fNNiM1jM1Binding, nEqnBR, nEqnTL) ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pNode = pElem->pBLNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsiiP1, fPsiPsiiP1Binding, psiEqnBL, psiEqnBR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsijM1, fPsiPsijM1Binding, psiEqnBL, psiEqnTL) ;
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiiP1, fNPsiiP1Binding, nEqnBL, psiEqnBR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNNiP1, fNNiP1Binding, nEqnBL, nEqnBR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsijM1, fNPsijM1Binding, nEqnBL, psiEqnTL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNNjM1, fNNjM1Binding, nEqnBL, nEqnTL) ;
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiiP1jM1, fNPsiiP1jM1Binding, nEqnBL, psiEqnTR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNNiP1jM1, fNNiP1jM1Binding, nEqnBL, nEqnTR) ;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Add terms for surface-field of inversion-layer mobility model.
|
||||
* Elements MUST be made from silicon for this to work.
|
||||
* No empty elements are allowed.
|
||||
* Don't need these pointers if SurfaceMobility isn't set.
|
||||
*/
|
||||
if ( MobDeriv && SurfaceMobility ) {
|
||||
for ( pCh = pDevice->pChannel; pCh != NULL;
|
||||
pCh = pCh->next ) {
|
||||
pElem = pCh->pNElem;
|
||||
switch (pCh->type) {
|
||||
case 0:
|
||||
psiEqnInM = pElem->pBLNode->psiEqn;
|
||||
psiEqnInP = pElem->pBRNode->psiEqn;
|
||||
psiEqnOxM = pElem->pTLNode->psiEqn;
|
||||
psiEqnOxP = pElem->pTRNode->psiEqn;
|
||||
break;
|
||||
case 1:
|
||||
psiEqnInM = pElem->pTLNode->psiEqn;
|
||||
psiEqnInP = pElem->pBLNode->psiEqn;
|
||||
psiEqnOxM = pElem->pTRNode->psiEqn;
|
||||
psiEqnOxP = pElem->pBRNode->psiEqn;
|
||||
break;
|
||||
case 2:
|
||||
psiEqnInM = pElem->pTLNode->psiEqn;
|
||||
psiEqnInP = pElem->pTRNode->psiEqn;
|
||||
psiEqnOxM = pElem->pBLNode->psiEqn;
|
||||
psiEqnOxP = pElem->pBRNode->psiEqn;
|
||||
break;
|
||||
case 3:
|
||||
psiEqnInM = pElem->pTRNode->psiEqn;
|
||||
psiEqnInP = pElem->pBRNode->psiEqn;
|
||||
psiEqnOxM = pElem->pTLNode->psiEqn;
|
||||
psiEqnOxP = pElem->pBLNode->psiEqn;
|
||||
break;
|
||||
}
|
||||
pElem = pCh->pSeed;
|
||||
nextIndex = (pCh->type + 2)%4;
|
||||
while (pElem && pElem->channel == pCh->id) {
|
||||
for ( nIndex = 0; nIndex <= 3; nIndex++ ) {
|
||||
pNode = pElem->pNodes[ nIndex ];
|
||||
psiEqn = pNode->psiEqn;
|
||||
nEqn = pNode->nEqn;
|
||||
if ( pCh->type % 2 == 0 ) { /* Vertical Slice */
|
||||
if ( nIndex == 0 || nIndex == 3 ) { /* Left Side */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiIn, fNPsiInBinding, nEqn, psiEqnInM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiInP1, fNPsiInP1Binding, nEqn, psiEqnInP) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiOx, fNPsiOxBinding, nEqn, psiEqnOxM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiOxP1, fNPsiOxP1Binding, nEqn, psiEqnOxP) ;
|
||||
|
||||
} else { /* Right Side */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiInM1, fNPsiInM1Binding, nEqn, psiEqnInM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiIn, fNPsiInBinding, nEqn, psiEqnInP) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiOxM1, fNPsiOxM1Binding, nEqn, psiEqnOxM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiOx, fNPsiOxBinding, nEqn, psiEqnOxP) ;
|
||||
|
||||
}
|
||||
} else { /* Horizontal Slice */
|
||||
if ( nIndex <= 1 ) { /* Top Side */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiIn, fNPsiInBinding, nEqn, psiEqnInM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiInP1, fNPsiInP1Binding, nEqn, psiEqnInP) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiOx, fNPsiOxBinding, nEqn, psiEqnOxM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiOxP1, fNPsiOxP1Binding, nEqn, psiEqnOxP) ;
|
||||
|
||||
} else { /* Bottom Side */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiInM1, fNPsiInM1Binding, nEqn, psiEqnInM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiIn, fNPsiInBinding, nEqn, psiEqnInP) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiOxM1, fNPsiOxM1Binding, nEqn, psiEqnOxM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fNPsiOx, fNPsiOxBinding, nEqn, psiEqnOxP) ;
|
||||
|
||||
}
|
||||
}
|
||||
} /* endfor nIndex */
|
||||
pElem = pElem->pElems[ nextIndex ];
|
||||
} /* endwhile pElem */
|
||||
} /* endfor pCh */
|
||||
} /* endif SurfaceMobility */
|
||||
|
||||
free (BindStructCSC) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The Jacobian and Rhs are loaded by the following function.
|
||||
|
|
@ -269,7 +859,17 @@ void
|
|||
}
|
||||
|
||||
/* zero the matrix */
|
||||
spClear( pDevice->matrix );
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
SMPclearKLUforCIDER (pDevice->matrix) ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
SMPclear(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
}
|
||||
#endif
|
||||
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
|
|
@ -434,7 +1034,17 @@ void
|
|||
TWONcommonTerms( pDevice, FALSE, FALSE, NULL );
|
||||
|
||||
/* zero the matrix */
|
||||
spClear( pDevice->matrix );
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
SMPclearKLUforCIDER (pDevice->matrix) ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
SMPclear(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
}
|
||||
#endif
|
||||
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@ Author: 1991 David A. Gates, U. C. Berkeley CAD Group
|
|||
#include "ngspice/cidersupt.h"
|
||||
#include "../../maths/misc/bernoull.h"
|
||||
|
||||
#ifdef KLU
|
||||
#include "ngspice/klu-binding.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Functions to setup and solve the continuity equations.
|
||||
* Both continuity equations are solved.
|
||||
|
|
@ -53,16 +57,41 @@ void
|
|||
pNode = pElem->pNodes[ nIndex ];
|
||||
/* get poisson-only pointer */
|
||||
psiEqn = pNode->psiEqn;
|
||||
pNode->fPsiPsi = spGetElement( matrix, psiEqn, psiEqn );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsi = SMPmakeEltKLUforCIDER (matrix, psiEqn, psiEqn) ;
|
||||
pNode->fPsiPsiBinding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsi = SMPmakeElt(matrix, psiEqn, psiEqn);
|
||||
#endif
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* get continuity-coupling terms */
|
||||
pEqn = pNode->pEqn;
|
||||
pNode->nEqn = 0;
|
||||
/* pointers for additional terms */
|
||||
pNode->fPsiP = spGetElement( matrix, psiEqn, pEqn );
|
||||
pNode->fPPsi = spGetElement( matrix, pEqn, psiEqn );
|
||||
pNode->fPP = spGetElement( matrix, pEqn, pEqn );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiP = SMPmakeEltKLUforCIDER (matrix, psiEqn, pEqn) ;
|
||||
pNode->fPsiPBinding = NULL ;
|
||||
#else
|
||||
pNode->fPsiP = SMPmakeElt(matrix, psiEqn, pEqn);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsi = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqn) ;
|
||||
pNode->fPPsiBinding = NULL ;
|
||||
#else
|
||||
pNode->fPPsi = SMPmakeElt(matrix, pEqn, psiEqn);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPP = SMPmakeEltKLUforCIDER (matrix, pEqn, pEqn) ;
|
||||
pNode->fPPBinding = NULL ;
|
||||
#else
|
||||
pNode->fPP = SMPmakeElt(matrix, pEqn, pEqn);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
pEqn = 0;
|
||||
}
|
||||
|
|
@ -91,66 +120,270 @@ void
|
|||
|
||||
/* now terms to couple to adjacent nodes */
|
||||
pNode = pElem->pTLNode;
|
||||
pNode->fPsiPsiiP1 = spGetElement(matrix, psiEqnTL, psiEqnTR );
|
||||
pNode->fPsiPsijP1 = spGetElement(matrix, psiEqnTL, psiEqnBL );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsiiP1 = SMPmakeEltKLUforCIDER (matrix, psiEqnTL, psiEqnTR) ;
|
||||
pNode->fPsiPsiiP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsiiP1 = SMPmakeElt(matrix, psiEqnTL, psiEqnTR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsijP1 = SMPmakeEltKLUforCIDER (matrix, psiEqnTL, psiEqnBL) ;
|
||||
pNode->fPsiPsijP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsijP1 = SMPmakeElt(matrix, psiEqnTL, psiEqnBL);
|
||||
#endif
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
pNode->fPPsiiP1 = spGetElement( matrix, pEqnTL, psiEqnTR );
|
||||
pNode->fPPiP1 = spGetElement( matrix, pEqnTL, pEqnTR );
|
||||
pNode->fPPsijP1 = spGetElement( matrix, pEqnTL, psiEqnBL );
|
||||
pNode->fPPjP1 = spGetElement( matrix, pEqnTL, pEqnBL );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiiP1 = SMPmakeEltKLUforCIDER (matrix, pEqnTL, psiEqnTR) ;
|
||||
pNode->fPPsiiP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiiP1 = SMPmakeElt(matrix, pEqnTL, psiEqnTR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPiP1 = SMPmakeEltKLUforCIDER (matrix, pEqnTL, pEqnTR) ;
|
||||
pNode->fPPiP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPiP1 = SMPmakeElt(matrix, pEqnTL, pEqnTR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsijP1 = SMPmakeEltKLUforCIDER (matrix, pEqnTL, psiEqnBL) ;
|
||||
pNode->fPPsijP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsijP1 = SMPmakeElt(matrix, pEqnTL, psiEqnBL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPjP1 = SMPmakeEltKLUforCIDER (matrix, pEqnTL, pEqnBL) ;
|
||||
pNode->fPPjP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPjP1 = SMPmakeElt(matrix, pEqnTL, pEqnBL);
|
||||
#endif
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
pNode->fPPsiiP1jP1 = spGetElement( matrix, pEqnTL, psiEqnBR );
|
||||
pNode->fPPiP1jP1 = spGetElement( matrix, pEqnTL, pEqnBR );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiiP1jP1 = SMPmakeEltKLUforCIDER (matrix, pEqnTL, psiEqnBR) ;
|
||||
pNode->fPPsiiP1jP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiiP1jP1 = SMPmakeElt(matrix, pEqnTL, psiEqnBR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPiP1jP1 = SMPmakeEltKLUforCIDER (matrix, pEqnTL, pEqnBR) ;
|
||||
pNode->fPPiP1jP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPiP1jP1 = SMPmakeElt(matrix, pEqnTL, pEqnBR);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pNode = pElem->pTRNode;
|
||||
pNode->fPsiPsiiM1 = spGetElement(matrix, psiEqnTR, psiEqnTL );
|
||||
pNode->fPsiPsijP1 = spGetElement(matrix, psiEqnTR, psiEqnBR );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsiiM1 = SMPmakeEltKLUforCIDER (matrix, psiEqnTR, psiEqnTL) ;
|
||||
pNode->fPsiPsiiM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsiiM1 = SMPmakeElt(matrix, psiEqnTR, psiEqnTL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsijP1 = SMPmakeEltKLUforCIDER (matrix, psiEqnTR, psiEqnBR) ;
|
||||
pNode->fPsiPsijP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsijP1 = SMPmakeElt(matrix, psiEqnTR, psiEqnBR);
|
||||
#endif
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
pNode->fPPsiiM1 = spGetElement( matrix, pEqnTR, psiEqnTL );
|
||||
pNode->fPPiM1 = spGetElement( matrix, pEqnTR, pEqnTL );
|
||||
pNode->fPPsijP1 = spGetElement( matrix, pEqnTR, psiEqnBR );
|
||||
pNode->fPPjP1 = spGetElement( matrix, pEqnTR, pEqnBR );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiiM1 = SMPmakeEltKLUforCIDER (matrix, pEqnTR, psiEqnTL) ;
|
||||
pNode->fPPsiiM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiiM1 = SMPmakeElt(matrix, pEqnTR, psiEqnTL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPiM1 = SMPmakeEltKLUforCIDER (matrix, pEqnTR, pEqnTL) ;
|
||||
pNode->fPPiM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPiM1 = SMPmakeElt(matrix, pEqnTR, pEqnTL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsijP1 = SMPmakeEltKLUforCIDER (matrix, pEqnTR, psiEqnBR) ;
|
||||
pNode->fPPsijP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsijP1 = SMPmakeElt(matrix, pEqnTR, psiEqnBR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPjP1 = SMPmakeEltKLUforCIDER (matrix, pEqnTR, pEqnBR) ;
|
||||
pNode->fPPjP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPjP1 = SMPmakeElt(matrix, pEqnTR, pEqnBR);
|
||||
#endif
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
pNode->fPPsiiM1jP1 = spGetElement( matrix, pEqnTR, psiEqnBL );
|
||||
pNode->fPPiM1jP1 = spGetElement( matrix, pEqnTR, pEqnBL );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiiM1jP1 = SMPmakeEltKLUforCIDER (matrix, pEqnTR, psiEqnBL) ;
|
||||
pNode->fPPsiiM1jP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiiM1jP1 = SMPmakeElt(matrix, pEqnTR, psiEqnBL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPiM1jP1 = SMPmakeEltKLUforCIDER (matrix, pEqnTR, pEqnBL) ;
|
||||
pNode->fPPiM1jP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPiM1jP1 = SMPmakeElt(matrix, pEqnTR, pEqnBL);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pNode = pElem->pBRNode;
|
||||
pNode->fPsiPsiiM1 = spGetElement(matrix, psiEqnBR, psiEqnBL );
|
||||
pNode->fPsiPsijM1 = spGetElement(matrix, psiEqnBR, psiEqnTR );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsiiM1 = SMPmakeEltKLUforCIDER (matrix, psiEqnBR, psiEqnBL) ;
|
||||
pNode->fPsiPsiiM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsiiM1 = SMPmakeElt(matrix, psiEqnBR, psiEqnBL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsijM1 = SMPmakeEltKLUforCIDER (matrix, psiEqnBR, psiEqnTR) ;
|
||||
pNode->fPsiPsijM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsijM1 = SMPmakeElt(matrix, psiEqnBR, psiEqnTR);
|
||||
#endif
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
pNode->fPPsiiM1 = spGetElement( matrix, pEqnBR, psiEqnBL );
|
||||
pNode->fPPiM1 = spGetElement( matrix, pEqnBR, pEqnBL );
|
||||
pNode->fPPsijM1 = spGetElement( matrix, pEqnBR, psiEqnTR );
|
||||
pNode->fPPjM1 = spGetElement( matrix, pEqnBR, pEqnTR );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiiM1 = SMPmakeEltKLUforCIDER (matrix, pEqnBR, psiEqnBL) ;
|
||||
pNode->fPPsiiM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiiM1 = SMPmakeElt(matrix, pEqnBR, psiEqnBL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPiM1 = SMPmakeEltKLUforCIDER (matrix, pEqnBR, pEqnBL) ;
|
||||
pNode->fPPiM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPiM1 = SMPmakeElt(matrix, pEqnBR, pEqnBL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsijM1 = SMPmakeEltKLUforCIDER (matrix, pEqnBR, psiEqnTR) ;
|
||||
pNode->fPPsijM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsijM1 = SMPmakeElt(matrix, pEqnBR, psiEqnTR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPjM1 = SMPmakeEltKLUforCIDER (matrix, pEqnBR, pEqnTR) ;
|
||||
pNode->fPPjM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPjM1 = SMPmakeElt(matrix, pEqnBR, pEqnTR);
|
||||
#endif
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
pNode->fPPsiiM1jM1 = spGetElement( matrix, pEqnBR, psiEqnTL );
|
||||
pNode->fPPiM1jM1 = spGetElement( matrix, pEqnBR, pEqnTL );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiiM1jM1 = SMPmakeEltKLUforCIDER (matrix, pEqnBR, psiEqnTL) ;
|
||||
pNode->fPPsiiM1jM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiiM1jM1 = SMPmakeElt(matrix, pEqnBR, psiEqnTL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPiM1jM1 = SMPmakeEltKLUforCIDER (matrix, pEqnBR, pEqnTL) ;
|
||||
pNode->fPPiM1jM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPiM1jM1 = SMPmakeElt(matrix, pEqnBR, pEqnTL);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pNode = pElem->pBLNode;
|
||||
pNode->fPsiPsiiP1 = spGetElement(matrix, psiEqnBL, psiEqnBR );
|
||||
pNode->fPsiPsijM1 = spGetElement(matrix, psiEqnBL, psiEqnTL );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsiiP1 = SMPmakeEltKLUforCIDER (matrix, psiEqnBL, psiEqnBR) ;
|
||||
pNode->fPsiPsiiP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsiiP1 = SMPmakeElt(matrix, psiEqnBL, psiEqnBR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsijM1 = SMPmakeEltKLUforCIDER (matrix, psiEqnBL, psiEqnTL) ;
|
||||
pNode->fPsiPsijM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsijM1 = SMPmakeElt(matrix, psiEqnBL, psiEqnTL);
|
||||
#endif
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
pNode->fPPsiiP1 = spGetElement( matrix, pEqnBL, psiEqnBR );
|
||||
pNode->fPPiP1 = spGetElement( matrix, pEqnBL, pEqnBR );
|
||||
pNode->fPPsijM1 = spGetElement( matrix, pEqnBL, psiEqnTL );
|
||||
pNode->fPPjM1 = spGetElement( matrix, pEqnBL, pEqnTL );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiiP1 = SMPmakeEltKLUforCIDER (matrix, pEqnBL, psiEqnBR) ;
|
||||
pNode->fPPsiiP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiiP1 = SMPmakeElt(matrix, pEqnBL, psiEqnBR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPiP1 = SMPmakeEltKLUforCIDER (matrix, pEqnBL, pEqnBR) ;
|
||||
pNode->fPPiP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPiP1 = SMPmakeElt(matrix, pEqnBL, pEqnBR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsijM1 = SMPmakeEltKLUforCIDER (matrix, pEqnBL, psiEqnTL) ;
|
||||
pNode->fPPsijM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsijM1 = SMPmakeElt(matrix, pEqnBL, psiEqnTL);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPjM1 = SMPmakeEltKLUforCIDER (matrix, pEqnBL, pEqnTL) ;
|
||||
pNode->fPPjM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPjM1 = SMPmakeElt(matrix, pEqnBL, pEqnTL);
|
||||
#endif
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
pNode->fPPsiiP1jM1 = spGetElement( matrix, pEqnBL, psiEqnTR );
|
||||
pNode->fPPiP1jM1 = spGetElement( matrix, pEqnBL, pEqnTR );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiiP1jM1 = SMPmakeEltKLUforCIDER (matrix, pEqnBL, psiEqnTR) ;
|
||||
pNode->fPPsiiP1jM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiiP1jM1 = SMPmakeElt(matrix, pEqnBL, psiEqnTR);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPiP1jM1 = SMPmakeEltKLUforCIDER (matrix, pEqnBL, pEqnTR) ;
|
||||
pNode->fPPiP1jM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPiP1jM1 = SMPmakeElt(matrix, pEqnBL, pEqnTR);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -199,27 +432,135 @@ void
|
|||
pEqn = pNode->pEqn;
|
||||
if ( pCh->type % 2 == 0 ) { /* Vertical Slice */
|
||||
if ( nIndex == 0 || nIndex == 3 ) { /* Left Side */
|
||||
pNode->fPPsiIn = spGetElement( matrix, pEqn, psiEqnInM );
|
||||
pNode->fPPsiInP1 = spGetElement( matrix, pEqn, psiEqnInP );
|
||||
pNode->fPPsiOx = spGetElement( matrix, pEqn, psiEqnOxM );
|
||||
pNode->fPPsiOxP1 = spGetElement( matrix, pEqn, psiEqnOxP );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiIn = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnInM) ;
|
||||
pNode->fPPsiInBinding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiIn = SMPmakeElt(matrix, pEqn, psiEqnInM);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiInP1 = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnInP) ;
|
||||
pNode->fPPsiInP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiInP1 = SMPmakeElt(matrix, pEqn, psiEqnInP);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiOx = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnOxM) ;
|
||||
pNode->fPPsiOxBinding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiOx = SMPmakeElt(matrix, pEqn, psiEqnOxM);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiOxP1 = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnOxP) ;
|
||||
pNode->fPPsiOxP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiOxP1 = SMPmakeElt(matrix, pEqn, psiEqnOxP);
|
||||
#endif
|
||||
|
||||
} else { /* Right Side */
|
||||
pNode->fPPsiInM1 = spGetElement( matrix, pEqn, psiEqnInM );
|
||||
pNode->fPPsiIn = spGetElement( matrix, pEqn, psiEqnInP );
|
||||
pNode->fPPsiOxM1 = spGetElement( matrix, pEqn, psiEqnOxM );
|
||||
pNode->fPPsiOx = spGetElement( matrix, pEqn, psiEqnOxP );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiInM1 = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnInM) ;
|
||||
pNode->fPPsiInM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiInM1 = SMPmakeElt(matrix, pEqn, psiEqnInM);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiIn = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnInP) ;
|
||||
pNode->fPPsiInBinding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiIn = SMPmakeElt(matrix, pEqn, psiEqnInP);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiOxM1 = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnOxM) ;
|
||||
pNode->fPPsiOxM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiOxM1 = SMPmakeElt(matrix, pEqn, psiEqnOxM);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiOx = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnOxP) ;
|
||||
pNode->fPPsiOxBinding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiOx = SMPmakeElt(matrix, pEqn, psiEqnOxP);
|
||||
#endif
|
||||
|
||||
}
|
||||
} else { /* Horizontal Slice */
|
||||
if ( nIndex == 0 || nIndex == 3 ) { /* Left (Top?) Side : bug 483 */
|
||||
pNode->fPPsiIn = spGetElement( matrix, pEqn, psiEqnInM );
|
||||
pNode->fPPsiInP1 = spGetElement( matrix, pEqn, psiEqnInP );
|
||||
pNode->fPPsiOx = spGetElement( matrix, pEqn, psiEqnOxM );
|
||||
pNode->fPPsiOxP1 = spGetElement( matrix, pEqn, psiEqnOxP );
|
||||
// <<<<<<< HEAD
|
||||
// if ( nIndex == 0 || nIndex == 3 ) { /* Left (Top?) Side : bug 483 */
|
||||
// pNode->fPPsiIn = spGetElement( matrix, pEqn, psiEqnInM );
|
||||
// pNode->fPPsiInP1 = spGetElement( matrix, pEqn, psiEqnInP );
|
||||
// pNode->fPPsiOx = spGetElement( matrix, pEqn, psiEqnOxM );
|
||||
// pNode->fPPsiOxP1 = spGetElement( matrix, pEqn, psiEqnOxP );
|
||||
// =======
|
||||
// if ( nIndex <= 1 ) { /* Top Side */
|
||||
//
|
||||
// #ifdef KLU
|
||||
// pNode->fPPsiIn = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnInM) ;
|
||||
// pNode->fPPsiInBinding = NULL ;
|
||||
// #else
|
||||
// pNode->fPPsiIn = SMPmakeElt(matrix, pEqn, psiEqnInM);
|
||||
// #endif
|
||||
//
|
||||
// #ifdef KLU
|
||||
// pNode->fPPsiInP1 = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnInP) ;
|
||||
// pNode->fPPsiInP1Binding = NULL ;
|
||||
// #else
|
||||
// pNode->fPPsiInP1 = SMPmakeElt(matrix, pEqn, psiEqnInP);
|
||||
// #endif
|
||||
//
|
||||
// #ifdef KLU
|
||||
// pNode->fPPsiOx = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnOxM) ;
|
||||
// pNode->fPPsiOxBinding = NULL ;
|
||||
// #else
|
||||
// pNode->fPPsiOx = SMPmakeElt(matrix, pEqn, psiEqnOxM);
|
||||
// #endif
|
||||
//
|
||||
// #ifdef KLU
|
||||
// pNode->fPPsiOxP1 = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnOxP) ;
|
||||
// pNode->fPPsiOxP1Binding = NULL ;
|
||||
// #else
|
||||
// pNode->fPPsiOxP1 = SMPmakeElt(matrix, pEqn, psiEqnOxP);
|
||||
// #endif
|
||||
//
|
||||
// >>>>>>> First KLU support of CIDER TWOD simulations
|
||||
} else { /* Bottom Side */
|
||||
pNode->fPPsiInM1 = spGetElement( matrix, pEqn, psiEqnInM );
|
||||
pNode->fPPsiIn = spGetElement( matrix, pEqn, psiEqnInP );
|
||||
pNode->fPPsiOxM1 = spGetElement( matrix, pEqn, psiEqnOxM );
|
||||
pNode->fPPsiOx = spGetElement( matrix, pEqn, psiEqnOxP );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiInM1 = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnInM) ;
|
||||
pNode->fPPsiInM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiInM1 = SMPmakeElt(matrix, pEqn, psiEqnInM);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiIn = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnInP) ;
|
||||
pNode->fPPsiInBinding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiIn = SMPmakeElt(matrix, pEqn, psiEqnInP);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiOxM1 = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnOxM) ;
|
||||
pNode->fPPsiOxM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiOxM1 = SMPmakeElt(matrix, pEqn, psiEqnOxM);
|
||||
#endif
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPPsiOx = SMPmakeEltKLUforCIDER (matrix, pEqn, psiEqnOxP) ;
|
||||
pNode->fPPsiOxBinding = NULL ;
|
||||
#else
|
||||
pNode->fPPsiOx = SMPmakeElt(matrix, pEqn, psiEqnOxP);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
} /* endfor nIndex */
|
||||
|
|
@ -229,6 +570,256 @@ void
|
|||
} /* endif SurfaceMobility */
|
||||
}
|
||||
|
||||
#ifdef KLU
|
||||
void
|
||||
TWOPbindCSC (TWOdevice *pDevice)
|
||||
{
|
||||
TWOelem *pElem;
|
||||
TWOnode *pNode;
|
||||
TWOchannel *pCh;
|
||||
BindKluElementCOO i, *matched, *BindStruct, *BindStructCSC ;
|
||||
int index ;
|
||||
size_t nz ;
|
||||
|
||||
int eIndex, nIndex;
|
||||
int nextIndex; /* index of node to find next element */
|
||||
int psiEqn, pEqn; /* scratch for deref'd eqn numbers */
|
||||
int psiEqnTL = 0, pEqnTL = 0;
|
||||
int psiEqnTR = 0, pEqnTR = 0;
|
||||
int psiEqnBR = 0, pEqnBR = 0;
|
||||
int psiEqnBL = 0, pEqnBL = 0;
|
||||
int psiEqnInM = 0, psiEqnInP = 0; /* scratch for deref'd surface eqns */
|
||||
int psiEqnOxM = 0, psiEqnOxP = 0; /* M= more negative, P= more positive */
|
||||
|
||||
BindStruct = pDevice->matrix->SMPkluMatrix->KLUmatrixBindStructCOO ;
|
||||
nz = pDevice->matrix->SMPkluMatrix->KLUmatrixNZ ;
|
||||
|
||||
BindStructCSC = (BindKluElementCOO *) malloc (nz * sizeof(BindKluElementCOO)) ;
|
||||
for (index = 0 ; index < (int)nz ; index++) {
|
||||
BindStructCSC [index] = BindStruct [index] ;
|
||||
}
|
||||
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
|
||||
/* first the self terms */
|
||||
for ( nIndex = 0; nIndex <= 3; nIndex++ ) {
|
||||
pNode = pElem->pNodes[ nIndex ];
|
||||
/* get poisson-only pointer */
|
||||
psiEqn = pNode->psiEqn;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsi, fPsiPsiBinding, psiEqn, psiEqn) ;
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* get continuity-coupling terms */
|
||||
pEqn = pNode->pEqn;
|
||||
pNode->nEqn = 0;
|
||||
/* pointers for additional terms */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiP, fPsiPBinding, psiEqn, pEqn) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsi, fPPsiBinding, pEqn, psiEqn) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPP, fPPBinding, pEqn, pEqn) ;
|
||||
|
||||
} else {
|
||||
pEqn = 0;
|
||||
}
|
||||
/* save equation indices */
|
||||
switch ( nIndex ) {
|
||||
case 0: /* TL Node */
|
||||
psiEqnTL = psiEqn;
|
||||
pEqnTL = pEqn;
|
||||
break;
|
||||
case 1: /* TR Node */
|
||||
psiEqnTR = psiEqn;
|
||||
pEqnTR = pEqn;
|
||||
break;
|
||||
case 2: /* BR Node */
|
||||
psiEqnBR = psiEqn;
|
||||
pEqnBR = pEqn;
|
||||
break;
|
||||
case 3: /* BL Node */
|
||||
psiEqnBL = psiEqn;
|
||||
pEqnBL = pEqn;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* now terms to couple to adjacent nodes */
|
||||
pNode = pElem->pTLNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsiiP1, fPsiPsiiP1Binding, psiEqnTL, psiEqnTR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsijP1, fPsiPsijP1Binding, psiEqnTL, psiEqnBL) ;
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiiP1, fPPsiiP1Binding, pEqnTL, psiEqnTR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPiP1, fPPiP1Binding, pEqnTL, pEqnTR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsijP1, fPPsijP1Binding, pEqnTL, psiEqnBL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPjP1, fPPjP1Binding, pEqnTL, pEqnBL) ;
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiiP1jP1, fPPsiiP1jP1Binding, pEqnTL, psiEqnBR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPiP1jP1, fPPiP1jP1Binding, pEqnTL, pEqnBR) ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pNode = pElem->pTRNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsiiM1, fPsiPsiiM1Binding, psiEqnTR, psiEqnTL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsijP1, fPsiPsijP1Binding, psiEqnTR, psiEqnBR) ;
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiiM1, fPPsiiM1Binding, pEqnTR, psiEqnTL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPiM1, fPPiM1Binding, pEqnTR, pEqnTL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsijP1, fPPsijP1Binding, pEqnTR, psiEqnBR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPjP1, fPPjP1Binding, pEqnTR, pEqnBR) ;
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiiM1jP1, fPPsiiM1jP1Binding, pEqnTR, psiEqnBL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPiM1jP1, fPPiM1jP1Binding, pEqnTR, pEqnBL) ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pNode = pElem->pBRNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsiiM1, fPsiPsiiM1Binding, psiEqnBR, psiEqnBL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsijM1, fPsiPsijM1Binding, psiEqnBR, psiEqnTR) ;
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiiM1, fPPsiiM1Binding, pEqnBR, psiEqnBL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPiM1, fPPiM1Binding, pEqnBR, pEqnBL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsijM1, fPPsijM1Binding, pEqnBR, psiEqnTR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPjM1, fPPjM1Binding, pEqnBR, pEqnTR) ;
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiiM1jM1, fPPsiiM1jM1Binding, pEqnBR, psiEqnTL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPiM1jM1, fPPiM1jM1Binding, pEqnBR, pEqnTL) ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pNode = pElem->pBLNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsiiP1, fPsiPsiiP1Binding, psiEqnBL, psiEqnBR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsijM1, fPsiPsijM1Binding, psiEqnBL, psiEqnTL) ;
|
||||
|
||||
if ( pElem->elemType == SEMICON ) {
|
||||
/* continuity equation pointers */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiiP1, fPPsiiP1Binding, pEqnBL, psiEqnBR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPiP1, fPPiP1Binding, pEqnBL, pEqnBR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsijM1, fPPsijM1Binding, pEqnBL, psiEqnTL) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPjM1, fPPjM1Binding, pEqnBL, pEqnTL) ;
|
||||
|
||||
/* Surface Mobility Model depends on diagonal node values */
|
||||
if ( MobDeriv && SurfaceMobility && pElem->channel ) {
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiiP1jM1, fPPsiiP1jM1Binding, pEqnBL, psiEqnTR) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPiP1jM1, fPPiP1jM1Binding, pEqnBL, pEqnTR) ;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Add terms for surface-field of inversion-layer mobility model.
|
||||
* Elements MUST be made from silicon for this to work.
|
||||
* No empty elements are allowed.
|
||||
* Don't need these pointers if SurfaceMobility isn't set.
|
||||
*/
|
||||
if ( MobDeriv && SurfaceMobility ) {
|
||||
for ( pCh = pDevice->pChannel; pCh != NULL;
|
||||
pCh = pCh->next ) {
|
||||
pElem = pCh->pNElem;
|
||||
switch (pCh->type) {
|
||||
case 0:
|
||||
psiEqnInM = pElem->pBLNode->psiEqn;
|
||||
psiEqnInP = pElem->pBRNode->psiEqn;
|
||||
psiEqnOxM = pElem->pTLNode->psiEqn;
|
||||
psiEqnOxP = pElem->pTRNode->psiEqn;
|
||||
break;
|
||||
case 1:
|
||||
psiEqnInM = pElem->pTLNode->psiEqn;
|
||||
psiEqnInP = pElem->pBLNode->psiEqn;
|
||||
psiEqnOxM = pElem->pTRNode->psiEqn;
|
||||
psiEqnOxP = pElem->pBRNode->psiEqn;
|
||||
break;
|
||||
case 2:
|
||||
psiEqnInM = pElem->pTLNode->psiEqn;
|
||||
psiEqnInP = pElem->pTRNode->psiEqn;
|
||||
psiEqnOxM = pElem->pBLNode->psiEqn;
|
||||
psiEqnOxP = pElem->pBRNode->psiEqn;
|
||||
break;
|
||||
case 3:
|
||||
psiEqnInM = pElem->pTRNode->psiEqn;
|
||||
psiEqnInP = pElem->pBRNode->psiEqn;
|
||||
psiEqnOxM = pElem->pTLNode->psiEqn;
|
||||
psiEqnOxP = pElem->pBLNode->psiEqn;
|
||||
break;
|
||||
}
|
||||
pElem = pCh->pSeed;
|
||||
nextIndex = (pCh->type + 2)%4;
|
||||
while (pElem && pElem->channel == pCh->id) {
|
||||
for ( nIndex = 0; nIndex <= 3; nIndex++ ) {
|
||||
pNode = pElem->pNodes[ nIndex ];
|
||||
psiEqn = pNode->psiEqn;
|
||||
pEqn = pNode->pEqn;
|
||||
if ( pCh->type % 2 == 0 ) { /* Vertical Slice */
|
||||
if ( nIndex == 0 || nIndex == 3 ) { /* Left Side */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiIn, fPPsiInBinding, pEqn, psiEqnInM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiInP1, fPPsiInP1Binding, pEqn, psiEqnInP) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiOx, fPPsiOxBinding, pEqn, psiEqnOxM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiOxP1, fPPsiOxP1Binding, pEqn, psiEqnOxP) ;
|
||||
|
||||
} else { /* Right Side */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiInM1, fPPsiInM1Binding, pEqn, psiEqnInM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiIn, fPPsiInBinding, pEqn, psiEqnInP) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiOxM1, fPPsiOxM1Binding, pEqn, psiEqnOxM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiOx, fPPsiOxBinding, pEqn, psiEqnOxP) ;
|
||||
|
||||
}
|
||||
} else { /* Horizontal Slice */
|
||||
if ( nIndex <= 1 ) { /* Top Side */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiIn, fPPsiInBinding, pEqn, psiEqnInM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiInP1, fPPsiInP1Binding, pEqn, psiEqnInP) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiOx, fPPsiOxBinding, pEqn, psiEqnOxM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiOxP1, fPPsiOxP1Binding, pEqn, psiEqnOxP) ;
|
||||
|
||||
} else { /* Bottom Side */
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiInM1, fPPsiInM1Binding, pEqn, psiEqnInM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiIn, fPPsiInBinding, pEqn, psiEqnInP) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiOxM1, fPPsiOxM1Binding, pEqn, psiEqnOxM) ;
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPPsiOx, fPPsiOxBinding, pEqn, psiEqnOxP) ;
|
||||
|
||||
}
|
||||
}
|
||||
} /* endfor nIndex */
|
||||
pElem = pElem->pElems[ nextIndex ];
|
||||
} /* endwhile pElem */
|
||||
} /* endfor pCh */
|
||||
} /* endif SurfaceMobility */
|
||||
|
||||
free (BindStructCSC) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The Jacobian and Rhs are loaded by the following function.
|
||||
|
|
@ -268,7 +859,17 @@ void
|
|||
}
|
||||
|
||||
/* zero the matrix */
|
||||
spClear( pDevice->matrix );
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
SMPclearKLUforCIDER (pDevice->matrix) ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
SMPclear(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
}
|
||||
#endif
|
||||
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
|
|
@ -432,7 +1033,17 @@ void
|
|||
TWOPcommonTerms( pDevice, FALSE, FALSE, NULL );
|
||||
|
||||
/* zero the matrix */
|
||||
spClear( pDevice->matrix );
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
SMPclearKLUforCIDER (pDevice->matrix) ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
SMPclear(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
}
|
||||
#endif
|
||||
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ Author: 1991 David A. Gates, U. C. Berkeley CAD Group
|
|||
#include "twoddefs.h"
|
||||
#include "twodext.h"
|
||||
|
||||
#ifdef KLU
|
||||
#include "ngspice/klu-binding.h"
|
||||
#endif
|
||||
|
||||
/* functions to setup and solve the 2D poisson equation */
|
||||
|
||||
|
|
@ -31,7 +34,14 @@ TWOQjacBuild(TWOdevice *pDevice)
|
|||
for ( nIndex = 0; nIndex <= 3; nIndex++ ) {
|
||||
if ( pElem->evalNodes[ nIndex ] ) {
|
||||
pNode = pElem->pNodes[ nIndex ];
|
||||
pNode->fPsiPsi = spGetElement( matrix, pNode->poiEqn, pNode->poiEqn );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsi = SMPmakeEltKLUforCIDER (matrix, pNode->poiEqn, pNode->poiEqn) ;
|
||||
pNode->fPsiPsiBinding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsi = SMPmakeElt(matrix, pNode->poiEqn, pNode->poiEqn);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -40,24 +50,80 @@ TWOQjacBuild(TWOdevice *pDevice)
|
|||
|
||||
pNode = pElem->pTLNode;
|
||||
pNode1 = pElem->pTRNode;
|
||||
pNode->fPsiPsiiP1 = spGetElement(matrix, pNode->poiEqn, pNode1->poiEqn );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsiiP1 = SMPmakeEltKLUforCIDER (matrix, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
pNode->fPsiPsiiP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsiiP1 = SMPmakeElt(matrix, pNode->poiEqn, pNode1->poiEqn);
|
||||
#endif
|
||||
|
||||
pNode1 = pElem->pBLNode;
|
||||
pNode->fPsiPsijP1 = spGetElement(matrix, pNode->poiEqn, pNode1->poiEqn );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsijP1 = SMPmakeEltKLUforCIDER (matrix, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
pNode->fPsiPsijP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsijP1 = SMPmakeElt(matrix, pNode->poiEqn, pNode1->poiEqn);
|
||||
#endif
|
||||
|
||||
pNode = pElem->pTRNode;
|
||||
pNode1 = pElem->pTLNode;
|
||||
pNode->fPsiPsiiM1 = spGetElement(matrix, pNode->poiEqn, pNode1->poiEqn );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsiiM1 = SMPmakeEltKLUforCIDER (matrix, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
pNode->fPsiPsiiM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsiiM1 = SMPmakeElt(matrix, pNode->poiEqn, pNode1->poiEqn);
|
||||
#endif
|
||||
|
||||
pNode1 = pElem->pBRNode;
|
||||
pNode->fPsiPsijP1 = spGetElement(matrix, pNode->poiEqn, pNode1->poiEqn );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsijP1 = SMPmakeEltKLUforCIDER (matrix, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
pNode->fPsiPsijP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsijP1 = SMPmakeElt(matrix, pNode->poiEqn, pNode1->poiEqn);
|
||||
#endif
|
||||
|
||||
pNode = pElem->pBRNode;
|
||||
pNode1 = pElem->pBLNode;
|
||||
pNode->fPsiPsiiM1 = spGetElement(matrix, pNode->poiEqn, pNode1->poiEqn );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsiiM1 = SMPmakeEltKLUforCIDER (matrix, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
pNode->fPsiPsiiM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsiiM1 = SMPmakeElt(matrix, pNode->poiEqn, pNode1->poiEqn);
|
||||
#endif
|
||||
|
||||
pNode1 = pElem->pTRNode;
|
||||
pNode->fPsiPsijM1 = spGetElement(matrix, pNode->poiEqn, pNode1->poiEqn );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsijM1 = SMPmakeEltKLUforCIDER (matrix, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
pNode->fPsiPsijM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsijM1 = SMPmakeElt(matrix, pNode->poiEqn, pNode1->poiEqn);
|
||||
#endif
|
||||
|
||||
pNode = pElem->pBLNode;
|
||||
pNode1 = pElem->pBRNode;
|
||||
pNode->fPsiPsiiP1 = spGetElement(matrix, pNode->poiEqn, pNode1->poiEqn );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsiiP1 = SMPmakeEltKLUforCIDER (matrix, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
pNode->fPsiPsiiP1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsiiP1 = SMPmakeElt(matrix, pNode->poiEqn, pNode1->poiEqn);
|
||||
#endif
|
||||
|
||||
pNode1 = pElem->pTLNode;
|
||||
pNode->fPsiPsijM1 = spGetElement(matrix, pNode->poiEqn, pNode1->poiEqn );
|
||||
|
||||
#ifdef KLU
|
||||
pNode->fPsiPsijM1 = SMPmakeEltKLUforCIDER (matrix, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
pNode->fPsiPsijM1Binding = NULL ;
|
||||
#else
|
||||
pNode->fPsiPsijM1 = SMPmakeElt(matrix, pNode->poiEqn, pNode1->poiEqn);
|
||||
#endif
|
||||
|
||||
}
|
||||
/*
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
|
|
@ -91,6 +157,81 @@ TWOQjacBuild(TWOdevice *pDevice)
|
|||
*/
|
||||
}
|
||||
|
||||
#ifdef KLU
|
||||
void
|
||||
TWOQbindCSC (TWOdevice *pDevice)
|
||||
{
|
||||
TWOelem *pElem;
|
||||
TWOnode *pNode, *pNode1;
|
||||
int eIndex, nIndex;
|
||||
int index ;
|
||||
BindKluElementCOO i, *matched, *BindStruct, *BindStructCSC ;
|
||||
size_t nz ;
|
||||
|
||||
BindStruct = pDevice->matrix->SMPkluMatrix->KLUmatrixBindStructCOO ;
|
||||
nz = pDevice->matrix->SMPkluMatrix->KLUmatrixNZ ;
|
||||
|
||||
BindStructCSC = (BindKluElementCOO *) malloc (nz * sizeof(BindKluElementCOO)) ;
|
||||
for (index = 0 ; index < (int)nz ; index++) {
|
||||
BindStructCSC [index] = BindStruct [index] ;
|
||||
}
|
||||
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
for ( nIndex = 0; nIndex <= 3; nIndex++ ) {
|
||||
if ( pElem->evalNodes[ nIndex ] ) {
|
||||
pNode = pElem->pNodes[ nIndex ];
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsi, fPsiPsiBinding, pNode->poiEqn, pNode->poiEqn) ;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
|
||||
pNode = pElem->pTLNode;
|
||||
pNode1 = pElem->pTRNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsiiP1, fPsiPsiiP1Binding, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
|
||||
pNode1 = pElem->pBLNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsijP1, fPsiPsijP1Binding, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
|
||||
pNode = pElem->pTRNode;
|
||||
pNode1 = pElem->pTLNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsiiM1, fPsiPsiiM1Binding, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
|
||||
pNode1 = pElem->pBRNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsijP1, fPsiPsijP1Binding, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
|
||||
pNode = pElem->pBRNode;
|
||||
pNode1 = pElem->pBLNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsiiM1, fPsiPsiiM1Binding, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
|
||||
pNode1 = pElem->pTRNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsijM1, fPsiPsijM1Binding, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
|
||||
pNode = pElem->pBLNode;
|
||||
pNode1 = pElem->pBRNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsiiP1, fPsiPsiiP1Binding, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
|
||||
pNode1 = pElem->pTLNode;
|
||||
|
||||
CREATE_KLU_BINDING_TABLE_CIDER(fPsiPsijM1, fPsiPsijM1Binding, pNode->poiEqn, pNode1->poiEqn) ;
|
||||
|
||||
}
|
||||
|
||||
free (BindStructCSC) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
TWOQsysLoad(TWOdevice *pDevice)
|
||||
{
|
||||
|
|
@ -109,7 +250,17 @@ TWOQsysLoad(TWOdevice *pDevice)
|
|||
}
|
||||
|
||||
/* zero the matrix */
|
||||
spClear( pDevice->matrix );
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
SMPclearKLUforCIDER (pDevice->matrix) ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
SMPclear(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
}
|
||||
#endif
|
||||
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
|
|
|
|||
|
|
@ -52,8 +52,13 @@ void NUMD2project(TWOdevice *pDevice, double delV)
|
|||
}
|
||||
incVpn = pDevice->dcDeltaSolution;
|
||||
storeNewRhs( pDevice, pContact );
|
||||
spSolve( pDevice->matrix, pDevice->rhs, incVpn, NULL, NULL );
|
||||
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, pDevice->rhs, incVpn, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolveForCIDER (pDevice->matrix, pDevice->rhs, incVpn) ;
|
||||
#endif
|
||||
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
for ( index = 0; index <= 3; index++ ) {
|
||||
|
|
@ -131,8 +136,13 @@ void NBJT2project(TWOdevice *pDevice, double delVce, double delVbe)
|
|||
if ( ABS( delVce ) > MIN_DELV ) {
|
||||
incVce = pDevice->dcDeltaSolution;
|
||||
storeNewRhs( pDevice, pColContact );
|
||||
spSolve( pDevice->matrix, pDevice->rhs, incVce, NULL, NULL);
|
||||
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, pDevice->rhs, incVce, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolveForCIDER (pDevice->matrix, pDevice->rhs, incVce) ;
|
||||
#endif
|
||||
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
for ( index = 0; index <= 3; index++ ) {
|
||||
|
|
@ -175,8 +185,13 @@ void NBJT2project(TWOdevice *pDevice, double delVce, double delVbe)
|
|||
if ( ABS( delVbe ) > MIN_DELV ) {
|
||||
incVbe = pDevice->copiedSolution;
|
||||
storeNewRhs( pDevice, pBaseContact );
|
||||
spSolve( pDevice->matrix, pDevice->rhs, incVbe, NULL, NULL);
|
||||
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, pDevice->rhs, incVbe, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolveForCIDER (pDevice->matrix, pDevice->rhs, incVbe) ;
|
||||
#endif
|
||||
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
for ( index = 0; index <= 3; index++ ) {
|
||||
|
|
@ -265,8 +280,13 @@ void NUMOSproject(TWOdevice *pDevice, double delVdb, double delVsb,
|
|||
|
||||
incVdb = pDevice->dcDeltaSolution;
|
||||
storeNewRhs( pDevice, pDContact );
|
||||
spSolve( pDevice->matrix, pDevice->rhs, incVdb, NULL, NULL);
|
||||
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, pDevice->rhs, incVdb, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolveForCIDER (pDevice->matrix, pDevice->rhs, incVdb) ;
|
||||
#endif
|
||||
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
for ( index = 0; index <= 3; index++ ) {
|
||||
|
|
@ -310,8 +330,13 @@ void NUMOSproject(TWOdevice *pDevice, double delVdb, double delVsb,
|
|||
|
||||
incVsb = pDevice->dcDeltaSolution;
|
||||
storeNewRhs( pDevice, pSContact );
|
||||
spSolve( pDevice->matrix, pDevice->rhs, incVsb, NULL, NULL);
|
||||
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, pDevice->rhs, incVsb, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolveForCIDER (pDevice->matrix, pDevice->rhs, incVsb) ;
|
||||
#endif
|
||||
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
for ( index = 0; index <= 3; index++ ) {
|
||||
|
|
@ -354,8 +379,13 @@ void NUMOSproject(TWOdevice *pDevice, double delVdb, double delVsb,
|
|||
|
||||
incVgb = pDevice->dcDeltaSolution;
|
||||
storeNewRhs( pDevice, pGContact );
|
||||
spSolve( pDevice->matrix, pDevice->rhs, incVgb, NULL, NULL);
|
||||
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, pDevice->rhs, incVgb, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolveForCIDER (pDevice->matrix, pDevice->rhs, incVgb) ;
|
||||
#endif
|
||||
|
||||
for ( eIndex = 1; eIndex <= pDevice->numElems; eIndex++ ) {
|
||||
pElem = pDevice->elements[ eIndex ];
|
||||
for ( index = 0; index <= 3; index++ ) {
|
||||
|
|
|
|||
|
|
@ -92,7 +92,13 @@ TWOdcSolve(TWOdevice *pDevice, int iterationLimit, BOOLEAN newSolver,
|
|||
|
||||
/* FACTOR */
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
error = spFactor(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
error = SMPreorderKLUforCIDER (pDevice->matrix) ;
|
||||
#else
|
||||
error = SMPluFacForCIDER (pDevice->matrix) ;
|
||||
#endif
|
||||
|
||||
factorTime += SPfrontEnd->IFseconds() - startTime;
|
||||
if (newSolver) {
|
||||
if (pDevice->iterationNumber == 1) {
|
||||
|
|
@ -116,7 +122,7 @@ TWOdcSolve(TWOdevice *pDevice, int iterationLimit, BOOLEAN newSolver,
|
|||
if (foundError(error)) {
|
||||
if (error == spSINGULAR) {
|
||||
int badRow, badCol;
|
||||
spWhereSingular(pDevice->matrix, &badRow, &badCol);
|
||||
SMPgetError(pDevice->matrix, &badRow, &badCol);
|
||||
printf("***** singular at (%d,%d)\n", badRow, badCol);
|
||||
}
|
||||
pDevice->converged = FALSE;
|
||||
|
|
@ -126,7 +132,13 @@ TWOdcSolve(TWOdevice *pDevice, int iterationLimit, BOOLEAN newSolver,
|
|||
|
||||
/* SOLVE */
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
spSolve(pDevice->matrix, rhs, delta, NULL, NULL);
|
||||
|
||||
#ifdef KLU
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, rhs, delta, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolveForCIDER (pDevice->matrix, rhs, delta) ;
|
||||
#endif
|
||||
|
||||
solveTime += SPfrontEnd->IFseconds() - startTime;
|
||||
|
||||
/* UPDATE */
|
||||
|
|
@ -362,7 +374,13 @@ TWOresetJacobian(TWOdevice *pDevice)
|
|||
printf("TWOresetJacobian: unknown carrier type\n");
|
||||
exit(-1);
|
||||
}
|
||||
error = spFactor(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
error = SMPreorderKLUforCIDER (pDevice->matrix) ;
|
||||
#else
|
||||
error = SMPluFacForCIDER (pDevice->matrix) ;
|
||||
#endif
|
||||
|
||||
if (foundError(error)) {
|
||||
exit(-1);
|
||||
}
|
||||
|
|
@ -464,7 +482,13 @@ int TWOequilSolve(TWOdevice *pDevice)
|
|||
FREE(pDevice->copiedSolution);
|
||||
FREE(pDevice->rhs);
|
||||
FREE(pDevice->rhsImag);
|
||||
spDestroy(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
SMPdestroyKLUforCIDER (pDevice->matrix) ;
|
||||
#else
|
||||
SMPdestroy (pDevice->matrix) ;
|
||||
#endif
|
||||
|
||||
/* FALLTHROUGH */
|
||||
case SLV_NONE: {
|
||||
/* Allocate memory needed for an equilibrium solution */
|
||||
|
|
@ -476,15 +500,64 @@ int TWOequilSolve(TWOdevice *pDevice)
|
|||
XCALLOC(pDevice->dcDeltaSolution, double, n_dim);
|
||||
XCALLOC(pDevice->copiedSolution, double, n_dim);
|
||||
XCALLOC(pDevice->rhs, double, n_dim);
|
||||
pDevice->matrix = spCreate(n_eqn, 0, &error);
|
||||
|
||||
pDevice->matrix = TMALLOC (SMPmatrix, 1) ;
|
||||
|
||||
#ifdef KLU
|
||||
pDevice->matrix->CKTkluMODE = CKTkluON ; /* Francesco Lannutti - To be sustitued with a value coming from the uplevel */
|
||||
error = SMPnewMatrixKLUforCIDER (pDevice->matrix, pDevice->numEqns, CKTkluMatrixReal) ;
|
||||
#else
|
||||
error = SMPnewMatrixForCIDER (pDevice->matrix, pDevice->numEqns, 0) ;
|
||||
#endif
|
||||
|
||||
if (error == spNO_MEMORY) {
|
||||
(void) fprintf(cp_err, "TWOequilSolve: Out of Memory\n");
|
||||
return E_NOMEM;
|
||||
}
|
||||
newSolver = TRUE;
|
||||
spSetReal(pDevice->matrix); /* set to a real matrix */
|
||||
|
||||
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
pDevice->matrix->SMPkluMatrix->KLUmatrixIsComplex = CKTkluMatrixReal ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
spSetReal (pDevice->matrix->SPmatrix) ;
|
||||
|
||||
#ifdef KLU
|
||||
}
|
||||
#endif
|
||||
|
||||
TWOQjacBuild(pDevice);
|
||||
pDevice->numOrigEquil = spElementCount(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
|
||||
/* Convert the COO Storage to CSC for KLU and Fill the Binding Table */
|
||||
SMPconvertCOOtoCSCKLUforCIDER (pDevice->matrix) ;
|
||||
|
||||
/* Bind the KLU Pointers */
|
||||
TWOQbindCSC (pDevice) ;
|
||||
|
||||
/* Perform KLU Matrix Analysis */
|
||||
pDevice->matrix->SMPkluMatrix->KLUmatrixSymbolic = klu_analyze ((int)pDevice->matrix->SMPkluMatrix->KLUmatrixN, pDevice->matrix->SMPkluMatrix->KLUmatrixAp,
|
||||
pDevice->matrix->SMPkluMatrix->KLUmatrixAi, pDevice->matrix->SMPkluMatrix->KLUmatrixCommon) ;
|
||||
if (pDevice->matrix->SMPkluMatrix->KLUmatrixSymbolic == NULL) {
|
||||
printf ("CIDER: KLU Failed\n") ;
|
||||
if (pDevice->matrix->SMPkluMatrix->KLUmatrixCommon->status == KLU_EMPTY_MATRIX) {
|
||||
return ; // Francesco Lannutti - Fix KLU return values
|
||||
}
|
||||
}
|
||||
printf ("CIDER: KLU to be fixed: spElementCount\n") ;
|
||||
pDevice->numOrigEquil = 0 ; // Francesco Lannutti - Fix for KLU
|
||||
} else {
|
||||
pDevice->numOrigEquil = spElementCount (pDevice->matrix->SPmatrix) ;
|
||||
}
|
||||
#else
|
||||
pDevice->numOrigEquil = spElementCount (pDevice->matrix->SPmatrix) ;
|
||||
#endif
|
||||
|
||||
pDevice->numFillEquil = 0;
|
||||
pDevice->solverType = SLV_EQUIL;
|
||||
break;
|
||||
|
|
@ -504,7 +577,21 @@ int TWOequilSolve(TWOdevice *pDevice)
|
|||
/* MISCELLANEOUS */
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
if (newSolver) {
|
||||
pDevice->numFillEquil = spFillinCount(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
// Francesco Lannutti - Fix for KLU
|
||||
printf ("CIDER: KLU to be fixed: spFillinCount\n") ;
|
||||
pDevice->numFillEquil = 0 ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
pDevice->numFillEquil = spFillinCount(pDevice->matrix->SPmatrix);
|
||||
|
||||
#ifdef KLU
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
if (pDevice->converged) {
|
||||
TWOQcommonTerms(pDevice);
|
||||
|
|
@ -557,7 +644,13 @@ TWObiasSolve(TWOdevice *pDevice, int iterationLimit, BOOLEAN tranAnalysis,
|
|||
FREE(pDevice->dcDeltaSolution);
|
||||
FREE(pDevice->copiedSolution);
|
||||
FREE(pDevice->rhs);
|
||||
spDestroy(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
SMPdestroyKLUforCIDER (pDevice->matrix) ;
|
||||
#else
|
||||
SMPdestroy (pDevice->matrix) ;
|
||||
#endif
|
||||
|
||||
/* FALLTHROUGH */
|
||||
case SLV_NONE:
|
||||
/* Set up for bias */
|
||||
|
|
@ -568,7 +661,16 @@ TWObiasSolve(TWOdevice *pDevice, int iterationLimit, BOOLEAN tranAnalysis,
|
|||
XCALLOC(pDevice->copiedSolution, double, pDevice->dimBias);
|
||||
XCALLOC(pDevice->rhs, double, pDevice->dimBias);
|
||||
XCALLOC(pDevice->rhsImag, double, pDevice->dimBias);
|
||||
pDevice->matrix = spCreate(pDevice->numEqns, 1, &error);
|
||||
|
||||
pDevice->matrix = TMALLOC (SMPmatrix, 1) ;
|
||||
|
||||
#ifdef KLU
|
||||
pDevice->matrix->CKTkluMODE = CKTkluON ; /* Francesco Lannutti - To be sustitued with a value coming from the uplevel */
|
||||
error = SMPnewMatrixKLUforCIDER (pDevice->matrix, pDevice->numEqns, CKTkluMatrixComplex) ;
|
||||
#else
|
||||
error = SMPnewMatrixForCIDER (pDevice->matrix, pDevice->numEqns, 1) ;
|
||||
#endif
|
||||
|
||||
if (error == spNO_MEMORY) {
|
||||
printf("TWObiasSolve: Out of Memory\n");
|
||||
exit(-1);
|
||||
|
|
@ -581,12 +683,56 @@ TWObiasSolve(TWOdevice *pDevice, int iterationLimit, BOOLEAN tranAnalysis,
|
|||
} else if (OneCarrier == P_TYPE) {
|
||||
TWOPjacBuild(pDevice);
|
||||
}
|
||||
pDevice->numOrigBias = spElementCount(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
|
||||
/* Convert the COO Storage to CSC for KLU and Fill the Binding Table */
|
||||
SMPconvertCOOtoCSCKLUforCIDER (pDevice->matrix) ;
|
||||
|
||||
/* Bind the KLU Pointers */
|
||||
if (!OneCarrier) {
|
||||
TWObindCSC (pDevice) ;
|
||||
} else if (OneCarrier == N_TYPE) {
|
||||
TWONbindCSC (pDevice) ;
|
||||
} else if (OneCarrier == P_TYPE) {
|
||||
TWOPbindCSC (pDevice) ;
|
||||
}
|
||||
|
||||
/* Perform KLU Matrix Analysis */
|
||||
pDevice->matrix->SMPkluMatrix->KLUmatrixSymbolic = klu_analyze ((int)pDevice->matrix->SMPkluMatrix->KLUmatrixN, pDevice->matrix->SMPkluMatrix->KLUmatrixAp,
|
||||
pDevice->matrix->SMPkluMatrix->KLUmatrixAi, pDevice->matrix->SMPkluMatrix->KLUmatrixCommon) ;
|
||||
if (pDevice->matrix->SMPkluMatrix->KLUmatrixSymbolic == NULL) {
|
||||
if (pDevice->matrix->SMPkluMatrix->KLUmatrixCommon->status == KLU_EMPTY_MATRIX) {
|
||||
printf ("CIDER: KLU failed\n") ;
|
||||
return ; // Francesco Lannutti - Fix KLU return values
|
||||
}
|
||||
}
|
||||
pDevice->numOrigBias = 0 ; // Francesco Lannutti - Fix for KLU
|
||||
} else {
|
||||
pDevice->numOrigBias = spElementCount(pDevice->matrix->SPmatrix);
|
||||
}
|
||||
#else
|
||||
pDevice->numOrigBias = spElementCount (pDevice->matrix->SPmatrix) ;
|
||||
#endif
|
||||
|
||||
pDevice->numFillBias = 0;
|
||||
TWOstoreInitialGuess(pDevice);
|
||||
/* FALLTHROUGH */
|
||||
case SLV_SMSIG:
|
||||
spSetReal(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
pDevice->matrix->SMPkluMatrix->KLUmatrixIsComplex = CKTkluMatrixReal ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
spSetReal (pDevice->matrix->SPmatrix) ;
|
||||
|
||||
#ifdef KLU
|
||||
}
|
||||
#endif
|
||||
|
||||
pDevice->solverType = SLV_BIAS;
|
||||
break;
|
||||
case SLV_BIAS:
|
||||
|
|
@ -604,7 +750,21 @@ TWObiasSolve(TWOdevice *pDevice, int iterationLimit, BOOLEAN tranAnalysis,
|
|||
/* MISCELLANEOUS */
|
||||
startTime = SPfrontEnd->IFseconds();
|
||||
if (newSolver) {
|
||||
pDevice->numFillBias = spFillinCount(pDevice->matrix);
|
||||
|
||||
#ifdef KLU
|
||||
if (pDevice->matrix->CKTkluMODE) {
|
||||
// Francesco Lannutti - Fix for KLU
|
||||
printf ("CIDER: KLU to be fixed: spFillinCount\n") ;
|
||||
pDevice->numFillBias = 0 ;
|
||||
} else {
|
||||
#endif
|
||||
|
||||
pDevice->numFillBias = spFillinCount (pDevice->matrix->SPmatrix) ; // Francesco Lannutti - Fix for KLU
|
||||
|
||||
#ifdef KLU
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
if ((!pDevice->converged) && iterationLimit > 1) {
|
||||
printf("TWObiasSolve: No Convergence\n");
|
||||
|
|
@ -1142,9 +1302,12 @@ TWOnuNorm(TWOdevice *pDevice)
|
|||
int index;
|
||||
|
||||
/* the LU Decomposed matrix is available. use it to calculate x */
|
||||
|
||||
spSolve(pDevice->matrix, pDevice->rhs, pDevice->rhsImag,
|
||||
NULL, NULL);
|
||||
#ifdef KLU
|
||||
printf ("CIDER: KLU to be fixed TWOnuNorm\n") ;
|
||||
SMPsolveKLUforCIDER (pDevice->matrix, pDevice->rhs, pDevice->rhsImag, NULL, NULL) ;
|
||||
#else
|
||||
SMPsolveForCIDER (pDevice->matrix, pDevice->rhs, pDevice->rhsImag) ;
|
||||
#endif
|
||||
|
||||
/* the solution is in the rhsImag vector */
|
||||
/* compute L2-norm of the rhsImag vector */
|
||||
|
|
@ -1202,7 +1365,14 @@ TWOjacCheck(TWOdevice *pDevice, BOOLEAN tranAnalysis, TWOtranInfo *info)
|
|||
pDevice->dcSolution[index] = pDevice->copiedSolution[index];
|
||||
for (rIndex = 1; rIndex <= pDevice->numEqns; rIndex++) {
|
||||
diff = (pDevice->rhsImag[rIndex] - pDevice->rhs[rIndex]) / del;
|
||||
dptr = spFindElement(pDevice->matrix, rIndex, index);
|
||||
|
||||
#ifdef KLU
|
||||
printf ("CIDER: KLU to be fixed: spFindElement") ;
|
||||
dptr = NULL ;
|
||||
#else
|
||||
dptr = spFindElement(pDevice->matrix->SPmatrix, rIndex, index); // Francesco Lannutti - Fix for KLU
|
||||
#endif
|
||||
|
||||
if (dptr != NULL) {
|
||||
tol = (1e-4 * pDevice->abstol) + (1e-2 * MAX(ABS(diff), ABS(*dptr)));
|
||||
if ((diff != 0.0) && (ABS(diff - *dptr) > tol)) {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@ Authors: 1987 Karti Mayaram, 1991 David Gates
|
|||
|
||||
#include "ngspice/material.h"
|
||||
|
||||
#ifdef KLU
|
||||
#include "ngspice/klu.h"
|
||||
#endif
|
||||
|
||||
typedef struct sTWOelem
|
||||
{
|
||||
struct sTWOelem *pElems[4]; /* array to store the element neighbors */
|
||||
|
|
@ -44,6 +48,20 @@ typedef struct sTWOelem
|
|||
int direction; /* direction of flow for channels */
|
||||
int evalNodes[4]; /* nodes to be evaluated in elem */
|
||||
int evalEdges[4]; /* edges to be evaluated in elem */
|
||||
|
||||
#ifdef KLU
|
||||
double *KLUleftLeftNode ;
|
||||
double *KLUleftRightNode ;
|
||||
double *KLUrightLeftNode ;
|
||||
double *KLUrightRightNode ;
|
||||
|
||||
BindKluElementCOO *KLUleftLeftNodeBinding ;
|
||||
BindKluElementCOO *KLUleftRightNodeBinding ;
|
||||
BindKluElementCOO *KLUrightLeftNodeBinding ;
|
||||
BindKluElementCOO *KLUrightRightNodeBinding ;
|
||||
|
||||
#endif
|
||||
|
||||
} TWOelem;
|
||||
|
||||
#define pTopElem pElems[0]
|
||||
|
|
@ -193,6 +211,67 @@ typedef struct sTWOnode {
|
|||
double *fPPsiOxM1;
|
||||
double *fPPsiOx;
|
||||
double *fPPsiOxP1;
|
||||
|
||||
#ifdef KLU
|
||||
BindKluElementCOO *fPsiPsiBinding ;
|
||||
BindKluElementCOO *fPsiNBinding ;
|
||||
BindKluElementCOO *fPsiPBinding ;
|
||||
BindKluElementCOO *fNPsiBinding ;
|
||||
BindKluElementCOO *fNNBinding ;
|
||||
BindKluElementCOO *fNPBinding ;
|
||||
BindKluElementCOO *fPPsiBinding ;
|
||||
BindKluElementCOO *fPNBinding ;
|
||||
BindKluElementCOO *fPPBinding ;
|
||||
BindKluElementCOO *fPsiPsiiP1Binding ;
|
||||
BindKluElementCOO *fPsiPsijP1Binding ;
|
||||
BindKluElementCOO *fNPsiiP1Binding ;
|
||||
BindKluElementCOO *fNNiP1Binding ;
|
||||
BindKluElementCOO *fNPsijP1Binding ;
|
||||
BindKluElementCOO *fNNjP1Binding ;
|
||||
BindKluElementCOO *fPPsiiP1Binding ;
|
||||
BindKluElementCOO *fPPiP1Binding ;
|
||||
BindKluElementCOO *fPPsijP1Binding ;
|
||||
BindKluElementCOO *fPPjP1Binding ;
|
||||
BindKluElementCOO *fNPsiiP1jP1Binding ;
|
||||
BindKluElementCOO *fNNiP1jP1Binding ;
|
||||
BindKluElementCOO *fPPsiiP1jP1Binding ;
|
||||
BindKluElementCOO *fPPiP1jP1Binding ;
|
||||
BindKluElementCOO *fPsiPsiiM1Binding ;
|
||||
BindKluElementCOO *fNPsiiM1Binding ;
|
||||
BindKluElementCOO *fNNiM1Binding ;
|
||||
BindKluElementCOO *fPPsiiM1Binding ;
|
||||
BindKluElementCOO *fPPiM1Binding ;
|
||||
BindKluElementCOO *fNPsiiM1jP1Binding ;
|
||||
BindKluElementCOO *fNNiM1jP1Binding ;
|
||||
BindKluElementCOO *fPPsiiM1jP1Binding ;
|
||||
BindKluElementCOO *fPPiM1jP1Binding ;
|
||||
BindKluElementCOO *fPsiPsijM1Binding ;
|
||||
BindKluElementCOO *fNPsijM1Binding ;
|
||||
BindKluElementCOO *fNNjM1Binding ;
|
||||
BindKluElementCOO *fPPsijM1Binding ;
|
||||
BindKluElementCOO *fPPjM1Binding ;
|
||||
BindKluElementCOO *fNPsiiM1jM1Binding ;
|
||||
BindKluElementCOO *fNNiM1jM1Binding ;
|
||||
BindKluElementCOO *fPPsiiM1jM1Binding ;
|
||||
BindKluElementCOO *fPPiM1jM1Binding ;
|
||||
BindKluElementCOO *fNPsiiP1jM1Binding ;
|
||||
BindKluElementCOO *fNNiP1jM1Binding ;
|
||||
BindKluElementCOO *fPPsiiP1jM1Binding ;
|
||||
BindKluElementCOO *fPPiP1jM1Binding ;
|
||||
BindKluElementCOO *fNPsiInBinding ;
|
||||
BindKluElementCOO *fNPsiInP1Binding ;
|
||||
BindKluElementCOO *fNPsiOxBinding ;
|
||||
BindKluElementCOO *fNPsiOxP1Binding ;
|
||||
BindKluElementCOO *fPPsiInBinding ;
|
||||
BindKluElementCOO *fPPsiInP1Binding ;
|
||||
BindKluElementCOO *fPPsiOxBinding ;
|
||||
BindKluElementCOO *fPPsiOxP1Binding ;
|
||||
BindKluElementCOO *fNPsiInM1Binding ;
|
||||
BindKluElementCOO *fNPsiOxM1Binding ;
|
||||
BindKluElementCOO *fPPsiInM1Binding ;
|
||||
BindKluElementCOO *fPPsiOxM1Binding ;
|
||||
#endif
|
||||
|
||||
} TWOnode;
|
||||
|
||||
#define pTLElem pElems[0]
|
||||
|
|
|
|||
Loading…
Reference in New Issue