-
Notifications
You must be signed in to change notification settings - Fork 247
Kratos For Dummies: Transient non linear heat transfer
In this second part we will modify the element and the solver in order to compute a transient non-linear problem, in other words, compute the dynamic contribution of the element. We will use the tools already available on the Kratos framework (or KratosCore), like the Newton-Rahpson strategy, the convergence criterion and the BDF scheme.
In order to accommodate the interoperability with other applicatiion in Kratos we will show how to integrate the already developed solver into the common interface for all the solvers. Finally all this will be integrated in one analysis stage file, that will replace the main script file. Helping in the future the development of coupled solver.
With all this components we will be able to run our problem in the same way it is designed and planned to be in the standard GiD interface. This will help you to integrate your developments into the Kratos ecosystem.
Additionally, you can see all the tools, processes, classes, variables, etc... available on the pỳthon interface of the KratosCore here.
- Adding dynamic contribution to the element
- Updating solver to Non-linear and transient
- Integrate into an analysis stage
- Using *.json parameters
The equation to solve now will be:
We have two different alternatives in order to compute the dynamic terms. Some elements compute internally the dynamic contribution. This is the case of the elements in the ConvectionDiffusionApplication and some fluid elements. The rest of the elements compute the contribution using mass and damping matrices (or the equivalent, depending of the physics being solved, the equivalent terms for the first and second time derivative).
Using the latter it is possible to use the interface of the existing schemes. The schemes are "utilities" used to compute the dynamic contributions of the problem. For this reason we will add the dynamic terms to our element.
We will modify our solver in order to enhance the capabilities, making us possible to compute a non-linear transient problem.
The base python interface can be found in Kratos/kratos/python_scripts/python_solver.py
The following wrapper for the convergence criteria is already available in the Kratos/kratos/python_scripts/base_convergence_criteria_factory.py. Like we are not considering any additional convergence criteria to the ones available on the framework we can work taking into account just these.
from __future__ import print_function, absolute_import, division # makes KratosMultiphysics backward compatible with python 2.6 and 2.7
# Importing the Kratos Library
import KratosMultiphysics
# Convergence criteria class
class ConvergenceCriteriaFactory(object):
def __init__(self, convergence_criterion_parameters):
# Note that all the convergence settings are introduced via a Kratos parameters object.
D_RT = convergence_criterion_parameters["solution_relative_tolerance"].GetDouble()
D_AT = convergence_criterion_parameters["solution_absolute_tolerance"].GetDouble()
R_RT = convergence_criterion_parameters["residual_relative_tolerance"].GetDouble()
R_AT = convergence_criterion_parameters["residual_absolute_tolerance"].GetDouble()
echo_level = convergence_criterion_parameters["echo_level"].GetInt()
convergence_crit = convergence_criterion_parameters["convergence_criterion"].GetString()
if(echo_level >= 1):
KratosMultiphysics.Logger.PrintInfo("::[ConvergenceCriterionFactory]:: ", "CONVERGENCE CRITERION : " +
convergence_criterion_parameters["convergence_criterion"].GetString())
if(convergence_crit == "solution_criterion"):
self.convergence_criterion = KratosMultiphysics.DisplacementCriteria(D_RT, D_AT)
self.convergence_criterion.SetEchoLevel(echo_level)
elif(convergence_crit == "residual_criterion"):
self.convergence_criterion = KratosMultiphysics.ResidualCriteria(R_RT, R_AT)
self.convergence_criterion.SetEchoLevel(echo_level)
elif(convergence_crit == "and_criterion"):
Displacement = KratosMultiphysics.DisplacementCriteria(D_RT, D_AT)
Displacement.SetEchoLevel(echo_level)
Residual = KratosMultiphysics.ResidualCriteria(R_RT, R_AT)
Residual.SetEchoLevel(echo_level)
self.convergence_criterion = KratosMultiphysics.AndCriteria(Residual, Displacement)
elif(convergence_crit == "or_criterion"):
Displacement = KratosMultiphysics.DisplacementCriteria(D_RT, D_AT)
Displacement.SetEchoLevel(echo_level)
Residual = KratosMultiphysics.ResidualCriteria(R_RT, R_AT)
Residual.SetEchoLevel(echo_level)
self.convergence_criterion = KratosMultiphysics.OrCriteria(Residual, Displacement)
else:
err_msg = "The requested convergence criterion \"" + convergence_crit + "\" is not available!\n"
err_msg += "Available options are: \"solution_criterion\", \"residual_criterion\", \"and_criterion\", \"or_criterion\""
raise Exception(err_msg)
Now if we want to integrate it into the solver, we just need to add the following to the solver:
def _create_convergence_criterion(self):
import base_convergence_criteria_factory as convergence_criteria_factory
convergence_criterion = convergence_criteria_factory.ConvergenceCriteriaFactory(self._get_convergence_criterion_settings())
return convergence_criterion.convergence_criterion
Depending of the approach followed on the implementation of our element
Finally, with all these components we are ready to integrate them into
The base python interface can be found in Kratos/kratos/python_scripts/analysis_stage.py. Following that very same structure we just need to define the following methods:
- The constructor (always needed). As a derived one will call first the base class constructor.
-
_CreateSolver
In order to create the solver -
_CreateProcesses
this one will create the list of processes to be executed -
_SetUpGiDOutput
To postprocess the problem -
_GetSimulationName
Minor method to have a nice and consistent name on the information printed
from __future__ import print_function, absolute_import, division # makes KratosMultiphysics backward compatible with python 2.6 and 2.7
# Importing Kratos
import KratosMultiphysics
import KratosMultiphysics.MyLaplacianApplication as Poisson
# Importing the solvers (if available)
try:
import KratosMultiphysics.ExternalSolversApplication
except ImportError:
KratosMultiphysics.Logger.PrintInfo("ExternalSolversApplication", "not imported")
# Importing the base class
from analysis_stage import AnalysisStage
# Other imports
import sys
class PoissonAnalysis(AnalysisStage):
"""
This class is the main-script of the Poisson put in a class
It can be imported and used as "black-box"
"""
def __init__(self, model, project_parameters):
# Calling the constructor of the base class
super(PoissonAnalysis, self).__init__(model, project_parameters)
## Import parallel modules if needed
if (self.parallel_type == "MPI"):
import KratosMultiphysics.MetisApplication as MetisApplication
import KratosMultiphysics.TrilinosApplication as TrilinosApplication
#### Internal functions ####
def _CreateSolver(self):
""" Create the Solver (and create and import the ModelPart if it is not alread in the model) """
## Solver construction
return pure_diffusion_solver.PureDiffusionSolver(self.model, self.project_parameters)
def _CreateProcesses(self, parameter_name, initialization_order):
"""Create a list of Processes
"""
list_of_processes = super(PoissonAnalysis, self)._CreateProcesses(parameter_name, initialization_order)
if parameter_name == "processes":
processes_block_names = ["constraints_process_list", "fluxes_process_list", "list_other_processes"]
if len(list_of_processes) == 0: # Processes are given in the old format
KratosMultiphysics.Logger.PrintInfo("PoissonAnalysis", "Using the old way to create the processes, this will be removed!")
from process_factory import KratosProcessFactory
factory = KratosProcessFactory(self.model)
for process_name in processes_block_names:
if (self.project_parameters.Has(process_name) is True):
list_of_processes += factory.ConstructListOfProcesses(self.project_parameters[process_name])
else: # Processes are given in the new format
for process_name in processes_block_names:
if (self.project_parameters.Has(process_name) is True):
raise Exception("Mixing of process initialization is not alowed!")
elif parameter_name == "output_processes":
if self.project_parameters.Has("output_configuration"):
#KratosMultiphysics.Logger.PrintInfo("PoissonAnalysis", "Using the old way to create the gid-output, this will be removed!")
gid_output= self._SetUpGiDOutput()
list_of_processes += [gid_output,]
else:
raise NameError("wrong parameter name")
return list_of_processes
def _SetUpGiDOutput(self):
'''Initialize a GiD output instance'''
self.__CheckForDeprecatedGiDSettings()
if self.parallel_type == "OpenMP":
from gid_output_process import GiDOutputProcess as OutputProcess
elif self.parallel_type == "MPI":
from gid_output_process_mpi import GiDOutputProcessMPI as OutputProcess
gid_output = OutputProcess(self._GetSolver().GetComputingModelPart(),
self.project_parameters["problem_data"]["problem_name"].GetString() ,
self.project_parameters["output_configuration"])
return gid_output
def _GetSimulationName(self):
return "::[Poisson Simulation]:: "
if __name__ == "__main__":
from sys import argv
if len(argv) > 2:
err_msg = 'Too many input arguments!\n'
err_msg += 'Use this script in the following way:\n'
err_msg += '- With default ProjectParameters (read from "ProjectParameters.json"):\n'
err_msg += ' "python3 poisson_analysis.py"\n'
err_msg += '- With custom ProjectParameters:\n'
err_msg += ' "python3 poisson_analysis.py CustomProjectParameters.json"\n'
raise Exception(err_msg)
if len(argv) == 2: # ProjectParameters is being passed from outside
project_parameters_file_name = argv[1]
else: # using default name
project_parameters_file_name = "ProjectParameters.json"
with open(parameter_file_name,'r') as parameter_file:
parameters = KratosMultiphysics.Parameters(parameter_file.read())
model = KratosMultiphysics.Model()
simulation = PoissonAnalysis(model, parameters)
simulation.Run()
Once everything has been packed into the designed workflow, using analysis and solvers derived from the already existing scripts and classes, we can define our problem using directly the a pair of *.json files, one for the configuration parameters and another for the material properties. In the following we will need to modify these files to modify our problem. Of course for more options we can always develop our own processes.
- 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