https://kratos-wiki.cimne.upc.edu/index.php?title=Special:Contributions/147.83.143.248&feed=atom&deletedOnly=&limit=50&target=147.83.143.248&topOnly=&year=&month=KratosWiki - User contributions [en]2022-12-10T09:34:19ZFrom KratosWikiMediaWiki 1.17.0https://kratos-wiki.cimne.upc.edu/index.php/How_to_Access_DataBaseHow to Access DataBase2007-11-30T15:09:36Z<p>147.83.143.248: </p>
<hr />
<div>Accessing to the database is one of the most frequent operations in a Finite Element context.<br />
<br />
In a Finite Element context we often need to store information on the Nodes and on the Elements. This data may take different forms (scalars, vectors, matrices ... ) and needs to be widely accessible inside a finite element program. In the Kratos, this data is stored direcly in the objecect from which it will be accessed, meaning that the nodes will contain the nodal data, and the elements the elemental data.<br />
<br />
The Kratos provides both a nodal and elemental "Variable Database", which allows to store in a flexible way VARIABLES of different type.<br />
A detailed description of the design concepts together with a study of the perfomance issues can be found in [[Pooyan's Thesis]]. The aim of current "How To" is just to provide a brief introduction on the usage of the cpp interface.<br />
<br />
<br />
== Nodal Database ==<br />
The "Nodes" constitute one of the building blocks of the Kratos interface and provide the richest database structure. Conceptually each nodes allocates a portion of memory sufficient to contain a database with all of its data. In the practice the memory needed is defined by the user which at the beginning of the program has to select and add to the model part the list of variables that will be needed during the analysis.<br />
<br />
As a concept we should also note that for some variables a "history" (the value of this variables in the past steps) will be needed, while for others only the current value will be necessary. In order to make this possible the Kratos provides two different implementations for the "Historical Database" and for the "Non-Historical one". <br />
<br />
The two databases are independent from each other and '''are not syncronized''' <br />
<br />
=== Historical Database ===<br />
The "Historical Database" stores the present value of a variable and the value it took in the previews steps. The Number of steps stored depends on the size of "Buffer". This can be modified by the function "SetBufferSize" while the present value can be obtained by "GetBufferSize()" <br />
<br />
to make an example<br />
model_part.SetBufferSize(3)<br />
unsigned int model_part.GetBufferSize(); ##now outputs 3<br />
implies storing the current step + the 2 last steps. <br />
<br />
The list of the variables to be stored and the buffer size needs to be known in order to use the Historical Database. This is obtained by providing at the beginning of the analysis the list of all the variables that will be involved in the calculation.<br />
to make an example if a given solver will need the variables TEMPERATURE and VELOCITY, the user should provide '''before creating the list of nodes''' the two commands<br />
model_part.AddNodalSolutionStepVariable(TEMPERATURE)<br />
model_part.AddNodalSolutionStepVariable(VELOCITY)<br />
In the practice each solver provides the list of its variables through the function AddVariables(...) ''(examples of this can be found in any of the "test examples")''<br />
<br />
Once this preliminary operations are performed, the memory for the Kratos is allocated and can be used efficiently. <br />
<br />
<br />
<br />
=== Non-Historical Database ===<br />
<br />
<br />
== Elemental Database ==</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/Who_are_weWho are we2007-11-30T15:04:50Z<p>147.83.143.248: /* In Barcelona (Spain): */</p>
<hr />
<div>Hello everyone ... here it is the Kratos Team, in the order at which we joined the project!<br />
<br />
== In Barcelona (Spain): ==<br />
<br />
* Dr. Pooyan Davdand ... "''The Father''" -- [mailto:pooyan@cimne.upc.edu pooyan@cimne.upc.edu] User:Pooyan<br />
* Dr. Riccardo Rossi ... "''Being Italian... The Godfather''" -- email: rrossi@cimne.upc.edu<br />
* Ing. Pavel Borisovich Ryzhakov ... "''The naughty child''" -- email: ryzhakov@yahoo.com<br />
* Ing. Antonia Larese De Tetto<br />
* Ing. Kazem Kamran<br />
* Dr. Henrik Lynga<br />
* Dr. Javier Mora<br />
<br />
and of course:<br />
<br />
* Prf. Eugenio Oñate ... "The Boss"<br />
<br />
== In Bochum (Germany): ==<br />
* Mr. Janosch Stasch<br />
* Mr. Felix Nagel</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/Who_are_weWho are we2007-11-30T15:04:42Z<p>147.83.143.248: /* In Barcelona (Spain): */</p>
<hr />
<div>Hello everyone ... here it is the Kratos Team, in the order at which we joined the project!<br />
<br />
== In Barcelona (Spain): ==<br />
<br />
* Dr. Pooyan Davdand ... "''The Father''" -- [mailto:pooyan@cimne.upc.edu pooyan@cimne.upc.edu] [User:Pooyan]<br />
* Dr. Riccardo Rossi ... "''Being Italian... The Godfather''" -- email: rrossi@cimne.upc.edu<br />
* Ing. Pavel Borisovich Ryzhakov ... "''The naughty child''" -- email: ryzhakov@yahoo.com<br />
* Ing. Antonia Larese De Tetto<br />
* Ing. Kazem Kamran<br />
* Dr. Henrik Lynga<br />
* Dr. Javier Mora<br />
<br />
and of course:<br />
<br />
* Prf. Eugenio Oñate ... "The Boss"<br />
<br />
== In Bochum (Germany): ==<br />
* Mr. Janosch Stasch<br />
* Mr. Felix Nagel</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/Who_are_weWho are we2007-11-30T15:04:17Z<p>147.83.143.248: /* In Barcelona (Spain): */</p>
<hr />
<div>Hello everyone ... here it is the Kratos Team, in the order at which we joined the project!<br />
<br />
== In Barcelona (Spain): ==<br />
<br />
* Dr. Pooyan Davdand ... "''The Father''" -- [mailto:pooyan@cimne.upc.edu pooyan@cimne.upc.edu] [[User:Pooyan|Pooyan]]<br />
* Dr. Riccardo Rossi ... "''Being Italian... The Godfather''" -- email: rrossi@cimne.upc.edu<br />
* Ing. Pavel Borisovich Ryzhakov ... "''The naughty child''" -- email: ryzhakov@yahoo.com<br />
* Ing. Antonia Larese De Tetto<br />
* Ing. Kazem Kamran<br />
* Dr. Henrik Lynga<br />
* Dr. Javier Mora<br />
<br />
and of course:<br />
<br />
* Prf. Eugenio Oñate ... "The Boss"<br />
<br />
== In Bochum (Germany): ==<br />
* Mr. Janosch Stasch<br />
* Mr. Felix Nagel</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/Who_are_weWho are we2007-11-30T15:03:43Z<p>147.83.143.248: /* In Barcelona (Spain): */</p>
<hr />
<div>Hello everyone ... here it is the Kratos Team, in the order at which we joined the project!<br />
<br />
== In Barcelona (Spain): ==<br />
<br />
* Dr. Pooyan Davdand ... "''The Father''" -- [mailto:pooyan@cimne.upc.edu pooyan@cimne.upc.edu] [[User:Pooyan|directly here]]<br />
* Dr. Riccardo Rossi ... "''Being Italian... The Godfather''" -- email: rrossi@cimne.upc.edu<br />
* Ing. Pavel Borisovich Ryzhakov ... "''The naughty child''" -- email: ryzhakov@yahoo.com<br />
* Ing. Antonia Larese De Tetto<br />
* Ing. Kazem Kamran<br />
* Dr. Henrik Lynga<br />
* Dr. Javier Mora<br />
<br />
and of course:<br />
<br />
* Prf. Eugenio Oñate ... "The Boss"<br />
<br />
== In Bochum (Germany): ==<br />
* Mr. Janosch Stasch<br />
* Mr. Felix Nagel</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/Who_are_weWho are we2007-11-30T15:03:35Z<p>147.83.143.248: /* In Barcelona (Spain): */</p>
<hr />
<div>Hello everyone ... here it is the Kratos Team, in the order at which we joined the project!<br />
<br />
== In Barcelona (Spain): ==<br />
<br />
* Dr. Pooyan Davdand ... "''The Father''" -- [mailto:pooyan@cimne.upc.edu | pooyan@cimne.upc.edu] [[User:Pooyan|directly here]]<br />
* Dr. Riccardo Rossi ... "''Being Italian... The Godfather''" -- email: rrossi@cimne.upc.edu<br />
* Ing. Pavel Borisovich Ryzhakov ... "''The naughty child''" -- email: ryzhakov@yahoo.com<br />
* Ing. Antonia Larese De Tetto<br />
* Ing. Kazem Kamran<br />
* Dr. Henrik Lynga<br />
* Dr. Javier Mora<br />
<br />
and of course:<br />
<br />
* Prf. Eugenio Oñate ... "The Boss"<br />
<br />
== In Bochum (Germany): ==<br />
* Mr. Janosch Stasch<br />
* Mr. Felix Nagel</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/Who_are_weWho are we2007-11-30T15:03:26Z<p>147.83.143.248: /* In Barcelona (Spain): */</p>
<hr />
<div>Hello everyone ... here it is the Kratos Team, in the order at which we joined the project!<br />
<br />
== In Barcelona (Spain): ==<br />
<br />
* Dr. Pooyan Davdand ... "''The Father''" -- [mailto:pooyan@cimne.upc.edu|pooyan@cimne.upc.edu] [[User:Pooyan|directly here]]<br />
* Dr. Riccardo Rossi ... "''Being Italian... The Godfather''" -- email: rrossi@cimne.upc.edu<br />
* Ing. Pavel Borisovich Ryzhakov ... "''The naughty child''" -- email: ryzhakov@yahoo.com<br />
* Ing. Antonia Larese De Tetto<br />
* Ing. Kazem Kamran<br />
* Dr. Henrik Lynga<br />
* Dr. Javier Mora<br />
<br />
and of course:<br />
<br />
* Prf. Eugenio Oñate ... "The Boss"<br />
<br />
== In Bochum (Germany): ==<br />
* Mr. Janosch Stasch<br />
* Mr. Felix Nagel</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/Who_are_weWho are we2007-11-30T15:02:58Z<p>147.83.143.248: /* In Barcelona (Spain): */</p>
<hr />
<div>Hello everyone ... here it is the Kratos Team, in the order at which we joined the project!<br />
<br />
== In Barcelona (Spain): ==<br />
<br />
* Dr. Pooyan Davdand ... "''The Father''" -- pooyan@cimne.upc.edu [[User:Pooyan|directly here]]<br />
* Dr. Riccardo Rossi ... "''Being Italian... The Godfather''" -- email: rrossi@cimne.upc.edu<br />
* Ing. Pavel Borisovich Ryzhakov ... "''The naughty child''" -- email: ryzhakov@yahoo.com<br />
* Ing. Antonia Larese De Tetto<br />
* Ing. Kazem Kamran<br />
* Dr. Henrik Lynga<br />
* Dr. Javier Mora<br />
<br />
and of course:<br />
<br />
* Prf. Eugenio Oñate ... "The Boss"<br />
<br />
== In Bochum (Germany): ==<br />
* Mr. Janosch Stasch<br />
* Mr. Felix Nagel</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/Who_are_weWho are we2007-11-30T15:02:35Z<p>147.83.143.248: /* In Barcelona (Spain): */</p>
<hr />
<div>Hello everyone ... here it is the Kratos Team, in the order at which we joined the project!<br />
<br />
== In Barcelona (Spain): ==<br />
<br />
* Dr. Pooyan Davdand ... "''The Father''" -- mailto:pooyan@cimne.upc.edu [[User:Pooyan|directly here]]<br />
* Dr. Riccardo Rossi ... "''Being Italian... The Godfather''" -- email: rrossi@cimne.upc.edu<br />
* Ing. Pavel Borisovich Ryzhakov ... "''The naughty child''" -- email: ryzhakov@yahoo.com<br />
* Ing. Antonia Larese De Tetto<br />
* Ing. Kazem Kamran<br />
* Dr. Henrik Lynga<br />
* Dr. Javier Mora<br />
<br />
and of course:<br />
<br />
* Prf. Eugenio Oñate ... "The Boss"<br />
<br />
== In Bochum (Germany): ==<br />
* Mr. Janosch Stasch<br />
* Mr. Felix Nagel</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/Who_are_weWho are we2007-11-30T15:02:25Z<p>147.83.143.248: /* In Barcelona (Spain): */</p>
<hr />
<div>Hello everyone ... here it is the Kratos Team, in the order at which we joined the project!<br />
<br />
== In Barcelona (Spain): ==<br />
<br />
* Dr. Pooyan Davdand ... "''The Father''" -- [mailto:pooyan@cimne.upc.edu] [[User:Pooyan|directly here]]<br />
* Dr. Riccardo Rossi ... "''Being Italian... The Godfather''" -- email: rrossi@cimne.upc.edu<br />
* Ing. Pavel Borisovich Ryzhakov ... "''The naughty child''" -- email: ryzhakov@yahoo.com<br />
* Ing. Antonia Larese De Tetto<br />
* Ing. Kazem Kamran<br />
* Dr. Henrik Lynga<br />
* Dr. Javier Mora<br />
<br />
and of course:<br />
<br />
* Prf. Eugenio Oñate ... "The Boss"<br />
<br />
== In Bochum (Germany): ==<br />
* Mr. Janosch Stasch<br />
* Mr. Felix Nagel</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/Who_are_weWho are we2007-11-30T15:01:41Z<p>147.83.143.248: /* In Barcelona (Spain): */</p>
<hr />
<div>Hello everyone ... here it is the Kratos Team, in the order at which we joined the project!<br />
<br />
== In Barcelona (Spain): ==<br />
<br />
* Dr. Pooyan Davdand ... "''The Father''" -- [mailto: pooyan@cimne.upc.edu] [[User:Pooyan|directly here]]<br />
* Dr. Riccardo Rossi ... "''Being Italian... The Godfather''" -- email: rrossi@cimne.upc.edu<br />
* Ing. Pavel Borisovich Ryzhakov ... "''The naughty child''" -- email: ryzhakov@yahoo.com<br />
* Ing. Antonia Larese De Tetto<br />
* Ing. Kazem Kamran<br />
* Dr. Henrik Lynga<br />
* Dr. Javier Mora<br />
<br />
and of course:<br />
<br />
* Prf. Eugenio Oñate ... "The Boss"<br />
<br />
== In Bochum (Germany): ==<br />
* Mr. Janosch Stasch<br />
* Mr. Felix Nagel</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/Who_are_weWho are we2007-11-30T15:01:32Z<p>147.83.143.248: /* In Barcelona (Spain): */</p>
<hr />
<div>Hello everyone ... here it is the Kratos Team, in the order at which we joined the project!<br />
<br />
== In Barcelona (Spain): ==<br />
<br />
* Dr. Pooyan Davdand ... "''The Father''" -- [[mailto: pooyan@cimne.upc.edu]] [[User:Pooyan|directly here]]<br />
* Dr. Riccardo Rossi ... "''Being Italian... The Godfather''" -- email: rrossi@cimne.upc.edu<br />
* Ing. Pavel Borisovich Ryzhakov ... "''The naughty child''" -- email: ryzhakov@yahoo.com<br />
* Ing. Antonia Larese De Tetto<br />
* Ing. Kazem Kamran<br />
* Dr. Henrik Lynga<br />
* Dr. Javier Mora<br />
<br />
and of course:<br />
<br />
* Prf. Eugenio Oñate ... "The Boss"<br />
<br />
== In Bochum (Germany): ==<br />
* Mr. Janosch Stasch<br />
* Mr. Felix Nagel</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/Who_are_weWho are we2007-11-30T15:01:16Z<p>147.83.143.248: </p>
<hr />
<div>Hello everyone ... here it is the Kratos Team, in the order at which we joined the project!<br />
<br />
== In Barcelona (Spain): ==<br />
<br />
* Dr. Pooyan Davdand ... "''The Father''" -- [mailto: pooyan@cimne.upc.edu|email] [[User:Pooyan|directly here]]<br />
* Dr. Riccardo Rossi ... "''Being Italian... The Godfather''" -- email: rrossi@cimne.upc.edu<br />
* Ing. Pavel Borisovich Ryzhakov ... "''The naughty child''" -- email: ryzhakov@yahoo.com<br />
* Ing. Antonia Larese De Tetto<br />
* Ing. Kazem Kamran<br />
* Dr. Henrik Lynga<br />
* Dr. Javier Mora<br />
<br />
and of course:<br />
<br />
* Prf. Eugenio Oñate ... "The Boss"<br />
<br />
== In Bochum (Germany): ==<br />
* Mr. Janosch Stasch<br />
* Mr. Felix Nagel</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/How_to_Access_DataBaseHow to Access DataBase2007-11-30T14:54:26Z<p>147.83.143.248: </p>
<hr />
<div>Accessing to the database is one of the most frequent operations in a Finite Element context.<br />
<br />
In a Finite Element context we often need to store information on the Nodes and on the Elements. This data may take different forms (scalars, vectors, matrices ... ) and needs to be widely accessible inside a finite element program. In the Kratos, this data is stored direcly in the objecect from which it will be accessed, meaning that the nodes will contain the nodal data, and the elements the elemental data.<br />
<br />
The Kratos provides both a nodal and elemental "Variable Database", which allows to store in a flexible way VARIABLES of different type.<br />
A detailed description of the design concepts together with a study of the perfomance issues can be found in [[Pooyan's Thesis]]. The aim of current "How To" is just to provide a brief introduction on the usage of the cpp interface.<br />
<br />
<br />
== Nodal Database ==<br />
The "Nodes" constitute one of the building blocks of the Kratos interface and provide the richest database structure. Conceptually each nodes allocates a portion of memory sufficient to contain a database with all of its data. In the practice the memory needed is defined by the user which at the beginning of the program has to select and add to the model part the list of variables that will be needed during the analysis.<br />
<br />
As a concept we should also note that for some variables a "history" (the value of this variables in the past steps) will be needed, while for others only the current value will be necessary. In order to make this possible the Kratos provides two different implementations for the "Historical Database" and for the "Non-Historical one". <br />
<br />
The two databases are independent from each other and '''are not syncronized''' <br />
<br />
=== Historical Database ===<br />
The "Historical Database" stores the present value of a variable and the value it took in the previews steps. The Number of steps stored depends on the size of "Buffer". This can be modified by the function "SetBufferSize" while the present value can be obtained by "GetBufferSize()" <br />
<br />
to make an example<br />
model_part.SetBufferSize(3)<br />
unsigned int model_part.GetBufferSize(); ##now outputs 3<br />
implies storing the current step + the 2 last steps. <br />
<br />
The list of the variables to be stored and the buffer size needs to be known in order to use the Historical Database. This is obtained by providing at the beginning of the analysis the list of all the variables that will be involved in the calculation.<br />
to make an example if a given solver will need the variables TEMPERATURE and VELOCITY, the user should provide '''before creating the list of nodes''' the two commands<br />
model_part.AddNodalSolutionStepVariable(TEMPERATURE)<br />
model_part.AddNodalSolutionStepVariable(VELOCITY)<br />
In the practice each solver provides the list of its variables through the function AddVariables(...) (examples of this can be found in any of the "test examples"<br />
<br />
=== Non-Historical Database ===<br />
<br />
<br />
== Elemental Database ==</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/How_to_Access_DataBaseHow to Access DataBase2007-11-30T14:31:26Z<p>147.83.143.248: </p>
<hr />
<div>Accessing to the database is one of the most frequent operations in a Finite Element context.<br />
<br />
In a Finite Element context we often need to store information on the Nodes and on the Elements. This data may take different forms (scalars, vectors, matrices ... ) and needs to be widely accessible inside a finite element program. In the Kratos, this data is stored direcly in the objecect from which it will be accessed, meaning that the nodes will contain the nodal data, and the elements the elemental data.<br />
<br />
The Kratos provides both a nodal and elemental "Variable Database", which allows to store in a flexible way VARIABLES of different type.<br />
A detailed description of the design concepts together with a study of the perfomance issues can be found in [[Pooyan's Thesis]]. The aim of current "How To" is just to provide a brief introduction on the usage of the cpp interface.<br />
<br />
<br />
== Nodal Database ==<br />
The "Nodes" constitute one of the building blocks of the Kratos interface and provide the richest database structure. Conceptually each nodes allocates a portion of memory sufficient to contain a database with all of its data. In the practice the memory needed is defined by the user which at the beginning of the program has to select and add to the model part the list of variables that will be needed during the analysis.<br />
<br />
As a concept we should also note that for some variables a "history" (the value of this variables in the past steps) will be needed, while for others only the current value will be necessary. In order to make this possible the Kratos provides two different implementations for the "Historical Database" and for the "Non-Historical one". The two databases are independent from each other and <br />
<br />
<br />
== Elemental Database ==</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/How_to_Access_DataBaseHow to Access DataBase2007-11-30T14:07:59Z<p>147.83.143.248: New page: Accessing to the database is one of the most frequent operations in a Finite Element context. The Kratos provides both a nodal and elemental "Variable Database", which allows to store in ...</p>
<hr />
<div>Accessing to the database is one of the most frequent operations in a Finite Element context.<br />
<br />
The Kratos provides both a nodal and elemental "Variable Database", which allows to store in a flexible way VARIABLES of different type.<br />
A detailed description of the design concepts together with a study of the perfomance issues can be found in [[Pooyan's Thesis]].<br />
<br />
The aim of current "How To" is just to provide a brief introduction on the usage of the user interface.<br />
<br />
== Nodal Database ==</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/CalculateAllCalculateAll2007-11-28T16:17:10Z<p>147.83.143.248: </p>
<hr />
<div>This functopn is called by [[CalculateLocalSystem]] to calculate RHS & LHS of the element. The function's body is presented in .cpp file.<br />
void CalculateAll(MatrixType& rLeftHandSideMatrix, VectorType& rRightHandSideVector, <br />
ProcessInfo& rCurrentProcessInfo,<br />
bool CalculateStiffnessMatrixFlag,<br />
bool CalculateResidualVectorFlag);</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/CalculateAllCalculateAll2007-11-28T16:14:41Z<p>147.83.143.248: New page: void CalculateAll(MatrixType& rLeftHandSideMatrix, VectorType& rRightHandSideVector, ProcessInfo& rCurrentProcessInfo, bool CalculateStiffnessMatrixFlag, bool CalculateResidualVectorF...</p>
<hr />
<div> void CalculateAll(MatrixType& rLeftHandSideMatrix, VectorType& rRightHandSideVector, <br />
ProcessInfo& rCurrentProcessInfo,<br />
bool CalculateStiffnessMatrixFlag,<br />
bool CalculateResidualVectorFlag);</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/CalculateLocalSystemCalculateLocalSystem2007-11-28T16:04:23Z<p>147.83.143.248: New page: void LinearElement::CalculateLocalSystem(MatrixType& rLeftHandSideMatrix, VectorType& rRightHandSideVector, ProcessInfo& rCurrentProcessInfo) { //calculation flags bool C...</p>
<hr />
<div> void LinearElement::CalculateLocalSystem(MatrixType& rLeftHandSideMatrix, VectorType& rRightHandSideVector, <br />
ProcessInfo& rCurrentProcessInfo)<br />
<br />
{<br />
//calculation flags<br />
bool CalculateStiffnessMatrixFlag = true;<br />
bool CalculateResidualVectorFlag = true;<br />
<br />
CalculateAll(rLeftHandSideMatrix, rRightHandSideVector, rCurrentProcessInfo, <br />
CalculateStiffnessMatrixFlag, CalculateResidualVectorFlag);<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/GetDofListGetDofList2007-11-28T16:01:31Z<p>147.83.143.248: New page: void LinearElement::GetDofList(DofsVectorType& ElementalDofList,ProcessInfo& CurrentProcessInfo) { ElementalDofList.resize(0); for (unsigned int i=0;i<GetGeometry().size();i+...</p>
<hr />
<div> void LinearElement::GetDofList(DofsVectorType& ElementalDofList,ProcessInfo& CurrentProcessInfo)<br />
<br />
{<br />
ElementalDofList.resize(0);<br />
for (unsigned int i=0;i<GetGeometry().size();i++)<br />
{<br />
ElementalDofList.push_back(GetGeometry()[i].pGetDof(DISPLACEMENT_X));<br />
ElementalDofList.push_back(GetGeometry()[i].pGetDof(DISPLACEMENT_Y));<br />
if(GetGeometry().WorkingSpaceDimension() == 3)<br />
ElementalDofList.push_back(GetGeometry()[i].pGetDof(DISPLACEMENT_Z));<br />
<br />
}<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/How_to_Create_New_ElementHow to Create New Element2007-11-28T16:00:34Z<p>147.83.143.248: /* '''GetDofList''' */</p>
<hr />
<div>== How to implement a new element ==<br />
The practical way to write an element is to look at some element exists there<br />
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.<br />
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<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry);<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties); <br />
<br />
Create function just changes in the Linear_Element.cpp file as below<br />
<br />
Element::Pointer [[LinearElement]]::Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer <br />
pProperties) const<br />
{<br />
return Element::Pointer(new [[LinearElement]](NewId, GetGeometry().Create(ThisNodes), pProperties));<br />
}<br />
<br />
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. <br />
<br />
==='''Telling to the kratos that a new element exists'''===<br />
<br />
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]])<br />
<br />
==='''Element Implementation'''===<br />
<br />
The aim of this section is to provide a brief introduction to the main functions provided by the element interface.<br />
<br />
<br />
===='''The "CurrentProcessInfo"''':====<br />
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).<br />
<br />
<br />
===='''The "Degrees Of Freedom" (DOF):'''====<br />
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. <br />
The constructor of the element should provide the list of dofs for all of the nodes which compose the element.<br />
An example follows:<br />
...<br />
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:<br />
...<br />
<br />
<br />
===='''Calculation of the Right Hand Side (RHS):'''====<br />
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.<br />
<br />
The residua is defined as <br />
RHS = dWext - dWint <br />
(note that indeed this corresponds to the standard definition changed of sign)<br />
<br />
For linear problems, if the vector of external "forces" fext is known,<br />
The RHS can be calculated as <br />
RHS=fext-K*xp<br />
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)<br />
<br />
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.<br />
<br />
<br />
===='''Id:'''====<br />
returns the elemental unique id. <br />
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)<br />
<br />
==='''Functions'''===<br />
===='''CalculateSystemContributions'''====<br />
this function is called during the build phase and performs the calculation of RHS and LHS at the same time.<br />
As described above the RHS is a residua.<br />
<br />
<br />
===='''[[GetDofList]]'''====<br />
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.<br />
<br />
===='''GetEquationId'''====<br />
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.<br />
<br />
<br />
===='''[[Initialize]]'''====<br />
Function called ONCE at the first time a solving strategy is used.<br />
<br />
===='''InitalizeSolutionStep and FinalizeSolutionStep'''====<br />
Functions called ONCE at the beginning and end of a given solution process (a call of the Solve function of the solving strategy)<br />
<br />
<br />
===='''InitializeNonLinIteration and FinalizeNonLinIteration'''====<br />
Functions called once at the beginning and end of each non linear iteration. (they are called inside the Build process)<br />
<br />
<br />
===='''MassMatrix and DampMatrix'''====<br />
Return the elemental matrices with the same name <br />
<br />
<br />
===='''GetFirstDerivatives, GetSecondDerivatives'''====<br />
Gets the vectors of values corresponding to the first and second time derivatives for the elemental unknowns (at the time step desired)<br />
<br />
<br />
===='''Calculate'''====<br />
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"<br />
<br />
<br />
===='''CalculateOnIntegrationPoints'''====<br />
Similar to the function above but performs at once the calculation of the desired var on all the integration points. Returns Vector<VariableType></div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/EquationIdVectorEquationIdVector2007-11-28T15:58:47Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::EquationIdVector(EquationIdVectorType& rResult, ProcessInfo& CurrentProcessInfo)<br />
<br />
{<br />
int number_of_nodes = GetGeometry().size();<br />
int dim = GetGeometry().WorkingSpaceDimension();<br />
unsigned int dim2 = number_of_nodes*dim;<br />
if(rResult.size() != dim2)<br />
rResult.resize(dim2);<br />
for (int i=0;i<number_of_nodes;i++)<br />
{<br />
int index = i*dim;<br />
rResult[index] = GetGeometry()[i].GetDof(DISPLACEMENT_X).EquationId();<br />
rResult[index + 1] = GetGeometry()[i].GetDof(DISPLACEMENT_Y).EquationId();<br />
if(dim == 3)<br />
rResult[index + 2] = GetGeometry()[i].GetDof(DISPLACEMENT_Z).EquationId();<br />
}<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/EquationIdVectorEquationIdVector2007-11-28T15:58:16Z<p>147.83.143.248: New page: void LinearElement::EquationIdVector(EquationIdVectorType& rResult, ProcessInfo& CurrentProcessInfo) { int number_of_nodes = GetGeometry().size(); int dim = GetGeometry().WorkingSp...</p>
<hr />
<div> void LinearElement::EquationIdVector(EquationIdVectorType& rResult, ProcessInfo& CurrentProcessInfo)<br />
<br />
{<br />
int number_of_nodes = GetGeometry().size();<br />
int dim = GetGeometry().WorkingSpaceDimension();<br />
unsigned int dim2 = number_of_nodes*dim;<br />
if(rResult.size() != dim2)<br />
rResult.resize(dim2);<br />
for (int i=0;i<number_of_nodes;i++)<br />
{<br />
int index = i*dim;<br />
rResult[index] = GetGeometry()[i].GetDof(DISPLACEMENT_X).EquationId();<br />
rResult[index + 1] = GetGeometry()[i].GetDof(DISPLACEMENT_Y).EquationId();<br />
if(dim == 3)<br />
rResult[index + 2] = GetGeometry()[i].GetDof(DISPLACEMENT_Z).EquationId();<br />
}<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:52:49Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::Initialize()<br />
{<br />
KRATOS_TRY<br />
const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();<br />
<br />
//resizing jacobian inverses containers<br />
<br />
mInvJ0.resize(integration_points.size());<br />
mDetJ0.resize(integration_points.size());<br />
GeometryType::JacobiansType J0;<br />
J0 = GetGeometry().Jacobian(J0); <br />
mTotalDomainInitialSize = 0.00;<br />
<br />
if(mConstitutiveLawVector.size() == 0)<br />
{<br />
mConstitutiveLawVector.resize(integration_points.size());<br />
InitializeMaterial();<br />
}<br />
<br />
//calculating the inverse J0<br />
<br />
for(unsigned int PointNumber = 0; PointNumber<integration_points.size(); PointNumber++)<br />
{<br />
//getting informations for integration<br />
double IntegrationWeight = integration_points[PointNumber].Weight();<br />
//calculating and storing inverse of the jacobian and the parameters needed<br />
<br />
MathUtils<double>::InvertMatrix(J0[PointNumber],mInvJ0[PointNumber],mDetJ0[PointNumber]); <br />
<br />
<br />
<br />
//calculating the total area<br />
<br />
mTotalDomainInitialSize += mDetJ0[PointNumber]*IntegrationWeight;<br />
<br />
}<br />
<br />
KRATOS_CATCH("")<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:51:39Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::Initialize()<br />
{<br />
KRATOS_TRY<br />
const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();<br />
<br />
//resizing jacobian inverses containers<br />
<br />
mInvJ0.resize(integration_points.size());<br />
mDetJ0.resize(integration_points.size());<br />
GeometryType::JacobiansType J0;<br />
J0 = GetGeometry().Jacobian(J0); <br />
mTotalDomainInitialSize = 0.00;<br />
<br />
if(mConstitutiveLawVector.size() == 0)<br />
{<br />
mConstitutiveLawVector.resize(integration_points.size());<br />
InitializeMaterial();<br />
}<br />
<br />
//calculating the inverse J0<br />
<br />
for(unsigned int PointNumber = 0; PointNumber<integration_points.size(); PointNumber++)<br />
{<br />
//getting informations for integration<br />
double IntegrationWeight = integration_points[PointNumber].Weight();<br />
//calculating and storing inverse of the jacobian and the parameters needed<br />
<br />
MathUtils<double>::InvertMatrix(J0[PointNumber],mInvJ0[PointNumber],mDetJ0[PointNumber]); <br />
<br />
<br />
<br />
//calculating the total area<br />
<br />
mTotalDomainInitialSize += mDetJ0[PointNumber]*IntegrationWeight;<br />
<br />
}<br />
<br />
KRATOS_CATCH("")<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:50:20Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::Initialize()<br />
{<br />
KRATOS_TRY<br />
const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();<br />
<br />
//resizing jacobian inverses containers<br />
<br />
mInvJ0.resize(integration_points.size());<br />
mDetJ0.resize(integration_points.size());<br />
GeometryType::JacobiansType J0;<br />
J0 = GetGeometry().Jacobian(J0); <br />
mTotalDomainInitialSize = 0.00;<br />
<br />
if(mConstitutiveLawVector.size() == 0)<br />
{<br />
mConstitutiveLawVector.resize(integration_points.size());<br />
InitializeMaterial();<br />
}<br />
<br />
//calculating the inverse J0<br />
<br />
for(unsigned int PointNumber = 0; PointNumber<integration_points.size(); PointNumber++)<br />
{<br />
//getting informations for integration<br />
double IntegrationWeight = integration_points[PointNumber].Weight();<br />
//calculating and storing inverse of the jacobian and the parameters needed<br />
<br />
MathUtils<double>::InvertMatrix(J0[PointNumber],mInvJ0[PointNumber],mDetJ0[PointNumber]); <br />
<br />
<br />
<br />
//calculating the total area<br />
<br />
mTotalDomainInitialSize += mDetJ0[PointNumber]*IntegrationWeight;<br />
<br />
}<br />
<br />
KRATOS_CATCH("")<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:49:57Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::Initialize()<br />
{<br />
KRATOS_TRY<br />
const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();<br />
<br />
//resizing jacobian inverses containers<br />
<br />
mInvJ0.resize(integration_points.size());<br />
mDetJ0.resize(integration_points.size());<br />
GeometryType::JacobiansType J0;<br />
J0 = GetGeometry().Jacobian(J0); <br />
mTotalDomainInitialSize = 0.00;<br />
<br />
if(mConstitutiveLawVector.size() == 0)<br />
{<br />
mConstitutiveLawVector.resize(integration_points.size());<br />
InitializeMaterial();<br />
}<br />
<br />
//calculating the inverse J0<br />
<br />
for(unsigned int PointNumber = 0; PointNumber<integration_points.size(); PointNumber++)<br />
{<br />
//getting informations for integration<br />
double IntegrationWeight = integration_points[PointNumber].Weight();<br />
//calculating and storing inverse of the jacobian and the parameters needed<br />
<br />
MathUtils<double>::InvertMatrix(J0[PointNumber],mInvJ0[PointNumber],mDetJ0[PointNumber]); <br />
<br />
<br />
<br />
//calculating the total area<br />
<br />
mTotalDomainInitialSize += mDetJ0[PointNumber]*IntegrationWeight;<br />
<br />
}<br />
<br />
KRATOS_CATCH("")<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:49:33Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::Initialize()<br />
{<br />
KRATOS_TRY<br />
const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();<br />
<br />
//resizing jacobian inverses containers<br />
<br />
mInvJ0.resize(integration_points.size());<br />
mDetJ0.resize(integration_points.size());<br />
GeometryType::JacobiansType J0;<br />
J0 = GetGeometry().Jacobian(J0); <br />
mTotalDomainInitialSize = 0.00;<br />
<br />
if(mConstitutiveLawVector.size() == 0)<br />
{<br />
mConstitutiveLawVector.resize(integration_points.size());<br />
InitializeMaterial();<br />
}<br />
<br />
//calculating the inverse J0<br />
for(unsigned int PointNumber = 0; PointNumber<integration_points.size(); PointNumber++)<br />
{<br />
//getting informations for integration<br />
double IntegrationWeight = integration_points[PointNumber].Weight();<br />
//calculating and storing inverse of the jacobian and the parameters needed<br />
<br />
MathUtils<double>::InvertMatrix(J0[PointNumber],mInvJ0[PointNumber],mDetJ0[PointNumber]); <br />
<br />
<br />
<br />
//calculating the total area<br />
<br />
mTotalDomainInitialSize += mDetJ0[PointNumber]*IntegrationWeight;<br />
<br />
}<br />
<br />
KRATOS_CATCH("")<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:49:14Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::Initialize()<br />
{<br />
KRATOS_TRY<br />
const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();<br />
<br />
//resizing jacobian inverses containers<br />
<br />
mInvJ0.resize(integration_points.size());<br />
mDetJ0.resize(integration_points.size());<br />
GeometryType::JacobiansType J0;<br />
J0 = GetGeometry().Jacobian(J0); <br />
mTotalDomainInitialSize = 0.00;<br />
<br />
if(mConstitutiveLawVector.size() == 0)<br />
{<br />
mConstitutiveLawVector.resize(integration_points.size());<br />
InitializeMaterial();<br />
}<br />
<br />
//calculating the inverse J0<br />
for(unsigned int PointNumber = 0; PointNumber<integration_points.size(); PointNumber++)<br />
{<br />
//getting informations for integration<br />
double IntegrationWeight = integration_points[PointNumber].Weight();<br />
//calculating and storing inverse of the jacobian and the parameters needed<br />
<br />
MathUtils<double>::InvertMatrix(J0[PointNumber],mInvJ0[PointNumber],mDetJ0[PointNumber]); <br />
<br />
<br />
<br />
//calculating the total area<br />
<br />
mTotalDomainInitialSize += mDetJ0[PointNumber]*IntegrationWeight;<br />
<br />
}<br />
<br />
KRATOS_CATCH("")<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:48:29Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::Initialize()<br />
{<br />
KRATOS_TRY<br />
const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();<br />
<br />
//resizing jacobian inverses containers<br />
<br />
mInvJ0.resize(integration_points.size());<br />
mDetJ0.resize(integration_points.size());<br />
GeometryType::JacobiansType J0;<br />
J0 = GetGeometry().Jacobian(J0); <br />
mTotalDomainInitialSize = 0.00;<br />
<br />
if(mConstitutiveLawVector.size() == 0)<br />
{<br />
mConstitutiveLawVector.resize(integration_points.size());<br />
InitializeMaterial();<br />
}<br />
<br />
//calculating the inverse J0<br />
for(unsigned int PointNumber = 0; PointNumber<integration_points.size(); PointNumber++)<br />
{<br />
//getting informations for integration<br />
double IntegrationWeight = integration_points[PointNumber].Weight();<br />
//calculating and storing inverse of the jacobian and the parameters needed<br />
<br />
MathUtils<double>::InvertMatrix(J0[PointNumber],mInvJ0[PointNumber],mDetJ0[PointNumber]); <br />
<br />
<br />
<br />
//calculating the total area<br />
<br />
mTotalDomainInitialSize += mDetJ0[PointNumber]*IntegrationWeight;<br />
<br />
}<br />
<br />
KRATOS_CATCH("")<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:47:49Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::Initialize()<br />
{<br />
KRATOS_TRY<br />
const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();<br />
//resizing jacobian inverses containers<br />
<br />
mInvJ0.resize(integration_points.size());<br />
mDetJ0.resize(integration_points.size());<br />
GeometryType::JacobiansType J0;<br />
J0 = GetGeometry().Jacobian(J0); <br />
mTotalDomainInitialSize = 0.00;<br />
<br />
if(mConstitutiveLawVector.size() == 0)<br />
{<br />
mConstitutiveLawVector.resize(integration_points.size());<br />
InitializeMaterial();<br />
}<br />
<br />
//calculating the inverse J0<br />
for(unsigned int PointNumber = 0; PointNumber<integration_points.size(); PointNumber++)<br />
{<br />
//getting informations for integration<br />
double IntegrationWeight = integration_points[PointNumber].Weight();<br />
//calculating and storing inverse of the jacobian and the parameters needed<br />
<br />
MathUtils<double>::InvertMatrix(J0[PointNumber],mInvJ0[PointNumber],mDetJ0[PointNumber]); <br />
<br />
<br />
<br />
//calculating the total area<br />
<br />
mTotalDomainInitialSize += mDetJ0[PointNumber]*IntegrationWeight;<br />
<br />
}<br />
<br />
KRATOS_CATCH("")<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:47:34Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::Initialize()<br />
{<br />
KRATOS_TRY<br />
const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();<br />
//resizing jacobian inverses containers<br />
mInvJ0.resize(integration_points.size());<br />
mDetJ0.resize(integration_points.size());<br />
GeometryType::JacobiansType J0;<br />
J0 = GetGeometry().Jacobian(J0); <br />
mTotalDomainInitialSize = 0.00;<br />
<br />
if(mConstitutiveLawVector.size() == 0)<br />
{<br />
mConstitutiveLawVector.resize(integration_points.size());<br />
InitializeMaterial();<br />
}<br />
<br />
//calculating the inverse J0<br />
for(unsigned int PointNumber = 0; PointNumber<integration_points.size(); PointNumber++)<br />
{<br />
//getting informations for integration<br />
double IntegrationWeight = integration_points[PointNumber].Weight();<br />
//calculating and storing inverse of the jacobian and the parameters needed<br />
<br />
MathUtils<double>::InvertMatrix(J0[PointNumber],mInvJ0[PointNumber],mDetJ0[PointNumber]); <br />
<br />
<br />
<br />
//calculating the total area<br />
<br />
mTotalDomainInitialSize += mDetJ0[PointNumber]*IntegrationWeight;<br />
<br />
}<br />
<br />
KRATOS_CATCH("")<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:47:11Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::Initialize()<br />
{<br />
KRATOS_TRY<br />
const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();<br />
//resizing jacobian inverses containers<br />
mInvJ0.resize(integration_points.size());<br />
mDetJ0.resize(integration_points.size());<br />
GeometryType::JacobiansType J0;<br />
J0 = GetGeometry().Jacobian(J0); <br />
mTotalDomainInitialSize = 0.00;<br />
<br />
if(mConstitutiveLawVector.size() == 0)<br />
{<br />
mConstitutiveLawVector.resize(integration_points.size());<br />
InitializeMaterial();<br />
}<br />
<br />
//calculating the inverse J0<br />
for(unsigned int PointNumber = 0; PointNumber<integration_points.size(); PointNumber++)<br />
{<br />
//getting informations for integration<br />
double IntegrationWeight = integration_points[PointNumber].Weight();<br />
//calculating and storing inverse of the jacobian and the parameters needed<br />
<br />
MathUtils<double>::InvertMatrix(J0[PointNumber],mInvJ0[PointNumber],mDetJ0[PointNumber]); <br />
<br />
<br />
<br />
//calculating the total area<br />
<br />
mTotalDomainInitialSize += mDetJ0[PointNumber]*IntegrationWeight;<br />
<br />
}<br />
<br />
KRATOS_CATCH("")<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:46:58Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::Initialize()<br />
{<br />
KRATOS_TRY<br />
const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();<br />
//resizing jacobian inverses containers<br />
mInvJ0.resize(integration_points.size());<br />
mDetJ0.resize(integration_points.size());<br />
GeometryType::JacobiansType J0;<br />
J0 = GetGeometry().Jacobian(J0); <br />
mTotalDomainInitialSize = 0.00;<br />
<br />
if(mConstitutiveLawVector.size() == 0)<br />
{<br />
mConstitutiveLawVector.resize(integration_points.size());<br />
InitializeMaterial();<br />
}<br />
<br />
//calculating the inverse J0<br />
for(unsigned int PointNumber = 0; PointNumber<integration_points.size(); PointNumber++)<br />
{<br />
//getting informations for integration<br />
double IntegrationWeight = integration_points[PointNumber].Weight();<br />
//calculating and storing inverse of the jacobian and the parameters needed<br />
<br />
MathUtils<double>::InvertMatrix(J0[PointNumber],mInvJ0[PointNumber],mDetJ0[PointNumber]); <br />
<br />
<br />
<br />
//calculating the total area<br />
<br />
mTotalDomainInitialSize += mDetJ0[PointNumber]*IntegrationWeight;<br />
<br />
}<br />
<br />
KRATOS_CATCH("")<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:46:19Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::Initialize()<br />
{<br />
KRATOS_TRY<br />
const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();<br />
<br />
//resizing jacobian inverses containers<br />
mInvJ0.resize(integration_points.size());<br />
mDetJ0.resize(integration_points.size());<br />
<br />
GeometryType::JacobiansType J0;<br />
J0 = GetGeometry().Jacobian(J0); <br />
mTotalDomainInitialSize = 0.00;<br />
<br />
if(mConstitutiveLawVector.size() == 0)<br />
{<br />
mConstitutiveLawVector.resize(integration_points.size());<br />
InitializeMaterial();<br />
}<br />
<br />
//calculating the inverse J0<br />
for(unsigned int PointNumber = 0; PointNumber<integration_points.size(); PointNumber++)<br />
{<br />
//getting informations for integration<br />
double IntegrationWeight = integration_points[PointNumber].Weight();<br />
//calculating and storing inverse of the jacobian and the parameters needed<br />
<br />
MathUtils<double>::InvertMatrix(J0[PointNumber],mInvJ0[PointNumber],mDetJ0[PointNumber]); <br />
<br />
<br />
<br />
//calculating the total area<br />
<br />
mTotalDomainInitialSize += mDetJ0[PointNumber]*IntegrationWeight;<br />
<br />
}<br />
<br />
KRATOS_CATCH("")<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:45:45Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::Initialize()<br />
{<br />
KRATOS_TRY<br />
const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();<br />
<br />
//resizing jacobian inverses containers<br />
mInvJ0.resize(integration_points.size());<br />
mDetJ0.resize(integration_points.size());<br />
<br />
GeometryType::JacobiansType J0;<br />
J0 = GetGeometry().Jacobian(J0); <br />
mTotalDomainInitialSize = 0.00;<br />
<br />
if(mConstitutiveLawVector.size() == 0)<br />
{<br />
mConstitutiveLawVector.resize(integration_points.size());<br />
InitializeMaterial();<br />
}<br />
<br />
//calculating the inverse J0<br />
for(unsigned int PointNumber = 0; PointNumber<integration_points.size(); PointNumber++)<br />
{<br />
//getting informations for integration<br />
double IntegrationWeight = integration_points[PointNumber].Weight();<br />
//calculating and storing inverse of the jacobian and the parameters needed<br />
<br />
MathUtils<double>::InvertMatrix(J0[PointNumber],mInvJ0[PointNumber],mDetJ0[PointNumber]); <br />
<br />
<br />
<br />
//calculating the total area<br />
<br />
mTotalDomainInitialSize += mDetJ0[PointNumber]*IntegrationWeight;<br />
<br />
}<br />
<br />
KRATOS_CATCH("")<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:44:26Z<p>147.83.143.248: </p>
<hr />
<div> void LinearElement::Initialize()<br />
{<br />
KRATOS_TRY<br />
const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();<br />
<br />
//resizing jacobian inverses containers<br />
mInvJ0.resize(integration_points.size());<br />
mDetJ0.resize(integration_points.size());<br />
<br />
GeometryType::JacobiansType J0;<br />
J0 = GetGeometry().Jacobian(J0); <br />
mTotalDomainInitialSize = 0.00;<br />
<br />
if(mConstitutiveLawVector.size() == 0)<br />
{<br />
mConstitutiveLawVector.resize(integration_points.size());<br />
InitializeMaterial();<br />
}<br />
<br />
//calculating the inverse J0<br />
for(unsigned int PointNumber = 0; PointNumber<integration_points.size(); PointNumber++)<br />
{<br />
//getting informations for integration<br />
double IntegrationWeight = integration_points[PointNumber].Weight();<br />
//calculating and storing inverse of the jacobian and the parameters needed<br />
<br />
MathUtils<double>::InvertMatrix(J0[PointNumber],mInvJ0[PointNumber],mDetJ0[PointNumber]); <br />
<br />
<br />
<br />
//calculating the total area<br />
<br />
mTotalDomainInitialSize += mDetJ0[PointNumber]*IntegrationWeight;<br />
<br />
}<br />
<br />
KRATOS_CATCH("")<br />
<br />
}</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/InitializeInitialize2007-11-28T15:41:22Z<p>147.83.143.248: New page: afsafasdfsadf</p>
<hr />
<div>afsafasdfsadf</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/How_to_Create_New_ElementHow to Create New Element2007-11-28T15:40:33Z<p>147.83.143.248: /* '''Initialize''' */</p>
<hr />
<div>== How to implement a new element ==<br />
The practical way to write an element is to look at some element exists there<br />
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.<br />
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<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry);<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties); <br />
<br />
Create function just changes in the Linear_Element.cpp file as below<br />
<br />
Element::Pointer [[LinearElement]]::Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer <br />
pProperties) const<br />
{<br />
return Element::Pointer(new [[LinearElement]](NewId, GetGeometry().Create(ThisNodes), pProperties));<br />
}<br />
<br />
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. <br />
<br />
==='''Telling to the kratos that a new element exists'''===<br />
<br />
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]])<br />
<br />
==='''Element Implementation'''===<br />
<br />
The aim of this section is to provide a brief introduction to the main functions provided by the element interface.<br />
<br />
<br />
===='''The "CurrentProcessInfo"''':====<br />
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).<br />
<br />
<br />
===='''The "Degrees Of Freedom" (DOF):'''====<br />
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. <br />
The constructor of the element should provide the list of dofs for all of the nodes which compose the element.<br />
An example follows:<br />
...<br />
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:<br />
...<br />
<br />
<br />
===='''Calculation of the Right Hand Side (RHS):'''====<br />
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.<br />
<br />
The residua is defined as <br />
RHS = dWext - dWint <br />
(note that indeed this corresponds to the standard definition changed of sign)<br />
<br />
For linear problems, if the vector of external "forces" fext is known,<br />
The RHS can be calculated as <br />
RHS=fext-K*xp<br />
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)<br />
<br />
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.<br />
<br />
<br />
===='''Id:'''====<br />
returns the elemental unique id. <br />
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)<br />
<br />
==='''Functions'''===<br />
===='''CalculateSystemContributions'''====<br />
this function is called during the build phase and performs the calculation of RHS and LHS at the same time.<br />
As described above the RHS is a residua.<br />
<br />
<br />
===='''GetDofList'''====<br />
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.<br />
<br />
<br />
===='''GetEquationId'''====<br />
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.<br />
<br />
<br />
===='''[[Initialize]]'''====<br />
Function called ONCE at the first time a solving strategy is used.<br />
<br />
===='''InitalizeSolutionStep and FinalizeSolutionStep'''====<br />
Functions called ONCE at the beginning and end of a given solution process (a call of the Solve function of the solving strategy)<br />
<br />
<br />
===='''InitializeNonLinIteration and FinalizeNonLinIteration'''====<br />
Functions called once at the beginning and end of each non linear iteration. (they are called inside the Build process)<br />
<br />
<br />
===='''MassMatrix and DampMatrix'''====<br />
Return the elemental matrices with the same name <br />
<br />
<br />
===='''GetFirstDerivatives, GetSecondDerivatives'''====<br />
Gets the vectors of values corresponding to the first and second time derivatives for the elemental unknowns (at the time step desired)<br />
<br />
<br />
===='''Calculate'''====<br />
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"<br />
<br />
<br />
===='''CalculateOnIntegrationPoints'''====<br />
Similar to the function above but performs at once the calculation of the desired var on all the integration points. Returns Vector<VariableType></div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/How_to_Create_New_ElementHow to Create New Element2007-11-28T15:39:17Z<p>147.83.143.248: /* How to implement a new element */</p>
<hr />
<div>== How to implement a new element ==<br />
The practical way to write an element is to look at some element exists there<br />
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.<br />
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<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry);<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties); <br />
<br />
Create function just changes in the Linear_Element.cpp file as below<br />
<br />
Element::Pointer [[LinearElement]]::Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer <br />
pProperties) const<br />
{<br />
return Element::Pointer(new [[LinearElement]](NewId, GetGeometry().Create(ThisNodes), pProperties));<br />
}<br />
<br />
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. <br />
<br />
==='''Telling to the kratos that a new element exists'''===<br />
<br />
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]])<br />
<br />
==='''Element Implementation'''===<br />
<br />
The aim of this section is to provide a brief introduction to the main functions provided by the element interface.<br />
<br />
<br />
===='''The "CurrentProcessInfo"''':====<br />
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).<br />
<br />
<br />
===='''The "Degrees Of Freedom" (DOF):'''====<br />
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. <br />
The constructor of the element should provide the list of dofs for all of the nodes which compose the element.<br />
An example follows:<br />
...<br />
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:<br />
...<br />
<br />
<br />
===='''Calculation of the Right Hand Side (RHS):'''====<br />
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.<br />
<br />
The residua is defined as <br />
RHS = dWext - dWint <br />
(note that indeed this corresponds to the standard definition changed of sign)<br />
<br />
For linear problems, if the vector of external "forces" fext is known,<br />
The RHS can be calculated as <br />
RHS=fext-K*xp<br />
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)<br />
<br />
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.<br />
<br />
<br />
===='''Id:'''====<br />
returns the elemental unique id. <br />
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)<br />
<br />
==='''Functions'''===<br />
===='''CalculateSystemContributions'''====<br />
this function is called during the build phase and performs the calculation of RHS and LHS at the same time.<br />
As described above the RHS is a residua.<br />
<br />
<br />
===='''GetDofList'''====<br />
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.<br />
<br />
<br />
===='''GetEquationId'''====<br />
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.<br />
<br />
<br />
===='''Initialize'''====<br />
Function called ONCE at the first time a solving strategy is used.<br />
<br />
<br />
===='''InitalizeSolutionStep and FinalizeSolutionStep'''====<br />
Functions called ONCE at the beginning and end of a given solution process (a call of the Solve function of the solving strategy)<br />
<br />
<br />
===='''InitializeNonLinIteration and FinalizeNonLinIteration'''====<br />
Functions called once at the beginning and end of each non linear iteration. (they are called inside the Build process)<br />
<br />
<br />
===='''MassMatrix and DampMatrix'''====<br />
Return the elemental matrices with the same name <br />
<br />
<br />
===='''GetFirstDerivatives, GetSecondDerivatives'''====<br />
Gets the vectors of values corresponding to the first and second time derivatives for the elemental unknowns (at the time step desired)<br />
<br />
<br />
===='''Calculate'''====<br />
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"<br />
<br />
<br />
===='''CalculateOnIntegrationPoints'''====<br />
Similar to the function above but performs at once the calculation of the desired var on all the integration points. Returns Vector<VariableType></div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/ConstructorsConstructors2007-11-28T15:34:32Z<p>147.83.143.248: </p>
<hr />
<div>The minimal informations needed at the moment of the construction of a new element are: <br />
<br />
*'''''Id''''': a unique identifier of the element<br />
*'''''Properties::Pointer''''': it is the pointer to the container of data which are common to a group of elements<br />
*'''''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)<br />
<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry);<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties); <br />
<br />
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.<br />
<br />
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<br />
<br />
1 unsigned int, a minimum of 3 "Shared Pointers"<br />
Having thus a non negligible memory occupation.</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/ConstructorsConstructors2007-11-28T15:31:38Z<p>147.83.143.248: </p>
<hr />
<div><br />
The minimal informations needed at the moment of the construction of a new element are: <br />
<br />
*'''''Id''''': a unique identifier of the element<br />
*'''''Properties::Pointer''''': it is the pointer to the container of data which are common to a group of elements<br />
*'''''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)<br />
<br />
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.<br />
<br />
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<br />
<br />
1 unsigned int, a minimum of 3 "Shared Pointers"<br />
Having thus a non negligible memory occupation.</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/ConstructorsConstructors2007-11-28T14:36:41Z<p>147.83.143.248: New page: 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 poin...</p>
<hr />
<div>The minimal informations needed at the moment of the construction of a new element are: <br />
<br />
*'''''Id''''': a unique identifier of the element<br />
*'''''Properties::Pointer''''': it is the pointer to the container of data which are common to a group of elements<br />
*'''''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)<br />
<br />
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.<br />
<br />
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<br />
<br />
1 unsigned int, a minimum of 3 "Shared Pointers"<br />
Having thus a non negligible memory occupation.</div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/How_to_Create_New_ElementHow to Create New Element2007-11-28T14:36:29Z<p>147.83.143.248: /* How to implement a new element */</p>
<hr />
<div>== How to implement a new element ==<br />
The practical way to write an element is to look at some element exists there<br />
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.<br />
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<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry);<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties); <br />
<br />
Create function just changes in the Linear_Element.cpp file as below<br />
<br />
Element::Pointer [[LinearElement]]::Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer <br />
pProperties) const<br />
{<br />
return Element::Pointer(new [[LinearElement]](NewId, GetGeometry().Create(ThisNodes), pProperties));<br />
}<br />
<br />
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. <br />
<br />
The implementation of a new element is a standard operation in the FEM and an effort was made to simplify<br />
LinearElement::LinearElement(IndexType NewId, GeometryType::Pointer pGeometry, <br />
PropertiesType::Pointer pProperties): Element(NewId, pGeometry, pProperties)<br />
<br />
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.<br />
<br />
<br />
==='''Telling to the kratos that a new element exists'''===<br />
<br />
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]])<br />
<br />
==='''Element Implementation'''===<br />
<br />
The aim of this section is to provide a brief introduction to the main functions provided by the element interface.<br />
<br />
<br />
===='''The "CurrentProcessInfo"''':====<br />
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).<br />
<br />
<br />
===='''The "Degrees Of Freedom" (DOF):'''====<br />
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. <br />
The constructor of the element should provide the list of dofs for all of the nodes which compose the element.<br />
An example follows:<br />
...<br />
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:<br />
...<br />
<br />
<br />
===='''Calculation of the Right Hand Side (RHS):'''====<br />
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.<br />
<br />
The residua is defined as <br />
RHS = dWext - dWint <br />
(note that indeed this corresponds to the standard definition changed of sign)<br />
<br />
For linear problems, if the vector of external "forces" fext is known,<br />
The RHS can be calculated as <br />
RHS=fext-K*xp<br />
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)<br />
<br />
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.<br />
<br />
<br />
===='''Id:'''====<br />
returns the elemental unique id. <br />
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)<br />
<br />
==='''Functions'''===<br />
===='''CalculateSystemContributions'''====<br />
this function is called during the build phase and performs the calculation of RHS and LHS at the same time.<br />
As described above the RHS is a residua.<br />
<br />
<br />
===='''GetDofList'''====<br />
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.<br />
<br />
<br />
===='''GetEquationId'''====<br />
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.<br />
<br />
<br />
===='''Initialize'''====<br />
Function called ONCE at the first time a solving strategy is used.<br />
<br />
<br />
===='''InitalizeSolutionStep and FinalizeSolutionStep'''====<br />
Functions called ONCE at the beginning and end of a given solution process (a call of the Solve function of the solving strategy)<br />
<br />
<br />
===='''InitializeNonLinIteration and FinalizeNonLinIteration'''====<br />
Functions called once at the beginning and end of each non linear iteration. (they are called inside the Build process)<br />
<br />
<br />
===='''MassMatrix and DampMatrix'''====<br />
Return the elemental matrices with the same name <br />
<br />
<br />
===='''GetFirstDerivatives, GetSecondDerivatives'''====<br />
Gets the vectors of values corresponding to the first and second time derivatives for the elemental unknowns (at the time step desired)<br />
<br />
<br />
===='''Calculate'''====<br />
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"<br />
<br />
<br />
===='''CalculateOnIntegrationPoints'''====<br />
Similar to the function above but performs at once the calculation of the desired var on all the integration points. Returns Vector<VariableType></div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/How_to_Create_New_ElementHow to Create New Element2007-11-28T14:31:15Z<p>147.83.143.248: /* How to implement a new element */</p>
<hr />
<div>== How to implement a new element ==<br />
The practical way to write an element is to look at some element exists there<br />
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.<br />
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<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry);<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties); <br />
<br />
Create function just changes in the Linear_Element.cpp file as below<br />
<br />
Element::Pointer [[LinearElement]]::Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer <br />
pProperties) const<br />
{<br />
return Element::Pointer(new [[LinearElement]](NewId, GetGeometry().Create(ThisNodes), pProperties));<br />
}<br />
<br />
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. <br />
<br />
The implementation of a new element is a standard operation in the FEM and an effort was made to simplify<br />
LinearElement::LinearElement(IndexType NewId, GeometryType::Pointer pGeometry, <br />
PropertiesType::Pointer pProperties): Element(NewId, pGeometry, pProperties)<br />
<br />
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.<br />
<br />
The minimal informations needed at the moment of the construction of a new element are: <br />
<br />
*'''''Id''''': a unique identifier of the element<br />
*'''''Properties::Pointer''''': it is the pointer to the container of data which are common to a group of elements<br />
*'''''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)<br />
<br />
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.<br />
<br />
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<br />
<br />
1 unsigned int, a minimum of 3 "Shared Pointers"<br />
Having thus a non negligible memory occupation.<br />
<br />
<br />
==='''Telling to the kratos that a new element exists'''===<br />
<br />
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]])<br />
<br />
==='''Element Implementation'''===<br />
<br />
The aim of this section is to provide a brief introduction to the main functions provided by the element interface.<br />
<br />
<br />
===='''The "CurrentProcessInfo"''':====<br />
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).<br />
<br />
<br />
===='''The "Degrees Of Freedom" (DOF):'''====<br />
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. <br />
The constructor of the element should provide the list of dofs for all of the nodes which compose the element.<br />
An example follows:<br />
...<br />
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:<br />
...<br />
<br />
<br />
===='''Calculation of the Right Hand Side (RHS):'''====<br />
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.<br />
<br />
The residua is defined as <br />
RHS = dWext - dWint <br />
(note that indeed this corresponds to the standard definition changed of sign)<br />
<br />
For linear problems, if the vector of external "forces" fext is known,<br />
The RHS can be calculated as <br />
RHS=fext-K*xp<br />
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)<br />
<br />
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.<br />
<br />
<br />
===='''Id:'''====<br />
returns the elemental unique id. <br />
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)<br />
<br />
==='''Functions'''===<br />
===='''CalculateSystemContributions'''====<br />
this function is called during the build phase and performs the calculation of RHS and LHS at the same time.<br />
As described above the RHS is a residua.<br />
<br />
<br />
===='''GetDofList'''====<br />
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.<br />
<br />
<br />
===='''GetEquationId'''====<br />
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.<br />
<br />
<br />
===='''Initialize'''====<br />
Function called ONCE at the first time a solving strategy is used.<br />
<br />
<br />
===='''InitalizeSolutionStep and FinalizeSolutionStep'''====<br />
Functions called ONCE at the beginning and end of a given solution process (a call of the Solve function of the solving strategy)<br />
<br />
<br />
===='''InitializeNonLinIteration and FinalizeNonLinIteration'''====<br />
Functions called once at the beginning and end of each non linear iteration. (they are called inside the Build process)<br />
<br />
<br />
===='''MassMatrix and DampMatrix'''====<br />
Return the elemental matrices with the same name <br />
<br />
<br />
===='''GetFirstDerivatives, GetSecondDerivatives'''====<br />
Gets the vectors of values corresponding to the first and second time derivatives for the elemental unknowns (at the time step desired)<br />
<br />
<br />
===='''Calculate'''====<br />
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"<br />
<br />
<br />
===='''CalculateOnIntegrationPoints'''====<br />
Similar to the function above but performs at once the calculation of the desired var on all the integration points. Returns Vector<VariableType></div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/How_to_Create_New_ElementHow to Create New Element2007-11-28T14:22:36Z<p>147.83.143.248: /* How to implement a new element */</p>
<hr />
<div>== How to implement a new element ==<br />
The practical way to write an element is to look at some element exists there<br />
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.<br />
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<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry);<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties); <br />
<br />
Create function just changes in the Linear_Element.cpp file as below<br />
<br />
Element::Pointer [[LinearElement]]::Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer <br />
pProperties) const<br />
{<br />
return Element::Pointer(new [[LinearElement]](NewId, GetGeometry().Create(ThisNodes), pProperties));<br />
}<br />
<br />
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. <br />
<br />
The implementation of a new element is a standard operation in the FEM and an effort was made to simplify<br />
LinearElement::LinearElement(IndexType NewId, GeometryType::Pointer pGeometry, <br />
PropertiesType::Pointer pProperties): Element(NewId, pGeometry, pProperties)<br />
<br />
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.<br />
<br />
The minimal informations needed at the moment of the construction of a new element are: <br />
<br />
*'''''Id''''': a unique identifier of the element<br />
*'''''Properties::Pointer''''': it is the pointer to the container of data which are common to a group of elements<br />
*'''''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)<br />
<br />
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.<br />
<br />
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<br />
<br />
1 unsigned int, a minimum of 3 "Shared Pointers"<br />
Having thus a non negligible memory occupation.<br />
<br />
<br />
==='''Telling to the kratos that a new element exists'''===<br />
<br />
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]])<br />
<br />
==='''Element Implementation'''===<br />
<br />
The aim of this section is to provide a brief introduction to the main functions provided by the element interface.<br />
<br />
<br />
===='''The "CurrentProcessInfo"''':====<br />
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).<br />
<br />
<br />
===='''The "Degrees Of Freedom" (DOF):'''====<br />
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. <br />
The constructor of the element should provide the list of dofs for all of the nodes which compose the element.<br />
An example follows:<br />
...<br />
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:<br />
...<br />
<br />
<br />
===='''Calculation of the Right Hand Side (RHS):'''====<br />
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.<br />
<br />
The residua is defined as <br />
RHS = dWext - dWint <br />
(note that indeed this corresponds to the standard definition changed of sign)<br />
<br />
For linear problems, if the vector of external "forces" fext is known,<br />
The RHS can be calculated as <br />
RHS=fext-K*xp<br />
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)<br />
<br />
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.<br />
<br />
<br />
===='''Id:'''====<br />
returns the elemental unique id. <br />
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)<br />
<br />
==='''Functions'''===<br />
===='''CalculateSystemContributions'''====<br />
this function is called during the build phase and performs the calculation of RHS and LHS at the same time.<br />
As described above the RHS is a residua.<br />
<br />
<br />
===='''GetDofList'''====<br />
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.<br />
<br />
<br />
===='''GetEquationId'''====<br />
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.<br />
<br />
<br />
===='''Initialize'''====<br />
Function called ONCE at the first time a solving strategy is used.<br />
<br />
<br />
===='''InitalizeSolutionStep and FinalizeSolutionStep'''====<br />
Functions called ONCE at the beginning and end of a given solution process (a call of the Solve function of the solving strategy)<br />
<br />
<br />
===='''InitializeNonLinIteration and FinalizeNonLinIteration'''====<br />
Functions called once at the beginning and end of each non linear iteration. (they are called inside the Build process)<br />
<br />
<br />
===='''MassMatrix and DampMatrix'''====<br />
Return the elemental matrices with the same name <br />
<br />
<br />
===='''GetFirstDerivatives, GetSecondDerivatives'''====<br />
Gets the vectors of values corresponding to the first and second time derivatives for the elemental unknowns (at the time step desired)<br />
<br />
<br />
===='''Calculate'''====<br />
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"<br />
<br />
<br />
===='''CalculateOnIntegrationPoints'''====<br />
Similar to the function above but performs at once the calculation of the desired var on all the integration points. Returns Vector<VariableType></div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/How_to_Create_New_ElementHow to Create New Element2007-11-28T14:14:06Z<p>147.83.143.248: /* How to implement a new element */</p>
<hr />
<div>== How to implement a new element ==<br />
The practical way to write an element is to look at some element exists there<br />
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.<br />
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<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry);<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties); <br />
<br />
Create function just changes in the Linear_Element.cpp file as below<br />
<br />
Element::Pointer [[LinearElement]]::Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer <br />
pProperties) const<br />
{<br />
return Element::Pointer(new [[LinearElement]](NewId, GetGeometry().Create(ThisNodes), pProperties));<br />
}<br />
<br />
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.<br />
<br />
The implementation of a new element is a standard operation in the FEM and an effort was made to simplify<br />
LinearElement::LinearElement(IndexType NewId, GeometryType::Pointer pGeometry, <br />
PropertiesType::Pointer pProperties): Element(NewId, pGeometry, pProperties)<br />
<br />
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.<br />
<br />
The minimal informations needed at the moment of the construction of a new element are: <br />
<br />
*'''''Id''''': a unique identifier of the element<br />
*'''''Properties::Pointer''''': it is the pointer to the container of data which are common to a group of elements<br />
*'''''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)<br />
<br />
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.<br />
<br />
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<br />
<br />
1 unsigned int, a minimum of 3 "Shared Pointers"<br />
Having thus a non negligible memory occupation.<br />
<br />
<br />
==='''Telling to the kratos that a new element exists'''===<br />
<br />
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]])<br />
<br />
==='''Element Implementation'''===<br />
<br />
The aim of this section is to provide a brief introduction to the main functions provided by the element interface.<br />
<br />
<br />
===='''The "CurrentProcessInfo"''':====<br />
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).<br />
<br />
<br />
===='''The "Degrees Of Freedom" (DOF):'''====<br />
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. <br />
The constructor of the element should provide the list of dofs for all of the nodes which compose the element.<br />
An example follows:<br />
...<br />
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:<br />
...<br />
<br />
<br />
===='''Calculation of the Right Hand Side (RHS):'''====<br />
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.<br />
<br />
The residua is defined as <br />
RHS = dWext - dWint <br />
(note that indeed this corresponds to the standard definition changed of sign)<br />
<br />
For linear problems, if the vector of external "forces" fext is known,<br />
The RHS can be calculated as <br />
RHS=fext-K*xp<br />
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)<br />
<br />
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.<br />
<br />
<br />
===='''Id:'''====<br />
returns the elemental unique id. <br />
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)<br />
<br />
==='''Functions'''===<br />
===='''CalculateSystemContributions'''====<br />
this function is called during the build phase and performs the calculation of RHS and LHS at the same time.<br />
As described above the RHS is a residua.<br />
<br />
<br />
===='''GetDofList'''====<br />
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.<br />
<br />
<br />
===='''GetEquationId'''====<br />
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.<br />
<br />
<br />
===='''Initialize'''====<br />
Function called ONCE at the first time a solving strategy is used.<br />
<br />
<br />
===='''InitalizeSolutionStep and FinalizeSolutionStep'''====<br />
Functions called ONCE at the beginning and end of a given solution process (a call of the Solve function of the solving strategy)<br />
<br />
<br />
===='''InitializeNonLinIteration and FinalizeNonLinIteration'''====<br />
Functions called once at the beginning and end of each non linear iteration. (they are called inside the Build process)<br />
<br />
<br />
===='''MassMatrix and DampMatrix'''====<br />
Return the elemental matrices with the same name <br />
<br />
<br />
===='''GetFirstDerivatives, GetSecondDerivatives'''====<br />
Gets the vectors of values corresponding to the first and second time derivatives for the elemental unknowns (at the time step desired)<br />
<br />
<br />
===='''Calculate'''====<br />
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"<br />
<br />
<br />
===='''CalculateOnIntegrationPoints'''====<br />
Similar to the function above but performs at once the calculation of the desired var on all the integration points. Returns Vector<VariableType></div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/How_to_Create_New_ElementHow to Create New Element2007-11-28T14:07:26Z<p>147.83.143.248: /* How to implement a new element */</p>
<hr />
<div>== How to implement a new element ==<br />
The practical way to write an element is to look at some element exists there<br />
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.<br />
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<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry);<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties); <br />
<br />
Create function just changes in the Linear_Element.cpp file as below<br />
<br />
Element::Pointer [[LinearElement]]::Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer <br />
pProperties) const<br />
{<br />
return Element::Pointer(new [[LinearElement]](NewId, GetGeometry().Create(ThisNodes), pProperties));<br />
}<br />
<br />
After these functions, some more familiar functions, for a 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.<br />
<br />
The implementation of a new element is a standard operation in the FEM and an effort was made to simplify<br />
LinearElement::LinearElement(IndexType NewId, GeometryType::Pointer pGeometry, <br />
PropertiesType::Pointer pProperties): Element(NewId, pGeometry, pProperties)<br />
<br />
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.<br />
<br />
The minimal informations needed at the moment of the construction of a new element are: <br />
<br />
*'''''Id''''': a unique identifier of the element<br />
*'''''Properties::Pointer''''': it is the pointer to the container of data which are common to a group of elements<br />
*'''''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)<br />
<br />
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.<br />
<br />
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<br />
<br />
1 unsigned int, a minimum of 3 "Shared Pointers"<br />
Having thus a non negligible memory occupation.<br />
<br />
<br />
==='''Telling to the kratos that a new element exists'''===<br />
<br />
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]])<br />
<br />
==='''Element Implementation'''===<br />
<br />
The aim of this section is to provide a brief introduction to the main functions provided by the element interface.<br />
<br />
<br />
===='''The "CurrentProcessInfo"''':====<br />
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).<br />
<br />
<br />
===='''The "Degrees Of Freedom" (DOF):'''====<br />
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. <br />
The constructor of the element should provide the list of dofs for all of the nodes which compose the element.<br />
An example follows:<br />
...<br />
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:<br />
...<br />
<br />
<br />
===='''Calculation of the Right Hand Side (RHS):'''====<br />
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.<br />
<br />
The residua is defined as <br />
RHS = dWext - dWint <br />
(note that indeed this corresponds to the standard definition changed of sign)<br />
<br />
For linear problems, if the vector of external "forces" fext is known,<br />
The RHS can be calculated as <br />
RHS=fext-K*xp<br />
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)<br />
<br />
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.<br />
<br />
<br />
===='''Id:'''====<br />
returns the elemental unique id. <br />
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)<br />
<br />
==='''Functions'''===<br />
===='''CalculateSystemContributions'''====<br />
this function is called during the build phase and performs the calculation of RHS and LHS at the same time.<br />
As described above the RHS is a residua.<br />
<br />
<br />
===='''GetDofList'''====<br />
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.<br />
<br />
<br />
===='''GetEquationId'''====<br />
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.<br />
<br />
<br />
===='''Initialize'''====<br />
Function called ONCE at the first time a solving strategy is used.<br />
<br />
<br />
===='''InitalizeSolutionStep and FinalizeSolutionStep'''====<br />
Functions called ONCE at the beginning and end of a given solution process (a call of the Solve function of the solving strategy)<br />
<br />
<br />
===='''InitializeNonLinIteration and FinalizeNonLinIteration'''====<br />
Functions called once at the beginning and end of each non linear iteration. (they are called inside the Build process)<br />
<br />
<br />
===='''MassMatrix and DampMatrix'''====<br />
Return the elemental matrices with the same name <br />
<br />
<br />
===='''GetFirstDerivatives, GetSecondDerivatives'''====<br />
Gets the vectors of values corresponding to the first and second time derivatives for the elemental unknowns (at the time step desired)<br />
<br />
<br />
===='''Calculate'''====<br />
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"<br />
<br />
<br />
===='''CalculateOnIntegrationPoints'''====<br />
Similar to the function above but performs at once the calculation of the desired var on all the integration points. Returns Vector<VariableType></div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/How_to_Create_New_ElementHow to Create New Element2007-11-28T14:05:47Z<p>147.83.143.248: /* How to implement a new element */</p>
<hr />
<div>== How to implement a new element ==<br />
The practical way to write an element is to look at some element exists there<br />
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.<br />
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<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry);<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties); <br />
<br />
Create function just changes in the Linear_Element.cpp file as <br />
<br />
Element::Pointer [[LinearElement]]::Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer <br />
pProperties) const<br />
{<br />
return Element::Pointer(new [[LinearElement]](NewId, GetGeometry().Create(ThisNodes), pProperties));<br />
}<br />
<br />
After these functions, some more familiar functions, for a 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.<br />
<br />
The implementation of a new element is a standard operation in the FEM and an effort was made to simplify<br />
LinearElement::LinearElement(IndexType NewId, GeometryType::Pointer pGeometry, <br />
PropertiesType::Pointer pProperties): Element(NewId, pGeometry, pProperties)<br />
<br />
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.<br />
<br />
The minimal informations needed at the moment of the construction of a new element are: <br />
<br />
*'''''Id''''': a unique identifier of the element<br />
*'''''Properties::Pointer''''': it is the pointer to the container of data which are common to a group of elements<br />
*'''''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)<br />
<br />
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.<br />
<br />
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<br />
<br />
1 unsigned int, a minimum of 3 "Shared Pointers"<br />
Having thus a non negligible memory occupation.<br />
<br />
<br />
==='''Telling to the kratos that a new element exists'''===<br />
<br />
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]])<br />
<br />
==='''Element Implementation'''===<br />
<br />
The aim of this section is to provide a brief introduction to the main functions provided by the element interface.<br />
<br />
<br />
===='''The "CurrentProcessInfo"''':====<br />
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).<br />
<br />
<br />
===='''The "Degrees Of Freedom" (DOF):'''====<br />
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. <br />
The constructor of the element should provide the list of dofs for all of the nodes which compose the element.<br />
An example follows:<br />
...<br />
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:<br />
...<br />
<br />
<br />
===='''Calculation of the Right Hand Side (RHS):'''====<br />
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.<br />
<br />
The residua is defined as <br />
RHS = dWext - dWint <br />
(note that indeed this corresponds to the standard definition changed of sign)<br />
<br />
For linear problems, if the vector of external "forces" fext is known,<br />
The RHS can be calculated as <br />
RHS=fext-K*xp<br />
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)<br />
<br />
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.<br />
<br />
<br />
===='''Id:'''====<br />
returns the elemental unique id. <br />
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)<br />
<br />
==='''Functions'''===<br />
===='''CalculateSystemContributions'''====<br />
this function is called during the build phase and performs the calculation of RHS and LHS at the same time.<br />
As described above the RHS is a residua.<br />
<br />
<br />
===='''GetDofList'''====<br />
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.<br />
<br />
<br />
===='''GetEquationId'''====<br />
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.<br />
<br />
<br />
===='''Initialize'''====<br />
Function called ONCE at the first time a solving strategy is used.<br />
<br />
<br />
===='''InitalizeSolutionStep and FinalizeSolutionStep'''====<br />
Functions called ONCE at the beginning and end of a given solution process (a call of the Solve function of the solving strategy)<br />
<br />
<br />
===='''InitializeNonLinIteration and FinalizeNonLinIteration'''====<br />
Functions called once at the beginning and end of each non linear iteration. (they are called inside the Build process)<br />
<br />
<br />
===='''MassMatrix and DampMatrix'''====<br />
Return the elemental matrices with the same name <br />
<br />
<br />
===='''GetFirstDerivatives, GetSecondDerivatives'''====<br />
Gets the vectors of values corresponding to the first and second time derivatives for the elemental unknowns (at the time step desired)<br />
<br />
<br />
===='''Calculate'''====<br />
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"<br />
<br />
<br />
===='''CalculateOnIntegrationPoints'''====<br />
Similar to the function above but performs at once the calculation of the desired var on all the integration points. Returns Vector<VariableType></div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/How_to_Create_New_ElementHow to Create New Element2007-11-28T14:05:14Z<p>147.83.143.248: /* How to implement a new element */</p>
<hr />
<div>== How to implement a new element ==<br />
The practical way to write an element is to look at some element exists there<br />
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.<br />
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<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry);<br />
[[LinearElement]](IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties); <br />
<br />
Create function just changes in the Linear_Element.cpp file as <br />
<br />
Element::Pointer [[LinearElement]]::Create(IndexType NewId, NodesArrayType const& ThisNodes, PropertiesType::Pointer <br />
pProperties) const<br />
{<br />
return Element::Pointer(new [[LinearElement]](NewId, GetGeometry().Create(ThisNodes), pProperties));<br />
}<br />
<br />
After these functions, some more familiar functions, for a 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.<br />
<br />
The implementation of a new element is a standard operation in the FEM and an effort was made to simplify<br />
LinearElement::LinearElement(IndexType NewId, GeometryType::Pointer pGeometry, <br />
PropertiesType::Pointer pProperties): Element(NewId, pGeometry, pProperties)<br />
<br />
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.<br />
<br />
The minimal informations needed at the moment of the construction of a new element are: <br />
<br />
*'''''Id''''': a unique identifier of the element<br />
*'''''Properties::Pointer''''': it is the pointer to the container of data which are common to a group of elements<br />
*'''''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)<br />
<br />
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.<br />
<br />
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<br />
<br />
1 unsigned int, a minimum of 3 "Shared Pointers"<br />
Having thus a non negligible memory occupation.<br />
<br />
<br />
==='''Telling to the kratos that a new element exists'''===<br />
<br />
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]])<br />
<br />
==='''Element Implementation'''===<br />
<br />
The aim of this section is to provide a brief introduction to the main functions provided by the element interface.<br />
<br />
<br />
===='''The "CurrentProcessInfo"''':====<br />
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).<br />
<br />
<br />
===='''The "Degrees Of Freedom" (DOF):'''====<br />
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. <br />
The constructor of the element should provide the list of dofs for all of the nodes which compose the element.<br />
An example follows:<br />
...<br />
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:<br />
...<br />
<br />
<br />
===='''Calculation of the Right Hand Side (RHS):'''====<br />
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.<br />
<br />
The residua is defined as <br />
RHS = dWext - dWint <br />
(note that indeed this corresponds to the standard definition changed of sign)<br />
<br />
For linear problems, if the vector of external "forces" fext is known,<br />
The RHS can be calculated as <br />
RHS=fext-K*xp<br />
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)<br />
<br />
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.<br />
<br />
<br />
===='''Id:'''====<br />
returns the elemental unique id. <br />
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)<br />
<br />
==='''Functions'''===<br />
===='''CalculateSystemContributions'''====<br />
this function is called during the build phase and performs the calculation of RHS and LHS at the same time.<br />
As described above the RHS is a residua.<br />
<br />
<br />
===='''GetDofList'''====<br />
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.<br />
<br />
<br />
===='''GetEquationId'''====<br />
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.<br />
<br />
<br />
===='''Initialize'''====<br />
Function called ONCE at the first time a solving strategy is used.<br />
<br />
<br />
===='''InitalizeSolutionStep and FinalizeSolutionStep'''====<br />
Functions called ONCE at the beginning and end of a given solution process (a call of the Solve function of the solving strategy)<br />
<br />
<br />
===='''InitializeNonLinIteration and FinalizeNonLinIteration'''====<br />
Functions called once at the beginning and end of each non linear iteration. (they are called inside the Build process)<br />
<br />
<br />
===='''MassMatrix and DampMatrix'''====<br />
Return the elemental matrices with the same name <br />
<br />
<br />
===='''GetFirstDerivatives, GetSecondDerivatives'''====<br />
Gets the vectors of values corresponding to the first and second time derivatives for the elemental unknowns (at the time step desired)<br />
<br />
<br />
===='''Calculate'''====<br />
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"<br />
<br />
<br />
===='''CalculateOnIntegrationPoints'''====<br />
Similar to the function above but performs at once the calculation of the desired var on all the integration points. Returns Vector<VariableType></div>147.83.143.248https://kratos-wiki.cimne.upc.edu/index.php/How_to_Use_an_ApplicationHow to Use an Application2007-11-28T13:31:12Z<p>147.83.143.248: </p>
<hr />
<div>This is a brief tutorial of how to read and use an Application in Kratos.<br />
<br />
This is not a description of the use of any application in particular. See the sections of every single application for details.<br />
<br />
<br />
<br />
== Test_Example.py file ==<br />
<br />
The starting point to read an Application is to open the [[Python Basics|Python]] file that describes the test-example.py (see for instance <tt>/kratos/application/<application_name>/test_examples/</tt> where there are some [[Python Basics|Python]] files that can be used as a sort of benchmarks in the construction of your own [[Python Basics|Python]] script).<br />
<br />
The test-example.py represents the [[General Structure|IO script]] to interact with Kratos without entering it.<br />
You can create or modify your own file without having knowledge of C++ programming or of the internal structure of Kratos.<br />
<br />
Your test-example.py file has to be put inside your [[GiD_example]] file when you want to run it.<br />
<br />
Once you have to execute your own example you will enter into your [[GiD_example]] folder from the command window and run your test-example.py file with [[Python Basics|Python]] from the command line typing:<br />
<br />
python <test_example name> <br />
<br />
That means that inside your test-example.py file all Kratos libraries, and any other utility is called and executed, 'implicitly'.<br />
<br />
<br />
===Reading a Test_Example.py file===<br />
<br />
The first instruction to insert is the dimension of the problem:<br />
<br />
#setting the domain size for the problem to be solved<br />
domain_size = 2<br />
<br />
<br />
Then you have to insert the path where the kratos libraries can be found: that means the path of the folders <tt>~/kratos/libs</tt> and <tt>~/kratos/applications</tt> in [[Python Basics|Python]] style:<br />
<br />
#including kratos path<br />
kratos_libs_path = '<Kratos_root_path>/libs' ##kratos_root/libs<br />
kratos_applications_path = '<Kratos_root_path>/applications/' ##kratos_root/applications<br />
<br />
Once you have inserted the full path you import the [[Python Basics|Python]] module ''sys'' (where all the directories are set) and you insert also these two new paths in it:<br />
<br />
import sys<br />
sys.path.append(kratos_libs_path)<br />
sys.path.append(kratos_applications_path)<br />
<br />
Now the program knows where to look for the different libraries. You can now import them:<br />
<br />
#importing Kratos main library<br />
from Kratos import *<br />
kernel = Kernel() #defining kernel<br />
<br />
Two things have to be pointed out about this sentences:<br />
* With the sentence <tt>from Kratos import *</tt> (instead of ''import Kratos''), you are automatically importing objects from Kratos that means you don't have to write<br />
kernel = Kratos.Kernel()<br />
but you have already assumed Kernel() to be a function of Kratos.<br />
<br />
* Where are you importing from? Or, in other words, where can you look for 'Kratos' just to see what are you importing? The sentence ' ''form Kratos import *'' ' as to be read as ' ''from the library Kratos.so, created compiling the whole Kratos, import'' '. You cannot actually open the Kratos.so file (into <tt>~kratos/libs</tt>), but you can for example, go into <tt>~/kratos/Python</tt>, where the interface between Kratos and Python is set, and look for the file ''add_kernel_to_python.cpp'', where you can read:<br />
<br />
// System includes <br />
// External includes <br />
#include <boost/python.hpp><br />
// Project includes<br />
#include "includes/define.h" <br />
'''#include "includes/kernel.h"'''<br />
#include "python/add_kernel_to_python.h"<br />
namespace Kratos<br />
{<br />
namespace Python <br />
{<br />
....<br />
} // namespace Python.<br />
} // Namespace Kratos<br />
<br />
Here you can find where kernel is defined (''includes/kernel.h''), and you can finally understand what it is.<br />
<br />
Following with the reading of the test-example.py you can find:<br />
<br />
#importing applications<br />
import applications_interface<br />
applications_interface.Import_<application_name> = True<br />
applications_interface.ImportApplications(kernel, kratos_applications_path)<br />
<br />
In this case you are importing from the file application_interface.py (that you can find into <tt>~/kratos/applications/</tt>) and you are choosing which one of the applications you want to use: in this case just look inside the ''application_interface.py'' to know the correct name of the application and choose which is the applications, that is set to ''False'', that you want to switch into ''True''.<br />
The last line calls the function ''ImportApplication'' (always inside application_interface.py) that sets all the missed path and opens the import process from the required application:<br />
<br />
from KratosR1<application_name> import *<br />
<br />
You have just open the access to the KratosR1<application_name>.so that you can find in (<tt>~/kratos/libs/</tt>), this ''.so'' file is the library connected to the application you want to use.<br />
<br />
Into <tt>~/kratosR1/application/<application_name></tt> you find a lot of different '''custom_folders''' where there are all the elements, strategies, utilities, and so on, that are particular only of the application you are using (that is the reason why it is 'custom').<br />
In principle it is probable that many things are taken directly from <tt>~/kratos/</tt> if a general approach is sufficient; on the contrary, everything that needs a particularization for the treated application is defined inside the custom part.<br />
<br />
<br />
Into the file '''<application_name>.cpp''' there is a list of registered variables and registered [[How to Create New Element|elements]] that are the specific added variables and elements. <br />
<br />
<br />
You have to pass to your program all the [[How to Use the ModelPart|model_parts]] (in a coupled problem the Structure part will olsa be present in addition to the fluid part) by typing:<br />
<br />
#defining a model part<br />
model_part = ModelPart("FluidPart");<br />
<br />
You have now to chose the solver you want to use: you are importing another file [[Python Basics|Python]] where the different solvers are called.<br />
If you want to see where the different solvers are defined and implemented see <tt>~/kratosR1/kratos/linear_solver</tt> .<br />
<br />
<br />
##importing the solver files and adding the variables<br />
import <application_name>_solver<br />
<application_name>_solver.AddVariables(model_part)<br />
<br />
Reading the file '''<application_name>_solver.py''' (that you can find into <tt>~/kratosR1/applications/<application_name>/python_scripts/</tt>), you usually find two basic functions for adding standard variables and adding standard dof of this kind of problem and then the class <application_name>solver is created.<br />
Inside this class thee functions are defined:<br />
* '''__init__''' :some basic characteristics of the problem (that is, for instance the velocity tolerance, the pressure tolerance and so on) are set to their default values and the solvers are chosen; <br />
* '''initialize''' : the strategy is chosen (look in <tt>~/kratosR1/applications/<application_name>/custom_strategies/strategies/</tt>);<br />
* '''solve''' : the solve function of the chosen strategy is called and executed;<br />
<br />
This is the moment to add extra variables if it is necessary. The only thing to do is to type:<br />
<br />
model_part.AddNodalSolutionStepVariable(<varible_name_in_capital_letters>)<br />
<br />
Now you have to allow your program to read the data files already created from GiD:<br />
<br />
#reading a model<br />
gid_io = GidIO("<GiD_example>",GiDPostMode.GiD_PostBinary)<br />
##gid_io.ReadMesh(model_part.GetMesh())<br />
gid_io.ReadModelPart(model_part)<br />
gid_io.WriteMesh((model_part).GetMesh(),domain_size,GiDPostMode.GiD_PostBinary);<br />
print model_part<br />
<br />
<br />
Here it is essential to modify each time the <GiD_example> name because if there is no correspondence the [[Python Basics|Python]] will give an error message and it will stuck. the rest of the command represents the standard way to read the model.<br />
<br />
#the buffer size should be set up here after the mesh is read for the first time<br />
model_part.SetBufferSize(3)<br />
<br />
You have to set the buffer size and if it is necessary you can now add other dofs to your problem in addition to those already defined as dofs in the function AddDofs inside the <application_name>_solver.py<br />
<br />
##add Degrees of Freedom to all of the nodes<br />
<application_name>_solver.AddDofs(model_part)<br />
<br />
You have to create the '''solver object''' of the class <application_name>Solver (see inside <application_name>_solver.py).<br />
<br />
#creating a fluid solver object<br />
fluid_solver = <application_name>_solver.<application_name>Solver(model_part,domain_size)<br />
<br />
fluid solver is from now on the object of the class <application_name>Solver defined inside <application_name>_solver.py file and you can now change the default variables already set into the construct function of the same <application_name>Solver class (__Init__) <br />
<br />
fluid_solver.laplacian_form = 2;<br />
fluid_solver.predictor_corrector = True<br />
fluid_solver.vel_toll = 1e-3<br />
fluid_solver.time_order = 2<br />
fluid_solver.echo_level = 0<br />
<br />
<br />
You have now to initialize the problem calling the function Initialize of the class:<br />
<br />
fluid_solver.Initialize()<br />
<br />
Once the problem is initialized you can insert all the operations you need to particularize your test_example. You have only to pay attention that here only actions that are '''time independent''' must be written because you are still out of the loop over the time steps. <br />
For example you can set the initial value value of a nodal variable typing:<br />
<br />
for node in model_part.Nodes:<br />
node.SetSolutionStepValue(VISCOSITY,0,1.0/Re)<br />
<br />
where VISCOSITY is the nodal variable you want to change, 0 or 1 or 2 indicate the actual time step (t+dt) that you are calculating or the previous time step (t) or the time step still previous (t-dt) respectively, and the third argument is the value you want to give to your variable.<br />
<br />
Here you have to define the total number of the step, time step or the time step to print results:<br />
<br />
nsteps = 200<br />
Dt = 1000.0/Re<br />
output_step = 1<br />
<br />
Once you have defined everything you need you can start the loop over the time steps:<br />
<br />
for step in range(1,nsteps):<br />
<br />
and you can start to solve the current step calling the solve function of the class <application_name>Solver defined inside <application_name>_solver.py<br />
<br />
fluid_solver.Solve()<br />
<br />
Finally this is the place where you can give instructions to set, for example, the values of some variables or something like this:<br />
<br />
for node in model_part.Nodes:<br />
node.SetSolutionStepValue(PRESS_PROJ,0,zero);<br />
<br />
<br />
The only thing that is missed is to print the results of the current time step:<br />
<br />
#print the results<br />
if(out == output_step): #if you are in the step you set to print results then print the following variables:<br />
gid_io.WriteNodalResults(PRESSURE,model_part.Nodes,time,0)<br />
gid_io.WriteNodalResults(VELOCITY,model_part.Nodes,time,0)<br />
gid_io.WriteNodalResults(PRESS_PROJ,model_part.Nodes,time,0)<br />
gid_io.WriteNodalResults(CONV_PROJ,model_part.Nodes,time,0)<br />
gid_io.WriteNodalResults(NODAL_AREA,model_part.Nodes,time,0)<br />
gid_io.WriteNodalResults(VISCOSITY,model_part.Nodes,time,0)</div>147.83.143.248