G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
Tutorial: Non-Linear dynamic analysis using Kirchhoff-Love shells

This example shows how to perform a non-linear dynamic analysis using the Dynamic solvers submodule of Structural Analysis Module. The dynamic solvers provided by this submodule work on user-defined operators from gsStructuralAnalysisOps, hence can be used with any element and in any application. In this example, we use the gsKLShell. The goals of the tutorial are the following:

For detailed information about the construction of gsThinShellAssembler and gsMaterialMatrixBase, please consult the tutorials Tutorial: Linear Kirchhoff-Love shell analysis and Tutorial: Non-Linear Kirchhoff-Love shell analysis.

Problem set-up

The set-up of the problem to be solved for this example is identical to the one in Tutorial: Non-Linear Kirchhoff-Love shell analysis. The reader is referred to that example for a full overview of the code.

Mass matrix assembly

The assembly of the linear stiffness matrix and the external force vector are similar as in Tutorial: Non-Linear Kirchhoff-Love shell analysis. To assemble the mass matrix, an additional assembly is performed using assembleMass(). The full assembly is given by:

assembler.assemble();
gsSparseMatrix<> K = assembler.matrix();
gsVector<> F = assembler.rhs();
assembler.assembleMass();
gsSparseMatrix<> M = assembler.matrix();

Jacobian and Residual

To use the Newmark time integrator or any other time integrator from Dynamic solvers, we need to define a Jacobian matrix and a residual, optionally time-independent. Both are defined from the gsStructuralAnalysisOps, similar to Tutorial: Non-Linear Kirchhoff-Love shell analysis using the gsStructuralAnalysis module.

In addition, an operator for mass and damping needs to be defined. These operators are simple lambda functions returning a constant matrix:

gsSparseMatrix<> C = gsSparseMatrix<>(assembler.numDofs(),assembler.numDofs());
gsStructuralAnalysisOps<real_t>::Damping_t Damping = [&C](const gsVector<real_t> &, gsSparseMatrix<real_t> & m) { m = C; return true; };
gsStructuralAnalysisOps<real_t>::Mass_t Mass = [&M]( gsSparseMatrix<real_t> & m) { m = M; return true; };
std::function< bool(gsSparseMatrix< T > &) > Mass_t
Mass matrix.
Definition gsStructuralAnalysisTypes.h:75
std::function< bool(gsVector< T > const &, gsSparseMatrix< T > &) > Damping_t
Damping matrix.
Definition gsStructuralAnalysisTypes.h:79

Define the dynamic solver

Using the mass, damping and Jacobian matrices \(M\), \(C\) and \(K_{NL}(\mathbf{u})\) and a residual vector \(R(\mathbf{u})\), an non-linear dynamic solver can be defined. In the following, a gsDynamicNewmark is defined:

gsInfo<<"Solving system with "<<assembler.numDofs()<<" DoFs\n";
gsDynamicNewmark<real_t,true> solver(Mass,Damping,Jacobian,Residual);
solver.options().setSwitch("Verbose",true);
#define gsInfo
Definition gsDebug.h:43

The solution is initialized with zero-vectors, as follows:

size_t N = assembler.numDofs();
gsVector<> U(N), V(N), A(N);
U.setZero();
V.setZero();
A.setZero();
solver.setU(U);
solver.setV(V);
solver.setA(A);

Solve the non-linear dynamic problem

The non-linear dynamic problem is solved by stepping over time. After some initializations, a simple time stepping loop is used:

index_t step = 50;
gsParaviewCollection collection("Deformation");
gsMultiPatch<> displ, def;
real_t time = 0;
real_t dt = 1e-2;
solver.setTimeStep(dt);
for (index_t k=0; k<step; k++)
{
gsInfo<<"Load step "<< k<<"\n";
gsStatus status = solver.step();
GISMO_ENSURE(status==gsStatus::Success,"Time integrator did not succeed");
U = solver.solutionU();
displ = assembler.constructDisplacement(U);
def = assembler.constructSolution(U);
// ! [Export visualization in ParaView]
if (plot)
{
// Plot the displacements on the deformed geometry
gsField<> solField(def, displ);
std::string outputName = "Deformation" + std::to_string(k) + "_";
gsWriteParaview<>( solField, outputName, 1000, true);
collection.addPart(outputName + "0.vts",time);
}
time = solver.time();
}
#define index_t
Definition gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
gsStatus
Definition gsStructuralAnalysisTypes.h:21
@ Success
Successful.

It can be seen that the export of the solution field is similar as in Tutorial: Linear Kirchhoff-Love shell analysis Tutorial: Non-Linear Kirchhoff-Love shell analysis, but the Paraview files are added to a gsParaviewCollection. This is saved at the end of the simulation as follows:

if (plot)
collection.save();

Annotated source file

Here is the full file nonlinear_shell_dynamic.cpp. Clicking on a function or class name will lead you to its reference documentation.

#include <gismo.h>
#ifdef gsKLShell_ENABLED
#include <gsKLShell/gsKLShell.h>
#endif
using namespace gismo;
// Choose among various shell examples, default = Thin Plate
int main(int argc, char *argv[])
{
#ifdef gsKLShell_ENABLED
bool plot = false;
index_t numRefine = 1;
index_t numElevate = 1;
gsCmdLine cmd("Linear shell tutorial.");
cmd.addInt( "e", "degreeElevation","Number of degree elevation steps to perform before solving (0: equalize degree in all directions)", numElevate );
cmd.addInt( "r", "uniformRefine", "Number of Uniform h-refinement steps to perform before solving", numRefine );
cmd.addSwitch("plot", "Create a ParaView visualization file with the solution", plot);
try { cmd.getValues(argc,argv); } catch (int rv) { return rv; }
// Initialize [ori]ginal and [def]ormed geometry
gsReadFile<>("surfaces/paraboloid.xml", ori);
// p-refine
if (numElevate!=0)
ori.degreeElevate(numElevate);
// h-refine
for (int r =0; r < numRefine; ++r)
gsMultiBasis<> bases(ori);
// Define the boundary conditions object
// Set the geometry map for computation of the Dirichlet BCs
bc.setGeoMap(ori);
// Set the boundary conditions
bc.addCornerValue(boundary::southwest, 0.0, 0, -1); // (corner,value, patch, unknown)
bc.addCornerValue(boundary::southeast, 0.0, 0, -1); // (corner,value, patch, unknown)
bc.addCornerValue(boundary::northwest, 0.0, 0, -1); // (corner,value, patch, unknown)
bc.addCornerValue(boundary::northeast, 0.0, 0, -1); // (corner,value, patch, unknown)
gsVector<> point(2);
gsVector<> load (3);
point<< 0.5, 0.5 ; load << 0, 0.0, -1e4 ;
pLoads.addLoad(point, load, 0 );
// The surface force is defined in the physical space, i.e. 3D
gsFunctionExpr<> force("0","0","0",3);
// Define material parameters
// The material parameters are defined in the physical domain as well (!)
gsConstantFunction<> nu (0.45,3);
gsConstantFunction<> rho(1.E5,3);
// Define a linear material, see \ref gsMaterialMatrixLinear.h
// The first parameter is the physical domain dimension
// gsMaterialMatrixLinear<3,real_t> materialMatrix(ori,t,E,nu);
std::vector<gsFunctionSet<>*> parameters{&E,&nu};
gsOptionList options;
options.addInt("Material","Material model: (0): SvK | (1): NH | (2): NH_ext | (3): MR | (4): Ogden",1);
options.addInt("Implementation","Implementation: (0): Composites | (1): Analytical | (2): Generalized | (3): Spectral",1);
gsMaterialMatrixBase<real_t>::uPtr materialMatrix = getMaterialMatrix<3,real_t>(ori,t,parameters,rho,options);
// Define the assembler.
// The first parameter is the physical domain dimension
// The second parameter is the real type
// The third parameter controls the bending stiffness
gsThinShellAssembler<3, real_t, true > assembler(ori,bases,bc,force,materialMatrix);
assembler.setPointLoads(pLoads);
assembler.assemble();
gsSparseMatrix<> K = assembler.matrix();
gsVector<> F = assembler.rhs();
assembler.assembleMass();
gsSparseMatrix<> M = assembler.matrix();
// Function for the Jacobian
{
assembler.constructSolution(x,def);
ThinShellAssemblerStatus status = assembler.assembleMatrix(def);
m = assembler.matrix();
};
// Function for the Residual
{
assembler.constructSolution(x,def);
ThinShellAssemblerStatus status = assembler.assembleVector(def);
v = assembler.rhs();
};
gsSparseMatrix<> C = gsSparseMatrix<>(assembler.numDofs(),assembler.numDofs());
gsStructuralAnalysisOps<real_t>::Damping_t Damping = [&C](const gsVector<real_t> &, gsSparseMatrix<real_t> & m) { m = C; return true; };
gsStructuralAnalysisOps<real_t>::Mass_t Mass = [&M]( gsSparseMatrix<real_t> & m) { m = M; return true; };
gsInfo<<"Solving system with "<<assembler.numDofs()<<" DoFs\n";
gsDynamicNewmark<real_t,true> solver(Mass,Damping,Jacobian,Residual);
solver.options().setSwitch("Verbose",true);
size_t N = assembler.numDofs();
gsVector<> U(N), V(N), A(N);
U.setZero();
V.setZero();
A.setZero();
solver.setU(U);
solver.setV(V);
solver.setA(A);
index_t step = 50;
gsParaviewCollection collection("Deformation");
gsMultiPatch<> displ, def;
real_t time = 0;
real_t dt = 1e-2;
solver.setTimeStep(dt);
for (index_t k=0; k<step; k++)
{
gsInfo<<"Load step "<< k<<"\n";
gsStatus status = solver.step();
GISMO_ENSURE(status==gsStatus::Success,"Time integrator did not succeed");
U = solver.solutionU();
displ = assembler.constructDisplacement(U);
def = assembler.constructSolution(U);
// ! [Export visualization in ParaView]
if (plot)
{
// Plot the displacements on the deformed geometry
gsField<> solField(def, displ);
std::string outputName = "Deformation" + std::to_string(k) + "_";
gsWriteParaview<>( solField, outputName, 1000, true);
collection.addPart(outputName + "0.vts",time);
}
time = solver.time();
}
// ![Save the paraview collection]
if (plot)
collection.save();
// ![Save the paraview collection]
return EXIT_SUCCESS;
#else
GISMO_ERROR("The tutorial needs to be compiled with gsKLShell enabled");
return EXIT_FAILED;
#endif
}// end main
Class containing a set of boundary conditions.
Definition gsBoundaryConditions.h:342
void addCornerValue(boxCorner c, T value, int p=0, short_t unknown=0, int component=-1)
Adds a boundary condition with value on a corner c of patch p for unknown component.
Definition gsBoundaryConditions.h:726
void setGeoMap(const gsFunctionSet< T > &gm)
Set the geometry map to evaluate boundary conditions.
Definition gsBoundaryConditions.h:916
Class for command-line argument parsing.
Definition gsCmdLine.h:57
Class defining a globally constant function.
Definition gsConstantFunction.h:34
Performs the arc length method to solve a nonlinear system of equations.
Definition gsDynamicNewmark.h:35
A scalar of vector field defined on a m_parametric geometry.
Definition gsField.h:55
Class defining a multivariate (real or vector) function given by a string mathematical expression.
Definition gsFunctionExpr.h:52
memory::unique_ptr< gsMaterialMatrixBase > uPtr
Unique pointer for gsGeometry.
Definition gsMaterialMatrixBase.h:44
Holds a set of patch-wise bases and their topology information.
Definition gsMultiBasis.h:37
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition gsMultiPatch.h:100
void degreeElevate(short_t const elevationSteps=1, short_t const dir=-1)
Elevate the degree of all patches by elevationSteps, preserves smoothness.
Definition gsMultiPatch.hpp:282
bool computeTopology(T tol=1e-4, bool cornersOnly=false, bool tjunctions=false)
Attempt to compute interfaces and boundaries automatically.
Definition gsMultiPatch.hpp:377
void uniformRefine(int numKnots=1, int mul=1, short_t const dir=-1)
Refine uniformly all patches by inserting numKnots in each knot-span with multipliplicity mul.
Definition gsMultiPatch.hpp:271
Class which holds a list of parameters/options, and provides easy access to them.
Definition gsOptionList.h:33
void addInt(const std::string &label, const std::string &desc, const index_t &value)
Adds a option named label, with description desc and value value.
Definition gsOptionList.cpp:201
This class is used to create a Paraview .pvd (collection) file.
Definition gsParaviewCollection.h:77
Class containing a set of points on a multi-patch isogeometric domain, together with boundary conditi...
Definition gsPointLoads.h:65
Reads an object from a data file, if such the requested object exists in the file.
Definition gsReadFile.h:43
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition gsSparseMatrix.h:139
Assembles the system matrix and vectors for 2D and 3D shell problems, including geometric nonlinearit...
Definition gsThinShellAssembler.h:77
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
Main header to be included by clients using the G+Smo library.
#define GISMO_ERROR(message)
Definition gsDebug.h:118
Class to perform time integration of second-order structural dynamics systems using the Explicit Eule...
Class providing Structural Analysis Utilities.
The G+Smo namespace, containing all definitions for the library.
ThinShellAssemblerStatus
Definition gsThinShellAssembler.h:54
@ Success
Assembly is successful.
std::function< bool(gsVector< T > const &, gsSparseMatrix< T > &) > Jacobian_t
Jacobian.
Definition gsStructuralAnalysisTypes.h:86
std::function< bool(gsVector< T > const &, gsVector< T > &)> Residual_t
Residual, Fint-Fext.
Definition gsStructuralAnalysisTypes.h:68