Skip to content

Commit

Permalink
Merge pull request #114 from precice/release_v1.0.1
Browse files Browse the repository at this point in the history
Release v1.0.1
  • Loading branch information
BenjaminRodenberg authored Jan 10, 2021
2 parents c9ba897 + 6ce2b0c commit bd74827
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 19 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# FEniCS-preCICE adapter changelog

## 1.0.1

* Bugfix for PointSources https://github.com/precice/fenics-adapter/issues/109
* Bugfix in parallelization https://github.com/precice/fenics-adapter/pull/110

## 1.0.0

* The paper *FEniCS-preCICE: Coupling FEniCS to other Simulation Software* (in preparation) describes features, usage and API of the adapter.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FEniCS-preCICE adapter
----------------------

<a style="text-decoration: none" href="https://travis-ci.org/precice/fenics-adapter" target="_blank">
<img src="https://travis-ci.org/precice/fenics-adapter.svg?branch=master" alt="Build status">
<a style="text-decoration: none" href="https://travis-ci.com/precice/fenics-adapter" target="_blank">
<img src="https://travis-ci.com/precice/fenics-adapter.svg?branch=master" alt="Build status">
</a>
<a style="text-decoration: none" href="https://github.com/precice/fenics-adapter/blob/master/LICENSE" target="_blank">
<img src="https://img.shields.io/github/license/precice/fenics-adapter.svg" alt="GNU LGPL license">
Expand Down
4 changes: 4 additions & 0 deletions docs/ReleaseGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The developer who is releasing a new version of FEniCS-preCICE adapter is expect

2. [Open a Pull Request from the branch `release_vX.X.X` to `master`](https://github.com/precice/fenics-adapter/compare) named after the version (i.e. `Release v1.0.0`) and briefly describe the new features of the release in the PR description.

a) Check `CHANGELOG.md`, if necessary, update `CHANGELOG.md` on `develop` and merge into `release_vX.X.X`

b) Before merging the PR, make sure to bump the version in `CHANGELOG.md` on `release_vX.X.X`

