Every Ending Is a New Beginning

Simulation of structural response to sequential hazards, e.g., fire following earthquake or tsunami following earthquake, is something OpenSees can handle. But suppose you want to look at different tsunami scenarios after a single earthquake. Tsunami loading occurs over a few seconds where the preceding earthquake lasted a minute or two. Do you want to repeat the same earthquake simulation for every tsunami loading scenario? No, me neither.

The database command in OpenSees allows you to save and restore models, so that in this hypothetical example you only need to run the earthquake simulation once. Although three database types are available, only the File option works–MySQL and BerkeleyDB haven’t been updated in a long time.

After creating a database, the save command will write the entire state of the domain–nodes, elements, constraints, loads, and time series, as well as the current time–to the database. You can save the domain multiple times, just give different commit tags. Also, the analysis options (algorithm, system, integrator, etc.) are not saved.

The restore command brings the domain back into memory, after which you can define the analysis options. Note that the time in the domain is restored, so you are not starting at t=0. This can makes things a little tricky when defining new time series on the restored model. Either reset the time in the domain or give a start time to the time series. Also, be sure to remove, either before you save or after you restore, any load patterns that should not be active in the analysis of the restored model.

Here is a simple example of a truss element with bilinear stress-strain and subjected to two separate loadings (A and B) that grossly oversimplify a tsunami load following an earthquake.

After defining the model and performing the first analysis (A), create a File database (in the code below I added a subfolder db/ to the database name because I don’t want a bunch of files in my current working directory), then save the model. Here I use the wipe command, then restore the model, but you could restore the model from a separate script as long as you know the commit tag. After the model is restored, I reset the domain time to zero and remove the cyclic load pattern–something you may not have to do depending on how you define the analyses–then do the second analysis (B).

#
# Define model, do first analysis
#

ops.database('File','db/testTrussDB')
ops.save(76) # Arbitrary commit tag

ops.wipe()

ops.database('File','db/testTrussDB')
ops.restore(76)

ops.setTime(0)
ops.remove('loadPattern',1)

#
# Do second analysis
#

The results of analyses A and B show the plastic strain was carried over from the save to the restore, i.e., the initial condition of analysis B was the final state of analysis A.

The correct execution of the save and restore commands relies on implementation of the sendSelf and recvSelf methods of all elements and materials in your model. In many cases, these methods are incorrect or not implemented at all. Let me know if you come across any cases where save and restore don’t work. Implementing or fixing sendSelf and recvSelf is usually pretty straightforward.

4 thoughts on “Every Ending Is a New Beginning

  1. Excellent post! I’d like to add that this combination of database save and restore commands can also be used to move models between interpreters – Python to Tcl and vice versa.

    Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.