View on GitHub

NumericalAnalyzers

Library that handles static, dynamic and non-linear procedures.

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.