Forum Message

 

 

We have moved the forum to https://forum.ngsolve.org . This is an archived version of the topics until 05/05/23. All the topics were moved to the new forum and conversations can be continued there. This forum is just kept as legacy to not invalidate old links. If you want to continue a conversation just look for the topic in the new forum.

Notice

The forum is in read only mode.

Gradient calculation on the boundary with dirichlet bc

  • nsch
  • New Member
  • New Member
More
1 year 9 months ago #4453 by nsch
Hi,

I am currently trying to calculate the drag / friction force in a fluid simulation.

In order to obtain the velocity and the pressure field, I have already solved the Stokes / Navier-Stokes equation, as described in the examples on the documentation website.
Now I need the gradient of the velocity normal to a boundary. Unfortunately, the gradient of the velocity is 0 on the boundaries with a dirichlet condition, making it impossible to determine the shear stresses on these surfaces.

I am using the Grad()-function like this:

velocity = gfu.components[0]

c_u = GridFunction(Q)
c_u.Set(velocity[0])
c_w = GridFunction(Q)
c_w.Set(velocity[2])

dudz = Grad(c_u)[2]
dwdx = Grad(c_w)[0]

tau = eta * (dudz + dwdx)

F_fric = Integrate(cf = tau,mesh=mesh,VOL_or_BND=BND,definedon=mesh.Boundaries('bottom'))

Is there any way to calculate the gradient of the velocity correctly on a surface with a dirichlet boundary condition?

I also tried to determine the tau tensor via the formula for incompressible fluids:

tau = eta *(Grad(velocity)+Grad(velocity).trans)
F_fric = Integrate(cf = tau*normal,mesh=mesh,VOL_or_BND=BND,definedon=mesh.Boundaries('bottom'))

But the gradient on "bottom" (dirichlet boundary condition) is always calculated to 0, this is also visible in the netgen visualisation.

Using grad() instead of Grad() doesn't work, either.

I hope, I made my problem clear.
Thank you for your help!

Best regards,
Niklas
More
1 year 9 months ago #4454 by hvwahl
Hi Niklas,

in principle there shoudn't be a problem with integrating the Gradient of a GridFunction on a boundary (Dirichlet or not). Could you please provide a MWE?

You might also want to look at  this tutorial  . Computing forces by testing the bilinear form with an appropriate non-conforming test-function computes forces significantly more accurately (with double order of convergence).

Best wishes,
Henry
The following user(s) said Thank You: nsch
  • nsch
  • New Member
  • New Member
More
1 year 9 months ago #4455 by nsch
Hi Henry,

thank you for your fast reply.

Unfortunately I am not able to attach files to this post. Therefore I am posting the source code as text:

Code:
from ngsolve import * from netgen.geom2d import * from netgen.occ import * U = 10          # velocity of surface rho = 890       # density of the oil eta = 0.0078792 # viscosity of the oil filename_geometry = 'wedge.step' # maximum element size of mesh mesh_max_h = 1e-1 # import geometry from given path geo = OCCGeometry(filename_geometry) # generate and refine mesh mesh = Mesh(geo.GenerateMesh(maxh=mesh_max_h)) # generate finite elemente spaces V = VectorH1(mesh,order=3, dirichlet='bottom|top|NONE')   # velocity #V = VectorH1(mesh,order=3, dirichlet='inlet')   # velocity Q = H1(mesh,order=2, dirichlet='inlet|outlet|right|left')    # pressure X = V * Q # obtain test and trial functions u,p = X.TrialFunction() v,q = X.TestFunction() # space for solution data gfu = GridFunction(X) # boundary condition uin = CoefficientFunction((U,0,0)) gfu.components[0].Set(uin, definedon=mesh.Boundaries("bottom")) # draw the boundary conditions Draw (Norm(gfu.components[0]), mesh, "velocity", sd=3) nu = (eta/rho) SetNumThreads(8) with TaskManager():     # right hand side of the equation     f = LinearForm(X)     f.Assemble()     # left hand side of the equation     stokes = nu*InnerProduct(grad(u), grad(v))+div(u)*q+div(v)*p - 1e-10*p*q     #stokes = (eta/rho)*InnerProduct(grad(u), grad(v)) + div(u)*q - div(v)*p + InnerProduct(v,div(u)*u) - 1e-12*p*q     a = BilinearForm(X, symmetric=True)     a += stokes*dx     a.Assemble()     # calculate solution data     inv_stokes = a.mat.Inverse(X.FreeDofs(), inverse="sparsecholesky")     res = f.vec.CreateVector()     res.data = f.vec - a.mat*gfu.vec     gfu.vec.data += inv_stokes * res # density free pressure --> pressure gfu.components[1].vec.data.FV().NumPy()[:] = gfu.components[1].vec.data.FV().NumPy() * rho velocity = gfu.components[0] # friction calculation c_u = GridFunction(Q) c_u.Set(velocity[0]) c_w = GridFunction(Q) c_w.Set(velocity[2]) Draw(Norm(Grad(velocity)),mesh,'velocity gradient') dudz = Grad(c_u)[2] dwdx = Grad(c_w)[0] tau = eta * (dudz + dwdx) #Draw(Norm(Grad(velocity)),mesh,'text') #Draw(tau,mesh,'dudz') F_fric = Integrate(cf = tau,mesh=mesh,VOL_or_BND=BND,definedon=mesh.Boundaries('bottom')) print('Friction force:',F_fric)


Best regards,
Niklas
 
More
1 year 8 months ago #4461 by mneunteufel
Hi Niklas,

integrating the gradient of an H1-GridFunction over the boundary will give zero (the gradient of H1 is in L2 -more precisely in HCurl- and therefore no -more precisely only the tangential- trace is defined).

Either you first interpolate the gradient of the GridFunction into another H1-GridFunction and then integrate this GridFunction over the boundary, or you use the before mentioned approach with the testfunction. I would recommend the second option, which is more accurate.

Best,
Michael
Time to create page: 0.136 seconds