C#: Single Span Girder

Problem Description

In this example a single span girder will be designed according to EN 1992-2004. The input (geometry, materials, sections…) will be written in Teddy, the design will be done by using the programming interface. We will use other modules and the sof_cdb_get() to create our ‘’own AQB module’’.


Please note that the algorithm for the cross-section design is just an example, it is simplified as much as possible (we use the simplified stress-strain curve). Do NOT compare AQB with this example, because by using this code sample you will get just approximate results.

The problem consists of a single span girder. The cross-section is designed for an ultimate moment MEd and the required reinforcement is determined.


In the workbook/project example the value of σsd = fyd for ε ≥ εyd (as shown in figure). AQB uses the second curve.

To show how to get the data and manipulate with it, through the example, next values will be read from the CDB:

  • fck is the characteristic compressive strength of concrete,

  • fyd is the characteristic yield strength of concrete reinforcement,

  • h is the height of the cross-section,

  • b is the width of the cross-section,

  • SU d is the offset of bottom reinforcement,

  • MEd is the design value of applied bending moment,

  • NEd is the design value of applied axial force.


To read the mentioned values, next keys are necessary:

  • fck @Rec:(1/NR) m_FCK

  • fyk @Rec:(1/NR) m_FY

  • h @Rec:(9/NR) m_H

  • b @Rec:(9/NR) m_B

  • SU @Rec:(9/NR) m_SU

  • MEd @Rec:(102/LC) m_MY

  • NEd @Rec:(102/LC) m_N

The C# project example can be found by following:

C:\<sofistik_installation>\2020\SOFiSTiK 2020\interfaces\examples\c#\single_span_girder


Please run the SINGLE_SPAN_GIRDER.DAT to generate the CDB. The file can be found in the interfaces folder.

In the C# project, the main files are:

  • Program.cs The main class

  • Gv.cs Global variables

  • Sof_Data.cs Classes defined for reading data from CDB

The main class - program.cs

In the main program.cs, the code will be explained in details:

Define the .DLLs functions

// The sofistik_daten.cs (SofistikDataTypes) can be found in the c# example folder
using SofistikDataTypes;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//importing DLLS
using System.Runtime.InteropServices;


//importing DLLS
using System.Runtime.InteropServices;

is necessary for using the DllImport attribute.

In the class Program:

public static class Program

following .DLL functions are defined:

public static extern int sof_cdb_init()
public static extern void sof_cdb_close()
public static extern int sof_cdb_status()
public static extern int sof_cdb_flush()
public static extern int sof_cdb_free()
public static extern void sof_cdb_kenq_ex()

For more details about the functions please read the CDBASE.CHM description.

Set-up the environment variables

Next step is to define the environment variable, in this example we will use the path of the 64-bit .DLLs.

int index = 0;
int status = 0;
int datalen;

string directory1 = @"C:\sofistik_installation\2020\SOFiSTiK 2020\interfaces\64bit";
string directory2 = @"C:\sofistik_installation\2020\SOFiSTiK 2020";
string cdbPath = @"S:\test\simple_span_girder.cdb";

// Get the path
string path = Environment.GetEnvironmentVariable("path");

// Set the new path environment variable + SOFiSTiK dlls path
path = directory1 + ";" + directory2 + ";" + path;

// Set the path variable (to read the data from CDB)
System.Environment.SetEnvironmentVariable("path", path);


string cdbPath = Environment.GetEnvironmentVariable("path")

we did read the PATH environment variable. Then we added the SOFiSTiK .DLL path to the PATH variable.

Connect to CDB

If the path environment variable is defined then connect to CDB:

// connect to CDB
index = sof_cdb_init(cdbPath, 99);
// check if sof_cdb_flush is working
status = Program.sof_cdb_status(index);

Read data from CDB

Read data: kwh=1, kwl=1
// Read the f_ck value
datalen = System.Runtime.InteropServices.Marshal.SizeOf(typeof(cs_mat_conc));
cs_mat_conc mat_conc;
while (sof_cdb_get(index, 1, 1, &mat_conc, ref datalen, 1) < 2)
    if (mat_conc.m_id == 1)
        // divide with 1000 because of units kN/m^2 -> MN/m^2
        Gv.fck = mat_conc.m_fck / 1000;
        Console.WriteLine(string.Format("{0,-7}", "fck") +
            string.Format("{0,-2}", "=") +
            string.Format("{0,-15}", Gv.fck) + " MPa");

    // Get data length
    datalen = System.Runtime.InteropServices.Marshal.SizeOf(typeof(cs_mat_conc));
// Release all locks


while (sof_cdb_get(index, 1, 1, &mat_conc, ref datalen, 1) < 2)

As it is shown, index value is:

index = sof_cdb_init()

The records keys are: kwh = 1 kwl = 1

The structure c_mat_conc can be found in the SofistikDataTypes namespace. datalen checks the maximum length for data in bytes and the value will be overwritten with the actual length of the item (may be shorter or longer).

datalen = System.Runtime.InteropServices.Marshal.SizeOf(typeof(cs_mat_conc));

The principle for reading the keys KWH/KWL: 1/2, 9/1, 102/1001 is same as shown in code above.

In the statement “< 2” means read the data to end of the record:

sof_cdb_get() == 2 → CD_ERR_DATAEND (2) End of file reached

As1 reinforcement is calculated by iteration. The εs1 starts from εs1= 25‰ and the εc2 from 0‰.

The step is set to 0.001:

// Iterate epss
epss = Convert.ToSingle(epss - 0.001);

// Iterate epsc
epsc = Convert.ToSingle(epsc + 0.1);

When MRds ≥ MEds or μ = 0.296 (ξ = x/d = 0.45) the iteration is stopped.

Global variables - Gv.cs

In the Gv class the global variables are defined. It means that any code in the application has the access to read and modify the variables.

// Read the Med and Ned values
public static float Ned = 0;
public static float Med = 0;

// fck and fy value
public static float fck = 0;
public static float fy = 0;

// Read the b, h, so, su values
public static float b = 0;
public static float h = 0;
public static float so = 0;
public static float su = 0;

// design
public static float Meds = 0;