SolidWorks-simulatie-API - AddForce3

Ik heb een cilinder en ik heb een cirkelvormig gezicht gemaakt met behulp van warpgereedschap. Ik wil de cilinder simuleren voor verplaatsing en in deze stap wil ik kracht uitoefenen op het cirkelvormige vlak dat ik heb geselecteerd. Ik wil uniforme kracht uitoefenen in de Z-richting van het coördinatensysteem ongeveer 400N. Toen ik deze code uitvoerde, kreeg ik foutcode 6 voor de AddForce3. Kan iemand me alsjeblieft helpen? Ik deed dit in C#. Ik probeer het in eerste instantie met één gezicht en kracht. Ik zal het met meerdere gezichten en kracht maken als dit lukt. Ik gaf de afbeelding van de cilinder hieronder.

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
We zien in het document dat:
Als ForceType = swsForceType_e.swsForceTypeNormal dan specificeer:

  • Composities met een matrix van zes waarden: [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
  • Ucode met 0
    Dus we moeten het proberen met Ucode op 0 in plaats van 4.

Dan geeft de fout een ongeldige matrix aan. Het kan ook de DispArray-parameter zijn die geen null-waarde accepteert.

Ik heb de code bijgewerkt zoals hieronder. Nu heb ik de foutcode 3.

        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 Kunt u mij hier ook mee helpen?

Goedenavond @Krishna_Prasanth_Thiruvalluvar ,

De parameter (beamArray) die u doorgeeft aan de functie AddForce3 moet een array zijn die vlakken of randen van een Solidworks-lichaam bevat.
In uw code verwijst dit naar de volumebehuizing zelf, niet naar de vlakken of randen. Zie de volgende instructies:

In uw geval is de eenvoudigste manier om Z-volgende inspanningen te creëren:

  • Selecteer een rand of as in de richting Z of een vlak met een normale Z en wijs deze toe aan de parameter ReferenceGeometry .
  • selecteer de vlakken die de kracht ondersteunen en geef ze in de vorm van een array door aan de parameter (DispArray);
  • Definieer de uCode-waarde als een additieve combinatie van 1, 2 en 4, afhankelijk van de gewenste componenten. Alleen al voor de Z-richting: uCode = 4;
  • definieer de waarden van de componenten en geef ze door aan de matrix (ComponentValues) (alleen de eerste drie zijn nodig).

VBA-syntaxis:

Kracht instellen = loadMgr.AddForce3(swsForceTypeForceOrMoment, _
swsSelectionFaceEdgeVertexPoint, 0, 0, 0, 0, (DistanceValues), (ForceValues), _
Onwaar, Onwaar, 0, 0, 1 + 2 + 4, 0, (ComponentWaarden), Onwaar, Onwaar, (DispArray), _
ReferenceGeometry, Onwaar, loadErr)

Moet ik alleen de selBeam gebruiken of moeten zowel selBeam als selFace worden gebruikt om het gewenste vlak te selecteren om de normaalkracht toe te passen? Ik had het mis in de oorspronkelijke vraag, omdat ik een normaalkracht wil die op elk vlak van de cilinder werkt. Kunt u mij helpen hoe ik verder moet gaan?

Aangezien het nu een normale kracht is, zou UCode 0 moeten zijn. Hoe zit het met de andere parameters?

Hallo

De samengevoegde macro, in VBA, creëert een normaalkracht op elk van de eerder geselecteerde vlakken op een SW-lichaam.
Om de inspanning aan elke kant normaal te laten zijn, is het noodzakelijk om:

  • of het type inspanning swsForceTypeNormal is,
  • dat uCode = 0
  • dat de waarde van de kracht (123,0) wordt doorgegeven aan de parameter TorqueNFVal
  • en dat ReferenceGeometry leeg is.

Geen opmerkingen en geen garanties... :wink:

AddForce.swp (60.5 KB)

Verbazingwekkend! Heel hartelijk bedankt. Ik heb de C#-code aangepast op basis van de VBA en toen heb ik de kracht erop laten uitoefenen.

Mijn volgende taak is het exporteren van de verplaatsing op een specifiek punt. Dus ik probeerde de GetDisplacementComponentForAllStepsAtNode-methode en de GetDisplacementAtPoints-methode te gebruiken. Maar ik kon het resultaat niet krijgen zoals verwacht.

Met behulp van de GetDisplacementComponentForAllStepsAtNode-methode heb ik het dichtstbijzijnde knooppunt gevonden van het punt waarin ik geïnteresseerd ben en heb ik dit knooppuntnummer vervolgens aan de methode gegeven om de verplaatsingswaarde op de console weer te geven.

Met behulp van de GetDisplacementAtPoints-methode heb ik de coördinaten van het dichtstbijzijnde knooppunt van het punt waarin ik geïnteresseerd ben rechtstreeks ingevoerd en vervolgens geprobeerd deze op de console weer te geven. Maar het werkte ook niet. Hoe kan ik dit mogelijk maken? Ik ben geïnteresseerd in het exporteren van de verplaatsingswaarden in .csv bestand. Dus ik wilde deze stap doen.

De onderstaande code wordt gedaan na de meshing en vervolgens het uitvoeren van de simulatie. Ik heb de maximale en minimale verplaatsing gevonden, dan wordt het punt waarop ik de verplaatsing wil meten nu direct in de code vermeld. Ik vond de dichtstbijzijnde node en probeerde de bovengenoemde methoden. De code geeft foutcode 4 wanneer ik de eerste methode gebruik

        // 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).");
        }

Goedenavond

Het probleem met de methode GetDisplacementComponentForAllStepsAtNode heeft waarschijnlijk te maken met het feit dat het onderzoek statisch is.

Voor het knooppunt dat door de parameter NNodeNum wordt verzonden, is deze functie bedoeld om de waarden van de verplaatsing te retourneren voor de opeenvolgende rekenstappen die door de oplosser worden uitgevoerd.
In het geval van een statische studie is er slechts één berekende stap die overeenkomt met de gevraagde eindtoestand en mislukt de functie met foutcode 4.
Animatie in de resultaten is een eenvoudige interpolatie tussen de initiële ongevraagde toestand en de gevraagde eindtoestand.

Als u een niet-lineair onderzoek uitvoert, voert de oplosser de berekening uit in opeenvolgende stappen, waarbij elke stap resultaten oplevert, en de methode GetDisplacementComponentForAllStepsAtNode werkt en retourneert de verplaatsingsmatrix...

Goedemiddag

Oh, dat is nu logisch. Maar ik wil Statische studie doen en het onpalecent in de . CSV-bestand? Dus kan ik de GetDisplacementAtPoints-methode gebruiken? Zo ja, help me dan met de code.