def boundary(x): return x[0] < 0.001 + DOLFIN_EPS or x[0] > 0.0015 - DOLFIN_EPS # define coupling domain as complete domain def coupling(x): return True dim = 2 coupling_domain = AutoSubDomain(coupling) # the FEniCS-preCICE adapter is configured via a json file. In there, we also need to specify some arbitrary (unused) read data. # We are currently trying to get rid of this technical restriction. precice = Adapter(adapter_config_filename="precice-adapter-config.json") precice_dt = precice.initialize( coupling_domain, write_object=V) # here we define where the coupling should happen # 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)
u_D = Expression('1 + gamma*t*x[0]*x[0] + (1-gamma)*x[0]*x[0] + alpha*x[1]*x[1] + beta*t', degree=2, alpha=alpha, beta=beta, gamma=gamma, t=0) u_D_function = interpolate(u_D, V) # Define flux in x direction on coupling interface (grad(u_D) in normal direction) f_N = Expression(("2 * gamma*t*x[0] + 2 * (1-gamma)*x[0]", "2 * alpha*x[1]"), degree=1, gamma=gamma, alpha=alpha, t=0) f_N_function = interpolate(f_N, V_g) # Define initial value u_n = interpolate(u_D, V) u_n.rename("Temperature", "") precice, precice_dt, initial_data = None, 0.0, None # Initialize the adapter according to the specific participant if problem is ProblemType.DIRICHLET: precice = Adapter(adapter_config_filename="precice-adapter-config-D.json") precice_dt = precice.initialize(coupling_boundary, read_function_space=V, write_object=f_N_function) elif problem is ProblemType.NEUMANN: precice = Adapter(adapter_config_filename="precice-adapter-config-N.json") precice_dt = precice.initialize(coupling_boundary, read_function_space=V_g, write_object=u_D_function) boundary_marker = False dt = Constant(0) dt.assign(np.min([fenics_dt, precice_dt])) # Define variational problem u = TrialFunction(V) v = TestFunction(V) f = Expression('beta + gamma*x[0]*x[0] - 2*gamma*t - 2*(1-gamma) - 2*alpha', degree=2, alpha=alpha, beta=beta, gamma=gamma, t=0)
# Define boundary condition u_D = Constant('310') u_D_function = interpolate(u_D, V) # We will only exchange flux in y direction on coupling interface. No initialization necessary. V_flux_y = V_g.sub(1) coupling_boundary = TopBoundary() bottom_boundary = BottomBoundary() # Define initial value u_n = interpolate(u_D, V) u_n.rename("T", "") # Adapter definition and initialization precice = Adapter(adapter_config_filename="precice-adapter-config.json") precice_dt = precice.initialize(coupling_boundary, read_function_space=V, write_object=V_flux_y) # Create a FEniCS Expression to define and control the coupling boundary values coupling_expression = precice.create_coupling_expression() # Assigning appropriate dt dt = Constant(0) dt.assign(np.min([fenics_dt, precice_dt])) # Define variational problem u = TrialFunction(V) v = TestFunction(V)
return on_boundary class RightBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and x[0] == 1 parser = argparse.ArgumentParser(description="Solving a volume coupled problem") command_group = parser.add_mutually_exclusive_group(required=True) command_group.add_argument("-s", "--source", help="create a source", dest="source", action="store_true") command_group.add_argument("-d", "--drain", help="create a drain", dest="drain", action="store_true") args = parser.parse_args() if args.source: precice = Adapter(adapter_config_filename="precice-adapter-config-source.json") elif args.drain: precice = Adapter(adapter_config_filename="precice-adapter-config-drain.json") mesh = UnitSquareMesh(10, 10) V = FunctionSpace(mesh, "P", 1) u = TrialFunction(V) v = TestFunction(V) u_n = Function(V) if args.source: u_ini = Expression("1", degree=1) bc = DirichletBC(V, u_ini, AllBoundary()) elif args.drain: u_ini = Expression("0", degree=1) bc = DirichletBC(V, u_ini, RightBoundary())
u_np1 = Function(V) saved_u_old = Function(V) # function known from previous timestep u_n = Function(V) v_n = Function(V) a_n = Function(V) f_N_function = interpolate(Expression(("1", "0"), degree=1), V) u_function = interpolate(Expression(("0", "0"), degree=1), V) coupling_boundary = AutoSubDomain(neumann_boundary) fixed_boundary = AutoSubDomain(clamped_boundary) precice = Adapter(adapter_config_filename="precice-adapter-config-fsi-s.json") # Initialize the coupling interface precice_dt = precice.initialize(coupling_boundary, read_function_space=V, write_object=V, fixed_boundary=fixed_boundary) fenics_dt = precice_dt # if fenics_dt == precice_dt, no subcycling is applied # fenics_dt = 0.02 # if fenics_dt < precice_dt, subcycling is applied dt = Constant(np.min([precice_dt, fenics_dt])) # clamp the beam at the bottom bc = DirichletBC(V, Constant((0, 0)), fixed_boundary) # alpha method parameters