Dear all, I am Boron. I am a new to DEALII. I am currently trying to write a parallel code in DEALII for solving nonlinear Poisson's equation. The file is also attahed below. My doubt is "How do we pass history variable while constructing the cell_matrix?" A code snippet is (Line No 211-225) :
for (; cell!=endc; ++cell) { if (cell->subdomain_id() == this_mpi_process) { cell_matrix = 0; cell_rhs = 0; fe_values.reinit (cell); fe_values.get_function_values(present_solution, old_solution); fe_values.get_function_gradients(present_solution, old_solution_gradients); for (unsigned int q_point=0; q_point<n_q_points; ++q_point) { // BUILD ELEMENTAL CELL MATRIX @ EACH GAUSS POINT } In the above code snippet, the line 'fe_values.get_function_values(present_solution, old_solution); ' throws an error. Is there a way to pass only the vectors relevant to the corresponding subdomains in DEALII? -- The deal.II project is located at http://www.dealii.org/ For mailing list/forum options, see https://groups.google.com/d/forum/dealii?hl=en --- You received this message because you are subscribed to the Google Groups "deal.II User Group" group. To unsubscribe from this group and stop receiving emails from it, send an email to dealii+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
/* PROGRAM TO SOLVE NON-LINEAR POISSON IN PARALLEL USING PETSC*/ // NABLA DOT ((1+U) (NABLA U)) = F // U =sin(3x) * sin(3y) in (0,1)^2 #include <deal.II/base/conditional_ostream.h> #include <deal.II/base/function.h> #include <deal.II/base/logstream.h> #include <deal.II/base/mpi.h> #include <deal.II/base/multithread_info.h> #include <deal.II/base/quadrature_lib.h> #include <deal.II/base/tensor.h> #include <deal.II/base/utilities.h> #include <deal.II/dofs/dof_accessor.h> #include <deal.II/dofs/dof_handler.h> #include <deal.II/dofs/dof_renumbering.h> #include <deal.II/dofs/dof_tools.h> #include <deal.II/fe/fe_q.h> #include <deal.II/fe/fe_values.h> #include <deal.II/fe/fe_system.h> #include <deal.II/grid/grid_generator.h> #include <deal.II/grid/grid_in.h> #include <deal.II/grid/grid_out.h> #include <deal.II/grid/grid_refinement.h> #include <deal.II/grid/grid_tools.h> #include <deal.II/grid/manifold_lib.h> #include <deal.II/grid/tria.h> #include <deal.II/grid/tria_accessor.h> #include <deal.II/grid/tria_iterator.h> #include <deal.II/lac/constraint_matrix.h> #include <deal.II/lac/dynamic_sparsity_pattern.h> #include <deal.II/lac/full_matrix.h> #include <deal.II/lac/petsc_parallel_vector.h> #include <deal.II/lac/petsc_parallel_sparse_matrix.h> #include <deal.II/lac/petsc_precondition.h> #include <deal.II/lac/petsc_solver.h> #include <deal.II/lac/precondition.h> #include <deal.II/lac/sparse_matrix.h> #include <deal.II/lac/sparsity_tools.h> #include <deal.II/lac/solver_cg.h> #include <deal.II/lac/solver_gmres.h> #include <deal.II/lac/vector.h> #include <deal.II/numerics/data_out.h> #include <deal.II/numerics/error_estimator.h> #include <deal.II/numerics/matrix_tools.h> #include <deal.II/numerics/vector_tools.h> #include <iostream> #include <cmath> #include <ctime> #include <fstream> #include <deal.II/numerics/solution_transfer.h> namespace Non_Linear_Poisson { using namespace std; using namespace dealii; template <int dim> class NLPoisson { public: NLPoisson(); ~NLPoisson(); void run(); private: void setup_system(const bool initial_step); void assemble_system(); unsigned int solve(); void refine_mesh(); void set_boundary_values(); double compute_residual(const double alpha) const; double determine_step_length() const; MPI_Comm mpi_communicator; const unsigned int n_mpi_processes; const unsigned int this_mpi_process; ConditionalOStream pcout; Triangulation<dim> triangulation; DoFHandler<dim> dof_handler; FE_Q<dim> fe; ConstraintMatrix hanging_node_constraints; PETScWrappers::MPI::SparseMatrix system_matrix; PETScWrappers::MPI::Vector present_solution; PETScWrappers::MPI::Vector newton_update; PETScWrappers::MPI::Vector system_rhs; }; template <int dim> class BoundaryValues : public Function<dim> { public: BoundaryValues(): Function<dim> () {} virtual double value(const Point<dim> &p, const unsigned int component = 0) const; }; template<int dim> double BoundaryValues<dim>::value(const Point<dim> &p, const unsigned int /*component*/) const { return sin(3*p[0]) * sin(3*p[1]); } template <int dim> class RightHandSide : public Function<dim> { public: RightHandSide(): Function<dim> () {} virtual double value(const Point<dim> &p, const unsigned int component = 0) const; }; template<int dim> double RightHandSide<dim>::value(const Point<dim> &p, const unsigned int /*component*/) const { return 18 * sin(3*p[0]) * sin(3*p[1])* (sin(3*p[0]) * sin(3*p[1]) + 1) - 9*cos(3*p[1])*cos(3*p[1]) * sin(3*p[0])*sin(3*p[0]) - 9*cos(3*p[0])*cos(3*p[0]) * sin(3*p[1])*sin(3*p[1]); } template<int dim> NLPoisson<dim>::NLPoisson() : mpi_communicator (MPI_COMM_WORLD), n_mpi_processes (Utilities::MPI::n_mpi_processes(mpi_communicator)), this_mpi_process (Utilities::MPI::this_mpi_process(mpi_communicator)), pcout (std::cout, (this_mpi_process == 0)), dof_handler(triangulation), fe(1) {} template<int dim> NLPoisson<dim>::~NLPoisson() { dof_handler.clear(); } template <int dim> void NLPoisson<dim>::setup_system(const bool initial_step) { if (initial_step) { pcout<<" inside setup 1"<<endl; GridTools::partition_triangulation (n_mpi_processes, triangulation); dof_handler.distribute_dofs(fe); DoFRenumbering::subdomain_wise (dof_handler); hanging_node_constraints.clear(); DoFTools::make_hanging_node_constraints (dof_handler, hanging_node_constraints); hanging_node_constraints.clear(); const std::vector<IndexSet> locally_owned_dofs_per_proc = DoFTools::locally_owned_dofs_per_subdomain(dof_handler); const IndexSet locally_owned_dofs = locally_owned_dofs_per_proc[this_mpi_process]; present_solution.reinit(locally_owned_dofs, mpi_communicator); } pcout<<" inside setup 2"<<endl; DynamicSparsityPattern dsp(dof_handler.n_dofs(),dof_handler.n_dofs()); DoFTools::make_sparsity_pattern(dof_handler, dsp, hanging_node_constraints, false); const std::vector<IndexSet> locally_owned_dofs_per_proc = DoFTools::locally_owned_dofs_per_subdomain(dof_handler); const IndexSet locally_owned_dofs = locally_owned_dofs_per_proc[this_mpi_process]; system_matrix.reinit(locally_owned_dofs, locally_owned_dofs, dsp, mpi_communicator); newton_update.reinit (locally_owned_dofs, mpi_communicator); system_rhs.reinit (locally_owned_dofs, mpi_communicator); } template <int dim> void NLPoisson<dim>::assemble_system () { pcout<<" inside assembly"<<endl; QGauss<dim> quadrature_formula(3); FEValues<dim> fe_values (fe, quadrature_formula, update_values | update_gradients | update_quadrature_points | update_JxW_values); const unsigned int dofs_per_cell = fe.dofs_per_cell; const unsigned int n_q_points = quadrature_formula.size(); FullMatrix<double> cell_matrix (dofs_per_cell, dofs_per_cell); Vector<double> cell_rhs (dofs_per_cell); const RightHandSide<dim> right_hand_side; std::vector<double> old_solution(n_q_points); std::vector<Tensor<1, dim>> old_solution_gradients(n_q_points); std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell); pcout<<" inside assembly1"<<endl; typename DoFHandler<dim>::active_cell_iterator cell = dof_handler.begin_active(), endc = dof_handler.end(); pcout<<" inside assembly2"<<endl; for (; cell!=endc; ++cell) { if (cell->subdomain_id() == this_mpi_process) { cell_matrix = 0; cell_rhs = 0; fe_values.reinit (cell); fe_values.get_function_values(present_solution, old_solution); fe_values.get_function_gradients(present_solution, old_solution_gradients); for (unsigned int q_point=0; q_point<n_q_points; ++q_point) { // BUILD ELEMENTAL STIFFNESS MATRIX @ EACH GAUSS POINT for (unsigned int i=0; i<dofs_per_cell; ++i) { for (unsigned int j=0; j<dofs_per_cell; ++j) { cell_matrix(i,j)+= ( fe_values.shape_grad(i, q_point) * (1+old_solution[q_point]) * fe_values.shape_grad(j, q_point) + fe_values.shape_grad(i, q_point) * old_solution_gradients[q_point] * fe_values.shape_value(j, q_point) ) * fe_values.JxW(q_point); } } // BUILD ELEMENTAL FORCE VECTOR @ EACH GAUSS POINT for (unsigned int i=0; i<dofs_per_cell; ++i) { cell_rhs(i) += ( fe_values.shape_value(i,q_point) * right_hand_side.value(fe_values.quadrature_point (q_point)) - fe_values.shape_grad(i, q_point) * (1+old_solution[q_point]) * old_solution_gradients[q_point] ) * fe_values.JxW(q_point); } } cell->get_dof_indices (local_dof_indices); hanging_node_constraints.distribute_local_to_global(cell_matrix, cell_rhs, local_dof_indices, system_matrix, system_rhs); } } pcout<<" inside assembly3"<<endl; system_matrix.compress(VectorOperation::add); system_rhs.compress(VectorOperation::add); pcout<<" inside assembly4"<<endl; std::map<types::global_dof_index,double> boundary_values; //VectorTools::interpolate_boundary_values ( dof_handler, // 0, // Functions::ZeroFunction<dim>(dim), // boundary_values); //pcout<<" inside assembly5"<<endl; //MatrixTools::apply_boundary_values ( boundary_values, // system_matrix, // newton_update, // system_rhs, // false); pcout<<" getting out assembly6"<<endl; } template <int dim> unsigned int NLPoisson<dim>::solve() { pcout<<"inside solver"<<endl; SolverControl solver_control(newton_update.size(), system_rhs.l2_norm()*1e-8); PETScWrappers::SolverCG solver(solver_control, mpi_communicator); PETScWrappers::PreconditionBlockJacobi preconditioner(system_matrix); solver.solve (system_matrix, newton_update, system_rhs, preconditioner); Vector<double> localized_newton_update (newton_update); hanging_node_constraints.distribute(localized_newton_update); newton_update = localized_newton_update; const double alpha = determine_step_length(); present_solution.add(alpha, newton_update); pcout<<"done"<<endl; return solver_control.last_step(); } template <int dim> void NLPoisson<dim>::set_boundary_values() { std::map<types::global_dof_index, double> boundary_values; VectorTools::interpolate_boundary_values(dof_handler, 0, BoundaryValues<dim>(), boundary_values); for(std::map<types::global_dof_index, double>::const_iterator p=boundary_values.begin(); p!=boundary_values.end(); ++p) { present_solution(p->first) = p->second; } } template <int dim> double NLPoisson<dim>::determine_step_length() const { return 1; } template <int dim> void NLPoisson<dim>::run() { pcout<<"inside run"<<endl; unsigned int refinement =0; bool first_step=true; const double tolerance = 1e-3; signed int iteration = -1; GridGenerator::hyper_cube (triangulation); triangulation.refine_global(1); double previous_res = 0; while (first_step || ((previous_res>tolerance) && iteration<0)) { iteration=iteration+1; pcout<<"----------------Iteration Number : "<<iteration<<endl; if (first_step == true) { pcout<<"************Inital Mesh************"<<endl; setup_system(true); set_boundary_values(); first_step=false; } else { ++refinement; pcout<<"************Refined Mesh************"<<endl; } for (unsigned int inner_iteration=0; inner_iteration<1; ++inner_iteration) { pcout<<" iteration: "<<inner_iteration<<endl; pcout<<"("; for (unsigned int p=0; p<n_mpi_processes; ++p) { pcout<<(p==0 ? ' ' : '+') << (DoFTools::count_dofs_with_subdomain_association (dof_handler, p)); } pcout << " )" << std::endl; assemble_system(); previous_res=system_rhs.l2_norm(); } } } } int main(int argc, char **argv) { try { using namespace dealii; using namespace Non_Linear_Poisson; Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1); Non_Linear_Poisson::NLPoisson<2> prob; prob.run(); } catch (std::exception &exc) { std::cerr << std::endl << std::endl << "----------------------------------------------------" << std::endl; std::cerr << "Exception on processing: " << std::endl << exc.what() << std::endl << "Aborting!" << std::endl << "----------------------------------------------------" << std::endl; return 1; } catch (...) { std::cerr << std::endl << std::endl << "----------------------------------------------------" << std::endl; std::cerr << "Unknown exception!" << std::endl << "Aborting!" << std::endl << "----------------------------------------------------" << std::endl; return 1; } return 0; }