Sure. I modified the SingleWheelTest demo to run the wheel under different slip ratios. I set a for loop in main function. But only the first slip ratio ran.
在2023年4月3日星期一 UTC+8 21:08:18<Dan Negrut> 写道: > Perhaps we can help if you drop here the file that runs the loop to carry > out the analysis. We need more info to try to help you. > > > > Dan > > --------------------------------------------- > > Bernard A. and Frances M. Weideman Professor > > NVIDIA CUDA Fellow > > Department of Mechanical Engineering > > Department of Computer Science > > University of Wisconsin - Madison > > 4150ME, 1513 University Avenue > > Madison, WI 53706-1572 > > 608 772 0914 <(608)%20772-0914> > > http://sbel.wisc.edu/ > > http://projectchrono.org/ > > --------------------------------------------- > > > > *From:* [email protected] <[email protected]> *On > Behalf Of *Chiny Lan > *Sent:* Monday, April 3, 2023 4:45 AM > *To:* ProjectChrono <[email protected]> > *Subject:* [chrono] Simulation with a set of parameters in one program > > > > Hi, > > > > I want to simulate sand with different parameters using FSI. I used a for > loop in main function to implement the series of simulation. But when the > first simulation done, the program also closed. > > > > How can I do seris simulation with a set of parameters in one program? > > > > Thanks and regards. > > -- > You received this message because you are subscribed to the Google Groups > "ProjectChrono" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/projectchrono/46b75e69-cef3-4c4f-9b00-26603e5bfff7n%40googlegroups.com > > <https://groups.google.com/d/msgid/projectchrono/46b75e69-cef3-4c4f-9b00-26603e5bfff7n%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "ProjectChrono" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/projectchrono/0503b868-9cbd-48f5-895e-a8da1ab431e4n%40googlegroups.com.
// ============================================================================= // PROJECT CHRONO - http://projectchrono.org // // Copyright (c) 2014 projectchrono.org // All rights reserved. // // Use of this source code is governed by a BSD-style license that can be found // in the LICENSE file at the top level of the distribution and at // http://projectchrono.org/license-chrono.txt. // // ============================================================================= // Author: Wei Hu, Radu Serban // ============================================================================= // 2023.04.01: Qingning Lan // Modified the code to run single wheel test with for loop in different slip // Slip ratio = -1.0, -0.6, -0.3, 0.0, 0.3, 0.6, 0.8 // ============================================================================= #include <cassert> #include <cstdlib> #include <iostream> #include <vector> #include <string> #include <sstream> #include <cmath> #include "chrono/ChConfig.h" #include "chrono/physics/ChSystemSMC.h" #include "chrono/physics/ChBody.h" #include "chrono/physics/ChInertiaUtils.h" #include "chrono/physics/ChLinkMotorRotationAngle.h" #include "chrono/utils/ChUtilsCreators.h" #include "chrono/utils/ChUtilsGenerators.h" #include "chrono/utils/ChUtilsGeometry.h" #include "chrono/assets/ChBoxShape.h" #include "chrono/utils/ChUtilsInputOutput.h" #include "chrono/assets/ChTriangleMeshShape.h" #include "chrono/core/ChTimer.h" #include "chrono_fsi/ChSystemFsi.h" #include "chrono_fsi/ChVisualizationFsi.h" #include "chrono_thirdparty/filesystem/path.h" // Chrono namespaces using namespace chrono; using namespace chrono::fsi; using namespace chrono::geometry; using namespace std; // Set Slip ratio vector std::vector<double> slip_ratios = {-1.0, -0.6, -0.3, 0.0, 0.3, 0.6, 0.8}; std::vector<string> slip_ratios_str = {"-1.0", "-0.6", "-0.3", "0.0", "0.3", "0.6", "0.8"}; // Physical properties of terrain particles double iniSpacing = 0.004; double kernelLength = 0.004; double density = 1700.0; // Dimension of the terrain container double smalldis = 1.0e-9; double bxDim = 1.0 + smalldis; double byDim = 0.4 + smalldis; double bzDim = 0.18 + smalldis; // Size of the wheel double wheel_radius = 0.135; double wheel_width = 0.165; double velocity = 0.04; // Gravity is 80N // double total_mass = 8.1549439348; double total_mass = 13.25; // Simulation time and stepsize // Simulate 20sec for each slip ratio, displacement = 0.6m double total_time = 16.0; double dT = 1.0e-4; // linear actuator and angular actuator auto actuator = chrono_types::make_shared<ChLinkLinActuator>(); auto motor = chrono_types::make_shared<ChLinkMotorRotationAngle>(); // Save data as csv files to see the results off-line using Paraview bool output = true; int out_fps = 10; // Enable/disable run-time visualization (if Chrono::OpenGL is available) bool render = true; float render_fps = 100; // Verbose terminal output bool verbose_fsi = true; bool verbose = true; //------------------------------------------------------------------ // Function to save wheel to Paraview VTK files //------------------------------------------------------------------ void WriteCylinderVTK(const std::string& filename, double radius, double length, const ChFrame<>& frame, unsigned int res) { std::ofstream outf; outf.open(filename, std::ios::app); outf << "# vtk DataFile Version 2.0\nUnstructured Grid Example\nASCII\n\n" << std::endl; outf << "DATASET UNSTRUCTURED_GRID\nPOINTS " << 2 * res << " float\n"; for (int i = 0; i < res; i++) { auto w = frame.TransformPointLocalToParent( ChVector<>(radius * cos(2 * i * 3.1415 / res), -1 * length / 2, radius * sin(2 * i * 3.1415 / res))); outf << w.x() << " " << w.y() << " " << w.z() << "\n"; } for (int i = 0; i < res; i++) { auto w = frame.TransformPointLocalToParent( ChVector<>(radius * cos(2 * i * 3.1415 / res), +1 * length / 2, radius * sin(2 * i * 3.1415 / res))); outf << w.x() << " " << w.y() << " " << w.z() << "\n"; } outf << "CELLS " << res + res << "\t" << 5 * (res + res) << "\n"; for (int i = 0; i < res - 1; i++) { outf << "4 " << i << " " << i + 1 << " " << i + res + 1 << " " << i + res << "\n"; } outf << "4 " << res - 1 << " " << 0 << " " << res << " " << 2 * res - 1 << "\n"; for (int i = 0; i < res / 4; i++) { outf << "4 " << i << " " << i + 1 << " " << +res / 2 - i - 1 << " " << +res / 2 - i << "\n"; } for (int i = 0; i < res / 4; i++) { outf << "4 " << i + res << " " << i + 1 + res << " " << +res / 2 - i - 1 + res << " " << +res / 2 - i + res << "\n"; } outf << "4 " << +res / 2 << " " << 1 + res / 2 << " " << +res - 1 << " " << 0 << "\n"; for (int i = 1; i < res / 4; i++) { outf << "4 " << i + res / 2 << " " << i + 1 + res / 2 << " " << +res / 2 - i - 1 + res / 2 << " " << +res / 2 - i + res / 2 << "\n"; } outf << "4 " << 3 * res / 2 << " " << 1 + 3 * res / 2 << " " << +2 * res - 1 << " " << +res << "\n"; for (int i = 1; i < res / 4; i++) { outf << "4 " << i + 3 * res / 2 << " " << i + 1 + 3 * res / 2 << " " << +2 * res - i - 1 << " " << +2 * res - i << "\n"; } outf << "\nCELL_TYPES " << res + res << "\n"; for (int iele = 0; iele < (res + res); iele++) { outf << "9\n"; } } //------------------------------------------------------------------ // Create the objects of the MBD system. Rigid bodies, and if FSI, // their BCE representation are created and added to the systems //------------------------------------------------------------------ void CreateSolidPhase(ChSystemSMC& sysMBS, ChSystemFsi& sysFSI, double wheel_slip) { // Wheel angular velocity double wheel_AngVel; if (wheel_slip >= 0) { wheel_AngVel = velocity / wheel_radius / (1 - wheel_slip); } else { wheel_AngVel = velocity / wheel_radius * (1 + wheel_slip); } // Common contact material auto cmaterial = chrono_types::make_shared<ChMaterialSurfaceSMC>(); cmaterial->SetYoungModulus(1e8); cmaterial->SetFriction(0.9f); cmaterial->SetRestitution(0.4f); cmaterial->SetAdhesion(0); // Create a container -- always FIRST body in the system auto ground = chrono_types::make_shared<ChBody>(); ground->SetIdentifier(-1); ground->SetBodyFixed(true); sysMBS.AddBody(ground); ground->GetCollisionModel()->ClearModel(); chrono::utils::AddBoxContainer(ground, cmaterial, ChFrame<>(), ChVector<>(bxDim, byDim, bzDim), 0.1, ChVector<int>(0, 0, -1), false); ground->GetCollisionModel()->BuildModel(); ground->SetCollide(true); // Add BCE particles attached on the walls into FSI system sysFSI.AddContainerBCE(ground, ChFrame<>(), ChVector<>(bxDim, byDim, 2 * bzDim), ChVector<int>(2, 0, -1)); // Create the wheel -- always SECOND body in the system auto wheel = chrono_types::make_shared<ChBody>(); // Set the general wheel properties ChVector<> gyration = chrono::utils::CalcCylinderGyration(wheel_radius, wheel_width / 2).diagonal(); ChVector<> wheel_IniPos(-bxDim / 2 + 1.2 * wheel_radius, 0.0, wheel_radius + bzDim + 1.0 * iniSpacing); ChVector<> wheel_IniVel(0.0, 0.0, 0.0); wheel->SetPos(wheel_IniPos); wheel->SetPos_dt(wheel_IniVel); wheel->SetWvel_loc(ChVector<>(0.0, 0.0, 0.0)); wheel->SetMass(total_mass * 1.0 / 2.0); wheel->SetInertiaXX(total_mass * gyration); // Set the collision wheel->SetCollide(false); wheel->SetBodyFixed(false); wheel->GetCollisionModel()->ClearModel(); // wheel->GetCollisionModel()->SetSafeMargin(iniSpacing); // chrono::utils::AddCylinderGeometry(wheel.get(), cmaterial, wheel_radius, wheel_width / 2, VNULL, QUNIT); wheel->GetCollisionModel()->AddCylinder(cmaterial, wheel_radius, wheel_radius, wheel_width / 2, VNULL, QUNIT); // wheel->GetCollisionModel()->SetEnvelope(0.001); wheel->GetCollisionModel()->BuildModel(); // Add the wheel to the MBD system sysMBS.AddBody(wheel); // Add the wheel to the FSI system sysFSI.AddFsiBody(wheel); // Add BCE particles attached on the wheel into FSI system sysFSI.AddCylinderBCE(wheel, ChFrame<>(VNULL, Q_from_AngX(CH_C_PI_2)), wheel_radius, wheel_width, true); // Create the chassis -- always THIRD body in the system auto chassis = chrono_types::make_shared<ChBody>(); chassis->SetMass(total_mass * 1.0 / 2.0); chassis->SetPos(wheel->GetPos()); chassis->SetCollide(false); chassis->SetBodyFixed(false); // Add geometry of the chassis. chassis->GetCollisionModel()->ClearModel(); chrono::utils::AddBoxGeometry(chassis.get(), cmaterial, ChVector<>(0.1, 0.01, 0.01), ChVector<>(0, 0, 0)); chassis->GetCollisionModel()->BuildModel(); sysMBS.AddBody(chassis); // Create the axle -- always FOURTH body in the system auto axle = chrono_types::make_shared<ChBody>(); axle->SetMass(total_mass * 1.0 / 2.0); axle->SetPos(wheel->GetPos()); axle->SetCollide(false); axle->SetBodyFixed(false); // Add geometry of the axle. axle->GetCollisionModel()->ClearModel(); chrono::utils::AddSphereGeometry(axle.get(), cmaterial, 0.01, ChVector<>(0, 0, 0)); axle->GetCollisionModel()->BuildModel(); sysMBS.AddBody(axle); // Connect the chassis to the containing bin (ground) through a translational joint and create a linear actuator. auto prismatic1 = chrono_types::make_shared<ChLinkLockPrismatic>(); prismatic1->Initialize(ground, chassis, ChCoordsys<>(chassis->GetPos(), Q_from_AngY(CH_C_PI_2))); prismatic1->SetName("prismatic_chassis_ground"); sysMBS.AddLink(prismatic1); auto actuator_fun = chrono_types::make_shared<ChFunction_Ramp>(0.0, velocity); actuator->Initialize(ground, chassis, false, ChCoordsys<>(chassis->GetPos(), QUNIT), ChCoordsys<>(chassis->GetPos() + ChVector<>(1, 0, 0), QUNIT)); actuator->SetName("actuator"); actuator->SetDistanceOffset(1); actuator->SetActuatorFunction(actuator_fun); sysMBS.AddLink(actuator); // Connect the axle to the chassis through a vertical translational joint. auto prismatic2 = chrono_types::make_shared<ChLinkLockPrismatic>(); prismatic2->Initialize(chassis, axle, ChCoordsys<>(chassis->GetPos(), QUNIT)); prismatic2->SetName("prismatic_axle_chassis"); sysMBS.AddLink(prismatic2); // Connect the wheel to the axle through a engine joint. motor->SetName("engine_wheel_axle"); motor->Initialize(wheel, axle, ChFrame<>(wheel->GetPos(), chrono::Q_from_AngAxis(-CH_C_PI / 2.0, ChVector<>(1, 0, 0)))); motor->SetAngleFunction(chrono_types::make_shared<ChFunction_Ramp>(0, wheel_AngVel)); sysMBS.AddLink(motor); } // ============================================================================= int main(int argc, char* argv[]) { // Output directories and settings, set the Release directory as the working directory const std::string out_dir_base = "output/"; if (!filesystem::create_directory(filesystem::path(out_dir_base))) std::cout << "Error creating directory " << out_dir_base << std::endl; // A loop to run the simulation for different slip ratios for (int i = 0; i < slip_ratios.size(); i++) { // Create the output directory std::string out_dir = out_dir_base + "S" + slip_ratios_str[i]; // Create oputput directories if (!filesystem::create_directory(filesystem::path(out_dir))) { std::cerr << "Error creating directory " << out_dir << std::endl; return 1; } if (!filesystem::create_directory(filesystem::path(out_dir + "/particles"))) { std::cerr << "Error creating directory " << out_dir + "/particles" << std::endl; return 1; } if (!filesystem::create_directory(filesystem::path(out_dir + "/fsi"))) { std::cerr << "Error creating directory " << out_dir + "/fsi" << std::endl; return 1; } if (!filesystem::create_directory(filesystem::path(out_dir + "/vtk"))) { std::cerr << "Error creating directory " << out_dir + "/vtk" << std::endl; return 1; } // Create the MBS and FSI systems ChSystemSMC sysMBS; ChSystemFsi sysFSI(&sysMBS); ChVector<> gravity = ChVector<>(0, 0, -9.81); sysMBS.Set_G_acc(gravity); sysFSI.Set_G_acc(gravity); sysFSI.SetVerbose(verbose_fsi); // Use the default input file or you may enter your input parameters as a command line argument std::string inputJson = "demo_FSI_SingleWheelTest.json"; sysFSI.ReadParametersFromFile(inputJson); // Set the terrain container size sysFSI.SetContainerDim(ChVector<>(bxDim, byDim, bzDim)); // Set SPH discretization type, consistent or inconsistent sysFSI.SetDiscreType(false, false); // Set wall boundary condition sysFSI.SetWallBC(BceVersion::ADAMI); // Set rigid body boundary condition sysFSI.SetRigidBodyBC(BceVersion::ADAMI); // Set cohsion of the granular material sysFSI.SetCohesionForce(0); // Setup the SPH method sysFSI.SetSPHMethod(FluidDynamics::WCSPH); // Set up the periodic boundary condition (if not, set relative larger values) ChVector<> cMin(-bxDim / 2 * 10, -byDim / 2 - 0.5 * iniSpacing, -bzDim * 3); ChVector<> cMax(bxDim / 2 * 10, byDim / 2 + 0.5 * iniSpacing, bzDim * 10); sysFSI.SetBoundaries(cMin, cMax); // Initialize the SPH particles chrono::utils::GridSampler<> sampler(iniSpacing); ChVector<> boxCenter(0.0, 0.0, bzDim / 2); ChVector<> boxHalfDim(bxDim / 2, byDim / 2, bzDim / 2); sysFSI.AddBoxSPH(boxCenter, boxHalfDim); // Create Solid region and attach BCE SPH particles CreateSolidPhase(sysMBS, sysFSI, slip_ratios[i]); // Set simulation data output length sysFSI.SetOutputLength(0); // Construction of the FSI system must be finalized before running sysFSI.Initialize(); auto wheel = sysMBS.Get_bodylist()[1]; ChVector<> force = actuator->Get_react_force(); ChVector<> torque = motor->Get_react_torque(); ChVector<> w_pos = wheel->GetPos(); ChVector<> w_vel = wheel->GetPos_dt(); ChVector<> angvel = wheel->GetWvel_loc(); // Write the information into a txt file std::ofstream myFile; std::ofstream myDBP_Torque; if (output) { myFile.open(out_dir + "/results.txt", std::ios::trunc); myDBP_Torque.open(out_dir + "/DBP_Torque.txt", std::ios::trunc); } // Create a run-tme visualizer ChVisualizationFsi fsi_vis(&sysFSI); if (render) { fsi_vis.SetTitle("Chrono::FSI single wheel demo"); fsi_vis.SetCameraPosition(ChVector<>(0.8 * bxDim, -3 * byDim, 3 * bzDim), ChVector<>(0, 1, -0.5)); fsi_vis.SetCameraMoveScale(0.05f); fsi_vis.EnableBoundaryMarkers(true); fsi_vis.Initialize(); } // Start the simulation unsigned int output_steps = (unsigned int)round(1 / (out_fps * dT)); unsigned int render_steps = (unsigned int)round(1 / (render_fps * dT)); double time = 0.0; int current_step = 0; ChTimer<> timer; timer.start(); double sinkage; while (time < total_time) { // Get the infomation of the wheel force = actuator->Get_react_force(); torque = motor->Get_react_torque(); w_pos = wheel->GetPos(); w_vel = wheel->GetPos_dt(); angvel = wheel->GetWvel_loc(); sinkage = bzDim + wheel_radius - w_pos.z() + 0.5 * iniSpacing; if (verbose) { std::cout << "slip ratio: " << slip_ratios_str[i] << std::endl; std::cout << "time: " << time << std::endl; std::cout << " wheel position: " << w_pos << std::endl; std::cout << " wheel linear velocity: " << w_vel << std::endl; std::cout << " wheel angular velocity: " << angvel << std::endl; std::cout << " drawbar pull: " << force << std::endl; std::cout << " wheel torque: " << torque << std::endl; std::cout << " sinkage: " << sinkage << std::endl; } if (output) { myFile << time << "\t" << w_pos.x() << "\t" << w_pos.y() << "\t" << w_pos.z() << "\t" << w_vel.x() << "\t" << w_vel.y() << "\t" << w_vel.z() << "\t" << angvel.x() << "\t" << angvel.y() << "\t" << angvel.z() << "\t" << force.x() << "\t" << force.y() << "\t" << force.z() << "\t" << torque.x() << "\t" << torque.y() << "\t" << torque.z() << "\n"; myDBP_Torque << time << "\t" << force.x() << "\t" << torque.z() << "\n"; } if (output && current_step % output_steps == 0) { std::cout << "-------- Output" << std::endl; sysFSI.PrintParticleToFile(out_dir + "/particles"); sysFSI.PrintFsiInfoToFile(out_dir + "/fsi", time); static int counter = 0; std::string filename = out_dir + "/vtk/wheel." + std::to_string(counter++) + ".vtk"; WriteCylinderVTK(filename, wheel_radius, wheel_width, sysFSI.GetFsiBodies()[0]->GetFrame_REF_to_abs(), 100); } // Render SPH particles if (render && current_step % render_steps == 0) { if (!fsi_vis.Render()) break; } // Call the FSI solver sysFSI.DoStepDynamics_FSI(); time += dT; current_step++; } timer.stop(); std::cout << "\nSimulation time: " << timer() << " seconds\n" << std::endl; if (output) { myFile.close(); myDBP_Torque.close(); } return 0; } }
