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); }
// 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; }