def solveFwd(self, state, x): """ Solve the possibly nonlinear forward problem: Given :math:`m`, find :math:`u` such that .. math:: \\delta_p F(u, m, p;\\hat{p}) = 0,\\quad \\forall \\hat{p}.""" self.n_calls["forward"] += 1 if self.solver is None: self.solver = self._createLUSolver() if self.is_fwd_linear: u = dl.TrialFunction(self.Vh[STATE]) m = vector2Function(x[PARAMETER], self.Vh[PARAMETER]) p = dl.TestFunction(self.Vh[ADJOINT]) res_form = self.varf_handler(u, m, p) A_form = ufl.lhs(res_form) b_form = ufl.rhs(res_form) A, b = dl.assemble_system(A_form, b_form, bcs=self.bc) self.solver.set_operator(A) self.solver.solve(state, b) else: u = vector2Function(x[STATE], self.Vh[STATE]) m = vector2Function(x[PARAMETER], self.Vh[PARAMETER]) p = dl.TestFunction(self.Vh[ADJOINT]) res_form = self.varf_handler(u, m, p) dl.solve(res_form == 0, u, self.bc) state.zero() state.axpy(1., u.vector())
def test_lhs_rhs_simple(): """Test taking lhs/rhs of DOLFIN specific forms (constants without cell). """ mesh = RectangleMesh(MPI.comm_world, [numpy.array([0.0, 0.0, 0.0]), numpy.array([2.0, 1.0, 0.0])], [3, 5], CellType.triangle) V = FunctionSpace(mesh, "CG", 1) f = 2.0 g = 3.0 v = TestFunction(V) u = TrialFunction(V) F = inner(g * grad(f * v), grad(u)) * dx + f * v * dx a, L = system(F) Fl = lhs(F) Fr = rhs(F) assert(Fr) a0 = inner(grad(v), grad(u)) * dx n = assemble(a).norm("frobenius") # noqa nl = assemble(Fl).norm("frobenius") # noqa n0 = 6.0 * assemble(a0).norm("frobenius") # noqa assert round(n - n0, 7) == 0 assert round(n - nl, 7) == 0
def forward(x): u = fn.TrialFunction(V) w = fn.TestFunction(V) sigma = lmbda * tr(sym(grad(u))) * Identity(2) + 2 * G * sym( grad(u)) # Stress R = simp(x) * inner(sigma, grad(w)) * dx - dot(b, w) * dx a, L = ufl.lhs(R), ufl.rhs(R) u = fa.Function(V) fa.solve(a == L, u, bcs) return u
def jvp_solve_eval( fenics_function: Callable, fenics_templates: Iterable[FenicsVariable], primals: Tuple[np.array], tangents: Tuple[np.array], ) -> Tuple[np.array]: """Computes the tangent linear model """ ( numpy_output_primal, fenics_solution_primal, residual_form, fenics_primals, bcs, ) = solve_eval(fenics_function, fenics_templates, *primals) # Now tangent evaluation! F = residual_form u = fenics_solution_primal V = u.function_space() if len(bcs) != 0: for bc in bcs: bc.homogenize() hbcs = bcs fenics_tangents = convert_all_to_fenics(fenics_primals, *tangents) fenics_output_tangents = [] for fp, ft in zip(fenics_primals, fenics_tangents): dFdu = fenics.derivative(F, u) dFdm = fenics.derivative(F, fp, ft) u_tlm = fenics.Function(V) tlm_F = ufl.action(dFdu, u_tlm) + dFdm tlm_F = ufl.replace(tlm_F, {u_tlm: fenics.TrialFunction(V)}) fenics.solve(ufl.lhs(tlm_F) == ufl.rhs(tlm_F), u_tlm, bcs=hbcs) fenics_output_tangents.append(u_tlm) jax_output_tangents = (fenics_to_numpy(ft) for ft in fenics_output_tangents) jax_output_tangent = sum(jax_output_tangents) return numpy_output_primal, jax_output_tangent
amplitude_list[i], center=sources_positions[i]) for i in range(len(omega_p_list)) ] g = sum(pulses) F = rho * inner(a_ * N_ddot(u, u0, a0, v0, dt, beta) \ + b_ * N_dot(u, u0, v0, a0, dt, beta, gamma) + c_ * u, w) * dx \ + inner(N_dot(S, U0, V0, A0, dt, beta, gamma).T * Lambda_e + S.T * Lambda_p, grad(w)) * dx \ - inner(g, w) * ds \ + inner(compliance(a_ * N_ddot(S, U0, A0, V0, dt, beta) + b_ * N_dot(S, U0, V0, A0, dt, beta, gamma) + c_ * S, u, mu, lmbda), T) * dx \ - 0.5 * inner(grad(u) * Lambda_p + Lambda_p * grad(u).T + grad(N_dot(u, u0, v0, a0, dt, beta, gamma)) * Lambda_e \ + Lambda_e * grad(N_dot(u, u0, v0, a0, dt, beta, gamma)).T, T) * dx \ a, L = lhs(F), rhs(F) # Assemble rhs (once) A = assemble(a) # Create GMRES Krylov solver solver = KrylovSolver(A, "gmres") # Create solution function S = Function(W) experiment_count_file = open("experiment_counter", 'rb') experiment_count = pickle.load(experiment_count_file) experiment_count_file.close() paraview_file_name = "experiment_{}".format(experiment_count)
k_absorb = Function(V) k_absorb.interpolate(adiabatic_layer) # Interpolate incident wave field onto V ui = Function(V) ui.interpolate(incident) # Define variational problem u = TrialFunction(V) v = TestFunction(V) F = inner(grad(u), grad(v)) * dx - k0**2 * inner(u, v) * dx - \ k_absorb * inner(u, v) * dx \ + inner(dot(grad(ui), n), v) * ds(1) a = lhs(F) L = rhs(F) ''' Assemble matrix and vector and set up direct solver ''' A = dolfinx.fem.assemble_matrix(a) A.assemble() b = dolfinx.fem.assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) solver = PETSc.KSP().create(mesh.mpi_comm()) opts = PETSc.Options() opts["ksp_type"] = "preonly" opts["pc_type"] = "lu" opts["pc_factor_mat_solver_type"] = "mumps" solver.setFromOptions() solver.setOperators(A)
def forward(mu_expression, lmbda_expression, rho, Lx=10, Ly=10, t_end=1, omega_p=5, amplitude=5000, center=0, target=False): Lpml = Lx / 10 #c_p = cp(mu.vector(), lmbda.vector(), rho) max_velocity = 200 #c_p.max() stable_hx = stable_dx(max_velocity, omega_p) nx = int(Lx / stable_hx) + 1 #nx = max(nx, 60) ny = int(Ly * nx / Lx) + 1 mesh = mesh_generator(Lx, Ly, Lpml, nx, ny) used_hx = Lx / nx dt = stable_dt(used_hx, max_velocity) cfl_ct = cfl_constant(max_velocity, dt, used_hx) print(used_hx, stable_hx) print(cfl_ct) #time.sleep(10) PE = FunctionSpace(mesh, "DG", 0) mu = interpolate(mu_expression, PE) lmbda = interpolate(lmbda_expression, PE) m = 2 R = 10e-8 t = 0.0 gamma = 0.50 beta = 0.25 ff = MeshFunction("size_t", mesh, mesh.geometry().dim() - 1) Dirichlet(Lx, Ly, Lpml).mark(ff, 1) # Create function spaces VE = VectorElement("CG", mesh.ufl_cell(), 1, dim=2) TE = TensorElement("DG", mesh.ufl_cell(), 0, shape=(2, 2), symmetry=True) W = FunctionSpace(mesh, MixedElement([VE, TE])) F = FunctionSpace(mesh, "CG", 2) V = W.sub(0).collapse() M = W.sub(1).collapse() alpha_0 = Alpha_0(m, stable_hx, R, Lpml) alpha_1 = Alpha_1(alpha_0, Lx, Lpml, degree=2) alpha_2 = Alpha_2(alpha_0, Ly, Lpml, degree=2) beta_0 = Beta_0(m, max_velocity, R, Lpml) beta_1 = Beta_1(beta_0, Lx, Lpml, degree=2) beta_2 = Beta_2(beta_0, Ly, Lpml, degree=2) alpha_1 = interpolate(alpha_1, F) alpha_2 = interpolate(alpha_2, F) beta_1 = interpolate(beta_1, F) beta_2 = interpolate(beta_2, F) a_ = alpha_1 * alpha_2 b_ = alpha_1 * beta_2 + alpha_2 * beta_1 c_ = beta_1 * beta_2 Lambda_e = as_tensor([[alpha_2, 0], [0, alpha_1]]) Lambda_p = as_tensor([[beta_2, 0], [0, beta_1]]) a_ = alpha_1 * alpha_2 b_ = alpha_1 * beta_2 + alpha_2 * beta_1 c_ = beta_1 * beta_2 Lambda_e = as_tensor([[alpha_2, 0], [0, alpha_1]]) Lambda_p = as_tensor([[beta_2, 0], [0, beta_1]]) # Set up boundary condition bc = DirichletBC(W.sub(0), Constant(("0.0", "0.0")), ff, 1) # Create measure for the source term dx = Measure("dx", domain=mesh) ds = Measure("ds", domain=mesh, subdomain_data=ff) # Set up initial values u0 = Function(V) u0.set_allow_extrapolation(True) v0 = Function(V) a0 = Function(V) U0 = Function(M) V0 = Function(M) A0 = Function(M) # Test and trial functions (u, S) = TrialFunctions(W) (w, T) = TestFunctions(W) g = ModifiedRickerPulse(0, omega_p, amplitude, center) F = rho * inner(a_ * N_ddot(u, u0, a0, v0, dt, beta) \ + b_ * N_dot(u, u0, v0, a0, dt, beta, gamma) + c_ * u, w) * dx \ + inner(N_dot(S, U0, V0, A0, dt, beta, gamma).T * Lambda_e + S.T * Lambda_p, grad(w)) * dx \ - inner(g, w) * ds \ + inner(compliance(a_ * N_ddot(S, U0, A0, V0, dt, beta) + b_ * N_dot(S, U0, V0, A0, dt, beta, gamma) + c_ * S, u, mu, lmbda), T) * dx \ - 0.5 * inner(grad(u) * Lambda_p + Lambda_p * grad(u).T + grad(N_dot(u, u0, v0, a0, dt, beta, gamma)) * Lambda_e \ + Lambda_e * grad(N_dot(u, u0, v0, a0, dt, beta, gamma)).T, T) * dx \ a, L = lhs(F), rhs(F) # Assemble rhs (once) A = assemble(a) # Create GMRES Krylov solver solver = KrylovSolver(A, "gmres") # Create solution function S = Function(W) if target: xdmffile_u = XDMFFile("inversion_temporal_file/target/u.xdmf") pvd = File("inversion_temporal_file/target/u.pvd") xdmffile_u.write(u0, t) timeseries_u = TimeSeries( "inversion_temporal_file/target/u_timeseries") else: xdmffile_u = XDMFFile("inversion_temporal_file/obs/u.xdmf") xdmffile_u.write(u0, t) timeseries_u = TimeSeries("inversion_temporal_file/obs/u_timeseries") rec_counter = 0 while t < t_end - 0.5 * dt: t += float(dt) if rec_counter % 10 == 0: print( '\n\rtime: {:.3f} (Progress: {:.2f}%)'.format( t, 100 * t / t_end), ) g.t = t # Assemble rhs and apply boundary condition b = assemble(L) bc.apply(A, b) # Compute solution solver.solve(S.vector(), b) (u, U) = S.split(True) # Update previous time step update(u, u0, v0, a0, beta, gamma, dt) update(U, U0, V0, A0, beta, gamma, dt) xdmffile_u.write(u, t) pvd << (u, t) timeseries_u.store(u.vector(), t) energy = inner(u, u) * dx E = assemble(energy) print("E = ", E) print(u.vector().max())