Hello, I am trying to simulate a case of flexible ball impacting water surface (similar to the case cylinderDrop, the difference is the cylinder is elastic install regid). The ball mesh was imported from obj file instead of generated manually.
1. I made an example case out of "fsi_felxbile element" & "fsi_cylinderdrop", but is a bit lost regarding the BCE setting? how can the BCE be applied for the imported fem mesh? 2. The examples case i made is attached. It seems the case can not be compiled with many errors. Could you please kindly help to quick check what is wrong in my codes? 3. Regarding the post processing, i would like to show the deformation & stress of the elastic body as well as the pressure/velocity contour map of the fluid to be exported to vtk file. how can this be done? -- 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/d7917585-9dd6-4989-9878-dd86fb95d425n%40googlegroups.com.
// ============================================================================= // PROJECT CHRONO - http://projectchrono.org // // Copyright (c) 2014 projectchrono.org // All right 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: Milad Rakhsha // ============================================================================= #include <assert.h> #include <stdlib.h> #include <ctime> #include "chrono/physics/ChSystemSMC.h" #ifdef CHRONO_PARDISO_MKL #include "chrono_pardisomkl/ChSolverPardisoMKL.h" #endif #include "chrono/solver/ChIterativeSolverLS.h" #include "chrono/utils/ChUtilsCreators.h" #include "chrono/utils/ChUtilsGenerators.h" #include "chrono/utils/ChUtilsGeometry.h" #include "chrono_fsi/ChSystemFsi.h" #include "chrono_fsi/ChVisualizationFsi.h" #include "chrono/assets/ChBoxShape.h" #include "chrono/fea/ChElementShellBST.h" #include "chrono/fea/ChMesh.h" #include "chrono/fea/ChMeshFileLoader.h" #include "chrono/fea/ChMeshExporter.h" #include "chrono/fea/ChBuilderBeam.h" #include "chrono/fea/ChLinkDirFrame.h" #include "chrono/fea/ChLinkPointFrame.h" #include "chrono_thirdparty/filesystem/path.h" // Chrono namespaces using namespace chrono; using namespace chrono::fea; using namespace chrono::collision; using namespace chrono::fsi; // Set the output directory const std::string out_dir = GetChronoOutputPath() + "FSI_Flexible_Elements/"; std::string MESH_CONNECTIVITY = out_dir + "Flex_MESH.vtk"; // Dimension of the domain double smalldis = 1.0e-9; double bxDim = 3.0 + smalldis; double byDim = 0.2 + smalldis; double bzDim = 2.0 + smalldis; // Dimension of the fluid domain double fxDim = 1.0 + smalldis; double fyDim = 0.2 + smalldis; double fzDim = 1.0 + smalldis; bool flexible_elem_1D = false; // Output frequency bool output = true; double out_fps = 20; // Final simulation time double t_end = 10.0; // Enable/disable run-time visualization (if Chrono::OpenGL is available) bool render = true; float render_fps = 100; std::vector<std::vector<int>> NodeNeighborElement_mesh; void Create_MB_FE(ChSystemSMC& sysMBS, ChSystemFsi& sysFSI); //------------------------------------------------------------------ // Function to add walls into Chrono system //------------------------------------------------------------------ void AddWall(std::shared_ptr<ChBody> body, const ChVector<>& dim, std::shared_ptr<ChMaterialSurface> mat, const ChVector<>& loc) { body->GetCollisionModel()->AddBox(mat, dim.x(), dim.y(), dim.z(), loc); auto box = chrono_types::make_shared<ChBoxShape>(); box->GetBoxGeometry().Size = dim; } int main(int argc, char* argv[]) { // 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 + "/vtk"))) { std::cerr << "Error creating directory " << out_dir + "/vtk" << std::endl; return 1; } // Create a physics system and an FSI system ChSystemSMC sysMBS; ChSystemFsi sysFSI(sysMBS); // Use the default input file or you may enter your input parameters as a command line argument std::string inputJson = GetChronoDataFile("fsi/input_json/demo_FSI_Flexible_Elements_Explicit.json"); if (argc == 1) { std::cout << "Use the default JSON file" << std::endl; } else if (argc == 2) { std::cout << "Use the specified JSON file" << std::endl; std::string my_inputJson = std::string(argv[1]); inputJson = my_inputJson; } else { std::cout << "usage: ./demo_FSI_Flexible_Elements <json_file>" << std::endl; return 1; } sysFSI.ReadParametersFromFile(inputJson); sysFSI.SetContainerDim(ChVector<>(bxDim, byDim, bzDim)); auto initSpace0 = sysFSI.GetInitialSpacing(); ChVector<> cMin = ChVector<>(-5 * bxDim, -byDim / 2.0 - initSpace0 / 2.0, -5 * bzDim ); ChVector<> cMax = ChVector<>( 5 * bxDim, byDim / 2.0 + initSpace0 / 2.0, 5 * bzDim ); sysFSI.SetBoundaries(cMin, cMax); // Setup the output directory for FSI data sysFSI.SetOutputDirectory(out_dir); // Create SPH particles of fluid region chrono::utils::GridSampler<> sampler(initSpace0); ChVector<> boxCenter(-bxDim / 2 + fxDim / 2, 0, fzDim / 2 + 1 * initSpace0); ChVector<> boxHalfDim(fxDim / 2, fyDim / 2, fzDim / 2); chrono::utils::Generator::PointVector points = sampler.SampleBox(boxCenter, boxHalfDim); size_t numPart = points.size(); for (int i = 0; i < numPart; i++) { sysFSI.AddSPHParticle(points[i]); } // Create solids Create_MB_FE(sysMBS, sysFSI); sysFSI.Initialize(); auto my_mesh = sysFSI.GetFsiMesh(); // Create a run-tme visualizer ChVisualizationFsi fsi_vis(&sysFSI); if (render) { fsi_vis.SetTitle("Chrono::FSI flexible element demo"); fsi_vis.SetCameraPosition(ChVector<>(bxDim / 8, -3, 0.25), ChVector<>(bxDim / 8, 0.0, 0.25)); fsi_vis.SetCameraMoveScale(1.0f); fsi_vis.EnableBoundaryMarkers(false); fsi_vis.Initialize(); } // Set MBS solver #ifdef CHRONO_PARDISO_MKL auto mkl_solver = chrono_types::make_shared<ChSolverPardisoMKL>(); mkl_solver->LockSparsityPattern(true); sysMBS.SetSolver(mkl_solver); #else auto solver = chrono_types::make_shared<ChSolverMINRES>(); sysMBS.SetSolver(solver); solver->SetMaxIterations(2000); solver->SetTolerance(1e-10); solver->EnableDiagonalPreconditioner(true); solver->SetVerbose(false); sysMBS.SetSolverForceTolerance(1e-10); #endif // Simulation loop double dT = sysFSI.GetStepSize(); unsigned int output_steps = (unsigned int)(1 / (out_fps * dT)); unsigned int render_steps = (unsigned int)(1 / (render_fps * dT)); double time = 0.0; int current_step = 0; ChTimer<> timer; timer.start(); while (time < t_end) { std::cout << current_step << " time: " << time << std::endl; if (output && current_step % output_steps == 0) { std::cout << "-------- Output" << std::endl; sysFSI.PrintParticleToFile(out_dir + "/particles"); static int counter = 0; std::string filename = out_dir + "/vtk/flex_body." + std::to_string(counter++) + ".vtk"; fea::ChMeshExporter::writeFrame(my_mesh, (char*)filename.c_str(), MESH_CONNECTIVITY); } // Render SPH particles if (render && current_step % render_steps == 0) { if (!fsi_vis.Render()) break; } sysFSI.DoStepDynamics_FSI(); time += dT; current_step++; } timer.stop(); std::cout << "\nSimulation time: " << timer() << " seconds\n" << std::endl; return 0; } //-------------------------------------------------------------------- // Create the objects of the MBD system. Rigid/flexible bodies, and if // fsi, their bce representation are created and added to the systems void Create_MB_FE(ChSystemSMC& sysMBS, ChSystemFsi& sysFSI) { sysMBS.Set_G_acc(ChVector<>(0, 0, 0)); sysFSI.Set_G_acc(ChVector<>(0, 0, -9.81)); // Set common material Properties auto wallmaterial = chrono_types::make_shared<ChMaterialSurfaceSMC>(); wallmaterial->SetYoungModulus(1e8); wallmaterial->SetFriction(0.2f); wallmaterial->SetRestitution(0.05f); wallmaterial->SetAdhesion(0); // Get particle spacing in the simulation auto initSpace0 = sysFSI.GetInitialSpacing(); // Bottom and top wall - size and position ChVector<> size_XY(bxDim / 2 + 3 * initSpace0, byDim / 2 + 3 * initSpace0, 2 * initSpace0); ChVector<> pos_zp(0, 0, 2 * bzDim + 1 * initSpace0); ChVector<> pos_zn(0, 0, -3 * initSpace0); // Left and right wall - size and position ChVector<> size_YZ(2 * initSpace0, byDim / 2 + 3 * initSpace0, bzDim); ChVector<> pos_xp(bxDim / 2 + initSpace0, 0.0, bzDim + 0 * initSpace0); ChVector<> pos_xn(-bxDim / 2 - 3 * initSpace0, 0.0, bzDim + 0 * initSpace0); // Front and back wall - size and position ChVector<> size_XZ(bxDim / 2, 2 * initSpace0, bzDim); ChVector<> pos_yp(0, byDim / 2 + initSpace0, bzDim + 0 * initSpace0); ChVector<> pos_yn(0, -byDim / 2 - 3 * initSpace0, bzDim + 0 * initSpace0); // Create a container auto box = chrono_types::make_shared<ChBody>(); box->SetPos(ChVector<>(0.0, 0.0, 0.0)); box->SetRot(ChQuaternion<>(1, 0, 0, 0)); box->SetIdentifier(-1); box->SetBodyFixed(true); box->GetCollisionModel()->ClearModel(); box->GetCollisionModel()->SetSafeMargin(initSpace0 / 2); // Add the walls into chrono system AddWall(box, size_XY, wallmaterial, pos_zp); AddWall(box, size_XY, wallmaterial, pos_zn); AddWall(box, size_YZ, wallmaterial, pos_xp); AddWall(box, size_YZ, wallmaterial, pos_xn); AddWall(box, size_XZ, wallmaterial, pos_yp); AddWall(box, size_XZ, wallmaterial, pos_yn); box->GetCollisionModel()->BuildModel(); box->SetCollide(true); sysMBS.AddBody(box); // Add BCE particles attached on the walls into FSI system sysFSI.AddBoxBCE(box, pos_zp, QUNIT, size_XY, 12); sysFSI.AddBoxBCE(box, pos_zn, QUNIT, size_XY, 12); sysFSI.AddBoxBCE(box, pos_xp, QUNIT, size_YZ, 23); sysFSI.AddBoxBCE(box, pos_xn, QUNIT, size_YZ, 23); sysFSI.AddBoxBCE(box, pos_yp, QUNIT, size_XZ, 13); sysFSI.AddBoxBCE(box, pos_yn, QUNIT, size_XZ, 13); // ******************************* Flexible bodies *********************************** double density = 100; double E = 6e5; double nu = 0.0; double thickness = 0.01; auto elasticity = chrono_types::make_shared<ChElasticityKirchhoffIsothropic>(E, nu); auto material = chrono_types::make_shared<ChMaterialShellKirchhoff>(elasticity); material->SetDensity(density); auto fem_mesh = chrono_types::make_shared<fea::ChMesh>(); ChMeshFileLoader::BSTShellFromObjFile(fem_mesh, GetChronoDataFile("models/cube.obj").c_str(), material, thickness); // Add the mesh to the system sysMBS.Add(fem_mesh); // fluid representation of flexible bodies bool multilayer = true; bool removeMiddleLayer = true; bool add1DElem = flexible_elem_1D; bool add2DElem = !flexible_elem_1D; sysFSI.AddFEAmeshBCE(fem_mesh, NodeNeighborElement_mesh, _1D_elementsNodes_mesh, _2D_elementsNodes_mesh, false, true, multilayer, removeMiddleLayer, 0, 0); sysFSI.SetShellElementsNodes(_2D_elementsNodes_mesh); sysFSI.SetFsiMesh(fem_mesh); }
