Have difficulty to create a cylinder with inlets

@karl

Hey Karl, sorry for posting a question again, I am trying to switch from GMSH to here. Now I am creating a big cylinder with two inlets (empty inside the cylinder, each of inlets is formed by two frustums which are stacked tightly, namely, the top r of frustum 1 is the same as the bottom r of the frustum 2, )

  1. So I first create the cylinder, assume it is volume 1, and then create two frustums (volume 2 and 3), the two frustums are moved to be stacked tightly, and then I subtract them from volume 1

  2. Do the same for another two frustums (volumes 4 and 5).

  3. Then do the local grid refine around the empty part of the cylinder, namely, the subtracted four frustums

But the error happened on my first definition, can you please help me make this .jou work, thank you so much!

reset
# Create main cylinder
create cylinder height 12 radius 0.75
# Let's assume this is volume 1 in Cubit

# Create first frustum/cone on the left side and subtract it from the main cylinder
create frustum height 1.5 radius 0.06 top 0.0569
# Move the frustum to its desired location
volume 2 move x -0.26
# Subtract frustum from cylinder
subtract volume 2 from volume 1
delete volume 2
# The result is still referred to as volume 1

# Create second smaller frustum/cone on top of the first on the left side
create frustum height 0.1 radius 0.0569 top 0.0139
# Move the frustum to its desired location
volume 3 move x -0.26 z 1.5
# Subtract this frustum from the main cylinder
subtract volume 3 from volume 1
delete volume 3
# The result is still referred to as volume 1

# Create third frustum/cone on the right side and subtract it from the main cylinder
create frustum height 1.55 radius 0.06 top 0.0569
# Move the frustum to its desired location
volume 4 move x 0.26
# Subtract frustum from cylinder
subtract volume 4 from volume 1
delete volume 4
# The result is still referred to as volume 1

# Create fourth smaller frustum/cone on top of the third on the right side
create frustum height 0.1 radius 0.0569 top 0.0139
# Move the frustum to its desired location
volume 5 move x 0.26 z 1.55
# Subtract this frustum from the main cylinder
subtract volume 5 from volume 1
delete volume 5
# The result is still referred to as volume 1

# Meshing with tetrahedra
mesh volume 1
Refine Tet all_of Volume 2 3 4 5 Size 0.025 Bias 1.5 Depth 2 Smooth

Thank you!

From a geometry standpoint, is this what you’re expecting?

Yes sir, but I expect the two inlets are located at the bottom of the big cylinder, namely the XOY plane, and +z is the height
I thought the reference point is the XOY, so I only move along XOY
Sorry, I forgot the factor u

# Define the scaling factor
set u = 0.0254

# Create main cylinder
create cylinder height 12*u radius 0.75*u
# Let's assume this is volume 1 in Cubit

# Create first frustum/cone on the left side and subtract it from the main cylinder
create frustum height 1.5*u radius 0.06*u top 0.0569*u
# Move the frustum to its desired location
volume 2 move x -0.26*u
# Subtract frustum from cylinder
subtract volume 2 from volume 1
delete volume 2
# The result is still referred to as volume 1

# Create second smaller frustum/cone on top of the first on the left side
create frustum height 0.1*u radius 0.0569*u top 0.0139*u
# Move the frustum to its desired location
volume 3 move x -0.26*u z 1.5*u
# Subtract this frustum from the main cylinder
subtract volume 3 from volume 1
delete volume 3
# The result is still referred to as volume 1

# Create third frustum/cone on the right side and subtract it from the main cylinder
create frustum height 1.55*u radius 0.06*u top 0.0569*u
# Move the frustum to its desired location
volume 4 move x 0.26*u
# Subtract frustum from cylinder
subtract volume 4 from volume 1
delete volume 4
# The result is still referred to as volume 1

# Create fourth smaller frustum/cone on top of the third on the right side
create frustum height 0.1*u radius 0.0569*u top 0.0139*u
# Move the frustum to its desired location
volume 5 move x 0.26*u z 1.55*u
# Subtract this frustum from the main cylinder
subtract volume 5 from volume 1
delete volume 5
# The result is still referred to as volume 1

