User Guide of openVFIFE
GinkGo Lv1

User Guide

Welcome to openVFIFE.

This is a very short guide on how to get started with openVFIFE. It has a dual purpose. It serves as a minimal introduction to the openVFIFE library for people who want to start coding as soon as possible. You can also read this page as the first part of the Tutorial, which explains the library in more detail.

What is openVFIFE?

The openVFIFE is a C++ library for structural nonliear dynamic analysis and discontinuous behaviour analysis based on vector form intrinsic finite element method (referred to as VFIFE).

Motivation: The VFIFE has already been applied in many research fields, and has made great achievements. However, there is no available software/platform for it, which is an main obstcale of the development and popularization of VFIFE. On the other hand, the author (Tan Biao or GinkGo) tries to introduce VFIFE into the collapse analysis of transmission tower. For this reason, the openVFIFE has been implemented to provide a general VFIFE analysis software/platform for researchers or engineers who interested in VFIFE.

Final goal: The openVFIFE is currently released in the form of C++ library. But it will never stop here. A completely independent cross-platform software package is my ultimate goal. The author will continue to work hard for this. And the contributions from all of you are quite important. If you have any suggestions or advices, or want to contribute new codes , please contact me (ginkgoltd@outlook.com).

Main Characters:

  • openVFIFE is a completely open source library, which strictly abides by GNU/GPL v3.0 License (see LICENSE file).
  • openVFIFE is fast.
  • openVFIFE is reliable.
  • openVFIFE is user- and developer-friendly.
  • openVFIFE is scalable.

Quick Start

How to install openVFIFE?

In order to use  openVFIFE, you just need to download and extract openVFIFE's source code. The header files in the headers subdirectory and the static library file in the './library' are the only files required to compile programs using  openVFIFE. The header files are the same for all platforms. It is not necessary to use CMake or install anything.

A simple first program

Here is a rather simple program to get you started.

Consider a single bar structure(as shown in the following figure) , the length \(l = 10m\), the section area is \(1m^2\), Young's modulus \(E=10^6Pa\) , mass density \(\rho = 10 kg/m^3\). In this case, I want to show you how to use openVFIFE to solve static problems, and explain the influence of damping coefficient and time step.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include "../../headers/structsystem.h" // see ./examples/example2/example2.cpp
using namespace std;

int main()
{
// create system
StructSystem system = StructSystem(1);
system.setJobname("example2");

// solve parameters
double endTime = 50.0; // total time, s
double h = 1.0e-3; // time step, s
double p = 100; // load, N
double zeta = 0.5; // damping coefficient

// create particles
Particle * p1 = new Particle(1, 0, 0);
Particle * p2 = new Particle(2, 10, 0);
system.addParticle(p1);
system.addParticle(p2);

// create material
LinearElastic mat = LinearElastic(1);
mat.setE(1.0E6);
mat.setDensity(10);

// create section
CustomSectionParas paras = {.A=1, .Sy=0, .Sz=0, .SHy=0, .SHz=0,
.CGy=0, .CGz=0.0, .Iyy=10, .Izz=10, .Iyz=10};
CustomSection sect = CustomSection(1, paras);

// create elements
Link2D* e = new Link2D(1, p1, p2, &mat, &sect);
system.addElement(e);

// constraints
DOF c1 = {.key = {true, true, true, true, true, true},
.val = {0, 0, 0, 0, 0, 0}};
DOF c2 = {.key = {false, true, true, true, true, true},
.val = {0, 0, 0, 0, 0, 0}};
system.addConstraint(1, c1);
system.addConstraint(2, c2);

// save model
string path = system.workdir() + "/" + system.jobname() + "/model";
system.saveModel(path);
system.info(); // print structsystem information

StdArray6d f1 = {100, 0, 0, 0, 0, 0};
int nStep = ceil(endTime/h);
cout << nStep << endl;
int interval = ceil(0.1/h);
for (int i = 0; i <= nStep; i++)
{
if (i == 0)
{
system.addExternalForce(2, f1); // add external force
system.solve(h, zeta, true);
system.setInternalForce();
}
else
{
system.solve(h, zeta);
system.clearParticleForce();
system.setExternalForce(2, f1);
system.setInternalForce();
}

// save results
if (i % interval == 0)
{
string path = system.workdir() + "/" + system.jobname() + "/" +
to_string(i*h);
system.saveParticleResult(path);
system.saveElementResult(path);
system.saveSupportReact(path);
}
}

system.releaseContainers(); // release the projects, it's important for avoiding memory leakage
return 0;
}

