suanPan-manual
  • Introduction
  • Basic
    • Obtain Application
    • Configure Application
    • Perform Analysis
    • Model Syntax
    • Model Structure
    • Tweak Performance
    • Compile Application
    • Build Documentation
    • Architecture Design
    • On Clusters
  • Example
    • Developer
      • element template
      • material template
    • Solid
      • wave propagation
    • Geotechnical
      • triaxial compression of sand
      • slope analysis
    • Structural
      • Statics
        • bending of a cantilever beam
        • bifurcation of a cantilever beam
        • double-edge notched specimen
        • lees frame
        • notched beam under cyclic loading
        • rc section analysis
        • truss roof
        • uniform tension of a rubber specimen
        • thin-walled section analysis for frame structures
        • calibration of subloading surface model
      • Dynamics
        • bouncing of a ball
        • mass-spring-dashpot system
        • dynamic analysis of a portal frame
        • elemental damping
        • particle collision
        • response history analysis of an elastic coupled wall
        • multi-support excitation
        • triple pendulum
        • computing response spectrum
        • integrate with python
        • process ground motion
      • Hybrid
        • vibration of a displaced beam
      • Buckling
        • buckling analysis of a cantilever beam
      • Contact
        • contact between beam and block
        • contact in 3d space
      • Optimization
        • evolutionary structural optimization
      • Isogeometric Analysis
        • linear analysis of a single element
    • Miscellaneous
      • batch execution for automation
  • Command Collection
    • Define
      • amplitude
      • bc
      • domain
      • element
      • expression
      • file
      • generate
      • group
      • import
      • initial
      • load
      • material
      • modifier
      • node
      • recorder
      • section
    • Configure
      • analyze
      • converger
      • criterion
      • integrator
      • precheck
      • step
    • Process
      • benchmark
      • clear
      • command
      • enable
      • exit
      • materialtest
      • materialtestbyload
      • sectiontest
      • peek
      • plot
      • protect
      • pwd
      • reset
      • save
      • set
      • upsampling
      • sdof_response
      • response_spectrum
  • Amplitude
    • Amplitude
    • Special
      • NZStrongMotion
    • Universal
      • Combine
      • Constant
      • Decay
      • Linear
      • Modulated
      • Tabular
      • TabularSpline
      • Trig
  • Constraint
    • MPC
    • ParticleCollision
    • RigidWall
    • RestitutionWall
    • FixedLength
    • MaxForce
    • NodeLine
    • NodeFacet
    • Embed2D
    • Embed3D
    • LJPotential2D
    • MaximumGap2D
    • MinimumGap2D
    • MaximumGap3D
    • MinimumGap3D
  • Converger
    • Converger
    • Absolute
      • AbsDisp
      • AbsError
      • AbsIncreDisp
      • AbsIncreAcc
      • AbsIncreEnergy
      • AbsResidual
    • Other
      • FixedNumber
      • Logic
    • Relative
      • RelDisp
      • RelError
      • RelIncreDisp
      • RelIncreAcc
      • RelIncreEnergy
      • RelResidual
  • Criterion
    • Criterion
    • MaxDisplacement
    • MaxHistory
    • MaxResistance
    • MinDisplacement
    • MinResistance
    • StrainEnergyEvolution
  • Element
    • Beam
      • B21
      • B21E
      • B21H
      • B31
      • B31OS
      • EB21
      • EB31OS
      • F21
      • F21H
      • F31
      • NMB21
      • NMB21E
      • NMB31
      • MVLEM
      • Orientation
    • Cube
      • C3D20
      • C3D4
      • C3D8
      • C3D8I
      • CIN3D8
      • DC3D4
      • DC3D8
    • Membrane
      • Couple Stress
      • Phase Field
        • DCP3
        • DCP4
      • Axisymmetric
        • CAX3
        • CAX4
        • CAX8
      • Plane
        • CP3
        • CP4
        • CP4I
        • CP5
        • CP6
        • CP7
        • CP8
      • Mixed
        • PS
        • QE2
      • Drilling
        • Allman
        • GCMQ
        • GQ12
      • Infinite
        • CINP4
      • Geotechnical
        • PCPE4DC
        • PCPE4UC
        • PCPE8DC
        • PCPE8UC
      • Membrane
    • Modifier
      • Modifier
      • ElementalLee
      • ElementalNonviscous
      • LinearViscosity
    • Patch
      • Patch
      • PatchCube
      • PatchQuad
    • Plate
      • DKT3
      • DKT4
      • Mindlin
    • Shell
      • DKTS3
      • DKTS4
      • S4
      • SGCMS
      • ShellBase
    • Special
      • Contact2D
      • Contact3D
      • Damper01
      • Damper02
      • Embedded2D
      • Embedded3D
      • Joint
      • Mass
      • SingleSection
      • Spring01
      • Spring02
      • Tie
      • TranslationConnector
    • Truss
      • T2D2
      • T2D2S
      • T3D2
      • T3D2S
  • Group
    • CustomNodeGroup
    • NodeGroup
    • ElementGroup
    • GroupGroup
  • Integrator
    • Implicit
      • Linear
      • BatheTwoStep
      • GeneralizedAlpha
      • OALTS
      • GSSSS
      • Newmark
        • LeeNewmark
        • LeeElementalNewmark
        • LeeNewmarkFull
        • LeeNewmarkIterative
        • Newmark
        • RayleighNewmark
        • WilsonPenzienNewmark
        • NonviscousNewmark
    • Explicit
      • Tchamwa
      • BatheExplicit
      • GeneralizedAlphaExplicit
  • Material
    • Guide
      • Metal
      • Customisation
    • Material1D
      • Concrete
        • ConcreteCM
        • ConcreteExp
        • ConcreteTsai
        • ConcreteTable
        • ConcreteK4
      • Degradation
        • Degradation
        • CustomStrainDegradation
        • CustomStressDegradation
        • Dhakal
        • TrilinearStrainDegradation
      • Elastic
        • BilinearElastic1D
        • Elastic1D
        • AsymmElastic1D
        • MultilinearElastic1D
        • PolyElastic1D
        • NLE1D01
        • Sinh1D
        • Tanh1D
        • CustomElastic1D
      • Hysteresis
        • AFC
        • AFCN
        • BilinearOO
        • BilinearPO
        • BoucWen
        • BWBN
        • Flag
        • MPF
        • MultilinearOO
        • MultilinearPO
        • RambergOsgood
        • SimpleHysteresis
        • SlipLock
        • SteelBRB
        • Trivial
        • Gap01
      • Viscosity
        • Kelvin
        • Maxwell
        • NonlinearViscosity
        • BilinearViscosity
        • CustomViscosity
        • Viscosity01
        • Viscosity02
        • CoulombFriction
        • Nonviscous01
      • vonMises
        • Subloading1D
        • ArmstrongFrederick1D
        • AFCO1D
        • Bilinear1D
        • BilinearMises1D
        • CustomGurson1D
        • CustomMises1D
        • ExpGurson1D
        • ExpMises1D
        • Mises1D
        • Multilinear1D
        • NonlinearGurson1D
        • VAFCRP1D
    • Material2D
      • AxisymmetricElastic
      • Concrete21
      • Concrete22
      • DuncanSelig
      • Elastic2D
      • Rebar2D
    • Material3D
      • CamClay
        • BilinearCC
        • ExpCC
        • NonlinearCamClay
        • ParabolicCC
      • Concrete
        • CDP
        • CDPM2
        • Rebar3D
        • TableCDP
        • CustomCDP
      • Damage
        • IsotropicDamage
        • LinearDamage
      • DruckerPrager
        • BilinearDP
        • ExpDP
        • CustomDP
        • NonlinearDruckerPrager
      • Elastic
        • BlatzKo
        • IsotropicElastic3D
        • IsotropicNonlinearElastic3D
        • MooneyRivlin
        • NLE3D01
        • OrthotropicElastic3D
        • Yeoh
      • Hoffman
        • BilinearHoffman
        • ExpHoffman
        • CustomHoffman
        • NonlinearHill
        • NonlinearHoffman
        • TimberPD
      • Sand
        • SimpleSand
        • DafalisaManzari
      • vonMises
        • ArmstrongFrederick
        • BilinearJ2
        • BilinearPeric
        • CustomGurson
        • TableGurson
        • CustomJ2
        • ExpGurson
        • ExpJ2
        • MultilinearJ2
        • NonlinearGurson
        • NonlinearJ2
        • NonlinearPeric
        • PolyJ2
        • VAFCRP
        • Subloading
    • MaterialOS
      • ElasticOS
    • Wrapper
      • Axisymmetric
      • Laminated
      • Parallel
      • PlaneStrain
      • PlaneSymmetric
      • PlaneStress
      • Rotation2D
      • Rotation3D
      • Sequential
      • Stacked
      • Uniaxial
      • OS146
      • OS146S
      • Substepping
  • Recorder
    • Recorder
    • OutputType
  • Section
    • Code
      • EU
      • NZ
      • US
    • Section1D
      • Circle1D
      • Fibre1D
      • Rectangle1D
      • TrussSection
    • Section2D
      • Bar2D
      • Box2D
      • Circle2D
      • CircularHollow2D
      • Fibre2D
      • HSection2D
      • ISection2D
      • Rectangle2D
      • TSection2D
    • Section3D
      • Bar3D
      • Box3D
      • Circle3D
      • CircularHollow3D
      • Fibre3D
      • ISection3D
      • Rectangle3D
      • TSection3D
    • SectionOS
      • Cell3DOS
      • Fibre3DOS
    • SectionNM
      • SectionNM
      • NM2D1
      • NM2D2
      • NM2D3
      • NM2D3K
      • NM3D1
      • NM3D2
      • NM3D3
      • NM3D3K
  • Solver
    • BFGS
    • MPDC
    • Newton
    • AICN
    • Ramm
  • Step
    • Overview
    • ArcLength
    • Buckle
    • Dynamic
    • Frequency
    • Optimization
    • Static
  • Developer
    • Prerequisites
    • C Style Interface
      • material
    • CPP Style Interface
      • material
      • element
      • constraint
Powered by GitBook
On this page
Edit on GitHub
  1. Example
  2. Developer

element template

Here we show the build-in element template. Comments explain the template a bit. A detailed guideline could be seen elsewhere.

/**
 * @class ElementTemplate
 * @brief The ElementTemplate class illustrates the basic formulation a typical
 * Element class used in FEM analysis.
 *
 * @author tlc
 * @date 05/01/2020
 * @version 0.1.3
 * @file ElementTemplate.h
 * @addtogroup Element
 * @{
 */

#ifndef ELEMENTTEMPLATE_H
#define ELEMENTTEMPLATE_H

#include "MaterialElement.h"

class ElementTemplate final : public MaterialElement2D {
 // As a universal practice, we define two static constants to
 // represent the number of nodes and the number of DoFs.
 // This is not necessary but only for clearness.
 static constexpr unsigned m_node = 3, m_dof = 2;

 double thickness = 0.; /**< thickness */
 double area = 0.;      /**< area */

 mat strain_mat;

 unique_ptr<Material> m_material; /**< store material model */
public:
 ElementTemplate(unsigned, uvec&&, unsigned, double = 1.);

 void initialize(const shared_ptr<DomainBase>&) override;

 int update_status() override;

 int commit_status() override;
 int clear_status() override;
 int reset_status() override;
};

