2455x
001806
19. Juli 2023

Tutorial Webservice & API in C#

Unser Webservice bietet Anwendern wie Ihnen die Möglichkeit, über verschiedene Programmiersprachen mit RFEM 6 und RSTAB 9 zu kommunizieren. Durch die High-Level-Functions (HLF) von Dlubal können Sie die Funktionalität des Webservice erweitern und vereinfachen. Die Verwendung unseres Webservice in Verbindung mit RFEM 6 und RSTAB 9 erleichtert und beschleunigt die Arbeit von Ingenieuren. Überzeugen Sie sich selbst! In diesem Tutorial wird Ihnen die Verwendung der C#-Bibliothek an einem einfachen Beispiel demonstriert.

Die HLF-Bibliothek für C# bietet zahlreiche nützliche Funktionen zur Strukturerstellung in RFEM und RSTAB, wovon einige in dem folgenden Beispiel Verwendung finden werden.

Damit der programmierte Code zur Anwendung kommen kann, ist zunächst eine Verbindung zum Programm erforderlich. Dafür muss einer der verfügbaren Ports als Adresse festgelegt werden. Die Standardadresse von RFEM/RSTAB ist http://localhost:8081. Diese kann bei Bedarf in den Programmoptionen geändert werden.

Im nächsten Schritt können dann mithilfe der verfügbaren Funktionen in der C#-Bibliothek verschiedene Objekte wie Knoten, Linien und Stäbe erstellt werden. Die Bibliothek umfasst Klassen für alle verfügbaren Objekte. Mithilfe von Parametern können die Eigenschaften der Objekte festgelegt und spezifiziert werden. Die Anzahl der Parameter kann dabei je nach Anwendungsfall variieren.
Nachfolgend wird am Beispiel eines Knotens gezeigt, wie Objekte definiert werden können:


            

node newNode = new()
{
    no = nodeId,
    coordinates = new vector_3d() { x = xVector, y = 0.0, z = 0.0 },
    coordinate_system_type = node_coordinate_system_type.COORDINATE_SYSTEM_CARTESIAN,
    coordinate_system_typeSpecified = true,
    comment = "node for beam"
};


Die Definition von Linien, Flächen und anderen Objekten erfolgt analog. Es ist zu beachten, dass für bestimmte Attribute zusätzlich ein zugehöriges „Specified“-Attribut definiert und auf „true“ gesetzt werden muss.

Praxisbeispiel

Dieses Beispiel zeigt, wie man einen Durchlaufträger mit konstanter Linienlast erstellt. Dabei können die Anzahl der Felder, Spannweite und Größe der Linienlast variabel über die Benutzereingabe festgelegt werden.
Zuerst werden die benötigten Variablen über die Benutzereingabe in der Konsole definiert. Dabei wird geprüft, ob die Eingabe des Nutzers mit dem Datentyp der jeweiligen Variable kompatibel ist. Falls die Eingabe falsch oder leer ist, erscheint eine Fehlermeldung in der Konsole. Bei der Programmierung wurde darauf geachtet, dass Kommazahlen sowohl durch Punkt- als auch durch Kommaschreibweise eingegeben werden können, um die Fehleranfälligkeit bei der Eingabe zu minimieren.

Verbindung zu RFEM/RSTAB

Im folgenden Code wird innerhalb eines Try-Catch-Blocks versucht, eine Verbindung mit RFEM/RSTAB herzustellen:


            

var logger = LogManager.GetCurrentClassLogger();
string CurrentDirectory = Directory.GetCurrentDirectory();
try
{
    application_information ApplicationInfo;

    try
    {
        // connect to RFEM6 or RSTAB9 application
        application = new ApplicationClient(Binding, Address);
    }
    catch (Exception exception)
    {
        if (application != null)
        {
            if (application.State != CommunicationState.Faulted)
            {
                application.Close();
                logger.Error(exception, "Something happened:" + exception.Message);
            }
            else
            {
                application.Abort();
                logger.Error(exception, "Communication with RFEM faulted:" + exception.Message);
            }
        }
        Console.WriteLine(exception.ToString());
    }
    finally
    {
        ApplicationInfo = application.get_information();
        logger.Info("Name: {0}, Version:{1}, Type: {2}, language: {3} ", ApplicationInfo.name, ApplicationInfo.version, ApplicationInfo.type, ApplicationInfo.language_name);
        Console.WriteLine("Name: {0}, Version:{1}, Type: {2}, language: {3} ", ApplicationInfo.name, ApplicationInfo.version, ApplicationInfo.type, ApplicationInfo.language_name);
    }
}

