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’’.

Hint

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.

../../_images/vba_single_span_girder_1.png

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.

../../_images/stress_strain.svg../../_images/single_span_girder_cross_section.svg

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

Problem Solution#

The following example can be found in the SOFiSTiK directory:

C:\<sofistik_installation>\2024\SOFiSTiK 2024\interfaces\examples\vb.net\single_span_girder

Note

Please run the SINGLE_SPAN_GIRDER.DAT file to generate the CDB.

In the Visual Basic .NET example folder, the main files are:

  • single_span_girder.sln (the solution)

  • main.vb (main .VB file)

  • single_span_girder.dat (.DAT file to generate the CDB)

  • sof_class.vb Classes

  • single_span_girder.vbproj Visual Studio Project file

The main.vb#

In the main module first the dlls functions are defined:

Imports System.Runtime.InteropServices

Module main

   Public Declare Function sof_cdb_init Lib "sof_cdb_w-2024.dll" Alias "VB_sof_cdb_init" (
      ByVal name As String,
      ByVal InitType As Integer
   ) As Integer

   Public Declare Function sof_cdb_status Lib "sof_cdb_w-2024.dll" Alias "VB_sof_cdb_status" (
      ByVal Index As Integer
   ) As Integer

   Public Declare Function sof_cdb_close Lib "sof_cdb_w-2024.dll" Alias "VB_sof_cdb_close" (
      ByVal Index As Integer
   ) As Integer

   Public Declare Function sof_cdb_flush Lib "sof_cdb_w-2024.dll" Alias "VB_sof_cdb_flush" (
      ByVal Index As Integer
   ) As Integer

   ' ...

where:

Imports System.Runtime.InteropServices

is used for importing DLLs. For more details about the functions please read the CDBASE.CHM description.

Next step is to define the environment path variable. The 64-bit DLLs are used, therefore the path to the 64-bit DLLs is added to the path environment.

Public Sub Main()
   Dim Filename As String
   Dim ie As Integer
   Dim Path As String
   Dim analysisPath As String
   Dim datalen As Integer
   Dim analysisPath2 As String

   'Path of the SOFiSTIK Directory
   analysisPath = "C:\sofistik_installation\trunk\SOFiSTiK trunk\interfaces\64bit"
   analysisPath2 = "C:\sofistik_installation\trunk\SOFiSTiK trunk"

   'Set the environment variable
   Path = Environment.GetEnvironmentVariable("path")
   Path = analysisPath2 + ";" + analysisPath + ";" + Path
   Environment.SetEnvironmentVariable("path", Path)

   ' ...

with:

Environment.SetEnvironmentVariable("path", Path)

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

Next step is to connect to the CDB.

'##################################################
'# Connect to the CDB

ie = sof_cdb_init(Filename, 99)
If ie < 0 Then
   Console.WriteLine("ERROR: Index= " & ie & " < 0 - see clib1.h for meaning of error codes")
   Console.ReadKey()
   Exit Sub
ElseIf ie = 0 Then
   Console.WriteLine("ERROR: Index= " & ie & " - The File is not a database")
   Console.ReadKey()
   Exit Sub
End If

Now lets read the fck value from the CDB.

'##################################################
'# Read the data
'#  sof_cdb_get()

' READ THE f_ck VALUE
Dim d_cmat_conc As New CMAT_CONC()
Dim fck As Single
' Get the data-length
datalen = Marshal.SizeOf(d_cmat_conc)

' Print the values
Do While Cc_mat_conc.sof_cdb_get(ie, 1, 1, d_cmat_conc, datalen, 1) < 2
   If (d_cmat_conc.m_ID = 1) Then
      fck = d_cmat_conc.m_FCK
   End If
   datalen = Marshal.SizeOf(d_cmat_conc)
Loop

' Release all locks. All memory for directories and
'     data is released.
' Only after this call the directory structure is
'     reread which allows the access to newly
'     defined keys.
Call sof_cdb_flush(ie)

We are looping through the record, until end is reached (return value = 2):

Do While Cc_mat_conc.sof_cdb_get(ie, 1, 1, d_cmat_conc, datalen, 1) < 2

The d_cmat_conc can be found in the cc_mat_conc class. It is necessary to update the datalen always before sof_cdb_get is called.

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

' READ THE f_yk VALUE
Dim d_cmat_stee As New CMAT_STEE

