int main() { // Sub domain for right part of mesh class Right : public SubDomain { bool inside(const Array<double>& x, bool on_boundary) const { return x[0] <= 0.5; } }; // Sub domain for inflow (right) class Inflow : public SubDomain { bool inside(const Array<double>& x, bool on_boundary) const { return x[0] > 1.0 - DOLFIN_EPS && on_boundary; } }; UnitSquareMesh mesh(5, 5); parameters["refinement_algorithm"] = "plaza_with_parent_facets"; // Create MeshFunction over cells MeshFunction<std::size_t> right_cells(mesh, mesh.topology().dim(), 0); Right right; right.mark(right_cells, 1); // Create MeshFunction over facets MeshFunction<std::size_t> inflow_facets(mesh, mesh.topology().dim() - 1, 0); Inflow inflow; inflow.mark(inflow_facets, 1); // Mark cells for refinement MeshFunction<bool> cell_markers(mesh, mesh.topology().dim(), false); Point p(1.0, 0.0); for (CellIterator c(mesh); !c.end(); ++c) { if (c->midpoint().distance(p) < 0.5) cell_markers[*c] = true; } // Refine mesh adapt(mesh, cell_markers); // Adapt cell function to refined mesh adapt(right_cells, mesh.child_shared_ptr()); // Adapt facet function to refined mesh adapt(inflow_facets, mesh.child_shared_ptr()); return 0; }
int main() { // Dirichlet boundary condition for clamp at left end class Clamp : public Expression { public: Clamp() : Expression(3) {} void eval(Array<double>& values, const Array<double>& x) const { values[0] = 0.0; values[1] = 0.0; values[2] = 0.0; } }; // Sub domain for clamp at left end class Left : public SubDomain { bool inside(const Array<double>& x, bool on_boundary) const { return x[0] < 0.5 && on_boundary; } }; // Dirichlet boundary condition for rotation at right end class Rotation : public Expression { public: Rotation() : Expression(3) {} void eval(Array<double>& values, const Array<double>& x) const { // Center of rotation const double y0 = 0.5; const double z0 = 0.219; // Angle of rotation (30 degrees) const double theta = 0.5236; // New coordinates const double y = y0 + (x[1] - y0)*cos(theta) - (x[2] - z0)*sin(theta); const double z = z0 + (x[1] - y0)*sin(theta) + (x[2] - z0)*cos(theta); // Clamp at right end values[0] = 0.0; values[1] = y - x[1]; values[2] = z - x[2]; } }; // Sub domain for rotation at right end class Right : public SubDomain { bool inside(const Array<double>& x, bool on_boundary) const { return x[0] > 0.9 && on_boundary; } }; // Read mesh and create function space Mesh mesh("gear.xml.gz"); Elasticity::Form_a::TestSpace V(mesh); // Create right-hand side Constant f(0.0, 0.0, 0.0); // Set up boundary condition at left end Clamp c; Left left; DirichletBC bcl(V, c, left); // Set up boundary condition at right end Rotation r; Right right; DirichletBC bcr(V, r, right); // Collect boundary conditions std::vector<const BoundaryCondition*> bcs; bcs.push_back(&bcl); bcs.push_back(&bcr); std::vector<const DirichletBC*> _bcs; _bcs.push_back(&bcl); _bcs.push_back(&bcr); // Set elasticity parameters double E = 10.0; double nu = 0.3; Constant mu(E / (2*(1 + nu))); Constant lambda(E*nu / ((1 + nu)*(1 - 2*nu))); // Define variational problem Elasticity::Form_a a(V, V); a.mu = mu; a.lmbda = lambda; Elasticity::Form_L L(V); L.f = f; Function u(V); LinearVariationalProblem problem(a, L, u, bcs); // Compute solution LinearVariationalSolver solver(problem); solver.parameters["symmetric"] = true; solver.parameters["linear_solver"] = "direct"; solver.solve(); // Extract solution components (deep copy) Function ux = u[0]; Function uy = u[1]; Function uz = u[2]; std::cout << "Norm (u): " << u.vector()->norm("l2") << std::endl; std::cout << "Norm (ux, uy, uz): " << ux.vector()->norm("l2") << " " << uy.vector()->norm("l2") << " " << uz.vector()->norm("l2") << std::endl; // Save solution in VTK format File vtk_file("elasticity.pvd", "compressed"); vtk_file << u; // Extract stress and write in VTK format Elasticity::Form_a_s::TestSpace W(mesh); Elasticity::Form_a_s a_s(W, W); Elasticity::Form_L_s L_s(W); L_s.mu = mu; L_s.lmbda = lambda; L_s.disp = u; Function stress(W); LocalSolver local_solver; local_solver.solve(*stress.vector(), a_s, L_s); File file_stress("stress.pvd"); file_stress << stress; // Save colored mesh paritions in VTK format if running in parallel if (dolfin::MPI::num_processes() > 1) { CellFunction<std::size_t> partitions(mesh, dolfin::MPI::process_number()); File file("partitions.pvd"); file << partitions; } // Write boundary condition facets markers to VTK format MeshFunction<std::size_t> facet_markers(mesh, 2, 0); left.mark(facet_markers, 1); right.mark(facet_markers, 2); File facet_file("facet_markers.pvd"); facet_file << facet_markers; // Plot solution plot(u, "Displacement", "displacement"); // Displace mesh and plot displaced mesh mesh.move(u); plot(mesh, "Deformed mesh"); // Make plot windows interactive interactive(); return 0; }