📄 elem.h
字号:
// $Id: elem.h 2970 2008-08-11 00:17:08Z roystgnr $// The libMesh Finite Element Library.// Copyright (C) 2002-2007 Benjamin S. Kirk, John W. Peterson // 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 __elem_h__#define __elem_h__// C++ includes#include <algorithm>#include <set>#include <vector>// Local includes#include "libmesh_common.h"#include "dof_object.h"#include "reference_counted_object.h"#include "node.h"#include "enum_elem_type.h"#include "enum_elem_quality.h"#include "enum_order.h"#include "enum_io_package.h"#include "auto_ptr.h"#include "multi_predicates.h"#include "variant_filter_iterator.h"// Forward declarationsclass MeshBase;class MeshRefinement;class Elem;/** * This is the base class from which all geometric entities * (elements) are derived. The \p Elem class contains information * that every entity might need, such as its number of nodes and * pointers to the nodes to which it is connected. This class * also provides virtual functions that will be overloaded by * derived classes. These functions provide information such as * the number of sides the element has, who its neighbors are, * how many children it might have, and who they are. * * In an \p Elem becomes an \p Edge in 1D, a \p Face in 2D, and a \p * Cell in 3D. An \p Elem is composed of a number of sides, which you * may access as \p Elem types in dimension \p D-1. For example, a * concrete element type in 3D is a \p Hex8, which is a hexahedral. A * \p Hex8 has 6 sides, which are \p Faces. You may access these * sides. * * An \p Elem is composed of a number of \p Node objects. Some of * these nodes live at the vertices of the element, and others may * live on edges (and faces in 3D) or interior to the element. The * number of vertices an element contains \p n_vertices() is * determined strictly by the type of geometric object it corresponds * to. For example, a \p Tri is a type of \p Face that always * contains 3 vertices. A \p Tri3 is a specific triangular element * type with three 3 nodes, all located at the vertices. A \p Tri6 is * another triangular element with 6 nodes, 3 of which are located at * vertices and another 3 that live on the edges. * In all that follows, nodes that live either on edges, faces or the * interior are named @e second-order nodes. * * \author Benjamin S. Kirk, 2002-2007 */// ------------------------------------------------------------// Elem class definitionclass Elem : public ReferenceCountedObject<Elem>, public DofObject{ protected: /** * Constructor. Creates an element with \p n_nodes nodes, * \p n_sides sides, \p n_children possible children, and * parent \p p. The constructor allocates the memory necessary * to support this data. */ Elem (const unsigned int n_nodes=0, const unsigned int n_sides=0, Elem* parent=NULL); public: /** * Destructor. Frees all the memory associated with the element. */ virtual ~Elem(); /** * @returns the \p Point associated with local \p Node \p i. */ virtual const Point & point (const unsigned int i) const; /** * @returns the \p Point associated with local \p Node \p i * as a writeable reference. */ virtual Point & point (const unsigned int i); /** * @returns the global id number of local \p Node \p i. */ virtual unsigned int node (const unsigned int i) const; /** * @returns the pointer to local \p Node \p i. */ virtual Node* get_node (const unsigned int i) const; /** * @returns the pointer to local \p Node \p i as a writeable reference. */ virtual Node* & set_node (const unsigned int i); /** * @returns the subdomain that this element belongs to. * To conserve space this is stored as an unsigned char. */ unsigned char subdomain_id () const; /** * @returns the subdomain that this element belongs to as a * writeable reference. */ unsigned char & subdomain_id (); /** * @returns an id associated with the \p s side of this element. * The id is not necessariy unique, but should be close. This is * particularly useful in the \p MeshBase::find_neighbors() routine. */ virtual unsigned int key (const unsigned int s) const = 0; /** * @returns true if two elements are identical, false otherwise. * This is true if the elements are connected to identical global * nodes, regardless of how those nodes might be numbered local * to the elements. */ virtual bool operator == (const DofObject& rhs) const; /** * @returns a pointer to the \f$ i^{th} \f$ neighbor of this element. * If \p MeshBase::find_neighbors() has not been called this * simply returns \p NULL. If \p MeshBase::find_neighbors() * has been called and this returns \p NULL then the side is on * a boundary of the domain. */ Elem* neighbor (const unsigned int i) const; /** * Assigns \p n as the \f$ i^{th} \f$ neighbor. */ void set_neighbor (const unsigned int i, Elem* n); /** * @returns \p true if the element \p elem in question is a neighbor * of this element, \p false otherwise. */ bool has_neighbor (const Elem* elem) const; /** * If the element \p elem in question is a neighbor * of a child of this element, this returns a pointer * to that child. Otherwise it returns NULL. */ Elem* child_neighbor (Elem* elem) const; /** * If the element \p elem in question is a neighbor * of a child of this element, this returns a pointer * to that child. Otherwise it returns NULL. */ const Elem* child_neighbor (const Elem* elem) const; /** * @returns \p true if this element has a side coincident * with a boundary (indicated by a \p NULL neighbor), \p false * otherwise. */ bool on_boundary () const; /** * This function tells you which neighbor you \p (e) are. * I.e. if s = a->which_neighbor_am_i(e); then * a->neighbor(s) will be an ancestor of e; */ unsigned int which_neighbor_am_i(const Elem *e) const; /** * This function returns true iff a vertex of e is contained * in this element */ bool contains_vertex_of(const Elem *e) const; /** * This function finds all elements which * touch the current element at any point */ void find_point_neighbors(std::set<const Elem *> &neighbor_set) const; /** * Resets this element's neighbors' appropriate neighbor pointers * and its parent's and children's appropriate pointers * to point to the global remote_elem instead of this. * Used by the library before a remote element is deleted on the * local processor. */ void make_links_to_me_remote (); /** * Returns true if this element is remote, false otherwise. * A remote element (see \p RemoteElem) is a syntactic convenience -- * it is a placeholder for an element which exists on some other * processor. Local elements are required to have valid neighbors, * and these ghost elements may have remote neighbors for data * structure consistency. The use of remote elements helps assure * that any element we may access has a NULL neighbor if and only if * it lies on the physical boundary of the domain. */ virtual bool is_remote () const { return false; } /** * Returns the connectivity for this element in a specific * format, which is specified by the IOPackage tag. This * method supercedes the tecplot_connectivity(...) and vtk_connectivity(...) * routines. */ virtual void connectivity(const unsigned int sc, const IOPackage iop, std::vector<unsigned int>& conn) const = 0; /** * Writes the element connectivity for various IO packages * to the passed ostream "out". Not virtual, since it is * implemented in the base class. This function supercedes the * write_tecplot_connectivity(...) and write_ucd_connectivity(...) * routines. */ void write_connectivity (std::ostream& out, const IOPackage iop) const;// /**// * @returns the VTK element type of the sc-th sub-element.// */// virtual unsigned int vtk_element_type (const unsigned int sc) const = 0; /** * @returns the type of element that has been derived from this * base class. */ virtual ElemType type () const = 0; /** * This array maps the integer representation of the \p ElemType enum * to the number of nodes in the element. */ static const unsigned int type_to_n_nodes_map[INVALID_ELEM]; /** * @returns the dimensionality of the object. */ virtual unsigned int dim () const = 0; /** * @returns the number of nodes this element contains. */ virtual unsigned int n_nodes () const = 0; /** * @returns the number of sides the element that has been derived * from this class has. In 2D the number of sides is the number * of edges, in 3D the number of sides is the number of faces. */ virtual unsigned int n_sides () const = 0; /** * @returns the number of neighbors the element that has been derived * from this class has. By default only face (or edge in 2D) * neighbors are stored, so this method returns n_sides(), * however it may be overloaded in a derived class */ virtual unsigned int n_neighbors () const { return this->n_sides(); } /** * @returns the number of vertices the element that has been derived * from this class has. */ virtual unsigned int n_vertices () const = 0; /** * @returns the number of edges the element that has been derived * from this class has. */ virtual unsigned int n_edges () const = 0; /** * @returns the number of faces the element that has been derived * from this class has. */ virtual unsigned int n_faces () const = 0; /** * @returns the number of children the element that has been derived * from this class may have. */ virtual unsigned int n_children () const = 0; /** * @returns true iff the specified (local) node number is a vertex. */ virtual bool is_vertex(const unsigned int i) const = 0; /** * @returns true iff the specified (local) node number is an edge. */ virtual bool is_edge(const unsigned int i) const = 0; /** * @returns true iff the specified (local) node number is a face. */ virtual bool is_face(const unsigned int i) const = 0; /* * @returns true iff the specified (local) node number is on the * specified side */ virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const = 0; /* * @returns true iff the specified (local) node number is on the * specified edge */ virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const = 0;// /**// * @returns the number of children this element has that// * share side \p s// */// virtual unsigned int n_children_per_side (const unsigned int) const = 0; /** * @returns the number of sub-elements this element may be broken * down into for visualization purposes. For example, this returns * 1 for a linear triangle, 4 for a quadratic (6-noded) triangle, etc... */ virtual unsigned int n_sub_elem () const = 0; /** * @returns a proxy element coincident with side \p i. This method returns * the _minimum_ element necessary to uniquely identify the side. So, * for example, the side of a hexahedral is always returned as a 4-noded * quadrilateral, regardless of what type of hex you are dealing with. If * you want the full-ordered face (i.e. a 9-noded quad face for a 27-noded * hexahedral) use the build_side method. */ virtual AutoPtr<DofObject> side (const unsigned int i) const = 0; /** * Creates an element coincident with side \p i. The element returned is * full-ordered, in contrast to the side method. For example, calling * build_side(0) on a 20-noded hex will build a 8-noded quadrilateral * coincident with face 0 and pass back the pointer. * * A \p AutoPtr<Elem> is returned to prevent a memory leak. * This way the user need not remember to delete the object. * * The second argument, which is true by default, specifies that a * "proxy" element (of type Side) will be returned. This type of * return value is useful because it does not allocate additional * memory, and is usually sufficient for FE calculation purposes. * If you really need a full-ordered, non-proxy side object, call * this function with proxy=false. */ virtual AutoPtr<Elem> build_side (const unsigned int i, bool proxy=true) const = 0; /** * Creates an element coincident with edge \p i. The element returned is * full-ordered. For example, calling build_edge(0) on a 20-noded hex will * build a 3-noded edge coincident with edge 0 and pass back the pointer. * * A \p AutoPtr<Elem> is returned to prevent a memory leak. * This way the user need not remember to delete the object. */ virtual AutoPtr<Elem> build_edge (const unsigned int i) const = 0; /** * @returns the default approximation order for this element type. * This is the order that will be used to compute the map to the * reference element. */ virtual Order default_order () const = 0; /** * @returns the centriod of the element. The centroid is * computed as the average of all the element vertices. * This method is overloadable since some derived elements * might want to use shortcuts to compute their centroid. */ virtual Point centroid () const; /** * @returns the minimum vertex separation for the element. */ virtual Real hmin () const; /** * @returns the maximum vertex separation for the element. */ virtual Real hmax () const; /** * @return the (length/area/volume) of the geometric element. */ virtual Real volume () const; /** * Based on the quality metric q specified by the user, * returns a quantitative assessment of element quality. */ virtual Real quality (const ElemQuality q) const; /** * Returns the suggested quality bounds for * the hex based on quality measure q. These are * the values suggested by the CUBIT User's Manual. * Since this function can have no possible meaning * for an abstract Elem, it is an error. */ virtual std::pair<Real,Real> qual_bounds (const ElemQuality) const { libmesh_error(); return std::make_pair(0.,0.); } /** * @returns true if the point p is contained in this element, * false otherwise. */ virtual bool contains_point (const Point& p) const; /** * @returns true iff the element map is definitely affine (i.e. the same at * every quadrature point) within numerical tolerances */ virtual bool has_affine_map () const { return false; } /** * @returns \p true if the element is active (i.e. has no active * descendants), \p false otherwise. Note that it suffices to check the * first child only. Always returns \p true if AMR is disabled. */ bool active () const; /** * @returns \p true if the element is an ancestor (i.e. has an * active child or ancestor child), \p false otherwise. Always * returns \p false if AMR is disabled. */ bool ancestor () const; /** * @returns \p true if the element is subactive (i.e. has no active * descendants), \p false otherwise. Always returns \p false if AMR * is disabled. */ bool subactive () const; /** * @returns \p true if the element has any children (active or not), * \p false otherwise. Always returns \p false if AMR is disabled. */ bool has_children () const; /** * @returns \p true if the element has any descendants other than * its immediate children, \p false otherwise. Always returns \p * false if AMR is disabled. */ bool has_ancestor_children () const;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -