Ejemplo n.º 1
0
 def secondary(self, Ue):
     """
     Calculate secondary variables
     =============================
     INPUT:
         Ue : vector of primary variables at each node
     STORED:
         None
     RETURNS:
         svs : dictionary with secondary values
     """
     nip = len(self.ipe)
     svs = {'wx': zeros(nip), 'wy': zeros(nip)}
     for k, ip in enumerate(self.ipe):
         S, G, _ = shape_derivs(self.xy, self.fce, ip)
         gra = dot(Ue, G)
         w = -dot(self.D, gra)
         svs['wx'][k] = w[0]
         svs['wy'][k] = w[1]
     return svs
Ejemplo n.º 2
0
 def secondary(self, UPe):
     """
     Calculate secondary variables
     =============================
     INPUT:
         UPe : vector of primary variables at each node
     STORED:
         None
     RETURNS:
         svs : dictionary with secondary values
     """
     Ue = array([UPe[i] for i in self.eqsU])
     Pe = array([UPe[i] for i in self.eqsP])
     nip = len(self.ipeU)
     svs = {
         'sxE': zeros(nip),
         'syE': zeros(nip),
         'szE': zeros(nip),
         'sxyE': zeros(nip),  # effective values
         'ex': zeros(nip),
         'ey': zeros(nip),
         'ez': zeros(nip),
         'exy': zeros(nip)
     }
     sq2 = sqrt(2.0)
     for k, ip in enumerate(self.ipeU):
         S, G, _ = shape_derivs(self.xyU, self.fceU, ip)
         B = self.calc_B(G)
         eps = dot(B, Ue)  # strains
         sig = dot(self.D, eps)  # stresses
         svs['sxE'][k] = sig[0]
         svs['syE'][k] = sig[1]
         svs['szE'][k] = sig[2]
         svs['sxyE'][k] = sig[3] / sq2
         svs['ex'][k] = eps[0]
         svs['ey'][k] = eps[1]
         svs['ez'][k] = eps[2]
         svs['exy'][k] = eps[3] / sq2
     return svs
Ejemplo n.º 3
0
 def secondary(self, Ue):
     """
     Calculate secondary variables
     =============================
     INPUT:
         Ue : vector of primary variables at each node
     STORED:
         None
     RETURNS:
         svs : dictionary with secondary values
     """
     nip = len(self.ipe)
     svs = {
         'sx': zeros(nip),
         'sy': zeros(nip),
         'sz': zeros(nip),
         'sxy': zeros(nip),
         'ex': zeros(nip),
         'ey': zeros(nip),
         'ez': zeros(nip),
         'exy': zeros(nip)
     }
     sq2 = sqrt(2.0)
     for k, ip in enumerate(self.ipe):
         S, G, _ = shape_derivs(self.xy, self.fce, ip)
         B = self.calc_B(G)
         eps = dot(B, Ue)  # strains
         sig = dot(self.D, eps)  # stresses
         svs['sx'][k] = sig[0]
         svs['sy'][k] = sig[1]
         svs['sz'][k] = sig[2]
         svs['sxy'][k] = sig[3] / sq2
         svs['ex'][k] = eps[0]
         svs['ey'][k] = eps[1]
         svs['ez'][k] = eps[2]
         svs['exy'][k] = eps[3] / sq2
     return svs
Ejemplo n.º 4
0
    def __init__(self, verts, params):
        """
        2D elasticity problem with porous media
        =======================================
            Example of input:
                      global_id  tag   x    y
               verts = [[3,    -100, 0.0, 0.0],
                        [4,    -100, 1.0, 0.0],
                        [7,    -100, 1.0, 1.0],
                        [1,    -100, 0.0, 1.0]]
               params = {'E':1., 'nu':1., 'pstress':True, 'thick':1.,
                         'geom':'tri3', 'ipe':'QuaIp4', 'rho':1.0}
               pstress : plane-stress instead of plane-strain? [optional]
               thick   : thickness for plane-stress only [optional]
               ipe     : [optional] integration points
               geom types:
                   tri3, tri6, qua4, qua8
        INPUT:
            verts  : list of vertices
            params : dictionary of parameters
        STORED:
            geom     : geometry key pair, ex: (tri6,tri3), (qua8,qua4)
            fce, fcf : element and face shape/deriv functions
            nne, nnf : element and face number of nodes
            ipe, ipf : integration points of element and edge/face
            rho      : density [optional]
            E        : Young modulus
            nu       : Poisson's coefficient
            pstress  : is plane-stress problem instead of plane-strain?
            thick    : thickness for plane-stress problems
            has_load : has applied distributed load to any side
            xy       : matrix of coordinates of nodes
            D        : constitutive modulus (matrix)
            K        : stiffness matrix
        """
        # set geometry
        if isinstance(params['geom'], str):
            self.geoU = params['geom']
            self.geoP = params['geom']
        else:
            self.geoU = params['geom'][0]
            self.geoP = params['geom'][1]
        self.fceU, self.nneU, self.fcfU, self.nnfU = get_shape_fcn(self.geoU)
        self.fceP, self.nneP, self.fcfP, self.nnfP = get_shape_fcn(self.geoP)
        self.ipeU, self.ipfU = get_ips(self.geoU)
        self.ipeP, self.ipfP = get_ips(self.geoP)
        if 'ipeU' in params: self.ipeU = params['ipeU']
        if 'ipeP' in params: self.ipeP = params['ipeP']

        # check
        if len(verts) != self.nneU:
            raise Exception('this element needs %d vertices exactly' %
                            self.nneU)

        # set data
        self.E = params['E']  # Young modulus
        self.nu = params['nu']  # Poisson's coefficient
        self.kx = params['kx']  # x-conductivity
        self.ky = params['ky']  # y-conductivity
        self.has_load = False  # has distributed loads
        self.has_flux = False  # has flux specified

        # other parameters
        rhoS = params['rhoS']  # density of solid grains
        rhoW = params['rhoW']  # water real density
        gamW = params['gamW']  # water unit weight of reference
        eta = params['eta']  # porosity
        Kw = params['Kw']  # water bulk modulus
        rho = (1.0 - eta) * rhoS + eta * rhoW  # density of mixture
        Cwb = eta / Kw

        # matrix of nodal coordinates
        self.xyU = zeros((2, self.nneU))  # 2 => 2D
        self.xyP = zeros((2, self.nneP))  # 2 => 2D
        for n, v in enumerate(verts):
            self.xyU[0][n] = v[2]  # x-coordinates
            self.xyU[1][n] = v[3]  # y-coordinates
            if n < self.nneP:
                self.xyP[0][n] = v[2]  # x-coordinates
                self.xyP[1][n] = v[3]  # y-coordinates

        # constitutive matrix (plane strain)
        nu = self.nu  # Poisson coef
        cf = self.E / ((1.0 + nu) * (1.0 - 2.0 * nu))
        self.D = cf * array([[1. - nu, nu, nu, 0.], [nu, 1. - nu, nu, 0.],
                             [nu, nu, 1. - nu, 0.], [0., 0., 0., 1. - 2. * nu]
                             ])

        # conductivity matrix
        self.kap = array([[self.kx / gamW, 0.0], [0.0, self.ky / gamW]])

        # iota tensor
        self.iota = array([1., 1., 1., 0.])

        # K, M, Q and O matrices
        self.K = zeros((self.nneU * 2, self.nneU * 2))
        self.M = zeros((self.nneU * 2, self.nneU * 2))
        self.Q = zeros((self.nneU * 2, self.nneP))
        self.O = zeros((self.nneP, self.nneU * 2))
        for ip in self.ipeU:
            # K and M
            S, G, detJ = shape_derivs(self.xyU, self.fceU, ip)
            B = self.calc_B(G)
            N = self.calc_N(S)
            cf = detJ * ip[2]
            self.K += cf * dot(transpose(B), dot(self.D, B))
            self.M += (cf * rho) * dot(transpose(N), N)
            # Q and O
            Sb, Gb, _ = shape_derivs(self.xyP, self.fceP, ip)
            self.Q += cf * dot(transpose(B), outer(self.iota, Sb))
            self.O += (cf * rhoW) * dot(Gb, dot(self.kap, N))
            #print detJ, detJb, detJ-detJb

        # L and H matrices
        self.L = zeros((self.nneP, self.nneP))
        self.H = zeros((self.nneP, self.nneP))
        for ip in self.ipeP:
            Sb, Gb, detJb = shape_derivs(self.xyP, self.fceP, ip)
            cf = detJb * ip[2]
            self.L += (cf * Cwb) * outer(Sb, Sb)
            self.H += cf * dot(Gb, dot(self.kap, transpose(Gb)))

        # local equation numbers
        neqs = self.nneU * 2 + self.nneP
        self.eqsP = [2 + n * 3 for n in range(self.nneP)]
        self.eqsU = [i for i in range(neqs) if i not in self.eqsP]