We will explain the program after telling you how to complie it.

Compiling and running your first program

The only thing that you need to keep in mind when compiling the above program is that the compiler must be able to find the openVFIFE header files. The directory in which you placed openVFIFEs source code must be in the include path. With GCC you use the -L option to achieve this, so you can compile the program with a command like this:

1
g++ -statick -O3 xxx.cpp -L /path/to/static/library -lvfife -o xxx.out

On Windows or Mac OS, you need to comiple all the files by yourself. In future, I will provide a makefile for cmake, but now you should compile openVFIFE by yourself. Here are the commands for compile a static library in Linux.

1
2
3
# change to the src directory
$ g++ -c -O3 element.cpp gridsection.cpp integrator.cpp material.cpp particle.cpp section.cpp structsystem.cpp
$ ar rcs libvfife.a element.o gridsection.o integrator.o material.o particle.o section.o structsystem.o

Explanation of the first program

Basic procedures of openVFIFE

openVFIFE is quite simple and intuitive. The basic procedures of a calculation is as follows:

  1. create a StructSystem to manage all struct objects
  2. create Particles
  3. create Materials and Sections (necessary in bar structures)
  4. create Elements
  5. add constraints
  6. add external force and solve

step 1: create a StructSystem object

1
2
3
// create system
StructSystem system = StructSystem(1);
system.setJobname("example2");

StructSystem::StructSystem(int id) is the constructor of the StructSystem class, you need to give a int number for represent the id of the structrure. And StructSystem::setjobname(const std::string &jobname) give a method to assign the name of the project, which will help create a ./jobname directory in the current working directory to restore the computing results.

step 2: create Particles

1
2
3
4
5
// create particles
Particle* p1 = new Particle(1, 0, 0);
Particle* p2 = new Particle(2, 10, 0);
system.addParticle(p1);
system.addParticle(p2);

Particle::Particle(int id, double x, double y, double z=0) create a Particle object, which has a unique id and located at \((x, y, z)\) in global coordinate system. Then using StructSystem::addParticle(Particle* p) to put the Particle object into system object in order to manage the Particle objects.

step 3: create Materials and Sections (necessary in bar structures)

1
2
3
4
5
6
7
8
9
// create material
LinearElastic mat = LinearElastic(1);
mat.setE(1.0E6);
mat.setDensity(10);

// create section
CustomSectionParas paras = {.A=1, .Sy=0, .Sz=0, .SHy=0, .SHz=0,
.CGy=0, .CGz=0.0, .Iyy=10, .Izz=10, .Iyz=10};
CustomSection sect = CustomSection(1, paras);

LinearElastic::LinearElastic(int id) create a LinearElastic material object; LinearElastic::setE(double val) and LinearElastic::setDensity(double val) set the Young's modulus and density of the material respectively. openVFIFE also provide UniIdeal and UniBilinear for uniaxial rate-independent plastic material, you can read the headers in ./headers/material directory.

CustomSetcion::CustomSection(int id, const CustomSectionParas &para) create a CustomSection object, which means you can assign the section characteristics. openVFIFE also provide Rectangle, AngleSteel and Ctube sections, you can read the headers in ./headers/section directory.

step 4: create Elements

1
2
3
// create elements
Link2D* e = new Link2D(1, p1, p2, &mat, &sect);
system.addElement(e);

Link2D::Link2D(int id, Particle* pi, Particle* pj, const BaseMaterial* mat, const BaseSection* sect) create a planar link element. StructSystem::addElement(BaseElement* e) put the element into system.

step 5: add constraints

1
2
3
4
5
6
7
// constraints, Ux, Uy, Uz, Rotx, Roty, Rotz
DOF c1 = {.key = {true, true, true, true, true, true},
.val = {0, 0, 0, 0, 0, 0}};
DOF c2 = {.key = {false, true, true, true, true, true},
.val = {0, 0, 0, 0, 0, 0}};
system.addConstraint(1, c1);
system.addConstraint(2, c2);

