Пример #1
0
/*ARGSUSED*/
int
SMPluFac(SMPmatrix *Matrix, double PivTol, double Gmin)
{
    spSetReal( (void *)Matrix );
    LoadGmin( (void *)Matrix, Gmin );
    return spFactor( (void *)Matrix );
}
Пример #2
0
/*
 * SMPreorder()
 */
int
SMPreorder(SMPmatrix *Matrix, double PivTol, double PivRel, double Gmin)
{
    spSetReal( (void *)Matrix );
    LoadGmin( (void *)Matrix, Gmin );
    return spOrderAndFactor( (void *)Matrix, (spREAL*)NULL,
                             (spREAL)PivRel, (spREAL)PivTol, YES );
}
Пример #3
0
/*
 * SMPcombine()
 */
void
SMPcombine(SMPmatrix *Matrix, double RHS[], double Spare[])
{
    spSetReal( (void *)Matrix );
    spCombine( (void *)Matrix, RHS, Spare, (spREAL*)NULL, (spREAL*)NULL );
}
Пример #4
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;
  }
}
Пример #5
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;
}
Пример #6
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;
}
Пример #7
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;
    
}