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