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);

}

Reply via email to