Ejemplo n.º 1
0
/*
 * SMPnewMatrix()
 */
int
SMPnewMatrix(SMPmatrix **pMatrix)
{
    int Error;
    *pMatrix = (SMPmatrix *)spCreate( 0, 1, &Error );
    return Error;
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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;
    }

}
Ejemplo n.º 4
0
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 {
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 7
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;
  }
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
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;
    
}