Saving and loading objects


In [1]:
import numpy as np
import json

import sfsimodels as sm

Define a soil


In [2]:
# Set the void ratio and specific gravity
sl = sm.Soil()
sl.id = 1  # Must set an id before saving
sl.e_curr = 0.7
assert sl.unit_dry_weight is None
sl.specific_gravity = 2.95
assert np.isclose(sl.unit_dry_weight, 17000, rtol=0.01)

# set modulus parameters
g_mod_set = 40e6 
sl.g_mod = g_mod_set
sl.poissons_ratio = 0.4

Save the soil to file then load it


In [3]:
# Create an output object
ecp_output = sm.Output()

# Add the soil to the output object
ecp_output.add_to_dict(sl)

# Add further info to the output object
ecp_output.name = "a single soil"
ecp_output.units = "N, kg, m, s"
ecp_output.comments = ""

# Export the output object to a json string, which can be saved to file
p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)

# load the json string using the sfsimodels.load_json method
objs = sm.loads_json(p_str, verbose=0)
loaded_soil = objs['soils'][1]
assert np.isclose(loaded_soil.g_mod, sl.g_mod)
print(sl.g_mod)


40000000.0

Define a soil profile


In [4]:
# Define another soil
sl_2 = sm.Soil()
sl_2.id = 2
sl_2.phi = 33.
sl_2.cohesion = 50000
sl_2.unit_dry_weight = 16000

# Define a soil profile
sp = sm.SoilProfile()
depth_1 = 0.0  # m (set to top of layer from surface)
depth_2 = 4.0  # m

sp.add_layer(depth_1, sl)
sp.add_layer(depth_2, sl_2)
sp.id = 0
sp.height = 12.0  # m (total height of profile)
sp.gwl = 5.0  # m (ground water level from surface)

Save and load a soil profile


In [5]:
# re-initiate the output object
ecp_output = sm.Output()

# add the soil profile, it automatically adds the associated soil objects
ecp_output.add_to_dict(sp)

# Add further info to the output object
ecp_output.name = "a soil profile"
ecp_output.units = "N, kg, m, s"
ecp_output.comments = ""

# Export the output object to a json string, which can be saved to file
p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"], indent=4)

# load the json string using the sfsimodels.load_json method
objs = sm.loads_json(p_str, verbose=0)
loaded_soil_profile = objs['soil_profiles'][0]
assert np.isclose(loaded_soil_profile.height, 12)
assert np.isclose(loaded_soil_profile.layer(1).g_mod, sl.g_mod)
print(loaded_soil_profile.height)


12.0

Extend a standard model

This example takes the soil model and adds new parameters and functionality.

Define the extension

In this example the Soil model is extended, however you can inherit from custom object and overwrite both the 'type' and 'base_type' parameters.


In [11]:
class SpecialSoil(sm.Soil):
    type = "special_soil"  # tag used to save a load
    
    def __init__(self):
        super(SpecialSoil, self).__init__()  # run the base model initialisation function
        
        self.cotton_content = None
        # list the extra save a load parameters that should be saved and loaded
        self._extra_class_inputs = ["cotton_content"] 
        self.inputs = self.inputs + self._extra_class_inputs
        
    def custom_func(self, value):  # Add additional functionality
        return value + self.cohesion

Save, load and use the extended soil model


In [19]:
s_soil = SpecialSoil()
s_soil.id = 1
s_soil.cohesion = 30000.0
print("Assert cotton_content initialises and is set to None: ", s_soil.cotton_content)
s_soil.cotton_content = 34
print("s_soil.cotton_content: ", s_soil.cotton_content)
print("custom_func(4): ", s_soil.custom_func(4))

# create an output object
ecp_output = sm.Output()
ecp_output.add_to_dict(s_soil)
# save to a string, use json.dump to save to file
p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"])

# load the json string using the sfsimodels.load_json method
# pass a dict of <base_type>-<type>: Object pairs in to load to a custom object
objs = sm.loads_json(p_str, verbose=0, custom={"soil-special_soil": SpecialSoil})
loaded_soil = objs['soils'][1]
assert isinstance(loaded_soil, SpecialSoil)
print("loaded_soil.cotton_content: ", loaded_soil.cotton_content)
print("loaded_soil.custom_func(5): ", s_soil.custom_func(5))


Assert cotton_content initialises and is set to None:  None
s_soil.cotton_content:  34
custom_func(4):  30004.0
loaded_soil.cotton_content:  34
loaded_soil.custom_func(5):  30005.0

Lazy alternative (just for saving)

If you just want to add some custom attributes to the output.


In [24]:
s2 = sm.Soil()
s2.id = 1
s2.special_prop = 3
# custom parameters are not saved by default
ecp_output = sm.Output()
ecp_output.add_to_dict(s2)
p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"])
objs = sm.loads_json(p_str, verbose=0)
loaded_soil = objs['soils'][1]
assert not hasattr(loaded_soil, "special_prop")

# to add to output without creating a new model
# just add directly to the inputs
s2.inputs += ["special_prop"]
ecp_output = sm.Output()
ecp_output.add_to_dict(s2)
p_str = json.dumps(ecp_output.to_dict(), skipkeys=["__repr__"])
objs = sm.loads_json(p_str, verbose=0)
loaded_soil = objs['soils'][1]
assert hasattr(loaded_soil, "special_prop")

In [ ]: