Dear Lucas, thanks very much for replying. I tried to solve the same problem without rotating the domain. I rotated the problem.
Unfortunately the issue is still there. I attach the new images. I also attach the source code again because I realized that the previous one had a misplaced bracket and was giving an error at compile time. I attached the wrong version of the file. Thanks again. Best, Roberto On Friday, April 13, 2018 at 7:54:54 AM UTC-4, Lucas Campos wrote: > > Dear Roberto, > > I think the problem is that you are using GridTools::transform (via > GridTools::rotate), in a distributed triangulation. This should not be > done, as noted here: > https://www.dealii.org/8.5.0/doxygen/deal.II/namespaceGridTools.html#a212e99cf0d923cebfa04f1d23fa60b04 > > If this is indeed the root of the issue, I see two options: > > 1. Rotate your problem, rather than your triangulation, 90 degrees. > 2. You can create a temporary local normal triangulation, rotate it, and > finally copy into the distributed triangulation. That is, something in the > lines of > > >>> Triangulation<2> tri_tmp; >> >> GridGenerator::hyper_cube_slit(tri_tmp, -1, 1, false); >> >> GridTools::rotate(-M_PI/2, tri_tmp); >> >> >>> triangultion.copy_triangulation(tri_tmp); >> >> triangulation.refine_global (6); >> >> Bests, > Lucas > On Thursday, 12 April 2018 00:54:05 UTC+2, Roberto Porcù wrote: >> >> Dear all, >> >> in the reply to my first post I forgot the code. >> I attach it to this reply. >> >> Best >> >> Roberto P. >> >> >> On Tuesday, February 20, 2018 at 7:27:37 PM UTC-5, Roberto Porcù wrote: >>> >>> Dear all, >>> >>> I'm solving a linear elasticity problem on a cracked domain created by >>> means >>> of the GridGenerator::hyper_cube_slit function. >>> When I solve it in serial everything works fine. >>> When I solve it in parallel I get a problem on a node which is on one >>> of the slit boundaries as it is possible to see from the attached >>> pictures. >>> I don't understand why that is happening because I wrote other parallel >>> codes in deal.II >>> and everything was always working fine. I've checked my code many times, >>> also comparing It to the tutorials. >>> I am supposing there is something related to the slit. >>> >>> Thanks in advance, >>> Roberto >>> >> -- 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.
#include <deal.II/base/quadrature_lib.h> #include <deal.II/base/function.h> #include <deal.II/lac/vector.h> #include <deal.II/lac/full_matrix.h> #include <deal.II/lac/solver_cg.h> #include <deal.II/lac/constraint_matrix.h> #include <deal.II/lac/dynamic_sparsity_pattern.h> #include <deal.II/lac/petsc_parallel_sparse_matrix.h> #include <deal.II/lac/petsc_parallel_vector.h> #include <deal.II/lac/petsc_solver.h> #include <deal.II/lac/petsc_precondition.h> #include <deal.II/grid/grid_generator.h> #include <deal.II/grid/grid_tools.h> #include <deal.II/grid/tria_accessor.h> #include <deal.II/grid/tria_iterator.h> #include <deal.II/dofs/dof_handler.h> #include <deal.II/dofs/dof_accessor.h> #include <deal.II/dofs/dof_tools.h> #include <deal.II/fe/fe_values.h> #include <deal.II/fe/fe_q.h> #include <deal.II/fe/fe_nothing.h> #include <deal.II/numerics/vector_tools.h> #include <deal.II/numerics/data_out.h> #include <deal.II/base/utilities.h> #include <deal.II/base/conditional_ostream.h> #include <deal.II/base/index_set.h> #include <deal.II/lac/sparsity_tools.h> #include <deal.II/distributed/tria.h> #include <fstream> #include <iostream> namespace CrackedDomain { namespace aux { class AnalyticalSolution : public dealii::Function<2> { public: AnalyticalSolution() : dealii::Function<2>(1) {} virtual double value(const dealii::Point<2> & p, const unsigned int component=0) const; virtual dealii::Tensor<1,2> gradient(const dealii::Point<2> & p, const unsigned int component=0) const; virtual double laplacian(const dealii::Point<2> & p, const unsigned int component=0) const; virtual double forcing(const dealii::Point<2> & p, const unsigned int component=0) const; }; class LeftCrack : public dealii::Function<2> { public: LeftCrack() : dealii::Function<2>(1) {} virtual double value(const dealii::Point<2> & p, const unsigned int component=0) const; }; class RightCrack : public dealii::Function<2> { public: RightCrack() : dealii::Function<2>(1) {} virtual double value(const dealii::Point<2> & p, const unsigned int component=0) const; }; class LeftEdge : public dealii::Function<2> { public: LeftEdge() : dealii::Function<2>(1) {} virtual double value(const dealii::Point<2> & p, const unsigned int component=0) const; }; class RightEdge : public dealii::Function<2> { public: RightEdge() : dealii::Function<2>(1) {} virtual double value(const dealii::Point<2> & p, const unsigned int component=0) const; }; double AnalyticalSolution::value(const dealii::Point<2> & p, const unsigned int) const { const double x = p[0]; const double y = p[1]; if((y > 0) or (std::abs(y) < 1.e-14)) return 0; if(x > 0) return y*y*std::exp(-1*y); if(x < 0) return -1*y*y*std::exp(-1*y); AssertThrow(false, dealii::ExcMessage("Error")); return 0; } dealii::Tensor<1,2> AnalyticalSolution::gradient(const dealii::Point<2> & p, const unsigned int) const { dealii::Tensor<1,2> result; result = 0; const double x = p[0]; const double y = p[1]; if((y > 0) or (std::abs(y) < 1.e-14)) { return result; } if(x > 0) { result[1] = 2*y*std::exp(-1*y) - y*y*std::exp(-1*y); return result; } if(x < 0) { result[1] = -2*y*std::exp(-1*y) + y*y*std::exp(-1*y); return result; } AssertThrow(false, dealii::ExcMessage("Error")); return result; } double AnalyticalSolution::laplacian(const dealii::Point<2> & p, const unsigned int) const { const double x = p[0]; const double y = p[1]; if((y > 0) or (std::abs(y) < 1.e-14)) return 0; if(x > 0) return 2*std::exp(-1*y) - 4*y*std::exp(-1*y) + y*y*std::exp(-1*y); if(x < 0) return -2*std::exp(-1*y) + 4*y*std::exp(-1*y) - y*y*std::exp(-1*y); AssertThrow(false, dealii::ExcMessage("Error")); return 0; } double AnalyticalSolution::forcing(const dealii::Point<2> & p, const unsigned int component) const { return -1 * laplacian(p, component); } double LeftCrack::value(const dealii::Point<2> & p, const unsigned int) const { const double y = p[1]; return y*y*std::exp(-1*y); } double RightCrack::value(const dealii::Point<2> & p, const unsigned int) const { const double y = p[1]; return -1*y*y*std::exp(-1*y); } double LeftEdge::value(const dealii::Point<2> &, const unsigned int) const { return std::exp(1); } double RightEdge::value(const dealii::Point<2> &, const unsigned int) const { return -1*std::exp(1); } }} namespace CrackedDomain { using namespace dealii; class Problem { public: Problem (); ~Problem (); void run (); private: void setup_system (); void assemble_system (); void solve (); void output_results () const; MPI_Comm mpi_communicator; parallel::distributed::Triangulation<2> triangulation; DoFHandler<2> dof_handler; FE_Q<2> fe; IndexSet locally_owned_dofs; IndexSet locally_relevant_dofs; ConstraintMatrix constraints; PETScWrappers::MPI::SparseMatrix system_matrix; PETScWrappers::MPI::Vector locally_relevant_solution; PETScWrappers::MPI::Vector system_rhs; ConditionalOStream pcout; }; Problem::Problem () : mpi_communicator (MPI_COMM_WORLD) , triangulation (mpi_communicator) , dof_handler (triangulation) , fe (1) , pcout (std::cout, Utilities::MPI::this_mpi_process(mpi_communicator) == 0) {} Problem::~Problem () { dof_handler.clear (); } void Problem::setup_system () { dof_handler.distribute_dofs (fe); locally_owned_dofs = dof_handler.locally_owned_dofs (); DoFTools::extract_locally_relevant_dofs (dof_handler, locally_relevant_dofs); locally_relevant_solution.reinit (locally_owned_dofs, locally_relevant_dofs, mpi_communicator); system_rhs.reinit (locally_owned_dofs, mpi_communicator); aux::AnalyticalSolution exact_sol; aux::LeftCrack left_crack; aux::RightCrack right_crack; aux::LeftEdge left_edge; aux::RightEdge right_edge; constraints.clear (); constraints.reinit (locally_relevant_dofs); DoFTools::make_hanging_node_constraints (dof_handler, constraints); for(unsigned int id(4); id < 7; ++id) dealii::VectorTools::interpolate_boundary_values( dof_handler, id, exact_sol, constraints); dealii::VectorTools::interpolate_boundary_values( dof_handler, 0, right_edge, constraints); dealii::VectorTools::interpolate_boundary_values( dof_handler, 1, left_crack, constraints); dealii::VectorTools::interpolate_boundary_values( dof_handler, 2, right_crack, constraints); dealii::VectorTools::interpolate_boundary_values( dof_handler, 3, left_edge, constraints); constraints.close (); DynamicSparsityPattern dsp (locally_relevant_dofs); DoFTools::make_sparsity_pattern (dof_handler, dsp, constraints, false); SparsityTools::distribute_sparsity_pattern (dsp, dof_handler.n_locally_owned_dofs_per_processor(), mpi_communicator, locally_relevant_dofs); system_matrix.reinit (locally_owned_dofs, locally_owned_dofs, dsp, mpi_communicator); } void Problem::assemble_system () { aux::AnalyticalSolution exact_sol; const QGauss<2> quadrature_formula(2); FEValues<2> 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); std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell); typename DoFHandler<2>::active_cell_iterator cell = dof_handler.begin_active(), endc = dof_handler.end(); for (; cell!=endc; ++cell) if (cell->is_locally_owned()) { cell_matrix = 0; cell_rhs = 0; fe_values.reinit (cell); for (unsigned int q_point=0; q_point<n_q_points; ++q_point) { const Point<2> & p = fe_values.quadrature_point(q_point); const double rhs_value = exact_sol.forcing(p); 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) * fe_values.shape_grad(j,q_point) * fe_values.JxW(q_point)); cell_rhs(i) += (rhs_value * fe_values.shape_value(i,q_point) * fe_values.JxW(q_point)); } } cell->get_dof_indices (local_dof_indices); constraints.distribute_local_to_global (cell_matrix, cell_rhs, local_dof_indices, system_matrix, system_rhs); } system_matrix.compress (VectorOperation::add); system_rhs.compress (VectorOperation::add); } void Problem::solve () { PETScWrappers::MPI::Vector completely_distributed_solution (locally_owned_dofs, mpi_communicator); SolverControl solver_control (dof_handler.n_dofs(), 1e-12); PETScWrappers::SolverCG solver(solver_control, mpi_communicator); PETScWrappers::PreconditionBoomerAMG preconditioner; PETScWrappers::PreconditionBoomerAMG::AdditionalData data; data.symmetric_operator = true; preconditioner.initialize(system_matrix, data); solver.solve (system_matrix, completely_distributed_solution, system_rhs, preconditioner); pcout << " Solved in " << solver_control.last_step() << " iterations." << std::endl; constraints.distribute (completely_distributed_solution); locally_relevant_solution = completely_distributed_solution; } void Problem::output_results () const { dealii::DataOut<2> data_out; data_out.attach_dof_handler(dof_handler); data_out.add_data_vector(locally_relevant_solution, "solution"); std::string filename; const unsigned int n_processes = dealii::Utilities::MPI::n_mpi_processes(mpi_communicator); const unsigned int rank = dealii::Utilities::MPI::this_mpi_process(mpi_communicator); if(n_processes > 1){ filename = "solution-rank" + dealii::Utilities::int_to_string(rank, 2) + ".vtu"; } else{ filename = "solution.vtu"; } data_out.build_patches(); std::ofstream output(filename); data_out.write_vtu(output); } void Problem::run () { GridGenerator::hyper_cube_slit(triangulation, -1, 1, true); triangulation.refine_global (6); // set boundary indicators { FE_Nothing<2> fe_nothing(2); QMidpoint<1> quad; FEFaceValues<2> fe_face_values(fe_nothing, quad, update_normal_vectors); parallel::distributed::Triangulation<2>::active_cell_iterator cell(triangulation.begin_active()), endc(triangulation.end()); for(; cell != endc; ++cell) { if(cell->is_locally_owned()) { for(unsigned int f(0); f<GeometryInfo<2>::faces_per_cell; ++f) { if(cell->face(f)->at_boundary()) { fe_face_values.reinit(cell, f); Point<2> face_center = cell->face(f)->center(); Tensor<1,2> n = fe_face_values.normal_vector(0); const double linfty = std::max(std::abs(n[0]), std::abs(n[1])); n /= linfty; const double x = face_center[0]; const double y = face_center[1]; if((n[1] == -1) and (std::abs(y+1) < 1.e-13) and (x < 0)) cell->face(f)->set_all_boundary_ids(0); if((n[0] == -1) and (std::abs(x) < 1.e-13)) cell->face(f)->set_all_boundary_ids(1); if((n[0] == 1) and (std::abs(x) < 1.e-13)) cell->face(f)->set_all_boundary_ids(2); if((n[1] == -1) and (std::abs(y+1) < 1.e-13) and (x > 0)) cell->face(f)->set_all_boundary_ids(3); if((n[0] == 1) and (std::abs(x-1) < 1.e-13)) cell->face(f)->set_all_boundary_ids(4); if((n[1] == 1) and (std::abs(y-1) < 1.e-13)) cell->face(f)->set_all_boundary_ids(5); if((n[0] == -1) and (std::abs(x+1) < 1.e-13)) cell->face(f)->set_all_boundary_ids(6); } } } } } setup_system (); pcout << " Number of active cells: " << triangulation.n_global_active_cells() << std::endl << " Number of degrees of freedom: " << dof_handler.n_dofs() << std::endl; assemble_system (); solve (); if (Utilities::MPI::n_mpi_processes(mpi_communicator) <= 32) { output_results (); } pcout << std::endl; } } int main(int argc, char *argv[]) { try { using namespace dealii; using namespace CrackedDomain; Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1); Problem problem; problem.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; }