Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bug in MappingFEField #6296

Merged
merged 3 commits into from Apr 30, 2018
Merged

Conversation

luca-heltai
Copy link
Member

@luca-heltai luca-heltai commented Apr 23, 2018

I'll commit here a bug fix that closes #6294.

For the moment it's only a failing test.

Fixes #6294.


/**
* Return the diameter of the largest active cell of a triangulation.
*/
template <int dim, int spacedim>
double
maximal_cell_diameter (const Triangulation<dim, spacedim> &triangulation);
maximal_cell_diameter (const Triangulation<dim, spacedim> &triangulation,
const Mapping<dim,spacedim> &mapping = (StaticMappingQ1<dim,spacedim>::mapping));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should document for these functions that the diameter is computed only by looking at the distances between vertices. For very deformed cells, this is not the diameter of the area/volume occupied by this cell.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not changed the original implementation. That's exactly what the function was doing before (i.e., that's what cell->diameter does). I'll document this as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, the comments you made should really be on #6295. This branch is based on that one. I'll rebase afterwards.

namespace
{
template <int dim, int spacedim>
double diameter(const typename Triangulation<dim, spacedim>::cell_iterator &cell,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this exactly what cell->diameter() does, ie. look at vertices? If so, can we avoid somehow code duplication and join the two?

(vertices[3]-vertices[4]).norm()) );
default:
Assert (false, ExcNotImplemented());
return -1e10;
Copy link
Contributor

@davydden davydden Apr 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::numeric_limits<double>::signaling_NaN()

// the top level of the deal.II distribution.
//
// ---------------------------------------------------------------------

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a quick note what this test does. Everyone will forget in half a year 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for the other test.

virtual
std::array<Point<spacedim>, GeometryInfo<dim>::vertices_per_cell>
get_vertices (const typename Triangulation<dim,spacedim>::cell_iterator &cell) const override;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we usually keep just one space for headers

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept was was already there. Do you want me to fix all the rest of the header as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, i saw that the header is different to whitespaces elsewhere. Up to you, i would probably just fix it to be one space everywhere.

