Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0382555
Update case according to https://github.com/precice/fenics-adapter/pu…
BenjaminRodenberg Aug 11, 2020
a178d1c
Update get_point_sources
BenjaminRodenberg Aug 11, 2020
c764405
Update get_point_sources
BenjaminRodenberg Aug 11, 2020
7d4eb3c
Revert "Update get_point_sources"
BenjaminRodenberg Aug 11, 2020
99b767a
Merge branch 'develop' into fenics-adapter-i80
BenjaminRodenberg Aug 11, 2020
7a8e4f5
Merge pull request #101 from precice/fenics-adapter-i80
IshaanDesai Aug 11, 2020
407a235
Uses new SegregatedRBFInterpolationExpression from https://github.com…
BenjaminRodenberg Aug 13, 2020
eb3283c
Merge pull request #102 from precice/fenics-adapter_update_pr_83
IshaanDesai Aug 17, 2020
0472974
Add valid interpolation strategy.
BenjaminRodenberg Sep 21, 2020
7273964
Use rbf_segregated
BenjaminRodenberg Sep 21, 2020
61a1cf9
Removes interpolation_type from all fenics adapter config files.
BenjaminRodenberg Oct 1, 2020
408ac14
Fix output frequency of Solid
BenjaminRodenberg Nov 3, 2020
c1b5523
Make output routine with dt_out more robust
BenjaminRodenberg Nov 4, 2020
3a6c3a6
Use same method for flux computation like in HT example. (#114)
BenjaminRodenberg Nov 6, 2020
23cc54e
Rename fenicsadapter to fenicsprecice (#113)
BenjaminRodenberg Nov 6, 2020
1ef2f7f
Convert dt to float (#115)
BenjaminRodenberg Nov 8, 2020
41ed6c8
Initial change to FEniCS-Adapter initialization
IshaanDesai Nov 17, 2020
6176297
Merging write_function_space and write_function into write_object
IshaanDesai Nov 24, 2020
ea14b9d
Explicitly mentioning optional parameter names in adapter initialization
IshaanDesai Nov 25, 2020
1b15c0f
Adding comment to explain why a function space is passed twice to ini…
IshaanDesai Nov 28, 2020
ebcc5ae
Initialize with V_g.sub(1) as write_object (#127)
BenjaminRodenberg Dec 10, 2020
ca4d7bb
Add SU2-FEniCS Perpendicular Flap FSI Tutorial (#91)
IshaanDesai Dec 19, 2020
d932e69
Modify FEniCS tutorials to enable parallel runs (#120)
IshaanDesai Dec 19, 2020
cdef4f0
Move */OpenFOAM-FEniCS to *_2D/OpenFOAM-FEniCS. (#141)
BenjaminRodenberg Dec 23, 2020
c8e6dee
Ensuring consistency in FEniCS scripts for FSI tutorial cases (#142)
IshaanDesai Jan 8, 2021
6e285bd
Fix ill-posed problem by providing additional data. (#144)
BenjaminRodenberg Jan 8, 2021
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
81 changes: 45 additions & 36 deletions CHT/flow-over-plate/buoyantPimpleFoam-fenics/Solid/heat.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
"""

from __future__ import print_function, division
from fenics import Function, SubDomain, RectangleMesh, BoxMesh, FunctionSpace, Point, Expression, Constant, DirichletBC, \
TrialFunction, TestFunction, File, solve, plot, lhs, rhs, grad, inner, dot, dx, ds, assemble, interpolate, project, \
near
from fenicsadapter import Adapter
from fenics import Function, SubDomain, RectangleMesh, BoxMesh, FunctionSpace, VectorFunctionSpace, Point, \
Expression, Constant, DirichletBC, \
TrialFunction, TestFunction, File, solve, plot, lhs, rhs, grad, inner, dot, dx, ds, interpolate, project, \
near, MeshFunction, MPI
from fenicsprecice import Adapter
import numpy as np


Expand Down Expand Up @@ -59,27 +60,21 @@ def inside(self, x, on_boundary):
return False


def fluxes_from_temperature_full_domain(f, v_vec, k):
"""Computes flux from weak form (see p.3 in Toselli, Andrea, and Olof
Widlund. Domain decomposition methods-algorithms and theory. Vol. 34.
Springer Science & Business Media, 2006.).

:param f: weak form with known u^{n+1}
:param v_vec: vector function space
def determine_heat_flux(V_g, u, k, flux):
"""
compute flux following http://hplgit.github.io/INF5620/doc/pub/fenics_tutorial1.1/tu2.html#tut-poisson-gradu
:param V_g: Vector function space
:param u: solution where gradient is to be determined
:param k: thermal conductivity
:return: fluxes function
:param flux: returns calculated flux into this value
"""
fluxes_vector = assemble(f) # assemble weak form -> evaluate integral
v = TestFunction(v_vec)
fluxes = Function(v_vec) # create function for flux
area = assemble(v * ds).get_local()
for i in range(area.shape[0]):
if area[i] != 0: # put weight from assemble on function
fluxes.vector()[i] = - k * fluxes_vector[i] / area[i] # scale by surface area
else:
assert (abs(fluxes_vector[i]) < 1E-9) # for non surface parts, we expect zero flux
fluxes.vector()[i] = - k * fluxes_vector[i]
return fluxes

w = TrialFunction(V_g)
v = TestFunction(V_g)

a = inner(w, v) * dx
L = inner(-k * grad(u), v) * dx
solve(a == L, flux)


# Create mesh and define function space
Expand All @@ -88,7 +83,7 @@ def fluxes_from_temperature_full_domain(f, v_vec, k):
nz = 1

fenics_dt = 0.01 # time step size
dt_out = 0.2
dt_out = 0.2 # interval for writing VTK files
y_top = 0
y_bottom = y_top - .25
x_left = 0
Expand All @@ -99,16 +94,16 @@ def fluxes_from_temperature_full_domain(f, v_vec, k):

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)
# Define flux in x direction on coupling interface (grad(u_D) in normal direction)
f_N = Constant('0')
f_N_function = interpolate(f_N, 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()
Expand All @@ -120,7 +115,7 @@ def fluxes_from_temperature_full_domain(f, v_vec, k):
# Adapter definition and initialization
precice = Adapter(adapter_config_filename="precice-adapter-config.json")

precice_dt = precice.initialize(coupling_boundary, mesh, V)
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()
Expand All @@ -142,13 +137,26 @@ def fluxes_from_temperature_full_domain(f, v_vec, k):

# Time-stepping
u_np1 = Function(V)
F_known_u = u_np1 * v / dt * dx + alpha * dot(grad(u_np1), grad(v)) * dx - u_n * v / dt * dx
t = 0
u_D.t = t + dt

# mark mesh w.r.t ranks
ranks = File("Solid/VTK/ranks%s.pvd.pvd" % precice.get_participant_name())
mesh_rank = MeshFunction("size_t", mesh, mesh.topology().dim())
mesh_rank.set_all(MPI.rank(MPI.comm_world))
mesh_rank.rename("myRank", "")
ranks << mesh_rank

# Create output file
file_out = File("Solid/VTK/%s.pvd" % precice.get_participant_name())
file_out << u_n

print("output vtk for time = {}".format(float(t)))
n = 0

fluxes = Function(V_g)
fluxes.rename("Fluxes", "")

while precice.is_coupling_ongoing():

if precice.is_action_required(precice.action_write_iteration_checkpoint()): # write checkpoint
Expand All @@ -165,8 +173,9 @@ def fluxes_from_temperature_full_domain(f, v_vec, k):
solve(a == L, u_np1, bcs)

# Dirichlet problem obtains flux from solution and sends flux on boundary to Neumann problem
fluxes = fluxes_from_temperature_full_domain(F_known_u, V, k)
precice.write_data(fluxes)
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))

Expand All @@ -177,17 +186,17 @@ def fluxes_from_temperature_full_domain(f, v_vec, k):
n = n_cp
else: # update solution
u_n.assign(u_np1)
t += dt
t += float(dt)
n += 1

if precice.is_time_window_complete():
# if abs(t % dt_out) < 10e-5: # output if t is a multiple of dt_out
tol = 10e-5 # we need some tolerance, since otherwise output might be skipped.
if abs((t + tol) % dt_out) < 2*tol: # output if t is a multiple of dt_out
print("output vtk for time = {}".format(float(t)))
file_out << u_n

# Update dirichlet BC
u_D.t = t + dt(0)

file_out << u_n
u_D.t = t + float(dt)

# Hold plot
precice.finalize()
14 changes: 7 additions & 7 deletions CHT/flow-over-plate/buoyantPimpleFoam-fenics/precice-config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<sink filter="%Severity% > debug and %Rank% = 0" format="---[precice] %ColorizedSeverity% %Message%" enabled="true"/>
</log>

<solver-interface dimensions="3">
<solver-interface dimensions="2">

<data:scalar name="Temperature"/>
<data:scalar name="Heat-Flux"/>
Expand All @@ -23,32 +23,32 @@

<participant name="Fluid">
<use-mesh name="Fluid-Mesh" provide="yes"/>
<use-mesh name="Solid-Mesh" from="Solid"/>
<read-data name="Heat-Flux" mesh="Fluid-Mesh"/>
<write-data name="Temperature" mesh="Fluid-Mesh"/>
<mapping:nearest-neighbor direction="read" from="Solid-Mesh" to="Fluid-Mesh" constraint="consistent"/>
</participant>

<participant name="Solid">
<use-mesh name="Fluid-Mesh" from="Fluid"/>
<use-mesh name="Solid-Mesh" provide="yes"/>
<read-data name="Temperature" mesh="Solid-Mesh"/>
<write-data name="Heat-Flux" mesh="Solid-Mesh"/>
<mapping:nearest-neighbor direction="read" from="Fluid-Mesh" to="Solid-Mesh" constraint="consistent" timing="initial"/>
<mapping:nearest-neighbor direction="write" from="Solid-Mesh" to="Fluid-Mesh" constraint="consistent" timing="initial"/>
<mapping:nearest-neighbor direction="read" from="Fluid-Mesh" to="Solid-Mesh" constraint="consistent"/>
</participant>

<m2n:sockets from="Fluid" to="Solid"/>

<coupling-scheme:serial-implicit>
<time-window-size value="0.01"/>
<max-time value="1"/>
<max-iterations value="200"/>
<participants first="Fluid" second="Solid"/>
<exchange data="Temperature" mesh="Fluid-Mesh" from="Fluid" to="Solid"/>
<exchange data="Heat-Flux" mesh="Fluid-Mesh" from="Solid" to="Fluid"/>
<exchange data="Heat-Flux" mesh="Solid-Mesh" from="Solid" to="Fluid"/>
<max-iterations value="200"/>
<relative-convergence-measure limit="1.0e-6" data="Temperature" mesh="Fluid-Mesh"/>
<extrapolation-order value="0"/>
<acceleration:IQN-ILS>
<data mesh="Fluid-Mesh" name="Heat-Flux" />
<data mesh="Solid-Mesh" name="Heat-Flux" />
<initial-relaxation value="0.01" />
<max-used-iterations value="80" />
<time-windows-reused value="10" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
Fluid
!Fluid
Fluid/*
!Fluid/0
!Fluid/0.orig
!Fluid/constant
Fluid/constant/polyMesh
!Fluid/system
!Fluid/Fluid.foam
!Fluid/precice-adapter-config.yml
Solid
!Solid
Solid/*
!Solid/cyl-flap.py
!Solid/precice-adapter-config-fsi-s.json
*.log
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from ufl import nabla_div
import numpy as np
import matplotlib.pyplot as plt
from fenicsadapter import Adapter
from fenicsprecice import Adapter
from enum import Enum

# Beam geometry
Expand Down Expand Up @@ -88,7 +88,9 @@ def remaining_boundary(x, on_boundary):
force_boundary = AutoSubDomain(remaining_boundary)

# Initialize the coupling interface
precice_dt = precice.initialize(coupling_boundary, mesh, V, dim)
# Function space V is passed twice as both read and write functions are defined using the same space
precice_dt = precice.initialize(coupling_boundary, read_function_space=V, write_object=V,
fixed_boundary=clamped_boundary_domain)

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
Expand Down Expand Up @@ -171,8 +173,6 @@ def avg(x_old, x_new, alpha):

res = m(avg(a_n, a_np1, alpha_m), v) + k(avg(u_n, du, alpha_f), v)

Forces_x, Forces_y = precice.create_point_sources(clamped_boundary_domain)

a_form = lhs(res)
L_form = rhs(res)

Expand Down Expand Up @@ -201,7 +201,7 @@ def avg(x_old, x_new, alpha):
read_data = precice.read_data()

# Update the point sources on the coupling boundary with the new read data
Forces_x, Forces_y = precice.update_point_sources(read_data)
Forces_x, Forces_y = precice.get_point_sources(read_data)

A, b = assemble_system(a_form, L_form, bc)

Expand Down Expand Up @@ -231,7 +231,7 @@ def avg(x_old, x_new, alpha):
n = n_cp
else:
u_n.assign(u_np1)
t += dt
t += float(dt)
n += 1

if precice.is_time_window_complete():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<sink filter="%Severity% > debug and %Rank% = 0" format="---[precice] %ColorizedSeverity% %Message%" enabled="true"/>
</log>

<solver-interface dimensions="3">
<solver-interface dimensions="2">

<data:vector name="Forces0"/>
<data:vector name="Displacements0"/>
Expand All @@ -30,15 +30,15 @@
<use-mesh name="Solid" from="fenics"/>
<write-data name="Forces0" mesh="Fluid-Mesh-Faces"/>
<read-data name="Displacements0" mesh="Fluid-Mesh-Nodes"/>
<mapping:rbf-thin-plate-splines direction="write" from="Fluid-Mesh-Faces" to="Solid" constraint="conservative" z-dead="true"/>
<mapping:rbf-thin-plate-splines direction="read" from="Solid" to="Fluid-Mesh-Nodes" constraint="consistent" z-dead="true"/>
<mapping:rbf-thin-plate-splines direction="write" from="Fluid-Mesh-Faces" to="Solid" constraint="conservative"/>
<mapping:rbf-thin-plate-splines direction="read" from="Solid" to="Fluid-Mesh-Nodes" constraint="consistent"/>
</participant>

<participant name="fenics">
<use-mesh name="Solid" provide="yes"/>
<read-data name="Forces0" mesh="Solid"/>
<write-data name="Displacements0" mesh="Solid"/>
<watch-point mesh="Solid" name="point1" coordinate="0.6;0.2;0." />
<watch-point mesh="Solid" name="point1" coordinate="0.6;0." />
</participant>

<m2n:sockets from="Fluid" to="fenics"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
Fluid
!Fluid
Fluid/*
!Fluid/0
!Fluid/0.orig
!Fluid/constant
Fluid/constant/polyMesh
!Fluid/system
!Fluid/Fluid.foam
!Fluid/precice-adapter-config.yml
Solid
!Solid
Solid/*
!Solid/perp-flap.py
!Solid/precice-adapter-config-fsi-s.json
*.log
elastodynamics-results.h5
elastodynamics-results.xdmf
preCICE-output
precice-fenics-events.json
precice-Fluid-events.json
Loading