/** Run solver iterations. */ int SweepSolver (Grid_Data *grid_data, bool block_jacobi) { Kernel *kernel = grid_data->kernel; int mpi_rank = 0; #ifdef KRIPKE_USE_MPI MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); #endif BLOCK_TIMER(grid_data->timing, Solve); // Loop over iterations double part_last = 0.0; for(int iter = 0;iter < grid_data->niter;++ iter){ /* * Compute the RHS: rhs = LPlus*S*L*psi + Q */ // Discrete to Moments transformation (phi = L*psi) { BLOCK_TIMER(grid_data->timing, LTimes); kernel->LTimes(grid_data); } // Compute Scattering Source Term (psi_out = S*phi) { BLOCK_TIMER(grid_data->timing, Scattering); kernel->scattering(grid_data); } // Compute External Source Term (psi_out = psi_out + Q) { BLOCK_TIMER(grid_data->timing, Source); kernel->source(grid_data); } // Moments to Discrete transformation (rhs = LPlus*psi_out) { BLOCK_TIMER(grid_data->timing, LPlusTimes); kernel->LPlusTimes(grid_data); } /* * Sweep (psi = Hinv*rhs) */ { BLOCK_TIMER(grid_data->timing, Sweep); if(true){ // Create a list of all groups std::vector<int> sdom_list(grid_data->subdomains.size()); for(int i = 0;i < grid_data->subdomains.size();++ i){ sdom_list[i] = i; } // Sweep everything SweepSubdomains(sdom_list, grid_data, block_jacobi); } // This is the ARDRA version, doing each groupset sweep independently else{ for(int group_set = 0;group_set < grid_data->num_group_sets;++ group_set){ std::vector<int> sdom_list; // Add all subdomains for this groupset for(int s = 0;s < grid_data->subdomains.size();++ s){ if(grid_data->subdomains[s].idx_group_set == group_set){ sdom_list.push_back(s); } } // Sweep the groupset SweepSubdomains(sdom_list, grid_data, block_jacobi); } } } { BLOCK_TIMER(grid_data->timing, ParticleEdit); double part = grid_data->particleEdit(); if(mpi_rank==0){ printf("iter %d: particle count=%e, change=%e\n", iter, part, (part-part_last)/part); } part_last = part; } } return(0); }