# How to use multiple model parts

## Using multiple model parts

The problem of handling complex geometries or domains characterized by multiple physical fields, is simplified by the usage of multiple model_parts. As a matter of fact, model_part is intended as a container for

- Elements
- Conditions
- Nodes
- Properties
- ProcessInfo

that describe a given part of the model.

The fundamental idea is that most of the information, and in particular the degrees of freedom are stored on the **Nodes**.
**Elements** and **Conditions** take care of describing the underlying mathematical structure.
All of the informations on the "status" of the model, for example the current TIME or the DELTA_TIME are stored in the **ProcessInfo**.
The **Properties** take care of keeping trace of the material properties.

Two main usage scenarios rise at this point:

## SCENARIO 1 : two different formulations on one domain

This is the case for example of fluid flow + temperature. The two problems share the same volume (and the same discretization of the model) but two distinct problems have to be solved, namely the flow problem and the temperature one.

The basic observation in this context is that the two formulations share the same discretization of the domain, and in particular *the same nodes*.
The important advantage is that any information stored at the nodes is immediately available to both the formulations. For example if the fluid solver computes VELOCITY the thermal solver will be able automatically to use this VELOCITY
to convect the TEMPERATURE.

The point we would like to highlight here is how to define the two different domains:

let's suppose that we start by reading a fluid_model_part

and we would like to define a thermal_model_part

that shares the same nodes as the one before but is defined by an array of Elements and Conditions which use a different formulation. Let's also suppose for now that an appropriate list of ThermalElements and ThermalConditions is already created.

in order to fill the thermal_model_part we should perform in python the following operations:

thermal_model_part.Nodes = fluid_model_part.Nodes ##make the new model part to use the same nodes as the original model part! thermal_model_part.ProcessInfo = fluid_model_part.ProcessInfo ##this makes all of the time informations to coincide between the two model parts thermal_model_part.Properties = fluid_model_part.Properties ##assign all of the "Material properties"

all of the operations up to this point copy Pointers so ... **any change in the fluid_model_part's Nodes, Properties and ProcessInfo will also affect the new thermal model part**

thermal_model_part.Elements = ThermalElements thermal_model_part.Conditions = ThermalConditions

here we assign to the Elements of the thermal model part the list of elements we created somewhere.

In the practice this operation is made automatic by an utility in the MeshingApplication (which of course **should be imported to have the option available**)

the usage in this case would be (assuming fluid_model_part is the origin and thermal_model_part the destination)

modeler_util = ConnectivityPreserveModeler() modeler_util.GenerateModelPart(fluid_model_part,thermal_model_part,"ThermalElementName","ThermalConditionName")

where "ThermalElementName" is a string that contains the kratos name for the element to be used in filling the new model part.

Please note that if the same nodes are shared between different model parts, |

## SCENARIO 2 : two different formulations on different parts of the domain

In the case that you do not want to create a copy of the whole model part (like in the example above), but instead need to create an empty model part, later on filled by sub-sets of the previously existing one (think of the "father" model part in FSI that contains all the nodes of the fluid and structure domain.. You wish to create two "sons" - "fluid part" and "structure part"), then after copying the necessary data (nodes, elements, etc) to the "sons", you need to** set the process info** of the new parts as:

son_model_part.SetProcessInfo(father_model_part.pGetProcessInfo()).

**Note: THAT you must use pGetProcessInfo and not GetProcessInfo. The latter one creates a copy, while the first and correct one "links" the pointer.**