next up previous contents index
Next: IX. Appendices Up: VIII. FeResPost Examples with Previous: VIII. FeResPost Examples with   Contents   Index

Subsections


VIII.1 Examples of use for .NET assembly

Presently, the examples of usage for the .NET assembly are limited mostly to C# language examples. These examples are provided in sub-directories of ``TESTSAT/NETEX'' and correspond to the small examples ``TESTSAT/SMALLEX'' of FeResPost ruby extension discussed in chapter IV.2.

In this chapter, one highlights the differences between ruby extension and .NET assembly. For that reason, only a few examples are discussed. For the other examples, the discussion of corresponding ruby examples in chapter IV.2 and refexamples.CLA.chap should be sufficient.


VIII.1.1 Reading a Nastran model


VIII.1.1.1 Reading a Nastran model with C#

The first C# example is very simple and illustrates the use of .NET assembly with C# programming language. The example is provided in ``TESTSAT/NETEX/EX01/readBdf.cs'' source file. The compilation is done with script ``readBdf.bat'' that contains the following lines:

@SET FRP=../../../SRC/OUTPUTS/NET
C:/Windows/Microsoft.NET/Framework/v3.5/csc.exe -platform:x86 \
        -r:%FRP%/FeResPost.dll ..\UTIL\util.cs readBdf.cs
readBdf.exe
(You may have to change the ``%FRP%'' path to FeResPost .NET assembly before compiling the example.) Note also that one uses the 3.5 version of .NET Framework. This is not strictly necessary in this example, but it might be useful for some examples in which classes are extended with extension methods. Once the compilation is done, the compiled program is run by line ``readBdf.exe''.

The file ``readBdf.cs'' begins with several ``using'' directives:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using System.Threading;

using FeResPost ;
using std ;
These directives allow to reduce the length of type names used in the program. For example, the ``using FeResPost'' directive allows to use ``NastranDb'' keyword instead of ``FeResPost.NastranDb''.

The first example is very simple and contains only one static ``Main'' function:

namespace ConsoleApplication1 {
    
    class readBdf {
        
