loadUserFunctionTest.py
You can view and download this file on Github: loadUserFunctionTest.py
1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2# This is an EXUDYN example
3#
4# Details: Test sensor with user function;
5# This test includes two cases:
6# 1) symbolic user function which allows to use regular graphics multithreading and is faster
7# 2) Python user function, which is convenient to be used, but requires to set useMultiThreadedRendering=False in visualizationSettings.general
8#
9# Author: Johannes Gerstmayr
10# Date: 2021-02-18
11#
12# 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.
13#
14#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15
16import exudyn as exu
17from exudyn.itemInterface import *
18from exudyn.basicUtilities import NormL2
19from exudyn.utilities import CreateSymbolicUserFunction
20from math import pi
21
22useGraphics = True #without test
23#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24#you can erase the following lines and all exudynTestGlobals related operations if this is not intended to be used as TestModel:
25try: #only if called from test suite
26 from modelUnitTests import exudynTestGlobals #for globally storing test results
27 useGraphics = exudynTestGlobals.useGraphics
28except:
29 class ExudynTestGlobals:
30 pass
31 exudynTestGlobals = ExudynTestGlobals()
32#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
33#useGraphics = False
34
35esym = exu.symbolic
36import numpy as np
37
38result = 0
39cases = ['PythonUserFunction', 'SymbolicUserFunction']
40for case in cases:
41 exu.Print('CASE: '+case)
42 SC = exu.SystemContainer()
43 mbs = SC.AddSystem()
44
45 useSymbolicUF = case == 'SymbolicUserFunction'
46
47 #variable can be used to switch behavior
48 #esym.variables.Set('flag',1)
49
50 if useSymbolicUF:
51 #scaling load with time
52 def UFload(mbs, t, loadVector):
53 return esym.cos(2*(2*pi)*t) * loadVector
54 else:
55 #general load changing over time (rotating)
56 def UFload(mbs, t, loadVector):
57 return [np.sin(2*(2*pi)*t) * loadVector[0],
58 np.cos(2*(2*pi)*t) * loadVector[0],
59 0]
60
61 oGround = mbs.CreateGround()
62
63 oMassPoint = mbs.CreateMassPoint(referencePosition=[1.+0.05,0,0], physicsMass=1, drawSize=0.1)
64 co = mbs.CreateSpringDamper(bodyNumbers=[oGround, oMassPoint],
65 referenceLength = 1, stiffness = 100, damping = 1)
66 sMass = mbs.AddSensor(SensorBody(bodyNumber=oMassPoint,
67 outputVariableType=exu.OutputVariableType.Position))
68
69 load = mbs.CreateForce(bodyNumber=oMassPoint, loadVector=[10,0,0],
70 loadVectorUserFunction=UFload)
71
72 if useSymbolicUF:
73 #these steps have to be done to inject the symbolic user function into exudyn as C-function
74 symFuncLoad = CreateSymbolicUserFunction(mbs, UFload, 'loadVectorUserFunction', load)
75 mbs.SetLoadParameter(load, 'loadVectorUserFunction', symFuncLoad)
76
77 #check function:
78 exu.Print('load user function: ',symFuncLoad)
79
80
81 #assemble and solve system for default parameters
82 mbs.Assemble()
83
84 endTime = 10
85 stepSize = 0.005
86
87 SC.visualizationSettings.loads.drawSimplified = False
88 SC.visualizationSettings.loads.drawWithUserFunction = True
89 SC.visualizationSettings.loads.fixedLoadSize = False #otherwise only sign will be shown
90 SC.visualizationSettings.loads.loadSizeFactor = 0.025
91 SC.visualizationSettings.general.useMultiThreadedRendering = useSymbolicUF
92 SC.visualizationSettings.nodes.drawNodesAsPoint = False
93 SC.visualizationSettings.nodes.tiling = 32
94 SC.visualizationSettings.general.graphicsUpdateInterval = 0.02
95 SC.visualizationSettings.general.renderWindowString = 'Test case: '+case
96
97 simulationSettings = exu.SimulationSettings()
98 #simulationSettings.solutionSettings.solutionWritePeriod = 0.01
99 simulationSettings.solutionSettings.writeSolutionToFile = False
100 simulationSettings.timeIntegration.verboseMode = 1
101 simulationSettings.timeIntegration.simulateInRealtime = useGraphics #for visualization to be viewed by user!
102
103 simulationSettings.timeIntegration.numberOfSteps = int(endTime/stepSize)
104 simulationSettings.timeIntegration.endTime = endTime
105 simulationSettings.timeIntegration.newton.useModifiedNewton = True
106
107 if useGraphics:
108 exu.StartRenderer()
109 mbs.WaitForUserToContinue()
110
111 mbs.SolveDynamic(simulationSettings, solverType=exu.DynamicSolverType.RK44)
112
113 if useGraphics:
114 exu.StopRenderer() #safely close rendering window!
115
116 result += NormL2(mbs.GetSensorValues(sMass))
117
118
119
120#evaluate final (=current) output values
121exu.Print('result of loadUserFunctionTest=',result)
122
123exudynTestGlobals.testResult = result #1.8051173706570725