Ejemplo n.º 1
0
Tree<N>::Tree (const MeshBase & m,
               unsigned int target_bin_size,
               const Trees::BuildType bt) :
  TreeBase(m),
  root(m,target_bin_size),
  build_type(bt)
{
  // Set the root node bounding box equal to the bounding
  // box for the entire domain.
  root.set_bounding_box (MeshTools::bounding_box(mesh));

  if (build_type == Trees::NODES)
    {
      // Add all the nodes to the root node.  It will
      // automagically build the tree for us.
      MeshBase::const_node_iterator       it  = mesh.nodes_begin();
      const MeshBase::const_node_iterator end = mesh.nodes_end();

      for (; it != end; ++it)
        {
#ifndef NDEBUG
          bool node_was_inserted =
#endif
            root.insert (*it);
          libmesh_assert(node_was_inserted);
        }

      // Now the tree contains the nodes.
      // However, we want element pointers, so here we
      // convert between the two.
      std::vector<std::vector<const Elem *> > nodes_to_elem;

      MeshTools::build_nodes_to_elem_map (mesh, nodes_to_elem);
      root.transform_nodes_to_elements (nodes_to_elem);
    }

  else if (build_type == Trees::ELEMENTS)
    {
      // Add all active elements to the root node.  It will
      // automatically build the tree for us.
      MeshBase::const_element_iterator       it  = mesh.active_elements_begin();
      const MeshBase::const_element_iterator end = mesh.active_elements_end();

      for (; it != end; ++it)
        {
#ifndef NDEBUG
          bool elem_was_inserted =
#endif
            root.insert (*it);
          libmesh_assert(elem_was_inserted);
        }
    }

  else if (build_type == Trees::LOCAL_ELEMENTS)
    {
      // Add all active, local elements to the root node.  It will
      // automatically build the tree for us.
      MeshBase::const_element_iterator       it  = mesh.active_local_elements_begin();
      const MeshBase::const_element_iterator end = mesh.active_local_elements_end();

      for (; it != end; ++it)
        {
#ifndef NDEBUG
          bool elem_was_inserted =
#endif
            root.insert (*it);
          libmesh_assert(elem_was_inserted);
        }
    }

  else
    libmesh_error_msg("Unknown build_type = " << build_type);
}
Ejemplo n.º 2
0
void FEXYZ<Dim>::compute_face_values(const Elem * elem,
                                     const Elem * side,
                                     const std::vector<Real> & qw)
{
  libmesh_assert(elem);
  libmesh_assert(side);

  START_LOG("compute_face_values()", "FEXYZ");

  // The number of quadrature points.
  const std::size_t n_qp = qw.size();

  // Number of shape functions in the finite element approximation
  // space.
  const unsigned int n_approx_shape_functions =
    this->n_shape_functions(this->get_type(),
                            this->get_order());

  // Resize the shape functions and their gradients
  this->phi.resize    (n_approx_shape_functions);
  this->dphi.resize   (n_approx_shape_functions);
  this->dphidx.resize (n_approx_shape_functions);
  this->dphidy.resize (n_approx_shape_functions);
  this->dphidz.resize (n_approx_shape_functions);

  for (unsigned int i=0; i<n_approx_shape_functions; i++)
    {
      this->phi[i].resize    (n_qp);
      this->dphi[i].resize   (n_qp);
      this->dphidx[i].resize (n_qp);
      this->dphidy[i].resize (n_qp);
      this->dphidz[i].resize (n_qp);
    }

  this->_fe_map->compute_face_map(this->dim, qw, side);

  const std::vector<libMesh::Point> & xyz = this->_fe_map->get_xyz();

  switch (this->dim)
    {
      // A 2D finite element living in either 2D or 3D space.
      // This means the boundary is a 1D finite element, i.e.
      // and EDGE2 or EDGE3.
    case 2:
      {
        // compute the shape function values & gradients
        for (unsigned int i=0; i<n_approx_shape_functions; i++)
          for (std::size_t p=0; p<n_qp; p++)
            {
              this->phi[i][p] = FE<Dim,XYZ>::shape (elem, this->fe_type.order, i, xyz[p]);

              this->dphi[i][p](0) =
                this->dphidx[i][p] = FE<Dim,XYZ>::shape_deriv (elem, this->fe_type.order, i, 0, xyz[p]);

              this->dphi[i][p](1) =
                this->dphidy[i][p] = FE<Dim,XYZ>::shape_deriv (elem, this->fe_type.order, i, 1, xyz[p]);

#if LIBMESH_DIM == 3
              this->dphi[i][p](2) = // can only assign to the Z component if LIBMESH_DIM==3
#endif
                this->dphidz[i][p] = 0.;
            }

        // done computing face values
        break;
      }

      // A 3D finite element living in 3D space.
    case 3:
      {
        // compute the shape function values & gradients
        for (unsigned int i=0; i<n_approx_shape_functions; i++)
          for (std::size_t p=0; p<n_qp; p++)
            {
              this->phi[i][p] = FE<Dim,XYZ>::shape (elem, this->fe_type.order, i, xyz[p]);

              this->dphi[i][p](0) =
                this->dphidx[i][p] = FE<Dim,XYZ>::shape_deriv (elem, this->fe_type.order, i, 0, xyz[p]);

              this->dphi[i][p](1) =
                this->dphidy[i][p] = FE<Dim,XYZ>::shape_deriv (elem, this->fe_type.order, i, 1, xyz[p]);

              this->dphi[i][p](2) =
                this->dphidz[i][p] = FE<Dim,XYZ>::shape_deriv (elem, this->fe_type.order, i, 2, xyz[p]);
            }

        // done computing face values
        break;
      }

    default:
      libmesh_error_msg("Invalid dim " << this->dim);
    }

  STOP_LOG("compute_face_values()", "FEXYZ");
}
Ejemplo n.º 3
0
Real FE<3,MONOMIAL>::shape_second_deriv(const ElemType,
                                        const Order libmesh_dbg_var(order),
                                        const unsigned int i,
                                        const unsigned int j,
                                        const Point& p)
{
#if LIBMESH_DIM == 3

  libmesh_assert_less (j, 6);

  libmesh_assert_less (i, (static_cast<unsigned int>(order)+1)*
                       (static_cast<unsigned int>(order)+2)*
                       (static_cast<unsigned int>(order)+3)/6);

  const Real xi   = p(0);
  const Real eta  = p(1);
  const Real zeta = p(2);

  // monomials. since they are hierarchic we only need one case block.
  switch (j)
    {
      // d^2()/dxi^2
    case 0:
      {
        switch (i)
          {
            // constant
          case 0:

            // linear
          case 1:
          case 2:
          case 3:
            return 0.;

            // quadratic
          case 4:
            return 2.;

          case 5:
          case 6:
          case 7:
          case 8:
          case 9:
            return 0.;

            // cubic
          case 10:
            return 6.*xi;

          case 11:
            return 2.*eta;

          case 12:
          case 13:
            return 0.;

          case 14:
            return 2.*zeta;

          case 15:
          case 16:
          case 17:
          case 18:
          case 19:
            return 0.;

            // quartics
          case 20:
            return 12.*xi*xi;

          case 21:
            return 6.*xi*eta;

          case 22:
            return 2.*eta*eta;

          case 23:
          case 24:
            return 0.;

          case 25:
            return 6.*xi*zeta;

          case 26:
            return 2.*eta*zeta;

          case 27:
          case 28:
            return 0.;

          case 29:
            return 2.*zeta*zeta;

          case 30:
          case 31:
          case 32:
          case 33:
          case 34:
            return 0.;

          default:
            unsigned int o = 0;
            for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
            unsigned int i2 = i - (o*(o+1)*(o+2)/6);
            unsigned int block=o, nz = 0;
            for (; block < i2; block += (o-nz+1)) { nz++; }
            const unsigned int nx = block - i2;
            const unsigned int ny = o - nx - nz;
            Real val = nx * (nx - 1);
            for (unsigned int index=2; index < nx; index++)
              val *= xi;
            for (unsigned int index=0; index != ny; index++)
              val *= eta;
            for (unsigned int index=0; index != nz; index++)
              val *= zeta;
            return val;
          }
      }


      // d^2()/dxideta
    case 1:
      {
        switch (i)
          {
            // constant
          case 0:

            // linear
          case 1:
          case 2:
          case 3:
            return 0.;

            // quadratic
          case 4:
            return 0.;

          case 5:
            return 1.;

          case 6:
          case 7:
          case 8:
          case 9:
            return 0.;

            // cubic
          case 10:
            return 0.;

          case 11:
            return 2.*xi;

          case 12:
            return 2.*eta;

          case 13:
          case 14:
            return 0.;

          case 15:
            return zeta;

          case 16:
          case 17:
          case 18:
          case 19:
            return 0.;

            // quartics
          case 20:
            return 0.;

          case 21:
            return 3.*xi*xi;

          case 22:
            return 4.*xi*eta;

          case 23:
            return 3.*eta*eta;

          case 24:
          case 25:
            return 0.;

          case 26:
            return 2.*xi*zeta;

          case 27:
            return 2.*eta*zeta;

          case 28:
          case 29:
            return 0.;

          case 30:
            return zeta*zeta;

          case 31:
          case 32:
          case 33:
          case 34:
            return 0.;

          default:
            unsigned int o = 0;
            for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
            unsigned int i2 = i - (o*(o+1)*(o+2)/6);
            unsigned int block=o, nz = 0;
            for (; block < i2; block += (o-nz+1)) { nz++; }
            const unsigned int nx = block - i2;
            const unsigned int ny = o - nx - nz;
            Real val = nx * ny;
            for (unsigned int index=1; index < nx; index++)
              val *= xi;
            for (unsigned int index=1; index < ny; index++)
              val *= eta;
            for (unsigned int index=0; index != nz; index++)
              val *= zeta;
            return val;
          }
      }


      // d^2()/deta^2
    case 2:
      {
        switch (i)
          {
            // constant
          case 0:

            // linear
          case 1:
          case 2:
          case 3:
            return 0.;

            // quadratic
          case 4:
          case 5:
            return 0.;

          case 6:
            return 2.;

          case 7:
          case 8:
          case 9:
            return 0.;

            // cubic
          case 10:
          case 11:
            return 0.;

          case 12:
            return 2.*xi;
          case 13:
            return 6.*eta;

          case 14:
          case 15:
            return 0.;

          case 16:
            return 2.*zeta;

          case 17:
          case 18:
          case 19:
            return 0.;

            // quartics
          case 20:
          case 21:
            return 0.;

          case 22:
            return 2.*xi*xi;

          case 23:
            return 6.*xi*eta;

          case 24:
            return 12.*eta*eta;

          case 25:
          case 26:
            return 0.;

          case 27:
            return 2.*xi*zeta;

          case 28:
            return 6.*eta*zeta;

          case 29:
          case 30:
            return 0.;

          case 31:
            return 2.*zeta*zeta;

          case 32:
          case 33:
          case 34:
            return 0.;

          default:
            unsigned int o = 0;
            for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
            unsigned int i2 = i - (o*(o+1)*(o+2)/6);
            unsigned int block=o, nz = 0;
            for (; block < i2; block += (o-nz+1)) { nz++; }
            const unsigned int nx = block - i2;
            const unsigned int ny = o - nx - nz;
            Real val = ny * (ny - 1);
            for (unsigned int index=0; index != nx; index++)
              val *= xi;
            for (unsigned int index=2; index < ny; index++)
              val *= eta;
            for (unsigned int index=0; index != nz; index++)
              val *= zeta;
            return val;
          }
      }


      // d^2()/dxidzeta
    case 3:
      {
        switch (i)
          {
            // constant
          case 0:

            // linear
          case 1:
          case 2:
          case 3:
            return 0.;

            // quadratic
          case 4:
          case 5:
          case 6:
            return 0.;

          case 7:
            return 1.;

          case 8:
          case 9:
            return 0.;

            // cubic
          case 10:
          case 11:
          case 12:
          case 13:
            return 0.;

          case 14:
            return 2.*xi;

          case 15:
            return eta;

          case 16:
            return 0.;

          case 17:
            return 2.*zeta;

          case 18:
          case 19:
            return 0.;

            // quartics
          case 20:
          case 21:
          case 22:
          case 23:
          case 24:
            return 0.;

          case 25:
            return 3.*xi*xi;

          case 26:
            return 2.*xi*eta;

          case 27:
            return eta*eta;

          case 28:
            return 0.;

          case 29:
            return 4.*xi*zeta;

          case 30:
            return 2.*eta*zeta;

          case 31:
            return 0.;

          case 32:
            return 3.*zeta*zeta;

          case 33:
          case 34:
            return 0.;

          default:
            unsigned int o = 0;
            for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
            unsigned int i2 = i - (o*(o+1)*(o+2)/6);
            unsigned int block=o, nz = 0;
            for (; block < i2; block += (o-nz+1)) { nz++; }
            const unsigned int nx = block - i2;
            const unsigned int ny = o - nx - nz;
            Real val = nx * nz;
            for (unsigned int index=1; index < nx; index++)
              val *= xi;
            for (unsigned int index=0; index != ny; index++)
              val *= eta;
            for (unsigned int index=1; index < nz; index++)
              val *= zeta;
            return val;
          }
      }

      // d^2()/detadzeta
    case 4:
      {
        switch (i)
          {
            // constant
          case 0:

            // linear
          case 1:
          case 2:
          case 3:
            return 0.;

            // quadratic
          case 4:
          case 5:
          case 6:
          case 7:
            return 0.;

          case 8:
            return 1.;

          case 9:
            return 0.;

            // cubic
          case 10:
          case 11:
          case 12:
          case 13:
          case 14:
            return 0.;

          case 15:
            return xi;

          case 16:
            return 2.*eta;

          case 17:
            return 0.;

          case 18:
            return 2.*zeta;

          case 19:
            return 0.;

            // quartics
          case 20:
          case 21:
          case 22:
          case 23:
          case 24:
          case 25:
            return 0.;

          case 26:
            return xi*xi;

          case 27:
            return 2.*xi*eta;

          case 28:
            return 3.*eta*eta;

          case 29:
            return 0.;

          case 30:
            return 2.*xi*zeta;

          case 31:
            return 4.*eta*zeta;

          case 32:
            return 0.;

          case 33:
            return 3.*zeta*zeta;

          case 34:
            return 0.;

          default:
            unsigned int o = 0;
            for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
            unsigned int i2 = i - (o*(o+1)*(o+2)/6);
            unsigned int block=o, nz = 0;
            for (; block < i2; block += (o-nz+1)) { nz++; }
            const unsigned int nx = block - i2;
            const unsigned int ny = o - nx - nz;
            Real val = ny * nz;
            for (unsigned int index=0; index != nx; index++)
              val *= xi;
            for (unsigned int index=1; index < ny; index++)
              val *= eta;
            for (unsigned int index=1; index < nz; index++)
              val *= zeta;
            return val;
          }
      }


      // d^2()/dzeta^2
    case 5:
      {
        switch (i)
          {
            // constant
          case 0:

            // linear
          case 1:
          case 2:
          case 3:
            return 0.;

            // quadratic
          case 4:
          case 5:
          case 6:
          case 7:
          case 8:
            return 0.;

          case 9:
            return 2.;

            // cubic
          case 10:
          case 11:
          case 12:
          case 13:
          case 14:
          case 15:
          case 16:
            return 0.;

          case 17:
            return 2.*xi;

          case 18:
            return 2.*eta;

          case 19:
            return 6.*zeta;

            // quartics
          case 20:
          case 21:
          case 22:
          case 23:
          case 24:
          case 25:
          case 26:
          case 27:
          case 28:
            return 0.;

          case 29:
            return 2.*xi*xi;

          case 30:
            return 2.*xi*eta;

          case 31:
            return 2.*eta*eta;

          case 32:
            return 6.*xi*zeta;

          case 33:
            return 6.*eta*zeta;

          case 34:
            return 12.*zeta*zeta;

          default:
            unsigned int o = 0;
            for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
            unsigned int i2 = i - (o*(o+1)*(o+2)/6);
            unsigned int block=o, nz = 0;
            for (; block < i2; block += (o-nz+1)) { nz++; }
            const unsigned int nx = block - i2;
            const unsigned int ny = o - nx - nz;
            Real val = nz * (nz - 1);
            for (unsigned int index=0; index != nx; index++)
              val *= xi;
            for (unsigned int index=0; index != ny; index++)
              val *= eta;
            for (unsigned int index=2; index < nz; index++)
              val *= zeta;
            return val;
          }
      }

    default:
      libmesh_error_msg("Invalid j = " << j);
    }

#endif

  libmesh_error_msg("We'll never get here!");
  return 0.;
}
Ejemplo n.º 4
0
Real RBEvaluation::rb_solve(unsigned int N)
{
    LOG_SCOPE("rb_solve()", "RBEvaluation");

    if(N > get_n_basis_functions())
        libmesh_error_msg("ERROR: N cannot be larger than the number of basis functions in rb_solve");

    const RBParameters & mu = get_parameters();

    // Resize (and clear) the solution vector
    RB_solution.resize(N);

    // Assemble the RB system
    DenseMatrix<Number> RB_system_matrix(N,N);
    RB_system_matrix.zero();

    DenseMatrix<Number> RB_Aq_a;
    for(unsigned int q_a=0; q_a<rb_theta_expansion->get_n_A_terms(); q_a++)
    {
        RB_Aq_vector[q_a].get_principal_submatrix(N, RB_Aq_a);

        RB_system_matrix.add(rb_theta_expansion->eval_A_theta(q_a, mu), RB_Aq_a);
    }

    // Assemble the RB rhs
    DenseVector<Number> RB_rhs(N);
    RB_rhs.zero();

    DenseVector<Number> RB_Fq_f;
    for(unsigned int q_f=0; q_f<rb_theta_expansion->get_n_F_terms(); q_f++)
    {
        RB_Fq_vector[q_f].get_principal_subvector(N, RB_Fq_f);

        RB_rhs.add(rb_theta_expansion->eval_F_theta(q_f, mu), RB_Fq_f);
    }

    // Solve the linear system
    if(N > 0)
    {
        RB_system_matrix.lu_solve(RB_rhs, RB_solution);
    }

    // Evaluate RB outputs
    DenseVector<Number> RB_output_vector_N;
    for(unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
    {
        RB_outputs[n] = 0.;
        for(unsigned int q_l=0; q_l<rb_theta_expansion->get_n_output_terms(n); q_l++)
        {
            RB_output_vectors[n][q_l].get_principal_subvector(N, RB_output_vector_N);
            RB_outputs[n] += rb_theta_expansion->eval_output_theta(n,q_l,mu)*RB_output_vector_N.dot(RB_solution);
        }
    }

    if(evaluate_RB_error_bound) // Calculate the error bounds
    {
        // Evaluate the dual norm of the residual for RB_solution_vector
        Real epsilon_N = compute_residual_dual_norm(N);

        // Get lower bound for coercivity constant
        const Real alpha_LB = get_stability_lower_bound();
        // alpha_LB needs to be positive to get a valid error bound
        libmesh_assert_greater ( alpha_LB, 0. );

        // Evaluate the (absolute) error bound
        Real abs_error_bound = epsilon_N / residual_scaling_denom(alpha_LB);

        // Now compute the output error bounds
        for(unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
        {
            RB_output_error_bounds[n] = abs_error_bound * eval_output_dual_norm(n, mu);
        }

        return abs_error_bound;
    }
    else // Don't calculate the error bounds
    {
        // Just return -1. if we did not compute the error bound
        return -1.;
    }
}
Ejemplo n.º 5
0
Real InfHex::quality (const ElemQuality q) const
{
  switch (q)
    {

      /**
       * Compue the min/max diagonal ratio.
       * Source: CUBIT User's Manual.
       *
       * For infinite elements, we just only compute
       * the diagonal in the face...
       * Don't know whether this makes sense,
       * but should be a feasible way.
       */
    case DIAGONAL:
      {
        // Diagonal between node 0 and node 2
        const Real d02 = this->length(0,2);

        // Diagonal between node 1 and node 3
        const Real d13 = this->length(1,3);

        // Find the biggest and smallest diagonals
        const Real min = std::min(d02, d13);
        const Real max = std::max(d02, d13);

        libmesh_assert_not_equal_to (max, 0.0);

        return min / max;

        break;
      }

      /**
       * Minimum ratio of lengths derived from opposite edges.
       * Source: CUBIT User's Manual.
       *
       * For IFEMs, do this only for the base face...
       * Does this make sense?
       */
    case TAPER:
      {

        /**
         * Compute the side lengths.
         */
        const Real d01 = this->length(0,1);
        const Real d12 = this->length(1,2);
        const Real d23 = this->length(2,3);
        const Real d03 = this->length(0,3);

        std::vector<Real> edge_ratios(2);

        // Bottom
        edge_ratios[8] = std::min(d01, d23) / std::max(d01, d23);
        edge_ratios[9] = std::min(d03, d12) / std::max(d03, d12);

        return *(std::min_element(edge_ratios.begin(), edge_ratios.end())) ;

        break;
      }


      /**
       * Minimum edge length divided by max diagonal length.
       * Source: CUBIT User's Manual.
       *
       * And again, we mess around a bit, for the IFEMs...
       * Do this only for the base.
       */
    case STRETCH:
      {
        /**
         * Should this be a sqrt2, when we do this for the base only?
         */
        const Real sqrt3 = 1.73205080756888;

        /**
         * Compute the maximum diagonal in the base.
         */
        const Real d02 = this->length(0,2);
        const Real d13 = this->length(1,3);
        const Real max_diag = std::max(d02, d13);

        libmesh_assert_not_equal_to ( max_diag, 0.0 );

        /**
         * Compute the minimum edge length in the base.
         */
        std::vector<Real> edges(4);
        edges[0]  = this->length(0,1);
        edges[1]  = this->length(1,2);
        edges[2]  = this->length(2,3);
        edges[3]  = this->length(0,3);

        const Real min_edge = *(std::min_element(edges.begin(), edges.end()));
        return sqrt3 * min_edge / max_diag ;
      }


      /**
       * I don't know what to do for this metric.
       * Maybe the base class knows...
       */
    default:
      return Elem::quality(q);
    }

  libmesh_error_msg("We'll never get here!");
  return 0.;
}
Ejemplo n.º 6
0
void ExodusII_IO::set_coordinate_offset(Point)
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 7
0
void RBEvaluation::read_in_vectors_from_multiple_files(System & sys,
        std::vector< std::vector<NumericVector<Number> *> * > multiple_vectors,
        const std::vector<std::string> & multiple_directory_names,
        const std::vector<std::string> & multiple_data_names,
        const bool read_binary_vectors)
{
    LOG_SCOPE("read_in_vectors_from_multiple_files()", "RBEvaluation");

    unsigned int n_files = multiple_vectors.size();
    unsigned int n_directories = multiple_directory_names.size();
    unsigned int n_data_names = multiple_data_names.size();
    libmesh_assert( (n_files == n_directories) && (n_files == n_data_names) );

    if (n_files == 0)
        return;

    // Make sure processors are synced up before we begin
    this->comm().barrier();

    std::ostringstream file_name;
    const std::string basis_function_suffix = (read_binary_vectors ? ".xdr" : ".dat");
    struct stat stat_info;

    // Assume that all the headers are the same, hence we can just use the first one.
    file_name << multiple_directory_names[0] << "/"
              << multiple_data_names[0] << "_header" << basis_function_suffix;
    assert_file_exists(file_name.str());

    Xdr header_data(file_name.str(),
                    read_binary_vectors ? DECODE : READ);

    // set the version number in header_data from io_version_string
    // (same code as in EquationSystemsIO::_read_impl)
    std::string io_version_string = get_io_version_string();
    std::string::size_type lm_pos = io_version_string.find("libMesh");
    std::istringstream iss(io_version_string.substr(lm_pos + 8));
    int ver_major = 0, ver_minor = 0, ver_patch = 0;
    char dot;
    iss >> ver_major >> dot >> ver_minor >> dot >> ver_patch;
    header_data.set_version(LIBMESH_VERSION_ID(ver_major, ver_minor, ver_patch));

    // We need to call sys.read_header (e.g. to set _written_var_indices properly),
    // but by setting the read_header argument to false, it doesn't reinitialize the system
    sys.read_header(header_data, io_version_string, /*read_header=*/false, /*read_additional_data=*/false);

    // Following EquationSystemsIO::read, we use a temporary numbering (node major)
    // before writing out the data
    MeshTools::Private::globally_renumber_nodes_and_elements(sys.get_mesh());

    for (unsigned int data_index=0; data_index<n_directories; data_index++)
    {
        std::vector<NumericVector<Number> *> & vectors = *multiple_vectors[data_index];

        // Allocate storage for each vector
        for (unsigned int i=0; i<vectors.size(); i++)
        {
            // vectors should all be NULL, otherwise we get a memory leak when
            // we create the new vectors in RBEvaluation::read_in_vectors.
            if (vectors[i])
                libmesh_error_msg("Non-NULL vector passed to read_in_vectors_from_multiple_files");

            vectors[i] = NumericVector<Number>::build(sys.comm()).release();

            vectors[i]->init (sys.n_dofs(),
                              sys.n_local_dofs(),
                              false,
                              PARALLEL);
        }

        file_name.str("");
        file_name << multiple_directory_names[data_index]
                  << "/" << multiple_data_names[data_index]
                  << "_data" << basis_function_suffix;

        // On processor zero check to be sure the file exists
        if (this->processor_id() == 0)
        {
            int stat_result = stat(file_name.str().c_str(), &stat_info);

            if (stat_result != 0)
                libmesh_error_msg("File does not exist: " << file_name.str());
        }

        assert_file_exists(file_name.str());
        Xdr vector_data(file_name.str(),
                        read_binary_vectors ? DECODE : READ);

        // The vector_data needs to know which version to read.
        vector_data.set_version(LIBMESH_VERSION_ID(ver_major, ver_minor, ver_patch));

        sys.read_serialized_vectors (vector_data, vectors);
    }

    // Undo the temporary renumbering
    sys.get_mesh().fix_broken_node_and_element_numbering();
}
Ejemplo n.º 8
0
void ExodusII_IO::write_global_data (const std::vector<Number> &,
                                     const std::vector<std::string> &)
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 9
0
void ExodusII_IO::write_nodal_data_discontinuous (const std::string &,
                                                  const std::vector<Number> &,
                                                  const std::vector<std::string> &)
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 10
0
void ExodusII_IO::write_element_data (const EquationSystems &)
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 11
0
void ExodusII_IO::write_information_records (const std::vector<std::string> &)
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 12
0
int ExodusII_IO::get_num_time_steps()
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 13
0
const std::vector<Real> & ExodusII_IO::get_time_steps()
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 14
0
Real Hex::quality (const ElemQuality q) const
{
  switch (q)
    {

      /**
       * Compue the min/max diagonal ratio.
       * Source: CUBIT User's Manual.
       */
    case DIAGONAL:
      {
        // Diagonal between node 0 and node 6
        const Real d06 = this->length(0,6);

        // Diagonal between node 3 and node 5
        const Real d35 = this->length(3,5);

        // Diagonal between node 1 and node 7
        const Real d17 = this->length(1,7);

        // Diagonal between node 2 and node 4
        const Real d24 = this->length(2,4);

        // Find the biggest and smallest diagonals
        const Real min = std::min(d06, std::min(d35, std::min(d17, d24)));
        const Real max = std::max(d06, std::max(d35, std::max(d17, d24)));

        libmesh_assert_not_equal_to (max, 0.0);

        return min / max;

        break;
      }

      /**
       * Minimum ratio of lengths derived from opposite edges.
       * Source: CUBIT User's Manual.
       */
    case TAPER:
      {

        /**
         * Compute the side lengths.
         */
        const Real d01 = this->length(0,1);
        const Real d12 = this->length(1,2);
        const Real d23 = this->length(2,3);
        const Real d03 = this->length(0,3);
        const Real d45 = this->length(4,5);
        const Real d56 = this->length(5,6);
        const Real d67 = this->length(6,7);
        const Real d47 = this->length(4,7);
        const Real d04 = this->length(0,4);
        const Real d15 = this->length(1,5);
        const Real d37 = this->length(3,7);
        const Real d26 = this->length(2,6);

        std::vector<Real> edge_ratios(12);
        // Front
        edge_ratios[0] = std::min(d01, d45) / std::max(d01, d45);
        edge_ratios[1] = std::min(d04, d15) / std::max(d04, d15);

        // Right
        edge_ratios[2] = std::min(d15, d26) / std::max(d15, d26);
        edge_ratios[3] = std::min(d12, d56) / std::max(d12, d56);

        // Back
        edge_ratios[4] = std::min(d67, d23) / std::max(d67, d23);
        edge_ratios[5] = std::min(d26, d37) / std::max(d26, d37);

        // Left
        edge_ratios[6] = std::min(d04, d37) / std::max(d04, d37);
        edge_ratios[7] = std::min(d03, d47) / std::max(d03, d47);

        // Bottom
        edge_ratios[8] = std::min(d01, d23) / std::max(d01, d23);
        edge_ratios[9] = std::min(d03, d12) / std::max(d03, d12);

        // Top
        edge_ratios[10] = std::min(d45, d67) / std::max(d45, d67);
        edge_ratios[11] = std::min(d56, d47) / std::max(d56, d47);

        return *(std::min_element(edge_ratios.begin(), edge_ratios.end())) ;

        break;
      }


      /**
       * Minimum edge length divided by max diagonal length.
       * Source: CUBIT User's Manual.
       */
    case STRETCH:
      {
        const Real sqrt3 = 1.73205080756888;

        /**
         * Compute the maximum diagonal.
         */
        const Real d06 = this->length(0,6);
        const Real d17 = this->length(1,7);
        const Real d35 = this->length(3,5);
        const Real d24 = this->length(2,4);
        const Real max_diag = std::max(d06, std::max(d17, std::max(d35, d24)));

        libmesh_assert_not_equal_to ( max_diag, 0.0 );

        /**
         * Compute the minimum edge length.
         */
        std::vector<Real> edges(12);
        edges[0]  = this->length(0,1);
        edges[1]  = this->length(1,2);
        edges[2]  = this->length(2,3);
        edges[3]  = this->length(0,3);
        edges[4]  = this->length(4,5);
        edges[5]  = this->length(5,6);
        edges[6]  = this->length(6,7);
        edges[7]  = this->length(4,7);
        edges[8]  = this->length(0,4);
        edges[9]  = this->length(1,5);
        edges[10] = this->length(2,6);
        edges[11] = this->length(3,7);

        const Real min_edge = *(std::min_element(edges.begin(), edges.end()));
        return sqrt3 * min_edge / max_diag ;
      }


      /**
       * I don't know what to do for this metric.
       * Maybe the base class knows...
       */
    default:
      return Elem::quality(q);
    }

  libmesh_error_msg("We'll never get here!");
  return 0.;
}
Ejemplo n.º 15
0
void ExodusII_IO::use_mesh_dimension_instead_of_spatial_dimension(bool)
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 16
0
void ExodusII_IO::write_nodal_data_common(std::string,
                                          const std::vector<std::string> &,
                                          bool)
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 17
0
void ExodusII_IO::write_as_dimension(unsigned)
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 18
0
void ExodusII_IO::read (const std::string & fname)
{
  // Get a reference to the mesh we are reading
  MeshBase & mesh = MeshInput<MeshBase>::mesh();

  // Clear any existing mesh data
  mesh.clear();

  // Keep track of what kinds of elements this file contains
  elems_of_dimension.clear();
  elems_of_dimension.resize(4, false);

#ifdef DEBUG
  this->verbose(true);
#endif

  // Instantiate the ElementMaps interface
  ExodusII_IO_Helper::ElementMaps em(*exio_helper);

  // Open the exodus file in EX_READ mode
  exio_helper->open(fname.c_str(), /*read_only=*/true);

  // Get header information from exodus file
  exio_helper->read_header();

  // Read the QA records
  exio_helper->read_qa_records();

  // Print header information
  exio_helper->print_header();

  // Read nodes from the exodus file
  exio_helper->read_nodes();

  // Reserve space for the nodes.
  mesh.reserve_nodes(exio_helper->num_nodes);

  // Read the node number map from the Exodus file.  This is
  // required if we want to preserve the numbering of nodes as it
  // exists in the Exodus file.  If the Exodus file does not contain
  // a node_num_map, the identity map is returned by this call.
  exio_helper->read_node_num_map();

  // Loop over the nodes, create Nodes with local processor_id 0.
  for (int i=0; i<exio_helper->num_nodes; i++)
    {
      // Use the node_num_map to get the correct ID for Exodus
      int exodus_id = exio_helper->node_num_map[i];

      // Catch the node that was added to the mesh
      Node * added_node = mesh.add_point (Point(exio_helper->x[i], exio_helper->y[i], exio_helper->z[i]), exodus_id-1);

      // If the Mesh assigned an ID different from what is in the
      // Exodus file, we should probably error.
      if (added_node->id() != static_cast<unsigned>(exodus_id-1))
        libmesh_error_msg("Error!  Mesh assigned node ID "    \
                          << added_node->id()                         \
                          << " which is different from the (zero-based) Exodus ID " \
                          << exodus_id-1                              \
                          << "!");
    }

  // This assert is no longer valid if the nodes are not numbered
  // sequentially starting from 1 in the Exodus file.
  // libmesh_assert_equal_to (static_cast<unsigned int>(exio_helper->num_nodes), mesh.n_nodes());

  // Get information about all the blocks
  exio_helper->read_block_info();

  // Reserve space for the elements
  mesh.reserve_elem(exio_helper->num_elem);

  // Read the element number map from the Exodus file.  This is
  // required if we want to preserve the numbering of elements as it
  // exists in the Exodus file.  If the Exodus file does not contain
  // an elem_num_map, the identity map is returned by this call.
  exio_helper->read_elem_num_map();

  // Read in the element connectivity for each block.
  int nelem_last_block = 0;

  // Loop over all the blocks
  for (int i=0; i<exio_helper->num_elem_blk; i++)
    {
      // Read the information for block i
      exio_helper->read_elem_in_block (i);
      int subdomain_id = exio_helper->get_block_id(i);

      // populate the map of names
      std::string subdomain_name = exio_helper->get_block_name(i);
      if (!subdomain_name.empty())
        mesh.subdomain_name(static_cast<subdomain_id_type>(subdomain_id)) = subdomain_name;

      // Set any relevant node/edge maps for this element
      const std::string type_str (exio_helper->get_elem_type());
      const ExodusII_IO_Helper::Conversion conv = em.assign_conversion(type_str);

      // Loop over all the faces in this block
      int jmax = nelem_last_block+exio_helper->num_elem_this_blk;
      for (int j=nelem_last_block; j<jmax; j++)
        {
          Elem * elem = Elem::build (conv.get_canonical_type()).release();
          libmesh_assert (elem);
          elem->subdomain_id() = static_cast<subdomain_id_type>(subdomain_id) ;

          // Use the elem_num_map to obtain the ID of this element in the Exodus file
          int exodus_id = exio_helper->elem_num_map[j];

          // Assign this element the same ID it had in the Exodus
          // file, but make it zero-based by subtracting 1.  Note:
          // some day we could use 1-based numbering in libmesh and
          // thus match the Exodus numbering exactly, but at the
          // moment libmesh is zero-based.
          elem->set_id(exodus_id-1);

          // Record that we have seen an element of dimension elem->dim()
          elems_of_dimension[elem->dim()] = true;

          // Catch the Elem pointer that the Mesh throws back
          elem = mesh.add_elem (elem);

          // If the Mesh assigned an ID different from what is in the
          // Exodus file, we should probably error.
          if (elem->id() != static_cast<unsigned>(exodus_id-1))
            libmesh_error_msg("Error!  Mesh assigned ID "       \
                              << elem->id()                             \
                              << " which is different from the (zero-based) Exodus ID " \
                              << exodus_id-1                            \
                              << "!");

          // Set all the nodes for this element
          for (int k=0; k<exio_helper->num_nodes_per_elem; k++)
            {
              // global index
              int gi = (j-nelem_last_block)*exio_helper->num_nodes_per_elem + conv.get_node_map(k);

              // The entries in 'connect' are actually (1-based)
              // indices into the node_num_map, so to get the right
              // node ID we:
              // 1.) Subtract 1 from connect[gi]
              // 2.) Pass it through node_num_map to get the corresponding Exodus ID
              // 3.) Subtract 1 from that, since libmesh node numbering is "zero"-based,
              //     even when the Exodus node numbering doesn't start with 1.
              int libmesh_node_id = exio_helper->node_num_map[exio_helper->connect[gi] - 1] - 1;

              // Set the node pointer in the Elem
              elem->set_node(k) = mesh.node_ptr(libmesh_node_id);
            }
        }

      // running sum of # of elements per block,
      // (should equal total number of elements in the end)
      nelem_last_block += exio_helper->num_elem_this_blk;
    }

  // This assert isn't valid if the Exodus file's numbering doesn't
  // start with 1!  For example, if Exodus's elem_num_map is 21, 22,
  // 23, 24, 25, 26, 27, 28, 29, 30, ... 84, then by the time you are
  // done with the loop above, mesh.n_elem() will report 84 and
  // nelem_last_block will be 64.
  // libmesh_assert_equal_to (static_cast<unsigned>(nelem_last_block), mesh.n_elem());

  // Set the mesh dimension to the largest encountered for an element
  for (unsigned char i=0; i!=4; ++i)
    if (elems_of_dimension[i])
      mesh.set_mesh_dimension(i);

  // Read in sideset information -- this is useful for applying boundary conditions
  {
    // Get basic information about all sidesets
    exio_helper->read_sideset_info();
    int offset=0;
    for (int i=0; i<exio_helper->num_side_sets; i++)
      {
        // Compute new offset
        offset += (i > 0 ? exio_helper->num_sides_per_set[i-1] : 0);
        exio_helper->read_sideset (i, offset);

        std::string sideset_name = exio_helper->get_side_set_name(i);
        if (!sideset_name.empty())
          mesh.get_boundary_info().sideset_name
            (cast_int<boundary_id_type>(exio_helper->get_side_set_id(i)))
            = sideset_name;
      }

    for (unsigned int e=0; e<exio_helper->elem_list.size(); e++)
      {
        // The numbers in the Exodus file sidesets should be thought
        // of as (1-based) indices into the elem_num_map array.  So,
        // to get the right element ID we have to:
        // 1.) Subtract 1 from elem_list[e] (to get a zero-based index)
        // 2.) Pass it through elem_num_map (to get the corresponding Exodus ID)
        // 3.) Subtract 1 from that, since libmesh is "zero"-based,
        //     even when the Exodus numbering doesn't start with 1.
        dof_id_type libmesh_elem_id =
          cast_int<dof_id_type>(exio_helper->elem_num_map[exio_helper->elem_list[e] - 1] - 1);

        // Set any relevant node/edge maps for this element
        Elem * elem = mesh.elem(libmesh_elem_id);

        const ExodusII_IO_Helper::Conversion conv = em.assign_conversion(elem->type());

        // Map the zero-based Exodus side numbering to the libmesh side numbering
        int mapped_side = conv.get_side_map(exio_helper->side_list[e]-1);

        // Check for errors
        if (mapped_side == ExodusII_IO_Helper::Conversion::invalid_id)
          libmesh_error_msg("Invalid 1-based side id: "                 \
                            << exio_helper->side_list[e]                \
                            << " detected for "                         \
                            << Utility::enum_to_string(elem->type()));

        // Add this (elem,side,id) triplet to the BoundaryInfo object.
        mesh.get_boundary_info().add_side (libmesh_elem_id,
                                           cast_int<unsigned short>(mapped_side),
                                           cast_int<boundary_id_type>(exio_helper->id_list[e]));
      }
  }

  // Read nodeset info
  {
    exio_helper->read_nodeset_info();

    for (int nodeset=0; nodeset<exio_helper->num_node_sets; nodeset++)
      {
        boundary_id_type nodeset_id =
          cast_int<boundary_id_type>(exio_helper->nodeset_ids[nodeset]);

        std::string nodeset_name = exio_helper->get_node_set_name(nodeset);
        if (!nodeset_name.empty())
          mesh.get_boundary_info().nodeset_name(nodeset_id) = nodeset_name;

        exio_helper->read_nodeset(nodeset);

        for (unsigned int node=0; node<exio_helper->node_list.size(); node++)
          {
            // As before, the entries in 'node_list' are 1-based
            // indcies into the node_num_map array, so we have to map
            // them.  See comment above.
            int libmesh_node_id = exio_helper->node_num_map[exio_helper->node_list[node] - 1] - 1;
            mesh.get_boundary_info().add_node(cast_int<dof_id_type>(libmesh_node_id),
                                              nodeset_id);
          }
      }
  }

#if LIBMESH_DIM < 3
  if (mesh.mesh_dimension() > LIBMESH_DIM)
    libmesh_error_msg("Cannot open dimension "        \
                      << mesh.mesh_dimension()            \
                      << " mesh file when configured without "        \
                      << mesh.mesh_dimension()                        \
                      << "D support.");
#endif
}
Ejemplo n.º 19
0
void ExodusII_IO::append(bool)
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 20
0
const std::vector<std::string> & ExodusII_IO::get_nodal_var_names()
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 21
0
void RBEvaluation::resize_data_structures(const unsigned int Nmax,
        bool resize_error_bound_data)
{
    LOG_SCOPE("resize_data_structures()", "RBEvaluation");

    if(Nmax < this->get_n_basis_functions())
        libmesh_error_msg("Error: Cannot set Nmax to be less than the current number of basis functions.");

    // Resize/clear inner product matrix
    if(compute_RB_inner_product)
        RB_inner_product_matrix.resize(Nmax,Nmax);

    // Allocate dense matrices for RB solves
    RB_Aq_vector.resize(rb_theta_expansion->get_n_A_terms());

    for(unsigned int q=0; q<rb_theta_expansion->get_n_A_terms(); q++)
    {
        // Initialize the memory for the RB matrices
        RB_Aq_vector[q].resize(Nmax,Nmax);
    }

    RB_Fq_vector.resize(rb_theta_expansion->get_n_F_terms());

    for(unsigned int q=0; q<rb_theta_expansion->get_n_F_terms(); q++)
    {
        // Initialize the memory for the RB vectors
        RB_Fq_vector[q].resize(Nmax);
    }


    // Initialize the RB output vectors
    RB_output_vectors.resize(rb_theta_expansion->get_n_outputs());
    for(unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
    {
        RB_output_vectors[n].resize(rb_theta_expansion->get_n_output_terms(n));
        for(unsigned int q_l=0; q_l<rb_theta_expansion->get_n_output_terms(n); q_l++)
        {
            RB_output_vectors[n][q_l].resize(Nmax);
        }
    }

    // Initialize vectors storing output data
    RB_outputs.resize(rb_theta_expansion->get_n_outputs(), 0.);


    if(resize_error_bound_data)
    {
        // Initialize vectors for the norms of the Fq representors
        unsigned int Q_f_hat = rb_theta_expansion->get_n_F_terms()*(rb_theta_expansion->get_n_F_terms()+1)/2;
        Fq_representor_innerprods.resize(Q_f_hat);

        // Initialize vectors for the norms of the representors
        Fq_Aq_representor_innerprods.resize(rb_theta_expansion->get_n_F_terms());
        for(unsigned int i=0; i<rb_theta_expansion->get_n_F_terms(); i++)
        {
            Fq_Aq_representor_innerprods[i].resize(rb_theta_expansion->get_n_A_terms());
            for(unsigned int j=0; j<rb_theta_expansion->get_n_A_terms(); j++)
            {
                Fq_Aq_representor_innerprods[i][j].resize(Nmax, 0.);
            }
        }

        unsigned int Q_a_hat = rb_theta_expansion->get_n_A_terms()*(rb_theta_expansion->get_n_A_terms()+1)/2;
        Aq_Aq_representor_innerprods.resize(Q_a_hat);
        for(unsigned int i=0; i<Q_a_hat; i++)
        {
            Aq_Aq_representor_innerprods[i].resize(Nmax);
            for(unsigned int j=0; j<Nmax; j++)
            {
                Aq_Aq_representor_innerprods[i][j].resize(Nmax, 0.);
            }
        }

        RB_output_error_bounds.resize(rb_theta_expansion->get_n_outputs(), 0.);

        // Resize the output dual norm vectors
        output_dual_innerprods.resize(rb_theta_expansion->get_n_outputs());
        for(unsigned int n=0; n<rb_theta_expansion->get_n_outputs(); n++)
        {
            unsigned int Q_l_hat = rb_theta_expansion->get_n_output_terms(n)*(rb_theta_expansion->get_n_output_terms(n)+1)/2;
            output_dual_innerprods[n].resize(Q_l_hat);
        }

        // Clear and resize the vector of Aq_representors
        clear_riesz_representors();

        Aq_representor.resize(rb_theta_expansion->get_n_A_terms());
        for(unsigned int q_a=0; q_a<rb_theta_expansion->get_n_A_terms(); q_a++)
        {
            Aq_representor[q_a].resize(Nmax);
        }
    }
}
Ejemplo n.º 22
0
void ExodusII_IO::write_element_data (const EquationSystems & es)
{
  // Be sure the file has been opened for writing!
  if (MeshOutput<MeshBase>::mesh().processor_id() == 0 && !exio_helper->opened_for_writing)
    libmesh_error_msg("ERROR, ExodusII file must be initialized before outputting element variables.");

  // This function currently only works on SerialMeshes. We rely on
  // having a reference to a non-const MeshBase object from our
  // MeshInput parent class to construct a MeshSerializer object,
  // similar to what is done in ExodusII_IO::write().  Note that
  // calling ExodusII_IO::write_timestep() followed by
  // ExodusII_IO::write_element_data() when the underlying Mesh is a
  // ParallelMesh will result in an unnecessary additional
  // serialization/re-parallelization step.
  MeshSerializer serialize(MeshInput<MeshBase>::mesh(), !MeshOutput<MeshBase>::_is_parallel_format);

  // To be (possibly) filled with a filtered list of variable names to output.
  std::vector<std::string> names;

  // If _output_variables is populated, only output the monomials which are
  // also in the _output_variables vector.
  if (_output_variables.size() > 0)
    {
      std::vector<std::string> monomials;
      const FEType type(CONSTANT, MONOMIAL);

      // Create a list of monomial variable names
      es.build_variable_names(monomials, &type);

      // Filter that list against the _output_variables list.  Note: if names is still empty after
      // all this filtering, all the monomial variables will be gathered
      std::vector<std::string>::iterator it = monomials.begin();
      for (; it!=monomials.end(); ++it)
        if (std::find(_output_variables.begin(), _output_variables.end(), *it) != _output_variables.end())
          names.push_back(*it);
    }

  // If we pass in a list of names to "get_solution" it'll filter the variables coming back
  std::vector<Number> soln;
  es.get_solution(soln, names);

  if(soln.empty()) // If there is nothing to write just return
    return;

  // The data must ultimately be written block by block.  This means that this data
  // must be sorted appropriately.
  if(MeshOutput<MeshBase>::mesh().processor_id())
    return;

  const MeshBase & mesh = MeshOutput<MeshBase>::mesh();

#ifdef LIBMESH_USE_COMPLEX_NUMBERS

  std::vector<std::string> complex_names = exio_helper->get_complex_names(names);

  exio_helper->initialize_element_variables(complex_names);

  unsigned int num_values = soln.size();
  unsigned int num_vars = names.size();
  unsigned int num_elems = num_values / num_vars;

  // This will contain the real and imaginary parts and the magnitude
  // of the values in soln
  std::vector<Real> complex_soln(3*num_values);

  for (unsigned i=0; i<num_vars; ++i)
    {

      for (unsigned int j=0; j<num_elems; ++j)
        {
          Number value = soln[i*num_vars + j];
          complex_soln[3*i*num_elems + j] = value.real();
        }
      for (unsigned int j=0; j<num_elems; ++j)
        {
          Number value = soln[i*num_vars + j];
          complex_soln[3*i*num_elems + num_elems +j] = value.imag();
        }
      for (unsigned int j=0; j<num_elems; ++j)
        {
          Number value = soln[i*num_vars + j];
          complex_soln[3*i*num_elems + 2*num_elems + j] = std::abs(value);
        }
    }

  exio_helper->write_element_values(mesh, complex_soln, _timestep);

#else
  exio_helper->initialize_element_variables(names);
  exio_helper->write_element_values(mesh, soln, _timestep);
#endif
}
Ejemplo n.º 23
0
void RBEvaluation::assert_file_exists(const std::string & file_name)
{
    if (!std::ifstream(file_name.c_str()))
        libmesh_error_msg("File missing: " + file_name);
}
Ejemplo n.º 24
0
ExodusII_IO::~ExodusII_IO ()
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 25
0
/**
 * Returns all valid quality metrics for
 * element type t.
 */
std::vector<ElemQuality> Quality::valid(const ElemType t)
{
  std::vector<ElemQuality> v;

  switch (t)
    {
    case EDGE2:
    case EDGE3:
    case EDGE4:
      {
        // None yet
        break;
      }

    case TRI3:
    case TRISHELL3:
    case TRI6:
      {
        v.resize(7);
        v[0] = MAX_ANGLE;
        v[1] = MIN_ANGLE;
        v[2] = CONDITION;
        v[3] = JACOBIAN;
        v[4] = SIZE;
        v[5] = SHAPE;
        v[6] = DISTORTION;
        break;
      }

    case QUAD4:
    case QUADSHELL4:
    case QUAD8:
    case QUADSHELL8:
    case QUAD9:
      {
        v.resize(13);
        v[0]  = ASPECT_RATIO;
        v[1]  = SKEW;
        v[2]  = TAPER;
        v[3]  = WARP;
        v[4]  = STRETCH;
        v[5]  = MIN_ANGLE;
        v[6]  = MAX_ANGLE;
        v[7]  = CONDITION;
        v[8]  = JACOBIAN;
        v[9]  = SHEAR;
        v[10] = SHAPE;
        v[11] = SIZE;
        v[12] = DISTORTION;
        break;
      }

    case TET4:
    case TET10:
      {
        v.resize(7);
        v[0]  = ASPECT_RATIO_BETA;
        v[1]  = ASPECT_RATIO_GAMMA;
        v[2]  = CONDITION;
        v[3]  = JACOBIAN;
        v[4]  = SHAPE;
        v[5]  = SIZE;
        v[6]  = DISTORTION;
        break;
      }

    case HEX8:
    case HEX20:
    case HEX27:
      {
        v.resize(11);
        v[0]  = ASPECT_RATIO;
        v[1]  = SKEW;
        v[2]  = SHEAR;
        v[3] = SHAPE;
        v[4]  = CONDITION;
        v[5]  = JACOBIAN;
        v[6]  = DISTORTION;
        v[7]  = TAPER;
        v[8]  = STRETCH;
        v[9]  = DIAGONAL;
        v[10]  = SIZE;
        break;
      }

    case PRISM6:
    case PRISM18:
      {
        // None yet
        break;
      }

    case PYRAMID5:
    case PYRAMID13:
    case PYRAMID14:
      {
        // None yet
        break;
      }



#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS

    case INFEDGE2:
      {
        // None yet
        break;
      }

    case INFQUAD4:
    case INFQUAD6:
      {
        // None yet
        break;
      }

    case INFHEX8:
    case INFHEX16:
    case INFHEX18:
      {
        // None yet
        break;
      }

    case INFPRISM6:
    case INFPRISM12:
      {
        // None yet
        break;
      }

#endif


    default:
      libmesh_error_msg("Undefined element type!");
    }

  return v;
}
Ejemplo n.º 26
0
void ExodusII_IO::read (const std::string &)
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 27
0
Real FE<3,MONOMIAL>::shape(const ElemType,
                           const Order libmesh_dbg_var(order),
                           const unsigned int i,
                           const Point& p)
{
#if LIBMESH_DIM == 3

  const Real xi   = p(0);
  const Real eta  = p(1);
  const Real zeta = p(2);

  libmesh_assert_less (i, (static_cast<unsigned int>(order)+1)*
                       (static_cast<unsigned int>(order)+2)*
                       (static_cast<unsigned int>(order)+3)/6);

  // monomials. since they are hierarchic we only need one case block.
  switch (i)
    {
      // constant
    case 0:
      return 1.;

      // linears
    case 1:
      return xi;

    case 2:
      return eta;

    case 3:
      return zeta;

      // quadratics
    case 4:
      return xi*xi;

    case 5:
      return xi*eta;

    case 6:
      return eta*eta;

    case 7:
      return xi*zeta;

    case 8:
      return zeta*eta;

    case 9:
      return zeta*zeta;

      // cubics
    case 10:
      return xi*xi*xi;

    case 11:
      return xi*xi*eta;

    case 12:
      return xi*eta*eta;

    case 13:
      return eta*eta*eta;

    case 14:
      return xi*xi*zeta;

    case 15:
      return xi*eta*zeta;

    case 16:
      return eta*eta*zeta;

    case 17:
      return xi*zeta*zeta;

    case 18:
      return eta*zeta*zeta;

    case 19:
      return zeta*zeta*zeta;

      // quartics
    case 20:
      return xi*xi*xi*xi;

    case 21:
      return xi*xi*xi*eta;

    case 22:
      return xi*xi*eta*eta;

    case 23:
      return xi*eta*eta*eta;

    case 24:
      return eta*eta*eta*eta;

    case 25:
      return xi*xi*xi*zeta;

    case 26:
      return xi*xi*eta*zeta;

    case 27:
      return xi*eta*eta*zeta;

    case 28:
      return eta*eta*eta*zeta;

    case 29:
      return xi*xi*zeta*zeta;

    case 30:
      return xi*eta*zeta*zeta;

    case 31:
      return eta*eta*zeta*zeta;

    case 32:
      return xi*zeta*zeta*zeta;

    case 33:
      return eta*zeta*zeta*zeta;

    case 34:
      return zeta*zeta*zeta*zeta;

    default:
      unsigned int o = 0;
      for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
      unsigned int i2 = i - (o*(o+1)*(o+2)/6);
      unsigned int block=o, nz = 0;
      for (; block < i2; block += (o-nz+1)) { nz++; }
      const unsigned int nx = block - i2;
      const unsigned int ny = o - nx - nz;
      Real val = 1.;
      for (unsigned int index=0; index != nx; index++)
        val *= xi;
      for (unsigned int index=0; index != ny; index++)
        val *= eta;
      for (unsigned int index=0; index != nz; index++)
        val *= zeta;
      return val;
    }

#endif

  libmesh_error_msg("We'll never get here!");
  return 0.;
}
Ejemplo n.º 28
0
void ExodusII_IO::verbose (bool)
{
  libmesh_error_msg("ERROR, ExodusII API is not defined.");
}
Ejemplo n.º 29
0
void ParmetisPartitioner::initialize (const MeshBase & mesh,
                                      const unsigned int n_sbdmns)
{
  const dof_id_type n_active_local_elem = mesh.n_active_local_elem();

  // Set parameters.
  _pmetis->wgtflag = 2;                                      // weights on vertices only
  _pmetis->ncon    = 1;                                      // one weight per vertex
  _pmetis->numflag = 0;                                      // C-style 0-based numbering
  _pmetis->nparts  = static_cast<Parmetis::idx_t>(n_sbdmns); // number of subdomains to create
  _pmetis->edgecut = 0;                                      // the numbers of edges cut by the
                                                             // partition

  // Initialize data structures for ParMETIS
  _pmetis->vtxdist.resize (mesh.n_processors()+1); std::fill (_pmetis->vtxdist.begin(), _pmetis->vtxdist.end(), 0);
  _pmetis->tpwgts.resize  (_pmetis->nparts);       std::fill (_pmetis->tpwgts.begin(),  _pmetis->tpwgts.end(),  1./_pmetis->nparts);
  _pmetis->ubvec.resize   (_pmetis->ncon);         std::fill (_pmetis->ubvec.begin(),   _pmetis->ubvec.end(),   1.05);
  _pmetis->part.resize    (n_active_local_elem);   std::fill (_pmetis->part.begin(),    _pmetis->part.end(), 0);
  _pmetis->options.resize (5);
  _pmetis->vwgt.resize    (n_active_local_elem);

  // Set the options
  _pmetis->options[0] = 1;  // don't use default options
  _pmetis->options[1] = 0;  // default (level of timing)
  _pmetis->options[2] = 15; // random seed (default)
  _pmetis->options[3] = 2;  // processor distribution and subdomain distribution are decoupled

  // Find the number of active elements on each processor.  We cannot use
  // mesh.n_active_elem_on_proc(pid) since that only returns the number of
  // elements assigned to pid which are currently stored on the calling
  // processor. This will not in general be correct for parallel meshes
  // when (pid!=mesh.processor_id()).
  _n_active_elem_on_proc.resize(mesh.n_processors());
  mesh.comm().allgather(n_active_local_elem, _n_active_elem_on_proc);

  // count the total number of active elements in the mesh.  Note we cannot
  // use mesh.n_active_elem() in general since this only returns the number
  // of active elements which are stored on the calling processor.
  // We should not use n_active_elem for any allocation because that will
  // be inheritly unscalable, but it can be useful for libmesh_assertions.
  dof_id_type n_active_elem=0;

  // Set up the vtxdist array.  This will be the same on each processor.
  // ***** Consult the Parmetis documentation. *****
  libmesh_assert_equal_to (_pmetis->vtxdist.size(),
                           cast_int<std::size_t>(mesh.n_processors()+1));
  libmesh_assert_equal_to (_pmetis->vtxdist[0], 0);

  for (processor_id_type pid=0; pid<mesh.n_processors(); pid++)
    {
      _pmetis->vtxdist[pid+1] = _pmetis->vtxdist[pid] + _n_active_elem_on_proc[pid];
      n_active_elem += _n_active_elem_on_proc[pid];
    }
  libmesh_assert_equal_to (_pmetis->vtxdist.back(), static_cast<Parmetis::idx_t>(n_active_elem));

  // ParMetis expects the elements to be numbered in contiguous blocks
  // by processor, i.e. [0, ne0), [ne0, ne0+ne1), ...
  // Since we only partition active elements we should have no expectation
  // that we currently have such a distribution.  So we need to create it.
  // Also, at the same time we are going to map all the active elements into a globally
  // unique range [0,n_active_elem) which is *independent* of the current partitioning.
  // This can be fed to ParMetis as the initial partitioning of the subdomains (decoupled
  // from the partitioning of the objects themselves).  This allows us to get the same
  // resultant partitioning independed of the input partitioning.
  MeshTools::BoundingBox bbox =
    MeshTools::bounding_box(mesh);

  _global_index_by_pid_map.clear();

  // Maps active element ids into a contiguous range independent of partitioning.
  // (only needs local scope)
  vectormap<dof_id_type, dof_id_type> global_index_map;

  {
    std::vector<dof_id_type> global_index;

    // create the mapping which is contiguous by processor
    dof_id_type pid_offset=0;
    for (processor_id_type pid=0; pid<mesh.n_processors(); pid++)
      {
        MeshBase::const_element_iterator       it  = mesh.active_pid_elements_begin(pid);
        const MeshBase::const_element_iterator end = mesh.active_pid_elements_end(pid);

        // note that we may not have all (or any!) the active elements which belong on this processor,
        // but by calling this on all processors a unique range in [0,_n_active_elem_on_proc[pid])
        // is constructed.  Only the indices for the elements we pass in are returned in the array.
        MeshCommunication().find_global_indices (mesh.comm(),
                                                 bbox, it, end,
                                                 global_index);

        for (dof_id_type cnt=0; it != end; ++it)
          {
            const Elem * elem = *it;
            libmesh_assert (!_global_index_by_pid_map.count(elem->id()));
            libmesh_assert_less (cnt, global_index.size());
            libmesh_assert_less (global_index[cnt], _n_active_elem_on_proc[pid]);

            _global_index_by_pid_map.insert(std::make_pair(elem->id(), global_index[cnt++] + pid_offset));
          }

        pid_offset += _n_active_elem_on_proc[pid];
      }

    // create the unique mapping for all active elements independent of partitioning
    {
      MeshBase::const_element_iterator       it  = mesh.active_elements_begin();
      const MeshBase::const_element_iterator end = mesh.active_elements_end();

      // Calling this on all processors a unique range in [0,n_active_elem) is constructed.
      // Only the indices for the elements we pass in are returned in the array.
      MeshCommunication().find_global_indices (mesh.comm(),
                                               bbox, it, end,
                                               global_index);

      for (dof_id_type cnt=0; it != end; ++it)
        {
          const Elem * elem = *it;
          libmesh_assert (!global_index_map.count(elem->id()));
          libmesh_assert_less (cnt, global_index.size());
          libmesh_assert_less (global_index[cnt], n_active_elem);

          global_index_map.insert(std::make_pair(elem->id(), global_index[cnt++]));
        }
    }
    // really, shouldn't be close!
    libmesh_assert_less_equal (global_index_map.size(), n_active_elem);
    libmesh_assert_less_equal (_global_index_by_pid_map.size(), n_active_elem);

    // At this point the two maps should be the same size.  If they are not
    // then the number of active elements is not the same as the sum over all
    // processors of the number of active elements per processor, which means
    // there must be some unpartitioned objects out there.
    if (global_index_map.size() != _global_index_by_pid_map.size())
      libmesh_error_msg("ERROR:  ParmetisPartitioner cannot handle unpartitioned objects!");
  }

  // Finally, we need to initialize the vertex (partition) weights and the initial subdomain
  // mapping.  The subdomain mapping will be independent of the processor mapping, and is
  // defined by a simple mapping of the global indices we just found.
  {
    std::vector<dof_id_type> subdomain_bounds(mesh.n_processors());

    const dof_id_type first_local_elem = _pmetis->vtxdist[mesh.processor_id()];

    for (processor_id_type pid=0; pid<mesh.n_processors(); pid++)
      {
        dof_id_type tgt_subdomain_size = 0;

        // watch out for the case that n_subdomains < n_processors
        if (pid < static_cast<unsigned int>(_pmetis->nparts))
          {
            tgt_subdomain_size = n_active_elem/std::min
              (cast_int<Parmetis::idx_t>(mesh.n_processors()), _pmetis->nparts);

            if (pid < n_active_elem%_pmetis->nparts)
              tgt_subdomain_size++;
          }
        if (pid == 0)
          subdomain_bounds[0] = tgt_subdomain_size;
        else
          subdomain_bounds[pid] = subdomain_bounds[pid-1] + tgt_subdomain_size;
      }

    libmesh_assert_equal_to (subdomain_bounds.back(), n_active_elem);

    MeshBase::const_element_iterator       elem_it  = mesh.active_local_elements_begin();
    const MeshBase::const_element_iterator elem_end = mesh.active_local_elements_end();

    for (; elem_it != elem_end; ++elem_it)
      {
        const Elem * elem = *elem_it;

        libmesh_assert (_global_index_by_pid_map.count(elem->id()));
        const dof_id_type global_index_by_pid =
          _global_index_by_pid_map[elem->id()];
        libmesh_assert_less (global_index_by_pid, n_active_elem);

        const dof_id_type local_index =
          global_index_by_pid - first_local_elem;

        libmesh_assert_less (local_index, n_active_local_elem);
        libmesh_assert_less (local_index, _pmetis->vwgt.size());

        // TODO:[BSK] maybe there is a better weight?
        _pmetis->vwgt[local_index] = elem->n_nodes();

        // find the subdomain this element belongs in
        libmesh_assert (global_index_map.count(elem->id()));
        const dof_id_type global_index =
          global_index_map[elem->id()];

        libmesh_assert_less (global_index, subdomain_bounds.back());

        const unsigned int subdomain_id =
          std::distance(subdomain_bounds.begin(),
                        std::lower_bound(subdomain_bounds.begin(),
                                         subdomain_bounds.end(),
                                         global_index));
        libmesh_assert_less (subdomain_id, static_cast<unsigned int>(_pmetis->nparts));
        libmesh_assert_less (local_index, _pmetis->part.size());

        _pmetis->part[local_index] = subdomain_id;
      }
  }
}
Ejemplo n.º 30
0
RealGradient FE<3,NEDELEC_ONE>::shape_second_deriv(const Elem* elem,
                                                   const Order order,
                                                   const unsigned int i,
                                                   const unsigned int j,
                                                   const Point& libmesh_dbg_var(p))
{
#if LIBMESH_DIM == 3

  libmesh_assert(elem);

  // j = 0 ==> d^2 phi / dxi^2
  // j = 1 ==> d^2 phi / dxi deta
  // j = 2 ==> d^2 phi / deta^2
  // j = 3 ==> d^2 phi / dxi dzeta
  // j = 4 ==> d^2 phi / deta dzeta
  // j = 5 ==> d^2 phi / dzeta^2
  libmesh_assert_less (j, 6);

  const Order totalorder = static_cast<Order>(order + elem->p_level());

  switch (totalorder)
    {
      // linear Lagrange shape functions
    case FIRST:
      {
        switch (elem->type())
          {
          case HEX20:
          case HEX27:
            {
              libmesh_assert_less (i, 12);

#ifndef NDEBUG
              const Real xi   = p(0);
              const Real eta  = p(1);
              const Real zeta = p(2);
#endif

              libmesh_assert_less_equal ( std::fabs(xi),   1.0+TOLERANCE );
              libmesh_assert_less_equal ( std::fabs(eta),  1.0+TOLERANCE );
              libmesh_assert_less_equal ( std::fabs(zeta), 1.0+TOLERANCE );

              switch (j)
                {
                  // d^2()/dxi^2
                case 0:
                  {
                    // All d^2()/dxi^2 derivatives for linear hexes are zero.
                    return RealGradient();
                  } // j=0

                  // d^2()/dxideta
                case 1:
                  {
                    switch(i)
                      {
                      case 0:
                      case 1:
                      case 2:
                      case 3:
                      case 8:
                      case 9:
                      case 10:
                      case 11:
                        return RealGradient();
                      case 4:
                        {
                          if( elem->point(0) > elem->point(4) )
                            return RealGradient( 0.0, 0.0, -0.125 );
                          else
                            return RealGradient( 0.0, 0.0,  0.125 );
                        }
                      case 5:
                        {
                          if( elem->point(1) > elem->point(5) )
                            return RealGradient( 0.0, 0.0,  0.125 );
                          else
                            return RealGradient( 0.0, 0.0, -0.125 );
                        }
                      case 6:
                        {
                          if( elem->point(2) > elem->point(6) )
                            return RealGradient( 0.0, 0.0, -0.125 );
                          else
                            return RealGradient( 0.0, 0.0,  0.125 );
                        }
                      case 7:
                        {
                          if( elem->point(3) > elem->point(7) )
                            return RealGradient( 0.0, 0.0,  0.125 );
                          else
                            return RealGradient( 0.0, 0.0, -0.125 );
                        }
                      default:
                        libmesh_error_msg("Invalid i = " << i);
                      } // switch(i)

                  } // j=1

                  // d^2()/deta^2
                case 2:
                  {
                    // All d^2()/deta^2 derivatives for linear hexes are zero.
                    return RealGradient();
                  } // j = 2

                  // d^2()/dxidzeta
                case 3:
                  {
                    switch(i)
                      {
                      case 0:
                      case 2:
                      case 4:
                      case 5:
                      case 6:
                      case 7:
                      case 8:
                      case 10:
                        return RealGradient();

                      case 1:
                        {
                          if( elem->point(1) > elem->point(2) )
                            return RealGradient( 0.0,  0.125 );
                          else
                            return RealGradient( 0.0, -0.125 );
                        }
                      case 3:
                        {
                          if( elem->point(3) > elem->point(0) )
                            return RealGradient( 0.0, -0.125 );
                          else
                            return RealGradient( 0.0,  0.125 );
                        }
                      case 9:
                        {
                          if( elem->point(5) > elem->point(6) )
                            return RealGradient( 0.0, -0.125, 0.0 );
                          else
                            return RealGradient( 0.0,  0.125, 0.0 );
                        }
                      case 11:
                        {
                          if( elem->point(4) > elem->point(7) )
                            return RealGradient( 0.0,  0.125, 0.0 );
                          else
                            return RealGradient( 0.0, -0.125, 0.0 );
                        }
                      default:
                        libmesh_error_msg("Invalid i = " << i);
                      } // switch(i)

                  } // j = 3

                  // d^2()/detadzeta
                case 4:
                  {
                    switch(i)
                      {
                      case 1:
                      case 3:
                      case 4:
                      case 5:
                      case 6:
                      case 7:
                      case 9:
                      case 11:
                        return RealGradient();

                      case 0:
                        {
                          if( elem->point(0) > elem->point(1) )
                            return RealGradient( -0.125, 0.0, 0.0 );
                          else
                            return RealGradient(  0.125, 0.0, 0.0 );
                        }
                      case 2:
                        {
                          if( elem->point(2) > elem->point(3) )
                            return RealGradient(  0.125, 0.0, 0.0 );
                          else
                            return RealGradient( -0.125, 0.0, 0.0 );
                        }
                      case 8:
                        {
                          if( elem->point(4) > elem->point(5) )
                            return RealGradient(  0.125, 0.0, 0.0 );
                          else
                            return RealGradient( -0.125, 0.0, 0.0 );
                        }
                      case 10:
                        {
                          if( elem->point(7) > elem->point(6) )
                            return RealGradient( -0.125, 0.0, 0.0 );
                          else
                            return RealGradient(  0.125, 0.0, 0.0 );
                        }
                      default:
                        libmesh_error_msg("Invalid i = " << i);
                      } // switch(i)

                  } // j = 4

                  // d^2()/dzeta^2
                case 5:
                  {
                    // All d^2()/dzeta^2 derivatives for linear hexes are zero.
                    return RealGradient();
                  } // j = 5

                default:
                  libmesh_error_msg("Invalid j = " << j);
                }

              return RealGradient();
            }

          case TET10:
            {
              libmesh_assert_less (i, 6);

              libmesh_not_implemented();
              return RealGradient();
            }

          default:
            libmesh_error_msg("ERROR: Unsupported 3D element type!: " << elem->type());

          } //switch(type)

      } // case FIRST:
      // unsupported order
    default:
      libmesh_error_msg("ERROR: Unsupported 3D FE order!: " << totalorder);
    }

#endif

  libmesh_error_msg("We'll never get here!");
  return RealGradient();
}