-
Notifications
You must be signed in to change notification settings - Fork 247
How to Access DataBase
Accessing to the database is one of the most frequent operations in a Finite Element context.
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 directly in the object from which it will be accessed, meaning that the nodes will contain the nodal data, and the elements the elemental data.
The Kratos provides both a nodal and elemental Variable Database
, which allows to store in a flexible way VARIABLES
of different type. A detailed description of the design concepts together with a study of the performance 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 C++
interface.
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.
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 are not synchronized.
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()
. To make an example :
model_part.SetBufferSize(3)
unsigned int model_part.GetBufferSize(); ##now outputs 3
Implies storing the current step plus the 2 last steps.
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. 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.
model_part.AddNodalSolutionStepVariable(TEMPERATURE)
model_part.AddNodalSolutionStepVariable(VELOCITY)
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 tests
). Note that trying to access for example to PRESSURE
will lead to an error as the database did not allocate any memory to hold the variable PRESSURE
Once this preliminary operations are performed, the memory for the Kratos is allocated and can be used efficiently. Two Functions exist to access to the solution step data:
GetSolutionStepData
FastGetSolutionStepData
Their functionality is identical but they differ in the checks that are performed internally in the Release version (They are identical in Debug). The Fast...
operator, does not perform any check, meaning that if, in the example before, we try to access to PRESSURE
(not in the variable list) we will get a segmentation fault without any further information.
The syntax is as follows:
Node<3>::iterator inode = model_part.NodesBegin(); //to make example let's take the first node
//here we get REFERENCES to the database!!
array_1d<double,3>& vel = inode->FastGetSolutionStepValue(VELOCITY); //vel here has the value of velocity at the current step
const array_1d<double,3>& oldvel = inode->FastGetSolutionStepValue(VELOCITY,1); //vel 1 step in the past
const array_1d<double,3>& veryoldvel = inode->FastGetSolutionStepValue(VELOCITY,2); //vel 2 steps in the past
//
//predicting the vel as vel = 2*oldvel - veryoldvel;
noalias(vel) = 2.0 * oldvel;
noalias(vel) -= veryoldvel;
//NOTE: "vel" is a REFERENCE to the database => changing "vel" we change the database
On the side of the "historical" database it is also possible to store variables which do not change as the time step evolves. As an important difference with respect to the historical database, the list of variables included nor the "size" of the objects does not need to be prescribed at the beginning of the program and can be changed dynamically during the run.
ANY element type can be included in this sort of database. As an example, a part for the standard types double array_1d<double,3>
Matrix
we can use user defined types. Two useful examples of this are:
NEIGHBOUR_NODES
NEIGHBOUR_ELEMENTS
The usage of such entities is described elsewhere (..) the important point is here that an array of pointers can be stored without any problems together with the standard datatypes. The implementation details and the discussion of the implementation can be found in Pooyan's Thesis.
The access is through the functions GetValue()
and SetValue()
. To make an example:
double temperature = inode->GetValue(TEMPERATURE)
or
double aaa = 10.0
inode->SetValue(TEMPERATURE,aaa);
The Elemental database is identical to the "non-historical" database (it shares exactly the same implementation). Non historical database is implemented for elements and conditions.
The user should nevertheless note that the user can implement a user-defined storage through the elemental interface (see for example the function Calculate
or CalculateOnIntegrationPoints
)
- Getting Kratos (Last compiled Release)
- Compiling Kratos
- Running an example from GiD
- Kratos input files and I/O
- Data management
- Solving strategies
- Manipulating solution values
- Multiphysics
- Video tutorials
- Style Guide
- Authorship of Kratos files
- Configure .gitignore
- How to configure clang-format
- How to use smart pointer in Kratos
- How to define adjoint elements and response functions
- Visibility and Exposure
- Namespaces and Static Classes
Kratos structure
Conventions
Solvers
Debugging, profiling and testing
- Compiling Kratos in debug mode
- Debugging Kratos using GDB
- Cross-debugging Kratos under Windows
- Debugging Kratos C++ under Windows
- Checking memory usage with Valgind
- Profiling Kratos with MAQAO
- Creating unitary tests
- Using ThreadSanitizer to detect OMP data race bugs
- Debugging Memory with ASAN
HOW TOs
- How to create applications
- Python Tutorials
- Kratos For Dummies (I)
- List of classes and variables accessible via python
- How to use Logger
- How to Create a New Application using cmake
- How to write a JSON configuration file
- How to Access DataBase
- How to use quaternions in Kratos
- How to do Mapping between nonmatching meshes
- How to use Clang-Tidy to automatically correct code
- How to use the Constitutive Law class
- How to use Serialization
- How to use GlobalPointerCommunicator
- How to use PointerMapCommunicator
- How to use the Geometry
- How to use processes for BCs
- How to use Parallel Utilities in futureproofing the code
- Porting to Pybind11 (LEGACY CODE)
- Porting to AMatrix
- How to use Cotire
- Applications: Python-modules
- How to run multiple cases using PyCOMPSs
- How to apply a function to a list of variables
- How to use Kratos Native sparse linear algebra
Utilities
Kratos API
Kratos Structural Mechanics API