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