Ejemplo n.º 5
0
    def __init__(self, verts, params):
        """
        2D elasticity problem
        =====================
            Example of input:
                      global_id  tag   x    y
               verts = [[3,    -100, 0.0, 0.0],
                        [4,    -100, 1.0, 0.0],
                        [7,    -100, 1.0, 1.0],
                        [1,    -100, 0.0, 1.0]]
               params = {'E':1., 'nu':1., 'pstress':True, 'thick':1.,
                         'geom':'tri3', 'ipe':'QuaIp4', 'rho':1.0}
               pstress : plane-stress instead of plane-strain? [optional]
               thick   : thickness for plane-stress only [optional]
               ipe     : [optional] integration points
               geom types:
                   tri3, tri6, qua4, qua8
        INPUT:
            verts  : list of vertices
            params : dictionary of parameters
        STORED:
            geom     : geometry key [tri3,tri6,qua4,qua8]
            fce, fcf : element and face shape/deriv functions
            nne, nnf : element and face number of nodes
            ipe, ipf : integration points of element and edge/face
            rho      : density [optional]
            E        : Young modulus
            nu       : Poisson's coefficient
            pstress  : is plane-stress problem instead of plane-strain?
            thick    : thickness for plane-stress problems
            has_load : has applied distributed load to any side
            xy       : matrix of coordinates of nodes
            D        : constitutive modulus (matrix)
            K        : stiffness matrix
        """
        # set geometry
        self.geom = params['geom']
        self.fce, self.nne, self.fcf, self.nnf = get_shape_fcn(self.geom)
        self.ipe, self.ipf = get_ips(self.geom)
        if 'ipe' in params: self.ipe = params['ipe']

        # check
        if len(verts) != self.nne:
            raise Exception('this element needs %d vertices exactly' %
                            self.nne)

        # set data
        self.rho = 0.0  # density
        self.E = params['E']  # Young modulus
        self.nu = params['nu']  # Poisson's coefficient
        self.pstress = False  # plane stress
        self.thick = 1.0  # thickness of element
        self.has_load = False  # has distributed loads
        if 'rho' in params: self.rho = params['rho']
        if 'pstress' in params:
            self.pstress = params['pstress']  # plane-stress?
            self.thick = params['thick']  # thickness

        # matrix of nodal coordinates
        self.xy = zeros((2, self.nne))  # 2 => 2D
        for n, v in enumerate(verts):
            self.xy[0][n] = v[2]  # x-coordinates
            self.xy[1][n] = v[3]  # y-coordinates

        # constitutive matrix
        nu = self.nu  # Poisson coef
        if self.pstress:
            cf = self.E / (1.0 - nu**2.0)
            self.D = cf * array([[1., nu, 0., 0.], [nu, 1., 0., 0.],
                                 [0., 0., 0., 0.], [0., 0., 0., 1. - nu]])
        else:  # plane strain
            cf = self.E / ((1.0 + nu) * (1.0 - 2.0 * nu))
            self.D = cf * array([[1. - nu, nu, nu, 0.], [nu, 1. - nu, nu, 0.],
                                 [nu, nu, 1. - nu, 0.],
                                 [0., 0., 0., 1. - 2. * nu]])

        # K and M matrices
        self.K = zeros((self.nne * 2, self.nne * 2))
        self.M = zeros((self.nne * 2, self.nne * 2))
        for i, ip in enumerate(self.ipe):
            S, G, detJ = shape_derivs(self.xy, self.fce, ip)
            B = self.calc_B(G)
            N = self.calc_N(S)
            cf = detJ * ip[2] * self.thick
            self.K += cf * dot(transpose(B), dot(self.D, B))
            self.M += (cf * self.rho) * dot(transpose(N), N)
