Commits

Panagiotis Mavrogiorgos committed 617155e Merge

Merged from default.

Comments (0)

Files changed (8)

 syntax: glob
 
 *.pyc
-*.wpr
+*.so
+*.wpr
 # Licence : GPL v3
 ##------------------------------------------------------------------------------
 
-from __future__ import division
-from __future__ import print_function
+from __future__ import division, print_function
 from copy import copy as ccopy
 from math import sqrt, exp
 from matplotlib.pyplot import (figure, axhline, axvline, title, legend,
 from concrete import ModelCode2010
 from lines import (line_slope, line_x, line_y, isascending, isdescending,
                    interpolation, calc_area, line_intersection)
-from bunch import Bunch
 
 class Bond(object):
     """ Abstract class"""
         tmax = fck / 3
         tr = friction_factor * tmax
 
+
+        #slip_mono = numpy.array([0, 0.005,  0.05,  0.2,   1,   2, 10, 15])
+        #bond_mono = numpy.array([0, 3.133, 6.267,  9.4, 9.4, 9.4,  5,  5])
+
         slip_mono = [0, 0.01,     0.1,  0.5,    1, 10.5, 15]
         bond_mono = [0,  fct, 2 * fct, tmax, tmax,   tr, tr]
 
         Only bond values are retured. No sign is assigned.
         """
         if n <= 10:
-            bond = (1 - sqrt((n//2) / 10)) * self.bond_mono
+            bond = (1 - sqrt((1 + n//2) / 10)) * self.bond_mono
         else:
             bond = (1 - sqrt(5 / 10)) * self.bond_mono
         return bond
 
     @staticmethod
     def initialize_db(db):
-        assert type(db) is Bunch, "db must be a bunch instance!!!"
 
-        db.slip_tot = []
-        db.bond_tot = []
-        db.smin_tot = []
-        db.tmin_tot = []
-        db.smax_tot = []
-        db.tmax_tot = []
+        db["slip_tot"] = []
+        db["bond_tot"] = []
+        db["smin_tot"] = []
+        db["tmin_tot"] = []
+        db["smax_tot"] = []
+        db["tmax_tot"] = []
 
     @staticmethod
     def store_to_db(db, slip, bond, smin, smax):
-        assert type(db) is Bunch, "db must be a bunch instance!!!"
 
-        db.slip_tot.append(ccopy(slip))
-        db.bond_tot.append(ccopy(bond))
-        db.smin_tot.append(ccopy(smin))
-        #db.tmin_tot.append(ccopy(tmin))
-        db.smax_tot.append(ccopy(smax))
-        #db.tmax_tot.append(ccopy(tmax))
+        db["slip_tot"].append(ccopy(slip))
+        db["bond_tot"].append(ccopy(bond))
+        db["smin_tot"].append(ccopy(smin))
+        #db["tmin_tot"].append(ccopy(tmin))
+        db["smax_tot"].append(ccopy(smax))
+        #db["tmax_tot"].append(ccopy(tmax))
 
 class TestTassios(Tassios):
     def __init__(self, fck, fctm):
         super(TestTassios, self).__init__(fck, fctm)
 
-        self.db = Bunch()
+        self.db = {}
 
     def plot_bond(self, numbers, x_label="Slip (mm)", y_label = "Bond Stress (MPa)"):
         """
         plot(-self.slip_mono, -self.bond_mono, label="Neg Mono")
 
         for j in numbers:
-            plot(self.db.slip_tot[j], self.db.bond_tot[j], label=str(j))
+            plot(self.db["slip_tot"][j], self.db["bond_tot"][j], label=str(j))
         axhline(y=0, color = "black")
         axvline(x=0, color = "black")
         ylabel(y_label)
         # get reduced monotonic curves and assign sign
         red_bond = -self._calc_reduced_monotonic_bond(d, g)
         red_slip = -self.slip_mono
+        tmin = interpolation(red_slip, red_bond, smin)
 
         # If during the reloading, slip sign hasn't changed (aka it is negative)
         # then depending on the bond value the first points of the bond-slip
         # curve are calculated.
         if s <= 0:
-            tmin = interpolation(red_slip, red_bond, smin)
             if t < 0:
-                slip = [line_x(self.slope1, s, t, 0), s, smin]
-                bond = [0, t, tmin]
+                slip = [line_x(self.slope1, s, t, 0), s]
+                bond = [0, t]
+                if smin < 0 and smin < s:
+                    slip.append(smin)
+                    bond.append(tmin)
             elif t == 0:
-                slip = [s, smin]
-                bond = [t, tmin]
+                slip = [s]
+                bond = [t]
+                if smin < 0 and smin < s:
+                    slip.append(smin)
+                    bond.append(tmin)
             else:
-                slip = [s, line_x(self.slope1, s, t, 0), smin]
-                bond = [t, 0, tmin]
+                slip = [s, line_x(self.slope1, s, t, 0)]
+                bond = [t, 0]
+                if smin < 0 and smin < s:
+                    slip.append(smin)
+                    bond.append(tmin)
         # If slipping has occured but it is very small (smax < 0.01mm),
         # then elastic behavior is assumed.
         elif s < self.slip_mono[1]:
         # get reduced monotonic curves and assign sign
         red_bond = self._calc_reduced_monotonic_bond(d, g)
         red_slip = self.slip_mono
+        tmax = interpolation(red_slip, red_bond, smax)
 
         # If during the unloading, slip sign hasn't changed (aka it is positive)
         # then depending on the bond value the first points of the bond-slip
         # curve are calculated.
         if s >= 0:
-            tmax = interpolation(red_slip, red_bond, smax)
             if t > 0:
-                slip = [line_x(self.slope1, s, t, 0), s, smax]
-                bond = [0, t, tmax]
+                slip = [line_x(self.slope1, s, t, 0), s]
+                bond = [0, t]
+                if smax > 0 and smax > s:
+                    slip.append(smax)
+                    bond.append(tmax)
             elif t == 0:
-                slip = [s, smax]
-                bond = [t, tmax]
+                slip = [s]
+                bond = [t]
+                if smax > 0 and smax > s:
+                    slip.append(smax)
+                    bond.append(tmax)
             else:
-                slip = [s, line_x(self.slope1, s, t, 0), smax]
-                bond = [t, 0, tmax]
+                slip = [s, line_x(self.slope1, s, t, 0)]
+                bond = [t, 0]
+                if smax > 0 and smax > s:
+                    slip.append(smax)
+                    bond.append(tmax)
+
         # If slipping has occured but it is very small (smin < 0.01)
         # then elastic behavior is assumed.
         elif s > -self.slip_mono[1]:
 
     @staticmethod
     def initialize_db(db):
-        assert type(db) is Bunch, "db must be a Bunch instance!!!"
 
-        db.smin_tot = []
-        db.tmin_tot = []
-        db.smax_tot = []
-        db.tmax_tot = []
-        db.slip_tot = []
-        db.bond_tot = []
+        db["smin_tot"]= []
+        db["tmin_tot"] = []
+        db["smax_tot"] = []
+        db["tmax_tot"] = []
+        db["slip_tot"] = []
+        db["bond_tot"] = []
 
-        db.E1_tot = []
-        db.E2_tot = []
-        db.Esum_tot = []
-        db.d_tot = []
-        db.g_tot = []
-        db.Ef_tot = []
-        db.Efsum_tot = []
-        db.df_tot = []
-        db.tf_tot = []
+        db["E1_tot"] = []
+        db["E2_tot"] = []
+        db["Esum_tot"] = []
+        db["d_tot"] = []
+        db["g_tot"] = []
+        db["Ef_tot"] = []
+        db["Efsum_tot"] = []
+        db["df_tot"] = []
+        db["tf_tot"] = []
 
     @staticmethod
     def store_to_db(db, slip, bond, smin, tmin, smax, tmax,
                       E1, E2, Esum, d, g, Ef, Efsum, df, tf):
 
-        assert type(db) is Bunch, "db must be a bunch instance!!!"
+        db["slip_tot"].append(ccopy(slip))
+        db["bond_tot"].append(ccopy(bond))
+        db["smin_tot"].append(ccopy(smin))
+        db["tmin_tot"].append(ccopy(tmin))
+        db["smax_tot"].append(ccopy(smax))
+        db["tmax_tot"].append(ccopy(tmax))
 
-        db.slip_tot.append(ccopy(slip))
-        db.bond_tot.append(ccopy(bond))
-        db.smin_tot.append(ccopy(smin))
-        db.tmin_tot.append(ccopy(tmin))
-        db.smax_tot.append(ccopy(smax))
-        db.tmax_tot.append(ccopy(tmax))
-
-        db.E1_tot.append(ccopy(E1))
-        db.E2_tot.append(ccopy(E2))
-        db.Esum_tot.append(ccopy(Esum))
-        db.d_tot.append(ccopy(d))
-        db.g_tot.append(ccopy(g))
-        db.Ef_tot.append(ccopy(Ef))
-        db.Efsum_tot.append(ccopy(Efsum))
-        db.df_tot.append(ccopy(df))
-        db.tf_tot.append(ccopy(tf))
+        db["E1_tot"].append(ccopy(E1))
+        db["E2_tot"].append(ccopy(E2))
+        db["Esum_tot"].append(ccopy(Esum))
+        db["d_tot"].append(ccopy(d))
+        db["g_tot"].append(ccopy(g))
+        db["Ef_tot"].append(ccopy(Ef))
+        db["Efsum_tot"].append(ccopy(Efsum))
+        db["df_tot"].append(ccopy(df))
+        db["tf_tot"].append(ccopy(tf))
 
 class TestEligenhausen(Eligenhausen):
     """Tests Eligenhausen's bond-slip law"""
         """"""
         super(TestEligenhausen, self).__init__(fck, fctm)
 
-        self.db = Bunch()
-
+        self.db = {}
 
     def plot_bond(self, numbers, x_label="Slip (mm)", y_label = "Bond Stress (MPa)"):
         """
         plot(-self.slip_mono, -self.bond_mono, label="Neg Mono")
 
         for j in numbers:
-            plot(self.db.slip_tot[j], self.db.bond_tot[j], label=str(j))
+            plot(self.db["slip_tot"][j], self.db["bond_tot"][j], label=str(j))
         axhline(y=0, color = "black")
         axvline(x=0, color = "black")
         ylabel(y_label)
 # Licence : GPL v3
 ##------------------------------------------------------------------------------
 
-from __future__ import division
-from __future__ import print_function
+from __future__ import division, print_function
 from math import sqrt, log
 import numpy
 from matplotlib.pyplot import (figure, axhline, axvline, title, legend,
 SIGNIFICANT_SLIP = 0.001
 ## The length of the infinitestimal element in meters. 1/100 is one cm.
 ## For development 1/100 is suggested. For final analysis 1/1000.
-INFINITESIMAL_LENGTH = 1/100
+INFINITESIMAL_LENGTH = 1/10
 ## the length (in m) where we suppose an omoiothetic decrease of the bond-slip law.
 LENGTH_OF_OMOIOTHECY = 0.05
 ## The name of the folder where the data of the analysis are going to be pickled
 DATA_FOLDER = "data"
 ## If True then omoiothecy length is taken under consideration for the front of the specimen.
-OMOIOTHECY_FRONT = True
-#OMOIOTHECY_FRONT = False
+#OMOIOTHECY_FRONT = True
+OMOIOTHECY_FRONT = False
 ## If True then omoiothecy length is taken under consideration for the back of the specimen.
 #OMOIOTHECY_BACK = True
 OMOIOTHECY_BACK = False
 import operator
 import numpy
 
-from lines_cython3 import interpolation
-
 def calc_area(a, b):
     """
     Calculates the area of an irregular convex polygon. The points must be
         pred = item
     return True
 
-def interpolation(xp, yp, x0, y0 = 999999999):
+def interpolation(xp, yp, x0):
     """
     Linear interpolation of a given abscissa for a given curve.
 
     function. E.g. interpolation(yp, xp, y0) where y and x are lists
     containing the coordinates of the points defining the curve.
 
-
     * x0     : the given abscissa.
     * xp : the abscissas of the points describing the curve.
     * yp : the ordinates of the points describing the curve.
     Output
 
     Tests
+
     -----
     >>> import numpy as np
 
     """
     # Calculate the number of points that define the curve.
     np = len(xp)
+    y0 = 999999999
 
     # check if the points are in ascending order.
     if xp[0] < xp[1]:
         ## If x0 > x_max interpolate between the last two points
         if x0 > xp[np-1]:
-            y0 = (x0 - xp[np-2]) *\
-               (yp[np-1] - yp[np-2]) /\
-               (xp[np-1] - xp[np-2]) + yp[np-2]
+            y0 = (x0 - xp[np-2]) * (yp[np-1] - yp[np-2]) / (xp[np-1] - xp[np-2]) + yp[np-2]
         else:
             for i in range(1, np, 1):
                 if x0 <= xp[i]:
-                    y0 = (x0 - xp[i-1]) *\
-                       (yp[i] - yp[i-1]) /\
-                       (xp[i] - xp[i-1]) + yp[i-1]
+                    y0 = (x0 - xp[i-1]) * (yp[i] - yp[i-1]) / (xp[i] - xp[i-1]) + yp[i-1]
                     break
 
     # check if the points are in descending order.
-from __future__ import division
-from __future__ import print_function
+from __future__ import division, print_function
 
-from matplotlib.pyplot import (figure, axhline, axvline, title, legend,
-                               show, xlabel, ylabel, grid, plot,
-                               close as closefig)
+import matplotlib.pyplot as plt
+
 import numpy
 from bunch import Bunch
+import os.path
+
+from matplotlib.backends.backend_pdf import PdfPages
+
+from constants import INFINITESIMAL_LENGTH
+
+
+def plot_s(db):
+    """
+    slips is a list containing the `s` arrays (one for each half-circle).
+    """
+    if type(db) is Bunch:
+        slips = db.s_tot
+    elif type(db) is dict:
+        slips = db["s_tot"]
+    else:
+        raise TypeError, "wrong type"
+
+    x_axis = numpy.arange(len(slips[0]), dtype = int) * int(INFINITESIMAL_LENGTH * 1000)
+
+    plt.figure()
+    plt.title("Distribution of slippage")
+    for i, slip in enumerate(slips):
+        plt.plot(x_axis, slip, label = "Cycle %d" % i)
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    plt.ylabel("s (mm)")
+    plt.xlabel("L (mm)")
+    plt.legend()
+    plt.grid(True)
+
+    plt.show()
+
+def plot_Ss(db):
+    """
+    stresses is a list containing the `Ss` arrays (one for each half-circle).
+    """
+    if type(db) is Bunch:
+        stresses = db.Ss_tot
+    elif type(db) is dict:
+        stresses = db["Ss_tot"]
+    else:
+        raise TypeError, "wrong type"
+
+    x_axis = numpy.arange(len(stresses[0]), dtype = int) * int(INFINITESIMAL_LENGTH * 1000)
+
+    plt.figure()
+    plt.title("Distribution of Steel's stresses")
+    for i, stress in enumerate(stresses):
+        plt.plot(x_axis, stress, label = "Cycle %d" % i)
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    plt.ylabel("Ss (MPa)")
+    plt.xlabel("L (mm)")
+    plt.legend()
+    plt.grid(True)
+
+    plt.show()
+
+def plot_t(db):
+    """
+    stresses is a list containing the `Ss` arrays (one for each half-circle).
+    """
+    if type(db) is Bunch:
+        stresses = db.t_tot
+    elif type(db) is dict:
+        stresses = db["t_tot"]
+    else:
+        raise TypeError, "wrong type"
+
+    x_axis = numpy.arange(len(stresses[0]), dtype = int) * int(INFINITESIMAL_LENGTH * 1000)
+
+    plt.figure()
+    plt.title("Distribution of Bond's stresses")
+    for i, stress in enumerate(stresses):
+        plt.plot(x_axis, stress, label = "Cycle %d" % i)
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    plt.ylabel("T (MPa)")
+    plt.xlabel("L (mm)")
+    plt.legend()
+    plt.grid(True)
+
+    plt.show()
+
+def plot_tred(db):
+    """
+    stresses is a list containing the `Ss` arrays (one for each half-circle).
+    """
+    if type(db) is Bunch:
+        stresses = db.tred_tot
+    elif type(db) is dict:
+        stresses = db["tred_tot"]
+    else:
+        raise TypeError, "wrong type"
+
+    x_axis = numpy.arange(len(stresses[0]), dtype = int) * int(INFINITESIMAL_LENGTH * 1000)
+
+    plt.figure()
+    plt.title("Distribution of Bond's stresses")
+    for i, stress in enumerate(stresses):
+        plt.plot(x_axis, stress, label = "Cycle %d" % i)
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    plt.ylabel("T (MPa)")
+    plt.xlabel("L (mm)")
+    plt.legend()
+    plt.grid(True)
+
+    plt.show()
+
+def plot_ttred(db):
+    """
+    stresses is a list containing the `Ss` arrays (one for each half-circle).
+    """
+    if type(db) is Bunch:
+        stresses = db.t_tot
+        reduced = db.tred_tot
+    elif type(db) is dict:
+        stresses = db["t_tot"]
+        reduced = db["tred_tot"]
+    else:
+        raise TypeError, "wrong type"
+
+    x_axis = numpy.arange(len(stresses[0]), dtype = int) * int(INFINITESIMAL_LENGTH * 1000)
+
+    plt.figure()
+    plt.title("Distribution of Bond's stresses")
+    for i, stress in enumerate(stresses):
+        plt.plot(x_axis, stress, label = "t %d" % i)
+        plt.plot(x_axis, reduced[i], label = "tred %d" % i)
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    plt.ylabel("T (MPa)")
+    plt.xlabel("L (mm)")
+    plt.legend()
+    plt.grid(True)
+
+    plt.show()
+
+def plot_Sc(db):
+    """
+    stresses is a list containing the `Sc` arrays (one for each half-circle).
+    """
+    if type(db) is Bunch:
+        stresses = db.Sc_tot
+    elif type(db) is dict:
+        stresses = db["Sc_tot"]
+    else:
+        raise TypeError, "wrong type"
+
+    x_axis = numpy.arange(len(stresses[0]), dtype = int) * int(INFINITESIMAL_LENGTH * 1000)
+
+    plt.figure()
+    plt.title("Distribution of Concrete's stresses")
+    for i, stress in enumerate(stresses):
+        plt.plot(x_axis, stress, label = "Cycle %d" % i)
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    plt.ylabel("Sc (MPa)")
+    plt.xlabel("L (mm)")
+    plt.legend()
+    plt.grid(True)
+
+    plt.show()
 
 def plot_cycle(db, i, x_label="L (mm)"):
     """
     np = len(db.s_tot[0])
     axon = numpy.arange(np)
 
-    figure(1)
-    title("Distribution of Steel Stresses")
-    plot(axon, db.Ss_tot[i])
-    axhline(y=0, color = "black")
-    axvline(x=0, color = "black")
-    ylabel("Ss (MPa)")
-    xlabel(x_label)
-    grid(True)
+    plt.figure(1)
+    plt.title("Distribution of Steel Stresses")
+    plt.plot(axon, db.Ss_tot[i])
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    plt.xticks(range(0, np, 10))
+    plt.ylabel("Ss (MPa)")
+    plt.xlabel(x_label)
+    plt.grid(True)
 
-    figure(2)
-    title("Distribution of Concrete Stresses")
-    plot(axon, db.Sc_tot[i])
-    axhline(y=0, color = "black")
-    axvline(x=0, color = "black")
-    ylabel("Sc (MPa)")
-    xlabel(x_label)
-    grid(True)
+    plt.figure(2)
+    plt.title("Distribution of Concrete Stresses")
+    plt.plot(axon, db.Sc_tot[i])
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    plt.xticks(range(0, np, 10))
+    plt.ylabel("Sc (MPa)")
+    plt.xlabel(x_label)
+    plt.grid(True)
 
-    figure(3)
-    title("Distribution of Bond Stresses")
-    plot(axon, db.t_tot[i])
-    plot(axon, db.tred_tot[i])
-    axhline(y=0, color = "black")
-    axvline(x=0, color = "black")
-    ylabel("bond (MPa)")
-    xlabel(x_label)
-    grid(True)
+    plt.figure(3)
+    plt.title("Distribution of Bond Stresses")
+    plt.plot(axon, db.t_tot[i])
+    plt.plot(axon, db.tred_tot[i])
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    plt.xticks(range(0, np, 10))
+    plt.ylabel("bond (MPa)")
+    plt.xlabel(x_label)
+    plt.grid(True)
 
-    figure(4)
-    title("Distribution of Steel Strains")
-    plot(axon, db.es_tot[i])
-    axhline(y=0, color = "black")
-    axvline(x=0, color = "black")
-    ylabel("es (o/oo)")
-    xlabel(x_label)
-    grid(True)
+    #plt.figure(4)
+    #plt.title("Distribution of Steel Strains")
+    #plt.plot(axon, db.es_tot[i])
+    #plt.axhline(y=0, color = "black")
+    #plt.axvline(x=0, color = "black")
+    #plt.xticks(range(0, np, 10))
+    #plt.ylabel("es (o/oo)")
+    #plt.xlabel(x_label)
+    #plt.grid(True)
 
-    figure(5)
-    title("Distribution of Concrete Strains")
-    plot(axon, db.ec_tot[i])
-    axhline(y=0, color = "black")
-    axvline(x=0, color = "black")
-    ylabel("ec (0/00)")
-    xlabel(x_label)
-    grid(True)
+    #plt.figure(5)
+    #plt.title("Distribution of Concrete Strains")
+    #plt.plot(axon, db.ec_tot[i])
+    #plt.axhline(y=0, color = "black")
+    #plt.axvline(x=0, color = "black")
+    #plt.xticks(range(0, np, 10))
+    #plt.ylabel("ec (0/00)")
+    #plt.xlabel(x_label)
+    #plt.grid(True)
 
-    figure(6)
-    title("Distribution of slippage")
-    plot(axon, db.s_tot[i])
-    axhline(y=0, color = "black")
-    axvline(x=0, color = "black")
-    ylabel("slip (mm)")
-    xlabel(x_label)
-    grid(True)
+    plt.figure(6)
+    plt.title("Distribution of slippage")
+    plt.plot(axon, db.s_tot[i])
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    plt.xticks(range(0, np, 10))
+    plt.ylabel("slip (mm)")
+    plt.xlabel(x_label)
+    plt.grid(True)
 
-    #figure(7)
-    #title("Distribution of slippage's change")
-    #plot(axon[:-1], db.s_tot[i][:-1] - db.s_tot[i][1:])
-    #axhline(y=0, color = "black")
-    #axvline(x=0, color = "black")
-    #ylabel("slip (mm)")
-    #xlabel(x_label)
-    #grid(True)
-    show()
+    #plt.figure(7)
+    #plt.title("Distribution of slippage's change")
+    #plt.plot(axon[:-1], db.s_tot[i][:-1] - db.s_tot[i][1:])
+    #plt.axhline(y=0, color = "black")
+    #plt.axvline(x=0, color = "black")
+    #plt.xticks(range(0, np, 10))
+    #plt.ylabel("slip (mm)")
+    #plt.xlabel(x_label)
+    #plt.grid(True)
+    plt.show()
 
 def plot_data(db, data, x_label="L (mm)"):
     """
         y_label = "t (MPa)"
         ttl = "Distribution of steel's stresses reduction"
 
-    figure(0)
-    title(ttl)
+    plt.figure(0)
+    plt.title(ttl)
     for i in range(len(data)):
-        plot(axon, data[i], label=str(i))
-    axhline(y=0, color = "black")
-    axvline(x=0, color = "black")
-    ylabel(y_label)
-    xlabel(x_label)
-    legend()
-    grid(True)
+        plt.plot(axon, data[i], label=str(i))
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    plt.ylabel(y_label)
+    plt.xlabel(x_label)
+    plt.legend()
+    plt.grid(True)
 
-    show()
+    plt.show()
 
 def plot_bond(db, i, x_label="Slip (mm)", y_label = "Bond Stress (MPa)"):
     """
     """
     assert type(db) is Bunch, "db must be a Bunch instance!!!"
 
-    figure(0)
-    title("Node's {0} bond-slip law".format(i))
-    plot(-db.slip_tot[0][0], -db.bond_tot[0][0], label="Neg Mono")
+    plt.figure(0)
+    plt.title("Node's {0} bond-slip law".format(i))
+    plt.plot(-db.slip_tot[0][0], -db.bond_tot[0][0], label="Neg Mono")
     for j in range(len(db.slip_tot)):
-        plot(db.slip_tot[j][i], db.bond_tot[j][i], label=str(j))
-    axhline(y=0, color = "black")
-    axvline(x=0, color = "black")
-    ylabel(y_label)
-    xlabel(x_label)
-    legend()
-    grid(True)
+        plt.plot(db.slip_tot[j][i], db.bond_tot[j][i], label=str(j))
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    plt.ylabel(y_label)
+    plt.xlabel(x_label)
+    plt.legend()
+    plt.grid(True)
 
-    show()
+    plt.show()
+
+def plot_slip_distribution(titlos, *args):
+    """
+    args are tuples. arg[0] is a list, arg[1] is the plt.legend label
+    """
+    np = len(args[0][0])
+    axon = numpy.arange(np)
+
+    plt.figure(0)
+    plt.title(titlos)
+    for arg in args:
+        plt.plot(axon, arg[0], label=arg[1])
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    plt.xticks(range(0, np, 10))
+    plt.ylabel("Slip (mm)")
+    plt.xlabel("L (mm)")
+    plt.legend()
+    plt.grid(True)
+
+    plt.show()
+
+def plot_general(path, titlos, x_label, y_label, limits, *args, **kwargs):
+    """
+    args are tuples. arg[0] is a list, arg[1] is the plt.legend label
+    """
+    assert len(args) <= 4, "Arguments must be lower than 4."
+    if len(kwargs) == 1:
+        show = True
+    else:
+        show = False
+
+    styles = ['-', ':', '-.', '--']
+
+    pp = PdfPages(os.path.join(path, titlos + ".pdf"))
+
+    plt.figure()
+    plt.title(titlos)
+
+    for i, arg in enumerate(args):
+        np = len(arg[0]) - 1
+        axon = numpy.arange(np)
+        plt.plot(axon, arg[0], linestyle = styles[i], label=arg[1])
+
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    plt.axis(limits)
+    #plt.xticks(range(0, np, int(1 / INFINITESIMAL_LENGTH / 10)))
+    plt.ylabel(y_label)
+    plt.xlabel(x_label)
+    plt.legend()
+    plt.grid(True)
+
+    pp.savefig()
+    if show:
+        plt.show()
+    pp.close()
+
+def plot_omoiothecy_length(path, show = True):
+
+    l_om = range(0, 110, 10)
+    s1 = [0.4512068,0.4678472,0.4828719,0.4977986,0.5126274,0.5273585,0.5419919,0.5565278,0.5709661,0.5853071,0.5995507]
+
+    s2 = [0.6362647,0.6529219,0.6679943,0.6829997,0.6979381,0.7128096,0.7276142,0.7423519,0.7570229,0.7716271,0.7861646]
+
+
+    lb1 = [397,403,408,413,418,423,428,433,438,443,448]
+
+
+    lb2 = [481,486,491,496,501,506,511,516,521,526,531]
+
+    k2 = [1.41,1.40,1.38,1.37,1.36,1.35,1.34,1.33,1.33,1.32,1.31]
+
+    pp = PdfPages(os.path.join(path, "Omoiothecy_slip.pdf"))
+
+    fig = plt.figure()
+    plt.title("Omoiothecy Front - Slip")
+    ax1 = fig.add_subplot(111)
+    ax1.plot(l_om, s1, label="s1")
+    ax1.plot(l_om, s2, label="s3")
+    plt.legend(loc = "upper left")
+    plt.figlegend(l_om, ("s1", "s3", "k2"), loc = "lower right")
+    ax2 = ax1.twinx()
+    ax2.plot(l_om, k2, 'm', label="k2")
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    #plt.xticks(range(0, np, 10))
+    ax1.set_ylabel("slip (mm)")
+    ax2.set_ylabel("k2")
+    plt.xlabel("L_om (mm)")
+    plt.grid(True)
+    plt.legend(loc = "lower right")
+    pp.savefig()
+    if show:
+        plt.show()
+    pp.close()
+
+    pp = PdfPages(os.path.join(path, "Omoiothecy_lb.pdf"))
+
+    plt.figure()
+    plt.title("Omoiothecy Front - Slip")
+    plt.plot(l_om, lb1, label="lb1")
+    plt.plot(l_om, lb2, label="lb2")
+    plt.axhline(y=0, color = "black")
+    plt.axvline(x=0, color = "black")
+    #plt.xticks(range(0, np, 10))
+    plt.ylabel("lb (mm)")
+    plt.xlabel("L_om (mm)")
+    plt.grid(True)
+    plt.legend(loc = "best")
+    pp.savefig()
+    if show:
+        plt.show()
+    pp.close()
+
+
+#def plot_infinitesimal_length():
+    #l_om = range(0, 110, 10)
+    #s1 = [0.4484571, 0.4788006, 0.4938716, 0.5087517, 0.523627, 0.5383115,
+          #0.5529914, 0.5674806, 0.5819654, 0.5962598, 0.6105499]
+
+
+    #s2 = [0.6339749, 0.6643209, 0.6794315, 0.6943985, 0.7093751, 0.7242083,
+          #0.7390511, 0.7537506, 0.7684598, 0.7830256, 0.7976014]
+
+
+    #lb1 = [390, 400, 410, 410, 420, 420, 430, 430, 440, 440, 450]
+
+    #lb2 = [470, 480, 490, 490, 500, 500, 510, 510, 520, 520, 530]
+
+    #k2 = [1.41, 1.39, 1.38, 1.36, 1.35, 1.35, 1.34, 1.33, 1.32, 1.31, 1.31]
+
+    #pp = PdfPages(os.path.join(path, "Omoiothecy_slip.pdf"))
+
+    #fig = plt.figure()
+    #plt.title("Omoiothecy Front - Slip")
+    #ax1 = fig.add_subplot(111)
+    #ax1.plot(l_om, s1, label="s1")
+    #ax1.plot(l_om, s2, label="s3")
+
+    #ax2 = ax1.twinx()
+    #ax2.plot(l_om, k2, 'm', label="k2")
+    #plt.axhline(y=0, color = "black")
+    #plt.axvline(x=0, color = "black")
+    ##plt.xticks(range(0, np, 10))
+    #ax1.set_ylabel("slip (mm)")
+    #ax2.set_ylabel("k2")
+    #plt.xlabel("L_om (mm)")
+    #plt.grid(True)
+
+    #pp.savefig()
+    #if show:
+        #plt.show()
+    #pp.close()
+
+    #pp = PdfPages(os.path.join(path, "Omoiothecy_lb.pdf"))
+
+    #plt.figure()
+    #plt.title("Omoiothecy Front - Slip")
+    #plt.plot(l_om, lb1)
+    #plt.plot(l_om, lb2)
+    #plt.axhline(y=0, color = "black")
+    #plt.axvline(x=0, color = "black")
+    ##plt.xticks(range(0, np, 10))
+    #plt.ylabel("lb (mm)")
+    #plt.xlabel("L_om (mm)")
+    #plt.grid(True)
+
+    #pp.savefig()
+    #if show:
+        #plt.show()
+    #pp.close()

pull_out_tests.py

 # Licence : GPL v3
 ##------------------------------------------------------------------------------
 
-from __future__ import division
-from __future__ import print_function
+from __future__ import division, print_function
 from copy import copy as ccopy
 from math import pi
 
 from scipy.optimize import brentq
-from bunch import Bunch
 from lines import (line_slope, line_x, line_y, isascending, isdescending,
                    interpolation, calc_area, line_intersection)
 from concrete import ModelCode2010
                        TOLERANCE, MAX_ITERATIONS)
 #from plot import *
 
