1 // =============================================================================
2 // PROJECT CHRONO - http://projectchrono.org
3 //
4 // Copyright (c) 2014 projectchrono.org
5 // All rights reserved.
6 //
7 // Use of this source code is governed by a BSD-style license that can be found
8 // in the LICENSE file at the top level of the distribution and at
9 // http://projectchrono.org/license-chrono.txt.
10 //
11 // =============================================================================
12 // Author: Milad Rakhsha, Arman Pazouki, Wei Hu
13 // =============================================================================
14 //
15 // Implementation of FSI system that includes all subclasses for proximity and
16 // force calculation, and time integration.
17 //
18 // =============================================================================
19 
20 #ifndef CH_SYSTEM_FSI_H
21 #define CH_SYSTEM_FSI_H
22 
23 #include "chrono/ChConfig.h"
24 #include "chrono/physics/ChSystem.h"
25 
26 #include "chrono_fsi/physics/ChBce.cuh"
27 #include "chrono_fsi/physics/ChFluidDynamics.cuh"
28 #include "chrono_fsi/physics/ChFsiGeneral.h"
29 #include "chrono_fsi/ChFsiInterface.h"
30 #include "chrono_fsi/ChFsiDefines.h"
31 #include "chrono_fsi/utils/ChUtilsPrintSph.cuh"
32 #include "chrono_fsi/utils/ChUtilsJSON.h"
33 
34 namespace chrono {
35 
36 // Forward declarations
37 namespace fea {
38 class ChNodeFEAxyzD;
39 class ChMesh;
40 class ChElementCableANCF;
41 class ChElementShellANCF_3423;
42 }
43 
44 namespace fsi {
45 
46 class ChSystemFsi_impl;
47 
48 /// @addtogroup fsi_physics
49 /// @{
50 
51 /// @brief Physical system for fluid-solid interaction problems.
52 ///
53 /// This class is used to represent fluid-solid interaction problems consisting of fluid dynamics and multibody system.
54 /// Each of the two underlying physics is an independent object owned and instantiated by this class. Additionally, the
55 /// FSI system owns other objects to handle the interface between the two systems, boundary condition enforcing markers,
56 /// and data.
57 class CH_FSI_API ChSystemFsi {
58   public:
59     /// Constructor for FSI system.
60     ChSystemFsi(ChSystem& other_physicalSystem,
61                 CHFSI_TIME_INTEGRATOR time_integrator = CHFSI_TIME_INTEGRATOR::ExplicitSPH);
62 
63     /// Destructor for the FSI system.
64     ~ChSystemFsi();
65 
66     /// Function to integrate the FSI system in time.
67     /// It uses a Runge-Kutta 2nd order algorithm to update both the fluid and multibody
68     /// system dynamics. The midpoint data of MBS is needed for fluid dynamics update.
69     void DoStepDynamics_FSI();
70 
71     /// Function to integrate the multibody system dynamics based on Runge-Kutta
72     /// 2nd-order integration scheme.
73     void DoStepDynamics_ChronoRK2();
74 
75     /// Function to initialize the midpoint device data of the fluid system by
76     /// copying from the full step
77     void CopyDeviceDataToHalfStep();
78 
79     /// Fill out the dependent data based on the independent one. For instance,
80     /// it copies the position of the rigid bodies from the multibody dynamics system
81     /// to arrays in FSI system since they are needed for internal use.
82     void FinalizeData();
83 
84     /// Get a pointer to the data manager.
GetFsiData()85     std::shared_ptr<ChSystemFsi_impl> GetFsiData() { return fsiSystem; }
86 
87     /// Set the linear system solver for implicit methods
SetFluidSystemLinearSolver(ChFsiLinearSolver::SolverType other_solverType)88     void SetFluidSystemLinearSolver(ChFsiLinearSolver::SolverType other_solverType) {
89         fluidDynamics->GetForceSystem()->SetLinearSolver(other_solverType);
90     }
91 
92     /// Set the SPH method to be used for fluid dynamics.
93     void SetFluidDynamics(fluid_dynamics params_type = fluid_dynamics::I2SPH);
94 
95     /// Get a pointer to the parameters used to set up the simulation.
GetSimParams()96     std::shared_ptr<SimParams> GetSimParams() { return paramsH; }
97 
98     /// Get a reference to the FSI bodies.
99     /// FSI bodies are the ones seen by the fluid dynamics system.
GetFsiBodies()100     std::vector<std::shared_ptr<ChBody>>& GetFsiBodies() { return fsiBodies; }
101 
102     /// Get a reference to the FSI ChElementCableANCF.
103     /// FSI ChElementCableANCF are the ones seen by the fluid dynamics system.
GetFsiCables()104     std::vector<std::shared_ptr<fea::ChElementCableANCF>>& GetFsiCables() { return fsiCables; }
105 
106     /// Get a reference to the FSI ChElementShellANCF_3423.
107     /// FSI ChElementShellANCF_3423 are the ones seen by the fluid dynamics system.
GetFsiShells()108     std::vector<std::shared_ptr<fea::ChElementShellANCF_3423>>& GetFsiShells() { return fsiShells; }
109 
110     /// Get a reference to the FSI ChNodeFEAxyzD.
111     /// FSI ChNodeFEAxyzD are the ones seen by the fluid dynamics system.
GetFsiNodes()112     std::vector<std::shared_ptr<fea::ChNodeFEAxyzD>>& GetFsiNodes() { return fsiNodes; }
113 
114     /// Add FSI body to the FsiSystem.
AddFsiBody(std::shared_ptr<ChBody> mbody)115     void AddFsiBody(std::shared_ptr<ChBody> mbody) { fsiBodies.push_back(mbody); }
116 
117     /// Complete construction of the FSI system (fluid and BDE objects).
118     void Finalize();
119 
120     /// Finalize the construction of cable elements in the FSI system.
SetCableElementsNodes(std::vector<std::vector<int>> elementsNodes)121     void SetCableElementsNodes(std::vector<std::vector<int>> elementsNodes) {
122         CableElementsNodes = elementsNodes;
123         size_t test = fsiSystem->fsiGeneralData->CableElementsNodes.size();
124         std::cout << "numObjects.numFlexNodes" << test << std::endl;
125     }
126 
127     /// Finalize the construction of cable elements in the FSI system.
SetShellElementsNodes(std::vector<std::vector<int>> elementsNodes)128     void SetShellElementsNodes(std::vector<std::vector<int>> elementsNodes) {
129         ShellElementsNodes = elementsNodes;
130         size_t test = fsiSystem->fsiGeneralData->ShellElementsNodes.size();
131         std::cout << "numObjects.numFlexNodes" << test << std::endl;
132     }
133 
134     /// Set the FSI mesh for flexible elements.
SetFsiMesh(std::shared_ptr<fea::ChMesh> other_fsi_mesh)135     void SetFsiMesh(std::shared_ptr<fea::ChMesh> other_fsi_mesh) {
136         fsi_mesh = other_fsi_mesh;
137         fsiInterface->SetFsiMesh(other_fsi_mesh);
138     }
139 
140     /// Set the FSI system output mode (default: NONE).
SetParticleOutputMode(CHFSI_OUTPUT_MODE mode)141     void SetParticleOutputMode(CHFSI_OUTPUT_MODE mode) { file_write_mode = mode; }
142 
143     /// Write FSI system particle output.
144     void WriteParticleFile(const std::string& outfilename) const;
145 
146     /// Save the SPH particle information into files.
147     /// This function creates three files to write fluid, boundary, and BCE markers data to separate files.
148     void PrintParticleToFile(const std::string& out_dir) const;
149 
150     /// Add SPH particle's information into the FSI system.
151     void AddSphMarker(const ChVector<>& point,
152                       double rho0,
153                       double pres0,
154                       double mu0,
155                       double h,
156                       double particle_type,
157                       const ChVector<>& velocity = ChVector<>(0),
158                       const ChVector<>& tauXxYyZz = ChVector<>(0),
159                       const ChVector<>& tauXyXzYz = ChVector<>(0));
160 
161     /// Add reference array for SPH particles.
162     void AddRefArray(const int start, const int numPart, const int typeA, const int typeB);
163 
164     /// Add BCE particle for a box.
165     void AddBceBox(std::shared_ptr<SimParams> paramsH,
166                    std::shared_ptr<ChBody> body,
167                    const ChVector<>& relPos,
168                    const ChQuaternion<>& relRot,
169                    const ChVector<>& size,
170                    int plane = 12);
171 
172     /// Add BCE particle for a cylinder.
173     void AddBceCylinder(std::shared_ptr<SimParams> paramsH,
174                         std::shared_ptr<ChBody> body,
175                         const ChVector<>& relPos,
176                         const ChQuaternion<>& relRot,
177                         double radius,
178                         double height,
179                         double kernel_h,
180                         bool cartesian = true);
181 
182     /// Add BCE particles from a set of points.
183     void AddBceFromPoints(std::shared_ptr<SimParams> paramsH,
184                           std::shared_ptr<ChBody> body,
185                           const std::vector<ChVector<>>& points,
186                           const ChVector<>& collisionShapeRelativePos,
187                           const ChQuaternion<>& collisionShapeRelativeRot);
188 
189     /// Add BCE particle from a file.
190     void AddBceFile(std::shared_ptr<SimParams> paramsH,
191                     std::shared_ptr<ChBody> body,
192                     const std::string& dataPath,
193                     const ChVector<>& collisionShapeRelativePos,
194                     const ChQuaternion<>& collisionShapeRelativeRot,
195                     double scale,
196                     bool isSolid = true);
197 
198     /// Add BCE particle from mesh.
199     void AddBceFromMesh(std::shared_ptr<SimParams> paramsH,
200                         std::shared_ptr<fea::ChMesh> my_mesh,
201                         const std::vector<std::vector<int>>& NodeNeighborElement,
202                         const std::vector<std::vector<int>>& _1D_elementsNodes,
203                         const std::vector<std::vector<int>>& _2D_elementsNodes,
204                         bool add1DElem,
205                         bool add2DElem,
206                         bool multiLayer,
207                         bool removeMiddleLayer,
208                         int SIDE,
209                         int SIZE2D);
210 
211     /// Set FSI parameters from a JSON file.
212     void SetSimParameter(const std::string& inputJson, std::shared_ptr<SimParams> paramsH, const ChVector<>& box_size);
213 
214     /// Set Periodic boundary condition for fluid.
215     void SetBoundaries(const ChVector<>& cMin, const ChVector<>& cMax, std::shared_ptr<SimParams> paramsH);
216 
217     /// Set prescribed initial pressure for gravity field.
218     void SetInitPressure(std::shared_ptr<SimParams> paramsH, const double fzDim);
219 
220     /// Gets the FSI mesh for flexible elements.
GetFsiMesh()221     std::shared_ptr<fea::ChMesh> GetFsiMesh() { return fsi_mesh; }
222 
223     /// Return the SPH kernel length of kernel function.
224     float GetKernelLength() const;
225 
226     /// Set subdomains so that we find neighbor particles faster.
227     void SetSubDomain(std::shared_ptr<SimParams> paramsH);
228 
229     /// Set output directory for FSI data.
230     void SetFsiOutputDir(std::shared_ptr<SimParams> paramsH,
231                          std::string& demo_dir,
232                          std::string out_dir,
233                          std::string inputJson);
234 
235     /// Return the SPH particle position.
236     std::vector<ChVector<>> GetParticlePosOrProperties();
237 
238     /// Return the SPH particle velocity.
239     std::vector<ChVector<>> GetParticleVel();
240 
241   private:
242     /// Set the type of the fluid dynamics.
243     void SetFluidIntegratorType(fluid_dynamics params_type);
244 
245     std::shared_ptr<ChSystemFsi_impl> fsiSystem;  ///< underlying system implementation
246 
247     CHFSI_OUTPUT_MODE file_write_mode;  ///< FSI particle output type (CSV, ChPF, or NONE)
248 
249     std::vector<std::shared_ptr<ChBody>> fsiBodies;                        ///< vector of a pointers to FSI bodies
250     std::vector<std::shared_ptr<fea::ChElementCableANCF>> fsiCables;       ///< vector of cable ANCF elements
251     std::vector<std::shared_ptr<fea::ChElementShellANCF_3423>> fsiShells;  ///< vector of shell ANCF elements
252     std::vector<std::shared_ptr<fea::ChNodeFEAxyzD>> fsiNodes;             ///< vector of FEA nodes
253     std::shared_ptr<fea::ChMesh> fsi_mesh;                                 ///< FEA mesh
254 
255     std::vector<std::vector<int>> ShellElementsNodes;  ///< indices of nodes of each shell element
256     std::vector<std::vector<int>> CableElementsNodes;  ///< indices of nodes of each cable element
257     std::shared_ptr<ChFluidDynamics> fluidDynamics;    ///< pointer to the fluid system
258     CHFSI_TIME_INTEGRATOR fluidIntegrator;             ///< IISPH by default
259     std::shared_ptr<ChFsiInterface> fsiInterface;      ///< pointer to the FSI interface system
260     std::shared_ptr<ChBce> bceWorker;                  ///< pointer to the bce workers
261     std::shared_ptr<SimParams> paramsH;                ///< pointer to the simulation parameters
262     std::shared_ptr<NumberOfObjects> numObjectsH;      ///< number of objects, fluid, bce, and boundary markers
263     chrono::ChSystem& mphysicalSystem;                 ///< reference to the multi-body system
264 
265     double mTime;  ///< current real time of the simulation
266 };
267 
268 /// @} fsi_physics
269 
270 }  // end namespace fsi
271 }  // end namespace chrono
272 
273 #endif
274