Ejemplo n.º 6
0
    def __init__(self, verts, params):
        """
        2D diffusion problem
        ====================
            Solving:         2         2
                    du      d u       d u
                rho == - kx ==== - ky ==== = s(x)
                    dt      d x2      d y2
            Example of input:
                      global_id  tag   x    y
               verts = [[3,    -100, 0.0, 0.0],
                        [4,    -100, 1.0, 0.0],
                        [7,    -100, 1.0, 1.0],
                        [1,    -100, 0.0, 1.0]]
               params = {'rho':1., 'kx':1., 'ky':1.,
                         'source':src_val_or_fcn, 'geom':qua4}
            Notes:
               src_val_or_fcn: can be a constant value or a
                               callback function such as
                               lambda x,y: x+y
               geom types:
                   tri3, tri6, qua4, qua8
        INPUT:
            verts  : list of vertices
            params : dictionary of parameters
        STORED:
            geom       : geometry key [tri3,tri6,qua4,qua8]
            fce, fcf   : element and face shape/deriv functions
            nne, nnf   : element and face number of nodes
            ipe, ipf   : integration points of element and edge/face
            rho        : rho parameter [optional]
            kx         : x-conductivity
            ky         : y-conductivity
            source     : the source term [optional]
            has_flux   : has flux applied to any side?
            has_conv   : has convection applied to any side?
            has_source : has source term
            xy         : matrix of coordinates of nodes
            D          : matrix with kx and ky
            C          : Ce matrix [rate of u]
            Kk         : Kke matrix [conductivity]
            Fs         : Fs vector [source]
        """
        # set geometry
        self.geom = params['geom']
        self.fce, self.nne, self.fcf, self.nnf = get_shape_fcn(self.geom)
        self.ipe, self.ipf = get_ips(self.geom)

        # check
        if len(verts) != self.nne:
            raise Exception('this element needs %d vertices exactly' %
                            self.nne)

        # set data
        self.rho = 0.0  # rho parameter
        self.kx = params['kx']  # x-conductivity
        self.ky = params['ky']  # y-conductivity
        self.has_flux = False  # has flux bry conditions
        self.has_conv = False  # has convection bry conds
        self.has_source = False  # has source term
        if 'rho' in params: self.rho = params['rho']
        if 'source' in params:
            self.source = params['source']
            self.has_source = True

        # matrix of nodal coordinates
        self.xy = zeros((2, self.nne))  # 2 => 2D
        for n, v in enumerate(verts):
            self.xy[0][n] = v[2]  # x-coordinates
            self.xy[1][n] = v[3]  # y-coordinates

        # conductivity matrix
        self.D = array([[self.kx, 0.0], [0.0, self.ky]])

        # Ce, Kke and source
        self.C = zeros((self.nne, self.nne))
        self.Kk = zeros((self.nne, self.nne))
        self.Fs = zeros(self.nne)
        for ip in self.ipe:
            S, G, detJ = shape_derivs(self.xy, self.fce, ip)
            cf = detJ * ip[2]
            self.C += cf * self.rho * outer(S, S)
            self.Kk += cf * dot(G, dot(self.D, transpose(G)))
            if self.has_source:
                if isinstance(self.source, float):  # constant value
                    self.Fs += cf * self.source * S
                else:  # function(x,y)
                    xip, yip = ip_coords(S, self.xy)
                    self.Fs += cf * self.source(xip, yip) * S