OpenSees Cloud
OpenSees AMI
Every Ending Is a New Beginning
Original Post - 22 Dec 2020 - Michael H. Scott
Show your support at Buy Me a Coffee.
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 do not work. Implementing or fixing sendSelf and 
recvSelf is usually pretty straightforward.