Hello,

I am trying to solve Laplace with Neumann boundary conditions (step-11). I 
implemented it the following way:

//includes and class definitions

BoundaryValues::BoundaryValues () : Function<2> () {
}

double BoundaryValues::value (const Point<2> &p, const unsigned int) const {
   return 1;
}

double RightHandSide::value (const Point<2> &p, const unsigned int) const {
   return -2;
}

int main (int argc, char *argv[]) {
   Utilities::System::MPI_InitFinalize mpi_initialization (argc, argv);
   LaplaceProblem problem;

   problem.run ();
   return 0;
}

LaplaceProblem::LaplaceProblem () : fe (2), dof_handler (triangulation), 
trilinos_communicator (Utilities::Trilinos::comm_world()) {
}

RightHandSide::RightHandSide () : Function<2> () {
}

void LaplaceProblem::assemble_system () {
//define variables

   for (DoFHandler<2>::active_cell_iterator cell = dof_handler.begin_active 
(); cell != dof_handler.end (); ++cell)
      if (cell->subdomain_id () == Utilities::Trilinos::get_this_mpi_process 
(trilinos_communicator)) {
         cell_matrix = 0;
         cell_rhs = 0;
         fe_values.reinit (cell);

         for (unsigned int q_point = 0; q_point < quadrature.size (); 
++q_point) {
            //assemble local_matrix

               cell_rhs (i) += JxW * right_hand_side.value 
(fe_values.quadrature_point (q_point)) * fe_values.shape_value (i, q_point);
            }
         }

         if (cell->at_boundary ())
            for (unsigned int face = 0; face < 
GeometryInfo<2>::faces_per_cell; ++face)
               if (cell->at_boundary (face)) {
                  fe_face_values.reinit (cell, face);

                  for (unsigned int q_point = 0; q_point < 
face_quadrature.size (); ++q_point) {
                     JxW = fe_face_values.JxW (q_point);

                     for (unsigned int i = 0; i < fe.dofs_per_cell; ++i)
                        cell_rhs (i) += JxW * boundary_values.value 
(fe_face_values.quadrature_point (q_point)) * fe_face_values.shape_value (i, 
q_point);
                  }
               }

         cell->get_dof_indices (cell_dof_indices);
         constraints.distribute_local_to_global (cell_matrix, 
cell_dof_indices, system_matrix);
         constraints.distribute_local_to_global (cell_rhs, cell_dof_indices, 
system_rhs);
      }
}

void LaplaceProblem::create_grid () {
   GridGenerator::hyper_ball (triangulation);

   {
      static const HyperBallBoundary<2> boundary;

      triangulation.set_boundary (0, boundary);
   }

   triangulation.refine_global (5);
   GridTools::partition_triangulation 
(Utilities::Trilinos::get_n_mpi_processes (trilinos_communicator), 
triangulation);
}

void LaplaceProblem::estimate_error () {
//estimator
}

void LaplaceProblem::refine_grid () {
//p-refinement
}

void LaplaceProblem::run () {
   create_grid ();
   setup_system ();
   assemble_system ();
   solve ();
   estimated_error_per_cell.reinit (Epetra_Map (triangulation.n_active_cells 
(), GridTools::count_cells_with_subdomain_association (triangulation, 
Utilities::Trilinos::get_this_mpi_process (trilinos_communicator)), 0, 
trilinos_communicator));
   estimate_error ();

   while (estimated_error_per_cell.l1_norm () > 1e-8) {
      refine_grid ();
      triangulation.prepare_coarsening_and_refinement ();
      triangulation.execute_coarsening_and_refinement ();
      setup_system ();
      assemble_system ();
      solve ();
      estimated_error_per_cell.reinit (Epetra_Map 
(triangulation.n_active_cells (), 
GridTools::count_cells_with_subdomain_association (triangulation, 
Utilities::Trilinos::get_this_mpi_process (trilinos_communicator)), 0, 
trilinos_communicator));
      estimate_error ();
   }
}

void LaplaceProblem::setup_system () {
   dof_handler.distribute_dofs (fe);
   DoFRenumbering::subdomain_wise (dof_handler);
   constraints.clear ();
   DoFTools::make_hanging_node_constraints (dof_handler, constraints);

   {
      std::vector<bool> boundary_dofs (dof_handler.n_dofs (), false);

      DoFTools::extract_boundary_dofs (dof_handler, std::vector<bool> (1, 
true), boundary_dofs);

      const unsigned int first_boundary_dof = std::distance 
(boundary_dofs.begin (), std::find (boundary_dofs.begin (), boundary_dofs.end 
(), true));

      constraints.add_line (first_boundary_dof);

      for (unsigned int i = first_boundary_dof + 1; i < dof_handler.n_dofs (); 
++i)
         if (boundary_dofs[i])
            constraints.add_entry (first_boundary_dof, i, -1);
   }

   constraints.close ();

   Epetra_Map map (dof_handler.n_dofs (), 
DoFTools::count_dofs_with_subdomain_association (dof_handler, 
Utilities::Trilinos::get_this_mpi_process (trilinos_communicator)), 0, 
trilinos_communicator);

   sparsity_pattern.reinit (map);
   DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern, 
constraints, false);
   sparsity_pattern.compress ();
   system_matrix.reinit (sparsity_pattern);
   solution.reinit (map);
   system_rhs.reinit (map);
}

void LaplaceProblem::solve () {
   SolverControl solver_control (system_rhs.size (), 1e-8 *  
system_rhs.l2_norm ());
   SolverCG<TrilinosWrappers::MPI::Vector> cg (solver_control);
   TrilinosWrappers::PreconditionSSOR preconditioner;

   preconditioner.initialize (system_matrix);
   cg.solve (system_matrix, solution, system_rhs, preconditioner);
   constraints.distribute (solution);
}

Unfortunately the cg-method does not converge. What do I have to change to get 
this program running?

Thanks,
Markus
_______________________________________________
dealii mailing list http://poisson.dealii.org/mailman/listinfo/dealii

Reply via email to