Applying boundary condition to large number of nodes
Applying boundary condition to large number of nodes
Hi!
I've recently started using Elmer, and so far I'm impressed with the capabilities of the software. I'm planning to use ElmerGrid and ElmerSolver for 3D linearly elastic mechanical problems. I'm writing a Python code, with the goal of optimizing parameters in CAD files with respect to stresses, as part of my master's thesis. I use GMSH as mesher.
I've successfully managed to run some simple analyses, where I've used the Boundary Condition sections in the .siffile to fix certains boundaries (keyword Target Boundaries) or nodes (keyword Target Nodes), and apply a force to other places. My goal is to be able to set forces and lock nodes in certain regions, e.g. lock (displacement=0) all nodes where x^2+y^2+z^2>r_1 and apply zforce to all nodes x^2+y^2+z^2<r_2.
My first thought was to use conditions in the .siffile, with MATCexpressions. However, as far as I understand you still have to specify which nodes/boundaries that the condition is tested for through the "Target Nodes/Boundaries" keywords, and it's not possible to list the same node in several boundary conditions, so I can't just set all nodes as target nodes in every Boundary Conditionsection, and let the MATCexpression do the actual sorting. So instead I went for finding the numbers of the nodes that satisfy my condition in my Python code, by collecting node numbers and coordinates and doing some math on them. However, I don't get the results that I expect. If I lock 284 nodes on the outer perimeter of my mesh, it works as expected. If I then lock one more node, which also is on the outer perimeter and therefore more or less undeformed in the previous case, I get a completely different result.
I attach pictures where both the results are shown, and the additional node is shown with its number (visualized with ParaView). The pink shape is undeformed, and the grey is deformed. I also attach the .siffile, where the first Boundary Condition contains two Target Nodeskeywords, one commented out which creates the working result, and the noncommented gives the weird result.
I've considered the possibility that the node numbering system gets changed somehow along the way. But it seems unreasonable that the node numbering in the .vtu result file that I view in ParaView (and there I can search for specific nodes using "Find Data") is different from the one I set in the .siffile. So now I'm leaning towards there being some sort of limitation on how many nodes one can set as Target Nodes. I've tried splitting the BC into several Boundary Condition sections to no avail.
I've recently started using Elmer, and so far I'm impressed with the capabilities of the software. I'm planning to use ElmerGrid and ElmerSolver for 3D linearly elastic mechanical problems. I'm writing a Python code, with the goal of optimizing parameters in CAD files with respect to stresses, as part of my master's thesis. I use GMSH as mesher.
I've successfully managed to run some simple analyses, where I've used the Boundary Condition sections in the .siffile to fix certains boundaries (keyword Target Boundaries) or nodes (keyword Target Nodes), and apply a force to other places. My goal is to be able to set forces and lock nodes in certain regions, e.g. lock (displacement=0) all nodes where x^2+y^2+z^2>r_1 and apply zforce to all nodes x^2+y^2+z^2<r_2.
My first thought was to use conditions in the .siffile, with MATCexpressions. However, as far as I understand you still have to specify which nodes/boundaries that the condition is tested for through the "Target Nodes/Boundaries" keywords, and it's not possible to list the same node in several boundary conditions, so I can't just set all nodes as target nodes in every Boundary Conditionsection, and let the MATCexpression do the actual sorting. So instead I went for finding the numbers of the nodes that satisfy my condition in my Python code, by collecting node numbers and coordinates and doing some math on them. However, I don't get the results that I expect. If I lock 284 nodes on the outer perimeter of my mesh, it works as expected. If I then lock one more node, which also is on the outer perimeter and therefore more or less undeformed in the previous case, I get a completely different result.
I attach pictures where both the results are shown, and the additional node is shown with its number (visualized with ParaView). The pink shape is undeformed, and the grey is deformed. I also attach the .siffile, where the first Boundary Condition contains two Target Nodeskeywords, one commented out which creates the working result, and the noncommented gives the weird result.
I've considered the possibility that the node numbering system gets changed somehow along the way. But it seems unreasonable that the node numbering in the .vtu result file that I view in ParaView (and there I can search for specific nodes using "Find Data") is different from the one I set in the .siffile. So now I'm leaning towards there being some sort of limitation on how many nodes one can set as Target Nodes. I've tried splitting the BC into several Boundary Condition sections to no avail.
 Attachments

 notworking.png
 (99.04 KiB) Not downloaded yet

 working.png
 (103.02 KiB) Not downloaded yet

 201935_14512.sif
 (3.99 KiB) Downloaded 30 times

 Site Admin
 Posts: 3448
 Joined: 22 Aug 2009, 11:57
 Antispam: Yes
 Location: Espoo, Finland
 Contact:
