I attach my python code that does what I want. It works well but it takes around 30 minutes when I evaluate over the whole geometry.
Code: Select all
from PyMpc import *
from PyMpc import MpcOdbVirtualResult as vr
import numpy as np
import os
#import pandas
# clear terminal
App.clearTerminal()
# get document
doc = App.postDocument()
# get first database
if len(doc.databases) == 0:
raise Exception("You need a database with ID = 1 for this script")
def get_Nodal_disp(finput,fdispx,fdispy,fdispz,fnodes,nodresult='Acceleration'):
db=doc.getDatabase(2)
nodes_target=np.loadtxt(finput,dtype=int)
print('n',nodes_target)
displacement = db.getNodalResult(nodresult, match = MpcOdb.Contains)
# create evaluation options
# here we want to extract data for all steps of the last stage
all_stages = db.getStageIDs() # get all model stages
last_stage = all_stages[-1] # get the last stage
all_steps = db.getStepIDs(last_stage) # get all steps of the last stage
all_times = db.getStepTimes(last_stage) # get all step times of the last stage
# initialize the evaluation options with the last stage
opt = MpcOdbVirtualResultEvaluationOptions()
opt.stage = last_stage
num_steps = len(all_steps)
## create node array with disp for all nodes, first row is time
arr_disp_x=np.zeros((num_steps,len(nodes_target)+1))
arr_disp_y=np.zeros((num_steps,len(nodes_target)+1))
arr_disp_z=np.zeros((num_steps,len(nodes_target)+1))
## create node array with node id and coordinates
arr_nodes=np.zeros((len(nodes_target),4))
# flag for updating arr_nodes only at first time step
create_node_file=True
for step_counter in range(num_steps):
# get step id and time
step_id = all_steps[step_counter]
step_time = all_times[step_counter]
# write something...
# and process all application events to avoid GUI freezing...
print('Evaluate results at step {} t = {}'.format(step_id, step_time))
App.processEvents()
# put the current step id in the evaluation options
opt.step = step_id
# evaluate all the results at the current step
displacement_field = displacement.evaluate(opt)
# This is how you extract data from a nodal result at one or multiple nodes
# and compute the relative drift accessing the mesh data
# this is a nodal field. The row is the nodal id
all_disps = []
for n,nod in enumerate(nodes_target):
## get nodal id
i_node_id=nodes_target[n]
# not sure what this does but works
i_row=MpcOdbResultField.node(int(nod-1))
Ux=displacement_field[i_row,0]
Uy=displacement_field[i_row,1]
Uz=displacement_field[i_row,2]
## update time step
arr_disp_x[step_counter,0]=step_time
arr_disp_y[step_counter,0]=step_time
arr_disp_z[step_counter,0]=step_time
## update disp
arr_disp_x[step_counter,n+1]=Ux
arr_disp_y[step_counter,n+1]=Uy
arr_disp_z[step_counter,n+1]=Uz
## if the flag for arr node coords is True, then create nodedata
if create_node_file:
node_data=displacement_field.mesh.nodes.values()[nod-1]
#print('bu',nod,n)
#print('x',node_data)
nodepos=np.array([nod,node_data.x,node_data.y,node_data.z])
arr_nodes[n,:]=nodepos
## turn off the flag!
create_node_file=False
# create a string with the node disp header
string=[str(x) for x in nodes_target]
string.insert(0,'time')
header_data=';'.join(string)
## create a string with the node coords header
header_nodes='id;x;y;z;'
#print(arr_disp_x.shape)
#print(arr_nodes)
## format for node_coords output file
format_nodes=['%i','%10.5f','%10.5f','%10.5f']
np.savetxt(fdispx,arr_disp_x,fmt='%10.5f',header=header_data,comments='',delimiter=';')
np.savetxt(fdispy,arr_disp_y,fmt='%10.5f',header=header_data,comments='',delimiter=';')
np.savetxt(fdispz,arr_disp_z,fmt='%10.5f',header=header_data,comments='',delimiter=';')
np.savetxt(fnodes,arr_nodes,fmt=format_nodes,header=header_nodes,comments='',delimiter=';')
lay='surface'
sta='AP01'
disp_type='V'
finput='MAULE_NODES_'+lay.upper()+'.txt'
fdispx=sta+'_'+disp_type+'x_'+lay+'.csv'
fdispy=sta+'_'+disp_type+'y_'+lay+'.csv'
fdispz=sta+'_'+disp_type+'z_'+lay+'.csv'
fnodes=sta+'_nodes_'+lay+'.csv'
get_Nodal_disp(finput,fdispx,fdispy,fdispz,fnodes,nodresult='Velocity')
print('done')