示例#1
0
文件: main.cpp 项目: Rlahuerta/dolfin
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;
}
示例#2
0
文件: main.cpp 项目: alogg/dolfin
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;
}