dt.assign(np.min([fenics_dt, precice_dt])) # Compute solution u^n+1, use bcs u_D^n+1, u^n and coupling bcs solve(a == L, u_np1, bcs) # Write data to preCICE according to which problem is being solved if problem is ProblemType.DIRICHLET: # Dirichlet problem reads temperature and writes flux on boundary to Neumann problem determine_gradient(V_g, u_np1, flux) precice.write_data(flux) elif problem is ProblemType.NEUMANN: # Neumann problem reads flux and writes temperature on boundary to Dirichlet problem precice.write_data(u_np1) precice_dt = precice.advance(dt(0)) if precice.is_action_required(precice.action_read_iteration_checkpoint()): # roll back to checkpoint u_cp, t_cp, n_cp = precice.retrieve_checkpoint() u_n.assign(u_cp) t = t_cp n = n_cp else: # update solution u_n.assign(u_np1) t += float(dt) n += 1 if precice.is_time_window_complete(): u_ref = interpolate(u_D, V) u_ref.rename("reference", " ") error, error_pointwise = compute_errors(u_n, u_ref, V, total_error_tol=error_tol)
# Define boundary condition on left and right boundary u0 = Constant(0.0) bc = DirichletBC(V, u0, boundary) # Define variational problem, simply copied from FEniCS demo u = TrialFunction(V) v = TestFunction(V) f = Expression("10*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / 0.02)", degree=2) g = Expression("sin(5*x[0])", degree=2) a = inner(grad(u), grad(v)) * dx L = f * v * dx + g * v * ds while precice.is_coupling_ongoing( ): # potential time loop, currently only one timestep is done # Compute solution u = Function(V) solve(a == L, u, bc) # Save solution in VTK format file = File("poisson.pvd") file << u # write data to preCICE and advance coupling precice.write_data(u) precice.advance(precice_dt) precice.finalize()
read_data = precice.read_data() # Update the coupling expression with the new read data precice.update_coupling_expression(volume_term, read_data) f.assign(interpolate(volume_term, V)) dt_inv.assign(1 / dt) # Compute solution u^n+1, use bcs u^n and coupling bcs a, L = lhs(F), rhs(F) solve(a == L, u_np1, bc) # Write data to preCICE according to which problem is being solved precice.write_data(u_np1) dt = precice.advance(dt) # roll back to checkpoint if precice.is_action_required(precice.action_read_iteration_checkpoint()): u_cp, t_cp, n_cp = precice.retrieve_checkpoint() u_n.assign(u_cp) t = t_cp n = n_cp else: # update solution u_n.assign(u_np1) t += float(dt) n += 1 if precice.is_time_window_complete(): solution_out << u_n