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.
Dear P.D.,
It is a very helpful. Thanks for sharing.
LikeLiked by 1 person
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.
LikeLiked by 1 person
Thanks pflnx, that’s an excellent point!
LikeLike
Thanks for sharing! Great post! I learned something new today! Keep up the great work and Happy Holidays!
LikeLiked by 1 person
Thanks professor, very nice post. I encountered a problem when I’m using database+save+restore, because I want to do seismic+tsunami pushover analysis. That is, I use save to save the Model State after seismic anslysis, and do the first Pushover analysis using the first pushover pattern, and it works successfully. Then, I use another pushover pattern to do the second analysis but it failed from the very first step. However, the first parameter works when I exchange the 1st and 2nd parameter, which means it is not the parameter itself that matters. To solve this, I change the properties of zeroLength Material used in my model. Here I use two Hysteretic Material (H1, H2) as components of a Parallel Material (P1), and then I used a ENT Material (ENT1) to combine with the Parallel Material P1, so I got a Series Material (S1). When I use S1, the 2nd analysis would fail, but when I further attach a small stiffness Elastic Material (E1) with material S1, it can work out.
I feel really confused about the result. Theoretically, if there is something wrong with the Material S1, then it will fail as well in the 1st analysis, whereas it only fails in the 2nd.
Hopefully, you can help me to better understand the reason, thanks a lot.
For better illustration, the code structure is like this,
# =================
# Model
# =================
wipe
source ModelDefinition.tcl
# =================
# Gravity & loadConst
# =================
source GravityAnalyze.tcl
loadConst -time 0.0
# =================
# Seismic
# =================
source SeismicAnalyze.tcl
remove loadPattern $seismicPattern
# =================
# Database
# =================
database $databasePath
save 1
# =================
# Tsunami
# =================
set pushoverParam $param1
source DefPushoverPattern.tcl
source Pushover.tcl
#
remove loadPattern $pushoverPattern
#
database $databasePath
restore 1
#
set pushoverParam $param2
source DefPushoverPattern.tcl
source Pushover.tcl; # unable to converge from the 1st step.
# end
exit
LikeLike
Thanks, I can’t really tell what’s happening. You can try posting your issue on the OpenSees message board or Facebook group, or seeking out additional services for 1-on-1 consultation.
LikeLike