Extracting node/element presence in model from *.mpco databases

Post Reply
Edward_Hayes
Posts: 1
Joined: Fri Jul 16, 2021 10:17 am

Extracting node/element presence in model from *.mpco databases

Post by Edward_Hayes » Thu Aug 05, 2021 4:15 pm

Hi all,

I am performing a progressive collapse analysis with a linear timeSeries in OpenSees using an external Tcl Script, and then loading mpco databases into the Post Processor. I want to compare two simulation models (one with damage and one without) that are otherwise identical.

In the analysis, elements and nodes are removed as they fail limit state checks. When elements/nodes are removed I 'pause time' by using the setTime command and subtracting $timeIncr of the timeSeries:

Code: Select all

	# ___TCL___
		# Pause time if failures occur:
		if {[llength $failure_list] > 0} {
			setTime [expr [getTime] - $timeIncrement];
		};
As a result, the Analysis Steps and model time are not consistent in each model as the number of time pauses depends on the number of failures and time at which they occur.

As part of my post-processing analysis, I want to identify which elements/nodes are present at each Analysis Step and relate this to a time using the getStepTimes PyMpc function (db.getStepTimes(stage_i)). Then I want to compare the elements/nodes present at a given time in the damaged and undamaged model towards generating a consequence or change in performance due to the damage applied.

To do this in the STKO Post-Processor Python API, I have been looping through each $nodeTag from an list generated inside OpenSees and then requesting a recorder result from the MPCO database using PyMpc commands, with a try: except: RuntimeError included to distinguish between components in the model and not in the model for a each analysis step.

Is there a better way to achieve this (see code snippet below) as all PyMpc errors are specified by RuntimeError and this would not be a robust solution. In the code node 111000 is a node which does exist and node 123456 does not.

Code: Select all

# ___Python API___
resultsField_u_Disp = db_u.getNodalResult("Displacement", match = MpcOdb.Contains)
# Check if node still exists in model:
for Analysis_Step_u in [1,2,3,4,5,6,7,8,9,10]:
	opt_u.step = Analysis_Step_u
	field = resultsField_u_Disp.evaluate(opt_u)
	row_u_does_exist = MpcOdbResultField.node(111000)
	row_u_does_not_exist = MpcOdbResultField.node(123456)
	x_disp = field[row_u_does_exist, 0]
	y_disp = field[row_u_does_exist, 1]
	print("When Node Does Exist in model:")
	print("x("+str(row_u_does_exist.n)+"): "+str(x_disp))
	print("y("+str(row_u_does_exist.n)+"): "+str(y_disp))
	print("When Node Does NOT Exist in model:")
	try:
		y_not_exist_disp = field[row_u_does_not_exist, 1]
		x_not_exist_disp = field[row_u_does_not_exist, 0]
	except RuntimeError as ex:
		template = "An exception of type {0} occurred. Arguments:\n{1!r}"
		message = template.format(type(ex).__name__, ex.args)
		print(message)
		print(traceback.format_exc())
		print("Node Selection "+str(row_u_does_not_exist.n)+" Not in Model")
		y_not_exist_disp = None
		x_not_exist_disp = None
		pass
	print("x("+str(row_u_does_not_exist.n)+"): "+str(x_not_exist_disp))
	print("y("+str(row_u_does_not_exist.n)+"): "+str(y_not_exist_disp))


I have also been unable to import modules like h5py to try and extract the data visible in the mpco files using HDFView (e.g. retrieve nodes or elements Tags from a set in an MPCO file which (as I understand it) corresponds to the region command in Tcl OpenSees) - although I am relatively new to Python and until now have been just using pip install <name> in the Windows cmd to this point alongside PyCharm + Python 3.9.6.

In summary:
1) Is there a better way to identify that a node or element exists at a given Analysis step using PyMpc functions and the mpco database than the try: except RuntimeError with a recorder output request? For example, a boolean or -1 value when using MpcOdbResultField.node(<nodeTag>) to identify the row index of <nodeTag> in the mpco database? PyMpc documentation: https://asdeasoft.net/stko-wiki/class_p ... ml#details

2) Is there a way to extract a list/vector of eleTags/nodeTags from the sets in mpco objects (Tcl Regions) and then update their 'presence' at each analysis step?

3) If these are not trivial to achieve with PyMpc functions, how would you go about installing a compatible version of h5py for use with STKO's Python API? (Plan would be to recursively identify keys in MPCO database and use regular expressions or a string search to access the relevant sets etc...)

STKO Team
Posts: 737
Joined: Tue Oct 29, 2019 8:45 am

Re: Extracting node/element presence in model from *.mpco databases

Post by STKO Team » Thu Aug 05, 2021 5:24 pm

1) Is there a better way to identify that a node or element exists at a given Analysis step using PyMpc functions and the mpco database than the try: except RuntimeError with a recorder output request? For example, a boolean or -1 value when using MpcOdbResultField.node(<nodeTag>) to identify the row index of <nodeTag> in the mpco database?
Yes and it is very easy. You need a couple of concepts:
  • the evaluate(opt) method of MpcOdbVirtualResult produces a MpcOdbResultField.
  • the mesh attribute of MpcOdbResultField gives you the mesh at the stage specified in opt (MpcOdbVirtualResultEvaluationOptions)
  • every time you remove a node/element, OpenSees issues the domainChange method, that leads to a new ModelStage in MPCO. This means that you don't need to check every step of every stage, but just the first step of each stage.

Code: Select all

from PyMpc import *
from PyMpc import MpcOdbVirtualResult as vr

App.clearTerminal()
doc = App.postDocument()
db = doc.getDatabase(1)

# the node we want to check.
# we can check the presence of a node from the mesh in
# the result field
check_node = 134

# we need a result to generate a field, and to
# get the mesh from the field
result = db.getNodalResult('Displacement', match=MpcOdb.Contains)

# create the eval options
opt = MpcOdbVirtualResultEvaluationOptions()

# keep in mind that when you remove a node or an element,
# we have a new model stage (due to the domainChange method).
# so we don't need to evaluate the result
all_stages = db.getStageIDs()
for i in range(len(all_stages)):
	# the current stage_id
	stage_id = all_stages[i]
	# get all step id and time for this stage
	steps = list(db.getStepIDs(stage_id))
	times = list(db.getStepTimes(stage_id))
	# make sure we have at least 1 step
	if len(steps) > 0:
		# take the first one
		step_id = steps[0]
		time = times[0]
		# make field
		opt.stage = stage_id
		opt.step = step_id
		field = result.evaluate(opt)
		mesh = field.mesh
		exists = check_node in mesh.nodes
		print('Stage: {}, Start Time: {}, Start Step: {}, Exists ? {}'.format(
			stage_id, time, step_id, exists))
2) Is there a way to extract a list/vector of eleTags/nodeTags from the sets in mpco objects (Tcl Regions) and then update their 'presence' at each analysis step?
There is no way to extract info from the OpenSees' regions. And they are not saved in the MPCO recorder.
However, if you generate your model from the STKO pre-processor, STKO generates a *.mpco.cdata file that contains all information coming from the pre-processor.
Among them you can find SELECTION_SETS. It will be very easy to parse this file:
sset.png
sset.png (72.12 KiB) Viewed 124 times

Post Reply