コード例 #1
0
// Matrix and Residual Fills
bool
Pitchfork_FiniteElementProblem::evaluate(FillType f,
                     const Epetra_Vector* soln,
                     Epetra_Vector* tmp_rhs,
                     Epetra_RowMatrix* tmp_matrix,
                     double jac_coeff,
                     double mass_coeff)
{
  flag = f;

  // Set the incoming linear objects
  if (flag == F_ONLY) {
    rhs = tmp_rhs;
  } else if (flag == MATRIX_ONLY) {
    A = dynamic_cast<Epetra_CrsMatrix*> (tmp_matrix);
    assert(A != NULL);
  } else if (flag == ALL) {
    rhs = tmp_rhs;
    A = dynamic_cast<Epetra_CrsMatrix*> (tmp_matrix);
    assert(A != NULL);
  } else {
    std::cout << "ERROR: Pitchfork_FiniteElementProblem::fillMatrix() - FillType flag is broken" << std::endl;
    throw;
  }

  // Create the overlapped solution and position vectors
  Epetra_Vector u(*OverlapMap);
  Epetra_Vector x(*OverlapMap);

  // Export Solution to Overlap vector
  u.Import(*soln, *Importer, Insert);

  // Declare required variables
  int i,j,ierr;
  int OverlapNumMyElements = OverlapMap->NumMyElements();

  int OverlapMinMyGID;
  if (MyPID==0) OverlapMinMyGID = StandardMap->MinMyGID();
  else OverlapMinMyGID = StandardMap->MinMyGID()-1;

  int row, column;
  double jac;
  double xx[2];
  double uu[2];
  Basis basis;

  // Create the nodal coordinates
  double Length=2.0;
  double dx=Length/((double) NumGlobalElements-1);
  for (i=0; i < OverlapNumMyElements; i++) {
    x[i]=-1.0 + dx*((double) OverlapMinMyGID+i);
  }

  // Zero out the objects that will be filled
  if ((flag == MATRIX_ONLY) || (flag == ALL)) {
    i = A->PutScalar(0.0);
    assert(i == 0);
  }
  if ((flag == F_ONLY)    || (flag == ALL)) {
    i = rhs->PutScalar(0.0);
    assert(i == 0);
  }

  // Loop Over # of Finite Elements on Processor
  for (int ne=0; ne < OverlapNumMyElements-1; ne++) {

    // Loop Over Gauss Points
    for(int gp=0; gp < 2; gp++) {
      // Get the solution and coordinates at the nodes
      xx[0]=x[ne];
      xx[1]=x[ne+1];
      uu[0]=u[ne];
      uu[1]=u[ne+1];
      // Calculate the basis function at the gauss point
      basis.getBasis(gp, xx, uu);

      // Loop over Nodes in Element
      for (i=0; i< 2; i++) {
    row=OverlapMap->GID(ne+i);
    //printf("Proc=%d GlobalRow=%d LocalRow=%d Owned=%d\n",
    //     MyPID, row, ne+i,StandardMap.MyGID(row));
    if (StandardMap->MyGID(row)) {
      if ((flag == F_ONLY)    || (flag == ALL)) {
        (*rhs)[StandardMap->LID(OverlapMap->GID(ne+i))]+=
          +basis.wt*basis.dx
          *((-1.0/(basis.dx*basis.dx))*basis.duu*
        basis.dphide[i]-source_term(basis.uu)*basis.phi[i]);
      }
    }
    // Loop over Trial Functions
    if ((flag == MATRIX_ONLY) || (flag == ALL)) {
      for(j=0;j < 2; j++) {
        if (StandardMap->MyGID(row)) {
          column=OverlapMap->GID(ne+j);
          jac=jac_coeff*basis.wt*basis.dx*
        ((-1.0/(basis.dx*basis.dx))*basis.dphide[j]*basis.dphide[i]
         -source_deriv(basis.uu)*basis.phi[j]*basis.phi[i]) +
        mass_coeff*basis.wt*basis.dx*basis.phi[j]*basis.phi[i];
          ierr=A->SumIntoGlobalValues(row, 1, &jac, &column);
          assert(ierr == 0);
        }
      }
    }
      }
    }
  }

  // Insert Boundary Conditions and modify Jacobian and function (F)
  // U(-1)=beta
  if (MyPID==0) {
    if ((flag == F_ONLY)    || (flag == ALL))
      (*rhs)[0]= (*soln)[0] - beta;
    if ((flag == MATRIX_ONLY) || (flag == ALL)) {
      column=0;
      jac=1.0*jac_coeff;
      A->ReplaceGlobalValues(0, 1, &jac, &column);
      column=1;
      jac=0.0*jac_coeff;
      A->ReplaceGlobalValues(0, 1, &jac, &column);
    }
  }

  // U(1)=beta
  if ( StandardMap->LID(StandardMap->MaxAllGID()) >= 0 ) {
    int lastDof = StandardMap->LID(StandardMap->MaxAllGID());
    if ((flag == F_ONLY)    || (flag == ALL))
       (*rhs)[lastDof] = (*soln)[lastDof] - beta;
    if ((flag == MATRIX_ONLY) || (flag == ALL)) {
       int row = StandardMap->MaxAllGID();
       column = row;
       jac=1.0*jac_coeff;
       A->ReplaceGlobalValues(row, 1, &jac, &column);
       column=row-1;
       jac=0.0*jac_coeff;
       A->ReplaceGlobalValues(row, 1, &jac, &column);
    }
  }
  // Sync up processors to be safe
  Comm->Barrier();

  A->FillComplete();

  return true;
}
コード例 #2
0
ファイル: ConvDiff_PDE.C プロジェクト: gitter-badger/quinoa
// A fill specialized to the single node at the coupling interface
void 
ConvDiff_PDE::computeHeatFlux( const Epetra_Vector * soln )
{
  
  int numDep = depProblems.size();

  // Create the overlapped solution and position vectors
  Epetra_Vector u(*OverlapMap);
  Epetra_Vector uold(*OverlapMap);
  std::vector<Epetra_Vector*> dep(numDep);
  for( int i = 0; i < numDep; ++i)
    dep[i] = new Epetra_Vector(*OverlapMap);

  Epetra_Vector xvec(*OverlapMap);

  // Export Solution to Overlap vector
  // If the vector to be used in the fill is already in the Overlap form,
  // we simply need to map on-processor from column-space indices to
  // OverlapMap indices. Note that the old solution is simply fixed data that
  // needs to be sent to an OverlapMap (ghosted) vector.  The conditional
  // treatment for the current soution vector arises from use of
  // FD coloring in parallel.

  uold.Import(*oldSolution, *Importer, Insert);

  for( int i = 0; i < numDep; ++i )
    (*dep[i]).Import(*( (*(depSolutions.find(depProblems[i]))).second ), *Importer, Insert);

  xvec.Import(*xptr, *Importer, Insert);

  if( NULL == soln )
    u.Import(*initialSolution, *Importer, Insert);
  else
    u.Import(*soln, *Importer, Insert);

  // Declare required variables
  int row;
  double * xx = new double[2];
  double * uu = new double[2]; 
  double * uuold = new double[2];
  std::vector<double*> ddep(numDep);
  for( int i = 0; i < numDep; ++i)
    ddep[i] = new double[2];

  Basis basis;

  // Bundle up the dependent variables in the way needed for computing
  // the source terms of each reaction
  map<string, double*> depVars;
  depVars.insert( pair< std::string, double*>(getName(), uu) );
  for( int i = 0; i < numDep; ++i )
    depVars.insert( pair<string, double*>(myManager->getProblemName(depProblems[i]), ddep[i]) );

  myFlux = 0.0;

  // Loop Over Gauss Points
  for( int gp = 0; gp < 2; ++gp ) 
  {
    // Get the solution and coordinates at the nodes 
    xx[0]=xvec[interface_elem];
    xx[1]=xvec[interface_elem+1];
    uu[0] = u[interface_elem];
    uu[1] = u[interface_elem+1];
    uuold[0] = uold[interface_elem];
    uuold[1] = uold[interface_elem+1];
    for( int i = 0; i < numDep; ++i ) 
    {
      ddep[i][0] = (*dep[i])[interface_elem];
      ddep[i][1] = (*dep[i])[interface_elem+1];
    }

    // Calculate the basis function and variables at the gauss points
    basis.getBasis(gp, xx, uu, uuold, ddep);

    row = OverlapMap->GID( interface_elem + local_node );

    if( StandardMap->MyGID(row) ) 
    {
      myFlux += 
        + basis.wt * basis.dx
        * ( peclet * (basis.duu / basis.dx) * basis.phi[local_node] 
        +   kappa * (1.0/(basis.dx*basis.dx)) * basis.duu * basis.dphide[local_node] );
    }
  }

  // Sync up processors to be safe
  Comm->Barrier();
 
  // Cleanup
  for( int i = 0; i < numDep; ++i)
  {
    delete [] ddep[i];
    delete     dep[i];
  }

  delete [] xx    ;
  delete [] uu    ;
  delete [] uuold ;

  //int lastDof = StandardMap->LID(StandardMap->MaxAllGID());
  //cout << "\t\"" << myName << "\" u[0] = " << u[0] 
  //     << "\tu[N] = " << u[lastDof] << std::endl;
  //cout << u << std::endl;
  //cout << "\t\"" << myName << "\" myFlux = " << myFlux << std::endl << std::endl;

  // Scale domain integration according to interface position
  myFlux *= dirScale;

  // Now add radiation contribution to flux
  myFlux += radiation * ( pow(u[interface_node], 4) - pow(u[opposite_node], 4) );

  return;
}
コード例 #3
0
ファイル: HMX_PDE.C プロジェクト: gitter-badger/quinoa
// Matrix and Residual Fills
bool 
HMX_PDE::evaluate(
                    NOX::Epetra::Interface::Required::FillType flag,
		    const Epetra_Vector* soln, 
		    Epetra_Vector* tmp_rhs)
{
  // Determine what to fill (F or Jacobian)
  bool fillF = false;
  bool fillMatrix = false;
  if (tmp_rhs != 0) {
    fillF = true;
    rhs = tmp_rhs;
  }
  else {
    fillMatrix = true;
  }
  
  // "flag" can be used to determine how accurate your fill of F should be
  // depending on why we are calling evaluate (Could be using computeF to
  // populate a Jacobian or Preconditioner).
  if (flag == NOX::Epetra::Interface::Required::Residual) {
    // Do nothing for now
  }
  else if (flag == NOX::Epetra::Interface::Required::Jac) {
    // Do nothing for now
  }
  else if (flag == NOX::Epetra::Interface::Required::Prec) {
    // Do nothing for now
  }
  else if (flag == NOX::Epetra::Interface::Required::User) {
    // Do nothing for now
  }

  int numDep = depProblems.size();

  // Create the overlapped solution and position vectors
  Epetra_Vector u(*OverlapMap);
  Epetra_Vector uold(*OverlapMap);
  std::vector<Epetra_Vector*> dep(numDep);
  for( int i = 0; i<numDep; i++)
    dep[i] = new Epetra_Vector(*OverlapMap);
  Epetra_Vector xvec(*OverlapMap);

  // Export Solution to Overlap vector
  // If the vector to be used in the fill is already in the Overlap form,
  // we simply need to map on-processor from column-space indices to
  // OverlapMap indices. Note that the old solution is simply fixed data that
  // needs to be sent to an OverlapMap (ghosted) vector.  The conditional
  // treatment for the current soution vector arises from use of
  // FD coloring in parallel.
  uold.Import(*oldSolution, *Importer, Insert);
  for( int i = 0; i<numDep; i++ )
    (*dep[i]).Import(*( (*(depSolutions.find(depProblems[i]))).second ), 
                   *Importer, Insert);
  xvec.Import(*xptr, *Importer, Insert);
  if( flag == NOX::Epetra::Interface::Required::FD_Res)
    // Overlap vector for solution received from FD coloring, so simply reorder
    // on processor
    u.Export(*soln, *ColumnToOverlapImporter, Insert);
  else // Communication to Overlap vector is needed
    u.Import(*soln, *Importer, Insert);

  // Declare required variables
  int OverlapNumMyNodes = OverlapMap->NumMyElements();

  int OverlapMinMyNodeGID;
  if (MyPID==0) OverlapMinMyNodeGID = StandardMap->MinMyGID();
  else OverlapMinMyNodeGID = StandardMap->MinMyGID()-1;

  // Setup iterators for looping over each problem source term contribution
  // to this one's PDE
  map<string, double>::iterator srcTermIter;
  map<string, double>::iterator srcTermEnd = SrcTermWeight.end();

  // Bundle up the dependent variables in the way needed for computing
  // the source terms of each reaction
  /*
  Epetra_Vector debugSrcTerm(*OverlapMap);
  map<string, Epetra_Vector*> debugDepVars;
  debugDepVars.insert( pair<string, Epetra_Vector*>(getName(), &u) );
  for( int i = 0; i<numDep; i++ )
    debugDepVars.insert( pair<string, Epetra_Vector*>
                    (myManager->getName(depProblems[i]), &dep[i]) );

  for( srcTermIter = SrcTermWeight.begin(); 
    srcTermIter != srcTermEnd; srcTermIter++) {
                     HMX_PDE &srcTermProb = 
                     dynamic_cast<HMX_PDE&>(
                     myManager->getProblem(srcTermIter->first) );
    std::cout << "Inside problem: \"" << getName() << "\" calling to get source term "
         << "from problem: \"" << srcTermIter->first << "\" :" << std::endl;
    srcTermProb.computeSourceTerm(debugDepVars, debugSrcTerm);
    std::cout << "Resulting source term :" << debugSrcTerm << std::endl;
  }
  */

  int row;
  double alpha = 500.0;
  double xx[2];
  double uu[2]; 
  double uuold[2];
  std::vector<double*> ddep(numDep);
  for( int i = 0; i<numDep; i++)
    ddep[i] = new double[2];
  double *srcTerm = new double[2];
  Basis basis;

  // Bundle up the dependent variables in the way needed for computing
  // the source terms of each reaction
  map<string, double*> depVars;
  depVars.insert( pair<string, double*>(getName(), uu) );
  for( int i = 0; i<numDep; i++ )
    depVars.insert( pair<string, double*>
                    (myManager->getProblemName(depProblems[i]), ddep[i]) );
  // Do a check on this fill
//  map<string, double*>::iterator iter;
//  for( iter = depVars.begin(); iter != depVars.end(); iter++)
//    std::cout << "Inserted ... " << iter->first << "\t" << iter->second << std::endl;
//  std::cout << "--------------------------------------------------" << std::endl;
//  for( iter = depVars.begin(); iter != depVars.end(); iter++)
//	  std::cout << iter->first << "\t" << (iter->second)[0] << ", " 
//               << (iter->second)[1] << std::endl;
//  std::cout << "--------------------------------------------------" << std::endl;

  // Zero out the objects that will be filled
  if ( fillMatrix ) A->PutScalar(0.0);
  if ( fillF ) rhs->PutScalar(0.0);

  // Loop Over # of Finite Elements on Processor
  for (int ne=0; ne < OverlapNumMyNodes-1; ne++) 
  {
    // Loop Over Gauss Points
    for(int gp=0; gp < 2; gp++) 
    {
      // Get the solution and coordinates at the nodes 
      xx[0]=xvec[ne];
      xx[1]=xvec[ne+1];
      uu[0] = u[ne];
      uu[1] = u[ne+1];
      uuold[0] = uold[ne];
      uuold[1] = uold[ne+1];
      for( int i = 0; i<numDep; i++ ) {
        ddep[i][0] = (*dep[i])[ne];
        ddep[i][1] = (*dep[i])[ne+1];
      }
      // Calculate the basis function and variables at the gauss points
      basis.getBasis(gp, xx, uu, uuold, ddep);

      // Loop over Nodes in Element
      for (int i=0; i< 2; i++) {
	row=OverlapMap->GID(ne+i);
	if (StandardMap->MyGID(row)) {
	  if ( fillF ) {

            // First do time derivative and diffusion operator
	    (*rhs)[StandardMap->LID(OverlapMap->GID(ne+i))]+=
	      +basis.wt*basis.dx
	      *((basis.uu - basis.uuold)/dt * basis.phi[i] 
              +(1.0/(basis.dx*basis.dx))*diffCoef*basis.duu*basis.dphide[i]);

            // Then do source term contributions
	    //
            for( srcTermIter = SrcTermWeight.begin(); 
                          srcTermIter != srcTermEnd; srcTermIter++) {
              HMX_PDE &srcTermProb = 
                       dynamic_cast<HMX_PDE&>(
			       myManager->getProblem((*srcTermIter).first) );
              srcTermProb.computeSourceTerm(2, depVars, srcTerm);
              (*rhs)[StandardMap->LID(OverlapMap->GID(ne+i))]+=
                +basis.wt*basis.dx
                *( basis.phi[i] * ( - (*srcTermIter).second * srcTerm[i] ));
            }
	    //
	  }
	}
	// Loop over Trial Functions
	if ( fillMatrix ) {
		/*
	  for(j=0;j < 2; j++) {
	    if (StandardMap->MyGID(row)) {
	      column=OverlapMap->GID(ne+j);
	      jac=basis.wt*basis.dx*(
                      basis.phi[j]/dt*basis.phi[i] 
                      +(1.0/(basis.dx*basis.dx))*diffCoef*basis.dphide[j]*
                                                        basis.dphide[i]
                      + basis.phi[i] * ( (beta+1.0)*basis.phi[j]
                      - 2.0*basis.uu*basis.phi[j]*basis.ddep[id_spec]) );  
	      ierr=A->SumIntoGlobalValues(row, 1, &jac, &column);
	    }
	  }
   */
	}
      }
    }
  } 

  // Apply Dirichlet BC for Temperature problem only (for now); this implies
  // no-flux across domain boundary for all species.
  if( getName() == tempFieldName ) 
  {
    // Insert Boundary Conditions and modify Jacobian and function (F)
    // U(0)=1
    if (MyPID==0) 
    {
      if ( fillF )
        (*rhs)[0]= (*soln)[0] - alpha;
      if ( fillMatrix ) 
      {
        int column=0;
        double jac=1.0;
        A->ReplaceGlobalValues(0, 1, &jac, &column);
        column=1;
        jac=0.0;
        A->ReplaceGlobalValues(0, 1, &jac, &column);
      }
    }
    // U(1)=1
    if ( StandardMap->LID(StandardMap->MaxAllGID()) >= 0 ) 
    {
      int lastDof = StandardMap->LID(StandardMap->MaxAllGID());
      if ( fillF )
        (*rhs)[lastDof] = (*soln)[lastDof] - alpha;
      if ( fillMatrix ) 
      {
        int row=StandardMap->MaxAllGID();
        int column = row;
        double jac = 1.0;
        A->ReplaceGlobalValues(row, 1, &jac, &column);
        jac=0.0;
        column--;
        A->ReplaceGlobalValues(row, 1, &jac, &column);
      }
    }
  }

  // Sync up processors to be safe
  Comm->Barrier();
 
  A->FillComplete();

#ifdef DEBUG
  A->Print(cout);

  if( fillF )
    std::cout << "For residual fill :" << std::endl << *rhs << std::endl;

  if( fillMatrix ) 
  {
    std::cout << "For jacobian fill :" << std::endl;
    A->Print(cout);
  }
#endif

  // Cleanup
  for( int i = 0; i < numDep; ++i)
  {
    delete [] ddep[i];
    delete     dep[i];
  }
  delete [] srcTerm;

  return true;
}
コード例 #4
0
ファイル: ConvDiff_PDE.C プロジェクト: gitter-badger/quinoa
// Matrix and Residual Fills
bool 
ConvDiff_PDE::evaluate(
                    NOX::Epetra::Interface::Required::FillType flag,
		    const Epetra_Vector * soln, 
		    Epetra_Vector * rhs)
{

  if( rhs == 0 ) 
  {
    std::string msg = "ERROR: ConvDiff_PDE::evaluate : callback appears to be other than a residual fill.  Others are not support for this type.";
    throw msg;
  }

  int numDep = depProblems.size();

  // Create the overlapped solution and position vectors
  Epetra_Vector u(*OverlapMap);
  Epetra_Vector uold(*OverlapMap);
  std::vector<Epetra_Vector*> dep(numDep);
  for( int i = 0; i < numDep; ++i)
    dep[i] = new Epetra_Vector(*OverlapMap);

  Epetra_Vector xvec(*OverlapMap);

  // Export Solution to Overlap vector
  // If the vector to be used in the fill is already in the Overlap form,
  // we simply need to map on-processor from column-space indices to
  // OverlapMap indices. Note that the old solution is simply fixed data that
  // needs to be sent to an OverlapMap (ghosted) vector.  The conditional
  // treatment for the current soution vector arises from use of
  // FD coloring in parallel.

  uold.Import(*oldSolution, *Importer, Insert);

  for( int i = 0; i < numDep; ++i )
    (*dep[i]).Import(*( (*(depSolutions.find(depProblems[i]))).second ), *Importer, Insert);

  xvec.Import(*xptr, *Importer, Insert);

  if( flag == NOX::Epetra::Interface::Required::FD_Res)
    // Overlap vector for solution received from FD coloring, so simply reorder
    // on processor
    u.Export(*soln, *ColumnToOverlapImporter, Insert);
  else // Communication to Overlap vector is needed
    u.Import(*soln, *Importer, Insert);

  // Declare required variables
  int OverlapNumMyNodes = OverlapMap->NumMyElements();

  int OverlapMinMyNodeGID;
  if (MyPID==0) OverlapMinMyNodeGID = StandardMap->MinMyGID();
  else OverlapMinMyNodeGID = StandardMap->MinMyGID()-1;

  int row;

  double * xx    = new double[2];
  double * uu    = new double[2]; 
  double * uuold = new double[2];
  std::vector<double*> ddep(numDep);
  for( int i = 0; i < numDep; ++i)
    ddep[i] = new double[2];

  Basis basis;

  // Bundle up the dependent variables in the way needed for computing
  // the source terms of each reaction
  map<string, double*> depVars;
  depVars.insert( pair< std::string, double*>(getName(), uu) );
  for( int i = 0; i < numDep; ++i )
    depVars.insert( pair<string, double*>(myManager->getProblemName(depProblems[i]), ddep[i]) );

  // Zero out the objects that will be filled
  rhs->PutScalar(0.0);

  // Loop Over # of Finite Elements on Processor
  for( int ne = 0; ne < OverlapNumMyNodes-1; ++ne )
  {
    // Loop Over Gauss Points
    for( int gp = 0; gp < 2; ++gp ) 
    {
      // Get the solution and coordinates at the nodes 
      xx[0]=xvec[ne];
      xx[1]=xvec[ne+1];
      uu[0] = u[ne];
      uu[1] = u[ne+1];
      uuold[0] = uold[ne];
      uuold[1] = uold[ne+1];
      for( int i = 0; i < numDep; ++i ) 
      {
        ddep[i][0] = (*dep[i])[ne];
        ddep[i][1] = (*dep[i])[ne+1];
      }
      // Calculate the basis function and variables at the gauss points
      basis.getBasis(gp, xx, uu, uuold, ddep);

      // Loop over Nodes in Element
      for( int i = 0; i < 2; ++i )
      {
	row = OverlapMap->GID(ne+i);
	if( StandardMap->MyGID(row) ) 
        {
          (*rhs)[StandardMap->LID(OverlapMap->GID(ne+i))] +=
            + basis.wt * basis.dx
            * ( peclet * (basis.duu / basis.dx) * basis.phi[i] 
            +   kappa * (1.0/(basis.dx*basis.dx)) * basis.duu * basis.dphide[i] );
	}
      }
    }
  } 

  //if( NOX::Epetra::Interface::Required::Residual == flag )
  //{
  //  int lastDof = StandardMap->LID(StandardMap->MaxAllGID());
  //  std::cout << "\t\"" << myName << "\" u[0] = " << (*soln)[0] 
  //       << "\tu[N] = " << (*soln)[lastDof] << std::endl;
  //  std::cout << "\t\"" << myName << "\" RHS[0] = " << (*rhs)[0] 
  //       << "\tRHS[N] = " << (*rhs)[lastDof] << std::endl << std::endl;
  //}


  // Apply BCs

  computeHeatFlux( soln );

  double bcResidual = bcWeight         * (myFlux - depProbPtr->getHeatFlux()                 ) -
                      (1.0 - bcWeight) * (u[interface_node] - depProbPtr->getInterfaceTemp() );

  int lastDof = StandardMap->LID(StandardMap->MaxAllGID());

  // "Left" boundary
  if( LEFT == myInterface ) // this may break in parallel
  {
    (*rhs)[0]       = bcResidual;
    (*rhs)[lastDof] = (*soln)[lastDof] - Tright;
  }
  // "Right" boundary
  else
  {
    (*rhs)[0]       = (*soln)[0] - Tleft;
    (*rhs)[lastDof] = bcResidual;
  }

  // Sync up processors to be safe
  Comm->Barrier();
 
  A->FillComplete();

#ifdef DEBUG
  std::cout << "For residual fill :" << std::endl << *rhs << std::endl;
#endif

  // Cleanup
  for( int i = 0; i < numDep; ++i)
  {
    delete [] ddep[i];
    delete     dep[i];
  }

  delete [] xx    ;
  delete [] uu    ;
  delete [] uuold ;

  return true;
}
コード例 #5
0
// Matrix and Residual Fills
bool FiniteElementProblem::
evaluate(FillType f, 
	 const Epetra_Vector* soln, 
	 Epetra_Vector* tmp_rhs, 
	 Epetra_RowMatrix* tmp_matrix,
	 NOX::Epetra::Interface::Required::FillType fillFlag)
{
  flag = f;

  // Set the incoming linear objects
  if (flag == F_ONLY) {
    rhs = tmp_rhs;
  } else if (flag == MATRIX_ONLY) {
    //A = dynamic_cast<Epetra_CrsMatrix*> (tmp_matrix);
  } else if (flag == ALL) { 
    rhs = tmp_rhs;
    //A = dynamic_cast<Epetra_CrsMatrix*> (tmp_matrix);
  } else {
    cout << "ERROR: FiniteElementProblem::fillMatrix() - FillType flag is broken" << endl;
    throw;
  }

  // Create the overlapped solution and position vectors
  Epetra_Vector u(*OverlapMap);
  Epetra_Vector x(*OverlapMap);

  // Export Solution to Overlap vector
  // If the vector to be used in the fill is already in the Overlap form,
  // we simply need to map on-processor from column-space indices to
  // OverlapMap indices.
  if( fillFlag == NOX::Epetra::Interface::Required::FD_Res)
  {
    u.Export(*soln, *ColumnToOverlapImporter, Insert);
  }
  // If the incoming vector used in the fill has not been scattered to 
  // OverlapMap (ghosted) entities, do it now.  This potentially involves
  // interprocessor communication unlike the previous condition.
  else
    u.Import(*soln, *Importer, Insert);

  // Declare required variables
  int i,j,ierr;
  int OverlapNumMyElements = OverlapMap->NumMyElements();

  int OverlapMinMyGID;
  if (MyPID==0) OverlapMinMyGID = StandardMap->MinMyGID();
  else OverlapMinMyGID = StandardMap->MinMyGID()-1;

  int row, column;
  double factor=1000.0;
  double jac;
  double xx[2];
  double uu[2];
  Basis basis;

  // Create the nodal coordinates
  double Length=1.0;
  double dx=Length/((double) NumGlobalElements-1);
  for (i=0; i < OverlapNumMyElements; i++) {
    x[i]=dx*((double) OverlapMinMyGID+i);
  }
  
  // Zero out the objects that will be filled
  if ((flag == MATRIX_ONLY) || (flag == ALL)) i=A->PutScalar(0.0);
  if ((flag == F_ONLY)    || (flag == ALL)) i=rhs->PutScalar(0.0);

  // Loop Over # of Finite Elements on Processor
  for (int ne=0; ne < OverlapNumMyElements-1; ne++) {
    
    // Loop Over Gauss Points
    for(int gp=0; gp < 2; gp++) {
      // Get the solution and coordinates at the nodes 
      xx[0]=x[ne];
      xx[1]=x[ne+1];
      uu[0]=u[ne];
      uu[1]=u[ne+1];
      // Calculate the basis function at the gauss point
      basis.getBasis(gp, xx, uu);
	            
      // Loop over Nodes in Element
      for (i=0; i< 2; i++) {
	row=OverlapMap->GID(ne+i);
	if (StandardMap->MyGID(row)) {
	  if ((flag == F_ONLY)    || (flag == ALL)) {
	    (*rhs)[StandardMap->LID(OverlapMap->GID(ne+i))]+=
	      +basis.wt*basis.dx
	      *((1.0/(basis.dx*basis.dx))*basis.duu*
		basis.dphide[i]+factor*basis.uu*basis.uu*basis.phi[i]);
	  }
	}
	// Loop over Trial Functions
	if ((flag == MATRIX_ONLY) || (flag == ALL)) {
	  for(j=0;j < 2; j++) {
	    if (StandardMap->MyGID(row)) {
	      column=OverlapMap->GID(ne+j);
	      jac=basis.wt*basis.dx*((1.0/(basis.dx*basis.dx))*
				     basis.dphide[j]*basis.dphide[i]
				     +2.0*factor*basis.uu*basis.phi[j]*
				     basis.phi[i]);  
	      ierr=A->SumIntoGlobalValues(row, 1, &jac, &column);
	    }
	  }
	}
      }
    }
  } 

  // Insert Boundary Conditions and modify Jacobian and function (F)
  // U(0)=1
  if (MyPID==0) {
    if ((flag == F_ONLY)    || (flag == ALL)) 
      (*rhs)[0]= (*soln)[0] - 1.0;
    if ((flag == MATRIX_ONLY) || (flag == ALL)) {
      column=0;
      jac=1.0;
      A->ReplaceGlobalValues(0, 1, &jac, &column);
      column=1;
      jac=0.0;
      A->ReplaceGlobalValues(0, 1, &jac, &column);
    }
  }

  // Sync up processors to be safe
  Comm->Barrier();
 
  A->FillComplete();
 
  return true;
}