On Mon, May 10, 2010 at 10:44 PM, James Avery <[email protected]> wrote:
> On Thu, May 6, 2010 at 7:22 PM,  <[email protected]> wrote:
>> Hi James,
>>
>> actually you'd have to exchange the cases Wolfgang gave below, see the 
>> documentation of GeometryInfo<dim>.
>>
>> Furthermore, you might also consider the following alternative approach:
>> a) Compute the volume/area of the cell by numerical quadrature (using 
>> FEValues).
>> b) Compute the area/length of the faces of the cell by numerical quadrature 
>> (using FEFaceValues).
>> c) Obtain an estimate of the length in one direction by dividing the cell 
>> volume by the mean value of the area of the two faces that are orthogonal to 
>> that direction (faces 0 and 1 for direction x(or 0)).
>
> Thanks a lot to both of you! I'll have a go at both methods today and
> see what's easiest -- I'll post again with the result.

I've now implemented Wolfgang Bangert's method (with Tobias Leicht's
correction of using the line enumeration described in
GeometryInfo<dim>). I don't know whether I can attach files on the
mailing list, so I'll just copy in the changes instead:

In deal.II/includes/grid/tria_accessor.h, the following has been
inserted in the TriaAccessor class (between the diameter() and
center() declarations):

***************************** snip *****************************

                                     /**
                                       * Length of an object in the direction of
                                       * the given axis, specified in the local
                                       * coordinate system. See the 
documentation
                                       * of GeometryInfo<dim> for the meaning 
and
                                       * enumeration of the local axes.
                                       */
    double extent_in_direction(const unsigned int axis) const;

***************************** snip *****************************

and in deal.II/sources/grid/tria_accessor.cc:

***************************** snip *****************************

#if deal_II_dimension == 1
template <> double TriaAccessor<1,1,1>::extent_in_direction(const
unsigned int axis) const {
  if(axis>0)
    Assert (false, ExcIndexRange (direction, 0, 1));

  return this->diameter();
}
#elsif deal_II_dimension == 2
template <> double TriaAccessor<2,2,2>::extent_in_direction(const
unsigned int axis) const {
  using std::max;

  int lines[2][2] = {{2,3}, /// Lines along x-axis -- see
GeometryInfo<dim>, N4), 2D
                         {0,1}};/// Lines along y-axis

  if(axis>1)
    Assert (false, ExcIndexRange (direction, 0, 2));

  return max(this->line(lines[axis][0])->diameter(),
                  this->line(lines[axis][1])->diameter());
}
#elsif deal_II_dimension == 3
template <> double TriaAccessor<3,3,3>::extent_in_direction(const
unsigned int axis) const {
  using std::max;

  int lines[3][4] = {{2,3,6,7},    /// Lines along x-axis -- see
GeometryInfo<dim>, N4), 3D
                         {0,1,4,5},     /// Lines along y-axis
                         {8,9,10,11}}; /// Lines along z-axis

  double lengths[4];

  if(axis>2)
    Assert (false, ExcIndexRange (direction, 0, 3));

  for(unsigned int i=0;i<4;i++)
    lengths[i] = this->line(lines[axis][i])->diameter();

  return max(max(lengths[0],lengths[1]), max(lengths[2],lengths[3]));
}
#else
// Not implemented for higher dimensions
#endif

***************************** snip *****************************

I'm not exactly sure how things works with structdim, dim and
spacedim, so I hope I did that part correctly. Anyway, it works quite
well, it seems! I used the following scheme to regularize the aspect
ratios:

***************************** snip *****************************

 fespace_member(void) refine_to_aspect_ratio(double max_aspect_ratio)
  {
    typename DoFHandler<dim>::active_cell_iterator
      cell,  endc = dof_handler.end();

    bool done = false;
    while(!done){
      done = true;
      unsigned int num_refined = 0;
      double max_found_ratio = 1.0, Lm[dim];
      int im,jm;

      for(cell = dof_handler.begin_active();cell!=endc;cell++){
        double L[dim];
        for(int i=0; i<dim;i++)
          L[i] = cell->extent_in_direction(i);

        for(int i=0; i<dim;i++)
          for(int j=0; j<dim;j++)
            if(L[i] > max_aspect_ratio*L[j]){

              if(L[i]/L[j] > max_found_ratio){
                max_found_ratio = L[i]/L[j];
                im = i; jm = j;
                for(int k=0;k<dim;k++) Lm[k] = L[k];
              }

              cell->set_refine_flag(RefinementCase<dim>::cut_axis(i));
              done = false;
              num_refined++;
            }
      }
      if(dim==3)
        fprintf(stderr,"Refining %d cells. Maximal aspect ratio found is %g.
(%g:%g:%g, axis %d>%d)\n",num_refined,max_found_ratio,
                Lm[0],Lm[1],Lm[2],im,jm);
      triangulation.execute_coarsening_and_refinement();
    }
  }

***************************** snip *****************************

An example of the result with max_aspect_ratio=3 can be seen at
http://diku.dk/~avery/aspect-out.tar.gz, where the important step is
between initial-mesh.msh and regularized-mesh.msh.

Thanks a lot for the help, and I hope the additions to
tria_accessor.{h,cpp} are useful!

-- 
Med venlig hilsen,
  James Avery <[email protected]>
_______________________________________________
dealii mailing list http://poisson.dealii.org/mailman/listinfo/dealii

Reply via email to