Dear all, I'm am trying to reproduce with my implementation, the results in the Photonic Crystal computations performed in [1]. Here, the author uses a grid with an inner disk with radius R=0.475, and for FEM it is used the software Concepts [2] that implements curvilinear elements denoted Blending technique, or transfinite interpolation in quadrilaterals [3], [4,p. 144]. Exponential convergence was obtained for the p-FEM version.
By using the deal.II SphericalManifold, I can only get with the attached code up to R<0.46, before I get the exception: "The image of the mapping applied to cell with center [0.446317 -0.206317] is distorted. The cell geometry or the mapping are invalid, giving a non-positive volume fraction of -0.000129188 in quadrature point 54." I am attaching a minimal test case (modified from step-10) that reproduces the errors: mesh_test.cc and the code for the same mesh used in [1], adapted to deal.II standards in: unit_cell.h The question is then if it is possible to get this example running for R=0.475, in order to reproduce the results in [1]. Is there something I am doing wrong that can be improved? Can this behaviour be explained by round off's? Furthermore, is anyone implementing transfinite interpolation [3,4] in deal.II? Thanks in advance, any help is greatly appreciated! References: [1] Engström, C.,Spectral approximation of quadratic operator polynomials arising in photonic band structure calculations, Numer. Math. (2014) 126: 413. [2] Concepts web page: http://wiki.math.ethz.ch/Concepts/WebRoot?redirectedfrom=Concepts.WebHome [3] W. J. Gordon, C. A. Hall, Construction of curvilinear coordinate systems and application to mesh generation Int. J. Num. Meth. Eng., Vol. 7 (1973), pp. 461-477 [4] Pavel Solin, Karel Segeth, Ivo Dolezel, Higher-Order Finite Element Methods, Studies in Advanced Mathematics, CRC Press, 2003. -- 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.
/* --------------------------------------------------------------------- * * Copyright (C) 2001 - 2014 by the deal.II authors * * This file is part of the deal.II library. * * The deal.II library is free software; you can use it, redistribute * it, and/or modify it under the terms of the GNU Lesser General * Public License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * The full text of the license can be found in the file LICENSE at * the top level of the deal.II distribution. * * --------------------------------------------------------------------- * * Authors: Wolfgang Bangerth, Ralf Hartmann, University of Heidelberg, 2001 */ #include <deal.II/base/quadrature_lib.h> #include <deal.II/base/convergence_table.h> #include <deal.II/grid/grid_generator.h> #include <deal.II/grid/tria_accessor.h> #include <deal.II/grid/tria_iterator.h> #include <deal.II/grid/manifold_lib.h> #include <deal.II/grid/tria.h> #include <deal.II/grid/grid_out.h> #include <deal.II/dofs/dof_handler.h> #include <deal.II/dofs/dof_accessor.h> #include <deal.II/fe/fe_q.h> #include <deal.II/fe/fe_values.h> #include <deal.II/fe/mapping_q.h> #include <iostream> #include <fstream> #include <cmath> // added lines #include "unit_cell.h" #include <deal.II/numerics/data_out.h> namespace Step10 { using namespace dealii; const long double pi = 3.141592653589793238462643; template <int dim> void gnuplot_output() { std::cout << "Output of grids into gnuplot files:" << std::endl << "===================================" << std::endl; Triangulation<dim> triangulation; GridGenerator::hyper_ball (triangulation); static const SphericalManifold<dim> boundary; triangulation.set_all_manifold_ids_on_boundary(0); triangulation.set_manifold (0, boundary); for (unsigned int refinement=0; refinement<2; ++refinement, triangulation.refine_global(1)) { std::cout << "Refinement level: " << refinement << std::endl; std::string filename_base = "ball"; filename_base += '0'+refinement; for (unsigned int degree=1; degree<4; ++degree) { std::cout << "Degree = " << degree << std::endl; const MappingQ<dim> mapping (degree); GridOut grid_out; GridOutFlags::Gnuplot gnuplot_flags(false, 30); grid_out.set_flags(gnuplot_flags); std::string filename = filename_base+"_mapping_q"; filename += ('0'+degree); filename += ".dat"; std::ofstream gnuplot_file (filename.c_str()); grid_out.write_gnuplot (triangulation, gnuplot_file, &mapping); } std::cout << std::endl; } } template <int dim> void compute_pi_by_area () { std::cout << "Computation of Pi by the area:" << std::endl << "==============================" << std::endl; // const QGauss<dim> quadrature(4); for (double R=0.45; R < 0.5; R += 0.005) for (unsigned int degree=1; degree<11; ++degree) { std::cout << "Radius = " << R << std::endl; std::cout << "Degree = " << degree << std::endl; Triangulation<dim> triangulation; // GridGenerator::hyper_ball (triangulation); // new lines Geom_parameters gp; unsigned int curved_faces_label=10; cell_rod ( triangulation, 1.0, R, gp, false ); static const SphericalManifold<dim> boundary; triangulation.set_manifold ( curved_faces_label, boundary ); // labels defined with the grid // triangulation.set_all_manifold_ids_on_boundary (0); const MappingQ<dim> mapping (degree, true); const QGauss<dim> quadrature(degree); // const FE_Q<dim> dummy_fe (1); const FE_Q<dim> dummy_fe (QGaussLobatto<1>(degree + 1)); DoFHandler<dim> dof_handler (triangulation); FEValues<dim> fe_values (mapping, dummy_fe, quadrature, update_JxW_values); ConvergenceTable table; // No refinements for (unsigned int refinement=0; refinement<1; ++refinement, triangulation.refine_global (1)) { table.add_value("cells", triangulation.n_active_cells()); dof_handler.distribute_dofs (dummy_fe); long double area = 0; typename DoFHandler<dim>::active_cell_iterator cell = dof_handler.begin_active(), endc = dof_handler.end(); for (; cell!=endc; ++cell) { double r = cell->center ().distance(Point<dim>(0,0)); fe_values.reinit (cell); for (unsigned int i=0; i<fe_values.n_quadrature_points; ++i) { if (r < R) area += fe_values.JxW (i); } }; double new_area = area/(R*R); table.add_value("eval.pi", static_cast<double> (new_area)); table.add_value("error", static_cast<double> (std::fabs(new_area-pi))); DataOut<dim> data_out; data_out.attach_dof_handler (dof_handler); Vector<double> dummy ( dof_handler.n_dofs() ); string name = "grid"; data_out.add_data_vector (dummy, name ); std::ostringstream ss; ss <<"grid_R" << R << "_p" << degree << "_ref" << refinement << ".vtk"; std::ofstream output (ss.str().c_str()); data_out.build_patches (mapping, 8, DataOut<dim>::curved_inner_cells); data_out.write_vtk (output); }; table.omit_column_from_convergence_rate_evaluation("cells"); table.omit_column_from_convergence_rate_evaluation("eval.pi"); table.evaluate_all_convergence_rates(ConvergenceTable::reduction_rate_log2); table.set_precision("eval.pi", 16); table.set_scientific("error", true); table.write_text(std::cout); std::cout << std::endl; }; } } int main () { try { std::cout.precision (16); Step10::compute_pi_by_area<2> (); } 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; }
#include <deal.II/grid/tria.h> #include <deal.II/grid/tria_accessor.h> #include <deal.II/grid/tria_iterator.h> #include <deal.II/grid/grid_generator.h> #include <deal.II/grid/grid_tools.h> #include <deal.II/grid/tria_boundary_lib.h> #include <deal.II/grid/grid_out.h> #include <deal.II/grid/grid_in.h> #include <deal.II/grid/grid_reordering.h> // #include <deal.II/grid/manifold_lib.h> #include <fstream> #include <assert.h> #include <map> #define PI 3.14159265358979323846 using namespace dealii; using namespace std; struct Geom_parameters { /* * model: geometric configuration, parameters must be dependent on the model problem */ unsigned int n_scatterers, scatterers_coarse_cells, n_balls, coated_coarse_cells, defective_index; double coat_radius; bool coated=false; bool defect=false; bool defect_n2=false; vector< Point<2> > ball_centers; vector<double> radius; vector<double> radius_PML; vector<unsigned int> ball_labels; // double a; string name; }; // In the article "Spectral approximation of quadratic operator polynomials arising in photonic band structure calculations", Christian Engström 2012, // // This mesh is used with R=0.475 and exponential convergence is obtained. // Check figure 1, and figure 3 on the mentioned paper. // // http://link.springer.com/article/10.1007/s00211-013-0568-y // // Software Concepts: // http://wiki.math.ethz.ch/Concepts/WebRoot?redirectedfrom=Concepts.WebHome void cell_rod ( Triangulation<2> &tria, double L, double r, // 2*r/L < 1.0 Geom_parameters &gp, bool mesh_out) { double l = 0.5*L, d = 0.5*r, q=1.0/sqrt(2.0); // q: corner points factor const unsigned int n = 2, n_vert = 24+1, n_cell = 19+1; bool info = false, plot_eps = true; // for printing cells, faces and vertex values int fv = 4, fc = 1; // f: fixed, displacement of index on the vertexes and cells ... inner objects // geometric information----------------------- gp.n_scatterers = 1; gp.scatterers_coarse_cells = 12; gp.n_balls = 1; // just one Manifold ... everything centered at origin gp.ball_centers.resize( gp.n_balls ); gp.radius.resize(gp.n_balls); gp.radius[0]=r; gp.ball_centers[0] = Point<2>( 0.0, 0.0 ); gp.name = "cell_rod"; if(mesh_out) printf("%% defined by using %d balls\n", gp.n_balls); std::vector<Point<2> > vertices(n_vert); vertices[0] = Point<2>( 0.0, 0.0 ); // inner 4 squares vertices[1] = Point<2>( d, 0.0 ); vertices[2] = Point<2>( .5*d, .5*d ); vertices[3] = Point<2>( 0.0, d ); vertices[4] = Point<2>( -.5*d, .5*d ); vertices[5] = Point<2>( -d, 0.0 ); vertices[6] = Point<2>( -.5*d, -.5*d ); vertices[7] = Point<2>( 0.0, -d ); vertices[8] = Point<2>( .5*d, -.5*d ); // touching circle vertices[9] = Point<2>( r, 0.0 ); vertices[10] = Point<2>( r*q, r*q ); vertices[11] = Point<2>( 0.0, r ); vertices[12] = Point<2>( -r*q, r*q ); vertices[13] = Point<2>( -r, 0.0 ); vertices[14] = Point<2>( -r*q, -r*q ); vertices[15] = Point<2>( 0.0, -r ); vertices[16] = Point<2>( r*q, -r*q ); vertices[17] = Point<2>( l, 0.0 ); vertices[18] = Point<2>( l, l ); vertices[19] = Point<2>( 0.0, l ); vertices[20] = Point<2>( -l, l ); vertices[21] = Point<2>( -l, 0.0 ); vertices[22] = Point<2>( -l, -l ); vertices[23] = Point<2>( 0.0, -l ); vertices[24] = Point<2>( l, -l ); //vertices[] = Point<2>( , ); std::vector< std::vector<int> > cell_v (n_cell, std::vector<int>(4)); cell_v[0][0] = 0; // cell, i = 0 cell_v[0][1] = 8; cell_v[0][2] = 2; cell_v[0][3] = 1; cell_v[1][0] = 0; // cell, i = 1 cell_v[1][1] = 2; cell_v[1][2] = 4; cell_v[1][3] = 3; cell_v[2][0] = 0; // cell, i = 2 cell_v[2][1] = 4; cell_v[2][2] = 6; cell_v[2][3] = 5; cell_v[3][0] = 0; // cell, i = 3 cell_v[3][1] = 6; cell_v[3][2] = 8; cell_v[3][3] = 7; cell_v[4][0] = 8; // cell, i = 4 cell_v[4][1] = 16; cell_v[4][2] = 1; cell_v[4][3] = 9; cell_v[5][0] = 2; // cell, i = 5 cell_v[5][1] = 1; cell_v[5][2] = 10; cell_v[5][3] = 9; cell_v[6][0] = 2; // cell, i = 6 cell_v[6][1] = 10; cell_v[6][2] = 3; cell_v[6][3] = 11; cell_v[7][0] = 4; // cell, i = 7 cell_v[7][1] = 3; cell_v[7][2] = 12; cell_v[7][3] = 11; cell_v[8][0] = 4; // cell, i = 8 cell_v[8][1] = 12; cell_v[8][2] = 5; cell_v[8][3] = 13; cell_v[9][0] = 6; // cell, i = 9 cell_v[9][1] = 5; cell_v[9][2] = 14; cell_v[9][3] = 13; cell_v[10][0] = 6; // cell, i = 10 cell_v[10][1] = 14; cell_v[10][2] = 7; cell_v[10][3] = 15; cell_v[11][0] = 8; // cell, i = 11 cell_v[11][1] = 7; cell_v[11][2] = 16; cell_v[11][3] = 15; // cell 12 cell_v[12][0] = 16; // cell, i = 12 cell_v[12][1] = 24; cell_v[12][2] = 9; cell_v[12][3] = 17; // cell 13 cell_v[13][0] = 10; // cell, i = 13 cell_v[13][1] = 9; cell_v[13][2] = 18; cell_v[13][3] = 17; // cell 14 cell_v[14][0] = 10; // cell, i = 14 cell_v[14][1] = 18; cell_v[14][2] = 11; cell_v[14][3] = 19; // cell 15 cell_v[15][0] = 12; // cell, i = 15 cell_v[15][1] = 11; cell_v[15][2] = 20; cell_v[15][3] = 19; // cell 16 cell_v[16][0] = 12; // cell, i = 16 cell_v[16][1] = 20; cell_v[16][2] = 13; cell_v[16][3] = 21; // cell 17 cell_v[17][0] = 14; // cell, i = 17 cell_v[17][1] = 13; cell_v[17][2] = 22; cell_v[17][3] = 21; // cell 18 cell_v[18][0] = 14; // cell, i = 18 cell_v[18][1] = 22; cell_v[18][2] = 15; cell_v[18][3] = 23; // cell 19 cell_v[19][0] = 16; // cell, i = cell_v[19][1] = 15; cell_v[19][2] = 24; cell_v[19][3] = 23; if (info) { for (unsigned int i = 0; i < n_cell; ++i) if(info) printf("cell[%d] = (%d,%d,%d,%d)\n", i, cell_v[i][0], cell_v[i][1],cell_v[i][2],cell_v[i][3]); } std::vector<CellData<2> > cells (n_cell, CellData<2>()); unsigned int cell_idx = 0; for (unsigned int i=0; i < n_cell; ++i) { // printf("%d: ", i); for (unsigned int j=0; j < 4; ++j) { cells[i].vertices[j] = cell_v[i][j]; if(info) printf("%d ",cell_v[i][j]); } if(info) printf(";\n"); cell_idx++; } for (unsigned int i=0; i < n_vert; ++i) { if(info) printf(" %f, %f;\n", vertices[i][0],vertices[i][1] ); } if(info) printf("\n\n"); //printf("after grid ordering\n"); tria.create_triangulation ( std::vector<Point<2> >(&vertices[0], &vertices[n_vert]), cells, SubCellData()); // no boundary information if(info) printf("after creating triangulation\n"); // colorizing ------------------------------------------------------------------------------------ double eps = 1e-5, mid; unsigned int label=10; // cell way for (Triangulation<2>::active_cell_iterator cell = tria.begin_active(); cell!=tria.end(); ++cell) { // cell->set_all_manifold_ids (label); for (unsigned int f=0; f < GeometryInfo<2>::faces_per_cell;++f) { const Point<2> face_center = cell->face(f)->center(), p0 = cell->face(f)->vertex(0) , p1 = cell->face(f)->vertex(1); double d0 = p0.distance( Point<2>( 0.0,0.0 ) ), d1 = p1.distance( Point<2>( 0.0,0.0 ) ); if(info) printf(" f=%d, dist=%f\n", f, cell->face(f)->center().distance( Point<2>( 0.0,0.0 ) ) ); if( (cell->face(f)->center().distance( Point<2>( 0.0,0.0 )) - mid) < eps ) { if(info) printf(" ... set one! ... dist=%f\n", cell->face(f)->center().distance( Point<2>( 0.0,0.0 ) ) ); cell->face(f)->set_all_manifold_ids (label+1); } // if face of circle if ( abs((d0+d1)-2*r) < eps ) { // disk faces cell->face(f)->set_all_manifold_ids (label); } // outer faces } // face if ( cell->center().distance( Point<2>( 0.0,0.0 ) ) < eps ) { // eliminating origin cell->set_all_manifold_ids (label+1); } } // cell // end-colorizing -------------------------------------------------------------------------------- if(mesh_out) { // printing the resulting geometry //printf("printing original mesh to eps ... \n"); std::ofstream gridfile ("coarse.eps"); GridOut grid_out; grid_out.write_eps (tria, gridfile); // printing vertices printf("vert=[\n"); for (unsigned int j = 0; j < n_vert; j++) { printf("\t%.3f, %.3f;\n", vertices[j](0), vertices[j](1)); } printf("];\n\n"); // printing cell indexes printf("cells=[\n"); for (unsigned int j = 0; j < n_cell; j++) { printf("\t%d, %d,%d, %d;\n", cell_v[j][0], cell_v[j][1], cell_v[j][2], cell_v[j][3] ); } printf("];\n"); } } void cell_rod ( Triangulation<2> &tria, double L, double diameter_ratio) { Geom_parameters gp; cell_rod ( tria, L, diameter_ratio, gp, false); } void cell_rod ( Triangulation<2> &tria, double L, double diameter_ratio, Geom_parameters &gp) { cell_rod ( tria, L, diameter_ratio, gp, false); }