GiDInterface
GiDInterface copied to clipboard
How to write Conditions
In the issue https://github.com/KratosMultiphysics/Kratos/issues/278 @RiccardoRossi , @maceligueta , @philbucher and me were talking about How should the problemtype write the conditions:
I've written this, trying to clearify some ideas (forgive me for the extension):
From the problemtype side, the most efficient way is to print the GiD element id. Let's call this the A way of writing the conditions. That is done using the customLib C++ lib, so it is faster and allows to handle larger number of elements than the current way of printing the conditions' block, in TCL.
The B way is do what we are doing now, each app implements it's way of printing/storing the conditions (or uses the common functions to do so). At this point, the pseudo-code looks like this:
In the Begin Conditions sections:
foreach condition in conditions: //(in the tree)
foreach group in GetGroupsOf(condition)
print "Begin Condition _ConditionName_"
foreach element in GetElementsOf(group)
nodes = GetNodesOf(element)
print "i 0 nodes"
++i
print "End Condition"
Store(condition,group, initial_id, end_id)
Each condition-group stores its interval of ids, to print them later in the submodelpart.
In the submodelparts sections:
foreach condition-group in GetStoredConditionsGroups // previously stored
Print "Begin SubModelPart _condition-group_
Print "Begin nodes"
foreach node in GetNodes(group)
print node
Print "End nodes"
Print "Begin conditions"
i = condition-group.getInitial
while i < condition-group.getFinal
print i
++i
print "End conditions"
print "End subModelPart"
Let's compare
THE A WAY: pros:
- Increased performance (C++ writing)
- Easier implementation (we do not need to keep control of assigned ids)
cons:
- Points are meshed as nodes, not as '1 noded elements', so it's ids are assigned as nodal id (We'll see it in an example). Dr. Abel Coll (manager of the GiD dept.) has explained me that he can change something in the GiD tcl API to get nodes meshed as elements.
- Conditions id will not be consecutive
- As @maceligueta said, it will be impossible to get different id for the same entity, if you need so.
THE B WAY: pros:
- It is already implemented
- Conditions on nodes have a valid id assigned, without telling GiD to change it's meshing criteria
cons:
- Lower performance (TCL writing)
- Lower amount of elements (TCL can store lower information in a variable, remember the BCN model problems)
- Difficult implementation
- The fact of storing the 'invented' ids makes dificult the interaction between apps
- Each app has needed to implement it's own system to control the assigned ids
EXAMPLES:
Imagine this geometry:

Groups assigned: Body: the only surface Top: The top line Left: The left line
After meshing it, we get the following elements and nodes (elements in gray, nodes in black):

