Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions 2025R2/thermal-desktop-opentd-for-demo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
###############
# folder #
###############
/**/DROP/
/**/TEMP/
/**/packages/
/**/bin/
/**/obj/
_site
10 changes: 10 additions & 0 deletions 2025R2/thermal-desktop-opentd-for-demo/.vale.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
StylesPath = styles

Vocab = ansys

MinAlertLevel = suggestion

Packages = Google

[*.md]
BasedOnStyles = Vale, Google
5 changes: 5 additions & 0 deletions 2025R2/thermal-desktop-opentd-for-demo/api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
###############
# temp file #
###############
*.yml
.manifest
2 changes: 2 additions & 0 deletions 2025R2/thermal-desktop-opentd-for-demo/api/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# PLACEHOLDER
TODO: Add .NET projects to the *src* folder and run `docfx` to generate **REAL** *API Documentation*!
62 changes: 62 additions & 0 deletions 2025R2/thermal-desktop-opentd-for-demo/articles/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Changelog

## Version 2024 R2

### New features

- added `case set group name` parameter to `TDSF_CoSolver` constructors
- added `Message` member to `CompareSuite`; just returns `Log` member
- twin lump ids are now automatically sequenced if `lump.TwinId == 0`
- added auto start of OpenTD servers on `_SAVEAS` for all versions of OpenTD

## Version 2024 R1

### Note

This was an administrative release. There is only one new feature: added `Comparer.ToString()` method.

## Version 2023 R2

### Major new features

- added support for controlling item visibility via the `ThermalDesktop.VisibilityManager`
- added `ReadMeshDataFile` method to read various mesh data formats into TD
- added support for stack aliases
- added `DynamicSindaStatus` class for interacting with messages generated by `Dynamic Sinda`
- added limited support for new beta `SaveX` file format

### Other new features

- added `MeshDisplayer.BaseTrans` property -- now you can move FEM's
- added experimental `CaseSetManager.IsCaseRunning()` method for asynchronous cases
- added `Contactor.Comment` property
- use lightweight SubmodelNameData's to identify submodels for FloCAD objects
- added `GetNumberOfDbObjects(...)` method
- implemented `ConvertFDtoFE` method
- `Matrix3d.SetOrigin` now returns the new matrix instead of `void`
- `Dataset.Factory.Load` method to load `sav`, `savx`, or `CSR`
- `Comparer` ctor overload to accept `IDatasets` instead of `Datasets`
- added `Close` and `ReOpen` methods to `IDataset`
- added `CloseDatasets` and `ReOpenDatasets` methods to `Comparer`
- added ability to rename and delete aliases
- added `CaseSetManagerOptions.ShowTextScreenDuringRun` member
- added `Conductor.UseGlobalAccelm` member
- added `RcEntityData.GlobalContactArray` member
- added `RcSolidElement.AnalysisGroupsVolumetric` member
- added `RcFdSolidData.AnalysisGroupsVolumetric` member
- added `FkLocator.Anchor` member
- added `Pipe.LengthDivisions` and `RadialDivisions` members
- added `Tie.LengthDivisions`, `RadialDivisions`, and `UseGlobalAccelm` members

### Performance improvements

- `CreateCone` returns correct node names
- `Polygon.Update()` no longer duplicates vertices
- `CoSolver.Continue()` returns -1 if `SF` disconnected, instead of an exception
- New `scr` filename and pipe name conventions to avoid Windows Defender mistaking `scr` files for viruses
- avoid issues with duplicate handles in Assembly
- fix parsing mixed-case subtypes like "DeltaP"
- fix `GetMeshFD(s)` so it populates returned object(s) correctly
- `GetPipe` no longer returns pipes with blank signatures
- pipe ties now handle domains correctly
- `CaseSet.Run` and `CaseSetManager.Run` now handle casesets with drive symbols from Excel
13 changes: 13 additions & 0 deletions 2025R2/thermal-desktop-opentd-for-demo/articles/docfx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Info Sensitive Data Finding

Other

More Details
Attribute Value
Data Classifier Other/Ansys Product Library
Data Classifier ID CUSTOM-bf52ecf9-8981-496e-96f6-18c88acdd79f

Sampled Examples

Key Value
globalMetadata/product ***
globalMetadata/title ***

Rule ID: CUSTOM-bf52ecf9-8981-496e-96f6-18c88acdd79f

