gtsPFacet

Asked by Lei Hang on 2020-07-20

Dear all,
     I'm try to study how to create a PFacet with the "yade.gridpfacet.gtsPFacet" function. When I run the example in yade, it appears some errors. The script of the example is as follows,
#
from yade import qt
from yade.gridpfacet import *
import gts, os.path, locale

locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') # Note: gts is locale-dependent. If, for example, german locale is used, gts.read()-function does not import floats normally

'''
if you get "Error: unsupported locale setting"
-> type as root: "dpkg-reconfigure locales"
-> choose "en_US.UTF-8" (press space to choose)
'''

################
### ENGINES ###
################

O.engines=[
 ForceResetter(),
 InsertionSortCollider([
  Bo1_Wall_Aabb(),
  Bo1_PFacet_Aabb(),
 ],sortThenCollide=True),
 InteractionLoop(
 [
        Ig2_GridNode_GridNode_GridNodeGeom6D(),
  Ig2_Wall_PFacet_ScGeom(),Ig2_Wall_Sphere_ScGeom()
 ],
 [
        Ip2_CohFrictMat_CohFrictMat_CohFrictPhys(setCohesionNow=True,setCohesionOnNewContacts=True),
  Ip2_FrictMat_FrictMat_FrictPhys()],
 [
        Law2_ScGeom6D_CohFrictPhys_CohesionMoment(),
  Law2_ScGeom_FrictPhys_CundallStrack(),
  Law2_ScGridCoGeom_FrictPhys_CundallStrack(),
  Law2_GridCoGridCoGeom_FrictPhys_CundallStrack()
 ]),
    GlobalStiffnessTimeStepper(timestepSafetyCoefficient=0.5,label='ts'),
 NewtonIntegrator(gravity=(0,-9.81,0),damping=0.1,label='newton')
]

#################
### MATERIAL ###
#################

O.materials.append(CohFrictMat(young=1e8,poisson=0.3,density=2650,frictionAngle=radians(20),normalCohesion=1e100,shearCohesion=1e100,momentRotationLaw=True,label='gridNodeMat'))
O.materials.append(FrictMat(young=1e8,poisson=0.3,density=2650,frictionAngle=radians(20),label='pFacetMat'))

###################
### IMPORT MESH ###
###################
radius=1e-02
wire=False
fixed=False

z=-1.2
color=[0,0,1]

nodesIds0,cylIds0,pfIds0 = gtsPFacet('octahedron.gts',shift=(0,0,0),scale=1.,radius=radius,wire=wire,fixed=fixed,materialNodes='gridNodeMat',material='pFacetMat',color=color)

nodesIds1,cylIds1,pfIds1 = gtsPFacet('box.gts',shift=(3.,0.,0.),scale=2,radius=radius,wire=wire,fixed=fixed,materialNodes='gridNodeMat',material='pFacetMat',color=color)

nodesIds2,cylIds2,pfIds2 = gtsPFacet('sphere.gts',shift=(6.,0.,0.),scale=1.0,radius=radius,wire=wire,fixed=fixed,materialNodes='gridNodeMat',material='pFacetMat',color=color)

#####################
##### Wall ###
#####################

O.bodies.append(utils.wall(position=z,sense=0, axis=1,color=Vector3(1,0,0),material='pFacetMat'))

##########
## VIEW ##
##########

qt.Controller()
qtv = qt.View()
qtr = qt.Renderer()
qtr.light2=True
qtr.lightPos=Vector3(1200,1500,500)
qtr.bgColor=[1,1,1]
qtv.ortho=True

O.saveTmp()
#
I copy the script into yade and run it, the errors appear:
#
Traceback (most recent call last):
  File "/usr/bin/yade", line 336, in runScript
    execfile(script,globals())
  File "/usr/lib/python3/dist-packages/past/builtins/misc.py", line 87, in execfile
    exec_(code, myglobals, mylocals)
  File "718.py", line 60, in <module>
    nodesIds0,cylIds0,pfIds0 = gtsPFacet('octahedron.gts',shift=(0,0,0),scale=1.,radius=radius,wire=wire,fixed=fixed,materialNodes='gridNodeMat',material='pFacetMat',color=color)
  File "/usr/lib/x86_64-linux-gnu/yade/py/yade/gridpfacet.py", line 382, in gtsPFacet
    surf=gts.read(open(meshfile))
FileNotFoundError: [Errno 2] No such file or directory: 'octahedron.gts'
#

It reminds me there is no 'octahedron.gts' file.But I don't know how to create this kind files. If there is anybody knowing about this, could you teach me how to create the gts files and show me an example?

Many thanks!

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Lei Hang
Solved:
2020-07-23
Last query:
2020-07-23
Last reply:
2020-07-23

This question was reopened

Jan Stránský (honzik) said : #1

> When I run the example in yade

next time please provide more info (where the example comes from, link, ...)

> It reminds me there is no 'octahedron.gts' file

In such case, run the example from original location [1], where the file is placed [2]

cheers
Jan

[1] https://gitlab.com/yade-dev/trunk/-/tree/master/examples/pfacet
[2] https://gitlab.com/yade-dev/trunk/-/blob/master/examples/pfacet/octahedron.gts

Lei Hang (h-stone) said : #2

Sorry, the link of the script is https://gitlab.com/yade-dev/trunk/blob/master/examples/pfacet/gts-pfacet.py.
Thank you so much!

Anther question is how to create a gts file? I don't understand the numbers in the 'octahedron.gts' file[1]. My final objective is to use this method to create a cylinder to simulate the membrane in the triaxial test. So understanding the meanings of numbers in the the 'octahedron.gts' file[1] maybe can help me know how to create a cylinder.gts file.

Thanks again!

 [1]https://gitlab.com/yade-dev/trunk/-/blob/master/examples/pfacet/octahedron.gts

Jan Stránský (honzik) said : #3

> I don't understand the numbers in the 'octahedron.gts' file

reverse engineering:

> 258 768 512
258 vertices, each line given the coordinates
768 edges, each line indices of connected vertices
512 faces, each line indices of face-forming edges

Example of "bi-tetrahedron":
###
5 9 6
0 0 -1
1 0 0
-1 -1 0
-1 1 0
0 0 2
1 2
1 3
1 4
2 3
3 4
4 2
2 5
3 5
4 5
1 4 2
2 5 3
3 6 1
4 7 8
5 8 9
6 9 7
###

test in yade:
###
import gts
from yade import pack
with open("test.gts") as f:
 surf = gts.read(f)
print(surf.is_closed(),surf.is_ok(),surf.is_orientable())
O.bodies.append(pack.gtsSurface2Facets(surf,wire=False))
###

cheers
Jan

Lei Hang (h-stone) said : #4

Hello Jan,

Thank you for your answers! After your explanation, I understand the meanings of the numbers.

1.According to your script, I just mark the vertices and lines by myself and change the indices of lines and faces based on my order. But I am failed to create the same "bi-tetrahedron" as you shown to me. So, is there any rules for creating the "vertices"and the indices of "edges" and "faces"?

2. For the simple geometry, we can create the coordinates of the vertices, the indices of the lines and faces by ourselves. But for complex geometry, it maybe have too many "vertices","edges" and "faces", such as the 'octahedron.gts' file. It has 258 vertices,768 edges and 512 faces. Do we have to write the coordinates of the vertices, the indices of the lines and faces by ourselves? Is there any methods to create them?

Thanks!

The modified numbers are as follows,
###
5 9 6
0 0 -1
1 0 0
-1 -1 0
-1 1 0
0 0 2
1 2
1 3
1 4
2 3
2 4
3 4
2 5
3 5
4 5
1 2 5
1 3 4
2 3 6
5 7 8
4 7 9
6 8 9
###

Jan Stránský (honzik) said : #5

1)
of course there are rules :-)
specifically for faces (where is your problem), the numbers are indices of edges, in counter-clockwise order (seen from the resulting normal direction).
In your case, your first face is
> 1 2 5
your 1st, 2nd and 5th edges are
> 1 2
> 1 3
> 2 4
I.e. you tell gts to create triangle from vertices number 1, 2, 3 and 4, which is the problem.

2)
there are plenty of options.

First, you need the vertices and triangles:
- "by hand" (like the simple example)
- programatically "by hand", e.g. cylinder should be ok to triangulate "manually"
- using some external meshing software
- from existing file (e.g. from STL file format you can convert to GTS using stl2gts utility from libgts-bin Ubuntu package)

Once having the data, you can:
- create the gts file "by hand"
- create the file programatically by yourself
- create the gts structure using gts.Vertex, gts.Edge, gts.Surface and finally gts.Surface.write method [3]
- save it to another format and convert it to gts (e.g. stl2gts)

cheers
Jan

[3] https://woodem.org/woo.gts.html

Lei Hang (h-stone) said : #6

 I am so sorry, Jan. I don't fully understand these methods you taught me.
Could you show me an example to create a cylinder gts file by the two steps as you taught me?
First step: Getting the vertices and triangles through this method (programatically "by hand", e.g. cylinder should be ok to triangulate "manually")
Second step: Creating the cylinder gts file "by hand" or "programatically by yourself"

I will simulate your process and further understand it.

Very grateful to you!

Jan Stránský (honzik) said : #7

###
import gts
center = (0,0,0)
radius = 1
height = 2

# triangles as yade facets, can be anything else, e.g. custom class
facets = geom.facetCylinder(center,radius,height)

# yade facet to gts.Face
def f2f(f):
    p = f.state.pos
    o = f.state.ori
    vs = [p+o*v for v in f.shape.vertices] # vertices in global coordinates
    vs = [gts.Vertex(v[0],v[1],v[2]) for v in vs] # Vector3 -> gts.Vertex
    es = [gts.Edge(v,vs[(i+1)%3]) for i,v in enumerate(vs)] # gts edges
    f = gts.Face(*es) # gts Face
    return f
faces = [f2f(f) for f in facets]

# gts Surface
surf = gts.Surface()
for f in faces: # filled with faces
    surf.add(f)
print(surf.is_ok(),surf.is_closed(),surf.is_orientable())
surf.cleanup(1e-6) # needs cleanup to merge "almost same vertices"
print(surf.is_ok(),surf.is_closed(),surf.is_orientable())

# save
with open("cyl.gts","w") as f:
    surf.write(f)
###

cheers
Jan

Lei Hang (h-stone) said : #8

Thank you for your time and effort!

Lei Hang (h-stone) said : #9

Hi Jan,

After I use yade to run the script you gave me. Why it create an empty cyl.gts file? The running information is as follows:
#
l@ubuntu:~/yade$ yade cyl.py
Welcome to Yade 2020.01a
Using python version: 3.8.2 (default, Apr 27 2020, 15:53:34)
[GCC 9.3.0]
TCP python prompt on localhost:9000, auth cookie `ykcuas'
XMLRPC info provider on http://localhost:21000
Running script cyl.py
True False True
True True True
[[ ^L clears screen, ^U kills line. F12 controller, F11 3D view (press "h" in 3D view for help), F10 both, F9 generator, F8 plot. ]]
#
Thanks!

Jan Stránský (honzik) said : #10

I have no idea, tested with 2018.02b and 2020-06-23.git-f03a37c and works as expected - creates cyl.gts file full of numbers..
cheers
Jan

Lei Hang (h-stone) said : #11

OK, Thanks a lot!