Exemplo n.º 1
0
//-----------------------------------------------------------------------------
void dolfin::assemble_multimesh(GenericTensor& A, const MultiMeshForm& a)
{
  MultiMeshAssembler assembler;
  assembler.assemble(A, a);
}
Exemplo n.º 2
0
  void test_assembly()
  {
    // Set some parameters
    parameters["reorder_dofs_serial"] = false;

    // Some parameters
    const std::size_t N = 4;
    const std::size_t n = 2;
    const double b1 = 1.0;
    const double b2 = 1.0;

    // Right-hand side
    class Source : public Expression
    {
    public:
      Source() : Expression(2) {}

      void eval(Array<double>& values, const Array<double>& x) const
      {
        values[0] = 2*DOLFIN_PI*sin(2*DOLFIN_PI*x[1])*
          (cos(2*DOLFIN_PI*x[0]) -
           2*DOLFIN_PI*DOLFIN_PI*cos(2*DOLFIN_PI*x[0]) +
           DOLFIN_PI*DOLFIN_PI);
        values[1] = 2*DOLFIN_PI*sin(2*DOLFIN_PI*x[0])*
          (cos(2*DOLFIN_PI*x[1]) +
           2*DOLFIN_PI*DOLFIN_PI*cos(2*DOLFIN_PI*x[1]) -
           DOLFIN_PI*DOLFIN_PI);
      }
    } source;

    // Subdomain for no-slip boundary
    class DirichletBoundary : public SubDomain
    {
      bool inside(const Array<double>& x, bool on_boundary) const
      {
        return on_boundary and
          (near(x[0], 0) || near(x[0], 1) ||
           near(x[1], 0) || near(x[1], 1));
      }
    } dirichlet_boundary;

    // Create meshes
    UnitSquareMesh mesh_0(N, N);
    const double c = 0.123123;
    RectangleMesh mesh_1(Point(0.5 - c, 0.5 - c), Point(0.5 + c, 0.5 + c), n, n);
    mesh_1.rotate(37, 2);

    // Create function spaces
    MultiMeshStokes2D::FunctionSpace W0(mesh_0);
    MultiMeshStokes2D::FunctionSpace W1(mesh_1);

    // Create forms
    MultiMeshStokes2D::BilinearForm a0(W0, W0);
    MultiMeshStokes2D::BilinearForm a1(W1, W1);
    MultiMeshStokes2D::LinearForm L0(W0);
    MultiMeshStokes2D::LinearForm L1(W1);
    MultiMeshStokes2D::Functional M0(mesh_0);
    MultiMeshStokes2D::Functional M1(mesh_1);

    // Build multimesh function space
    MultiMeshFunctionSpace W;
    W.parameters("multimesh")["quadrature_order"] = 3;
    W.add(W0);
    W.add(W1);
    W.build();

    // Create constants
    Constant beta_1(b1);
    Constant beta_2(b2);

    // Create solution function
    MultiMeshFunction w(W);

    // Set coefficients
    a0.w0 = beta_1;
    a1.w0 = beta_1;
    a0.w1 = beta_2;
    a1.w1 = beta_2;
    L0.w0 = source;
    L1.w0 = source;
    L0.w1 = beta_2;
    L1.w1 = beta_2;
    M0.w0 = *w.part(0);
    M1.w0 = *w.part(1);

    // Build multimesh forms
    MultiMeshForm a(W, W);
    MultiMeshForm L(W);
    MultiMeshForm M(W);
    a.add(a0);
    a.add(a1);
    L.add(L0);
    L.add(L1);
    M.add(M0);
    M.add(M1);
    a.build();
    L.build();
    M.build();

    // Create subspaces for boundary conditions
    MultiMeshSubSpace V(W, 0);
    MultiMeshSubSpace Q(W, 1);

    // Create boundary condition
    Constant zero(0, 0);
    MultiMeshDirichletBC bc(V, zero, dirichlet_boundary);

    // Assemble system matrix and right-hand side
    Matrix A;
    Vector b;
    MultiMeshAssembler assembler;
    assembler.assemble(A, a);
    assembler.assemble(b, L);

    // Apply boundary condition
    bc.apply(A, b);

    // Compute solutipon
    solve(A, *w.vector(), b);

    // Compute squared L2 norm of solution
    Scalar m;
    assembler.assemble(m, M);

    // Check value
    CPPUNIT_ASSERT_DOUBLES_EQUAL(2.217133856286212, m.get_scalar_value(), 1e-12);
  }
Exemplo n.º 3
0
// Compute solution for given mesh configuration
void solve(double t,
           double x1, double y1,
           double x2, double y2,
           bool plot_solution,
           File& u0_file, File& u1_file, File& u2_file)
{
  // Create meshes
  double r = 0.5;
  RectangleMesh mesh_0(Point(-r, -r), Point(r, r), 16, 16);
  RectangleMesh mesh_1(Point(x1 - r, y1 - r), Point(x1 + r, y1 + r), 8, 8);
  RectangleMesh mesh_2(Point(x2 - r, y2 - r), Point(x2 + r, y2 + r), 8, 8);
  mesh_1.rotate(70*t);
  mesh_2.rotate(-70*t);

  // Create function spaces
  MultiMeshPoisson::FunctionSpace V0(mesh_0);
  MultiMeshPoisson::FunctionSpace V1(mesh_1);
  MultiMeshPoisson::FunctionSpace V2(mesh_2);

  // FIXME: Some of this stuff may be wrapped or automated later to
  // avoid needing to explicitly call add() and build()

  // Create forms
  MultiMeshPoisson::BilinearForm a0(V0, V0);
  MultiMeshPoisson::BilinearForm a1(V1, V1);
  MultiMeshPoisson::BilinearForm a2(V2, V2);
  MultiMeshPoisson::LinearForm L0(V0);
  MultiMeshPoisson::LinearForm L1(V1);
  MultiMeshPoisson::LinearForm L2(V2);

  // Build multimesh function space
  MultiMeshFunctionSpace V;
  V.parameters("multimesh")["quadrature_order"] = 2;
  V.add(V0);
  V.add(V1);
  V.add(V2);
  V.build();

  // Set coefficients
  Source f;
  L0.f = f;
  L1.f = f;
  L2.f = f;

  // Build multimesh forms
  MultiMeshForm a(V, V);
  MultiMeshForm L(V);
  a.add(a0);
  a.add(a1);
  a.add(a2);
  L.add(L0);
  L.add(L1);
  L.add(L2);
  a.build();
  L.build();

  // Create boundary condition
  Constant zero(0);
  DirichletBoundary boundary;
  MultiMeshDirichletBC bc(V, zero, boundary);

  // Assemble linear system
  Matrix A;
  Vector b;
  MultiMeshAssembler assembler;
  assembler.assemble(A, a);
  assembler.assemble(b, L);

  // Apply boundary condition
  bc.apply(A, b);

  // Compute solution
  MultiMeshFunction u(V);
  solve(A, *u.vector(), b);

  // Save to file
  u0_file << *u.part(0);
  u1_file << *u.part(1);
  u2_file << *u.part(2);

  // Plot solution (last time)
  if (plot_solution)
  {
    plot(V.multimesh());
    plot(u.part(0), "u_0");
    plot(u.part(1), "u_1");
    plot(u.part(2), "u_2");
    interactive();
  }
  }