-
 class Data(object):
     def __init__(self, L, Ds, Dc):
         super(Data, self).__init__()
         self.tmax = [0.] * np
 
         # Database for holding test history
-        self.db = Bunch()
+        self.db = {}
 
         # Omoiothecy array
         self._yield_reduction_omoiothecy()
         Appends the calculated data to the containers.
         Should be called, after each (re)loading/unloading half-cycle.
         """
-        assert type(db) is Bunch, "db must be a Bunch instance!!!"
 
-        db.Ss_tot.append(ccopy(Ss))
-        db.Sc_tot.append(ccopy(Sc))
-        db.es_tot.append(ccopy(es))
-        db.ec_tot.append(ccopy(ec))
-        db.t_tot.append(ccopy(t))
-        db.tred_tot.append(ccopy(tred))
-        db.s_tot.append(ccopy(s))
-        db.DSs_tot.append(ccopy(DSs))
+        db["Ss_tot"].append(ccopy(Ss))
+        db["Ss_tot"].append(ccopy(Ss))
+        db["Sc_tot"].append(ccopy(Sc))
+        db["es_tot"].append(ccopy(es))
+        db["ec_tot"].append(ccopy(ec))
+        db["t_tot"].append(ccopy(t))
+        db["tred_tot"].append(ccopy(tred))
+        db["s_tot"].append(ccopy(s))
+        db["DSs_tot"].append(ccopy(DSs))
 
     @staticmethod
     def db_initialize_data(db):
-        assert type(db) is Bunch, "db must be a Bunch instance!!!"
-
         # Lists holding history of the loading history.
-        db.Ss_tot   = []
-        db.Sc_tot   = []
-        db.es_tot   = []
-        db.ec_tot   = []
-        db.t_tot    = []
-        db.tred_tot = []
-        db.s_tot    = []
-        db.DSs_tot  = []
+        db["Ss_tot"] = []
+        db["Ss_tot"] = []
+        db["Sc_tot"] = []
+        db["es_tot"] = []
+        db["ec_tot"] = []
+        db["t_tot"] = []
+        db["tred_tot"] = []
+        db["s_tot"] = []
+        db["DSs_tot"] = []
 
 class PullOutClassic(Data):
     def __init__(self, fck, fyk, L, Ds, Dc):
         slip = self.slip
         bond = self.bond
 
+        ey = self.S.ey
+        eu = self.S.eu
+
         for i in range(1, np):
             Ss[i] = Ss[i-1] - DSs[i-1]
             Sc[i] = Sc[i-1] - (Ss[i] - Ss[i-1]) * rho
             ec[i] = self.C.get_strain(Sc[i])
             s[i] = s[i-1] - ((es[i-1] + es[i]) - (ec[i-1] + ec[i])) * temp1
             t[i] = interpolation(slip[i], bond[i], s[i])
-            tred[i] = t[i] * self.S.yield_reduction_CEB(es[i]) * Ko[i]
+            Ky = 1
+            if es[i] > ey and es[i] < eu:
+                Ky = self.S.yield_reduction_CEB(es[i])
+            else:
+                Ky = 1
+            tred[i] = t[i] * Ky * Ko[i]
             DSs[i] = tred[i] * temp2
 
         self.Ss = Ss
 
     @staticmethod
     def print_summary(db):
-        for i in range(len(db.s_tot)):
-            print("N = %d \t\t slip = % .2f (mm)" %(i, db.s_tot[i][0]))
+        for i in range(len(db["s_tot"])):
+            print("N = %d \t\t slip = % .2f (mm)" %(i, db["s_tot"][i][0]))
 
         print()
-        print("k2 = %.2f" % abs(db.s_tot[3][0] / db.s_tot[1][0]))
+        print("k2 = %.2f" % abs(db["s_tot"][3][0] / db["s_tot"][1][0]))
 
 
 class PullOutClassicTassios(PullOutClassic):
         Appends the new consitutive laws to the containers.
         must be called, after each change of sign.
         """