Re: Applying boundary condition to large number of nodes
Hi
You can set the displacements & related condition whether to apply them in BCs or body forces, for example
This is a little cumbersome and certainly not the fastest as MATC is very slow but at least quite easy to use.
This uses the generic feature of any Dirichlet condition that if we set "Varname = a" it is only applied if in "Varname Condition = b", b > 0.
Peter
You can set the displacements & related condition whether to apply them in BCs or body forces, for example
Code: Select all
Boundary Condition 1
Name = "MoveSphere"
Target Boundaries(1) = 1
Displacement 1 = 0.0
Displacement 2 = 0.0
Displacement 3 = 1.0
$r = 1.0
Displacement 1 Condition = Variable "Coordinate"
Real MATC "r^2tx(0)^2tx(1)^2tx(2)^2"
Displacement 2 Condition = Variable "Coordinate"
Real MATC "r^2tx(0)^2tx(1)^2tx(2)^2"
Displacement 3 Condition = Variable "Coordinate"
Real MATC "r^2tx(0)^2tx(1)^2tx(2)^2"
End
This is a little cumbersome and certainly not the fastest as MATC is very slow but at least quite easy to use.
This uses the generic feature of any Dirichlet condition that if we set "Varname = a" it is only applied if in "Varname Condition = b", b > 0.
Peter
Re: Applying boundary condition to large number of nodes
Hi and thanks for the reply!
I did try using MATC expressions, but the problem with that for my application seems to be that I still have to specify which boundaries the BC will (conditionally) apply to. I want to set several boundary conditions, and it doesn't seem allowed to list the same boundary in two different Boundary Condition sections, so I can't just set all boundaries in my mesh as target boundaries for all BCs. So I have to know which boundaries pertain to which region in my model, which I don't see any simpler solution to than to parse the ELMER mesh boundary file and use the nodal coordinate data and let my Python code sort out the boundaries with the right coordinates, but then I wouldn't need the MATC sorting anyway.
I did try using MATC expressions, but the problem with that for my application seems to be that I still have to specify which boundaries the BC will (conditionally) apply to. I want to set several boundary conditions, and it doesn't seem allowed to list the same boundary in two different Boundary Condition sections, so I can't just set all boundaries in my mesh as target boundaries for all BCs. So I have to know which boundaries pertain to which region in my model, which I don't see any simpler solution to than to parse the ELMER mesh boundary file and use the nodal coordinate data and let my Python code sort out the boundaries with the right coordinates, but then I wouldn't need the MATC sorting anyway.

 Site Admin
 Posts: 3448
 Joined: 22 Aug 2009, 11:57
 Antispam: Yes
 Location: Espoo, Finland
 Contact:
Re: Applying boundary condition to large number of nodes
Hi
You could use the "Body Force" section as well if you want to fix all the nodes in some region.
Also you could use "Defaul Target" that sets all boundaries not otherwise set as follows:
Peter
You could use the "Body Force" section as well if you want to fix all the nodes in some region.
Also you could use "Defaul Target" that sets all boundaries not otherwise set as follows:
Code: Select all
Boundary Condition 1
Name = "fixed"
Target Boundaries(1) = 1
Displacement 1 = 0.0
Displacement 2 = 0.0
Displacement 3 = 1.0
End
Boundary Condition 2
Name = "MoveSphere"
Default Target = Logical True
Displacement 1 = 0.0
Displacement 2 = 0.0
Displacement 3 = 1.0
$r = 1.0
Displacement 1 Condition = Variable "Coordinate"
Real MATC "r^2tx(0)^2tx(1)^2tx(2)^2"
Displacement 2 Condition = Variable "Coordinate"
Real MATC "r^2tx(0)^2tx(1)^2tx(2)^2"
Displacement 3 Condition = Variable "Coordinate"
Real MATC "r^2tx(0)^2tx(1)^2tx(2)^2"
End
Re: Applying boundary condition to large number of nodes
Hi again,
Thanks for your help! I was not aware that displacements also could be set in the Body Force section. It works well when I set my displacement condition there. However, I can't get the force I want to apply to the center of my geometry to work as a Body Force, if I move that force from Boundary Condition to Body Force I get a solution that's trivially zero everywhere.
This is the definition of the force, that I've put in either Body Force or Boundary Conditionsections:
I've tried putting it in the same Body Forcesection as I set the displacement in, and also to put it in a separate Body Forcesection, and setting
in the Bodysection. I also tried separating 1 and 2 with a comma, with no change in results.
Another quick question referring back to my original post: Is there a limitation to the number of nodes that one can set as "Target Nodes" in the BCsection, so that option is out of the question?
I much appreciate your kind help, I wouldn't have been able to get this far without all the information on this forum
Thanks for your help! I was not aware that displacements also could be set in the Body Force section. It works well when I set my displacement condition there. However, I can't get the force I want to apply to the center of my geometry to work as a Body Force, if I move that force from Boundary Condition to Body Force I get a solution that's trivially zero everywhere.
This is the definition of the force, that I've put in either Body Force or Boundary Conditionsections:
Code: Select all
Force 3 = Real 100000000000
Force 3 Condition = Variable Coorinate 1, Coordinate 2
Real MATC "(tx(0)*tx(0)+tx(1)*tx(1))+0.000004" !innerradie på fjäder = 0.00125, låst radie < 0.002, 0.002^2 = 0.000004
Code: Select all
Body Force = 1 2
Another quick question referring back to my original post: Is there a limitation to the number of nodes that one can set as "Target Nodes" in the BCsection, so that option is out of the question?
I much appreciate your kind help, I wouldn't have been able to get this far without all the information on this forum

 Site Admin
 Posts: 3448
 Joined: 22 Aug 2009, 11:57
 Antispam: Yes
 Location: Espoo, Finland
 Contact:
