void Albany::SolutionMaxValueResponseFunction:: computeMaxValue(const Epetra_Vector& x, double& global_max, int& global_index) { double my_max = -Epetra_MaxDouble; int my_index = -1, index; // Loop over nodes to find max value for equation eq int num_my_nodes = x.MyLength() / neq; for (int node=0; node<num_my_nodes; node++) { if (interleavedOrdering) index = node*neq+eq; else index = node + eq*num_my_nodes; if (x[index] > my_max) { my_max = x[index]; my_index = index; } } // Get max value across all proc's x.Comm().MaxAll(&my_max, &global_max, 1); // Compute min of all global indices equal to max value if (my_max == global_max) my_index = x.Map().GID(my_index); else my_index = x.GlobalLength(); x.Comm().MinAll(&my_index, &global_index, 1); }
int Ifpack_AnalyzeVectorElements(const Epetra_Vector& Diagonal, const bool abs, const int steps) { bool verbose = (Diagonal.Comm().MyPID() == 0); double min_val = DBL_MAX; double max_val = -DBL_MAX; for (int i = 0 ; i < Diagonal.MyLength() ; ++i) { double v = Diagonal[i]; if (abs) if (v < 0) v = -v; if (v > max_val) max_val = v; if (v < min_val) min_val = v; } if (verbose) { cout << endl; Ifpack_PrintLine(); cout << "Vector label = " << Diagonal.Label() << endl; cout << endl; } double delta = (max_val - min_val) / steps; for (int k = 0 ; k < steps ; ++k) { double below = delta * k + min_val; double above = below + delta; int MyBelow = 0, GlobalBelow; for (int i = 0 ; i < Diagonal.MyLength() ; ++i) { double v = Diagonal[i]; if (v < 0) v = -v; if (v >= below && v < above) MyBelow++; } Diagonal.Comm().SumAll(&MyBelow, &GlobalBelow, 1); if (verbose) { printf("Elements in [%+7e, %+7e) = %10d ( = %5.2f %%)\n", below, above, GlobalBelow, 100.0 * GlobalBelow / Diagonal.GlobalLength64()); } } if (verbose) { Ifpack_PrintLine(); cout << endl; } return(0); }
void observeSolution( const Epetra_Vector& solution) { double norm; solution.Norm2(&norm); if (solution.Comm().MyPID()==0) std::cout << "ObserveSolution: Norm = " << norm << std::endl; }
void observeSolution( const Epetra_Vector& solution, double time_or_param_val) { double norm; solution.Norm2(&norm); if (solution.Comm().MyPID()==0) std::cout << "ObserveSolution: Norm = " << norm << " for param/time = " << time_or_param_val << std::endl; }
/****************************************************************** Compute weight balance ******************************************************************/ int compute_balance(const Epetra_Vector &wgts, double myGoalWeight, double &min, double &max, double &avg) { if ((myGoalWeight < 0) || (myGoalWeight > 1.0)){ std::cerr << "compute_balance: Goal weight should be in the range [0, 1]" << std::endl; return -1; } double weightTotal; wgts.Norm1(&weightTotal); double weightLocal = 0.0; for (int i=0; i < wgts.MyLength(); i++){ weightLocal += wgts[i]; } /* My degree of imbalance. * If myGoalWeight is zero, I'm in perfect balance since I got what I wanted. */ double goalWeight = myGoalWeight * weightTotal; double imbalance = 1.0; if (myGoalWeight > 0.0){ if (weightLocal >= goalWeight) imbalance += (weightLocal - goalWeight) / goalWeight; else imbalance += (goalWeight - weightLocal) / goalWeight; } const Epetra_Comm &comm = wgts.Comm(); comm.MaxAll(&imbalance, &max, 1); comm.MinAll(&imbalance, &min, 1); comm.SumAll(&imbalance, &avg, 1); avg /= comm.NumProc(); return 0; }
bool FiniteDifferenceColoring::computeJacobian(const Epetra_Vector& x, Epetra_Operator& Jac) { // First check to make sure Jac is a // NOX::Epetra::FiniteDifferenceColoring object FiniteDifferenceColoring* testMatrix = dynamic_cast<FiniteDifferenceColoring*>(&Jac); if (testMatrix == 0) { cout << "ERROR: NOX::Epetra::FiniteDifferenceColoring::computeJacobian() - " << "Jacobian to evaluate is not a FiniteDifferenceColoring object!" << endl; throw "NOX Error"; } const Epetra_BlockMap& map = fo.Map(); // Create a timer for performance Epetra_Time fillTimer(x.Comm()); // We need the Epetra_CrsMatrix inside the FiniteDifferenceColoring object // for the correct insertion commands. Epetra_CrsMatrix& jac = *testMatrix->jacobian; // Zero out Jacobian jac.PutScalar(0.0); // Create an extra perturbed residual vector pointer if needed if ( diffType == Centered ) if ( Teuchos::is_null(fmPtr) ) fmPtr = Teuchos::rcp(new Epetra_Vector(x)); double scaleFactor = 1.0; if ( diffType == Backward ) scaleFactor = -1.0; int myMin = map.MinMyGID(); // Minimum locally owned GID int myMax = map.MaxMyGID(); // Maximum locally owned GID // We need to loop over the largest number of colors on a processor // Use the overlap (column-space) version of the solution xCol_perturb->Import(x, *rowColImporter, Insert); // Compute the RHS at the initial solution if( coloringType == NOX_SERIAL ) computeF(*xCol_perturb, fo, NOX::Epetra::Interface::Required::FD_Res); else { // x_perturb.Export(*xCol_perturb, *rowColImporter, Insert); for (int i=0; i<x_perturb.MyLength(); i++) x_perturb[i] = (*xCol_perturb)[columnMap->LID(map.GID(i))]; computeF(x_perturb, fo, NOX::Epetra::Interface::Required::FD_Res); } // loop over each color in the colorGraph list<int>::iterator allBegin = listOfAllColors.begin(), allEnd = listOfAllColors.end(), allIter; std::map<int, int>::iterator mapEnd = colorToNumMap.end(), myMapIter; for ( allIter = allBegin; allIter != allEnd; ++allIter ) { bool skipIt = true; // Used to screen colors this proc does not have int k = -1; // index in colorList of color myMapIter = colorToNumMap.find( *allIter ); if( myMapIter != mapEnd ) { skipIt = false; k = (*myMapIter).second; } // Perturb the solution vector using coloring // ----- First create color map and assoc perturbation vectors int color = -1; if( !skipIt ) color = colorList[k]; cMap = colorMap->GenerateMap(color); colorVect = new Epetra_Vector(*cMap); betaColorVect = new Epetra_Vector(*cMap); betaColorVect->PutScalar(beta); // ----- Fill colorVect with computed perturbation values // NOTE that we do the mapping ourselves here instead of using an // Epetra_Import object. This is to ensure local mapping only since // Import/Export operations involve off-processor transfers, which we // wish to avoid. for (int i=0; i<colorVect->MyLength(); i++) (*colorVect)[i] = (*xCol_perturb)[columnMap->LID(cMap->GID(i))]; colorVect->Abs(*colorVect); colorVect->Update(1.0, *betaColorVect, alpha); // ----- Map perturbation vector to original index space // ----- and use it mappedColorVect->PutScalar(0.0); // Here again we do the mapping ourselves to avoid off-processor data // transfers that would accompany use of Epetra_Import/Export objects. for (int i=0; i<colorVect->MyLength(); i++) (*mappedColorVect)[columnMap->LID(cMap->GID(i))] = (*colorVect)[i]; xCol_perturb->Update(scaleFactor, *mappedColorVect, 1.0); // Compute the perturbed RHS if( coloringType == NOX_SERIAL ) computeF(*xCol_perturb, fp, NOX::Epetra::Interface::Required::FD_Res); else { //x_perturb.Export(*xCol_perturb, *rowColImporter, Insert); for (int i=0; i<x_perturb.MyLength(); i++) x_perturb[i] = (*xCol_perturb)[columnMap->LID(map.GID(i))]; computeF(x_perturb, fp, NOX::Epetra::Interface::Required::FD_Res); } if ( diffType == Centered ) { xCol_perturb->Update(-2.0, *mappedColorVect, 1.0); if( coloringType == NOX_SERIAL ) computeF(*xCol_perturb, *fmPtr, NOX::Epetra::Interface::Required::FD_Res); else { //x_perturb.Export(*xCol_perturb, *rowColImporter, Insert); for (int i=0; i<x_perturb.MyLength(); i++) x_perturb[i] = (*xCol_perturb)[columnMap->LID(map.GID(i))]; computeF(x_perturb, *fmPtr, NOX::Epetra::Interface::Required::FD_Res); } } // Compute the column k of the Jacobian // Note that division by the perturbation is delayed until insertion below if ( diffType != Centered ) { Jc.Update(1.0, fp, -1.0, fo, 0.0); } else { Jc.Update(1.0, fp, -1.0, *fmPtr, 0.0); } // Insert nonzero column entries into the jacobian if( !skipIt ) { for (int j = myMin; j < myMax+1; j++) { // Allow for the possibility that rows j from myMin to myMax are not necessarily contigous if (!map.MyGID(j)) continue; int globalColumnID = (*columns)[k][map.LID(j)]; // If using distance1 coloring, only allow diagonal fills if( distance1 && (j != globalColumnID) ) continue; // Skip off-diagonals if( globalColumnID >= 0) { // Now complete the approximation to the derivative by dividing by // the appropriate perturbation if ( diffType != Centered ) Jc[map.LID(j)] /= (scaleFactor * (*mappedColorVect)[columnMap->LID(globalColumnID)]); else Jc[map.LID(j)] /= (2.0 * (*mappedColorVect)[columnMap->LID(globalColumnID)]); int err = jac.ReplaceGlobalValues(j,1,&Jc[map.LID(j)],&globalColumnID); if(err) { cout << "ERROR (" << map.Comm().MyPID() << ") : " << "Inserting global value with indices (" << j << "," << globalColumnID << ") = " << Jc[map.LID(j)] << endl; } } } } // Clean up memory for color-dependent objects delete Importer; Importer = 0; delete betaColorVect; betaColorVect = 0; delete colorVect; colorVect = 0; delete cMap; cMap = 0; // Unperturb the solution vector xCol_perturb->Import(x, *rowColImporter, Insert); } double fillTime = fillTimer.ElapsedTime(); x.Comm().Barrier(); if (utils.isPrintType(Utils::Details)) { for(int n = 0; n < map.Comm().NumProc(); n++) { if(map.Comm().MyPID() == n) cout << "\tTime to fill Jacobian [" << n << "] --> " << fillTime << " sec." << endl; x.Comm().Barrier(); } cout << endl; } jac.FillComplete(); return true; }
bool FiniteDifferenceColoringWithUpdate::differenceProbe(const Epetra_Vector& x, Epetra_CrsMatrix& jac,const Epetra_MapColoring& colors){ // Allocate space for perturbation, get column version of x for scaling Epetra_Vector xp(x); Epetra_Vector *xcol; int N=jac.NumMyRows(); if(jac.ColMap().SameAs(x.Map())) xcol=const_cast<Epetra_Vector*>(&x); else{ xcol=new Epetra_Vector(jac.ColMap(),true);//zeros out by default xcol->Import(x,*jac.Importer(),InsertAdd); } // Counters for probing diagnostics double tmp,probing_error_lower_bound=0.0,jc_norm=0.0; // Grab coloring info (being very careful to ignore color 0) int Ncolors=colors.MaxNumColors()+1; int num_c0_global,num_c0_local=colors.NumElementsWithColor(0); colors.Comm().MaxAll(&num_c0_local,&num_c0_global,1); if(num_c0_global>0) Ncolors--; if(Ncolors==0) return false; // Pointers for Matrix Info int entries, *indices; double *values; // NTS: Fix me if ( diffType == Centered ) exit(1); double scaleFactor = 1.0; if ( diffType == Backward ) scaleFactor = -1.0; // Compute RHS at initial solution computeF(x,fo,NOX::Epetra::Interface::Required::FD_Res); /* Probing, vector by vector since computeF does not have a MultiVector interface */ // Assume that anything with Color 0 gets ignored. for(int j=1;j<Ncolors;j++){ xp=x; for(int i=0;i<N;i++){ if(colors[i]==j) xp[i] += scaleFactor*(alpha*abs(x[i])+beta); } computeF(xp, fp, NOX::Epetra::Interface::Required::FD_Res); // Do the subtraction to estimate the Jacobian (w/o including step length) Jc.Update(1.0, fp, -1.0, fo, 0.0); // Relative error in probing if(use_probing_diags){ Jc.Norm2(&tmp); jc_norm+=tmp*tmp; } for(int i=0;i<N;i++){ // Skip for uncolored row/columns, else update entries if(colors[i]==0) continue; jac.ExtractMyRowView(i,entries,values,indices); for(int k=0;k<jac.NumMyEntries(i);k++){ if(colors[indices[k]]==j){ values[k]=Jc[i] / (scaleFactor*(alpha*abs((*xcol)[indices[k]])+beta)); // If probing diagnostics are on, zero out the entries as they are used if(use_probing_diags) Jc[i]=0.0; break;// Only one value per row... } } } if(use_probing_diags){ Jc.Norm2(&tmp); probing_error_lower_bound+=tmp*tmp; } } // If diagnostics are requested, output Frobenius norm lower bound if(use_probing_diags && !x.Comm().MyPID()) printf("Probing Error Lower Bound (Frobenius) abs = %6.4e rel = %6.4e\n",sqrt(probing_error_lower_bound),sqrt(probing_error_lower_bound)/sqrt(jc_norm)); // Cleanup if(!jac.ColMap().SameAs(x.Map())) delete xcol; return true; }