def _get_M_tns_product_type(self, psi_mtx): ''' Returns the 4th order damage effect tensor 'M4' using product-type symmetrization ''' n_dim = self.n_dim # Get the direction orthogonal to the principle damage coordinates (pdc): # @todo: is this direction orthogonal? Which one do we want? psi_eig_value, psi_eig_mtx = eigh(psi_mtx) psi_eig_value_real = array([pe.real for pe in psi_eig_value]) # transform phi_mtx to PDC: # (assure that besides the diagonal the entries are exactly zero) psi_pdc_mtx = zeros((n_dim, n_dim), dtype=float) for i in range(n_dim): psi_pdc_mtx[i, i] = psi_eig_value_real[i] # second order damage effect tensor: w_hat_pdc_mtx = arr_sqrt(psi_pdc_mtx) # print "w_hat_pdc_mtx", w_hat_pdc_mtx # transform the matrix w back to x-y-coordinates: w_hat_mtx = dot(dot(psi_eig_mtx, w_hat_pdc_mtx), transpose(psi_eig_mtx)) # print "w_hat_mtx", w_hat_mtx # M_ijkl = w_hat_ik * w_hat_lj (cf. Eq.(5.62) Script Prag Jirasek (2007)) # = w_hat_ik * w_hat_jl (w is a symmetric tensor) # Exploiting numpy-functionality using the # method 'outer' (returns M_ijkl = w_hat_ij * w_hat_kl), # therefore the axis j and k need to be swapped M4_ = outer(w_hat_mtx, w_hat_mtx).reshape(n_dim, n_dim, n_dim, n_dim) M4 = M4_.swapaxes(1, 2) return M4
def _get_beta_tns_product_type(self, phi_mtx): ''' Returns the 4th order damage tensor 'beta4' using product-type symmetrization (cf. [Baz97], Eq.(87)) ''' n_dim = self.n_dim # Get the direction of the principle damage coordinates (pdc): phi_eig_value, phi_eig_mtx = eigh(phi_mtx) phi_eig_value_real = array([pe.real for pe in phi_eig_value]) # transform phi_mtx to PDC: # (assure that besides the diagonal the entries are exactly zero) phi_pdc_mtx = zeros((n_dim, n_dim), dtype=float) for i in range(n_dim): phi_pdc_mtx[i, i] = phi_eig_value_real[i] # w_mtx = tensorial square root of the second order damage tensor: w_pdc_mtx = arr_sqrt(phi_pdc_mtx) # print "w_pdc_mtx", w_pdc_mtx # transform the matrix w back to x-y-coordinates: w_mtx = dot(dot(phi_eig_mtx, w_pdc_mtx), transpose(phi_eig_mtx)) # beta_ijkl = w_ik * w_jl (cf. [Baz 97]) # exploiting numpy-functionality (faster). # Method 'outer' returns beta_ijkl = w_ij * w_kl, # therefore the axis j and k need to be swapped beta4_ = outer(w_mtx, w_mtx).reshape(n_dim, n_dim, n_dim, n_dim) beta4 = beta4_.swapaxes(1, 2) return beta4
def _get_e_T_arr(self, e_vct_arr): ''' Returns a list of the microplane shear strains (scalar) based on the list of microplane strain vectors (Subsidary method for '_get_e_s_T_arr'.) ''' # magnitude of the normal strain vector for each microplane e_N_arr = self._get_e_N_arr(e_vct_arr) # normal strain vector for each microplane e_N_vct_arr = array( [self._MPN[i, :] * e_N_arr[i] for i in range(0, self.n_mp)]) # tangential strain vector for each microplane e_T_vct_arr = e_vct_arr - e_N_vct_arr # squared tangential strain vector for each microplane e_TT_arr = array([inner(e_T_vct, e_T_vct) for e_T_vct in e_T_vct_arr]) # equivalent strain for each microplane e_T_arr = arr_sqrt(e_TT_arr) return e_T_arr
def _get_e_equiv_arr(self, e_vct_arr): ''' Returns a list of the microplane equivalent strains based on the list of microplane strain vectors ''' # magnitude of the normal strain vector for each microplane # @todo: faster numpy functionality possible? e_N_arr = array( [dot(e_vct, mpn) for e_vct, mpn in zip(e_vct_arr, self._MPN)]) # positive part of the normal strain magnitude for each microplane e_N_pos_arr = (fabs(e_N_arr) + e_N_arr) / 2 # normal strain vector for each microplane # @todo: faster numpy functionality possible? e_N_vct_arr = array( [self._MPN[i, :] * e_N_arr[i] for i in range(0, self.n_mp)]) # tangent strain ratio c_T = self.c_T # tangential strain vector for each microplane e_T_vct_arr = e_vct_arr - e_N_vct_arr # squared tangential strain vector for each microplane e_TT_arr = array([inner(e_T_vct, e_T_vct) for e_T_vct in e_T_vct_arr]) # equivalent strain for each microplane e_equiv_arr = arr_sqrt(e_N_pos_arr * e_N_pos_arr + c_T * e_TT_arr) return e_equiv_arr
def get_corr_pred( self, sctx, eps_app_eng, tn, tn1 ): ''' Corrector predictor computation. @param eps_app_eng input variable - engineering strain ''' #n_d = self.n_d n_mp = self.n_mp E = self.E nu = self.nu phi_list, e_max_list = self._get_phi_list( sctx, eps_app_eng ) MPN = self._MPN MPW = self._MPW MPNN = self._MPNN # TODO Put it into the parameters - this is a temporary hack # if self.update_state_on: sctx.state_array[:] = e_max_list self.update_state_on = False # integration terms for each microplanes phi_vct_list = array( [ phi_list[i] * MPNN[i,:,:] * MPW[i] for i in range(0,n_mp) ] ) # integration terms for each microplanes psi_vct_list = array( [ 1. / phi_list[i] * MPNN[i,:,:] * MPW[i] for i in range(0,n_mp) ] ) # sum of contributions from all microplanes # sum over the first dimension (over the microplanes) phi_mtx2d = phi_vct_list.sum(0) psi_mtx2d = psi_vct_list.sum(0) phi_mtx = vstack( [hstack( [phi_mtx2d, [[0],[0]]] ), [[0,0,1]]] ) psi_mtx = vstack( [hstack( [psi_mtx2d, [[0],[0]]] ), [[0,0,1]]] ) # Lame constants calculated from E and nu # first Lame paramter calculated from E, nu la = E * nu / ( ( 1 + nu ) * ( 1 - 2 * nu ) ) # second Lame parameter (shear modulus) calculated from E, nu mu = E / ( 2 + 2 * nu ) n_d = 3 # rank-four tensor including damage effect D4s_mdm = self.D4s_mdm C4c_mdm = self.C4c_mdm D4s_e = self.D4s_e C4c_e = self.C4c_e # rank-two tensor (matrix) including damage effect D2s_mdm = self.D2s_mdm C2c_mdm = self.C2c_mdm D2s_e = self.D2s_e C2c_e = self.C2c_e delta = identity(3) # Fill the rank-four matrices for i in range(0,n_d): for j in range(0,n_d): for k in range(0,n_d): for l in range(0,n_d): #-------------------------------------------------------------------------------- # Damaged material #-------------------------------------------------------------------------------- D4s_mdm[i,j,k,l] = la * phi_mtx[i,j] * phi_mtx[k,l] + \ mu * ( phi_mtx[i,k] * phi_mtx[j,l] + phi_mtx[i,l] * phi_mtx[j,k] ) C4c_mdm[i,j,k,l] = (1+nu)/(2*E) * \ ( psi_mtx[i,k] * psi_mtx[j,l] + psi_mtx[i,l]* psi_mtx[j,k] ) - \ nu / E * psi_mtx[i,j] * psi_mtx[k,l] D2s_mdm[map3d_ijkl2mn(i,j,k,l)] = D4s_mdm[i,j,k,l] C2c_mdm[map3d_ijkl2mn(i,j,k,l)] = C4c_mdm[i,j,k,l] #-------------------------------------------------------------------------------- # Elastic material #-------------------------------------------------------------------------------- D4s_e[i,j,k,l] = la * delta[i,j] * delta[k,l] + \ mu * ( delta[i,k] * delta[j,l] + delta[i,l] * delta[j,k] ) C4c_e[i,j,k,l] = (1+nu)/(2*E) * \ ( delta[i,k] * delta[j,l] + delta[i,l]* delta[j,k] ) - \ nu / E * delta[i,j] * delta[k,l] D2s_e[map3d_ijkl2mn(i,j,k,l)] = D4s_e[i,j,k,l] C2c_e[map3d_ijkl2mn(i,j,k,l)] = C4c_e[i,j,k,l] if self.elastic_debug: C2cc_e = self._compliance_mapping( C2c_e ) D2c_e = inv( C2cc_e ) if self.stress_state == 'plane_stress': D2r_e = self._get_D_plane_stress( D2s_e ) else: # plane strain D2r_e = self._get_D_plane_strain( D2s_e ) sig_eng = tensordot( D2r_e, eps_app_eng, [[1],[0]]) return sig_eng, D2r_e C2cc_mdm = self._compliance_mapping( C2c_mdm ) D2c_mdm = inv( C2cc_mdm ) #--------------------------------------------------------------------------------------------- # Product symmetrization using explicitly expressed beta tensor #--------------------------------------------------------------------------------------------- phi_eig_val, phi_eig_mtx = eig( phi_mtx ) phi_eig = array([ pe.real for pe in phi_eig_val] ) # verify the transformation #phi_pdc_mtx = tensordot( tensordot( phi_eig_mtx, phi_mtx, [[0],[0]] ), phi_eig_mtx, [[1],[0]] ) phi_pdc_mtx = tensordot( tensordot( phi_mtx, phi_eig_mtx, [[0],[0]] ), phi_eig_mtx, [[1],[0]] ) w_mtx = arr_sqrt( phi_pdc_mtx ) beta4_tns = zeros([n_d,n_d,n_d,n_d]) for i in range(0,n_d): for j in range(0,n_d): for k in range(0,n_d): for l in range(0,n_d): beta4_tns[i,j,k,l] = w_mtx[i,k] * w_mtx[j,l] D4_bb_mdm = tensordot( tensordot( D4s_e, beta4_tns, [[0,1],[2,3]] ), beta4_tns, [[2,3],[2,3]] ) # Postprocess the material stiffness according to the # specified configuration # if self.model_version == 'stiffness' : D2_mdm = D2s_mdm else: # compliance D2_mdm = D2c_mdm if self.stress_state == 'plane_stress': D2r_mdm = self._get_D_plane_stress( D2_mdm ) else: # plane strain D2r_mdm = self._get_D_plane_strain( D2_mdm ) sig_eng = tensordot( D2r_mdm, eps_app_eng, [[1],[0]]) return sig_eng, D2r_mdm
# --- n_dim = 2 phi_mtx = phi phi_eig_value, phi_eig_mtx = eigh( phi_mtx ) print 'phi_eig_value, phi_eig_mtx', phi_eig_value, phi_eig_mtx phi_eig_value_real = array([ pe.real for pe in phi_eig_value] ) # transform phi_mtx to PDC: # (assure that besides the diagonal the entries are exactly zero) phi_pdc_mtx = zeros((n_dim,n_dim),dtype=float) for i in range(n_dim): phi_pdc_mtx[i,i] = phi_eig_value_real[i] print 'phi_pdc_mtx', phi_pdc_mtx # w_mtx = tensorial square root of the second order damage tensor: w_pdc_mtx = arr_sqrt( phi_pdc_mtx ) print "w_pdc_mtx", w_pdc_mtx # transform the matrix w back to x-y-coordinates: w_mtx = dot(dot(phi_eig_mtx, w_pdc_mtx),transpose(phi_eig_mtx)) print "w_mtx", w_mtx # --- # M4 = mats2D_explore.mats2D_eval._get_M_tns_sum_type(phi) M4 = mats2D_explore.mats2D_eval._get_M_tns_product_type(psi) print 'M4' print M4 C4_e = mats2D_explore.mats2D_eval.C4_e print 'elastic tensor' print C4_e
# use 'tensordot (correct): phi_pdc_mtx_ten = tensordot( tensordot( phi_eig_mtx, phi_mtx, [[0],[0]] ), phi_eig_mtx, [[1],[0]] ) ## # verify the transformation ## #phi_pdc_mtx = tensordot( tensordot( phi_eig_mtx, phi_mtx, [[0],[0]] ), phi_eig_mtx, [[1],[0]] ) ## phi_pdc_mtx = tensordot( tensordot( phi_mtx, phi_eig_mtx, [[0],[0]] ), phi_eig_mtx, [[1],[0]] ) ## w_mtx = arr_sqrt( phi_pdc_mtx ) n_d = 3 phi_pdc_mtx_v = identity(n_d) for i in range(0,n_d): phi_pdc_mtx_v[i,i]=phi_eig[i] w_mtx_pdc = arr_sqrt( phi_pdc_mtx_v ) w_mtx = dot(dot(phi_eig_mtx,w_mtx_pdc),transpose(phi_eig_mtx)) print "\n" print "phi_mtx = ", phi_mtx ,"\n" print "phi_eig_val = ", phi_eig_val ,"\n" print "phi_eig = ", phi_eig ,"\n" print "phi_eig_mtx = ", phi_eig_mtx ,"\n" print "use dot: phi_pdc_mtx = ", phi_pdc_mtx, "\n" print "use tensordot (correct order of arguments): phi_pdc_mtx_ten = ", phi_pdc_mtx_ten, "\n" print "construct phi_pdc based on the eigen-values: phi_pdc_mtx_v = ", phi_pdc_mtx_v, "\n" print "tensorial squareroot: w_mtx_pdc = ", w_mtx_pdc, "\n"