Kratos For Dummies OLD

From KratosWiki
Revision as of 16:54, 22 February 2011 by Gcasas (Talk | contribs)
Jump to: navigation, search

Warn_icon.gif Warning. Please, note that:

  • If you have some questions, comments or suggestions, you can use the "discussion" tab to include them.

Info_icon.gif Things to do:

  • This article needs a language revision.
  • This article will be expanded with sample examples, complementary explanations, etc.


Contents

The Most Basic Finite Element Method Formulation

Suggested Prerequisites

  • Linear algebra
  • Partial differential equations
  • ... ...

Our Partial Differential Equation: Poisson's equation

As our first example, we will use the Poisson's Equation in two-dimensional Cartesian coordinates, that it takes the form:


Dominio2D.jpg
\left[ \frac{\partial}{\partial x}\cdot \left( K_{x} \cdot \frac{\partial}{\partial x}\right) + \frac{\partial}{\partial y}\cdot \left(K_{y} \cdot \frac{\partial}{\partial y} \right) \right]\varphi(x,y) = f(x,y)


for a domain Ω, equivalent to write:


\nabla \cdot (K \nabla \varphi )= f


where K is the material property, \varphi is the unknown to obtain and f is a source term.

Boundary Conditions

Two different boundary conditions will be considered:

Dirichlet boundary condition

The first type boundary condition specifies the values the solution needs to take (\varphi_{0}) on a boundary ({\Gamma_{\varphi}}) of the domain:

\varphi(x,y)\mid_{\Gamma_{\varphi}}  = \varphi_{0}

Neumann boundary condition

The second type boundary condition specifies the values that the derivative of a solution (q0) is to take on the boundary (Γq) of the domain:

K \nabla \varphi(x,y)\mid_{\Gamma_{q}}  = q_{0}

Finite Element Method Formulation

The Weak formulation using the Weighted Residual Form (Galerkin Method) of Poisson equation can be written as follows:

 
    {
    \int_{\Omega} W [\nabla^T D \nabla \varphi + \rho_v]\partial \Omega 
    + \oint_{\Gamma_q}\overline{W}[n^T D \nabla \varphi +  \overline{q}]\partial \Gamma_q=0
    }

with W, \overline{W} the weights for each differential equation. If \overline{W}=W and using the integration by parts, this equation becomes:

 
    {
    \int_{\Omega} \nabla^T W^T D \nabla \varphi \partial \Omega =
    \int_{\Omega} W^T \rho_v \partial \Omega 
    - \oint_{\Gamma_q} W^T \overline{q_n} \partial \Gamma_q
    - \oint_{\Gamma_{\varphi}} W^T q_n \partial \Gamma_{\varphi}
    }

for the two-dimensional Cartesian coordinates, each term can be written:

D = 
   \begin{bmatrix}
     K_x & 0      \\
     0   & K_y
   \end{bmatrix}
\partial \Omega = \partial x \partial y
x=[x,y]^T = \sum N_i[x_i,y_i]^T

with N_i the shape forms of the element.

\varphi = \sum N_i \varphi_i = N a^{(e)}
q=- D \nabla \varphi = - D \nabla N a^{(e)} = - D B a^{(e)}

with B defined as:

B = 
   \begin{bmatrix}
      B_1...  & B_n
   \end{bmatrix}
B_i =
   \begin{bmatrix}
     \frac{\partial N_i}{\partial x}      \\
     \frac{\partial N_i}{\partial y}
   \end{bmatrix}

These system of equations can be written as the following matricial form:

K \cdot a = f

with K the stiffness matrix of the system, a the vector of nodal values to obatin (unknown vector), and f the source vector (independent forces or charges).

The superscript (e) refers to the equation applied for each element.

K^{(e)} =
   {
    \int_{\Omega^{(e)}} B^T D B \partial \Omega^{(e)}
    }
