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:
In this article, we will focus on how to implement the integration between Azure Digital Twins and the Ansys Twin Builder runtime:
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.
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:
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.
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);
}
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;
}
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;
}
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;
}
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;
}
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;
}
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);
}
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);
}
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.
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.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.