Wednesday, November 10, 2021

Integrate Azure Digital Twins with Ansys Twin Builder

Digital Twins are virtual representations of real-world entities and processes, synchronized at a specified frequency and fidelity to track the past, provide deeper insights into the present, predict and influence future behavior. Simulation is the killer application that allows you to predict the future states of your digital twin. Those simulations can then goal seek to find optimizations that are too complex to find by monitoring the physical environment alone. Once the simulation is completed, you can apply the insights that you have gained back to the real digital twin and affect inputs into the physical environment.

 

Physics-based simulations integrate physical principals such as hydraulics, collision detection, rigid body dynamics and motion into the modeling and learning process. Combining data-driven modeling approaches with physics-based approaches while building digital twin and IoT solutions allows us to create virtual sensors to “measure” missing data, perform what-ifs before applying a solution, analyze accurate and deterministic predictions based on physical principles and explore causality and failure modes using physics.

 

ANSYS is a leader in the simulation world. ANSYS Twin Builder combines the power of physics-based simulations with analytics-driven digital twins. Tata Consultancy Services, ANSYS Twin Builder and Microsoft Azure IoT teams came together to integrate physics-based simulations with Azure Digital Twins and IoT data.  

 

This article is meant to provide guidelines to developers whose goal is to implement physics-based simulations for their digital twin solutions leveraging the integration between Ansys Twin Builder and Azure Digital Twins.

 

Here is a diagram showing how Azure Digital Twins and Ansys Twin Builder Runtime could take part in an end-to-end IoT solution:

 

Simulation based digital twin architectureSimulation based digital twin architecture

 

In this article, we will focus on how to implement the integration between Azure Digital Twins and the Ansys Twin Builder runtime:

 

blog_image2.png

 

You can use Azure Digital Twins to represent your asset hierarchy. It helps you keep twin data as well as a live execution environment where you can create endpoints and subscribe to twin change events. The twin can be anything based on your functional requirements and conforming to the domain specific ontology.

 

In the above example, the updates in the digital twin on specific models trigger an event that invokes the Ansys Digital Twin Runtime and the results are saved back to the Azure Digital Twins instance.

 

Twin processor will be the core function or integrator between the Azure Digital Twins instance and the Ansys Digital Twin Runtime. Please find the process diagram below.

 

Simulation execution process flowSimulation execution process flow

 

Ansys Twin Builder and Ansys Twin Deployer will be used to generate the models representing the asset to monitor and export a digital twin runtime that can be made available in the environment to run the simulations. Ansys Digital Twin Runtime exposes multiple APIs (interface specification is attached to this article), all of which should be invoked in a specific order to get the response from Ansys as described in the architecture section.

 

In a “real” digital twin application, the digital twin instance is connected to IoT data streams to keep the digital twin “alive” and there would be a continuous evaluation of the simulation runtime based on the new data coming from the connected assets. In some cases, you might have a static digital twin where you might not have IoT data streams yet and the simulation models might be static and need to be evaluated one single time. Depending on your case, the sequence of core functions to invoke on the Ansys Digital Twin runtime from the Twin Processor function are listed below:

 

  • Initialization phase
    1. Receive twin update
    2. Prepare the requested parameters and inputs to invoke the Ansys Digital Twin Runtime
    3. Invoke the Ansys Digital Twin Runtime API
      1. Invoke model load API
      2. Invoke model instantiate API
      3. Invoke set parameters API
      4. Invoke set inputs API
      5. Invoke model initialize API
      6. Invoke get output API  (if your digital twin is static, invoke close API and stop at step v and don’t execute the “running phase”)
    4. Prepare the simulation result object
    5. Update the digital twin with the simulation result
  • Running phase
    1. Receive Twin update
    2. Prepare the requested inputs to invoke Ansys Digital Twin Runtime
    3. Invoke Ansys Digital Twin Runtime API
      1. Invoke simulation step or simulation batch API
    4. Prepare the simulation result object
    5. Update the digital twin with the simulation result
  • Closing phase
    1. Invoke close API

 

