Formulating Navier-Stokes as a non-linear equation

Hi! I’m trying to solve the (Navier-)Stokes equations using Chorin’s method. Stokes already works just fine, but when I try to solve the nonlinear Navier-Stokes equation, I get an error message of the type

TypeError: ‘bool’ object is not iterable

I tried to cut out unnecessary code to make it more readable, but let me know if you need the rest!

from dolfin import *
import mshr
import sys
import matplotlib.pyplot as plt

[…]

#Define function spaces
V_el = VectorElement('P', triangle, 2)
P_el = FiniteElement('P', triangle, 1)

W = FunctionSpace(mesh, V_el * P_el)
V = W.sub(0).collapse()
Q = W.sub(1).collapse()

 #Inflow profile
 inflow_profile = ('1.0','0.0')

 #Boundary conditions
 bcu_inflow = DirichletBC(V, Expression(inflow_profile, degree=2), inflow)
 bcu_walls = DirichletBC(V, Constant((0, 0)), walls)
 bcu_cylinder = DirichletBC(V, Constant((0, 0)), cylinder)
 bcu = [bcu_inflow, bcu_walls, bcu_cylinder]

 #Viscosity
 nu = 0.1

[…]

#1: Stokes
#2: Navier-Stokes
equation_type = 2

pressure_eq = inner(grad(p),grad(q))*dx == -1/dt*div(u_tmp)*q*dx

vel_update_eq = inner(u,v)*dx == inner(u_tmp,v)*dx - dt*dot(grad(p0),v)*dx

timestep = 1

#Chorin iteration
for timestep in range(1, num_timesteps+1):
    t = timestep * dt_val

    begin('Timestep {} / {} (t = {})'.format(timestep, num_timesteps, t))

    if equation_type == 1: #Stokes **<- works fine**
        solve(inner(u,v)*dx + dt*inner(nu*grad(u),grad(v))*dx == inner(u0, v) * dx,u_tmp,bcu)
    else: #Navier-Stokes **<-throws error message**
        solve(inner(u,v)*dx + dt*inner(dot(u,nabla_grad(u)),v)*dx + dt*inner(nu*grad(u),grad(v))*dx - inner(u0, v) * dx == 0,u_tmp,bcu)

    solve(pressure_eq,p0,DirichletBC(Q, Constant(0), 'near(x[0],2.2)'))

    solve(vel_update_eq,u0)

    #pressure with mean 0 
    p0.vector()[:] = p0.vector() - assemble(p0*dx) 
    end()  

I’ve googled and tried several versions to write (u \cdot grad(u)) v, but everything so far has thrown error messages on dolfin 2019.1.0. What is the right way to do it?

Thank you!

You can find a complete example of Navier stokes with Chorin here:
https://bitbucket.org/fenics-project/dolfin/src/master/python/demo/documented/navier-stokes/demo_navier-stokes.py

Thank you for this!

From that demo I learned that

F1 = inner(u - u0, v)*dx + dt*inner(grad(u0)*u0, v)*dx + dt*nu*inner(grad(u), grad(v))*dx    
A1 = assemble(lhs(F1))   
b1 = assemble(rhs(F1)) 
[bc.apply(A1, b1) for bc in bcu]
solve(A1,u_tmp.vector(),b1, "bicgstab", "default")

works but

F1 = inner(u - u0, v)*dx + dt*inner(grad(u0)*u0, v)*dx + dt*nu*inner(grad(u), grad(v))*dx
solve(F1 == 0, u_tmp,bcu)

doesn’t. I don’t really understand why though …

This is a linear problem, as

Removes the potential nonlinearity, and thus you should use trial and test functions in your variational form. For non-linear problems, you should use a function u, and solve F==0

This solved my problem, thank you so much!