コード例 #1
0
ファイル: face_tri3.C プロジェクト: ArtisticCoding/libmesh
std::pair<Real, Real> Tri3::min_and_max_angle() const
{
  Point v10 ( this->point(1) - this->point(0) );
  Point v20 ( this->point(2) - this->point(0) );
  Point v21 ( this->point(2) - this->point(1) );

  const Real
    len_10=v10.size(),
    len_20=v20.size(),
    len_21=v21.size()
    ;

  const Real
    theta0=std::acos(( v10*v20)/len_10/len_20),
    theta1=std::acos((-v10*v21)/len_10/len_21),
    theta2=libMesh::pi - theta0 - theta1
    ;

  libmesh_assert_greater (theta0, 0.);
  libmesh_assert_greater (theta1, 0.);
  libmesh_assert_greater (theta2, 0.);

  return std::make_pair(std::min(theta0, std::min(theta1,theta2)),
                        std::max(theta0, std::max(theta1,theta2)));
}
コード例 #2
0
ファイル: quadrature.C プロジェクト: ArtisticCoding/libmesh
void QBase::scale(std::pair<Real, Real> old_range,
                  std::pair<Real, Real> new_range)
{
  // Make sure we are in 1D
  libmesh_assert_equal_to (_dim, 1);

  Real
    h_new = new_range.second - new_range.first,
    h_old = old_range.second - old_range.first;

  // Make sure that we have sane ranges
  libmesh_assert_greater (h_new, 0.);
  libmesh_assert_greater (h_old, 0.);

  // Make sure there are some points
  libmesh_assert_greater (_points.size(), 0);

  // Compute the scale factor
  Real scfact = h_new/h_old;

  // We're mapping from old_range -> new_range
  for (unsigned int i=0; i<_points.size(); i++)
    {
      _points[i](0) = new_range.first +
        (_points[i](0) - old_range.first) * scfact;

      // Scale the weights
      _weights[i] *= scfact;
    }
}
コード例 #3
0
ファイル: quadrature.C プロジェクト: paulovieira/libmesh
void QBase::scale(std::pair<Real, Real> old_range,
		  std::pair<Real, Real> new_range)
{
  // Make sure we are in 1D
  libmesh_assert_equal_to (_dim, 1);

  // Make sure that we have sane ranges
  libmesh_assert_greater (new_range.second, new_range.first);
  libmesh_assert_greater (old_range.second, old_range.first);

  // Make sure there are some points
  libmesh_assert_greater (_points.size(), 0);

  // We're mapping from old_range -> new_range
  for (unsigned int i=0; i<_points.size(); i++)
    {
      _points[i](0) =
	(_points[i](0) - old_range.first) *
	(new_range.second - new_range.first) /
	(old_range.second - old_range.first) +
	new_range.first;
    }

  // Compute the scale factor and scale the weights
  const Real scfact = (new_range.second - new_range.first) /
                      (old_range.second - old_range.first);

  for (unsigned int i=0; i<_points.size(); i++)
    _weights[i] *= scfact;
}
コード例 #4
0
ファイル: sphere.C プロジェクト: giorgiobornia/libmesh
Real Sphere::distance (const Sphere & other_sphere) const
{
  libmesh_assert_greater ( this->radius(), 0. );
  libmesh_assert_greater ( other_sphere.radius(), 0. );

  const Real the_distance = (this->center() - other_sphere.center()).norm();

  return the_distance - (this->radius() + other_sphere.radius());
}
void
MAST::Examples::ThermalJacobianScaling::set_acceleration_factor(Real f) {

    libmesh_assert_greater(f, 0.);
    
    _accel_factor = f;
}
コード例 #6
0
void SubdomainPartitioner::_do_partition (MeshBase & mesh,
                                          const unsigned int n)
{
  libmesh_assert_greater (n, 0);

  // Check for an easy return.  If the user has not specified any
  // entries in the chunks vector, we just do a single partitioning.
  if ((n == 1) || chunks.empty())
    {
      this->single_partition (mesh);
      return;
    }

  // Now actually do the partitioning.
  LOG_SCOPE ("_do_partition()", "SubdomainPartitioner");

  // For each chunk, construct an iterator range for the set of
  // subdomains in question, and pass it to the internal Partitioner.
  for (std::size_t c=0; c<chunks.size(); ++c)
    {
      MeshBase::element_iterator
        it = mesh.active_subdomain_set_elements_begin(chunks[c]),
        end = mesh.active_subdomain_set_elements_end(chunks[c]);

      _internal_partitioner->partition_range(mesh, it, end, n);
    }
}
コード例 #7
0
void MeshRefinement::flag_elements_by_error_tolerance (const ErrorVector & error_per_cell_in)
{
  parallel_object_only();

  libmesh_assert_greater (_coarsen_threshold, 0);

  // Check for valid fractions..
  // The fraction values must be in [0,1]
  libmesh_assert_greater_equal (_refine_fraction, 0);
  libmesh_assert_less_equal (_refine_fraction, 1);
  libmesh_assert_greater_equal (_coarsen_fraction, 0);
  libmesh_assert_less_equal (_coarsen_fraction, 1);

  // How much error per cell will we tolerate?
  const Real local_refinement_tolerance =
    _absolute_global_tolerance / std::sqrt(static_cast<Real>(_mesh.n_active_elem()));
  const Real local_coarsening_tolerance =
    local_refinement_tolerance * _coarsen_threshold;

  // Prepare another error vector if we need to sum parent errors
  ErrorVector error_per_parent;
  if (_coarsen_by_parents)
    {
      Real parent_error_min, parent_error_max;

      create_parent_error_vector(error_per_cell_in,
                                 error_per_parent,
                                 parent_error_min,
                                 parent_error_max);
    }

  for (auto & elem : _mesh.active_element_ptr_range())
    {
      Elem * parent = elem->parent();
      const dof_id_type elem_number    = elem->id();
      const ErrorVectorReal elem_error = error_per_cell_in[elem_number];

      if (elem_error > local_refinement_tolerance &&
          elem->level() < _max_h_level)
        elem->set_refinement_flag(Elem::REFINE);

      if (!_coarsen_by_parents && elem_error <
          local_coarsening_tolerance)
        elem->set_refinement_flag(Elem::COARSEN);

      if (_coarsen_by_parents && parent)
        {
          ErrorVectorReal parent_error = error_per_parent[parent->id()];
          if (parent_error >= 0.)
            {
              const Real parent_coarsening_tolerance =
                std::sqrt(parent->n_children() *
                          local_coarsening_tolerance *
                          local_coarsening_tolerance);
              if (parent_error < parent_coarsening_tolerance)
                elem->set_refinement_flag(Elem::COARSEN);
            }
        }
    }
}
コード例 #8
0
ファイル: sphere.C プロジェクト: giorgiobornia/libmesh
Sphere::Sphere (const Point & c,
                const Real r)
{
  libmesh_assert_greater (r, 0.);

  this->create_from_center_radius (c, r);
}
コード例 #9
0
ファイル: sphere.C プロジェクト: giorgiobornia/libmesh
void Sphere::create_from_center_radius (const Point & c, const Real r)
{
  this->center() = c;
  this->radius() = r;

  libmesh_assert_greater (this->radius(), 0.);
}
コード例 #10
0
void EpetraVector<T>::localize (const numeric_index_type first_local_idx,
                                const numeric_index_type last_local_idx,
                                const std::vector<numeric_index_type> & send_list)
{
  // Only good for serial vectors.
  libmesh_assert_equal_to (this->size(), this->local_size());
  libmesh_assert_greater (last_local_idx, first_local_idx);
  libmesh_assert_less_equal (send_list.size(), this->size());
  libmesh_assert_less (last_local_idx, this->size());

  const unsigned int my_size       = this->size();
  const unsigned int my_local_size = (last_local_idx - first_local_idx + 1);

  // Don't bother for serial cases
  if ((first_local_idx == 0) &&
      (my_local_size == my_size))
    return;

  // Build a parallel vector, initialize it with the local
  // parts of (*this)
  EpetraVector<T> parallel_vec(this->comm(), PARALLEL);

  parallel_vec.init (my_size, my_local_size, true, PARALLEL);

  // Copy part of *this into the parallel_vec
  for (numeric_index_type i=first_local_idx; i<=last_local_idx; i++)
    parallel_vec.set(i,this->el(i));

  // localize like normal
  parallel_vec.close();
  parallel_vec.localize (*this, send_list);
  this->close();
}
コード例 #11
0
ファイル: sphere.C プロジェクト: giorgiobornia/libmesh
Point Sphere::unit_normal (const Point & p) const
{
  libmesh_assert_greater (this->radius(), 0.);

  libmesh_assert_not_equal_to (p, this->center());

  // Create a vector from the center to the point
  Point n = p - this->center();

  return n.unit();
}
コード例 #12
0
ファイル: sphere.C プロジェクト: giorgiobornia/libmesh
bool Sphere::above_surface (const Point & p) const
{
  libmesh_assert_greater (this->radius(), 0.);

  // create a vector from the center to the point.
  const Point w = p - this->center();

  if (w.norm() > this->radius())
    return true;

  return false;
}
コード例 #13
0
void MeshFunction::init (const Trees::BuildType /*point_locator_build_type*/)
{
  // are indices of the desired variable(s) provided?
  libmesh_assert_greater (this->_system_vars.size(), 0);

  // Don't do twice...
  if (this->_initialized)
    {
      libmesh_assert(this->_point_locator);
      return;
    }

  /*
   * set up the PointLocator: either someone else
   * is the master (go and get the address of his
   * point locator) or this object is the master
   * (build the point locator  on our own).
   */
  if (this->_master != NULL)
    {
      // we aren't the master
      const MeshFunction* master =
        cast_ptr<const MeshFunction*>(this->_master);

      if (master->_point_locator == NULL)
        libmesh_error_msg("ERROR: When the master-servant concept is used, the master has to be initialized first!");

      else
        {
          this->_point_locator = master->_point_locator;
        }
    }
  else
    {
      // we are the master: build the point locator

      // constant reference to the other mesh
      const MeshBase& mesh = this->_eqn_systems.get_mesh();

      // build the point locator.  Only \p TREE version available
      //UniquePtr<PointLocatorBase> ap (PointLocatorBase::build (TREE, mesh));
      //this->_point_locator = ap.release();
      // this->_point_locator = new PointLocatorTree (mesh, point_locator_build_type);
      this->_point_locator = mesh.sub_point_locator().release();

      // Point locator no longer needs to be initialized.
      //      this->_point_locator->init();
    }


  // ready for use
  this->_initialized = true;
}
void
MAST::GCMMAOptimizationInterface::set_integer_parameter(const std::string &nm, int val) {
    
    if (nm == "max_inner_iters") {
        
        libmesh_assert_greater(val, 0);
        
        _max_inner_iters = val;
    }
    else
        libMesh::out
        << "Unrecognized integer parameter: " << nm << std::endl;
}
void
MAST::GCMMAOptimizationInterface::set_real_parameter(const std::string &nm, Real val) {

    if (nm == "constraint_penalty") {
        
        libmesh_assert_greater(val, 0.);
        
        _constr_penalty = val;
    }
    else
        libMesh::out
        << "Unrecognized real parameter: " << nm << std::endl;
}
コード例 #16
0
ファイル: sphere.C プロジェクト: giorgiobornia/libmesh
Point Sphere::closest_point (const Point & p) const
{
  libmesh_assert_greater (this->radius(), 0.);

  // get the normal from the surface in the direction
  // of p
  Point normal = this->unit_normal (p);

  // The closest point on the sphere is in the direction
  // of the normal a distance r from the center.
  const Point cp = this->center() + normal*this->radius();

  return cp;
}
コード例 #17
0
ファイル: sphere.C プロジェクト: giorgiobornia/libmesh
bool Sphere::on_surface (const Point & p) const
{
  libmesh_assert_greater (this->radius(), 0.);

  // Create a vector from the center to the point.
  const Point w = p - this->center();

  // if the size of that vector is the same as the radius() then
  // the point is on the surface.
  if (std::abs(w.norm() - this->radius()) < 1.e-10)
    return true;

  return false;
}
コード例 #18
0
void MeshTools::Subdivision::prepare_subdivision_mesh(MeshBase & mesh, bool ghosted)
{
  mesh.prepare_for_use();

  // convert all mesh elements to subdivision elements
  all_subdivision(mesh);

  if (!ghosted)
    {
      // add the ghost elements for the boundaries
      add_boundary_ghosts(mesh);
    }
  else
    {
      // This assumes that the mesh already has the ghosts. Only tagging them is required here.
      tag_boundary_ghosts(mesh);
    }

  mesh.prepare_for_use();

  std::vector<std::vector<const Elem *> > nodes_to_elem_map;
  MeshTools::build_nodes_to_elem_map(mesh, nodes_to_elem_map);

  // compute the node valences
  MeshBase::const_node_iterator       nd     = mesh.nodes_begin();
  const MeshBase::const_node_iterator end_nd = mesh.nodes_end();
  for (; nd != end_nd; ++nd)
    {
      Node * node = *nd;
      std::vector<const Node *> neighbors;
      MeshTools::find_nodal_neighbors(mesh, *node, nodes_to_elem_map, neighbors);
      const unsigned int valence =
        cast_int<unsigned int>(neighbors.size());
      libmesh_assert_greater(valence, 1);
      node->set_valence(valence);
    }

  MeshBase::const_element_iterator       el     = mesh.elements_begin();
  const MeshBase::const_element_iterator end_el = mesh.elements_end();
  for (; el != end_el; ++el)
    {
      Tri3Subdivision * elem = dynamic_cast<Tri3Subdivision *>(*el);
      libmesh_assert(elem);
      if (!elem->is_ghost())
        elem->prepare_subdivision_properties();
    }
}
コード例 #19
0
ファイル: linear_partitioner.C プロジェクト: bwspenc/libmesh
// ------------------------------------------------------------
// LinearPartitioner implementation
void LinearPartitioner::_do_partition (MeshBase& mesh,
                                       const unsigned int n)
{
  libmesh_assert_greater (n, 0);

  // Check for an easy return
  if (n == 1)
    {
      this->single_partition (mesh);
      return;
    }

  // Create a simple linear partitioning
  {
    START_LOG ("partition()", "LinearPartitioner");

    const dof_id_type n_active_elem = mesh.n_active_elem();
    const dof_id_type blksize       = n_active_elem/n;

    dof_id_type e = 0;

    MeshBase::element_iterator       elem_it  = mesh.active_elements_begin();
    const MeshBase::element_iterator elem_end = mesh.active_elements_end();

    for ( ; elem_it != elem_end; ++elem_it)
      {
        if ((e/blksize) < n)
          {
            Elem *elem = *elem_it;
            elem->processor_id() =
              libmesh_cast_int<processor_id_type>(e/blksize);
          }
        else
          {
            Elem *elem = *elem_it;
            elem->processor_id() = 0;
            elem = elem->parent();
          }

        e++;
      }

    STOP_LOG ("partition()", "LinearPartitioner");
  }
}
コード例 #20
0
void LaspackMatrix<T>::init (const numeric_index_type libmesh_dbg_var(m_in),
                             const numeric_index_type libmesh_dbg_var(n_in),
                             const numeric_index_type libmesh_dbg_var(m_l),
                             const numeric_index_type libmesh_dbg_var(n_l),
                             const numeric_index_type libmesh_dbg_var(nnz),
                             const numeric_index_type,
                             const numeric_index_type)
{
  // noz ignored...  only used for multiple processors!
  libmesh_assert_equal_to (m_in, m_l);
  libmesh_assert_equal_to (n_in, n_l);
  libmesh_assert_equal_to (m_in, n_in);
  libmesh_assert_greater (nnz, 0);

  libmesh_error_msg("ERROR: Only the init() member that uses the DofMap is implemented for Laspack matrices!");

  this->_is_initialized = true;
}
コード例 #21
0
ファイル: eigen_sparse_matrix.C プロジェクト: YSB330/libmesh
void EigenSparseMatrix<T>::init (const numeric_index_type m_in,
                                 const numeric_index_type n_in,
                                 const numeric_index_type libmesh_dbg_var(m_l),
                                 const numeric_index_type libmesh_dbg_var(n_l),
                                 const numeric_index_type nnz,
                                 const numeric_index_type,
                                 const numeric_index_type)
{
  // noz ignored...  only used for multiple processors!
  libmesh_assert_equal_to (m_in, m_l);
  libmesh_assert_equal_to (n_in, n_l);
  libmesh_assert_equal_to (m_in, n_in);
  libmesh_assert_greater  (nnz, 0);

  _mat.resize(m_in, n_in);
  _mat.reserve(Eigen::Matrix<numeric_index_type, Eigen::Dynamic, 1>::Constant(m_in,nnz));

  this->_is_initialized = true;
}
コード例 #22
0
ファイル: laspack_matrix.C プロジェクト: paulovieira/libmesh
void LaspackMatrix<T>::init (const unsigned int libmesh_dbg_var(m),
			     const unsigned int libmesh_dbg_var(n),
			     const unsigned int libmesh_dbg_var(m_l),
			     const unsigned int libmesh_dbg_var(n_l),
			     const unsigned int libmesh_dbg_var(nnz),
			     const unsigned int)
{
  // noz ignored...  only used for multiple processors!
  libmesh_assert_equal_to (m, m_l);
  libmesh_assert_equal_to (n, n_l);
  libmesh_assert_equal_to (m, n);
  libmesh_assert_greater (nnz, 0);


  libMesh::err << "ERROR: Only the init() member that uses the" << std::endl
	        << "DofMap is implemented for Laspack matrices!" << std::endl;
  libmesh_error();

  this->_is_initialized = true;
}
コード例 #23
0
ファイル: sphere.C プロジェクト: giorgiobornia/libmesh
Sphere::Sphere(const Point & pa,
               const Point & pb,
               const Point & pc,
               const Point & pd)
{
  Point pad = pa - pd;
  Point pbd = pb - pd;
  Point pcd = pc - pd;

  TensorValue<Real> T(pad,pbd,pcd);

  Real D = T.det();

  // The points had better not be coplanar
  libmesh_assert_greater (std::abs(D), 1e-12);

  Real e = 0.5*(pa.norm_sq() - pd.norm_sq());
  Real f = 0.5*(pb.norm_sq() - pd.norm_sq());
  Real g = 0.5*(pc.norm_sq() - pd.norm_sq());

  TensorValue<Real> T1(e,pad(1),pad(2),
                       f,pbd(1),pbd(2),
                       g,pcd(1),pcd(2));
  Real sx = T1.det()/D;

  TensorValue<Real> T2(pad(0),e,pad(2),
                       pbd(0),f,pbd(2),
                       pcd(0),g,pcd(2));
  Real sy = T2.det()/D;

  TensorValue<Real> T3(pad(0),pad(1),e,
                       pbd(0),pbd(1),f,
                       pcd(0),pcd(1),g);
  Real sz = T3.det()/D;

  Point c(sx,sy,sz);
  Real r = (c-pa).norm();

  this->create_from_center_radius(c,r);
}
コード例 #24
0
void NonlinearNeoHookeCurrentConfig::init_for_qp(VectorValue<Gradient> & grad_u, unsigned int qp) {
  this->current_qp = qp;
  F.zero();
  S.zero();

  {
    RealTensor invF;
    invF.zero();
    for (unsigned int i = 0; i < 3; ++i)
      for (unsigned int j = 0; j < 3; ++j) {
        invF(i, j) += libmesh_real(grad_u(i)(j));
      }
    F.add(inv(invF));

    libmesh_assert_greater (F.det(), -TOLERANCE);
  }

  if (this->calculate_linearized_stiffness) {
    this->calculate_tangent();
  }

  this->calculate_stress();
}
コード例 #25
0
ファイル: fe_xyz_map.C プロジェクト: dongliangchu/libmesh
void FEXYZMap::compute_face_map(int dim, const std::vector<Real>& qw, const Elem* side)
{
  libmesh_assert(side);

  START_LOG("compute_face_map()", "FEXYZMap");

  // The number of quadrature points.
  const unsigned int n_qp = libmesh_cast_int<unsigned int>(qw.size());

  switch(dim)
    {
    case 2:
      {

        // Resize the vectors to hold data at the quadrature points
        {
          this->xyz.resize(n_qp);
          this->dxyzdxi_map.resize(n_qp);
          this->d2xyzdxi2_map.resize(n_qp);
          this->tangents.resize(n_qp);
          this->normals.resize(n_qp);
          this->curvatures.resize(n_qp);

          this->JxW.resize(n_qp);
        }

        // Clear the entities that will be summed
        // Compute the tangent & normal at the quadrature point
        for (unsigned int p=0; p<n_qp; p++)
          {
            this->tangents[p].resize(LIBMESH_DIM-1); // 1 Tangent in 2D, 2 in 3D
            this->xyz[p].zero();
            this->dxyzdxi_map[p].zero();
            this->d2xyzdxi2_map[p].zero();
          }

        // compute x, dxdxi at the quadrature points
        for (unsigned int i=0; i<this->psi_map.size(); i++) // sum over the nodes
          {
            const Point& side_point = side->point(i);

            for (unsigned int p=0; p<n_qp; p++) // for each quadrature point...
              {
                this->xyz[p].add_scaled          (side_point, this->psi_map[i][p]);
                this->dxyzdxi_map[p].add_scaled  (side_point, this->dpsidxi_map[i][p]);
                this->d2xyzdxi2_map[p].add_scaled(side_point, this->d2psidxi2_map[i][p]);
              }
          }

        // Compute the tangent & normal at the quadrature point
        for (unsigned int p=0; p<n_qp; p++)
          {
            const Point n(this->dxyzdxi_map[p](1), -this->dxyzdxi_map[p](0), 0.);

            this->normals[p]     = n.unit();
            this->tangents[p][0] = this->dxyzdxi_map[p].unit();
#if LIBMESH_DIM == 3  // Only good in 3D space
            this->tangents[p][1] = this->dxyzdxi_map[p].cross(n).unit();
#endif
            // The curvature is computed via the familiar Frenet formula:
            // curvature = [d^2(x) / d (xi)^2] dot [normal]
            // For a reference, see:
            // F.S. Merritt, Mathematics Manual, 1962, McGraw-Hill, p. 310
            //
            // Note: The sign convention here is different from the
            // 3D case.  Concave-upward curves (smiles) have a positive
            // curvature.  Concave-downward curves (frowns) have a
            // negative curvature.  Be sure to take that into account!
            const Real numerator   = this->d2xyzdxi2_map[p] * this->normals[p];
            const Real denominator = this->dxyzdxi_map[p].size_sq();
            libmesh_assert_not_equal_to (denominator, 0);
            this->curvatures[p] = numerator / denominator;
          }

        // compute the jacobian at the quadrature points
        for (unsigned int p=0; p<n_qp; p++)
          {
            const Real the_jac = std::sqrt(this->dxdxi_map(p)*this->dxdxi_map(p) +
                                           this->dydxi_map(p)*this->dydxi_map(p));

            libmesh_assert_greater (the_jac, 0.);

            this->JxW[p] = the_jac*qw[p];
          }

        break;
      }

    case 3:
      {
        // Resize the vectors to hold data at the quadrature points
        {
          this->xyz.resize(n_qp);
          this->dxyzdxi_map.resize(n_qp);
          this->dxyzdeta_map.resize(n_qp);
          this->d2xyzdxi2_map.resize(n_qp);
          this->d2xyzdxideta_map.resize(n_qp);
          this->d2xyzdeta2_map.resize(n_qp);
          this->tangents.resize(n_qp);
          this->normals.resize(n_qp);
          this->curvatures.resize(n_qp);

          this->JxW.resize(n_qp);
        }

        // Clear the entities that will be summed
        for (unsigned int p=0; p<n_qp; p++)
          {
            this->tangents[p].resize(LIBMESH_DIM-1); // 1 Tangent in 2D, 2 in 3D
            this->xyz[p].zero();
            this->dxyzdxi_map[p].zero();
            this->dxyzdeta_map[p].zero();
            this->d2xyzdxi2_map[p].zero();
            this->d2xyzdxideta_map[p].zero();
            this->d2xyzdeta2_map[p].zero();
          }

        // compute x, dxdxi at the quadrature points
        for (unsigned int i=0; i<this->psi_map.size(); i++) // sum over the nodes
          {
            const Point& side_point = side->point(i);

            for (unsigned int p=0; p<n_qp; p++) // for each quadrature point...
              {
                this->xyz[p].add_scaled             (side_point, this->psi_map[i][p]);
                this->dxyzdxi_map[p].add_scaled     (side_point, this->dpsidxi_map[i][p]);
                this->dxyzdeta_map[p].add_scaled    (side_point, this->dpsideta_map[i][p]);
                this->d2xyzdxi2_map[p].add_scaled   (side_point, this->d2psidxi2_map[i][p]);
                this->d2xyzdxideta_map[p].add_scaled(side_point, this->d2psidxideta_map[i][p]);
                this->d2xyzdeta2_map[p].add_scaled  (side_point, this->d2psideta2_map[i][p]);
              }
          }

        // Compute the tangents, normal, and curvature at the quadrature point
        for (unsigned int p=0; p<n_qp; p++)
          {
            const Point n  = this->dxyzdxi_map[p].cross(this->dxyzdeta_map[p]);
            this->normals[p]     = n.unit();
            this->tangents[p][0] = this->dxyzdxi_map[p].unit();
            this->tangents[p][1] = n.cross(this->dxyzdxi_map[p]).unit();

            // Compute curvature using the typical nomenclature
            // of the first and second fundamental forms.
            // For reference, see:
            // 1) http://mathworld.wolfram.com/MeanCurvature.html
            //    (note -- they are using inward normal)
            // 2) F.S. Merritt, Mathematics Manual, 1962, McGraw-Hill
            const Real L  = -this->d2xyzdxi2_map[p]    * this->normals[p];
            const Real M  = -this->d2xyzdxideta_map[p] * this->normals[p];
            const Real N  = -this->d2xyzdeta2_map[p]   * this->normals[p];
            const Real E  =  this->dxyzdxi_map[p].size_sq();
            const Real F  =  this->dxyzdxi_map[p]      * this->dxyzdeta_map[p];
            const Real G  =  this->dxyzdeta_map[p].size_sq();

            const Real numerator   = E*N -2.*F*M + G*L;
            const Real denominator = E*G - F*F;
            libmesh_assert_not_equal_to (denominator, 0.);
            this->curvatures[p] = 0.5*numerator/denominator;
          }

        // compute the jacobian at the quadrature points, see
        // http://sp81.msi.umn.edu:999/fluent/fidap/help/theory/thtoc.htm
        for (unsigned int p=0; p<n_qp; p++)
          {
            const Real g11 = (this->dxdxi_map(p)*this->dxdxi_map(p) +
                              this->dydxi_map(p)*this->dydxi_map(p) +
                              this->dzdxi_map(p)*this->dzdxi_map(p));

            const Real g12 = (this->dxdxi_map(p)*this->dxdeta_map(p) +
                              this->dydxi_map(p)*this->dydeta_map(p) +
                              this->dzdxi_map(p)*this->dzdeta_map(p));

            const Real g21 = g12;

            const Real g22 = (this->dxdeta_map(p)*this->dxdeta_map(p) +
                              this->dydeta_map(p)*this->dydeta_map(p) +
                              this->dzdeta_map(p)*this->dzdeta_map(p));


            const Real the_jac = std::sqrt(g11*g22 - g12*g21);

            libmesh_assert_greater (the_jac, 0.);

            this->JxW[p] = the_jac*qw[p];
          }

        break;
      }
    default:
      libmesh_error_msg("Invalid dim = " << dim);

    } // switch(dim)

  STOP_LOG("compute_face_map()", "FEXYZMap");

  return;
}
コード例 #26
0
// ------------------------------------------------------------
// SFCPartitioner implementation
void SFCPartitioner::_do_partition (MeshBase & mesh,
                                    const unsigned int n)
{

  libmesh_assert_greater (n, 0);

  // Check for an easy return
  if (n == 1)
    {
      this->single_partition (mesh);
      return;
    }

  // What to do if the sfcurves library IS NOT present
#ifndef LIBMESH_HAVE_SFCURVES

  libmesh_here();
  libMesh::err << "ERROR: The library has been built without"    << std::endl
               << "Space Filling Curve support.  Using a linear" << std::endl
               << "partitioner instead!" << std::endl;

  LinearPartitioner lp;

  lp.partition (mesh, n);

  // What to do if the sfcurves library IS present
#else

  LOG_SCOPE("sfc_partition()", "SFCPartitioner");

  const dof_id_type n_active_elem = mesh.n_active_elem();
  const dof_id_type n_elem        = mesh.n_elem();

  // the forward_map maps the active element id
  // into a contiguous block of indices
  std::vector<dof_id_type>
    forward_map (n_elem, DofObject::invalid_id);

  // the reverse_map maps the contiguous ids back
  // to active elements
  std::vector<Elem *> reverse_map (n_active_elem, libmesh_nullptr);

  int size = static_cast<int>(n_active_elem);
  std::vector<double> x      (size);
  std::vector<double> y      (size);
  std::vector<double> z      (size);
  std::vector<int>    table  (size);


  // We need to map the active element ids into a
  // contiguous range.
  {
    MeshBase::element_iterator       elem_it  = mesh.active_elements_begin();
    const MeshBase::element_iterator elem_end = mesh.active_elements_end();

    dof_id_type el_num = 0;

    for (; elem_it != elem_end; ++elem_it)
      {
        libmesh_assert_less ((*elem_it)->id(), forward_map.size());
        libmesh_assert_less (el_num, reverse_map.size());

        forward_map[(*elem_it)->id()] = el_num;
        reverse_map[el_num]           = *elem_it;
        el_num++;
      }
    libmesh_assert_equal_to (el_num, n_active_elem);
  }


  // Get the centroid for each active element
  {
    //     const_active_elem_iterator       elem_it (mesh.const_elements_begin());
    //     const const_active_elem_iterator elem_end(mesh.const_elements_end());

    MeshBase::element_iterator       elem_it  = mesh.active_elements_begin();
    const MeshBase::element_iterator elem_end = mesh.active_elements_end();

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

        libmesh_assert_less (elem->id(), forward_map.size());

        const Point p = elem->centroid();

        x[forward_map[elem->id()]] = p(0);
        y[forward_map[elem->id()]] = p(1);
        z[forward_map[elem->id()]] = p(2);
      }
  }

  // build the space-filling curve
  if (_sfc_type == "Hilbert")
    Sfc::hilbert (&x[0], &y[0], &z[0], &size, &table[0]);

  else if (_sfc_type == "Morton")
    Sfc::morton  (&x[0], &y[0], &z[0], &size, &table[0]);

  else
    {
      libmesh_here();
      libMesh::err << "ERROR: Unknown type: " << _sfc_type << std::endl
                   << " Valid types are"                   << std::endl
                   << "  \"Hilbert\""                      << std::endl
                   << "  \"Morton\""                       << std::endl
                   << " "                                  << std::endl
                   << "Proceeding with a Hilbert curve."   << std::endl;

      Sfc::hilbert (&x[0], &y[0], &z[0], &size, &table[0]);
    }


  // Assign the partitioning to the active elements
  {
    //      {
    //        std::ofstream out ("sfc.dat");
    //        out << "variables=x,y,z" << std::endl;
    //        out << "zone f=point" << std::endl;

    //        for (unsigned int i=0; i<n_active_elem; i++)
    //  out << x[i] << " "
    //      << y[i] << " "
    //      << z[i] << std::endl;
    //      }

    const dof_id_type blksize = (n_active_elem+n-1)/n;

    for (dof_id_type i=0; i<n_active_elem; i++)
      {
        libmesh_assert_less (static_cast<unsigned int>(table[i]-1), reverse_map.size());

        Elem * elem = reverse_map[table[i]-1];

        elem->processor_id() = cast_int<processor_id_type>
          (i/blksize);
      }
  }

#endif

}
コード例 #27
0
Real FE<2,HIERARCHIC>::shape(const Elem* elem,
			     const Order order,
			     const unsigned int i,
			     const Point& p)
{
  libmesh_assert(elem);

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

  switch (elem->type())
    {
    case TRI3:
    case TRI6:
      {
	const Real zeta1 = p(0);
	const Real zeta2 = p(1);
	const Real zeta0 = 1. - zeta1 - zeta2;

	libmesh_assert_less (i, (totalorder+1u)*(totalorder+2u)/2);
	libmesh_assert (elem->type() == TRI6 || totalorder < 2);

        // Vertex DoFs
        if (i == 0)
          return zeta0;
        else if (i == 1)
          return zeta1;
        else if (i == 2)
          return zeta2;
        // Edge DoFs
        else if (i < totalorder + 2u)
          {
            // Avoid returning NaN on vertices!
            if (zeta0 + zeta1 == 0.)
              return 0.;

            const unsigned int basisorder = i - 1;
	    // Get factors to account for edge-flipping
	    Real f0 = 1;
	    if (basisorder%2 && (elem->point(0) > elem->point(1)))
	      f0 = -1.;

            Real edgeval = (zeta1 - zeta0) / (zeta1 + zeta0);
            Real crossfunc = zeta0 + zeta1;
            for (unsigned int n=1; n != basisorder; ++n)
              crossfunc *= (zeta0 + zeta1);

            return f0 * crossfunc *
                   FE<1,HIERARCHIC>::shape(EDGE3, totalorder,
                                           basisorder, edgeval);
          }
        else if (i < 2u*totalorder + 1)
          {
            // Avoid returning NaN on vertices!
            if (zeta1 + zeta2 == 0.)
              return 0.;

            const unsigned int basisorder = i - totalorder;
	    // Get factors to account for edge-flipping
	    Real f1 = 1;
	    if (basisorder%2 && (elem->point(1) > elem->point(2)))
	      f1 = -1.;

            Real edgeval = (zeta2 - zeta1) / (zeta2 + zeta1);
            Real crossfunc = zeta2 + zeta1;
            for (unsigned int n=1; n != basisorder; ++n)
              crossfunc *= (zeta2 + zeta1);

            return f1 * crossfunc *
                   FE<1,HIERARCHIC>::shape(EDGE3, totalorder,
                                           basisorder, edgeval);
          }
        else if (i < 3u*totalorder)
          {
            // Avoid returning NaN on vertices!
            if (zeta0 + zeta2 == 0.)
              return 0.;

            const unsigned int basisorder = i - (2u*totalorder) + 1;
	    // Get factors to account for edge-flipping
	    Real f2 = 1;
	    if (basisorder%2 && (elem->point(2) > elem->point(0)))
	      f2 = -1.;

            Real edgeval = (zeta0 - zeta2) / (zeta0 + zeta2);
            Real crossfunc = zeta0 + zeta2;
            for (unsigned int n=1; n != basisorder; ++n)
              crossfunc *= (zeta0 + zeta2);

            return f2 * crossfunc *
                   FE<1,HIERARCHIC>::shape(EDGE3, totalorder,
                                           basisorder, edgeval);
          }
        // Interior DoFs
        else
          {
            const unsigned int basisnum = i - (3u*totalorder);
            unsigned int exp0 = triangular_number_column[basisnum] + 1;
            unsigned int exp1 = triangular_number_row[basisnum] + 1 -
                                triangular_number_column[basisnum];

            Real returnval = 1;
            for (unsigned int n = 0; n != exp0; ++n)
              returnval *= zeta0;
            for (unsigned int n = 0; n != exp1; ++n)
              returnval *= zeta1;
            returnval *= zeta2;
            return returnval;
          }
      }

    // Hierarchic shape functions on the quadrilateral.
    case QUAD4:
      libmesh_assert_less (totalorder, 2);
    case QUAD8:
    case QUAD9:
      {
        // Compute quad shape functions as a tensor-product
        const Real xi  = p(0);
        const Real eta = p(1);

        libmesh_assert_less (i, (totalorder+1u)*(totalorder+1u));

// Example i, i0, i1 values for totalorder = 5:
//                                    0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
//  static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 0, 0, 0, 0, 2, 3, 3, 2, 4, 4, 4, 3, 2, 5, 5, 5, 5, 4, 3, 2};
//  static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 2, 2, 3, 3, 2, 3, 4, 4, 4, 2, 3, 4, 5, 5, 5, 5};

        unsigned int i0, i1;

        // Vertex DoFs
        if (i == 0)
          { i0 = 0; i1 = 0; }
        else if (i == 1)
          { i0 = 1; i1 = 0; }
        else if (i == 2)
          { i0 = 1; i1 = 1; }
        else if (i == 3)
          { i0 = 0; i1 = 1; }
        // Edge DoFs
        else if (i < totalorder + 3u)
          { i0 = i - 2; i1 = 0; }
        else if (i < 2u*totalorder + 2)
          { i0 = 1; i1 = i - totalorder - 1; }
        else if (i < 3u*totalorder + 1)
          { i0 = i - 2u*totalorder; i1 = 1; }
        else if (i < 4u*totalorder)
          { i0 = 0; i1 = i - 3u*totalorder + 1; }
        // Interior DoFs
        else
          {
            unsigned int basisnum = i - 4*totalorder;
            i0 = square_number_column[basisnum] + 2;
            i1 = square_number_row[basisnum] + 2;
          }

        // Flip odd degree of freedom values if necessary
        // to keep continuity on sides
        Real f = 1.;

        if ((i0%2) && (i0 > 2) && (i1 == 0))
	  f = (elem->point(0) > elem->point(1))?-1.:1.;
        else if ((i0%2) && (i0>2) && (i1 == 1))
	  f = (elem->point(3) > elem->point(2))?-1.:1.;
        else if ((i0 == 0) && (i1%2) && (i1>2))
	  f = (elem->point(0) > elem->point(3))?-1.:1.;
        else if ((i0 == 1) && (i1%2) && (i1>2))
	  f = (elem->point(1) > elem->point(2))?-1.:1.;

        return f*(FE<1,HIERARCHIC>::shape(EDGE3, totalorder, i0, xi)*
		  FE<1,HIERARCHIC>::shape(EDGE3, totalorder, i1, eta));
      }

    default:
      libMesh::err << "ERROR: Unsupported element type!" << std::endl;
      libmesh_error();
    }

  return 0.;
}
コード例 #28
0
Real FE<2,HIERARCHIC>::shape_deriv(const Elem* elem,
				   const Order order,
				   const unsigned int i,
				   const unsigned int j,
				   const Point& p)
{
  libmesh_assert(elem);

  const ElemType type = elem->type();

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

  libmesh_assert_greater (totalorder, 0);

  switch (type)
    {
      // 1st & 2nd-order Hierarchics.
    case TRI3:
    case TRI6:
      {
	const Real eps = 1.e-6;

	libmesh_assert_less (j, 2);

	switch (j)
	  {
	    //  d()/dxi
	  case 0:
	    {
	      const Point pp(p(0)+eps, p(1));
	      const Point pm(p(0)-eps, p(1));

	      return (FE<2,HIERARCHIC>::shape(elem, order, i, pp) -
		      FE<2,HIERARCHIC>::shape(elem, order, i, pm))/2./eps;
	    }

	     // d()/deta
	  case 1:
	    {
	      const Point pp(p(0), p(1)+eps);
	      const Point pm(p(0), p(1)-eps);

	      return (FE<2,HIERARCHIC>::shape(elem, order, i, pp) -
		      FE<2,HIERARCHIC>::shape(elem, order, i, pm))/2./eps;
	    }


	  default:
	    libmesh_error();
	  }
      }

    case QUAD4:
      libmesh_assert_less (totalorder, 2);
    case QUAD8:
    case QUAD9:
      {
	// Compute quad shape functions as a tensor-product
	const Real xi  = p(0);
	const Real eta = p(1);

        libmesh_assert_less (i, (totalorder+1u)*(totalorder+1u));

// Example i, i0, i1 values for totalorder = 5:
//                                    0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
//  static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 0, 0, 0, 0, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5};
//  static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};

        unsigned int i0, i1;

        // Vertex DoFs
        if (i == 0)
          { i0 = 0; i1 = 0; }
        else if (i == 1)
          { i0 = 1; i1 = 0; }
        else if (i == 2)
          { i0 = 1; i1 = 1; }
        else if (i == 3)
          { i0 = 0; i1 = 1; }
        // Edge DoFs
        else if (i < totalorder + 3u)
          { i0 = i - 2; i1 = 0; }
        else if (i < 2u*totalorder + 2)
          { i0 = 1; i1 = i - totalorder - 1; }
        else if (i < 3u*totalorder + 1u)
          { i0 = i - 2u*totalorder; i1 = 1; }
        else if (i < 4u*totalorder)
          { i0 = 0; i1 = i - 3u*totalorder + 1; }
        // Interior DoFs
        else
          {
            unsigned int basisnum = i - 4*totalorder;
            i0 = square_number_column[basisnum] + 2;
            i1 = square_number_row[basisnum] + 2;
          }

        // Flip odd degree of freedom values if necessary
        // to keep continuity on sides
        Real f = 1.;

        if ((i0%2) && (i0 > 2) && (i1 == 0))
	  f = (elem->point(0) > elem->point(1))?-1.:1.;
        else if ((i0%2) && (i0>2) && (i1 == 1))
	  f = (elem->point(3) > elem->point(2))?-1.:1.;
        else if ((i0 == 0) && (i1%2) && (i1>2))
	  f = (elem->point(0) > elem->point(3))?-1.:1.;
        else if ((i0 == 1) && (i1%2) && (i1>2))
	  f = (elem->point(1) > elem->point(2))?-1.:1.;

	switch (j)
	  {
	    // d()/dxi
	  case 0:
	    return f*(FE<1,HIERARCHIC>::shape_deriv(EDGE3, totalorder, i0, 0, xi)*
		      FE<1,HIERARCHIC>::shape      (EDGE3, totalorder, i1,    eta));

	    // d()/deta
	  case 1:
	    return f*(FE<1,HIERARCHIC>::shape      (EDGE3, totalorder, i0,    xi)*
		      FE<1,HIERARCHIC>::shape_deriv(EDGE3, totalorder, i1, 0, eta));

	  default:
	    libmesh_error();
	  }

      }

    default:
      libMesh::err << "ERROR: Unsupported element type!" << std::endl;
      libmesh_error();
    }

  return 0.;
}
コード例 #29
0
ファイル: main.C プロジェクト: kameeko/harriet_libmesh
// The main program
int main(int argc, char** argv)
{
    // Initialize libMesh
    LibMeshInit init(argc, argv);

    // Parameters
    GetPot infile("fem_system_params.in");
    const Real global_tolerance          = infile("global_tolerance", 0.);
    const unsigned int nelem_target      = infile("n_elements", 400);
    const bool transient                 = infile("transient", true);
    const Real deltat                    = infile("deltat", 0.005);
    unsigned int n_timesteps             = infile("n_timesteps", 1);
    //const unsigned int coarsegridsize    = infile("coarsegridsize", 1);
    const unsigned int coarserefinements = infile("coarserefinements", 0);
    const unsigned int max_adaptivesteps = infile("max_adaptivesteps", 10);
    //const unsigned int dim               = 2;

#ifdef LIBMESH_HAVE_EXODUS_API
    const unsigned int write_interval    = infile("write_interval", 5);
#endif

    // Create a mesh, with dimension to be overridden later, distributed
    // across the default MPI communicator.
    Mesh mesh(init.comm());
    GetPot infileForMesh("convdiff_mprime.in");
    std::string find_mesh_here = infileForMesh("mesh","psiLF_mesh.xda");
    mesh.read(find_mesh_here);

    std::cout << "Read in mesh from: " << find_mesh_here << "\n\n";

    // And an object to refine it
    MeshRefinement mesh_refinement(mesh);
    mesh_refinement.coarsen_by_parents() = true;
    mesh_refinement.absolute_global_tolerance() = global_tolerance;
    mesh_refinement.nelem_target() = nelem_target;
    mesh_refinement.refine_fraction() = 0.3;
    mesh_refinement.coarsen_fraction() = 0.3;
    mesh_refinement.coarsen_threshold() = 0.1;

    //mesh_refinement.uniformly_refine(coarserefinements);

    // Print information about the mesh to the screen.
    mesh.print_info();

    // Create an equation systems object.
    EquationSystems equation_systems (mesh);

    // Name system
    ConvDiff_MprimeSys & system =
        equation_systems.add_system<ConvDiff_MprimeSys>("Diff_ConvDiff_MprimeSys");

    // Steady-state problem
    system.time_solver =
        AutoPtr<TimeSolver>(new SteadySolver(system));

    // Sanity check that we are indeed solving a steady problem
    libmesh_assert_equal_to (n_timesteps, 1);

    // Read in all the equation systems data from the LF solve (system, solutions, rhs, etc)
    std::string find_psiLF_here = infileForMesh("psiLF_file","psiLF.xda");
    std::cout << "Looking for psiLF at: " << find_psiLF_here << "\n\n";

    equation_systems.read(find_psiLF_here, READ,
                          EquationSystems::READ_HEADER |
                          EquationSystems::READ_DATA |
                          EquationSystems::READ_ADDITIONAL_DATA);

    // Check that the norm of the solution read in is what we expect it to be
    Real readin_L2 = system.calculate_norm(*system.solution, 0, L2);
    std::cout << "Read in solution norm: "<< readin_L2 << std::endl << std::endl;

    //DEBUG
    //equation_systems.write("right_back_out.xda", WRITE, EquationSystems::WRITE_DATA |
    //		 EquationSystems::WRITE_ADDITIONAL_DATA);
#ifdef LIBMESH_HAVE_GMV
    //GMVIO(equation_systems.get_mesh()).write_equation_systems(std::string("right_back_out.gmv"), equation_systems);
#endif

    // Initialize the system
    //equation_systems.init ();  //already initialized by read-in

    // And the nonlinear solver options
    NewtonSolver *solver = new NewtonSolver(system);
    system.time_solver->diff_solver() = AutoPtr<DiffSolver>(solver);
    solver->quiet = infile("solver_quiet", true);
    solver->verbose = !solver->quiet;
    solver->max_nonlinear_iterations =
        infile("max_nonlinear_iterations", 15);
    solver->relative_step_tolerance =
        infile("relative_step_tolerance", 1.e-3);
    solver->relative_residual_tolerance =
        infile("relative_residual_tolerance", 0.0);
    solver->absolute_residual_tolerance =
        infile("absolute_residual_tolerance", 0.0);

    // And the linear solver options
    solver->max_linear_iterations =
        infile("max_linear_iterations", 50000);
    solver->initial_linear_tolerance =
        infile("initial_linear_tolerance", 1.e-3);

    // Print information about the system to the screen.
    equation_systems.print_info();

    // Now we begin the timestep loop to compute the time-accurate
    // solution of the equations...not that this is transient, but eh, why not...
    for (unsigned int t_step=0; t_step != n_timesteps; ++t_step)
    {
        // A pretty update message
        std::cout << "\n\nSolving time step " << t_step << ", time = "
                  << system.time << std::endl;

        // Adaptively solve the timestep
        unsigned int a_step = 0;
        for (; a_step != max_adaptivesteps; ++a_step)
        {   // VESTIGIAL for now ('vestigial' eh ? ;) )

            std::cout << "\n\n I should be skipped what are you doing here lalalalalalala *!**!*!*!*!*!* \n\n";

            system.solve();
            system.postprocess();
            ErrorVector error;
            AutoPtr<ErrorEstimator> error_estimator;

            // To solve to a tolerance in this problem we
            // need a better estimator than Kelly
            if (global_tolerance != 0.)
            {
                // We can't adapt to both a tolerance and a mesh
                // size at once
                libmesh_assert_equal_to (nelem_target, 0);

                UniformRefinementEstimator *u =
                    new UniformRefinementEstimator;

                // The lid-driven cavity problem isn't in H1, so
                // lets estimate L2 error
                u->error_norm = L2;

                error_estimator.reset(u);
            }
            else
            {
                // If we aren't adapting to a tolerance we need a
                // target mesh size
                libmesh_assert_greater (nelem_target, 0);

                // Kelly is a lousy estimator to use for a problem
                // not in H1 - if we were doing more than a few
                // timesteps we'd need to turn off or limit the
                // maximum level of our adaptivity eventually
                error_estimator.reset(new KellyErrorEstimator);
            }

            // Calculate error
            std::vector<Real> weights(9,1.0);  // based on u, v, p, c, their adjoints, and source parameter

            // Keep the same default norm type.
            std::vector<FEMNormType>
            norms(1, error_estimator->error_norm.type(0));
            error_estimator->error_norm = SystemNorm(norms, weights);

            error_estimator->estimate_error(system, error);

            // Print out status at each adaptive step.
            Real global_error = error.l2_norm();
            std::cout << "Adaptive step " << a_step << ": " << std::endl;
            if (global_tolerance != 0.)
                std::cout << "Global_error = " << global_error
                          << std::endl;
            if (global_tolerance != 0.)
                std::cout << "Worst element error = " << error.maximum()
                          << ", mean = " << error.mean() << std::endl;

            if (global_tolerance != 0.)
            {
                // If we've reached our desired tolerance, we
                // don't need any more adaptive steps
                if (global_error < global_tolerance)
                    break;
                mesh_refinement.flag_elements_by_error_tolerance(error);
            }
            else
            {
                // If flag_elements_by_nelem_target returns true, this
                // should be our last adaptive step.
                if (mesh_refinement.flag_elements_by_nelem_target(error))
                {
                    mesh_refinement.refine_and_coarsen_elements();
                    equation_systems.reinit();
                    a_step = max_adaptivesteps;
                    break;
                }
            }

            // Carry out the adaptive mesh refinement/coarsening
            mesh_refinement.refine_and_coarsen_elements();
            equation_systems.reinit();

            std::cout << "Refined mesh to "
                      << mesh.n_active_elem()
                      << " active elements and "
                      << equation_systems.n_active_dofs()
                      << " active dofs." << std::endl;
        } // End loop over adaptive steps

        // Do one last solve if necessary
        if (a_step == max_adaptivesteps)
        {
            QoISet qois;
            std::vector<unsigned int> qoi_indices;

            qoi_indices.push_back(0);
            qois.add_indices(qoi_indices);

            qois.set_weight(0, 1.0);

            system.assemble_qoi_sides = true; //QoI doesn't involve sides

            std::cout << "\n~*~*~*~*~*~*~*~*~ adjoint solve start ~*~*~*~*~*~*~*~*~\n" << std::endl;
            std::pair<unsigned int, Real> adjsolve = system.adjoint_solve();
            std::cout << "number of iterations to solve adjoint: " << adjsolve.first << std::endl;
            std::cout << "final residual of adjoint solve: " << adjsolve.second << std::endl;
            std::cout << "\n~*~*~*~*~*~*~*~*~ adjoint solve end ~*~*~*~*~*~*~*~*~" << std::endl;

            NumericVector<Number> &dual_solution = system.get_adjoint_solution(0);
            NumericVector<Number> &primal_solution = *system.solution;

            primal_solution.swap(dual_solution);
            ExodusII_IO(mesh).write_timestep("super_adjoint.exo",
                                             equation_systems,
                                             1, /* This number indicates how many time steps
	                                       are being written to the file */
                                             system.time);
            primal_solution.swap(dual_solution);

            system.assemble(); //overwrite residual read in from psiLF solve

            // The total error estimate
            system.postprocess(); //to compute M_HF(psiLF) and M_LF(psiLF) terms
            Real QoI_error_estimate = (-0.5*(system.rhs)->dot(dual_solution)) + system.get_MHF_psiLF() - system.get_MLF_psiLF();
            std::cout << "\n\n 0.5*M'_HF(psiLF)(superadj): " << std::setprecision(17) << 0.5*(system.rhs)->dot(dual_solution) << "\n";
            std::cout << " M_HF(psiLF): " << std::setprecision(17) << system.get_MHF_psiLF() << "\n";
            std::cout << " M_LF(psiLF): " << std::setprecision(17) << system.get_MLF_psiLF() << "\n";
            std::cout << "\n\n Residual L2 norm: " << system.calculate_norm(*system.rhs, L2) << "\n";
            std::cout << " Residual discrete L2 norm: " << system.calculate_norm(*system.rhs, DISCRETE_L2) << "\n";
            std::cout << " Super-adjoint L2 norm: " << system.calculate_norm(dual_solution, L2) << "\n";
            std::cout << " Super-adjoint discrete L2 norm: " << system.calculate_norm(dual_solution, DISCRETE_L2) << "\n";
            std::cout << "\n\n QoI error estimate: " << std::setprecision(17) << QoI_error_estimate << "\n\n";

            //DEBUG
            std::cout << "\n------------ herp derp ------------" << std::endl;
            //libMesh::out.precision(16);
            //dual_solution.print();
            //system.get_adjoint_rhs().print();

            AutoPtr<NumericVector<Number> > adjresid = system.solution->clone();
            (system.matrix)->vector_mult(*adjresid,system.get_adjoint_solution(0));
            SparseMatrix<Number>& adjmat = *system.matrix;
            (system.matrix)->get_transpose(adjmat);
            adjmat.vector_mult(*adjresid,system.get_adjoint_solution(0));
            //std::cout << "******************** matrix-superadj product (libmesh) ************************" << std::endl;
            //adjresid->print();
            adjresid->add(-1.0, system.get_adjoint_rhs(0));
            //std::cout << "******************** superadjoint system residual (libmesh) ***********************" << std::endl;
            //adjresid->print();
            std::cout << "\n\nadjoint system residual (discrete L2): " << system.calculate_norm(*adjresid,DISCRETE_L2) << std::endl;
            std::cout << "adjoint system residual (L2, all): " << system.calculate_norm(*adjresid,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 0): " << system.calculate_norm(*adjresid,0,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 1): " << system.calculate_norm(*adjresid,1,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 2): " << system.calculate_norm(*adjresid,2,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 3): " << system.calculate_norm(*adjresid,3,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 4): " << system.calculate_norm(*adjresid,4,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 5): " << system.calculate_norm(*adjresid,5,L2) << std::endl;
            /*
            	AutoPtr<NumericVector<Number> > sadj_matlab = system.solution->clone();
            	AutoPtr<NumericVector<Number> > adjresid_matlab = system.solution->clone();
            	if(FILE *fp=fopen("superadj_matlab.txt","r")){
              	Real value;
              	int counter = 0;
              	int flag = 1;
              	while(flag != -1){
              		flag = fscanf(fp,"%lf",&value);
              		if(flag != -1){
            				sadj_matlab->set(counter, value);
            				counter += 1;
              		}
              	}
              	fclose(fp);
            	}
            	(system.matrix)->vector_mult(*adjresid_matlab,*sadj_matlab);
            	//std::cout << "******************** matrix-superadj product (matlab) ***********************" << std::endl;
            	//adjresid_matlab->print();
            	adjresid_matlab->add(-1.0, system.get_adjoint_rhs(0));
            	//std::cout << "******************** superadjoint system residual (matlab) ***********************" << std::endl;
            	//adjresid_matlab->print();
            	std::cout << "\n\nmatlab import adjoint system residual (discrete L2): " << system.calculate_norm(*adjresid_matlab,DISCRETE_L2) << "\n" << std::endl;
            */
            /*
            	AutoPtr<NumericVector<Number> > sadj_fwd_hack = system.solution->clone();
            	AutoPtr<NumericVector<Number> > adjresid_fwd_hack = system.solution->clone();
            	if(FILE *fp=fopen("superadj_forward_hack.txt","r")){
              	Real value;
              	int counter = 0;
              	int flag = 1;
              	while(flag != -1){
              		flag = fscanf(fp,"%lf",&value);
              		if(flag != -1){
            				sadj_fwd_hack->set(counter, value);
            				counter += 1;
              		}
              	}
              	fclose(fp);
            	}
            	(system.matrix)->vector_mult(*adjresid_fwd_hack,*sadj_fwd_hack);
            	//std::cout << "******************** matrix-superadj product (fwd_hack) ***********************" << std::endl;
            	//adjresid_fwd_hack->print();
            	adjresid_fwd_hack->add(-1.0, system.get_adjoint_rhs(0));
            	//std::cout << "******************** superadjoint system residual (fwd_hack) ***********************" << std::endl;
            	//adjresid_fwd_hack->print();
            	std::cout << "\n\nfwd_hack import adjoint system residual (discrete L2): " << system.calculate_norm(*adjresid_fwd_hack,DISCRETE_L2) << "\n" << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 0): " << system.calculate_norm(*adjresid_fwd_hack,0,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 1): " << system.calculate_norm(*adjresid_fwd_hack,1,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 2): " << system.calculate_norm(*adjresid_fwd_hack,2,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 3): " << system.calculate_norm(*adjresid_fwd_hack,3,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 4): " << system.calculate_norm(*adjresid_fwd_hack,4,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 5): " << system.calculate_norm(*adjresid_fwd_hack,5,L2) << std::endl;
            */
            //std::cout << "************************ system.matrix ***********************" << std::endl;
            //system.matrix->print();

            std::cout << "\n------------ herp derp ------------" << std::endl;

            // The cell wise breakdown
            ErrorVector cell_wise_error;
            cell_wise_error.resize((system.rhs)->size());
            for(unsigned int i = 0; i < (system.rhs)->size() ; i++)
            {
                if(i < system.get_mesh().n_elem())
                    cell_wise_error[i] = fabs(-0.5*((system.rhs)->el(i) * dual_solution(i))
                                              + system.get_MHF_psiLF(i) - system.get_MLF_psiLF(i));
                else
                    cell_wise_error[i] = fabs(-0.5*((system.rhs)->el(i) * dual_solution(i)));

                /*csv from 'save data' from gmv output gives a few values at each node point (value
                for every element that shares that node), yet paraview display only seems to show one
                of them -> the value in an element is given at each of the nodes that it has, hence the
                repetition; what is displayed in paraview is each element's value; even though MHF_psiLF
                and MLF_psiLF are stored by element this seems to give elemental contributions that
                agree with if we had taken the superadj-residual dot product by integrating over elements*/

                /*at higher mesh resolutions and lower k, weird-looking artifacts start to appear and
                it no longer agrees with output from manual integration of superadj-residual...*/
            }
            // Plot it
            std::ostringstream error_gmv;
            error_gmv << "error.gmv";
            cell_wise_error.plot_error(error_gmv.str(), equation_systems.get_mesh());

            //alternate element-wise breakdown, outputed as values matched to element centroids; for matlab plotz
            primal_solution.swap(dual_solution);
            system.postprocess(1);
            primal_solution.swap(dual_solution);
            system.postprocess(2);
            std::cout << "\n\n -0.5*M'_HF(psiLF)(superadj): " << std::setprecision(17) << system.get_half_adj_weighted_resid() << "\n";
            primal_solution.swap(dual_solution);

            std::string write_error_here = infileForMesh("error_est_output_file", "error_est_breakdown.dat");
            std::ofstream output(write_error_here);
            for(unsigned int i = 0 ; i < system.get_mesh().n_elem(); i++) {
                Point elem_cent = system.get_mesh().elem(i)->centroid();
                if(output.is_open()) {
                    output << elem_cent(0) << " " << elem_cent(1) << " "
                           << fabs(system.get_half_adj_weighted_resid(i) + system.get_MHF_psiLF(i) - system.get_MLF_psiLF(i)) << "\n";
                }
            }
            output.close();

        } // End if at max adaptive steps

#ifdef LIBMESH_HAVE_EXODUS_API
        // Write out this timestep if we're requested to
        if ((t_step+1)%write_interval == 0)
        {
            std::ostringstream file_name;
            /*
                // We write the file in the ExodusII format.
                file_name << "out_"
                          << std::setw(3)
                          << std::setfill('0')
                          << std::right
                          << t_step+1
                          << ".e";
            			//this should write out the primal which should be the same as what's read in...
            			ExodusII_IO(mesh).write_timestep(file_name.str(),
            							                        equation_systems,
            							                        1, //number of time steps written to file
            							                        system.time);
            */
        }
#endif // #ifdef LIBMESH_HAVE_EXODUS_API
    }

    // All done.
    return 0;

} //end main
コード例 #30
0
ファイル: libmesh.C プロジェクト: huangh-inl/libmesh
LibMeshInit::LibMeshInit (int argc, const char* const* argv,
                          MPI_Comm COMM_WORLD_IN)