string modelName = "MyTestModel";
string modelUrl ="";
ModelClient model = new ModelClient(Binding, new EndpointAddress(modelUrl));



Damit eine Verbindung aufgebaut werden kann, muss das Programm vor Ausführung des Codes geöffnet sein. Nach erfolgreicher Verbindung werden die Programminformationen in der Konsole ausgegeben und es wird ein neues Modell mit benutzerdefiniertem Namen in RFEM/RSTAB erstellt.

Definition der Basisobjekte

Im nächsten Schritt können Material und Querschnitt des Durchlaufträgers festgelegt werden. Dabei ist wichtig, dass die Bezeichnung der Bezeichnung in der RFEM Material- bzw. Querschnittsbibliothek entspricht.


            

material materialConcrete = new material
{
    no = 1,
    name = "C20/25 | EN 1992-1-1:2004/A1:2014"
};

section sectionRectangle = new section
{
    no = 1,
    material = materialConcrete.no,
    materialSpecified = true,
    type = section_type.TYPE_PARAMETRIC_MASSIVE_I,
    typeSpecified = true,
    parametrization_type = section_parametrization_type.PARAMETRIC_MASSIVE_I__MASSIVE_RECTANGLE__R_M1,
    parametrization_typeSpecified = true,
    name = "R_M1 0.5/1.0"
};


Mithilfe von Schleifen werden die verschiedenen Objekte (Knoten, Linien, Stäbe) erstellt und in Listen organisiert. Die Knoten werden in Abhängigkeit von der nutzerdefinierten Anzahl der Felder definiert und in die Liste „lineDefinitionNodes“ übergeben. Diese Liste dient später dazu, Linien anhand ihrer Definitionsknoten zu erstellen. Wenn ein RSTAB-Modell erstellt werden soll, dient sie zur Definition der Stäbe anhand ihrer Definitionsknoten. Bei Verwendung von RFEM werden die Stäbe dagegen über Linien definiert.


            

SortedList nodes = new SortedList();
int[] lineDefinitionNodes = new int[spanNumber + 1];
int nodeId = 1;
double xVector = 0.0;

for (int i = 0; i < spanNumber + 1; i++)
{
    node newNode = new()
    {
        no = nodeId,
        coordinates = new vector_3d() { x = xVector, y = 0.0, z = 0.0 },
        coordinate_system_type = node_coordinate_system_type.COORDINATE_SYSTEM_CARTESIAN,
        coordinate_system_typeSpecified = true,
        comment = "concrete part"
    };
    nodes.Add(nodeId, newNode);
    lineDefinitionNodes[i] = nodeId;
    xVector = xVector + span;
    nodeId++;
}

// create lines
int lineId = 1;
SortedList lines = new SortedList();

for (int i = 0; i < spanNumber; i++)
{
    line newLine = new()
    {
        no = lineId,
        definition_nodes = new int[] { lineDefinitionNodes[i], lineDefinitionNodes[i + 1] },
        comment = "lines for beams",
        type = line_type.TYPE_POLYLINE,
        typeSpecified = true,
    };
    lines.Add(lineId, newLine);
    lineId++;
}


Nachdem alle Basisobjekte erstellt wurden, werden zwei verschiedene Knotenlager definiert. Das Knotenlager am ersten Knoten soll fest, die restlichen Lager verschieblich in X-Richtung ausgebildet werden. Die Definitionsknoten für die verschiedenen Lagertypen werden je in einer eigenen Liste zusammengefasst.


            

nodal_support support1 = new()
{
    no = 1,
    nodes = supportedNodes1.ToArray(),
    spring = new vector_3d() { x = double.PositiveInfinity, y = double.PositiveInfinity, z = double.PositiveInfinity },
    rotational_restraint = new vector_3d() { x = double.PositiveInfinity, y = 0.0, z = double.PositiveInfinity }
};