Re: Applying boundary condition to large number of nodes
Hi
The Neumann conditions and Dirichlet conditions are quite different. In Dirichlet condition we directly set a value of the variable. You can generalize this quite easily from boundaries to bodies. The SI unit is m. Also the "condition" makes sense since it is either on or off.
The Neumann condition, on the other hand has unit N/m^2. The corresponding body force has unit N/m^3. Also it does not as much make sense to have a condition since you can as well multiply the force with a distribution function. When Neumann condition goes to zero then there is no condition. If Dirichlet condition goes to zero, it is still a Dirichlet condition.
Look at the documentation how to set body force in units of N/m^3. I would think its called "Stress Bodyforce 1" etc. or something like that.
Peter
The Neumann conditions and Dirichlet conditions are quite different. In Dirichlet condition we directly set a value of the variable. You can generalize this quite easily from boundaries to bodies. The SI unit is m. Also the "condition" makes sense since it is either on or off.
The Neumann condition, on the other hand has unit N/m^2. The corresponding body force has unit N/m^3. Also it does not as much make sense to have a condition since you can as well multiply the force with a distribution function. When Neumann condition goes to zero then there is no condition. If Dirichlet condition goes to zero, it is still a Dirichlet condition.
Look at the documentation how to set body force in units of N/m^3. I would think its called "Stress Bodyforce 1" etc. or something like that.
Peter
Re: Applying boundary condition to large number of nodes
Hi again and thanks for the reply!
I'm somewhat familiar with Neumann and Dirichlet conditions and the differences between them, but not knowledgeable enough to feel completely confident swimming around these waters. The ElmerSolver manual seems to indicate that the Boundary Conditionsection is for Dirichlet conditions, if looking at the explanation for the Boundary Condition section:
but obviously it's also possible to set forces in this section, which, to my understanding, is a Neumann type condition since I'm specifying a force, which is related to the derivative of the variable the solver is treating (displacement). My end goal is to apply a known net force, evenly distributed across a set of nodes. Now I'm leaning towards reading the mesh.boundaryfile and finding the boundary numbers of the boundaries containing my node set. But then I have (at least ) one more question: if I set a force on a specified Target Boundary, like:
does this mean that I set a force of 1 N (I use SI units for everything) on every node in boundary 48, or a force of 1/(# of nodes in boundary) N on every node?
I'm somewhat familiar with Neumann and Dirichlet conditions and the differences between them, but not knowledgeable enough to feel completely confident swimming around these waters. The ElmerSolver manual seems to indicate that the Boundary Conditionsection is for Dirichlet conditions, if looking at the explanation for the Boundary Condition section:
Code: Select all
Boundary Condition bc id
Target Boundaries(n) Integer
The set of boundaries on which the Dirichlet conditions will be applied
Code: Select all
Boundary Condition 1
Target Boundaries(1) = 48
Force 3 = 1
End

 Site Admin
 Posts: 3448
 Joined: 22 Aug 2009, 11:57
 Antispam: Yes
 Location: Espoo, Finland
 Contact:
Re: Applying boundary condition to large number of nodes
Hi
The Dirichlet conditions is always done by library subroutines and hence is explained in the ElmerSolver manual.
The Neumann conditions are module specific and are explained in Elmer Models Manual under the correct module.
Peter
The Dirichlet conditions is always done by library subroutines and hence is explained in the ElmerSolver manual.
The Neumann conditions are module specific and are explained in Elmer Models Manual under the correct module.
Peter
Re: Applying boundary condition to large number of nodes
Hi and thanks for your answer!
To answer my own question about force setting,
results in a force of 1 N/m^2 on boundary 48 (if one has been using SI units in the model). Adding the keyword
gives a net force of 1 N on the boundary, as I wished.
I ended up parsing the boundary file to find boundary numbers from node numbers. If anyone ever would have the same need, here's my Python code for doing so. Given a set of nodes (object type 'list'), it finds boundaries whose nodes are all in the node set. So the nodeset can include more nodes than only those in the boundaries one wishes to find, but not less.
To answer my own question about force setting,
Code: Select all
Boundary Condition 1
Target Boundaries(1) = 48
Force 3 = 1
End
Code: Select all
Force 3 Normalize by Area = Logical True
I ended up parsing the boundary file to find boundary numbers from node numbers. If anyone ever would have the same need, here's my Python code for doing so. Given a set of nodes (object type 'list'), it finds boundaries whose nodes are all in the node set. So the nodeset can include more nodes than only those in the boundaries one wishes to find, but not less.
Code: Select all
def findElmerBoundary(self, nodes):
# finds the boundary index(ices) of the boundaries that only have node numbers contained within input argument nodes
if not self.elmerMeshPath:
print('Error: Elmer mesh path must be created before finding Elmer boundaries. Run convertToElmerMesh or add path to valid Elmer mesh')
return
allBndrs = set() # gonna be filled with all boundary indices in mesh
notBndrs = set() # gonna be filled with those boundary indices that have nodes NOT in inputarg nodes
f = open(self.elmerMeshPath+'\\mesh.boundary', 'r')
for line in f:
entries = line.split(' ')
if int(entries[4]) == 303: # just for safety, only 2D linear triangle elements are observed
allBndrs.add(int(entries[1]))
if not ((int(entries[5]) in nodes) and (int(entries[6]) in nodes) and (int(entries[7]) in nodes)):
# if any of the nodes in this element are NOT in inputarg nodes, add it to notBndrs
notBndrs.add(int(entries[1]))
else:
print('warning: boundary element of type that is not 2D triangle found')
f.close()
foundBndrs = allBndrs.difference(notBndrs)
self.allBndrs = allBndrs
self.notBndrs = notBndrs
return foundBndrs