// Matrix and Residual Fills bool Pitchfork_FiniteElementProblem::evaluate(FillType f, const Epetra_Vector* soln, Epetra_Vector* tmp_rhs, Epetra_RowMatrix* tmp_matrix, double jac_coeff, double mass_coeff) { flag = f; // Set the incoming linear objects if (flag == F_ONLY) { rhs = tmp_rhs; } else if (flag == MATRIX_ONLY) { A = dynamic_cast<Epetra_CrsMatrix*> (tmp_matrix); assert(A != NULL); } else if (flag == ALL) { rhs = tmp_rhs; A = dynamic_cast<Epetra_CrsMatrix*> (tmp_matrix); assert(A != NULL); } else { std::cout << "ERROR: Pitchfork_FiniteElementProblem::fillMatrix() - FillType flag is broken" << std::endl; throw; } // Create the overlapped solution and position vectors Epetra_Vector u(*OverlapMap); Epetra_Vector x(*OverlapMap); // Export Solution to Overlap vector u.Import(*soln, *Importer, Insert); // Declare required variables int i,j,ierr; int OverlapNumMyElements = OverlapMap->NumMyElements(); int OverlapMinMyGID; if (MyPID==0) OverlapMinMyGID = StandardMap->MinMyGID(); else OverlapMinMyGID = StandardMap->MinMyGID()-1; int row, column; double jac; double xx[2]; double uu[2]; Basis basis; // Create the nodal coordinates double Length=2.0; double dx=Length/((double) NumGlobalElements-1); for (i=0; i < OverlapNumMyElements; i++) { x[i]=-1.0 + dx*((double) OverlapMinMyGID+i); } // Zero out the objects that will be filled if ((flag == MATRIX_ONLY) || (flag == ALL)) { i = A->PutScalar(0.0); assert(i == 0); } if ((flag == F_ONLY) || (flag == ALL)) { i = rhs->PutScalar(0.0); assert(i == 0); } // Loop Over # of Finite Elements on Processor for (int ne=0; ne < OverlapNumMyElements-1; ne++) { // Loop Over Gauss Points for(int gp=0; gp < 2; gp++) { // Get the solution and coordinates at the nodes xx[0]=x[ne]; xx[1]=x[ne+1]; uu[0]=u[ne]; uu[1]=u[ne+1]; // Calculate the basis function at the gauss point basis.getBasis(gp, xx, uu); // Loop over Nodes in Element for (i=0; i< 2; i++) { row=OverlapMap->GID(ne+i); //printf("Proc=%d GlobalRow=%d LocalRow=%d Owned=%d\n", // MyPID, row, ne+i,StandardMap.MyGID(row)); if (StandardMap->MyGID(row)) { if ((flag == F_ONLY) || (flag == ALL)) { (*rhs)[StandardMap->LID(OverlapMap->GID(ne+i))]+= +basis.wt*basis.dx *((-1.0/(basis.dx*basis.dx))*basis.duu* basis.dphide[i]-source_term(basis.uu)*basis.phi[i]); } } // Loop over Trial Functions if ((flag == MATRIX_ONLY) || (flag == ALL)) { for(j=0;j < 2; j++) { if (StandardMap->MyGID(row)) { column=OverlapMap->GID(ne+j); jac=jac_coeff*basis.wt*basis.dx* ((-1.0/(basis.dx*basis.dx))*basis.dphide[j]*basis.dphide[i] -source_deriv(basis.uu)*basis.phi[j]*basis.phi[i]) + mass_coeff*basis.wt*basis.dx*basis.phi[j]*basis.phi[i]; ierr=A->SumIntoGlobalValues(row, 1, &jac, &column); assert(ierr == 0); } } } } } } // Insert Boundary Conditions and modify Jacobian and function (F) // U(-1)=beta if (MyPID==0) { if ((flag == F_ONLY) || (flag == ALL)) (*rhs)[0]= (*soln)[0] - beta; if ((flag == MATRIX_ONLY) || (flag == ALL)) { column=0; jac=1.0*jac_coeff; A->ReplaceGlobalValues(0, 1, &jac, &column); column=1; jac=0.0*jac_coeff; A->ReplaceGlobalValues(0, 1, &jac, &column); } } // U(1)=beta if ( StandardMap->LID(StandardMap->MaxAllGID()) >= 0 ) { int lastDof = StandardMap->LID(StandardMap->MaxAllGID()); if ((flag == F_ONLY) || (flag == ALL)) (*rhs)[lastDof] = (*soln)[lastDof] - beta; if ((flag == MATRIX_ONLY) || (flag == ALL)) { int row = StandardMap->MaxAllGID(); column = row; jac=1.0*jac_coeff; A->ReplaceGlobalValues(row, 1, &jac, &column); column=row-1; jac=0.0*jac_coeff; A->ReplaceGlobalValues(row, 1, &jac, &column); } } // Sync up processors to be safe Comm->Barrier(); A->FillComplete(); return true; }
// 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; }
// 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; }
// 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; }
// Matrix and Residual Fills bool FiniteElementProblem:: evaluate(FillType f, const Epetra_Vector* soln, Epetra_Vector* tmp_rhs, Epetra_RowMatrix* tmp_matrix, NOX::Epetra::Interface::Required::FillType fillFlag) { flag = f; // Set the incoming linear objects if (flag == F_ONLY) { rhs = tmp_rhs; } else if (flag == MATRIX_ONLY) { //A = dynamic_cast<Epetra_CrsMatrix*> (tmp_matrix); } else if (flag == ALL) { rhs = tmp_rhs; //A = dynamic_cast<Epetra_CrsMatrix*> (tmp_matrix); } else { cout << "ERROR: FiniteElementProblem::fillMatrix() - FillType flag is broken" << endl; throw; } // Create the overlapped solution and position vectors Epetra_Vector u(*OverlapMap); Epetra_Vector x(*OverlapMap); // Export Solution to Overlap vector // If the vector to be used in the fill is already in the Overlap form, // we simply need to map on-processor from column-space indices to // OverlapMap indices. if( fillFlag == NOX::Epetra::Interface::Required::FD_Res) { u.Export(*soln, *ColumnToOverlapImporter, Insert); } // If the incoming vector used in the fill has not been scattered to // OverlapMap (ghosted) entities, do it now. This potentially involves // interprocessor communication unlike the previous condition. else u.Import(*soln, *Importer, Insert); // Declare required variables int i,j,ierr; int OverlapNumMyElements = OverlapMap->NumMyElements(); int OverlapMinMyGID; if (MyPID==0) OverlapMinMyGID = StandardMap->MinMyGID(); else OverlapMinMyGID = StandardMap->MinMyGID()-1; int row, column; double factor=1000.0; double jac; double xx[2]; double uu[2]; Basis basis; // Create the nodal coordinates double Length=1.0; double dx=Length/((double) NumGlobalElements-1); for (i=0; i < OverlapNumMyElements; i++) { x[i]=dx*((double) OverlapMinMyGID+i); } // Zero out the objects that will be filled if ((flag == MATRIX_ONLY) || (flag == ALL)) i=A->PutScalar(0.0); if ((flag == F_ONLY) || (flag == ALL)) i=rhs->PutScalar(0.0); // Loop Over # of Finite Elements on Processor for (int ne=0; ne < OverlapNumMyElements-1; ne++) { // Loop Over Gauss Points for(int gp=0; gp < 2; gp++) { // Get the solution and coordinates at the nodes xx[0]=x[ne]; xx[1]=x[ne+1]; uu[0]=u[ne]; uu[1]=u[ne+1]; // Calculate the basis function at the gauss point basis.getBasis(gp, xx, uu); // Loop over Nodes in Element for (i=0; i< 2; i++) { row=OverlapMap->GID(ne+i); if (StandardMap->MyGID(row)) { if ((flag == F_ONLY) || (flag == ALL)) { (*rhs)[StandardMap->LID(OverlapMap->GID(ne+i))]+= +basis.wt*basis.dx *((1.0/(basis.dx*basis.dx))*basis.duu* basis.dphide[i]+factor*basis.uu*basis.uu*basis.phi[i]); } } // Loop over Trial Functions if ((flag == MATRIX_ONLY) || (flag == ALL)) { for(j=0;j < 2; j++) { if (StandardMap->MyGID(row)) { column=OverlapMap->GID(ne+j); jac=basis.wt*basis.dx*((1.0/(basis.dx*basis.dx))* basis.dphide[j]*basis.dphide[i] +2.0*factor*basis.uu*basis.phi[j]* basis.phi[i]); ierr=A->SumIntoGlobalValues(row, 1, &jac, &column); } } } } } } // Insert Boundary Conditions and modify Jacobian and function (F) // U(0)=1 if (MyPID==0) { if ((flag == F_ONLY) || (flag == ALL)) (*rhs)[0]= (*soln)[0] - 1.0; if ((flag == MATRIX_ONLY) || (flag == ALL)) { column=0; jac=1.0; A->ReplaceGlobalValues(0, 1, &jac, &column); column=1; jac=0.0; A->ReplaceGlobalValues(0, 1, &jac, &column); } } // Sync up processors to be safe Comm->Barrier(); A->FillComplete(); return true; }