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.