Timo,

Just insert all boundaries into the set and call
compute_no_normal_flux_constraints() once.

If that is not the problem, try to reduce the number of cells and
boundary conditions further. I don't think you would need that many
conditions to trigger the problem. Then you can try to print the
constraint matrix out to see what is going on.

Inserting all the boundaries into the set once didn't help. You're right that I can reduce the conditions and still trigger the problem. I've got it down to once cell, and applying no normal flux conditions on boundary 0 and 2, which gives me the error. Applying to only boundaries 0 and 1, which don't have an intersection, does not trigger the problem.

I can't print out the constraint matrix before constraints.close() is called, correct? I tried and got an empty file. When I was playing with this before my original email, I went into source/lac/constraint_matrix.cc and printed some information before the exception was triggered at line 304, and it appeared like the corners were being overconstrained and ended up depending upon themselves, which triggered the exception. What could I be missing in my code that would cause this problem?

Attached is the new minimal code with fewer conditions that still cause the error.

Thanks,

Jennifer


-------------------------------------


#include <grid/tria.h>
#include <grid/grid_generator.h>
#include <grid/tria_boundary_lib.h>
#include <dofs/dof_handler.h>
#include <fe/fe_system.h>
#include <fe/mapping_q1.h>
#include <numerics/vectors.h>
#include <numerics/data_out.h>
#include <base/exceptions.h>
#include <base/function.h>

#include <fstream>
#include <ostream>

using namespace dealii;

template <int dim>
static void
colorize_sixty_deg_hyper_shell(Triangulation<dim> & tria,
                               const Point<dim>& center,
                               const double inner_radius,
                               const double outer_radius);

template<int dim>
    static void sixty_deg_hyper_shell (Triangulation<dim>   &tria,
                                       const Point<dim>     &center,
                                       const double        inner_radius,
                                       const double        outer_radius,
                                       const unsigned int  n_cells = 0,
                                       const bool colorize = false);

template <int dim>
class SixtyDegHyperShellBoundary : public HyperShellBoundary<dim>
{
  public:

 SixtyDegHyperShellBoundary (const Point<dim> &center,
                                        const double inner_radius,
                                        const double outer_radius);

private:
    const double inner_radius;
    const double outer_radius;
};

// Implementation for 3D only
template <>
void
colorize_sixty_deg_hyper_shell(Triangulation<3> & tria,
                                            const Point<3>& center,
                                            const double inner_radius,
                                            const double outer_radius)
{

  //    if (tria.n_cells() != 4)
  //      AssertThrow (false, ExcNotImplemented());

  double middle = (outer_radius-inner_radius)/2e0 + inner_radius;
  double eps = 1e-3*middle;
  Triangulation<3>::cell_iterator cell = tria.begin();

  for (;cell!=tria.end();++cell)
    for(unsigned int f=0; f<GeometryInfo<3>::faces_per_cell; ++f)
      {
        if(!cell->face(f)->at_boundary())
          continue;

        double radius = cell->face(f)->center().norm() - center.norm();
if (std::fabs(cell->face(f)->center()(2) - sqrt(3.)*cell->face(f)->center()(0)) < eps ) // z = sqrt(3)x set boundary 2
          {
            cell->face(f)->set_boundary_indicator(2);
for (unsigned int j=0;j<GeometryInfo<3>::lines_per_face;++j)
              if(cell->face(f)->line(j)->at_boundary())
if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) > eps)
                  cell->face(f)->line(j)->set_boundary_indicator(2);
          }
else if (std::fabs(cell->face(f)->center()(2) + sqrt(3.)*cell->face(f)->center()(0)) < eps) // z = -sqrt(3)x set boundary 3
          {
            cell->face(f)->set_boundary_indicator(3);
for (unsigned int j=0;j<GeometryInfo<3>::lines_per_face;++j)
              if(cell->face(f)->line(j)->at_boundary())
if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) > eps)
                  cell->face(f)->line(j)->set_boundary_indicator(3);
          }
else if (std::fabs(cell->face(f)->center()(2) - sqrt(3.)*cell->face(f)->center()(1)) < eps ) // z = sqrt(3)y set boundary 4
          {
            cell->face(f)->set_boundary_indicator(4);
for (unsigned int j=0;j<GeometryInfo<3>::lines_per_face;++j)
              if(cell->face(f)->line(j)->at_boundary())
if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) > eps)
                  cell->face(f)->line(j)->set_boundary_indicator(4);
          }
else if (std::fabs(cell->face(f)->center()(2) + sqrt(3.)*cell->face(f)->center()(1)) < eps ) // z = -sqrt(3)y set boundary 5
          {
            cell->face(f)->set_boundary_indicator(5);
for (unsigned int j=0;j<GeometryInfo<3>::lines_per_face;++j)
              if(cell->face(f)->line(j)->at_boundary())
if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) > eps)
                  cell->face(f)->line(j)->set_boundary_indicator(5);
          }
        else if (radius < middle) // inner radius set boundary 0
          {
            cell->face(f)->set_boundary_indicator(0);
for (unsigned int j=0;j<GeometryInfo<3>::lines_per_face;++j)
              if(cell->face(f)->line(j)->at_boundary())
if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) < eps)
                  cell->face(f)->line(j)->set_boundary_indicator(0);
          }
        else if (radius > middle) // outer radius set boundary 1
          {
            cell->face(f)->set_boundary_indicator(1);
for (unsigned int j=0;j<GeometryInfo<3>::lines_per_face;++j)
              if(cell->face(f)->line(j)->at_boundary())
if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) < eps)
                  cell->face(f)->line(j)->set_boundary_indicator(1);
          }
        else
          AssertThrow (false, ExcInternalError());
      }
}