3. [Draft a New Release](https://github.com/precice/fenics-adapter/releases/new) in the `Releases` section of the repository page in a web browser. The release tag needs to be the exact version number (i.e.`v1.0.0` or `v1.0.0rc1`, compare to [existing tags](https://github.com/precice/fenics-adapter/tags)). Use `@target:master`. Release title is also the version number (i.e. `v1.0.0` or `v1.0.0rc1`, compare to [existing releases](https://github.com/precice/fenics-adapter/tags)).
*Note:* If it is a pre-release then the option *This is a pre-release* needs to be selected at the bottom of the page. Use `@target:release_vX.X.X` for a pre-release, since we will never merge a pre-release into master.

Expand Down
17 changes: 9 additions & 8 deletions fenicsprecice/adapter_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,18 @@ def convert_fenics_to_precice(fenics_function, local_ids):
if type(fenics_function) is not Function:
raise Exception("Cannot handle data type {}".format(type(fenics_function)))

sampled_data = fenics_function.compute_vertex_values(fenics_function.function_space().mesh())

precice_data = []

if fenics_function.function_space().num_sub_spaces() > 0:
dims = fenics_function.function_space().num_sub_spaces()
sampled_data = fenics_function.compute_vertex_values().reshape([dims, -1])
else:
sampled_data = fenics_function.compute_vertex_values()

if len(local_ids):
if fenics_function.function_space().num_sub_spaces() > 0: # function space is VectorFunctionSpace
for lid in local_ids:
precice_data.append([sampled_data[lid], sampled_data[lid+1]])
precice_data.append(sampled_data[:, lid])
else: # function space is FunctionSpace (scalar)
for lid in local_ids:
precice_data.append(sampled_data[lid])
Expand Down Expand Up @@ -365,7 +370,7 @@ def get_forces_as_point_sources(fixed_boundary, function_space, data):
nodal_data = np.array(list(data.values()))

# Check for shape of coupling_mesh_vertices and raise Assertion for 3D
n_vertices, dims = fenics_vertices.shape
n_vertices, _ = fenics_vertices.shape

vertices_x = fenics_vertices[:, 0]
vertices_y = fenics_vertices[:, 1]
Expand Down Expand Up @@ -538,8 +543,6 @@ def communicate_shared_vertices(comm, rank, fenics_vertices, send_pts, recv_pts,
hash_tag.update((str(src) + str(recv_gid) + str(rank)).encode('utf-8'))
tag = int(hash_tag.hexdigest()[:6], base=16)
recv_reqs.append(comm.irecv(source=src, tag=tag))
else:
print("Rank {}: Nothing to Receive".format(rank))

send_reqs = []
if send_pts:
Expand All @@ -552,8 +555,6 @@ def communicate_shared_vertices(comm, rank, fenics_vertices, send_pts, recv_pts,
tag = int(hash_tag.hexdigest()[:6], base=16)
req = comm.isend(coupling_data[tuple(fenics_coords[send_lid])], dest=dest, tag=tag)
send_reqs.append(req)
else:
print("Rank {}: Nothing to Send".format(rank))

# Wait for all non-blocking communications to complete
MPI.Request.Waitall(send_reqs)
Expand Down
2 changes: 1 addition & 1 deletion fenicsprecice/expression_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def eval(self, value, x):
:param x: coordinate where expression has to be evaluated
:param value: buffer where result has to be returned to
"""
assert(MPI.size(MPI.comm_world) > 1)
assert(MPI.COMM_WORLD.Get_size() > 1)
for i in range(self._vals.ndim):
value[i] = 0

Expand Down
7 changes: 4 additions & 3 deletions fenicsprecice/fenicsprecice.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,6 @@ def update_coupling_expression(self, coupling_expression, data):
vertices = np.array(list(data.keys()))
nodal_data = np.array(list(data.values()))
coupling_expression.update_boundary_data(nodal_data, vertices[:, 0], vertices[:, 1])
else:
print("Rank {}: No update for Expression as this rank has no vertices".format(self._rank))

def get_point_sources(self, data):
"""
Expand Down Expand Up @@ -363,12 +361,15 @@ def initialize(self, coupling_subdomain, read_function_space=None, write_object=
# Set up mesh in preCICE
if self._fenics_vertices.get_global_ids().size > 0:
self._empty_rank = False
else:
print("Rank {} has no part of coupling boundary.".format(self._rank))

# Define mesh in preCICE
self._precice_vertex_ids = self._interface.set_mesh_vertices(self._interface.get_mesh_id(
self._config.get_coupling_mesh_name()), self._owned_vertices.get_coordinates())

if self._coupling_type is CouplingMode.UNI_DIRECTIONAL_READ_COUPLING or self._coupling_type is CouplingMode.BI_DIRECTIONAL_COUPLING:
if self._coupling_type is CouplingMode.UNI_DIRECTIONAL_READ_COUPLING or \
self._coupling_type is CouplingMode.BI_DIRECTIONAL_COUPLING:
# Determine shared vertices with neighbouring processes and get dictionaries for communication
self._send_map, self._recv_map = get_communication_map(self._comm, self._rank, self._read_function_space,
self._owned_vertices, self._unowned_vertices)
Expand Down
50 changes: 49 additions & 1 deletion tests/test_adapter_core.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from unittest.mock import MagicMock, patch
from unittest import TestCase
import tests.MockedPrecice
from fenics import FunctionSpace, UnitSquareMesh, SubDomain, near, vertices
import numpy as np
from fenics import FunctionSpace, VectorFunctionSpace,UnitSquareMesh, SubDomain, near, vertices, Expression, interpolate


@patch.dict('sys.modules', **{'precice': tests.MockedPrecice})
Expand Down Expand Up @@ -34,3 +35,50 @@ def inside(self, x, on_boundary):

self.assertEqual(len(edge_vertex_ids1), 10)
self.assertEqual(len(edge_vertex_ids2), 10)

def test_convert_fenics_to_precice(self):
"""
Test conversion from function to write_data
"""
from fenicsprecice.adapter_core import convert_fenics_to_precice
from sympy import lambdify, symbols, printing

mesh = UnitSquareMesh(10, 10) # create dummy mesh

# scalar valued
V = FunctionSpace(mesh, 'P', 2) # Create function space using mesh
x, y = symbols('x[0], x[1]')
fun_sym = y + x*x
fun_lambda = lambdify([x, y], fun_sym)
fun_string = printing.ccode(fun_sym)
expression = Expression(fun_string, degree=2)
fenics_function = interpolate(expression, V)

local_ids = []
manual_sampling = []
for v in vertices(mesh):
local_ids.append(v.index())
manual_sampling.append(fun_lambda(v.x(0), v.x(1)))

data = convert_fenics_to_precice(fenics_function, local_ids)

np.testing.assert_allclose(data, manual_sampling)

# vector valued
W = VectorFunctionSpace(mesh, 'P', 2) # Create function space using mesh
fun_sym_x = y + x*x
fun_sym_y = y*y + x*x*x*2
fun_lambda = lambdify([x,y], [fun_sym_x, fun_sym_y])
fun_string = (printing.ccode(fun_sym_x), printing.ccode(fun_sym_y))
expression = Expression(fun_string, degree=2)
fenics_function = interpolate(expression, W)

local_ids = []
manual_sampling = []
for v in vertices(mesh):
local_ids.append(v.index())
manual_sampling.append(fun_lambda(v.x(0), v.x(1)))

data = convert_fenics_to_precice(fenics_function, local_ids)

np.testing.assert_allclose(data, manual_sampling)
8 changes: 4 additions & 4 deletions tests/test_write_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def test_vector_write(self):
"""
from precice import Interface
import fenicsprecice
from fenicsprecice.adapter_core import VertexType, Vertices, set_owned_vertices, convert_fenics_to_precice
from fenicsprecice.adapter_core import VertexType, Vertices, convert_fenics_to_precice

Interface.write_block_vector_data = MagicMock()
Interface.get_dimensions = MagicMock(return_value=self.dimension)
Expand All @@ -102,9 +102,9 @@ def test_vector_write(self):
precice.write_data(self.vector_function)

expected_data_id = self.fake_id
owned_vertices = Vertices(VertexType.OWNED)
set_owned_vertices(self.vector_V, RightBoundary(), owned_vertices)
expected_values = convert_fenics_to_precice(self.vector_function, owned_vertices.get_local_ids())
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(self.n_vertices)
expected_args = [expected_data_id, expected_ids, expected_values]

Expand Down

0 comments on commit bd74827

Please sign in to comment.