generalContactSpheresTest.py
You can view and download this file on Github: generalContactSpheresTest.py
1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2# This is an EXUDYN example
3#
4# Details: test with parallel computation and particles
5#
6# Author: Johannes Gerstmayr
7# Date: 2021-11-01
8#
9# Copyright:This file is part of Exudyn. Exudyn is free software. You can redistribute it and/or modify it under the terms of the Exudyn license. See 'LICENSE.txt' for more details.
10#
11#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12
13import exudyn as exu
14from exudyn.utilities import *
15
16import numpy as np
17
18useGraphics = True #without test
19#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20#you can erase the following lines and all exudynTestGlobals related operations if this is not intended to be used as TestModel:
21try: #only if called from test suite
22 from modelUnitTests import exudynTestGlobals #for globally storing test results
23 useGraphics = exudynTestGlobals.useGraphics
24except:
25 class ExudynTestGlobals:
26 pass
27 exudynTestGlobals = ExudynTestGlobals()
28 exudynTestGlobals.isPerformanceTest = False
29#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
30
31SC = exu.SystemContainer()
32mbs = SC.AddSystem()
33
34nGround = mbs.AddNode(NodePointGround(referenceCoordinates=[0,0,0]))
35
36np.random.seed(1) #always get same results
37
38
39isPerformanceTest = exudynTestGlobals.isPerformanceTest
40# useGraphics = False
41# isPerformanceTest = True
42
43L = 1
44n = 500
45row = 8 #number of spheres in plane
46
47a = L
48vInit= -20
49
50if isPerformanceTest:
51 n *= 100
52 a *= 0.5
53 row *= 2
54 vInit *= 10
55
56radius = 0.5*a
57m = 0.05
58k = 4e4
59d = 0.001*k*4*0.5*0.2 *0.25
60markerList = []
61radiusList = []
62gDataList = []
63
64
65rb = 30*L
66H = 8*L
67Hy=3*L
68pos0 = [0,-rb-0.5*H,0]
69pos1 = [-rb-H,-Hy,0]
70pos2 = [ rb+H,-Hy,0]
71pos3 = [ 0,-Hy,rb+H]
72pos4 = [ 0,-Hy,-rb-H]
73posList=[pos0,pos1,pos2,pos3,pos4]
74for pos in posList:
75 colBG = color4grey
76 colBG[3] = 0.05
77 gDataList += [GraphicsDataSphere(point=pos, radius=rb, color= colBG, nTiles=50)]
78 nMass = mbs.AddNode(NodePointGround(referenceCoordinates=pos,
79 visualization=VNodePointGround(show=False)))
80
81 mThis = mbs.AddMarker(MarkerNodePosition(nodeNumber=nMass))
82 markerList += [mThis]
83 radiusList += [rb]
84
85
86ns = 20
87gDataSphere = []
88for i in range(ns):
89 gRad = radius*(0.75+0.4*(i/ns))
90 gSphere = GraphicsDataSphere(point=[0,0,0], radius=gRad, color=color4blue, nTiles=5)
91 gDataSphere += [[gSphere]]
92
93gDataSphere = []
94
95timeCreateStart= -time.time()
96
97color4node = color4blue
98maxY = 0
99for i in range(n):
100
101 kk = int(i/int(n/16))
102 color4node = color4list[min(kk%9,9)]
103
104 if (i%20000 == 0): exu.Print("create mass",i)
105 offy = 0
106
107 iy = int(i/(row*row))
108 ix = i%row
109 iz = int(i/row)%row
110
111 if iy % 2 == 1:
112 ix+=0.5
113 iz+=0.5
114
115 offy = -0.25*H-1.5*a+iy*a*0.74 #0.70x is limit value!
116 offx = -0.6*a-H*0.5 + (ix+1)*a
117 offz = -0.6*a-H*0.5 + (iz+1)*a
118
119 valueRand = np.random.random(1)[0]
120 rFact = 0.2 #random part
121 gRad = radius*(1-rFact+rFact*valueRand)
122 pRef = np.array([offx,offy,offz])
123 maxY = max(maxY,offy)
124 nMass = mbs.AddNode(NodePoint(referenceCoordinates=pRef,
125 initialVelocities=[0,vInit,0],
126 visualization=VNodePoint(show=True,drawSize=2*gRad, color=color4node)))
127 if i==row*int(row/4)-int(row/2):
128 sNodeNum = nMass
129 if useGraphics:
130 sNode=mbs.AddSensor(SensorNode(nodeNumber=nMass, fileName='solution/generalContactSpheres.txt',
131 outputVariableType=exu.OutputVariableType.Position))
132
133 oMass = mbs.AddObject(MassPoint(physicsMass=m, nodeNumber=nMass))
134 mThis = mbs.AddMarker(MarkerNodePosition(nodeNumber=nMass))
135 mbs.AddLoad(Force(markerNumber=mThis, loadVector= [0,-m*9.81,0]))
136 markerList += [mThis]
137 radiusList += [gRad]
138
139 mLast = mThis
140
141#put here, such that it is transparent in background
142oGround=mbs.AddObject(ObjectGround(referencePosition= [0,0,0],
143 visualization=VObjectGround(graphicsData=gDataList)))
144
145exu.Print('generalContactSpheresTest: create bodies:',timeCreateStart+time.time(),'seconds')
146timeCreateStart= -time.time()
147
148if True:
149 gContact = mbs.AddGeneralContact()
150 gContact.verboseMode = 1
151
152 for i in range(len(markerList)):
153 m = markerList[i]
154 r = radiusList[i]
155 gContact.AddSphereWithMarker(m, radius=r, contactStiffness=k, contactDamping=d, frictionMaterialIndex=0)
156
157 ssx = 20 #search tree size
158 ssy = 20
159 if isPerformanceTest:
160 ssy*=4
161 # mbs.Assemble()
162 # gContact.FinalizeContact(mbs, searchTreeSize=np.array([ssx,ssy,ssx]), frictionPairingsInit=np.eye(1),
163 # searchTreeBoxMin=np.array([-1.2*H,-H,-1.2*H]), searchTreeBoxMax=np.array([1.2*H,14*H,1.2*H]) #80000 particles
164 # )
165
166 gContact.SetFrictionPairings(0.*np.eye(1))
167 gContact.SetSearchTreeCellSize(numberOfCells=[ssx,ssy,ssx])
168 gContact.SetSearchTreeBox(pMin=np.array([-1.2*H,-H,-1.2*H]), pMax=np.array([1.2*H,maxY,1.2*H]))
169
170 exu.Print('treesize=',ssx*ssx*ssy)
171
172exu.Print('generalContactSpheresTest: gContact:',timeCreateStart+time.time(),'seconds')
173
174mbs.Assemble()
175exu.Print("finish gContact")
176
177tEnd = 0.1
178if isPerformanceTest: tEnd *= 0.5
179h= 0.0002
180simulationSettings = exu.SimulationSettings()
181simulationSettings.linearSolverType = exu.LinearSolverType.EigenSparse
182#simulationSettings.solutionSettings.writeSolutionToFile = True
183simulationSettings.solutionSettings.writeSolutionToFile = True
184simulationSettings.solutionSettings.solutionWritePeriod = 0.02
185simulationSettings.solutionSettings.sensorsWritePeriod = h*10
186simulationSettings.solutionSettings.outputPrecision = 5 #make files smaller
187simulationSettings.solutionSettings.exportAccelerations = False
188simulationSettings.solutionSettings.exportVelocities = False
189simulationSettings.solutionSettings.coordinatesSolutionFileName = 'solution/test.txt'
190simulationSettings.displayComputationTime = True
191#simulationSettings.displayStatistics = True
192simulationSettings.timeIntegration.verboseMode = 1
193simulationSettings.parallel.numberOfThreads = 1 #use 1 thread to create reproducible results (due to round off errors in sparse vector?)
194if isPerformanceTest: simulationSettings.parallel.numberOfThreads = 8
195
196simulationSettings.timeIntegration.newton.numericalDifferentiation.forODE2 = False
197simulationSettings.timeIntegration.newton.useModifiedNewton = False
198
199SC.visualizationSettings.general.graphicsUpdateInterval=0.5
200SC.visualizationSettings.general.circleTiling=200
201SC.visualizationSettings.general.drawCoordinateSystem=False
202SC.visualizationSettings.loads.show=False
203SC.visualizationSettings.bodies.show=True
204SC.visualizationSettings.markers.show=False
205
206SC.visualizationSettings.nodes.show=True
207SC.visualizationSettings.nodes.drawNodesAsPoint = False
208SC.visualizationSettings.nodes.defaultSize = 0 #must not be -1, otherwise uses autocomputed size
209SC.visualizationSettings.nodes.tiling = 4
210
211SC.visualizationSettings.window.renderWindowSize=[800,800]
212#SC.visualizationSettings.window.renderWindowSize=[1024,1400]
213SC.visualizationSettings.openGL.multiSampling = 4
214#improved OpenGL rendering
215
216
217if useGraphics:
218 SC.visualizationSettings.general.autoFitScene = False
219 exu.StartRenderer()
220 if 'renderState' in exu.sys:
221 SC.SetRenderState(exu.sys['renderState'])
222 mbs.WaitForUserToContinue()
223
224simulationSettings.timeIntegration.numberOfSteps = int(tEnd/h)
225simulationSettings.timeIntegration.endTime = tEnd
226simulationSettings.timeIntegration.explicitIntegration.computeEndOfStepAccelerations = False #increase performance, accelerations less accurate
227simulationSettings.timeIntegration.explicitIntegration.computeMassMatrixInversePerBody = True ##2022-12-16: increase performance for multi-threading, Newton increment faster by factor 6 for 8 threads
228
229mbs.SolveDynamic(simulationSettings, solverType=exu.DynamicSolverType.ExplicitEuler)
230
231u = mbs.GetNodeOutput(sNodeNum, exu.OutputVariableType.Coordinates)
232uSum = u[0] + u[1] + u[2]
233exu.Print("u =", u)
234exu.Print('solution of generalContactSpheresTest=',uSum)
235
236if isPerformanceTest:
237 exudynTestGlobals.testError = uSum - (-5.946497644233068)
238else:
239 exudynTestGlobals.testError = uSum - (-1.0947542400425323)
240
241exudynTestGlobals.testResult = uSum
242
243
244if useGraphics:
245 SC.WaitForRenderEngineStopFlag()
246 exu.StopRenderer() #safely close rendering window!
247
248if useGraphics:
249
250 # mbs.PlotSensor([sNode], [2])
251 mbs.PlotSensor([sNode,sNode], [0,1])