Running Ansys Digital Twin Runtime Service

 

Ansys Digital Twin Runtime is made available in a “tar.gz” format of Docker image. We need to run the container from the GZip file. For that, we need to first load that Docker image into an Azure Container Registry. The instructions to create an Azure Container Registry can be found here.

 

As a pre-requisite, you will need to upload the tar.gz file to any repository. Then, you can use the below YAML code in Azure Devops to create a pipeline for that process. You need to specify <Your Repo Folder Path> and <Your Container Registry Id> in the script below. You can then run the pipeline to create a Docker container on the specified Azure Container Registry:

 

# Variable 'Source_FileName' was defined in the Variables tab
# Variable 'Source_ImageName' was defined in the Variables tab
# Variable 'Source_Tag' was defined in the Variables tab
# Variable 'Target_ACR' was defined in the Variables tab
# Variable 'Target_ImageName' was defined in the Variables tab
# Variable 'Target_Tag' was defined in the Variables tab
resources:
  repositories:
  - repository: self
    type: git
    ref: <Your Repo Folder Path>
jobs:
- job: Job_1
  displayName: Docker push
  pool:
    vmImage: ubuntu-16.04
  steps:
  - checkout: self
  - task: CopyFiles@2
    displayName: Copy Files From Repo
    inputs:
      SourceFolder: DockerImage
      TargetFolder: $(build.artifactstagingdirectory)
  - task: Docker@2
    displayName: login
    inputs:
      containerRegistry: <Your Container Registry Id>
      command: login
  - task: CmdLine@2
    displayName: Command Line Script
    inputs:
      script: "docker image load --input $(build.artifactstagingdirectory)/$(Source_FileName)\n\ndocker image ls\n   \ndocker image tag $(Source_ImageName):$(Source_Tag) $(Target_ACR)/$(Target_ImageName):$(Target_Tag)\n\ndocker push $(Target_ACR)/$(Target_ImageName):$(Target_Tag)"
  - task: Docker@2
    displayName: logout
    inputs:
      containerRegistry: <Your Container Registry Id>
      command: logout

 

As a second step, you will need to create an App Service in Azure with Docker based deployment. While creating the App Service, you can select the new Docker image as the application source.

 

Now your Ansys Digital Twin Runtime service is ready to serve the requests.

 

Twin Processor Azure Function Implementation

 

This function plays the role of integrator which will be invoked with Azure Digital Twin event trigger. You can follow the steps here to set up the endpoints, routes and create the Azure Function that watches for twin life cycle events that should trigger the Ansys Digital Twin Runtime and reflect the changes back to the Azure Digital Twins instance.

 

Once the Azure Function receives any specific trigger to call the Ansys Digital Twin Runtime, it needs to prepare the request body with specific parameters and invoke services in sequence. As an initial setup you can specify the URLs as follows:

_loadUrl = _config["Ansys  BaseUrl"] + "/restAPI/load_model";
_instantiateUrl = _config["Ansys  BaseUrl"] + "/restAPI/instantiate_model";
_initializeUrl = _config["Ansys  BaseUrl"] + "/restAPI/initialize_model";
_setParametersUrl = _config["Ansys  BaseUrl"] + "/restAPI/set_parameters";
_setInputsUrl = _config["Ansys  BaseUrl"] + "/restAPI/set_inputs";
_simulationStepUrl = _config["Ansys  BaseUrl"] + "/restAPI/simulation_step ";
_simulationBatchUrl = _config["Ansys  BaseUrl"] + "/restAPI/simulation_batch ";_getOutputsUrl = _config["Ansys  BaseUrl"] + "/restAPI/get_outputs";
_closeUrl = _config["Ansys  BaseUrl"] + "/restAPI/close_model";

 

Then you can invoke the below APIs. You need to call the “Close Model” API in case any failure happens in the sequence, to unload the model. You can use the below code snippet for this:

 

