Table of Contents

Creating analysis model

ABSTRACT

In this article you'll learn:

  • how to create structural analysis models with ADM
  • how to add, modify, and remove elements from the model
  • how to handle validation and error management
  • how to use other features of ADM, like querying and transformation

Creating a structural analysis model can be done entirely with ADM (Analysis Data Model). At this stage, you don't need to use SCIA Open API at all.

ADM is based on a service-oriented architecture pattern. All model operations, such as creating new elements, querying, modifying or removing existing ones are done via services.

Service Scope Management

To properly manage resources and ensure thread safety, all operations must be performed within a scoped service provider. The AnalysisDataModelBootstrapper creates and manages the dependency injection container:

IBootstrapper bootstrapper = new AnalysisDataModelBootstrapper();

using(IScopedServiceProvider scope = bootstrapper.CreateThreadedScope())
{
    IAnalysisModelService modelService = scope.GetService<IAnalysisModelService>();
    // all model operations should be performed within this scope
}
Important

Always use the using statement to ensure proper disposal of the scoped service provider. This prevents resource leaks and ensures thread safety.

Working with Model Elements

Adding a Single Element

The IAnalysisModelService can be used to add new elements to the model. All elements are automatically validated before being added to ensure model integrity. The following example demonstrates how to add a structural node:

IBootstrapper bootstrapper = new AnalysisDataModelBootstrapper();
AnalysisModel model = new AnalysisModel();

using(IScopedServiceProvider scope = bootstrapper.CreateThreadedScope())
{
    IAnalysisModelService modelService = scope.GetService<IAnalysisModelService>();

    // Create a structural node at the origin
    StructuralPointConnection node = new StructuralPointConnection(
        Guid.NewGuid(), 
        "N1", 
        Length.Zero, 
        Length.Zero, 
        Length.Zero
    );

    // Add the node to the model with automatic validation
    if(modelService.AddItemToModel(model, node))
    {
        Console.WriteLine("Node added successfully!");
    }
    else
    {
        Console.WriteLine("Failed to add node to model");
        // At this stage, you can check model.ValidationResults for detailed error information
        // Refer to the article "Validating the model" for more information
    }
}

Adding Multiple Elements

For better performance when adding multiple elements, use the batch operation method:

IBootstrapper bootstrapper = new AnalysisDataModelBootstrapper();
AnalysisModel model = new AnalysisModel();

using(IScopedServiceProvider scope = bootstrapper.CreateThreadedScope())
{
    IAnalysisModelService modelService = scope.GetService<IAnalysisModelService>();

    // Create multiple structural nodes
    StructuralPointConnection node1 = new StructuralPointConnection(Guid.NewGuid(), "N1", Length.Zero, Length.Zero, Length.Zero);
    StructuralPointConnection node2 = new StructuralPointConnection(Guid.NewGuid(), "N2", Length.FromMeters(2), Length.Zero, Length.Zero);
    StructuralPointConnection node3 = new StructuralPointConnection(Guid.NewGuid(), "N3", Length.FromMeters(2), Length.FromMeters(2), Length.Zero);
    StructuralPointConnection node4 = new StructuralPointConnection(Guid.NewGuid(), "N4", Length.Zero, Length.FromMeters(2), Length.Zero);

    // Add all nodes in a single operation
    IDictionary<Guid, bool> results = modelService.AddItemsToModel(model, node1, node2, node3, node4);
    
    if(results.All(x => x.Value))
    {
        Console.WriteLine("All nodes added successfully!");
    }
    else
    {
        Console.WriteLine("Some nodes failed to add:");
        foreach(var result in results.Where(x => !x.Value))
        {
            Console.WriteLine($"  Node {result.Key} failed validation");
            // Detailed validation errors are available in model.ValidationResults
            // Refer to the article "Validating the model" for more information
        }
    }
}

Removing Elements

When removing elements from the model, ADM enforces referential integrity. When you try to use IAnalysisModelService to remove elements, that are referenced by other elements, it will throw an exception:

IBootstrapper bootstrapper = new AnalysisDataModelBootstrapper();
AnalysisModel model = new AnalysisModel();

using(IScopedServiceProvider scope = bootstrapper.CreateThreadedScope())
{
    IAnalysisModelService modelService = scope.GetService<IAnalysisModelService>();

    // Find a beam by name
    StructuralCurveMember beam = model.OfType<StructuralCurveMember>()
        .FirstOrDefault(x => x.Name == "B1");

    if(beam != null)
    {
        try
        {
            modelService.RemoveItemFromModel(model, beam);
            Console.WriteLine("Beam removed successfully!");
        }
        catch (ModelExchangerException mee) 
        {
            // Exception is thrown if the element is referenced by other elements
            // For example, a beam cannot be remover, when there is a support assigned to it
            Console.WriteLine($"Cannot remove beam: {mee.Message}");
        }
    }
}

Alternatively, you can use IAnalysisModelItemDeleteService. Specifically, the CascadingRemoveItemFromModel() method, like:

AnalysisModel model = new AnalysisModel();
AnalysisDataModelBootstrapper bootstrapper = new AnalysisDataModelBootstrapper();

using(IScopedServiceProvider scope = bootstrapper.CreateThreadedScope())
{
  IAnalysisModelItemDeleteService service = scope.GetService<IAnalysisModelItemDeleteService>();

  var beamToDelete = model.OfType<StructuralCurveMember>().FirstOrDefault(x => x.Name == "B1");

  service.CascadingRemoveItemFromModel(model, beamToDelete);
}
Warning

Use this service with caution! Also elements referenced by the deleted element and not referenced by other elements are deleted! For example, the above code snippet would remove:

  • the beam itself
  • all elements referencing it, like: supports, line loads, hinges
  • all elements, this beam was referencing to, which are not referenced by other elements, e.g. nodes, materials, cross-sections.

Especially the latter may result in removing elements from the model, that you may want to use later.