# How to Create New Element

## How to implement a new element

The practical way to write an element is to look at some element exists there in Kratos. One of these elements is LinearElement that is a plane-strain two dimensional three nodded element. In header file of this element after some "includes", the element class is defined. Constructor and creat functions in this part are common for all elements and just need to be renamed by your element. i.e in the case of LinearElement the constructors are

LinearElement(IndexType NewId, GeometryType::Pointer pGeometry); LinearElement(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties);

Create function just changes in the Linear_Element.cpp file as below

Element::Pointer LinearElement::Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer pProperties) const { return Element::Pointer(new LinearElement(NewId, GetGeometry().Create(ThisNodes), pProperties)); }

After these functions some more familiar functions in FEM code like Initialize, CalculateLocalSystem, CalculateRightHandSide, EquationIdVector, CalculateLeftHandSide, GetDofList are presented. These functions are chosen among main functions, defined in the class element.h, according to favorite elements' necessities. In the private part, after definition of some variables, main functions characterizing the element, i.e. LinearElement, are defined. Mostly these functions are changed in different elements and then are called by public functions, as is obvious by their name public and private. For example in LinearElement, private function CalculateAll calculates left hand side (LHS) and right hand side (RHS), which in this element are simply stiffness matrix and body force, and then is called by public function CalculateLocalSystem to calculate LHS and RHS of the element.

### **Telling to the kratos that a new element exists**

After implementing and compiling an element, it is necessary to "teach" to the kratos how to recognize the new element. The idea is here to create a "model element" from which all the other elements will be creates. This is done in the "application.h" and "application.cpp" where an object is created and a Name is associated to it. This process for LinearElement is presented here. At the moment of reading a datafile the kratos parses the Value of the Element, asks the kernel for the model element with the corresponding Value and creates the new elements by creating copies of the model (calling internally the function Create)

### **Element Implementation**

The aim of this section is to provide a brief introduction to the main functions provided by the element interface.

- CalculateLocalSystem: this function is called during the build phase and performs the calculation of RHS and LHS
- CalculateLeftHandSide: just calculate left hand side LHS
- CalculateRightHandSide: just calculate RHS
- EquationIdVector: This function returns a vector with the list of "EquationIds" associated to each element. Those ids are intended as the position of the corresnding dof in the global system matrix. This list has to follow the same ordering used in the construction of the LHS and RHS.
- MassMatrix and DampMatrix: Return the elemental mass and damp matrices with the same name
- GetDofList: This function returns a vector with the list of dofs in the element. This list has to follow the same ordering used in the construction of the LHS and RHS.
- Initialize: Function called ONCE at the first time a solving strategy is used.
- InitalizeSolutionStep and FinalizeSolutionStep: Functions called ONCE at the beginning and end of a given solution process (a call of the Solve function of the solving strategy)
- InitializeNonLinearIteration and FinalizeNonLinearIteration:

#### **The "CurrentProcessInfo"**:

Most of the elemental functions accept a parameter "CurrentProcessInfo". The basic use of this object is to carry informations about the current state of the process, for example the current TIME or DELTA\_TIME. This object is however a flexible container of variables and can be used to pass any variable to the element. An example is the implementation of a fractional step process where the element has to provide a different behaviour depending of the step in execution. This can be achieved easily by passing a variable FRACTIONAL\_STEP with the number of the current step. Note that the type of the variable passed ia free: as an example different backword differencing schemes can be implemented by simply passing a vector with the correct values of the BDF coefficients (see the element Fluid2D in the "incompressible\_fluid\_application" as example).

#### **The "Degrees Of Freedom" (DOF):**

The first step needed to solve a given problem is of course to define the variables we are trying to determine. Those unknowns are called degrees of freedom. The constructor of the element should provide the list of dofs for all of the nodes which compose the element. An example follows: ... Note that if the reactions are needed it is necessary to associate to each dof its action. This can be obtained by the following code: ...

#### **Calculation of the Right Hand Side (RHS):**

The kratos requires the elements to return A RESIDUA as RHS. This may not represent the natural choice for linear problems but allows to mix linear and non linear elements.

The residua is defined as RHS = dWext - dWint (note that indeed this corresponds to the standard definition changed of sign)

For linear problems, if the vector of external "forces" fext is known, The RHS can be calculated as RHS=fext-K*xp Where K is the "standard" stiffness matrix and xp is a vector containing the last known values of the dofs (note that the prescribed values are all known here)

Clearly the residual form is natural for non linear problems and requires no further explanation. The "tangent" stiffness matrix, called here LHS should be introduce with its natural sign. Note that for linear elements the "tangent" coincides with the "standard" stiffness matrix.

#### **Id:**

returns the elemental unique id. WARNING: unpredictable results may occur if different elements are constructed with the same Id. (generally speaking just one of the elements with the same Id will be preserved)

### **Functions**

#### **CalculateSystemContributions**

this function is called during the build phase and performs the calculation of RHS and LHS at the same time. As described above the RHS is a residua.

#### **GetDofList**

This function returns a vector with the list of dofs in the element. This list has to follow the same ordering used in the construction of the LHS and RHS.

#### **GetEquationId**

This function returns a vector with the list of "EquationIds" associated to each element. Those ids are intended as the position of the corresnding dof in the global system matrix. This list has to follow the same ordering used in the construction of the LHS and RHS.

#### **Initialize**

Function called ONCE at the first time a solving strategy is used.

#### **InitalizeSolutionStep and FinalizeSolutionStep**

Functions called ONCE at the beginning and end of a given solution process (a call of the Solve function of the solving strategy)

#### **InitializeNonLinIteration and FinalizeNonLinIteration**

Functions called once at the beginning and end of each non linear iteration. (they are called inside the Build process)

#### **MassMatrix and DampMatrix**

Return the elemental matrices with the same name

#### **GetFirstDerivatives, GetSecondDerivatives**

Gets the vectors of values corresponding to the first and second time derivatives for the elemental unknowns (at the time step desired)

#### **Calculate**

This function exists with different overloads to accept variables of different type. The element can overload it as needed to calculate a given value or to perform a given operation. Returns a result of type "VariableType"

#### **CalculateOnIntegrationPoints**

Similar to the function above but performs at once the calculation of the desired var on all the integration points. Returns Vector<VariableType>