status = await Ansys  LoadAsync(AnsysModelId, token);
 if (!status)
{
await Ansys  CloseAsync(AnsysModelId, token);
return (false, null);
}

 

Invoke - Load Model API

 

You can use the code snippet provided below to load the Ansys Digital Twin Runtime model:

private async Task<bool> AnsysLoadAsync(string AnsysModelId, CancellationToken token)
{
Uri loadUri = new Uri(_loadUrl).AddQueryParameter("modelname", AnsysModelId);
HttpResponseMessage response = await _httpClinetAdapter.GetAsync(loadUri, token);
return response.IsSuccessStatusCode;
}

 

Invoke - Model Instantiate API

 

You can use the code snippet provided below to instantiate the Ansys Digital Twin Runtime model:

private async Task<bool> AnsysInstantiateAsync(string AnsysModelId, CancellationToken token)
{
Uri loadUri = new Uri(_instantiateUrl).AddQueryParameter("modelname", AnsysModelId);
HttpResponseMessage response = await _httpClinetAdapter.GetAsync(loadUri, token);
return response.IsSuccessStatusCode;
}

 

 Invoke - Set Parameters API

 

You can use the code snippet provided below to set parameters for the  Ansys Digital Twin Runtime model:

private async Task<bool> AnsysSetParametersAsync(string AnsysModelId, string parameters, CancellationToken token)
{
Uri loadUri = new Uri(_setParametersUrl);
SimulationRequest simulationRequest = new SimulationRequest
{
ModelName = AnsysModelId,
Parameters = parameters
};
string content = JsonConvert.SerializeObject(simulationRequest);
using StringContent stringContent = new StringContent(content, Encoding.UTF8, "application/json");
HttpResponseMessage response = await _httpClinetAdapter.PostAsync(loadUri, stringContent, token);
string jsonResponse = await response.Content.ReadAsStringAsync();
return response.IsSuccessStatusCode;
}

 

Invoke - Set Inputs API

 

You can use the code snippet provided below to set inputs for the Ansys Digital Twin Runtime model:

private async Task<bool> AnsysSetInputsAsync(string AnsysModelId, string inputs, CancellationToken token)
{
Uri loadUri = new Uri(_setInputsUrl);
SimulationRequest simulationRequest = new SimulationRequest
{
ModelName = AnsysModelId,
Inputs = inputs
};
string content = JsonConvert.SerializeObject(simulationRequest);
using StringContent stringContent = new StringContent(content, Encoding.UTF8, "application/json");
HttpResponseMessage response = await _httpClinetAdapter.PostAsync(loadUri, stringContent, token);
string jsonResponse = await response.Content.ReadAsStringAsync();
return response.IsSuccessStatusCode;
}

 

Invoke - Model Initialize API

 

You can use the code snippet provided below to initialize the Ansys Digital Twin Runtime model:

private async Task<bool> AnsysInitializeAsync(string AnsysModelId, CancellationToken token)
{
Uri loadUri = new Uri(_initializeUrl).AddQueryParameter("modelname", AnsysModelId);
HttpResponseMessage response = await _httpClinetAdapter.GetAsync(loadUri, token);
return response.IsSuccessStatusCode;
}

 

 Invoke – Simulation Step API

 

You can use the code snippet provided below to simulate one step with the Ansys Digital Twin Runtime model:

private async Task<bool> AnsysSimulationStepAsync(string AnsysModelId, string inputs, string endtime, CancellationToken token)
{
Uri loadUri = new Uri(_simulationStep Url);
SimulationRequest simulationRequest = new SimulationRequest
{
ModelName = AnsysModelId,
Inputs = inputs
Endtime = endtime
};
string content = JsonConvert.SerializeObject(simulationRequest);
using StringContent stringContent = new StringContent(content, Encoding.UTF8, "application/json");
HttpResponseMessage response = await _httpClinetAdapter.PostAsync(loadUri, stringContent, token);
string jsonResponse = await response.Content.ReadAsStringAsync();
return (response.IsSuccessStatusCode, jsonResponse);

}

 

