Dear FEniCS community,
I have some issues obtaining a proper velocity solution, when I prescribe a pressure as boundary condition. I observe a flow, that highly oscillates around the expected flow value (numerical noise).
I have a geometry consisting of multiple outlets (Aortic Arch). At the inlet I prescribe a periodic velocity curve (based on an aortic inflow pulse). At the outlets I want a windkessel afterload, that describes the pressure-flow relation.
Something simular to the first example in: http://hplgit.github.io/fenics-mixed/doc/pub/fenics-mixed-4paper.pdf
For every timestep the new pressure is calculated from the known flow (q(n)) (fraction of inflow) and the previous pressure (p(n)).
p(n+1)_outlet_n = f(p(n), q(n))
Every timestep this value is given as Dirichlet BC for the pressure. I obtain the pressure relation that I was expecting. (see figure 1) But the flow is oscillating around the expected flow curve, such that the value between the two extrema is the value that i would expect. (see figure 2). The flow changes from direction every timestep, no matter how small I set the timestep, indicating it is numerical noise.
1
2
I expect the problem to be within the declaration of the pressure BC within the 3-steps IPCS method. I've found a somewhat simular problem here: https://fenicsproject.org/qa/11819/stokes-flow-simulation-imposing-pressure-sensible-results
But their solution (use Neuman BC instead of Dirichlet) is not an option since I am using the IPCS method.
I use the optimized IPCS solver Oasis (https://github.com/mikaem/Oasis) but the code below is a simple representation of my code in Oasis.
I hope that someone can help me with this.
Thanks in advance,
Martijn
Basic idea (within time integration loop)
(total simplified version of my code below in comments)
while t < simulationTime:
# Update velocity inlet BC
inflow_expression.t = t
inflow_expression.v_max = cur_vel
bcu_inlet = DirichletBC(V, inflow_expression, boundaries, surf_inlet)
# Obtain previous values
pt_1 = previous_pres_of_outlet_1
pt_2 = previous_pres_of_outlet_2
qnm1_1 = previous_flow_of_outlet_1
qnm1_2 = previous_flow_of_outlet_2
# Obtain current flow
q_1 = 0.3 * flow_inlet
q_2 = 0.7 * flow_inlet
# Calculate new pressure for outlet 1 and outlet 2
pnp1_outlet_1 = ((Z_1*dt + R_1*dt + Z_1*R_1*C_1)/(R_1*C_1 + dt ))*q_1 - ((Z_1*R_1*C_1)/(R_1*C_1 + dt))*qnm1_1 + (R_1*C_1/(R_1*C_1 + dt)) * pt_1
pnp1_outlet_2 = ((Z_2*dt + R_2*dt + Z_2*R_2*C_2)/(R_2*C_2 + dt ))*q_2 - ((Z_2*R_2*C_2)/(R_2*C_2 + dt))*qnm1_2 + (R_2*C_2/(R_2*C_2 + dt)) * pt_2
# Z_1, R_1, C_1 and Z_2, R_2, C_2 are known windkessel constants
# Update pressure BC
bcp_outlet_1 = DirichletBC(Q, Constant(pnp1_1), boundaries, surf_1)
bcp_outlet_2 = DirichletBC(Q, Constant(pnp1_2), boundaries, surf_2)
# Solve tentative velocity step
# with no-slip and velocity inflow BC
# Solve pressure correction step
# with calculated pressure at outlets as BC
# Solve velocity update step
# update time
t += dt