This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

Result of FEM computation depends on number of processes: issue with using a 2D function in 3D?

0 votes

Dear All,

I have a fenics code whose results depend on the number of processes when ran in parallel. Not surprisingly I am deeply concerned about this. After my analysis I am not sure whether it is a bug. Anyhow, if somebody knew about a workaround that would be great.

I am solving a steady state advection diffusion equation in 3D with a 2D velocity u(x,y). I solve the velocity field in a separate program, load it from disk, and use Expression to define a 3D velocity g(x,y,z)=u(x,y) which I can use when I define the bilinear form.

The general idea is outlined below. I played with my code and found that if I replace the line which is marked by #(*) below (e. g., I do not call u_old(x,y)), the problem does not occur.

from dolfin import *
from mpi4py import MPI

comm = MPI.COMM_WORLD
rank = comm.Get_rank()

#Some global variables
Order = 2

def MakeUFunction2(FlowFieldMesh="TestFlowMesh",FlowField="TestFlowField"):
   old_mesh=Mesh(FlowFieldMesh+".xml")
   V_old = FunctionSpace(old_mesh,"Lagrange",Order)
   u_old = Function(V_old,FlowField+".xml")
   u_old.set_allow_extrapolation(True)
   class MyExpression(Expression):
      def eval(self,value,x):
         value[0] = u_old(x[0],x[1]) #(*)
         #value[0]=0 #Now it is independent of number of processes
     def value_shape(self):
        return (1,)
   g = MyExpression(degree=3)
   print "Example output: rank  "+str(rank) + ".....u_old(0,0)" +str(u_old(0,0)) #(**)
   ##########Debug lines to make sure that g/u_old was loaded correctly. 
   uip = interpolate(g,V_old)        
   fd = File("FlowDump.pvd")
   d<<uip 
   ##########End Debug.
   return g


def SolveAdvectionDiffusionEquation(...): #Example
   #(...)
   a = inner(grad(c),grad(v))*dx+U*u*c.dx(2)*v*dx
   #(...)
   L = f*v*dx() + g*v*ds()
   #(...)

I suspected that it is an issue with extrapolating u_old, so I switched off the extrapolation - set_allow_extrapolation(False)). In this case, the code crashes complaining that I tried to evaluate u_old at a value outside of its domain and suggests to switch extrapolation on.

Even more suspicious now, I added the line marked by #(**). If extrapolation is not allowed, the code crashes if the number of processes is >1, if it is allowed and the number of processes is >1 most processes obtain values which do not make sense (I expect zero).

Any ideas?


I suspect the problem is the following:

The function u_old is partitioned between the processes in 2D, since the mesh is 2D. Each process can evaluate u_old (and therefore g) only for those x,y-values for which it has the partition. That's why it crashes at line #(**) when extrapolation is switched off and gives some pretty far off values when extrapolation is switched on.

I believe that (based on the vtu-files when saved for paraview) the 3D mesh for the advection diffusion equation is partitioned along the z-axes between the processes. Thus, when each process evaluates g(x,y,z) = u_old(x,y) the parts of u_old(x,y) which are not part of the processes' share have to extrapolated, which leads to inaccurate results.


Working example: the function MakeUFunction2() should work, mesh and flow field are given here

asked Jun 26, 2017 by merlinaetzold FEniCS Novice (520 points)
edited Jun 27, 2017 by merlinaetzold

"Thus, when each process evaluates g(x,y,z) = u_old(x,y) the parts of u_old(x,y) which are not part of the processes' share have to extrapolated, which leads to inaccurate results."

-> I had an identical issue, I think that's the point. Unfortunately, I haven't solved the problem completely since I worked on other things in the last time. Despite, I don't understand why you are using the u_old Function to set values in an expression to interpolate this expression on the same Functionspace again.

Thank you for your reply - glad to see that I am not the only one with the problem and sad that you have not solved it yet. For some of the geometries I am interested in I have an analytical solution which I am using now, for the others I have to see... will probably project on a 3D mesh :(

Despite, I don't understand why you are using the u_old Function to set values in an expression to interpolate this expression on the same Functionspace again.<

Thank you for your comment - this was for debugging purposes only and I forgot to remove the line. I am going to update my initial question accordingly.

1 Answer

0 votes

Try defining:

old_mesh=Mesh(mpi_comm_self(), FlowFieldMesh+".xml")
answered Jun 28, 2017 by umberto FEniCS User (6,440 points)
...