double ML_DD_Additive(ML_1Level *curr, double *sol, double *rhs, int approx_all_zeros, ML_Comm *comm, int res_norm_or_not, ML *ml) { ML_Operator * Amat = curr->Amat; ML_Operator * Rmat = curr->Rmat; ML_Smoother * post = curr->post_smoother; int lengf = Amat->outvec_leng; int lengc = Rmat->outvec_leng; double * sols = new double[lengf]; double * rhs2 = new double[lengc]; double * sol2 = new double[lengc]; for ( int i = 0; i < lengf; i++ ) sols[i] = 0.0, sol[i] = 0.0; for ( int i = 0; i < lengc; i++ ) sol2[i] = 0.0, rhs2[i] = 0.0; ML_Smoother_Apply(post, lengf, sol, lengf, rhs, approx_all_zeros); ML_Operator_ApplyAndResetBdryPts(Rmat, lengf, rhs, lengc, rhs2); ML_Smoother_Apply(Rmat->to->post_smoother, lengc, sol2, lengc, rhs2, ML_NONZERO); ML_Operator_ApplyAndResetBdryPts(Rmat->to->Pmat, lengc, sol2, lengf, sols); for ( int i = 0; i < lengf; i++ ) sol[i] += sols[i]; delete [] sols; delete [] rhs2; delete [] sol2; return 0.0; }
double ML_DD_Hybrid_2(ML_1Level *curr, double *sol, double *rhs, int approx_all_zeros, ML_Comm *comm, int res_norm_or_not, ML *ml) { ML_Operator *Amat, *Rmat; ML_Smoother *pre, *post; // ML_CSolve *csolve; Amat = curr->Amat; Rmat = curr->Rmat; pre = curr->pre_smoother; post = curr->post_smoother; // csolve = curr->csolve; int lengf = Amat->outvec_leng; int lengc = Rmat->outvec_leng; double * alpha1 = new double[lengf]; double * alpha2 = new double[lengf]; double * tmp_c = new double[lengc]; double * tmp2_c = new double[lengc]; for ( int i = 0; i < lengf ; i++ ) alpha1[i] = 0.0, alpha2[i] = 0.0, sol[i] = 0.0; for ( int i = 0; i < lengc ; i++ ) tmp_c[i] = 0.0, tmp2_c[i] = 0.0; // first step ML_Smoother_Apply(pre, lengf, alpha1, lengf, rhs, approx_all_zeros); // second step ML_Operator_ApplyAndResetBdryPts(Amat, lengf, alpha1, lengc, sol); for ( int i = 0; i < lengf; i++ ) sol[i] = rhs[i] - sol[i]; ML_Operator_ApplyAndResetBdryPts(Rmat, lengf, sol, lengc, tmp_c); ML_Smoother_Apply(Rmat->to->post_smoother, lengc, tmp2_c, lengc, tmp_c, ML_NONZERO); ML_Operator_ApplyAndResetBdryPts(Rmat->to->Pmat, lengc, tmp2_c, lengf, alpha2); // third step for ( int i = 0; i < lengf ; i++ ) alpha1[i] += alpha2[i]; for ( int i = 0; i < lengf ; i++ ) alpha2[i] = 0.0, sol[i] = 0.0; ML_Operator_ApplyAndResetBdryPts(Amat, lengf, alpha1, lengc, alpha2); for ( int i = 0; i < lengf; i++ ) alpha2[i] = rhs[i] - alpha2[i] ; ML_Smoother_Apply(post, lengf, sol, lengf, alpha2, approx_all_zeros); // compose solution for ( int i = 0; i < lengf; i++ ) sol[i] += alpha1[i]; delete [] alpha1; delete [] alpha2; delete [] tmp_c; delete [] tmp2_c; return 0.0; }
double ML_DD_OneLevel(ML_1Level *curr, double *sol, double *rhs, int approx_all_zeros, ML_Comm *comm, int res_norm_or_not, ML *ml) { ML_Smoother * post = curr->post_smoother; ML_Operator * Amat = curr->Amat; int lengf = Amat->outvec_leng; for ( int i = 0; i < lengf; i++ ) sol[i] = 0.0; ML_Smoother_Apply(post, lengf, sol, lengf, rhs, approx_all_zeros); return 0.0; } /* ML_DD_OneLevel */
// ============================================================================ // Visualize aggregates and (for XYZ or VTK format) also plot vectors // date: Aug-04 int ML_Epetra::MultiLevelPreconditioner:: Visualize(bool VizAggre, bool VizPreSmoother, bool VizPostSmoother, bool VizCycle, int NumApplPreSmoother, int NumApplPostSmoother, int NumCycleSmoother) { ML_Aggregate *aggregates = agg_; char filename[80] = ""; int NumDimensions = 0; ML_Aggregate_Viz_Stats *grid_info = (ML_Aggregate_Viz_Stats *) ml_->Grid[LevelID_[0]].Grid; double * x_coord = grid_info->x; double * y_coord = grid_info->y; double * z_coord = grid_info->z; if( x_coord ) NumDimensions++; if( y_coord ) NumDimensions++; if( z_coord ) NumDimensions++; assert( NumDimensions != 0 ); if (VizAggre == true) { // stats about level matrix sizes if( verbose_ ) std::cout << std::endl << "- number of rows for each level's matrix:" << std::endl << std::endl; for( int ilevel=0 ; ilevel < NumLevels_ ; ++ilevel ) { int imin, iavg, imax; int Nrows = ml_->Amat[LevelID_[ilevel]].outvec_leng/NumPDEEqns_; Comm().MinAll(&Nrows,&imin,1); Comm().MaxAll(&Nrows,&imax,1); Comm().SumAll(&Nrows,&iavg,1); iavg /= Comm().NumProc(); if( verbose_ ) { printf( "\t(level %d) rows per process (min) = %d\n", ilevel, imin); printf( "\t(level %d) rows per process (avg) = %d\n", ilevel, iavg); printf( "\t(level %d) rows per process (max) = %d\n", ilevel, imax); std::cout << std::endl; } } if( verbose_ ) std::cout << std::endl << "- analysis of the computational domain (finest level):" << std::endl << std::endl; ML_Aggregate_Stats_Analyze(ml_,aggregates); } // prepare output format. Now it can be: // - OpenDX (1D/2D/3D) // - XD3D (2D only) // - Paraview, or any other package that can read .vtk files (1D/2D/3D) int Format; std::string FileFormat = List_.get("viz: output format", "vtk"); // you are a cool guy if you plot with "xyz" if( FileFormat == "xyz" ) Format = 1; // you are a poor man if you need "dx". God bless you. else if( FileFormat == "dx" ) Format = 0; // you are a very cool guy if you plot with the "vtk" option (paraview) else if( FileFormat == "vtk" ) Format = 2; else { std::cerr << ErrorMsg_ << "Option `viz: output format' has an incorrect" << std::endl << ErrorMsg_ << "value (" << FileFormat << "). Possible values are" << std::endl << ErrorMsg_ << "<dx> / <xyz> / <vtk>" << std::endl; exit( EXIT_FAILURE ); } int ieqn = List_.get("viz: equation to plot", -1); if (AMGSolver_ == ML_MAXWELL) ieqn = -1; if( ieqn >= NumPDEEqns_ ) ieqn = 0; bool PrintStarting = List_.get("viz: print starting solution", false); ML_Smoother * ptr; double * tmp_rhs = new double[NumMyRows()]; double * tmp_sol = new double[NumMyRows()]; double * plot_me = new double[NumMyRows()/NumPDEEqns_]; // Note that this requires the new version of the // visualization routines. OpenDX cannot visualize vectors. if( ( VizPreSmoother || VizPostSmoother || VizCycle ) && ( Format == 0) ) { std::cerr << std::endl; std::cerr << ErrorMsg_ << "Option `viz: output format' == `dx' cannot be used" << std::endl << ErrorMsg_ << "to visualize the effect of smoothers and cycle." << std::endl; std::cerr << std::endl; VizPreSmoother = false; VizPostSmoother = false; VizCycle = false; } if( verbose_ ) std::cout << std::endl << "- visualization:" << std::endl << std::endl; // =============================================================== // // cycle over all levels. Note that almost the same thing // // is done for pre-smoothing, post-smoothing, and the effect // // of the cycle itself. For each of these, I plot on file // // the starting solution (before-), the final solution (after-), // // for each equation, and for each level (smoother only). // // All these junk works with XYZ only, and it should work in // // 3D too (although I never tested in 3D). // // // // JJH 3/11/2005 Paraview has been tested in 3D for .vtk output, // // and it works. // // =============================================================== // std::cout << "cycling thru levels 0 to " << NumLevels_ -1 << std::endl; for( int ilevel=0 ; ilevel<NumLevels_ ; ++ilevel ) { // =================== // // plot the aggregates // // =================== // if( VizAggre ) ML_Aggregate_Viz(ml_,aggregates,Format,NULL,NULL,LevelID_[ilevel]); // ============ // // pre-smoother // // ============ // ptr = ((ml_->SingleLevel[LevelID_[ilevel]]).pre_smoother); if( ptr != NULL && VizPreSmoother ) { RandomAndZero(tmp_sol,tmp_rhs,ml_->Amat[LevelID_[ilevel]].outvec_leng); // visualize starting vector if( PrintStarting ) { if( ieqn != -1 ) { for( int i=0 ; i<NumMyRows() ; i+=NumPDEEqns_ ) plot_me[i/NumPDEEqns_] = tmp_sol[i+ieqn]; sprintf(filename,"before-presmoother-eq%d", ieqn); printf("%s, numrows = %d\n",filename, NumMyRows()); ML_Aggregate_Viz(ml_,aggregates,Format,plot_me, filename,LevelID_[ilevel]); } else { // by default, print out all equations for( int eq=0 ; eq<NumPDEEqns_ ; eq++ ) { sprintf(filename,"before-presmoother-eq%d", eq); printf("%s, numrows = %d\n",filename, NumMyRows()); for( int i=0 ; i<NumMyRows() ; i+=NumPDEEqns_ ) { plot_me[i/NumPDEEqns_] = tmp_sol[i+eq]; //FIXME JJH temporary print //printf("(eq %d, %d) %d: %lf\n",eq,LevelID_[ilevel],i,tmp_sol[i+eq]); } ML_Aggregate_Viz(ml_,aggregates,Format,plot_me, filename,LevelID_[ilevel]); } } } // increase the number of applications of the smoother // and run the smoother int old_ntimes = ptr->ntimes; ptr->ntimes = NumApplPreSmoother; ML_Smoother_Apply(ptr, ml_->Amat[LevelID_[ilevel]].outvec_leng, tmp_sol, ml_->Amat[LevelID_[ilevel]].outvec_leng, tmp_rhs, ML_NONZERO); ptr->ntimes = old_ntimes; // visualize // user may have required one specific equation only if( ieqn != -1 ) { for( int i=0 ; i<NumMyRows() ; i+=NumPDEEqns_ ) plot_me[i/NumPDEEqns_] = tmp_sol[i+ieqn]; sprintf(filename,"after-presmoother-eq%d", ieqn); ML_Aggregate_Viz(ml_,aggregates,Format,plot_me, filename,LevelID_[ilevel]); } else { // by default, print out all equations for( int eq=0 ; eq<NumPDEEqns_ ; eq++ ) { for( int i=0 ; i<NumMyRows() ; i+=NumPDEEqns_ ) plot_me[i/NumPDEEqns_] = tmp_sol[i+eq]; sprintf(filename,"after-presmoother-eq%d", eq); ML_Aggregate_Viz(ml_,aggregates,Format,plot_me, filename,LevelID_[ilevel]); } } } // VizPreSmoother // ============= // // post-smoother // // ============= // ptr = ((ml_->SingleLevel[LevelID_[ilevel]]).post_smoother); if( ptr != NULL && VizPostSmoother ) { // random solution and 0 rhs RandomAndZero(tmp_sol,tmp_rhs,ml_->Amat[LevelID_[ilevel]].outvec_leng); // visualize starting vector if( PrintStarting ) { if( ieqn != -1 ) { for( int i=0 ; i<NumMyRows() ; i+=NumPDEEqns_ ) plot_me[i/NumPDEEqns_] = tmp_sol[i+ieqn]; sprintf(filename,"before-postsmoother-eq%d", ieqn); ML_Aggregate_Viz(ml_,aggregates,Format,plot_me, filename,LevelID_[ilevel]); } else { // by default, print out all equations for( int eq=0 ; eq<NumPDEEqns_ ; eq++ ) { for( int i=0 ; i<NumMyRows() ; i+=NumPDEEqns_ ) plot_me[i/NumPDEEqns_] = tmp_sol[i+eq]; sprintf(filename,"before-postsmoother-eq%d", eq); ML_Aggregate_Viz(ml_,aggregates,Format,plot_me, filename,LevelID_[ilevel]); } } } // increase the number of applications of the smoother // and run the smoother int old_ntimes = ptr->ntimes; ptr->ntimes = NumApplPostSmoother; ML_Smoother_Apply(ptr, ml_->Amat[LevelID_[ilevel]].outvec_leng, tmp_sol, ml_->Amat[LevelID_[ilevel]].outvec_leng, tmp_rhs, ML_ZERO); ptr->ntimes = old_ntimes; // visualize // user may have required one specific equation only if( ieqn != -1 ) { for( int i=0 ; i<NumMyRows() ; i+=NumPDEEqns_ ) plot_me[i/NumPDEEqns_] = tmp_sol[i+ieqn]; printf(filename,"after-postsmoother-eq%d", ieqn); ML_Aggregate_Viz(ml_,aggregates,Format,plot_me, filename,LevelID_[ilevel]); } else { // by default, print out all equations for( int eq=0 ; eq<NumPDEEqns_ ; eq++ ) { for( int i=0 ; i<NumMyRows() ; i+=NumPDEEqns_ ) plot_me[i/NumPDEEqns_] = tmp_sol[i+eq]; sprintf(filename,"after-postsmoother-eq%d", eq); ML_Aggregate_Viz(ml_,aggregates,Format,plot_me, filename,LevelID_[ilevel]); } } } // VizPostSmoother } // for( ilevel ) // =============================== // // run ML cycle on a random vector // // =============================== // if( VizCycle ) { // random solution and zero rhs RandomAndZero(tmp_sol, tmp_rhs,ml_->Amat[LevelID_[0]].outvec_leng); // visualize starting vector if( PrintStarting ) { if( ieqn != -1 ) { for( int i=0 ; i<NumMyRows() ; i+=NumPDEEqns_ ) plot_me[i/NumPDEEqns_] = tmp_sol[i+ieqn]; sprintf(filename,"before-cycle-eq%d", ieqn); ML_Aggregate_Viz(ml_,aggregates,Format,plot_me,filename,LevelID_[0]); } else { // by default, print out all equations for( int eq=0 ; eq<NumPDEEqns_ ; eq++ ) { for( int i=0 ; i<NumMyRows() ; i+=NumPDEEqns_ ) plot_me[i/NumPDEEqns_] = tmp_sol[i+eq]; sprintf(filename,"before-cycle-eq%d", eq); ML_Aggregate_Viz(ml_,aggregates,Format,plot_me, filename,LevelID_[0]); } } } // run the cycle for( int i=0 ; i<NumCycleSmoother ; ++i ) ML_Cycle_MG(&(ml_->SingleLevel[ml_->ML_finest_level]), tmp_sol, tmp_rhs, ML_NONZERO, ml_->comm, ML_NO_RES_NORM, ml_); // visualize // user may have required one specific equation only if( ieqn != -1 ) { for( int i=0 ; i<NumMyRows() ; i+=NumPDEEqns_ ) plot_me[i/NumPDEEqns_] = tmp_sol[i+ieqn]; sprintf(filename,"after-cycle-eq%d", ieqn); ML_Aggregate_Viz(ml_,aggregates,Format,plot_me,filename,LevelID_[0]); } else { // by default, print out all equations for( int eq=0 ; eq<NumPDEEqns_ ; eq++ ) { for( int i=0 ; i<NumMyRows() ; i+=NumPDEEqns_ ) plot_me[i/NumPDEEqns_] = tmp_sol[i+eq]; sprintf(filename,"after-cycle-eq%d", eq); ML_Aggregate_Viz(ml_,aggregates,Format,plot_me,filename,LevelID_[0]); } } } // VizCycle // =================== // // clean up and return // // =================== // delete [] tmp_sol; delete [] tmp_rhs; delete [] plot_me; return(0); }