' In VB.NET fixed array in structs are not supported
' please see the structure CMAT_STEE
' all arrays must be redimensioned
' size = 2 (m_DUMMY(0), m_DUMMY(1))
ReDim d_cmat_stee.m_DUMMY(1)
Dim fyk As Single
' Get the data-length
datalen = Marshal.SizeOf(d_cmat_stee)

' Print the values
Do While Cc_mat_stee.sof_cdb_get(ie, 1, 2, d_cmat_stee, datalen, 1) < 2
   If (d_cmat_stee.m_ID = 1) Then
      fyk = d_cmat_stee.m_FY
   End If
   datalen = Marshal.SizeOf(d_cmat_stee)
Loop

' Release all locks
Call sof_cdb_flush(ie)

' READ THE b, h, so, su
Dim d_sect_rec As New CSECT_REC

' Get the data-length
datalen = Marshal.SizeOf(d_sect_rec)
Dim b As Single
Dim h As Single
Dim so As Single
Dim su As Single

' kwh = 9, kwl = 1
Do While (Cc_sect_rec.sof_cdb_get(ie, 9, 1, d_sect_rec, datalen, 1) < 2)
   If (d_sect_rec.m_ID = 10) Then
      b = d_sect_rec.m_B
      h = d_sect_rec.m_H
      so = d_sect_rec.m_SO
      su = d_sect_rec.m_SU
   End If
   datalen = Marshal.SizeOf(d_sect_rec)
Loop

' Release all locks
Call sof_cdb_flush(ie)

' READ THE INTERNAL FORCES M, N
Dim d_beam_foc As New CBEAM_FOC

' Get the data-length
datalen = Marshal.SizeOf(d_beam_foc)
Dim Ned As Single
Dim Med As Single

' kwh = 102, kwl = 1001
Do While (Cc_beam_foc.sof_cdb_get(ie, 102, 1001, d_beam_foc, datalen, 1) < 2)
   If (d_beam_foc.m_ID = 0) Then
      If (Math.Abs(Ned) < Math.Abs(d_beam_foc.m_N)) And (Math.Abs(d_beam_foc.m_N) < 1.0E+35) Then
            Ned = d_beam_foc.m_N
      End If
      If (Math.Abs(Med) < Math.Abs(d_beam_foc.m_MY)) And (Math.Abs(d_beam_foc.m_MY) < 1.0E+35) Then
            Med = d_beam_foc.m_MY
      End If
   End If
   datalen = Marshal.SizeOf(d_beam_foc)
Loop

' Release all locks
Call sof_cdb_flush(ie)

The iteration starts from εs1 = 25 ‰ and εc2 = 0 ‰. First the εs1 is modified and iterated. When it reaches the minimum the program iterates εc2 value from 0 to 3.5 ‰.

Do While (Mrd <= Meds) And (mu <= 0.296)

As shown above the μ value must be μ < 0.296 to avoid additional symmetrical reinforcement (x/d ≤ 0.45):

fyd = fyks

γs = 1.15

The formulas for fcd:

fcd = αcc·(fckc)

where: αcc = 0.85 and γc = 1.50

The d value can not be read from the CDB but can be calculated by reading the su value (representing d1) d = h - su.

The conditions for the calculations are:

ΣM = 0 Myd = Fc·z = Fs1·z

ΣH = 0 Fc = Fs1

'**************************************************
' CROSS SECTION DESIGN
' iterating the reinforcement to get equilibrium
Dim epss As Single
epss = 25
Dim epsc As Single
Dim Mrd As Single
Dim mu As Single
Dim alpha As Single
Dim xi As Single
Dim x As Single
Dim d As Single
d = h - su
Dim ka As Single
Dim z As Single
Dim zeta As Single
Dim omega As Single
Dim fcd As Single
fcd = (fck * 0.85) / 1.5
Dim fyd As Single
fyd = fyk / 1.15
Dim As1 As Single
Dim Meds As Single

Meds = Med - Ned * (h / 2 - su)