#endif
#include "ElementTemplate.h"
#include <Domain/DomainBase.h>
#include <Domain/Node.h>
#include <Material/Material2D/Material2D.h>

/**
 * @brief
 * Here we target our ElementTemplate class to fulfil the functionality of a
 * constant stress triangular element, viz., CPS3, in ABAQUS notation.
 *
 * The example element is derived from the `MaterialElement2D` class, hence it
 * is a 2D element using material models (instead of sections).
 *
 * The constructor of `MaterialElement2D` class asks for six parameters:
 * - Unique Element Object Tag (T)
 * - Number of Nodes (NN)
 * - Number of DoFs (ND)
 * - Node Encoding Tags (NT)
 * - Material Tag (MT)
 * - Nonlinear Switch (F)
 *
 * In our example, CT and F will be constants, NN is 3 and ND is 2. So we have
 * three parameters plus thickness for our derived element. Except for
 * initializing private member variables, we do not have to do anything. All
 * other initializations will be handled by the Element and Domain class. As
 * simple as this.
 */
ElementTemplate::ElementTemplate(const unsigned T, uvec&& NT, const unsigned MT, const double TH)
 : MaterialElement2D(T, m_node, m_dof, std::forward<uvec>(NT), uvec{MT}, false)
 , thickness(TH) {}

/**
 * @brief
 * As explained before, this method get all necessary information, which
 * includes getting copies of Material objects and other operations, from the
 * Domain object.
 *
 * Please note that **we do not have to check the existence of any objects**
 * which are used in the element. The validity of the connected node objects and
 * the material models is checked in the base initialisation before calling
 * this method. The execution of this `initialize()` method automatically
 * implies that this is a valid Element object with valid material model.
 *
 * The displacement mode is
 * \f{gather}{\phi=\begin{bmatrix}1&x&y\end{bmatrix}.\f}
 *
 * The strain matrix is calculated as
 * \f{gather}{B=\partial{}N=\partial{}\left(\phi{}C^{-1}\right),\f}
 * where
 * \f{gather}{C=\begin{bmatrix}1&x_i&y_i\\1&x_j&y_j\\1&x_k&y_k\end{bmatrix}.\f}
 *
 * One can also initialize stiffness matrix and/or other build-in matrices from
 * Element class (check the definition for details) in the `initialize()` method.
 * However, this it not necessary, as the Solver will always call
 * update_status() method with a zero trial displacement to update current
 * stiffness and resistance before running iterations.
 */
