fix vsrc for pz analysis

This commit is contained in:
rlar 2016-06-19 17:49:53 +02:00
parent 34d43556f6
commit 91fe96cdc4
4 changed files with 118 additions and 0 deletions

View File

@ -14,6 +14,20 @@ Copyright 1990 Regents of the University of California. All rights reserved.
#include "ngspice/devdefs.h"
#include "ngspice/sperror.h"
#ifdef KLU
#include <stdlib.h>
static
int
BindCompare (const void *a, const void *b)
{
BindElement *A, *B ;
A = (BindElement *)a ;
B = (BindElement *)b ;
return ((int)(A->Sparse - B->Sparse)) ;
}
#endif
int
CKTpzSetup(CKTcircuit *ckt, int type)
@ -89,6 +103,77 @@ CKTpzSetup(CKTcircuit *ckt, int type)
job->PZnumswaps = 1;
#ifdef KLU
if (ckt->CKTmatrix->CKTkluMODE)
{
fprintf (stderr, "Using KLU as Direct Linear Solver\n") ;
int i ;
int n = SMPmatSize (ckt->CKTmatrix) ;
ckt->CKTmatrix->CKTkluN = n ;
SMPnnz (ckt->CKTmatrix) ;
int nz = ckt->CKTmatrix->CKTklunz ;
ckt->CKTmatrix->CKTkluAp = TMALLOC (int, n + 1) ;
ckt->CKTmatrix->CKTkluAi = TMALLOC (int, nz) ;
ckt->CKTmatrix->CKTkluAx = TMALLOC (double, nz) ;
ckt->CKTmatrix->CKTkluIntermediate = TMALLOC (double, n) ;
ckt->CKTmatrix->CKTbindStruct = TMALLOC (BindElement, nz) ;
ckt->CKTmatrix->CKTdiag_CSC = TMALLOC (double *, n) ;
/* Complex Stuff needed for AC Analysis */
ckt->CKTmatrix->CKTkluAx_Complex = TMALLOC (double, 2 * nz) ;
ckt->CKTmatrix->CKTkluIntermediate_Complex = TMALLOC (double, 2 * n) ;
/* Binding Table from Sparse to CSC Format Creation */
SMPmatrix_CSC (ckt->CKTmatrix) ;
/* Binding Table Sorting */
qsort (ckt->CKTmatrix->CKTbindStruct, (size_t)nz, sizeof(BindElement), BindCompare) ;
/* KLU Pointers Assignment */
for (i = 0 ; i < DEVmaxnum ; i++)
if (DEVices [i] && DEVices [i]->DEVbindCSC && ckt->CKThead [i])
DEVices [i]->DEVbindCSC (ckt->CKThead [i], ckt) ;
/* ReOrder */
error = SMPpreOrder (ckt->CKTmatrix) ;
if (error) {
fprintf (stderr, "Error during ReOrdering\n") ;
}
/* Conversion from Real Matrix to Complex Matrix */
for (i = 0 ; i < DEVmaxnum ; i++)
if (DEVices [i] && DEVices [i]->DEVbindCSCComplex && ckt->CKThead [i])
DEVices [i]->DEVbindCSCComplex (ckt->CKThead [i], ckt) ;
ckt->CKTmatrix->CKTkluMatrixIsComplex = CKTkluMatrixComplex ;
/* Input Pos */
if ((input_pos != 0) && (solution_col != 0))
{
double *j ;
j = job->PZdrive_pptr ;
job->PZdrive_pptr = ((BindElement *) bsearch (&j, ckt->CKTmatrix->CKTbindStruct, (size_t)nz, sizeof(BindElement), BindCompare))->CSC_Complex ;
}
/* Input Neg */
if ((input_neg != 0) && (solution_col != 0))
{
double *j ;
j = job->PZdrive_nptr ;
job->PZdrive_nptr = ((BindElement *) bsearch (&j, ckt->CKTmatrix->CKTbindStruct, (size_t)nz, sizeof(BindElement), BindCompare))->CSC_Complex ;
}
} else {
fprintf (stderr, "Using SPARSE 1.3 as Direct Linear Solver\n") ;
}
#endif
error = NIreinit(ckt);
if (error)
return(error);

View File

@ -43,6 +43,17 @@ VSRCbindCSC (GENmodel *inModel, CKTcircuit *ckt)
CREATE_KLU_BINDING_TABLE(VSRCnegIbrPtr, VSRCnegIbrBinding, VSRCnegNode, VSRCbranch);
CREATE_KLU_BINDING_TABLE(VSRCibrNegPtr, VSRCibrNegBinding, VSRCbranch, VSRCnegNode);
CREATE_KLU_BINDING_TABLE(VSRCibrPosPtr, VSRCibrPosBinding, VSRCbranch, VSRCposNode);
/* Pole-Zero Analysis */
if ((here-> VSRCbranch != 0) && (here-> VSRCbranch != 0))
{
i = here->VSRCibrIbrPtr ;
matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ;
here->VSRCibrIbrBinding = matched ;
if (matched != NULL)
{
here->VSRCibrIbrPtr = matched->CSC ;
}
}
}
}
@ -67,6 +78,14 @@ VSRCbindCSCComplex (GENmodel *inModel, CKTcircuit *ckt)
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VSRCnegIbrPtr, VSRCnegIbrBinding, VSRCnegNode, VSRCbranch);
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VSRCibrNegPtr, VSRCibrNegBinding, VSRCbranch, VSRCnegNode);
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VSRCibrPosPtr, VSRCibrPosBinding, VSRCbranch, VSRCposNode);
/* Pole-Zero Analysis */
if ((here-> VSRCbranch != 0) && (here-> VSRCbranch != 0))
{
if (here->VSRCibrIbrBinding != NULL)
{
here->VSRCibrIbrPtr = here->VSRCibrIbrBinding->CSC_Complex ;
}
}
}
}
@ -91,6 +110,14 @@ VSRCbindCSCComplexToReal (GENmodel *inModel, CKTcircuit *ckt)
CONVERT_KLU_BINDING_TABLE_TO_REAL(VSRCnegIbrPtr, VSRCnegIbrBinding, VSRCnegNode, VSRCbranch);
CONVERT_KLU_BINDING_TABLE_TO_REAL(VSRCibrNegPtr, VSRCibrNegBinding, VSRCbranch, VSRCnegNode);
CONVERT_KLU_BINDING_TABLE_TO_REAL(VSRCibrPosPtr, VSRCibrPosBinding, VSRCbranch, VSRCposNode);
/* Pole-Zero Analysis */
if ((here-> VSRCbranch != 0) && (here-> VSRCbranch != 0))
{
if (here->VSRCibrIbrBinding != NULL)
{
here->VSRCibrIbrPtr = here->VSRCibrIbrBinding->CSC ;
}
}
}
}

View File

@ -83,6 +83,7 @@ typedef struct sVSRCinstance {
BindElement *VSRCnegIbrBinding ;
BindElement *VSRCibrNegBinding ;
BindElement *VSRCibrPosBinding ;
BindElement *VSRCibrIbrBinding ;
#endif
} VSRCinstance ;

View File

@ -53,6 +53,11 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
TSTALLOC(VSRCnegIbrPtr, VSRCnegNode, VSRCbranch);
TSTALLOC(VSRCibrNegPtr, VSRCbranch, VSRCnegNode);
TSTALLOC(VSRCibrPosPtr, VSRCbranch, VSRCposNode);
#ifdef KLU
here->VSRCibrIbrPtr = NULL ;
#endif
}
}
return(OK);