// Implementation for 3D only
template <>
void sixty_deg_hyper_shell (Triangulation<3> & tria,
                                         const Point<3>& center,
                                         const double inner_radius,
                                         const double outer_radius,
                                         const unsigned int n,
                                         const bool colorize)
{
  //  Assert ((inner_radius > 0) && (inner_radius < outer_radius),
  //          ExcInvalidRadii ());
  if (n == 0 || n == 2)
    {
      const double r0 = inner_radius;
      const double r1 = outer_radius;

      std::vector<Point<3> > vertices;

vertices.push_back (center+Point<3>( 1.0/sqrt(5.)*r0, 1.0/sqrt(5.)*r0, sqrt(3./5.)*r0)); //8 -> 0 vertices.push_back (center+Point<3>( 1.0/sqrt(5.)*r1, 1.0/sqrt(5.)*r1, sqrt(3./5.)*r1)); //9 -> 1 vertices.push_back (center+Point<3>( 1.0/sqrt(5.)*r0, -1.0/sqrt(5.)*r0, sqrt(3./5.)*r0)); //10 -> 2 vertices.push_back (center+Point<3>( 1.0/sqrt(5.)*r1, -1.0/sqrt(5.)*r1, sqrt(3./5.)*r1)); //11 -> 3 vertices.push_back (center+Point<3>( -1.0/sqrt(5.)*r0, 1.0/sqrt(5.)*r0, sqrt(3./5.)*r0)); //14 -> 4 vertices.push_back (center+Point<3>( -1.0/sqrt(5.)*r1, 1.0/sqrt(5.)*r1, sqrt(3./5.)*r1)); //15 -> 5 vertices.push_back (center+Point<3>( -1.0/sqrt(5.)*r0, -1.0/sqrt(5.)*r0, sqrt(3./5.)*r0)); //16 -> 6 vertices.push_back (center+Point<3>( -1.0/sqrt(5.)*r1, -1.0/sqrt(5.)*r1, sqrt(3./5.)*r1)); //17 -> 7

      const int cell_vertices[1][8] = {
        {6, 2, 4, 0, 7, 3, 5, 1},
      };

      std::vector<CellData<3> > cells(1);

      for (unsigned int i=0; i<1; ++i)
        {
          for (unsigned int j=0; j<8; ++j)
            cells[i].vertices[j] = cell_vertices[i][j];
          cells[i].material_id = 0;
        }

tria.create_triangulation ( vertices, cells, SubCellData()); // no boundary information
    }
  else
    {
      AssertThrow(false, ExcNotImplemented());
    }

  if (colorize)
colorize_sixty_deg_hyper_shell(tria, center, inner_radius, outer_radius);
}

template<int dim>
SixtyDegHyperShellBoundary<dim>::SixtyDegHyperShellBoundary (const Point<dim> &center, const double inner_radius, const double outer_radius)
                :
                HyperShellBoundary<dim> (center),
                inner_radius (inner_radius),
                outer_radius (outer_radius)
{
  if (dim > 2)
    Assert ((inner_radius >= 0) &&
            (outer_radius > 0) &&
            (outer_radius > inner_radius),
ExcMessage ("Inner and outer radii must be specified explicitly in 3d."));
}

template <int dim>
void run()
{
  Triangulation<dim> triangulation;
  FESystem<dim> fe(FE_Q<dim>(1), dim);
  DoFHandler<dim> dof_handler (triangulation);
  ConstraintMatrix constraints;
  Vector<double> solution;

  sixty_deg_hyper_shell (triangulation,
                                   Point<dim>(),
                                   0.5,
                                   1.0,
                                   2,
                                   true);

  static SixtyDegHyperShellBoundary<dim> boundary(Point<dim>(),
                                                  0.5,
                                                  1.0);
  triangulation.set_boundary (0, boundary);
  triangulation.set_boundary (1, boundary);

  triangulation.refine_global(2);

  dof_handler.distribute_dofs (fe);
  solution.reinit(dof_handler.n_dofs());
  solution = 0;

  std::set<unsigned char> no_normal_flux_boundaries;
  no_normal_flux_boundaries.insert (0);
  no_normal_flux_boundaries.insert (2);
  VectorTools::compute_no_normal_flux_constraints
    (dof_handler, 0,
     no_normal_flux_boundaries,
     constraints);

// print constraint matrix, gives empty file. needs to be after .close() is called, but that's where the error occurs.
  std::ostringstream constraint_filename;
  constraint_filename << "constraint_matrix.txt";
  std::ofstream constraint_output (constraint_filename.str().c_str());
  constraints.print(constraint_output);

  constraints.close();

  DataOut<dim> data_out;
  data_out.attach_dof_handler(dof_handler);
  data_out.add_data_vector(solution, "solution");
  data_out.build_patches();
  const std::string filename = "solution.vtk";
  std::ofstream output (filename.c_str());
  data_out.write_vtk(output);
}

int main (int argc, char *argv[])
{
  deallog.depth_console (0);

  run<3>();
}


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

Reply via email to