-        assert type(db) is Bunch, "db must be a Bunch instance!!!"
 
         self.B.store_to_db(db, self.slip, self.bond,
                                 self.smin, self.smax)
         self.pull_load(P)
         self.store_laws_and_data(self.db)
 
-        self.print_summary(self.db)
+        #self.print_summary(self.db)
         1
 
     def run_recycling_negative(self, P, times):
         1
 
 class PullOutExternalTassios(PullOutClassicTassios):
-    def __init__(self, fck, fyk, L, Ds, Dc, lb):
+    def __init__(self, fck, fyk, L, Ds, Dc, lext):
         super(PullOutExternalTassios, self).__init__(fck, fyk, L, Ds, Dc)
 
-        assert L >= lb, "L must be greater than lb!!!"
+        assert L >= lext, "L must be greater than lext!!!"
 
-        self.lb = lb / 1000
+        self.lext = lext / 1000
         self.tex = [0.] * self.np
 
         #self.C.get_concrete_strain = self.get_concrete_strain
 
-    def _calc_external_stresses(self, P, lb):
+    def _calc_external_stresses(self, P, lext):
 
-        te0 = (3/8) * (self.Ds**2 / self.Dc) * (self.S.fy / lb) * (P / self.S.fy)
+        te0 = (3/8) * (self.Ds**2 / self.Dc) * (self.S.fy / lext) * (P / self.S.fy)
 
