$ENGINE=VBSCRIPT
nUnloaded = 0
ReDim unLoadedName(0)
ReDim unLoadedStiff(2, 0)
nLoaded = 0
ReDim loadedName(0)
ReDim loadedStiff(2, 0)

' 1. Remove RTA loading 
set loadcase = database.getLoadset("Deck Temp (Manual NL)", 0)
call loadcase.removeAssignments("Loading")
set loadcase = nothing

' 2. Remove nonlinear control 
set loadcase = database.getLoadset("Deck Temp (Manual NL)", 0)
call loadcase.removeTransientControl()
set loadcase = nothing

' 3. Change loadcase name to "Loadcase 1" 
set loadcase = database.getLoadset("Deck Temp (Manual NL)", 0)
call loadcase.setName("Loadcase 1")
set loadcase = nothing

' 4. Add Eigenvalue control 
call database.options.setBoolean("Option 311", false, false, "Analysis 1")
call database.options.setBoolean("Option 432", false, false, "Analysis 1")
set loadcase = database.getLoadset("Loadcase 1", 0)
call loadcase.setEigenvalueRangeControl("Frequency", "Frequency", 50.0, 0.0, 0)
call loadcase.getEigenvalueControl().setValue("MaxIterations", 30).setValue("SuccessiveTolerance", 0.1E-3)
call loadcase.getEigenvalueControl().setValue("NormalisationProcedure", "GlobalMass").setValue("Eigensolver", "Default")
set loadcase = nothing

' 5. Give all necessary materials their correct densities
set attr = database.createIsotropicMaterial("Rail Material Property (elastic)", "210.0E9", "0.3", "7.85E3").setValue("alpha", "12.0E-6", 0)
set attr = nothing
set attr = database.createIsotropicMaterial("Deck EN1992-2:2005 C35/45", "34.0E9", "0.2", "2.54842E3").setValue("alpha", "10.0E-6", 0)
set attr = nothing
set attr = database.createIsotropicMaterial("Deck EN1992-2:2005 C50/60", "36.0E9", "0.2", "2.54842E3").setValue("alpha", "10.0E-6", 0)
set attr = nothing
set attr = database.createIsotropicMaterial("Deck EN1992-2:2005 C60/75", "38.0E9", "0.2", "2.54842E3").setValue("alpha", "10.0E-6", 0)
set attr = nothing
set attr = database.createIsotropicMaterial("Pier EN1992-2:2005 C25/30", "31.0E9", "0.2", "2.54842E3").setValue("alpha", "10.0E-6", 0)
set attr = nothing

' 6. Define a weightless material for the rigid offsets and assign it to
' those features so they do not have massive mass
set attr = database.createIsotropicMaterial("Rigid Deck Offsets EN1992-2:2005 C35/45", "34.0E9", "0.2", "0.0").setValue("alpha", "10.0E-6", 0)
set attr = nothing
set attr = database.createIsotropicMaterial("Rigid Deck Offsets EN1992-2:2005 C50/60", "36.0E9", "0.2", "0.0").setValue("alpha", "10.0E-6", 0)
set attr = nothing
set attr = database.createIsotropicMaterial("Rigid Deck Offsets EN1992-2:2005 C60/75", "38.0E9", "0.2", "0.0").setValue("alpha", "10.0E-6", 0)
set attr = nothing

Dim deckMat(2), rigidMat(2)
deckMat(0)  = "Deck EN1992-2:2005 C35/45"
rigidMat(0) = "Rigid Deck Offsets EN1992-2:2005 C35/45"
deckMat(1)  = "Deck EN1992-2:2005 C50/60"
rigidMat(1) = "Rigid Deck Offsets EN1992-2:2005 C50/60"
deckMat(2)  = "Deck EN1992-2:2005 C60/75"
rigidMat(2) = "Rigid Deck Offsets EN1992-2:2005 C60/75"

For imat = 0 To UBound(deckMat)
    ' Get the rigid support offsets for the decks
    call selection.remove("All")
    set attr = database.getAttribute("Line Geometric", "Rigid Support Offset")
    call assignment.setIgnoreAll()
    call selection.add(attr)
    set attr = nothing
    ' Select the current deck material to keep
    call database.options.setBoolean("associateDown", false)
    call selection.keep("Material", deckMat(imat))
    call database.options.setBoolean("associateDown", true)
    ' Assign the weightless material to the rigid support offsets
    call assignment.setAllDefaults()
    call assignment.setLoadset("Loadcase 1")
    call database.getAttribute("Isotropic Material", rigidMat(imat)).assignTo(selection, assignment)
Next
call selection.remove("All")

' 7. Give the "Fixed Track Lateral" and "Fixed Track Ends" extra support
set attr = database.createSupportStructural("Fixed Track Lateral")
call attr.setStructural("F", "F", "R", "R", "R", "F", "F", "F", "C", "F")
call attr.setAnalysisCategory("3D")
set attr = nothing
set attr = database.createSupportStructural("Fixed Track Ends")
call attr.setStructural("R", "R", "R", "R", "R", "R", "F", "F", "C", "F")
call attr.setAnalysisCategory("3D")
set attr = nothing

