Skip to content

Commit 3a6c3a6

Browse files
Use same method for flux computation like in HT example. (#114)
1 parent c1b5523 commit 3a6c3a6

1 file changed

Lines changed: 25 additions & 26 deletions

File tree

  • CHT/flow-over-plate/buoyantPimpleFoam-fenics/Solid

CHT/flow-over-plate/buoyantPimpleFoam-fenics/Solid/heat.py

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
"""
44

55
from __future__ import print_function, division
6-
from fenics import Function, SubDomain, RectangleMesh, BoxMesh, FunctionSpace, Point, Expression, Constant, DirichletBC, \
7-
TrialFunction, TestFunction, File, solve, plot, lhs, rhs, grad, inner, dot, dx, ds, assemble, interpolate, project, \
6+
from fenics import Function, SubDomain, RectangleMesh, BoxMesh, FunctionSpace, VectorFunctionSpace, Point, \
7+
Expression, Constant, DirichletBC, \
8+
TrialFunction, TestFunction, File, solve, plot, lhs, rhs, grad, inner, dot, dx, ds, interpolate, project, \
89
near
910
from fenicsadapter import Adapter
1011
import numpy as np
@@ -59,27 +60,21 @@ def inside(self, x, on_boundary):
5960
return False
6061

6162

62-
def fluxes_from_temperature_full_domain(f, v_vec, k):
63-
"""Computes flux from weak form (see p.3 in Toselli, Andrea, and Olof
64-
Widlund. Domain decomposition methods-algorithms and theory. Vol. 34.
65-
Springer Science & Business Media, 2006.).
66-
67-
:param f: weak form with known u^{n+1}
68-
:param v_vec: vector function space
63+
def determine_heat_flux(V_g, u, k, flux):
64+
"""
65+
compute flux following http://hplgit.github.io/INF5620/doc/pub/fenics_tutorial1.1/tu2.html#tut-poisson-gradu
66+
:param V_g: Vector function space
67+
:param u: solution where gradient is to be determined
6968
:param k: thermal conductivity
70-
:return: fluxes function
69+
:param flux: returns calculated flux into this value
7170
"""
72-
fluxes_vector = assemble(f) # assemble weak form -> evaluate integral
73-
v = TestFunction(v_vec)
74-
fluxes = Function(v_vec) # create function for flux
75-
area = assemble(v * ds).get_local()
76-
for i in range(area.shape[0]):
77-
if area[i] != 0: # put weight from assemble on function
78-
fluxes.vector()[i] = - k * fluxes_vector[i] / area[i] # scale by surface area
79-
else:
80-
assert (abs(fluxes_vector[i]) < 1E-9) # for non surface parts, we expect zero flux
81-
fluxes.vector()[i] = - k * fluxes_vector[i]
82-
return fluxes
71+
72+
w = TrialFunction(V_g)
73+
v = TestFunction(V_g)
74+
75+
a = inner(w, v) * dx
76+
L = inner(-k * grad(u), v) * dx
77+
solve(a == L, flux)
8378

8479

8580
# Create mesh and define function space
@@ -99,14 +94,15 @@ def fluxes_from_temperature_full_domain(f, v_vec, k):
9994

10095
mesh = RectangleMesh(p0, p1, nx, ny)
10196
V = FunctionSpace(mesh, 'P', 1)
97+
V_g = VectorFunctionSpace(mesh, 'P', 1)
10298

10399
alpha = 1 # m^2/s, https://en.wikipedia.org/wiki/Thermal_diffusivity
104100
k = 100 # kg * m / s^3 / K, https://en.wikipedia.org/wiki/Thermal_conductivity
105101

106102
# Define boundary condition
107103
u_D = Constant('310')
108104
u_D_function = interpolate(u_D, V)
109-
# Define flux in x direction on coupling interface (grad(u_D) in normal direction)
105+
# Define flux in y direction on coupling interface (grad(u_D) in normal direction)
110106
f_N = Constant('0')
111107
f_N_function = interpolate(f_N, V)
112108

@@ -120,7 +116,7 @@ def fluxes_from_temperature_full_domain(f, v_vec, k):
120116
# Adapter definition and initialization
121117
precice = Adapter(adapter_config_filename="precice-adapter-config.json")
122118

123-
precice_dt = precice.initialize(coupling_boundary, mesh, V)
119+
precice_dt = precice.initialize(coupling_boundary, mesh, V, write_function=f_N_function)
124120

125121
# Create a FEniCS Expression to define and control the coupling boundary values
126122
coupling_expression = precice.create_coupling_expression()
@@ -142,7 +138,6 @@ def fluxes_from_temperature_full_domain(f, v_vec, k):
142138

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

@@ -151,6 +146,9 @@ def fluxes_from_temperature_full_domain(f, v_vec, k):
151146
print("output vtk for time = {}".format(float(t)))
152147
n = 0
153148

149+
fluxes = Function(V_g)
150+
fluxes.rename("Fluxes", "")
151+
154152
while precice.is_coupling_ongoing():
155153

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

169167
# Dirichlet problem obtains flux from solution and sends flux on boundary to Neumann problem
170-
fluxes = fluxes_from_temperature_full_domain(F_known_u, V, k)
171-
precice.write_data(fluxes)
168+
determine_heat_flux(V_g, u_np1, k, fluxes)
169+
fluxes_y = fluxes.sub(1) # only exchange y component of flux.
170+
precice.write_data(fluxes_y)
172171

173172
precice_dt = precice.advance(dt(0))
174173

0 commit comments

Comments
 (0)