コード例 #1
0
ファイル: code_gen_factory.py プロジェクト: simvisage/bmcs
class CodeGenCompiledFactory(HasStrictTraits):
    '''Depending on the sampling type return .
    '''
    mapping_table = Dict(value = {'TGrid' : CodeGenCompiledTGrid,
                                  'PGrid' : CodeGenCompiledPGrid,
                                  'MCS' : CodeGenCompiledIrregular,
                                  'LHS' : CodeGenCompiledIrregular
                                  })
コード例 #2
0
ファイル: hp_shell.py プロジェクト: rosoba/simvisage
class HPShell(HasTraits):
    '''Geometry definition of a hyperbolic parabolid shell.
    '''

    #-----------------------------------------------------------------
    # geometric parameters of the shell
    #-----------------------------------------------------------------

    # dimensions of the shell for one quarter of mush_roof
    #
    length_xy_quarter = Float(3.5, input=True)  # [m]
    length_z = Float(0.927, input=True)  # [m]

    # corresponds to the delta in the geometry .obj-file with name '4x4m' as a cut off
    #
    delta_h = Float(0.865, input=True)  # [m]

    # scale factors for geometric dimensions
    # NOTE: parameters can be scaled separately, i.e. scaling of 'delta_h' (inclination of the shell)
    # does not effect the scaling of the thickness
    #
    scalefactor_delta_h = Float(1.00, input=True)  # [-]
    scalefactor_length_xy = Float(1.00, input=True)  # [-]

    # thickness of the shell
    # NOTE: only used by the option 'const_reinf_layer'
    #
    t_shell = Float(0.06, input=True)  # [m]

    width_top_col = Float(0.45, input=True)  # [m]

    # factor shifting the z coordinates at the middle nodes of the edges upwards
    # in order to include the effect of imperfection in the formwork
    z_imperfection_factor = Float(0.0)

    #-----------------------------------------------------------------
    # specify the relation of the total structure (in the 'mushroof'-model)
    # with respect to a quarter of one shell defined in 'HPShell'
    #-----------------------------------------------------------------

    # @todo: "four" is not supported by "n_elems_xy_dict"in mushroff_model
    mushroof_part = Enum('one', 'quarter', 'four', input=True)

    # 'scale_size' parameter is used as scale factor for different mushroof parts
    # Defines the proportion between the length of the total model
    # with respect to the length of a quarter shell as the
    # basic substructure of which the model consists of.
    # @todo: add "depends_on" or remove "cached_property"
    # @todo: move to class definition of "mushroof_model" not in "HPShell"
    #        (also see there "n_elems_dict" with implicit "scale_factor")
    #
    scale_size = Property(Float, depends_on='mushroof_part')

    @cached_property
    def _get_scale_size(self):
        scale_dict = {'quarter': 1.0, 'one': 2.0, 'four': 4.0}
        return scale_dict[self.mushroof_part]

    # origin of the shell
    #
    X0 = Array(float, input=True)

    def _X0_default(self):
        return array([0., 0., 0.])

    #-----------------------------------------------------------------
    # discretisation
    #-----------------------------------------------------------------

    # number of element used for the discretisation ( dimensions of the entire model)
    #
    n_elems_xy_quarter = Int(5, input=True)
    n_elems_z = Int(3, input=True)

    n_elems_xy = Property(Int, depends_on='n_elems_xy_quarter, +input')

    @cached_property
    def _get_n_elems_xy(self):
        return self.n_elems_xy_quarter * self.scale_size

    #-----------------------------------------------------------------
    # option: 'shift_elems'
    #-----------------------------------------------------------------

    # shift of column elements
    # if set to "True" (default) the information defined in 'shift_array' is used.
    #
    shift_elems = Bool(True, input=True)

    # 'shift_array' is used to place element corners at a defined global
    # position in order to connect the shell with the corner nodes of the column.
    # [x_shift, y_shift, number of element s between the coordinate position]
    # NOTE: 'shift_array' needs to have shape (:,3)!
    #
    shift_array = Array(float, input=True)

    def _shift_array_default(self):
        return array(
            [[self.width_top_col / 2**0.5, self.width_top_col / 2**0.5, 1]])

    #-----------------------------------------------------------------
    # option: 'const_reinf_layer'
    #-----------------------------------------------------------------
    # 'const_reinf_layer' - parameter is used only for the non-linear analysis,
    # where an element layer with a constant thickness is needed to simulate the
    # reinforced concrete at the top and bottom of the TRC-shell.
    #
    const_reinf_layer_elem = Bool(False, input=True)
    t_reinf_layer = Float(0.03, input=True)  # [m]
    n_elems_reinf_layer = Int(
        1, input=True)  #number of dofs used for edge refinement

    #-----------------------------------------------------------------
    # read vertice points of the shell and derive a normalized
    # RBF-function for the shell approximation
    #-----------------------------------------------------------------

    # "lowerface_cut_off" - option replaces constant height for the coordinates
    # which connect to the column (this cuts of the shell geometry horizontally
    # at the bottom of the lower face of the shell geometry.
    #
    cut_off_lowerface = Bool(True, input=True)

    # choose geometric file (obj-data file)
    #
    geo_input_name = Enum('350x350cm', '4x4m', '02', input=True)

    # filter for '4x4m' file needs to be done to have regular grid
    # in order to rbf-function leading to stable solution without oscilation
    #
    geo_filter = Dict({'4x4m': delete_second_rows})

    #                        ,'350x350cm' : delete_second_rows} )

    def _read_arr(self, side='lowerface_'):
        '''read the robj-file saved in the subdirectory 
        'geometry_files'
        '''
        file_name = side + self.geo_input_name + '.robj'
        file_path = join('geometry_files', file_name)
        # get an array with the vertice coordinates
        #
        v_arr = read_rsurface(file_path)
        #        print 'v_arr before filtering \n', v_arr
        #        print 'v_arr.shape before filtering \n', v_arr.shape
        filter = self.geo_filter.get(self.geo_input_name, None)
        if filter != None:
            v_arr = filter(v_arr)


