void unified_dot::run(GTask *t)
{
    GData &a =* t->args->args[0];
    GData &b =* t->args->args[1];
    GData &r =* t->args->args[2];
    udot(a,b,r,t);
}
void SimultaneousImpulseBasedConstraintSolverStrategy::Solve(float dt, std::vector<std::unique_ptr<IConstraint> >& c, Mat<float>& q, Mat<float>& qdot, SparseMat<float>& invM, SparseMat<float>& S, const Mat<float>& Fext )
{
	//std::cout << "STATE :" << std::endl;
	//q.afficher();
	
	Mat<float> qdotminus(qdot);
	this->dt = dt;
	//computeConstraintsJacobian(c);
	Mat<float> tempInvMFext( dt*(invM * Fext) ) ;
	//qdot += tempInvMFext;
	//computeConstraintsJacobian(c,q,qdot);
	computeConstraintsANDJacobian(c,q,qdot);
	
	//BAUMGARTE STABILIZATION has been handled in the computeConstraintsANDJacobian function....
	//std::cout << "Constraints : norme  = " << norme2(C) << std::endl;
	//C.afficher();
	
	Mat<float> tConstraintsJacobian( transpose(constraintsJacobian) );
	//std::cout << "t Constraints Jacobian :" << std::endl;
	//tConstraintsJacobian.afficher();
	
	
	//PREVIOUS METHOD :
	//--------------------------------
	//David Baraff 96 STAR.pdf Interactive Simulation of Rigid Body Dynamics in Computer Graphics : Lagrange Multipliers Method :
	//Construct A :
	/*
	Mat<float> A( (-1.0f)*tConstraintsJacobian );
	Mat<float> M( invGJ( invM.SM2mat() ) );
	A = operatorL( M, A);
	A = operatorC( A , operatorL( constraintsJacobian, Mat<float>((float)0,constraintsJacobian.getLine(), constraintsJacobian.getLine()) ) );
	*/
	//----------------------------
	Mat<float> A( constraintsJacobian * invM.SM2mat() * tConstraintsJacobian );
	
	//---------------------------
	Mat<float> invA( invGJ(A) );//invM*tConstraintsJacobian ) * constraintsJacobian );
	
	//Construct b and compute the solution.
	//----------------------------------
	//Mat<float> tempLambda( invA * operatorC( Mat<float>((float)0,invA.getLine()-constraintsJacobian.getLine(),1) , (-1.0f)*(constraintsJacobian*(invM*Fext) + offset) ) );
	//-----------------------------------
	Mat<float> tempLambda( invA * ((-1.0f)*(constraintsJacobian*tempInvMFext + offset) ) );
	//-----------------------------------
	
	//Solutions :
	//------------------------------------
	//lambda = extract( &tempLambda, qdot.getLine()+1, 1, tempLambda.getLine(), 1);
	//if(isnanM(lambda))
	//	lambda = Mat<float>(0.0f,lambda.getLine(),lambda.getColumn());
	//Mat<float> udot( extract(  &tempLambda, 1,1, qdot.getLine(), 1) );
	//------------------------------------
	lambda = tempLambda;
	Mat<float> udot(  tConstraintsJacobian * tempLambda);
	//------------------------------------
	
	if(isnanM(udot))
		udot = Mat<float>(0.0f,udot.getLine(),udot.getColumn());
	
	
	float clampingVal = 1e4f;
	for(int i=1;i<=udot.getLine();i++)
	{
		if(udot.get(i,1) > clampingVal)
		{
			udot.set( clampingVal,i,1);
		}
	}
	
#ifdef debuglvl1	
	std::cout << " SOLUTIONS : udot and lambda/Pc : " << std::endl;
	transpose(udot).afficher();
	transpose(lambda).afficher();
	transpose( tConstraintsJacobian*lambda).afficher();
#endif	
	//Assumed model :
	//qdot = tempInvMFext + dt*extract(  &tempLambda, 1,1, qdot.getLine(), 1);
	//qdot = tempInvMFext + udot;
	qdot += tempInvMFext + invM*udot;
	//qdot += invM*udot;
	//qdot += tempInvMFext + udot;
	float clampingValQ = 1e3f;
	for(int i=1;i<=qdot.getLine();i++)
	{
		if( fabs_(qdot.get(i,1)) > clampingValQ)
		{
			qdot.set( clampingValQ * fabs_(qdot.get(i,1))/qdot.get(i,1),i,1);
		}
	}
	//qdot = udot;
	
	//Assumed model if the update of the integration is applied after that constraints solver :
	//qdot += dt*extract(  &tempLambda, 1,1, qdot.getLine(), 1);//+tempInvMFext
	
	Mat<float> t( dt*( S*qdot ) );	
	
	float clampQuat = 1e-1f;
	float idxQuat = 3;
	while(idxQuat < t.getLine())
	{
		for(int i=1;i<4;i++)
		{
			if( fabs_(t.get(idxQuat+i,1)) > clampQuat)
			{
				t.set( clampQuat*(t.get(idxQuat+i,1))/t.get(idxQuat+i,1), idxQuat+i,1);
			}
		}
		
		idxQuat += 7;
	}
	
	//the update is done by the update via an accurate integration and we must construct q and qdot at every step
	//q += t;
	
	//--------------------------------------	
	//let us normalize each quaternion :
	/*
	idxQuat = 3;
	while(idxQuat < q.getLine())
	{
		float scaler = q.get( idxQuat+4,1);
		
		if(scaler != 0.0f)
		{
			for(int i=1;i<=4;i++)
			{
				q.set( q.get(idxQuat+i,1)/scaler, idxQuat+i,1);
			}
		}
		
		idxQuat += 7;
	}
	*/
	
	//--------------------------------------
	
#ifdef debuglvl2	
	//std::cout << " computed Pc : " << std::endl;
	//(tConstraintsJacobian*tempLambda).afficher();
	//std::cout << " q+ : " << std::endl;
	//transpose(q).afficher();
	std::cout << " qdot+ : " << std::endl;
	transpose(qdot).afficher();
	std::cout << " qdotminus : " << std::endl;
	transpose(qdotminus).afficher();
#endif

#ifdef debuglvl3	
	std::cout << "SOME VERIFICATION ON : J*qdot + c = 0 : " << std::endl;
	transpose(constraintsJacobian*qdot+offset).afficher();
	
	
	float normC = (transpose(C)*C).get(1,1);
	Mat<float> Cdot( constraintsJacobian*qdot);
	float normCdot = (transpose(Cdot)*Cdot).get(1,1);
	float normQdot = (transpose(qdot)*qdot).get(1,1);
	
	//rs->ltadd(std::string("normC"),normC);
	//rs->ltadd(std::string("normCdot"),normCdot);
	rs->ltadd(std::string("normQdot"),normQdot);
	char name[5];
	for(int i=1;i<=t.getLine();i++)
	{
		sprintf(name,"dq%d",i);
		rs->ltadd(std::string(name), t.get(i,1));
	}
	rs->tWriteFileTABLE();
#endif	
	//END OF PREVIOUS METHOD :
	//--------------------------------
	
	//--------------------------------
	//--------------------------------
	//Second Method :
	/*
	//According to Tonge Richar's Physucs For Game pdf :
	Mat<float> tempLambda( (-1.0f)*invGJ( constraintsJacobian*invM.SM2mat()*tConstraintsJacobian)*constraintsJacobian*qdot );
	qdot += invM*tConstraintsJacobian*tempLambda;
	
	
	//qdot += tempInvMFext;	//contraints not satisfied.
	
	//qdot += tempInvMFext;	//qdot+ = qdot- + dt*M-1Fext;
	//Mat<float> qdotreal( qdot + dt*extract(  &tempLambda, 1,1, qdot.getLine(), 1) );	//qdotreal = qdot+ + Pc;
	
	Mat<float> t( dt*( S*qdot ) );
	q += t;
	*/
	//--------------------------------
	//--------------------------------
	//End of second method...
	//--------------------------------
	
	
	
	//--------------------------------
	//--------------------------------
	//THIRD METHOD :
	//--------------------------------
	//With reference to A Unified Framework for Rigid Body Dynamics Chap. 4.6.2.Simultaneous Force-based methods :
	//which refers to Bara96 :
	/*
	Mat<float> iM(invM.SM2mat());
	Mat<float> b((-1.0f)*constraintsJacobian*iM*Fext+offset);
	Mat<float> tempLambda( invGJ( constraintsJacobian*iM*tConstraintsJacobian) * b );
	//Mat<float> qdoubledot(iM*(tConstraintsJacobian*tempLambda+Fext)); 
	Mat<float> qdoubledot(iM*(tConstraintsJacobian*tempLambda)); 
	qdot += dt*qdoubledot;
	
	
	//qdot += tempInvMFext;	//contraints not satisfied.
	
	//qdot += tempInvMFext;	//qdot+ = qdot- + dt*M-1Fext;
	//Mat<float> qdotreal( qdot + dt*extract(  &tempLambda, 1,1, qdot.getLine(), 1) );	//qdotreal = qdot+ + Pc;
	
	Mat<float> t( dt*( S*qdot ) );
	q += t;
	
	std::cout << " computed Pc : " << std::endl;
	(tConstraintsJacobian*tempLambda).afficher();
	std::cout << " q+ : " << std::endl;
	q.afficher();
	std::cout << " qdot+ : " << std::endl;
	qdot.afficher();
	*/
	//END OF THIRD METHOD :
	//--------------------------------
	
	
	
	
	//S.print();
	
	//std::cout << " computed Pc : " << std::endl;
	//(tConstraintsJacobian*lambda).afficher();
	//std::cout << " delta state = S * qdotreal : " << std::endl; 
	//t.afficher();
	//std::cout << " S & qdotreal : " << std::endl;
	//S.print();
	//qdot.afficher();
	//std::cout << "invM*Fext : " << std::endl;
	//tempInvMFext.afficher();
	
	
	//temp.afficher();
	//(constraintsJacobian*(invM*Fext)).afficher();
	//(invM*Fext).afficher();
	//std::cout << " A : " << std::endl;
	//A.afficher();
    //std::cout << " SVD A*tA :  S : " << std::endl;
    //SVD<float> instanceSVD(A*transpose(A));
    //instanceSVD.getS().afficher();
	//std::cout << " invA : " << std::endl;
	//invA.afficher();
	
	//std::cout << " LAMBDA : " << std::endl;
	//lambda.afficher();
	
	//std::cout << " qdot+ & qdot- : " << std::endl;
	//qdot.afficher();
	//qdotminus.afficher();
	
	//std::cout << " q+ : " << std::endl;
	//q.afficher();
#ifdef debuglvl4	
	//BAUMGARTE STABILIZATION has been handled in the computeConstraintsANDJacobian function....
	std::cout << "tConstraints : norme  = " << norme2(C) << std::endl;
	transpose(C).afficher();
	std::cout << "Cdot : " << std::endl;
	(constraintsJacobian*qdot).afficher();
	std::cout << " JACOBIAN : " << std::endl;
	//transpose(constraintsJacobian).afficher();
	constraintsJacobian.afficher();
	std::cout << " Qdot+ : " << std::endl;
	transpose(qdot).afficher();
#endif	
	//BAUMGARTE STABILIZATION has been handled in the computeConstraintsANDJacobian function....
	//std::cout << "Constraints : norme  = " << norme2(C) << std::endl;
	//C.afficher();
	
}
/*	FORCE BASED : */
void SimultaneousImpulseBasedConstraintSolverStrategy::SolveForceBased(float dt, std::vector<std::unique_ptr<IConstraint> >& c, Mat<float>& q, Mat<float>& qdot, SparseMat<float>& invM, SparseMat<float>& S, const Mat<float>& Fext )
{	
	Mat<float> qdotminus(qdot);
	this->dt = dt;
	Mat<float> tempInvMFext( dt*(invM * Fext) ) ;


	computeConstraintsANDJacobian(c,q,qdot);
	
	Mat<float> tConstraintsJacobian( transpose(constraintsJacobian) );
	Mat<float> A( constraintsJacobian * invM.SM2mat() * tConstraintsJacobian );
	
	//---------------------------
	Mat<float> invA( invGJ(A) );
	
	//Construct b and compute the solution.
	//-----------------------------------
	Mat<float> tempLambda( invA * ((-1.0f)*(constraintsJacobian*tempInvMFext + offset) ) );
	//-----------------------------------
	
	//Solutions :
	//------------------------------------
	lambda = tempLambda;
	Mat<float> udot(  tConstraintsJacobian * tempLambda);
	//------------------------------------
	
	if(isnanM(udot))
		udot = Mat<float>(0.0f,udot.getLine(),udot.getColumn());
	
	
	float clampingVal = 1e4f;
	for(int i=1;i<=udot.getLine();i++)
	{
		if(udot.get(i,1) > clampingVal)
		{
			udot.set( clampingVal,i,1);
		}
	}
	
#ifdef debuglvl1	
	std::cout << " SOLUTIONS : udot and lambda/Pc : " << std::endl;
	transpose(udot).afficher();
	transpose(lambda).afficher();
	transpose( tConstraintsJacobian*lambda).afficher();
#endif	
	//Assumed model :
	qdot += tempInvMFext + dt*(invM*udot);
	float clampingValQ = 1e3f;
	for(int i=1;i<=qdot.getLine();i++)
	{
		if( fabs_(qdot.get(i,1)) > clampingValQ)
		{
			qdot.set( clampingValQ * fabs_(qdot.get(i,1))/qdot.get(i,1),i,1);
		}
	}
	
	//--------------------------------------
	
#ifdef debuglvl2	
	//std::cout << " computed Pc : " << std::endl;
	//(tConstraintsJacobian*tempLambda).afficher();
	//std::cout << " q+ : " << std::endl;
	//transpose(q).afficher();
	std::cout << " qdot+ : " << std::endl;
	transpose(qdot).afficher();
	std::cout << " qdotminus : " << std::endl;
	transpose(qdotminus).afficher();
#endif

	//END OF PREVIOUS METHOD :
	//--------------------------------
	
	
#ifdef debuglvl4	
	//BAUMGARTE STABILIZATION has been handled in the computeConstraintsANDJacobian function....
	std::cout << "tConstraints : norme  = " << norme2(C) << std::endl;
	transpose(C).afficher();
	std::cout << "Cdot : " << std::endl;
	(constraintsJacobian*qdot).afficher();
	std::cout << " JACOBIAN : " << std::endl;
	//transpose(constraintsJacobian).afficher();
	constraintsJacobian.afficher();
	std::cout << " Qdot+ : " << std::endl;
	transpose(qdot).afficher();
#endif	
	
	
}
void IterativeImpulseBasedConstraintSolverStrategy::Solve(float dt, std::vector<std::unique_ptr<IConstraint> >& c, Mat<float>& q, Mat<float>& qdot, SparseMat<float>& invM, SparseMat<float>& S, const Mat<float>& Fext )
{
	float clampingVal = 1e20f;
	float clampingValQ = 1e20f;

	Mat<float> qdotminus(qdot);
	this->dt = dt;
	Mat<float> tempInvMFext( dt*(invM * Fext) ) ;
	
	
	std::vector<float> constraintsNormeCdotAfterImpulses(c.size(),1.0f);
	std::vector<Mat<float> > constraintsVAfterImpulses;
	
	
	bool continuer = true;
	int nbrIteration = 0;
	while( continuer)
	{
		
		computeConstraintsANDJacobian(c,q,qdot,invM);	
		constraintsImpulses.clear();	
		constraintsImpulses.resize(constraintsC.size());
		
		if( nbrIteration == 0)
		{
			constraintsVAfterImpulses = constraintsV;
		}
		
		int nbrConstraintsSolved = 0;	
		
		for(int k=0;k<constraintsC.size();k++)
		{
			if(constraintsNormeCdotAfterImpulses[k] >= 0.0f)
			{
				Mat<float> tConstraintsJacobian( transpose( constraintsJacobians[k] ) );
				Mat<float> A( constraintsJacobians[k] * constraintsInvM[k] * tConstraintsJacobian );
	
				//Construct the inverse matrix :
				//---------------------------
				Mat<float> invA( invGJ(A) );
	
				//Construct b and compute the solution.
				//----------------------------------
				Mat<float> tempLambda( invA * ((-1.0f)*(constraintsJacobians[k]*constraintsV[k] + constraintsOffsets[k]) ) );
				//-----------------------------------
	
				//Solution Impulse :
				//------------------------------------
				constraintsImpulses[k] =  tConstraintsJacobian * tempLambda;
				Mat<float> udot( constraintsInvM[k]*constraintsImpulses[k]);
				//------------------------------------
	
				if(isnanM(udot))
				{
					std::cout << " ITERATIVE SOLVER :: udot :: NAN ISSUE : " << std::endl;
					transpose(udot).afficher();
					udot = Mat<float>(0.0f,udot.getLine(),udot.getColumn());
				}
	
	
				/*
				for(int i=1;i<=udot.getLine();i++)
				{
					if(udot.get(i,1) > clampingVal)
					{
						udot.set( clampingVal,i,1);
					}
				}
				*/
			
				//---------------------------------			
				// UPDATE OF THE VELOCITY :
				//---------------------------------
				std::vector<int> indexes = constraintsIndexes[k];
				//constraintsVAfterImpulses[k] = constraintsV[k]-udot;
				constraintsVAfterImpulses[k] = constraintsV[k]+udot;
			
				std::cout << " UDOT : ids : " << indexes[0] << "  and " << indexes[1] << std::endl;
				transpose(udot).afficher();
			
				for(int kk=0;kk<=1;kk++)
				{
					for(int i=1;i<=6;i++)
					{
						qdot.set( constraintsVAfterImpulses[k].get(kk*6+i,1), indexes[kk]*6+i, 1);
					}
				}
			
				//---------------------------------	
	
				/*
				for(int i=1;i<=qdot.getLine();i++)
				{
					if( fabs_(qdot.get(i,1)) > clampingValQ)
					{
						qdot.set( clampingValQ * fabs_(qdot.get(i,1))/qdot.get(i,1),i,1);
					}
				}
				*/
					
			}
			else
			{
				std::cout << "CONSTRAINTS : " << k << "/" << constraintsC.size() << " : has been solved for." << std::endl;
				
			}
					
		}
	
	
		for(int k=0;k<constraintsC.size();k++)
		{
//#ifdef debuglvl3	
				std::cout << "SOME VERIFICATION ON : J*qdot + c = 0 :  k = " << k << std::endl;
				Mat<float> cdot( constraintsJacobians[k]*constraintsVAfterImpulses[k]+constraintsOffsets[k]);
				transpose(cdot).afficher();
					
				constraintsNormeCdotAfterImpulses[k] = (transpose(cdot)*cdot).get(1,1);
	
				std::cout << "NORME : "<< k << " : " << constraintsNormeCdotAfterImpulses[k] << std::endl;
				
				if( constraintsNormeCdotAfterImpulses[k] <= 1e-20f)
				{
					nbrConstraintsSolved++;
				}
//#endif
		}
		
		
		if(nbrConstraintsSolved == constraintsC.size() )
		{
			continuer = false;
			std::cout << " IterativeImpulseBasedConstraintsSolver::Solve :: Constraints solved : " << nbrConstraintsSolved << " / " << constraintsC.size() << " :: ENDED CLEANLY." << std::endl;
		}
		else
		{
			continuer = true;
			nbrIteration++;
		
			if(nbrIteration > this->nbrIterationSolver)
			{
				continuer = false;
				std::cout << " IterativeImpulseBasedConstraintsSolver::Solve :: Constraints solved : " << nbrConstraintsSolved << " / " << constraintsC.size() << " :: ENDED WITH UNRESOLVED CONSTRAINTS." << std::endl;
			}
		}
		//--------------------------------------
		
#ifdef debuglvl4	
		std::cout << " Qdot+ : " << std::endl;
		transpose(qdot).afficher();
#endif

	
	}
	
	wrappingUp(c,q,qdot);
}
Пример #5
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;
}