Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update adapter and partitioned-heat-conduction #1

Open
wants to merge 39 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
6c973a8
Perform some obvious updates when importing.
BenjaminRodenberg Nov 30, 2021
22d7930
Merge branch 'develop' into dev-partitioned-heat-equation
BenjaminRodenberg Nov 30, 2021
31ec84e
Merge branch 'develop' into dev-partitioned-heat-equation
BenjaminRodenberg Nov 30, 2021
19ecbcd
Remove parallelization and PointSources. Update tests.
BenjaminRodenberg Dec 2, 2021
fee57d7
Fix most tests, remove nearest projection.
BenjaminRodenberg Dec 2, 2021
b571537
Fix remaining test.
BenjaminRodenberg Dec 2, 2021
d8e1fd8
Follow FEniCSx workflow and ask user for MPI.COMM_WORLD.
BenjaminRodenberg Dec 7, 2021
506a152
Partial update to dolfinx.
BenjaminRodenberg Dec 7, 2021
e35e7a1
Improve code.
BenjaminRodenberg Dec 7, 2021
543c596
continue with update to dolfinx
arvedes Jan 3, 2022
0d96b7c
update in discussion with Benjamin and Max
arvedes Jan 5, 2022
eccb894
continue update
Jan 7, 2022
c175e01
Add output, debug
Jan 7, 2022
3ca38dc
make coupling_expression derived class from dolfinx.fem.Function
Jan 10, 2022
ac96d50
use Constant for dt
Jan 10, 2022
f60ff1e
Add development version
BenjaminRodenberg Feb 24, 2022
115533b
Delete tutorials.patch
BenjaminRodenberg Feb 24, 2022
13f663a
Include dockerfile with development-version #6
arvedes Mar 3, 2022
9c09993
Repaired most test #1, update Dockerfile
arvedes Mar 3, 2022
a9c42d5
Fix linting errors.
BenjaminRodenberg Mar 8, 2022
630d7ec
Fix PEP8.
BenjaminRodenberg Mar 8, 2022
8592972
Manually fix more PEP8.
BenjaminRodenberg Mar 8, 2022
8c511fe
Manually fix linter, but some links are still broken.
BenjaminRodenberg Mar 8, 2022
4e809b0
Add sympy as dependency for tests.
BenjaminRodenberg Mar 8, 2022
8bffc27
Don't install sympy in docker.
BenjaminRodenberg Mar 8, 2022
e873f9d
Fix format.
BenjaminRodenberg Mar 8, 2022
e08cdd1
Don't install fenicsx-adapter in base image.
BenjaminRodenberg Mar 8, 2022
29b590f
Update test pipeline to use docker image.
BenjaminRodenberg Mar 8, 2022
81ea7d5
Fix docker namespace.
BenjaminRodenberg Mar 8, 2022
b83dee7
debug test_update_expression_scalar - still failing
arvedes Mar 10, 2022
59f63fa
clean up, debug tests
arvedes Mar 10, 2022
9184c71
Update detection of coupling subdomain: use array
arvedes Mar 30, 2022
6db7f45
bugfix in subdomain identification
arvedes Mar 30, 2022
3cface3
update for new dolfinx release
arvedes Apr 29, 2022
a5c28d0
update to doflinx v0.4.1
arvedes Jun 22, 2022
5af2065
debug adapter_core.convert_fenicsx_to_precice
arvedes Jun 22, 2022
da90074
Minor corrections
IshaanDesai Aug 17, 2022
d7a2491
Merge branch 'develop' into dev-partitioned-heat-equation
IshaanDesai Aug 18, 2022
26678c1
Fixing the error computation in the partitioned-heat-equation tutoria…
PhilipHildebrand Dec 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
515 changes: 24 additions & 491 deletions fenicsxprecice/adapter_core.py

Large diffs are not rendered by default.

83 changes: 18 additions & 65 deletions fenicsxprecice/expression_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
This module provides a mechanism to imterpolate point data acquired from preCICE into FEniCSx Expressions.
"""

from dolfinx import UserExpression
from .adapter_core import FunctionType
from scipy.interpolate import Rbf
from scipy.linalg import lstsq
Expand All @@ -15,10 +14,12 @@
logger.setLevel(level=logging.INFO)


class CouplingExpression(UserExpression):
class CouplingExpression():
"""
Creates functional representation (for FEniCSx) of nodal data provided by preCICE.
"""
def __init__(self, dims):
self._dimension = dims

def set_function_type(self, function_type):
self._function_type = function_type
Expand All @@ -39,13 +40,10 @@ def update_boundary_data(self, vals, coords_x, coords_y=None, coords_z=None):
Z coordinate of points of which point data is provided.
"""
self._coords_x = coords_x
self._dimension = 3
if coords_y is None:
self._dimension -= 1
coords_y = np.zeros(self._coords_x.shape)
self._coords_y = coords_y
if coords_z is None:
self._dimension -= 1
coords_z = np.zeros(self._coords_x.shape)

