diff --git a/src/fe_engine/fe_engine.hh b/src/fe_engine/fe_engine.hh index 1c0516a8f..859d605c3 100644 --- a/src/fe_engine/fe_engine.hh +++ b/src/fe_engine/fe_engine.hh @@ -1,393 +1,393 @@ /** * @file fe_engine.hh * * @author Guillaume Anciaux * @author Nicolas Richart * * @date creation: Fri Jun 18 2010 * @date last modification: Tue Feb 20 2018 * * @brief FEM class * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu 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 3 of the License, or (at your option) any * later version. * * Akantu 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 Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_memory.hh" #include "element_type_map.hh" #include "mesh_events.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_FE_ENGINE_HH__ #define __AKANTU_FE_ENGINE_HH__ namespace akantu { class Mesh; class Integrator; class ShapeFunctions; class DOFManager; class Element; } // namespace akantu /* -------------------------------------------------------------------------- */ namespace akantu { /* -------------------------------------------------------------------------- */ /** * The generic FEEngine class derived in a FEEngineTemplate class * containing the * shape functions and the integration method */ class FEEngine : protected Memory, public MeshEventHandler { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: FEEngine(Mesh & mesh, UInt spatial_dimension = _all_dimensions, const ID & id = "fem", MemoryID memory_id = 0); ~FEEngine() override; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// pre-compute all the shape functions, their derivatives and the jacobians virtual void initShapeFunctions(const GhostType & ghost_type = _not_ghost) = 0; /// extract the nodal values and store them per element template static void extractNodalToElementField( const Mesh & mesh, const Array & nodal_f, Array & elemental_f, const ElementType & type, const GhostType & ghost_type = _not_ghost, const Array & filter_elements = empty_filter); /// filter a field template static void filterElementalData(const Mesh & mesh, const Array & quad_f, Array & filtered_f, const ElementType & type, const GhostType & ghost_type = _not_ghost, const Array & filter_elements = empty_filter); /* ------------------------------------------------------------------------ */ /* Integration method bridges */ /* ------------------------------------------------------------------------ */ /// integrate f for all elements of type "type" virtual void integrate(const Array & f, Array & intf, UInt nb_degree_of_freedom, const ElementType & type, const GhostType & ghost_type = _not_ghost, const Array & filter_elements = empty_filter) const = 0; /// integrate a scalar value f on all elements of type "type" virtual Real integrate(const Array & f, const ElementType & type, const GhostType & ghost_type = _not_ghost, const Array & filter_elements = empty_filter) const = 0; /// integrate f for all integration points of type "type" but don't sum over /// all integration points virtual void integrateOnIntegrationPoints( const Array & f, Array & intf, UInt nb_degree_of_freedom, const ElementType & type, const GhostType & ghost_type = _not_ghost, const Array & filter_elements = empty_filter) const = 0; /// integrate one element scalar value on all elements of type "type" virtual Real integrate(const Vector & f, const ElementType & type, UInt index, const GhostType & ghost_type = _not_ghost) const = 0; /* ------------------------------------------------------------------------ */ /* compatibility with old FEEngine fashion */ /* ------------------------------------------------------------------------ */ #ifndef SWIG /// get the number of integration points virtual UInt getNbIntegrationPoints(const ElementType & type, const GhostType & ghost_type = _not_ghost) const = 0; /// get the precomputed shapes const virtual Array & getShapes(const ElementType & type, const GhostType & ghost_type = _not_ghost, UInt id = 0) const = 0; /// get the derivatives of shapes const virtual Array & getShapesDerivatives(const ElementType & type, const GhostType & ghost_type = _not_ghost, UInt id = 0) const = 0; /// get integration points const virtual Matrix & getIntegrationPoints(const ElementType & type, const GhostType & ghost_type = _not_ghost) const = 0; #endif /* ------------------------------------------------------------------------ */ /* Shape method bridges */ /* ------------------------------------------------------------------------ */ /// Compute the gradient nablauq on the integration points of an element type /// from nodal values u virtual void gradientOnIntegrationPoints( const Array & u, Array & nablauq, const UInt nb_degree_of_freedom, const ElementType & type, const GhostType & ghost_type = _not_ghost, const Array & filter_elements = empty_filter) const = 0; /// Interpolate a nodal field u at the integration points of an element type /// -> uq virtual void interpolateOnIntegrationPoints( const Array & u, Array & uq, UInt nb_degree_of_freedom, const ElementType & type, const GhostType & ghost_type = _not_ghost, const Array & filter_elements = empty_filter) const = 0; /// Interpolate a nodal field u at the integration points of many element /// types -> uq virtual void interpolateOnIntegrationPoints( const Array & u, ElementTypeMapArray & uq, const ElementTypeMapArray * filter_elements = nullptr) const = 0; /// pre multiplies a tensor by the shapes derivaties virtual void computeBtD(const Array & Ds, Array & BtDs, const ElementType & type, const GhostType & ghost_type, const Array & filter_elements = empty_filter) const = 0; /// left and right multiplies a tensor by the shapes derivaties virtual void computeBtDB(const Array & Ds, Array & BtDBs, UInt order_d, const ElementType & type, const GhostType & ghost_type, const Array & filter_elements = empty_filter) const = 0; /// Compute the interpolation point position in the global coordinates for /// many element types virtual void computeIntegrationPointsCoordinates( ElementTypeMapArray & integration_points_coordinates, const ElementTypeMapArray * filter_elements = nullptr) const = 0; /// Compute the interpolation point position in the global coordinates for an /// element type virtual void computeIntegrationPointsCoordinates( Array & integration_points_coordinates, const ElementType & type, const GhostType & ghost_type = _not_ghost, const Array & filter_elements = empty_filter) const = 0; /// Build pre-computed matrices for interpolation of field form integration /// points at other given positions (interpolation_points) virtual void initElementalFieldInterpolationFromIntegrationPoints( const ElementTypeMapArray & interpolation_points_coordinates, ElementTypeMapArray & interpolation_points_coordinates_matrices, ElementTypeMapArray & integration_points_coordinates_inv_matrices, const ElementTypeMapArray * element_filter) const = 0; /// interpolate field at given position (interpolation_points) from given /// values of this field at integration points (field) virtual void interpolateElementalFieldFromIntegrationPoints( const ElementTypeMapArray & field, const ElementTypeMapArray & interpolation_points_coordinates, ElementTypeMapArray & result, const GhostType ghost_type, const ElementTypeMapArray * element_filter) const = 0; /// Interpolate field at given position from given values of this field at /// integration points (field) /// using matrices precomputed with /// initElementalFieldInterplationFromIntegrationPoints virtual void interpolateElementalFieldFromIntegrationPoints( const ElementTypeMapArray & field, const ElementTypeMapArray & interpolation_points_coordinates_matrices, const ElementTypeMapArray & integration_points_coordinates_inv_matrices, ElementTypeMapArray & result, const GhostType ghost_type, const ElementTypeMapArray * element_filter) const = 0; /// interpolate on a phyiscal point inside an element virtual void interpolate(const Vector & real_coords, const Matrix & nodal_values, Vector & interpolated, const Element & element) const = 0; /// compute the shape on a provided point virtual void computeShapes(const Vector & real_coords, UInt elem, const ElementType & type, Vector & shapes, const GhostType & ghost_type = _not_ghost) const = 0; /// compute the shape derivatives on a provided point virtual void computeShapeDerivatives(const Vector & real__coords, UInt element, const ElementType & type, Matrix & shape_derivatives, const GhostType & ghost_type = _not_ghost) const = 0; /* ------------------------------------------------------------------------ */ /* Other methods */ /* ------------------------------------------------------------------------ */ /// pre-compute normals on integration points virtual void computeNormalsOnIntegrationPoints( const GhostType & ghost_type = _not_ghost) = 0; /// pre-compute normals on integration points virtual void computeNormalsOnIntegrationPoints( __attribute__((unused)) const Array & field, __attribute__((unused)) const GhostType & ghost_type = _not_ghost) { AKANTU_TO_IMPLEMENT(); } /// pre-compute normals on integration points virtual void computeNormalsOnIntegrationPoints( __attribute__((unused)) const Array & field, __attribute__((unused)) Array & normal, __attribute__((unused)) const ElementType & type, __attribute__((unused)) const GhostType & ghost_type = _not_ghost) const { AKANTU_TO_IMPLEMENT(); } -#ifdef AKANTU_STRUCTURAL_MECHANICS - - /// assemble a field as a matrix for structural elements (ex. rho to mass - /// matrix) - virtual void assembleFieldMatrix( - __attribute__((unused)) const Array & field_1, - __attribute__((unused)) UInt nb_degree_of_freedom, - __attribute__((unused)) SparseMatrix & M, - __attribute__((unused)) Array * n, - __attribute__((unused)) ElementTypeMapArray & rotation_mat, - __attribute__((unused)) ElementType type, - __attribute__((unused)) const GhostType & ghost_type) const { - - AKANTU_TO_IMPLEMENT(); - } - /// compute shapes function in a matrix for structural elements - virtual void computeShapesMatrix( - __attribute__((unused)) const ElementType & type, - __attribute__((unused)) UInt nb_degree_of_freedom, - __attribute__((unused)) UInt nb_nodes_per_element, - __attribute__((unused)) Array * n, __attribute__((unused)) UInt id, - __attribute__((unused)) UInt degree_to_interpolate, - __attribute__((unused)) UInt degree_interpolated, - __attribute__((unused)) const bool sign, - __attribute__((unused)) const GhostType & ghost_type) const { - - AKANTU_TO_IMPLEMENT(); - } - -#endif +// #ifdef AKANTU_STRUCTURAL_MECHANICS + +// /// assemble a field as a matrix for structural elements (ex. rho to mass +// /// matrix) +// virtual void assembleFieldMatrix( +// __attribute__((unused)) const Array & field_1, +// __attribute__((unused)) UInt nb_degree_of_freedom, +// __attribute__((unused)) SparseMatrix & M, +// __attribute__((unused)) Array * n, +// __attribute__((unused)) ElementTypeMapArray & rotation_mat, +// __attribute__((unused)) ElementType type, +// __attribute__((unused)) const GhostType & ghost_type) const { + +// AKANTU_TO_IMPLEMENT(); +// } +// /// compute shapes function in a matrix for structural elements +// virtual void computeShapesMatrix( +// __attribute__((unused)) const ElementType & type, +// __attribute__((unused)) UInt nb_degree_of_freedom, +// __attribute__((unused)) UInt nb_nodes_per_element, +// __attribute__((unused)) Array * n, __attribute__((unused)) UInt id, +// __attribute__((unused)) UInt degree_to_interpolate, +// __attribute__((unused)) UInt degree_interpolated, +// __attribute__((unused)) const bool sign, +// __attribute__((unused)) const GhostType & ghost_type) const { + +// AKANTU_TO_IMPLEMENT(); +// } + +// #endif /// function to print the containt of the class virtual void printself(std::ostream & stream, int indent = 0) const; private: /// initialise the class void init(); /* ------------------------------------------------------------------------ */ /* Mesh Event Handler interface */ /* ------------------------------------------------------------------------ */ public: void onNodesAdded(const Array &, const NewNodesEvent &) final {} void onNodesRemoved(const Array &, const Array &, const RemovedNodesEvent &) final {} void onElementsAdded(const Array &, const NewElementsEvent &) override{}; void onElementsRemoved(const Array &, const ElementTypeMapArray &, const RemovedElementsEvent &) override {} void onElementsChanged(const Array &, const Array &, const ElementTypeMapArray &, const ChangedElementsEvent &) override {} /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: using ElementTypesIteratorHelper = ElementTypeMapArray::ElementTypesIteratorHelper; ElementTypesIteratorHelper elementTypes(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost, ElementKind kind = _ek_regular) const; /// get the dimension of the element handeled by this fe_engine object AKANTU_GET_MACRO(ElementDimension, element_dimension, UInt); /// get the mesh contained in the fem object AKANTU_GET_MACRO(Mesh, mesh, const Mesh &); /// get the mesh contained in the fem object AKANTU_GET_MACRO_NOT_CONST(Mesh, mesh, Mesh &); /// get the in-radius of an element static inline Real getElementInradius(const Matrix & coord, const ElementType & type); /// get the normals on integration points AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(NormalsOnIntegrationPoints, normals_on_integration_points, Real); /// get cohesive element type for a given facet type static inline ElementType getCohesiveElementType(const ElementType & type_facet); /// get igfem element type for a given regular type static inline Vector getIGFEMElementTypes(const ElementType & type); /// get the interpolation element associated to an element type static inline InterpolationType getInterpolationType(const ElementType & el_type); /// get the shape function class (probably useless: see getShapeFunction in /// fe_engine_template.hh) virtual const ShapeFunctions & getShapeFunctionsInterface() const = 0; /// get the integrator class (probably useless: see getIntegrator in /// fe_engine_template.hh) virtual const Integrator & getIntegratorInterface() const = 0; /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: /// spatial dimension of the problem UInt element_dimension; /// the mesh on which all computation are made Mesh & mesh; /// normals at integration points ElementTypeMapArray normals_on_integration_points; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ /// standard output stream operator inline std::ostream & operator<<(std::ostream & stream, const FEEngine & _this) { _this.printself(stream); return stream; } } // namespace akantu #include "fe_engine_inline_impl.cc" #include "fe_engine_template.hh" #endif /* __AKANTU_FE_ENGINE_HH__ */ diff --git a/src/fe_engine/fe_engine_template.hh b/src/fe_engine/fe_engine_template.hh index 4325dbce6..e320f4127 100644 --- a/src/fe_engine/fe_engine_template.hh +++ b/src/fe_engine/fe_engine_template.hh @@ -1,407 +1,407 @@ /** * @file fe_engine_template.hh * * @author Guillaume Anciaux * @author Nicolas Richart * * @date creation: Fri Jun 18 2010 * @date last modification: Mon Jan 29 2018 * * @brief templated class that calls integration and shape objects * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu 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 3 of the License, or (at your option) any * later version. * * Akantu 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 Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_FE_ENGINE_TEMPLATE_HH__ #define __AKANTU_FE_ENGINE_TEMPLATE_HH__ /* -------------------------------------------------------------------------- */ #include "fe_engine.hh" #include "integrator.hh" #include "shape_functions.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ namespace akantu { class DOFManager; namespace fe_engine { namespace details { template struct AssembleLumpedTemplateHelper; template struct AssembleFieldMatrixHelper; } // namespace details } // namespace fe_engine template struct AssembleFieldMatrixStructHelper; struct DefaultIntegrationOrderFunctor { template static inline constexpr int getOrder() { return ElementClassProperty::polynomial_degree; } }; /* -------------------------------------------------------------------------- */ template