def morph_fenics(mesh, nodes, u, other_fix=[]): """ Morph using FEniCS Functions. Returns a CG0 Function of DeltaX, such that w = DeltaX / dt """ X_orig = mesh.coordinates().copy() X_defo = X_orig.copy() uN = u.compute_vertex_values().reshape(u.geometric_dimension(), len(nodes)).T X_defo[list(nodes), :] += uN # Warp the mesh X_new = do_tri_map(list(nodes) + list(other_fix), X_defo, X_orig) mesh.coordinates()[:] = X_new # Calculate w from fenics import VectorFunctionSpace, Function V = VectorFunctionSpace(mesh, "CG", 1) DeltaX = Function(V) nodeorder = V.dofmap().dofs(mesh, 0) utot = (X_new - X_orig).ravel() for i, l in enumerate(nodeorder): DeltaX.vector()[l] = utot[i] return DeltaX # w = DeltaX / Dt
# 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() if domain_part is DomainPart.RIGHT: flux_x = -1 * flux_x t, n, precice_timestep_complete, precice_dt = precice.advance(
from fenicstools import Probes # Local import from stress_tensor import * from common import * from weak_form import * # Set output from FEniCS set_log_active(False) # Set ut problem mesh = Mesh( path.join(rel_path, "mesh", "von_karman_street_FSI_structure_refine2.xml")) # Function space V = VectorFunctionSpace(mesh, "CG", 2) VV = V * V # Get the point [0.2,0.6] at the end of bar for coord in mesh.coordinates(): if coord[0] == 0.6 and (0.2 - DOLFIN_EPS <= coord[1] <= 0.2 + DOLFIN_EPS): #print coord break BarLeftSide = AutoSubDomain(lambda x: "on_boundary" and \ (((x[0] - 0.2) * (x[0] - 0.2) + (x[1] - 0.2) * (x[1] - 0.2) < 0.0505*0.0505 ) and x[1] >= 0.19 \ and x[1] <= 0.21 \ and x[0] > 0.2) )
ny = 25 nz = 1 fenics_dt = 0.01 # time step size dt_out = 0.2 # interval for writing VTK files y_top = 0 y_bottom = y_top - .25 x_left = 0 x_right = x_left + 1 p0 = Point(x_left, y_bottom, 0) p1 = Point(x_right, y_top, 1) mesh = RectangleMesh(p0, p1, nx, ny) V = FunctionSpace(mesh, 'P', 1) V_g = VectorFunctionSpace(mesh, 'P', 1) alpha = 1 # m^2/s, https://en.wikipedia.org/wiki/Thermal_diffusivity k = 100 # kg * m / s^3 / K, https://en.wikipedia.org/wiki/Thermal_conductivity # 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)
nu = 0.3 mu = Constant(E / (2.0 * (1.0 + nu))) lambda_ = Constant(E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu))) # create Mesh n_x_Direction = 4 n_y_Direction = 26 mesh = RectangleMesh(Point(-W / 2, 0), Point(W / 2, H), n_x_Direction, n_y_Direction) h = Constant(H / n_y_Direction) # create Function Space V = VectorFunctionSpace(mesh, 'P', 2) # BCs tol = 1E-14 # Trial and Test Functions du = TrialFunction(V) v = TestFunction(V) 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)
class TestWriteData(TestCase): dummy_config = "tests/precice-adapter-config.json" mesh = UnitSquareMesh(10, 10) dimension = 2 scalar_expr = Expression("x[0]*x[0] + x[1]*x[1]", degree=2) scalar_V = FunctionSpace(mesh, "P", 2) scalar_function = interpolate(scalar_expr, scalar_V) vector_expr = Expression(("x[0] + x[1]*x[1]", "x[0] - x[1]*x[1]"), degree=2) vector_V = VectorFunctionSpace(mesh, "P", 2) vector_function = interpolate(vector_expr, vector_V) def setUp(self): pass def test_write_scalar_data(self): from precice import Interface import fenicsadapter def dummy_set_mesh_vertices(mesh_id, positions): vertex_ids = np.arange(len(positions)) return vertex_ids Interface.configure = MagicMock() Interface.write_block_scalar_data = MagicMock() Interface.read_block_vector_data = MagicMock() Interface.get_dimensions = MagicMock(return_value=2) Interface.set_mesh_vertices = MagicMock( side_effect=dummy_set_mesh_vertices) Interface.initialize = MagicMock() Interface.initialize_data = MagicMock() Interface.is_action_required = MagicMock(return_value=False) Interface.mark_action_fulfilled = MagicMock() Interface.is_time_window_complete = MagicMock() Interface.advance = MagicMock() Interface.get_mesh_id = MagicMock() Interface.get_data_id = MagicMock(return_value=15) Interface.is_read_data_available = MagicMock(return_value=False) Interface.set_mesh_edge = MagicMock() write_u = self.scalar_function read_u = self.vector_function u_init = self.scalar_function precice = fenicsadapter.Adapter(self.dummy_config) precice._coupling_bc_expression = MagicMock() precice.initialize(RightBoundary(), self.mesh, read_u, write_u, u_init) precice.advance(write_u, u_init, u_init, 0, 0, 0) expected_data_id = 15 expected_values = np.array([ self.scalar_expr(x_right, y) for y in np.linspace(y_bottom, y_top, 11) ]) expected_ids = np.arange(11) expected_args = [expected_data_id, expected_ids, expected_values] for arg, expected_arg in zip( Interface.write_block_scalar_data.call_args[0], expected_args): if type(arg) is int: self.assertTrue(arg == expected_arg) elif type(arg) is np.ndarray: np.testing.assert_allclose(arg, expected_arg) def test_write_vector_data(self): from precice import Interface import fenicsadapter def dummy_set_mesh_vertices(mesh_id, positions): vertex_ids = np.arange(len(positions)) return vertex_ids Interface.configure = MagicMock() Interface.write_block_vector_data = MagicMock() Interface.read_block_scalar_data = MagicMock() Interface.get_dimensions = MagicMock(return_value=2) Interface.set_mesh_vertices = MagicMock( side_effect=dummy_set_mesh_vertices) Interface.initialize = MagicMock() Interface.initialize_data = MagicMock() Interface.is_action_required = MagicMock(return_value=False) Interface.mark_action_fulfilled = MagicMock() Interface.is_time_window_complete = MagicMock() Interface.advance = MagicMock() Interface.get_mesh_id = MagicMock() Interface.get_data_id = MagicMock(return_value=15) Interface.is_read_data_available = MagicMock(return_value=False) Interface.set_mesh_edge = MagicMock() write_u = self.vector_function read_u = self.scalar_function u_init = self.vector_function precice = fenicsadapter.Adapter(self.dummy_config) precice._coupling_bc_expression = MagicMock() precice.initialize(RightBoundary(), self.mesh, read_u, write_u, u_init) precice.advance(write_u, u_init, u_init, 0, 0, 0) expected_data_id = 15 expected_values_x = np.array([ self.vector_expr(x_right, y)[0] for y in np.linspace(y_bottom, y_top, 11) ]) expected_values_y = np.array([ self.vector_expr(x_right, y)[1] for y in np.linspace(y_bottom, y_top, 11) ]) expected_values = np.stack([expected_values_x, expected_values_y], axis=1) expected_ids = np.arange(11) expected_args = [expected_data_id, expected_ids, expected_values] for arg, expected_arg in zip( Interface.write_block_vector_data.call_args[0], expected_args): if type(arg) is int: self.assertTrue(arg == expected_arg) elif type(arg) is np.ndarray: np.testing.assert_almost_equal(arg, expected_arg) def test_read_scalar_data(self): from precice import Interface import fenicsadapter def return_dummy_data(data_id, value_indices): read_data = np.arange(len(value_indices)) return read_data def dummy_set_mesh_vertices(mesh_id, positions): vertex_ids = np.arange(len(positions)) return vertex_ids Interface.configure = MagicMock() Interface.write_block_vector_data = MagicMock() Interface.read_block_scalar_data = MagicMock( side_effect=return_dummy_data) Interface.get_dimensions = MagicMock(return_value=self.dimension) Interface.set_mesh_vertices = MagicMock( side_effect=dummy_set_mesh_vertices) Interface.initialize = MagicMock() Interface.initialize_data = MagicMock() Interface.is_action_required = MagicMock(return_value=False) Interface.mark_action_fulfilled = MagicMock() Interface.is_time_window_complete = MagicMock() Interface.advance = MagicMock() Interface.get_mesh_id = MagicMock() Interface.get_data_id = MagicMock(return_value=15) Interface.is_read_data_available = MagicMock(return_value=False) Interface.set_mesh_edge = MagicMock() write_u = self.vector_function read_u = self.scalar_function u_init = self.vector_function precice = fenicsadapter.Adapter(self.dummy_config) precice._coupling_bc_expression = MagicMock() precice.initialize(RightBoundary(), self.mesh, read_u, write_u, u_init) precice.advance(write_u, u_init, u_init, 0, 0, 0) expected_data_id = 15 expected_ids = np.arange(11) expected_args = [expected_data_id, expected_ids] for arg, expected_arg in zip( Interface.read_block_scalar_data.call_args[0], expected_args): if type(arg) is int: self.assertTrue(arg == expected_arg) elif type(arg) is np.ndarray: np.testing.assert_allclose(arg, expected_arg) def test_read_vector_data(self): from precice import Interface import fenicsadapter def return_dummy_data(data_id, value_indices): read_data = np.arange(len(value_indices) * self.dimension).reshape( len(value_indices), self.dimension) return read_data def dummy_set_mesh_vertices(mesh_id, positions): vertex_ids = np.arange(len(positions)) return vertex_ids Interface.configure = MagicMock() Interface.write_block_scalar_data = MagicMock() Interface.read_block_vector_data = MagicMock( side_effect=return_dummy_data) Interface.get_dimensions = MagicMock(return_value=self.dimension) Interface.set_mesh_vertices = MagicMock( side_effect=dummy_set_mesh_vertices) Interface.initialize = MagicMock() Interface.initialize_data = MagicMock() Interface.is_action_required = MagicMock(return_value=False) Interface.mark_action_fulfilled = MagicMock() Interface.is_time_window_complete = MagicMock() Interface.advance = MagicMock() Interface.get_mesh_id = MagicMock() Interface.get_data_id = MagicMock(return_value=15) Interface.is_read_data_available = MagicMock(return_value=False) Interface.set_mesh_edge = MagicMock() write_u = self.scalar_function read_u = self.vector_function u_init = self.scalar_function precice = fenicsadapter.Adapter(self.dummy_config) precice._coupling_bc_expression = MagicMock() precice.initialize(RightBoundary(), self.mesh, read_u, write_u, u_init) precice.advance(write_u, u_init, u_init, 0, 0, 0) expected_data_id = 15 expected_ids = np.arange(11) expected_args = [expected_data_id, expected_ids] for arg, expected_arg in zip( Interface.read_block_vector_data.call_args[0], expected_args): if type(arg) is int: self.assertTrue(arg == expected_arg) elif type(arg) is np.ndarray: np.testing.assert_allclose(arg, expected_arg)
def __init__( self, eval_times, n=10, lx=1., ly=.1, lz=.1, f=(0.0, 0.0, -50.), time=1., timestep=.1, tol=1e-5, max_iter=30, rel_tol=1e-10, param_remapper=None): """Parameters ---------- eval_times: numpy.ndarray Times at which evaluation (interpolation) of the solution is required. n: int, default 10 Dimension of the grid along the smallest side of the beam (the grid size along all other dimensions will be scaled proportionally. lx: float, default 1. Length of the beam along the x axis. ly: float, default .1 Length of the beam along the y axis. lz: float, default .1 Length of the beam along the z axis. f: tuple or numpy.ndarray, default (0.0, 0.0, -50.) Force per unit volume acting on the beam. time: float, default 1. Final time of the simulation. timestep: float, default 1. Time discretization step to solve the problem. tol: float, default 1e-5 Tolerance parameter to ensure the last time step is included in the solution. max_iter: int, default 30 Maximum iterations for the SNES solver. rel_tol: int, Relative tolerance for the convergence of the SNES solver. param_remapper: object, default None Either None (no remapping of the parameters), or a function remapping the parameter of the problem (Young's modulus) to values suitable for the definition of the solution. """ # solver parameters self.solver = CountIt(solve) self.solver_parameters = { 'nonlinear_solver': 'snes', 'snes_solver': { 'linear_solver': 'lu', 'line_search': 'basic', 'maximum_iterations': max_iter, 'relative_tolerance': rel_tol, 'report': False, 'error_on_nonconvergence': False}} self.param_remapper = param_remapper # mesh creation self.n = n self.lx = lx self.ly = ly self.lz = lz min_len = min(lx, ly, lz) mesh_dims = (int(n * lx / min_len), int(n * ly / min_len), int(n * lz / min_len)) self.mesh = BoxMesh(Point(0, 0, 0), Point(lx, ly, lz), *mesh_dims) self.V = VectorFunctionSpace(self.mesh, 'Lagrange', 1) # boundary conditions self.left = CompiledSubDomain('near(x[0], side) && on_boundary', side=0.0) self.right = CompiledSubDomain('near(x[0], side) && on_boundary', side=lx) self.top = CompiledSubDomain('near(x[2], side) && on_boundary', side=lz) self.boundaries = MeshFunction('size_t', self.mesh, self.mesh.topology().dim() - 1, 0) self.boundaries.set_all(0) self.left.mark(self.boundaries, 1) self.right.mark(self.boundaries, 2) self.top.mark(self.boundaries, 3) self.bcs1 = DirichletBC(self.V, Constant([0.0, 0.0, 0.0]), self.boundaries, 1) self.bcs2 = DirichletBC(self.V, Constant([0.0, 0.0, 0.0]), self.boundaries, 2) self.bcs = [self.bcs1, self.bcs2] # surface force self.f = Constant(f) self.ds = Measure('ds', domain=self.mesh, subdomain_data=self.boundaries) # evaluation times self.eval_times = eval_times self.dt = timestep self.T = time + tol self.times = np.arange(self.dt, self.T, self.dt) self.time = Expression('t', t=self.dt, degree=0)
alpha = 3 # parameter alpha beta = 1.3 # parameter beta if args.dirichlet and not args.neumann: problem = ProblemType.DIRICHLET domain_part = DomainPart.LEFT elif args.neumann and not args.dirichlet: problem = ProblemType.NEUMANN domain_part = DomainPart.RIGHT mesh, coupling_boundary, remaining_boundary = get_geometry(domain_part) # Define function space using mesh V = FunctionSpace(mesh, 'P', 2) V_g = VectorFunctionSpace(mesh, 'P', 1) W = V_g.sub(0).collapse() # Define boundary conditions u_D = Expression('1 + x[0]*x[0] + alpha*x[1]*x[1] + beta*t', degree=2, alpha=alpha, beta=beta, t=0) u_D_function = interpolate(u_D, V) if problem is ProblemType.DIRICHLET: # Define flux in x direction f_N = Expression("2 * x[0]", degree=1, alpha=alpha, t=0) f_N_function = interpolate(f_N, W) # Define initial value u_n = interpolate(u_D, V) u_n.rename("Temperature", "")