Dear CalculiX community,
Good morning! I hope this message finds you well.
I am working on a custom user element (UEL) for a 3βnode beam element with 6 degrees of freedom per node. The compilation of CalculiX (version 2.22) went fine, and the uel_ symbol is present in the executable:
nm ccx_2.22 | grep uel_
0000000000010a30 T uel_
The analysis runs without problems when I use a standard element (e.g. B31), but when I switch to my user element I encounter a segmentation fault during the stress calculation. Moreover, my UEL routine does not seem to be called at all (no debug file is written, even with a simple open/write at the very beginning of the subroutine).
My input file (simplified)
*HEADING
Test UEL beam - Simplified
*NODE
1, 0.0, 0.0, 0.0
2, 2.5, 0.0, 0.0
3, 5.0, 0.0, 0.0
*USER ELEMENT, TYPE=U1, NODES=3, MAXDOF=6, INTEGRATIONPOINTS=2
*ELEMENT, TYPE=U1, ELSET=TRAVE
1, 1, 2, 3
*MATERIAL, NAME=DUMMY
*ELASTIC
2.1e11, 0.3
*SOLID SECTION, ELSET=TRAVE, MATERIAL=DUMMY
*UEL PROPERTY, ELSET=TRAVE
1, 0.01, 8.33e-6, 8.33e-6, 0.0, 0.85, 2.1e11, 0.3, 0.0, 1.0, 0.0, 0.0, 0.0
*BOUNDARY
1, 1, 6, 0.0
*STEP
*STATIC
0.01, 1.0
*CLOAD
3, 2, -10000.0
*END STEP
Warnings and error
During the run I get these warnings:
*WARNING in calinput. Card image cannot be interpreted:
*UELPROPERTY,ELSET=TRAVE
*WARNING in calinput. Card image cannot be interpreted:
1,0.01,8.33E-6,8.33E-6,0.,0.85,2.1E11,0.3,0.,1.,0.,0.,0.
Then the analysis proceeds, the matrix structure is determined, and finally a segmentation fault occurs:
Determining the structure of the matrix:
number of equations 12
number of nonzero lower triangular matrix elements 66
Using up to 1 cpu(s) for the stress calculation.
Errore di segmentazione (core dump creato)
No debug file is created, which makes me think that the UEL routine is never entered.
What I have already tried
Using *UEL PROPERTY (with a space) instead of *UELPROPERTY β the warning persists.
Adding a simple open/write at the very beginning of uel.f β the file is never created.
Compiling with -g and running under gdb β the backtrace points to a memory access issue inside the solver, not inside my UEL.
Confirming that the uel_ symbol is indeed present in the executable.
Trying different element types: TYPE=U1, TYPE=U, TYPE=-1, TYPE=100001, with and without *USER ELEMENT.
Removing the *SOLID SECTION block β but then I get a βno material assignedβ error.
My questions
Is the syntax for *UEL PROPERTY correct in my input file? The persistent warning suggests that the line is not being parsed as expected.
Why would the UEL routine not be called, even though the symbol is present and the element type seems to be recognised?
Could there be something wrong with the way the user element properties are passed? (The code in uel.f reads 13 properties; I am providing exactly 13 numbers.)
Any suggestions on how to further debug this segmentation fault?
I would be very grateful for any insights or examples of working UEL input decks for CalculiX 2.22.
Thank you very much in advance for your time and help!
Kind regards,
Bruno Zilli
Italia
File uel.f β 3βnode beam element with 6 DOF per node
subroutine uel(rhs,amatrx,svars,energy,ndofel,nrhs,nsvars,
& props,nprops,coords,mcrd,nnode,u,du,v,a,time,dtime,
& ttime,kstep,kinc,iel,iproc,jmatyp,
& iflags,iperiod,iprop,iprops,nadapt,msp,isvars,noel)
implicit none
! ================================================================
! INPUT / OUTPUT PARAMETERS
! ================================================================
! Standard CalculiX UEL interface
!
! INPUT:
! ndofel : number of degrees of freedom for the element
! nrhs : number of right-hand sides
! nsvars : number of state variables
! nprops : number of material properties
! mcrd : maximum number of coordinates (3 for 3D)
! nnode : number of nodes for the element
! props : array of user-defined properties
! coords : nodal coordinates (mcrd, nnode)
! u : total displacement vector
! du : displacement increment
! v : velocity
! a : acceleration
! time : time parameters
! dtime : time increment
! ttime : total time
! kstep : step number
! kinc : increment number
! iel : element number
! iproc : processor number (for parallel runs)
! jmatyp : element type identifier (from \*USER ELEMENT)
! iflags : flags for element operations
! iperiod : periodicity flag
! iprop : property index
! iprops : integer properties
! nadapt : adaptation flag
! msp : maximum number of state variables
! isvars : integer state variables
! noel : element number (same as iel, kept for compatibility)
!
! OUTPUT:
! rhs : residual vector (forces)
! amatrx : stiffness matrix (tangent matrix)
! svars : state variables (updated)
! energy : energy contributions
! ================================================================
! Dummy arguments
integer ndofel, nrhs, nsvars, nprops, mcrd, nnode, kstep, kinc,
& iel, iproc, jmatyp, iperiod, iprop, nadapt, msp, noel
integer iflags(*), iprops(*), isvars(\*)
real*8 rhs(ndofel,*)
real*8 amatrx(ndofel,*)
real*8 svars(*)
real*8 energy(*)
real*8 props(*)
real*8 coords(mcrd,*)
real*8 u(*), du(*), v(*), a(*), time(*), dtime, ttime
! ================================================================
! LOCAL VARIABLES
! ================================================================
! Element geometry and shape functions
integer i, j, k, ii, ipt, idx
integer nope, ndof, npoints
parameter (nope=3, ndof=6, npoints=2) ! 3 nodes, 6 DOF/node, 2 Gauss points
real*8 xl(3,3) ! Nodal coordinates in local array (3 coordinates, 3 nodes)
real*8 e1(3), e2(3), e3(3) ! Local axes vectors
real*8 len ! Element length
real*8 xi, wgt ! Gauss point coordinate and weight
real*8 detJ, jac ! Jacobian and its determinant
real*8 N(3) ! Shape functions
real*8 dN_dxi(3) ! Derivative of shape functions w.r.t. natural coordinate
real*8 dNdx(3) ! Derivative of shape functions w.r.t. global coordinates
! Matrices
real*8 B(6,18) ! Strain-displacement matrix (6 strain components, 18 DOF)
real*8 D(6,6) ! Constitutive matrix (6x6)
real*8 Ke(18,18) ! Element stiffness matrix in global coordinates
real*8 Ke_loc(18,18) ! Element stiffness matrix in local coordinates
real*8 tm(3,3) ! Transformation matrix (3x3)
real*8 tmg(18,18) ! Transformation matrix expanded to 18x18
real\*8 sg(18,18) ! Temporary matrix for transformation
! Section properties
real*8 area, Iyy, Izz, Iyz, shearK, E, nu, G, J_t
real*8 offset1, offset2
real\*8 dN, Ni
! Gauss integration points
real\*8 gauss_xi(2), gauss_w(2)
data gauss_xi / -0.5773502691896257d0, 0.5773502691896257d0 /
data gauss_w / 1.0d0, 1.0d0 /
! ================================================================
! DEBUG OUTPUT β to verify if UEL is called
! ================================================================
open(88, file=βuel_called.txtβ, status=βunknownβ)
write(88,*) βUEL called! IEL=β, iel, β JMATYP=', jmatyp
write(88,*) βNPROPS=β, nprops
write(88,\*) βNNODE=β, nnode, β NDOFEL=', ndofel
close(88)
! ================================================================
! READ USER-DEFINED PROPERTIES
! ================================================================
! Properties are passed through the \*UEL PROPERTY card
! Expected order:
! 1: area
! 2: Iyy (moment of inertia about local y-axis)
! 3: Izz (moment of inertia about local z-axis)
! 4: Iyz (product of inertia)
! 5: shearK (shear correction factor)
! 6: E (Youngβs modulus)
! 7: nu (Poissonβs ratio)
! 8-10: e2(1:3) β local y-direction vector (global coordinates)
! 11: offset1
! 12: offset2
! ================================================================
area = props(1)
Iyy = props(2)
Izz = props(3)
Iyz = props(4)
shearK = props(5)
E = props(6)
nu = props(7)
e2(1) = props(8)
e2(2) = props(9)
e2(3) = props(10)
offset1 = props(11)
offset2 = props(12)
! Shear modulus and torsional constant
G = E / (2.d0 \* (1.d0 + nu))
J_t = Iyy + Izz ! Torsional constant for simple cross-sections
! ================================================================
! INITIALISE STIFFNESS MATRIX
! ================================================================
do i = 1, 18
do j = 1, 18
Ke(i,j) = 0.d0
enddo
enddo
! ================================================================
! GAUSS INTEGRATION LOOP
! ================================================================
do ipt = 1, npoints
xi = gauss_xi(ipt)
wgt = gauss_w(ipt)
! Shape functions and their derivatives (quadratic 1D element)
N(1) = -0.5d0 \* xi \* (1.d0 - xi)
N(2) = (1.d0 - xi) \* (1.d0 + xi)
N(3) = 0.5d0 \* xi \* (1.d0 + xi)
dN_dxi(1) = -0.5d0 + xi
dN_dxi(2) = -2.0d0 * xi
dN_dxi(3) = 0.5d0 + xi
! Store nodal coordinates in local array
do j = 1, 3
xl(1,j) = coords(1,j)
xl(2,j) = coords(2,j)
xl(3,j) = coords(3,j)
enddo
! Compute Jacobian
jac = 0.d0
do j = 1, 3
jac = jac + dN_dxi(1) \* xl(1,j)
jac = jac + dN_dxi(2) \* xl(2,j)
jac = jac + dN_dxi(3) \* xl(3,j)
enddo
detJ = jac / 2.d0
! Compute element local x-axis (e1) β from node 1 to node 3
do j = 1, 3
e1(j) = (xl(j,3) - xl(j,1)) / 2.d0
enddo
len = dsqrt(e1(1)\*\*2 + e1(2)\*\*2 + e1(3)\*\*2)
do j = 1, 3
e1(j) = e1(j) / len
enddo
! Compute local z-axis (e3) as cross product e1 Γ e2
e3(1) = e1(2)\*e2(3) - e1(3)\*e2(2)
e3(2) = e1(3)\*e2(1) - e1(1)\*e2(3)
e3(3) = e1(1)\*e2(2) - e1(2)\*e2(1)
! Build transformation matrix tm (3x3) from global to local
do i = 1, 3
do j = 1, 3
tm(i,j) = 0.d0
enddo
enddo
tm(1,1) = e1(1)
tm(1,2) = e1(2)
tm(1,3) = e1(3)
tm(2,1) = e2(1)
tm(2,2) = e2(2)
tm(2,3) = e2(3)
tm(3,1) = e3(1)
tm(3,2) = e3(2)
tm(3,3) = e3(3)
! Compute derivatives of shape functions w.r.t. global coordinates
dNdx(1) = dN_dxi(1) / detJ
dNdx(2) = dN_dxi(2) / detJ
dNdx(3) = dN_dxi(3) / detJ
! Initialise B matrix
do i = 1, 6
do j = 1, 18
B(i,j) = 0.d0
enddo
enddo
! Assemble B matrix (6 strain components Γ 18 DOF)
! DOF ordering per node: \[u1, u2, u3, phi1, phi2, phi3\]
do ii = 1, 3
idx = (ii-1) \* 6
dN = dNdx(ii)
Ni = N(ii)
! Axial strain
B(1, idx+1) = dN
! Shear strains (using beam theory)
B(2, idx+2) = dN
B(2, idx+6) = -Ni
B(3, idx+3) = dN
B(3, idx+5) = Ni
! Bending and torsional strains
B(4, idx+5) = dN
B(5, idx+6) = dN
B(6, idx+4) = dN
enddo
! Build constitutive matrix D (6x6)
do i = 1, 6
do j = 1, 6
D(i,j) = 0.d0
enddo
enddo
D(1,1) = E \* area
D(2,2) = shearK \* G \* area
D(3,3) = shearK \* G \* area
D(4,4) = E \* Iyy
D(5,5) = E \* Izz
D(6,6) = G \* J_t
! Compute local stiffness matrix: Ke_loc = B^T \* D \* B
do i = 1, 18
do j = 1, 18
Ke_loc(i,j) = 0.d0
do k = 1, 6
Ke_loc(i,j) = Ke_loc(i,j) + B(k,i) \* D(k,k) \* B(k,j)
enddo
enddo
enddo
! Integrate: add contribution of current Gauss point
do i = 1, 18
do j = 1, 18
Ke(i,j) = Ke(i,j) + wgt \* Ke_loc(i,j) \* detJ
enddo
enddo
enddo ! end of Gauss integration loop
! ================================================================
! TRANSFORM STIFFNESS MATRIX FROM LOCAL TO GLOBAL COORDINATES
! ================================================================
! Expand transformation matrix tm to 18x18
do i = 1, 18
do j = 1, 18
tmg(i,j) = 0.d0
enddo
enddo
do i = 1, 3
do j = 1, 3
tmg(i,j) = tm(i,j)
tmg(i+3,j+3) = tm(i,j)
tmg(i+6,j+6) = tm(i,j)
tmg(i+9,j+9) = tm(i,j)
tmg(i+12,j+12) = tm(i,j)
tmg(i+15,j+15) = tm(i,j)
enddo
enddo
! Transform: Ke_global = tmg^T \* Ke_local \* tmg
! First multiply: sg = Ke_local \* tmg
do i = 1, 18
do j = 1, 18
sg(i,j) = 0.d0
do k = 1, 18
sg(i,j) = sg(i,j) + Ke(i,k) \* tmg(k,j)
enddo
enddo
enddo
! Then multiply: Ke_global = tmg^T \* sg
do i = 1, 18
do j = 1, 18
Ke(i,j) = 0.d0
do k = 1, 18
Ke(i,j) = Ke(i,j) + tmg(k,i) \* sg(k,j)
enddo
enddo
enddo
! ================================================================
! ASSEMBLE OUTPUT MATRICES
! ================================================================
! Stiffness matrix
do i = 1, 18
do j = 1, 18
amatrx(i,j) = Ke(i,j)
enddo
enddo
! Residual vector (set to zero for linear static analysis)
do i = 1, 18
rhs(i,1) = 0.d0
enddo
return
end
File beam_uel_test.inp β Input file
*HEADING
Test for 3-node beam UEL with 6 DOF per node
*NODE
1, 0.0, 0.0, 0.0
2, 2.5, 0.0, 0.0
3, 5.0, 0.0, 0.0
*USER ELEMENT, TYPE=U1, NODES=3, MAXDOF=6, INTEGRATIONPOINTS=2
*ELEMENT, TYPE=U1, ELSET=TRAVE
1, 1, 2, 3
*MATERIAL, NAME=DUMMY
*ELASTIC
2.1e11, 0.3
*SOLID SECTION, ELSET=TRAVE, MATERIAL=DUMMY
*UEL PROPERTY, ELSET=TRAVE
1, 0.01, 8.33e-6, 8.33e-6, 0.0, 0.85, 2.1e11, 0.3, 0.0, 1.0, 0.0, 0.0, 0.0
*BOUNDARY
1, 1, 6, 0.0
*STEP
*STATIC
0.01, 1.0
*CLOAD
3, 2, -10000.0
*END STEP
CalculiX version: 2.22
Compiler: gfortran
System: Caelinux / Ubuntu