FCS Load Groups, Envelopes & Combinations

Extracted from the fcs-HBC-2-tacr production codebase (FcsEntity / AnalysisSocket).


1. FitLoadGroup — Properties

Name       := ""           # human-readable name
isOn       := True
Relation   := "Exclusive"  # combinatorial behaviour (see table below)
Load       := "Permanent"  # "Permanent" or "Variable"
Structure  := ""           # e.g. "Frame"
LoadType   := ""           # e.g. "Snow: H <= 1000", "Wind", "Cat E : Storage"
Content    := []           # child FitLoadGroup objects (tree hierarchy)
Attributes := []
isEnvironmental := False   # True → affects K_FI factor
notLeading      := True    # True → not the leading variable action (γQ1 treatment)
notStabilising  := True    # True → applies inf/sup γ values (permanent groups only)

Relation Types (Combinatorial Semantics)

Relation Variations Meaning
"Permanent" 1 All items are always present
"Together" / "TogetherOptional" 2 All present, or none at all
"Exclusive" n Exactly one of n items
"ExclusiveOptional" n+1 One of n items, or none
"Standard" / "Variable" / "Independent" 2ⁿ All possible on/off combinations

Hierarchy Rules


2. FitLoadCase — Properties

Name          := ""
isOn          := True
Description   := ""
LoadGroup     := FitLoadGroup{ Load := "Permanent" }   # reference to parent group
ActionType    := LoadGroup.Load                         # auto-derived from parent
LoadType      := "Standard"
Specification := ""
Direction     := ""
loadCaseId    := Name

Every FitLoadCase links to a FitLoadGroup via its LoadGroup property. The ActionType is automatically derived from the parent group's Load field.


3. FitLoadEnvelope & FitLoadCombination

Name           := ""
isOn           := True
Description    := ""
LimitStateType := "ULS"     # "ULS" or "SLS"
Content        := []        # list of load-case references with factors

4. FitEnvelopeSet

Name        := LimitState + " " + Equation + " " + Reference
isOn        := True
LimitState  := ""           # e.g. "ULS-Fundamental-STR/GEO(B)"
Equation    := ""           # e.g. "Eq.6.10"
Reference   := ""
ContentType := ""
Content     := []

5. FitDesignSituation

CountryIndex          := 0
Name                  := ""
HumanName             := ""
Description           := ""
EnvelopeSetGenerators := []    # list of envelope generators (e.g. EnLoadEnvelopeSets)
Content := {
   EnvelopeSets := EnvelopeSetGenerators.SelectManyFn(esg => esg.EnvelopeSets),
   Envelopes    := EnvelopeSetGenerators.SelectManyFn(esg => esg.Envelopes)
}

Also has a chapter property that generates a Fcs.Reporting.Chapter for documentation.


6. FitCombinationGroup

Symbol    := ""
Relation  := ""
ContentFn := lgA => lgA
Content   := []
CoeffFn   := lg  => []

7. FitResultClass

Name        := HumanName
HumanName   := ""
isOn        := True
Description := ""
Reference   := ""
ContentType := ""
Content     := []

8. Practical Usage Pattern (Eurocode, from HBC-2)

Step 1: Define base load group templates

LoadGroup = res.fit.FitLoadGroup

PermanentLoadGroup = LoadGroup{ Name = "Permanent", Load = "Permanent", notStabilising = True }
SnowLoadGroup      = LoadGroup{ Name = "Snow",      Load = "Variable",  Structure = "Frame",
                                LoadType = "Snow: H <= 1000", notLeading = False, isEnvironmental = True }
WindLoadGroup      = LoadGroup{ Name = "Wind",      Load = "Variable",  Structure = "Frame",
                                LoadType = "Wind", notLeading = False, isEnvironmental = True }

Step 2: Build hierarchy with relations

Permanent = PermanentLoadGroup{ Relation = "Together",         Content = [SelfWeightBase, DeadLoadBase] }
Snow      = SnowLoadGroup{      Relation = "ExclusiveOptional", Content = [Snow_i, Snow_ii, Snow_iii] }
WindAll   = WindLoadGroup{      Relation = "Together",         Content = [WindOuter, WindInner] }
WindOuter = WindLoadGroup{ Name = "Wind outer", Relation = "ExclusiveOptional", Content = [WL1, WL2, ...] }
WindInner = WindLoadGroup{ Name = "Wind inner", Relation = "ExclusiveOptional", Content = [CpiPlus, CpiMinus] }

