(testmodels-symbolicuserfunctioncopytest)= # symbolicUserFunctionCopyTest.py You can view and download this file on Github: [symbolicUserFunctionCopyTest.py](https://github.com/jgerstmayr/EXUDYN/tree/master/python/TestModels/symbolicUserFunctionCopyTest.py) ```{code-block} python :linenos: #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # This is an EXUDYN example # # Details: A model with a symbolic user function, copied through mbs.GetDictionary() and # mbs.SetDictionary() into a second system (#1888): the copy keeps the function symbolic # and computes the same motion. A mass on a spring, driven by a load whose user function # is symbolic; the result is the position of the copy after 1 s, which equals the original. # # Author: Johannes Gerstmayr # Date: 2026-09-29 # # 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. # #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ import exudyn as exu from exudyn.utilities import * #includes itemInterface and rigidBodyUtilities import numpy as np testIsActive = exu.sys.get('testIsActive', False) esym = exu.symbolic SC = exu.SystemContainer() mbs = SC.AddSystem() node = mbs.AddNode(NodePoint(referenceCoordinates=[0,0,0])) mbs.AddObject(ObjectMassPoint(nodeNumber=node, mass=1)) mNode = mbs.AddMarker(MarkerNodePosition(nodeNumber=node)) nFixed = mbs.AddNode(NodePointGround()) mbs.AddObject(ObjectConnectorCartesianSpringDamper(markerNumbers=[mbs.AddMarker(MarkerNodePosition(nodeNumber=nFixed)), mNode], stiffness=[100,100,100], damping=[1,1,1])) def UFload(mbs, t, loadVector): return [loadVector[0]*esym.sin(10*t), loadVector[1], 0] load = mbs.AddLoad(LoadForceVector(markerNumber=mNode, loadVector=[10,5,0])) symbolicLoad = CreateSymbolicUserFunction(mbs, UFload, 'loadVectorUserFunction', load) mbs.SetLoadParameter(load, 'loadVectorUserFunction', symbolicLoad) def Solve(mbs): mbs.Assemble() simulationSettings = exu.SimulationSettings() simulationSettings.timeIntegration.numberOfSteps = 200 simulationSettings.timeIntegration.endTime = 1 simulationSettings.solution.file.write = False mbs.SolveDynamic(simulationSettings) return mbs.GetNodeOutput(node, exu.OutputVariableType.Position) #the copy is made before solving, from the dictionary of the model mbsCopy = SC.AddSystem() mbsCopy.SetDictionary(mbs.GetDictionary()) isSymbolic = mbsCopy.GetLoadParameter(load, 'loadVectorUserFunction')['type'] == 'Symbolic' pOriginal = Solve(mbs) pCopy = Solve(mbsCopy) exu.Print('copy is symbolic:', isSymbolic, ', difference to the original:', np.linalg.norm(pCopy - pOriginal)) testResult = sum(pCopy) + (0 if isSymbolic else 1) exu.Print('solution of symbolicUserFunctionCopyTest=', testResult) exu.sys['testResult'] = testResult ```