-
Notifications
You must be signed in to change notification settings - Fork 17
Description
Description
Context
We need to establish a clear structure for implementing National Annexes (NA) to Eurocodes in the Blueprints library. National Annexes contain country-specific modifications, additional formulas, and parameter values that differ from the base Eurocode standards.
Reference PR: #842
Current Situation
- Base Eurocodes (e.g., EN 1992-1-1:2004) are implemented in the main eurocode structure
- National Annexes are not yet systematically supported
- No clear strategy exists for managing multiple versions of National Annexes
Objectives
- Define a clear folder structure for National Annexes
- Establish a strategy for handling multiple versions of the same National Annex
- Minimize code duplication between base norms and National Annexes
- Keep the implementation maintainable for multiple countries
Proposed Structure
Option 1: Separate national_annex directory
blueprints/
└── eurocode/
├── en_1992_1_1_2004/
│ └── chapter_3_materials/
│ └── formula_3_1.py
└── national_annex/
├── netherlands/
│ └── nen_en_1992_1_1_2005/
│ └── chapter_3_materials/
│ └── formula_3_1.py
├── germany/
│ └── din_en_1992_1_1_2005/
│ └── chapter_3_materials/
│ └── formula_3_1.py
└── belgium/
└── nbn_en_1992_1_1_2005/
└── chapter_3_materials/
└── formula_3_1.py
Pros:
- Clear separation between base norms and National Annexes
- Easy to navigate and understand
- Follows geographical grouping
Cons:
- Many nested levels
- Potential for deep directory structures
Key Decisions Needed
1. Content Strategy
Agreed: National Annexes should only contain formulas and tables that differ from the base Eurocode, not duplicate everything.
Rationale:
- Reduces code duplication
- Easier maintenance
- Clearer what is actually different per country
2. Version Management Strategy
Challenge: National Annexes have multiple versions over time (corrections, updates, etc.)
Proposed approach:
- Implement ONE National Annex per norm per country (latest/most relevant version)
- Document version information in:
- Class docstrings
- Formula documentation
- Central documentation file per National Annex
Example implementation for a National Annex formula:
class Form3Dot1NLCharacteristicCompressiveStrength(Formula):
"""Class representing NEN-EN 1992-1-1 National Annex formula for Table 3.1.
This is the Dutch National Annex version which modifies the base Eurocode values.
Source: NEN-EN 1992-1-1+C2:2011 - National Annex Table 3.1
Notes
-----
This formula is based on NEN-EN 1992-1-1+C2:2011.
Previous versions (NEN-EN 1992-1-1:2005) may have different values.
"""
label = "3.1 (NL)"
source_document = NEN_EN_1992_1_1_C2_2011
def __init__(
self,
fck: MPa,
) -> None:
"""Initialize the formula with Dutch National Annex parameters.
NEN-EN 1992-1-1+C2:2011 - National Annex - Table 3.1
Parameters
----------
fck : MPa
[$f_{ck}$] Characteristic compressive cylinder strength [MPa].
"""
super().__init__()
self.fck = fck
@staticmethod
def _evaluate(
fck: MPa,
) -> MPa:
"""Evaluates the formula. See __init__ for details."""
# Dutch-specific calculation or parameter
return fck * 0.85 # Example
# ... rest of the implementationExample for modified limit values (like in PR #842):
class Form5Dot1NLCriteriumDisregardSecondOrderEffects(ComparisonFormula):
"""Dutch National Annex version of formula 5.1 with modified limit values.
Source: NEN-EN 1993-1-1+C2:2011 - National Annex
Notes
-----
The Dutch National Annex uses different limit values than the base Eurocode:
- Elastic analysis: 12 (instead of 10)
- Plastic analysis: 18 (instead of 15)
"""
label = "5.1 (NL)"
source_document = NEN_EN_1993_1_1_C2_2011
def __init__(
self,
f_cr: N,
f_ed: N,
analysis_type: Literal["elastic", "plastic"]
) -> None:
"""Check if second order effects can be disregarded (Dutch NA version).
NEN-EN 1993-1-1+C2:2011 - National Annex - Formula (5.1)
Parameters
----------
f_cr: N
[$F_{cr}$] Elastic critical buckling load [N].
f_ed: N
[$F_{Ed}$] Design loading on the structure [N].
analysis_type: Literal["elastic", "plastic"]
Type of analysis being performed.
"""
super().__init__()
self.f_cr = f_cr
self.f_ed = f_ed
self.analysis_type = analysis_type
@staticmethod
def _limit(analysis_type: Literal["elastic", "plastic"]) -> float:
"""Returns Dutch NA limit values."""
analysis_type_map = {
"elastic": 12, # NL: 12 instead of 10
"plastic": 18, # NL: 18 instead of 15
}
limit = analysis_type_map.get(analysis_type.lower())
if limit is None:
raise ValueError(
f"Invalid analysis type: {analysis_type}. "
"Must be 'elastic' or 'plastic'."
)
return limit
# ... rest of implementation similar to base formulaOpen question: How do we handle conflicting versions when users combine formulas from different NA versions?
3. Eurocode Generations
Agreed: Distinguish between Generation 1 (current) and Generation 2 (upcoming) Eurocodes, but not between minor corrections within a generation.
Rationale: Prevents version sprawl while supporting major standard changes.
Implementation Questions
- Class naming conventions: Should we use suffixes like
NL,DE,BEin class names or rely on import paths?
# Option A: Suffix in class name
From5Dot1NLCriteriumDisregardSecondOrderEffects
# Option B: Same name, different import path
from blueprints.eurocode.national_annex.netherlands.nen_en_1993_1_1_2005 import From5Dot1CriteriumDisregardSecondOrderEffectsProposed: Use suffix in class name for clarity (Option A)
-
Documentation: Where should we document which version of the NA is implemented?
- In each formula class docstring ✓
- In
source_documentattribute ✓
-
Inheritance strategy: Should NA formulas inherit from base Eurocode formulas when only parameters differ?
# Option A: Full reimplementation
class Form5Dot1NLCriteriumDisregardSecondOrderEffects(ComparisonFormula):
# Complete implementation
# Option B: Inherit and override
class Form5Dot1NLCriteriumDisregardSecondOrderEffects(
From5Dot1CriteriumDisregardSecondOrderEffects
):
"""Dutch NA version with modified limits."""
@staticmethod
def _limit(analysis_type: Literal["elastic", "plastic"]) -> float:
"""Override with Dutch NA limit values."""
# Only override what's differentQuestion: Which approach is cleaner and more maintainable?
-
Testing: How do we test that NA formulas correctly override or extend base formulas?
-
API design: How should users import and use National Annex formulas?
# Explicit import
from blueprints.eurocode.national_annex.netherlands.nen_en_1993_1_1_2005.chapter_5_structural_analysis import (
Form5Dot1NLCriteriumDisregardSecondOrderEffects
)
# Usage
check = Form5Dot1NLCriteriumDisregardSecondOrderEffects(
f_cr=1000,
f_ed=80,
analysis_type="elastic"
)References
- PR Feature/nen en 1993 1 1 formula 5 1 #842: First implementation attempt (EN 1993-1-1 Formula 5.1)
- Discussion in team chat (01-12-2025 - 03-12-2025)
Questions for the team
- What do you think about the proposed structure?
- Should we go for Option A (suffix in class name) or Option B (inheritance)?
- How do we handle formulas that only have parameter changes vs. formulas that are completely different?
Acceptance Criteria
Next Steps
- Gather feedback from core team
- Make final decision on folder structure
- Decide on class naming and inheritance strategy
- Create implementation guidelines document
- Start with Netherlands (NEN) as pilot implementation
- Document versioning strategy in contributing guidelines
Dependencies
No response
Confirmation
- I have checked that this feature does not already exist in the issue tracker.
- I have read and understood the contribution guidelines.