"build": {
"globalMetadata": {
"title": "Thermal Desktop OpenTD 2025 R2",
"summary": "",
"version": "2025 R2",
"product": "Thermal Desktop",
"programming language": "C#",
"product collection": "Fluids",
"physics": "Fluids"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Appendix A: Using OpenTD with MATLAB

While it is not feasible for us to maintain separate "Getting Started with OpenTD" guides for every programming language, we would still like to help you get started with OpenTD, even if you are not using C\#. The following .m script is a MATLAB port of the program in the [Create and run a case](working-with-case-sets.md#create-and-run-a-case) section. This can be used as a sort of "Rosetta Stone" to help you translate other C\# examples to MATLAB.

```MATLAB
%% Using OpenTDv242 with MATLAB
% CRTech
% Tested with MATLAB R2023b
% OpenTD is an Application Programming Interface (API) for Thermal Desktop
% (TD) that allows you to automate many of the tasks currently performed
% interactively using TD’s Graphical User Interface (GUI). OpenTD gives you
% the tools to programmatically create, query, edit, delete, and run
% models. You can use any .NET language to interact with OpenTD (C\#,
% VB.NET, F\#, etc.) or any system that can load .NET assemblies such as
% MATLAB or Python.
% Regardless of how you interact with OpenTD, you’ll need to have at least
% an intermediate understanding of .NET object-oriented programming. If you
% are starting from scratch, we recommend learning C\#, since it is the
% language that we support. However, we understand that there might be
% compelling reasons for you to connect to OpenTD via MATLAB. It is
% possible, although the way MATLAB handles .NET enums is awkward and
% MATLAB does not support implicit constructors.
% To get started with OpenTD, read "Getting Started with OpenTDv242.pdf",
% which can be found in your TD v241 installation directory under "Manual".
% The Getting Started guide explains the fundamental concepts of OpenTD,
% using several C\# examples. We've ported one of those examples to MATLAB
% below.
%% The "Create and Run a Case" example ported to MATLAB
% See "Getting Started with OpenTDv242.pdf" in your TD v241 installation
% directory under "Manual" for an explanation of this script.
% Note: Please contact us at crtech.support@ansys.com if you think there are
% better ways to use OpenTD with MATLAB, especially with regard to .NET
% enums and implicit constructors. For examples of awkward code, see how a
% node is set to be a boundary node and how the InitialTemp of a node is
% set -- in the script below vs. in the original C\#.
openTD = NET.addAssembly('OpenTDv242');
import OpenTDv242.\*;
td = ThermalDesktop;
td.Connect();
% \*\*\* Create a simple model of a heated bar \*\*\*
barNodes = NET.createArray('OpenTDv242.Node', 10);
for i = 1:10
n = td.CreateNode();
n.Submodel = SubmodelNameData('bar');
n.Id = i;
n.MassVol = 10;
n.Origin = Point3d(0.01 \* (i - 1), 1, 0);
n.InitialTemp = Dimensional(n.InitialTemp, 300);
n.Update();
barNodes(i) = n;
end
for i = 1:9
c = td.CreateConductor(...
Connection(barNodes(i).Handle), Connection(barNodes(i+1).Handle));
c.Submodel = SubmodelNameData('bar');
c.Value = 0.1;
c.Update();
end
roomAir = td.CreateNode();
roomAir.Submodel = SubmodelNameData('room');
roomAir.NodeType = OpenTDv242.('RcNodeData+NodeTypes').BOUNDARY;
roomAir.Origin = Point3d(0.055, 1.1, 0);
roomAir.InitialTemp = Dimensional(roomAir.InitialTemp, 300);
roomAir.Update();
barConnections = NET.createGeneric(...
'System.Collections.Generic.List', {'OpenTDv242.Connection'},10);
for i = 1:10
barConnections.Add(Connection(barNodes(i).Handle));
end
convection = td.CreateConductor(...
Connection(roomAir.Handle), barConnections);
convection.Value = 1;
convection.Submodel = SubmodelNameData('room');
convection.Update();
qTorch = td.CreateSymbol('qTorch', '80');
heatLoadConnections = NET.createGeneric(...
'System.Collections.Generic.List', {'OpenTDv242.Connection'},1);
heatLoadConnections.Add(Connection(barNodes(1).Handle));
torch = td.CreateHeatLoad(heatLoadConnections);
torch.ValueExp.Value = qTorch.Name;
torch.Submodel = SubmodelNameData('torch');
torch.Update();
td.ZoomExtents();
% \*\*\* End simple model creation \*\*\*
% Create a transient case and run it:
nominal = td.CreateCaseSet(...
'transient with nominal torch', '', 'torchNom');
nominal.SteadyState = 0;
nominal.Transient = 1;
nominal.SindaControl.timend...
= Dimensional(nominal.SindaControl.timend, 600);
nominal.Update();
nominal.Run();
% Create a cold case by overriding a symbol, and run it:
cold = td.CreateCaseSet(...
'transient with cold torch', '', 'torchCold');
cold.SteadyState = 0;
cold.Transient = 1;
cold.SindaControl.timend...
= Dimensional(nominal.SindaControl.timend, 1200);
cold.SymbolNames.Add(qTorch.Name);
cold.SymbolValues.Add('50');
cold.SymbolComments.Add('cold torch heat input');
cold.SaveAll = 1;
cold.Update();
cold.Run();
%% Working with Dimensionals
% All dimensional quanitities in the API are stored using a custom .NET
% generic type called a Dimensional. For example, a Dimensional\<Temp\>
% stores temperatures. Using C\#, Dimensionals are implicitly cast to and
% from doubles as required, but this does not appear to work in MATLAB.
% Instead, we've overloaded the double function and created a Dimensional
% function to explicitly cast doubles to Dimensionals.
function x = double(Dimensional)
% Cast a .NET generic Dimensional type to a double
x = Dimensional.op_Implicit(Dimensional);
end
function x = Dimensional(Dimensional, double)
% Cast a double to a .NET generic Dimensional type
x = Dimensional.op_Implicit(double);
end
%% Acknowledgements
% Thank you to Dan Hensley and Daniel Reasa with ATA Engineering for
% performing some of the early work to determine how to use OpenTD with
% MATLAB.
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Appendix B: Using OpenTD with Python

While it is not feasible for us to maintain separate "Getting Started with OpenTD" guides for every programming language, we would still like to help you get started with OpenTD, even if you are not using C\#. The following .py script is a MATLAB port of the program in the [Create and run a case](working-with-case-sets.md#create-and-run-a-case) section. This can be used as a sort of "Rosetta Stone" to help you translate other C\# examples to Python. It uses the pythonnet module, found at: [http://pythonnet.github.io/](http://pythonnet.github.io/).

```python
\#\#\#\# Using OpenTDv242 with Python \#\#\#\#
\# CRTech
\# Feb, 2022
\# Created with Python 2.7.15 and pythonnet 2.3.0
\# OpenTD is an Application Programming Interface (API) for Thermal Desktop
\# (TD) that allows you to automate many of the tasks currently performed
\# interactively using TD's Graphical User Interface (GUI). OpenTD gives you
\# the tools to programmatically create, query, edit, delete, and run
\# models. You can use any .NET language to interact with OpenTD (C\#,
\# VB.NET, F\#, etc.) or any system that can load .NET assemblies such as
\# MATLAB or Python.
\# Regardless of how you interact with OpenTD, you'll need to have at least
\# an intermediate understanding of .NET object-oriented programming. If you
\# are starting from scratch, we recommend learning C\#, since it is the
\# language that we support. However, we understand that there might be
\# compelling reasons for you to connect to OpenTD via Python. It is
\# possible using the pythonnet module:
\# http://pythonnet.github.io/
\# To get started with OpenTD, read "Getting Started with OpenTDv242.pdf",
\# which can be found in your TD v241 installation directory under "Manual".
\# The Getting Started guide explains the fundamental concepts of OpenTD,
\# using several C\# examples. We've ported one of those examples to Python
\# below.
\#\#\#\# The "Create and Run a Case" example ported to Python \#\#\#\#
\# See "Getting Started with OpenTDv242.pdf" in your TD v241 installation
\# directory under "Manual" for an explanation of this script.
\# Note: Please contact us at crtech.support@ansys.com if you think there are
\# better ways to use OpenTD with Python, especially with regard to setting
\# dimensional values.
\# REQUIREMENT: You must install the pythonnet module to use this script.
import sys
import clr
\# Need to add explicit GAC path to sys.path so clr.AddReference
\# can find OpenTDv242.dll. Note the use of forward slashes in the path:
sys.path.append("C:/Windows/Microsoft.NET/assembly/GAC_MSIL/OpenTDv242/ReplaceMe")
clr.AddReference("OpenTDv242")
from OpenTDv242 import \*
\# We'll want to use .NET System types and generic Lists:
from System import \*
from System.Collections.Generic import List
\# To access dimensional quantities in OpenTD, we need to use Dimensionals.
\# These are cast to/from doubles implicitly in C\#, but here we'll need to
\# refer to them explicitly. (See setting InitialTemp, below.)
from OpenTDv242 import Dimension
from OpenTDv242.Dimension import \*
td = ThermalDesktop()
td.Connect()
\# \*\*\* Create a simple model of a heated bar \*\*\*
barNodes = List[Node]()
for i in range(10):
n = td.CreateNode()
n.Submodel = SubmodelNameData("bar")
n.Id = i + 1
n.MassVol = 10.0
n.Origin = Point3d(0.01 \* i, 1.0, 0.0)
n.InitialTemp = Dimensional[Dimension.Temp](300.0)
n.Update()
barNodes.Add(n)
for i in range(9):
c = td.CreateConductor(Connection(barNodes[i]), Connection(barNodes[i+1]))
c.Submodel = SubmodelNameData("bar")
c.Value = 0.1
c.Update()
roomAir = td.CreateNode()
roomAir.Submodel = SubmodelNameData('room')
roomAir.NodeType = RcNodeData.NodeTypes.BOUNDARY
roomAir.Origin = Point3d(0.055, 1.1, 0.0)
roomAir.InitialTemp = Dimensional[Dimension.Temp](300.0)
roomAir.Update()
barConnections = List[Connection]()
for n in barNodes:
barConnections.Add(Connection(n))
convection = td.CreateConductor(Connection(roomAir), barConnections)
convection.Value = 1.0
convection.Submodel = SubmodelNameData("room")
convection.Update()
qTorch = td.CreateSymbol("qTorch", "80")
heatLoadConnections = List[Connection]()
heatLoadConnections.Add(Connection(barNodes[0]))
torch = td.CreateHeatLoad(heatLoadConnections)
torch.ValueExp.Value = qTorch.Name
torch.Submodel = SubmodelNameData("torch")
torch.Update()
td.ZoomExtents()
\# \*\*\* End simple model creation \*\*\*
\# Create a transient case and run it:
nominal = td.CreateCaseSet("transient with nominal torch", "", "torchNom")
nominal.SteadyState = 0
nominal.Transient = 1
nominal.SindaControl.timend = Dimensional[Dimension.Time](600.0)
nominal.Update()
nominal.Run()
\# Create a cold case by overriding a symbol, and run it:
cold = td.CreateCaseSet("transient with cold torch", "", "torchCold")
cold.SteadyState = 0
cold.Transient = 1
cold.SindaControl.timend = Dimensional[Dimension.Time](1200.0)
cold.SaveQ = 1
cold.SymbolNames.Add(qTorch.Name)
cold.SymbolValues.Add("50")
cold.SymbolComments.Add("cold torch heat input");
cold.SaveAll = 1;
cold.Update()
cold.Run()
\#\#\#\# Acknowledgements
\# Thank you to James Etchells with the European Space Agency (ESA) for
\# performing some of the early work to determine how to use OpenTD with
\# Python.
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Appendix C: Using OpenTD with PowerShell

Windows PowerShell can be used to interact with OpenTD, which is useful since it is included with Windows, that is, you don't need to install Visual Studio, MATLAB, or anything extra to use OpenTD. And unlike Python or MATLAB, PowerShell was designed to support .NET objects, so its .NET syntax isn't too bad.

PowerShell is likely already installed on your Windows machine. If not, or you'd like help finding it, check out the official documentation:

[https://docs.microsoft.com/en-us/powershell/](https://docs.microsoft.com/en-us/powershell/)

Here’s a simple PowerShell script that loads OpenTD, creates a ThermalDesktop instance and opens it:

```powershell
Add-Type -Path "C:\\Windows\\Microsoft.NET\\assembly\\GAC_MSIL\\OpenTDv242\\v4.0_23.2.0.0__65e6d95ed5c2e178\\OpenTDv242.dll"
\$td = New-Object -TypeName 'OpenTDv232.ThermalDesktop'
\$td.Connect()
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

# Appendix D: Using OpenTD Interactively with the C# Interactive Compiler

Normally C\# is compiled before running, but you can open an interactive C\# Read-eval-print loop (REPL) in Visual Studio using the following command: View-\>Other Windows-\>C\# Interactive

Once open, you can use it to interactively execute C\# code, including OpenTD. For example:

```csharp
\> \#r "OpenTDv242" // loads the dll as a reference
\> using OpenTDv242;
\> var td = new ThermalDesktop();
\> td.Connect();
\> var n = td.CreateNode(new Point3d(1, 1, 3));
\> td.ZoomExtents();
\> n.Comment = "Hello World!";
\> n.Update();
\> var nTest = td.GetNodes().First();
\> Console.WriteLine(nTest);
RcNode.MAIN.1::236 "Hello World!"
\> td.Quit();
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Communicating with SINDA/FLUINT

OpenTD can be used to communicate with and control running SINDA/FLUINT (S/F) solutions using the classes in the OpenTDv242.*CoSolver* namespace:

- *SF_Launcher* is used to load and run a S/F model directly from an input file, such as an *inp* file created by the TD Case Set Manager. Once launched, the solution proceeds normally with no interaction from the SF_Launcher object.
- *SF_CoSolver* is like an SF_Launcher in that it launches a S/F model from an input file, but once launched it attempts to connect to and control it.
- *TDSF_CoSolver* launches a S/F model from within the TD Case Set Manager, then attempts to connect to and control it.

There is a demo of CoSolver usage available in the OpenTD 2023 R2 demos package. (See [Further reading section](further-reading.md))
Loading