The hierarchy forms a tree:

All = [ Permanent, Imposed, Snow, WindAll, Imperfections ]
       |                          |
       +-- SelfWeight             +-- WindOuter (ExclusiveOptional)
       +-- DeadLoad               |     +-- WL_X+ cpe++
                                  |     +-- WL_X+ cpe--
                                  |     +-- ...
                                  +-- WindInner (ExclusiveOptional)
                                        +-- Cpi+
                                        +-- Cpi-

Step 3: Create leaf (base) load groups for individual load cases

baseLgFn       = (name, lg) => LoadGroup{ Name = name }
SelfWeightBase = baseLgFn("Self weight", PermanentLoadGroup)
DeadLoadBase   = baseLgFn("Dead load",   PermanentLoadGroup)

Step 4: Define load cases linked to groups

LC_SelfWeight = res.fit.FitLoadCase{ Name = "SelfWeight", LoadGroup = LoadGroups.SelfWeightBase, Direction = "Gravity" }
LC_Snow1      = res.fit.FitLoadCase{ Name = "Snow_i",     LoadGroup = LoadGroups.SnowLoadBase_i, Direction = "Gravity" }

Step 5: Generate combinations (Eurocode automatic)

EnSet = res.en.load.EnLoadEnvelopeSets{
   CountryIndex               = 1,
   EnLoadConsequenceClassBase = res.en.load.EnLoadConsequenceClass{ inEnLoadConsequenceClassId = 1 },
   EnLoadPartialFactorsBase   = res.en.load.EnLoadPartialFactors{ CountryIndex = 1 },
}

DesignSituation = res.fit.DesignSituation{
   Name          = "DesignSituation",
   HumanName     = "Design situation",
   Description   = "Loading acc. to EN-1991",
   EnvelopeSetGenerators = [
      EnSet{
         NameRoot    = "F_1-",
         Content     = loadGroups.All,
         Equations   = ["Eq.6.10", "Eq.6.14b"],
         LimitStates = ["ULS-Fundamental-STR/GEO(B)", "SLS-Characteristic"],
      }
   ]
}

Step 6: Extract generated envelopes

allEnvelopes = designSituations.Select(ds => ds.Content.Envelopes)[0]
envelopesUls = allEnvelopes.Where(it => it.LimitStateType == "ULS")
envelopesSls = allEnvelopes.Where(it => it.LimitStateType == "SLS")

9. GClass Alias Registration

All Fit types are typically imported via a resource file:

gclass {fit} filename "_Submodules/fcs-common/FcsEntity/_FcsEntityResources.fcs"

Which registers aliases like:

gclass {LoadGroup}        filename "FitLoadGroup.fcs"
gclass {LoadCase}         filename "FitLoadCase.fcs"
gclass {LoadEnvelope}     filename "FitLoadEnvelope.fcs"
gclass {LoadCombination}  filename "FitLoadCombination.fcs"
gclass {EnvelopeSet}      filename "FitEnvelopeSet.fcs"
gclass {CombinationGroup} filename "FitCombinationGroup.fcs"
gclass {DesignSituation}  filename "FitDesignSituation.fcs"
gclass {ResultClass}      filename "FitResultClass.fcs"

Then used as res.fit.FitLoadGroup, res.fit.FitLoadCase, etc.


10. Quick Reference

# Permanent group (always present):
Permanent = LoadGroup{ Relation = "Together", Load = "Permanent", Content = [...] }

# Variable group (one or none):
Snow = LoadGroup{ Relation = "ExclusiveOptional", Load = "Variable",
                  LoadType = "Snow: H <= 1000", isEnvironmental = True }

# Link load case to group:
LC = res.fit.FitLoadCase{ Name = "Snow_i", LoadGroup = SnowBase }

# Extract ULS envelopes after combination generation:
ulsEnvelopes = allEnvelopes.Where(e => e.LimitStateType == "ULS")