#        print 'v_arr after filtering \n', v_arr
#        print 'v_arr.shape after filtering \n', v_arr.shape
        return v_arr

    # array of the vertex positions in global
    # x,y,z-coordinates defining the lower surface of the shell
    #
    vl_arr = Property(Array(float), depends_on='geo_input_name')

    @cached_property
    def _get_vl_arr(self):
        vl_arr = self._read_arr('lowerface_')
        if self.cut_off_lowerface == True:
            print '--- lower face z-coords cut off ---'

            # z-values of the coords from the lower face are cut off.
            # From the highest z-coordinate of the lower face the vertical
            # distance is 'delta h (for 4x4m: delta_h = 1.0m).
            # At this limit the lower face is cut off.
            # NOTE: the global z coordinate is assumed to point up
            # and must be given in the same unite as 'delta_h', i.e. in [m].
            #
            vl_z_max = max(vl_arr[:, 2])
            if self.geo_input_name == '4x4m':
                # NOTE: the global z-coordinates are given in the geo data file in [m]
                # no conversion of unites necessary (self.delta_h is given in [m])
                delta_h = self.delta_h
            elif self.geo_input_name == '350x350cm':
                # NOTE: the global z-coordinates are given in the geo data file in [cm]
                # convert delta_h from [m] to [cm]
                #
                delta_h = self.delta_h * 100.
            vl_z_min = vl_z_max - delta_h
            vl_arr_z = where(vl_arr[:, 2] < vl_z_min, vl_z_min, vl_arr[:, 2])
            vl_arr = c_[vl_arr[:, 0:2], vl_arr_z]

        return vl_arr

    # array of the vertex positions in global
    # x,y,z-coordinates defining the upper surface of the shell
    #
    vu_arr = Property(Array(float), depends_on='geo_input_name')

    @cached_property
    def _get_vu_arr(self):
        return self._read_arr('upperface_')

    # normalized coordinates of the vertices for the lowerface
    # NOTE: the underline character indicates a normalized value
    # @todo: 'normalize_rsurfaces' is called twice for 'vl_arr_' and 'vu_arr_'
    #
    vl_arr_ = Property(Array(float), depends_on='geo_input_name')

    @cached_property
    def _get_vl_arr_(self):
        vl_arr_, vu_arr_ = normalize_rsurfaces(self.vl_arr, self.vu_arr)
        return vl_arr_

    # normalized coordinates of the vertices for the lowerface
    # NOTE: the underline character indicates a normalized value
    #
    vu_arr_ = Property(Array(float), depends_on='geo_input_name')

    @cached_property
    def _get_vu_arr_(self):
        vl_arr_, vu_arr_ = normalize_rsurfaces(self.vl_arr, self.vu_arr)
        return vu_arr_

    rbf_l_ = Property(Instance(Rbf), depends_on='geo_input_name')

    @cached_property
    def _get_rbf_l_(self):
        # use a radial basis function approximation (rbf) (i.e. interpolation of
        # scattered data) based on the normalized vertex points of the lower face
        #
        xl_ = self.vl_arr_[:, 0]
        yl_ = self.vl_arr_[:, 1]
        zl_ = self.vl_arr_[:, 2]

        # flip the orientation of the local coordinate axis
        # depending on the geometry file used
        #
        if self.geo_input_name == '350x350cm':
            xl_ = 1 - self.vl_arr_[:, 0]
        if self.geo_input_name == '4x4m':
            yl_ = 1 - self.vl_arr_[:, 1]

        rbf_l_ = Rbf(xl_, yl_, zl_, function='cubic')
        #        rbf_l_ = Rbf( xl_, yl_, zl_, function = 'linear' )
        return rbf_l_

    rbf_u_ = Property(Instance(Rbf), depends_on='geo_input_name')

    @cached_property
    def _get_rbf_u_(self):
        # use a radial basis function approximation (rbf) (i.e. interpolation of
        # scattered data) based on the normalized vertex points of the upper face
        #
        xu_ = self.vu_arr_[:, 0]
        yu_ = self.vu_arr_[:, 1]
        zu_ = self.vu_arr_[:, 2]

        # flip the orientation of the local coordinate axis
        # depending on the geometry file used
        #
        if self.geo_input_name == '350x350cm':
            xu_ = 1 - self.vu_arr_[:, 0]
        if self.geo_input_name == '4x4m':
            yu_ = 1 - self.vu_arr_[:, 1]

        rbf_u_ = Rbf(xu_, yu_, zu_, function='cubic')
        #        rbf_u_ = Rbf( xu_, yu_, zu_, function = 'linear' )
        return rbf_u_

    #------------------------------------------------------------------------------
    # hp_shell geometric transformation
    # NOTE: returns the global coordinates of the shell based on the supplied local
    #       grid points
    #------------------------------------------------------------------------------

    def __call__(self, points):
        '''Return the global coordinates of the supplied local points.
        '''

        # number of local grid points for each coordinate direction
        # NOTE: values must range between 0 and 1
        #
        xi_, yi_, zi_ = points[:, 0], points[:, 1], points[:, 2]

        # insert imperfection (shift the middle node of the shell upwards)
        imp = self.z_imperfection_factor
        zi_ += imp * xi_ + imp * yi_ - 2 * imp * xi_ * yi_

        # size of total structure
        #
        # @todo: move to class definition of "mushroof_model" and send to "__call__"
        scale_size = self.scale_size
        # @todo: add "_quarter" (see above)
        length_xy_tot = self.length_xy_quarter * scale_size
        n_elems_xy_quarter = self.n_elems_xy_quarter

        #        print 'HPShell n_elems_xy_quarter', n_elems_xy_quarter
        # distance from origin for each mushroof_part
        #
        def d_origin_fn(self, coords):
            if self.mushroof_part == 'quarter':
                return coords
            if self.mushroof_part == 'one':
                return abs(2.0 * coords - 1.0)
            # @todo: corresponding "scale_factor" needs to be added
            #        in order for this to work
            if self.mushroof_part == 'four':
                return where(coords < 0.5, abs(4 * coords - 1),
                             abs(-4 * coords + 3))

        # element at column shift
        #
        if self.shift_elems == True:

            # define the origin for each model part
            #
            def origin_fn(self, coords):
                if self.mushroof_part == 'quarter':
                    return zeros_like(coords)
                if self.mushroof_part == 'one':
                    return ones_like(xi_) * 0.5
                if self.mushroof_part == 'four':
                    return where(coords < 0.5, 0.25, 0.75)

            def piecewise_linear_fn(x, x_fix_arr_, y_fix_arr_):
                '''creates a piecewise linear_fn going through the fix_points
                values need to be normed running between 0..1
                and values have to be unique'''
                x_fix_arr_ = hstack((0, x_fix_arr_, 1))
                y_fix_arr_ = hstack((0, y_fix_arr_, 1))
                rbf_fn_ = Rbf(x_fix_arr_, y_fix_arr_,
                              function='linear')  #rbf has to be linear
                return rbf_fn_(x)

            # define origin for quarter
            #
            xi_origin_arr_ = origin_fn(self, xi_)
            yi_origin_arr_ = origin_fn(self, yi_)
            #            print 'xi_origin_arr_', xi_origin_arr_

            # delta towards origin
            #
            xi_delta_arr_ = (xi_ - xi_origin_arr_) * scale_size
            yi_delta_arr_ = (yi_ - yi_origin_arr_) * scale_size
            #            print 'xi_delta_arr_', xi_delta_arr

            # define sign
            #
            xi_sign_arr = where(xi_delta_arr_ == 0., 0.,
                                xi_delta_arr_ / abs(xi_delta_arr_))
            yi_sign_arr = where(yi_delta_arr_ == 0., 0.,
                                yi_delta_arr_ / abs(yi_delta_arr_))
            #            print 'xi_sign_arr', xi_sign_arr

            # fix points defined in shift array as normelized values
            #
            x_fix_ = self.shift_array[:, 0] / self.length_xy_quarter
            #            print 'x_fix_', x_fix_

            y_fix_ = self.shift_array[:, 1] / self.length_xy_quarter
            n_fix_ = add.accumulate(self.shift_array[:,
                                                     2]) / n_elems_xy_quarter

            #            print 'add.accumulate( self.shift_array[:, 2] )', add.accumulate( self.shift_array[:, 2] )
            #            print 'n_fix_', n_fix_
            #            print 'piecewise_linear_fn', piecewise_linear_fn( abs( xi_delta_arr_ ),
            #                                                                   n_fix_,
            #                                                                   x_fix_ ) / scale_size

            # new xi_
            #
            xi_ = xi_origin_arr_ + xi_sign_arr * piecewise_linear_fn(
                abs(xi_delta_arr_), n_fix_, x_fix_) / scale_size

            #            print 'xi_new', xi_

            # new yi
            #
            yi_ = yi_origin_arr_ + yi_sign_arr * piecewise_linear_fn(
                abs(yi_delta_arr_), n_fix_, y_fix_) / scale_size

            #-------------------------------------------------------------------------------------

        # values are used to calculate the z-coordinate using RBF-function of the quarter
        # (= values of the distance to the origin as absolute value)
        #
        xi_rbf_ = d_origin_fn(self, xi_)
        #        print 'xi_rbf_', xi_rbf_
        yi_rbf_ = d_origin_fn(self, yi_)

        # get the z-value at the supplied local grid points
        # of the lower face
        #
        zi_lower_ = self.rbf_l_(xi_rbf_, yi_rbf_)

        # get the z-value at the supplied local grid points
        # of the upper face
        #
        zi_upper_ = self.rbf_u_(xi_rbf_, yi_rbf_)

        # constant edge element transformation
        #
        if self.const_reinf_layer_elem == True:
            # arrange and check data
            #
            if self.t_reinf_layer > self.t_shell / 2. or self.n_elems_z < 3:
                print '--- constant edge element transformation canceled ---'
                print 'the following condition needs to be fullfilled: \n'
                print 'self.t_reinf_layer <= self.t_shell/2 and self.n_elems_z >= 3'
            else:
                n_elems_z = float(self.n_elems_z)
                # normed thickness will evaluate as t_reinf_layer at each element
                t_reinf_layer_ = self.t_reinf_layer / self.length_z / (
                    zi_upper_ - zi_lower_)

                # zi_old set off from top which needs to be shifted
                delta_ = self.n_elems_reinf_layer / n_elems_z

                # get upper, lower and internal coordinates, that need to be shifted
                zi_lower = where(zi_ <= delta_)
                zi_upper = where(abs(1 - zi_) <= delta_ + 1e-10)
                zi_inter = where(abs(zi_ - 0.5) < 0.5 - (delta_ + 1e-10))

                # narrowing of coordinates
                zi_[zi_lower] = zi_[zi_lower] * t_reinf_layer_[
                    zi_lower] / delta_
                zi_[zi_upper] = 1 - (
                    1 - zi_[zi_upper]) * t_reinf_layer_[zi_upper] / delta_
                zi_[zi_inter] = t_reinf_layer_[zi_inter] + \
                                (zi_[zi_inter] - delta_) / (1 - 2 * delta_)\
                                 * (1 - 2 * t_reinf_layer_[zi_inter])
                print '--- constant edge elements transformation done ---'

        # thickness is multiplied by the supplied zi coordinate
        #
        z_ = (zi_lower_ * self.scalefactor_delta_h +
              (zi_upper_ - zi_lower_) * zi_)

        # coordinates of origin
        #
        X_0, Y_0, Z_0 = self.X0

        print '--- geometric transformation done ---'

        # multiply the local grid points with the real dimensions in order to obtain the
        # global coordinates of the mushroof_part:
        #
        return c_[X_0 + (xi_ * length_xy_tot) * self.scalefactor_length_xy,
                  Y_0 + (yi_ * length_xy_tot) * self.scalefactor_length_xy,
                  Z_0 + z_ * self.length_z]
コード例 #3
0
class HPShell(HasTraits):
    '''Geometry definition.
    '''
    # dimensions of the shell structure [m]
    # (only one quart of the shell structure)
    #
    # NOTE: lenth_z = 1.0 m + 0.062 m = 1.062
    # NOTE: lenth_z = 0.865 m + 0.062 m = 0.927
    length_x = Float(3.50)
    length_y = Float(3.50)
    length_z = Float(0.927)

    # corresponds to the delta in the geometry obj file '4x4m'
    delta_h = Float(0.865)  # [m]

    # factor to scale height of lower surface
    # thickness remains unchanged as 0.06 m
    #
    delta_h_scalefactor = Float(1.00)  # [-]

    # cut of the z-coordinates of the lowerface if set to True
    #
    cut_off_lowerface = Bool(True)

    geo_input_name = Enum('350x350cm')
    geo_filter = Dict({'4x4m': delete_second_rows})

    def _read_arr(self, side='lowerface_'):
        file_name = side + self.geo_input_name + '.robj'
        file_path = join('geometry_files', file_name)
        v_arr = read_rsurface(file_path)

        filter = self.geo_filter.get(self.geo_input_name, None)
        if filter != None:
            v_arr = filter(v_arr)
        return v_arr

    # array of the vertex positions in global
    # x,y,z-coordinates defining the lower surface of the shell
    vl_arr = Property(Array(float))

    @cached_property
    def _get_vl_arr(self):
        vl_arr = self._read_arr('lowerface_')
        if self.cut_off_lowerface == True:
            print '--- lower face z-coords cut off ---'

            # z-values of the coords from the lower face are cut off.
            # From the highest z-coordinate of the lower face the vertical
            # distance is 1 m (=delta h). At this limit the lower face is
            # cut off. Global z coordinate is assumed to point up.
            #
            vl_z_max = max(vl_arr[:, 2])
            if self.geo_input_name == '4x4m':
                # NOTE: the global z-coordinates are given in the geo data file in [m]
                # no conversion of unites necessary (self.delta_h is given in [m])
                delta_h = self.delta_h
            elif self.geo_input_name == '350x350cm':
                # NOTE: the global z-coordinates are given in the geo data file in [cm]
                # convert delta_h from [m] to [cm]
                #
                delta_h = self.delta_h * 100.
            vl_z_min = vl_z_max - self.delta_h
            vl_arr_z = where(vl_arr[:, 2] < vl_z_min, vl_z_min, vl_arr[:, 2])
            vl_arr = c_[vl_arr[:, 0:2], vl_arr_z]
        return vl_arr

    # array of the vertex positions in global
    # x,y,z-coordinates defining the upper surface of the shell
    vu_arr = Property(Array(float))

    @cached_property
    def _get_vu_arr(self):
        return self._read_arr('upperface_')

    def get_mid_surface_and_thickness(self, points, perpendicular_t=True):
        '''Return the global coordinates of the supplied local points.
        '''
        print '*** get mid surface and thickness ***'

        #-----------------------------------------------
        # get the global coordinates as defined in the
        # input file and transform them to the coordinate
        # system of the master quarter
        #-----------------------------------------------

        #
        if self.geo_input_name == '350x350cm':
            X0 = [3.50, 3.50, 0.]
        else:
            X0 = [0., 0., 0.]

        # number of global grid points for each coordinate direction
        #
        xi, yi = points[:, 0] - X0[0], points[:, 1] - X0[1]

        # NOTE:
        # -- The available rbf-function is only defined for a quarter of one shell.
        # in order to get z and t values for an entire shell the abs-function
        # is used. The coordinate system of the quarter must be defined in the
        # lower left corner; the coordinate systemn of the entire one shell must
        # be defined in the center of the shell so that the coordinate system
        # for the master quarter remains unchanged.
        # -- The transformation is performed based on the defined class attributes
        # of hp_shell_stb: length_x, length_y, length_z, delta_h, delta_h_scalefactor
        # characterizing the properties of the master quarter

        # number of local grid points for each coordinate direction
        # values must range between 0 and 1
        #
        points_tilde_list = []
        for i_row in range(points.shape[0]):
            # get the x, y coordinate pair defined in the input
            # file in global coordinates
            #
            x = xi[i_row]
            y = yi[i_row]

            # transform values to local coordinate system,
            # i.e. move point to the 'master roof' containing the
            # global coordinate system:
            #
            if x <= self.length_x and y <= self.length_y:
                # point lays in first (master) roof
                #
                x_tilde = x
                y_tilde = y

            elif x >= self.length_x and y <= self.length_y:
                # point lays in second roof:
                #
                # roof length = 2* length of the master quarter
                # (e.g. 2*4,0m = 8,00m for obj-file "4x4m")
                x_tilde = x - 2 * self.length_x
                y_tilde = y

            elif x <= self.length_x and y >= self.length_y:
                # point lays in third roof:
                #
                x_tilde = x
                y_tilde = y - 2 * self.length_y

            elif x >= self.length_x and y >= self.length_y:
                # point lays in fourth roof:
                #
                x_tilde = x - 2 * self.length_x
                y_tilde = y - 2 * self.length_y

            points_tilde_list.append([x_tilde, y_tilde])

        points_tilde_arr = array(points_tilde_list, dtype='float_')
        xi_tilde = points_tilde_arr[:, 0]
        yi_tilde = points_tilde_arr[:, 1]
        #        print 'points_tilde_arr', points_tilde_arr

        xi_ = abs(xi_tilde) / self.length_x
        yi_ = abs(yi_tilde) / self.length_y

        #-----------------------------------------------
        # get the normalized rbf-function for the upper
        # and lower face of the master quarter
        #-----------------------------------------------
        # NOTE: the underline character indicates a normalized value

        # normalized coordinates of the vertices for lower- and upper-face
        #
        vl_arr_, vu_arr_ = normalize_rsurfaces(self.vl_arr, self.vu_arr)

        # use a radial basis function approximation (rbf) (i.e. interpolation of
        # scattered data) based on the normalized vertex points of the lower face
        #
        x_ = vl_arr_[:, 0]
        y_ = vl_arr_[:, 1]

        if self.geo_input_name == '350x350cm':
            x_ = 1 - vl_arr_[:, 0]

        z_l_ = vl_arr_[:, 2]
        rbf_l = Rbf(x_, y_, z_l_, function='cubic')

        # get the z-value at the supplied local grid points
        # of the lower face
        #
        zi_lower_ = rbf_l(xi_, yi_)

        # use a radial basis function approximation (rbf) (i.e. interpolation of
        # scattered data) based on the normalized vertex points of the upper face
        #
        x_ = vu_arr_[:, 0]
        y_ = vu_arr_[:, 1]

        if self.geo_input_name == '350x350cm':
            x_ = 1 - vu_arr_[:, 0]

        z_u_ = vu_arr_[:, 2]
        rbf_u = Rbf(x_, y_, z_u_, function='cubic')

        # get the z-value at the supplied local grid points
        # of the upper face
        #
        zi_upper_ = rbf_u(xi_, yi_)

        # approach of the slope to get thickness perpendicular to slope
        #
        # thickness is multiplied by the supplied zi coordinate
        # and z value of mid plane
        #
        t_ = zi_upper_ - zi_lower_

        z_middle_ = (zi_lower_ + (zi_upper_ - zi_lower_) * 0.5 /
                     self.delta_h_scalefactor) * self.delta_h_scalefactor

        if perpendicular_t == True:
            # delta shift of x and y for estimation of slope will be done in 4 direction
            # 0, 45, 90 and 135 degrees
            print "--- perpendicular ---"
            delta = 0.000001

            # shift in x

            dz_x_p_ = (rbf_u(xi_ + delta, yi_) + rbf_l(xi_ + delta, yi_)) / 2.0
            dz_x_m_ = (rbf_u(xi_ - delta, yi_) + rbf_l(xi_ - delta, yi_)) / 2.0

            slope_x_ = (dz_x_p_ - dz_x_m_) / (2.0 * delta)
            angle_x = arctan(slope_x_ * self.length_z / self.length_x)
            f_1 = cos(angle_x)

            # shift in y

            dz_y_p_ = (rbf_u(xi_, yi_ + delta) + rbf_l(xi_, yi_ + delta)) / 2.0
            dz_y_m_ = (rbf_u(xi_, yi_ - delta) + rbf_l(xi_, yi_ - delta)) / 2.0

            slope_y_ = (dz_y_p_ - dz_y_m_) / (2.0 * delta)
            angle_y = arctan(slope_y_ * self.length_z / self.length_x)
            f_2 = cos(angle_y)

            #shift +x +y; -x -y

            dz_x_p_y_p_ = (rbf_u(xi_ + delta, yi_ + delta) +
                           rbf_l(xi_ + delta, yi_ + delta)) / 2.0
            dz_x_m_y_m_ = (rbf_u(xi_ - delta, yi_ - delta) +
                           rbf_l(xi_ - delta, yi_ - delta)) / 2.0

            slope_x_p_y_p_ = (dz_x_p_y_p_ - dz_x_m_y_m_) / (2.0 * sqrt(2) *
                                                            delta)
            angle_x_p_y_p = arctan(slope_x_p_y_p_ * self.length_z /
                                   (self.length_x**2 + self.length_y**2)**0.5)
            f_3 = cos(angle_x_p_y_p)

            # shift in +x,-y ; -x and +y

            dz_x_p_y_m_ = (rbf_u(xi_ + delta, yi_ - delta) +
                           rbf_l(xi_ + delta, yi_ - delta)) / 2.0
            dz_x_m_y_p_ = (rbf_u(xi_ - delta, yi_ + delta) +
                           rbf_l(xi_ - delta, yi_ + delta)) / 2.0

            slope_x_p_y_m_ = (dz_x_p_y_m_ - dz_x_m_y_p_) / (sqrt(2) * 2.0 *
                                                            delta)
            angle_x_p_y_m = arctan(slope_x_p_y_m_ * self.length_z /
                                   (self.length_x**2 + self.length_y**2)**0.5)
            f_4 = cos(angle_x_p_y_m)

            # obtain minimum factor for good estimate of maximum slope

            factor = min([f_1, f_2, f_3, f_4], axis=0)
            t_ = t_ * factor

        return xi, yi, z_middle_ * self.length_z, t_ * self.length_z

    def _read_thickness_data(self, file_name):
        '''to read the stb - X and Y coordinates ( m ) save the xls - worksheet
        to a csv - file using ';' as filed delimiter and ' ' ( blank )
        as text delimiter.
        Stb Data needs to have same range of values in X and Y direction and same unit [m],
        as defined as length_x and length_y
        '''
        print '*** reading thickness data from file: ', file_name, ' ***'

        # get the column headings defined in the second row
        # of the csv thickness input file
        # "Nr.;X;Y;Z;[mm]"
        #
        file = open(file_name, 'r')
        lines = file.readlines()
        column_headings = array(lines[1].split(';'))
        elem_no_idx = where('Nr.' == column_headings)[0]
        X_idx = where('X' == column_headings)[0]
        Y_idx = where('Y' == column_headings)[0]
        Z_idx = where('Z' == column_headings)[0]
        thickness_idx = where('[mm]\n' == column_headings)[0]

        input_arr = loadtxt(file_name, delimiter=';', skiprows=2)

        # elem number:
        #
        elem_no = input_arr[:, elem_no_idx]

        # coordinates [m]:
        #
        X = input_arr[:, X_idx][:, 0]
        Y = input_arr[:, Y_idx][:, 0]

        #        print 'thickness_idx', thickness_idx
        if thickness_idx != []:
            thickness_stb = input_arr[:, thickness_idx][:, 0] / 1000.
            return elem_no, X, Y, thickness_stb
        else:
            thickness_stb = ones_like(elem_no)
            return elem_no, X, Y, thickness_stb

    def _read_elem_coords(self, file_name):
        '''x,y -coordinates must be read from old file
        '''
        input_arr = loadtxt(file_name, delimiter=';', skiprows=2)

        elem_no = input_arr[:, 0]
        X = input_arr[:, 2]
        Y = input_arr[:, 3]

        return elem_no, X, Y

    def _read_nodal_coords(self, file_name):
        '''read the nodal coordinates of the mid - surface
        defined in a csv - file. To export the excel sheet
        to csv use ";" as a field delimiter and "" ( none )
        as a text delimiter.
        Note that some lines do not contain values !
        '''
        print '*** reading nodal coordinates from file: ', file_name, ' ***'

        file = open(file_name, 'r')

        # read the column headings (first two lines)
        #
        first_line = file.readline()
        second_line = file.readline()
        column_headings = second_line.split(';')
        # remove '\n' from last string element in list
        column_headings[-1] = column_headings[-1][:-1]
        column_headings_arr = array(column_headings)

        # check in which column the node number and the
        # carthesian coordinates can be found
        #
        elem_no_idx = where('Nr.' == column_headings_arr)[0]
        X_idx = where('X [m]' == column_headings_arr)[0]
        Y_idx = where('Y [m]' == column_headings_arr)[0]
        Z_idx = where('Z [m]' == column_headings_arr)[0]

        lines = file.readlines()

        lines_list = [line.split(';') for line in lines]

        empty_lines_idx = []
        ll = []
        for i_line, line in enumerate(lines_list):

            # check if line contains values or only a node number!
            #
            if line[1] == 'Standard':
                ll.append(
                    [line[elem_no_idx], line[X_idx], line[Y_idx], line[Z_idx]])
            else:
                # NOTE: current number in file starts with 1, index in loop starts with 0
                # therefore add 1 in the index list
                #
                empty_lines_idx.append(i_line + 1)

        input_arr = array(ll, dtype='float_')

        node_no = input_arr[:, 0]
        X = input_arr[:, 1]
        Y = input_arr[:, 2]
        Z = input_arr[:, 2]

        return node_no, X, Y, Z, empty_lines_idx

    def compare_thickness_values(self, thickness, thickness_stb):
        '''get relative difference between the calucated thickness
        read in from the obj file, cut of and projected with respect to
        the approximated data given from stb.
        '''
        thickness = thickness.reshape(shape(thickness_stb))
        error = abs(1 - thickness / thickness_stb) * 100
        return error

    def export_midsurface_data(self, node_no, x, y, z_middle, file_name,
                               empty_lines_idx):
        '''exports data to csv - worksheet
        '''
        print '*** writing middle surface data to file,', file_name, ' ***'

        data = c_[node_no, x, y, z_middle]
        file = open(file_name, 'w')
        writer = csv.writer(file, delimiter=";", lineterminator="\n")
        writer.writerow(['node_number', 'x[m]', 'y[m]', 'z[m]'])
        writer.writerows(data)

        file = file.close()

        # if file contains empty lines add them at the positions
        # defined in 'empty_lines_idx'
        #
        if len(empty_lines_idx) != 0:

            print '--- file contains ', len(
                empty_lines_idx), ' empty_lines ---'

            # file without empty lines
            #
            file = open(file_name, 'r')
            lines = file.readlines()

            # overwrite file including empty lines
            #
            file = open(file_name, 'w')

            # index 'n' runs in the array without empty lines
            # index 'i' runs in the array with empty lines
            #
            n = 0
            for i in range(data.shape[0] + len(empty_lines_idx)):

                if i in empty_lines_idx:
                    file.writelines(str(i) + ";;;;\n")
                else:
                    file.writelines(lines[n])
                    n += 1

            # add last line:
            #
            file.writelines(lines[-1])

            file.close()
            print '--- empty lines added to file ---'

        return

    def export_thickness_data(self, elem_no, x, y, t, file_name):
        '''exports data to csv - worksheet
        '''
        print '*** writing thickness data to file,', file_name, ' ***'

        data = c_[elem_no, x, y, t * 1000]
        print shape(data)
        writer = csv.writer(open(file_name, 'w'),
                            delimiter=";",
                            lineterminator="\n")
        writer.writerow(['element_number', 'x[m]', 'y[m]', 't[mm]'])
        writer.writerows(data)
        return

    @show
    def show(self, x, y, z_middle, displayed_value):
        """Test contour_surf on regularly spaced co-ordinates like MayaVi.
        """
        print '*** plotting data***'
        s = points3d(X,
                     Y,
                     z_middle,
                     displayed_value,
                     colormap="gist_rainbow",
                     mode="cube",
                     scale_factor=0.3)

        sb = colorbar(s)
        # Recorded script from Mayavi2
        #try:
        #    engine = mayavi.engine
        #except NameError:
        #    from etsproxy.mayavi.api import Engine
        #    engine = Engine()
        #    engine.start()
        #if len(engine.scenes) == 0:
        #    engine.new_scene()
        # -------------------------------------------
        glyph = s  #.pipeline.scenes[0].children[0].children[0].children[0]
        glyph.glyph.glyph_source.glyph_source.center = array([0., 0., 0.])
        glyph.glyph.glyph_source.glyph_source.progress = 1.0
        glyph.glyph.glyph_source.glyph_source.x_length = 0.6
        glyph.glyph.glyph_source.glyph_source.y_length = 0.6
        sb.scalar_bar.title = 'thickness [m]'
        #print s.pipeline
        #s.scene.background = (1.0, 1.0, 1.0)

        return s