-        lp = int(self.lb / self.Dx) + 1
+        lp = int(self.lext / self.Dx) + 1
 
         for i in range(self.np):
             if i < lp:
         For a given boundary condition at the loaded end,
         calculates the specimen, node by node.
         """
-        for i in xrange(1, self.np):
-            self.Ss[i] = self.Ss[i-1] - self.DSs[i-1]
-            self.Sc[i] = (self.Sc[i-1] - (self.Ss[i] - self.Ss[i-1]) * self.rho -
-                          self.tex[i] * 4 * self.Dx / self.Dc)
-            self.es[i] = self.S.get_strain(self.strain[i], self.stress[i],
-                                                     self.Ss[i])
-            self.ec[i] = self.C.get_strain(self.Sc[i])
-            self.s[i] = (self.s[i-1] - ((self.es[i-1] + self.es[i]) -
-                                        (self.ec[i-1] + self.ec[i])) *
-                                        self.Dx * 1000 / 2)
+        np = self.np
+        Ss = self.Ss
+        Sc = self.Sc
+        es = self.es
+        ec = self.ec
+        s = self.s
+        t = self.t
+        tred = self.tred
+        DSs = self.DSs
+        Ko = self.Ko
+        tex = self.tex
+
+        rho = self.rho
+        Dx = self.Dx
+        Ds = self.Ds
+        Dc = self.Dc
+        temp1 = Dx * 1000 / 2
+        temp2 = 4 * Dx / Ds
+        temp3 = 4 * Dx / Dc
+
+        stress = self.stress
+        strain = self.strain
+        slip = self.slip
+        bond = self.bond
+
+        ey = self.S.ey
+        eu = self.S.eu
+
+        for i in xrange(1, np):
+            Ss[i] = Ss[i-1] - DSs[i-1]
+            self.Sc[i] = (Sc[i-1] - (Ss[i] - Ss[i-1]) * rho -
+                          tex[i] * temp3)
+            es[i] = interpolation(stress[i], strain[i], Ss[i])
+            ec[i] = self.C.get_strain(Sc[i])
+            s[i] = s[i-1] - ((es[i-1] + es[i]) - (ec[i-1] + ec[i])) * temp1
             self.t[i] = self.B.get_bond(self.slip[i], self.bond[i], self.s[i])
-            Ky = self.S.yield_reduction_CEB(self.es[i])
-            self.tred[i] = self.t[i] * Ky * self.Ko[i]
-            self.DSs[i] = 4 * self.tred[i] * self.Dx / self.Ds
+            Ky = 1
+            if es[i] > ey and es[i] < eu:
+                Ky = self.S.yield_reduction_CEB(es[i])
+            else:
+                Ky = 1
+            tred[i] = t[i] * Ky * Ko[i]
+            tred[i] = t[i] * Ky * Ko[i]
+            DSs[i] = tred[i] * temp2
+
+        self.Ss = Ss
+        self.Sc = Sc
+        self.es = es
+        self.ec = ec
+        self.t = t
+        self.tred = tred
+        self.s = s
+        self.DSs = DSs
 
     def run(self, P):
 
         self.define_monotonic_laws(1)
-        self._calc_external_stresses(0, self.lb)
+        self._calc_external_stresses(0, self.lext)
         self.pull_load(0)
         self.store_laws_and_data(self.db)
 
-        self._calc_external_stresses(P, self.lb)
+        self._calc_external_stresses(P, self.lext)
         self.pull_load(P)
         self.store_laws_and_data(self.db)
 
     def run_recycling_positive(self, P, times):
 
         self.define_monotonic_laws(1)
-        self._calc_external_stresses(0, self.lb)
+        self._calc_external_stresses(0, self.lext)
         self.pull_load(0)
         self.store_laws_and_data(self.db)
 
         for i in range(times):
-            self._calc_external_stresses(P, self.lb)
+            self._calc_external_stresses(P, self.lext)
             self.pull_load(P)
             self.store_laws_and_data(self.db)
             self.define_unloading_laws()
-            self._calc_external_stresses(0, self.lb)
+            self._calc_external_stresses(0, self.lext)
             self.pull_unload(P)
-            self._calc_external_stresses(-P, self.lb)
+            self._calc_external_stresses(-P, self.lext)
             self.push_load(P)
             self.store_laws_and_data(self.db)
             self.define_reloading_laws()
-            self._calc_external_stresses(0, self.lb)
+            self._calc_external_stresses(0, self.lext)
             self.push_unload(P)
 
         # finish with a pull-out
-        self._calc_external_stresses(P, self.lb)
+        self._calc_external_stresses(P, self.lext)
         self.pull_load(P)
         self.store_laws_and_data(self.db)
 
-        self.print_summary(self.db)
+        #self.print_summary(self.db)
         1
 
 class PullOutClassicEligenhausen(PullOutClassic):
         Appends the new consitutive laws to the containers.
         must be called, after each change of sign.
         """