StructSystem::addConstraint(int pid, const DOF &d) constraint Paricle pid.

step 6: add external force and solve

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// external force, typedef array<double, 6> StdArray6d;
StdArray6d f1 = {100, 0, 0, 0, 0, 0};

int nStep = ceil(endTime/h);
int interval = ceil(0.1/h);
for (int i = 0; i <= nStep; i++)
{
if (i == 0) // first step
{
system.addExternalForce(2, f1); // add external force
system.solve(h, zeta, true);
system.setInternalForce();
}
else // n > 1
{
system.solve(h, zeta);
system.clearParticleForce();
system.setExternalForce(2, f1);
system.setInternalForce();
}

// save results
if (i % interval == 0)
{
string path = system.workdir() + "/" + system.jobname() + "/" + to_string(i*h);
system.saveParticleResult(path);
system.saveElementResult(path);
system.saveSupportReact(path);
}
}

int nStep = ceil(endTime/h); calculate the total time steps \(n = \frac{t}{\Delta t}\)

If you do not want save results of every step, you can set a int interval = ceil(0.1/h); for skip some steps.

In the first time step, we set external force by StructSystem::addExternalFroce(int pid, const StdArray6d &force) of Particle (id). Then StructSystem::solve(double h, double zeta, const bool firststep) solve the gorverning equation at \(t=0\). Then StructSystem::setInternalForce() assign all element internal force to all Particles.

In the other step (\(t>0\)), StructSystem::solve(double h, double zeta, const bool firststep=false) solve the governing equation (movement of all the particles). StructSystem::clearParticleForce() remove all the forces acted on the particles, and then StructSystem::setExternalForce(int pid, const StdArray6d &force) add the external forces, StructSystem::setInternalForce() add the element internal force to all particles.

string path = system.workdir() + "/" + system.jobname() + "/" + to_string(i*h); set the directory for saving results. StructSystem::saveParticleResult(const string &path), StructSystem::saveElementResult(const string &path) and StructSystem::saveSupportReact(const string &path) save the computing results of all particles, elements and support reactions.

Results

when \(\Delta t = 0.01\), the axail force of the bar

\(\zeta\) Target (N) openVFIFE
0.0 100.0 --
0.5 100.0 100.0
1.0 100.0 100.0

if \(\zeta= 0.0\), the axial force of the bar will not converge (umdamped free vibration); and when \(\zeta\) increased, the answer will finally converge to the static solution, and the larger \(\zeta\) is, the faster convergence is. Besides, \(\zeta\) won't affect the static solution. Hence, for static problems, large \(\zeta\) could be adopted to help converge.

The critical time step \[ \Delta t_{critical} = \frac{2l}{v_c} = \frac{2l}{\sqrt{E/\rho}}=0.0316s \] when \(\zeta= 0.5\), the axail force of the bar

\(\Delta t\) Target (N) openVFIFE
0.001 100.0 99.89860658682635
0.01 100.0 99.89854111776447
0.1 100.0 nan
0.5 100.0 nan

Fig. Axial Force of The Bar, (a) \(\Delta t = 0.001, 0.01\), (b) \(\Delta t = 0.001, 0.01, 0.1, 0.5\),

If \(\Delta t > \Delta t_{critical}\), the solution will unconverge, hence it is important to assign time step. openVFIFE provides a autoTimeStep() function for setting proper time step automaticly.

For more examples, see ./examples.

Where to go from here?

The detailed and completed documentations for users and developers are still under construction. The author hope the researchers who are interested on vector form instrinsic finite element can contribute to this project for building a easy and robust general software.

TODO LIST

  • provide a detailed and well organized documentation for users and developers
  • write makefiles
  • write a unittest for this library
  • redesign and refactor the project to fit more incoming functions
  • introduce a script language (tcl/tk, lua or python3) to make the software easy to use

Ultimate Goal

  • build a open source software like openSees and openFoam
  • Post title:User Guide of openVFIFE
  • Post author:GinkGo
  • Create time:2021-06-13 00:41:02
  • Post link:https://ginkgoltd.github.io/2021/06/13/openVFIFE_quick_strart/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.