コード例 #4
0
class PDistrib(HasTraits):

    implements = IPDistrib

    # puts all chosen continuous distributions distributions defined
    # in the scipy.stats.distributions module as a list of strings
    # into the Enum trait
    distr_choice = Enum(distr_enum)
    distr_dict = Dict(distr_dict)

    #    distr_choice = Enum('sin2x', 'weibull_min', 'sin_distr', 'uniform', 'norm')
    #    distr_dict = {'sin2x' : sin2x,
    #                  'uniform' : uniform,
    #                  'norm' : norm,
    #                  'weibull_min' : weibull_min,
    #                  'sin_distr' : sin_distr}

    # instantiating the continuous distributions
    distr_type = Property(Instance(Distribution), depends_on='distr_choice')

    @cached_property
    def _get_distr_type(self):
        return Distribution(self.distr_dict[self.distr_choice])

    # change monitor - accumulate the changes in a single event trait
    changed = Event

    @on_trait_change('distr_choice, distr_type.changed, quantile, n_segments')
    def _set_changed(self):
        self.changed = True

    # ------------------------------------------------------------------------
    # Methods setting the statistical modments
    # ------------------------------------------------------------------------
    mean = Property

    def _get_mean(self):
        return self.distr_type.mean

    def _set_mean(self, value):
        self.distr_type.mean = value

    variance = Property

    def _get_variance(self):
        return self.distr_type.mean

    def _set_variance(self, value):
        self.distr_type.mean = value

    # ------------------------------------------------------------------------
    # Methods preparing visualization
    # ------------------------------------------------------------------------

    quantile = Float(0.00001, auto_set=False, enter_set=True)
    range = Property(Tuple(Float), depends_on='distr_type.changed, quantile')

    @cached_property
    def _get_range(self):
        return (self.distr_type.distr.ppf(self.quantile),
                self.distr_type.distr.ppf(1 - self.quantile))

    n_segments = Int(500, auto_set=False, enter_set=True)

    dx = Property(Float, depends_on='distr_type.changed, quantile, n_segments')

    @cached_property
    def _get_dx(self):
        range_length = self.range[1] - self.range[0]
        return range_length / self.n_segments

    # -------------------------------------------------------------------------
    # Discretization of the distribution domain
    # -------------------------------------------------------------------------
    x_array = Property(Array('float_'),
                       depends_on='distr_type.changed,'
                       'quantile, n_segments')

    @cached_property
    def _get_x_array(self):
        '''Get the intrinsic discretization of the distribution
        respecting its  bounds.
        '''
        return linspace(self.range[0], self.range[1], self.n_segments + 1)

    # ===========================================================================
    # Access function to the scipy distribution
    # ===========================================================================
    def pdf(self, x):
        return self.distr_type.distr.pdf(x)

    def cdf(self, x):
        return self.distr_type.distr.cdf(x)

    def rvs(self, n):
        return self.distr_type.distr.rvs(n)

    def ppf(self, e):
        return self.distr_type.distr.ppf(e)

    # ===========================================================================
    # PDF - permanent array
    # ===========================================================================

    pdf_array = Property(Array('float_'),
                         depends_on='distr_type.changed,'
                         'quantile, n_segments')

    @cached_property
    def _get_pdf_array(self):
        '''Get pdf values in intrinsic positions'''
        return self.distr_type.distr.pdf(self.x_array)

    def get_pdf_array(self, x_array):
        '''Get pdf values in externally specified positions'''
        return self.distr_type.distr.pdf(x_array)

    # ===========================================================================
    # CDF permanent array
    # ===========================================================================
    cdf_array = Property(Array('float_'),
                         depends_on='distr_type.changed,'
                         'quantile, n_segments')

    @cached_property
    def _get_cdf_array(self):
        '''Get cdf values in intrinsic positions'''
        return self.distr_type.distr.cdf(self.x_array)

    def get_cdf_array(self, x_array):
        '''Get cdf values in externally specified positions'''
        return self.distr_type.distr.cdf(x_array)

    # -------------------------------------------------------------------------
    # Randomization
    # -------------------------------------------------------------------------
    def get_rvs_array(self, n_samples):
        return self.distr_type.distr.rvs(n_samples)
コード例 #5
0
class FunctionRandomization(HasStrictTraits):

    # response function
    q = Callable(input=True)

    #===========================================================================
    # Inspection of the response function parameters
    #===========================================================================
    var_spec = Property(depends_on='q')

    @cached_property
    def _get_var_spec(self):
        '''Get the names of the q_parameters'''
        if type(self.q) is types.FunctionType:
            arg_offset = 0
            q = self.q
        else:
            arg_offset = 1
            q = self.q.__call__
        argspec = inspect.getargspec(q)
        args = np.array(argspec.args[arg_offset:])
        dflt = np.array(argspec.defaults)
        return args, dflt

    var_names = Property(depends_on='q')

    @cached_property
    def _get_var_names(self):
        '''Get the array of default values.
        None - means no default has been specified
        '''
        return self.var_spec[0]

    var_defaults = Property(depends_on='q')

    @cached_property
    def _get_var_defaults(self):
        '''Get the array of default values.
        None - means no default has been specified
        '''
        dflt = self.var_spec[1]
        defaults = np.repeat(None, len(self.var_names))
        start_idx = min(len(dflt), len(defaults))
        defaults[-start_idx:] = dflt[-start_idx:]
        return defaults

    #===========================================================================
    # Control variable specification
    #===========================================================================
    evars = Dict(Str, Array, input_change=True)

    def __evars_default(self):
        return {'e': [0, 1]}

    evar_lst = Property()

    def _get_evar_lst(self):
        ''' sort entries according to var_names.'''
        return [self.evars[nm] for nm in self.evar_names]

    evar_names = Property(depends_on='evars')

    @cached_property
    def _get_evar_names(self):
        evar_keys = list(self.evars.keys())
        return [nm for nm in self.var_names if nm in evar_keys]

    evar_str = Property()

    def _get_evar_str(self):
        s_list = [
            '%s = [%g, ..., %g] (%d)' % (name, value[0], value[-1], len(value))
            for name, value in zip(self.evar_names, self.evar_lst)
        ]
        return string.join(s_list, '\n')

    # convenience property to specify a single control variable without
    # the need to send a dictionary
    e_arr = Property

    def _set_e_arr(self, e_arr):
        '''Get the first free argument of var_names and set it to e vars
        '''
        self.evars[self.var_names[0]] = e_arr

    #===========================================================================
    # Specification of parameter value / distribution
    #===========================================================================

    tvars = Dict(input_change=True)

    tvar_lst = Property(depends_on='tvars')

    @cached_property
    def _get_tvar_lst(self):
        '''sort entries according to var_names
        '''
        return [self.tvars[nm] for nm in self.tvar_names]

    tvar_names = Property

    def _get_tvar_names(self):
        '''get the tvar names in the order given by the callable'''
        tvar_keys = list(self.tvars.keys())
        return np.array([nm for nm in self.var_names if nm in tvar_keys],
                        dtype=str)

    tvar_str = Property()

    def _get_tvar_str(self):
        s_list = [
            '%s = %s' % (name, str(value))
            for name, value in zip(self.tvar_names, self.tvar_lst)
        ]
        return string.join(s_list, '\n')

    # number of integration points
    n_int = Int(10, input_change=True)
