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

Generic face element (crazy hack) #3521

Draft
wants to merge 7 commits into
base: devel
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DisableFormat: true
1 change: 1 addition & 0 deletions include/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,7 @@ include_HEADERS = \
geom/elem_range.h \
geom/elem_side_builder.h \
geom/face.h \
geom/face_generic.h \
geom/face_inf_quad.h \
geom/face_inf_quad4.h \
geom/face_inf_quad6.h \
Expand Down
2 changes: 2 additions & 0 deletions include/enums/enum_elem_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ enum ElemType : int {
PRISM20 = 35,
PRISM21 = 36,
PYRAMID18 = 37,
// Generic variable node count elements
GENERIC_FACE = 38,
// Invalid
INVALID_ELEM}; // should always be last

Expand Down
5 changes: 5 additions & 0 deletions include/geom/elem.h
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,11 @@ class Elem : public ReferenceCountedObject<Elem>,
*/
virtual ElemType type () const = 0;

/**
* \returns True if the element supports libmesh quadrature
*/
virtual bool has_quadrature_support() const { return true; }

/**
* \returns The dimensionality of the object.
*/
Expand Down
292 changes: 292 additions & 0 deletions include/geom/face_generic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
// The libMesh Finite Element Library.
// Copyright (C) 2002-2023 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can 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.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#ifndef LIBMESH_FACE_GENERIC_H
#define LIBMESH_FACE_GENERIC_H

// Local includes
#include "libmesh/libmesh_common.h"
#include "libmesh/face.h"

namespace libMesh
{

/**
* The \p Generic element is an collection of nodes in 2D. No assumptions
* about node connectivity are made.
*
* \author Daniel Schwen
* \date 2023
* \brief The base class for all triangular element types.
*/
class GenericFace : public Face
{
public:

/**
* Generic 2D element, takes number of nodes and an optional
* parent. Order and interpretation of the nodes is up to the user.
*/
GenericFace(const unsigned int nn, Elem * p = nullptr) : Face(nn, 0, p, &_parent_link, nullptr)
{
// copy nodes
_nodelinks_data.resize(nn);
_nodes = _nodelinks_data.data();

// Make sure the interior parent isn't undefined
if (LIBMESH_DIM > 2)
this->set_interior_parent(nullptr);
}

GenericFace (GenericFace &&) = delete;
GenericFace (const GenericFace &) = delete;
GenericFace & operator= (const GenericFace &) = delete;
GenericFace & operator= (GenericFace &&) = delete;
virtual ~GenericFace() = default;

/**
* \returns The \p Point associated with local \p Node \p i,
* in master element rather than physical coordinates.
*/
virtual Point master_point(const unsigned int /*i*/) const override final
{
libmesh_error_msg("Generic 2d elements have no master points");
}

/**
* \returns 3. All tri-derivatives are guaranteed to have at
* least 3 nodes.
*/
virtual unsigned int n_nodes() const override { return _nodelinks_data.size(); }

/**
* \returns 0.
*/
virtual unsigned int n_sides() const override final { return 0; }

/**
* \returns 3. All triangles have 3 vertices.
*/
virtual unsigned int n_vertices() const override final { return n_nodes(); }

/**
* \returns 3. All triangles have 3 edges.
*/
virtual unsigned int n_edges() const override final { libmesh_error_msg("Generic 2d elements do not have fixed edges"); }

/**
* \returns 4.
*/
virtual unsigned int n_children() const override final { libmesh_error_msg("Generic 2d elements do not support adaptivity"); }

/**
* \returns \p true if the specified child is on the
* specified side.
*/
virtual bool is_child_on_side(const unsigned int /*c*/,
const unsigned int /*s*/) const override final
{
return false;
}

/**
* Don't hide Elem::key() defined in the base class.
*/
using Elem::key;

/**
* \returns An id associated with the \p s side of this element.
* The id is not necessarily unique, but should be close. This is
* particularly useful in the \p MeshBase::find_neighbors() routine.
*/
virtual dof_id_type key(const unsigned int /*s*/) const override
{
libmesh_error_msg("not implemented");
}

/**
* \returns An id associated with the global node ids of this
* element. The id is not necessarily unique, but should be
* close.
*/
virtual dof_id_type key() const override final { libmesh_error_msg("not implemented"); }

/**
* \returns \p Tri3::side_nodes_map[side][side_node] after doing some range checking.
*/
virtual unsigned int local_side_node(unsigned int /*side*/,
unsigned int /*side_node*/) const override
{
libmesh_error_msg("not implemented");
}

/**
* Calls local_side_node(edge, edge_node). For 2D elements, there is an implied
* equivalence between edges and sides, e.g. n_edges() == n_sides(), so we treat
* these two functions the same.
*/
virtual unsigned int local_edge_node(unsigned int /*edge*/,
unsigned int /*edge_node*/) const override
{
libmesh_error_msg("not implemented");
}

/**
* \returns A primitive (2-noded) edge for edge i.
*/
virtual std::unique_ptr<Elem> side_ptr(const unsigned int /*i*/) override final
{
libmesh_error_msg("not implemented");
}

/**
* Rebuilds an EDGE2 coincident with face i.
*/
virtual void side_ptr(std::unique_ptr<Elem> & /*elem*/, const unsigned int /*i*/) override final
{
libmesh_error_msg("not implemented");
}

/**
* \returns A quantitative assessment of element quality based on
* the quality metric \p q specified by the user.
*/
virtual Real quality(const ElemQuality /*q*/) const override
{
libmesh_error_msg("not implemented");
}

/**
* \returns The suggested quality bounds for the hex based on quality
* measure \p q. These are the values suggested by the CUBIT User's
* Manual.
*/
virtual std::pair<Real, Real> qual_bounds(const ElemQuality /*q*/) const override
{
libmesh_error_msg("not implemented");
}

/**
* Do not permute a generic element!
*/
virtual unsigned int n_permutations() const override final { return 0; }

virtual void orient(BoundaryInfo *) override final {}

virtual ElemType type() const override { return GENERIC_FACE; }

/**
* \returns True if the element supports libmesh quadrature
*/
virtual bool has_quadrature_support() const { return false; }
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
virtual bool has_quadrature_support() const { return false; }
virtual bool has_quadrature_support() const override { return false; }


virtual unsigned int n_sub_elem() const override { return 1; }

virtual bool is_vertex(const unsigned int) const override { return false; }

virtual bool is_edge(const unsigned int) const override { return false; }
virtual bool is_face(const unsigned int) const override { return false; }

virtual bool is_node_on_side(const unsigned int /*n*/, const unsigned int /*s*/) const override
{
return false;
}

virtual std::vector<unsigned int> nodes_on_side(const unsigned int /*s*/) const override
{
libmesh_error_msg("not implemented");
}

virtual std::vector<unsigned int> nodes_on_edge(const unsigned int /*e*/) const override
{
libmesh_error_msg("not implemented");
}

virtual bool is_node_on_edge(const unsigned int /*n*/, const unsigned int /*e*/) const override
{
return false;
}

virtual bool has_affine_map() const override { return true; }

virtual bool has_invertible_map(Real /*tol*/) const override { return true; }

virtual bool is_linear() const override { return true; }

virtual Order default_order() const override { return FIRST; }

virtual std::unique_ptr<Elem> build_side_ptr(const unsigned int /*i*/,
bool /*proxy = false*/) override
{
libmesh_error_msg("not implemented");
}

/**
* Rebuilds an EDGE2 coincident with face i.
*/
virtual void build_side_ptr(std::unique_ptr<Elem> & /*elem*/, const unsigned int /*i*/) override
{
libmesh_error_msg("not implemented");
}

virtual void connectivity(const unsigned int /*sf*/,
const IOPackage /*iop*/,
std::vector<dof_id_type> & /*conn*/) const override
{
}

virtual Point true_centroid() const override { libmesh_error_msg("not implemented"); }

virtual Real volume() const override { libmesh_error_msg("not implemented"); }

std::pair<Real, Real> min_and_max_angle() const { libmesh_error_msg("not implemented"); }

virtual bool contains_point(const Point & /*p*/, Real /*tol*/) const override { return false; }

// virtual BoundingBox loose_bounding_box() const override;

virtual void permute(unsigned int /*perm_num*/) override final {}

virtual void flip(BoundaryInfo *) override final {}

ElemType side_type(const unsigned int /*s*/) const override final
{
libmesh_error_msg("not implemented");
}

/**
* Matrix used to create the elements children.
*/
virtual Real embedding_matrix(const unsigned int /*i*/,
const unsigned int /*j*/,
const unsigned int /*k*/) const override
{
libmesh_error_msg("not implemented");
}

protected:
/**
* node locations
*/
std::vector<Node *> _nodelinks_data;

Elem * _parent_link;
};

} // namespace libMesh

