Merge branch 'master' into netgen-1.5
This commit is contained in:
commit
7cbf15aab1
|
|
@ -5218,14 +5218,23 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
|
||||||
|
|
||||||
if (comb == TRUE) {
|
if (comb == TRUE) {
|
||||||
double pd;
|
double pd;
|
||||||
|
int hascrit = FALSE;
|
||||||
int mult, cidx = -1;
|
int mult, cidx = -1;
|
||||||
struct valuelist *avl, *cvl = NULL;
|
struct valuelist **avl, **cvl;
|
||||||
|
struct valuelist *cvlp;
|
||||||
|
|
||||||
critval.type = PROP_ENDLIST;
|
critval.type = PROP_ENDLIST;
|
||||||
critval.value.dval = 0.0;
|
critval.value.dval = 0.0;
|
||||||
|
|
||||||
|
/* Track properties separately so that multiple properties can be
|
||||||
|
* added together (e.g., area and perimeter)
|
||||||
|
*/
|
||||||
|
avl = (struct valuelist **)CALLOC(pcount, sizeof(struct valuelist *));
|
||||||
|
cvl = (struct valuelist **)CALLOC(pcount, sizeof(struct valuelist *));
|
||||||
|
|
||||||
for (i = 0; i < run; i++) {
|
for (i = 0; i < run; i++) {
|
||||||
avl = NULL;
|
for (p = 0; p < pcount; p++) avl[p] = NULL;
|
||||||
// if (vlist[0][i] == NULL) continue;
|
|
||||||
// mult = vlist[0][i]->value.ival;
|
|
||||||
if (vlist[0][i] == NULL)
|
if (vlist[0][i] == NULL)
|
||||||
mult = 1;
|
mult = 1;
|
||||||
else
|
else
|
||||||
|
|
@ -5242,6 +5251,7 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
|
||||||
|
|
||||||
/* critical properties never combine, but track them */
|
/* critical properties never combine, but track them */
|
||||||
if ((series == TRUE) && (ctype & MERGE_S_CRIT)) {
|
if ((series == TRUE) && (ctype & MERGE_S_CRIT)) {
|
||||||
|
hascrit = TRUE;
|
||||||
pd = 2 * fabs(vl->value.dval - critval.value.dval) /
|
pd = 2 * fabs(vl->value.dval - critval.value.dval) /
|
||||||
(vl->value.dval + critval.value.dval);
|
(vl->value.dval + critval.value.dval);
|
||||||
if ((vl->type != critval.type) || (pd > kl->slop.dval))
|
if ((vl->type != critval.type) || (pd > kl->slop.dval))
|
||||||
|
|
@ -5253,6 +5263,7 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ((series == FALSE) && (ctype & MERGE_P_CRIT)) {
|
if ((series == FALSE) && (ctype & MERGE_P_CRIT)) {
|
||||||
|
hascrit = TRUE;
|
||||||
pd = 2 * fabs(vl->value.dval - critval.value.dval) /
|
pd = 2 * fabs(vl->value.dval - critval.value.dval) /
|
||||||
(vl->value.dval + critval.value.dval);
|
(vl->value.dval + critval.value.dval);
|
||||||
if ((vl->type != critval.type) || (pd > kl->slop.dval))
|
if ((vl->type != critval.type) || (pd > kl->slop.dval))
|
||||||
|
|
@ -5286,19 +5297,30 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ctype & (MERGE_S_ADD | MERGE_P_ADD | MERGE_S_PAR | MERGE_P_PAR))
|
if (ctype & (MERGE_S_ADD | MERGE_P_ADD | MERGE_S_PAR | MERGE_P_PAR))
|
||||||
avl = vl;
|
avl[p] = vl;
|
||||||
}
|
}
|
||||||
if (cidx == i) cvl = avl;
|
if (hascrit == FALSE) cidx = 0; /* No critical property */
|
||||||
|
|
||||||
|
/* Each time a new critical value is found, set the location */
|
||||||
|
/* of the property record that will collect the summation or */
|
||||||
|
/* parallel combination of values. */
|
||||||
|
if (cidx == i) {
|
||||||
|
for (p = 1; p < pcount; p++) {
|
||||||
|
cvl[p] = avl[p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Sorting should have put all records with the same critical */
|
/* Sorting should have put all records with the same critical */
|
||||||
/* value together sequentially. So if there are still */
|
/* value together sequentially. So if there are still */
|
||||||
/* multiple property records, then merge them into the first */
|
/* multiple property records, then merge them into the first */
|
||||||
/* record with the same critical property value. */
|
/* record with the same critical property value. If no */
|
||||||
|
/* critical value exists, then all records can be merged. */
|
||||||
|
|
||||||
if ((i > 0) && (cidx >= 0) && (cidx < i)) {
|
if ((i > 0) && (cidx >= 0) && (cidx < i)) {
|
||||||
for (p = 1; p < pcount; p++) {
|
for (p = 1; p < pcount; p++) {
|
||||||
vl = vlist[p][i];
|
vl = vlist[p][i];
|
||||||
ctype = clist[p][i];
|
ctype = clist[p][i];
|
||||||
|
cvlp = cvl[p];
|
||||||
|
|
||||||
if (ctype & (MERGE_S_ADD | MERGE_P_ADD)) {
|
if (ctype & (MERGE_S_ADD | MERGE_P_ADD)) {
|
||||||
if (!vlist[0][i]) {
|
if (!vlist[0][i]) {
|
||||||
|
|
@ -5307,21 +5329,21 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
|
||||||
sizeof(struct valuelist));
|
sizeof(struct valuelist));
|
||||||
}
|
}
|
||||||
vlist[0][i]->value.ival = 0; /* set M to 0 */
|
vlist[0][i]->value.ival = 0; /* set M to 0 */
|
||||||
if (cvl && (cvl->type == PROP_INTEGER))
|
if (cvlp && (cvlp->type == PROP_INTEGER))
|
||||||
{
|
{
|
||||||
if (vl->type == PROP_INTEGER)
|
if (vl->type == PROP_INTEGER)
|
||||||
cvl->value.ival += vl->value.ival;
|
cvlp->value.ival += vl->value.ival;
|
||||||
else {
|
else {
|
||||||
cvl->type = PROP_DOUBLE;
|
cvlp->type = PROP_DOUBLE;
|
||||||
cvl->value.dval = (double)cvl->value.ival + vl->value.dval;
|
cvlp->value.dval = (double)cvlp->value.ival + vl->value.dval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((cvl && vl->type == PROP_DOUBLE))
|
else if ((cvlp && vl->type == PROP_DOUBLE))
|
||||||
{
|
{
|
||||||
if (vl->type == PROP_INTEGER)
|
if (vl->type == PROP_INTEGER)
|
||||||
cvl->value.dval += (double)vl->value.ival;
|
cvlp->value.dval += (double)vl->value.ival;
|
||||||
else
|
else
|
||||||
cvl->value.dval += vl->value.dval;
|
cvlp->value.dval += vl->value.dval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ctype & (MERGE_S_PAR | MERGE_P_PAR)) {
|
else if (ctype & (MERGE_S_PAR | MERGE_P_PAR)) {
|
||||||
|
|
@ -5331,21 +5353,22 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
|
||||||
sizeof(struct valuelist));
|
sizeof(struct valuelist));
|
||||||
}
|
}
|
||||||
vlist[0][i]->value.ival = 0; /* set M to 0 */
|
vlist[0][i]->value.ival = 0; /* set M to 0 */
|
||||||
/* To do parallel combination, both types need to
|
/* Parallel value combination: (X * Y) / (X + Y)
|
||||||
|
* To do parallel combination, both types need to
|
||||||
* be double, so recast them if they are integer.
|
* be double, so recast them if they are integer.
|
||||||
*/
|
*/
|
||||||
if (vl->type == PROP_INTEGER) {
|
if (vl->type == PROP_INTEGER) {
|
||||||
vl->type = PROP_DOUBLE;
|
vl->type = PROP_DOUBLE;
|
||||||
vl->value.dval = (double)(vl->value.ival);
|
vl->value.dval = (double)(vl->value.ival);
|
||||||
}
|
}
|
||||||
if (cvl && (cvl->type == PROP_INTEGER)) {
|
if (cvlp && (cvlp->type == PROP_INTEGER)) {
|
||||||
cvl->type = PROP_DOUBLE;
|
cvlp->type = PROP_DOUBLE;
|
||||||
cvl->value.dval = (double)cvl->value.ival;
|
cvlp->value.dval = (double)cvlp->value.ival;
|
||||||
}
|
}
|
||||||
if ((cvl && (vl->type == PROP_DOUBLE))) {
|
if ((cvlp && (vl->type == PROP_DOUBLE))) {
|
||||||
cvl->value.dval =
|
cvlp->value.dval =
|
||||||
sqrt(cvl->value.dval * cvl->value.dval
|
(vl->value.dval * cvlp->value.dval) /
|
||||||
+ vl->value.dval * vl->value.dval);
|
(vl->value.dval + cvlp->value.dval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5357,6 +5380,9 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
|
||||||
Printf("Combined %d parallel devices.\n", changed);
|
Printf("Combined %d parallel devices.\n", changed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FREE(avl);
|
||||||
|
FREE(cvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove entries with M (S) = 0
|
// Remove entries with M (S) = 0
|
||||||
|
|
|
||||||
12
base/spice.c
12
base/spice.c
|
|
@ -534,7 +534,12 @@ void ReadSpiceFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||||
if ((EndParseFile()) && (nexttok == NULL)) break;
|
if ((EndParseFile()) && (nexttok == NULL)) break;
|
||||||
if (nexttok == NULL) break;
|
if (nexttok == NULL) break;
|
||||||
|
|
||||||
if (nexttok[0] == '*') SkipNewLine(NULL);
|
/* Handle comment lines. Note that some variants of CDL format
|
||||||
|
* use "*." for information that is transparent to SPICE simulators.
|
||||||
|
* Handle "*.GLOBAL" entries. All others are ignored.
|
||||||
|
*/
|
||||||
|
if ((nexttok[0] == '*') && (!matchnocase(nexttok, "*.GLOBAL")))
|
||||||
|
SkipNewLine(NULL);
|
||||||
|
|
||||||
else if (matchnocase(nexttok, ".SUBCKT")) {
|
else if (matchnocase(nexttok, ".SUBCKT")) {
|
||||||
SpiceTokNoNewline();
|
SpiceTokNoNewline();
|
||||||
|
|
@ -822,7 +827,10 @@ skip_ends:
|
||||||
|
|
||||||
// Handle some commonly-used cards
|
// Handle some commonly-used cards
|
||||||
|
|
||||||
else if (matchnocase(nexttok, ".GLOBAL")) {
|
/* .GLOBAL and *.GLOBAL. Note that *.GLOBAL is excepted from comment-line
|
||||||
|
* handling, above, so any line starting with '*' is "*.GLOBAL".
|
||||||
|
*/
|
||||||
|
else if (matchnocase(nexttok, ".GLOBAL") || (nexttok[0] == '*')) {
|
||||||
while (nexttok != NULL) {
|
while (nexttok != NULL) {
|
||||||
int numnodes = 0;
|
int numnodes = 0;
|
||||||
SpiceTokNoNewline();
|
SpiceTokNoNewline();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue