From d9561123f99984144182844a2d9f344581c099a4 Mon Sep 17 00:00:00 2001 From: dwarning Date: Sat, 11 Feb 2012 19:45:25 +0000 Subject: [PATCH] Add temperature coefficients for B sources --- ChangeLog | 6 + src/frontend/inpcom.c | 5 +- src/spicelib/devices/asrc/Makefile.am | 3 +- src/spicelib/devices/asrc/asrc.c | 9 +- src/spicelib/devices/asrc/asrcacld.c | 23 +- src/spicelib/devices/asrc/asrcask.c | 24 +- src/spicelib/devices/asrc/asrcdefs.h | 25 +- src/spicelib/devices/asrc/asrcext.h | 2 +- src/spicelib/devices/asrc/asrcinit.c | 2 +- src/spicelib/devices/asrc/asrcload.c | 180 +- src/spicelib/devices/asrc/asrcpar.c | 12 +- src/spicelib/devices/asrc/asrcpzld.c | 21 +- visualc/vngspice.vcproj | 17724 ++++++++++++------------ 13 files changed, 9055 insertions(+), 8981 deletions(-) diff --git a/ChangeLog b/ChangeLog index 795c4d6eb..09e488db2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2012-02-11 Dietmar Warning + * src/spicelib/devices/asrc/*.c,*.h,Makefile.am + * src/frontend/inpcom.c, + * vngspice.vcproj + Add temperature coefficients for B sources + 2012-02-11 Holger Vogt * inpcom.c: Robert's patch, reading libs, incs etc. diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 433004fda..ee1aaf2c9 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -4871,10 +4871,11 @@ static void inp_bsource_compat(struct line *deck) } buf[i] = '\0'; /* no parens {} around time, hertz, temper, the constants - pi and e which are defined in inpptree.c and around pwl */ + pi and e which are defined in inpptree.c, around pwl and temp. coeffs */ if ((*str_ptr == '(') || cieq(buf, "hertz") || cieq(buf, "temper") || cieq(buf, "time") || cieq(buf, "pi") || cieq(buf, "e") - || cieq(buf, "pwl")) { + || cieq(buf, "pwl") + || cieq(buf, "tc") || cieq(buf, "tc1") || cieq(buf, "tc2")) { /* special handling of pwl lines: Put braces around tokens and around expressions, use ',' as separator like: diff --git a/src/spicelib/devices/asrc/Makefile.am b/src/spicelib/devices/asrc/Makefile.am index b971570dd..a5db57d78 100644 --- a/src/spicelib/devices/asrc/Makefile.am +++ b/src/spicelib/devices/asrc/Makefile.am @@ -19,7 +19,8 @@ libasrc_la_SOURCES = \ asrcmdel.c \ asrcpar.c \ asrcpzld.c \ - asrcset.c + asrcset.c \ + asrctemp.c AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include diff --git a/src/spicelib/devices/asrc/asrc.c b/src/spicelib/devices/asrc/asrc.c index 8bce8a833..11404b229 100644 --- a/src/spicelib/devices/asrc/asrc.c +++ b/src/spicelib/devices/asrc/asrc.c @@ -11,9 +11,14 @@ Author: 1987 Kanwar Jit Singh /* Arbitrary source */ IFparm ASRCpTable[] = { /* parameters */ - IP( "i", ASRC_CURRENT, IF_PARSETREE, "Current source "), + IP( "i", ASRC_CURRENT, IF_PARSETREE, "Current source"), IP( "v", ASRC_VOLTAGE, IF_PARSETREE, "Voltage source"), - OP( "i", ASRC_OUTPUTCURRENT, IF_REAL, "Current through source "), + IOPZU( "temp", ASRC_TEMP, IF_REAL, "Instance operating temperature"), + IOPZ( "dtemp", ASRC_DTEMP, IF_REAL, + "Instance temperature difference with the rest of the circuit"), + IOPU( "tc1", ASRC_TC1, IF_REAL, "First order temp. coefficient"), + IOPU( "tc2", ASRC_TC2, IF_REAL, "Second order temp. coefficient"), + OP( "i", ASRC_OUTPUTCURRENT, IF_REAL, "Current through source"), OP( "v", ASRC_OUTPUTVOLTAGE, IF_REAL, "Voltage across source"), OP( "pos_node", ASRC_POS_NODE, IF_INTEGER, "Positive Node"), OP( "neg_node", ASRC_NEG_NODE, IF_INTEGER, "Negative Node") diff --git a/src/spicelib/devices/asrc/asrcacld.c b/src/spicelib/devices/asrc/asrcacld.c index c84a06cd0..5dea71624 100644 --- a/src/spicelib/devices/asrc/asrcacld.c +++ b/src/spicelib/devices/asrc/asrcacld.c @@ -29,6 +29,8 @@ ASRCacLoad(GENmodel *inModel, CKTcircuit *ckt) int i, j; double *derivs; double rhs; + double difference; + double factor; NG_IGNORE(ckt); @@ -42,6 +44,13 @@ ASRCacLoad(GENmodel *inModel, CKTcircuit *ckt) if (here->ASRCowner != ARCHme) continue; + if(!here->ASRCtc1Given) here->ASRCtc1 = 0.0; + if(!here->ASRCtc2Given) here->ASRCtc2 = 0.0; + + difference = (here->ASRCtemp + here->ASRCdtemp) - 300.15; + factor = 1.0 + (here->ASRCtc1)*difference + + (here->ASRCtc2)*difference*difference; + /* * Get the function and its derivatives from the * field in the instance structure. The field is @@ -65,21 +74,21 @@ ASRCacLoad(GENmodel *inModel, CKTcircuit *ckt) case IF_INSTANCE: if( here->ASRCtype == ASRC_VOLTAGE) { /* CCVS */ - *(here->ASRCposptr[j++]) -= derivs[i]; + *(here->ASRCposptr[j++]) -= derivs[i] / factor; } else{ /* CCCS */ - *(here->ASRCposptr[j++]) += derivs[i]; - *(here->ASRCposptr[j++]) -= derivs[i]; + *(here->ASRCposptr[j++]) += derivs[i] / factor; + *(here->ASRCposptr[j++]) -= derivs[i] / factor; } break; case IF_NODE: if(here->ASRCtype == ASRC_VOLTAGE) { /* VCVS */ - *(here->ASRCposptr[j++]) -= derivs[i]; + *(here->ASRCposptr[j++]) -= derivs[i] / factor; } else { - /*VCCS*/ - *(here->ASRCposptr[j++]) += derivs[i]; - *(here->ASRCposptr[j++]) -= derivs[i]; + /* VCCS */ + *(here->ASRCposptr[j++]) += derivs[i] / factor; + *(here->ASRCposptr[j++]) -= derivs[i] / factor; } break; default: diff --git a/src/spicelib/devices/asrc/asrcask.c b/src/spicelib/devices/asrc/asrcask.c index 339a0e46d..babd823d4 100644 --- a/src/spicelib/devices/asrc/asrcask.c +++ b/src/spicelib/devices/asrc/asrcask.c @@ -29,13 +29,25 @@ ASRCask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFvalu NG_IGNORE(select); switch(which) { + case ASRC_TEMP: + value->rValue = here->ASRCtemp - CONSTCtoK; + return(OK); + case ASRC_DTEMP: + value->rValue = here->ASRCdtemp; + return(OK); + case ASRC_TC1: + value->rValue = here->ASRCtc1; + return(OK); + case ASRC_TC2: + value->rValue = here->ASRCtc2; + return(OK); case ASRC_CURRENT: value->tValue = here->ASRCtype == ASRC_CURRENT ? - here->ASRCtree : NULL; + here->ASRCtree : NULL; return (OK); case ASRC_VOLTAGE: value->tValue = here->ASRCtype == ASRC_VOLTAGE ? - here->ASRCtree : NULL; + here->ASRCtree : NULL; return (OK); case ASRC_POS_NODE: value->iValue = here->ASRCposNode; @@ -44,12 +56,12 @@ ASRCask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFvalu value->iValue = here->ASRCnegNode; return (OK); case ASRC_OUTPUTCURRENT: - value->rValue = ckt->CKTrhsOld[here->ASRCbranch]; + value->rValue = ckt->CKTrhsOld[here->ASRCbranch]; return (OK); case ASRC_OUTPUTVOLTAGE: - value->rValue = ckt->CKTrhsOld[here->ASRCposNode] - - ckt->CKTrhsOld[here->ASRCnegNode]; - return(OK); + value->rValue = ckt->CKTrhsOld[here->ASRCposNode] - + ckt->CKTrhsOld[here->ASRCnegNode]; + return(OK); default: return (E_BADPARM); } diff --git a/src/spicelib/devices/asrc/asrcdefs.h b/src/spicelib/devices/asrc/asrcdefs.h index 8f347626c..a5419cc69 100644 --- a/src/spicelib/devices/asrc/asrcdefs.h +++ b/src/spicelib/devices/asrc/asrcdefs.h @@ -6,34 +6,41 @@ Author: 1985 Thomas L. Quarles #ifndef ASRC #define ASRC - #include "ngspice/cktdefs.h" #include "ngspice/ifsim.h" #include "ngspice/complex.h" - /* - * structures to describe Arbitrary sources - */ +/* + * structures to describe Arbitrary sources +*/ /* information to describe a single instance */ typedef struct sASRCinstance { struct sASRCmodel *ARRCmodPtr; /* backpointer to model */ struct sASRCinstance *ASRCnextInstance; /* pointer to next instance of - *current model*/ + * current model */ IFuid ASRCname; /* pointer to character string naming this instance */ int ASRCowner; /* number of owner process */ int ASRCstates; /* state info */ int ASRCposNode; /* number of positive node of source */ int ASRCnegNode; /* number of negative node of source */ - int ASRCtype; /* Whether source is voltage or current */ + int ASRCtype; /* Whether source is voltage or current */ int ASRCbranch; /* number of branch equation added for v source */ IFparseTree *ASRCtree; /* The parse tree */ + double ASRCtemp; /* temperature at which this resistor operates */ + double ASRCdtemp; /* delta-temperature of a particular instance */ + double ASRCtc1; /* first temperature coefficient of resistors */ + double ASRCtc2; /* second temperature coefficient of resistors */ double **ASRCposptr; /* pointer to pointers of the elements - * in the sparce matrix */ + * in the sparce matrix */ double ASRCprev_value; /* Previous value for the convergence test */ double *ASRCacValues; /* Store rhs and derivatives for ac anal */ int ASRCcont_br; /* Temporary store for controlling current branch */ + unsigned ASRCtempGiven : 1; /* indicates temperature specified */ + unsigned ASRCdtempGiven : 1; /* indicates delta-temp specified */ + unsigned ASRCtc1Given : 1; /* indicates tc1 parameter specified */ + unsigned ASRCtc2Given : 1; /* indicates tc2 parameter specified */ } ASRCinstance ; @@ -59,6 +66,10 @@ typedef struct sASRCmodel { /* model structure for a source */ #define ASRC_PARSE_TREE 5 #define ASRC_OUTPUTVOLTAGE 6 #define ASRC_OUTPUTCURRENT 7 +#define ASRC_TEMP 8 +#define ASRC_DTEMP 9 +#define ASRC_TC1 10 +#define ASRC_TC2 11 /* module-wide variables */ diff --git a/src/spicelib/devices/asrc/asrcext.h b/src/spicelib/devices/asrc/asrcext.h index e408adbf3..a0a23f636 100644 --- a/src/spicelib/devices/asrc/asrcext.h +++ b/src/spicelib/devices/asrc/asrcext.h @@ -15,4 +15,4 @@ extern int ASRCpzLoad(GENmodel*,CKTcircuit*,SPcomplex*); extern int ASRCacLoad(GENmodel*,CKTcircuit*); extern int ASRCsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int ASRCunsetup(GENmodel*,CKTcircuit*); - +extern int ASRCtemp(GENmodel*,CKTcircuit*); diff --git a/src/spicelib/devices/asrc/asrcinit.c b/src/spicelib/devices/asrc/asrcinit.c index 3484e51fd..a9339deee 100644 --- a/src/spicelib/devices/asrc/asrcinit.c +++ b/src/spicelib/devices/asrc/asrcinit.c @@ -47,7 +47,7 @@ SPICEdev ASRCinfo = { /* DEVsetup */ ASRCsetup, /* DEVunsetup */ ASRCunsetup, /* DEVpzSetup */ ASRCsetup, - /* DEVtemperature*/ NULL, + /* DEVtemperature*/ ASRCtemp, /* DEVtrunc */ NULL, /* DEVfindBranch */ ASRCfindBr, /* DEVacLoad */ ASRCacLoad, /* ac and normal load functions NOT identical */ diff --git a/src/spicelib/devices/asrc/asrcload.c b/src/spicelib/devices/asrc/asrcload.c index e9d83adfe..692b3abac 100644 --- a/src/spicelib/devices/asrc/asrcload.c +++ b/src/spicelib/devices/asrc/asrcload.c @@ -13,7 +13,7 @@ Author: 1987 Kanwar Jit Singh #include "ngspice/suffix.h" double *asrc_vals, *asrc_derivs; -int asrc_nvals; +int asrc_nvals; /*ARGSUSED*/ int @@ -28,109 +28,117 @@ ASRCload(GENmodel *inModel, CKTcircuit *ckt) ASRCinstance *here; int i, j; double rhs; + double difference; + double factor; /* loop through all the Arbitrary source models */ for( ; model != NULL; model = model->ASRCnextModel ) { /* loop through all the instances of the model */ for (here = model->ASRCinstances; here != NULL ; - here=here->ASRCnextInstance) - { - if (here->ASRCowner != ARCHme) - continue; - - /* - * Get the function and its derivatives evaluated - */ - i = here->ASRCtree->numVars; - if (asrc_nvals < i) { - if (asrc_nvals) { - FREE(asrc_vals); - FREE(asrc_derivs); - } - asrc_nvals = i; - asrc_vals = NEWN(double, i); - asrc_derivs = NEWN(double, i); - } - - j=0; - - /* - * Fill the vector of values from the previous solution - */ - for( i=0; i < here->ASRCtree->numVars; i++) - if( here->ASRCtree->varTypes[i] == IF_INSTANCE) { - int branch = CKTfndBranch(ckt, here->ASRCtree->vars[i].uValue); - asrc_vals[i] = *(ckt->CKTrhsOld + branch); - } else { - int node_num = (here->ASRCtree->vars[i].nValue) -> number; - asrc_vals[i] = *(ckt->CKTrhsOld + node_num); - } - - if (here->ASRCtree->IFeval (here->ASRCtree, ckt->CKTgmin, &rhs, asrc_vals, asrc_derivs) != OK) - return(E_BADPARM); - - /* The convergence test */ - here->ASRCprev_value = rhs; - - /* The ac load precomputation and storage */ - - if (ckt->CKTmode & MODEINITSMSIG) { - int size = (here->ASRCtree->numVars) + 1 ; - here->ASRCacValues = NEWN(double, size); - for ( i = 0; i < here->ASRCtree->numVars; i++) - here->ASRCacValues[i] = asrc_derivs[i]; - } - - if( here->ASRCtype == ASRC_VOLTAGE) { - *(here->ASRCposptr[j++]) += 1.0; - *(here->ASRCposptr[j++]) -= 1.0; - *(here->ASRCposptr[j++]) -= 1.0; - *(here->ASRCposptr[j++]) += 1.0; + here=here->ASRCnextInstance) + { + if (here->ASRCowner != ARCHme) + continue; + + if(!here->ASRCtc1Given) here->ASRCtc1 = 0.0; + if(!here->ASRCtc2Given) here->ASRCtc2 = 0.0; + + difference = (here->ASRCtemp + here->ASRCdtemp) - 300.15; + factor = 1.0 + (here->ASRCtc1)*difference + (here->ASRCtc2)*difference*difference; + + /* + * Get the function and its derivatives evaluated + */ + i = here->ASRCtree->numVars; + if (asrc_nvals < i) { + if (asrc_nvals) { + FREE(asrc_vals); + FREE(asrc_derivs); + } + asrc_nvals = i; + asrc_vals = NEWN(double, i); + asrc_derivs = NEWN(double, i); + } + + j=0; + + /* + * Fill the vector of values from the previous solution + */ + for( i=0; i < here->ASRCtree->numVars; i++) + if( here->ASRCtree->varTypes[i] == IF_INSTANCE) { + int branch = CKTfndBranch(ckt, here->ASRCtree->vars[i].uValue); + asrc_vals[i] = *(ckt->CKTrhsOld + branch); + } else { + int node_num = (here->ASRCtree->vars[i].nValue) -> number; + asrc_vals[i] = *(ckt->CKTrhsOld + node_num); + } + + if (here->ASRCtree->IFeval (here->ASRCtree, ckt->CKTgmin, &rhs, asrc_vals, asrc_derivs) != OK) + return(E_BADPARM); + + /* The convergence test */ + here->ASRCprev_value = rhs; + + /* The ac load precomputation and storage */ + + if (ckt->CKTmode & MODEINITSMSIG) { + int size = (here->ASRCtree->numVars) + 1 ; + here->ASRCacValues = NEWN(double, size); + for ( i = 0; i < here->ASRCtree->numVars; i++) + here->ASRCacValues[i] = asrc_derivs[i]; + } + + if( here->ASRCtype == ASRC_VOLTAGE) { + *(here->ASRCposptr[j++]) += 1.0; + *(here->ASRCposptr[j++]) -= 1.0; + *(here->ASRCposptr[j++]) -= 1.0; + *(here->ASRCposptr[j++]) += 1.0; } - for(i=0; i < here->ASRCtree->numVars; i++) { - rhs -= (asrc_vals[i] * asrc_derivs[i]); - - switch(here->ASRCtree->varTypes[i]) { - case IF_INSTANCE: - if( here->ASRCtype == ASRC_VOLTAGE) { - /* CCVS */ - *(here->ASRCposptr[j++]) -= asrc_derivs[i]; - } else{ - /* CCCS */ - *(here->ASRCposptr[j++]) += asrc_derivs[i]; - *(here->ASRCposptr[j++]) -= asrc_derivs[i]; - } - break; - - case IF_NODE: - if(here->ASRCtype == ASRC_VOLTAGE) { - /* VCVS */ - *(here->ASRCposptr[j++]) -= asrc_derivs[i]; - } else { - /*VCCS*/ - *(here->ASRCposptr[j++]) += asrc_derivs[i]; - *(here->ASRCposptr[j++]) -= asrc_derivs[i]; - } - break; - - default: - return(E_BADPARM); + for(i=0; i < here->ASRCtree->numVars; i++) { + rhs -= (asrc_vals[i] * asrc_derivs[i]); + + switch(here->ASRCtree->varTypes[i]) { + case IF_INSTANCE: + if( here->ASRCtype == ASRC_VOLTAGE) { + /* CCVS */ + *(here->ASRCposptr[j++]) -= asrc_derivs[i] * factor; + } else{ + /* CCCS */ + *(here->ASRCposptr[j++]) += asrc_derivs[i] * factor; + *(here->ASRCposptr[j++]) -= asrc_derivs[i] * factor; + } + break; + + case IF_NODE: + if(here->ASRCtype == ASRC_VOLTAGE) { + /* VCVS */ + *(here->ASRCposptr[j++]) -= asrc_derivs[i] * factor; + } else { + /* VCCS */ + *(here->ASRCposptr[j++]) += asrc_derivs[i] * factor; + *(here->ASRCposptr[j++]) -= asrc_derivs[i] * factor; + } + break; + + default: + return(E_BADPARM); } } /* Insert the RHS */ if( here->ASRCtype == ASRC_VOLTAGE) { - *(ckt->CKTrhs+(here->ASRCbranch)) += rhs; + *(ckt->CKTrhs+(here->ASRCbranch)) += factor * rhs; } else { - *(ckt->CKTrhs+(here->ASRCposNode)) -= rhs; - *(ckt->CKTrhs+(here->ASRCnegNode)) += rhs; + *(ckt->CKTrhs+(here->ASRCposNode)) -= factor * rhs; + *(ckt->CKTrhs+(here->ASRCnegNode)) += factor * rhs; } /* Store the rhs for small signal analysis */ if (ckt->CKTmode & MODEINITSMSIG) { - here->ASRCacValues[here->ASRCtree->numVars] = rhs; + here->ASRCacValues[here->ASRCtree->numVars] = factor * rhs; } } } diff --git a/src/spicelib/devices/asrc/asrcpar.c b/src/spicelib/devices/asrc/asrcpar.c index f25d8d80b..e317830ad 100644 --- a/src/spicelib/devices/asrc/asrcpar.c +++ b/src/spicelib/devices/asrc/asrcpar.c @@ -24,11 +24,19 @@ ASRCparam(int param, IFvalue *value, GENinstance *fast, IFvalue *select) switch(param) { case ASRC_VOLTAGE: here->ASRCtype = ASRC_VOLTAGE; - here->ASRCtree = value->tValue; + here->ASRCtree = value->tValue; break; case ASRC_CURRENT: here->ASRCtype = ASRC_CURRENT; - here->ASRCtree = value->tValue; + here->ASRCtree = value->tValue; + break; + case ASRC_TC1: + here->ASRCtc1 = value->rValue; + here->ASRCtc1Given = TRUE; + break; + case ASRC_TC2: + here->ASRCtc2 = value->rValue; + here->ASRCtc2Given = TRUE; break; default: return(E_BADPARM); diff --git a/src/spicelib/devices/asrc/asrcpzld.c b/src/spicelib/devices/asrc/asrcpzld.c index 277fb5682..1f1a64155 100644 --- a/src/spicelib/devices/asrc/asrcpzld.c +++ b/src/spicelib/devices/asrc/asrcpzld.c @@ -22,6 +22,8 @@ ASRCpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) ASRCinstance *here; double value; int i, j; + double difference; + double factor; NG_IGNORE(s); @@ -35,6 +37,13 @@ ASRCpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) if (here->ASRCowner != ARCHme) continue; + if(!here->ASRCtc1Given) here->ASRCtc1 = 0.0; + if(!here->ASRCtc2Given) here->ASRCtc2 = 0.0; + + difference = (here->ASRCtemp + here->ASRCdtemp) - 300.15; + factor = 1.0 + (here->ASRCtc1)*difference + + (here->ASRCtc2)*difference*difference; + j = 0; /* Get the function evaluated and the derivatives too */ @@ -75,21 +84,21 @@ ASRCpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) case IF_INSTANCE: if( here->ASRCtype == ASRC_VOLTAGE) { /* CCVS */ - *(here->ASRCposptr[j++]) -= asrc_derivs[i]; + *(here->ASRCposptr[j++]) -= asrc_derivs[i] / factor; } else { /* CCCS */ - *(here->ASRCposptr[j++]) += asrc_derivs[i]; - *(here->ASRCposptr[j++]) -= asrc_derivs[i]; + *(here->ASRCposptr[j++]) += asrc_derivs[i] / factor; + *(here->ASRCposptr[j++]) -= asrc_derivs[i] / factor; } break; case IF_NODE: if(here->ASRCtype == ASRC_VOLTAGE) { /* VCVS */ - *(here->ASRCposptr[j++]) -= asrc_derivs[i]; + *(here->ASRCposptr[j++]) -= asrc_derivs[i] / factor; } else { /* VCCS */ - *(here->ASRCposptr[j++]) += asrc_derivs[i]; - *(here->ASRCposptr[j++]) -= asrc_derivs[i]; + *(here->ASRCposptr[j++]) += asrc_derivs[i] / factor; + *(here->ASRCposptr[j++]) -= asrc_derivs[i] / factor; } break; default: diff --git a/visualc/vngspice.vcproj b/visualc/vngspice.vcproj index a606a93b5..bdf2e7042 100644 --- a/visualc/vngspice.vcproj +++ b/visualc/vngspice.vcproj @@ -1,8860 +1,8864 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +