/// Solve again w/ the specified RHS, put result in specified vector (specialized)
  void p_resolveImpl(const VectorType& b, VectorType& x) const
  {
    PetscErrorCode ierr(0);
    int me(this->processor_rank());
    try {
      const Vec *bvec(PETScVector(b));
      Vec *xvec(PETScVector(x));

      ierr = KSPSolve(p_KSP, *bvec, *xvec); CHKERRXX(ierr);
      int its;
      KSPConvergedReason reason;
      PetscReal rnorm;
      ierr = KSPGetIterationNumber(p_KSP, &its); CHKERRXX(ierr);
      ierr = KSPGetConvergedReason(p_KSP, &reason); CHKERRXX(ierr);
      ierr = KSPGetResidualNorm(p_KSP, &rnorm); CHKERRXX(ierr);
      std::string msg;
      if (reason < 0) {
        msg = 
          boost::str(boost::format("%d: PETSc KSP diverged after %d iterations, reason: %d") % 
                     me % its % reason);
        throw Exception(msg);
      } else if (me == 0) {
        msg = 
          boost::str(boost::format("%d: PETSc KSP converged after %d iterations, reason: %d") % 
                     me % its % reason);
        std::cerr << msg << std::endl;
      }
    } catch (const PETSC_EXCEPTION_TYPE& e) {
      throw PETScException(ierr, e);
    } catch (const Exception& e) {
      throw e;
    }
  }    
Beispiel #2
0
void MainWindow::_update_scene_matrix(const QMatrix4x4& mat)
{
    QMatrix4x4 moo;

    QVector3D eye(sqrt(2.0)*_axis_len/2.0,
                  0,
                  sqrt(2.0)*_axis_len/2.0);
    QVector3D center(0,0,0);
    QVector3D up(0,1,0);

    //moo.lookAt(eye,center,up);

    QVector4D xvec(_axis_len,0,0,1);
    QVector4D yvec(0,_axis_len,0,1);
    QVector4D zvec(0,0,_axis_len,1);

    xvec = moo*_mat*xvec;
    yvec = moo*_mat*yvec;
    zvec = moo*_mat*zvec;

    _xitem->setLine(0,0,xvec.x(),-xvec.y());
    _yitem->setLine(0,0,yvec.x(),-yvec.y());
    _zitem->setLine(0,0,zvec.x(),-zvec.y());
}
Beispiel #3
0
bool LinearSolverPCG<MatrixType>::solve(const SparseBlockMatrix<MatrixType>& A, double* x, double* b)
{
  const bool indexRequired = _indices.size() == 0;
  _diag.clear();
  _J.clear();

  // put the block matrix once in a linear structure, makes mult faster
  int colIdx = 0;
  for (size_t i = 0; i < A.blockCols().size(); ++i){
    const typename SparseBlockMatrix<MatrixType>::IntBlockMap& col = A.blockCols()[i];
    if (col.size() > 0) {
      typename SparseBlockMatrix<MatrixType>::IntBlockMap::const_iterator it;
      for (it = col.begin(); it != col.end(); ++it) {
        if (it->first == (int)i) { // only the upper triangular block is needed
          _diag.push_back(it->second);
          _J.push_back(it->second->inverse());
          break;
        }
        if (indexRequired) {
          _indices.push_back(std::make_pair(it->first > 0 ? A.rowBlockIndices()[it->first-1] : 0, colIdx));
          _sparseMat.push_back(it->second);
        }

      }
    }
    colIdx = A.colBlockIndices()[i];
  }

  int n = A.rows();
  assert(n > 0 && "Hessian has 0 rows/cols");
  Eigen::Map<VectorXD> xvec(x, A.cols());
  const Eigen::Map<VectorXD> bvec(b, n);
  xvec.setZero();

  VectorXD r, d, q, s;
  d.setZero(n);
  q.setZero(n);
  s.setZero(n);

  r = bvec;
  multDiag(A.colBlockIndices(), _J, r, d);
  double dn = r.dot(d);
  double d0 = _tolerance * dn;

  if (_absoluteTolerance) {
    if (_residual > 0.0 && _residual > d0)
      d0 = _residual;
  }

  int maxIter = _maxIter < 0 ? A.rows() : _maxIter;

  int iteration;
  for (iteration = 0; iteration < maxIter; ++iteration) {
    if (_verbose)
      std::cerr << "residual[" << iteration << "]: " << dn << std::endl;
    if (dn <= d0)
      break;  // done
    mult(A.colBlockIndices(), d, q);
    double a = dn / d.dot(q);
    xvec += a*d;
    // TODO: reset residual here every 50 iterations
    r -= a*q;
    multDiag(A.colBlockIndices(), _J, r, s);
    double dold = dn;
    dn = r.dot(s);
    double ba = dn / dold;
    d = s + ba*d;
  }
  //std::cerr << "residual[" << iteration << "]: " << dn << std::endl;
  _residual = 0.5 * dn;
  G2OBatchStatistics* globalStats = G2OBatchStatistics::globalStats();
  if (globalStats) {
    globalStats->iterationsLinearSolver = iteration;
  }

  return true;
}
Beispiel #4
0
CString CGenethonDoc::runTest3(PyObject *pModule, CString& function) {

    CString output = CString();
    PyObject *pDict, *pFunc;
    PyObject *pArgTuple, *pValue, *pXVec, *pYVec;
    PyObject *ptype, *pvalue, *ptraceback;

    int i;

    // Set the path to include the current directory in case the module is located there. Found from
    // http://stackoverflow.com/questions/7624529/python-c-api-doesnt-load-module
    // and http://stackoverflow.com/questions/7283964/embedding-python-into-c-importing-modules


    if (pModule != NULL) {
        pFunc = PyObject_GetAttrString(pModule, function);   //Get the function by its name
        // pFunc is a new reference

        if (pFunc && PyCallable_Check(pFunc)) {

            //Set up a tuple that will contain the function arguments. In this case, the
            //function requires two tuples, so we set up a tuple of size 2.
            pArgTuple = PyTuple_New(2);

            //Make some vectors containing the data
            static const double xarr[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14 };
            std::vector<double> xvec(xarr, xarr + sizeof(xarr) / sizeof(xarr[0]));
            static const double yarr[] = { 0,0,1,1,0,0,2,2,0,0,1,1,0,0 };
            std::vector<double> yvec(yarr, yarr + sizeof(yarr) / sizeof(yarr[0]));

            //Transfer the C++ vector to a python tuple
            pXVec = PyTuple_New(xvec.size());
            for (i = 0; i < xvec.size(); ++i) {
                pValue = PyFloat_FromDouble(xvec[i]);
                if (!pValue) {
                    Py_DECREF(pXVec);
                    Py_DECREF(pModule);
                    return "Cannot convert array value\n";
                }
                PyTuple_SetItem(pXVec, i, pValue);
            }

            //Transfer the other C++ vector to a python tuple
            pYVec = PyTuple_New(yvec.size());
            for (i = 0; i < yvec.size(); ++i) {
                pValue = PyFloat_FromDouble(yvec[i]);
                if (!pValue) {
                    Py_DECREF(pYVec);
                    Py_DECREF(pModule);
                    return "Cannot convert array value\n";
                }
                PyTuple_SetItem(pYVec, i, pValue); //
            }

            //Set the argument tuple to contain the two input tuples
            PyTuple_SetItem(pArgTuple, 0, pXVec);
            PyTuple_SetItem(pArgTuple, 1, pYVec);

            //Call the python function
            pValue = PyObject_CallObject(pFunc, pArgTuple);

            Py_DECREF(pArgTuple);
            //			Py_DECREF(pXVec);
            //			Py_DECREF(pYVec);

            if (pValue != NULL) {
                PyObject* v = PyObject_GetAttrString(pModule, "richTextOutput");
                output.Format("Result of call: %ld", PyLong_AsLong(pValue));
                Py_DECREF(pValue);
            }

            //Some error catching
            else {
                Py_DECREF(pFunc);
                Py_DECREF(pModule);
                return handlePyError();
            }
        }
        else {
            if (PyErr_Occurred()) {
                return handlePyError();
            }
        }
        Py_XDECREF(pFunc);
        Py_DECREF(pModule);
    }
    else {
        return handlePyError();
    }
    return output;
}
Beispiel #5
0
// 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;
}
Beispiel #6
0
// 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;
}
Beispiel #7
0
FoMo::RenderCube CGAL2D(FoMo::GoftCube goftcube, const double l, const int x_pixel, const int y_pixel, const int lambda_pixel, const double lambda_width)
{
//
// results is an array of at least dimension (x2-x1+1)*(y2-y1+1)*lambda_pixel and must be initialized to zero
//
// determine contributions per pixel

    typedef K::FT                                         Coord_type;
    typedef K::Point_2                                    Point;
    std::map<Point, Coord_type, K::Less_xy_2> peakmap, fwhmmap, losvelmap;
//        typedef CGAL::Data_access< std::map<Point, Coord_type, K::Less_xyz_3 > >  Value_access;

    int commrank;
#ifdef HAVEMPI
    MPI_Comm_rank(MPI_COMM_WORLD,&commrank);
#else
    commrank = 0;
#endif
    //FoMo::DataCube goftcube=object.datacube;
    FoMo::tgrid grid = goftcube.readgrid();
    int ng=goftcube.readngrid();

    // We will calculate the maximum image coordinates by projecting the grid onto the image plane
    // Rotate the grid over an angle -l (around z-axis), and -b (around y-axis)
    // Take the min and max of the resulting coordinates, those are coordinates in the image plane
    if (commrank==0) std::cout << "Rotating coordinates to POS reference... " << std::flush;
    std::vector<double> xacc, yacc, zacc;
    xacc.resize(ng);
    yacc.resize(ng);
    zacc.resize(ng);
    std::vector<double> gridpoint;
    gridpoint.resize(3);
    Point temporarygridpoint;
    // Define the unit vector along the line-of-sight: the LOS is along y
    std::vector<double> unit = {cos(l), sin(l)};
    // Read the physical variables
    FoMo::tphysvar peakvec=goftcube.readvar(0);//Peak intensity
    FoMo::tphysvar fwhmvec=goftcube.readvar(1);// line width, =1 for AIA imaging
    FoMo::tphysvar vx=goftcube.readvar(2);
    FoMo::tphysvar vy=goftcube.readvar(3);
    double losvelval;

// No openmp possible here
// Because of the insertions at the end of the loop, we get segfaults :(
    /*#ifdef _OPENMP
    #pragma omp parallel for
    #endif*/
    for (int i=0; i<ng; i++)
    {
        for (int j=0; j<2; j++)	gridpoint[j]=grid[j][i];
        xacc[i]=gridpoint[0]*cos(l)-gridpoint[1]*sin(l);// rotated grid
        yacc[i]=gridpoint[0]*sin(l)+gridpoint[1]*cos(l);
        temporarygridpoint=Point(grid[0][i],grid[1][i]); //position vector
        // also create the map function_values here
        std::vector<double> velvec = {vx[i], vy[i]};// velocity vector
        losvelval = inner_product(unit.begin(),unit.end(),velvec.begin(),0.0);//velocity along line of sight for position [i]/[ng]
        losvelmap[temporarygridpoint]=Coord_type(losvelval);
        peakmap[temporarygridpoint]=Coord_type(peakvec[i]);
        fwhmmap[temporarygridpoint]=Coord_type(fwhmvec[i]);
        /*		peakmap.insert(make_pair(temporarygridpoint,Coord_type(peakvec[i])));
        		fwhmmap.insert(make_pair(temporarygridpoint,Coord_type(fwhmvec[i])));
        		losvelmap.insert(make_pair(temporarygridpoint,Coord_type(losvelval)));*/
    }
    double minx=*(min_element(xacc.begin(),xacc.end()));
    double maxx=*(max_element(xacc.begin(),xacc.end()));
    double miny=*(min_element(yacc.begin(),yacc.end()));
    double maxy=*(max_element(yacc.begin(),yacc.end()));
    /*	Value_access peak=Value_access(peakmap);
    	Value_access fwhm=Value_access(fwhmmap);
    	Value_access losvel=Value_access(losvelmap);*/
    xacc.clear(); // release the memory
    yacc.clear();
    if (commrank==0) std::cout << "Done!" << std::endl;

    std::string chiantifile=goftcube.readchiantifile();
    double lambda0=goftcube.readlambda0();// lambda0=AIA bandpass for AIA imaging
    double lambda_width_in_A=lambda_width*lambda0/speedoflight;
    Delaunay_triangulation_2 DT=triangulationfrom2Ddatacube(goftcube);
    Delaunay_triangulation_2 * DTpointer=&DT;

    if (commrank==0) std::cout << "Building frame: " << std::flush;
    double x,y,z,intpolpeak,intpolfwhm,intpollosvel,lambdaval,tempintens;
    int li,lj,ind;
    Point p,nearest;
    Delaunay_triangulation_2::Vertex_handle v;
    Delaunay_triangulation_2::Locate_type lt;
    Delaunay_triangulation_2::Face_handle c;
    boost::progress_display show_progress(x_pixel*y_pixel);

    //initialize grids
    FoMo::tgrid newgrid;
    FoMo::tcoord xvec(x_pixel*lambda_pixel),yvec(x_pixel*lambda_pixel),lambdavec(x_pixel*lambda_pixel);
    newgrid.push_back(xvec);
    if (lambda_pixel > 1) newgrid.push_back(lambdavec);
    FoMo::tphysvar intens(x_pixel*lambda_pixel,0);

#ifdef _OPENMP
    #pragma omp parallel for schedule(dynamic) private (x,y,p,lt,li,v,nearest,intpolpeak,intpolfwhm,intpollosvel,lambdaval,tempintens,ind)
#endif
    for (int j=0; j<x_pixel; j++)
    {
#ifdef _OPENMP
        #pragma omp task
#endif
        for (int i=0; i<y_pixel; i++) // scanning through ccd
        {
            x = double(j)/(x_pixel-1)*(maxx-minx)+minx;
            y = double(i)/(y_pixel-1)*(maxy-miny)+miny;
            // calculate the interpolation in the original frame of reference
            // i.e. derotate the point using angles -l and -b
            p= {x*cos(l)+y*sin(l),-x*sin(l)+y*cos(l)};

            c=DTpointer->locate(p,lt,li);

            // Only look for the nearest point and interpolate, if the point p is inside the convex hull.
            if (lt!=Delaunay_triangulation_2::OUTSIDE_CONVEX_HULL)
            {
                // is this a critical operation?
                v=DTpointer->nearest_vertex(p,c);
                nearest=v->point();
                /* This is how it is done in the CGAL examples
                 			pair<Coord_type,bool> tmppeak=peak(nearest);
                			pair<Coord_type,bool> tmpfwhm=fwhm(nearest);
                			pair<Coord_type,bool> tmplosvel=losvel(nearest);
                			intpolpeak=tmppeak.first;
                			intpolfwhm=tmpfwhm.first;
                			intpollosvel=tmplosvel.first;*/
                intpolpeak=peakmap[nearest];
                intpolfwhm=fwhmmap[nearest];
                intpollosvel=losvelmap[nearest];
            }
            else
            {
                intpolpeak=0;
            }
            if (lambda_pixel>1)// spectroscopic study
            {
                for (int il=0; il<lambda_pixel; il++) // changed index from global variable l into il [D.Y. 17 Nov 2014]
                {
                    // lambda is made around lambda0, with a width of lambda_width
                    lambdaval=double(il)/(lambda_pixel-1)*lambda_width_in_A-lambda_width_in_A/2.;
                    tempintens=intpolpeak*exp(-pow(lambdaval-intpollosvel/speedoflight*lambda0,2)/pow(intpolfwhm,2)*4.*log(2.));
                    ind=j*lambda_pixel+il;//
                    newgrid[0][ind]=x;
                    newgrid[2][ind]=lambdaval+lambda0;
                    // this is critical, but with tasks, the ind is unique for each task, and no collision should occur
                    intens[ind]+=tempintens;// loop over z and lambda [D.Y 17 Nov 2014]
                }
            }

            if (lambda_pixel==1) // AIA imaging study. Algorithm not verified [DY 14 Nov 2014]
            {
                tempintens=intpolpeak;
                ind=j;
                newgrid[0][ind]=x;
                intens[ind]+=tempintens; // loop over z [D.Y 17 Nov 2014]
            }
            // print progress
            ++show_progress;
        }
    }
    if (commrank==0) std::cout << " Done! " << std::endl << std::flush;

    FoMo::RenderCube rendercube(goftcube);
    FoMo::tvars newdata;
    double pathlength=(maxy-miny)/(y_pixel-1);
    intens=FoMo::operator*(pathlength*1e8,intens); // assume that the coordinates are given in Mm, and convert to cm
    newdata.push_back(intens);
    rendercube.setdata(newgrid,newdata);
    rendercube.setrendermethod("CGAL2D");
    rendercube.setresolution(x_pixel,y_pixel,1,lambda_pixel,lambda_width);
    if (lambda_pixel == 1)
    {
        rendercube.setobservationtype(FoMo::Imaging);
    }
    else
    {
        rendercube.setobservationtype(FoMo::Spectroscopic);
    }
    return rendercube;
}
Beispiel #8
0
// 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;
}
Beispiel #9
0
vector<MX> FX::call(const MX &arg){
  vector<MX> xvec(1,arg);
  return call(xvec);
}
Beispiel #10
0
bool 
PelletTransport::evaluate(NOX::Epetra::Interface::Required::FillType fType, 
				    const Epetra_Vector* soln, 
				    Epetra_Vector* tmp_rhs, 
				    Epetra_RowMatrix* tmp_matrix)
{

  if( fType == NOX::Epetra::Interface::Required::Jac ) 
  {
    cout << "This problem only works for Finite-Difference or Matrix-Free Based Jacobians." 
         << " No analytic Jacobian fill available !!" << endl;
    throw "Problem ERROR";
  }
  else 
    rhs = new Epetra_Vector(*OverlapMap);

  // Create the overlapped solution and position vectors
  Epetra_Vector u(*OverlapMap);
  Epetra_Vector uold(*OverlapMap);
  Epetra_Vector xvec(*OverlapNodeMap);

  // Export Solution to Overlap vector
  uold.Import(*oldSolution, *Importer, Insert);
  xvec.Import(*xptr, *nodeImporter, Insert);
  u.Import(*soln, *Importer, Insert);

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

  MaterialPropBase::PropData materialProps;
  // Hard-code use of UO2 for now - RWH 5/14/2007
  string fixedType = "UO2";
  
  int OverlapMinMyNodeGID;
  if (MyPID==0) OverlapMinMyNodeGID = StandardNodeMap->MinMyGID();
  else OverlapMinMyNodeGID = StandardNodeMap->MinMyGID()-1;

  int row1, row2;
  double term1, term2;
  double flux1, flux2;
  double xx[2];
  double uu[2*NUMSPECIES]; // Use of the anonymous enum is needed for SGI builds
  double uuold[2*NUMSPECIES];
  Basis basis(NumSpecies);

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

  ACTIVE_REGIONS propType;

  // Loop Over # of Finite Elements on Processor
  for( int ne = 0; ne < OverlapNumMyNodes - 1; ++ne )
  {
    propType = (ACTIVE_REGIONS) (*elemTypes)[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];
      for (int k=0; k<NumSpecies; k++) {
        uu[NumSpecies * 0 + k] = u[NumSpecies * ne + k];
        uu[NumSpecies * 1 + k] = u[NumSpecies * (ne+1) + k];
        uuold[NumSpecies * 0 + k] = uold[NumSpecies * ne + k];
        uuold[NumSpecies * 1 + k] = uold[NumSpecies * (ne+1) + k];
      }
      // Calculate the basis function at the gauss point
      basis.getBasis(gp, xx, uu, uuold);
      MaterialPropFactory::computeProps( propType, basis.uu[0], basis.uu[1], materialProps );
      double & rho1    = materialProps.density  ;
      double & k1      = materialProps.k_thermal;
      double & Cp1     = materialProps.Cp       ;
      double & Qstar1  = materialProps.Qstar    ;
      double & Qdot1   = materialProps.Qdot     ;
      double & Ffunc   = materialProps.thermoF  ;
      double & D_diff1 = materialProps.D_diff   ;

	            
      // Loop over Nodes in Element
      for( i = 0; i < 2; ++i ) 
      {
	row1=OverlapMap->GID(NumSpecies * (ne+i));
	row2=OverlapMap->GID(NumSpecies * (ne+i) + 1);
        flux1 = -k1*basis.duu[0]/basis.dx;
        flux2 = -0.5*D_diff1*(basis.duu[1]/basis.dx 
              + basis.uu[1]*Qstar1/(Ffunc*8.3142*basis.uu[0]*basis.uu[0])*basis.duu[0]/basis.dx);
        term1 = basis.wt*basis.dx*basis.xx*( 
                    rho1*Cp1*(basis.uu[0] - basis.uuold[0])/dt * basis.phi[i] 
                  - flux1*basis.dphide[i]/basis.dx
                  - Qdot1*basis.phi[i]
                );
        term2 = basis.wt*basis.dx*basis.xx*(
                    0.5*(basis.uu[1] - basis.uuold[1])/dt * basis.phi[i] 
                  - flux2*basis.dphide[i]/basis.dx 
                );
        (*rhs)[NumSpecies*(ne+i)]   += term1;
        (*rhs)[NumSpecies*(ne+i)+1] += term2;
      }
    }
  }

  // Insert Boundary Conditions and modify Jacobian and function (F)
  // Dirichlet BCs at xminUO2
  const double xB = dynamic_cast<const MaterialProp_UO2 &>(MaterialPropFactory::factory().get_model(PelletTransport::UO2)).get_xB();
  if (MyPID==0) 
  {
    // Use no-flux BCs
    //(*rhs)[0]= (*soln)[0] - 0.6;
    //(*rhs)[1]= (*soln)[1] - 10.0/3.0;
  }
  // Dirichlet BCs at xmaxUO2
  if( StandardMap->LID(NumSpecies*(NumGlobalElementsUO2)) >= 0 ) 
  {
    int lastUO2Dof = StandardMap->LID(NumSpecies*(NumGlobalElementsUO2) + 1);
    //(*rhs)[lastDof - 1] = (*soln)[lastDof - 1] - 840.0;
    (*rhs)[lastUO2Dof] = (*soln)[lastUO2Dof] - xB;
  }
  // Dirichlet BCs at all He and Clad species variables
  int lastUO2DofGID = NumSpecies*NumGlobalElementsUO2 + 1;
  int lastGID = StandardMap->MaxAllGID();
  for( int i = lastUO2DofGID; i < lastGID; i+=2 )
    if( StandardMap->LID(i) >= 0 ) 
      (*rhs)[StandardMap->LID(i)] = (*soln)[StandardMap->LID(i)] - xB;
    
  // Dirichlet BCs at xmaxClad
  if( StandardMap->LID(StandardMap->MaxAllGID()) >= 0 ) 
  {
    int lastDof = StandardMap->LID(StandardMap->MaxAllGID());
    (*rhs)[lastDof - 1] = (*soln)[lastDof - 1] - 750.0;
    (*rhs)[lastDof] = (*soln)[lastDof] - xB;
  }

  // Sync up processors to be safe
  Comm->Barrier();
 
  // Do an assemble for overlap nodes
  tmp_rhs->Export(*rhs, *Importer, Add);

  delete rhs;

  return true;
}
Beispiel #11
0
// Matrix and Residual Fills
bool Brusselator::evaluate(NOX::Epetra::Interface::Required::FillType fType, 
				    const Epetra_Vector* soln, 
				    Epetra_Vector* tmp_rhs, 
				    Epetra_RowMatrix* tmp_matrix,
                                    double jac_coeff, double mass_coeff)
{

  if( fType == NOX::Epetra::Interface::Required::Jac ) {
    if( overlapType == NODES ) {
      cout << "This problem only works for Finite-Difference Based Jacobians" 
           << endl << "when overlapping nodes." << endl
           << "No analytic Jacobian fill available !!" << endl;
      exit(1);
    }
    flag = MATRIX_ONLY;
  }
  else {
    flag = F_ONLY;
    if( overlapType == NODES ) 
      rhs = new Epetra_Vector(*OverlapMap);
    else
      rhs = tmp_rhs;
  }

//  cout << "\nfTpye--> " << fType << endl
//       << "Incoming soln vector :\n" << endl << *soln << endl;

  // Create the overlapped solution and position vectors
  Epetra_Vector u(*OverlapMap);
  Epetra_Vector udot(*OverlapMap);
  Epetra_Vector xvec(*OverlapNodeMap);

  // 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.
  udot.Import(*solnDot, *Importer, Insert);
  xvec.Import(*xptr, *nodeImporter, Insert);
  if( (overlapType == ELEMENTS) && 
      (fType == 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 i,j,ierr;
  int OverlapNumMyNodes = OverlapNodeMap->NumMyElements();
  //int OverlapNumMyUnknowns = OverlapMap->NumMyElements();

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

  int row1, row2, column1, column2;
  double term1, term2;
  double Dcoeff1 = 0.025;
  double Dcoeff2 = 0.025;
//  double alpha = 0.6;
//  double beta = 2.0;
  double jac11, jac12, jac21, jac22;
  double xx[2];
  double uu[2*NUMSPECIES]; // Use of the anonymous enum is needed for SGI builds
  double uudot[2*NUMSPECIES];
  Basis basis(NumSpecies);

  
  // Zero out the objects that will be filled
  if ((flag == MATRIX_ONLY) || (flag == ALL)) A->PutScalar(0.0);
  if ((flag == F_ONLY)      || (flag == ALL)) 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];
      for (int k=0; k<NumSpecies; k++) {
        uu[NumSpecies * 0 + k] = u[NumSpecies * ne + k];
        uu[NumSpecies * 1 + k] = u[NumSpecies * (ne+1) + k];
        uudot[NumSpecies * 0 + k] = udot[NumSpecies * ne + k];
        uudot[NumSpecies * 1 + k] = udot[NumSpecies * (ne+1) + k];
      }
      // Calculate the basis function at the gauss point
      basis.getBasis(gp, xx, uu, uudot);
	            
      // Loop over Nodes in Element
      for (i=0; i< 2; i++) {
	row1=OverlapMap->GID(NumSpecies * (ne+i));
	row2=OverlapMap->GID(NumSpecies * (ne+i) + 1);
        term1 = basis.wt*basis.dx * (
  	       basis.uudot[0] * basis.phi[i] 
              +(1.0/(basis.dx*basis.dx))*Dcoeff1*basis.duu[0]*basis.dphide[i]
              + basis.phi[i] * ( -alpha + (beta+1.0)*basis.uu[0]
              - basis.uu[0]*basis.uu[0]*basis.uu[1]) );
        term2 = basis.wt*basis.dx * (
              basis.uudot[1] * basis.phi[i] 
              +(1.0/(basis.dx*basis.dx))*Dcoeff2*basis.duu[1]*basis.dphide[i]
              + basis.phi[i] * ( -beta*basis.uu[0]
              + basis.uu[0]*basis.uu[0]*basis.uu[1]) );
	//printf("Proc=%d GlobalRow=%d LocalRow=%d Owned=%d\n",
	//     MyPID, row, ne+i,StandardMap.MyGID(row));
        if ((flag == F_ONLY)    || (flag == ALL)) {
          if( overlapType == NODES ) {
            (*rhs)[NumSpecies*(ne+i)]   += term1;
	    (*rhs)[NumSpecies*(ne+i)+1] += term2;
          }
	  else
	    if (StandardMap->MyGID(row1)) {
              (*rhs)[StandardMap->LID(OverlapMap->GID(NumSpecies*(ne+i)))]+=
                term1;
              (*rhs)[StandardMap->LID(OverlapMap->GID(NumSpecies*(ne+i)+1))]+=
                term2;
	  }
	}
        // Loop over Trial Functions
        if ((flag == MATRIX_ONLY) || (flag == ALL)) {
          for(j=0;j < 2; j++) {
            if (StandardMap->MyGID(row1)) {
              column1=OverlapMap->GID(NumSpecies * (ne+j));
              column2=OverlapMap->GID(NumSpecies * (ne+j) + 1);
              jac11=basis.wt*basis.dx*(
                      mass_coeff*basis.phi[j]*basis.phi[i]
                      +jac_coeff*
                      +((1.0/(basis.dx*basis.dx))*Dcoeff1*basis.dphide[j]*
                                                        basis.dphide[i]
                      + basis.phi[i] * ( (beta+1.0)*basis.phi[j]
                      - 2.0*basis.uu[0]*basis.phi[j]*basis.uu[1])) );
              jac12=basis.wt*basis.dx*(
                      jac_coeff*basis.phi[i] * ( -basis.uu[0]*basis.uu[0]*basis.phi[j]) );
              jac21=basis.wt*basis.dx*(
                      jac_coeff*basis.phi[i] * ( -beta*basis.phi[j]
                      + 2.0*basis.uu[0]*basis.phi[j]*basis.uu[1]) );
              jac22=basis.wt*basis.dx*(
                      mass_coeff*basis.phi[j]*basis.phi[i]
                      +jac_coeff*
                      +((1.0/(basis.dx*basis.dx))*Dcoeff2*basis.dphide[j]*
                                                        basis.dphide[i]
                      + basis.phi[i] * basis.uu[0]*basis.uu[0]*basis.phi[j] ));
              ierr=A->SumIntoGlobalValues(row1, 1, &jac11, &column1);
              column1++;
              ierr=A->SumIntoGlobalValues(row1, 1, &jac12, &column1);
              ierr=A->SumIntoGlobalValues(row2, 1, &jac22, &column2);
              column2--;
              ierr=A->SumIntoGlobalValues(row2, 1, &jac21, &column2);
            }
          }
        }
      }
    }
  }

  // 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] - alpha;
      (*rhs)[1]= (*soln)[1] - beta/alpha;
    }
    if ((flag == MATRIX_ONLY) || (flag == ALL)) {
      int column=0;
      double jac=1.0*jac_coeff;
      A->ReplaceGlobalValues(0, 1, &jac, &column);
      column++;
      A->ReplaceGlobalValues(1, 1, &jac, &column);
      jac=0.0;
      column=0;
      A->ReplaceGlobalValues(1, 1, &jac, &column);
      column++;
      A->ReplaceGlobalValues(0, 1, &jac, &column);
      column++;
      A->ReplaceGlobalValues(0, 1, &jac, &column);
      A->ReplaceGlobalValues(1, 1, &jac, &column);
      column++;
      A->ReplaceGlobalValues(0, 1, &jac, &column);
      A->ReplaceGlobalValues(1, 1, &jac, &column);
    }
  }
  // U(1)=1
  if ( StandardMap->LID(StandardMap->MaxAllGID()) >= 0 ) {
    int lastDof = StandardMap->LID(StandardMap->MaxAllGID());
    if ((flag == F_ONLY)    || (flag == ALL)) {
      (*rhs)[lastDof - 1] = (*soln)[lastDof - 1] - alpha;
      (*rhs)[lastDof] = (*soln)[lastDof] - beta/alpha;
    }
    if ((flag == MATRIX_ONLY) || (flag == ALL)) {
      int row=StandardMap->MaxAllGID() - 1;
      int column = row;
      double jac = 1.0*jac_coeff;
      A->ReplaceGlobalValues(row++, 1, &jac, &column);
      column++;
      A->ReplaceGlobalValues(row, 1, &jac, &column);
      jac=0.0;
      row = column - 1;
      A->ReplaceGlobalValues(row, 1, &jac, &column);
      column--;
      A->ReplaceGlobalValues(row+1, 1, &jac, &column);
      column--;
      A->ReplaceGlobalValues(row, 1, &jac, &column);
      A->ReplaceGlobalValues(row+1, 1, &jac, &column);
      column--;
      A->ReplaceGlobalValues(row, 1, &jac, &column);
      A->ReplaceGlobalValues(row+1, 1, &jac, &column);
    }
  }

  // Sync up processors to be safe
  Comm->Barrier();
 
  // Do an assemble for overlap nodes
  if( overlapType == NODES )
    tmp_rhs->Export(*rhs, *Importer, Add);

//  Comm->Barrier();
//  cout << "Returned tmp_rhs residual vector :\n" << endl << *tmp_rhs << endl;

  return true;
}
void MeshTopoData::ApplyMap(int mapType,  BOOL normalizeMap, Matrix3 gizmoTM, UnwrapMod *mod)
{
//this just catches some strane cases where the z axis is 0 which causes some bad numbers
/*
if (Length(gizmoTM.GetRow(2)) == 0.0f)
	{
		gizmoTM.SetRow(2,Point3(0.0f,0.0f,1.0f));
	}
*/

	float circ = 1.0f;
/*
 	if (!normalizeMap)
	{
		for (int i = 0; i < 3; i++)
		{
			Point3 vec = gizmoTM.GetRow(i);
			vec = Normalize(vec);
			gizmoTM.SetRow(i,vec);
		}
	}
*/
	Matrix3 toGizmoSpace = gizmoTM;

	BitArray tempVSel;
	DetachFromGeoFaces(mFSel, tempVSel, mod);
	TimeValue t = GetCOREInterface()->GetTime();

	//build available list

	if (mapType == SPHERICALMAP)
	{
		Tab<int> quads;
		quads.SetCount(TVMaps.v.Count());

		float longestR = 0.0f;
		for (int i = 0; i < TVMaps.v.Count(); i++)
		{
			BOOL found = FALSE;
			quads[i] = -1;
			if (tempVSel[i])
			{

				Point3 tp = TVMaps.v[i].GetP() * gizmoTM;//gverts.d[i].p * gtm;
					//z our y

				int quad = 0;
				if ((tp.x >= 0) && (tp.y >= 0))
					quad = 0;
				else if ((tp.x < 0) && (tp.y >= 0))
					quad = 1;
				else if ((tp.x < 0) && (tp.y < 0))
					quad = 2;
				else if ((tp.x >= 0) && (tp.y < 0))
					quad = 3;

				quads[i] = quad;

				//find the quad the point is in
			 	Point3 xvec(1.0f,0.0f,0.0f);
				Point3 zvec(0.0f,0.0f,-1.0f);

				float x= 0.0f;
				Point3 zp = tp;
				zp.z = 0.0f;
				
				float dot = DotProd(xvec,Normalize(zp));
				float angle = 0.0f;
				if (dot >= 1.0f)
					angle = 0.0f;
				else angle = acos(dot);

				x = angle/(PI*2.0f);
				if (quad > 1)
					x = (0.5f - x) + 0.5f;

				dot = DotProd(zvec,Normalize(tp));
				float yangle = 0.0f;
				if (dot >= 1.0f)
					yangle = 0.0f;
				else yangle = acos(dot);

				float y = yangle/(PI);
								
				tp.x = x;	
				tp.y = y;//tp.z;	
				float d = Length(tp);	
				tp.z = d;
				if (d > longestR)
					longestR = d;	

				TVMaps.v[i].SetFlag( 0 );
				TVMaps.v[i].SetInfluence( 0.0f );					
				TVMaps.v[i].SetP(tp);
				TVMaps.v[i].SetControlID(-1);
				mVSel.Set(i);
/*
				if (ct < alist.Count() )
				{
					int j = alist[ct];
					TVMaps.v[j].flags = 0;
					TVMaps.v[j].influence = 0.0f;					


					TVMaps.v[j].p = tp;
					vsel.Set(j);

					if (TVMaps.cont[j]) TVMaps.cont[j]->SetValue(0,&tp,CTRL_ABSOLUTE);
					gverts.d[i].newindex = j;
					ct++;

				}
				else
				{
					UVW_TVVertClass tempv;

					tempv.p = tp;

					tempv.flags = 0;
					tempv.influence = 0.0f;
					gverts.d[i].newindex = TVMaps.v.Count();
					TVMaps.v.Append(1,&tempv,5000);

					int vct = TVMaps.v.Count()-1;
					extraSel.Append(1,&vct,5000);


					Control* c;
					c = NULL;
					TVMaps.cont.Append(1,&c,5000);
					if (TVMaps.cont[TVMaps.v.Count()-1]) 
						TVMaps.cont[TVMaps.v.Count()-1]->SetValue(0,&TVMaps.v[TVMaps.v.Count()-1].p,CTRL_ABSOLUTE);
				}
*/
			}
		}


		//now copy our face data over
		Tab<int> faceAcrossSeam;
		for (int i = 0; i < TVMaps.f.Count(); i++)
		{			
			if (mFSel[i])
			{
				//		ActiveAddFaces.Append(1,&i,1);
				int ct = i;//gfaces[i]->FaceIndex;
//				TVMaps.f[ct]->flags = gfaces[i]->flags;
//				TVMaps.f[ct]->flags |= FLAG_SELECTED;
				int pcount = 3;
				//		if (gfaces[i].flags & FLAG_QUAD) pcount = 4;
				pcount = TVMaps.f[i]->count;//gfaces[i]->count;
				int quad0 = 0;
				int quad3 = 0;
				for (int j = 0; j < pcount; j++)
				{
					int index = TVMaps.f[i]->t[j];
					if (quads[index] == 0) quad0++;
					if (quads[index] == 3) quad3++;
					//find spot in our list
//					TVMaps.f[ct]->t[j] = gverts.d[index].newindex;
					if ((TVMaps.f[ct]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[ct]->vecs))
					{
						index = TVMaps.f[i]->vecs->handles[j*2];

						if (quads[index] == 0) quad0++;
						if (quads[index] == 3) quad3++;
						//find spot in our list
//						TVMaps.f[ct]->vecs->handles[j*2] = gverts.d[index].newindex;

						index = TVMaps.f[i]->vecs->handles[j*2+1];
						if (quads[index] == 0) quad0++;
						if (quads[index] == 3) quad3++;
						//find spot in our list
//						TVMaps.f[ct]->vecs->handles[j*2+1] = gverts.d[index].newindex;

						if (TVMaps.f[ct]->flags & FLAG_INTERIOR)
						{
							index = TVMaps.f[i]->vecs->interiors[j];
							if (quads[index] == 0) quad0++;
							if (quads[index] == 3) quad3++;
							//find spot in our list
//							TVMaps.f[ct]->vecs->interiors[j] = gverts.d[index].newindex;
						}

					}
				}

				if ((quad3 > 0) && (quad0 > 0))
				{
 					for (int j = 0; j < pcount; j++)
					{
						//find spot in our list
						int index = TVMaps.f[ct]->t[j];
						if (TVMaps.v[index].GetP().x <= 0.25f)
						{
							UVW_TVVertClass tempv = TVMaps.v[index];
							Point3 fp = tempv.GetP();
							fp.x += 1.0f;
							tempv.SetP(fp);
							tempv.SetFlag(0);
							tempv.SetInfluence( 0.0f);
							TVMaps.v.Append(1,&tempv,5000);
							int vct = TVMaps.v.Count()-1;
							TVMaps.f[ct]->t[j] = vct;
						}

						if ((TVMaps.f[ct]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[ct]->vecs))
						{
							

							//find spot in our list
							int index = TVMaps.f[ct]->vecs->handles[j*2];

							if (TVMaps.v[index].GetP().x <= 0.25f)
							{
								UVW_TVVertClass tempv = TVMaps.v[index];
								Point3 fp = tempv.GetP();
								fp.x += 1.0f;
								tempv.SetP(fp);
								tempv.SetFlag(0);
								tempv.SetInfluence( 0.0f);
								TVMaps.v.Append(1,&tempv,5000);
								int vct = TVMaps.v.Count()-1;
								TVMaps.f[ct]->vecs->handles[j*2] = vct;
							}
							//find spot in our list
							index = TVMaps.f[ct]->vecs->handles[j*2+1];
							if (TVMaps.v[index].GetP().x <= 0.25f)
							{
								UVW_TVVertClass tempv = TVMaps.v[index];
								Point3 fp = tempv.GetP();
								fp.x += 1.0f;
								tempv.SetP(fp);
								tempv.SetFlag(0);
								tempv.SetInfluence( 0.0f);
								TVMaps.v.Append(1,&tempv,5000);
								int vct = TVMaps.v.Count()-1;
								TVMaps.f[ct]->vecs->handles[j*2+1] = vct;
							}
							if (TVMaps.f[ct]->flags & FLAG_INTERIOR)
							{
								index = TVMaps.f[ct]->vecs->interiors[j];
								if (TVMaps.v[index].GetP().x <= 0.25f)
								{
									UVW_TVVertClass tempv = TVMaps.v[index];
									Point3 fp = tempv.GetP();
									fp.x += 1.0f;
									tempv.SetP(fp);
									tempv.SetFlag(0);
									tempv.SetInfluence( 0.0f);
									TVMaps.v.Append(1,&tempv,5000);
									int vct = TVMaps.v.Count()-1;
									TVMaps.f[ct]->vecs->interiors[j] = vct;
								}
							}

						}
					}
				}

			}
		}

		if (!normalizeMap)
		{
			BitArray processedVerts;
			processedVerts.SetSize(TVMaps.v.Count());
			processedVerts.ClearAll();
			circ = circ * PI * longestR * 2.0f;
			for (int i = 0; i < TVMaps.f.Count(); i++)
			{	
				if (mFSel[i])
				{
					int pcount = 3;
					//		if (gfaces[i].flags & FLAG_QUAD) pcount = 4;
					pcount = TVMaps.f[i]->count;
 					int ct = i;
						
						for (int j = 0; j < pcount; j++)
						{
							//find spot in our list
							int index = TVMaps.f[ct]->t[j];
							if (!processedVerts[index])
							{
								Point3 p = TVMaps.v[index].GetP();
								p.x *= circ;
								p.y *= circ;
								TVMaps.v[index].SetP(p);
								processedVerts.Set(index,TRUE);
							}

							if ((TVMaps.f[ct]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[ct]->vecs))
							{
								

								//find spot in our list
								int index = TVMaps.f[ct]->vecs->handles[j*2];
								if (!processedVerts[index])
								{
									Point3 p = TVMaps.v[index].GetP();
									p.x *= circ;
									p.y *= circ;
									TVMaps.v[index].SetP(p);
									processedVerts.Set(index,TRUE);
								}
								//find spot in our list
								index = TVMaps.f[ct]->vecs->handles[j*2+1];
								if (!processedVerts[index])
								{
									Point3 p = TVMaps.v[index].GetP();
									p.x *= circ;
									p.y *= circ;
									TVMaps.v[index].SetP(p);
									processedVerts.Set(index,TRUE);
								}
								if (TVMaps.f[ct]->flags & FLAG_INTERIOR)
								{
									index = TVMaps.f[ct]->vecs->interiors[j];
									if (!processedVerts[index])
									{
										Point3 p = TVMaps.v[index].GetP();
										p.x *= circ;
										p.y *= circ;
										TVMaps.v[index].SetP(p);
										processedVerts.Set(index,TRUE);
									}
								}
							}
						}						
					}
			}
		}

		
		//now find the seam
		mVSel.SetSize(TVMaps.v.Count(), 1);
		mVSel.Set(TVMaps.v.Count()-1);
		TVMaps.mSystemLockedFlag.SetSize(TVMaps.v.Count(), 1);
/*		for (int i = 0; i < extraSel.Count(); i++)
			vsel.Set(extraSel[i],TRUE);
*/
	}
	else if (mapType == CYLINDRICALMAP)
	{
		Tab<int> quads;
		quads.SetCount(TVMaps.v.Count());

		float longestR = 0.0f;

		for (int i = 0; i < TVMaps.v.Count(); i++)
		{

			BOOL found = FALSE;
			quads[i] = -1;
			if (tempVSel[i])
//			if (gverts.sel[i])
			{

				Point3 gp = TVMaps.v[i].GetP();//gverts.d[i].p;
				Point3 tp = gp * toGizmoSpace;
					//z our y

				int quad = 0;
				if ((tp.x >= 0) && (tp.y >= 0))
					quad = 0;
				else if ((tp.x < 0) && (tp.y >= 0))
					quad = 1;
				else if ((tp.x < 0) && (tp.y < 0))
					quad = 2;
				else if ((tp.x >= 0) && (tp.y < 0))
					quad = 3;

				quads[i] = quad;

				//find the quad the point is in
			 	Point3 xvec(1.0f,0.0f,0.0f);
				
				float x= 0.0f;
				Point3 zp = tp;
				zp.z = 0.0f;
				
				float dot = DotProd(xvec,Normalize(zp));
				float angle = 0.0f;
				if (dot >= 1.0f)
					angle = 0.0f;
				else angle = acos(dot);

				x = angle/(PI*2.0f);
				if (quad > 1)
					x = (0.5f - x) + 0.5f;

				TVMaps.v[i].SetFlag(0);
				TVMaps.v[i].SetInfluence(0.0f);

				Point3 fp;
				fp.x = x;	
				fp.y = tp.z;	
				float d = Length(zp);	
				fp.z = d;

				SetTVVert(t,i,fp,mod);				


				if (d > longestR)
					longestR = d;
								
			}
		}


		//now copy our face data over
		Tab<int> faceAcrossSeam;
		for (int i = 0; i < TVMaps.f.Count(); i++)
		{			
			if (mFSel[i])
			{
				int ct = i;
				int pcount = 3;
				//		if (gfaces[i].flags & FLAG_QUAD) pcount = 4;
				pcount = TVMaps.f[i]->count;
				int quad0 = 0;
				int quad3 = 0;
				for (int j = 0; j < pcount; j++)
				{
					int index = TVMaps.f[i]->t[j];
					if (quads[index] == 0) quad0++;
					if (quads[index] == 3) quad3++;
					if ((TVMaps.f[ct]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[ct]->vecs))
					{
						index = TVMaps.f[i]->vecs->handles[j*2];

						if (quads[index] == 0) quad0++;
						if (quads[index] == 3) quad3++;

						index = TVMaps.f[i]->vecs->handles[j*2+1];
						if (quads[index] == 0) quad0++;
						if (quads[index] == 3) quad3++;
						//find spot in our list

						if (TVMaps.f[ct]->flags & FLAG_INTERIOR)
						{
							index = TVMaps.f[i]->vecs->interiors[j];
							if (quads[index] == 0) quad0++;
							if (quads[index] == 3) quad3++;
						}

					}
				}

				if ((quad3 > 0) && (quad0 > 0))
				{
 					for (int j = 0; j < pcount; j++)
					{
						//find spot in our list
						int index = TVMaps.f[ct]->t[j];
						if (TVMaps.v[index].GetP().x <= 0.25f)
						{
							UVW_TVVertClass tempv = TVMaps.v[index];
							Point3 tpv = tempv.GetP();
							tpv.x += 1.0f;
							tempv.SetP(tpv);							
							tempv.SetFlag(0);
							tempv.SetInfluence(0.0f);
							tempv.SetControlID(-1);
							TVMaps.v.Append(1,&tempv,5000);
							int vct = TVMaps.v.Count()-1;
							TVMaps.f[ct]->t[j] = vct;
						}

						if ((TVMaps.f[ct]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[ct]->vecs))
						{
							

							//find spot in our list
							int index = TVMaps.f[ct]->vecs->handles[j*2];

							if (TVMaps.v[index].GetP().x <= 0.25f)
							{
								UVW_TVVertClass tempv = TVMaps.v[index];
								Point3 tpv = tempv.GetP();
								tpv.x += 1.0f;
								tempv.SetP(tpv);							
								tempv.SetFlag(0);
								tempv.SetInfluence(0.0f);
								tempv.SetControlID(-1);
								TVMaps.v.Append(1,&tempv,5000);
								int vct = TVMaps.v.Count()-1;
								TVMaps.f[ct]->vecs->handles[j*2] = vct;
							}
							//find spot in our list
							index = TVMaps.f[ct]->vecs->handles[j*2+1];
							if (TVMaps.v[index].GetP().x <= 0.25f)
							{
								UVW_TVVertClass tempv = TVMaps.v[index];
								Point3 tpv = tempv.GetP();
								tpv.x += 1.0f;
								tempv.SetP(tpv);							
								tempv.SetFlag(0);
								tempv.SetInfluence(0.0f);
								tempv.SetControlID(-1);
								TVMaps.v.Append(1,&tempv,5000);
								int vct = TVMaps.v.Count()-1;
								TVMaps.f[ct]->vecs->handles[j*2+1] = vct;
								
							}
							if (TVMaps.f[ct]->flags & FLAG_INTERIOR)
							{
								index = TVMaps.f[ct]->vecs->interiors[j];
								if (TVMaps.v[index].GetP().x <= 0.25f)
								{
									UVW_TVVertClass tempv = TVMaps.v[index];
									Point3 tpv = tempv.GetP();
									tpv.x += 1.0f;
									tempv.SetP(tpv);							
									tempv.SetFlag(0);
									tempv.SetInfluence(0.0f);
									tempv.SetControlID(-1);
									TVMaps.v.Append(1,&tempv,5000);
									int vct = TVMaps.v.Count()-1;
									TVMaps.f[ct]->vecs->interiors[j] = vct;
								}
							}

						}
					}
				}

			}
		}

		if (!normalizeMap)
		{
			BitArray processedVerts;
			processedVerts.SetSize(GetNumberTVVerts());//TVMaps.v.Count());
			processedVerts.ClearAll();
			circ = circ * PI * longestR * 2.0f;
			for (int i = 0; i < GetNumberFaces(); i++)//gfaces.Count(); i++)
			{	
				if (mFSel[i])
				{
					int pcount = 3;
					//		if (gfaces[i].flags & FLAG_QUAD) pcount = 4;
					pcount = GetFaceDegree(i);//gfaces[i]->count;
 					int ct = i;//gfaces[i]->FaceIndex;
						
						for (int j = 0; j < pcount; j++)
						{
							//find spot in our list
							int index = TVMaps.f[ct]->t[j];
							if (!processedVerts[index])
							{
								Point3 p = TVMaps.v[index].GetP();
								p.x *= circ;
								TVMaps.v[index].SetP(p);
								processedVerts.Set(index,TRUE);
							}

							if ((TVMaps.f[ct]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[ct]->vecs))
							{
								

								//find spot in our list
								int index = TVMaps.f[ct]->vecs->handles[j*2];
								if (!processedVerts[index])
								{
									Point3 p = TVMaps.v[index].GetP();
									p.x *= circ;
									TVMaps.v[index].SetP(p);
									processedVerts.Set(index,TRUE);
								}
								//find spot in our list
								index = TVMaps.f[ct]->vecs->handles[j*2+1];
								if (!processedVerts[index])
								{
									Point3 p = TVMaps.v[index].GetP();
									p.x *= circ;
									TVMaps.v[index].SetP(p);
									processedVerts.Set(index,TRUE);
								}
								if (TVMaps.f[ct]->flags & FLAG_INTERIOR)
								{
									index = TVMaps.f[ct]->vecs->interiors[j];
									if (!processedVerts[index])
									{
										Point3 p = TVMaps.v[index].GetP();
										p.x *= circ;
										TVMaps.v[index].SetP(p);
										processedVerts.Set(index,TRUE);
									}
								}

							}
						
					}
				}
			}
		}

		
		//now find the seam
		mVSel.SetSize(TVMaps.v.Count(), 1);
		mVSel.Set(TVMaps.v.Count()-1);
		TVMaps.mSystemLockedFlag.SetSize(TVMaps.v.Count(), 1);
//		for (int i = 0; i < extraSel.Count(); i++)
//			vsel.Set(extraSel[i],TRUE);

	}
	else if ((mapType == PLANARMAP) || (mapType == PELTMAP)|| (mapType == BOXMAP))
	{
		for (int i = 0; i < TVMaps.v.Count(); i++)
		{
			if (tempVSel[i])
			{
				TVMaps.v[i].SetFlag(0);
				TVMaps.v[i].SetInfluence(0.0f);

				Point3 tp = TVMaps.v[i].GetP();
				tp = tp * toGizmoSpace;
				tp.x += 0.5f;
				tp.y += 0.5f;
				tp.z = 0.0f;
				SetTVVert(t,i,tp,mod);				
			}
		}
	}
	
	BuildTVEdges();	
	BuildVertexClusterList();
}
Beispiel #13
0
// Matrix and Residual Fills
bool Brusselator::evaluate(FillType fType, 
			   const Epetra_Vector* soln, 
			   Epetra_Vector* tmp_rhs, 
			   Epetra_RowMatrix* tmp_matrix,
			   double jac_coeff, double mass_coeff)
{

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

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

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

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

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

  int row1, row2, column1, column2;
  double term1, term2;
  double jac11, jac12, jac21, jac22;
  double xx[2];
  double uu[2*NUMSPECIES]; // Use of the anonymous enum is needed for SGI builds
  Basis basis(NumSpecies);

  
  // Zero out the objects that will be filled
  if ((fType == MATRIX_ONLY) || (fType == ALL)) A->PutScalar(0.0);
  if ((fType == F_ONLY)      || (fType == ALL)) 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];
      for (int k=0; k<NumSpecies; k++) {
        uu[NumSpecies * 0 + k] = u[NumSpecies * ne + k];
        uu[NumSpecies * 1 + k] = u[NumSpecies * (ne+1) + k];
      }
      // Calculate the basis function at the gauss point
      basis.getBasis(gp, xx, uu);
	            
      // Loop over Nodes in Element
      for (i=0; i< 2; i++) {
	row1=OverlapMap->GID(NumSpecies * (ne+i));
	row2=OverlapMap->GID(NumSpecies * (ne+i) + 1);
        term1 = basis.wt*basis.dx
	  *((1.0/(basis.dx*basis.dx))*D1*basis.duu[0]*basis.dphide[i]
	    + basis.phi[i] * ( -alpha + (beta+1.0)*basis.uu[0]
			       - basis.uu[0]*basis.uu[0]*basis.uu[1]) );
        term2 = basis.wt*basis.dx
	  *((1.0/(basis.dx*basis.dx))*D2*basis.duu[1]*basis.dphide[i]
	    + basis.phi[i] * ( -beta*basis.uu[0]
			       + basis.uu[0]*basis.uu[0]*basis.uu[1]) );
	//printf("Proc=%d GlobalRow=%d LocalRow=%d Owned=%d\n",
	//     MyPID, row, ne+i,StandardMap.MyGID(row));
        if ((fType == F_ONLY)    || (fType == ALL)) {
	  if (StandardMap->MyGID(row1)) {
	    (*rhs)[StandardMap->LID(OverlapMap->GID(NumSpecies*(ne+i)))]+=
	      term1;
	    (*rhs)[StandardMap->LID(OverlapMap->GID(NumSpecies*(ne+i)+1))]+=
	      term2;
	  }
	}
        // Loop over Trial Functions
        if ((fType == MATRIX_ONLY) || (fType == ALL)) {
          for(j=0;j < 2; j++) {
            if (StandardMap->MyGID(row1)) {
              column1=OverlapMap->GID(NumSpecies * (ne+j));
              column2=OverlapMap->GID(NumSpecies * (ne+j) + 1);
              jac11=basis.wt*basis.dx
		*(-mass_coeff*basis.phi[j]*basis.phi[i]
		  +jac_coeff*
		  ((1.0/(basis.dx*basis.dx))*D1*basis.dphide[j]*
		   basis.dphide[i] + 
		   basis.phi[i]*((beta+1.0)*basis.phi[j]
				 -2.0*basis.uu[0]*basis.phi[j]*basis.uu[1])));
              jac12=basis.wt*basis.dx
		*(jac_coeff*basis.phi[i]
		  *(-basis.uu[0]*basis.uu[0]*basis.phi[j]));
              jac21=basis.wt*basis.dx
		*(jac_coeff*basis.phi[i]
		  *(-beta*basis.phi[j]
		    + 2.0*basis.uu[0]*basis.phi[j]*basis.uu[1]) );
              jac22=basis.wt*basis.dx
		*(-mass_coeff*basis.phi[j]*basis.phi[i]
		  +jac_coeff*
		  ((1.0/(basis.dx*basis.dx))*D2*basis.dphide[j]*
		   basis.dphide[i]
		   + basis.phi[i] * basis.uu[0]*basis.uu[0]*basis.phi[j] ));
              ierr=A->SumIntoGlobalValues(row1, 1, &jac11, &column1);
              column1++;
              ierr=A->SumIntoGlobalValues(row1, 1, &jac12, &column1);
              ierr=A->SumIntoGlobalValues(row2, 1, &jac22, &column2);
              column2--;
              ierr=A->SumIntoGlobalValues(row2, 1, &jac21, &column2);
            }
          }
        }
      }
    }
  }

  // Insert Boundary Conditions and modify Jacobian and function (F)
  // T(0)=alpha, C(0) = beta/alpha
  if (MyPID==0) {
    if ((fType == F_ONLY)    || (fType == ALL)) {
      (*rhs)[0]= (*soln)[0] - alpha;
      (*rhs)[1]= (*soln)[1] - beta/alpha;
    }
    if ((fType == MATRIX_ONLY) || (fType == ALL)) {
      int column=0;
      double jac=1.0*jac_coeff;
      A->ReplaceGlobalValues(0, 1, &jac, &column);
      column++;
      A->ReplaceGlobalValues(1, 1, &jac, &column);
      jac=0.0;
      column=0;
      A->ReplaceGlobalValues(1, 1, &jac, &column);
      column++;
      A->ReplaceGlobalValues(0, 1, &jac, &column);
      column++;
      A->ReplaceGlobalValues(0, 1, &jac, &column);
      A->ReplaceGlobalValues(1, 1, &jac, &column);
      column++;
      A->ReplaceGlobalValues(0, 1, &jac, &column);
      A->ReplaceGlobalValues(1, 1, &jac, &column);
    }
  }
  // T(1)=alpha, C(1) = beta/alpha
  if ( StandardMap->LID(StandardMap->MaxAllGID()) >= 0 ) {
    int lastDof = StandardMap->LID(StandardMap->MaxAllGID());
    if ((fType == F_ONLY)    || (fType == ALL)) {
      (*rhs)[lastDof - 1] = (*soln)[lastDof - 1] - alpha;
      (*rhs)[lastDof] = (*soln)[lastDof] - beta/alpha;
    }
    if ((fType == MATRIX_ONLY) || (fType == ALL)) {
      int row=StandardMap->MaxAllGID() - 1;
      int column = row;
      double jac = 1.0*jac_coeff;
      A->ReplaceGlobalValues(row++, 1, &jac, &column);
      column++;
      A->ReplaceGlobalValues(row, 1, &jac, &column);
      jac=0.0;
      row = column - 1;
      A->ReplaceGlobalValues(row, 1, &jac, &column);
      column--;
      A->ReplaceGlobalValues(row+1, 1, &jac, &column);
      column--;
      A->ReplaceGlobalValues(row, 1, &jac, &column);
      A->ReplaceGlobalValues(row+1, 1, &jac, &column);
      column--;
      A->ReplaceGlobalValues(row, 1, &jac, &column);
      A->ReplaceGlobalValues(row+1, 1, &jac, &column);
    }
  }

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

  A->FillComplete();

  return true;
}