def permeability_tensor(self, K): FS = self.geometry.f0.function_space() TS = TensorFunctionSpace(self.geometry.mesh, 'P', 1) d = self.geometry.dim() fibers = Function(FS) fibers.vector()[:] = self.geometry.f0.vector().get_local() fibers.vector()[:] /= df.norm(self.geometry.f0) if self.geometry.s0 is not None: # normalize vectors sheet = Function(FS) sheet.vector()[:] = self.geometry.s0.vector().get_local() sheet.vector()[:] /= df.norm(self.geometry.s0) if d == 3: csheet = Function(FS) csheet.vector()[:] = self.geometry.n0.vector().get_local() csheet.vector()[:] /= df.norm(self.geometry.n0) else: return Constant(1) from ufl import diag factor = 10 if d == 3: ftensor = df.as_matrix(((fibers[0], sheet[0], csheet[0]), (fibers[1], sheet[1], csheet[1]), (fibers[2], sheet[2], csheet[2]))) ktensor = diag(df.as_vector([K, K / factor, K / factor])) else: ftensor = df.as_matrix( ((fibers[0], sheet[0]), (fibers[1], sheet[1]))) ktensor = diag(df.as_vector([K, K / factor])) permeability = df.project( df.dot(df.dot(ftensor, ktensor), df.inv(ftensor)), TS) return permeability
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) # r = .1*sqrt((x-np.pi)**2 + (y-np.pi)**2) # self.u_ = pow(r,1.5) * sin(x) * sin(y) # Set up explicit solution self.u_ = sin(x) * sin(y) # Init coefficient matrix self.a1 = as_matrix([[2, .5], [ 0.5, 1.5 ]]) + conditional(x * y > 0, 1., -1.) * as_matrix([[1., .5], [.5, .5]]) self.a2 = as_matrix([[1.5, .5], [ 0.5, 2. ]]) + conditional(x * y > 0, 1., -1.) * as_matrix([[.5, .5], [.5, 1.]]) self.a = self.gamma[0] * self.a1 + (1. - self.gamma[0]) * self.a2 # Init right-hand side self.f1 = inner(self.a1, grad(grad(self.u_))) self.f2 = inner(self.a2, grad(grad(self.u_))) self.fcond = conditional(x * y > 0, 0., 1.) # self.f = self.fcond * self.f1 + (1.-self.fcond) * self.f2 self.f = self.gamma[0] * self.f1 + (1. - self.gamma[0]) * self.f2 # conditional(x*x*x-y>0.0,2.0,1.0)]]) # self.f = inner(self.a, grad(grad(self.u_))) # Set boundary conditions to exact solution self.g = Constant(0.0)
def updateCoefficients(self): # Init coefficient matrix x, y = SpatialCoordinate(self.mesh) self.a = 0.5 * as_matrix( [[cos(self.gamma[0]), sin(self.gamma[0])], [- sin(self.gamma[0]), cos(self.gamma[0])]]) \ * as_matrix([[1, sin(self.gamma[1])], [0, cos(self.gamma[1])]]) \ * as_matrix([[1, 0], [sin(self.gamma[1]), cos(self.gamma[1])]]) \ * as_matrix( [[cos(self.gamma[0]), - sin(self.gamma[0])], [sin(self.gamma[0]), cos(self.gamma[0])]]) self.b = as_vector([Constant(0.0), Constant(0.0)]) self.c = -pi**2 self.u_ = exp(x * y) * sin(pi * x) * sin(pi * y) # Init right-hand side self.f = - sqrt(3) * (sin(self.gamma[1])/pi)**2 \ + 111111 # TODO work here # Set boundary conditions self.g = Constant(0.0)
def updateCoefficients(self): # Init coefficient matrix x, y = SpatialCoordinate(self.mesh) self.a = 0.5 * as_matrix( [[cos(self.gamma[0]), sin(self.gamma[0])], [- sin(self.gamma[0]), cos(self.gamma[0])]]) \ * as_matrix([[20, 1], [1, 0.1]]) \ * as_matrix( [[cos(self.gamma[0]), - sin(self.gamma[0])], [sin(self.gamma[0]), cos(self.gamma[0])]]) self.b = as_vector([Constant(0.0), Constant(1.0)]) self.c = Constant(-10.0) self.u_ = (2*x-1.) \ * (exp(1 - abs(2*x-1.)) - 1) \ * (y + (1 - exp(y/self.delta))/(exp(1/self.delta)-1)) # Init right-hand side self.f = inner(self.a, grad(grad(self.u_))) \ + inner(self.b, grad(self.u_)) \ + self.c * self.u_ # Set boundary conditions self.g = Constant(0.0)
def set_model(self): measures = [self.dx, self.ds, self.dS] actuation = ActuationShear(self.z, self.mesh, self.parameters, measures) _a = self.parameters['material']['a'] _b = self.parameters['material']['b'] _c = self.parameters['material']['c'] _ta = _a + 1 / 3 _tb = _b + 1 / 3 _tc = _a - _c + 1 / 3 Qn = [as_matrix([[0, 0, 0], [0, 0, 0], [0, 0, 0]])] * 4 Qn[0] = as_matrix([[_a, -np.sqrt(_ta * _tb), np.sqrt(_ta * _tc)], [np.sqrt(_ta * _tb), _b, -np.sqrt(_tb * _tc)], [np.sqrt(_ta * _tc), np.sqrt(_tb * _tc), _c]]) Qn[1] = as_matrix([[_a, np.sqrt(_ta * _tb), np.sqrt(_ta * _tc)], [np.sqrt(_ta * _tb), _b, np.sqrt(_tb * _tc)], [np.sqrt(_ta * _tc), np.sqrt(_tb * _tc), _c]]) Qn[2] = as_matrix([[_a, -np.sqrt(_ta * _tb), -np.sqrt(_ta * _tc)], [np.sqrt(_ta * _tb), _b, np.sqrt(_tb * _tc)], [np.sqrt(_ta * _tc), np.sqrt(_tb * _tc), _c]]) Qn[3] = as_matrix([[_a, np.sqrt(_ta * _tb), -np.sqrt(_ta * _tc)], [np.sqrt(_ta * _tb), _b, -np.sqrt(_tb * _tc)], [np.sqrt(_ta * _tc), np.sqrt(_tb * _tc), _c]]) # import pdb; pdb.set_trace() actuation.Q1n = Qn[0] actuation.Q2n = Qn[1] actuation.Q3n = Qn[2] actuation.Q4n = Qn[3] self.Q = Qn actuation.define_variational_equation() self.F = actuation.F self.J = actuation.jacobian self.energy_mem = actuation.energy_mem self.energy_ben = actuation.energy_ben self.energy_nem = actuation.energy_nem self.work = actuation.work
def create_Fg(growthFactor, type="uniaxial"): gf = growthFactor if type == "uniaxial": Fg = dl.as_matrix(((1.0 + gf, 0.0), (0., 1.0))) elif type == "isotropic": Fg = dl.as_matrix(((1.0 + gf, 0.0), (0., 1.0 + gf))) else: Fg = None print("Error specifying growth type") sys.exit() return Fg
def __init__( self, mesh, materials, subdomains, global_dimensions=None, facet_regions=None, **kwargs, ): """ Parameters ---------- subdomains : dolfin.MeshFunction Indicates the subdomains that have been defined in the mesh. """ self.mesh = mesh self.dim = mesh.topology().dim() # dimension d'espace de depart self.materials = materials self.subdomains = subdomains self.global_dimensions = global_dimensions self.facet_regions = facet_regions if isinstance(materials, mat.Material): self.elasticity_tensor = fe.as_matrix(materials.get_C()) elif isinstance(materials, dict): self.elasticity_tensor = mat.mat_per_subdomains( subdomains, materials, self.dim) else: raise TypeError( "Expected a (dict of) Material as materials argument") if "bottom_left_corner" in kwargs.keys(): self.bottom_left_corner = np.asarray(kwargs["bottom_left_corner"]) self.name = kwargs.get("name", None) self._mat_area = None
def updateCoefficients(self): # Init coefficient matrix x = SpatialCoordinate(self.mesh)[0] self.a = as_matrix([[.5 * (x * self.gamma[0] * self.sigmax)**2]]) self.b = as_vector([x * (self.gamma[0] * (self.mu - self.r) + self.r)]) self.c = Constant(0.0) # Init right-hand side self.f = Constant(0.0) self.u_ = exp( ((self.mu - self.r)**2 / (2 * self.sigmax**2) * self.alpha / (1 - self.alpha) + self.r * self.alpha) * (self.T[1] - self.t)) * (x**self.alpha) / self.alpha self.u_T = (x**self.alpha) / self.alpha # Set boundary conditions # self.g_t = lambda t : [(Constant(0.0), "near(x[0],0)")] self.g = Constant(0.0) # self.g_t = lambda t : self.u_t(t) self.gamma_star = [ Constant((self.mu - self.r) / (self.sigmax**2 * (1 - self.alpha))) ] self.loc = conditional(x > 0.5, conditional(x < 1.5, 1, 0), 0)
def updateCoefficients(self): # Init coefficient matrix P, Inv = SpatialCoordinate(self.mesh) self.a = as_matrix([[+.5 * (P * self.sigma)**2, 0], [0, 0]]) # def K(t): return self.K0 + beta_SA * sin(4*pi*(t - t_SA)) def K(t): return self.K0 self.b = as_vector([ +self.alpha * (K(self.t) - P), -(self.gamma[0] + self.cost(self.gamma[0])) ]) self.c = Constant(-self.r) # Init right-hand side self.f = -(self.gamma[0] - self.cost(self.gamma[0])) * P self.u_T = -2 * P * ufl.Max(1000 - Inv, 0) # self.u_T = Constant(0.0) # Set boundary conditions # self.g_t = lambda t : [(Constant(0.0), "near(x[0],0)")] self.g = self.u_T
def mat_per_subdomains(cell_function, mat_dict, topo_dim): """Définir un comportement hétérogène par sous domaine. Parameters ---------- cell_function : FEniCS Mesh function Denified on the cells. Indicates the subdomain to which belongs each cell. mat_dict : dictionnary [description] topo_dim : int [description] Returns ------- C_per FEniCS matrix that represents the stiffness inside the RVE. """ C = [] nb_val = int(topo_dim * (topo_dim + 1) / 2) for i in range(nb_val): Cj = [] for j in range(nb_val): Cj = Cj + [StiffnessComponent(cell_function, mat_dict, i, j, degree=0)] C = C + [Cj] C_per = fe.as_matrix(C) return C_per
def set_D_from_data(phys, data): if data is not None: func, mesh = fields.get_functions(**data) D = func["D"] #dolfin.plot(D[0], title="Dx", interactive=True) D = dolfin.as_matrix(np.diag([D[i] for i in range(phys.dim)])) phys.update(Dp=D, Dm=D)
def updateCoefficients(self): x, y, z = SpatialCoordinate(self.mesh) # Init coefficient matrix self.a = as_matrix([[Constant(1.), Constant(0.), Constant(0.)], [Constant(0.), Constant(1.), Constant(0.)], [Constant(0.), Constant(0.), Constant(1.)]]) # Set up explicit solution print('Chosen alpha is {}'.format(self.alpha)) print('Solution is in H^{}'.format(1.5 + self.alpha)) r = sqrt((x - .5)**2 + (y - .5)**2 + (z - .5)**2) self.u_ = r**self.alpha # Init right-hand side self.f = inner(self.a, grad(grad(self.u_))) # Set boundary conditions to exact solution self.g = self.u_
def bulk_electrostriction(E, e_r, p, direction, q_b): """ calculate the bulk electrostriction force """ pp = as_matrix(p) # photoelestic tensor is stored as as numpy array if direction == 'backward': EE_6vec_r = as_vector([ E[0] * E[0], E[1] * E[1], -E[2] * E[2], 0.0, 0.0, 2.0 * E[0] * E[1] ]) EE_6vec_i = as_vector( [0.0, 0.0, 0.0, 2.0 * E[1] * E[2], 2.0 * E[0] * E[2], 0.0]) sigma_r = -0.5 * epsilon_0 * e_r**2 * pp * EE_6vec_r sigma_i = -0.5 * epsilon_0 * e_r**2 * pp * EE_6vec_i f_r = f_elst_r(sigma_r, sigma_i, q_b) f_i = f_elst_i(sigma_r, sigma_i, q_b) elif direction == 'forward': EE_6vec_r = as_vector([ E[0] * E[0], E[1] * E[1], E[2] * E[2], 0.0, 0.0, 2.0 * E[0] * E[1] ]) # EE_6vec_i, sigma_i, q_b is zero sigma_r = -0.5 * epsilon_0 * e_r**2 * pp * EE_6vec_r # no need to multiply zeros ... f_r = as_vector([ -Dx(sigma_r[0], 0) - Dx(sigma_r[5], 1), -Dx(sigma_r[5], 0) - Dx(sigma_r[1], 1), -Dx(sigma_r[4], 0) - Dx(sigma_r[3], 1) ]) f_i = Constant((0.0, 0.0, 0.0), cell=triangle) #f_i = as_vector([ - q_b*sigma_r[4],- q_b*sigma_r[3],- q_b*sigma_r[2]]) else: raise ValueError('Specify scattering direction as forward or backward') return (f_r, f_i)
def sigma(self, uu): eps = self.RR*self.epsilon(uu)*self.RR.T ss = self.DD*dolfin.as_vector([eps[0, 0], eps[1, 1], eps[2, 2]]) ss_01 = 2*self.G_01*eps[0, 1] ss_02 = 2*self.G_02*eps[0, 2] ss_12 = 2*self.G_12*eps[1, 2] return self.RR.T*dolfin.as_matrix([[ss[0], ss_01, ss_02], [ss_01, ss[1], ss_12], [ss_02, ss_12, ss[2]]])*self.RR
def get_residual_form(u, v, rho_e, phi_angle, k, alpha, method='RAMP', Th=df.Constant(1.)): if method == 'SIMP': C = rho_e**3 else: C = rho_e / (1 + 8. * (1. - rho_e)) E = k # C is the design variable, its values is from 0 to 1 nu = 0.49 # Poisson's ratio lambda_ = E * nu / (1. + nu) / (1 - 2 * nu) mu = E / 2 / (1 + nu) #lame's parameters # Th = df.Constant(5e1) # Th = df.Constant(1.) # Th = df.Constant(5e0) w_ij = 0.5 * (df.grad(u) + df.grad(u).T) v_ij = 0.5 * (df.grad(v) + df.grad(v).T) S = df.as_matrix([[-2., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) L = df.as_matrix([[df.cos(phi_angle), df.sin(phi_angle), 0.], [-df.sin(phi_angle), df.cos(phi_angle), 0.], [0., 0., 1.]]) alpha_e = alpha * C eps = w_ij - alpha_e * Th * L.T * S * L d = len(u) sigm = lambda_ * df.div(u) * df.Identity(d) + 2 * mu * eps a = df.inner(sigm, v_ij) * df.dx return a
def assemble_matrices(self): V = VectorElement("Lagrange", self.mesh.ufl_cell(), self.lagrange_order, dim = 3) self._VComplex = FunctionSpace(self.mesh, V*V) u = TrialFunction(self._VComplex) (ur, ui) = split(u) v = TestFunction(self._VComplex) (vr, vi) = split(v) A_ij = None B_ij = None # construct matrices for each domain if not isinstance(self.materials, collections.Iterable): material = self.materials C = as_matrix(material.el.C) rho = material.el.rho DX = material.domain A_ij = LHS(self.q_b, C, ur, ui, vr, vi, DX) B_ij = RHS(rho, ur, ui, vr, vi, DX) else: counter = 0 # a work around for summing forms for material in self.materials: C = as_matrix(material.el.C) rho = material.el.rho DX = material.domain if counter == 0: A_ij = LHS(self.q_b, C, ur, ui, vr, vi, DX) B_ij = RHS(rho, ur, ui, vr, vi, DX) counter += 1 else: a_ij = LHS(self.q_b, C, ur, ui, vr, vi, DX) b_ij = RHS(rho, ur, ui, vr, vi, DX) A_ij += a_ij B_ij += b_ij # assemble the matrices assemble(A_ij, tensor=self._A) assemble(B_ij, tensor=self._B)
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) self.a = as_matrix([[1., 0.], [0., 1.]]) self.u_ = sin(pi * x) * sin(pi * y) self.f = inner(self.a, grad(grad(self.u_))) self.g = Constant(0.0)
def updateCoefficients(self): # Init coefficient matrix self.a = as_matrix([[.5, 0.95], [.95, 2.]]) # Init right-hand side self.f = 1.0 # Set boundary conditions to exact solution self.g = Constant(0.0)
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) self.a = as_matrix([[1., 0.], [0., 1.]]) self.u_ = x * (1 - x) + y * (1 - y) # self.u_ = sin(x)*exp(cos(y)) self.f = inner(self.a, grad(grad(self.u_))) self.g = self.u_
def __init__(self, V=None, nu=None, ldds=None, outflowds=None, phione=None, phitwo=None): self.mesh = V.mesh() self.n = dolfin.FacetNormal(self.mesh) # self.Id = dolfin.Identity(self.mesh.geometry().dim()) self.ldds = ldds self.outflowds = outflowds self.nu = nu self.A = dolfin.as_matrix([[0., 1.], [-1., 0.]]) pickx = dolfin.as_matrix([[1., 0.], [0., 0.]]) picky = dolfin.as_matrix([[0., 0.], [0., 1.]]) self.phionex = pickx*phione self.phioney = picky*phione self.phitwo = phitwo def epsilon(u): return 0.5*(dolfin.nabla_grad(u) + dolfin.nabla_grad(u).T) self.epsilon = epsilon
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) # Init coefficient matrix self.a = as_matrix([[1.0, self.kappa], [self.kappa, 1.0]]) # Init right-hand side self.f = (1 + x**2) * sin(pi * x) * pi**2 # Set boundary conditions to exact solution self.g = Constant(0.0)
def updateCoefficients(self): # Init coefficient matrix x, y = SpatialCoordinate(self.mesh) self.a = as_matrix([[.02, .01], [0.01, conditional(x**3 - y > 0.0, 2.0, 1.0)]]) # Init right-hand side self.f = -1.0 # Set boundary conditions to exact solution self.g = Constant(0.0)
def __init__(self, mesh, *, domains = None, facets = None, coefficients = None): super().__init__(mesh, domains = domains, facets = facets) coeffs = self.coefficient_functions(coefficients) cos = dolfin.cos(coeffs['angle']) sin = dolfin.sin(coeffs['angle']) ax_0, ax_1, ax_2 = coeffs['axis_0'], coeffs['axis_1'], coeffs['axis_2'] E_0, E_1, E_2 = coeffs['E_0'], coeffs['E_1'], coeffs['E_2'] nu_01, nu_02, nu_12 = coeffs['nu_01'], coeffs['nu_02'], coeffs['nu_12'] self.G_01, self.G_02, self.G_12 = coeffs['G_01'], coeffs['G_02'], coeffs['G_12'] self.RR = dolfin.as_matrix([ [cos + ax_0*ax_0*(1 - cos), ax_0*ax_1*(1 - cos) - ax_2*sin, ax_0*ax_2*(1 - cos) + ax_1*sin], [ax_0*ax_1*(1 - cos) + ax_2*sin, cos + ax_1*ax_1*(1 - cos), ax_1*ax_2*(1 - cos) - ax_0*sin], [ax_0*ax_2*(1 - cos) - ax_1*sin, ax_1*ax_2*(1 - cos) + ax_0*sin, cos + ax_2*ax_2*(1 - cos)] ]) nu_10 = nu_01*E_1/E_0; nu_20 = nu_02*E_2/E_0; nu_21 = nu_12*E_2/E_1 kk = 1 - nu_01*nu_10 - nu_12*nu_21 - nu_02*nu_20 - 2*nu_01*nu_12*nu_20 self.DD = dolfin.as_matrix([ [E_0*(1 - nu_12*nu_21)/kk, E_0*(nu_12*nu_20 + nu_10)/kk, E_0*(nu_21*nu_10 + nu_20)/kk], [E_1*(nu_02*nu_21 + nu_01)/kk, E_1*(1 - nu_02*nu_20)/kk, E_1*(nu_20*nu_01 + nu_21)/kk], [E_2*(nu_01*nu_12 + nu_02)/kk, E_2*(nu_10*nu_02 + nu_12)/kk, E_2*(1 - nu_01*nu_10)/kk] ])
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) self.a = as_matrix([[Constant(1.), Constant(self.kappa)], [Constant(self.kappa), Constant(1.)]]) self.u_ = sin(2 * pi * x) * sin(2 * pi * y) self.f = inner(self.a, grad(grad(self.u_))) self.g = Constant(0.0)
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) z = -1. / ln(sqrt(pow(x, 2) + pow(y, 2))) # Init coefficient matrix self.a = as_matrix([[5 * z + 15, 1.], [1., 1 * z + 3]]) self.u_ = pow(pow(x, 2) + pow(y, 2), 7. / 8) # Init right-hand side self.f = inner(self.a, grad(grad(self.u_))) # Set boundary conditions to exact solution self.g = self.u_
def convert_to_ufl_form(self): #call the member functions self.read_system() self.compute_system() # self.SA_x_ufl = df.as_matrix(self.SA_x) self.SA_y_ufl = df.as_matrix(self.SA_y) self.SP_Coeff_ufl = df.as_matrix(self.SP_Coeff) self.BC1_ufl = df.as_matrix(self.BC1) self.BC2_ufl = df.as_matrix(self.BC2) self.BC1_rhs_ufl = df.as_matrix(self.BC1_rhs) self.BC2_rhs_ufl = df.as_matrix(self.BC2_rhs)
def updateCoefficients(self): # Init coefficient matrix x, y = SpatialCoordinate(self.mesh) off_diag = conditional(x * y > 0, 1.0, -1.0) self.a = as_matrix([[2.0, off_diag], [off_diag, 2.0]]) self.u_ = x * y * (1 - exp(1 - abs(x))) * (1 - exp(1 - abs(y))) # Init right-hand side self.f = inner(self.a, grad(grad(self.u_))) # Set boundary conditions to exact solution self.g = self.u_
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) z = pow(sqrt(pow(x, 2) + pow(y, 2)), .5) # Init coefficient matrix self.a = as_matrix([[z + 1., -z], [-z, 5 * z + 1.]]) self.u_ = sin(2 * pi * x) * sin(2 * pi * y) * exp(x * cos(y)) # Init right-hand side self.f = inner(self.a, grad(grad(self.u_))) # Set boundary conditions to exact solution self.g = self.u_
def updateCoefficients(self): # Init coefficient matrix x, y = SpatialCoordinate(self.mesh) self.a = as_matrix([[1., 0.], [0., (pow(pow(x, 2) * pow(y, 2), 1.0 / 3) + 1.0)]]) # Init exact solution self.u_ = exp(-10 * (pow(x, 2) + pow(y, 2))) # Init right-hand side self.f = inner(self.a, grad(grad(self.u_))) # Set boundary conditions to exact solution self.g = self.u_
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) self.a = as_matrix([[1.0, 0.], [0., 1.]]) # Init right-hand side xi = 0.5 + pi / 100 self.u_ = conditional(x <= xi, 0.0, 0.5 * (x - xi)**2) # self.f = inner(self.a, grad(grad(self.u_))) self.f = conditional(x <= xi, 0.0, 1.0) # Set boundary conditions to exact solution self.g = self.u_
def __init__(self, Vh, covariance, mean=None): """ Constructor Inputs: - :code:`Vh`: Finite element space on which the prior is defined. Must be the Real space with one global degree of freedom - :code:`covariance`: The covariance of the prior. Must be a :code:`numpy.ndarray` of appropriate size - :code:`mean`(optional): Mean of the prior distribution. Must be of type `dolfin.Vector()` """ self.Vh = Vh if Vh.dim() != covariance.shape[0] or Vh.dim() != covariance.shape[1]: raise ValueError("Covariance incompatible with Finite Element space") if not np.issubdtype(covariance.dtype, np.floating): raise TypeError("Covariance matrix must be a float array") self.covariance = covariance #np.linalg.cholesky automatically provides more error checking, #so use those self.chol = np.linalg.cholesky(self.covariance) self.chol_inv = scila.solve_triangular( self.chol, np.identity(Vh.dim()), lower=True) self.precision = np.dot(self.chol_inv.T, self.chol_inv) trial = dl.TrialFunction(Vh) test = dl.TestFunction(Vh) domain_measure_inv = dl.Constant(1.0 \ / dl.assemble(dl.Constant(1.) * dl.dx(Vh.mesh()))) #Identity mass matrix self.M = dl.assemble(domain_measure_inv * dl.inner(trial, test) * dl.dx) self.Msolver = Operator2Solver(self.M) if mean: self.mean = mean else: tmp = dl.Vector() self.M.init_vector(tmp, 0) tmp.zero() self.mean = tmp if Vh.dim() == 1: trial = dl.as_matrix([[trial]]) test = dl.as_matrix([[test]]) #Create form matrices covariance_op = dl.as_matrix(list(map(list, self.covariance))) precision_op = dl.as_matrix(list(map(list, self.precision))) chol_op = dl.as_matrix(list(map(list, self.chol))) chol_inv_op = dl.as_matrix(list(map(list, self.chol_inv))) #variational for the regularization operator, or the precision matrix var_form_R = domain_measure_inv \ * dl.inner(test, dl.dot(precision_op, trial)) * dl.dx #variational for the inverse regularization operator, or the covariance #matrix var_form_Rinv = domain_measure_inv \ * dl.inner(test, dl.dot(covariance_op, trial)) * dl.dx #variational form for the square root of the regularization operator var_form_R_sqrt = domain_measure_inv \ * dl.inner(test, dl.dot(chol_inv_op.T, trial)) * dl.dx #variational form for the square root of the inverse regularization #operator var_form_Rinv_sqrt = domain_measure_inv \ * dl.inner(test, dl.dot(chol_op, trial)) * dl.dx self.R = dl.assemble(var_form_R) self.RSolverOp = dl.assemble(var_form_Rinv) self.Rsolver = Operator2Solver(self.RSolverOp) self.sqrtR = dl.assemble(var_form_R_sqrt) self.sqrtRinv = dl.assemble(var_form_Rinv_sqrt)
def main(): L = 10.0 H = 10.0 mesh = df.UnitSquare(10,10,'left') mesh.coordinates()[:,0] *= L mesh.coordinates()[:,1] *= H U = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=2) U_x, U_y = U.split() u = df.TrialFunction(U) v = df.TestFunction(U) E = 2.0E11 nu = 0.3 lmbda = nu*E/((1.0 + nu)*(1.0 - 2.0*nu)) mu = E/(2.0*(1.0 + nu)) # Elastic Modulus C_numpy = np.array([[lmbda + 2.0*mu, lmbda, 0.0], [lmbda, lmbda + 2.0*mu, 0.0], [0.0, 0.0, mu ]]) C = df.as_matrix(C_numpy) from dolfin import dot, dx, grad, inner, ds def eps(u): """ Returns a vector of strains of size (3,1) in the Voigt notation layout {eps_xx, eps_yy, gamma_xy} where gamma_xy = 2*eps_xy""" return df.as_vector([u[i].dx(i) for i in range(2)] + [u[i].dx(j) + u[j].dx(i) for (i,j) in [(0,1)]]) a = inner(eps(v), C*eps(u))*dx A = a # Dirichlet BC class LeftBoundary(df.SubDomain): def inside(self, x, on_boundary): tol = 1E-14 return on_boundary and np.abs(x[0]) < tol class RightBoundary(df.SubDomain): def inside(self, x, on_boundary): tol = 1E-14 return on_boundary and np.abs(x[0] - self.L) < tol class BottomBoundary(df.SubDomain): def inside(self, x, on_boundary): tol = 1E-14 return on_boundary and np.abs(x[1]) < tol left_boundary = LeftBoundary() right_boundary = RightBoundary() right_boundary.L = L bottom_boundary = BottomBoundary() zero = df.Constant(0.0) bc_left_Ux = df.DirichletBC(U_x, zero, left_boundary) bc_bottom_Uy = df.DirichletBC(U_y, zero, bottom_boundary) bcs = [bc_left_Ux, bc_bottom_Uy] # Neumann BCs t = df.Constant(10000.0) boundary_parts = df.EdgeFunction("uint", mesh, 1) right_boundary.mark(boundary_parts, 0) l = inner(t,v[0])*ds(0) u_h = df.Function(U) problem = df.LinearVariationalProblem(A, l, u_h, bcs=bcs) solver = df.LinearVariationalSolver(problem) solver.parameters["linear_solver"] = "direct" solver.solve() u_x, u_y = u_h.split() stress = df.project(C*eps(u_h), df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3)) df.plot(u_x) df.plot(u_y) df.plot(stress[0]) df.interactive()