This commit is contained in:
Holger Vogt 2026-07-26 12:54:19 +02:00
parent d603b060da
commit 53e0e00176
2 changed files with 25 additions and 1 deletions

View File

@ -59,6 +59,16 @@ com_hb(wordlist *wl)
return;
}
/* Honor `.option klu`: a bare `hb` builds the circuit here rather than via
* cktdojob (which is where a normal analysis copies task->TSKkluMODE), so pull
* the KLU mode from the task before CKTsetup wires the matrix -- else the matrix
* defaults to Sparse and the `.option klu` request is silently ignored. */
#ifdef KLU
if (ft_curckt->ci_defTask &&
(ckt->CKTmatrix == NULL || SMPmatSize(ckt->CKTmatrix) <= 0))
ckt->CKTkluMODE = ft_curckt->ci_defTask->TSKkluMODE;
#endif
/* make sure the circuit is built (matrix + states allocated) */
if (ckt->CKTmatrix == NULL || SMPmatSize(ckt->CKTmatrix) <= 0) {
if ((err = CKTsetup(ckt)) != OK || (err = CKTtemp(ckt)) != OK) {

View File

@ -1259,7 +1259,21 @@ hb_extract(CKTcircuit *ckt, const double *vsamp, int N, int P, int K,
return 1;
bsave = TMALLOC(double, N);
spSetComplex(ckt->CKTmatrix->SPmatrix);
/* Matrix must be in complex mode so CKTacLoad stamps G(el[0]) + jC(el[1]) and
* SMPfindElt reads both parts. Under KLU the live matrix is the CSC form, not
* SPmatrix, so bind the device pointers to the complex CSC (mirrors
* pac_extract_harmonics -- this is what makes HB solver-independent). */
#ifdef KLU
if (ckt->CKTmatrix->CKTkluMODE) {
if (!ckt->CKTmatrix->SMPkluMatrix->KLUmatrixIsComplex) {
for (i = 0; i < DEVmaxnum; i++)
if (DEVices[i] && DEVices[i]->DEVbindCSCComplex && ckt->CKThead[i])
DEVices[i]->DEVbindCSCComplex(ckt->CKThead[i], ckt);
ckt->CKTmatrix->SMPkluMatrix->KLUmatrixIsComplex = KLUMatrixComplex;
}
} else
#endif
spSetComplex(ckt->CKTmatrix->SPmatrix);
/* establish structure at sample 0's bias */
for (i = 1; i <= N; i++)