# Meshing with tetrahedra
mesh volume 1
Refine Tet all_of Volume 2 3 4 5 Size 0.025 Bias 1.5 Depth 2 Smooth

image

Ok - thanks for the clarification. Let me summarize a few things that should hopefully clear things up for you:

Entity ids

Many geometry commands in Cubit use the concept of tool and target – those commands often allow you to keep the tools or targets and so, to respect their entity ids the new geometry is given a new id appended to the entity id list. For example, the below command will create a hollow sphere with a volume id of 3:

resest
sphere r 1
sphere r 2
subtract vol 1 from vol 2 # Creates hollow sphere of id=3
## If instead executed:
# subtract volume 1 from volume 2 keep_tool
## Then volume 1 (the inner core) would be left, as well as the hollow sphere (volume 3)

So when you’re subtracting volumes in your original script, volume 1 no longer exists after the first subtraction

Origin of primitives

When creating primitives in Cubit they are centered on the origin. You need to take this into account when moving them to align with other entities.

Math in Cubit

One simple way to do math in Cubit is to use the Python API, which I’ll talk about in another section. But within the Cubit Command Language (CCL) you need to use the APREPRO markup. APREPRO is an algebraic preprocessor developed by Sandia National Labs as part of their SEACAS project, the project that owns the Exodus finite element mesh format around which Cubit was developed. I’ll leave you to read the manual for the full details, but here’s how you might do some of the math from your script. Note that the format for declaring a variable looks like a comment in that it has the form #{varName=varValue}

# Define the scaling factor
#{u = 0.0254}

# Create main cylinder, referencing the scaling factor
create cylinder height {12*u} radius {0.75*u}

Python in Cubit

Alternatively, you could use the Python API and Python’s “f-strings”. Every CCL command can be consumed by the cubit.cmd() method when passed as a string. For example, the previous code block would be:

# Define the scaling factor
u = 0.0254

# Create main cylinder, referencing the scaling factor
cubit.cmd( f"create cylinder height {12*u} radius {0.75*u}" )

Updated script

Here’s the journal file, written in CCL, that creates the geometry. Review this and let me know if that looks good to you… then we can move on to talking about meshing:

reset

# Define the scaling factor
#{u = 0.0254}

# Create main cylinder
create cylinder height {12*u} radius {0.75*u}
volume 1 move z {12/2 * u}

# Create cavity volumes
create frustum height {1.5*u}  radius {0.06*u}   top {0.0569*u}
create frustum height {0.1*u}  radius {0.0569*u} top {0.0139*u}
create frustum height {1.55*u} radius {0.06*u}   top {0.0569*u}
create frustum height {0.1*u}  radius {0.0569*u} top {0.0139*u}

volume 2 move x {-0.26*u}
volume 3 move x {-0.26*u} z {(1.5/2 + 0.1/2)*u}
volume 4 move x {0.26*u}
volume 5 move x {0.26*u}  z {(1.55/2 + 0.1/2)*u}

# Subtract cavity volumes from main cylinder
subtract vol 2 3 4 5 from volume 1

# Compress entity id numbering
compress ids

Thank you so much, sir @gvernon , it looks good. I actually don’t have access to Python due to some reasons, so it will be great if the .jou can figure my problem. Just a few more things, and all done

  1. I see this, is commented, but this factor is important, can I just simply uncomment it, right?
# Define the scaling factor
{u = 0.0254}
  1. For mesh (tetra), I need LGR around these frustum

  2. For future simulation purposes
    I gave nodeset to surfaces 3 and 4 and renamed it as bb
    I gave nodeset to surfaces 6 and 7 and renamed it as ss
    I gave nodeset to surface 4 and renamed it as pp
    Nodeset 1 Add Surface 3 4

Nodeset 1 Add Surface 3 4
nodeset 1 name "bb"

Nodeset 2 Add Surface 6 7
nodeset 2 name "ss"

Nodeset 3 Add Surface 4
# Name the nodeset as "pp"

but they are not shown in the GUI after I run the .jou, am I assigned them well?
image

  1. Actually this is the part that makes me move from GMSH, so my goal is to able to create a mesh distinct around a surface (like z:11*u) because I need to later in another script to find the elements whose Z are bigger than the surface. So the mesh must be back-to-back
    image
    look like this

I don’t know how to do this properly in Cubit, maybe add another clinder, or, like in GMSH, use fragments, but this surface must not affect the connection, which means cannot create discontinuity in the cylinder

Nope, leave it as a Cubit comment – the APREPRO is still evaluated but doesn’t issue a Cubit command. If you don’t comment it, Cubit will try to run a CCL command that will result in a syntax error:

Cubit>{t=5}
ERROR: Missing keyword in command.
       Command can not begin with a number
ERROR: syntax error
ERROR: Missing keyword in command.
       Command can not begin with a number
ERROR: syntax error

vs.

Cubit>#{v=5}  # No syntax errors from Cubit, APREPRO sets 'v' equal to 5

See the documentation for more information.

Regarding Python

You actually do have Python as we ship Python with Cubit and it can be accessed within the GUI. Note the Python tab in the command line widget:

And you can quickly convert a journal file into a Python script in the journal editor by clicking the Python icon:

Before:

After:

Of course we’d need to come through and modify many of those to use f-strings, and we’d want to convert line 2 from an APREPRO command to a standard Python assignment:

After cleanup:

Nodesets

They appear in the model tree under the Node Sets object:
image

I don’t know what your specific needs are, but note that you may wish to use sideset instead of nodeset if your code requires surface information (e.g., to compute a flux over the surface)

Volume splitting

You can use a webcut and then merge the two volumes back together:

webcut volume 1 with plane zplane offset {1*0.0254}
merge volume 1 2

Updated journal file

reset

# Define the scaling factor
#{u = 0.0254}

# Create main cylinder
create cylinder height {12*u} radius {0.75*u}
volume 1 move z {12/2 * u}

# Create cavity volumes
create frustum height {1.5*u}  radius {0.06*u}   top {0.0569*u}
create frustum height {0.1*u}  radius {0.0569*u} top {0.0139*u}
create frustum height {1.55*u} radius {0.06*u}   top {0.0569*u}
create frustum height {0.1*u}  radius {0.0569*u} top {0.0139*u}

volume 2 move x {-0.26*u}
volume 3 move x {-0.26*u} z {(1.5/2 + 0.1/2)*u}
volume 4 move x {0.26*u}
volume 5 move x {0.26*u}  z {(1.55/2 + 0.1/2)*u}

# Subtract cavity volumes from main cylinder
subtract vol 2 3 4 5 from volume 1

# Compress entity id numbering
compress ids

# Assign sets
nodeset 1 add surface 3 4  
nodeset 1 name "bb"

nodeset 2 add surface 6 7  
nodeset 2 name "ss"

nodeset 3 add surface 4 
nodeset 3 name "pp"

# Create splitting surface
webcut volume 1 with plane zplane offset {1*0.0254} 
merge volume 1 2

# Create mesh
volume all size {0.1*u}
volume all scheme tetmesh
mesh volume all
1 Like

So for webcut and merge,

  1. I want to double-check (see) if they are meshed back to back along this surface, how can I check? I use
graphics mode transparent

but it is not what I want

  1. The webcut and merge won’t affect the connection in the future simulation right? There is no realy boundary, right?
draw surface with is_merged

draw tri in surface with is_merged

draw tet in tri in surface with is_merged


As long as the two volumes are assigned to the same block prior to export and you don’t assign a boundary condition to the surface, you should be good.

1 Like

A quick question, when I create the frustum, where is the reference point? the center point at lower circle or the center of the whole frustum?

At the center of the frustrum. We can verify this by:

reset
graphics axis type origin on
graphics mode transparent

#{u = 0.0254}
create frustum height {0.1*u}  radius {0.0569*u} top {0.0139*u}

1 Like

So how to change this in order to reduce the grid number, I already try 10*u, and it exceed the simulator maxium grid number, not 50000 of Cubit

# Create mesh
volume all size {0.1*u}
volume all scheme tetmesh
mesh volume all

Because the size is changed, I need to move the whole cone, not half of it

reset

# Define the scaling factor
#{u = 0.0254}

# Create main cylinder
create cylinder height {12.5*u} radius {0.75*u}
volume 1 move z {12.5/2 * u}

# Create cavity volumes
create frustum height {1.5*u}  radius {0.06*u}   top {0.0569*u}
create frustum height {0.1*u}  radius {0.0569*u} top {0.0139*u}
create frustum height {1.55*u} radius {0.06*u}   top {0.0569*u}
create frustum height {0.1*u}  radius {0.0569*u} top {0.0139*u}

volume 2 move x {-0.26*u} z {(1.5/2*u)}
volume 3 move x {-0.26*u} z {(1.5 + 0.1/2)*u}
volume 4 move x {0.26*u}  z {(1.55/2*u)}
volume 5 move x {0.26*u}  z {(1.55 + 0.1/2)*u}

# Subtract cavity volumes from main cylinder
subtract vol 2 3 4 5 from volume 1

# Compress entity id numbering
compress ids

# Assign sets
nodeset 1 add surface 3 4  
nodeset 1 name "bb"

nodeset 2 add surface 6 7  
nodeset 2 name "ss"

nodeset 3 add surface 4 
nodeset 3 name "pp"

block 1 add volume 1 2
block 1 name 'co'


# Create splitting surface
webcut volume 1 with plane zplane offset {12*0.0254} 
merge volume 1 2

# Create mesh
volume all size {0.1*u}
volume all scheme tetmesh
mesh volume all

#graphics mode transparent
#draw tet in tri in surface with is_merged

Which simulation code are you using? As you’ve seen Coreform Cubit Learn is limited to 50K elements for export, but you can request a trial license through our website that does not have any limits on export. But if you’re trying to, say, run a simulation in a solver that itself has limits on the number of elements or nodes there’s not much more you can do other than reduce the size of the geometry (shrink its length), use symmetry, etc., or use a different solver that doesn’t have the limitation.

1 Like

So, the solver is limited to 50000, now with 10*u, I have 56000 from Cubit, is there any way just to make it below 50000? Thank you!

One thing you can do is slightly change the “Deviation Angle” in the surface meshing settings for the tetmesher.

image

Here’s the command panel for the TetMesh scheme in Cubit, notice I’ve selected the Surfaces tab which shows me the deviation angle input.

The default angle is 15 degrees, but if I increase it to 16 degrees it results in a mesh with 49704 tets. Here are the Cubit commands that are issued by my choice:

volume all scheme tetmesh geometry approximation angle 16
mesh volume all

Hi @gvernon, I want to give nodeset to the part of my volume 4, so my idea is to break volume into two small (height 0.05 and 1.5) volumes, and then give the nodeset to the one with height of 1.5, please let me know if there is a better method, like directly assign by height

Does anyone have an idea about how to assign a set directly?

Is the geometry you’re talking about is still this one from the last script I provided:

Because note that the heights don’t seem to match the values you provided.

If this is the geometry (maybe just with different scaling) you do have several choices for assigning nodesets programmatically. Note that it’s not clear to me exactly what you want in the nodeset:

  1. Do you want every node in the yellow volume in the nodeset?
  2. Do you just want a specific surface of the yellow volume in the nodeset?
  3. Do you actually want a block (i.e., an element set)?

Options:

  1. If you know the volumes will be “stacked” and know the location (e.g., z=.3048) of their split:
nodeset 1 add volume with z_coord<0.3048
  1. You can do some more sophisticated checks using the Python API:
for vid in cubit.get_entities( "volume" ):
    # Useful queries
    cubit.get_bounding_box( "volume", vid ) # Returns list: [ xmin, xmax, xrange, ymin, ymax, yrange, zmin, zmax, zrange, diagonal_length ]
    cubit.volume(vid).volume() # Return scalar: volume
    cubit.volume(vid).center_point() # Return list: [center_x, center_y, center_z]
    cubit.volume(vid).centroid() # Return list: [centroid_x, centroid_y, centroid_z]

With those queries (or others from our Python API documentation), you should be able to create a pretty sophisticated identification routine, with which you could then assign your nodeset. Within Python I’d recommend doing this through the Python “f-string” functionality:

vid = get_large_cylinder() # a querying routine as discussed above
cubit.cmd( f"nodeset 1 volume {vid}" )

thank you so much, another question, is there a way to do the LGR around the YOZ plane?