SolidWorks Simulations-API - AddForce3

Ich habe einen Zylinder und habe mit dem Verkrümmungswerkzeug eine kreisförmige Fläche erstellt. Ich möchte den Zylinder für die Verschiebung simulieren und in diesem Schritt eine Kraft auf die von mir ausgewählte kreisförmige Fläche ausüben. Ich möchte eine gleichmäßige Kraft in Z-Richtung des Koordinatensystems von etwa 400N aufbringen. Wenn ich diesen Code ausführe, erhalte ich den Fehlercode 6 für AddForce3. Könnte mir bitte jemand helfen? Ich habe das in C # gemacht. Ich versuche es zunächst mit einem Gesicht und Kraft. Ich werde es mit mehreren Facetten und Gewalt schaffen, wenn das klappt. Ich habe das Bild des Zylinders unten angegeben.

image

using SldWorks;
using SolidWorks.Interop.cosworks;
using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
using System;
using System.IO;
using System.Threading;
using ISldWorks = SolidWorks.Interop.sldworks.ISldWorks;
using ModelDoc2 = SolidWorks.Interop.sldworks.ModelDoc2;
using SelectionMgr = SolidWorks.Interop.sldworks.SelectionMgr;

class Program
{
    static void Main()
    {
        Console.WriteLine("Starting SolidWorks...");
        var swApp = Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application")) as ISldWorks;
        if (swApp == null)
        {
            Console.WriteLine("Failed to start SolidWorks.");
            return;
        }

        swApp.Visible = true;
        Console.WriteLine("SolidWorks launched.");
        Thread.Sleep(5000);

        string partFilePath = @"C:\Users\Student\Tasks\API Tasks\L1_4 Task07.SLDPRT";
        if (!System.IO.File.Exists(partFilePath))
        {
            Console.WriteLine("File not found: " + partFilePath);
            return;
        }

        int errors = 0, warnings = 0;
        ModelDoc2 model = swApp.OpenDoc6(partFilePath,
                                         (int)swDocumentTypes_e.swDocPART,
                                         (int)swOpenDocOptions_e.swOpenDocOptions_Silent,
                                         "", ref errors, ref warnings);

        if (model == null)
        {
            Console.WriteLine("Failed to open part file.");
            return;
        }

        Console.WriteLine("Part file opened.");

        Thread.Sleep(2500);

        string simDllPath = @"C:\Program Files\SOLIDWORKS Corp\SOLIDWORKS\Simulation\cosworks.dll";
        int loadResult = swApp.LoadAddIn(simDllPath);
        Console.WriteLine($"Simulation Add-in load result: {loadResult}");

        var simAddIn = swApp.GetAddInObject("CosmosWorks.CosmosWorks") as CwAddincallback;
        if (simAddIn == null)
        {
            Console.WriteLine("Failed to load Simulation Add-in object.");
            return;
        }
            
        CosmosWorks cosmos = simAddIn.CosmosWorks;
        CWModelDoc simDoc = cosmos?.ActiveDoc;
        if (simDoc == null)
        {
            Console.WriteLine("Simulation document not active.");
            return;
        }

        Thread.Sleep(1500);

        ICWStudyManager studyMgr = simDoc.StudyManager;
        studyMgr.ActiveStudy = 0;
        CWStudy study = studyMgr.GetStudy(0);
        if (study == null)
        {
            Console.WriteLine("No study found.");
            return;
        }

        Thread.Sleep(1500);

        // ==================== APPLY FORCE LOAD ====================
        Console.WriteLine("Applying force load...");

        // Get ModelDocExtension for face selection
        object selFace = null;
        
        SelectionMgr swSelMgr = model.SelectionManager;

        model.Extension.SelectByID2("", "FACE", 4.848210781, -0.473088237, 1.944270691, false, 0, null, 0);
        selFace = (object)swSelMgr.GetSelectedObject6(1, -1);

        if (selFace == null)
        {
            Console.WriteLine("Failed to select face. Check face name.");
        }
        else
        {
            // Get Loads and Fixtures manager
            ICWLoadsAndRestraintsManager loadMgr = study.LoadsAndRestraintsManager;

            if (loadMgr == null)
            {
                Console.WriteLine("Failed to get Loads/Fixtures manager.");
            }
            else
            {
                int loadErr = 0;

                double[] data = new double[6];
                // Create the force
                data[0] = 1.0;
                data[1] = 1.0;
                data[2] = 1.0;
                data[3] = 1.0;
                data[4] = 1.0;
                data[5] = 1.0;

                object[] forceArray = { data[0], data[1], data[2], data[3], data[4], data[5] };

                CWForce force = loadMgr.AddForce3(
                    (int)swsForceType_e.swsForceTypeNormal,        // Load type: force
                    (int)swsSelectionType_e.swsSelectionFaceEdgeVertexPoint,     // Apply on faces
                    -1,                                             // No reference direction
                    0,                                              // Not table-driven
                    0,                                              // Not table-driven
                    0,                                              // No rows
                    new object[0],                                  // DistValue irrelevant
                    new object[0],                                  // ForceValue irrelevant
                    false,                                          // Uniform loading
                    false,                                          // Not a beam
                    0,                                              // No non-uniform def
                    0,                                              // No non-uniform type
                    4,                                              // Ucode: 0 = Normal
                    400.0,                                          // Force magnitude (N)
                    (forceArray),                                   // Comps array [Fx, Fy, Fz...]
                    false,                                          // FlipOrigin = false
                    false,                                          // Not curved beam
                    null,                                           // DispArray not used
                    selFace,                                        // RefGeom not used
                    false,                                          // PerUnitLength = false
                    out loadErr                                     // Error code
                );


                if (force == null || loadErr != 0)
                {
                    Console.WriteLine($"Failed to apply force. Error code: {loadErr}");
                }
                else
                {
                    Console.WriteLine("Force of 400 N in +Z applied successfully.");
                }
            }
        }

        Console.WriteLine("Done. Press any key to exit.");
        Console.ReadKey();
    }
}