コード例 #6
0
class FunctionRandomization(HasStrictTraits):

    # response function
    q = Callable(input=True)

    # ===========================================================================
    # Inspection of the response function parameters
    # ===========================================================================
    var_spec = Property(depends_on='q')

    @cached_property
    def _get_var_spec(self):
        '''Get the names of the q_parameters'''
        if type(self.q) is types.FunctionType:
            arg_offset = 0
            q = self.q
        else:
            arg_offset = 1
            q = self.q.__call__
        argspec = inspect.getargspec(q)
        args = np.array(argspec.args[arg_offset:])
        dflt = np.array(argspec.defaults)
        return args, dflt

    var_names = Property(depends_on='q')

    @cached_property
    def _get_var_names(self):
        '''Get the array of default values.
        None - means no default has been specified
        '''
        return self.var_spec[0]

    var_defaults = Property(depends_on='q')

    @cached_property
    def _get_var_defaults(self):
        '''Get the array of default values.
        None - means no default has been specified
        '''
        dflt = self.var_spec[1]
        defaults = np.repeat(None, len(self.var_names))
        start_idx = min(len(dflt), len(defaults))
        defaults[-start_idx:] = dflt[-start_idx:]
        return defaults

    # ===========================================================================
    # Control variable specification
    # ===========================================================================
    eps_vars = Dict(Str, Array, input_change=True)

    def _eps_vars_default(self):
        return {'e': [0, 1]}

    evar_lst = Property()

    def _get_evar_lst(self):
        ''' sort entries according to var_names.'''
        return [self.eps_vars[nm] for nm in self.evar_names]

    evar_names = Property(depends_on='eps_vars')

    @cached_property
    def _get_evar_names(self):
        evar_keys = self.eps_vars.keys()
        return [nm for nm in self.var_names if nm in evar_keys]

    evar_str = Property()

    def _get_evar_str(self):
        s_list = [
            '%s = [%g, ..., %g] (%d)' % (name, value[0], value[-1], len(value))
            for name, value in zip(self.evar_names, self.evar_lst)
        ]
        return string.join(s_list, '\n')

    # convenience property to specify a single control variable without
    # the need to send a dictionary
    e_arr = Property

    def _set_e_arr(self, e_arr):
        '''Get the first free argument of var_names and set it to e vars
        '''
        self.eps_vars[self.var_names[0]] = e_arr

    # ===========================================================================
    # Specification of parameter value / distribution
    # ===========================================================================

    theta_vars = Dict(input_change=True)

    _theta_vars = Property(depends_on='theta_vars')

    @cached_property
    def _get__theta_vars(self):
        _theta_vars = {}
        for key, value in self.theta_vars.items():

            # type checking
            is_admissible = False
            for admissible_type in [float, int, RV]:
                if isinstance(value, admissible_type):
                    is_admissible = True
            if not is_admissible:
                raise TypeError, 'bad type of theta variable %s' % key

            # type conversion
            if isinstance(value, int):
                value = float(value)

            _theta_vars[key] = value
        return _theta_vars

    tvar_lst = Property()

    def _get_tvar_lst(self):
        '''sort entries according to var_names
        '''
        return [self._theta_vars[nm] for nm in self.tvar_names]

    tvar_names = Property

    def _get_tvar_names(self):
        '''get the tvar names in the order given by the callable'''
        tvar_keys = self._theta_vars.keys()
        return np.array([nm for nm in self.var_names if nm in tvar_keys],
                        dtype=str)

    tvar_str = Property()

    def _get_tvar_str(self):
        s_list = [
            '%s = %s' % (name, str(value))
            for name, value in zip(self.tvar_names, self.tvar_lst)
        ]
        return string.join(s_list, '\n')

    # number of integration points
    n_int = Int(10, input_change=True)

    # count the random variables
    n_rand_vars = Property

    def _get_n_rand_vars(self):
        dt = map(type, self.tvar_lst)
        return dt.count(RV)

    # get the indexes of the random variables within the parameter list
    rand_var_idx_list = Property(depends_on='theta_vars, recalc')

    @cached_property
    def _get_rand_var_idx_list(self):
        dt = np.array(map(type, self.tvar_lst))
        return np.where(dt == RV)[0]
