# 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()
precice.store_checkpoint(u_n, t, n) read_data = precice.read_data() # Update the coupling expression with the new read data precice.update_coupling_expression(coupling_expression, read_data) dt.assign(np.min([fenics_dt, precice_dt])) # Compute solution solve(a == L, u_np1, bcs) # Dirichlet problem obtains flux from solution and sends flux on boundary to Neumann problem determine_heat_flux(V_g, u_np1, k, fluxes) fluxes_y = fluxes.sub(1) # only exchange y component of flux. precice.write_data(fluxes_y) 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():
# See https://github.com/precice/fenics-adapter/issues/113 for details. read_data[(0, 0)] = u_D(0, 0) # Update the coupling expression with the new read data precice.update_coupling_expression(coupling_expression, read_data) 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
for ps in forces_x: ps.apply(b_forces) for ps in forces_y: ps.apply(b_forces) for ps in forces_z: ps.apply(b_forces) assert (b is not b_forces) solve(A, u_np1.vector(), b_forces) dt = Constant(np.min([precice_dt, fenics_dt])) # Write relative displacements to preCICE u_delta.vector()[:] = u_np1.vector()[:] - u_n.vector()[:] precice.write_data(u_delta) # Call to advance coupling, also returns the optimum time step value precice_dt = precice.advance(dt(0)) # Either revert to old step if timestep has not converged or move to next timestep 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: u_n.assign(u_np1) t += float(dt) n += 1