Invoke – Simulation Batch API

 

You can use the code snippet provided below to simulate a batch of data at once with the Ansys Digital Twin Runtime model:

private async Task<bool> AnsysSimulationBatchAsync(string AnsysModelId, string inputs, CancellationToken token)
{
Uri loadUri = new Uri(_simulationStep Url);
SimulationRequest simulationRequest = new SimulationRequest
{
ModelName = AnsysModelId,
Inputs = inputs
};
string content = JsonConvert.SerializeObject(simulationRequest);
using StringContent stringContent = new StringContent(content, Encoding.UTF8, "application/json");
HttpResponseMessage response = await _httpClinetAdapter.PostAsync(loadUri, stringContent, token);
string jsonResponse = await response.Content.ReadAsStringAsync();
return (response.IsSuccessStatusCode, jsonResponse);
}

 

Invoke - Get Output API

 

You can use the code snippet provided below to get output from the Ansys Digital Twin Runtime:

private async Task<(bool, string)> AnsysGetOutputsAsync(string AnsysModelId, CancellationToken token)
{
Uri loadUri = new Uri(_getOutputsUrl).AddQueryParameter("modelname", AnsysModelId);
HttpResponseMessage response = await _httpClinetAdapter.GetAsync(loadUri, token);
string jsonResponse = await response.Content.ReadAsStringAsync();
return (response.IsSuccessStatusCode, jsonResponse);
}

 

Now you have the results from the Ansys Digital Twin Runtime API, which can be used to update the digital twin.

 

Invoke – Close Model API

 

You can use the code snippet provided below to close the model in the Ansys Digital Twin Runtime:

private async Task<bool> AnsysCloseAsync(string AnsysModelId, CancellationToken token)
{
Uri loadUri = new Uri(_closeUrl).AddQueryParameter("modelname", AnsysModelId);
HttpResponseMessage response = await _httpClinetAdapter.GetAsync(loadUri, token);
return response.IsSuccessStatusCode;
}

 

We have completed the Ansys Digital Twin Runtime invocation. To ease and automate the process, you can deploy the Twin Processor function based on a Docker image and create a devops pipeline for it. You can use below YAML to create a Docker based application for the Twin Processor function. You need to specify <Your Container Registry Id> in the script below:

jobs:
- job: Twin Processor Docker Push
  displayName: AgentJob1
  pool:
    vmImage: ubuntu-16.04
  steps:
  - checkout: self
  - task: DotNetCoreCLI@2
    displayName: dotnet restore
    inputs:
      command: restore
      projects: TwinProcessor.sln
  - task: DotNetCoreCLI@2
    displayName: dotnet build
    inputs:
      projects: TwinProcessor.sln
      arguments: --configuration Release
  - task: CopyFiles@2
    displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)'
    inputs:
      TargetFolder: $(Build.ArtifactStagingDirectory)
  - task: Docker@2
    displayName: login
    inputs:
      containerRegistry: <Your Container Registry Id>
      command: login
  - task: Docker@2
    displayName: buildAndPush
    inputs:
      containerRegistry: <Your Container Registry Id>
      repository: ADTTwinProcessor
      Dockerfile: TwinProcessDockerfile
  - task: Docker@2
    displayName: logout
    inputs:
      containerRegistry: <Your Container Registry Id>
      command: logout
  - task: PublishBuildArtifacts@1
    displayName: 'Publish Artifact: drop'
    enabled: False

 

The above pipeline will create a Docker container for your Twin Processor Azure Function.

 

Build your own simulation based digital twins

 

Learn more about simulation based digital twins and start building your own with Azure Digital Twins and Ansys Twin Builder Free Trial

 

Please keep the discussion going. Leave your questions and comments below.

 

Posted at https://sl.advdat.com/3C4pDWg