Skip to main content
Milcapy provides several membrane element types for 2D finite element analysis in plane stress or plane strain conditions.

add_cst()

Add a Constant Strain Triangle (CST) membrane element - a 3-node triangular element.

Syntax

model.add_cst(id, node_i_id, node_j_id, node_k_id, section_name, state='PLANE_STRESS')

Parameters

id
int
required
Unique identifier for the CST element.
node_i_id
int
required
ID of the first node.
node_j_id
int
required
ID of the second node.
node_k_id
int
required
ID of the third node.
section_name
str
required
Name of the shell section (defined with add_shell_section()).
state
str | ConstitutiveModelType
default:"'PLANE_STRESS'"
Constitutive model for the element:
  • 'PLANE_STRESS' - Plane stress condition (thin plates)
  • 'PLANE_STRAIN' - Plane strain condition (thick members)

Returns

Returns a MembraneTriangle object. Each node has 2 degrees of freedom (ux, uy).

Example

import milcapy as milca

model = milca.SystemMilcaModel()

# Define material and shell section
model.add_material('concrete', modulus_elasticity=25e9, poisson_ratio=0.2)
model.add_shell_section('wall', 'concrete', thickness=0.15)

# Add nodes (counterclockwise)
model.add_node(1, 0.0, 0.0)
model.add_node(2, 1.0, 0.0)
model.add_node(3, 0.5, 0.866)

# Add CST element
model.add_cst(1, 1, 2, 3, 'wall', state='PLANE_STRESS')
Nodes must be enumerated in counterclockwise order to ensure proper element formulation.

add_membrane_q4()

Add a 4-node bilinear quadrilateral membrane element (Q4) with 4-point integration.

Syntax

model.add_membrane_q4(id, node_i_id, node_j_id, node_k_id, node_l_id, section_name, state='PLANE_STRESS')

Parameters

id
int
required
Unique identifier for the Q4 element.
node_i_id
int
required
ID of the first node.
node_j_id
int
required
ID of the second node.
node_k_id
int
required
ID of the third node.
node_l_id
int
required
ID of the fourth node.
section_name
str
required
Name of the shell section.
state
str | ConstitutiveModelType
default:"'PLANE_STRESS'"
Constitutive model: 'PLANE_STRESS' or 'PLANE_STRAIN'.

Returns

Returns a MembraneQuad4 object. Each node has 2 degrees of freedom (ux, uy).

Example

# Add nodes for quadrilateral (counterclockwise)
model.add_node(1, 0.0, 0.0)
model.add_node(2, 2.0, 0.0)
model.add_node(3, 2.0, 1.5)
model.add_node(4, 0.0, 1.5)

# Add Q4 element
model.add_membrane_q4(1, 1, 2, 3, 4, 'wall', state='PLANE_STRESS')
The Q4 element has poor convergence. It’s recommended to use mesh refinement or prefer Q8 elements for better accuracy.

add_membrane_q6()

Add a 4-node quadrilateral membrane element with drilling degrees of freedom (Q6) - 3 DOF per node.

Syntax

model.add_membrane_q6(id, node_i_id, node_j_id, node_k_id, node_l_id, section_name, state='PLANE_STRESS')

Parameters

id
int
required
Unique identifier for the Q6 element.
node_i_id
int
required
ID of the first node.
node_j_id
int
required
ID of the second node.
node_k_id
int
required
ID of the third node.
node_l_id
int
required
ID of the fourth node.
section_name
str
required
Name of the shell section.
state
str | ConstitutiveModelType
default:"'PLANE_STRESS'"
Constitutive model: 'PLANE_STRESS' or 'PLANE_STRAIN'.

Returns

Returns a MembraneQuad6 object. Each node has 3 degrees of freedom (ux, uy, rz).

Example

model.add_membrane_q6(1, 1, 2, 3, 4, 'wall', state='PLANE_STRESS')
This element implements the Q6 formulation from Dr. Wilson’s “Static and Dynamic Analysis of Structures” with drilling degrees of freedom.

add_membrane_q6i()

Add a 4-node quadrilateral membrane element with incompatible modes (Q6I) - similar to ETABS/SAP2000.

Syntax

model.add_membrane_q6i(id, node_i_id, node_j_id, node_k_id, node_l_id, section_name, state='PLANE_STRESS')

Parameters

id
int
required
Unique identifier for the Q6I element.
node_i_id
int
required
ID of the first node.
node_j_id
int
required
ID of the second node.
node_k_id
int
required
ID of the third node.
node_l_id
int
required
ID of the fourth node.
section_name
str
required
Name of the shell section.
state
str | ConstitutiveModelType
default:"'PLANE_STRESS'"
Constitutive model: 'PLANE_STRESS' or 'PLANE_STRAIN'.

Returns

Returns a MembraneQuad6I object. Each node has 2 degrees of freedom (ux, uy).

Example

model.add_membrane_q6i(1, 1, 2, 3, 4, 'wall', state='PLANE_STRESS')
The Q6I element uses the same formulation as ETABS and SAP2000, making it suitable for compatibility with those programs.

add_membrane_q8()

Add an 8-node serendipity quadrilateral membrane element (Q8) with selectable integration.

Syntax

model.add_membrane_q8(id, node_i_id, node_j_id, node_k_id, node_l_id, section_name, state='PLANE_STRESS', integration='COMPLETE')

Parameters

id
int
required
Unique identifier for the Q8 element.
node_i_id
int
required
ID of the first corner node.
node_j_id
int
required
ID of the second corner node.
node_k_id
int
required
ID of the third corner node.
node_l_id
int
required
ID of the fourth corner node.
section_name
str
required
Name of the shell section.
state
str | ConstitutiveModelType
default:"'PLANE_STRESS'"
Constitutive model: 'PLANE_STRESS' or 'PLANE_STRAIN'.
integration
str | IntegrationType
default:"'COMPLETE'"
Integration scheme:
  • 'COMPLETE' - 9-point Gauss integration
  • 'REDUCED' - 4-point Gauss integration (reduces shear locking)

Returns

Returns a MembraneQuad8 object. Each node has 2 degrees of freedom (ux, uy).

Example

# Add corner nodes only (mid-side nodes are computed automatically)
model.add_node(1, 0.0, 0.0)
model.add_node(2, 4.0, 0.0)
model.add_node(3, 4.0, 3.0)
model.add_node(4, 0.0, 3.0)

# Add Q8 element with reduced integration
model.add_membrane_q8(1, 1, 2, 3, 4, 'wall', 
                      state='PLANE_STRESS', 
                      integration='REDUCED')
The Q8 element has 8 nodes total. The 4 mid-side nodes are automatically computed at the midpoint of the quadrilateral edges and condensed into the 4 corner nodes.
The Q8 element provides excellent convergence with a single element. Avoid over-discretization, as excessive mesh refinement can make the element overly flexible and diverge from the exact solution. Reduced integration helps mitigate parasitic shear locking.

Element Comparison

CST (3-node)

Simplest element. Constant strain field. Use for simple geometries or refined meshes.

Q4 (4-node)

Basic quadrilateral. Poor convergence - requires mesh refinement.

Q6 (4-node + drilling)

Includes rotational DOF. Based on Wilson’s formulation.

Q6I (4-node + incompatible)

Incompatible modes. Compatible with ETABS/SAP2000.

Q8 (8-node)

Higher-order element. Excellent accuracy with single element. Reduced integration available.

General Notes

All quadrilateral elements require nodes to be enumerated in counterclockwise order for proper formulation.
Use add_shell_section() to define thickness and material properties for membrane elements.

Complete Example

import milcapy as milca

model = milca.SystemMilcaModel()

# Define material and section
model.add_material('steel', modulus_elasticity=200e9, poisson_ratio=0.3)
model.add_shell_section('plate', 'steel', thickness=0.01)

# Create a mesh with different element types
model.add_node(1, 0.0, 0.0)
model.add_node(2, 1.0, 0.0)
model.add_node(3, 2.0, 0.0)
model.add_node(4, 0.0, 1.0)
model.add_node(5, 1.0, 1.0)
model.add_node(6, 2.0, 1.0)
model.add_node(7, 0.5, 0.5)

# Add CST element
model.add_cst(1, 1, 2, 7, 'plate', state='PLANE_STRESS')

# Add Q4 element
model.add_membrane_q4(2, 2, 3, 6, 5, 'plate', state='PLANE_STRESS')

# Add Q8 element with reduced integration
model.add_membrane_q8(3, 1, 4, 5, 2, 'plate', 
                      state='PLANE_STRESS', 
                      integration='REDUCED')

Build docs developers (and LLMs) love