compareFullModifiedNewton.py

You can view and download this file on Github: compareFullModifiedNewton.py

  1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2# This is an EXUDYN example
  3#
  4# Details:  pendulum example: check difference of full and modified newton
  5#
  6# Author:   Johannes Gerstmayr
  7# Date:     2020-06-19
  8#
  9# 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.
 10#
 11#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 12
 13import exudyn as exu
 14#a local run must not open a plot window when windows are suppressed (#2477)
 15if exu.special.userInterface.suppressPlots: import matplotlib; matplotlib.use('Agg')
 16from exudyn.utilities import * #includes itemInterface and rigidBodyUtilities
 17import exudyn.graphics as graphics
 18
 19import numpy as np
 20import matplotlib.pyplot as plt
 21import matplotlib.ticker as ticker
 22
 23testIsActive = exu.sys.get('testIsActive', False)
 24
 25SC = exu.SystemContainer()
 26mbs = SC.AddSystem()
 27
 28
 29#%%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 30#rigid pendulum:
 31rect = [-2,-2,2,2] #xmin,ymin,xmax,ymax
 32background = {'type':'Line', 'color':[0.1,0.1,0.8,1], 'data':[rect[0],rect[1],0, rect[2],rect[1],0, rect[2],rect[3],0, rect[0],rect[3],0, rect[0],rect[1],0]} #background
 33oGround=mbs.AddObject(ObjectGround(referencePosition= [0,0,0], visualization=VObjectGround(graphicsData= [background])))
 34a = 0.5     #x-dim of pendulum
 35b = 0.05    #y-dim of pendulum
 36massRigid = 12
 37inertiaRigid = massRigid/12*(2*a)**2
 38g = 9.81    # gravity
 39
 40graphics2 = {'type':'Line', 'color':[0.1,0.1,0.8,1], 'data':[-a,-b,0, a,-b,0, a,b,0, -a,b,0, -a,-b,0]} #background
 41omega0 = 5*0 #inconsistent initial conditions lead to integration problems!
 42nRigid = mbs.AddNode(Rigid2D(referenceCoordinates=[a,0,0], initialVelocities=[0,omega0*a,omega0]));
 43oRigid = mbs.AddObject(RigidBody2D(mass=massRigid, inertia=inertiaRigid,nodeNumber=nRigid,visualization=VObjectRigidBody2D(graphicsData= [graphics2])))
 44
 45mR1 = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oRigid, localPosition=[-a,0.,0.])) #support point
 46mR2 = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oRigid, localPosition=[ a,0.,0.])) #end point
 47
 48mG0 = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oGround, localPosition=[0,0,0.]))
 49mbs.AddObject(RevoluteJoint2D(markerNumbers=[mG0,mR1]))
 50
 51mbs.AddLoad(Force(markerNumber = mR2, loadVector = [0, -massRigid*g, 0]))
 52
 53#this model is the designated writing test of the suite (#2418): while most test models keep their
 54#results internally (storeInternal=True) and write nothing, this one writes the coordinates
 55#solution file AND a sensor file, and reads both back, so that both writers stay tested
 56sensorEnd = mbs.AddSensor(SensorBody(bodyNumber=oRigid, localPosition=[a,0.,0.],
 57                                     outputVariableType=exu.OutputVariableType.Position,
 58                                     fileName='solution/endPointPosition.txt',
 59                                     storeInternal=True))
 60
 61mbs.Assemble()
 62#exu.Print(mbs)
 63
 64simulationSettings = exu.SimulationSettings() #takes currently set values or default values
 65
 66simulationSettings.timeIntegration.numberOfSteps = 100 #100
 67simulationSettings.timeIntegration.endTime = 2
 68simulationSettings.timeIntegration.newton.relativeTolerance = 1e-8
 69simulationSettings.timeIntegration.newton.absoluteTolerance = 1e-4
 70simulationSettings.timeIntegration.verboseMode = 1
 71
 72simulationSettings.timeIntegration.newton.numericalDifferentiation.minimumCoordinateSize = 1
 73#simulationSettings.timeIntegration.generalizedAlpha.useNewmark = True
 74#simulationSettings.timeIntegration.generalizedAlpha.useIndex2Constraints = True
 75simulationSettings.timeIntegration.generalizedAlpha.spectralRadius = 0.5
 76simulationSettings.show.statistics = True
 77simulationSettings.solution.file.writePeriod = 1e-4
 78
 79simulationSettings.timeIntegration.newton.useModifiedNewton = True
 80simulationSettings.solution.file.name = "solution/modifiedNewton.txt"
 81mbs.SolveDynamic(simulationSettings)#, experimentalNewSolver=False)
 82
 83simulationSettings.timeIntegration.newton.useModifiedNewton = False
 84simulationSettings.solution.file.name = "solution/fullNewton.txt"
 85mbs.SolveDynamic(simulationSettings)#, experimentalNewSolver=False)
 86
 87
 88#%%*****************************************
 89#post processing for mass point system
 90
 91#OutputFilePath merges the file name with exudyn.config.outputDirectory, which the test suite
 92#sets per model and which is '' when this model is run standalone (#2454)
 93import os
 94from exudyn.basicUtilities import OutputFilePath
 95def OutputFile(name):
 96    return OutputFilePath(name, 'compareFullModifiedNewton')
 97
 98dataM = np.loadtxt(OutputFile('solution/modifiedNewton.txt'), comments='#', delimiter=',')
 99dataF = np.loadtxt(OutputFile('solution/fullNewton.txt'), comments='#', delimiter=',')
