# How to Create New Element

(Difference between revisions)
 Revision as of 14:14, 28 November 2007 (view source) (→How to implement a new element)← Older edit Revision as of 14:22, 28 November 2007 (view source) (→How to implement a new element)Newer edit → Line 14: Line 14: } } − After these functions some more familiar functions in FEM code like [[Initialize]], [[CalculateLocalSystem]], [[CalculateRightHandSide]], [[EquationIdVector]], [[CalculateLeftHandSide]], [[GetDofList]] are presented. These functions are chosen among standard 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 elements and then called by public functions, as is obvious by their name public and private. For example in [[LinearElement]], [[CalculateAll]] calculates left hand side ([[LHS]]) and right hand side ([[RHS]]) which in this element are simply stiffness matrix and body force. This function is then called by public function [[CalculateLocalSystem]] to calculate  [[LHS]] and [[RHS]] of the element. + After these functions some more familiar functions in FEM code like [[Initialize]], [[CalculateLocalSystem]], [[CalculateRightHandSide]], [[EquationIdVector]], [[CalculateLeftHandSide]], [[GetDofList]] are presented. These functions are chosen among standard 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. The implementation of a new element is a standard operation in the FEM and an effort was made to simplify The implementation of a new element is a standard operation in the FEM and an effort was made to simplify

## 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 standard 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.

The implementation of a new element is a standard operation in the FEM and an effort was made to simplify

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

The basic interface to the element is provided in the class element.h which defines the interface for all the public functions allowed on a generic element.

The minimal informations needed at the moment of the construction of a new element are:

• Id: a unique identifier of the element
• Properties::Pointer: it is the pointer to the container of data which are common to a group of elements
• Geometry::Pointer: pointer to the entity which represents the topology of the element (tetrahedra, exahedra...). In its easiest instance the geometry is simply a list of pointers to the nodes of the element, but it may contain many more informations (described in a specific tutorial)

All of the informations above need to be given at the moment of construction. Additional info may be provided for the construction of specific element, however in general the kratos will have no direct access to them.

To conclude the element contains a pointer to a "DataValueContainer" which allows to store VARIABLES per each element. This implies that an empty element will store

1 unsigned int, a minimum of 3 "Shared Pointers" Having thus a non negligible memory occupation.

### 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.

#### 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>