#endif // LIBMESH_FACE_GENERIC_H
1 change: 1 addition & 0 deletions include/include_HEADERS
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ include_HEADERS = \
geom/elem_range.h \
geom/elem_side_builder.h \
geom/face.h \
geom/face_generic.h \
geom/face_inf_quad.h \
geom/face_inf_quad4.h \
geom/face_inf_quad6.h \
Expand Down
4 changes: 4 additions & 0 deletions include/libmesh/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ BUILT_SOURCES = \
elem_range.h \
elem_side_builder.h \
face.h \
face_generic.h \
face_inf_quad.h \
face_inf_quad4.h \
face_inf_quad6.h \
Expand Down Expand Up @@ -967,6 +968,9 @@ elem_side_builder.h: $(top_srcdir)/include/geom/elem_side_builder.h
face.h: $(top_srcdir)/include/geom/face.h
$(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@

face_generic.h: $(top_srcdir)/include/geom/face_generic.h
$(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@

face_inf_quad.h: $(top_srcdir)/include/geom/face_inf_quad.h
$(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@

Expand Down
31 changes: 17 additions & 14 deletions include/libmesh/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -553,20 +553,20 @@ BUILT_SOURCES = auto_ptr.h dirichlet_boundaries.h dof_map.h \
cell_tet14.h cell_tet4.h compare_elems_by_level.h edge.h \
edge_edge2.h edge_edge3.h edge_edge4.h edge_inf_edge2.h elem.h \
elem_cutter.h elem_hash.h elem_internal.h elem_quality.h \
elem_range.h elem_side_builder.h face.h face_inf_quad.h \
face_inf_quad4.h face_inf_quad6.h face_quad.h face_quad4.h \
face_quad4_shell.h face_quad8.h face_quad8_shell.h \
face_quad9.h face_tri.h face_tri3.h face_tri3_shell.h \
face_tri3_subdivision.h face_tri6.h face_tri7.h node.h \
node_elem.h node_range.h plane.h point.h reference_elem.h \
remote_elem.h side.h sphere.h stored_range.h surface.h \
default_coupling.h ghost_point_neighbors.h ghosting_functor.h \
point_neighbor_coupling.h sibling_coupling.h abaqus_io.h \
boundary_info.h boundary_mesh.h checkpoint_io.h \
distributed_mesh.h dyna_io.h ensight_io.h exodusII_io.h \
exodusII_io_helper.h exodus_header_info.h fro_io.h gmsh_io.h \
gmv_io.h gnuplot_io.h inf_elem_builder.h matlab_io.h \
medit_io.h mesh.h mesh_base.h mesh_communication.h \
elem_range.h elem_side_builder.h face.h face_generic.h \
face_inf_quad.h face_inf_quad4.h face_inf_quad6.h face_quad.h \
face_quad4.h face_quad4_shell.h face_quad8.h \
face_quad8_shell.h face_quad9.h face_tri.h face_tri3.h \
face_tri3_shell.h face_tri3_subdivision.h face_tri6.h \
face_tri7.h node.h node_elem.h node_range.h plane.h point.h \
reference_elem.h remote_elem.h side.h sphere.h stored_range.h \
surface.h default_coupling.h ghost_point_neighbors.h \
ghosting_functor.h point_neighbor_coupling.h \
sibling_coupling.h abaqus_io.h boundary_info.h boundary_mesh.h \
checkpoint_io.h distributed_mesh.h dyna_io.h ensight_io.h \
exodusII_io.h exodusII_io_helper.h exodus_header_info.h \
fro_io.h gmsh_io.h gmv_io.h gnuplot_io.h inf_elem_builder.h \
matlab_io.h medit_io.h mesh.h mesh_base.h mesh_communication.h \
mesh_function.h mesh_generation.h mesh_input.h \
mesh_inserter_iterator.h mesh_modification.h mesh_output.h \
mesh_refinement.h mesh_serializer.h mesh_smoother.h \
Expand Down Expand Up @@ -1302,6 +1302,9 @@ elem_side_builder.h: $(top_srcdir)/include/geom/elem_side_builder.h
face.h: $(top_srcdir)/include/geom/face.h
$(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@

face_generic.h: $(top_srcdir)/include/geom/face_generic.h
$(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@

face_inf_quad.h: $(top_srcdir)/include/geom/face_inf_quad.h
$(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@

Expand Down
Loading