100
101#the sensor file must contain what the internal storage holds; this is the check that keeps the
102#file writer honest now that the other models store internally
103sensorFromFile = np.loadtxt(OutputFile('solution/endPointPosition.txt'), comments='#', delimiter=',')
104sensorInternal = mbs.GetSensorStoredData(sensorEnd)
105sensorDeviation = np.max(np.abs(sensorFromFile - sensorInternal))
106exu.Print("compareFullModifiedNewton sensor file vs internal =", sensorDeviation)
107if sensorFromFile.shape != sensorInternal.shape or sensorDeviation > 1e-8: #file output has ~10 digits (solution.precision), internal data is exact
108    raise ValueError('sensor file and internal sensor data disagree: shapes '
109                     + str(sensorFromFile.shape) + ' and ' + str(sensorInternal.shape)
110                     + ', largest deviation ' + str(sensorDeviation))
111
112# exu.Print("solFullNewton     =",sum(abs(dataF[:,5])))
113# exu.Print("solModifiedNewton =",sum(abs(dataM[:,5])))
114
115u=sum(abs(dataM[:,5]-dataF[:,5]))
116exu.Print("compareFullModifiedNewton u=",u)
117
118exu.sys['testResult'] = u
119
120os.remove(OutputFile('solution/modifiedNewton.txt'))
121os.remove(OutputFile('solution/fullNewton.txt'))
122os.remove(OutputFile('solution/endPointPosition.txt'))
123
124if not testIsActive:
125    # plt.plot(dataM[:,0], dataM[:,3+2], 'b-') #plot column i over column 0 (time)
126    # plt.plot(dataF[:,0], dataF[:,3+2], 'r-') #plot column i over column 0 (time)
127    plt.plot(dataF[:,0], dataF[:,5]-dataM[:,5], 'r-') 
128    
129    ax=plt.gca() # get current axes
130    ax.grid(True, 'major', 'both')
131    ax.xaxis.set_major_locator(ticker.MaxNLocator(10)) #use maximum of 8 ticks on y-axis
132    ax.yaxis.set_major_locator(ticker.MaxNLocator(10)) #use maximum of 8 ticks on y-axis
133    plt.tight_layout()
134    plt.show()