コード例 #7
0
class HPShell(HasTraits):
    '''Geometry definition.
    '''

    #===========================================================================
    # geometric variables and values
    #===========================================================================

    # part of mushroof
    #
    # @todo: "four" is not supported by "n_elems_xy_dict"in mushroff_model
    mushroof_part = Enum('detail', 'quarter', 'one', 'four')

    # origin
    # @todo: define as "_default"
    #
    X0 = Array(float, value=[0., 0., 0.])

    # element properties of grid
    #
    n_elems_xy = Int(6)
    n_elems_z = Int(3)

    n_elems_xy_quarter = Property(Int)

    @cached_property
    def _get_n_elems_xy_quarter(self):
        return self.n_elems_xy / self.scale_size

    # standard array for column shift
    # shift array shifts the elements towards the defined coordinates
    # [x_shift,y_shift,element_between]
    # array needs to have the right shape (:,3)!!
    #
    # @todo: define as "_default"
    #
    shift_array = Array(float,
                        shape=(None, 3),
                        value=[[0.45 / 2**0.5, 0.45 / 2**0.5, 1]])

    # dimensions of the shell for one quarter of mush_roof
    # @todo: add "_quarter"
    #
    length_x = Float(4.0)  # [m]
    length_y = Float(4.0)  # [m]
    length_z = Float(1.062)  # [m]
    t_shell = Float(0.06)  # [m]
    width_column = Float(0.45)  # [m]

    length_x_detail = Float(1.5)  # [m]
    length_y_detail = Float(1.5)  # [m]

    scale_size_detail_x = Property(Float)

    def _get_scale_size_detail_x(self):
        return self.length_x_detail / self.length_x * 2.

    scale_size_detail_y = Property(Float)

    def _get_scale_size_detail_y(self):
        return self.length_y_detail / self.length_y * 2.

    # scale factor for different mushroof parts
    # Defines the proportion between the lenght of the model
    # with respect to the length of a quarter shell as the
    # basic substructure of which the model consists of.
    # @todo: add "depend_on" or remove "cached_property"
    # @todo: move to class definition of "mushroof_model" not in "HPShell"
    #        (also see there "n_elems_dict" with implicit "scale_factor")
    #
    scale_size = Property(Float)

    #    @cached_property
    def _get_scale_size(self):
        #        scale_size_detail = self.lenght_x_detail / self.length_x
        scale_dict = {
            'detail': self.scale_size_detail_x,
            'quarter': 1.0,
            'one': 2.0,
            'four': 4.0
        }
        return scale_dict[self.mushroof_part]

    # factor to scale delta_h (inclination of the shell)
    # The thickness remains unchanged by this scaling, e.g. self.thickness = 0.06 [m]
    #
    delta_h_scalefactor = Float(1.00)  # [-]

    # shift of column elements
    #
    shift_elems = Bool(True)

    # const_edge element operator
    # (for non-linear analysis only, where an element layer of constant
    # thickness is needed to simulate the reinforced behaviour of the
    # concrete.
    #
    const_edge_elem = Bool(False)
    t_edge = Float(0.03)  # [m]
    n_elems_edge = Int(1)  #number of dofs used for edge refinement

    #===========================================================================
    # reading options
    #===========================================================================

    # "lowerface_cut_off" - option replaces constant height for the coordinates
    # which connect to the column (this cuts of the shell geometry horizontally
    # at the bottom of the lower face of the shell geometry.
    # Option should be used for the robj-file with 4x4m geometry
    #
    cut_off_lowerface = Bool(True)

    # corresponds to the delta in the geometry .obj-file with name '4x4m' as a cut off
    #
    delta_h = Float(1.00)  # [m]

    # choose geometric file (obj-data file)
    #
    geo_input_name = Enum('4x4m', '02')

    # filter for '4x4m' file needs to be done to have regular grid
    # in order to rbf-function leading to stable solution without oscilation
    #
    geo_filter = Dict({'4x4m': delete_second_rows})

    def _read_arr(self, side='lowerface_'):
        file_name = side + self.geo_input_name + '.robj'
        file_path = join('geometry_files', file_name)
        v_arr = read_rsurface(file_path)
        filter = self.geo_filter.get(self.geo_input_name, None)
        if filter != None:
            v_arr = filter(v_arr)
        return v_arr

    # array of the vertex positions in global
    # x,y,z-coordinates defining the lower surface of the shell
    vl_arr = Property(Array(float))

    @cached_property
    def _get_vl_arr(self):
        vl_arr = self._read_arr('lowerface_')
        if self.cut_off_lowerface == True:
            print '--- lower face z-coords cut off ---'

            # z-values of the coords from the lower face are cut off.
            # From the highest z-coordinate of the lower face the vertical
            # distance is 1 m (=delta h). At this limit the lower face is
            # cut off. Global z coordinate is assumed to point up.
            #
            vl_z_max = max(vl_arr[:, 2])
            vl_z_min = vl_z_max - self.delta_h
            vl_arr_z = where(vl_arr[:, 2] < vl_z_min, vl_z_min, vl_arr[:, 2])
            vl_arr = c_[vl_arr[:, 0:2], vl_arr_z]
        return vl_arr

    # array of the vertex positions in global
    # x,y,z-coordinates defining the upper surface of the shell
    vu_arr = Property(Array(float))

    @cached_property
    def _get_vu_arr(self):
        return self._read_arr('upperface_')

    #------------------------------------------------------------------------------
    # hp_shell geometric transformation
    #------------------------------------------------------------------------------

    def __call__(self, points):
        '''Return the global coordinates of the supplied local points.
        '''

        # number of local grid points for each coordinate direction
        # values must range between 0 and 1
        #
        xi, yi, zi = points[:, 0], points[:, 1], points[:, 2]
        print "xi", xi
        print "xi.shape", xi.shape

        # size of total structure
        #
        # @todo: move to class definition of "mushroof_model" and send to "__call__"
        scale_size = self.scale_size
        print "scale_size", scale_size

        # @todo: add "_quarter" (see above)
        length_x_tot = self.length_x * scale_size
        length_y_tot = self.length_y * scale_size
        n_elems_xy_quarter = self.n_elems_xy_quarter

        # distance from origin for each mushroof_part
        #
        def d_origin_fn(self, coords):
            #            if self.mushroof_part == 'quarter':
            #                return coords
            #            if self.mushroof_part == 'one':
            #                return abs( 2.0 * coords - 1.0 )

            if self.mushroof_part == 'detail':
                print 'in d_origin_fn'
                return abs(1.0 * coords - 0.5) * scale_size


#            # @todo: corresponding "scale_factor" needs to be added
#            #        in order for this to work
#            if self.mushroof_part == 'four':
#                return  where( coords < 0.5, abs( 4 * coords - 1 ), abs( -4 * coords + 3 ) )

# values are used to calculate the z-coordinate using RBF-function of the quarter
# (= values of the distance to the origin as absolute value)
#

        xi_rbf = d_origin_fn(self, xi)
        print 'xi_rbf', xi_rbf
        yi_rbf = d_origin_fn(self, yi)

        # normalized coordinates of the vertices for lower- and upperface
        # NOTE: the underline character indicates a normalized value
        #
        vl_arr_, vu_arr_ = normalize_rsurfaces(self.vl_arr, self.vu_arr)

        # use a radial basis function approximation (rbf) (i.e. interpolation of
        # scattered data) based on the normalized vertex points of the lower face
        #
        x_ = vl_arr_[:, 0]

        # flip the orientation of the local coordinate system in the
        # corresponding y-direction depending on the data file
        #
        geo_input_name = self.geo_input_name
        if geo_input_name == '4x4m':
            y_ = vl_arr_[:, 1]
        else:
            y_ = 1 - vl_arr_[:, 1]

        z_ = vl_arr_[:, 2]
        rbf = Rbf(x_, y_, z_, function='cubic')

        # get the z-value at the supplied local grid points
        # of the lower face
        #
        zi_lower_ = rbf(xi_rbf, yi_rbf)

        # use a radial basis function approximation (rbf) (i.e. interpolation of
        # scattered data) based on the normalized vertex points of the upper face
        #
        x_ = vu_arr_[:, 0]

        # flip the orientation of the local coordinate system in the
        # corresponding y-direction depending on the data file
        #
        geo_input_name = self.geo_input_name
        if geo_input_name == '4x4m':
            y_ = vu_arr_[:, 1]
        else:
            y_ = 1 - vu_arr_[:, 1]

        z_ = vu_arr_[:, 2]
        rbf = Rbf(x_, y_, z_, function='cubic')

        # get the z-value at the supplied local grid points
        # of the upper face
        #
        # note that zi_upper_ is a normalized coordinate!
        #
        zi_upper_ = rbf(xi_rbf, yi_rbf)

        # thickness is multiplied by the supplied zi coordinate
        #
        z_ = (zi_lower_ + (zi_upper_ - zi_lower_) * zi /
              self.delta_h_scalefactor) * self.delta_h_scalefactor

        # coordinates of origin
        #
        X, Y, Z = self.X0

        print '--- geometric transformation done ---'

        # multiply the local grid points with the real dimensions in order to obtain the
        # global coordinates of the mushroof_part:
        #
        return c_[X + xi * length_x_tot, Y + yi * length_y_tot,
                  Z + z_ * self.length_z]
コード例 #8
0
class MFnPlotAdapter(HasPrivateTraits):
    """ The base class for adapting function implementation in order to plot
    it in a plotting toolkit (either Chaco or Matplotlib)
    """

    # label on the x axis (only used when var_x empty)
    #
    label_x = Str('')

    # label on the y axis (only used when var_y empty)
    label_y = Str('')

    # title of the diagram
    #
    title = Str('')

    # color of the title
    title_color = Str('black')

    # when specified take the label of the axis from the value
    # of the variable trait in object
    #
    var_x = Str('')

    # when specified take the label of the axis from the value
    # of the variable trait in object
    #
    var_y = Str('')

    # label for line in legend
    #
    line_label = Str('')

    # @todo - further attributes to be made available

    # limits of number positions for switching into scientific notation 1eXX
    scilimits = Tuple(-3., 4.)

    # Plot properties

    line_color = List([
        'blue', 'red', 'green', 'black', 'magenta', 'yellow', 'white', 'cyan'
    ])

    #rr: is the dictionary necessary here?
    #why not a list of keys? chaco as well mpl can work with the key
    line_style = Dict({
        'solid': '-',
        'dash': '.',
        'dot dash': '-.',
        'dot': ':',
    })

    #horisontal axis scale ('log', 'symlog', 'linear')
    xscale = Str('linear')

    #vertical axis scale ('log', 'symlog', 'linear')
    yscale = Str('linear')

    # linewidth
    line_width = List(2.0)

    # color of the plotting background
    bgcolor = Str('white')

    # Border, padding properties
    border_visible = Bool(False)

    # @todo - unused - padding defined below - should be used in Chaco -
    # in Matplotlib it is working already [Faezeh, Check please]
    border_width = Int(0)

    # @todo does this work in both Mpl and Chaco? [Faeseh Check please]
    #
    padding_bg_color = Str('white')

    # labels in legend

    # @todo - no labels here - the defaults should make sense - are they active?
    #
    legend_labels = Tuple()

    # maximum size - None means arbitrarily resizable
    #
    max_size = Tuple()

    # minimum size
    #
    min_size = Tuple((200, 200))

    # padding

    padding = Dict({'left': 0.1, 'bottom': 0.1, 'right': 0.9, 'top': 0.9})

    # No of values displayed on the x axis
    xticks = Int(0)

    # No of values displayed on the y axis
    yticks = Int(0)