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

Extend FESystem for more than a unique face #12647

Closed
wants to merge 2 commits into from

Conversation

peterrum
Copy link
Member

...references #12646

Comment on lines +1412 to +1413
if (this->n_unique_faces() > 1)
return;
Copy link
Member Author

Choose a reason for hiding this comment

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

Not ideal but we currently don't support hanging-nodes for meshes with wedges/pyramids anyway.

Copy link
Member

Choose a reason for hiding this comment

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

Hm, yes, not ideal. How can we catch this error in a better way? Is there a better place where this assertion could be put?


for (unsigned int i = 0; i < points.size(); ++i)
for (unsigned int i = 0; i < values.size(); ++i)
Copy link
Member

Choose a reason for hiding this comment

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

No, this isn't right. If the function is called with a different number of input and output arguments, then the place where the function is called needs to be fixed.

/**
* GenericDoFsPerObject object this class was initialized with.
*/
const internal::GenericDoFsPerObject data;
Copy link
Member

Choose a reason for hiding this comment

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

First, can we give this variable a better name? Second, why is this necessary?

Copy link
Member

Choose a reason for hiding this comment

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

Also, why is it public?

fes[i]->n_dofs_per_quad(0) * multiplicities[i];
multiplied_dofs_per_hex +=
fes[i]->n_dofs_per_hex() * multiplicities[i];
if (initialized == false)
Copy link
Member

Choose a reason for hiding this comment

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

If I read this right, what you are doing here is initialize the dpo object the first time you find an element with multiplicity>0. I would much rather you do this before the current for loop, as in

  for (i=...)
    if (multiplicity>0)
      {
         ...do it here...
         break;
      }

I think that would be easier to read, and avoid the initialized variable altogether.

++j)
for (unsigned int k = 0;
k < fes[i]->data.dofs_per_object_exclusive[j].size();
++k)
Copy link
Member

Choose a reason for hiding this comment

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

It seems to me like you're repeating many of these loop statements. Could their bodies be merged?

@@ -1140,6 +1140,8 @@ ReferenceCell::face_to_cell_lines(const unsigned int face,
AssertIndexRange(face, n_faces());
AssertIndexRange(line, face_reference_cell(face).n_lines());

static unsigned int X = numbers::invalid_unsigned_int;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
static unsigned int X = numbers::invalid_unsigned_int;
static constexpr unsigned int X = numbers::invalid_unsigned_int;

Assert(1 <= degree && degree <= 2, ExcNotImplemented())

for (double z = 0.0; z <= 1.0; z += (degree == 1 ? 1.0 : 0.5))
{
Copy link
Member

Choose a reason for hiding this comment

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

indentation looks funny here

if (degree == 1)
Assert(1 <= degree && degree <= 2, ExcNotImplemented())

for (double z = 0.0; z <= 1.0; z += (degree == 1 ? 1.0 : 0.5))
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
for (double z = 0.0; z <= 1.0; z += (degree == 1 ? 1.0 : 0.5))
for (double z = 0.0; z <= 1.0; z += 1./degree)

This is going to run into trouble for values of degree for which 1./degree is not exactly representable in floating point arithmetic. The test z<=1 will then either work or not work, by accident. It's better to write this as

  for (unsigned int layer=0; layer<=degree; ++layer)
  {
     const double delta_z = 1./degree;
     const double z = layer * delta_z;
     ...

this->unit_support_points.emplace_back(1.0, 0.0, z);
this->unit_support_points.emplace_back(0.0, 1.0, z);

if (degree == 2)
Copy link
Member

Choose a reason for hiding this comment

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

Maybe not for now, but if you wanted to leave a comment: These points are just the tensor product of the triangle points with z. We could simply create a FE_SimplexP<2>(degree) and ask for its support points; then you don't have to repeat the code for degree>2 and it has to be implemented in only one place.


this->unit_face_support_points.resize(5);

for (unsigned int f = 0; f < 5; ++f)
Copy link
Member

Choose a reason for hiding this comment

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

same thing here with the bare 5

template <int dim, int spacedim>
void
FE_WedgePoly<dim, spacedim>::
convert_generalized_support_point_values_to_dof_values(
Copy link
Member

Choose a reason for hiding this comment

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

same here -- put it into a separate PR to make this one simpler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants