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 
13 #include "chrono/physics/ChSystem.h"
14 #include "chrono/core/ChRealtimeStep.h"
15 
16 #include "chrono/fea/ChMatterMeshless.h"
17 #include "chrono/fea/ChProximityContainerMeshless.h"
18 
19 #include "chrono_irrlicht/ChBodySceneNode.h"
20 #include "chrono_irrlicht/ChBodySceneNodeTools.h"
21 #include "chrono_irrlicht/ChIrrApp.h"
22 
23 #include <irrlicht.h>
24 
25 // Use the namespace of Chrono
26 
27 using namespace chrono;
28 using namespace fea;
29 
30 // Use the main namespaces of Irrlicht
31 using namespace irr;
32 
33 using namespace core;
34 using namespace scene;
35 using namespace video;
36 using namespace io;
37 using namespace gui;
38 
main(int argc,char * argv[])39 int main(int argc, char* argv[]) {
40     // Create a ChronoENGINE physical system
41     ChSystem mphysicalSystem;
42 
43     // Create the Irrlicht visualization (open the Irrlicht device,
44     // bind a simple user interface, etc. etc.)
45     ChIrrApp application(&mphysicalSystem, L"Meshless deformable material", core::dimension2d<u32>(800, 600), false);
46     application.AddTypicalLogo();
47     application.AddTypicalSky();
48     application.AddTypicalLights();
49     application.AddTypicalCamera(core::vector3df(0, 3, -3));
50 
51     // CREATE A FLOOR
52 
53     ChSharedPtr<ChBodyEasyBox> mfloorBody( new ChBodyEasyBox(20,1,20,1000,true,true));
54     my_system.Add(mfloorBody);
55     mfloorBody->SetBodyFixed(true);
56     mfloorBody->SetPos(ChVector<>(0, -5, 0));
57 
58     ChSharedPtr<ChTexture> mtexture( new ChTexture(GetChronoDataFile("textures/concrete.jpg").c_str()));
59     mfloorBody->AddAsset(mtexture);
60 
61 
62     // CREATE THE ELASTOPLASTIC MESHLESS CONTINUUM
63 
64     // Create elastoplastic matter
65     ChSharedPtr<ChMatterMeshless> mymatter(new ChMatterMeshless);
66 
67     // Use the FillBox easy way to create the set of nodes in the meshless matter
68     mymatter->FillBox(ChVector<>(4, 2, 4),                          // size of box
69                       4.0 / 10.0,                                   // resolution step
70                       1000,                                         // initial density
71                       ChCoordsys<>(ChVector<>(0, -3.9, 0), QUNIT),  // position & rotation of box
72                       true,                                         // do a centered cubic lattice initial arrangement
73                       2.1);                                         // set the kernel radius (as multiples of step)
74 
75     GetLog() << "Added " << mymatter->GetNnodes() << " nodes \n";
76 
77     // Set some material properties of the meshless matter
78 
79     ChSharedPtr<ChContinuumDruckerPrager> mmaterial(new ChContinuumDruckerPrager);
80     mymatter->ReplaceMaterial(mmaterial);
81     mmaterial->Set_v(0.35);
82     mmaterial->Set_E(30000.0);
83     mmaterial->Set_elastic_yeld(0);
84     mmaterial->Set_alpha(30 * CH_C_DEG_TO_RAD);
85     // mmaterial->Set_from_MohrCoulomb(30 * CH_C_DEG_TO_RAD, 1000);
86     mmaterial->Set_dilatancy(30 * CH_C_DEG_TO_RAD);
87     mmaterial->Set_flow_rate(50000000.0);
88     mmaterial->Set_hardening_limit(mmaterial->Get_elastic_yeld());
89     mmaterial->Set_hardening_speed(100000000);
90 
91     /*
92         ChSharedPtr<ChContinuumPlasticVonMises> mmaterial(new ChContinuumPlasticVonMises);
93         mymatter->ReplaceMaterial(mmaterial);
94         mmaterial->Set_v(0.38);
95         mmaterial->Set_E(60000.0);
96         mmaterial->Set_elastic_yeld(0.06);
97         mmaterial->Set_flow_rate(300);
98     */
99 
100     mymatter->SetViscosity(5000);
101 
102     // Add the matter to the physical system
103     mymatter->SetCollide(true);
104     mphysicalSystem.Add(mymatter);
105 
106     // Join some nodes of meshless matter to a ChBody
107     /*
108     ChSharedPtr<ChIndexedNodes> mnodes = mymatter;
109     for (int ij = 0; ij < 120; ij++)
110     {
111         ChSharedPtr<ChLinkPointFrame> myjointnodebody(new ChLinkPointFrame);
112         myjointnodebody->Initialize(mnodes,
113                                     ij,
114                                     mfloorBody->GetBody());
115         mphysicalSystem.Add(myjointnodebody);
116     }
117     */
118 
119     // IMPORTANT!
120     // This takes care of the interaction between the particles of the meshless material
121     ChSharedPtr<ChProximityContainerMeshless> my_sph_proximity(new ChProximityContainerMeshless);
122     mphysicalSystem.Add(my_sph_proximity);
123 
124 
125     // CREATE A SPHERE PRESSING THE MATERIAL:
126 
127     ChSharedPtr<ChBodyEasySphere> msphere( new ChBodyEasySphere(2, 7000, true,true));
128     my_system.Add(msphere);
129     msphere->SetPos(ChVector<>(0, -0.5, 0));
130 
131 
132 
133     // Use this function for adding a ChIrrNodeAsset to all items
134     // Otherwise use application.AssetBind(myitem); on a per-item basis.
135     application.AssetBindAll();
136 
137     // Use this function for 'converting' assets into Irrlicht meshes
138     application.AssetUpdateAll();
139 
140 
141     // Modify some setting of the physical system for the simulation, if you want
142 
143     mphysicalSystem.SetSolverMaxIterations(25);  // lower the LCP iters, no needed here
144 
145     //
146     // THE SOFT-REAL-TIME CYCLE
147     //
148 
149     static int printed_prox = 0;
150     application.SetTimestep(0.002);
151 
152     while (application.GetDevice()->run()) {
153         application.BeginScene(true, true, SColor(255, 140, 161, 192));
154 
155         application.DrawAll();
156 
157         ChSystem::IteratorOtherPhysicsItems myiter = mphysicalSystem.IterBeginOtherPhysicsItems();
158 
159         while (myiter != mphysicalSystem.IterEndOtherPhysicsItems()) {
160             if ((*myiter).IsType<ChMatterMeshless>()) {
161                 ChSharedPtr<ChMatterMeshless> mymatter((*myiter).DynamicCastTo<ChMatterMeshless>());
162 
163                 for (unsigned int ip = 0; ip < mymatter->GetNnodes(); ip++) {
164                     ChSharedPtr<ChNodeMeshless> mnode(mymatter->GetNode(ip).DynamicCastTo<ChNodeMeshless>());
165                     ChVector<> mv = mnode->GetPos();
166                     float rad = (float)mnode->GetKernelRadius();
167                     core::vector3df mpos((irr::f32)mv.x, (irr::f32)mv.y, (irr::f32)mv.z);
168                     core::position2d<s32> spos =
169                         application.GetSceneManager()->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(
170                             mpos);
171                     application.GetVideoDriver()->draw2DRectangle(
172                         video::SColor(100, 200, 200, 230),
173                         core::rect<s32>(spos.X - 2, spos.Y - 2, spos.X + 2, spos.Y + 2));
174                     /*
175                     application.GetVideoDriver()->setTransform(video::ETS_WORLD, core::matrix4());
176                     application.GetVideoDriver()->draw3DBox( core::aabbox3d<f32>(
177                                     (irr::f32)mv.x-rad ,(irr::f32)mv.y-rad , (irr::f32)mv.z-rad    ,
178                                     (irr::f32)mv.x+rad ,(irr::f32)mv.y+rad , (irr::f32)mv.z+rad )   ,
179                                     video::SColor(300,200,200,230) );
180                     */
181 
182                     /*
183                     double strain_scale =10;
184                     ChIrrTools::drawSegment(application.GetVideoDriver(), mnode->GetPos(),
185                     mnode->GetPos()+(VECT_X*mnode->p_strain.XX()* strain_scale), video::SColor(255,255,0,0),false);
186                     ChIrrTools::drawSegment(application.GetVideoDriver(), mnode->GetPos(),
187                     mnode->GetPos()+(VECT_Y*mnode->p_strain.YY()* strain_scale), video::SColor(255,0,255,0),false);
188                     ChIrrTools::drawSegment(application.GetVideoDriver(), mnode->GetPos(),
189                     mnode->GetPos()+(VECT_Z*mnode->p_strain.ZZ()* strain_scale), video::SColor(255,0,0,255),false);
190                     */
191 
192                     /*
193                     double stress_scale =0.008;
194                     ChIrrTools::drawSegment(application.GetVideoDriver(), mnode->GetPos(),
195                     mnode->GetPos()+(VECT_X*mnode->e_stress.XX()* stress_scale), video::SColor(100,255,0,0),false);
196                     ChIrrTools::drawSegment(application.GetVideoDriver(), mnode->GetPos(),
197                     mnode->GetPos()+(VECT_Y*mnode->e_stress.YY()* stress_scale), video::SColor(100,0,255,0),false);
198                     ChIrrTools::drawSegment(application.GetVideoDriver(), mnode->GetPos(),
199                     mnode->GetPos()+(VECT_Z*mnode->e_stress.ZZ()* stress_scale), video::SColor(100,0,0,255),false);
200                     */
201 
202                     double stress_scale = 0.00001;
203                     ChIrrTools::drawSegment(
204                         application.GetVideoDriver(), mnode->GetPos(),
205                         mnode->GetPos() + (VECT_X * mnode->e_stress.GetInvariant_I1() * stress_scale),
206                         video::SColor(100, 255, 0, 0), false);
207 
208                     // GetLog() << "Mass i="<< ip << "   m=" << mnode->GetMass() << "\n";
209                     // ChIrrTools::drawSegment(application.GetVideoDriver(), mnode->GetPos(),
210                     // mnode->GetPos()+(mnode->UserForce * 0.1), video::SColor(100,0,0,0),false);
211                 }
212             }
213             ++myiter;
214         }
215 
216         application.DoStep();
217 
218         application.EndScene();
219     }
220 
221     return 0;
222 }
223