1 // =============================================================================
2 // PROJECT CHRONO - http://projectchrono.org
3 //
4 // Copyright (c) 2019 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 // Authors: Radu Serban
13 // =============================================================================
14 //
15 // Benchmark test for contact simulation using NSC contact.
16 //
17 // =============================================================================
18
19 #include "chrono/ChConfig.h"
20 #include "chrono/utils/ChBenchmark.h"
21
22 #include "chrono/physics/ChSystemNSC.h"
23 #include "chrono/physics/ChBodyEasy.h"
24 #include "chrono/physics/ChLinkMotorRotationSpeed.h"
25
26 #include "chrono/assets/ChColorAsset.h"
27
28 #ifdef CHRONO_IRRLICHT
29 #include "chrono_irrlicht/ChIrrApp.h"
30 #endif
31
32 using namespace chrono;
33
34 // =============================================================================
35
36 template <int N>
37 class MixerTestNSC : public utils::ChBenchmarkTest {
38 public:
39 MixerTestNSC();
~MixerTestNSC()40 ~MixerTestNSC() { delete m_system; }
41
GetSystem()42 ChSystem* GetSystem() override { return m_system; }
ExecuteStep()43 void ExecuteStep() override { m_system->DoStepDynamics(m_step); }
44
45 void SimulateVis();
46
47 private:
48 ChSystemNSC* m_system;
49 double m_step;
50 };
51
52 template <int N>
MixerTestNSC()53 MixerTestNSC<N>::MixerTestNSC() : m_system(new ChSystemNSC()), m_step(0.02) {
54 auto mat = chrono_types::make_shared<ChMaterialSurfaceNSC>();
55
56 for (int bi = 0; bi < N; bi++) {
57 auto sphereBody = chrono_types::make_shared<ChBodyEasySphere>(1.0, 1000, true, true, mat);
58 sphereBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10));
59 sphereBody->AddAsset(chrono_types::make_shared<ChColorAsset>(0.4f, 0.0f, 0.0f));
60 m_system->Add(sphereBody);
61
62 auto boxBody = chrono_types::make_shared<ChBodyEasyBox>(1.25, 1.25, 1.25, 1000, true, true, mat);
63 boxBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10));
64 boxBody->AddAsset(chrono_types::make_shared<ChColorAsset>(0.0f, 0.4f, 0.0f));
65 m_system->Add(boxBody);
66
67 auto cylBody = chrono_types::make_shared<ChBodyEasyCylinder>(0.8, 1.0, 1000, true, true, mat);
68 cylBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10));
69 cylBody->AddAsset(chrono_types::make_shared<ChColorAsset>(0.0f, 0.0f, 0.4f));
70 m_system->Add(cylBody);
71 }
72
73 auto floorBody = chrono_types::make_shared<ChBodyEasyBox>(20, 1, 20, 1000, true, true, mat);
74 floorBody->SetPos(ChVector<>(0, -5, 0));
75 floorBody->SetBodyFixed(true);
76 m_system->Add(floorBody);
77
78 auto wallBody1 = chrono_types::make_shared<ChBodyEasyBox>(1, 10, 20.99, 1000, true, true, mat);
79 wallBody1->SetPos(ChVector<>(-10, 0, 0));
80 wallBody1->SetBodyFixed(true);
81 m_system->Add(wallBody1);
82
83 auto wallBody2 = chrono_types::make_shared<ChBodyEasyBox>(1, 10, 20.99, 1000, true, true, mat);
84 wallBody2->SetPos(ChVector<>(10, 0, 0));
85 wallBody2->SetBodyFixed(true);
86 m_system->Add(wallBody2);
87
88 auto wallBody3 = chrono_types::make_shared<ChBodyEasyBox>(20.99, 10, 1, 1000, true, true, mat);
89 wallBody3->SetPos(ChVector<>(0, 0, -10));
90 wallBody3->SetBodyFixed(true);
91 m_system->Add(wallBody3);
92
93 auto wallBody4 = chrono_types::make_shared<ChBodyEasyBox>(20.99, 10, 1, 1000, true, true, mat);
94 wallBody4->SetPos(ChVector<>(0, 0, 10));
95 wallBody4->SetBodyFixed(true);
96 m_system->Add(wallBody4);
97
98 auto rotatingBody = chrono_types::make_shared<ChBodyEasyBox>(10, 5, 1, 4000, true, true, mat);
99 rotatingBody->SetPos(ChVector<>(0, -1.6, 0));
100 m_system->Add(rotatingBody);
101
102 auto motor = chrono_types::make_shared<ChLinkMotorRotationSpeed>();
103 motor->Initialize(rotatingBody, floorBody, ChFrame<>(ChVector<>(0, 0, 0), Q_from_AngAxis(CH_C_PI_2, VECT_X)));
104 auto fun = chrono_types::make_shared<ChFunction_Const>(CH_C_PI / 3.0);
105 motor->SetSpeedFunction(fun);
106 m_system->AddLink(motor);
107 }
108
109 template <int N>
SimulateVis()110 void MixerTestNSC<N>::SimulateVis() {
111 #ifdef CHRONO_IRRLICHT
112 irrlicht::ChIrrApp application(m_system, L"Rigid contacts", irr::core::dimension2d<irr::u32>(800, 600));
113 application.AddTypicalLogo();
114 application.AddTypicalSky();
115 application.AddTypicalLights();
116 application.AddTypicalCamera(irr::core::vector3df(0, 14, -20));
117
118 application.AssetBindAll();
119 application.AssetUpdateAll();
120
121 while (application.GetDevice()->run()) {
122 application.BeginScene();
123 application.DrawAll();
124 ExecuteStep();
125 application.EndScene();
126 }
127 #endif
128 }
129
130 // =============================================================================
131
132 #define NUM_SKIP_STEPS 2000 // number of steps for hot start
133 #define NUM_SIM_STEPS 1000 // number of simulation steps for each benchmark
134
135 CH_BM_SIMULATION_LOOP(MixerNSC032, MixerTestNSC<32>, NUM_SKIP_STEPS, NUM_SIM_STEPS, 10);
136 CH_BM_SIMULATION_LOOP(MixerNSC064, MixerTestNSC<64>, NUM_SKIP_STEPS, NUM_SIM_STEPS, 10);
137
138 // =============================================================================
139
main(int argc,char * argv[])140 int main(int argc, char* argv[]) {
141 ::benchmark::Initialize(&argc, argv);
142
143 #ifdef CHRONO_IRRLICHT
144 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) {
145 MixerTestNSC<64> test;
146 test.SimulateVis();
147 return 0;
148 }
149 #endif
150
151 ::benchmark::RunSpecifiedBenchmarks();
152 }
153