/* * SMPnewMatrix() */ int SMPnewMatrix(SMPmatrix **pMatrix) { int Error; *pMatrix = (SMPmatrix *)spCreate( 0, 1, &Error ); return Error; }
void * M_MatrixNew_SP(Uint m, Uint n) { M_MatrixSP *A; int error; A = Malloc(sizeof(M_MatrixSP)); MMATRIX(A)->ops = &mMatOps_SP; A->d = spCreate(0, 0, &error); MROWS(A) = m; MCOLS(A) = n; return (A); }
void C2F(lufact1)(double *val, int *lln, int *col, int *n, int *nel, int *fmatindex, double *eps, double *releps, int *nrank, int *ierr) { int error, i, i0, i1, k, j; char *fmat; spREAL *pelement; *ierr = 0; fmat = spCreate(*n, 0, &error); if (error != spOKAY) { *ierr = 1; return; } *fmatindex = addluptr (fmat); if ( *fmatindex == -1) { *ierr = 1; return; } i0 = 0; i1 = i0; i = 1; for (k = 0 ; k < *nel; k++) { i0 = i0 + 1; while (i0 - i1 > lln[i - 1]) { i1 = i0; i = i + 1; i0 = i0 + 1; } j = col[k]; pelement = spGetElement(fmat, i, j); if (pelement == 0) { *ierr = 2; return; } spADD_REAL_ELEMENT(pelement, (spREAL)(val[k])); } /* Fix the AbsThresold with scilex %eps */ spFixThresold(fmat, *eps, *releps); /* spPrint((char *) *fmat,1,1,1); */ error = spFactor(fmat); spGetNumRank(fmat, nrank); switch (error) { case spZERO_DIAG: Scierror(999, _("%s: A zero was encountered on the diagonal the matrix.\n"), "zero_diag"); break; case spNO_MEMORY: *ierr = 3; break; case spSINGULAR: *ierr = -1; /*Singular matrix" */ break; case spSMALL_PIVOT: *ierr = -2; /* matrix is singular at precision level */ break; } }
int sens_sens(CKTcircuit *ckt, int restart) { SENS_AN *sen_info = ((SENS_AN *) ckt->CKTcurJob); static int size; static double *delta_I, *delta_iI, *delta_I_delta_Y, *delta_iI_delta_Y; sgen *sg; static double freq; static int nfreqs; static int i; static SMPmatrix *delta_Y = NULL, *Y; static double step_size; double *E, *iE; IFvalue value, nvalue; double *output_values; IFcomplex *output_cvalues; double delta_var; int (*fn)( ); static int is_dc; int k, j, n; int num_vars, branch_eq; char *sen_data; char namebuf[513]; IFuid *output_names, freq_name; int bypass; int type; #ifndef notdef double *save_states[8]; #ifdef notdef for (sg = sgen_init(ckt, 0); sg; sgen_next(&sg)) { if (sg->is_instparam) printf("%s:%s:%s -> param %s\n", DEVices[sg->dev]->DEVpublic.name, sg->model->GENmodName, sg->instance->GENname, sg->ptable[sg->param].keyword); else printf("%s:%s:%s -> mparam %s\n", DEVices[sg->dev]->DEVpublic.name, sg->model->GENmodName, sg->instance->GENname, sg->ptable[sg->param].keyword); } #endif #ifdef ASDEBUG DEBUG(1) printf(">>> restart : %d\n", restart); #endif /* get to work */ restart = 1; if (restart) { freq = 0.0; is_dc = (sen_info->step_type == SENS_DC); nfreqs = count_steps(sen_info->step_type, sen_info->start_freq, sen_info->stop_freq, sen_info->n_freq_steps, &step_size); if (!is_dc) freq = sen_info->start_freq; error = CKTop(ckt, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, ckt->CKTdcMaxIter); #ifdef notdef ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG; #endif if (error) return error; size = spGetSize(ckt->CKTmatrix, 1); /* Create the perturbation matrix */ /* XXX check error return, '1' is complex -- necessary? * only in ac */ delta_Y = spCreate(size, !is_dc, &error); size += 1; /* Create an extra rhs */ delta_I = NEWN(double, size); delta_iI = NEWN(double, size); delta_I_delta_Y = NEWN(double, size); delta_iI_delta_Y = NEWN(double, size); num_vars = 0; for (sg = sgen_init(ckt, is_dc); sg; sgen_next(&sg)) { num_vars += 1; } if (!num_vars) return OK; /* XXXX Should be E_ something */ k = 0; output_names = NEWN(IFuid, num_vars); for (sg = sgen_init(ckt, is_dc); sg; sgen_next(&sg)) { if (!sg->is_instparam) { sprintf(namebuf, "%s:%s", sg->instance->GENname, sg->ptable[sg->param].keyword); } else if ((sg->ptable[sg->param].dataType & IF_PRINCIPAL) && sg->is_principle == 1) { sprintf(namebuf, "%s", sg->instance->GENname); } else { sprintf(namebuf, "%s_%s", sg->instance->GENname, sg->ptable[sg->param].keyword); } (*SPfrontEnd->IFnewUid)((GENERIC *) ckt, output_names + k, NULL, namebuf, UID_OTHER, NULL); k += 1; } if (is_dc) { type = IF_REAL; freq_name = NULL; } else { type = IF_COMPLEX; (*SPfrontEnd->IFnewUid)((GENERIC *) ckt, &freq_name, NULL, "frequency", UID_OTHER, NULL); } error = (*SPfrontEnd->OUTpBeginPlot)((GENERIC *) ckt, (GENERIC *) ckt->CKTcurJob, ckt->CKTcurJob->JOBname, freq_name, IF_REAL, num_vars, output_names, type, (GENERIC **) &sen_data); if (error) return error; FREE(output_names); if (is_dc) { output_values = NEWN(double, num_vars); output_cvalues = NULL; } else { output_values = NULL; output_cvalues = NEWN(IFcomplex, num_vars); if (sen_info->step_type != SENS_LINEAR) (*(SPfrontEnd->OUTattributes))((GENERIC *)sen_data, NULL, OUT_SCALE_LOG, NULL); } } else {
int main (int argc, char **argv) { int ch; int errflg=0,i,j; double l,c,ctot,r=0.0,g=0.0,k=0.0,lm=0.0,cm=0.0,len; unsigned gotl=0,gotc=0,gotr=0,gotg=0,gotk=0,gotcm=0,gotlen=0; unsigned gotname=0, gotnum=0; char *name = ""; double **matrix, **inverse; double *tpeigenvalues, *gammaj; char *options; int num, node; char **pname, *s; int use_opt; char *optarg; pname = argv; argv++; argc--; ch = 0; while (argc > 0) { s = *argv++; argc--; while ((ch = *s++)) { if (*s) optarg = s; else if (argc) optarg = *argv; else optarg = NULL; use_opt = 0; switch (ch) { case 'o': name = (char *) tmalloc((unsigned) (strlen(optarg)*sizeof(char))); (void) strcpy(name,optarg); gotname=1; use_opt = 1; break; case 'l': sscanf(optarg,"%lf",&l); gotl=1; use_opt = 1; break; case 'c': sscanf(optarg,"%lf",&c); gotc=1; use_opt = 1; break; case 'r': sscanf(optarg,"%lf",&r); use_opt = 1; gotr=1; break; case 'g': sscanf(optarg,"%lf",&g); use_opt = 1; gotg=1; break; case 'k': sscanf(optarg,"%lf",&k); use_opt = 1; gotk=1; break; case 'x': sscanf(optarg,"%lf",&cm); use_opt = 1; gotcm=1; break; case 'L': sscanf(optarg,"%lf",&len); use_opt = 1; gotlen=1; break; case 'n': sscanf(optarg,"%d",&num); use_opt = 1; gotnum=1; break; case 'h': usage(pname); exit(1); break; case '-': break; default: usage(pname); exit(2); break; } if (use_opt) { if (optarg == s) s += strlen(s); else if (optarg) { argc--; argv++; } } } } if (errflg) { usage(argv); exit (2); } if (gotl + gotc + gotname + gotnum + gotlen < 5) { fprintf(stderr,"l, c, model_name, number_of_conductors and length must be specified.\n"); fprintf(stderr,"%s -u for details.\n",pname[0]); fflush(stdout); exit(1); } if ( (k<0.0?-k:k) >=1.0 ) { fprintf(stderr,"Error: |k| must be less than 1.0\n"); fflush(stderr); exit(1); } if (num == 1) { fprintf(stdout,"* single conductor line\n"); fflush(stdout); exit(1); } lm = l*k; switch(num) { case 1: ctot = c; break; case 2: ctot = c + cm; break; default: ctot = c + 2*cm; break; } comments(r,l,g,c,ctot,cm,lm,k,name,num,len); matrix = (double **) tmalloc((unsigned) (sizeof(double*)*(num+1))); inverse = (double **) tmalloc((unsigned) (sizeof(double*)*(num+1))); tpeigenvalues = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); for (i=1;i<=num;i++) { matrix[i] = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); inverse[i] = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); } for (i=1;i<=num;i++) { tpeigenvalues[i] = -2.0 * cos(M_PI*i/(num+1)); } for (i=1;i<=num;i++) { for (j=1;j<=num;j++) { matrix[i][j] = phi(i-1,tpeigenvalues[j]); } } gammaj = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); for (j=1;j<=num;j++) { gammaj[j] = 0.0; for (i=1;i<=num;i++) { gammaj[j] += matrix[i][j] * matrix[i][j]; } gammaj[j] = sqrt(gammaj[j]); } for (j=1;j<=num;j++) { for (i=1;i<=num; i++) { matrix[i][j] /= gammaj[j]; } } tfree(gammaj); /* matrix = M set up */ { MatrixPtr othermatrix; double *rhs, *solution; double *irhs, *isolution; int errflg, err, singular_row, singular_col; double *elptr; rhs = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); irhs = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); solution = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); isolution = (double *) tmalloc((unsigned) (sizeof(double)*(num+1))); othermatrix = spCreate(num,0,&errflg); for (i=1;i<=num;i++) { for (j=1; j<=num; j++) { elptr = spGetElement(othermatrix,i,j); *elptr = matrix[i][j]; } } #ifdef DEBUG_LEVEL1 (void) spPrint(othermatrix,0,1,0); #endif for (i=1;i<=num;i++) rhs[i] = 0.0; rhs[1]=1.0; err = spOrderAndFactor(othermatrix,rhs,THRSH,ABS_THRSH,DIAG_PIVOTING); spErrorMessage(othermatrix,stderr,NULL); switch(err) { case spNO_MEMORY: fprintf(stderr,"No memory in spOrderAndFactor\n"); fflush(stderr); exit(1); case spSINGULAR: (void) spWhereSingular(othermatrix,&singular_row,&singular_col); fprintf(stderr,"Singular matrix: problem in row %d and col %d\n", singular_row, singular_col); fflush(stderr); exit(1); default: break; } for (i=1;i<=num;i++) { for (j=1;j<=num;j++) { rhs[j] = (j==i?1.0:0.0); irhs[j] = 0.0; } (void) spSolveTransposed(othermatrix,rhs,solution, irhs, isolution); for (j=1;j<=num;j++) { inverse[i][j] = solution[j]; } } tfree(rhs); tfree(solution); } /* inverse = M^{-1} set up */ fprintf(stdout,"\n"); fprintf(stdout,"* Lossy line models\n"); options = (char *) tmalloc((unsigned) 256); (void) strcpy(options,"rel=1.2 nocontrol"); for (i=1;i<=num;i++) { fprintf(stdout,".model mod%d_%s ltra %s r=%0.12g l=%0.12g g=%0.12g c=%0.12g len=%0.12g\n", i,name,options,r,l+tpeigenvalues[i]*lm,g,ctot-tpeigenvalues[i]*cm,len); /*i,name,options,r,l+tpeigenvalues[i]*lm,g,ctot+tpeigenvalues[i]*cm,len);*/ } fprintf(stdout,"\n"); fprintf(stdout,"* subcircuit m_%s - modal transformation network for %s\n",name,name); fprintf(stdout,".subckt m_%s", name); for (i=1;i<= 2*num; i++) { fprintf(stdout," %d",i); } fprintf(stdout,"\n"); for (j=1;j<=num;j++) fprintf(stdout,"v%d %d 0 0v\n",j,j+2*num); for (j=1;j<=num;j++) { for (i=1; i<=num; i++) { fprintf(stdout,"f%d 0 %d v%d %0.12g\n", (j-1)*num+i,num+j,i,inverse[j][i]); } } node = 3*num+1; for (j=1;j<=num;j++) { fprintf(stdout,"e%d %d %d %d 0 %0.12g\n", (j-1)*num+1, node, 2*num+j, num+1, matrix[j][1]); node++; for (i=2; i<num; i++) { fprintf(stdout,"e%d %d %d %d 0 %0.12g\n", (j-1)*num+i, node,node-1,num+i,matrix[j][i]); node++; } fprintf(stdout,"e%d %d %d %d 0 %0.12g\n", j*num,j,node-1, 2*num,matrix[j][num]); } fprintf(stdout,".ends m_%s\n",name); fprintf(stdout,"\n"); fprintf(stdout,"* Subckt %s\n", name); fprintf(stdout,".subckt %s",name); for (i=1;i<=2*num;i++) { fprintf(stdout," %d",i); } fprintf(stdout,"\n"); fprintf(stdout,"x1"); for (i=1;i<=num;i++) fprintf(stdout," %d", i); for (i=1;i<=num;i++) fprintf(stdout," %d", 2*num+i); fprintf(stdout," m_%s\n",name); for (i=1;i<=num;i++) fprintf(stdout,"o%d %d 0 %d 0 mod%d_%s\n",i,2*num+i,3*num+i,i,name); fprintf(stdout,"x2"); for (i=1;i<=num;i++) fprintf(stdout," %d", num+i); for (i=1;i<=num;i++) fprintf(stdout," %d", 3*num+i); fprintf(stdout," m_%s\n",name); fprintf(stdout,".ends %s\n",name); tfree(tpeigenvalues); for (i=1;i<=num;i++) { tfree(matrix[i]); tfree(inverse[i]); } tfree(matrix); tfree(inverse); tfree(name); tfree(options); return EXIT_NORMAL; }
int pgBuildMNAEquation(Circuit *ckt) { char *matrix; char *pstr; FILE *fp; char line[1024]; int error; char cValue[128]; double dValue; int n1, n2; struct spTemplate sTemplate; Branches *daux; assert(ckt->theDeviceList); theMatrix = spCreate(1, 0, &error); spClear(theMatrix); theRhs = (double *)malloc((ckt->nMatrixSize + 1) * sizeof(double)); theSol = (double *)malloc((ckt->nMatrixSize + 1) * sizeof(double)); /* initialization */ memset(theRhs, 0, (ckt->nMatrixSize + 1)*sizeof(double)); memset(theSol, 0, (ckt->nMatrixSize + 1)*sizeof(double)); for( daux= ckt->theDeviceList; daux; daux = daux->next ) { if(daux->stat == sAbnormal) continue; switch(daux->type) { case dRES: /* resistor */ error = spGetAdmittance(theMatrix, daux->n1, daux->n2, &sTemplate); if(error != spOKAY) return -1; dValue = 1/daux->value; /* printf("admittance: %lf.\n",dValue); */ spADD_REAL_QUAD(sTemplate, dValue); break; case dCUR: /* independent current source */ /* printf("current source: %g.\n",daux->value); */ /* the current direction is from n1 to n2 */ if(daux->n1 != 0) theRhs[daux->n1] -= daux->value; if(daux->n2 !=0) theRhs[daux->n2] += daux->value; break; case dVOL: /* independent voltage source */ /* printf("voltage source: %g.\n",daux->value); */ /* n1: positive, n2: negative */ if(daux->vn != 0) theRhs[daux->vn] = daux->value; error = spGetOnes(theMatrix, daux->n1, daux->n2, daux->vn, &sTemplate); if(error != spOKAY) return -1; /* spADD_REAL_QUAD(sTemplate, 1); */ break; default: sprintf(buf, "Unknow device type: %s.", pstr); error_mesg(INT_ERROR,buf); break; } } return 0; }
/* the equilibrium solution is taken as an initial guess */ void TWObiasSolve(TWOdevice *pDevice, int iterationLimit, BOOLEAN tranAnalysis, TWOtranInfo *info) { BOOLEAN newSolver = FALSE; int error; int index, eIndex; TWOelem *pElem; TWOnode *pNode; double refPsi; double startTime, setupTime, miscTime; setupTime = miscTime = 0.0; /* SETUP */ startTime = SPfrontEnd->IFseconds(); switch (pDevice->solverType) { case SLV_EQUIL: /* free up the vectors allocated in the equilibrium solution */ FREE(pDevice->dcSolution); FREE(pDevice->dcDeltaSolution); FREE(pDevice->copiedSolution); FREE(pDevice->rhs); spDestroy(pDevice->matrix); case SLV_NONE: pDevice->poissonOnly = FALSE; pDevice->numEqns = pDevice->dimBias - 1; XCALLOC(pDevice->dcSolution, double, pDevice->dimBias); XCALLOC(pDevice->dcDeltaSolution, double, pDevice->dimBias); XCALLOC(pDevice->copiedSolution, double, pDevice->dimBias); XCALLOC(pDevice->rhs, double, pDevice->dimBias); XCALLOC(pDevice->rhsImag, double, pDevice->dimBias); pDevice->matrix = spCreate(pDevice->numEqns, 1, &error); if (error == spNO_MEMORY) { printf("TWObiasSolve: Out of Memory\n"); exit(-1); } newSolver = TRUE; if (!OneCarrier) { TWO_jacBuild(pDevice); } else if (OneCarrier == N_TYPE) { TWONjacBuild(pDevice); } else if (OneCarrier == P_TYPE) { TWOPjacBuild(pDevice); } pDevice->numOrigBias = spElementCount(pDevice->matrix); pDevice->numFillBias = 0; TWOstoreInitialGuess(pDevice); case SLV_SMSIG: spSetReal(pDevice->matrix); case SLV_BIAS: pDevice->solverType = SLV_BIAS; break; default: fprintf(stderr, "Panic: Unknown solver type in bias solution.\n"); exit(-1); break; } setupTime += SPfrontEnd->IFseconds() - startTime; /* SOLVE */ TWOdcSolve(pDevice, iterationLimit, newSolver, tranAnalysis, info); /* MISCELLANEOUS */ startTime = SPfrontEnd->IFseconds(); if (newSolver) { pDevice->numFillBias = spFillinCount(pDevice->matrix); } if ((!pDevice->converged) && iterationLimit > 1) { printf("TWObiasSolve: No Convergence\n"); } else if (pDevice->converged) { /* update the nodal quantities */ for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) { pElem = pDevice->elements[eIndex]; refPsi = pElem->matlInfo->refPsi; for (index = 0; index <= 3; index++) { if (pElem->evalNodes[index]) { pNode = pElem->pNodes[index]; if (pNode->nodeType != CONTACT) { pNode->psi = pDevice->dcSolution[pNode->psiEqn]; if (pElem->elemType == SEMICON) { if (!OneCarrier) { pNode->nConc = pDevice->dcSolution[pNode->nEqn]; pNode->pConc = pDevice->dcSolution[pNode->pEqn]; } else if (OneCarrier == N_TYPE) { pNode->nConc = pDevice->dcSolution[pNode->nEqn]; pNode->pConc = pNode->nie * exp(-pNode->psi + refPsi); } else if (OneCarrier == P_TYPE) { pNode->pConc = pDevice->dcSolution[pNode->pEqn]; pNode->nConc = pNode->nie * exp(pNode->psi - refPsi); } } } } } } /* update the current terms */ if (!OneCarrier) { TWO_commonTerms(pDevice, FALSE, tranAnalysis, info); } else if (OneCarrier == N_TYPE) { TWONcommonTerms(pDevice, FALSE, tranAnalysis, info); } else if (OneCarrier == P_TYPE) { TWOPcommonTerms(pDevice, FALSE, tranAnalysis, info); } } else if (iterationLimit <= 1) { for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) { pElem = pDevice->elements[eIndex]; refPsi = pElem->matlInfo->refPsi; for (index = 0; index <= 3; index++) { if (pElem->evalNodes[index]) { pNode = pElem->pNodes[index]; if (pNode->nodeType != CONTACT) { pNode->psi = pDevice->dcSolution[pNode->psiEqn]; pDevice->devState0 [pNode->nodePsi] = pNode->psi; if (pElem->elemType == SEMICON) { if (!OneCarrier) { pNode->nConc = pDevice->dcSolution[pNode->nEqn]; pNode->pConc = pDevice->dcSolution[pNode->pEqn]; } else if (OneCarrier == N_TYPE) { pNode->nConc = pDevice->dcSolution[pNode->nEqn]; pNode->pConc = pNode->nie * exp(-pNode->psi + refPsi); } else if (OneCarrier == P_TYPE) { pNode->pConc = pDevice->dcSolution[pNode->pEqn]; pNode->nConc = pNode->nie * exp(pNode->psi - refPsi); } pDevice->devState0 [pNode->nodeN] = pNode->nConc; pDevice->devState0 [pNode->nodeP] = pNode->pConc; } } } } } } miscTime += SPfrontEnd->IFseconds() - startTime; if (tranAnalysis) { pDevice->pStats->setupTime[STAT_TRAN] += setupTime; pDevice->pStats->miscTime[STAT_TRAN] += miscTime; } else { pDevice->pStats->setupTime[STAT_DC] += setupTime; pDevice->pStats->miscTime[STAT_DC] += miscTime; } }
void TWOequilSolve(TWOdevice *pDevice) { BOOLEAN newSolver = FALSE; int error; int nIndex, eIndex; TWOelem *pElem; TWOnode *pNode; double startTime, setupTime, miscTime; setupTime = miscTime = 0.0; /* SETUP */ startTime = SPfrontEnd->IFseconds(); switch (pDevice->solverType) { case SLV_SMSIG: case SLV_BIAS: /* free up memory allocated for the bias solution */ FREE(pDevice->dcSolution); FREE(pDevice->dcDeltaSolution); FREE(pDevice->copiedSolution); FREE(pDevice->rhs); FREE(pDevice->rhsImag); spDestroy(pDevice->matrix); case SLV_NONE: pDevice->poissonOnly = TRUE; pDevice->numEqns = pDevice->dimEquil - 1; XCALLOC(pDevice->dcSolution, double, pDevice->dimEquil); XCALLOC(pDevice->dcDeltaSolution, double, pDevice->dimEquil); XCALLOC(pDevice->copiedSolution, double, pDevice->dimEquil); XCALLOC(pDevice->rhs, double, pDevice->dimEquil); pDevice->matrix = spCreate(pDevice->numEqns, 0, &error); if (error == spNO_MEMORY) { printf("TWOequilSolve: Out of Memory\n"); exit(-1); } newSolver = TRUE; spSetReal(pDevice->matrix); TWOQjacBuild(pDevice); pDevice->numOrigEquil = spElementCount(pDevice->matrix); pDevice->numFillEquil = 0; case SLV_EQUIL: pDevice->solverType = SLV_EQUIL; break; default: fprintf(stderr, "Panic: Unknown solver type in equil solution.\n"); exit(-1); break; } TWOstoreNeutralGuess(pDevice); setupTime += SPfrontEnd->IFseconds() - startTime; /* SOLVE */ TWOdcSolve(pDevice, MaxIterations, newSolver, FALSE, NULL); /* MISCELLANEOUS */ startTime = SPfrontEnd->IFseconds(); if (newSolver) { pDevice->numFillEquil = spFillinCount(pDevice->matrix); } if (pDevice->converged) { TWOQcommonTerms(pDevice); /* save equilibrium potential */ for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) { pElem = pDevice->elements[eIndex]; for (nIndex = 0; nIndex <= 3; nIndex++) { if (pElem->evalNodes[nIndex]) { pNode = pElem->pNodes[nIndex]; pNode->psi0 = pNode->psi; } } } } else { printf("TWOequilSolve: No Convergence\n"); } miscTime += SPfrontEnd->IFseconds() - startTime; pDevice->pStats->setupTime[STAT_SETUP] += setupTime; pDevice->pStats->miscTime[STAT_SETUP] += miscTime; }
int StanfordSolveSparseMatrix(Kentry* Kentries, double b[], int numUniqueEntries, int size, double soln[]) { int i; int row; int col; double value; spMatrix A; spError err, Error; spREAL AbsThreshold,RelThreshold; spREAL *pElement; #ifdef REALLY_OUTPUT_A_WHOLE_BUNCH FILE *fp; fp = NULL; fp = fopen("nonzero-inside-solver-call","w"); fprintf(fp,"title goes here (%i nonzero)\n",numUniqueEntries); fprintf(fp,"%i real\n",size); for (i = 0; i < numUniqueEntries; i++) { /* we add 1 to row and col numbers for sparse */ fprintf(fp,"%i %i %lf\n",Kentries[i].row+SPARSE_OFFSET,Kentries[i].col+SPARSE_OFFSET, Kentries[i].value); } fprintf(fp,"0 0 0.0\n"); for (i = 0; i < size; i++) { fprintf(fp,"%lf\n",b[i+SPARSE_OFFSET]); } fclose(fp); #endif /* create the matrix */ debugprint(stddbg," allocate A matrix.\n"); fflush(stdout); A = spCreate(size, 0, &err); if( err >= spFATAL || A == NULL) { fprintf(stderr,"error allocating matrix.\n"); exit(-1); } for (i = 0; i < numUniqueEntries; i++) { if (!(i % (int)(numUniqueEntries/50.0))) { debugprint(stddbg,"inserting into A: %i of %i\n",i,numUniqueEntries); } row = Kentries[i].row+SPARSE_OFFSET; col = Kentries[i].col+SPARSE_OFFSET; value = Kentries[i].value; pElement = spGetElement(A,row,col); if (pElement == NULL) { fprintf(stderr, "error: insufficient memory available.\n"); exit(-1); } *pElement = value; } debugprint(stddbg," free memory for Kentries\n"); deleteKentries(Kentries); spSetReal( A ); #if MODIFIED_NODAL spMNA_Preorder( A ); #endif RelThreshold = 0; AbsThreshold = 0; debugprint(stddbg," order and factor matrix.\n"); Error = spOrderAndFactor( A, b, RelThreshold, AbsThreshold, 1 ); if ( Error >= spFATAL ) { fprintf(stdout,"Fatal error (%i)\n",Error); exit(-1); } /* spPrint( A,1,1,1); */ for (i = 0; i <= size; i++) { soln[0] = 0; } debugprint(stddbg," call spSolve.\n"); spSolve( A, b, soln); debugprint(stddbg," destroy A.\n"); spDestroy(A); return 0; }
int main(int argc, char* argv[]) { int i; char title[1024]; char line[1024]; int size; int row; int col; double value; spMatrix A; spREAL x[4096]; spREAL b[4096]; spError err, Error; spREAL AbsThreshold,RelThreshold; spREAL *pElement; FILE *fp = NULL; if (argc != 2) { fprintf(stderr,"usage: sptest <matrix_filename>\n"); exit(-1); } fprintf(stdout,"Reading file [%s]\n",argv[1]); if ((fp = fopen(argv[1],"r")) == NULL) { fprintf(stderr,"Error opening file [%s]\n",argv[1]); exit(-1); } title[0]='\0'; fgets(title,1024,fp); fgets(line,1024,fp); if (sscanf(line,"%i real",&size) != 1) { fprintf(stderr,"Error reading size.\n"); exit(-1); } // create the matrix A = spCreate(size, 0, &err); if( err >= spFATAL || A == NULL) { fprintf(stderr,"error allocating matrix.\n"); exit(-1); } while (0 == 0) { line[0]='\0'; fgets(line,1024,fp); if (sscanf(line,"%i %i %lf",&row,&col,&value) != 3) { fprintf(stderr,"Error reading matrix.\n"); exit(-1); } if (row == 0 && col == 0) break; //spElement *pElement; pElement = spGetElement(A,row,col); if (pElement == NULL) { fprintf(stderr, "error: insufficient memory available.\n"); exit(-1); } *pElement = value; pElement = spGetElement(A,row,col); } b[0] = 0; for (i = 1; i <= size; i++) { line[0]='\0'; fgets(line,1024,fp); if (sscanf(line,"%lf",&value) != 1) { fprintf(stderr,"Error reading RHS.\n"); exit(-1); } b[i] = value; } spSetReal( A ); /*spPrint( A,1,1,1);*/ #if MODIFIED_NODAL spMNA_Preorder( A ); #endif RelThreshold = 0; AbsThreshold = 0; Error = spOrderAndFactor( A, b, RelThreshold, AbsThreshold, 1 ); if ( Error >= spFATAL ) { fprintf(stdout,"Fatal error (%i)\n",Error); exit(-1); } /*spPrint( A,1,1,1);*/ for (i = 0; i <= size; i++) { x[0] = 0; } spSolve( A, b, x); /* Print the Solution. */ for (i = 1; i <= size; i++) { fprintf(stdout,"diplacement[%i] = %lg\n",i,x[i]); } spDestroy(A); return 0; }