nodal_support support2 = new()
{
    no = 2,
    nodes = supportedNodes2.ToArray(),
    spring = new vector_3d() { x = 0.0, y = double.PositiveInfinity, z = double.PositiveInfinity },
    rotational_restraint = new vector_3d() { x = 0.0, y = 0.0, z = double.PositiveInfinity }
};

nodalSupports.Add(support1);
nodalSupports.Add(support2);


Übermittlung der Objekte an RFEM

Damit die erstellten Objekte in RFEM/RSTAB verfügbar sind, müssen sie zunächst an das Programm übergeben werden. Dies erfolgt zwischen den beiden Funktionen „model.begin_modification“ und „model.end_modification“ mithilfe von objektspezifischen Funktionen der HLF-Bibliothek. Mithilfe von foreach-Schleifen werden alle Objekte eines Typs an das Programm übergeben.


            

try
{
    model.begin_modification("Geometry");
    model.set_material(materialConcrete);
    model.set_section(sectionRectangle);

    foreach (KeyValuePair nodeItem in nodes)
    {
        model.set_node(nodeItem.Value);
    }
    foreach (KeyValuePair lineItem in lines)
    {
        model.set_line(lineItem.Value);
    }
    foreach (KeyValuePair memberItem in members)
    {
       	model.set_member(memberItem.Value);
    }
    foreach (var nodalSupport in nodalSupports)
    {
        model.set_nodal_support(nodalSupport);
    }
}
catch (Exception exception)
{
    model.cancel_modification();
    logger.Error(exception, "Something happened while creation of geometry" + exception.Message);
    throw;
}
finally
{
    try
    {
       	model.finish_modification();
    }
    catch (Exception exception)
    {
        logger.Error(exception, "Something went wrong while finishing modification of geometry\n" + exception.Message + "\n");
         model.reset();
    }
}


Definition der Lasten

Die Lastfälle, Lastkombinationen und Bemessungssituationen werden in ähnlicher Weise wie die Basisobjekte erstellt und anschließend an das Programm übergeben.
Danach kann die Stablast, die zuvor vom Benutzer vorgegeben wurde, erstellt werden:


            

SortedList member_loads = new SortedList();
int member_load_id = 1;

for (int i = 0; i < spanNumber; i++)
{
    member_load newMemberLoad = new()
    {
        no = i + 1,
        members_string = (i + 1).ToString(),
        members = new int[] { i + 1 },
        load_distribution = member_load_load_distribution.LOAD_DISTRIBUTION_UNIFORM,
        load_distributionSpecified = true,
        magnitude = memberLoad * 1000,
        magnitudeSpecified = true,
        load_is_over_total_length = true,
        load_is_over_total_lengthSpecified = true,
    };
    member_loads.Add(i + 1, newMemberLoad);
    member_load_id++;
}  


Neben gleichmäßig verteilten Lasten sind unter anderem auch Trapez- und parabelförmige Lasten möglich.

Berechnung und Ergebnisausgabe

Mit der Funktion model.calculate(all) werden alle Berechnungen in RFEM durchgeführt.
Nach erfolgreicher Berechnung werden die Ergebnisse in diesem Beispiel in der Konsole ausgegeben. Die HLF-Bibliothek für C# ermöglicht außerdem den Export von Ergebnissen in XML- oder CSV-Dateien.
Mit der Funktion model.save() kann das Modell schließlich in dem in Klammern angegebenen Dateipfad gespeichert werden:


            

//save the model before closing
model.save(CurrentDirectory + @"\testmodels\");
application.close_model(0, true);


Zusammenfassung

Im gezeigten Beispiel werden die Vorteile und die einfache Bedienbarkeit der C#-Bibliothek deutlich. Durch benutzerdefinierte Eingaben lässt sich die Struktur schnell anpassen, wodurch eine hohe Zeitersparnis bei der Eingabe von statischen Systemen in RFEM 6 und RSTAB 9 erzielt werden kann. Die HLF-Bibliothek für C# bietet darüber hinaus viele weitere Funktionen, die auch die Erstellung komplexer Systeme ermöglichen.


Autor

Frau Göbel betreut die Dlubal-Anwender im Kundensupport.

Links