namespace
{
template<int dim>
Quadrature<dim> get_vertex_quadrature()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a quick doxygen documentation

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unnecessary. Its in the source and an anonymous namespace - its never exposed to the user.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I never said that it's for users 😃

Documentation of internal functions are also good to have so that we don't need to guess what's the purpose. Otherwise we might as well get rid of all in-code comments, no users will ever read them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise we might as well get rid of all in-code comments, no users will ever read them.

Sigh. This was not particularly constructive.

Documentation of internal functions are also good to have so that we don't need to guess what's the purpose.

So, you recommend an inline comment to explain the purpose of this function, rather than making generated documentation?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was not particularly constructive.

the point was that we do document internal functions/algorithms.

you recommend an inline comment to explain the purpose of this function

Does not matter which format it is (as it's never rendered) but a short one sentence explaining the function can never harm.

typename DoFHandler<dim,spacedim>::cell_iterator dof_cell(*cell,
euler_dof_handler);

Assert (dof_cell->active() == true, ExcInactiveCell());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need == true

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to be explicit.

Reading (dof_cell->active()) is worse than (dof_cell->active == true) which is what we do everywhere else...

Also because active is not, unfortunately, a good member name. is_active would have been more informative, and I'd have agreed with you then...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(in other words, active does not suggest what the return type may be, so == true makes this more informative)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p.s. is_active() would indeed be better...

@davydden
Copy link
Contributor

/run-tests

@davydden
Copy link
Contributor

Let's see if @bangerth has further comments.

@bangerth
Copy link
Member

There is a problem:

161/3560 Test #163: mappings/mapping_fe_field_02.debug ...................................***Failed   17.64 sec
Test mappings/mapping_fe_field_02.debug: RUN
===============================   OUTPUT BEGIN  ===============================
[ 50%] Generating mapping_fe_field_02.debug/interrupt_guard.cc
Scanning dependencies of target mapping_fe_field_02.debug
[ 50%] Building CXX object CMakeFiles/mapping_fe_field_02.debug.dir/mapping_fe_field_02.cc.o
Building CXX object CMakeFiles/mapping_fe_field_02.debug.dir/mapping_fe_field_02.debug/interrupt_guard.cc.o
Linking CXX executable mapping_fe_field_02.debug/mapping_fe_field_02.debug
[100%] Built target mapping_fe_field_02.debug
Scanning dependencies of target mapping_fe_field_02.debug.diff
[100%] Generating mapping_fe_field_02.debug/output
mappings/mapping_fe_field_02.debug: BUILD successful.
mappings/mapping_fe_field_02.debug: RUN failed. ------ Return code 134
mappings/mapping_fe_field_02.debug: RUN failed. ------ Result: /home/bob/build-gcc/tests/mappings/mapping_fe_field_02.debug/failing_output
mappings/mapping_fe_field_02.debug: RUN failed. ------ Partial output:
JobId e68cde002913 Tue Apr 24 20:26:11 2018
DEAL::dim, spacedim: 1, 1
DEAL::cells: 1, dofs: 2

mappings/mapping_fe_field_02.debug: RUN failed. ------ Additional output on stdout/stderr:


--------------------------------------------------------
An error occurred in line <104> of file </home/bob/source/source/base/subscriptor.cc> in function
    void dealii::Subscriptor::check_no_subscribers() const
The violated condition was: 
    counter == 0
Additional information: 
    (none)

std::vector<Point<dim> > points(GeometryInfo<dim>::vertices_per_cell);
for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
points[i] = GeometryInfo<dim>::unit_cell_vertex(i);
return Quadrature<dim>(points);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this what QTrapez already does?

I'm wondering about this because the code you have here creates the same quadrature object every time. This might not matter because we don't create MappingFEField very often, but it's still annoying. It would be nice if you could just write something like

template <int dim>
const Quadrature<dim> &     // note: reference!
get_vertex_quadrature ()
{
  static const QTrapez<dim> q;
  return q;
}

which would create the quadrature formula only once.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QTrapez does not assure that the order of the quadrature points is the same as the order of the vertices, or does it? I'll make the code return a reference to a static object.

inline
const double &
MappingFEField<dim,spacedim,DoFHandlerType,VectorType>::InternalData::shape
MappingFEField<dim,spacedim,VectorType,DoFHandlerType>::InternalData::shape
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha, how funny! nobody ever noticed this!

// we transform our tria iterator into a dof iterator so we can access
// data not associated with triangulations
typename DoFHandler<dim,spacedim>::cell_iterator dof_cell(*cell,
euler_dof_handler);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make it const

@luca-heltai
Copy link
Member Author

luca-heltai commented Apr 25, 2018

@masterleinad , this problem is related to your recent changes on the fe collection inside dh:

161/3560 Test #163: mappings/mapping_fe_field_02.debug ...................................***Failed   17.64 sec
Test mappings/mapping_fe_field_02.debug: RUN
===============================   OUTPUT BEGIN  ===============================
[ 50%] Generating mapping_fe_field_02.debug/interrupt_guard.cc
Scanning dependencies of target mapping_fe_field_02.debug
[ 50%] Building CXX object CMakeFiles/mapping_fe_field_02.debug.dir/mapping_fe_field_02.cc.o
Building CXX object CMakeFiles/mapping_fe_field_02.debug.dir/mapping_fe_field_02.debug/interrupt_guard.cc.o
Linking CXX executable mapping_fe_field_02.debug/mapping_fe_field_02.debug
[100%] Built target mapping_fe_field_02.debug
Scanning dependencies of target mapping_fe_field_02.debug.diff
[100%] Generating mapping_fe_field_02.debug/output
mappings/mapping_fe_field_02.debug: BUILD successful.
mappings/mapping_fe_field_02.debug: RUN failed. ------ Return code 134
mappings/mapping_fe_field_02.debug: RUN failed. ------ Result: /home/bob/build-gcc/tests/mappings/mapping_fe_field_02.debug/failing_output
mappings/mapping_fe_field_02.debug: RUN failed. ------ Partial output:
JobId e68cde002913 Tue Apr 24 20:26:11 2018
DEAL::dim, spacedim: 1, 1
DEAL::cells: 1, dofs: 2

mappings/mapping_fe_field_02.debug: RUN failed. ------ Additional output on stdout/stderr:


--------------------------------------------------------
An error occurred in line <104> of file </home/bob/source/source/base/subscriptor.cc> in function
    void dealii::Subscriptor::check_no_subscribers() const
The violated condition was: 
    counter == 0
Additional information: 
    (none)

Do you still make sure that the fe inside the dof handler is not destroyed and regenerated if it has not changed?

The following simple test breaks again MappingFEField and MappingQEulerian (even if I did not touch MappingQEulerian):

  Triangulation<dim,spacedim> tria;
  GridGenerator::hyper_cube (tria);
  FE_Q<dim,spacedim> fe(1);

  DoFHandler<dim,spacedim> dh(tria);
  dh.distribute_dofs(fe);

  ... build one of MappingFEField, or MappingQEulerian here

  // This is the root of the cause (which is now internally in both MappingFEField and MappingQEulerian)
  // They both have an FEValues object, that stores a SmartPointer to the fe.
  // SmartPointer<const FiniteElement<dim,spacedim>> fe_p(&dh.get_fe());

  tria.refine_global (1);
  dh.distribute_dofs(fe);

the second distribute_dofs fails, because there is an FEValues object inside both MappingQEulerian and MappingFEField that stores a SmartPointer to fe.

Apparently the failing part is here:

 if (fe_collection == nullptr || &((*fe_collection)[0]) != &ff)
     fe_collection = std_cxx14::make_unique<hp::FECollection<dim, spacedim>>(ff);  // Triggers.

Somehow the fe_collection is being recreated even if it should not, in principle, since the finite element is not changed. Is this maybe related to your recent changes @masterleinad (#6305 ?)

@luca-heltai
Copy link
Member Author

luca-heltai commented Apr 25, 2018

PR #6330 should fix the failing test in this PR too. I'll rebase once that is merged.

@tamiko
Copy link
Member

tamiko commented Apr 27, 2018

Blocks #6156

@tamiko
Copy link
Member

tamiko commented Apr 27, 2018

@luca-heltai Please rebase and fix the indenting. :-)

@masterleinad masterleinad merged commit 9a48660 into dealii:master Apr 30, 2018
@luca-heltai luca-heltai deleted the failing-test branch April 30, 2018 11:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MappingFEField does not implement get_vertices
6 participants