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.utilities import CreateSymbolicUserFunction
19from math import pi
20
21testIsActive = exu.sys.get('testIsActive', False)
22#testIsActive = True
23
24esym = exu.symbolic
25import numpy as np
26
27result = 0
28cases = ['PythonUserFunction', 'SymbolicUserFunction']
29for case in cases:
30 exu.Print('CASE: '+case)
31 SC = exu.SystemContainer()
32 mbs = SC.AddSystem()
33
34 useSymbolicUF = case == 'SymbolicUserFunction'
35
36 #variable can be used to switch behavior
37 #esym.variables.Set('flag',1)
38
39 if useSymbolicUF:
40 #scaling load with time
41 def UFload(mbs, t, loadVector):
42 return esym.cos(2*(2*pi)*t) * loadVector
43 else:
44 #general load changing over time (rotating)
45 def UFload(mbs, t, loadVector):
46 return [np.sin(2*(2*pi)*t) * loadVector[0],
47 np.cos(2*(2*pi)*t) * loadVector[0],
48 0]
49
50 oGround = mbs.CreateGround()
51
52 oMassPoint = mbs.CreateMassPoint(referencePosition=[1.+0.05,0,0], mass=1, drawSize=0.1)
53 co = mbs.CreateSpringDamper(itemNumbers=[oGround, oMassPoint],
54 referenceLength = 1, stiffness = 100, damping = 1)
55 sMass = mbs.AddSensor(SensorBody(bodyNumber=oMassPoint,
56 outputVariableType=exu.OutputVariableType.Position))
57
58 load = mbs.CreateForce(itemNumber=oMassPoint, loadVector=[10,0,0],
59 loadVectorUserFunction=UFload)
60
61 if useSymbolicUF:
62 #these steps have to be done to inject the symbolic user function into exudyn as C-function
63 symFuncLoad = CreateSymbolicUserFunction(mbs, UFload, 'loadVectorUserFunction', load)
64 mbs.SetLoadParameter(load, 'loadVectorUserFunction', symFuncLoad)
65
66 #check function:
67 exu.Print('load user function: ',symFuncLoad)
68
69
70 #assemble and solve system for default parameters
71 mbs.Assemble()
72
73 endTime = 10
74 stepSize = 0.005
75
76 SC.visualizationSettings.loads.drawSimplified = False
77 SC.visualizationSettings.loads.drawWithUserFunction = True
78 SC.visualizationSettings.loads.fixedLoadSize = False #otherwise only sign will be shown
79 SC.visualizationSettings.loads.loadSizeFactor = 0.025
80 SC.visualizationSettings.general.useMultiThreadedRendering = useSymbolicUF
81 SC.visualizationSettings.nodes.drawNodesAsPoint = False
82 SC.visualizationSettings.nodes.tiling = 32
83 SC.visualizationSettings.general.graphicsUpdateInterval = 0.02
84 SC.visualizationSettings.general.renderWindowString = 'Test case: '+case
85
86 simulationSettings = exu.SimulationSettings()
87 #simulationSettings.solution.file.writePeriod = 0.01
88 simulationSettings.solution.file.write = False
89 simulationSettings.timeIntegration.verboseMode = 1
90 simulationSettings.timeIntegration.realtime.active = (not testIsActive) #for visualization to be viewed by user!
91
92 simulationSettings.timeIntegration.numberOfSteps = int(endTime/stepSize)
93 simulationSettings.timeIntegration.endTime = endTime
94 simulationSettings.timeIntegration.newton.useModifiedNewton = True
95
96 if not testIsActive:
97 SC.renderer.Start()
98 SC.renderer.DoIdleTasks()
99
100 mbs.SolveDynamic(simulationSettings, solverType=exu.DynamicSolverType.RK44)
101
102 if not testIsActive:
103 SC.renderer.Stop() #safely close rendering window!
104
105 result += np.linalg.norm(mbs.GetSensorValues(sMass))
106
107
108
109#evaluate final (=current) output values
110exu.Print('result of loadUserFunctionTest=',result)
111
112exu.sys['testResult'] = result #1.8051173706570725