Skip to content

[✨ Feature request]: Define structure and versioning strategy for National Annexes #855

@egarciamendez

Description

@egarciamendez

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

  1. Define a clear folder structure for National Annexes
  2. Establish a strategy for handling multiple versions of the same National Annex
  3. Minimize code duplication between base norms and National Annexes
  4. 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 implementation

Example 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 formula

Open 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

  1. Class naming conventions: Should we use suffixes like NL, DE, BE in 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 From5Dot1CriteriumDisregardSecondOrderEffects

Proposed: Use suffix in class name for clarity (Option A)

  1. Documentation: Where should we document which version of the NA is implemented?

    • In each formula class docstring ✓
    • In source_document attribute ✓
  2. 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 different

Question: Which approach is cleaner and more maintainable?

  1. Testing: How do we test that NA formulas correctly override or extend base formulas?

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

Questions for the team

  1. What do you think about the proposed structure?
  2. Should we go for Option A (suffix in class name) or Option B (inheritance)?
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions