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 eval(self, values, x): # Discretize control set n_alpha = 200 alpha_space = np.linspace(self.amin, self.amax, n_alpha + 1) alpha_space = alpha_space[:-1] vxx = np.ndarray((1, )) vxy = np.ndarray((1, )) vyx = np.ndarray((1, )) vyy = np.ndarray((1, )) self.dxx.eval(vxx, x) self.dxy.eval(vxy, x) self.dyx.eval(vyx, x) self.dyy.eval(vyy, x) maxres = -1e10 # print(x) for alpha in alpha_space: R = np.array([[cos(alpha), -sin(alpha)], [sin(alpha), cos(alpha)]]) A = 0.5 * R.T @ np.array([[20, 1], [1, 0.1]]) @ R res = A[0, 0] * vxx \ + A[0, 1] * vxy \ + A[1, 0] * vyx \ + A[1, 1] * vyy if res > maxres: maxres = res values[:] = alpha
def get_N_form(self): try: return self.N_form except AttributeError: pass # Set up magnetic field and equivalent electric current forms H_r = -curl(self.E_i)/(self.k0*Z0) H_i = curl(self.E_r)/(self.k0*Z0) J_r = cross(self.n, H_r) J_i = cross(self.n, H_i) #------------------------------ # Set up form for far field potential N theta_hat = self.theta_hat phi_hat = self.phi_hat phase = self.phase N_r = J_r*dolfin.cos(phase) - J_i*dolfin.sin(phase) N_i = J_r*dolfin.sin(phase) + J_i*dolfin.cos(phase) # UFL does not seem to like vector valued functionals, so we split the # final functional from into theta and phi components self.N_form = dict( r_theta=dot(theta_hat, N_r)*ds, r_phi=dot(phi_hat, N_r)*ds, i_theta=dot(theta_hat, N_i)*ds, i_phi=dot(phi_hat, N_i)*ds) return self.N_form
def __init__(self, mock_problem, expression_type, basis_generation): self.V = mock_problem.V # Parametrized function to be interpolated mu = SymbolicParameters(mock_problem, self.V, (1., )) x = SpatialCoordinate(self.V.mesh()) f = (1 - x[0]) * cos(3 * pi * mu[0] * (1 + x[0])) * exp(-mu[0] * (1 + x[0])) # folder_prefix = os.path.join("test_eim_approximation_09_tempdir", expression_type, basis_generation) assert expression_type in ("Function", "Vector", "Matrix") if expression_type == "Function": # Call Parent constructor EIMApproximation.__init__(self, mock_problem, ParametrizedExpressionFactory(f), folder_prefix, basis_generation) elif expression_type == "Vector": v = TestFunction(self.V) form = f * v * dx # Call Parent constructor EIMApproximation.__init__(self, mock_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation) elif expression_type == "Matrix": u = TrialFunction(self.V) v = TestFunction(self.V) form = f * u * v * dx # Call Parent constructor EIMApproximation.__init__(self, mock_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation) else: # impossible to arrive here anyway thanks to the assert raise AssertionError("Invalid expression_type")
def __init__(self, V, **kwargs): # Call parent ParametrizedProblem.__init__( self, os.path.join("test_eim_approximation_14_tempdir", expression_type, basis_generation, "mock_problem")) # Minimal subset of a ParametrizedDifferentialProblem self.V = V self._solution = Function(V) self.components = ["u", "s", "p"] # Parametrized function to be interpolated x = SpatialCoordinate(V.mesh()) mu = SymbolicParameters(self, V, (1., )) self.f00 = (1 - x[0]) * cos(3 * pi * mu[0] * (1 + x[0])) * exp(-mu[0] * (1 + x[0])) self.f01 = (1 - x[0]) * sin(3 * pi * mu[0] * (1 + x[0])) * exp(-mu[0] * (1 + x[0])) # Inner product f = TrialFunction(self.V) g = TestFunction(self.V) self.inner_product = assemble(inner(f, g) * dx) # Collapsed vector and space self.V0 = V.sub(0).collapse() self.V00 = V.sub(0).sub(0).collapse() self.V1 = V.sub(1).collapse()
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 get_L_form(self): try: return self.L_form except AttributeError: pass # Set up equivalent magnetic current forms M_r = -cross(self.n, self.E_r) M_i = -cross(self.n, self.E_i) #------------------------------ # Set up form for far field potential L theta_hat = self.theta_hat phi_hat = self.phi_hat phase = self.phase L_r = M_r * dolfin.cos(phase) - M_i * dolfin.sin(phase) L_i = M_r * dolfin.sin(phase) + M_i * dolfin.cos(phase) self.L_form = dict(r_theta=dot(theta_hat, L_r) * ds, r_phi=dot(phi_hat, L_r) * ds, i_theta=dot(theta_hat, L_i) * ds, i_phi=dot(phi_hat, L_i) * ds) return self.L_form
def get_L_form(self): try: return self.L_form except AttributeError: pass # Set up equivalent magnetic current forms M_r = -cross(self.n, self.E_r) M_i = -cross(self.n, self.E_i) #------------------------------ # Set up form for far field potential L theta_hat = self.theta_hat phi_hat = self.phi_hat phase = self.phase L_r = M_r*dolfin.cos(phase) - M_i*dolfin.sin(phase) L_i = M_r*dolfin.sin(phase) + M_i*dolfin.cos(phase) self.L_form = dict( r_theta=dot(theta_hat, L_r)*ds, r_phi=dot(phi_hat, L_r)*ds, i_theta=dot(theta_hat, L_i)*ds, i_phi=dot(phi_hat, L_i)*ds) return self.L_form
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): x, y = SpatialCoordinate(self.mesh) # Init coefficient matrix self.a = as_matrix( [[pow(abs(sin(4 * pi * (x - 0.5))), 1.0 / 5), cos(2 * pi * x * y)], [ cos(2 * pi * x * y), pow(abs(sin(4 * pi * (y - 0.5))), 1.0 / 5) + 1. ]]) # Init exact solution self.u_ = x * y * sin(2 * pi * x) * sin( 3 * pi * y) / (pow(x, 2) + pow(y, 2) + 1) # 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 initControl(self): self.controlSpace = [ FunctionSpace(self.mesh, "DG", 1), FunctionSpace(self.mesh, "DG", 1) ] u_x = Dx(self.u, 0) u_y = Dx(self.u, 1) # phi = atan(u_y/u_x) <==> sin(phi) / cos(phi) = u_y / u_x self.gamma = [] phi = ufl.atan_2(u_y, u_x) self.gamma.append(1. / self.alpha * (cos(phi) * u_x + sin(phi) * u_y)) self.gamma.append(phi)
def __init__(self, V, **kwargs): # Call parent ParametrizedProblem.__init__(self, os.path.join("test_eim_approximation_12_tempdir", expression_type, basis_generation, "mock_problem")) # Minimal subset of a ParametrizedDifferentialProblem self.V = V self._solution = Function(V) self.components = ["u"] # Parametrized function to be interpolated x = SpatialCoordinate(V.mesh()) mu = SymbolicParameters(self, V, (1., )) self.f = (1-x[0])*cos(3*pi*mu[0]*(1+x[0]))*exp(-mu[0]*(1+x[0])) # Inner product f = TrialFunction(self.V) g = TestFunction(self.V) self.inner_product = assemble(f*g*dx)
def get_N_form(self): try: return self.N_form except AttributeError: pass # Set up magnetic field and equivalent electric current forms H_r = -curl(self.E_i) / (self.k0 * Z0) H_i = curl(self.E_r) / (self.k0 * Z0) J_r = cross(self.n, H_r) J_i = cross(self.n, H_i) #------------------------------ # Set up form for far field potential N theta_hat = self.theta_hat phi_hat = self.phi_hat phase = self.phase N_r = J_r * dolfin.cos(phase) - J_i * dolfin.sin(phase) N_i = J_r * dolfin.sin(phase) + J_i * dolfin.cos(phase) # UFL does not seem to like vector valued functionals, so we split the # final functional from into theta and phi components self.N_form = dict(r_theta=dot(theta_hat, N_r) * ds, r_phi=dot(phi_hat, N_r) * ds, i_theta=dot(theta_hat, N_i) * ds, i_phi=dot(phi_hat, N_i) * ds) return self.N_form
def updateCoefficients(self): # Init coefficient matrix x, y = SpatialCoordinate(self.mesh) self.a = as_matrix([[1.0, 0.0], [0.0, 1.0]]) # self.a = as_matrix([[1.0 , 0.0], [0.0, 1.0]]) self.b = -self.gamma[0] * \ as_vector([cos(self.gamma[1]), sin(self.gamma[1])]) # self.u_ = x*y*(1-exp(1-abs(x))) * (1-exp(1-abs(y))) # Init right-hand side self.f = -1 \ - 0.5 * self.alpha * sqrt(pow(self.gamma[0], 2)) # Set boundary conditions 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 linear_interpolation_two(self, image0, image1, n): """ Define a linear interpolation between two states of the energy band (m0, m1) to get an initial state. The interpolation is done in the magnetic moments that constitute the magnetic system. """ # Get the spherical coordinates dolfin functions # for the m0 and m1 magnetisation vector fields self.sim.set_m(self.initial_images[image0]) theta0, phi0 = self.sim._m_field.get_spherical() self.sim.set_m(self.initial_images[image1]) theta1, phi1 = self.sim._m_field.get_spherical() # To not depend on numpy arrays, we will assemble every # interpolation into dolfin functions and assign their # values to the subdomains of the MixedFunctionSpace of images # Create a scalar Function Space S1 = df.FunctionSpace(self.sim.m_field.functionspace.mesh(), 'CG', 1) # Define a variable to use as vector in all the assemble instances assemble_vector = None # Define the interpolations step for theta assemble_vector = df.assemble(df.dot((theta1 - theta0) / (n + 1)) * df.dP, tensor=assemble_vector) dtheta = df.Function(S1) dtheta.vector().axpy(1, assemble_vector) # The same for Phi assemble_vector = df.assemble(df.dot((theta1 - theta0) / (n + 1)) * df.dP, tensor=assemble_vector) dphi = df.Function(S1) dphi.vector().axpy(1, assemble_vector) # Now loop for every interpolation and assign it to # the MixedFunctionSpace for i in xrange(n): # Create a dolfin function from the FS, for the interpolation interpolation_theta = df.Function(S1) interpolation_phi = df.Function(S1) # Compute the radius using the assemble method with dolfin dP # (like a dirac delta to get values on every node of the mesh) # This returns a dolfin vector # Theta assemble_vector = df.assemble(df.dot(theta0 + (i + 1) * dtheta, # df.TestFunction(S1)) * df.dP, tensor=assemble_vector ) # Set the vector values to the dolfin function interpolation_theta.vector().axpy(1, assemble_vector) # Phi assemble_vector = df.assemble(df.dot(phi0 + (i + 1) * dphi, # df.TestFunction(S1)) * df.dP, tensor=assemble_vector ) # Set the vector values to the dolfin function interpolation_phi.vector().axpy(1, assemble_vector) # Now set this interpolation to the corresponding image # Set a vector function space for the simulation # magnetisation vector field interpolation = df.VectorFunction(self.sim.S3) interpolation = df.assemble(df.dot(df.as_vector((df.sin(interpolation_theta) * df.cos(interpolation_phi), df.sin(interpolation_theta) * df.sin(interpolation_phi), df.cos(interpolation_theta) )), df.TestFunction(self.sim.S3)) * df.dP ) interpolation.vector().axpy(1, interpolation) # Now assign the interpolation vector function values to the corresponding # image in the MixedFunctionSpace df.assign(self.images_fun.sub(i), interpolation)
def eval(self, values, x): y_0 = -H + a0 * (exp(-((x[0]-L/2.)**2 + (x[1]-L/2.)**2) / sigma**2)) values[0] = sin(theta)/cos(theta) * (x[0] + sin(theta)*y_0) \ + cos(theta)*y_0
n = FacetNormal(multimesh) s_top = deformation_vector() s_bottom = project_to_background(s_top) # Create Spatial Coordinates for each mesh x0 = SpatialCoordinate(meshes[0]) x1 = SpatialCoordinate(meshes[1]) degree = 2 V = MultiMeshFunctionSpace(multimesh, "CG", degree) # Assign a function to each mesh, such that T and lmb are discontinuous at the # interface Gamma T = MultiMeshFunction(V) T.assign_part(0, project(sin(x0[1]), FunctionSpace(meshes[0], "CG", degree))) T.assign_part( 1, project(cos(x1[0]) * x1[1], FunctionSpace(meshes[1], "CG", degree))) lmb = MultiMeshFunction(V) lmb.assign_part( 0, project(cos(x0[1]) * x0[0], FunctionSpace(meshes[0], "CG", degree))) lmb.assign_part( 1, project(x1[0] * sin(x1[1]), FunctionSpace(meshes[1], "CG", degree))) # Create bilinear form and corresponding gradients #---------------------------------------------------------------------------- a1 = inner(grad(T), grad(lmb)) * dX # Classic shape derivative term top mesh da1_top = div(s_top) * inner(grad(T), grad(lmb)) * dX # Term stemming from grad(T) da1_top -= inner(dot(grad(s_top), grad(T)), grad(lmb)) * dX # Term stemming from grad(lmb)