Advanced Programming in C#

C# provides two major advantages over IronPython:

  • Better performance

  • Superior development environment that provides auto completion

It is assumed that you already know how to create assemblies in C#. The following topics explains how to replace IronPython code with C# assemblies:


Note:  While C# assemblies are specifically referenced, you can use any language that creates .NET assemblies.



Tip:  Included in the supplied workflow templates is a folder CSharp. This folder contains files for a simple workflow-based app that is coded using C#. While this example is for Mechanical, the concept is supported ACT-wide. For download information, see Extension and Template Examples.


Initialize the C# Project

Once you have created a C# project and associated the type Class Library with this project, add references to the Ansys.ACT.Interfaces and Ansys.ACT.WB1 assemblies of ACT. Related DLLs for these assemblies are located in the following directories, where Platform is either Win64 or Linux64, depending on your operating system:

  • C:\Program Files\ANSYS Inc\v242\Addins\ACT\bin\Platform\Ansys.ACT.Interfaces.dll.

  • C:\Program Files\ANSYS Inc\v242\aisol\bin\Platform\Ansys.ACT.WB1.dll.

C# Implementation for a Load

The following XML file declares a load to be created in Mechanical that requires C# implementation:

<extension version="1" name="CSharp">

  <author>Ansys</author>
  <description>This extension demonstrates how to use CSharp to write extension.</description>
  
  <assembly src="CSharp.dll" namespace="CSharp" />

  <interface context="Mechanical">
    
    <images>images</images>

  </interface>

  <simdata context="Mechanical">

    <load name="CSharpLoad" caption="CSharp Load" version="1" icon="tload" unit="Temperature"
          color="#0000FF" class="CSharp.Load">
      <property name="Geometry" control="scoping">
        <attributes>
          <selection_filter>face</selection_filter>
        </attributes>
      </property>
    </load>

  </simdata>

</extension>

In the definition of the load object, the only change is the use of the attribute class. This attribute must be set to the name of the class to be used for the integration of the load.

A description of the class CSharp.Load follows.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ansys.ACT.Interfaces.Common;
using Ansys.ACT.Interfaces.Mesh;
using Ansys.ACT.Interfaces.Mechanical;
using Ansys.ACT.Interfaces.UserObject;

namespace CSharp
{
    public class Load
    {
        private readonly IMechanicalExtAPI _api;
        private readonly IMechanicalUserLoad _load;
        public Load(IExtAPI api, IUserLoad load)
        {
            _api = (IMechanicalExtAPI) api;
            _load = (IMechanicalUserLoad) load;
        }
        
        public virtual IEnumerable<double> getnodalvaluesfordisplay(IUserLoad load, IEnumerable<int> nodeIds)
        {
            var res = new List<double>();
            IMeshData mesh = _load.Analysis.MeshData;
            foreach (int nodeId in nodeIds)
            {
                INode node = mesh.NodeById(nodeId);
                res.Add(Math.Sqrt(node.X * node.X + node.Y * node.Y + node.Z * node.Z));
            
            }
            return res;
        }
        
    }
}

To implement a callback in C#, create a new method in your class with the name of the callback in lower case.

In the example, you implement the callback <getnodalvaluesfordisplay> by adding the method getnodalvaluesfordisplay to the class.

C# Implementation for a Result

The following XML file declares a result to be created in Mechanical that requires C# implementation:

<extension version="1" name="CSharp">

  <author>Ansys</author>
  <description>This extension demonstrates how to use CSharp to write extension.</description>
  
  <assembly src="CSharp.dll" namespace="CSharp" />

  <interface context="Mechanical">
    
    <images>images</images>

  </interface>

  <simdata context="Mechanical">

    <result name="CSharpResult" caption="CSharp Result" version="1" unit="Temperature" icon="tload" location="node" type="scalar" class="CSharp.Result">
      <property name="Geometry" control="scoping" />
    </result>
    
  </simdata>

</extension>

For the load definition, the attribute class must be set to the name of the class to be used for the integration of the result.

A description of the class CSharp.Result follows.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ansys.ACT.Interfaces.Common;
using Ansys.ACT.Interfaces.Mesh;
using Ansys.ACT.Interfaces.Mechanical;
using Ansys.ACT.Interfaces.UserObject;
using Ansys.ACT.Interfaces.Post;

namespace CSharp
{
    public class Result
    {
        internal double[] res = new double[1];

        public Result(IMechanicalExtAPI extApi, IUserResult result)
        {
        }

        public void evaluate(IUserResult entity, IStepInfo stepInfo, IResultCollector collector)
        {
            foreach (var id in collector.Ids)
            {
                 res[0] = id;
                 collector.SetValues(id, res);
            }
        }
    }
}

As for the load definition, the implementation of a new callback simply requires you add a new method with the name of the callback.