committed by
Holger Vogt
10 changed files with 622 additions and 11 deletions
-
7src/include/ngspice/dllitf.h
-
52src/include/ngspice/klu-binding.h
-
27src/include/ngspice/mifdefs.h
-
5src/include/ngspice/mifproto.h
-
6src/xspice/cm/cmexport.c
-
6src/xspice/cmpp/writ_ifs.c
-
13src/xspice/icm/dlmain.c
-
4src/xspice/mif/Makefile.am
-
507src/xspice/mif/mifbindCSC.c
-
6src/xspice/xspice.c
@ -1,20 +1,54 @@ |
|||
#ifndef _KLU_BINDING_H |
|||
#define _KLU_BINDING_H |
|||
|
|||
#define CREATE_KLU_BINDING_TABLE(ptr, binding, a, b) \ |
|||
if ((here->a != 0) && (here->b != 0)) { \ |
|||
i = here->ptr ; \ |
|||
#define CREATE_KLU_BINDING_TABLE(ptr, binding, a, b) \ |
|||
if ((here->a != 0) && (here->b != 0)) { \ |
|||
i = here->ptr ; \ |
|||
matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; \ |
|||
here->binding = matched ; \ |
|||
here->ptr = matched->CSC ; \ |
|||
here->binding = matched ; \ |
|||
here->ptr = matched->CSC ; \ |
|||
} |
|||
|
|||
#define CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(ptr, binding, a, b) \ |
|||
if ((here->a != 0) && (here->b != 0)) \ |
|||
#define CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(ptr, binding, a, b) \ |
|||
if ((here->a != 0) && (here->b != 0)) \ |
|||
here->ptr = here->binding->CSC_Complex ; |
|||
|
|||
#define CONVERT_KLU_BINDING_TABLE_TO_REAL(ptr, binding, a, b) \ |
|||
if ((here->a != 0) && (here->b != 0)) \ |
|||
#define CONVERT_KLU_BINDING_TABLE_TO_REAL(ptr, binding, a, b) \ |
|||
if ((here->a != 0) && (here->b != 0)) \ |
|||
here->ptr = here->binding->CSC ; |
|||
|
|||
#ifdef XSPICE |
|||
#define CREATE_KLU_BINDING_TABLE_XSPICE_OUTPUTS(ptr, binding, a, b) \ |
|||
if ((smp_data_out->a != 0) && (smp_data_out->b != 0)) { \ |
|||
i = smp_data_out->ptr ; \ |
|||
matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; \ |
|||
here->binding = matched ; \ |
|||
smp_data_out->ptr = matched->CSC ; \ |
|||
} |
|||
|
|||
#define CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_OUTPUTS(ptr, binding, a, b) \ |
|||
if ((smp_data_out->a != 0) && (smp_data_out->b != 0)) \ |
|||
smp_data_out->ptr = here->binding->CSC_Complex ; |
|||
|
|||
#define CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_OUTPUTS(ptr, binding, a, b) \ |
|||
if ((smp_data_out->a != 0) && (smp_data_out->b != 0)) \ |
|||
smp_data_out->ptr = here->binding->CSC ; |
|||
|
|||
#define CREATE_KLU_BINDING_TABLE_XSPICE_INPUTS(ptr, binding, a, b) \ |
|||
if ((smp_data_out->a != 0) && (smp_data_cntl->b != 0)) { \ |
|||
i = smp_data_out->input[k].port[l].ptr ; \ |
|||
matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; \ |
|||
here->binding = matched ; \ |
|||
smp_data_out->input[k].port[l].ptr = matched->CSC ; \ |
|||
} |
|||
|
|||
#define CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_INPUTS(ptr, binding, a, b) \ |
|||
if ((smp_data_out->a != 0) && (smp_data_cntl->b != 0)) \ |
|||
smp_data_out->input[k].port[l].ptr = here->binding->CSC_Complex ; |
|||
|
|||
#define CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_INPUTS(ptr, binding, a, b) \ |
|||
if ((smp_data_out->a != 0) && (smp_data_cntl->b != 0)) \ |
|||
smp_data_out->input[k].port[l].ptr = here->binding->CSC ; |
|||
#endif |
|||
|
|||
#endif |
|||
@ -0,0 +1,507 @@ |
|||
/* |
|||
** Author: Francesco Lannutti |
|||
** Date: 15 March 2020 |
|||
** Purpose: KLU binding table routines for XSPICE |
|||
*/ |
|||
|
|||
#include "ngspice/ngspice.h" |
|||
#include "ngspice/cktdefs.h" |
|||
#include "ngspice/sperror.h" |
|||
#include "ngspice/klu-binding.h" |
|||
|
|||
#include "ngspice/mifproto.h" |
|||
#include "ngspice/mifdefs.h" |
|||
|
|||
#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)) ; |
|||
} |
|||
|
|||
int |
|||
MIFbindCSC (GENmodel *inModel, CKTcircuit *ckt) |
|||
{ |
|||
MIFmodel *model = (MIFmodel *)inModel ; |
|||
MIFinstance *here ; |
|||
double *i ; |
|||
BindElement *matched, *BindStruct ; |
|||
int ii, j, k, l, num_conn, num_port, num_port_k ; |
|||
Mif_Boolean_t is_input, is_output ; |
|||
Mif_Cntl_Src_Type_t cntl_src_type ; |
|||
Mif_Port_Type_t in_type, out_type, type ; |
|||
Mif_Smp_Ptr_t *smp_data_cntl, *smp_data_out ; |
|||
size_t nz ; |
|||
|
|||
BindStruct = ckt->CKTmatrix->CKTbindStruct ; |
|||
nz = (size_t)ckt->CKTmatrix->CKTklunz ; |
|||
|
|||
/* loop through all the MIF models */ |
|||
for ( ; model != NULL ; model = MIFnextModel(model)) |
|||
{ |
|||
/* loop through all the instances of the model */ |
|||
for (here = MIFinstances(model); here != NULL ; here = MIFnextInstance(here)) |
|||
{ |
|||
/* Skip these expensive allocations if the instance is not analog */ |
|||
if(! here->analog) |
|||
continue; |
|||
|
|||
num_conn = here->num_conn; |
|||
|
|||
/* loop through all connections on this instance */ |
|||
/* and create matrix data needed for outputs and */ |
|||
/* V sources associated with I inputs */ |
|||
for(ii = 0; ii < num_conn; ii++) { |
|||
|
|||
/* if the connection is null, skip to next connection */ |
|||
if(here->conn[ii]->is_null) |
|||
continue; |
|||
|
|||
/* prepare things for convenient access later */ |
|||
is_input = here->conn[ii]->is_input; |
|||
is_output = here->conn[ii]->is_output; |
|||
num_port = here->conn[ii]->size; |
|||
|
|||
/* loop through all ports on this connection */ |
|||
for(j = 0; j < num_port; j++) { |
|||
|
|||
/* if port is null, skip to next */ |
|||
if(here->conn[ii]->port[j]->is_null) |
|||
continue; |
|||
|
|||
/* determine the type of this port */ |
|||
type = here->conn[ii]->port[j]->type; |
|||
|
|||
/* create a pointer to the smp data for quick access */ |
|||
smp_data_out = &(here->conn[ii]->port[j]->smp_data); |
|||
|
|||
/* if it has a voltage source output, */ |
|||
/* create the matrix data needed */ |
|||
if( (is_output && (type == MIF_VOLTAGE || type == MIF_DIFF_VOLTAGE)) || |
|||
(type == MIF_RESISTANCE || type == MIF_DIFF_RESISTANCE) ) { |
|||
|
|||
/* then make the matrix pointers */ |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_OUTPUTS(pos_branch, pos_branchBinding, pos_node, branch); |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_OUTPUTS(neg_branch, neg_branchBinding, neg_node, branch); |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_OUTPUTS(branch_pos, branch_posBinding, branch, pos_node); |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_OUTPUTS(branch_neg, branch_negBinding, branch, neg_node); |
|||
} /* end if current input */ |
|||
|
|||
/* if it is a current input */ |
|||
/* create the matrix data needed for the associated zero-valued V source */ |
|||
if(is_input && (type == MIF_CURRENT || type == MIF_DIFF_CURRENT)) { |
|||
|
|||
/* then make the matrix pointers */ |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_OUTPUTS(pos_ibranch, pos_ibranchBinding, pos_node, ibranch); |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_OUTPUTS(neg_ibranch, neg_ibranchBinding, neg_node, ibranch); |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_OUTPUTS(ibranch_pos, ibranch_posBinding, ibranch, pos_node); |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_OUTPUTS(ibranch_neg, ibranch_negBinding, ibranch, neg_node); |
|||
} /* end if current input */ |
|||
} /* end for number of ports */ |
|||
} /* end for number of connections */ |
|||
|
|||
/* now loop through all connections on the instance and create */ |
|||
/* matrix data needed for partial derivatives of outputs */ |
|||
for(ii = 0; ii < num_conn; ii++) { |
|||
|
|||
/* if the connection is null or is not an output */ |
|||
/* skip to next connection */ |
|||
if((here->conn[ii]->is_null) || (! here->conn[ii]->is_output)) |
|||
continue; |
|||
|
|||
/* loop through all ports on this connection */ |
|||
|
|||
num_port = here->conn[ii]->size; |
|||
for(j = 0; j < num_port; j++) { |
|||
|
|||
/* if port is null, skip to next */ |
|||
if(here->conn[ii]->port[j]->is_null) |
|||
continue; |
|||
|
|||
/* determine the type of this output port */ |
|||
out_type = here->conn[ii]->port[j]->type; |
|||
|
|||
/* create a pointer to the smp data for quick access */ |
|||
smp_data_out = &(here->conn[ii]->port[j]->smp_data); |
|||
|
|||
/* for this port, loop through all connections */ |
|||
/* and all ports to touch on each possible input */ |
|||
for(k = 0; k < num_conn; k++) { |
|||
|
|||
/* if the connection is null or is not an input */ |
|||
/* skip to next connection */ |
|||
if((here->conn[k]->is_null) || (! here->conn[k]->is_input)) |
|||
continue; |
|||
|
|||
num_port_k = here->conn[k]->size; |
|||
/* loop through all the ports of this connection */ |
|||
for(l = 0; l < num_port_k; l++) { |
|||
|
|||
/* if port is null, skip to next */ |
|||
if(here->conn[k]->port[l]->is_null) |
|||
continue; |
|||
|
|||
/* determine the type of this input port */ |
|||
in_type = here->conn[k]->port[l]->type; |
|||
|
|||
/* create a pointer to the smp data for quick access */ |
|||
smp_data_cntl = &(here->conn[k]->port[l]->smp_data); |
|||
|
|||
/* determine type of controlled source according */ |
|||
/* to input and output types */ |
|||
cntl_src_type = MIFget_cntl_src_type(in_type, out_type); |
|||
|
|||
switch(cntl_src_type) { |
|||
case MIF_VCVS: |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_INPUTS(e.branch_poscntl, branch_poscntlBinding, branch, pos_node); |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_INPUTS(e.branch_negcntl, branch_negcntlBinding, branch, neg_node); |
|||
break; |
|||
case MIF_ICIS: |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_INPUTS(f.pos_ibranchcntl, pos_ibranchcntlBinding, pos_node, ibranch); |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_INPUTS(f.neg_ibranchcntl, neg_ibranchcntlBinding, neg_node, ibranch); |
|||
break; |
|||
case MIF_VCIS: |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_INPUTS(g.pos_poscntl, pos_poscntlBinding, pos_node, pos_node); |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_INPUTS(g.pos_negcntl, pos_negcntlBinding, pos_node, neg_node); |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_INPUTS(g.neg_poscntl, neg_poscntlBinding, neg_node, pos_node); |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_INPUTS(g.neg_negcntl, neg_negcntlBinding, neg_node, neg_node); |
|||
break; |
|||
case MIF_ICVS: |
|||
CREATE_KLU_BINDING_TABLE_XSPICE_INPUTS(h.branch_ibranchcntl, branch_ibranchcntlBinding, branch, ibranch); |
|||
break; |
|||
case MIF_minus_one: |
|||
break; |
|||
} /* end switch on controlled source type */ |
|||
} /* end for number of input ports */ |
|||
} /* end for number of input connections */ |
|||
} /* end for number of output ports */ |
|||
} /* end for number of output connections */ |
|||
} |
|||
} |
|||
|
|||
return (OK) ; |
|||
} |
|||
|
|||
int |
|||
MIFbindCSCComplex (GENmodel *inModel, CKTcircuit *ckt) |
|||
{ |
|||
MIFmodel *model = (MIFmodel *)inModel ; |
|||
MIFinstance *here ; |
|||
int ii, j, k, l, num_conn, num_port, num_port_k ; |
|||
Mif_Boolean_t is_input, is_output ; |
|||
Mif_Cntl_Src_Type_t cntl_src_type ; |
|||
Mif_Port_Type_t in_type, out_type, type ; |
|||
Mif_Smp_Ptr_t *smp_data_cntl, *smp_data_out ; |
|||
|
|||
NG_IGNORE (ckt) ; |
|||
|
|||
/* loop through all the MIF models */ |
|||
for ( ; model != NULL ; model = MIFnextModel(model)) |
|||
{ |
|||
/* loop through all the instances of the model */ |
|||
for (here = MIFinstances(model); here != NULL ; here = MIFnextInstance(here)) |
|||
{ |
|||
/* Skip these expensive allocations if the instance is not analog */ |
|||
if(! here->analog) |
|||
continue; |
|||
|
|||
num_conn = here->num_conn; |
|||
|
|||
/* loop through all connections on this instance */ |
|||
/* and create matrix data needed for outputs and */ |
|||
/* V sources associated with I inputs */ |
|||
for(ii = 0; ii < num_conn; ii++) { |
|||
|
|||
/* if the connection is null, skip to next connection */ |
|||
if(here->conn[ii]->is_null) |
|||
continue; |
|||
|
|||
/* prepare things for convenient access later */ |
|||
is_input = here->conn[ii]->is_input; |
|||
is_output = here->conn[ii]->is_output; |
|||
num_port = here->conn[ii]->size; |
|||
|
|||
/* loop through all ports on this connection */ |
|||
for(j = 0; j < num_port; j++) { |
|||
|
|||
/* if port is null, skip to next */ |
|||
if(here->conn[ii]->port[j]->is_null) |
|||
continue; |
|||
|
|||
/* determine the type of this port */ |
|||
type = here->conn[ii]->port[j]->type; |
|||
|
|||
/* create a pointer to the smp data for quick access */ |
|||
smp_data_out = &(here->conn[ii]->port[j]->smp_data); |
|||
|
|||
/* if it has a voltage source output, */ |
|||
/* create the matrix data needed */ |
|||
if( (is_output && (type == MIF_VOLTAGE || type == MIF_DIFF_VOLTAGE)) || |
|||
(type == MIF_RESISTANCE || type == MIF_DIFF_RESISTANCE) ) { |
|||
|
|||
/* then make the matrix pointers */ |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_OUTPUTS(pos_branch, pos_branchBinding, pos_node, branch); |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_OUTPUTS(neg_branch, neg_branchBinding, neg_node, branch); |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_OUTPUTS(branch_pos, branch_posBinding, branch, pos_node); |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_OUTPUTS(branch_neg, branch_negBinding, branch, neg_node); |
|||
} /* end if current input */ |
|||
|
|||
/* if it is a current input */ |
|||
/* create the matrix data needed for the associated zero-valued V source */ |
|||
if(is_input && (type == MIF_CURRENT || type == MIF_DIFF_CURRENT)) { |
|||
|
|||
/* then make the matrix pointers */ |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_OUTPUTS(pos_ibranch, pos_ibranchBinding, pos_node, ibranch); |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_OUTPUTS(neg_ibranch, neg_ibranchBinding, neg_node, ibranch); |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_OUTPUTS(ibranch_pos, ibranch_posBinding, ibranch, pos_node); |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_OUTPUTS(ibranch_neg, ibranch_negBinding, ibranch, neg_node); |
|||
} /* end if current input */ |
|||
} /* end for number of ports */ |
|||
} /* end for number of connections */ |
|||
|
|||
/* now loop through all connections on the instance and create */ |
|||
/* matrix data needed for partial derivatives of outputs */ |
|||
for(ii = 0; ii < num_conn; ii++) { |
|||
|
|||
/* if the connection is null or is not an output */ |
|||
/* skip to next connection */ |
|||
if((here->conn[ii]->is_null) || (! here->conn[ii]->is_output)) |
|||
continue; |
|||
|
|||
/* loop through all ports on this connection */ |
|||
|
|||
num_port = here->conn[ii]->size; |
|||
for(j = 0; j < num_port; j++) { |
|||
|
|||
/* if port is null, skip to next */ |
|||
if(here->conn[ii]->port[j]->is_null) |
|||
continue; |
|||
|
|||
/* determine the type of this output port */ |
|||
out_type = here->conn[ii]->port[j]->type; |
|||
|
|||
/* create a pointer to the smp data for quick access */ |
|||
smp_data_out = &(here->conn[ii]->port[j]->smp_data); |
|||
|
|||
/* for this port, loop through all connections */ |
|||
/* and all ports to touch on each possible input */ |
|||
for(k = 0; k < num_conn; k++) { |
|||
|
|||
/* if the connection is null or is not an input */ |
|||
/* skip to next connection */ |
|||
if((here->conn[k]->is_null) || (! here->conn[k]->is_input)) |
|||
continue; |
|||
|
|||
num_port_k = here->conn[k]->size; |
|||
/* loop through all the ports of this connection */ |
|||
for(l = 0; l < num_port_k; l++) { |
|||
|
|||
/* if port is null, skip to next */ |
|||
if(here->conn[k]->port[l]->is_null) |
|||
continue; |
|||
|
|||
/* determine the type of this input port */ |
|||
in_type = here->conn[k]->port[l]->type; |
|||
|
|||
/* create a pointer to the smp data for quick access */ |
|||
smp_data_cntl = &(here->conn[k]->port[l]->smp_data); |
|||
|
|||
/* determine type of controlled source according */ |
|||
/* to input and output types */ |
|||
cntl_src_type = MIFget_cntl_src_type(in_type, out_type); |
|||
|
|||
switch(cntl_src_type) { |
|||
case MIF_VCVS: |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_INPUTS(e.branch_poscntl, branch_poscntlBinding, branch, pos_node); |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_INPUTS(e.branch_negcntl, branch_negcntlBinding, branch, neg_node); |
|||
break; |
|||
case MIF_ICIS: |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_INPUTS(f.pos_ibranchcntl, pos_ibranchcntlBinding, pos_node, ibranch); |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_INPUTS(f.neg_ibranchcntl, neg_ibranchcntlBinding, neg_node, ibranch); |
|||
break; |
|||
case MIF_VCIS: |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_INPUTS(g.pos_poscntl, pos_poscntlBinding, pos_node, pos_node); |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_INPUTS(g.pos_negcntl, pos_negcntlBinding, pos_node, neg_node); |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_INPUTS(g.neg_poscntl, neg_poscntlBinding, neg_node, pos_node); |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_INPUTS(g.neg_negcntl, neg_negcntlBinding, neg_node, neg_node); |
|||
break; |
|||
case MIF_ICVS: |
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX_XSPICE_INPUTS(h.branch_ibranchcntl, branch_ibranchcntlBinding, branch, ibranch); |
|||
break; |
|||
case MIF_minus_one: |
|||
break; |
|||
} /* end switch on controlled source type */ |
|||
} /* end for number of input ports */ |
|||
} /* end for number of input connections */ |
|||
} /* end for number of output ports */ |
|||
} /* end for number of output connections */ |
|||
} |
|||
} |
|||
|
|||
return (OK) ; |
|||
} |
|||
|
|||
int |
|||
MIFbindCSCComplexToReal (GENmodel *inModel, CKTcircuit *ckt) |
|||
{ |
|||
MIFmodel *model = (MIFmodel *)inModel ; |
|||
MIFinstance *here ; |
|||
int ii, j, k, l, num_conn, num_port, num_port_k ; |
|||
Mif_Boolean_t is_input, is_output ; |
|||
Mif_Cntl_Src_Type_t cntl_src_type ; |
|||
Mif_Port_Type_t in_type, out_type, type ; |
|||
Mif_Smp_Ptr_t *smp_data_cntl, *smp_data_out ; |
|||
|
|||
NG_IGNORE (ckt) ; |
|||
|
|||
/* loop through all the MIF models */ |
|||
for ( ; model != NULL ; model = MIFnextModel(model)) |
|||
{ |
|||
/* loop through all the instances of the model */ |
|||
for (here = MIFinstances(model); here != NULL ; here = MIFnextInstance(here)) |
|||
{ |
|||
/* Skip these expensive allocations if the instance is not analog */ |
|||
if(! here->analog) |
|||
continue; |
|||
|
|||
num_conn = here->num_conn; |
|||
|
|||
/* loop through all connections on this instance */ |
|||
/* and create matrix data needed for outputs and */ |
|||
/* V sources associated with I inputs */ |
|||
for(ii = 0; ii < num_conn; ii++) { |
|||
|
|||
/* if the connection is null, skip to next connection */ |
|||
if(here->conn[ii]->is_null) |
|||
continue; |
|||
|
|||
/* prepare things for convenient access later */ |
|||
is_input = here->conn[ii]->is_input; |
|||
is_output = here->conn[ii]->is_output; |
|||
num_port = here->conn[ii]->size; |
|||
|
|||
/* loop through all ports on this connection */ |
|||
for(j = 0; j < num_port; j++) { |
|||
|
|||
/* if port is null, skip to next */ |
|||
if(here->conn[ii]->port[j]->is_null) |
|||
continue; |
|||
|
|||
/* determine the type of this port */ |
|||
type = here->conn[ii]->port[j]->type; |
|||
|
|||
/* create a pointer to the smp data for quick access */ |
|||
smp_data_out = &(here->conn[ii]->port[j]->smp_data); |
|||
|
|||
/* if it has a voltage source output, */ |
|||
/* create the matrix data needed */ |
|||
if( (is_output && (type == MIF_VOLTAGE || type == MIF_DIFF_VOLTAGE)) || |
|||
(type == MIF_RESISTANCE || type == MIF_DIFF_RESISTANCE) ) { |
|||
|
|||
/* then make the matrix pointers */ |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_OUTPUTS(pos_branch, pos_branchBinding, pos_node, branch); |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_OUTPUTS(neg_branch, neg_branchBinding, neg_node, branch); |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_OUTPUTS(branch_pos, branch_posBinding, branch, pos_node); |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_OUTPUTS(branch_neg, branch_negBinding, branch, neg_node); |
|||
} /* end if current input */ |
|||
|
|||
/* if it is a current input */ |
|||
/* create the matrix data needed for the associated zero-valued V source */ |
|||
if(is_input && (type == MIF_CURRENT || type == MIF_DIFF_CURRENT)) { |
|||
|
|||
/* then make the matrix pointers */ |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_OUTPUTS(pos_ibranch, pos_ibranchBinding, pos_node, ibranch); |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_OUTPUTS(neg_ibranch, neg_ibranchBinding, neg_node, ibranch); |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_OUTPUTS(ibranch_pos, ibranch_posBinding, ibranch, pos_node); |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_OUTPUTS(ibranch_neg, ibranch_negBinding, ibranch, neg_node); |
|||
} /* end if current input */ |
|||
} /* end for number of ports */ |
|||
} /* end for number of connections */ |
|||
|
|||
/* now loop through all connections on the instance and create */ |
|||
/* matrix data needed for partial derivatives of outputs */ |
|||
for(ii = 0; ii < num_conn; ii++) { |
|||
|
|||
/* if the connection is null or is not an output */ |
|||
/* skip to next connection */ |
|||
if((here->conn[ii]->is_null) || (! here->conn[ii]->is_output)) |
|||
continue; |
|||
|
|||
/* loop through all ports on this connection */ |
|||
|
|||
num_port = here->conn[ii]->size; |
|||
for(j = 0; j < num_port; j++) { |
|||
|
|||
/* if port is null, skip to next */ |
|||
if(here->conn[ii]->port[j]->is_null) |
|||
continue; |
|||
|
|||
/* determine the type of this output port */ |
|||
out_type = here->conn[ii]->port[j]->type; |
|||
|
|||
/* create a pointer to the smp data for quick access */ |
|||
smp_data_out = &(here->conn[ii]->port[j]->smp_data); |
|||
|
|||
/* for this port, loop through all connections */ |
|||
/* and all ports to touch on each possible input */ |
|||
for(k = 0; k < num_conn; k++) { |
|||
|
|||
/* if the connection is null or is not an input */ |
|||
/* skip to next connection */ |
|||
if((here->conn[k]->is_null) || (! here->conn[k]->is_input)) |
|||
continue; |
|||
|
|||
num_port_k = here->conn[k]->size; |
|||
/* loop through all the ports of this connection */ |
|||
for(l = 0; l < num_port_k; l++) { |
|||
|
|||
/* if port is null, skip to next */ |
|||
if(here->conn[k]->port[l]->is_null) |
|||
continue; |
|||
|
|||
/* determine the type of this input port */ |
|||
in_type = here->conn[k]->port[l]->type; |
|||
|
|||
/* create a pointer to the smp data for quick access */ |
|||
smp_data_cntl = &(here->conn[k]->port[l]->smp_data); |
|||
|
|||
/* determine type of controlled source according */ |
|||
/* to input and output types */ |
|||
cntl_src_type = MIFget_cntl_src_type(in_type, out_type); |
|||
|
|||
switch(cntl_src_type) { |
|||
case MIF_VCVS: |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_INPUTS(e.branch_poscntl, branch_poscntlBinding, branch, pos_node); |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_INPUTS(e.branch_negcntl, branch_negcntlBinding, branch, neg_node); |
|||
break; |
|||
case MIF_ICIS: |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_INPUTS(f.pos_ibranchcntl, pos_ibranchcntlBinding, pos_node, ibranch); |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_INPUTS(f.neg_ibranchcntl, neg_ibranchcntlBinding, neg_node, ibranch); |
|||
break; |
|||
case MIF_VCIS: |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_INPUTS(g.pos_poscntl, pos_poscntlBinding, pos_node, pos_node); |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_INPUTS(g.pos_negcntl, pos_negcntlBinding, pos_node, neg_node); |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_INPUTS(g.neg_poscntl, neg_poscntlBinding, neg_node, pos_node); |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_INPUTS(g.neg_negcntl, neg_negcntlBinding, neg_node, neg_node); |
|||
break; |
|||
case MIF_ICVS: |
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL_XSPICE_INPUTS(h.branch_ibranchcntl, branch_ibranchcntlBinding, branch, ibranch); |
|||
break; |
|||
case MIF_minus_one: |
|||
break; |
|||
} /* end switch on controlled source type */ |
|||
} /* end for number of input ports */ |
|||
} /* end for number of input connections */ |
|||
} /* end for number of output ports */ |
|||
} /* end for number of output connections */ |
|||
} |
|||
} |
|||
|
|||
return (OK) ; |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue