Example 2: Beam2D Corotational Nonlinear Example
The following example demonstrates the geometrically nonlinear behavior of a cantilever Beam2D struture using the corotational formulation. To this purpose, two tests are shown, one using the Newton-Raphson analyzer and a second one using the Displacement Control analyzer.
For both tests we have to define the mechanical properties of the beam cross-section and the material, such that:
double youngModulus = 21000.0;
double poissonRatio = 0.3;
double nodalLoad = 20000.0;
double area = 91.04;
double inertia = 8091.0;
int nNodes = 3;
int nElems = 2;
int monitorNode = 3;
// Create new 2D material
var material = new ElasticMaterial
{
YoungModulus = youngModulus,
PoissonRatio = poissonRatio,
};
Define nodal geometry:
// Node creation
IList<Node> nodes = new List<Node>();
Node node1 = new Node(id: 1, x: 0.0, y: 0.0);
Node node2 = new Node(id: 2, x: 100.0, y: 0.0);
Node node3 = new Node(id: 3, x: 200.0, y: 0.0);
nodes.Add(node1);
nodes.Add(node2);
nodes.Add(node3);
Define model and subdomain:
// Model creation
var model = new Model();
// Add a single subdomain to the model
model.SubdomainsDictionary.Add(subdomainID, new Subdomain(subdomainID));
// Add nodes to the nodes dictonary of the model
for (int i = 0; i < nodes.Count; ++i)
{
model.NodesDictionary.Add(i + 1, nodes[i]);
}
Constrain the node with key equal to 1, as:
// Constrain bottom nodes of the model
model.NodesDictionary[1].Constraints.Add(new Constraint() { DOF = StructuralDof.TranslationX, Amount = 0.0 });
model.NodesDictionary[1].Constraints.Add(new Constraint() { DOF = StructuralDof.TranslationY, Amount = 0.0 });
model.NodesDictionary[1].Constraints.Add(new Constraint() { DOF = StructuralDof.RotationZ, Amount = 0.0 });
Define the geometrically nonlinear corotational beam2D elements:
// Generate elements of the structure
int iNode = 1;
for (int iElem = 0; iElem < nElems; iElem++)
{
// element nodes
IList<Node> elementNodes = new List<Node>();
elementNodes.Add(model.NodesDictionary[iNode]);
elementNodes.Add(model.NodesDictionary[iNode + 1]);
// Create new Beam3D section and element
var beamSection = new BeamSection2D(area, inertia);
// Create elements
var element = new Element()
{
ID = iElem + 1,
ElementType = new Beam2DCorotational(elementNodes, material, 7.85, beamSection)
};
// Add nodes to the created element
element.AddNode(model.NodesDictionary[iNode]);
element.AddNode(model.NodesDictionary[iNode + 1]);
var a = element.ElementType.StiffnessMatrix(element);
// Add beam element to the element and subdomains dictionary of the model
model.ElementsDictionary.Add(element.ID, element);
model.SubdomainsDictionary[subdomainID].Elements.Add(element);
iNode++;
}
Add load on the third on along the y-axis:
// Add nodal load values at the top nodes of the model
model.Loads.Add(new Load() { Amount = nodalLoad, Node = model.NodesDictionary[monitorNode], DOF = StructuralDof.TranslationY });
Choose Skyline solver and Structural provider:
// Choose Skyline solver
var solverBuilder = new SkylineSolver.Builder();
ISolver solver = solverBuilder.BuildSolver(model);
// Choose the provider of the problem -> here a structural problem
var provider = new ProblemStructural(model, solver);
Define Static analyzer as parent and Newton-Raphson analyzer as the nonlinear method that solves the system of equations as child analyzer:
// Choose child analyzer -> NewtonRaphsonNonLinearAnalyzer
int increments = 10;
var childAnalyzerBuilder = new LoadControlAnalyzer.Builder(model, solver, provider, increments);
LoadControlAnalyzer childAnalyzer = childAnalyzerBuilder.Build();
// Choose parent analyzer -> Static
var parentAnalyzer = new StaticAnalyzer(model, solver, provider, childAnalyzer);
At last we run the analysis and check if the test satisfies the criterion that we have dafined:
// Run the analysis
parentAnalyzer.Initialize();
parentAnalyzer.Solve();
// Check output
DOFSLog log = (DOFSLog)childAnalyzer.Logs[subdomainID][0];
Assert.Equal(146.5587362562, log.DOFValues[4], 3);
For the second test, according to the Displacement Control method, instead of applying nodal load at node 3, a displacement is applied according to the following:
// Applied displacement
model.NodesDictionary[3].Constraints.Add(new Constraint { DOF = StructuralDof.TranslationY, Amount = nodalDisplacement });
While the Skyline solver, the Structural provider and the Static analyzer as a parent analyzer remain the same, we have to define the Diplacement Control analyzer as a child analyzer, as:
// Choose child analyzer -> Child: DisplacementControlAnalyzer
var subdomainUpdaters = new[] { new NonLinearSubdomainUpdater(model.SubdomainsDictionary[subdomainID]) };
int numIncrements = 10;
var childAnalyzerBuilder = new DisplacementControlAnalyzer.Builder(model, solver, provider, numIncrements);
var childAnalyzer = childAnalyzerBuilder.Build();
This replaces the Newron-Raphson analyzer (LoadControlAnalyzer) of the first test.