' 8. Change the usage type of all of the interaction joints to "Normal" to allow their assignments to be changed
matAttr = database.getAttributes("Material", "All") 
For iattr = 0 To UBound(matAttr)
    If StrComp(matAttr(iattr).getUsageType(),"RailTrack",1) = 0 Then
        ' Update the storage for unloaded or loaded joints
        matName = matAttr(iattr).getName()
        Stiff = matAttr(iattr).getValue("K")
        If InStr(1, matName, "Unloaded spring", 1) > 0 Then
            nUnloaded = nUnloaded + 1
            If nUnloaded > 1 Then
                ReDim Preserve unLoadedName(nUnloaded - 1)
                ReDim Preserve unLoadedStiff(2, nUnloaded - 1)
            End If
            unLoadedName(nUnloaded - 1) = matName
            For istiff = 0 To UBound(Stiff)
                unLoadedStiff(istiff, nUnloaded - 1) = Stiff(istiff)
            Next
        Else
            nLoaded = nLoaded + 1
            If nLoaded > 1 Then
                ReDim Preserve loadedName(nLoaded - 1)
                ReDim Preserve loadedStiff(2, nLoaded - 1)
            End If
            loadedName(nLoaded - 1) = matName
            For istiff = 0 To UBound(Stiff)
                loadedStiff(istiff, nLoaded - 1) = Stiff(istiff)
            Next
        End If
        ' Set to "normal"
        matAttr(iattr).setUsageType("normal")
    End If
Next

' 9. Define new half unloaded/loaded linear interaction joints properties for each of the definitions
'    and over-assign the unloaded interaction joint definition with the new linear definition
call selection.remove("All")
For iattr = 0 To UBound(unLoadedName)
    iposBall = InStr(1, unLoadedName(iattr), "(", 1)
    attrName = Mid(unLoadedName(iattr), iposBall)
    Call defineHalfUnloadLoadSpring(iattr, unLoadedStiff, loadedStiff, attrName)
    ' Select the assignments of the unloaded interaction joint definition
    set attr = database.getAttribute("Joint Material", unLoadedName(iattr))
    call assignment.setIgnoreAll()
    call selection.add(attr)
    set attr = nothing
    ' Assign the new linear definition
    call assignment.setAllDefaults()
    call assignment.setLoadset("Loadcase 1")
    call database.getAttribute("Joint Material", attrName).assignTo(selection, assignment)
    ' Clear the selection
    call selection.remove("All")
Next

' 10. Define new joints to replace the expansion joints and effectively "lock" them
matAttr = database.getAttributes("Material", "All") 
For iattr = 0 To UBound(matAttr)
    matName = matAttr(iattr).getName()
    If InStr(1, matName, "Rail Expansion Joint", 1) > 0 Then
        Call defineLockedExpansionJoint(matName, newExpJntName)
        ' Clear the selection
        call selection.remove("All")
        ' Select the assignments of the original expansion joint
        set attr = database.getAttribute("Joint Material", matName)
        call assignment.setIgnoreAll()
        call selection.add(attr)
        set attr = nothing
        ' Assign the new locked expansion joint
        call assignment.setAllDefaults()
        call assignment.setLoadset("Loadcase 1")
        call database.getAttribute("Joint Material", newExpJntName).assignTo(selection, assignment)
        ' Clear the selection
        call selection.remove("All")
    End If
Next

' 11. Define and assign any search areas required to the tracks 
call selection.remove("All")
For iTrk = 1 To 10
    trackName = "Track " & iTrk
    If database.existsGroupByName(trackName) Then
        ' Define search area
        set attr = database.createSearchArea(trackName)
        set attr = nothing
        ' Add track features to selection
        call selection.add("Group", trackName, "Recurse")
        ' Assign search area to the selection
        call assignment.setAllDefaults()
        call assignment.setSelectionNone()
        call assignment.addToSelection("Line")
        call assignment.setLoadset("Loadcase 1")
        call database.getAttribute("Search Area", trackName).assignTo(selection, assignment)
        call database.updateMesh()
        ' Clear the selection
        call selection.remove("All")
    End If
Next

' 12. Define the unit axle load
redim FEAtemp(2)
FEAtemp(0) = 0.0
FEAtemp(1) = 1.0
FEAtemp(2) = 0.0
set attr = database.createLoadingDiscretePoint("Unit Axle Load")
call attr.setDiscrete("Y", FEAtemp, 0, 0)
call attr.addRow(0.0, 0.0, 0.0, "-1.0")
erase FEAtemp
call attr.setAnalysisCategory("3D")
set attr = nothing


' What remains to be done is:
'
' 13. Define the lines for the paths for each track, ensuring the line directions match the travel 

' 14. Define any vehicles required, in this case we are using the train from the worked example 

' 15. Save the model 