        static void Main(string[] args) {
            
            ...
            
        } // static void Main(string[] args)
        
    } // class readBdf
    
} // namespace ConsoleApplication1
Note however, that the static function is contained in a class. (C# does not allow to define a function outside of a class.) The ``readBdf'' class is also contained in a ``ConsoleApplication1'' namespace.

The other lines defining the program are very simple and considered as ``classical'' C# programming:

            NastranDb db = new NastranDb();
            db.Name="tmpDB1";
            db.readBdf("../../MODEL/MAINS/unit_xyz.bdf");
            
            // A Second DataBase is created :
            
            db = new NastranDb();
            db.Name="tmpDB2";
            db.readBdf("unit_xyz_V1.bdf","../../MODEL/MESH/","bdf",
                    new Dictionary<string,string>(),true);
(The reader is referred to chapter III.1 for the description of ``readBdf'' arguments.) Note that in the second call to ``readBdf'', one uses a void ``Dictionary'' instead of a ruby ``Hash'' object as parameter.

One presents in ``readBdf_V2.cs'' and ``readBdf_V3.cs'' variants on of this first example.


VIII.1.1.2 Reading a Nastran model with IronRuby

``readBdf_V2_rb.rb'' contains an IronRuby version of C# example ``readBdf_V2.cs''. The first call to ``readBdf is done as follows:

     ...
     bdfName=System::String.new("unit_xyz_V2.bdf") 

    symbols=Hash.new
    symbols["INCDIR"]="../../MODEL"

    db=NastranDb.new()
    db.Name="tmpDB2"
    begin 
        db.readBdf(bdfName,[],System.String("bdf"),symbols,true)
    rescue Exception => x then
        ...
Of course, this call fails because ruby standard Arrays or Hashes cannot be used as CLI Arrays or dictionaries. Instead, the following statements work:
     ...
     symbols=System::Collections::Generic::Dictionary[System::String,System::String].new
     symbols.Add("INCDIR","../../MODEL");

     db.readBdf(bdfName,System::Array[System::String].new(0),System::String.new("bdf"),symbols,true)
     ...
The example illustrates the difficulty of marshaling CLI data types with IronRuby. We expect this to be true for all interpreted languages.


VIII.1.2 ``printStressMax'' example

The example is provided in ``TESTSAT/NETEX/EX05/printStressMax.cs'' source file. This example is worth discussing because it illustrates the difference between the value returned by ``Result.getData'' method in ruby extension and in C#.

In the example, one extracts the data on a Result which associates only one key-value pair, but the present principles are valid for more general Results. The following ruby lines make use of the ruby extension and extract and print the stress components :

    ...
    maxScalarData = maxScalar.getData()[0]
    maxStressData = maxStress.getData()[0]
    ...
    printf("   %.2f Pa on element %d (layer=\"%s\").\n",
            maxScalarData[5],maxScalarData[0],maxScalarData[2])
    printf("      Sxx = %.2f, Syy = %.2f, Szz = %.2f,\n",maxStressData[5],\
            maxStressData[6],maxStressData[7])
    printf("      Sxy = %.2f, Syz = %.2f, Szx = %.2f\n",maxStressData[8],\
            maxStressData[9],maxStressData[10])
    ...
The same operation is performed with .NET assembly by the following C# code:
    ...
    maxScalarData=maxScalar.getData();
    maxStressData=maxStress.getData();

    Console.WriteLine();
    Console.WriteLine("Maximum Von Mises stress in panel +Z skins :");
    Console.WriteLine();
    Console.Write("   {0:F2} Pa ",maxScalarData[0,5]);
    Console.Write("on element {0:D} ",maxScalarData[0,0]);
    Console.WriteLine("(layer=\"{0:S}\")",maxScalarData[0,2]);
    Console.Write("      Sxx = {0:F2}, ",maxStressData[0,5]);
    Console.Write("Syy = {0:F2}, ",maxStressData[0,6]);
    Console.WriteLine("Szz = {0:F2}, ",maxStressData[0,7]);
    Console.Write("      Sxy = {0:F2}, ",maxStressData[0,8]);
    Console.Write("Syz = {0:F2}, ",maxStressData[0,9]);
    Console.WriteLine("Szx = {0:F2} ",maxStressData[0,10]);
    ...
One notices that one no longer accesses element 0 of the array returned by ``getData''. Indeed, in .NET assembly, the method returns a 2D Array, and not an Array of Arrays as in ruby extension.


VIII.1.3 Accessing FEM data

In the ``NETEX/EX02/properties.cs'' example, one shows how one can access the properties in the finite element model. The C# code looks as follows:

    object[] card;
    foreach (int pid in db.iter_propertyId()) {
        os.Write("{0,8}",pid);
        os.Write("\n\n");
        
        card=db.fillCard("Property",pid);
        os.Write("{0,8}",card[0]);
        for (int i=1;i<card.Length;i++) {
            os.Write("{0,8}",card[i]);
            if (i%8==0&&i!=card.Length-1) {
                os.Write("\n");
                os.Write("{0,8}","");
            }
        }
        os.Write("\n\n");
    }
This example illustrates the use of ``fillCard'' method, already presented in sections III.1.1.4 and IV.2.3


VIII.1.4 Extending CLA classes

The examples provided in ``NETEX/EX13'' illustrate the possibility to extend FeResPost classes in C# by defining ``extension'' methods. Note however that this capability exists only if a version 3 or above of the C# compiler is used.

In the following example, extracted from ``NETEX/EX13/extendedCla.cs'', The ClaMat class is extended with method ``write_Compliance'':

namespace extension {
    static class ext {
        ...
        public static void write_Compliance(this ClaMat m,
                StreamWriter os,float theta) {
            writeMat(os,m.getCompliance(theta));
        }
        ...
Note that the first argument is ``this ClaMat m'', which indicates the class that is being extended. In file ``NETEX/EX13/extendedCla.cs'', the extension methods are defined in ``extension'' namespace. A ``using extension'' statement must be present in the client program to access the extensions.

Note also, that many of the methods defined in C# differ from the ruby corresponding ruby methods with ruby extension. For example, the following C# source lines take into account that ``getPliesStresses'' method of .NET assembly returns a 2D Array:

    ...
    sigTab=l.getPliesStresses();
    nbrLines=sigTab.GetLength(0);
    os.Write("   {0,8}{1,5}","layer","loc");
    os.Write("{0,14}{1,14}{2,14}","sig_11","sig_22","sig_12");
    os.Write("\n");
    for (i=0;i<nbrLines;i++) {
        os.Write("   {0,8}{1,5}",sigTab[i,0],sigTab[i,1]);
        os.WriteLine("{0,14}{1,14}{2,14}",sigTab[i,2],
                     sigTab[i,3],sigTab[i,7]);
    }
    os.Write("\n");
    ...
Ruby extension returns an Array of Arrays and the corresponding lines would be:
    ...
    sigTab=getPliesStresses
    os.printf("   %8s%5s","layer","loc")
    os.printf("%14s%14s%14s","sig_11","sig_22","sig_12")
    os.printf("\n")
    (0...sigTab.size).each do |i|
        os.printf("   %8d%5s",sigTab[i][0],sigTab[i][1])
        os.printf("%14g%14g%14g",sigTab[i][2],sigTab[i][3],
                  sigTab[i][7])
        os.printf("\n")
    end
    ...


VIII.1.5 Saving and retrieving Results from an SQL database

This example is presented in files ``rehashDynamicResults.cs'' and ``deleteSomeResults.cs'' of directory ``TESTSAT/NETEX/EX20'' correspond exactly to the ruby examples of section IV.2.6.

The access to SQLite .NET assembly, which must be installed on the computer is done by the following statement:

    using System.Data.SQLite ;
Note also the binding of parameters to SQLite command:
        cmd.CommandText = sql;
        cmd.Parameters.Clear();
        cmd.Parameters.AddWithValue("@lcName", id[0]);
        cmd.Parameters.AddWithValue("@scName", id[1]);
        cmd.Parameters.AddWithValue("@resName", id[2]);
        cmd.Parameters.AddWithValue("@tensorOrder", tensorOrder);
        cmd.Parameters.AddWithValue("@intId1", intId1);
        cmd.Parameters.AddWithValue("@intId2", intId2);
        cmd.Parameters.AddWithValue("@realId1", realId1);
        cmd.Parameters.AddWithValue("@realId2", realId2);
        cmd.Parameters.AddWithValue("@size", size);
        cmd.Parameters.AddWithValue("@result", resBlob);
        cmd.ExecuteNonQuery();


next up previous contents index
Next: IX. Appendices Up: VIII. FeResPost Examples with Previous: VIII. FeResPost Examples with   Contents   Index
FeResPost 2017-05-28