Hallo
Wir sehen in der Dokumentation, dass:
Wenn ForceType = swsForceType_e.swsForceTypeNormal, geben Sie Folgendes an:

  • Comps mit einem Array von sechs Werten: [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
  • Ucode mit 0
    Wir sollten es also mit Ucode bei 0 statt bei 4 versuchen.

Dann zeigt der Fehler ein ungültiges Array an. Es kann sich auch um den DispArray-Parameter handeln, der keinen NULL-Wert akzeptiert.

Ich habe den Code wie folgt aktualisiert. Jetzt habe ich den Fehlercode 3 bekommen.

        object selFace = null;
        object selBeam = null;

        SelectionMgr swSelMgr = model.SelectionManager;

        model.Extension.SelectByID2("", "SOLIDBODY", 1.83008089, 0.343248073, 1.970325039, false, 0, null, 0);
        selBeam = (object)swSelMgr.GetSelectedObject6(1, -1);

        model.Extension.SelectByID2("", "FACE", 4.848210781, -0.473088237, 1.944270691, false, 0, null, 0);
        selFace = (object)swSelMgr.GetSelectedObject6(1, -1);

        object[] beamArray = { selBeam };

        if (selFace == null)
        {
            Console.WriteLine("Failed to select face. Check face name.");
        }
        else
        {
            // Get Loads and Fixtures manager
            ICWLoadsAndRestraintsManager loadMgr = study.LoadsAndRestraintsManager;

            if (loadMgr == null)
            {
                Console.WriteLine("Failed to get Loads/Fixtures manager.");
            }
            else
            {
                int loadErr = 0;

                double[] data = new double[6];
                // Create the force
                data[0] = 1.0;
                data[1] = 1.0;
                data[2] = 1.0;
                data[3] = 1.0;
                data[4] = 1.0;
                data[5] = 1.0;

                object[] forceArray = { data[0], data[1], data[2], data[3], data[4], data[5] };
                

                CWForce force = loadMgr.AddForce3(
                    (int)swsForceType_e.swsForceTypeNormal,        // Load type: force
                    (int)swsSelectionType_e.swsSelectionFaceEdgeVertexPoint,     // Apply on faces
                    -1,                                             // No reference direction
                    0,                                              // Not table-driven
                    0,                                              // Not table-driven
                    0,                                              // No rows
                    new object[0],                                  // DistValue irrelevant
                    new object[0],                                  // ForceValue irrelevant
                    false,                                          // Uniform loading
                    false,                                          // Not a beam
                    0,                                              // No non-uniform def
                    0,                                              // No non-uniform type
                    0,                                              // Ucode: 0 = Normal
                    400.0,                                          // Force magnitude (N)
                    (forceArray),                                   // Comps array [Fx, Fy, Fz...]
                    false,                                          // FlipOrigin = false
                    false,                                          // Not curved beam
                    (beamArray),                                    // DispArray
                    selFace,                                        // RefGeom not used
                    false,                                          // PerUnitLength = false
                    out loadErr                                     // Error code
                );

@m_blt Könnten Sie mir auch bitte dabei helfen?

Guten Abend @Krishna_Prasanth_Thiruvalluvar ,

Der Parameter (beamArray), den Sie an die AddForce3-Funktion übergeben, sollte ein Array sein, das Flächen oder Kanten eines Solidworks-Körpers enthält.
In Ihrem Code bezieht sich dies auf den Volumenkörper selbst, nicht auf seine Flächen oder Kanten. Weitere Informationen finden Sie in den folgenden Anweisungen:

In Ihrem Fall besteht die einfachste Möglichkeit zum Erstellen von Z-Follower-Bemühungen darin, Folgendes zu tun:

  • Wählen Sie eine Kante oder Achse in Z-Richtung oder eine Fläche der Normalen Z aus, und weisen Sie sie dem Parameter Referenzgeometrie zu.
  • Wählen Sie die Flächen aus, die die Kraft tragen, und übergeben Sie sie in Form eines Arrays an den Parameter (DispArray);
  • Definieren Sie den uCode-Wert als additive Kombination aus 1, 2 und 4, abhängig von den gewünschten Komponenten. Nur für die Z-Richtung: uCode = 4;
  • Definieren Sie die Werte der Komponenten und übergeben Sie sie an das Array (ComponentValues) (es werden nur die ersten drei benötigt).

VBA-Syntax:

Set force = loadMgr.AddForce3(swsForceTypeForceOrMoment, _
swsSelectionFaceEdgeVertexPoint, 0, 0, 0, 0, (DistanceValues), (ForceValues), _
Falsch, Falsch, 0, 0, 1 + 2 + 4, 0, (ComponentValues), Falsch, Falsch, (DispArray), _
ReferenceGeometry, False, loadErr)

Soll ich nur den selBeam verwenden oder sowohl selBeam als auch selFace verwendet werden, um die gewünschte Fläche für die Anwendung der Normalkraft auszuwählen? Ich habe mich in der ursprünglichen Frage geirrt, da ich eine Normalkraft haben möchte, die auf jede Seite des Zylinders wirkt. Können Sie mir helfen, wie ich weiter vorgehen soll?

Da es sich jetzt um eine normale Kraft handelt, sollte UCode 0 sein. Was ist mit den anderen Parametern?

Hallo

Das verbundene Makro in VBA erzeugt eine Normalkraft an jeder der zuvor ausgewählten Flächen auf einem SW-Körper.
Damit die Anstrengung auf jeder Seite normal ist, ist es notwendig:

  • ob der Aufwandstyp swsForceTypeNormal ist,
  • dass uCode = 0 ist
  • dass der Wert der Kraft (123,0) an den Parameter TorqueNFVal übergeben wird
  • und dass ReferenceGeometry leer ist.

Keine Kommentare und keine Garantien... :wink:

AddForce.swp (60,5 KB)

Verblüffend! Vielen Dank. Ich habe den C # -Code basierend auf der VBA geändert und dann die Kraft darauf angewendet.

Meine nächste Aufgabe ist es, die Verschiebung an einer bestimmten Stelle zu exportieren. Also habe ich versucht, die GetDisplacementComponentForAllStepsAtNode-Methode und die GetDisplacementAtPoints-Methode zu verwenden. Aber ich konnte das Ergebnis nicht wie erwartet bekommen.

Mit der GetDisplacementComponentForAllStepsAtNode-Methode habe ich den nächstgelegenen Knoten des Punktes gefunden, an dem ich interessiert bin, und dann diese Knotennummer an die Methode übergeben, um den Verschiebungswert in der Konsole anzuzeigen.

Mit der GetDisplacementAtPoints-Methode habe ich die Koordinaten des nächstgelegenen Knotens des Punktes, an dem ich interessiert bin, direkt eingegeben und dann versucht, sie auf der Konsole anzuzeigen. Aber es hat auch nicht funktioniert. Wie kann ich das ermöglichen? Ich bin daran interessiert, die Verschiebungswerte in .csv Datei zu exportieren. Also wollte ich diesen Schritt machen.

Der folgende Code wird nach der Vernetzung und dem anschließenden Ausführen der Simulation ausgeführt. Ich habe die maximale und minimale Verschiebung gefunden, dann wird der Punkt, an dem ich die Verschiebung messen möchte, jetzt direkt im Code erwähnt. Ich habe den nächstgelegenen Knoten gefunden und die oben genannten Methoden ausprobiert. Der Code gibt den Fehlercode 4 aus, wenn ich die erste Methode verwende

        // Create displacement plot
        CWResults results = study.Results;
        Thread.Sleep(2000);
        if (results == null)
        {
            Console.WriteLine("No results available.");
            return;
        }

        int errCode;
        CWPlot dispPlot = results.CreatePlot(
            (int)swsPlotResultTypes_e.swsResultDisplacementOrAmplitude,
            (int)swsDisplacementComponent_e.swsDisplacementComponentURES,
            (int)swsUnit_e.swsUnitSI,
            false,
            out errCode);

        if (dispPlot == null || errCode != 0)
        {
            Console.WriteLine($"Failed to create displacement plot. Error: {errCode}");
            return;
        }
                
        // Optional: Change units to millimeters
        errCode = dispPlot.SetComponentUnitAndValueByElem(
            (int)swsDisplacementComponent_e.swsDisplacementComponentURES,
            (int)swsLinearUnit_e.swsLinearUnitMillimeters,
            false);
        if (errCode != 0)
        {
            Console.WriteLine("Failed to set units for displacement plot.");
        }

        dispPlot = results.GetPlot("Displacement1", out errCode);

        // Activate plot
        errCode = dispPlot.ActivatePlot();
        if (errCode != 0)
        {
            Console.WriteLine("Failed to activate displacement plot.");
            return;
        }
        Thread.Sleep(1500);

        object[] dispResults = (object[])dispPlot.GetMinMaxResultValues(out errCode);
        if (errCode != 0 || dispResults == null || dispResults.Length < 4)
        {
            Console.WriteLine("Failed to get displacement results.");
            return;
        }

        double minDisp = Convert.ToDouble(dispResults[1]);
        double maxDisp = Convert.ToDouble(dispResults[3]);

        Console.WriteLine($"Resultant Displacement:\n  Min: {minDisp} mm\n  Max: {maxDisp} mm");

        Thread.Sleep(1500);

        // Step 1: Get all mesh nodes
        object[] nodesRaw = (object[])mesh.GetNodes();

        double[] targetPoint = new double[] { 4500, -280, 1980 }; // millimeters

        double minDistance = double.MaxValue;
        int closestNodeId = -1;
        double[] closestNodeCoords = new double[3];

        for (int i = 0; i < nodesRaw.Length; i += 4)
        {
            int nodeId = Convert.ToInt32(nodesRaw[i]);  // Node ID

            // Coordinates as floats, cast to double
            double x = Convert.ToDouble(nodesRaw[i + 1]) * 1000.0;
            double y = Convert.ToDouble(nodesRaw[i + 2]) * 1000.0;
            double z = Convert.ToDouble(nodesRaw[i + 3]) * 1000.0;

            double dx = x - targetPoint[0];
            double dy = y - targetPoint[1];
            double dz = z - targetPoint[2];
            double distance = Math.Sqrt(dx * dx + dy * dy + dz * dz);

            if (distance < minDistance)
            {
                minDistance = distance;
                closestNodeId = nodeId;
                closestNodeCoords[0] = x;
                closestNodeCoords[1] = y;
                closestNodeCoords[2] = z;
            }
        }

        Console.WriteLine("Closest node to target point:");
        Console.WriteLine($"Node ID: {closestNodeId}");
        Console.WriteLine($"Coordinates: X = {closestNodeCoords[0]}, Y = {closestNodeCoords[1]}, Z = {closestNodeCoords[2]}");
        Console.WriteLine($"Distance to target: {minDistance} mm");

        Thread.Sleep(2000);

        // Verify we have a valid node ID
        if (closestNodeId == -1)
        {
            Console.WriteLine("No valid node found near the target point.");
            return;
        }

        object dispValuesObj = results.GetDisplacementComponentForAllStepsAtNode(
            (int)swsDisplacementComponent_e.swsDisplacementComponentURES,
            80066,
            null,
            (int)swsLinearUnit_e.swsLinearUnitMillimeters,
            out int dispErrCode
        );

        Console.WriteLine("Raw dispValuesObj output:");

        // Check for errors first
        if (dispErrCode != 0)
        {
            Console.WriteLine($"Failed to get displacement. Error code: {dispErrCode}");
            return;
        }

        // Check if we got DBNull
        if (dispValuesObj == DBNull.Value)
        {
            Console.WriteLine("No displacement data available for this node.");
            return;
        }

        // Now try to cast to Array
        Array dispArray = null;
        try
        {
            dispArray = (Array)dispValuesObj;
        }
        catch (InvalidCastException)
        {
            Console.WriteLine("Invalid data type returned. Expected array.");
            return;
        }

        if (dispArray != null && dispArray.Length > 0)
        {
            for (int i = 0; i < dispArray.Length; i++)
            {
                object value = dispArray.GetValue(i);
                Console.WriteLine($"  Index {i}: {value}");
            }
            object firstValue = dispArray.GetValue(0);
            double dispAtPoint = Convert.ToDouble(firstValue);
            Console.WriteLine(
                $"Displacement at point ({closestNodeCoords[0]}, {closestNodeCoords[1]}, {closestNodeCoords[2]}): {dispAtPoint} mm"
            );
        }
        else
        {
            Console.WriteLine("No displacement values returned (array was null or empty).");
        }

Guten Abend

Das Problem mit der GetDisplacementComponentForAllStepsAtNode-Methode hängt wahrscheinlich damit zusammen, dass die Studie statisch ist.

Für den Knoten, der vom Parameter NNodeNum übertragen wird, soll diese Funktion die Werte der Verschiebung für die aufeinanderfolgenden Rechenschritte zurückgeben, die vom Solver ausgeführt werden.
Bei einer statischen Studie gibt es nur einen berechneten Schritt, der dem angeforderten Endzustand entspricht, und die Funktion schlägt mit dem Fehlercode 4 fehl.
Die Animation in den Ergebnissen ist eine einfache Interpolation zwischen dem anfänglichen nicht angeforderten Zustand und dem angeforderten Endzustand.

Wenn Sie eine nichtlineare Studie durchführen, führt der Gleichungslöser die Berechnung in aufeinanderfolgenden Schritten aus, wobei jeder Schritt Ergebnisse liefert, und die GetDisplacementComponentForAllStepsAtNode-Methode funktioniert und gibt das Verschiebungsarray zurück...

Guten Tag

Oh, das macht jetzt Sinn. Aber ich möchte eine statische Studie durchführen und das Abweichende in die bekommen. CSV-Datei? Kann ich also die GetDisplacementAtPoints-Methode verwenden? Wenn ja, helfen Sie mir bitte mit dem Code.