self._coords_y = coords_y
Expand All @@ -55,7 +53,7 @@ def update_boundary_data(self, vals, coords_x, coords_y=None, coords_z=None):
self._f = self.create_interpolant()

if self.is_scalar_valued():
assert (self._vals.shape == self._coords_x.shape)
assert (self._vals.shape[0] == self._coords_x.shape[0])
elif self.is_vector_valued():
assert (self._vals.shape[0] == self._coords_x.shape[0])

Expand Down Expand Up @@ -100,20 +98,16 @@ def create_interpolant(self, x):
raise Exception("Please use one of the classes derived from this class, that implements an actual strategy for"
"interpolation.")

def eval(self, value, x):
def __call__(self, x):
"""
Evaluates expression at x using self.interpolate(x) and stores result to value.

Parameters
----------
value : double
Buffer where result has to be returned to.
x : double
Coordinate where expression has to be evaluated.
"""
return_value = self.interpolate(x)
for i in range(self._vals.ndim):
value[i] = return_value[i]
return self.interpolate(x)

def is_scalar_valued(self):
"""
Expand All @@ -124,17 +118,7 @@ def is_scalar_valued(self):
tag : bool
True if function being interpolated is scalar-valued, False otherwise.
"""
try:
if self._vals.ndim == 1:
assert(self._function_type is FunctionType.SCALAR)
return True
elif self._vals.ndim > 1:
assert(self._function_type is FunctionType.VECTOR)
return False
else:
raise Exception("Dimension of the function is 0 or negative!")
except AttributeError:
return self._function_type is FunctionType.SCALAR
return self._function_type is FunctionType.SCALAR

def is_vector_valued(self):
"""
Expand All @@ -145,17 +129,7 @@ def is_vector_valued(self):
tag : bool
True if function being interpolated is vector-valued, False otherwise.
"""
try:
if self._vals.ndim > 1:
assert(self._function_type is FunctionType.VECTOR)
return True
elif self._vals.ndim == 1:
assert(self._function_type is FunctionType.SCALAR)
return False
else:
raise Exception("Dimension of the function is 0 or negative!")
except AttributeError:
return self._function_type is FunctionType.VECTOR
return self._function_type is FunctionType.VECTOR


class SegregatedRBFInterpolationExpression(CouplingExpression):
Expand Down Expand Up @@ -200,7 +174,8 @@ def create_interpolant(self):
interpolant = []

if self.is_scalar_valued(): # check if scalar or vector-valued
interpolant.append(self.segregated_interpolant_2d(self._coords_x, self._coords_y, self._vals))
for d in range(1):
interpolant.append(self.segregated_interpolant_2d(self._coords_x, self._coords_y, self._vals[:, d]))
elif self.is_vector_valued():
for d in range(2):
interpolant.append(self.segregated_interpolant_2d(self._coords_x, self._coords_y, self._vals[:, d]))
Expand All @@ -215,34 +190,12 @@ def interpolate(self, x):
"""
assert (self._dimension == 2) # current implementation only supports two dimensions

return_value = self._vals.ndim * [None]

for i in range(self._vals.ndim):
return_value[i] = self._f[i](x[0], x[1])


if self.is_scalar_valued():
return_value = [self._f[0](x[0], x[1])]
if self.is_vector_valued():
return_value = self._vals.ndim * [None]
for i in range(self._vals.ndim):
return_value[i] = self._f[i](x[0], x[1])
return return_value


class EmptyExpression(CouplingExpression):
"""A dummy expression that can be used for implementing a coupling boundary condition, if the participant's mesh has
no vertices on the coupling domain. Only used for parallel runs.

Example:
We want solve
F = u * v / dt * dx + dot(grad(u), grad(v)) * dx - (u_n / dt + f) * v * dx + v * coupling_expression * ds
The user defines F, but does not know whether the rank even has vertices on the Neumann coupling boundary.
If the rank does not have any vertices on the Neumann coupling boundary the coupling_expression is an
EmptyExpression. This "deactivates" the Neumann BC for that specific rank.
"""

def eval(self, value, x):
""" Evaluates expression at x. For EmptyExpression always returns zero.

:param x: coordinate where expression has to be evaluated
:param value: buffer where result has to be returned to
"""
assert(MPI.COMM_WORLD.Get_size() > 1)
for i in range(self._vals.ndim):
value[i] = 0

def update_boundary_data(self, vals, coords_x, coords_y=None, coords_z=None):
pass # an EmptyExpression is never updated
Loading