' Iterate the reinforcement
Do While (Mrd <= Meds) And (mu <= 0.296)
   If (epsc >= 0) And (epsc <= 2) Then
      alpha = epsc / 12 * (6 - epsc)
   ElseIf (epsc > 2) And (epsc <= 3.5) Then
      alpha = (3 * epsc - 2) / (3 * epsc)
   End If


   ' Calculate the Xi value
   xi = epsc / (epss + epsc)

   ' Calculate x
   x = xi * d

   ' Calcualte ka
   If (epsc >= 0) And (epsc <= 2) Then
      ka = (8 - epsc) / (4 * (6 - epsc))
   ElseIf (epsc < 2) And (epsc <= 3.5) Then
      ka = (epsc * (3 * epsc - 4) + 2) / (2 * epsc * (3 * epsc - 2))
   End If

   ' Calculate z
   z = d - ka * x

   ' Calculate zeta
   zeta = 1 - ka * xi

   ' Calculate omega
   omega = alpha * xi

   ' Calculate mu
   mu = alpha * xi * zeta

   ' Calculate the Mrd resistance moment
   Mrd = alpha * xi * d * b * fcd * zeta * d

   ' Required reinforcement
   As1 = (1 / fyd) * (omega * b * d * fcd + Ned)


   If (epsc >= 3.5) Then
      Do While (Mrd <= Meds) And (epss >= 0) And (mu < 0.296)
            If (epsc > 0) And (epsc <= 2) Then
               alpha = epsc / 12 * (6 - epsc)
            ElseIf (epsc > 2) And (epsc <= 3.5) Then
               alpha = (3 * epsc - 2) / (3 * epsc)
            End If

            ' Calculate the Xi value
            xi = epsc / (epss + epsc)

            ' Calculate x
            x = xi * d

            ' Calculate ka
            If (epsc > 0) And (epsc <= 2) Then
               ka = (8 - epsc) / (4 * (6 - epsc))
            ElseIf (epsc > 2) And (epsc <= 3.5) Then
               ka = (epsc * (3 * epsc - 4) + 2) / (2 * epsc * (3 * epsc - 2))
            End If

            ' Calculate z
            z = d - ka * x

            ' Calculate zeta
            zeta = 1 - ka * xi

            ' Calculate omega
            omega = alpha * xi

            ' Calculate mu
            mu = alpha * xi * zeta

            ' Calculate the Mrd resistance moment
            Mrd = alpha * xi * d * b * fcd * zeta * d

            ' Required reinforcement
            As1 = (1 / fyd) * (omega * b * d * fcd + Ned)

            If (epss = 0) Then
               Console.WriteLine("Reinforcement reached 0 [o/oo]")
            End If

            ' Iterate epss
            epss = epss - 0.001
      Loop
   End If
   ' Iterate epsc
   epsc = epsc + 0.001
Loop

'**************************************************
'* OUTPUT
Console.WriteLine("{0,-6} {1,6} {2,-12} {3,0}", "fcd", "=", fcd / 1000, "[MPa]")
Console.WriteLine("{0,-6} {1,6} {2,-12} {3,0}", "fyd", "=", fyd / 1000, "[MPa]")
Console.WriteLine("{0,-6} {1,6} {2,-12} {3,0}", "epsc", "=", epsc, "[o/oo]")
Console.WriteLine("{0,-6} {1,6} {2,-12} {3,0}", "epss", "=", epss, "[o/oo]")
Console.WriteLine("{0,-6} {1,6} {2,-12} {3,0}", "alpha", "=", alpha, "[-]")
Console.WriteLine("{0,-6} {1,6} {2,-12} {3,0}", "ka", "=", ka, "[-]")
Console.WriteLine("{0,-6} {1,6} {2,-12} {3,0}", "z", "=", z, "[m]")
Console.WriteLine("{0,-6} {1,6} {2,-12} {3,0}", "zeta", "=", zeta, "[-]")
Console.WriteLine("{0,-6} {1,6} {2,-12} {3,0}", "omega", "=", omega, "[-]")
Console.WriteLine("{0,-6} {1,6} {2,-12} {3,0}", "mu", "=", mu, "[-]")
Console.WriteLine("{0,-6} {1,6} {2,-12} {3,0}", "d", "=", d, "[m]")
Console.WriteLine("{0,-6} {1,6} {2,-12} {3,0}", "Xi", "=", xi, "[-]")
Console.WriteLine("-------------")
Console.WriteLine("{0,-6} {1,6} {2,-12} {3,0}", "As1", "=", As1 * 100 * 100, "[cm2]")

' This outputs the status of the CDB, please refer to cdbase.chm for more details
Console.WriteLine("Index: " & ie)
Console.WriteLine("CDB Status: " & sof_cdb_status(ie))

' Close the CDB
Call sof_cdb_close(0)

'Check the CDB Status
If sof_cdb_status(ie) = 0 Then
   Console.WriteLine("CDB closed succesfully, status = 0")
End If

Console.Write("Press any <key> to close the program")
Console.ReadKey()

At end we need to close the CDB (to avoid that CDB locks occur).

'Close the CDB
Call sof_cdb_close(0)