Issues with BST shell elements

44 views
Skip to first unread message

Thomas Caleb

unread,
Apr 13, 2026, 10:09:50 AM (4 days ago) Apr 13
to ProjectChrono
Hi everyone,

First, thank you to the developers of Chrono — it is an excellent tool.

I am using PyChrono 10.0.0 for finite element simulations, but I observe the same behaviour in version 9.0.1. I am working with BST shell elements, and I have an issue where the mass of the element does not seem to be computed. The mesh mass is always 0 kg, and all nodes also have 0 kg mass. I do not have this problem with other elements (ANCF_3423 and EulerBeams), since the mass is accuratly computed.

Below is a minimal working example where a BST element is created. However, the resulting mesh still has zero mass.

I have a few questions:
  1. Is this expected behaviour? If so, how can it be fixed or avoided?
  2. In Python, there does not seem to be a way to cast a ChElementBase to a ChElementShellBST. Is there another method to do this?
Thank you for reading this.
Thomas

Minimal working example :

import pychrono as chrono
import pychrono.fea as fea

# Create system and mesh
sys = chrono.ChSystemSMC()
sys.SetGravitationalAcceleration(chrono.ChVector3d(0, 0, -10))
mesh = fea.ChMesh()
sys.Add(mesh)

# Material properties (aluminium)
young_modulus = 7e+7 # Pa
nu = 0.3 # Poisson's ratio
rho = 2700 # kg/m^3
thickness = 0.01 # m

# Create Kirchhoff material
elasticity_kirchhoff = fea.ChElasticityKirchhoffIsothropic(young_modulus, nu)
mat_kirchhoff = fea.ChMaterialShellKirchhoff(elasticity_kirchhoff)
mat_kirchhoff.SetDensity(rho)

# Make list of nodes
list_pos = [
    chrono.ChVector3d(0, 0, 0),
    chrono.ChVector3d(0, 1, 0),
    chrono.ChVector3d(1, 0, 0)]
nodes = []
for pos in list_pos:
    node = fea.ChNodeFEAxyz(pos)
    mesh.AddNode(node)
    nodes.append(node)

# Make element
el = fea.ChElementShellBST()
el.SetNodes(*nodes[:3], None, None, None)
el.AddLayer(thickness, 0 * chrono.CH_DEG_TO_RAD, mat_kirchhoff)
el.Update()
el.ComputeNodalMass()
mesh.AddElement(el)

# Compute mass of the elements and the mesh
sys.Update(True)
print(f"Element area: {el.area}")
print(f"Element density: {el.GetDensity()}")
print(f"Element thickness: {el.GetThickness()}")
print(f"Element expected mass: {el.GetThickness()*el.area*el.GetDensity()}")
print(f"Mesh = element mass: {mesh.ComputeMassProperties().mass}")
for i in range(3):
    print(f"Node {i} mass: {fea.CastToChNodeFEAxyz(fea.CastToChNodeFEAbase(el.GetNode(i))).GetMass()}")


Alessandro Tasora

unread,
Apr 16, 2026, 6:24:01 AM (21 hours ago) Apr 16
to ProjectChrono
Dear Thomas,

Hi everyone,

First, thank you to the developers of Chrono — it is an excellent tool.

I am using PyChrono 10.0.0 for finite element simulations, but I observe the same behaviour in version 9.0.1. I am working with BST shell elements, and I have an issue where the mass of the element does not seem to be computed. The mesh mass is always 0 kg, and all nodes also have 0 kg mass. I do not have this problem with other elements (ANCF_3423 and EulerBeams), since the mass is accuratly computed.

Below is a minimal working example where a BST element is created. However, the resulting mesh still has zero mass.

I have a few questions:
  1. Is this expected behaviour? If so, how can it be fixed or avoided?
no, this is not expected. Strange... The mass should be nonzero, and it is computed as a diagonal matrix with lumped masses at the nodes.  But I never had this issue in my tests (in c++). If I find some spare time I'll try to see where the trouble happens. 
 
  1. In Python, there does not seem to be a way to cast a ChElementBase to a ChElementShellBST. Is there another method to do this?
This because we must provide custom instructions in the Swig preprocessor when we generate the python wrapper. Do you really need this?
Note, for other elements (and in general for other c++ classes) the downcasting must be done on the Python side using statements like  chrono.CastToXxxxXXxx(...), so what you need would be

    myshell = chrono.CastToChElementShellBST(myelement)

...But it is not yet implemented. Sorry. Others are already in place, for instance you can do stuff like    mybeam = chrono.CastTo ChElementBeamEuler(myelement)  
At the moment our Swig preprocessor just implements the following casting for elements:

%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementBar) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementSpring) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementTetraCorot_4) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementTetraCorot_4_P) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementTetraCorot_10) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementHexaCorot_8) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementHexaCorot_20) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementBeamEuler) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementBeamANCF_3243) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementBeamANCF_3333) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementBeamIGA) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementBeamTaperedTimoshenko) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementBeamTaperedTimoshenkoFPM) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementCableANCF) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementShellReissner4) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementShellANCF_3423) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementShellANCF_3833) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementHexaANCF_3813) 
%DefSharedPtrDynamicCast(chrono::fea,ChElementBase,ChElementHexaANCF_3813_9)


I'll remember to add the corresponding %DefSharedPtrDynamicCast(...) for the BST shell in future releases. 

thanks

Alessandro Tasora

Thomas Caleb

unread,
Apr 16, 2026, 6:48:13 AM (21 hours ago) Apr 16
to ProjectChrono
Ciao Alessandro,

Thank you for you reply. 
The mass problem is indeed strange, I tried to look it up myself in the c++ source code but i did not find an explaination for this. Maybe my setup is wrong ? Did the example I provided repplicates the problem an your side ?
Regarding the cast functions, I understand, the need fot the CastToChElementShellBS method was essentialy for debugging purposes in order to understand this mass issue. So you probably have other priorities as this is not that important.

Thanks again to all contributors :)

Thomas
Reply all
Reply to author
Forward
0 new messages