def solve(self, **arguments): t_start = time.clock() # definig Function space on this mesh using Lagrange #polynoimals of degree 1. H = FunctionSpace(self.mesh, "CG", 1) # Setting up the variational problem v = TrialFunction(H) w = TestFunction(H) coeff_dx2 = Constant(1) coeff_v = Constant(1) f = Expression("(4*pow(pi,2))*exp(-(1/coeff_v)*t)*sin(2*pi*x[0])", {'coeff_v': coeff_v}, degree=2) v0 = Expression("sin(2*pi*x[0])", degree=2) f.t = 0 def boundary(x, on_boundary): return on_boundary bc = DirichletBC(H, v0, boundary) v1 = interpolate(v0, H) dt = self.steps.time a = (dt * inner(grad(v), grad(w)) + dt * coeff_v * inner(v, w)) * dx L = (f * dt - coeff_v * v1) * w * dx A = assemble(a) v = Function(H) T = self.domain.time[-1] t = dt # solving the variational problem. while t <= T: b = assemble(L, tensor=b) vo.t = t bc.apply(A, b) solve(A, v.vector(), b) t += dt v1.assign(v) self.solution.extend(v.vector().array()) return [self.solution, time.clock() - t_start]
temperature_out = File("out/%s.pvd" % precice.get_solver_name()) ref_out = File("out/ref%s.pvd" % precice.get_solver_name()) error_out = File("out/error%s.pvd" % precice.get_solver_name()) # output solution and reference solution at t=0, n=0 n = 0 print('output u^%d and u_ref^%d' % (n, n)) temperature_out << u_n ref_out << u_ref error_total, error_pointwise = compute_errors(u_n, u_ref, V) error_out << error_pointwise # set t_1 = t_0 + dt, this gives u_D^1 u_D.t = t + dt( 0) # call dt(0) to evaluate FEniCS Constant. Todo: is there a better way? f.t = t + dt(0) V_g = VectorFunctionSpace(mesh, 'P', 1) flux = Function(V_g) flux.rename("Flux", "") while precice.is_coupling_ongoing(): # Compute solution u^n+1, use bcs u_D^n+1, u^n and coupling bcs solve(a == L, u_np1, bcs) if problem is ProblemType.DIRICHLET: # Dirichlet problem obtains flux from solution and sends flux on boundary to Neumann problem determine_gradient(V_g, u_np1, flux) flux_x, flux_y = flux.split()
error_out = File("out/error%s.pvd" % precice.get_participant_name()) ranks = File("out/ranks%s.pvd" % precice.get_participant_name()) # output solution and reference solution at t=0, n=0 n = 0 print('output u^%d and u_ref^%d' % (n, n)) temperature_out << u_n ref_out << u_ref ranks << mesh_rank error_total, error_pointwise = compute_errors(u_n, u_ref, V) error_out << error_pointwise # set t_1 = t_0 + dt, this gives u_D^1 # call dt(0) to evaluate FEniCS Constant. Todo: is there a better way? u_D.t = t + dt(0) f.t = t + dt(0) if problem is ProblemType.DIRICHLET: flux = Function(V_g) flux.rename("Flux", "") while precice.is_coupling_ongoing(): # write checkpoint if precice.is_action_required(precice.action_write_iteration_checkpoint()): precice.store_checkpoint(u_n, t, n) read_data = precice.read_data() # Update the coupling expression with the new read data
# reference solution at t=0 u_e = interpolate(u_D, V) u_e.rename("reference", " ") file_out = File("out/%s.pvd" % solver_name) ref_out = File("out/ref%s.pvd" % solver_name) # output solution and reference solution at t=0, n=0 n = 0 print('output u^%d and u_ref^%d' % (n, n)) file_out << u_n ref_out << u_e # set t_1 = t_0 + dt, this gives u_D^1 u_D.t = t + precice._precice_tau assert (dt == precice._precice_tau) while precice.is_coupling_ongoing(): # Compute solution u^n+1, use bcs u_D^n+1, u^n and coupling bcs solve(a == L, u_np1, bcs) if problem is ProblemType.DIRICHLET: # Dirichlet problem obtains flux from solution and sends flux on boundary to Neumann problem fluxes = fluxes_from_temperature_full_domain(F_known_u, V) is_converged = precice.advance(fluxes, dt) elif problem is ProblemType.NEUMANN: # Neumann problem obtains sends temperature on boundary to Dirichlet problem is_converged = precice.advance(u_np1, dt)