diff --git a/ChangeLog b/ChangeLog index 0724f9ee4..562cec73f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-01-21 Paolo Nenzi + + * src/include/ifsim.h, src/frontend/spiceif.c, src/frontend/shyu.c, + src/spicelib/cktntask.c: Applied the options patch made by + Charles Williams + 2004-01-20 Paolo Nenzi * src/maths/ni/*: Cleaned up code removing unnecessary includes. diff --git a/src/frontend/shyu.c b/src/frontend/shyu.c index c1a7a8c1d..cad279f0d 100644 --- a/src/frontend/shyu.c +++ b/src/frontend/shyu.c @@ -69,7 +69,8 @@ if_sens_run(char *t, wordlist *args, INPtables *tab) } } err = (*(ft_sim->newTask))(ft_curckt->ci_ckt, - (void **) &(ft_curckt->ci_specTask),"special"); + (void **) &(ft_curckt->ci_specTask),"special", + (void**)&(ft_curckt->ci_defTask)); if(err) { ft_sperror(err,"newTask"); return(0); /* temporary */ diff --git a/src/frontend/spiceif.c b/src/frontend/spiceif.c index 162daa5d3..0984ec41f 100644 --- a/src/frontend/spiceif.c +++ b/src/frontend/spiceif.c @@ -12,6 +12,39 @@ Modified: 2000 AlansFixes * that includes ngspice.header files. */ +/*CDHW Notes: + +I have never really understood the way Berkeley intended the six pointers +to default values (ci_defOpt/Task ci_specOpt/Task ci_curOpt/Task) to work, +as there only see to be two data blocks to point at, or I've missed something +clever elsewhere. + +Anyway, in the original 3f4 the interactive command 'set temp = 10' +set temp for its current task and clobbered the default values as a side +effect. When an interactive is run it created specTask using the spice +application default values, not the circuit defaults affected +by 'set temp = 10'. + +The fix involves two changes + + 1. Make 'set temp = 10' change the values in the 'default' block, not whatever + the 'current' pointer happens to be pointing at (which is usually the + default block except when one interactive is run immediately +after another). + + 2. Hack CKTnewTask() so that it looks to see whether it is creating +a 'special' + task, in which case it copies the values from +ft_curckt->ci_defTask providing + everything looks sane, otherwise it uses the hard-coded +'application defaults'. + +These are fairly minor changes, and as they don't change the data structures +they should be fairly 'safe'. However, ... + + +CDHW*/ + #include "ngspice.h" #include "cpdefs.h" #include "tskdefs.h" /* Is really needed ? */ @@ -70,18 +103,28 @@ if_inpdeck(struct line *deck, INPtables **tab) return (NULL); } +/*CDHW Create a task DDD with a new UID. ci_defTask will point to it CDHW*/ + err = IFnewUid(ckt,&taskUid,(IFuid)NULL,"default",UID_TASK,(void**)NULL); if(err) { ft_sperror(err,"newUid"); return(NULL); } - - err = (*(ft_sim->newTask))(ckt,(void**)&(ft_curckt->ci_defTask),taskUid); +#if (0) + err = + (*(ft_sim->newTask))(ckt,(void**)&(ft_curckt->ci_defTask),taskUid); +#else /*CDHW*/ + err = + (*(ft_sim->newTask))(ckt,(void**)&(ft_curckt->ci_defTask),taskUid, + (void**)NULL); +#endif if(err) { ft_sperror(err,"newTask"); return(NULL); } +/*CDHW which options available for this simulator? CDHW*/ + for(j=0;jnumAnalyses;j++) { if(strcmp(ft_sim->analyses[j]->name,"options")==0) { which = j; @@ -100,12 +143,16 @@ if_inpdeck(struct line *deck, INPtables **tab) err = (*(ft_sim->newAnalysis))(ft_curckt->ci_ckt,which,optUid, (void**)&(ft_curckt->ci_defOpt), (void*)ft_curckt->ci_defTask); + +/*CDHW ci_defTask and ci_defOpt point to parameters DDD CDHW*/ + if(err) { ft_sperror(err,"createOptions"); return(NULL); } ft_curckt->ci_curOpt = ft_curckt->ci_defOpt; +/*CDHW ci_curOpt and ci_defOpt point to DDD CDHW*/ } ft_curckt->ci_curTask = ft_curckt->ci_defTask; @@ -157,6 +204,7 @@ if_run(char *t, char *what, wordlist *args, char *tab) /* First parse the line... */ + /*CDHW Look for an interactive task CDHW*/ if (eq(what, "tran") || eq(what, "ac") || eq(what, "dc") @@ -176,29 +224,43 @@ if_run(char *t, char *what, wordlist *args, char *tab) deck.li_linenum = 0; deck.li_line = buf; +/*CDHW Delete any previous special task CDHW*/ + if(ft_curckt->ci_specTask) { + if (ft_curckt->ci_specTask == ft_curckt->ci_defTask) { /*CDHW*/ + printf("Oh dear...something bad has happened to the options.\n"); + } err=(*(ft_sim->deleteTask))(ft_curckt->ci_ckt, ft_curckt->ci_specTask); if(err) { ft_sperror(err,"deleteTask"); return(2); } + ft_curckt->ci_specTask = ft_curckt->ci_specOpt = NULL; /*CDHW*/ } + /*CDHW Create an interactive task AAA with a new UID. +ci_specTask will point to it CDHW*/ + err = IFnewUid(ft_curckt->ci_ckt,&specUid,(IFuid)NULL,"special", UID_TASK,(void**)NULL); if(err) { ft_sperror(err,"newUid"); return(2); } - err = (*(ft_sim->newTask))(ft_curckt->ci_ckt, +#if (0) + err = (*(ft_sim->newTask))(ft_curckt->ci_ckt, (void**)&(ft_curckt->ci_specTask),specUid); - - +#else /*CDHW*/ + err = (*(ft_sim->newTask))(ft_curckt->ci_ckt, + (void**)&(ft_curckt->ci_specTask), + specUid,(void**)&(ft_curckt->ci_defTask)); +#endif if(err) { ft_sperror(err,"newTask"); return(2); } - + +/*CDHW which options available for this simulator? CDHW*/ for(j=0;jnumAnalyses;j++) { if(strcmp(ft_sim->analyses[j]->name,"options")==0) { @@ -206,7 +268,7 @@ if_run(char *t, char *what, wordlist *args, char *tab) break; } } - if(which != -1) { + if(which != -1) { /*CDHW options are available CDHW*/ err = IFnewUid(ft_curckt->ci_ckt,&optUid,(IFuid)NULL,"options", UID_ANALYSIS,(void**)NULL); if(err) { @@ -216,61 +278,23 @@ if_run(char *t, char *what, wordlist *args, char *tab) err = (*(ft_sim->newAnalysis))(ft_curckt->ci_ckt,which,optUid, (void**)&(ft_curckt->ci_specOpt), (void*)ft_curckt->ci_specTask); + +/*CDHW 'options' ci_specOpt points to AAA in this case CDHW*/ + if(err) { ft_sperror(err,"createOptions"); return(2); } - ft_curckt->ci_curOpt = ft_curckt->ci_specOpt; - - /* This is a very dirty hack but it is the only one I - was able to find without intervening on all the code - It will be changed in the future. */ - - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKtemp = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKtemp; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKnomTemp = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnomTemp; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKgmin = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKgmin; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKgshunt = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKgshunt; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKabstol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKabstol; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKreltol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKreltol; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKchgtol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKchgtol; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKvoltTol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKvoltTol; -#ifdef NEWTRUNC - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKlteReltol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKlteReltol; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKlteAbstol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKlteAbstol; -#endif - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKtrtol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKtrtol; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKbypass = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKbypass; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKtranMaxIter = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKtranMaxIter; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKdcMaxIter = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdcMaxIter; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKdcTrcvMaxIter = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdcTrcvMaxIter; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKintegrateMethod = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKintegrateMethod; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKmaxOrder = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKmaxOrder; - - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKnumSrcSteps = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnumSrcSteps; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKnumGminSteps = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnumGminSteps; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKgminFactor = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKgminFactor; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKpivotAbsTol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKpivotAbsTol; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKpivotRelTol = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKpivotRelTol; - - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosM = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosM; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosL = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosL; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosW = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosW; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosAD = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosAD; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKdefaultMosAS = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKdefaultMosAS; - - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKnoOpIter = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnoOpIter; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKtryToCompact = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKtryToCompact; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKbadMos3 = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKbadMos3; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKkeepOpInfo = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKkeepOpInfo; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKcopyNodesets = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKcopyNodesets; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKnodeDamping = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKnodeDamping; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKabsDv = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKabsDv; - ((TSKtask *)(ft_curckt->ci_specOpt))->TSKrelDv = ((TSKtask *)(ft_curckt->ci_defOpt))->TSKrelDv; - + + ft_curckt->ci_curOpt = ft_curckt->ci_specOpt; + +/*CDHW ci_specTask ci_specOpt and ci_curOpt all point to AAA CDHW*/ - } + } + ft_curckt->ci_curTask = ft_curckt->ci_specTask; - + +/*CDHW ci_curTask and ci_specTask point to the interactive task AAA CDHW*/ INPpas2(ckt, (card *) &deck, (INPtables *)tab, ft_curckt->ci_specTask); @@ -280,14 +304,12 @@ if_run(char *t, char *what, wordlist *args, char *tab) } } -/* -- *** BUG! ****/ -/* -- A bug fix suggested by Cecil Aswell (aswell@netcom.com) to let */ -/* -- the interactive analysis commands get the current temperature */ -/* -- and other options. */ - -/* dw With this the last simulation will be repeated on the input line, and the -last valid temperature is used. (Why is the  temperature is within defOpt?!) -*/ + /*CDHW + ** if the task is to 'run' the deck, change ci_curTask and + ** ci_curOpt to point to DDD + ** created by if_inpdeck(), otherwise they point to AAA. + CDHW*/ + if( eq(what,"run") ) { ft_curckt->ci_curTask = ft_curckt->ci_defTask; ft_curckt->ci_curOpt = ft_curckt->ci_defOpt; @@ -306,7 +328,9 @@ last valid temperature is used. (Why is the  temperature is within defOpt?!) ||(eq(what, "sens")) ||(eq(what,"tf")) ||(eq(what, "run")) ) { -/*dw Nutzung der letzten gültigen Temperatur, z.B. nach "set temp" s.o. */ + +/*CDHW Run the analysis pointed to by ci_curTask CDHW*/ + ft_curckt->ci_curOpt = ft_curckt->ci_defOpt; if ((err = (*(ft_sim->doAnalyses))(ckt, 1, ft_curckt->ci_curTask))!=OK){ ft_sperror(err, "doAnalyses"); @@ -455,11 +479,19 @@ if_option(void *ckt, char *name, int type, char *value) return 1; } - if ((err = (*(ft_sim->setAnalysisParm))(cc, (void *)ft_curckt->ci_curOpt, - ft_sim->analyses[which]->analysisParms[i].id, &pval, - (IFvalue *)NULL)) != OK) - ft_sperror(err, "setAnalysisParm(options)"); - return 1; +#if (0) + if ((err = (*(ft_sim->setAnalysisParm))(cc, (void *)ft_curckt->ci_curOpt, + ft_sim->analyses[which]->analysisParms[i].id, &pval, + (IFvalue *)NULL)) != OK) + ft_sperror(err, "setAnalysisParm(options) ci_curOpt"); +#else /*CDHW*/ + if ((err = (*(ft_sim->setAnalysisParm))(cc, (void *)ft_curckt->ci_defOpt, + ft_sim->analyses[which]->analysisParms[i].id, &pval, + (IFvalue *)NULL)) != OK) + ft_sperror(err, "setAnalysisParm(options) ci_curOpt"); + return 1; +#endif + badtype: fprintf(cp_err, "Error: bad type given for option %s --\n", name); fprintf(cp_err, "\ttype given was "); diff --git a/src/include/ifsim.h b/src/include/ifsim.h index 6121b1dcd..99a5b1294 100644 --- a/src/include/ifsim.h +++ b/src/include/ifsim.h @@ -380,7 +380,7 @@ typedef struct sIFsimulator { int ((*deleteModel)(void*,void*)); /* delete a model from the circuit*/ - int ((*newTask)(void*,void**,IFuid)); + int ((*newTask)(void*,void**,IFuid, void**)); /*CDHW*/ /* create a new task */ int ((*newAnalysis)(void*,int,IFuid,void**,void*)); /* create new analysis within a task */ diff --git a/src/spicelib/analysis/cktntask.c b/src/spicelib/analysis/cktntask.c index 5c5f077a1..06c1a74bb 100644 --- a/src/spicelib/analysis/cktntask.c +++ b/src/spicelib/analysis/cktntask.c @@ -14,51 +14,97 @@ Modified: 2000 AlansFixes /* ARGSUSED */ +/* int CKTnewTask(void *ckt, void **taskPtr, IFuid taskName) + */ +int +CKTnewTask(void *ckt, void **taskPtr, IFuid taskName, void **defPtr) +/*CDHW See notes in spiceif.c for an explanation of these fixes CDHW*/ { - TSKtask *tsk; + TSKtask *tsk, *def=NULL; - *taskPtr = (void *)MALLOC(sizeof(TSKtask)); + *taskPtr = (void *)tmalloc(sizeof(TSKtask)); if(*taskPtr==NULL) return(E_NOMEM); tsk = *(TSKtask **)taskPtr; tsk->TSKname = taskName; - tsk->TSKgmin = 1e-12; - tsk->TSKgshunt = 0; - tsk->TSKabstol = 1e-12; - tsk->TSKreltol = 1e-3; - tsk->TSKchgtol = 1e-14; - tsk->TSKvoltTol = 1e-6; +#if (1) /*CDHW*/ + if(defPtr) + def = *(TSKtask **)defPtr; + if ((strcmp(taskName,"special")==0) && def ) { + /* create options by copying the circuit's defaults */ + tsk->TSKgmin = def->TSKgmin; + tsk->TSKabstol = def->TSKabstol; + tsk->TSKreltol = def->TSKreltol; + tsk->TSKchgtol = def->TSKchgtol; + tsk->TSKvoltTol = def->TSKvoltTol; #ifdef NEWTRUNC - tsk->TSKlteReltol = 1e-3; - tsk->TSKlteAbstol = 1e-6; + tsk->TSKlteReltol = def->TSKlteRelto; + tsk->TSKlteAbstol = def->TSKlteAbstol; #endif /* NEWTRUNC */ - tsk->TSKtrtol = 7; - tsk->TSKbypass = 0; - tsk->TSKtranMaxIter = 10; - tsk->TSKdcMaxIter = 100; - tsk->TSKdcTrcvMaxIter = 50; - tsk->TSKintegrateMethod = TRAPEZOIDAL; - tsk->TSKmaxOrder = 2; - tsk->TSKnumSrcSteps = 1; - tsk->TSKnumGminSteps = 1; - tsk->TSKgminFactor = 10; - tsk->TSKpivotAbsTol = 1e-13; - tsk->TSKpivotRelTol = 1e-3; - tsk->TSKtemp = 300.15; - tsk->TSKnomTemp = 300.15; - tsk->TSKdefaultMosM = 1; - tsk->TSKdefaultMosL = 1e-4; - tsk->TSKdefaultMosW = 1e-4; - tsk->TSKdefaultMosAD = 0; - tsk->TSKdefaultMosAS = 0; - tsk->TSKnoOpIter=0; - tsk->TSKtryToCompact=0; - tsk->TSKbadMos3=0; - tsk->TSKkeepOpInfo=0; - tsk->TSKcopyNodesets=0; - tsk->TSKnodeDamping=0; - tsk->TSKabsDv=0.5; - tsk->TSKrelDv=2.0; + tsk->TSKtrtol = def->TSKtrtol; + tsk->TSKbypass = def->TSKbypass; + tsk->TSKtranMaxIter = def->TSKtranMaxIter; + tsk->TSKdcMaxIter = def->TSKdcMaxIter; + tsk->TSKdcTrcvMaxIter = def->TSKdcTrcvMaxIter; + tsk->TSKintegrateMethod = def->TSKintegrateMethod; + tsk->TSKmaxOrder = def->TSKmaxOrder; + tsk->TSKnumSrcSteps = def->TSKnumSrcSteps; + tsk->TSKnumGminSteps = def->TSKnumGminSteps; + tsk->TSKpivotAbsTol = def->TSKpivotAbsTol; + tsk->TSKpivotRelTol = def->TSKpivotRelTol; + tsk->TSKtemp = def->TSKtemp; + tsk->TSKnomTemp = def->TSKnomTemp; + tsk->TSKdefaultMosL = def->TSKdefaultMosL; + tsk->TSKdefaultMosW = def->TSKdefaultMosW; + tsk->TSKdefaultMosAD = def->TSKdefaultMosAD; + tsk->TSKdefaultMosAS = def->TSKdefaultMosAS; + tsk->TSKnoOpIter= def->TSKnoOpIter; + tsk->TSKtryToCompact = def->TSKtryToCompact; + tsk->TSKbadMos3 = def->TSKbadMos3; + tsk->TSKkeepOpInfo = def->TSKkeepOpInfo; + } else { + /* use the application defaults */ +#endif /*CDHW*/ + tsk->TSKgmin = 1e-12; + tsk->TSKgshunt = 0; + tsk->TSKabstol = 1e-12; + tsk->TSKreltol = 1e-3; + tsk->TSKchgtol = 1e-14; + tsk->TSKvoltTol = 1e-6; +#ifdef NEWTRUNC + tsk->TSKlteReltol = 1e-3; + tsk->TSKlteAbstol = 1e-6; +#endif /* NEWTRUNC */ + tsk->TSKtrtol = 7; + tsk->TSKbypass = 0; + tsk->TSKtranMaxIter = 10; + tsk->TSKdcMaxIter = 100; + tsk->TSKdcTrcvMaxIter = 50; + tsk->TSKintegrateMethod = TRAPEZOIDAL; + tsk->TSKmaxOrder = 2; + tsk->TSKnumSrcSteps = 1; + tsk->TSKnumGminSteps = 1; + tsk->TSKgminFactor = 10; + tsk->TSKpivotAbsTol = 1e-13; + tsk->TSKpivotRelTol = 1e-3; + tsk->TSKtemp = 300.15; + tsk->TSKnomTemp = 300.15; + tsk->TSKdefaultMosM = 1; + tsk->TSKdefaultMosL = 1e-4; + tsk->TSKdefaultMosW = 1e-4; + tsk->TSKdefaultMosAD = 0; + tsk->TSKdefaultMosAS = 0; + tsk->TSKnoOpIter=0; + tsk->TSKtryToCompact=0; + tsk->TSKbadMos3=0; + tsk->TSKkeepOpInfo=0; + tsk->TSKcopyNodesets=0; + tsk->TSKnodeDamping=0; + tsk->TSKabsDv=0.5; + tsk->TSKrelDv=2.0; +#if (1) /*CDHW*/ + } +#endif return(OK); }