-        assert type(db) is Bunch, "db must be a Bunch instance!!!"
-
         self.B.store_to_db(
             db, self.slip, self.bond,
             self.smin, self.tmin, self.smax, self.tmax,
 # Licence : GPL v3
 ##------------------------------------------------------------------------------
 
-from __future__ import division
-from __future__ import print_function
+from __future__ import division, print_function
 from math import exp, sqrt
 from copy import deepcopy as ccopy
 import numpy
                                show, xlabel, ylabel, grid, plot,
                                close as closefig)
 from lines import interpolation, line_intersection, line_y, line_x
-from bunch import Bunch
 import unittest
 
 class Steel(object):
     """ An abstract Steel class."""
-    def __init__(self, fy, Es = 200000):
+    def __init__(self, fy, Es = 210000):
         super(Steel, self).__init__()
 
         self.fy = fy
         show()
 
     def initialize_db(self, db):
-        assert type(db) is Bunch, "db must be a Bunch instance!!!"
 
-        db.strain_tot = []
-        db.stress_tot = []
+        db["strain_tot"] = []
+        db["stress_tot"] = []
 
     def store_to_db(self, db, strain, stress):
-        assert type(db) is Bunch, "db must be a Bunch instance."
-
-        db.strain_tot.append(ccopy(strain))
-        db.stress_tot.append(ccopy(stress))
+        db["strain_tot"].append(ccopy(strain))
+        db["stress_tot"].append(ccopy(stress))
 
 class B500C(Steel):
     def __init__(self, fy, Es = 200000):
     def __init__(self, fy):
         super(TestB500C, self).__init__(fy)
 
-        self.db = Bunch()
+        self.db = {}
 
         self.initialize_db(self.db)