A First Vfs Program
As an example of a simple VfsTools application the following program computes the deflection of two truss elements under a load. The resulting deflections are printed to standard output.
A First Program - C Version
#include <stdio.h>
#include <math.h>
#include "sam/vfs/vfs.h"
/* Stiffnesses (Lower Triangle) for Two Trusses */
static Vdouble kt[2][10] = {
{100., 0., 0., -100., 0., 100., 0., 0., 0., 0.},
{0., 0., 100., 0., 0., 0., 0., -100., 0., 100.},
};
/* Connectivity for Two Trusses */
static Vint ix[2][2] = {{1, 2}, {2, 3}};
/* Generic Truss Dof Map */
static Vint loc[4] = {1, 1, 2, 2};
static Vint tag[4] = {SYS_DOF_TX, SYS_DOF_TY, SYS_DOF_TX, SYS_DOF_TY};
/*
_ 10. load at 45 degrees
/|
/
1 -/\/\- 2
pin |
/
\
|
3
pin
*/
/*----------------------------------------------------------------------
Solve for Displacement of Two Trusses.
----------------------------------------------------------------------*/
int
main()
{
vfs_SysMatrix* sysmatrix;
vfs_SysVector *load, *soln;
vfs_DofTab* doftab;
Vint numnp, numel;
Vint nix, nndofs, nedofs;
Vint eid, nid;
Vint restag[2];
Vint neq, nre;
Vint lodtag[2];
Vdouble lodval[2];
Vint lm[4];
Vint soltag[2];
Vdouble solval[2];
/* Set number of nodes, elements */
numnp = 3;
numel = 2;
/* Set number of nodes per element */
nix = 2;
/* Set dof per node, dof per element */
nndofs = 2;
nedofs = nix * nndofs;
/* Create degree of freedom table */
doftab = vfs_DofTabBegin();
vfs_DofTabDef(doftab, numnp, numel);
/* Loop over elements to set degree of freedom use */
vfs_DofTabSetMap(doftab, nedofs, loc, tag);
for (eid = 1; eid <= numel; eid++) {
vfs_DofTabElemUse(doftab, eid, nix, ix[eid - 1]);
}
/* Suppress all translations at nodes 1 and 3 */
restag[0] = SYS_DOF_TX;
restag[1] = SYS_DOF_TY;
nid = 1;
vfs_DofTabNodePerm(doftab, nid, nndofs, restag);
nid = 3;
vfs_DofTabNodePerm(doftab, nid, nndofs, restag);
/* Process dof table, count equations and reactions */
vfs_DofTabProcess(doftab, &neq, &nre);
/* Create system stiffness matrix */
sysmatrix = vfs_SysMatrixBegin();
vfs_SysMatrixDef(sysmatrix, SYSMATRIX_SYMM_SPARSE, neq);
vfs_SysMatrixSetObject(sysmatrix, VFS_DOFTAB, (Vobject*)doftab);
/* Initialize */
vfs_SysMatrixPreProcess(sysmatrix);
vfs_SysMatrixInit(sysmatrix, 0.);
/* Assemble actual stiffness */
for (eid = 1; eid <= numel; eid++) {
vfs_DofTabElemDof(doftab, eid, nix, ix[eid - 1], &nedofs, lm);
vfs_SysMatrixAssem(sysmatrix, nedofs, lm, kt[eid - 1]);
}
/* Factorize matrix */
vfs_SysMatrixProcess(sysmatrix);
vfs_SysMatrixFactor(sysmatrix);
/* Create system vector for assembled load */
load = vfs_SysVectorBegin();
vfs_SysVectorDef(load, neq);
/* Define load at node 2 */
nid = 2;
lodtag[0] = SYS_DOF_TX;
lodtag[1] = SYS_DOF_TY;
vfs_DofTabNodeDof(doftab, nid, nndofs, lodtag, lm);
lodval[0] = .5 * sqrt(2.) * 10.;
lodval[1] = .5 * sqrt(2.) * 10.;
vfs_SysVectorAssem(load, nndofs, lm, lodval);
/* Create system vector for solution */
soln = vfs_SysVectorBegin();
vfs_SysVectorDef(soln, neq);
/* Backsubstitution for solution */
vfs_SysMatrixSolve(sysmatrix, load, soln);
/* Gather and print solution */
printf("Displacements\n");
soltag[0] = SYS_DOF_TX;
soltag[1] = SYS_DOF_TY;
for (nid = 1; nid <= numnp; nid++) {
vfs_DofTabNodeDof(doftab, nid, nndofs, soltag, lm);
solval[0] = 0.;
solval[1] = 0.;
vfs_SysVectorGather(soln, nndofs, lm, solval);
printf(" nid= %d ux= %10f uy= %10f\n", nid, solval[0], solval[1]);
}
/* Delete objects */
vfs_DofTabEnd(doftab);
vfs_SysVectorEnd(load);
vfs_SysVectorEnd(soln);
vfs_SysMatrixEnd(sysmatrix);
return 0;
}
A First Program - C++ Version
The following program is a listing of the C++ version of the same “A First Program” listed above which used C language bindings.
#include <stdio.h>
#include <math.h>
#include "sam/base/base.h"
#include "sam/vfs/vfs.h"
/* Stiffnesses (Lower Triangle) for Two Trusses */
static Vdouble kt[2][10] = {
{100., 0., 0., -100., 0., 100., 0., 0., 0., 0.},
{0., 0., 100., 0., 0., 0., 0., -100., 0., 100.},
};
/* Connectivity for Two Trusses */
static Vint ix[2][2] = {{1, 2}, {2, 3}};
/* Generic Truss Dof Map */
static Vint loc[4] = {1, 1, 2, 2};
static Vint tag[4] = {SYS_DOF_TX, SYS_DOF_TY, SYS_DOF_TX, SYS_DOF_TY};
/*
_ 10. load at 45 degrees
/|
/
1 -/\/\- 2
pin |
/
\
|
3
pin
*/
/*----------------------------------------------------------------------
Solve for Displacement of Two Trusses.
----------------------------------------------------------------------*/
int
main()
{
vfs_SysMatrix* sysmatrix;
vfs_SysVector *load, *soln;
vfs_DofTab* doftab;
Vint numnp, numel;
Vint nix, nndofs, nedofs;
Vint eid, nid;
Vint restag[2];
Vint neq, nre;
Vint lodtag[2];
Vdouble lodval[2];
Vint lm[4];
Vint soltag[2];
Vdouble solval[2];
/* Set number of nodes, elements */
numnp = 3;
numel = 2;
/* Set number of nodes per element */
nix = 2;
/* Set dof per node, dof per element */
nndofs = 2;
nedofs = nix * nndofs;
/* Create degree of freedom table */
doftab = new vfs_DofTab;
doftab->Def(numnp, numel);
/* Loop over elements to set degree of freedom use */
doftab->SetMap(nedofs, loc, tag);
for (eid = 1; eid <= numel; eid++) {
doftab->ElemUse(eid, nix, ix[eid - 1]);
}
/* Suppress all translations at nodes 1 and 3 */
restag[0] = SYS_DOF_TX;
restag[1] = SYS_DOF_TY;
nid = 1;
doftab->NodePerm(nid, nndofs, restag);
nid = 3;
doftab->NodePerm(nid, nndofs, restag);
/* Process dof table, count equations and reactions */
doftab->Process(&neq, &nre);
/* Create system stiffness matrix */
sysmatrix = new vfs_SysMatrix;
sysmatrix->Def(SYSMATRIX_SYMM_SPARSE, neq);
sysmatrix->SetObject(VFS_DOFTAB, (Vobject*)doftab);
/* Initialize */
sysmatrix->PreProcess();
sysmatrix->Init(0.);
/* Assemble actual stiffness */
for (eid = 1; eid <= numel; eid++) {
doftab->ElemDof(eid, nix, ix[eid - 1], &nedofs, lm);
sysmatrix->Assem(nedofs, lm, kt[eid - 1]);
}
/* Factorize matrix */
sysmatrix->Process();
sysmatrix->Factor();
/* Create system vector for assembled load */
load = new vfs_SysVector;
load->Def(neq);
/* Define load at node 2 */
nid = 2;
lodtag[0] = SYS_DOF_TX;
lodtag[1] = SYS_DOF_TY;
doftab->NodeDof(nid, nndofs, lodtag, lm);
lodval[0] = .5 * sqrt(2.) * 10.;
lodval[1] = .5 * sqrt(2.) * 10.;
load->Assem(nndofs, lm, lodval);
/* Create system vector for solution */
soln = new vfs_SysVector;
soln->Def(neq);
/* Backsubstitution for solution */
sysmatrix->Solve(load, soln);
/* Gather and print solution */
printf("Displacements\n");
soltag[0] = SYS_DOF_TX;
soltag[1] = SYS_DOF_TY;
for (nid = 1; nid <= numnp; nid++) {
doftab->NodeDof(nid, nndofs, soltag, lm);
solval[0] = 0.;
solval[1] = 0.;
soln->Gather(nndofs, lm, solval);
printf(" nid= %d ux= %10f uy= %10f\n", nid, solval[0], solval[1]);
}
/* Delete objects */
delete doftab;
delete load;
delete soln;
delete sysmatrix;
return 0;
}
A First Program - FORTRAN Version
The following program is a listing of the FORTRAN version of the same “A First Program” listed above which used C language bindings. Although the FORTRAN language does not distinguish between upper and lower case characters, the example retains the conventions employed in the C version for clarity. Note that the prefix vfs_ is replaced by vfsf_.
C
C _ 10. load at 45 degrees
C /|
C /
C 1 -/\/\- 2
C pin |
C /
C \
C |
C 3
C pin
C
C-----------------------------------------------------------------------
C Solve for Displacement of Two Trusses.
C-----------------------------------------------------------------------
program main
include 'base/fortran/base.inc'
include 'vfs/fortran/vfs.inc'
C Stiffnesses (Lower Triangle) for Two Trusses
double precision kt(10,2)
data kt /
& 100.,
& 0., 0.,
& -100., 0., 100.,
& 0., 0., 0., 0.,
& 0.,
& 0., 100.,
& 0., 0., 0.,
& 0.,-100., 0., 100. /
C Connectivity for Two Trusses
integer ix(2,2)
data ix / 1,2, 2,3 /
C Generic Truss Dof Map
integer loc(4)
data loc / 1,1, 2,2 /
integer tag(4)
data tag / SYS_DOF_TX, SYS_DOF_TY, SYS_DOF_TX, SYS_DOF_TY /
double precision sysmatrix
double precision load, soln
double precision doftab
integer numnp, numel
integer nix, nndofs, nedofs
integer eid, nid
integer restag(2)
integer neq, nre
integer lodtag(2)
double precision lodval(2)
integer lm(4)
integer soltag(2)
double precision solval(2)
C Set number of nodes, elements
numnp = 3
numel = 2
C Set number of nodes per element
nix = 2
C Set dof per node, dof per element
nndofs = 2
nedofs = nix * nndofs
C Create degree of freedom table
call vfsf_DofTabBegin (doftab)
call vfsf_DofTabDef (doftab,numnp,numel)
C Loop over elements to set degree of freedom use
call vfsf_DofTabSetMap (doftab,nedofs,loc,tag)
do eid = 1,numel
call vfsf_DofTabElemUse (doftab,eid,nix,ix(1,eid))
enddo
C Suppress all translations at nodes 1 and 3
restag(1) = SYS_DOF_TX
restag(2) = SYS_DOF_TY
nid = 1
call vfsf_DofTabNodePerm (doftab,nid,nndofs,restag)
nid = 3
call vfsf_DofTabNodePerm (doftab,nid,nndofs,restag)
C Process dof table, count equations and reactions
call vfsf_DofTabProcess (doftab,neq,nre)
C Create system stiffness matrix
call vfsf_SysMatrixBegin (sysmatrix)
call vfsf_SysMatrixDef (sysmatrix,SYSMATRIX_SYMM_SPARSE,neq)
C Preprocess stiffness matrix
call vfsf_SysMatrixSetObject (sysmatrix,VFS_DOFTAB,doftab)
call vfsf_SysMatrixPreProcess (sysmatrix)
C Initialize
call vfsf_SysMatrixInit (sysmatrix,0.)
C Assemble actual stiffness
do eid = 1,numel
call vfsf_DofTabElemDof (doftab,eid,nix,ix(1,eid),nedofs,lm)
call vfsf_SysMatrixAssem (sysmatrix,nedofs,lm,kt(1,eid))
enddo
C Factorize matrix
call vfsf_SysMatrixProcess (sysmatrix)
call vfsf_SysMatrixFactor (sysmatrix)
C Create system vector for assembled load
call vfsf_SysVectorBegin (load)
call vfsf_SysVectorDef (load,neq)
C Define load at node 2
nid = 2
lodtag(1) = SYS_DOF_TX
lodtag(2) = SYS_DOF_TY
call vfsf_DofTabNodeDof (doftab,nid,nndofs,lodtag,lm)
lodval(1) = .5*sqrt(2.)*10.
lodval(2) = .5*sqrt(2.)*10.
call vfsf_SysVectorAssem (load,nndofs,lm,lodval)
C Create system vector for solution
call vfsf_SysVectorBegin (soln)
call vfsf_SysVectorDef (soln,neq)
C Backsubstitution for solution
call vfsf_SysMatrixSolve (sysmatrix,load,soln)
C Gather and print solution
write(6,*) "Displacements"
soltag(1) = SYS_DOF_TX
soltag(2) = SYS_DOF_TY
do nid = 1,numnp
call vfsf_DofTabNodeDof (doftab,nid,nndofs,soltag,lm)
solval(1) = 0.
solval(2) = 0.
call vfsf_SysVectorGather (soln,nndofs,lm,solval)
write(6,1000) nid,solval(1),solval(2)
enddo
C Delete objects
call vfsf_DofTabEnd (doftab)
call vfsf_SysVectorEnd (load)
call vfsf_SysVectorEnd (soln)
call vfsf_SysMatrixEnd (sysmatrix)
1000 format(' nid= ',i2,' ux= ',f11.6,' uy= ',f11.6)
stop
end
A First Program - C# Version
The following program is a listing of the C# version of the same “A First Program” listed above which used C language bindings. Note that the prefix vfs_ is replaced by vfs..
using System;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Text;
using DevTools;
public class Intro1
{
/* Stiffnesses (Lower Triangle) for Two Trusses */
public static double[][] kt = {
new double[] { 100.0,
0.0, 0.0,
-100.0, 0.0, 100.0,
0.0, 0.0, 0.0, 0.0 },
new double[] { 0.0,
0.0, 100.0,
0.0, 0.0, 0.0,
0.0,-100.0, 0.0, 100.0 }
};
/* Connectivity for Two Trusses */
public static int[][] ix = {
new int[] {1,2},
new int[] {2,3}
};
/* Generic Truss Dof Map */
public static int[] loc = { 1, 1, 2, 2 };
public static int[] tag = {
vsy.SYS_DOF_TX, vsy.SYS_DOF_TY, vsy.SYS_DOF_TX, vsy.SYS_DOF_TY };
/*
_ 10. load at 45 degrees
/|
/
1 -/\/\- 2
pin |
/
\
|
3
pin
*/
/*----------------------------------------------------------------------
Set environment path
----------------------------------------------------------------------*/
public static void SetEnvironmentPath()
{
var pathVariableName = "PATH";
var scope = EnvironmentVariableTarget.Process;
var oldPathVariableValue = Environment.GetEnvironmentVariable(pathVariableName, scope);
var newPathVariableValue = oldPathVariableValue + @";${CEE_SAM_EXTERNAL_LIBRARIES_BIN_PATHS}";
Environment.SetEnvironmentVariable(pathVariableName, newPathVariableValue, scope);
}
/*----------------------------------------------------------------------
Solve for Displacement of Two Trusses.
----------------------------------------------------------------------*/
public static void Main()
{
IntPtr sysmatrix;
IntPtr load, soln;
IntPtr doftab;
int[] restag = new int[2];
int neq = 0, nre = 0;
int[] lodtag = new int[2];
double[] lodval = new double[2];
int[] lm = new int[4];
int[] soltag = new int[2];
double[] solval = new double[2];
SetEnvironmentPath();
vsy.LicenseValidate(new StringBuilder(HOOPS_LICENSE.KEY));
/* Set number of nodes, elements */
int numnp = 3;
int numel = 2;
/* Set number of nodes per element */
int nix = 2;
/* Set dof per node, dof per element */
int nndofs = 2;
int nedofs = nix * nndofs;
/* Create degree of freedom table */
doftab = vfs.DofTabBegin();
vfs.DofTabDef(doftab, numnp, numel);
/* Loop over elements to set degree of freedom use */
vfs.DofTabSetMap(doftab, nedofs, loc, tag);
int eid;
for (eid = 1; eid <= numel; eid++)
{
vfs.DofTabElemUse(doftab, eid, nix, ix[eid - 1]);
}
/* Suppress all translations at nodes 1 and 3 */
restag[0] = vsy.SYS_DOF_TX;
restag[1] = vsy.SYS_DOF_TY;
int nid = 1;
vfs.DofTabNodePerm(doftab, nid, nndofs, restag);
nid = 3;
vfs.DofTabNodePerm(doftab, nid, nndofs, restag);
/* Process dof table, count equations and reactions */
vfs.DofTabProcess(doftab, ref neq, ref nre);
/* Create system stiffness matrix */
sysmatrix = vfs.SysMatrixBegin();
vfs.SysMatrixDef(sysmatrix, vfs.SYSMATRIX_SYMM_SPARSE, neq);
vfs.SysMatrixSetObject(sysmatrix, vfs.VFS_DOFTAB, doftab);
/* PreProcess, to form matrix structure */
vfs.SysMatrixPreProcess(sysmatrix);
/* Initialize */
vfs.SysMatrixInit(sysmatrix, 0.0);
/* Assemble actual stiffness */
for (eid = 1; eid <= numel; eid++)
{
vfs.DofTabElemDof(doftab, eid, nix, ix[eid - 1], ref nedofs, lm);
vfs.SysMatrixAssem(sysmatrix, nedofs, lm, kt[eid - 1]);
}
/* Factorize matrix */
vfs.SysMatrixProcess(sysmatrix);
vfs.SysMatrixFactor(sysmatrix);
/* Create system vector for assembled load */
load = vfs.SysVectorBegin();
vfs.SysVectorDef(load, neq);
/* Define load at node 2 */
nid = 2;
lodtag[0] = vsy.SYS_DOF_TX;
lodtag[1] = vsy.SYS_DOF_TY;
vfs.DofTabNodeDof(doftab, nid, nndofs, lodtag, lm);
lodval[0] = 0.5 * Math.Sqrt(2.0) * 10.0;
lodval[1] = 0.5 * Math.Sqrt(2.0) * 10.0;
vfs.SysVectorAssem(load, nndofs, lm, lodval);
/* Create system vector for solution */
soln = vfs.SysVectorBegin();
vfs.SysVectorDef(soln, neq);
/* Backsubstitution for solution */
vfs.SysMatrixSolve(sysmatrix, load, soln);
/* Gather and print solution */
Console.Write("Displacements\n");
soltag[0] = vsy.SYS_DOF_TX;
soltag[1] = vsy.SYS_DOF_TY;
for (nid = 1; nid <= numnp; nid++)
{
vfs.DofTabNodeDof(doftab, nid, nndofs, soltag, lm);
solval[0] = 0.0;
solval[1] = 0.0;
vfs.SysVectorGather(soln, nndofs, lm, solval);
Console.Write(" nid= {0} ux= {1} uy= {2}\n", nid, solval[0], solval[1]);
}
/* Delete objects */
vfs.DofTabEnd(doftab);
vfs.SysVectorEnd(load);
vfs.SysVectorEnd(soln);
vfs.SysMatrixEnd(sysmatrix);
}
}
The output of this example program appears below.
Displacements
nid= 1 ux= 0.000000 uy= 0.000000
nid= 2 ux= 0.070711 uy= 0.070711
nid= 3 ux= 0.000000 uy= 0.000000