f^{(e)} =
   {
    \int_{\Omega^{(e)}} N^T \rho_v \partial \Omega^{(e)}
    - \oint_{\Gamma_q^{(e)}} N^T \overline{q} \partial \Gamma_q^{(e)}
    - \oint_{\Gamma_{\varphi}^{(e)}} n^T N^T q_n \partial \Gamma_{\varphi}^({(e)}
   }

A very symple example (to be prepared).


A First Kratos Element

Suggested Prerequisites:

  • Finite Element Formulation for a PDE

Introduction

An element in Kratos is the implementation code of the Elemental Finite Element Formulation for a PDE. An element can be used for any already existing application in Kratos, by including it in their corresponding files. The next section will explain the creation of a new application in Kratos. For simplicity reasons, we will focus now in the creation of the element, leaving the application's aspects in the next section.

Therefore, to check the element operation we will need to create the application, and we have not way to validate it here for the moment.

In this point we will need just to know the name of the application for their corresponding files ("kPoisson"), and the name of the application methods "PoissonApplication".

Our first element in Kratos will be the implementation of the Poisson's equation, so we will call it "poisson_2d". The class name for the element will be called "Poisson2D".

The most basic element implemented in Kratos only needs two files:

  • poisson_2d.h
  • poisson_2d.cpp

A quick way to create an element is to select one of the existing ones close to our formulation and modifying some specific parts. We are going to show the code of these two files with some comments in those lines you probably would want to customise.

The following code includes the most usual sections needed to operate with a Kratos element. Most of the code is common in all the elements and it doesn't need any change. Specific customisation is remarked using bold characters, therefore in general terms you should pay attention just to these parts and keep the rest unchanged.

Element header file: poisson_2d.h

First lines: legal issues

The first lines are just the typical legal issues related to Kratos as a framework to create simulation programs. You should keep them as they are. The only sentence to customise is the name of the application (in bold characters) in the third line, KratosR1PoissonApplication:

/*
==============================================================================
KratosR1PoissonApplication 
A library based on:
Kratos
A General Purpose Software for Multi-Physics Finite Element Analysis
Version 1.0 (Released on march 05, 2007).

Copyright 2008
Pooyan Dadvand, Riccardo Rossi
pooyan@cimne.upc.edu 
rrossi@cimne.upc.edu
- CIMNE (International Center for Numerical Methods in Engineering),
Gran Capita' s/n, 08034 Barcelona, Spain

Permission is hereby granted, free  of charge, to any person obtaining
a  copy  of this  software  and  associated  documentation files  (the
"Software"), to  deal in  the Software without  restriction, including
without limitation  the rights to  use, copy, modify,  merge, publish,
distribute,  sublicense and/or  sell copies  of the  Software,  and to
permit persons to whom the Software  is furnished to do so, subject to
the following condition:

Distribution of this code for  any  commercial purpose  is permissible
ONLY BY DIRECT ARRANGEMENT WITH THE COPYRIGHT OWNERS.

The  above  copyright  notice  and  this permission  notice  shall  be
included in all copies or substantial portions of the Software.

THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT  SHALL THE AUTHORS OR COPYRIGHT HOLDERS  BE LIABLE FOR ANY
CLAIM, DAMAGES OR  OTHER LIABILITY, WHETHER IN AN  ACTION OF CONTRACT,
TORT  OR OTHERWISE, ARISING  FROM, OUT  OF OR  IN CONNECTION  WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

==============================================================================
*/

The following lines (comments again) indicate the author's name (your name), date and hour of the last revision, and revision number, as usual in other codes.

//   
//   Project Name:        Kratos       
//   Last modified by:    $Author: it's me! $
//   Date:                $Date: 2008-08-08 23:58:38 $
//   Revision:            $Revision: 1.0 $
//
//


In order to avoid class redefinition, you have to define a label for your element definition, as follows:

#if !defined(KRATOS_POISSON_2D_ELEM_H_INCLUDED)
#define  KRATOS_POISSON_2D_ELEM_H_INCLUDED

the #endif is at the end of the code (the rest of the lines must be included between these ones):

#endif // KRATOS_POISSON_2D_ELEM_H_INCLUDED  defined

Now you have to add the "include" files (copy as it is):

// System includes 


// External includes 
#include "boost/smart_ptr.hpp"


// Project includes
#include "includes/define.h"
#include "includes/element.h"
#include "includes/ublas_interface.h"
#include "includes/variables.h"

Declare the namespace Kratos (copy at it is):

namespace Kratos
{

 ///@name Kratos Globals
 ///@{ 
  
 ///@} 
 ///@name Type Definitions
 ///@{ 
 
 ///@} 
 ///@name  Enum's
 ///@{
     
 ///@}
 ///@name  Functions 
 ///@{
     
 ///@}
 ///@name Kratos Classes
 ///@{
 
 /// Short class definition.
 /** Detail class definition.
 */

The namespace is closed at the end of the file (just before the #endif):

}  // namespace Kratos.

Our class definition starts now. We will call it "Poisson2D":

 class Poisson2D
	  : public Element
   {
   public:
     ///@name Type Definitions
     ///@{
     
     /// Counted pointer of Poisson2D
     KRATOS_CLASS_POINTER_DEFINITION(Poisson2D);


     ///@}
     ///@name Life Cycle 
     ///@{

Constructor and destructor declaration (you should just change the class name):

    /// Default constructor.
     Poisson2D(IndexType NewId, GeometryType::Pointer pGeometry);
     Poisson2D(IndexType NewId, GeometryType::Pointer pGeometry,  PropertiesType::Pointer pProperties);

     /// Destructor.
     virtual ~ Poisson2D();

     ///@}
     ///@name Operators 
     ///@{
     
     
     ///@}
     ///@name Operations
     ///@{

And we add the class methods we need to perform the implementation of the element. By now we will just declare the methods, leaving a more detailed explanation in the implementation file (.cpp). Note that for this simple element you don't need change anything:

     Element::Pointer Create(IndexType NewId, NodesArrayType const& ThisNodes,  PropertiesType::Pointer pProperties) const;

     void CalculateLocalSystem(MatrixType& rLeftHandSideMatrix, VectorType& rRightHandSideVector, ProcessInfo& rCurrentProcessInfo);
     
     void CalculateRightHandSide(VectorType& rRightHandSideVector, ProcessInfo& rCurrentProcessInfo);
     
     void EquationIdVector(EquationIdVectorType& rResult, ProcessInfo& rCurrentProcessInfo);

     void GetDofList(DofsVectorType& ElementalDofList,ProcessInfo& CurrentProcessInfo);

     void InitializeSolutionStep(ProcessInfo& CurrentProcessInfo);

Additional lines not important for this element (you don't need to modify anything):

    ///@}
     ///@name Access
     ///@{ 
     
     
     ///@}
     ///@name Inquiry
     ///@{
     
     
     ///@}      
     ///@name Input and output
     ///@{
 
   
           
     ///@}      
     ///@name Friends
     ///@{

           
     ///@}
     
   protected:
     ///@name Protected static Member Variables 
     ///@{ 
       
       
     ///@} 
     ///@name Protected member Variables 
     ///@{ 
       
       
     ///@} 
     ///@name Protected Operators
     ///@{ 
       
       
     ///@} 
     ///@name Protected Operations
     ///@{ 
       
       
     ///@} 
     ///@name Protected  Access 
     ///@{ 
       
       
     ///@}      
     ///@name Protected Inquiry 
     ///@{ 
       
       
     ///@}    
     ///@name Protected LifeCycle 
     ///@{ 
     
           
     ///@}

The declaration of the class's attributes we will know to perform the element computation (note again the use of the class name):

   private:
     ///@name Member Variables 
     ///@{ 
       boost::numeric::ublas::bounded_matrix<double,3,2> msDN_DX;
       boost::numeric::ublas::bounded_matrix<double,2,2> msD;
       array_1d<double,3> msN; //dimension = number of nodes
       array_1d<double,3> ms_temp; //dimension = number of nodes
       array_1d<double,3> point_sources; //dimension = number of nodes

and to close the class definition:

     ///@} 
     ///@name Member Variables 
     ///@{        
       
     ///@} 
     ///@name Private Operators
     ///@{ 
         
     ///@} 
     ///@name Private Operations
     ///@{ 
       
       
     ///@} 
     ///@name Private  Access 
     ///@{ 
              
     ///@}    
     ///@name Private Inquiry 
     ///@{ 
              
     ///@}    
     ///@name Un accessible methods 
     ///@{ 
           
     /// Assignment operator.
     // Poisson2D& operator=(const Poisson2D& rOther);

     /// Copy constructor.
     // Poisson2D(const Poisson2D& rOther);
       
     ///@}    
       
   }; // Class Poisson2D

To finalise the header code, we should add (no changes are needed):

 ///@} 
 
 ///@name Type Definitions       
 ///@{ 
 
 
 ///@} 
 ///@name Input and output 
 ///@{ 
       
 /// input stream function

 /// output stream function

 ///@} 

This code can be downloaded here: poisson_2d.h

Element implementation methods file: poisson_2d.cpp

First lines: legal issues

The first lines are just again the typical legal issues related to Kratos as a framework to create simulation programs. You should keep them as they are. The only sentence to customise is the name of the application (in bold characters) in the third line, KratosR1PoissonApplication:

/*
==============================================================================
KratosR1PoissonApplication 
A library based on:
Kratos
A General Purpose Software for Multi-Physics Finite Element Analysis
Version 1.0 (Released on march 05, 2007).

Copyright 2008
Pooyan Dadvand, Riccardo Rossi
pooyan@cimne.upc.edu 
rrossi@cimne.upc.edu
- CIMNE (International Center for Numerical Methods in Engineering),
Gran Capita' s/n, 08034 Barcelona, Spain

Permission is hereby granted, free  of charge, to any person obtaining
a  copy  of this  software  and  associated  documentation files  (the
"Software"), to  deal in  the Software without  restriction, including
without limitation  the rights to  use, copy, modify,  merge, publish,
distribute,  sublicense and/or  sell copies  of the  Software,  and to
permit persons to whom the Software  is furnished to do so, subject to
the following condition:

Distribution of this code for  any  commercial purpose  is permissible
ONLY BY DIRECT ARRANGEMENT WITH THE COPYRIGHT OWNERS.

The  above  copyright  notice  and  this permission  notice  shall  be
included in all copies or substantial portions of the Software.

THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT  SHALL THE AUTHORS OR COPYRIGHT HOLDERS  BE LIABLE FOR ANY
CLAIM, DAMAGES OR  OTHER LIABILITY, WHETHER IN AN  ACTION OF CONTRACT,
TORT  OR OTHERWISE, ARISING  FROM, OUT  OF OR  IN CONNECTION  WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

==============================================================================
*/

The following lines (comments again) indicate the author's name (your name), date and hour of the last revision, and revision number, as usual in other codes.

//   
//   Project Name:        Kratos       
//   Last modified by:    $Author: it's me! $
//   Date:                $Date: 2008-08-08 23:58:38 $
//   Revision:            $Revision: 1.0 $
//
//

Now you have to add the "include" files. Note that you have to change the element header file name (poisson_2d.h) and the application header file name where you want to include your element (in this case, kPoisson.h, not yet created). The related subdirectories will be explained in the application section:

// System includes 


// External includes 


// Project includes 
#include "includes/define.h"
#include "custom_elements/poisson_2d.h"
#include "kPoisson.h"
#include "utilities/math_utils.h"
#include "utilities/geometry_utilities.h"

Declare the namespace Kratos (copy at it is), and create the main class methods as follows. Just note that you have to be sure that you are using your element class name (Poisson2D in this example, in bold characters):

namespace Kratos
{
	//************************************************************************************
	//************************************************************************************
	Poisson2D::Poisson2D(IndexType NewId, GeometryType::Pointer pGeometry)
		: Element(NewId, pGeometry)
	{		
		//DO NOT ADD DOFS HERE!!!
	}

	//************************************************************************************
	//************************************************************************************
	Poisson2D::Poisson2D(IndexType NewId, GeometryType::Pointer pGeometry,  PropertiesType::Pointer pProperties)
		: Element(NewId, pGeometry, pProperties)
	{

	}

	Element::Pointer Poisson2D::Create(IndexType NewId, NodesArrayType const& ThisNodes,  PropertiesType::Pointer pProperties) const

	{
		return Element::Pointer(new Poisson2D(NewId, GetGeometry().Create(ThisNodes), pProperties));
	}

	Poisson2D::~Poisson2D()
	{
	}

Remember to close the namespace at the end of the file.

}  // namespace Kratos.

Now, it's the critical moment to transfer your Finite Element Formulation to the Kratos code. Some preliminary comments are:

  • Kratos allows different ways to implement the formulation, therefore don't worry if you find different Kratos elements with different implementation approaches, even if you leave some methods unused, or parts without contents. Just check the coherence of your formulation.
  • Kratos has been designed to allow you to focus your attention to the element formulation. That is, again, don't worry about the other programming aspects of your simulation program, such as the matrix assembly, solvers, etc... Of course, you are able to customise them, but for basic applications is not necessary at all.

Copy the following code as it is, with two exceptions (in bold characters):

  • use your element class name (Poisson2D in this example);
  • your variable names (we will use DUMMY_UNKNOWN for the unknown, DUMMY_MATERIAL for the material property and DUMMY_POINT_SOURCE for the source term);
	//************************************************************************************
	//************************************************************************************
	void Poisson2D::CalculateLocalSystem(MatrixType& rLeftHandSideMatrix, VectorType& rRightHandSideVector, ProcessInfo& rCurrentProcessInfo)
	{
		KRATOS_TRY
               
               boost::numeric::ublas::bounded_matrix<double,3,2> msDN_DX;
               boost::numeric::ublas::bounded_matrix<double,2,2> msD;
               array_1d<double,3> msN; //dimension = number of nodes
               array_1d<double,3> ms_temp; //dimension = number of nodes
               array_1d<double,3> point_sources; //dimension = number of nodes	
		const unsigned int number_of_points = GetGeometry().size();

		if(rLeftHandSideMatrix.size1() != number_of_points)
			rLeftHandSideMatrix.resize(number_of_points,number_of_points,false);

		if(rRightHandSideVector.size() != number_of_points)
			rRightHandSideVector.resize(number_of_points,false);

		//getting data for the given geometry
		double Area;
		GeometryUtils::CalculateGeometryData(GetGeometry(), msDN_DX, msN, Area);

		//reading properties and conditions
		double dummy_material = GetProperties()[DUMMY_MATERIAL];
		msD(0,0)=dummy_material;
		msD(1,1)=dummy_material;
		point_sources[0] = GetGeometry()[0].FastGetSolutionStepValue(DUMMY_POINT_SOURCE);
		point_sources[1] = GetGeometry()[1].FastGetSolutionStepValue(DUMMY_POINT_SOURCE);
		point_sources[2] = GetGeometry()[2].FastGetSolutionStepValue(DUMMY_POINT_SOURCE);
		
		// main loop	
		const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints();

		noalias(rLeftHandSideMatrix) = prod(msDN_DX,Matrix(prod(msD,trans(msDN_DX))));

		rLeftHandSideMatrix *= Area;

		//Point charge contribution 
		noalias(rRightHandSideVector) = point_sources;  

		//subtracting the dirichlet term
		// RHS -= LHS*DUMMY_UNKNOWNs
		for(unsigned int iii = 0; iii<number_of_points; iii++)
			ms_temp[iii] = GetGeometry()[iii].FastGetSolutionStepValue(DUMMY_UNKNOWN);
		noalias(rRightHandSideVector) -= prod(rLeftHandSideMatrix,ms_temp);
		
		KRATOS_CATCH("");
	}

The code is self-explanatory, but just a few comments to link it with our basic finite element formulation:

  • CalculateGeometryData obtains msDN_DX, msN and the elemental Area, that is, the B and N matrix;
  • msD is the material properties matrix (the D matrix);
  • With prod(msDN_DX,Matrix(prod(msD,trans(msDN_DX)))) we obtain the stiffness matrix (the K matrix);
  • With noalias(rRightHandSideVector) = point_sources we add the point_source contribution to the source vector f;
  • Finally, with prod(rLeftHandSideMatrix,ms_temp) we compute the Dirichlet contribution to the source vector f;

The following code is not used for this specific element (keep at it is, just changing the class name):

	//************************************************************************************
	//************************************************************************************
	void Poisson2D::CalculateRightHandSide(VectorType& rRightHandSideVector, ProcessInfo& rCurrentProcessInfo)
	{
		KRATOS_ERROR(std::logic_error,  "method not implemented" , "");
	}	 

	//************************************************************************************
	//************************************************************************************
	// this subroutine calculates the nodal contributions for the explicit steps of the 
	// fractional step procedure
	void Poisson2D::InitializeSolutionStep(ProcessInfo& CurrentProcessInfo)
	{
		KRATOS_TRY

		KRATOS_CATCH("");
	}

And, finally, the next lines give us the unknows (you have just change the class and variables' names):

	//************************************************************************************
	//************************************************************************************
	void Poisson2D::EquationIdVector(EquationIdVectorType& rResult, ProcessInfo& CurrentProcessInfo)
	{
		unsigned int number_of_nodes = GetGeometry().PointsNumber();
		if(rResult.size() != number_of_nodes)
			rResult.resize(number_of_nodes,false);	

		for (unsigned int i=0;i<number_of_nodes;i++)
				rResult[i] = GetGeometry()[i].GetDof(DUMMY_UNKNOWN).EquationId();
	}

	//************************************************************************************
	//************************************************************************************
	  void Poisson2D::GetDofList(DofsVectorType& ElementalDofList,ProcessInfo& CurrentProcessInfo)
	{
		unsigned int number_of_nodes = GetGeometry().PointsNumber();
		if(ElementalDofList.size() != number_of_nodes)
			ElementalDofList.resize(number_of_nodes);	

		for (unsigned int i=0;i<number_of_nodes;i++)
			ElementalDofList[i] = GetGeometry()[i].pGetDof(DUMMY_UNKNOWN);

	}

Tips for a basic Kratos Element creation

If you want to create the element from any existing one, you can also use the following quick steps:

  1. copy the .h and .cpp original element in your working directory;
    • for example, copy conv_diff_2d.h and conv_diff_2d.h to myKratos/my_elements;
  2. rename the .h and .cpp copied files to your element name;
    • for example: poisson_2d.h and poisson_2d.cpp;
  3. edit your element header (.h) file and:
    • for example, edit your poisson_2d.h file;
    1. search and replace the "KratosR1OriginalNameApplication" word to "KratosR1YourApplication";
      • for example, search and replace KratosR1ConvectionDiffusionApplication for KratosR1PoissonApplication;
    2. modify the authors, data and hour of the last creation/modification, and version of the code;
    3. search and replace the KRATOS_elementType_2D_ELEM_H_INCLUDED string for your specific label;
      • for example, search and replace KRATOS_TRIANGULAR_CONVDIFF_ELEM_H_INCLUDED for KRATOS_POISSON_2D_ELEM_H_INCLUDED;
    4. search and replace the class name from the original to your new element;
      • for example, search and replace ConvDiff2D for Poisson2D;
  4. edit your element implementation (.cpp) file and:
    • for example, edit your poisson_2d.cpp file;
    1. search and replace the "KratosR1OriginalNameApplication" word to "KratosR1YourApplication";
      • for example, search and replace KratosR1ConvectionDiffusionApplication for KratosR1PoissonApplication;
    2. modify the authors, data and hour of the last creation/modification, and version of the code;
    3. add your specific include files (your element header file and your application header file);
      • for example, add #include "custom_elements/poisson_2d.h" and #include "kPoisson.h";
    4. search and replace the class name from the original to your new element;
      • for example, search and replace ConvDiff2D for Poisson2D;
    5. search and replace variable's names from the original to your new element;
      • for example, search and replace CONDUCTIVITY for DUMMY_MATERIAL;
      • for example, search and replace conductivity for dummy_material;
      • for example, search and replace TEMPERATURE for DUMMY_UNKNOWN;
    6. create, if needed, new variables or equation terms (for example, the point_source contribution);
      • for example, add in your CalculateLocalSystem method, the following lines:
      point_sources[0] = GetGeometry()[0].FastGetSolutionStepValue(DUMMY_POINT_SOURCE);
      point_sources[1] = GetGeometry()[1].FastGetSolutionStepValue(DUMMY_POINT_SOURCE);
      point_sources[2] = GetGeometry()[2].FastGetSolutionStepValue(DUMMY_POINT_SOURCE);
      //Point charge contribution
      noalias(rRightHandSideVector) = point_sources;


Excellent! Now you have your first basic element! To check it, you will now to include them in an application or to create a new one, the topic of the next section.

A First Kratos Application

Suggested Prerequisites

Introduction

An application in Kratos is an specific customisation of the Kratos elements in order to perform an specific simulation. That means that you can combine already existing Kratos elements, solvers, strategies and so on to create your application.

In this section, we will create a new application to use our recently created element for our Poisson PDE example. It is almost the simplest application, but include a lot of tips that is highly convenient to know in order to properly work with Kratos. It is a kind of the Kratos' 'Hello world'.

Kratos's framework is implemented at two different levels: C++ and python programming. You will need to create or modify C++ code for low level operations, such as to implement the element, solvers or IO routines. You will use the python codes to combine these elements at a higher level, closer to the end-user, such as to select the elements or solvers, decide what are the variables you want to print, etc.

Coming from our Poisson element, remember that we have already selected the name:

  • of our application: kPoisson;
  • the application methods: PoissonApplication;
  • our element: poisson_2d;
  • class name for the element: Poisson2D;
  • variables: DUMMY_UNKNOWN, DUMMY_MATERIAL, DUMMY_POINT_SOURCE;

Kratos is an open source code framework and that means that you can share, modify and freely use the code. You can also contribute with your code, your applications and examples in the growing of the Kratos' community.

For this reason, Kratos has been designed to work at other two development levels:

  • Kratos kernel, that it is supposed to be the most inner part of Kratos, of common interest for all the Kratos' community;
  • Kratos applications, with specific code for every each unique details of each problem, user profile or simulation case;

Basically, to classify and separate these two development levels, we will work with code in files located in different subdirectories. In this way, you can experiment with your application without worry about modifying important code in the Kratos Kernel. You can also share your code with the rest of the Kratos community, if you want, by using the CVS, but without provoking conflicts with the rest of the Kratos framework.

Warn_icon.gif Warning. Please, note that:

if you have to change or modify anything of the Kratos kernel to improve your application, you can do it in your stand-alone Kratos installation, but you should contact the main Kratos developers (Dr. Pooyan Davdand or Dr. Riccardo Rossi) before updating it in the Kratos CVS.

Basic Kratos Directory Tree

If you have successfully installed Kratos, you should have a directory's tree like this (minor changes are allowed, such as the location of the python files, etc):

/kratosR1
	/applications
	/bin
	/CVS
	/Debug
	/doc
	/external_libraries
	/kratos
	/libs
	/Python25
	/Release

Our main working directory will be our specific application's directory (to be created), in the applications subdirectory. Nevertheless, the rest of the structure is presented to indicate where are located other important files to work with Kratos.

The files' structure for a Kratos application

In the /KratosR1/applications directory you have to create a new directory (let's go to call it "kPoisson"). You have to create a set of custom directories for your application (basically /custom_elements, /custom_python, /python_scripts and /test_examples):

/KratosR1
	/applications
		/kPoisson 
			/custom_elements 
			/custom_python 
			/python_scripts 
			/test_examples 

Each of these subdirectories will contain the specific C++ or python code needed for our application. We will focus our attention in using our customised element, therefore, the other needed code will be, simply, copied from other already existing applications.

Note that if you want to use a new strategy or solver, then you have to create other typical customisation directories or files such as /custom_strategies, etc...

Creation of our Kratos application files: copying already existing files

  1. Copy the header (.h), implementation (.cpp) C++ file and Jamfile from other application to your main application subdirectory (kPoisson);
    • for example copy the files from /kratosR1/applications/convection_diffusion_application to /kratosR1/applications/kPoisson;
      • convection_diffusion_application.h
      • convection_diffusion_application.cpp
      • Jamfile
  2. Copy your element's code (poisson_2d.h, poisson_2d.cpp) in your custom_elements subdirectory (/kratosR1/applications/kPoisson/custom_elements);
  3. Copy the custom_python files from other application to your custom_python subdirectory;
    • for example copy the content from /kratosR1/applications/convection_diffusion_application/custom_python to /kratosR1/applications/kPoisson/custom_python;
      • kratos_convection_diffusion_python_application.cpp
  4. Copy the python_scripts files from other application to your python_scripts subdirectory;
    • for example copy the content from /kratosR1/applications/convection_diffusion_application/python_scripts to /kratosR1/applications/kPoisson/python_scripts;
      • convection_diffusion_solver.py
      • nonlinear_convection_diffusion_solver.py
    • As you can see, in this directory the python file to run the solver is saved; therefore, you have to select the most appropriate solver for your application from those already existing ones;
    • For this application (the Poisson equation), we recommend to use the strategy and solver coming from the structural application (a very similar problem); therefore, copy from \kratosR1\applications\structural_application\python_scripts to your local directory (\kratosR1\applications\kPoisson\python_scripts) the following files:
      • structural_solver_static.py
      • strategy_python.py
  5. Depending on your interest, you can also copy an example from other application in your test_examples directory;

The following files (above in bold characters) are those that you will have to modify, that we will review later. The rest of them, in principle, you can keep as they are.

  • convection_diffusion_application.h
  • convection_diffusion_application.cpp
  • Jamfile
  • kratos_convection_diffusion_python_application.cpp
  • structural_solver_static.py

In addition, you have to indicate to the Kratos Kernel that you have created a new application, in order to be included in the whole Kratos. To do this, you will have also to modify the following files:

  • in the main applications' directory (/kratosR1/applications/applications_interface.py);
  • in the Kratos root (/kratosR1/Jamroot);

Customisation of our Application files

In summary, we have to modify:

  • /kratosR1/applications/kPoisson/convection_diffusion_application.h
  • /kratosR1/applications/kPoisson/convection_diffusion_application.cpp
  • /kratosR1/applications/kPoisson/Jamfile
  • /kratosR1/applications/kPoisson/custom_python/kratos_convection_diffusion_python_application.cpp
  • /kratosR1/applications/kPoisson/python_scripts/structural_solver_static.py
  • /kratosR1/applications/applications_interface.py
  • /kratosR1/Jamroot

The first thing to do is to rename the other application files (convection_diffusion_application or structural in this case) to our specific application name (kPoisson), for example by doing:

  • /kratosR1/applications/kPoisson/kPoisson.h
  • /kratosR1/applications/kPoisson/kPoisson.cpp
  • /kratosR1/applications/kPoisson/Jamfile
  • /kratosR1/applications/kPoisson/custom_python/kPoisson_python_application.cpp
  • /kratosR1/applications/kPoisson/python_scripts/static_poisson_solver.py
  • /kratosR1/applications/applications_interface.py
  • /kratosR1/Jamroot

Let's go to edit these files (note that we have three C++ files and three python files):

Customising the header application file: kPoisson.h

The first lines (comments) indicate the author's name (your name), date and hour of the last revision, and revision number, as usual in other codes.

//   
//   Project Name:        Kratos       
//   Last modified by:    $Author: it's me! $
//   Date:                $Date: 2008-08-08 23:58:38 $
//   Revision:            $Revision: 1.0 $
//
//

In order to avoid class redefinition, you have to define a label for your application definition, as follows:

#if !defined(KRATOS_POISSON__H_INCLUDED)
#define  KRATOS_POISSON_H_INCLUDED

the #endif is at the end of the code (the rest of the lines must be included between these ones):

#endif // KRATOS_POISSON_H_INCLUDED  defined

Now you have to add the "include" files (note that here you define the element to be used, poisson_2d.h, for the rest of include files you can copy as it is):

// System includes
#include <string>
#include <iostream>  


// External includes 


// Project includes
#include "includes/define.h"
#include "includes/kratos_application.h" 

#include "custom_elements/poisson_2d.h"

#include "includes/variables.h"
#include "includes/condition.h"
#include "includes/ublas_interface.h"

Declare the namespace Kratos (copy at it is):

namespace Kratos
{

 	///@name Kratos Globals
 	///@{ 

 	// Variables definition 

	///@} 
	///@name Type Definitions
	///@{ 

	///@} 
	///@name  Enum's
	///@{

	///@}
	///@name  Functions 
	///@{

	///@}
	///@name Kratos Classes
	///@{

	/// Short class definition.
	/** Detail class definition.
	*/

Now, coming from the element definition, remember that we have called our application KratosR1PoissonApplication, the name we have to use in the following lines:

	class KratosR1PoissonApplication : public KratosApplication
	{
	public:
		///@name Type Definitions
		///@{
		
		/// Pointer definition of KratosR1PoissonApplication
		KRATOS_CLASS_POINTER_DEFINITION(KratosR1PoissonApplication);

		///@}
		///@name Life Cycle 
		///@{ 

		/// Default constructor.
		KratosR1PoissonApplication();

		/// Destructor.
		virtual ~KratosR1PoissonApplication(){}

		///@}
		///@name Operators 
		///@{

		///@}
		///@name Operations
		///@{

		virtual void Register();

		///@}
		///@name Access
		///@{ 

		///@}
		///@name Inquiry
		///@{

		///@}      
		///@name Input and output
		///@{

		/// Turn back information as a string.
		virtual std::string Info() const
		{
			return "KratosR1PoissonApplication";
		}

		/// Print information about this object.
		virtual void PrintInfo(std::ostream& rOStream) const
		{
			rOStream << Info();
			PrintData(rOStream);
		}

		///// Print object's data.
      virtual void PrintData(std::ostream& rOStream) const
      {
     	KRATOS_WATCH("in KratosR1PoissonApplication");
     	KRATOS_WATCH(KratosComponents<VariableData>::GetComponents().size() );
		rOStream << "Variables:" << std::endl;
		KratosComponents<VariableData>().PrintData(rOStream);
		rOStream << std::endl;
		rOStream << "Elements:" << std::endl;
		KratosComponents<Element>().PrintData(rOStream);
		rOStream << std::endl;
		rOStream << "Conditions:" << std::endl;
		KratosComponents<Condition>().PrintData(rOStream);
     }
 
		///@}      
		///@name Friends
 		///@{

  		///@}

	protected:
		///@name Protected static Member Variables 
		///@{ 


 		///@} 
		///@name Protected member Variables 
		///@{ 
 

		///@} 
		///@name Protected Operators
		///@{ 

 		///@} 
		///@name Protected Operations
		///@{ 

		///@} 
		///@name Protected  Access 
		///@{ 

 		///@}      
		///@name Protected Inquiry 
		///@{ 

		///@}    
		///@name Protected LifeCycle 
		///@{ 

		///@}

Now we have to declare our element class name (Poisson2D):

	private:
		///@name Static Member Variables 
		///@{ 

		//       static const ApplicationCondition  msApplicationCondition; 

		///@} 
		///@name Member Variables 
		///@{ 
		const Poisson2D  mPoisson2D;

		///@} 
		///@name Private Operators
		///@{ 

		///@} 
		///@name Private Operations
		///@{ 

		///@} 
		///@name Private  Access 
		///@{ 

		///@}    
		///@name Private Inquiry 
		///@{ 

		///@}    
		///@name Un accessible methods 
		///@{

And, finally, we have to declare the assignment operator and constructor method (remember to close the namespace definition and #endif label if you had not done it before):

		/// Assignment operator.
		KratosR1PoissonApplication& operator=(KratosR1PoissonApplication const& rOther);

		/// Copy constructor.
		KratosR1PoissonApplication(KratosR1PoissonApplication const& rOther);


		///@}    

	}; // Class KratosR1PoissonApplication 

	///@} 


	///@name Type Definitions       
	///@{ 


	///@} 
	///@name Input and output 
	///@{ 

	///@} 


}  // namespace Kratos.


#endif // KRATOS_POISSON_H_INCLUDED  defined

Customising the implementation application file: kPoisson.cpp

The implementation file really doesn't need any comment. Just note that your customising parts are remarked in bold characters:

//   
//   Project Name:        Kratos       
//   Last Modified by:    $Author: it's me $
//   Date:                $Date: 2008-08-08 $
//   Revision:            $Revision: 1.0 $
//
// 

// System includes

// External includes 

// Project includes
#include "includes/define.h"
#include "geometries/triangle_2d_3.h"
#include "geometries/triangle_3d_3.h"
#include "geometries/tetrahedra_3d_4.h"
#include "geometries/line_2d.h"
#include "kPoisson.h"
#include "includes/variables.h"

namespace Kratos
{
	KratosR1PoissonApplication::KratosR1PoissonApplication():
		mPoisson2D(0, Element::GeometryType::Pointer(new Triangle2D3<Node<3> >(Element::GeometryType::PointsArrayType(3, Node<3>()))))
	{}

	void KratosR1PoissonApplication::Register()
	{
		// calling base class register to register Kratos components
		KratosApplication::Register();
		std::cout << "Initializing KratosR1PoissonApplication... " << std::endl;

		// Registering elements and conditions here
		KRATOS_REGISTER_ELEMENT("Poisson2D", mPoisson2D);
	}
	
}  // namespace Kratos

Customising the python compiling application file: Jamfile

This file indicates Kratos where to find all the specific application files, therefore basically you should include your custom directories and files (note again that you have just to pay attention to the bold characters). Take care while modifying this file because python is highly sensitive to spaces and tab characters.

project PoissonApplication
    : 
    source-location
       .
       custom_elements
       custom_python
       custom_utilities
       external_includes
    :
    requirements <include>. 
		<define>KRATOS_PYTHON
		<link>shared
    ;

#################################################################################
#################################################################################
##definition of "dependencies for the project"
# no libs needed for this application ... have a look to PFEMapplication for examples
# of use in a more general case

#################################################################################
#################################################################################
## list of files to be build, including dependencies to other libraries
import python ;
python-extension KratosR1PoissonApplication
    :  
	#list of sources
	kPoisson.cpp
	kPoisson_python_application.cpp
	poisson_2d.cpp
	add_custom_strategies_to_python.cpp 
	add_custom_utilities_to_python.cpp

	#kratos library
        ##/kratos-prj/kratos//libkratos/<link>static
    /KratosProject//libkratos_static
    	 
	#"system" includes	
	/KratosProject//pythonlib
	/KratosProject//boost_python_lib
    ;

#################################################################################
#################################################################################
## rules to install ... and to remove the prefix "lib"

install install : KratosR1PoissonApplication : <location>$(TOP)/libs ;

Customising the python variables file: kPoisson_python.cpp

The following file basically indicates Kratos the variables to be used by the pyhton commands. Therefore, we have just to modify the name of the application (KratosR1PoissonApplication) and to add the variables names (DUMMY_UNKNOWN for the unknown, DUMMY_MATERIAL for the material property and DUMMY_POINT_SOURCE for the source term).

Legal issues

/*
==============================================================================
KratosR1PoissonApplication 
A library based on:
Kratos
A General Purpose Software for Multi-Physics Finite Element Analysis
Version 1.0 (Released on march 05, 2007).

Copyright 2008
Pooyan Dadvand, Riccardo Rossi
pooyan@cimne.upc.edu 
rrossi@cimne.upc.edu
- CIMNE (International Center for Numerical Methods in Engineering),
Gran Capita' s/n, 08034 Barcelona, Spain

Permission is hereby granted, free  of charge, to any person obtaining
a  copy  of this  software  and  associated  documentation files  (the
"Software"), to  deal in  the Software without  restriction, including
without limitation  the rights to  use, copy, modify,  merge, publish,
distribute,  sublicense and/or  sell copies  of the  Software,  and to
permit persons to whom the Software  is furnished to do so, subject to
the following condition:

Distribution of this code for  any  commercial purpose  is permissible
ONLY BY DIRECT ARRANGEMENT WITH THE COPYRIGHT OWNERS.

The  above  copyright  notice  and  this permission  notice  shall  be
included in all copies or substantial portions of the Software.

THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT  SHALL THE AUTHORS OR COPYRIGHT HOLDERS  BE LIABLE FOR ANY
CLAIM, DAMAGES OR  OTHER LIABILITY, WHETHER IN AN  ACTION OF CONTRACT,
TORT  OR OTHERWISE, ARISING  FROM, OUT  OF OR  IN CONNECTION  WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

==============================================================================
*/
//   
//   Project Name:        Kratos       
//   Last modified by:    $Author: it's me! $
//   Date:                $Date: 2008-08-08 23:58:38 $
//   Revision:            $Revision: 1.0 $
//
//
// System includes 

#if defined(KRATOS_PYTHON)
// External includes 
#include <boost/python.hpp>


// Project includes 
#include "includes/define.h"
#include "kPoisson.h"
#include "custom_python/add_custom_strategies_to_python.h"
#include "custom_python/add_custom_utilities_to_python.h"
  
namespace Kratos
{

namespace Python
{

  using namespace boost::python;


  
  BOOST_PYTHON_MODULE(KratosR1PoissonApplication)
  {

	  class_<KratosR1PoissonApplication, 
			  KratosR1PoissonApplication::Pointer, 
			  bases<KratosApplication>, boost::noncopyable >("KratosR1PoissonApplication")
			;

		AddCustomStrategiesToPython();
		AddCustomUtilitiesToPython();

		//registering variables in python

		KRATOS_REGISTER_IN_PYTHON_VARIABLE(DUMMY_UNKNOWN)
		KRATOS_REGISTER_IN_PYTHON_VARIABLE(DUMMY_MATERIAL)
		KRATOS_REGISTER_IN_PYTHON_VARIABLE(DUMMY_POINT_SOURCE)
			 
  }  
  
}  // namespace Python.

}  // namespace Kratos. 

#endif // KRATOS_PYTHON defined


Customising the python solver file: static_poisson_solver.py

The following file customise the Kratos solvers and strategies for our specific application. This file purpose is just to put together our variable names and solvers to be used, as follows (bold characters indicates the lines to be modified for each application):

#importing the Kratos Library
from Kratos import *
from KratosR1PoissonApplication import * 

def AddVariables(model_part):
    model_part.AddNodalSolutionStepVariable(DUMMY_UNKNOWN);
    model_part.AddNodalSolutionStepVariable(DUMMY_POINT_SOURCE);

def AddDofs(model_part):
    for node in model_part.Nodes: 

        #adding dofs
        node.AddDof(DUMMY_UNKNOWN);

    print "variables for the Poisson solver added correctly"

class StaticPoissonSolver:
    #######################################################################
    def __init__(self,model_part,domain_size):

        self.model_part = model_part
        self.time_scheme = ResidualBasedIncrementalUpdateStaticScheme()

        #definition of the solvers
        self.poisson_linear_solver =  SkylineLUFactorizationSolver()
        
        #definition of the convergence criteria
        self.conv_criteria = DisplacementCriteria(1e-6,1e-9)
        
    #######################################################################
    def Initialize(self):
        #creating the solution strategy
        CalculateReactionFlag = False
        ReformDofSetAtEachStep = False
        MoveMeshFlag = False
        import strategy_python
        self.solver = strategy_python.SolvingStrategyPython(self.model_part,self.time_scheme,self.poisson_linear_solver,self.conv_criteria,CalculateReactionFlag,ReformDofSetAtEachStep,MoveMeshFlag)
      
                 
    #######################################################################   
    def Solve(self):
        (self.solver).Solve()

    #######################################################################   
    def SetEchoLevel(self,level):
        (self.solver).SetEchoLevel(level)

Customising the python applications interface: applications_interface.py

The python file for the applications (applications_interface.py) registers the applications' names and paths in order to load them from our specific simulation program. You have to edit this file and delete the applications_interface.pyc file.

Remember that our new application is called PoissonApplication with a class named KratosR1PoissonApplication in the path /kPoisson. We need to add our specific application name and paths, as follows (note that the new lines are written in bold characters).

#path for applications s
import sys

Import_ALEApplication = False
Import_IncompressibleFluidApplication = False
Import_StructuralApplication = False
Import_ConvectionDiffusionApplication = False
Import_FSIApplication = False
Import_PFEMApplication = False
Import_ExternalSolversApplication = False
Import_ULFApplication = False
Import_MeshingApplication = False
Import_PoissonApplication = False

print "Applications Available:"
print "Import_ALEApplication: False"
print "Import_IncompressibleFluidApplication: False"
print "Import_StructuralApplication: False"
print "Import_ConvectionDiffusionApplication: False"
print "Import_FSIApplication: False"
print "Import_ExternalSolversApplication: False"
print "Import_ULFApplication: False"
print "Import_MeshingApplication: False"
print "Import_PoissonApplication: False"   

def ImportApplications(kernel, applications_path):
    ##########################################################################
    ##importing the applications
    print "Applications Available:"
    print "Import_ALEApplication: "+str(Import_ALEApplication)
    print "Import_IncompressibleFluidApplication: "+str(Import_IncompressibleFluidApplication)
    print "Import_StructuralApplication: "+str(Import_StructuralApplication)
    print "Import_ConvectionDiffusionApplication: "+str(Import_ConvectionDiffusionApplication)
    print "Import_FSIApplication: "+str(Import_FSIApplication)
    print "Import_ExternalSolversApplication: "+str(Import_ExternalSolversApplication)
    print "Import_ULFApplication: "+str(Import_ULFApplication)
    print "Import_ULFApplication: "+str(Import_MeshingApplication)
    print "Import_ PoissonApplication: "+str(Import_PoissonApplication)
    if(Import_ALEApplication == True):
        print "importing KratosR1ALEApplication ..."
        sys.path.append(applications_path + '/ALEapplication/python_scripts' )
        sys.path.append(applications_path + '/ALEapplication/Linux')
        from KratosR1ALEApplication import *
        ale_app = KratosR1ALEApplication()
        kernel.AddApplication(ale_app)
        print "KratosR1ALEApplication Succesfully imported"
        
    if(Import_IncompressibleFluidApplication == True):
        print "importing KratosR1IncompressibleFluidApplication ..."
        sys.path.append(applications_path + '/incompressible_fluid_application/python_scripts') 
        sys.path.append(applications_path + '/incompressible_fluid_application/Linux') 
        from KratosR1IncompressibleFluidApplication import *
        print "KratosR1IncompressibleFluidApplication lib loaded"
        incompressible_fluid_application = KratosR1IncompressibleFluidApplication()
        print "KratosR1IncompressibleFluidApplication application created"
        kernel.AddApplication(incompressible_fluid_application)
        print "KratosR1IncompressibleFluidApplication Succesfully imported"

    if(Import_StructuralApplication == True):
        print "importing KratosR1StructuralApplication ..."
        sys.path.append(applications_path + '/structural_application/python_scripts') 
        sys.path.append(applications_path + '/structural_application/Linux') 
        from KratosR1StructuralApplication import *
        structural_application = KratosR1StructuralApplication()
        kernel.AddApplication(structural_application)
        print "KratosR1StructuralApplication Succesfully imported"

    if(Import_ConvectionDiffusionApplication == True):
        print "importing KratosR1ConvectionDiffusionApplication ..."
        sys.path.append(applications_path + '/convection_diffusion_application/python_scripts') 
        sys.path.append(applications_path + '/convection_diffusion_application/Linux') 
        from KratosR1ConvectionDiffusionApplication import *
        convection_diffusion_application = KratosR1ConvectionDiffusionApplication()
        kernel.AddApplication(convection_diffusion_application)
        print "KratosR1ConvectionDiffusionApplication Succesfully imported" 

    if(Import_FSIApplication == True):
        print "importing FSIapplication ..."
        sys.path.append(applications_path + '/FSIapplication/python_scripts') 
        sys.path.append(applications_path + '/FSIapplication/Linux') 
        from KratosR1FSIApplication import *
        fsi_application = KratosR1FSIApplication()
        kernel.AddApplication(fsi_application)
        print "FSIapplication Succesfully imported"

    if(Import_PFEMApplication == True):
        print "importing KratosR1PFEMApplication ..."
        sys.path.append(applications_path + '/PFEMapplication/python_scripts') 
        sys.path.append(applications_path + '/PFEMapplication/Linux') 
        from KratosR1PFEMApplication import *
        pfkElectrostatic = KratosR1PFEMApplication()
        kernel.AddApplication(pfkElectrostatic)
        print "KratosR1PFEMApplication Succesfully imported"
	
   if(Import_ExternalSolversApplication == True): 
        print "importing KratosExternalSolversApplication ..."
        sys.path.append(applications_path + '/ExternalSolversApplication/python_scripts')
        sys.path.append(applications_path + '/ExternalSolversApplication/Linux')
        from KratosR1ExternalSolversApplication import *
        external_solvers_application = KratosR1ExternalSolversApplication()
        kernel.AddApplication(external_solvers_application)
        print "KratosExternalSolversApplication sucessfully imported"
 	
    if(Import_ULFApplication == True):
        print "importing KratosR1ULFApplication ..."
        sys.path.append(applications_path + '/ULFapplication/python_scripts')
        sys.path.append(applications_path + '/ULFapplication/Linux')
        from KratosR1ULFApplication import *
        ulf_application = KratosR1ULFApplication()
        kernel.AddApplication(ulf_application)
        print "KratosULFApplication sucessfully imported"

    if(Import_MeshingApplication == True):
        print "importing KratosR1MeshingApplication ..."
        sys.path.append(applications_path + '/MeshingApplication/python_scripts')
        from KratosR1MeshingApplication import *
        meshing_application = KratosR1MeshingApplication()
        kernel.AddApplication(meshing_application)
        print "KratosMeshingApplication sucessfully imported" 
       
    if(Import_PoissonApplication == True):
        print "importing KratosR1PoissonApplication ..."
        sys.path.append(applications_path + '/kPoisson/python_scripts')
        sys.path.append(applications_path + '/kPoisson/Linux')
        from KratosR1PoissonApplication import *
        kPoisson = KratosR1PoissonApplication()
        kernel.AddApplication(kPoisson)
        print "Kratos PoissonApplication sucessfully imported"

    ##########################################################################
    ##dynamic renumbering of variables to ensure the consistency
    kernel.Initialize()
    if(Import_ALEApplication == True):
        kernel.InitializeApplication(ale_app);
    if(Import_IncompressibleFluidApplication == True):
        kernel.InitializeApplication(incompressible_fluid_application);    
    if(Import_StructuralApplication == True):
        kernel.InitializeApplication(structural_application);    
    if(Import_ConvectionDiffusionApplication == True):
        kernel.InitializeApplication(convection_diffusion_application); 
    if(Import_FSIApplication == True):
        kernel.InitializeApplication(fsi_application); 
    if(Import_PFEMApplication == True):
        kernel.InitializeApplication(pfkElectrostatic); 
    if(Import_ExternalSolversApplication == True):
        kernel.InitializeApplication(external_solvers_application);
    if(Import_ULFApplication == True):
        kernel.InitializeApplication(ulf_application);
    if(Import_MeshingApplication == True):
        kernel.InitializeApplication(meshing_application);
    if(Import_PoissonApplication == True):
        kernel.InitializeApplication(kPoisson);

Customising the main Kratos python compiling file: Jamroot

The last file to modify is the python guide to compile Kratos, the Jamroot file in the Kratos root. The only lines to include are those related to your application, that is, at the end of the file, the list of applications included in the compilation. Note that if you don't want to load any specific application, you can remove it from this file or also just simply comment it using the "#" character:

using gcc ;
using intel : : : <cxxflags>"-fPIC -ansi -funroll-loops -cxxlib-gcc -openmp -wd654 -wd10010" ;
using msvc ;
using python ; 


#################################################################################
## defining "common includes" and external libraries
path-constant TOP : . ;
project KratosProject 
	:
	#############################################################################
	############### TO BE CUSTOMARIZED -- LINUX VERSION EXAMPLE!! ###############
	##requirements <include>/usr/include/boost         #to be customarized 
	##		 <include>/usr/include/python2.5/        #to be customarized 
       ##     	<include>$(TOP)/kratos
	##	     <include>$(TOP)/external_libraries
	#############################################################################

	#############################################################################
	############### TO BE CUSTOMARIZED -- WINDOWS VERSION EXAMPLE!! ###############
	requirements <include>"D:/kratosR1/external_libraries/boost_1_34_1/"    #to be customarized
			 <include>"D:/kratosR1/Python25/include"                                #to be customarized 
               <include>$(TOP)/kratos
		     <include>$(TOP)/external_libraries
	#############################################################################	

		     ##omptl - necessary for parallelism
		     <include>$(TOP)/external_libraries/omptl
			
			#basic configurations
		     <threading>multi
		     <define>NDEBUG

			 #compiler settings - can be customarized by the user
			 #WARNING -fPIC is NEEDED to compile on 64bit systems - it has to be specified here in order to include it in the 
			 #kratos "static" library
			 <warnings>on

			 #gcc settings
			<toolset>gcc:<cflags>"-fPIC -funroll-loops" ##settings for external libraries
 			<toolset>gcc:<cxxflags>"-fPIC -ansi -funroll-loops -ffast-math" 

			#msvc settings
			<toolset>msvc:<linkflags>"/NODEFAULTLIB:libcmt"
			<toolset>msvc:<cxxflags>"/D_SCL_SECURE_NO_DEPRECATE  /wd4335"

			#intel settings
		##	<toolset>intel:<cxxflags>"-fPIC -ansi -funroll-loops -ffast-math" 
	: 
		     default-build release
	;

#################################################################################
## defining "common external libraries" 
## the user should adapt this depending on the installations directories on his system

#############################################################################
############### TO BE CUSTOMARIZED -- LINUX VERSION EXAMPLE!! ###############
##lib pythonlib : : <name>python2.5 ; 
##lib boost_python_lib : : <variant>debug <name>boost_python-mt-d ;   
##lib boost_python_lib : : <variant>release <name>boost_python-mt ;   
##lib boost_python_lib : : <variant>debug <name>boost_python-gcc-mt-d-1_34_1 ;   
##lib boost_python_lib : : <variant>release <name>boost_python-gcc-mt-1_34_1 ;   
##lib gidpost : : <name>gidpost <search>$(TOP)/external_libraries/gidpost/unix/release ;
#############################################################################

#############################################################################
############### TO BE CUSTOMARIZED -- WINDOWS VERSION EXAMPLE!! ###############
lib pythonlib : : <name>python25 <search>"D:/kratosR1/Python25/libs"  ; 
lib boost_python_lib : : <variant>release <name>boost_python-vc80-mt-1_34_1 <search>"D:/kratosR1/external_libraries/boost_1_34_1/lib" ;   
lib boost_python_lib : : <variant>debug <name>boost_python-vc80-mt-gd-1_34_1 <search>"D:/kratosR1/external_libraries/boost_1_34_1/lib" ;   
lib gidpost : : <name>gidpost <search>$(TOP)/external_libraries/gidpost/win/Release/ ; 
#############################################################################

#intel omp library...
lib intelomp  : : <name>guide  ; 

#ATTENTION: "this requires adding threading=multi to the bjam call"
alias libomp : intelomp : <toolset>intel ;
alias libomp : : <toolset>gcc ;
alias libomp : : <toolset>msvc ;


#################################################################################
# IN PRINCIPLE THIS SHOULD REQUIRE NO CUSTOMARIZATION .. apart for compiling new applications
## defining "ids" for the different projects
use-project /kratos-prj : . ;

##kratos base library and python interfaces
use-project /kratos-prj/kratos : kratos ; 

##applications included in the compilation
use-project /kratos-prj/PFEMapplication : $(TOP)/applications/PFEMapplication ;
use-project /kratos-prj/incompressible_fluid_application : $(TOP)/applications/incompressible_fluid_application ;
use-project /kratos-prj/structural_application : $(TOP)/applications/structural_application ;
use-project /kratos-prj/convection_diffusion_application : $(TOP)/applications/convection_diffusion_application ;
use-project /kratos-prj/ExternalSolversApplication : $(TOP)/applications/ExternalSolversApplication ;
use-project /kratos-prj/ULFapplication : $(TOP)/applications/ULFapplication ;
use-project /kratos-prj/ALEapplication : $(TOP)/applications/ALEapplication ;
use-project /kratos-prj/FSIapplication : $(TOP)/applications/FSIapplication ;
use-project /kratos-prj/kPoisson : $(TOP)/applications/kPoisson ;


alias libkratos_static : /kratos-prj/kratos//libkratos/<link>static ;

#################################################################################
## installation
alias install : 
		/kratos-prj//kratos 
		/kratos-prj/PFEMapplication//install
		/kratos-prj/incompressible_fluid_application//install
		/kratos-prj/structural_application//install
		/kratos-prj/convection_diffusion_application//install
# 		/kratos-prj/ExternalSolversApplication//install
		/kratos-prj/ULFapplication//install
		/kratos-prj/ALEapplication//install
#		/kratos-prj/FSIapplication//install
		/kratos-prj/kPoisson//install

		;

ECHO $(TOP) ;

Rebuilding Kratos

Now it is the moment to compile all our new files. It's expected to find minor errors, and we will include in this section the most frequent problems found. Please, use the discussion tab to include your questions or difficulties.

Info_icon.gif Things to do:

  • Include the most frequent compilation errors.

One typical error is to use something not yet undefined in Kratos. The most evident case is the variables' name: DUMMY_UNKNOWN, DUMMY_MATERIAL, DUMMY_POINT_SOURCE for your application.

The variables are defined, created and registered in the variables.h file in the kratosR1\kratos\includes directory and in the variables.cpp file in the kratosR1\kratos\sources directory (see How_to_Add_a_variable).

In variables.h, check if the following lines are included (if not, please include them):

	KRATOS_DEFINE_VARIABLE(double, DUMMY_UNKNOWN)
	KRATOS_DEFINE_VARIABLE(double, DUMMY_MATERIAL)
	KRATOS_DEFINE_VARIABLE(double, DUMMY_POINT_SOURCE)

In variables.cpp, check if the following lines are included (if not, please include them):

	KRATOS_CREATE_VARIABLE(double, DUMMY_UNKNOWN)
	KRATOS_CREATE_VARIABLE(double, DUMMY_MATERIAL)
	KRATOS_CREATE_VARIABLE(double, DUMMY_POINT_SOURCE)

and:

	KRATOS_REGISTER_VARIABLE(DUMMY_UNKNOWN)
	KRATOS_REGISTER_VARIABLE(DUMMY_MATERIAL)
	KRATOS_REGISTER_VARIABLE(DUMMY_POINT_SOURCE)

Source Files for this Kratos Application

The kPoisson directory with all their files can be found in KPoisson.dir.zip. Please download, unzip and copy the whole directory in your /kratosR1/applications directory.

The other files can be also download here (please download, unzip and copy in their each specific Kratos directory, as it is indicated):

Warn_icon.gif Warning. Please, note that:

  • Do not copy these files inside your KratosR1 directory, because doing this would imply destroying the CVS. You should instead merge manually the differences.

A First GiD - Kratos Interface

Suggested Prerequisites

  • Kratos application
  • Basic knowledge about GiD customisation (an excellent introduction can be found in the GiD's Reference Manual

We will use GiD as our favourite pre and post-processor. To customise GiD for our Kratos kPoisson application, we will create two kind of files:

  • code to customise the GiD windows for input data (files with .mat, .cnd and .prb extensions);
  • code to get the user's input data from the windows and translate them to Kratos input data (files with .bas extension);

For our kPoisson application, it is enough to create two data files: the materials and the conditions windows.

Go to the GiD's problemtype directory (in MS Windows typically in something like "C:\Archivos de programa\GiD\GiD 8.2.0b\problemtypes\") and create a new folder with the name of your application, for example, kPoisson.gid.

Customising GiD input data Windows

Materials GiD window: kPoisson.mat

Create a new text file with the name kPoisson.mat in your GiD kPoisson problemtype directory (kPoisson.gid).

Defining the materials' properties in GiD requires just to indicate the variable name and value of the property, for example:

MATERIAL: Air
QUESTION: Dummy_Material
VALUE: 1.0
END MATERIAL

This will generate in GiD:

KPoisson.mat.jpg

If you want to include different material values, you can add them by simply copying the same lines:

MATERIAL: Air
QUESTION: Dummy_Material
VALUE: 1.0
END MATERIAL
MATERIAL: Aluminium
QUESTION: Dummy_Material
VALUE: 1000.0
END MATERIAL

KPoisson.mat.2.jpg


Conditions GiD window: kPoisson.cnd

Create a new text file with the name kPoisson.cnd in your GiD kPoisson problemtype directory (kPoisson.gid).

We will define just two conditions: the Dirichlet boundary condition to be applied on points or lines, and a point source condition (to be applied on points). We will split both conditions by using the "BOOK" tab of GiD:

BOOK: Dirichlet_Conditions
CONDITION: Point_Fix_Value
CONDTYPE: over points
CONDMESHTYPE: over nodes
QUESTION: Value
VALUE: 0.0
END CONDITION

This will generate in GiD the window:

KPoisson.cnd.jpg

To include the same boundary condition on lines, we add the following lines:

CONDITION: Line_Fix_Value
CONDTYPE: over lines
CONDMESHTYPE: over nodes
QUESTION: Value
VALUE: 0.0
END CONDITION

And for the point source condition:

BOOK: Dummy_Sources
CONDITION: Point_Dummy_Load
CONDTYPE: over points
CONDMESHTYPE: over nodes
QUESTION: Q
VALUE: 0.0
END CONDITION

with the result of:

KPoisson.cnd.2.jpg KPoisson.cnd.3.jpg

Transferring GiD input data to Kratos input data files

All the data in GiD (geometrical data, mesh information, material and conditions assigned to our model) will be transferred to Kratos by using .bas files. Basically, you have to translate the GiD labels to the Kratos variable name's.

Properties data file: 010_kPoisson.prop.bas

Create a new text file with the name 010_kPoisson.prop.bas in your GiD kPoisson problemtype directory (kPoisson.gid).

For the materials properties, you have to translate the GiD material label (Dummy_Material) to our Kratos variable (DUMMY_MATERIAL), as follows:

*loop materials 
*format "%i%f" 
PROPERTIES[*MatNum][DUMMY_MATERIAL] = *MatProp(Dummy_Material);  
*end materials

This code will generate a file with the different materials used in our problem, like this one:

PROPERTIES[1][DUMMY_MATERIAL] = 1.000000;  
PROPERTIES[2][DUMMY_MATERIAL] = 1000.000000;  

Element data file: 011_kPoisson.elem.bas

Create a new text file with the name 011_kPoisson.elem.bas in your GiD kPoisson problemtype directory (kPoisson.gid).

Now you have to indicate the kind of Kratos element you are going to use for your problem, in order to create a list with the elements numbers, connectivities and assigned material. In this case is Poisson2D.

// Reading Elements

ElementsGroup = dummy_group;

*loop elems
*Set var i=0
*set var j= ElemsNnode
*format "%i%i%i%i%i%i%i%i"
ELEMENTS[*ElemsNum] = Poisson2D([*\
*for(i=1;i<j;i=i+1)*\
*ElemsConec(*i),*\
*end*\
*ElemsConec(*ElemsNnode)],*ElemsMat);
*end elems

This template file will generate something like:

// Reading Elements

ElementsGroup = dummy_group;

ELEMENTS[1] = Poisson2D([2,1,3],1);
ELEMENTS[2] = Poisson2D([3,4,2],1);
ELEMENTS[3] = Poisson2D([4,3,7],2);
ELEMENTS[4] = Poisson2D([7,8,4],2);
ELEMENTS[5] = Poisson2D([5,2,4],1);
ELEMENTS[6] = Poisson2D([4,6,5],1);
ELEMENTS[7] = Poisson2D([6,4,8],2);
ELEMENTS[8] = Poisson2D([8,9,6],2);

This is a file generated with a GiD mesh like the following:

KPoisson.elem.jpg

Conditions data file: 012_kPoisson.cond.bas

Create a new text file with the name 012_kPoisson.cond.bas in your GiD kPoisson problemtype directory (kPoisson.gid).

Remember that we have defined three conditions (two for the Dirichlet Boundary type and a third one for the point source), corresponding to fix the value of our DUMMY_UNKNOWN and our DUMMY_POINT_SOURCE:

  • Point_Fix_Value (Value)
  • Line_Fix_Value (Value)
  • Point_Dummy_Load (Q)
// Fixing degrees of freedom in nodes

*Set cond Point_Fix_Value *nodes
*Add cond Line_Fix_Value *nodes
*loop nodes  *OnlyInCond
*format "%i%f"
NODES[*NodesNum].Fix(DUMMY_UNKNOWN);
*end nodes

*Set cond Point_Dummy_Load *nodes
*loop nodes  *OnlyInCond
NODES[*NodesNum].Fix(DUMMY_POINT_SOURCE);
*end nodes

With this file, we are saying to Kratos what the conditions are (the fixed values or the source values), but not the specific value. This is done in this way for transient problems, where the value of a condition can change for each time step.

Assigning the following conditions to our model:

KPoisson.cnd.4.jpg KPoisson.cnd.5.jpg

this file will produce a data file like the following:

// Fixing degrees of freedom in nodes

NODES[1].Fix(DUMMY_UNKNOWN);
NODES[2].Fix(DUMMY_UNKNOWN);
NODES[5].Fix(DUMMY_UNKNOWN);
NODES[7].Fix(DUMMY_UNKNOWN);
NODES[8].Fix(DUMMY_UNKNOWN);
NODES[9].Fix(DUMMY_UNKNOWN);

NODES[4].Fix(DUMMY_POINT_SOURCE);

Initial Values data file: 013_kPoisson.init.bas

Create a new text file with the name 013_kPoisson.init.bas in your GiD kPoisson problemtype directory (kPoisson.gid).

To indicate the initial values (the fix values for static problems), we have to create the following file:

// Fixing degrees of freedom in nodes

*Set cond Point_Fix_Value *nodes
*Add cond Line_Fix_Value *nodes
*loop nodes  *OnlyInCond
*format "%i%f"
NODES[*NodesNum](DUMMY_UNKNOWN,0) = *cond(Value);
*end nodes
*Set cond Point_Dummy_Load *nodes
*loop nodes  *OnlyInCond
NODES[*NodesNum](DUMMY_POINT_SOURCE,0) = *cond(Q);
*end nodes

That it will generate for the previous example:

// Fixing degrees of freedom in nodes

NODES[1](DUMMY_UNKNOWN,0) = 0.000000;
NODES[2](DUMMY_UNKNOWN,0) = 0.000000;
NODES[5](DUMMY_UNKNOWN,0) = 0.000000;
NODES[7](DUMMY_UNKNOWN,0) = 7.000000;
NODES[8](DUMMY_UNKNOWN,0) = 7.000000;
NODES[9](DUMMY_UNKNOWN,0) = 7.000000;
NODES[4](DUMMY_POINT_SOURCE,0) = 500.0;

Node data file: 014_kPoisson.node.bas

Create a new text file with the name 014_kPoisson.node.bas in your GiD kPoisson problemtype directory (kPoisson.gid).

In general terms, you will not modify this file in your applications, because it is just the list of nodes' coordinates of your problem.

*RealFormat "%10.5f"
NODES = NodesList([
*set var i=1
*loop nodes
*if(i>1)
,
*endif
[*nodesnum,*NodesCoord(1),*NodesCoord(2),*NodesCoord(3)]*\
*set var i=i+1
*end

])

For our specific mesh, this file will generate something like:

NODES = NodesList([
[1,  -8.57703,  -4.79186,   0.00000],
[2,  -8.57703,   3.98651,   0.00000],
[3,   6.08043,  -4.79186,   0.00000],
[4,   6.08043,   3.98651,   0.00000],
[5,  -8.57703,  12.76488,   0.00000],
[6,   6.08043,  12.76488,   0.00000],
[7,  20.73789,  -4.79186,   0.00000],
[8,  20.73789,   3.98651,   0.00000],
[9,  20.73789,  12.76488,   0.00000]
])

Batch files for your GiD kPoisson Problemtype

We have almost customised our GiD problemtype. We only need to create two additional files:

  • the template file kPoisson.bas to generate the python command lines for running our problem in Kratos;
  • the MS Windows (or Linux) batch file kPoisson.win.bat, basically to clean our working directory, to rename our files and to do some stuff previously to run python with our problem;

Python application file: kPoisson.bas

Create a new text file with the name kPoisson.bas in your GiD kPoisson problemtype directory (kPoisson.gid).

This template file will create each python command line file customised to our specific GiD example and our Kratos application (with the kPoisson element and the selected solver). Note that once again the bold characters indicates those lines you should modify, using our specific class, methods or variables denomination.

##################################################################
##################################################################
#setting the domain size for the problem to be solved
domain_size = 2

##################################################################
##################################################################
## ATTENTION: here the order is important

#including kratos path
kratos_libs_path = '../../../../libs' ##kratos_root/libs
kratos_applications_path = '../../../../applications' ##kratos_root/applications
import sys
sys.path.append(kratos_libs_path)
sys.path.append(kratos_applications_path)

print "before importing kratos"

#importing Kratos main library
from Kratos import **
print "Kratos library imported"
kernel = Kernel()   #defining kernel
print "kernel created"
#importing applications
import applications_interface
applications_interface.Import_PoissonApplication = True

applications_interface.ImportApplications(kernel, kratos_applications_path)

## from now on the order is not anymore crucial
##################################################################
################################################################## 

from KratosR1PoissonApplication import **

#defining a model part
model_part = ModelPart("PoissonPart");  

#adding of Variables to Model Part
import static_poisson_solver
static_poisson_solver.AddVariables(model_part)

#reading a model
gid_mode = GiDPostMode.GiD_PostBinary
multifile = MultiFileFlag.MultipleFiles
deformed_mesh_flag = WriteDeformedMeshFlag.WriteUndeformed
write_conditions = WriteConditionsFlag.WriteElementsOnly
gid_io = GidIO("*tcl(file tail [GiD_Info project  modelname])",gid_mode,multifile,deformed_mesh_flag,write_conditions)
gid_io.ReadModelPart(model_part)

mesh_name = 0.0
gid_io.InitializeMesh( mesh_name );
gid_io.WriteMesh((model_part).GetMesh());
gid_io.FinalizeMesh()
print model_part

#the buffer size should be set up here after the mesh is read for the first time
model_part.SetBufferSize(3)

#importing the solver files
static_poisson_solver.AddDofs(model_part)
    
#creating a solver object
solver = static_poisson_solver.StaticPoissonSolver(model_part,domain_size)
solver.time_order = 1
solver.linear_solver = SkylineLUFactorizationSolver();
solver.echo_level = 0
solver.Initialize()

gid_io.InitializeResults(mesh_name,(model_part).GetMesh())

solver.Solve() 

gid_io.WriteNodalResults(DUMMY_UNKNOWN,model_part.Nodes,0,0)
gid_io.FinalizeResults()

This file will create for our specific problem the following our_example.py file:

##################################################################
##################################################################
#setting the domain size for the problem to be solved
domain_size = 2

##################################################################
##################################################################
## ATTENTION: here the order is important

#including kratos path
kratos_libs_path = '../../../../libs' ##kratos_root/libs
kratos_applications_path = '../../../../applications' ##kratos_root/applications
import sys
sys.path.append(kratos_libs_path)
sys.path.append(kratos_applications_path)

print "before importing kratos"

#importing Kratos main library
from Kratos import *
print "Kratos library imported"
kernel = Kernel()   #defining kernel
print "kernel created"
#importing applications
import applications_interface
applications_interface.Import_PoissonApplication = True

applications_interface.ImportApplications(kernel, kratos_applications_path)

## from now on the order is not anymore crucial
##################################################################
##################################################################

from KratosR1PoissonApplication import *

#defining a model part
model_part = ModelPart("PoissonPart");  

#adding of Variables to Model Part
import static_poisson_solver
static_poisson_solver.AddVariables(model_part)

#reading a model
gid_mode = GiDPostMode.GiD_PostBinary
multifile = MultiFileFlag.MultipleFiles
deformed_mesh_flag = WriteDeformedMeshFlag.WriteUndeformed
write_conditions = WriteConditionsFlag.WriteElementsOnly
gid_io = GidIO("our_example",gid_mode,multifile,deformed_mesh_flag,write_conditions)
gid_io.ReadModelPart(model_part)

mesh_name = 0.0
gid_io.InitializeMesh( mesh_name );
gid_io.WriteMesh((model_part).GetMesh());
gid_io.FinalizeMesh()
print model_part

#the buffer size should be set up here after the mesh is read for the first time
model_part.SetBufferSize(3)

#importing the solver files
static_poisson_solver.AddDofs(model_part)
    
#creating a solver object
solver = static_poisson_solver.StaticPoissonSolver(model_part,domain_size)
solver.time_order = 1
solver.linear_solver = SkylineLUFactorizationSolver();
solver.echo_level = 0
solver.Initialize()

gid_io.InitializeResults(mesh_name,(model_part).GetMesh())

solver.Solve()

gid_io.WriteNodalResults(DUMMY_UNKNOWN,model_part.Nodes,0,0)
gid_io.FinalizeResults()

that is almost the same, but with the specific reference to the name of our example.

MS Window Batch file: kPoisson.win.bat

Create a new text file with the name kPoisson.win.bat in your GiD kPoisson problemtype directory (kPoisson.gid).

No special comments are needed for this file. Just take cure about where your python bin is located. For Linux or Unix systems is almost the same.

@ECHO OFF

rem OutputFile: %1.log

del %2\%1.info
del %2\%1.flavia.res
del %2\%1.flavia.dat
del %2\%1.err

del %2\%1.py

del %2\%1.prop
del %2\%1.elem
del %2\%1.cond
del %2\%1.init
del %2\%1.node

ren %2\%1.dat %2\%1.py
ren %2\%1-1.dat %2\%1.prop
ren %2\%1-2.dat %2\%1.elem
ren %2\%1-3.dat %2\%1.cond
ren %2\%1-4.dat %2\%1.init
ren %2\%1-5.dat %2\%1.node

C:\kratosR1\Python25\python %2\%1.py >%2\%1.log

del %2\%1.post.res
ren %2\%1_0.post.bin %2\%1.post.res

A possible Linux version could be kPoisson.unix.bat:

#!/bin/csh -f
#    OutputFile: $2/$1.info
#    ErrorFile: $2/$1.err
#delete previous result file 
rm -f  $2/$1.flavia.res 
rm $2/$1.info
rm $2/$1.flavia.dat
rm $2/$1.err
rm $2/$1.node
rm $2/$1.prop
rm $2/$1.elem
rm $2/$1.cond
rm $2/$1.init
rm $2/$1.py
mv $2/$1.dat $2/$1.py
mv $2/$1-1.dat $2/$1.prop
mv $2/$1-2.dat $2/$1.elem
mv $2/$1-3.dat $2/$1.cond
mv $2/$1-4.dat $2/$1.init
mv $2/$1-5.dat $2/$1.node
python $2/$1.py >$2/$1.log
rm $2/$1.post.res
rm $2/$1_0.post.bin $2/$1.post.res

Source Files for your GiD-Kratos Application Problem Type

The kPoisson.gid directory with all their files can be found in KPoisson.gid.zip. Please download, unzip and copy the whole directory in your GiD problemtype directory.

Files and Results in GiD

If everything is ok, now you can create your geometry, assign materials and conditions with GiD, launch your Kratos application and see the results.

Data files in GiD

After selecting our GiD problemtype (kPoisson),

KPoissonGiDproblemtype.jpg

we can create our geometry,

Our example geo.jpg

assign materials and conditions,

Our example mat.jpg

KPoisson.cnd.4.jpg
KPoisson.cnd.5.jpg

If we save now this problem with the name our_example, GiD will automatically generate the following files:

  • our_example.cnd
  • our_example.geo
  • our_example.lin
  • our_example.mat
  • our_example.png
  • our_example.rdr
  • our_example.vv

Now we can mesh our model, generating the already presented mesh:

KPoisson.elem.jpg

and creating the files:

  • our_example.msh

If now we run our Kratos application, by doing:

Our example calculate.jpg

a set of new files are generated:

  • our_example.cond
  • our_example.elem
  • our_example.init
  • our_example.node
  • our_example.prop
  • our_example.py
  • our_example.log
  • our_example.post.res

The first six files have been already explained.

The log file contains the details about how the simulation have been performed, including warnings or errors (if there is something).

Results files in GiD

our_example.log

Relevant aspects are indicated with bold characters:

"kerneal entered in AddApplication" : kerneal entered in AddApplication

Initializing KratosR1PoissonApplication... 
"Application Registered" : Application Registered
"Variables Registered Registered" : Variables Registered Registered
"Elements Registered" : Elements Registered
"Conditions Registered" : Conditions Registered
our_example opened for io
our_example.node opened for io
our_example.prop opened for io
our_example.elem opened for io
our_example.cond opened for io
our_example.init opened for io
initializing result files
reading nodes
temp : Node #9 : (20.7379 , 12.7649 , 0)
Nodes succesfully read
reading Properties
Properties succesfully read
reading Elements
Properties succesfully read
reading Conditions
Properties succesfully read
reading Initial Values
 reading initiali values 
 finished reading initial values 
Initial Values succesfully read
Reading completed succesfully
writing a 2D mesh
"setting up the dofs" : setting up the dofs
Building Time : 0
LU factorization solver finished.

System Solve Time : 0
Building Time : 0
LU factorization solver finished.

System Solve Time : 0
DISPLACEMENT CRITERIA :: obtained tol = 0.0206048;  expected ratio = 1e-006absolute tol = 0.194195
Building Time : 0
LU factorization solver finished.

System Solve Time : 0
DISPLACEMENT CRITERIA :: obtained tol = 0.00405189;  expected ratio = 1e-006absolute tol = 0.0380348
Building Time : 0
LU factorization solver finished.

System Solve Time : 0
DISPLACEMENT CRITERIA :: obtained tol = 0.000159258;  expected ratio = 1e-006absolute tol = 0.00149484
Building Time : 0
LU factorization solver finished.

System Solve Time : 0
DISPLACEMENT CRITERIA :: obtained tol = 2.82165e-005;  expected ratio = 1e-006absolute tol = 0.000264855
Building Time : 0
LU factorization solver finished.

System Solve Time : 0
DISPLACEMENT CRITERIA :: obtained tol = 1.42173e-006;  expected ratio = 1e-006absolute tol = 1.33451e-005
Building Time : 0
LU factorization solver finished.

System Solve Time : 0
DISPLACEMENT CRITERIA :: obtained tol = 2.80121e-007;  expected ratio = 1e-006absolute tol = 2.62936e-006
"convergence is achieved" : convergence is achieved
before importing kratos
Kratos library imported
kernel created
Applications Available:
Import_ALEApplication: False
Import_IncompressibleFluidApplication: False
Import_StructuralApplication: False
Import_ConvectionDiffusionApplication: False
Import_FSIApplication: False
Import_ExternalSolversApplication: False
Import_ULFApplication: False
Import_MeshingApplication: False
Import_ElectrostaticApplication: False
Import_PoissonApplication: False
Applications Available:
Import_ALEApplication: False
Import_IncompressibleFluidApplication: False
Import_StructuralApplication: False
Import_ConvectionDiffusionApplication: False
Import_FSIApplication: False
Import_ExternalSolversApplication: False
Import_ULFApplication: False
Import_ULFApplication: False
Import_ ElectrostaticApplication: False
Import_ PoissonApplication: True
importing KratosR1PoissonApplication ...
Kratos PoissonApplication1 sucessfully imported
PoissonPart model part
    Buffer Size : 1
    Current solution step index : 0

    Mesh 0 : 
    Number of Nodes      : 9
    Number of Properties : 2
    Number of Elements   : 8
    Number of Conditions : 0

variables for the Poisson solver added correctly
 

The file our_example.post.res contains the results of the simulation, that is, the value of the unknowns for each node. It is written in binary format according to the GiD standards, and we can see the results by using the GiD post-processor:

Our example results.jpg

If you want to get the results in a readable format, you can ask Gid to write them in an ascii format:

Our example results ascii.jpg

If we write results_ascii as the name to write the results in ascii format, we will obtain two files: results_ascii.msh and results_ascii.res.

Mesh file: results_ascii.msh

# encoding utf-8
MESH "Kratos Triangle2D3 Mesh" dimension 3 ElemType Triangle Nnode 3
Coordinates
1 -8.5770302 -4.7918601 0
2 -8.5770302 3.98651 0
3 6.08043 -4.7918601 0
4 6.08043 3.98651 0
5 -8.5770302 12.76488 0
6 6.08043 12.76488 0
7 20.73789 -4.7918601 0
8 20.73789 3.98651 0
9 20.73789 12.76488 0
end coordinates 

Elements
1 2 1 3 1 
2 3 4 2 1 
5 5 2 4 1 
6 4 6 5 1 
end elements
MESH "Kratos Triangle2D3 Mesh 2" dimension 3 ElemType Triangle Nnode 3
Coordinates
end coordinates 

Elements
3 4 3 7 2 
4 7 8 4 2 
7 6 4 8 2 
8 8 9 6 2 
end elements

Results file: results_ascii.res

GiD Post Results File 1.0

# encoding utf-8
Result "DUMMY UNKNOWN" "Kratos" 0 Scalar OnNodes
ComponentNames "DUMMY UNKNOWN"
Values
1 0
2 0
3 8.92342
4 9.84336
5 0
6 9.37023
7 7
8 7
9 7
End values

Data Files for an Specific Example with Kratos in GiD

The our_example.gid directory with all their files can be found in our_example.gid.zip. Please download, unzip and copy the whole directory in your examples directory.

Use and Validation of Our First Kratos Simulation Program

Suggested Prerequisites:

Personal tools
Categories