#endif
{
  // should _not_ be initialized already.
  libmesh_assert (!libMesh::initialized());

  // Build a command-line parser.
  command_line.reset (new GetPot (argc, argv));

  // Disable performance logging upon request
  {
    if (libMesh::on_command_line ("--disable-perflog"))
      libMesh::perflog.disable_logging();
  }

  // Build a task scheduler
  {
    // Get the requested number of threads, defaults to 1 to avoid MPI and
    // multithreading competition.  If you would like to use MPI and multithreading
    // at the same time then (n_mpi_processes_per_node)x(n_threads) should be the
    //  number of processing cores per node.
    std::vector<std::string> n_threads(2);
    n_threads[0] = "--n_threads";
    n_threads[1] = "--n-threads";
    libMesh::libMeshPrivateData::_n_threads =
      libMesh::command_line_value (n_threads, 1);

    // Set the number of OpenMP threads to the same as the number of threads libMesh is going to use
#ifdef LIBMESH_HAVE_OPENMP
    omp_set_num_threads(libMesh::libMeshPrivateData::_n_threads);
#endif

    task_scheduler.reset (new Threads::task_scheduler_init(libMesh::n_threads()));
  }

  // Construct singletons who may be at risk of the
  // "static initialization order fiasco"
  Singleton::setup();

  // Make sure the construction worked
  libmesh_assert(remote_elem);

#if defined(LIBMESH_HAVE_MPI)

  // Allow the user to bypass MPI initialization
  if (!libMesh::on_command_line ("--disable-mpi"))
    {
      // Check whether the calling program has already initialized
      // MPI, and avoid duplicate Init/Finalize
      int flag;
      MPI_Initialized (&flag);

      if (!flag)
        {
#if MPI_VERSION > 1
          int mpi_thread_provided;
          const int mpi_thread_requested = libMesh::n_threads() > 1 ?
                                           MPI_THREAD_FUNNELED :
                                           MPI_THREAD_SINGLE;

          MPI_Init_thread (&argc, const_cast<char***>(&argv),
                           mpi_thread_requested, &mpi_thread_provided);

          if ((libMesh::n_threads() > 1) &&
              (mpi_thread_provided < MPI_THREAD_FUNNELED))
            {
              libmesh_warning("Warning: MPI failed to guarantee MPI_THREAD_FUNNELED\n" << 
                              "for a threaded run.\n" <<
                              "Be sure your library is funneled-thread-safe..." <<
                               std::endl);

              // Ideally, if an MPI stack tells us it's unsafe for us
              // to use threads, we shouldn't use threads.
              // In practice, we've encountered one MPI stack (an
              // mvapich2 configuration) that returned
              // MPI_THREAD_SINGLE as a proper warning, two stacks
              // that handle MPI_THREAD_FUNNELED properly, and two
              // current stacks plus a couple old stacks that return
              // MPI_THREAD_SINGLE but support libMesh threaded runs
              // anyway.

              // libMesh::libMeshPrivateData::_n_threads = 1;
              // task_scheduler.reset (new Threads::task_scheduler_init(libMesh::n_threads()));
            }
#else
          if (libMesh::libMeshPrivateData::_n_threads > 1)
            {
              libmesh_warning("Warning: using MPI1 for threaded code.\n" <<
                              "Be sure your library is funneled-thread-safe..." <<
                              std::endl);
            }

          MPI_Init (&argc, const_cast<char***>(&argv));
#endif
          libmesh_initialized_mpi = true;
        }

      // Duplicate the input communicator for internal use
      // And get a Parallel::Communicator copy too, to use
      // as a default for that API
      this->_comm = COMM_WORLD_IN;

      libMesh::GLOBAL_COMM_WORLD = COMM_WORLD_IN;

#ifndef LIBMESH_DISABLE_COMMWORLD
      libMesh::COMM_WORLD = COMM_WORLD_IN;
      Parallel::Communicator_World = COMM_WORLD_IN;
#endif

      //MPI_Comm_set_name not supported in at least SGI MPT's MPI implementation
      //MPI_Comm_set_name (libMesh::COMM_WORLD, "libMesh::COMM_WORLD");

      libMeshPrivateData::_processor_id =
        libmesh_cast_int<processor_id_type>(this->comm().rank());
      libMeshPrivateData::_n_processors =
        libmesh_cast_int<processor_id_type>(this->comm().size());

      // Set up an MPI error handler if requested.  This helps us get
      // into a debugger with a proper stack when an MPI error occurs.
      if (libMesh::on_command_line ("--handle-mpi-errors"))
        {
#if MPI_VERSION > 1
          MPI_Comm_create_errhandler(libMesh_MPI_Handler, &libmesh_errhandler);
          MPI_Comm_set_errhandler(libMesh::GLOBAL_COMM_WORLD, libmesh_errhandler);
          MPI_Comm_set_errhandler(MPI_COMM_WORLD, libmesh_errhandler);
#else
          MPI_Errhandler_create(libMesh_MPI_Handler, &libmesh_errhandler);
          MPI_Errhandler_set(libMesh::GLOBAL_COMM_WORLD, libmesh_errhandler);
          MPI_Errhandler_set(MPI_COMM_WORLD, libmesh_errhandler);
#endif // #if MPI_VERSION > 1
        }
    }

  // Could we have gotten bad values from the above calls?
  libmesh_assert_greater (libMeshPrivateData::_n_processors, 0);

  // The libmesh_cast_int already tested _processor_id>=0
  // libmesh_assert_greater_equal (libMeshPrivateData::_processor_id, 0);

  // Let's be sure we properly initialize on every processor at once:
  libmesh_parallel_only(this->comm());

#endif

#if defined(LIBMESH_HAVE_PETSC)

  // Allow the user to bypass PETSc initialization
  if (!libMesh::on_command_line ("--disable-petsc")

#if defined(LIBMESH_HAVE_MPI)
      // If the user bypassed MPI, we'd better be safe and assume that
      // PETSc was built to require it; otherwise PETSc initialization
      // dies.
      && !libMesh::on_command_line ("--disable-mpi")
#endif
      )
    {
      int ierr=0;

      PETSC_COMM_WORLD = libMesh::GLOBAL_COMM_WORLD;

      // Check whether the calling program has already initialized
      // PETSc, and avoid duplicate Initialize/Finalize
      PetscBool petsc_already_initialized;
      ierr = PetscInitialized(&petsc_already_initialized);
      CHKERRABORT(libMesh::GLOBAL_COMM_WORLD,ierr);
      if (petsc_already_initialized != PETSC_TRUE)
        libmesh_initialized_petsc = true;
# if defined(LIBMESH_HAVE_SLEPC)

      // If SLEPc allows us to check whether the calling program
      // has already initialized it, we do that, and avoid
      // duplicate Initialize/Finalize.
      // We assume that SLEPc will handle PETSc appropriately,
      // which it does in the versions we've checked.
#  if !SLEPC_VERSION_LESS_THAN(2,3,3)
      if (!SlepcInitializeCalled)
#  endif
        {
          ierr = SlepcInitialize  (&argc, const_cast<char***>(&argv), NULL, NULL);
          CHKERRABORT(libMesh::GLOBAL_COMM_WORLD,ierr);
          libmesh_initialized_slepc = true;
        }
# else
      if (libmesh_initialized_petsc)
        {
          ierr = PetscInitialize (&argc, const_cast<char***>(&argv), NULL, NULL);
          CHKERRABORT(libMesh::GLOBAL_COMM_WORLD,ierr);
        }
# endif
    }
#endif

  // Re-parse the command-line arguments.  Note that PETSc and MPI
  // initialization above may have removed command line arguments
  // that are not relevant to this application in the above calls.
  // We don't want a false-positive by detecting those arguments.
  command_line->parse_command_line (argc, argv);

  // The following line is an optimization when simultaneous
  // C and C++ style access to output streams is not required.
  // The amount of benefit which occurs is probably implementation
  // defined, and may be nothing.  On the other hand, I have seen
  // some IO tests where IO peformance improves by a factor of two.
  if (!libMesh::on_command_line ("--sync-with-stdio"))
    std::ios::sync_with_stdio(false);

  // Honor the --separate-libmeshout command-line option.
  // When this is specified, the library uses an independent ostream
  // for libMesh::out/libMesh::err messages, and
  // std::cout and std::cerr are untouched by any other options
  if (libMesh::on_command_line ("--separate-libmeshout"))
    {
      // Redirect.  We'll share streambufs with cout/cerr for now, but
      // presumably anyone using this option will want to replace the
      // bufs later.
      std::ostream* newout = new std::ostream(std::cout.rdbuf());
      libMesh::out = *newout;
      std::ostream* newerr = new std::ostream(std::cerr.rdbuf());
      libMesh::err = *newerr;
    }

  // Honor the --redirect-stdout command-line option.
  // When this is specified each processor sends
  // libMesh::out/libMesh::err messages to
  // stdout.processor.####
  if (libMesh::on_command_line ("--redirect-stdout"))
    {
      std::ostringstream filename;
      filename << "stdout.processor." << libMesh::global_processor_id();
      _ofstream.reset (new std::ofstream (filename.str().c_str()));
      // Redirect, saving the original streambufs!
      out_buf = libMesh::out.rdbuf (_ofstream->rdbuf());
      err_buf = libMesh::err.rdbuf (_ofstream->rdbuf());
    }

  // redirect libMesh::out to nothing on all
  // other processors unless explicitly told
  // not to via the --keep-cout command-line argument.
  if (libMesh::global_processor_id() != 0)
    if (!libMesh::on_command_line ("--keep-cout"))
      libMesh::out.rdbuf (NULL);

  // Check command line to override printing
  // of reference count information.
  if(libMesh::on_command_line("--disable-refcount-printing") )
    ReferenceCounter::disable_print_counter_info();

#ifdef LIBMESH_ENABLE_EXCEPTIONS
  // Set our terminate handler to write stack traces in the event of a
  // crash
  old_terminate_handler = std::set_terminate(libmesh_terminate_handler);
#endif


  if (libMesh::on_command_line("--enable-fpe"))
    libMesh::enableFPE(true);

  // The library is now ready for use
  libMeshPrivateData::_is_initialized = true;


  // Make sure these work.  Library methods
  // depend on these being implemented properly,
  // so this is a good time to test them!
  libmesh_assert (libMesh::initialized());
  libmesh_assert (!libMesh::closed());
}