void ElementTemplate::initialize(const shared_ptr<DomainBase>& D) {
 //! As CPS3 is a constant stress/strain element, one integration point at the
 //! center of the element is enough. Hence we only have one material model
 //! defined. First we get a reference of the Material object from the Domain
 //! and then call the `get_copy()` method to get a local copy. Direct
 //! assignment is allowed, the move semantics will automatically be invoked.
 //! There is no need to check if the material model is a 2D one. The validation
 //! is done in base Element class initialisation.
 m_material = D->get<Material>(material_tag(0))->get_copy();

 //! The node pointers are handled in the base Element class, we do not have to
 //! set it manually. Now we could fill in the `ele_coor` matrix. The
 //! area/natural coordinate is another version of implementation. Please refer
 //! to FEM textbooks for theories. This will be used for the computation of
 //! the shape function.
 mat ele_coor(m_node, m_node, fill::ones);
 for(unsigned i = 0; i < m_node; ++i) {
  auto& tmp_coor = node_ptr[i].lock()->get_coordinate();
  for(unsigned j = 0; j < m_dof; ++j) ele_coor(i, j + 1llu) = tmp_coor(j);
 }

 //! The area is half of the determinant of the above matrix.
 //! The area of 2D polygons can also be computed by the `shoelace` function.
 area = .5 * det(ele_coor);

 const mat inv_coor = inv(ele_coor);

 //! A standard way to construct the strain mat is to derive from the partial
 //! derivative of the shape function N. For CP3, as it is a constant
 //! stress/strain element, the derivatives are constants which can be directly
 //! obtained from above matrix.
 strain_mat.zeros(3, m_node * m_dof);
 for(unsigned i = 0, j = 0, k = 1; i < 3; ++i, j += m_dof, k += m_dof) {
  strain_mat(2, k) = strain_mat(0, j) = inv_coor(1, i);
  strain_mat(2, j) = strain_mat(1, k) = inv_coor(2, i);
 }

 trial_stiffness = current_stiffness = initial_stiffness = strain_mat.t() * m_material->get_initial_stiffness() * strain_mat * area * thickness;

 if(const auto t_density = area * thickness * m_material->get_parameter(); t_density > 0.) {
  initial_mass.zeros(m_size, m_size);
  const rowvec n = mean(ele_coor) * inv_coor;
  const mat t_mass = n.t() * n * t_density * area * thickness;
  initial_mass(uvec{1, 3, 5}, uvec{1, 3, 5}) = t_mass;
  initial_mass(uvec{0, 2, 4}, uvec{0, 2, 4}) = t_mass;
 }

 //! We use function `ConstantMass()` to indicate the mass matrix will not change
 //! so that `trial_mass`, `current_mass` and `initial_mass` matrices can point to
 //! the same memory location. This avoids unnecessary allocation of memory.
 //! It is not compulsory to call `ConstantMass()`, `ConstantStiffness()` and
 //! `ConstantDamping()` but highly recommended to do so when one or some matrices
 //! indeed remain unchanged for the whole analysis.
 ConstantMass(this);
}

/**
 * @brief Now we handle the status update method. We get trial displacement via
 * build-in method and pass trial strain to the material model. Then get updated
 * stiffness and stress back to form element stiffness and resistance.
 *
 * For a static analysis, **stiffness** and **resistance** have to be
 * formulated. Apart from this, there is nothing you have to do. They will be
 * send to global assembler by methods in base Element class, which can also be
 * overridden to be customized.
 */
int ElementTemplate::update_status() {
 m_material->update_trial_status(strain_mat * get_trial_displacement());

 trial_stiffness = area * thickness * strain_mat.t() * m_material->get_trial_stiffness() * strain_mat;
 trial_resistance = area * thickness * strain_mat.t() * m_material->get_trial_stress();

 return 0;
}

/**
 * \brief Simply call corresponding methods in material objects. If the element
 * itself has history variables, they should also be updated/modified in
 * following methods.
 */
int ElementTemplate::commit_status() { return m_material->commit_status(); }

int ElementTemplate::clear_status() { return m_material->clear_status(); }

int ElementTemplate::reset_status() { return m_material->reset_status(); }
PreviousDeveloperNextmaterial template

Last updated 3 years ago