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 __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_17_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., -1.)) self.f00 = 1. / sqrt( pow(x[0] - mu[0], 2) + pow(x[1] - mu[1], 2) + 0.01) self.f01 = 1. / sqrt( pow(x[0] - mu[0], 4) + pow(x[1] - mu[1], 4) + 0.01) # 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 recompute_dJ(self): """ Create gradient expression for deformation algorithm """ # FIXME: probably only works with one obstacle # Recalculate barycenter and volume of obstacle self.geometric_quantities() self.integrand_list = [] dJ = 0 solver.dJ_form = [] for i in range(1, self.N): # Integrand of gradient x = SpatialCoordinate(self.multimesh.part(i)) u_i = self.u.part(i) dJ_stokes = -inner(grad(u_i), grad(u_i)) dJ_vol = -Constant(2 * self.vfac) * (self.Vol - self.Vol0) dJ_bar = Constant(2 * self.bfac) / self.Vol * ( (self.bx - x[0]) * self.bxoff + (self.by - x[1]) * self.byoff) integrand = dJ_stokes + dJ_vol + dJ_bar dDeform = Measure("ds", subdomain_data=self.mfs[i]) from femorph import VolumeNormal n = VolumeNormal(self.multimesh.part(i)) s = TestFunction(self.S[i]) self.integrand_list.append(n * integrand) dJ = inner(s, n) * integrand * dDeform(self.move_dict[i]["Deform"]) self.dJ_form.append(dJ)
def solve(self, dt): self.u = Function(self.V0) self.w = TestFunction(self.V0) self.du = TrialFunction(self.V0) x = SpatialCoordinate(self.mesh0) L = inner( self.S(), self.eps(self.w) )*dx(degree=4)\ - inner( self.b, self.w )*dx(degree=4)\ - inner( self.h, self.w )*ds(degree=4)\ + inner( 1e-6*self.u, self.w )*ds(degree=4)\ - inner( min_value(x[2]+self.ut[2]+self.u[2], 0) * Constant((0,0,-1.0)), self.w )*ds(degree=4) a = derivative(L, self.u, self.du) problem = NonlinearVariationalProblem(L, self.u, bcs=[], J=a) solver = NonlinearVariationalSolver(problem) solver.solve() self.ut.vector()[:] = self.ut.vector()[:] + self.u.vector()[:] ALE.move(self.mesh, Function(self.V, self.u.vector())) self.v.vector()[:] = self.u.vector()[:] / dt self.n = FacetNormal(self.mesh)
def __init__(self, ui, time_step_method, rho, mu, u, p0, dt, bcs, f, my_dx): super(TentativeVelocityProblem, self).__init__() W = ui.function_space() v = TestFunction(W) self.bcs = bcs r = SpatialCoordinate(ui.function_space().mesh())[0] def me(uu, ff): return _momentum_equation(uu, v, p0, ff, rho, mu, my_dx) self.F0 = rho * dot(ui - u[0], v) / dt * 2 * pi * r * my_dx if time_step_method == "forward euler": self.F0 += me(u[0], f[0]) elif time_step_method == "backward euler": self.F0 += me(ui, f[1]) else: assert ( time_step_method == "crank-nicolson" ), "Unknown time stepper '{}'".format( time_step_method ) self.F0 += 0.5 * (me(u[0], f[0]) + me(ui, f[1])) self.jacobian = derivative(self.F0, ui) self.reset_sparsity = True return
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 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 = 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 test_local_assembler_on_facet_integrals(): mesh = UnitSquareMesh(MPI.comm_world, 4, 4, 'right') Vdgt = FunctionSpace(mesh, 'DGT', 1) v = TestFunction(Vdgt) x = SpatialCoordinate(mesh) w = (1.0 + x[0] ** 2.2 + 1. / (0.1 + x[1] ** 3)) * 300 # Define form that tests that the correct + and - values are used L = w('-') * v('+') * dS # Compile form. This is collective L = Form(L) # Get global cell 10. This will return a cell only on one of the # processes c = get_cell_at(mesh, 5 / 12, 1 / 3, 0) if c: # Assemble locally on the selected cell b_e = assemble_local(L, c) # Compare to values from phonyx (fully independent # implementation) b_phonyx = numpy.array([266.55210302, 266.55210302, 365.49000122, 365.49000122, 0.0, 0.0]) error = sum((b_e - b_phonyx)**2)**0.5 error = float(error) # MPI.max does strange things to numpy.float64 else: error = 0.0 error = MPI.max(MPI.comm_world, float(error)) assert error < 1e-8
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 initControl(self): self.controlSpace = [FunctionSpace(self.mesh, "DG", 0)] x, y = SpatialCoordinate(self.mesh) u_ = (2*x-1.) \ * (exp(1 - abs(2*x-1.)) - 1) \ * (y + (1 - exp(y/self.delta))/(exp(1/self.delta)-1)) cs = self.controlSpace[0] du = self.u - u_ du_xx = Dx(Dx(du, 0), 0) du_xy = Dx(Dx(du, 0), 1) du_yx = Dx(Dx(du, 1), 0) du_yy = Dx(Dx(du, 1), 1) du_xx_proj = project(du_xx, cs) du_xy_proj = project(du_xy, cs) du_yx_proj = project(du_yx, cs) du_yy_proj = project(du_yy, cs) # Use the UserExpression gamma_star = Gallistl_Sueli_1_optControl(du_xx_proj, du_xy_proj, du_yx_proj, du_yy_proj, self.alphamin, self.alphamax) # Interpolate evaluates expression in centers of mass # Project evaluates expression in vertices self.gamma = [gamma_star]
def get_voltage_current_matrix(phi, physical_indices, dx, Sigma, omega, v_ref): """Compute the matrix that relates the voltages with the currents in the coil rings. (The relationship is indeed linear.) This is according to :cite:`KP02`. The entry :math:`J_{k,l}` in the resulting matrix is the contribution of the potential generated by coil :math:`l` to the current in coil :math:`k`. """ mesh = phi[0].function_space().mesh() r = SpatialCoordinate(mesh)[0] num_coil_rings = len(phi) J = numpy.empty((num_coil_rings, num_coil_rings), dtype=numpy.complex) for l, pi0 in enumerate(physical_indices): partial_phi_r, partial_phi_i = phi[l].split() for k, pi1 in enumerate(physical_indices): # -1i*omega*int_{coil_k} sigma phi. int_r = assemble(Sigma[pi1] * partial_phi_r * dx(pi1)) int_i = assemble(Sigma[pi1] * partial_phi_i * dx(pi1)) J[k][l] = -1j * omega * (int_r + 1j * int_i) # v_ref/(2*pi) * int_{coil_l} sigma/r. # 1/r doesn't explode since we only evaluate it in the coils where # r!=0. # For assemble() to work, a mesh needs to be supplied either implicitly # by the integrand, or explicitly. Since the integrand doesn't contain # mesh information here, pass it through explicitly. J[l][l] += v_ref / (2 * pi) * assemble(Sigma[pi0] / r * dx(pi0)) return J
def compute_velocity_correction( ui, p0, p1, u_bcs, rho, mu, dt, rotational_form, my_dx, tol, verbose ): """Compute the velocity correction according to .. math:: U = u_0 - \\frac{dt}{\\rho} \\nabla (p_1-p_0). """ W = ui.function_space() P = p1.function_space() u = TrialFunction(W) v = TestFunction(W) a3 = dot(u, v) * my_dx phi = Function(P) phi.assign(p1) if p0: phi -= p0 if rotational_form: r = SpatialCoordinate(W.mesh())[0] div_ui = 1 / r * (r * ui[0]).dx(0) + ui[1].dx(1) phi += mu * div_ui L3 = dot(ui, v) * my_dx - dt / rho * (phi.dx(0) * v[0] + phi.dx(1) * v[1]) * my_dx u1 = Function(W) solve( a3 == L3, u1, bcs=u_bcs, solver_parameters={ "linear_solver": "iterative", "symmetric": True, "preconditioner": "hypre_amg", "krylov_solver": { "relative_tolerance": tol, "absolute_tolerance": 0.0, "maximum_iterations": 100, "monitor_convergence": verbose, }, }, ) # u = project(ui - k/rho * grad(phi), V) # div_u = 1/r * div(r*u) r = SpatialCoordinate(W.mesh())[0] div_u1 = 1.0 / r * (r * u1[0]).dx(0) + u1[1].dx(1) info("||u||_div = {:e}".format(sqrt(assemble(div_u1 * div_u1 * my_dx)))) return u1
def updateControl(self): """ The optimal continuous control in this example depends on the gradient. """ x, y = SpatialCoordinate(self.mesh) # Dxu = project(Dx(self.u,0),FunctionSpace(self.mesh, "DG", 0)) Dxxu = Dx(Dx(self.u, 0), 0) Dxxu = self.H[0, 0] self.gamma[0] = .5 * (x**2) * Dxxu
def __init__(self, WPQ, kappa, rho, rho_const, mu, cp, g, extra_force, heat_source, u_bcs, p_bcs, theta_dirichlet_bcs=None, theta_neumann_bcs=None, theta_robin_bcs=None, my_dx=dx, my_ds=ds): super(StokesHeat, self).__init__() theta_dirichlet_bcs = theta_dirichlet_bcs or {} theta_neumann_bcs = theta_neumann_bcs or {} theta_robin_bcs = theta_robin_bcs or {} # Translate the Dirichlet boundary conditions into the product space. self.dirichlet_bcs = helpers.dbcs_to_productspace( WPQ, [u_bcs, p_bcs, theta_dirichlet_bcs]) self.uptheta = Function(WPQ) u, p, theta = split(self.uptheta) v, q, zeta = TestFunctions(WPQ) mesh = WPQ.mesh() r = SpatialCoordinate(mesh)[0] # Right-hand side for momentum equation. f = rho(theta) * g # coupling if extra_force is not None: f += as_vector((extra_force[0], extra_force[1], 0.0)) self.stokes_F = stokes.F(u, p, v, q, f, r, mu, my_dx) self.heat_F = heat.F( theta, zeta, kappa=kappa, rho=rho_const, cp=cp, convection=u, # coupling source=heat_source, r=r, neumann_bcs=theta_neumann_bcs, robin_bcs=theta_robin_bcs, my_dx=my_dx, my_ds=my_ds) self.F0 = self.stokes_F + self.heat_F self.jacobian = derivative(self.F0, self.uptheta) return
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 _init_geometric_functions(self): """ Helper initializer to compute original volume and barycenter of the obstacle. """ x = SpatialCoordinate(self.mesh) VolOmega = assemble(Constant(1)*dx(domain=self.mesh)) self.Vol0 = Constant(1 - VolOmega) self.bx0 = Constant((Constant(1./2)-assemble(x[0]*dx))/self.Vol0) self.by0 = Constant((Constant(1./2)-assemble(x[1]*dx))/self.Vol0)
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 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 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 compute_volume_bary(self): """ Compute barycenter and volume of obstacle with current mesh """ x = SpatialCoordinate(self.mesh) VolOmega = assemble(Constant(1)*dx(domain=self.mesh)) self.Vol = Constant(1 - VolOmega) self.bx = Constant((Constant(1./2)-assemble(x[0]*dx))/self.Vol) self.by = Constant((Constant(1./2)-assemble(x[1]*dx))/self.Vol) self.bx_off = self.bx - self.bx0 self.by_off = self.by - self.by0 self.vol_off = self.Vol - self.Vol0
def initControl(self): # Initialize control spaces self.controlSpace = [FunctionSpace(self.mesh, "DG", 1)] # Initialize controls x = SpatialCoordinate(self.mesh)[0] u_x = Dx(self.u, 0) u_xx = Dx(u_x, 0) g1 = conditional( x > 0, -(self.mu - self.r) * u_x / (x * self.sigmax**2 * u_xx), 0) self.gamma = [g1]
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 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_