//----------------------------------------------------------------------------- double dolfin::assemble(const Form& a) { if (a.rank() != 0) { dolfin_error("assemble.cpp", "assemble form", "Expecting a scalar form but rank is %d", a.rank()); } Scalar s; Assembler assembler; assembler.assemble(s, a); return s.get_scalar_value(); }
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); }