void pgPrintCurLPObjFunc(Circuit *ckt, FILE *fp) { double cst, vdrop; char name[128]; Branches *daux; int count = 0; assert(ckt->theDeviceList); fprintf(fp,"MIN: "); for(daux = ckt->theDeviceList; daux; daux = daux->next) { if(daux->stat != sNormal) continue; if(daux->type != dRES) continue; /* ignore branch with very small current */ if(fabs(daux->current) <= MIN_CURRENT || fabs(ckt->theNodeArray[daux->n1].voltage - ckt->theNodeArray[daux->n2].voltage) <= MIN_VOLTAGE ) { sprintf(buf,"branch %s: current or voltage drop is close to 0, ignored.\n", daux->name); print_mesg(buf); daux->stat = sAbnormal; continue; } count++; assert(daux->n1 < (ckt->nMatrixSize+1)); assert(daux->n2 < (ckt->nMatrixSize+1)); vdrop = ckt->theNodeArray[daux->n1].voltage - ckt->theNodeArray[daux->n2].voltage; cst = daux->length*daux->length*daux->lay->unitRes/(vdrop + FTINY); /* variable must be positive */ if(daux->current < 0) { cst = -cst; sprintf(name,"IN_%d",daux->index); } else { sprintf(name,"I_%d",daux->index); } if(cst >= 0) fprintf(fp,"+%1.10g %s ", cst, name); else fprintf(fp,"%1.10g %s ", cst, name); if(count%3 == 0) fprintf(fp,"\n"); } fprintf(fp,";\n"); }
/* * Announce an invitation to talk. If the user is * accepting messages, announce that a talk is requested. */ int announce(CTL_MSG *request, char *remote_machine) { char full_tty[MAXPATHLEN]; FILE *tf; struct stat stbuf; (void)snprintf(full_tty, sizeof(full_tty), "%s/%s", _PATH_DEV, request->r_tty); if (access(full_tty, 0) != 0) return (FAILED); if ((tf = fopen(full_tty, "w")) == NULL) return (PERMISSION_DENIED); if (fstat(fileno(tf), &stbuf) < 0) { fclose(tf); return (PERMISSION_DENIED); } if ((stbuf.st_mode & S_IWGRP) == 0) { fclose(tf); return (PERMISSION_DENIED); } print_mesg(tf, request, remote_machine); fclose(tf); return (SUCCESS); }
/* * See if the user is accepting messages. If so, announce that * a talk is requested. */ int announce(CTL_MSG *request, const char *remote_machine) { char full_tty[32]; struct stat stbuf; (void)snprintf(full_tty, sizeof(full_tty), "%s%s", _PATH_DEV, request->r_tty); if (stat(full_tty, &stbuf) < 0 || (stbuf.st_mode&020) == 0) return (PERMISSION_DENIED); return (print_mesg(request->r_tty, request, remote_machine)); }
void main_menu_select(int value) { char title[512]; switch(value) { case 1: face_reset ( face ) ; glutPostRedisplay(); break; case 2: print_mesg(); break; case 3: face->muscle[m]->mstat += 0.25 ; activate_muscle ( face, face->muscle[m]->head, face->muscle[m]->tail, face->muscle[m]->fs, face->muscle[m]->fe, face->muscle[m]->zone, +0.25 ) ; glutPostRedisplay(); break; case 4: face->muscle[m]->mstat -= 0.25 ; activate_muscle ( face, face->muscle[m]->head, face->muscle[m]->tail, face->muscle[m]->fs, face->muscle[m]->fe, face->muscle[m]->zone, -0.25 ) ; glutPostRedisplay(); break; case 5: m++ ; if ( m >= face->nmuscles ) m = 0 ; sprintf(title, "geoface (%s)", face->muscle[m]->name); glutSetWindowTitle(title); break; case 666: exit(0); break; } }
double pgComputeIntConstValue(IntConst * icp) { Products *paux; double dsum = 0, diff; if(!icp) return 0; for(paux = icp->prod_list; paux; paux = paux->next) { if(paux->branch)/* current variable */ dsum += paux->sign*paux->coeff*paux->branch->current; else if(paux->node) /* voltage variable */ dsum += paux->sign*paux->coeff*paux->node->voltage; else { error_mesg(FAT_ERROR,"No variable in product."); continue; } } dsum += icp->cst; if(icp->type == GE && dsum >= 0.0) icp->stat = csSatisfied; else if((icp->type == GE) && (dsum < 0) && (fabs(dsum/icp->cst) > 1e-6) ) { icp->stat = csViolated; pgPrintIntConst(stdout,icp); sprintf(buf," is violated (%g) vol: %g.\n",dsum, icp->prod_list->node->voltage); print_mesg(buf); } else if(icp->type == EQ) icp->stat = csSatisfied; else { /* pgPrintIntConst(stdout,icp); print_mesg(" is not supported.\n"); */ return 0; } return dsum; }
/* ARGSUSED1 */ static void Key ( unsigned char key, int x, int y ) { char title[512]; switch ( key ) { case 27 : case 'q' : case 'Q' : exit (0) ; case 'r' : case 'R' : printf ("Rereading expression file\n"); read_expressions(); e = 0; /* reset the expression count variable */ glutPostRedisplay(); break; case 'a' : printf ("increment muscle: %s\n", face->muscle[m]->name ) ; /* set the muscle activation */ face->muscle[m]->mstat += 0.1 ; activate_muscle ( face, face->muscle[m]->head, face->muscle[m]->tail, face->muscle[m]->fs, face->muscle[m]->fe, face->muscle[m]->zone, 0.1 ) ; glutPostRedisplay(); break; case 'A' : printf ("decrement muscle: %s\n", face->muscle[m]->name ) ; face->muscle[m]->mstat -= 0.1 ; activate_muscle ( face, face->muscle[m]->head, face->muscle[m]->tail, face->muscle[m]->fs, face->muscle[m]->fe, face->muscle[m]->zone, -0.1 ) ; glutPostRedisplay(); break; case 'b' : DRAW_MODE++ ; if ( DRAW_MODE >= 3 ) DRAW_MODE = 0 ; printf ("draw mode: %d\n", DRAW_MODE ) ; glutPostRedisplay(); break; case 'c' : face_reset ( face ) ; glutPostRedisplay(); break; case 'n' : m++ ; if ( m >= face->nmuscles ) m = 0 ; sprintf(title, "geoface (%s)", face->muscle[m]->name); glutSetWindowTitle(title); break; case 'e' : if (face->expression) { face_reset ( face ) ; expressions ( face, e ) ; e++ ; if ( e >= face->nexpressions ) e = 0 ; glutPostRedisplay(); } break; case 'h' : print_mesg(); } }
void pgBuildCurLPConst(Circuit *ckt, ExtConst *ext_const, OptMode mode) { long index = 1; ExtConst *etaux; IntConst *itaux; Nodes *naux; int i,sign; Products *paux; Branches *daux, *bch1 = NULL, *bch2=NULL; BranchLink *blaux; double coeff, cst; double vdrop; assert(ext_const); assert(ckt->theNodeArray); assert(ckt->theDeviceList); if(ckt->LPIntConstList) { pgFreeIntConst(ckt->LPIntConstList); ckt->LPIntConstList = NULL; } /* * constraints due to KCL law */ for( i = 1; i <= ckt->nNumNode; i++) { /* ignore the dangling node */ if(ckt->theNodeArray[i].stat != nNormal || ckt->theNodeArray[i].isVDD ) continue; /* if(ckt->theNodeArray[i].stat != nNormal) continue; */ /* each node has a constraint */ itaux = pgNewIntConst(EQ,index++); pgAddIntConst(&(ckt->LPIntConstList),itaux); for(blaux = ckt->theNodeArray[i].blist; blaux; blaux = blaux->next) { /* the sign is positive if the current direction of the branch is toward node i. */ if(blaux->dev->type == dCUR && blaux->dev->n1 == i) { cst = -1*blaux->dev->value; pgAddNumConst(itaux,cst); } else if(blaux->dev->type == dCUR && blaux->dev->n2 == i) { cst = blaux->dev->value; pgAddNumConst(itaux,cst); } /* the sign is positive if the current direction of the branch is toward node i. */ else if(blaux->dev->type == dRES && blaux->dev->n1 == i) { paux = pgNewProductByBranch(-1, 1.0,blaux->dev); pgAddProduct(itaux,paux); } else if(blaux->dev->type == dRES && blaux->dev->n2 == i) { paux = pgNewProductByBranch(1, 1.0,blaux->dev); pgAddProduct(itaux,paux); } else { sprintf(buf, "Irrelevant branch: %s for node %d.", blaux->dev->name, i); error_mesg(INT_ERROR,buf); continue; } } } /* * minimum width constraints * 1/(Vi2 - Vi1)*Ii - Wmin/(Resistivity*Li) >= 0 */ for(daux = ckt->theDeviceList; daux; daux = daux->next) { if(daux->stat != sNormal) continue; if(daux->type != dRES) continue; /* ignore branch with very small current */ /* if(fabs(daux->current) <= MIN_CURRENT || fabs(ckt->theNodeArray[daux->n1].voltage - ckt->theNodeArray[daux->n2].voltage) <= MIN_VOLTAGE ) { sprintf(buf,"branch %s: current or voltage drop is close to 0, ignored.\n", daux->name); print_mesg(buf); daux->stat = sAbnormal; continue; } */ /* make sure current is not zero */ if(daux->current != 0.0) { itaux = pgNewIntConst( GE,index++ ); pgAddIntConst(&(ckt->LPIntConstList),itaux); /* we creat a product terms and a constant */ /* the product */ assert(daux->n1 < (ckt->nMatrixSize+1)); assert(daux->n2 < (ckt->nMatrixSize+1)); vdrop = ckt->theNodeArray[daux->n1].voltage - ckt->theNodeArray[daux->n2].voltage; if(vdrop == 0) { printf("n%d (%g) -> n%d (%g)", daux->n1, ckt->theNodeArray[daux->n1].voltage, daux->n2, ckt->theNodeArray[daux->n2].voltage); printf("current %g", daux->current); assert(vdrop != 0.0); } coeff = 1/(vdrop+FTINY); paux = pgNewProductByBranch(1, coeff, daux); pgAddProduct(itaux,paux); /* the constant */ if(mode == optConjugate) cst = 0 - (daux->lay->minWidth*EPSILON)/(daux->length* daux->lay->unitRes); else cst = 0 - (daux->lay->minWidth)/(daux->length* daux->lay->unitRes); pgAddNumConst(itaux,cst); } else { sprintf(buf,"%s(Linear): current=0, ignored.\n", daux->name); print_mesg(buf); } } /* * Equivalence-width constraint * (li*Ii)/(Vi1-Vi2) - (lj*Ij)/(Vj1-Vj2) = 0 */ for( etaux = ext_const; etaux; etaux = etaux->next ) { if( etaux->topic == cWIDTH ) { if(etaux->type != EQ ) { sprintf(buf,"Invalid width constraint: v(%d).", etaux->node1); error_mesg(PARSE_ERROR,buf); continue; } itaux = pgNewIntConst(EQ, index++); pgAddIntConst(&(ckt->LPIntConstList),itaux); daux = pgFindBranchByName(ckt,etaux->bname1); assert(daux); vdrop = ckt->theNodeArray[daux->n1].voltage - ckt->theNodeArray[daux->n2].voltage; assert(vdrop != 0.0); coeff = daux->length/(vdrop+FTINY); paux = pgNewProductByBranch(1, coeff, daux); pgAddProduct(itaux, paux); daux = pgFindBranchByName(ckt, etaux->bname2); assert(daux); vdrop = ckt->theNodeArray[daux->n1].voltage - ckt->theNodeArray[daux->n2].voltage; assert(vdrop != 0.0); coeff = daux->length/(vdrop + FTINY); paux = pgNewProductByBranch(-1, coeff, daux); pgAddProduct(itaux, paux); } } }
void pgBuildNLPConst(Circuit *ckt, ExtConst *ext_const) { long index = 1; ExtConst *etaux; IntConst *itaux; Nodes *naux; int sign; Products *paux; Branches *daux, *bch1 = NULL, *bch2=NULL; double cst; assert(ext_const); assert(ckt->theNodeArray); assert(ckt->theDeviceList); if(ckt->NLPIntConstList){ pgFreeIntConst(ckt->NLPIntConstList); ckt->NLPIntConstList = NULL; } /* ** build all the constraints for minimum width ** and also reserve current direction */ for(daux = ckt->theDeviceList; daux; daux = daux->next) { if(daux->stat != sNormal) continue; if(daux->type != dRES) continue; /* ignore branch with very small current */ /* if(fabs(daux->current) <= MIN_CURRENT || fabs(theNodeArray[daux->n1].voltage - theNodeArray[daux->n2].voltage) <= MIN_VOLTAGE ){ sprintf(buf,"branch %s: current or voltage drop is close to 0, ignored.\n", daux->name); print_mesg(buf); daux->stat = sAbnormal; continue; } */ assert(daux->n1 < (ckt->nMatrixSize+1)); assert(daux->n2 < (ckt->nMatrixSize+1)); /* first constraint */ if(daux->current != 0.0 ) { itaux = pgNewIntConst(GE,index++); pgAddIntConst(&(ckt->NLPIntConstList),itaux); naux = &(ckt->theNodeArray[daux->n1]); paux = pgNewProductByNode(-1, 1/(daux->current),naux); pgAddProduct(itaux,paux); naux = &(ckt->theNodeArray[daux->n2]); paux = pgNewProductByNode(1, 1/(daux->current),naux); pgAddProduct(itaux,paux); cst = (daux->lay->unitRes*daux->length/ (daux->lay->minWidth)); pgAddNumConst(itaux,cst); /* second constraint */ itaux = pgNewIntConst(GE,index++); pgAddIntConst(&(ckt->NLPIntConstList),itaux); /* second constraint */ naux = &(ckt->theNodeArray[daux->n1]); paux = pgNewProductByNode(1,1/daux->current, naux); pgAddProduct(itaux,paux); naux = &(ckt->theNodeArray[daux->n2]); paux = pgNewProductByNode(-1,1/daux->current, naux); pgAddProduct(itaux,paux); } else{ sprintf(buf,"%s(nonlinear): current=0, ignored.\n", daux->name); print_mesg(buf); } } /* the internal constrain related to the user defined external constraints. */ for( etaux = ext_const; etaux; etaux = etaux->next ) { if(etaux->topic == cVOL) { /* voltage constraint */ /* create a new internal constraints and add it into the constraint list */ assert(etaux->node1 <= ckt->nMatrixSize); /* ignore the abnormal case */ if(ckt->theNodeArray[etaux->node1].stat != nNormal) continue; naux = &(ckt->theNodeArray[etaux->node1]); if(etaux->type == GT || etaux->type == GE ) { itaux = pgNewIntConst(GE,index++); sign = 1; } else if(etaux->type == LE || etaux->type == LS) { itaux = pgNewIntConst(GE,index++); sign = -1; } else{ sprintf(buf, "Invalid voltage constraint: v(%d).", etaux->node1); error_mesg(PARSE_ERROR,buf); continue; } paux = pgNewProductByNode(sign,1/(etaux->value+FTINY), naux); pgAddProduct(itaux,paux); pgAddNumConst(itaux, (-1)*sign); pgAddIntConst(&(ckt->NLPIntConstList),itaux); } if(etaux->topic == cWIDTH) { /* * Equivalence-width constraint * (1/(li*Ii))(Vi1-Vi2) - (1/(lj*Ij))*(Vj1-Vj2) = 0 */ if(etaux->type == EQ) { naux = &(ckt->theNodeArray[etaux->node1]); /* we only deal with equival width constraint here */ if(etaux->type != EQ ) { sprintf(buf, "Invalid width constraint: v(%d).", etaux->node1); error_mesg(PARSE_ERROR,buf); continue; } itaux = pgNewIntConst(EQ,index++); pgAddIntConst(&(ckt->NLPIntConstList),itaux); daux = pgFindBranchByName(ckt,etaux->bname1); assert(daux); cst = (daux->length*daux->current); if(daux->n1) { naux = &(ckt->theNodeArray[daux->n1]); paux = pgNewProductByNode(1, 1/cst,naux); pgAddProduct(itaux,paux); } if(daux->n2) { naux = &(ckt->theNodeArray[daux->n2]); paux = pgNewProductByNode(-1, 1/cst,naux); pgAddProduct(itaux,paux); } daux = pgFindBranchByName(ckt,etaux->bname2); assert(daux); cst = (daux->length*daux->current); if(daux->n1) { naux = &(ckt->theNodeArray[daux->n1]); paux = pgNewProductByNode(-1, 1/cst,naux); pgAddProduct(itaux,paux); } if(daux->n2) { naux = &(ckt->theNodeArray[daux->n2]); paux = pgNewProductByNode(1, 1/cst,naux); pgAddProduct(itaux,paux); } } } } }
void pgBuildVolLPConst(Circuit *ckt, ExtConst *ext_const) { long i,index = 1; ExtConst *etaux; IntConst *itaux; Nodes *naux; int sign; Products *paux; Branches *daux, *bch1 = NULL, *bch2=NULL; double cst; double vdrop; char pgiBname[128]; assert(ext_const); assert(ckt->theNodeArray); assert(ckt->theDeviceList); if(ckt->NLPIntConstList) { pgFreeIntConst(ckt->NLPIntConstList); ckt->NLPIntConstList = NULL; } for(i=0; i<=ckt->nMatrixSize; i++) { ckt->theNodeArray[i].coeff = 0.0; } /* * We then begin to build the constraints */ for(daux = ckt->theDeviceList; daux; daux = daux->next) { if(daux->stat != sNormal) continue; if(daux->type != dRES && daux->type != dVOL) continue; /* ignore branch with very small current */ /* if(fabs(daux->current) <= MIN_CURRENT || fabs(ckt->theNodeArray[daux->n1].voltage - ckt->theNodeArray[daux->n2].voltage) <= MIN_VOLTAGE ) { sprintf(buf,"branch %s: current or voltage drop is close to 0, ignored.\n", daux->name); print_mesg(buf); daux->stat = sAbnormal; continue; } */ /* * For power network, the power pin should be * restricted to the power supply voltage. */ if(daux->type == dVOL) { itaux = pgNewIntConst(EQ,index++); pgAddIntConst(&(ckt->NLPIntConstList),itaux); if(daux->n1) naux = &(ckt->theNodeArray[daux->n1]); else naux = &(ckt->theNodeArray[daux->n2]); paux = pgNewProductByNode(1, 1.0,naux); pgAddProduct(itaux,paux); pgAddNumConst(itaux,-daux->value); continue; } /* ignore branch with very small current */ assert(daux->n1 < (ckt->nMatrixSize+1)); assert(daux->n2 < (ckt->nMatrixSize+1)); daux->vdrop = ckt->theNodeArray[daux->n1].voltage - ckt->theNodeArray[daux->n2].voltage; if(fabs(daux->current) <= MIN_CURRENT || fabs(daux->vdrop) <= MIN_VOLTAGE ) { sprintf(buf,"branch %s: current or voltage close to 0, ignored.\n", daux->name); print_mesg(buf); daux->stat = sAbnormal; continue; } /* Compute the cost or objective function: calculate the * coefficient of each node voltage in the objective function. */ /* daux->vdrop = ckt->theNodeArray[daux->n1].voltage - ckt->theNodeArray[daux->n2].voltage; */ cst = -(daux->current*daux->length*daux->length* daux->lay->unitRes)/(daux->vdrop*daux->vdrop +FTINY); ckt->theNodeArray[daux->n1].coeff += cst; ckt->theNodeArray[daux->n2].coeff += -cst; /* * minimum width constraint: * -(Vi1 - Vi2)/I1 + Resistivity*Ii/Wmin >= 0 */ if(daux->current != 0.0 ) { itaux = pgNewIntConst(GE,index++); pgAddIntConst(&(ckt->NLPIntConstList),itaux); if(daux->n1) { naux = &(ckt->theNodeArray[daux->n1]); paux = pgNewProductByNode(-1, 1/(daux->current),naux); pgAddProduct(itaux,paux); } if(daux->n2) { naux = &(ckt->theNodeArray[daux->n2]); paux = pgNewProductByNode(1, 1/(daux->current),naux); pgAddProduct(itaux,paux); } cst = (daux->lay->unitRes*daux->length/ daux->lay->minWidth); pgAddNumConst(itaux,cst); /* * Linearizaton companion constraint: * (Vi1-Vi2)/(xi * (Vi1^0-Vi2^0)) -1 >= 0. */ itaux = pgNewIntConst(GE,index++); pgAddIntConst(&(ckt->NLPIntConstList),itaux); if(daux->n1) { naux = &(ckt->theNodeArray[daux->n1]); paux = pgNewProductByNode(1,1/((daux->vdrop+FTINY)*RestrFactor), naux); pgAddProduct(itaux,paux); } if(daux->n2) { naux = &(ckt->theNodeArray[daux->n2]); paux = pgNewProductByNode(-1,1/((daux->vdrop+FTINY)*RestrFactor), naux); pgAddProduct(itaux,paux); } pgAddNumConst(itaux,-1.0); } else { sprintf(buf,"%s(nonlinear): current=0, ignored.\n", daux->name); print_mesg(buf); } } for( etaux = ext_const; etaux; etaux = etaux->next ) { assert(etaux->node1 <= ckt->nMatrixSize); /* * Voltage IR drop constraint: * Vi >= Vmin or Vi <= Vmax */ if(etaux->topic == cVOL) { /* skip ground node which has 0 index */ if(etaux->node1 == 0) continue; /* ignore the abnormal case */ if(ckt->theNodeArray[etaux->node1].stat != nNormal) continue; if(ckt->theNodeArray[etaux->node1].coeff == 0.0) continue; naux = &(ckt->theNodeArray[etaux->node1]); if(etaux->type == GT || etaux->type == GE ) { itaux = pgNewIntConst(GE,index++); sign = 1; } else if(etaux->type == LE || etaux->type == LS) { itaux = pgNewIntConst(GE,index++); sign = -1; } else { sprintf(buf, "Invalid voltage constraint: v(%d).", etaux->node1); error_mesg(PARSE_ERROR,buf); continue; } paux = pgNewProductByNode(sign,1/(etaux->value+FTINY), naux); pgAddProduct(itaux,paux); pgAddNumConst(itaux, (-1)*sign); pgAddIntConst(&(ckt->NLPIntConstList),itaux); } /* * Equivalence-width constraint * 1/(li*Ii)(Vi1-Vi2) - 1/(lj*Ij)*(Vj1-Vj2) = 0 */ else if( etaux->topic == cWIDTH ) { naux = &(ckt->theNodeArray[etaux->node1]); /* we only deal with equivalence width constraint here */ if(etaux->type != EQ ) { sprintf(buf, "Invalid width constraint: v(%d).", etaux->node1); error_mesg(PARSE_ERROR,buf); continue; } itaux = pgNewIntConst(EQ,index++); pgAddIntConst(&(ckt->NLPIntConstList),itaux); daux = pgFindBranchByName(ckt, etaux->bname1); assert(daux); cst = (daux->length*daux->current); if(daux->n1) { naux = &(ckt->theNodeArray[daux->n1]); paux = pgNewProductByNode(1, 1/cst,naux); pgAddProduct(itaux,paux); } if(daux->n2) { naux = &(ckt->theNodeArray[daux->n2]); paux = pgNewProductByNode(-1, 1/cst,naux); pgAddProduct(itaux,paux); } daux = pgFindBranchByName(ckt,etaux->bname2); assert(daux); cst = (daux->length*daux->current); if(daux->n1) { naux = &(ckt->theNodeArray[daux->n1]); paux = pgNewProductByNode(-1, 1/cst,naux); pgAddProduct(itaux,paux); } if(daux->n2) { naux = &(ckt->theNodeArray[daux->n2]); paux = pgNewProductByNode(1, 1/cst,naux); pgAddProduct(itaux,paux); } } } /* node 0 is bounded to zero */ /* itaux = pgNewIntConst(LE,index++); pgAddIntConst(&(ckt->NLPIntConstList),itaux); paux = pgNewProductByNode(1, 1, &(ckt->theNodeArray[0])); pgAddProduct(itaux,paux); pgAddNumConst(itaux, 0); */ }