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.save(76) # Arbitrary commit tag




# 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.

7 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

  2. 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
    # =================
    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


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 )

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.