This commit is contained in:
Meisam Bahadori 2026-07-26 18:45:46 +02:00 committed by Holger Vogt
parent 13210bbf42
commit 19a8e10dc7
3 changed files with 34 additions and 16 deletions

View File

@ -903,8 +903,14 @@ SMPcaSolve (SMPmatrix *Matrix, double RHS[], double iRHS[], double Spare[], doub
Matrix->SMPkluMatrix->KLUmatrixIntermediateComplex [2 * i + 1] = iRHS [i + 1] ;
}
ret = klu_z_solve (Matrix->SMPkluMatrix->KLUmatrixSymbolic, Matrix->SMPkluMatrix->KLUmatrixNumeric, (int)Matrix->SMPkluMatrix->KLUmatrixN, 1,
Matrix->SMPkluMatrix->KLUmatrixIntermediateComplex, Matrix->SMPkluMatrix->KLUmatrixCommon) ;
/* SMPcaSolve is the complex *adjoint* (transposed) solve -- the Sparse
* branch below uses spSolveTransposed, so the KLU branch must solve
* A.'x = b too (klu_z_tsolve, conj_solve = 0). The plain klu_z_solve
* used here before silently produced WRONG results for any asymmetric
* matrix (every circuit with a transistor or controlled source), which
* is why KLU noise and pole-zero were disabled. */
ret = klu_z_tsolve (Matrix->SMPkluMatrix->KLUmatrixSymbolic, Matrix->SMPkluMatrix->KLUmatrixNumeric, (int)Matrix->SMPkluMatrix->KLUmatrixN, 1,
Matrix->SMPkluMatrix->KLUmatrixIntermediateComplex, 0, Matrix->SMPkluMatrix->KLUmatrixCommon) ;
for (i = 0 ; i < Matrix->SMPkluMatrix->KLUmatrixN ; i++)
{

View File

@ -69,13 +69,9 @@ NOISEan(CKTcircuit* ckt, int restart)
g_mif_info.circuit.anal_init = MIF_TRUE;
#endif
#ifdef KLU
if (ckt->CKTkluMODE) {
fprintf(stderr, "Error: Noise simulation is not (yet) supported with 'option KLU'.\n");
fprintf(stderr, " Use 'option sparse' instead.\n");
return(E_UNSUPP);
}
#endif
/* Noise runs under KLU: the adjoint solve it relies on (SMPcaSolve) now
* performs a proper transposed solve under KLU (klu_z_tsolve) -- see
* SMPcaSolve in src/maths/KLU/klusmp.c. */
NOISEAN* job = (NOISEAN*)ckt->CKTcurJob;
GENinstance* inst = CKTfndDev(ckt, job->input);

View File

@ -26,13 +26,13 @@ PZan(CKTcircuit *ckt, int reset)
NG_IGNORE(reset);
#ifdef KLU
if (ckt->CKTkluMODE) {
fprintf(stderr, "Error: Pole/zero analysis is not (yet) supported with 'option KLU'.\n");
fprintf(stderr, " Use 'option sparse' instead.\n");
return(E_UNSUPP);
}
#endif
/* Pole-zero runs under KLU for the common single-ended (grounded output
* reference) case. The one exception is a non-grounded output reference
* (balanced/differential output): its zeros phase folds columns
* (SMPcAddCol/SMPcZeroCol in CKTpzLoad) at solve time, which KLU's fixed
* symbolic factorization cannot survive the way Sparse's dynamic Markowitz
* re-ordering does. That case is caught below, after CKTpzSetup determines
* job->PZbalance_col. */
error = PZinit(ckt);
if (error != OK) return error;
@ -68,6 +68,14 @@ PZan(CKTcircuit *ckt, int reset)
error = CKTpzSetup(ckt, PZ_DO_POLES);
if (error != OK)
return error;
#ifdef KLU
if (ckt->CKTkluMODE && job->PZbalance_col) {
fprintf(stderr, "Error: pole-zero with a non-grounded output reference "
"node (balanced/differential output) is not supported with "
"'option KLU'; use 'option sparse' for that case.\n");
return(E_UNSUPP);
}
#endif
error = CKTpzFindZeros(ckt, &job->PZpoleList, &job->PZnPoles);
if (error != OK)
return(error);
@ -77,6 +85,14 @@ PZan(CKTcircuit *ckt, int reset)
error = CKTpzSetup(ckt, PZ_DO_ZEROS);
if (error != OK)
return error;
#ifdef KLU
if (ckt->CKTkluMODE && job->PZbalance_col) {
fprintf(stderr, "Error: pole-zero with a non-grounded output reference "
"node (balanced/differential output) is not supported with "
"'option KLU'; use 'option sparse' for that case.\n");
return(E_UNSUPP);
}
#endif
error = CKTpzFindZeros(ckt, &job->PZzeroList, &job->PZnZeros);
if (error != OK)
return(error);