So assigned groups will have: Body: 6 Nodes: 1 2 3 4 5 6 4 Elements (4 Triangle): 1 2 3 4 Top: 3 Nodes: 2 4 6 2 Elements (2 Linear): 5 6 Left: 2 Nodes: 1 2 1 Elements (1 Linear): 7
Imagine that we assign (in the kratos tree): LINE_LOAD_CONDITION <-> Top -> with some properties LINE_LOAD_CONDITION <-> Top -> with other properties (interval changes...) LINE_PRESSURE_CONDITION <-> Top -> with some properties LINE_LOAD_CONDITION <-> Left-> with some properties
The A way mdpa could look:
Begin Conditions LineLoadCondition2D2N// GUI group identifier: Top
5 0 2 4
6 0 4 6
End Conditions
Begin Conditions LinePressureCondition2D2N// GUI group identifier: Top
5 0 2 4
6 0 4 6
End Conditions
// Note that we are applying two different conditions to the same ids, and we need to repeat their connectivities
Begin Conditions LineLoadCondition2D2N// GUI group identifier: Left
7 0 1 2
End Conditions
Begin SubModelPart LineLoad2D_Top // Group Top // Subtree LineLoad2D
Begin SubModelPartNodes
2
4
6
End SubModelPartNodes
Begin SubModelPartConditions
5
6
End SubModelPartConditions
End SubModelPart
Begin SubModelPart LinePressure2D_Top // Group Top // Subtree LinePressure2D
Begin SubModelPartNodes
2
4
6
End SubModelPartNodes
Begin SubModelPartConditions
5
6
End SubModelPartConditions
End SubModelPart
//Note that it's the same for both
Begin SubModelPart LineLoad2D_Left // Group Left // Subtree LineLoad2D
Begin SubModelPartNodes
1
2
End SubModelPartNodes
Begin SubModelPartConditions
7
End SubModelPartConditions
End SubModelPart
Meanwhile, the B Way is looking like this:
Begin Conditions LineLoadCondition2D2N// GUI group identifier: top
1 0 2 4
2 0 4 6
End Conditions
Begin Conditions LineLoadCondition2D2N// GUI group identifier: left
3 0 1 2
End Conditions
Begin Conditions LinePressureCondition2D2N// GUI group identifier: left
4 0 2 4
4 0 4 6
End Conditions
Begin SubModelPart LineLoad2D_top // Group top // Subtree LineLoad2D
Begin SubModelPartNodes
2
4
6
End SubModelPartNodes
Begin SubModelPartElements
End SubModelPartElements
Begin SubModelPartConditions
1
2
End SubModelPartConditions
End SubModelPart
Begin SubModelPart LineLoad2D_left // Group left // Subtree LineLoad2D
Begin SubModelPartNodes
1
2
End SubModelPartNodes
Begin SubModelPartElements
End SubModelPartElements
Begin SubModelPartConditions
3
End SubModelPartConditions
End SubModelPart
Begin SubModelPart LinePressure2D_top // Group top // Subtree LinePressure2D
Begin SubModelPartNodes
2
4
6
End SubModelPartNodes
Begin SubModelPartElements
End SubModelPartElements
Begin SubModelPartConditions
4
5
End SubModelPartConditions
End SubModelPart
As you can see, both ways have more or less the same information, but in A, is GiD the one who assigns the ids, meanwhile in B, it's the problemtype.
Anyway, I still thinking that MDPA should only be a full dump of GiD Groups information (nodes and elements)
Hi Javi, fist of all thx for expressing in detail what the problem is.
let me try to explain why optionA is no-go (from my point of view). Let's consider a submodelpart structure as follows
A
/ \
B1 B2
|
C1
let's now assume you add a given element with Id 1234 to model part C1 (which is submodelpart of B1 and of A)
when the kratos reads element 1234, it walks upwards the tree until the root is found. the element is thus added to A and then the corresponding pointer is added to B1 and C1. let's imagine that this pointer is 0x0.
If we now add "the same" element to B2, kratos would walk upwards the tree and construct a new element 1234 with a pointer (say) 0x1. The result of this second addition is that the pointers contained by the submodelparts would be A 0x1 (the second would delete the first) B1 0x0 B2 0x1 C1 0x0
thus "the same" element would actually correspond to two different instances of the object 0x0 and 0x1. Indeed the possibility exist of waliking recursively the tree to ensure that this is not happening. The cost of such walk is however VERY high, and we can not afford it in the reading loop. The Replace elements function actually does it.
In any case since this behaviour is unwanted (and really horrorful to debug) the choice was made to catch it when possible. This is done by throwing an error in case the ConstructNewCondition (or Node/Element) function detects that a new instance of "the same" object is being created.
A different problem which i foresee is that one may want to generate a "node" element for example just on the node1 and not on any of the others. This is needed to add for example a concentrated mass on that node or a point force.
As a final comment i believe that the Kratos input is as of now (relatively) sane in design and I do not think we should change the design basing on the peculiarities of the GiD, since i guess that any preprocessor will have its own ones.
Rather i more and more think that we should read geometries (i mean elements) and generate ourselves the nodes, elements, etc on the basis of the knowledge of the geometries. Such geometries should of course be cathegorized in "groups". This of course can not be a patch... but i guess is the only real way forward
just to mention @dbaumgaertner who was following the discussion
Thanks @RiccardoRossi , now I understand part of the problem.
So, if I understood it properly, the same physical entity, a face of a triangle, for example, will need 2 different Condition id if it is needed in 2 different submodelparts (B1 and B2) if they are not applying the same condition; but they can reuse the id if they are applying the same condition.
This is the kind of logic that makes the writing procedures slow, and overflow the tcl variables. 2 years ago, I asked about this to Mr. Donal Fellows, one of the tcl core team, when the former kratos problemtype couldn't write the MPDA of the largest model computed with Kratos (the BCN model) http://stackoverflow.com/questions/31314749/tcl-max-size-of-array
One of the problems was that the former problemtype used to store in arrays all the assigned Ids for conditions, instead of letting C++ structures in GiD the management of this information. This is why now we are using only iterators to write conditions, and we are not able to remember if a face has already a condition id assigned.
Sorry, this message gives no solutions, only brings some light to the problem
Hi Javi, No, what se need (for fluid, structure is different) is to construct the conditions with a given id only once, as you are doing in b
Then un the submodelparts you only assign the id (so that the pointer Will be recovered and Will be the same across all modelparts)
An important feature os that Kratos ALSO allows to assign two conditions yo the same triangles. The use case here is to have say a point Mass and a point forcé on the same node.
Such usage is however not viable for the fluid, where se need boundary faces not to be superimposed (It vives hice troubles at the momento of cómputo global boundary integrales)
I have been looking into the code,
and maybe a possible workaround to relieve the problem i was describing is to add some extra logic to the CreateNewConditon function:
what we could do is that if:
- the condition already exists
- the connectivity of the new one is identical to the old one
- the type of condition is the same
then i could give back the existing pointer and do nothing more. The CreateNewNode function is currently doing something similar in the case a new node is being create with the same Id and exactly at the same position.
I don't love this solution, but we may decide to allow such behaviour. @KratosMultiphysics/technical-committee what do you guys think about this?
still i think what we can do right now is only a patch. I'll open a different discussion issue about how to solve once for good this problem.
I agree with the mechanism of check if exist and is equal as described by @RiccardoRossi. However I'mlly I'm not sure if we should put this mechanism in ModelPartIO or in ModelPart.CreateNewCondition?
