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

Wrong DirichletBC dimension in 3D

0 votes

I am implementing a 3D mixed poission equation using RT0 elements. Everything is done using the C++ version of FEniCS.

I am getting this error regarding my Dirichlet boundary conditions, the error message is below:

*** -------------------------------------------------------------------------
*** Error:   Unable to create Dirichlet boundary condition.
*** Reason:  Illegal value dimension (3), expecting (2).
*** Where:   This error was encountered inside DirichletBC.cpp.
*** Process: unknown
*** 
*** DOLFIN version: 1.5.0
*** Git changeset:  f467b66dcfd821ec20e9f9070c7cef5a991dbc42
*** -------------------------------------------------------------------------

Here's my ufl file:

V = FiniteElement("RT", triangle, 1)
P  = FiniteElement("DG", triangle, 0)
W = V * P

# Trial and test functions
(v,p) = TrialFunctions(W)
(w,q) = TestFunctions(W)

# Define coefficients
n = FacetNormal(triangle)
alpha = Constant(triangle)
rhob = Coefficient(V)
p_Production = Constant(triangle)
p_Injection = Constant(triangle)

a = dot(alpha*v,w)*dx - p*div(w)*dx - div(v)*q*dx
L = dot(rhob,w)*dx - dot(w,n)*p_Production*ds(9) - dot(w,n)*p_Injection*ds(7) - dot(w,n)*p_Injection*ds(8)

And the main.cpp:

#include <dolfin.h>
#include "RT0.h"
//#include "papi.h"

using namespace dolfin;

// Boundaries
class SE : public SubDomain
{
  bool inside(const Array<double>& x, bool on_boundary) const
  { return near(x[1],0.0,DOLFIN_EPS) && x[0] >= 1;}
};

class SW : public SubDomain
{
  bool inside(const Array<double>& x, bool on_boundary) const
  { return near(x[0],0.0,DOLFIN_EPS) && x[1] >= 1;}
};

class NW : public SubDomain
{
  bool inside(const Array<double>& x, bool on_boundary) const
  { return near(x[1],100.0,DOLFIN_EPS);}
};

class NE : public SubDomain
{
  bool inside(const Array<double>& x, bool on_boundary) const
  { return near(x[2],100.0,DOLFIN_EPS);}
};

class Top : public SubDomain
{
  bool inside(const Array<double>& x, bool on_boundary) const
  { return near(x[2], 30.0, DOLFIN_EPS) && (x[0] <= 99 || x[1] <= 99);}
};

class Bottom: public SubDomain
{
  bool inside(const Array<double>& x, bool on_boundary) const
  { return near(x[2], 0.0, DOLFIN_EPS);}
};

class SEpressure : public SubDomain
{
  bool inside(const Array<double>& x, bool on_boundary) const
  { return near(x[1],0.0,DOLFIN_EPS) && x[0] <= 1;}
};

class SWpressure : public SubDomain
{
  bool inside(const Array<double>& x, bool on_boundary) const
  { return near(x[0],0.0,DOLFIN_EPS) && x[1] <= 1;}
};

class Toppressure : public SubDomain
{
  bool inside(const Array<double>& x, bool on_boundary) const
  { return near(x[2], 30.0, DOLFIN_EPS) && (x[0] >= 99 && x[1] >= 99);}
};

// Boundary source for flux boundary condition
class BoundarySource : public Expression
{
  public:

    BoundarySource(const Mesh& mesh) : Expression(3), mesh(mesh) {}

    void eval(Array<double>& values, const Array<double>& x,
              const ufc::cell& ufc_cell) const
    {
      dolfin_assert(ufc_cell.local_facet >= 0);

      Cell cell(mesh, ufc_cell.index);
      Point n = cell.normal(ufc_cell.local_facet);

      const double g = 0;
      values[0] = g*n[0];
      values[1] = g*n[1];
      values[2] = g*n[2];
    }

  private:
    const Mesh& mesh; 
};

int main(int argc, char* argv[])
{ 
  // Read any command line flags
  parameters.parse(argc,argv);

  // Create mesh
  BoxMesh mesh(0,0,0,100,100,30,200,200,5);

  // Construct function space
  RT0::FunctionSpace W(mesh);
  RT0::BilinearForm a(W, W);
  RT0::LinearForm L(W);

  // Define boundaries
  SubSpace W0(W, 0);
  BoundarySource G(mesh);
  SW sw;
  SE se;
  NE ne;
  NW nw;
  Top top;
  Bottom bottom;
  SWpressure swpressure;
  SEpressure sepressure;
  Toppressure toppressure;
  MeshFunction<std::size_t> boundaries(mesh,mesh.topology().dim()-1);
  boundaries.set_all(0);
  sw.mark(boundaries,1);
  se.mark(boundaries,2);
  ne.mark(boundaries,3);
  nw.mark(boundaries,4);
  top.mark(boundaries,5);
  bottom.mark(boundaries,6);
  swpressure.mark(boundaries,7);
  sepressure.mark(boundaries,8);
  toppressure.mark(boundaries,9);

  // Apply boundary conditions
  DirichletBC bc1(W0,G,sw);
  DirichletBC bc2(W0,G,se);
  DirichletBC bc3(W0,G,ne);
  DirichletBC bc4(W0,G,nw);
  DirichletBC bc5(W0,G,top);
  DirichletBC bc6(W0,G,bottom);
  std::vector<const DirichletBC*> bcs;
  bcs.push_back(&bc1);
  bcs.push_back(&bc2);
  bcs.push_back(&bc3);
  bcs.push_back(&bc4);
  bcs.push_back(&bc5);
  bcs.push_back(&bc6);

  // Material properties
  Constant alpha(3.95e7);
  Constant rhob(0.0,0.0,-4699);
  Constant p_Production(101325.0);
  Constant p_Injection(101325000.0);
  a.alpha = alpha;
  L.rhob = rhob;
  L.p_Production = p_Production;
  L.p_Injection = p_Injection;

  // Compute solution
  Function w(W);
  Matrix A;
  Vector b;
  assemble_system(A,b,a,L,bcs);
  solve(A,*w.vector(),b,"gmres","bjacobi");

  // Extract sub functions (function views)
  Function& sigma = w[0];
  Function& u = w[1];
  list_timings();
  // Plot solutions
  //plot(u);
  //plot(sigma);
  //interactive();

  return 0;
}

This is a 3D problem, but it seems my program (namely the DirichletBC) keeps expecting a 2D problem. Any idea how to fix this? Thanks.

asked Mar 2, 2015 by jychang48 FEniCS Novice (510 points)

1 Answer

0 votes
 
Best answer

Hi, try

cell = tetrahedron
V = FiniteElement("RT", cell, 1)
P  = FiniteElement("DG", cell, 0)
W = V * P

# Trial and test functions
(v,p) = TrialFunctions(W)
(w,q) = TestFunctions(W)

# Define coefficients
n = FacetNormal(cell)
alpha = Constant(cell)
rhob = Coefficient(V)
p_Production = Constant(cell)
p_Injection = Constant(cell)
answered Mar 2, 2015 by MiroK FEniCS Expert (80,920 points)
selected Mar 3, 2015 by jychang48

That did the trick, thanks

...