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 #include "chrono/core/ChTypes.h"
20 
21 #include "chrono/fea/ChElementCableANCF.h"
22 #include "chrono/fea/ChElementShellANCF_3423.h"
23 #include "chrono/fea/ChMesh.h"
24 #include "chrono/fea/ChNodeFEAxyzD.h"
25 
26 #include "chrono_fsi/ChSystemFsi.h"
27 #include "chrono_fsi/utils/ChUtilsTypeConvert.h"
28 #include "chrono_fsi/utils/ChUtilsGeneratorFsi.h"
29 
30 namespace chrono {
31 namespace fsi {
32 
33 //--------------------------------------------------------------------------------------------------------------------------------
ChSystemFsi(ChSystem & other_physicalSystem,CHFSI_TIME_INTEGRATOR other_integrator)34 ChSystemFsi::ChSystemFsi(ChSystem& other_physicalSystem, CHFSI_TIME_INTEGRATOR other_integrator)
35     : mphysicalSystem(other_physicalSystem),
36       mTime(0),
37       fluidIntegrator(other_integrator),
38       file_write_mode(CHFSI_OUTPUT_MODE::NONE) {
39     fsiSystem = chrono_types::make_shared<ChSystemFsi_impl>();
40     paramsH = chrono_types::make_shared<SimParams>();
41     numObjectsH = fsiSystem->numObjects;
42     bceWorker = chrono_types::make_shared<ChBce>(fsiSystem->sortedSphMarkersD, fsiSystem->markersProximityD,
43                                                  fsiSystem->fsiGeneralData, paramsH, numObjectsH);
44     fluidDynamics =
45         chrono_types::make_shared<ChFluidDynamics>(bceWorker, fsiSystem, paramsH, numObjectsH, other_integrator);
46 
47     fsi_mesh = chrono_types::make_shared<fea::ChMesh>();
48     fsiBodies.resize(0);
49     fsiShells.resize(0);
50     fsiCables.resize(0);
51     fsiNodes.resize(0);
52     fsiInterface = chrono_types::make_shared<ChFsiInterface>(
53         mphysicalSystem, fsi_mesh, paramsH, fsiSystem->fsiBodiesH, fsiSystem->fsiMeshH, fsiBodies, fsiNodes, fsiCables,
54         fsiShells, fsiSystem->fsiGeneralData->CableElementsNodesH, fsiSystem->fsiGeneralData->CableElementsNodes,
55         fsiSystem->fsiGeneralData->ShellElementsNodesH, fsiSystem->fsiGeneralData->ShellElementsNodes,
56         fsiSystem->fsiGeneralData->rigid_FSI_ForcesD, fsiSystem->fsiGeneralData->rigid_FSI_TorquesD,
57         fsiSystem->fsiGeneralData->Flex_FSI_ForcesD);
58 }
59 //--------------------------------------------------------------------------------------------------------------------------------
SetFluidIntegratorType(fluid_dynamics params_type)60 void ChSystemFsi::SetFluidIntegratorType(fluid_dynamics params_type) {
61     if (params_type == fluid_dynamics::IISPH) {
62         fluidIntegrator = CHFSI_TIME_INTEGRATOR::IISPH;
63         std::cout << "=====================   Fluid dynamics is reset to IISPH   ====================" << std::endl;
64         std::cout << "===============================================================================" << std::endl;
65         std::cout << "===============================================================================" << std::endl;
66     } else if (params_type == fluid_dynamics::WCSPH) {
67         fluidIntegrator = CHFSI_TIME_INTEGRATOR::ExplicitSPH;
68         std::cout << "===============================================================================" << std::endl;
69         std::cout << "=====================   Fluid dynamics is reset to WCSPH   ====================" << std::endl;
70         std::cout << "===============================================================================" << std::endl;
71     } else {
72         fluidIntegrator = CHFSI_TIME_INTEGRATOR::I2SPH;
73         std::cout << "===============================================================================" << std::endl;
74         std::cout << "=====================   Fluid dynamics is reset to I2SPH   ====================" << std::endl;
75         std::cout << "===============================================================================" << std::endl;
76     }
77 }
78 //--------------------------------------------------------------------------------------------------------------------------------
SetFluidDynamics(fluid_dynamics params_type)79 void ChSystemFsi::SetFluidDynamics(fluid_dynamics params_type) {
80     SetFluidIntegratorType(params_type);
81     fluidDynamics =
82         chrono_types::make_shared<ChFluidDynamics>(bceWorker, fsiSystem, paramsH, numObjectsH, fluidIntegrator);
83 }
84 //--------------------------------------------------------------------------------------------------------------------------------
Finalize()85 void ChSystemFsi::Finalize() {
86     printf("===============================================================================\n");
87     printf("ChSystemFsi::Finalize 1-FinalizeData\n");
88     FinalizeData();
89 
90     printf("===============================================================================\n");
91     printf("ChSystemFsi::Finalize 2-bceWorker->Finalize\n");
92     bceWorker->Finalize(fsiSystem->sphMarkersD1, fsiSystem->fsiBodiesD1, fsiSystem->fsiMeshD);
93 
94     printf("===============================================================================\n");
95     printf("ChSystemFsi::Finalize 3-fluidDynamics->Finalize\n");
96     fluidDynamics->Finalize();
97     std::cout << "referenceArraySize in fluid dynamics is "
98               << fsiSystem->fsiGeneralData->referenceArray.size()
99               << std::endl;
100     printf("===============================================================================\n");
101 }
102 //--------------------------------------------------------------------------------------------------------------------------------
~ChSystemFsi()103 ChSystemFsi::~ChSystemFsi() {}
104 //--------------------------------------------------------------------------------------------------------------------------------
CopyDeviceDataToHalfStep()105 void ChSystemFsi::CopyDeviceDataToHalfStep() {
106     thrust::copy(fsiSystem->sphMarkersD2->posRadD.begin(), fsiSystem->sphMarkersD2->posRadD.end(),
107                  fsiSystem->sphMarkersD1->posRadD.begin());
108     thrust::copy(fsiSystem->sphMarkersD2->velMasD.begin(), fsiSystem->sphMarkersD2->velMasD.end(),
109                  fsiSystem->sphMarkersD1->velMasD.begin());
110     thrust::copy(fsiSystem->sphMarkersD2->rhoPresMuD.begin(), fsiSystem->sphMarkersD2->rhoPresMuD.end(),
111                  fsiSystem->sphMarkersD1->rhoPresMuD.begin());
112     thrust::copy(fsiSystem->sphMarkersD2->tauXxYyZzD.begin(), fsiSystem->sphMarkersD2->tauXxYyZzD.end(),
113                  fsiSystem->sphMarkersD1->tauXxYyZzD.begin());
114     thrust::copy(fsiSystem->sphMarkersD2->tauXyXzYzD.begin(), fsiSystem->sphMarkersD2->tauXyXzYzD.end(),
115                  fsiSystem->sphMarkersD1->tauXyXzYzD.begin());
116 }
117 //--------------------------------------------------------------------------------------------------------------------------------
DoStepDynamics_FSI()118 void ChSystemFsi::DoStepDynamics_FSI() {
119     if (fluidDynamics->GetIntegratorType() == CHFSI_TIME_INTEGRATOR::ExplicitSPH) {
120         // The following is used to execute the Explicit WCSPH
121         fsiInterface->Copy_ChSystem_to_External();
122         CopyDeviceDataToHalfStep();
123         ChUtilsDevice::FillMyThrust3(fsiSystem->fsiGeneralData->derivTauXxYyZzD, mR3(0));
124         ChUtilsDevice::FillMyThrust3(fsiSystem->fsiGeneralData->derivTauXyXzYzD, mR3(0));
125         ChUtilsDevice::FillMyThrust4(fsiSystem->fsiGeneralData->derivVelRhoD, mR4(0));
126         fluidDynamics->IntegrateSPH(fsiSystem->sphMarkersD2, fsiSystem->sphMarkersD1, fsiSystem->fsiBodiesD2,
127                                     fsiSystem->fsiMeshD, 0.5 * paramsH->dT);
128         fluidDynamics->IntegrateSPH(fsiSystem->sphMarkersD1, fsiSystem->sphMarkersD2, fsiSystem->fsiBodiesD2,
129                                     fsiSystem->fsiMeshD, 1.0 * paramsH->dT);
130         bceWorker->Rigid_Forces_Torques(fsiSystem->sphMarkersD2, fsiSystem->fsiBodiesD2);
131         fsiInterface->Add_Rigid_ForceTorques_To_ChSystem();
132 
133         bceWorker->Flex_Forces(fsiSystem->sphMarkersD2, fsiSystem->fsiMeshD);
134         // Note that because of applying forces to the nodal coordinates using SetForce() no other external forces can
135         // be applied, or if any thing has been applied will be rewritten by Add_Flex_Forces_To_ChSystem();
136         fsiInterface->Add_Flex_Forces_To_ChSystem();
137 
138         fsiInterface->Copy_External_To_ChSystem();
139 
140         // dT_Flex is the time step of solid body system
141         mTime += 1 * paramsH->dT;
142         if (paramsH->dT_Flex == 0)
143             paramsH->dT_Flex = paramsH->dT;
144         int sync = int(paramsH->dT / paramsH->dT_Flex);
145         if (sync < 1)
146             sync = 1;
147         for (int t = 0; t < sync; t++) {
148             mphysicalSystem.DoStepDynamics(paramsH->dT / sync);
149         }
150 
151         fsiInterface->Copy_fsiBodies_ChSystem_to_FluidSystem(fsiSystem->fsiBodiesD2);
152         bceWorker->UpdateRigidMarkersPositionVelocity(fsiSystem->sphMarkersD2, fsiSystem->fsiBodiesD2);
153     } else {
154         // A different coupling scheme is used for implicit SPH formulations
155         printf("Copy_ChSystem_to_External\n");
156         fsiInterface->Copy_ChSystem_to_External();
157         printf("IntegrateIISPH\n");
158         fluidDynamics->IntegrateSPH(fsiSystem->sphMarkersD2, fsiSystem->sphMarkersD2, fsiSystem->fsiBodiesD2,
159                                     fsiSystem->fsiMeshD, 0.0);
160         printf("Fluid-structure forces\n");
161         bceWorker->Rigid_Forces_Torques(fsiSystem->sphMarkersD2, fsiSystem->fsiBodiesD2);
162         fsiInterface->Add_Rigid_ForceTorques_To_ChSystem();
163 
164         bceWorker->Flex_Forces(fsiSystem->sphMarkersD2, fsiSystem->fsiMeshD);
165         // Note that because of applying forces to the nodal coordinates using SetForce() no other external forces can
166         // be applied, or if any thing has been applied will be rewritten by Add_Flex_Forces_To_ChSystem();
167         fsiInterface->Add_Flex_Forces_To_ChSystem();
168 
169         mTime += 1 * paramsH->dT;
170         if (paramsH->dT_Flex == 0)
171             paramsH->dT_Flex = paramsH->dT;
172         int sync = int(paramsH->dT / paramsH->dT_Flex);
173         if (sync < 1)
174             sync = 1;
175         printf("%d * Chrono StepDynamics with dt= %f\n", sync, paramsH->dT / sync);
176         for (int t = 0; t < sync; t++) {
177             mphysicalSystem.DoStepDynamics(paramsH->dT / sync);
178         }
179 
180         printf("Update Rigid Marker\n");
181         fsiInterface->Copy_fsiBodies_ChSystem_to_FluidSystem(fsiSystem->fsiBodiesD2);
182         bceWorker->UpdateRigidMarkersPositionVelocity(fsiSystem->sphMarkersD2, fsiSystem->fsiBodiesD2);
183 
184         printf("Update Flexible Marker\n");
185         fsiInterface->Copy_fsiNodes_ChSystem_to_FluidSystem(fsiSystem->fsiMeshD);
186         bceWorker->UpdateFlexMarkersPositionVelocity(fsiSystem->sphMarkersD2, fsiSystem->fsiMeshD);
187 
188         printf("Update Flexible Marker\n");
189         fsiInterface->Copy_fsiNodes_ChSystem_to_FluidSystem(fsiSystem->fsiMeshD);
190         bceWorker->UpdateFlexMarkersPositionVelocity(fsiSystem->sphMarkersD2, fsiSystem->fsiMeshD);
191         printf("=================================================================================================\n");
192     }
193 }
194 //--------------------------------------------------------------------------------------------------------------------------------
DoStepDynamics_ChronoRK2()195 void ChSystemFsi::DoStepDynamics_ChronoRK2() {
196     fsiInterface->Copy_ChSystem_to_External();
197     mTime += 0.5 * paramsH->dT;
198 
199     mphysicalSystem.DoStepDynamics(0.5 * paramsH->dT);
200     mTime -= 0.5 * paramsH->dT;
201     fsiInterface->Copy_External_To_ChSystem();
202     mTime += paramsH->dT;
203     mphysicalSystem.DoStepDynamics(1.0 * paramsH->dT);
204 }
205 //--------------------------------------------------------------------------------------------------------------------------------
FinalizeData()206 void ChSystemFsi::FinalizeData() {
207     printf("fsiInterface->ResizeChronoBodiesData()\n");
208     fsiInterface->ResizeChronoBodiesData();
209     int fea_node = 0;
210     fsiInterface->ResizeChronoCablesData(CableElementsNodes, fsiSystem->fsiGeneralData->CableElementsNodesH);
211     fsiInterface->ResizeChronoShellsData(ShellElementsNodes, fsiSystem->fsiGeneralData->ShellElementsNodesH);
212     fsiInterface->ResizeChronoFEANodesData();
213     printf("fsiSystem->ResizeDataManager()\n");
214     fea_node = fsi_mesh->GetNnodes();
215 
216     fsiSystem->ResizeDataManager(fea_node);
217 
218     printf("fsiInterface->Copy_fsiBodies_ChSystem_to_FluidSystem()\n");
219     fsiInterface->Copy_fsiBodies_ChSystem_to_FluidSystem(fsiSystem->fsiBodiesD1);
220     fsiInterface->Copy_fsiNodes_ChSystem_to_FluidSystem(fsiSystem->fsiMeshD);
221     fsiInterface->Copy_fsiNodes_ChSystem_to_FluidSystem(fsiSystem->fsiMeshD);
222 
223     std::cout << "referenceArraySize in FinalizeData is "
224               << fsiSystem->fsiGeneralData->referenceArray.size()
225               << std::endl;
226     fsiSystem->fsiBodiesD2 = fsiSystem->fsiBodiesD1;  //(2) construct midpoint rigid data
227 }
228 //--------------------------------------------------------------------------------------------------------------------------------
WriteParticleFile(const std::string & outfilename) const229 void ChSystemFsi::WriteParticleFile(const std::string& outfilename) const {
230     if (file_write_mode == CHFSI_OUTPUT_MODE::CSV) {
231         utils::WriteCsvParticlesToFile(fsiSystem->sphMarkersD2->posRadD, fsiSystem->sphMarkersD2->velMasD,
232                                        fsiSystem->sphMarkersD2->rhoPresMuD, fsiSystem->fsiGeneralData->referenceArray,
233                                        outfilename);
234     } else if (file_write_mode == CHFSI_OUTPUT_MODE::CHPF) {
235         utils::WriteChPFParticlesToFile(fsiSystem->sphMarkersD2->posRadD, fsiSystem->fsiGeneralData->referenceArray,
236                                         outfilename);
237     }
238 }
239 //--------------------------------------------------------------------------------------------------------------------------------
PrintParticleToFile(const std::string & out_dir) const240 void ChSystemFsi::PrintParticleToFile(const std::string& out_dir) const {
241     utils::PrintToFile(fsiSystem->sphMarkersD2->posRadD, fsiSystem->sphMarkersD2->velMasD,
242                        fsiSystem->sphMarkersD2->rhoPresMuD, fsiSystem->fsiGeneralData->sr_tau_I_mu_i,
243                        fsiSystem->fsiGeneralData->referenceArray, thrust::host_vector<int4>(), out_dir, true);
244 }
245 //--------------------------------------------------------------------------------------------------------------------------------
AddSphMarker(const ChVector<> & point,double rho0,double pres0,double mu0,double h,double particle_type,const ChVector<> & velocity,const ChVector<> & tauXxYyZz,const ChVector<> & tauXyXzYz)246 void ChSystemFsi::AddSphMarker(const ChVector<>& point,
247                                double rho0,
248                                double pres0,
249                                double mu0,
250                                double h,
251                                double particle_type,
252                                const ChVector<>& velocity,
253                                const ChVector<>& tauXxYyZz,
254                                const ChVector<>& tauXyXzYz) {
255     fsiSystem->AddSphMarker(ChUtilsTypeConvert::ChVectorToReal4(point, h), mR4(rho0, pres0, mu0, particle_type),
256                             ChUtilsTypeConvert::ChVectorToReal3(velocity),
257                             ChUtilsTypeConvert::ChVectorToReal3(tauXxYyZz),
258         ChUtilsTypeConvert::ChVectorToReal3(tauXyXzYz));
259 }
260 //--------------------------------------------------------------------------------------------------------------------------------
AddRefArray(const int start,const int numPart,const int typeA,const int typeB)261 void ChSystemFsi::AddRefArray(const int start, const int numPart, const int typeA, const int typeB) {
262     fsiSystem->fsiGeneralData->referenceArray.push_back(mI4(start, numPart, typeA, typeB));
263 }
264 //--------------------------------------------------------------------------------------------------------------------------------
AddBceBox(std::shared_ptr<SimParams> paramsH,std::shared_ptr<ChBody> body,const ChVector<> & relPos,const ChQuaternion<> & relRot,const ChVector<> & size,int plane)265 void ChSystemFsi::AddBceBox(std::shared_ptr<SimParams> paramsH,
266                             std::shared_ptr<ChBody> body,
267                             const ChVector<>& relPos,
268                             const ChQuaternion<>& relRot,
269                             const ChVector<>& size,
270                             int plane) {
271     utils::AddBoxBce(fsiSystem, paramsH, body, relPos, relRot, size, plane);
272 }
273 //--------------------------------------------------------------------------------------------------------------------------------
AddBceCylinder(std::shared_ptr<SimParams> paramsH,std::shared_ptr<ChBody> body,const ChVector<> & relPos,const ChQuaternion<> & relRot,double radius,double height,double kernel_h,bool cartesian)274 void ChSystemFsi::AddBceCylinder(std::shared_ptr<SimParams> paramsH,
275                                  std::shared_ptr<ChBody> body,
276                                  const ChVector<>& relPos,
277                                  const ChQuaternion<>& relRot,
278                                  double radius,
279                                  double height,
280                                  double kernel_h,
281                                  bool cartesian) {
282     utils::AddCylinderBce(fsiSystem, paramsH, body, relPos, relRot, radius, height, kernel_h, cartesian);
283 }
284 //--------------------------------------------------------------------------------------------------------------------------------
AddBceFromPoints(std::shared_ptr<SimParams> paramsH,std::shared_ptr<ChBody> body,const std::vector<chrono::ChVector<>> & points,const ChVector<> & collisionShapeRelativePos,const ChQuaternion<> & collisionShapeRelativeRot)285 void ChSystemFsi::AddBceFromPoints(std::shared_ptr<SimParams> paramsH,
286                                    std::shared_ptr<ChBody> body,
287                                    const std::vector<chrono::ChVector<>>& points,
288                                    const ChVector<>& collisionShapeRelativePos,
289                                    const ChQuaternion<>& collisionShapeRelativeRot) {
290     utils::AddBCE_FromPoints(fsiSystem, paramsH, body, points, collisionShapeRelativePos, collisionShapeRelativeRot);
291 }
292 //--------------------------------------------------------------------------------------------------------------------------------
AddBceFile(std::shared_ptr<SimParams> paramsH,std::shared_ptr<ChBody> body,const std::string & dataPath,const ChVector<> & collisionShapeRelativePos,const ChQuaternion<> & collisionShapeRelativeRot,double scale,bool isSolid)293 void ChSystemFsi::AddBceFile(std::shared_ptr<SimParams> paramsH,
294                              std::shared_ptr<ChBody> body,
295                              const std::string& dataPath,
296                              const ChVector<>& collisionShapeRelativePos,
297                              const ChQuaternion<>& collisionShapeRelativeRot,
298                              double scale,
299                              bool isSolid) {  // true means moving body, false means fixed boundary
300     utils::AddBCE_FromFile(fsiSystem, paramsH, body, dataPath, collisionShapeRelativePos, collisionShapeRelativeRot,
301                            scale, isSolid);
302 }
303 //--------------------------------------------------------------------------------------------------------------------------------
AddBceFromMesh(std::shared_ptr<SimParams> paramsH,std::shared_ptr<fea::ChMesh> my_mesh,const std::vector<std::vector<int>> & NodeNeighborElement,const std::vector<std::vector<int>> & _1D_elementsNodes,const std::vector<std::vector<int>> & _2D_elementsNodes,bool add1DElem,bool add2DElem,bool multiLayer,bool removeMiddleLayer,int SIDE,int SIDE2D)304 void ChSystemFsi::AddBceFromMesh(std::shared_ptr<SimParams> paramsH,
305                                  std::shared_ptr<fea::ChMesh> my_mesh,
306                                  const std::vector<std::vector<int>>& NodeNeighborElement,
307                                  const std::vector<std::vector<int>>& _1D_elementsNodes,
308                                  const std::vector<std::vector<int>>& _2D_elementsNodes,
309                                  bool add1DElem,
310                                  bool add2DElem,
311                                  bool multiLayer,
312                                  bool removeMiddleLayer,
313                                  int SIDE,
314                                  int SIDE2D) {
315     utils::AddBCE_FromMesh(fsiSystem, paramsH, my_mesh, this->GetFsiNodes(), this->GetFsiCables(), this->GetFsiShells(),
316                            NodeNeighborElement, _1D_elementsNodes, _2D_elementsNodes, add1DElem, add2DElem, multiLayer,
317                            removeMiddleLayer, SIDE, SIDE2D);
318 }
319 //--------------------------------------------------------------------------------------------------------------------------------
SetSimParameter(const std::string & inputJson,std::shared_ptr<SimParams> paramsH,const ChVector<> & box_size)320 void ChSystemFsi::SetSimParameter(const std::string& inputJson,
321                                   std::shared_ptr<SimParams> paramsH,
322                                   const ChVector<>& box_size) {
323     utils::ParseJSON(inputJson, paramsH, ChUtilsTypeConvert::ChVectorToReal3(box_size));
324 }
325 //--------------------------------------------------------------------------------------------------------------------------------
SetBoundaries(const ChVector<> & cMin,const ChVector<> & cMax,std::shared_ptr<SimParams> paramsH)326 void ChSystemFsi::SetBoundaries(const ChVector<>& cMin, const ChVector<>& cMax, std::shared_ptr<SimParams> paramsH) {
327     paramsH->cMin = ChUtilsTypeConvert::ChVectorToReal3(cMin);
328     paramsH->cMax = ChUtilsTypeConvert::ChVectorToReal3(cMax);
329 }
330 //--------------------------------------------------------------------------------------------------------------------------------
SetInitPressure(std::shared_ptr<SimParams> paramsH,const double fzDim)331 void ChSystemFsi::SetInitPressure(std::shared_ptr<SimParams> paramsH, const double fzDim) {
332     size_t numParticles = fsiSystem->sphMarkersH->rhoPresMuH.size();
333     for (int i = 0; i < numParticles; i++) {
334         double z = fsiSystem->sphMarkersH->posRadH[i].z;
335         fsiSystem->sphMarkersH->rhoPresMuH[i].y =
336             -paramsH->rho0 * paramsH->gravity.z * paramsH->gravity.z * (z - fzDim);
337     }
338 }
339 //--------------------------------------------------------------------------------------------------------------------------------
GetKernelLength() const340 float ChSystemFsi::GetKernelLength() const {
341     return paramsH->HSML;
342 }
343 //--------------------------------------------------------------------------------------------------------------------------------
SetSubDomain(std::shared_ptr<SimParams> paramsH)344 void ChSystemFsi::SetSubDomain(std::shared_ptr<SimParams> paramsH) {
345     utils::FinalizeDomain(paramsH);
346 }
347 //--------------------------------------------------------------------------------------------------------------------------------
SetFsiOutputDir(std::shared_ptr<SimParams> paramsH,std::string & demo_dir,std::string out_dir,std::string inputJson)348 void ChSystemFsi::SetFsiOutputDir(std::shared_ptr<SimParams> paramsH,
349                                   std::string& demo_dir,
350                                   std::string out_dir,
351                                   std::string inputJson) {
352     utils::PrepareOutputDir(paramsH, demo_dir, out_dir, inputJson);
353 }
354 //--------------------------------------------------------------------------------------------------------------------------------
GetParticlePosOrProperties()355 std::vector<ChVector<>> ChSystemFsi::GetParticlePosOrProperties() {
356     thrust::host_vector<Real4> posRadH = fsiSystem->sphMarkersD2->posRadD;
357     std::vector<ChVector<>> pos;
358     for (size_t i = 0; i < posRadH.size(); i++) {
359         pos.push_back(ChUtilsTypeConvert::Real4ToChVector(posRadH[i]));
360     }
361     return pos;
362 }
363 //--------------------------------------------------------------------------------------------------------------------------------
GetParticleVel()364 std::vector<ChVector<>> ChSystemFsi::GetParticleVel() {
365     thrust::host_vector<Real3> velH = fsiSystem->sphMarkersD2->velMasD;
366     std::vector<ChVector<>> vel;
367     for (size_t i = 0; i < velH.size(); i++) {
368         vel.push_back(ChUtilsTypeConvert::Real3ToChVector(velH[i]));
369     }
370     return vel;
371 }
372 //--------------------------------------------------------------------------------------------------------------------------------
373 
374 }  // end namespace fsi
375 }  // end namespace chrono
376