Sub defineHalfUnloadLoadSpring(imat, unloadedK, loadedK, attributeName)
    ' Create Half Unloaded/Loaded spring (Ballast ID=?;EffWidth=?)
    ballEffWdt = attributeName
    attributeName = "Half Unloaded/Loaded spring " & Trim(ballEffWdt)

    redim FEAtemp1(2)
    redim FEAtemp2(2)
    redim FEAtemp3(2)
    redim FEAtemp4(2)
    redim FEAtemp5(2)
    redim FEAtemp6(2)
    FEAtemp1(0) = 0.5 * (unloadedK(0, imat) + loadedK(0, imat))
    FEAtemp2(0) = "0.0"
    FEAtemp3(0) = 0.0
    FEAtemp4(0) = 0.0
    FEAtemp5(0) = 0.0
    FEAtemp6(0) = 0.0
    FEAtemp1(1) = 0.5 * (unloadedK(1, imat) + loadedK(1, imat))
    FEAtemp2(1) = "0.0"
    FEAtemp3(1) = 0.0
    FEAtemp4(1) = 0.0
    FEAtemp5(1) = 0.0
    FEAtemp6(1) = 0.0
    FEAtemp1(2) = 0.5 * (unloadedK(2, imat) + loadedK(2, imat))
    FEAtemp2(2) = "0.0"
    FEAtemp3(2) = 0.0
    FEAtemp4(2) = 0.0
    FEAtemp5(2) = 0.0
    FEAtemp6(2) = 0.0
    set attr = database.createGeneralJointMaterial(attributeName, "Between nodes", FEAtemp1, FEAtemp2)
    call attr.setValue("Assignment", "Point")
    call attr.setValue("alpha", FEAtemp3, 0)
    call attr.setValue("ar", FEAtemp4, 0)
    call attr.setValue("br", FEAtemp5, 0)
    call attr.setValue("eta", FEAtemp6, 0)
    erase FEAtemp1
    erase FEAtemp2
    erase FEAtemp3
    erase FEAtemp4
    erase FEAtemp5
    erase FEAtemp6
    call attr.setAnalysisCategory("3D")
    set attr = nothing

End Sub

Sub defineLockedExpansionJoint(expJntName, lockExpJntName)
    ' Create the locked expansion joint for the attribute name supplied
    ' in expJntName, the new attribute name will be in lockExpJntName
    materAttr = database.getAttributes("Material", "All") 
    For iMatAttr = 0 To UBound(materAttr)
        materName = materAttr(iMatAttr).getName()
        If StrComp(materName, expJntName, 1) = 0 Then
            ElasK = materAttr(iMatAttr).getValue("K")
            lockExpJntName = "Locked " & expJntName

            redim FEAtemp1(5)
            redim FEAtemp2(5)
            redim FEAtemp3(5)
            redim FEAtemp4(5)
            redim FEAtemp5(5)
            redim FEAtemp6(5)
            FEAtemp1(0) = ElasK(0)
            FEAtemp2(0) = "0.0"
            FEAtemp3(0) = 0.0
            FEAtemp4(0) = 0.0
            FEAtemp5(0) = 0.0
            FEAtemp6(0) = 0.0
            FEAtemp1(1) = ElasK(1)
            FEAtemp2(1) = "0.0"
            FEAtemp3(1) = 0.0
            FEAtemp4(1) = 0.0
            FEAtemp5(1) = 0.0
            FEAtemp6(1) = 0.0
            FEAtemp1(2) = ElasK(2)
            FEAtemp2(2) = "0.0"
            FEAtemp3(2) = 0.0
            FEAtemp4(2) = 0.0
            FEAtemp5(2) = 0.0
            FEAtemp6(2) = 0.0
            FEAtemp1(3) = ElasK(3)
            FEAtemp2(3) = "0.0"
            FEAtemp3(3) = 0.0
            FEAtemp4(3) = 0.0
            FEAtemp5(3) = 0.0
            FEAtemp6(3) = 0.0
            FEAtemp1(4) = ElasK(4)
            FEAtemp2(4) = "0.0"
            FEAtemp3(4) = 0.0
            FEAtemp4(4) = 0.0
            FEAtemp5(4) = 0.0
            FEAtemp6(4) = 0.0
            FEAtemp1(5) = ElasK(5)
            FEAtemp2(5) = "0.0"
            FEAtemp3(5) = 0.0
            FEAtemp4(5) = 0.0
            FEAtemp5(5) = 0.0
            FEAtemp6(5) = 0.0
            set attr = database.createGeneralJointMaterial(lockExpJntName, "Between nodes", FEAtemp1, FEAtemp2)
            call attr.setValue("Assignment", "Point")
            call attr.setValue("alpha", FEAtemp3, 0)
            call attr.setValue("ar", FEAtemp4, 0)
            call attr.setValue("br", FEAtemp5, 0)
            call attr.setValue("eta", FEAtemp6, 0)
            erase FEAtemp1
            erase FEAtemp2
            erase FEAtemp3
            erase FEAtemp4
            erase FEAtemp5
            erase FEAtemp6
            call attr.setAnalysisCategory("3D")
            set attr = nothing

        End If
    Next
    
End Sub
