libMesh::HPCoarsenTest Class Reference

#include <hp_coarsentest.h>

Inheritance diagram for libMesh::HPCoarsenTest:

List of all members.

Public Member Functions

 HPCoarsenTest ()
virtual ~HPCoarsenTest ()
virtual void select_refinement (System &system)

Public Attributes

Real p_weight
std::vector< float > component_scale

Protected Member Functions

void add_projection (const System &, const Elem *, unsigned int var)

Protected Attributes

const Elemcoarse
std::vector< dof_id_typedof_indices
AutoPtr< FEBasefe
AutoPtr< FEBasefe_coarse
const std::vector< std::vector
< Real > > * 
phi
const std::vector< std::vector
< Real > > * 
phi_coarse
const std::vector< std::vector
< RealGradient > > * 
dphi
const std::vector< std::vector
< RealGradient > > * 
dphi_coarse
const std::vector< std::vector
< RealTensor > > * 
d2phi
const std::vector< std::vector
< RealTensor > > * 
d2phi_coarse
const std::vector< Real > * JxW
const std::vector< Point > * xyz_values
std::vector< Pointcoarse_qpoints
AutoPtr< QBaseqrule
DenseMatrix< NumberKe
DenseVector< NumberFe
DenseVector< NumberUc
DenseVector< NumberUp

Detailed Description

This class uses the error estimate given by different types of derefinement (h coarsening or p reduction) to choose between h refining and p elevation. Currently we assume that a set of elements has already been flagged for h refinement, and we may want to change some of those elements to be flagged for p refinement.

This code is currently experimental and will not produce optimal hp meshes without significant improvement.

Author:
Roy H. Stogner, 2006.

Definition at line 67 of file hp_coarsentest.h.


Constructor & Destructor Documentation

libMesh::HPCoarsenTest::HPCoarsenTest (  )  [inline]

Constructor.

Definition at line 74 of file hp_coarsentest.h.

00074                   : p_weight(1.0)
00075   {
00076     libmesh_experimental();
00077   }

virtual libMesh::HPCoarsenTest::~HPCoarsenTest (  )  [inline, virtual]

Destructor.

Definition at line 82 of file hp_coarsentest.h.

00082 {}


Member Function Documentation

void libMesh::HPCoarsenTest::add_projection ( const System system,
const Elem elem,
unsigned int  var 
) [protected]

The helper function which adds individual fine element data to the coarse element projection

Definition at line 46 of file hp_coarsentest.C.

References libMesh::Elem::active(), libMesh::TypeTensor< T >::add_scaled(), libMesh::TypeVector< T >::add_scaled(), libMeshEnums::C_ONE, libMeshEnums::C_ZERO, libMesh::Elem::child(), coarse, coarse_qpoints, libMesh::TypeTensor< T >::contract(), libMesh::System::current_solution(), d2phi, d2phi_coarse, dof_indices, libMesh::DofMap::dof_indices(), dphi, Fe, fe, fe_coarse, libMesh::System::get_dof_map(), libMesh::System::get_mesh(), libMesh::FEInterface::inverse_map(), Ke, libMesh::MeshBase::mesh_dimension(), libMesh::Elem::n_children(), phi_coarse, qrule, libMesh::DenseVector< T >::resize(), libMesh::DenseMatrix< T >::resize(), libMesh::DenseVector< T >::size(), libMesh::Elem::subactive(), Uc, libMesh::DofMap::variable_type(), xyz_values, libMesh::zero, libMesh::DenseVector< T >::zero(), and libMesh::DenseMatrix< T >::zero().

Referenced by select_refinement().

00049 {
00050   // If we have children, we need to add their projections instead
00051   if (!elem->active())
00052     {
00053       libmesh_assert(!elem->subactive());
00054       for (unsigned int c = 0; c != elem->n_children(); ++c)
00055         this->add_projection(system, elem->child(c), var);
00056       return;
00057     }
00058 
00059   // The DofMap for this system
00060   const DofMap& dof_map = system.get_dof_map();
00061 
00062   // The type of finite element to use for this variable
00063   const FEType& fe_type = dof_map.variable_type (var);
00064 
00065   const FEContinuity cont = fe->get_continuity();
00066 
00067   fe->reinit(elem);
00068 
00069   dof_map.dof_indices(elem, dof_indices, var);
00070 
00071   const unsigned int n_dofs =
00072     libmesh_cast_int<unsigned int>(dof_indices.size());
00073 
00074   FEInterface::inverse_map (system.get_mesh().mesh_dimension(),
00075     fe_type, coarse, *xyz_values, coarse_qpoints);
00076 
00077   fe_coarse->reinit(coarse, &coarse_qpoints);
00078 
00079   const unsigned int n_coarse_dofs =
00080     libmesh_cast_int<unsigned int>(phi_coarse->size());
00081 
00082   if (Uc.size() == 0)
00083     {
00084       Ke.resize(n_coarse_dofs, n_coarse_dofs);
00085       Ke.zero();
00086       Fe.resize(n_coarse_dofs);
00087       Fe.zero();
00088       Uc.resize(n_coarse_dofs);
00089       Uc.zero();
00090     }
00091   libmesh_assert_equal_to (Uc.size(), phi_coarse->size());
00092 
00093   // Loop over the quadrature points
00094   for (unsigned int qp=0; qp<qrule->n_points(); qp++)
00095     {
00096       // The solution value at the quadrature point
00097       Number val = libMesh::zero;
00098       Gradient grad;
00099       Tensor hess;
00100 
00101       for (unsigned int i=0; i != n_dofs; i++)
00102         {
00103           dof_id_type dof_num = dof_indices[i];
00104           val += (*phi)[i][qp] *
00105             system.current_solution(dof_num);
00106           if (cont == C_ZERO || cont == C_ONE)
00107             grad.add_scaled((*dphi)[i][qp],system.current_solution(dof_num));
00108            // grad += (*dphi)[i][qp] *
00109             //  system.current_solution(dof_num);
00110           if (cont == C_ONE)
00111             hess.add_scaled((*d2phi)[i][qp], system.current_solution(dof_num));
00112             // hess += (*d2phi)[i][qp] *
00113             //  system.current_solution(dof_num);
00114         }
00115 
00116       // The projection matrix and vector
00117       for (unsigned int i=0; i != Fe.size(); ++i)
00118         {
00119           Fe(i) += (*JxW)[qp] *
00120             (*phi_coarse)[i][qp]*val;
00121           if (cont == C_ZERO || cont == C_ONE)
00122             Fe(i) += (*JxW)[qp] *
00123               (grad*(*dphi_coarse)[i][qp]);
00124           if (cont == C_ONE)
00125             Fe(i) += (*JxW)[qp] *
00126               hess.contract((*d2phi_coarse)[i][qp]);
00127             // Fe(i) += (*JxW)[qp] *
00128             //  (*d2phi_coarse)[i][qp].contract(hess);
00129 
00130           for (unsigned int j=0; j != Fe.size(); ++j)
00131             {
00132               Ke(i,j) += (*JxW)[qp] *
00133                 (*phi_coarse)[i][qp]*(*phi_coarse)[j][qp];
00134               if (cont == C_ZERO || cont == C_ONE)
00135                 Ke(i,j) += (*JxW)[qp] *
00136                   (*dphi_coarse)[i][qp]*(*dphi_coarse)[j][qp];
00137               if (cont == C_ONE)
00138                 Ke(i,j) += (*JxW)[qp] *
00139                   ((*d2phi_coarse)[i][qp].contract((*d2phi_coarse)[j][qp]));
00140             }
00141         }
00142     }
00143 }

void libMesh::HPCoarsenTest::select_refinement ( System system  )  [virtual]

This pure virtual function must be redefined in derived classes to take a mesh flagged for h refinement and potentially change the desired refinement type.

Implements libMesh::HPSelector.

Definition at line 145 of file hp_coarsentest.C.

References libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), add_projection(), libMesh::TypeTensor< T >::add_scaled(), libMesh::TypeVector< T >::add_scaled(), libMesh::FEGenericBase< Real >::build(), libMeshEnums::C_ONE, libMeshEnums::C_ZERO, libMesh::DenseMatrix< T >::cholesky_solve(), coarse, coarse_qpoints, libMesh::HPSelector::component_scale, libMesh::TypeTensor< T >::contract(), libMesh::System::current_solution(), d2phi, d2phi_coarse, libMesh::FEType::default_quadrature_rule(), libMeshEnums::DISCONTINUOUS, libMesh::Elem::DO_NOTHING, dof_indices, libMesh::DofMap::dof_indices(), libMesh::DofObject::dof_number(), dphi, dphi_coarse, libMesh::err, libMesh::ErrorVectorReal, Fe, fe, fe_coarse, libMesh::AutoPtr< Tp >::get(), libMesh::System::get_dof_map(), libMesh::System::get_mesh(), libMesh::Elem::get_node(), libMesh::DofObject::id(), libMesh::FEInterface::inverse_map(), libMesh::Elem::is_vertex(), JxW, Ke, std::max(), mesh, libMesh::MeshBase::mesh_dimension(), libMesh::Elem::n_children(), libMesh::FEInterface::n_dofs(), libMesh::MeshBase::n_elem(), libMesh::Elem::n_nodes(), n_nodes, libMesh::System::n_vars(), n_vars, libMesh::TensorTools::norm_sq(), libMesh::System::number(), libMesh::FEType::order, libMesh::Elem::p_level(), p_weight, libMesh::Elem::parent(), phi, phi_coarse, qrule, libMesh::Real, libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::DenseMatrix< T >::resize(), libMesh::DenseVector< T >::resize(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), libMesh::DenseVector< T >::size(), libMesh::TypeTensor< T >::size_sq(), libMesh::TypeVector< T >::size_sq(), libMesh::TypeTensor< T >::subtract_scaled(), libMesh::TypeVector< T >::subtract_scaled(), libMesh::Elem::type(), Uc, Up, libMesh::DofMap::variable_type(), xyz_values, libMesh::zero, libMesh::DenseVector< T >::zero(), and libMesh::DenseMatrix< T >::zero().

00146 {
00147   START_LOG("select_refinement()", "HPCoarsenTest");
00148 
00149   // The current mesh
00150   MeshBase& mesh = system.get_mesh();
00151 
00152   // The dimensionality of the mesh
00153   const unsigned int dim = mesh.mesh_dimension();
00154 
00155   // The number of variables in the system
00156   const unsigned int n_vars = system.n_vars();
00157 
00158   // The DofMap for this system
00159   const DofMap& dof_map = system.get_dof_map();
00160 
00161   // The system number (for doing bad hackery)
00162   const unsigned int sys_num = system.number();
00163 
00164   // Check for a valid component_scale
00165   if (!component_scale.empty())
00166     {
00167       if (component_scale.size() != n_vars)
00168         {
00169           libMesh::err << "ERROR: component_scale is the wrong size:"
00170                         << std::endl
00171                         << " component_scale.size()=" << component_scale.size()
00172                         << std::endl
00173                         << " n_vars=" << n_vars
00174                         << std::endl;
00175           libmesh_error();
00176         }
00177     }
00178   else
00179     {
00180       // No specified scaling.  Scale all variables by one.
00181       component_scale.resize (n_vars, 1.0);
00182     }
00183 
00184   // Resize the error_per_cell vectors to handle
00185   // the number of elements, initialize them to 0.
00186   std::vector<ErrorVectorReal> h_error_per_cell(mesh.n_elem(), 0.);
00187   std::vector<ErrorVectorReal> p_error_per_cell(mesh.n_elem(), 0.);
00188 
00189   // Loop over all the variables in the system
00190   for (unsigned int var=0; var<n_vars; var++)
00191     {
00192       // Possibly skip this variable
00193       if (!component_scale.empty())
00194         if (component_scale[var] == 0.0) continue;
00195 
00196       // The type of finite element to use for this variable
00197       const FEType& fe_type = dof_map.variable_type (var);
00198 
00199       // Finite element objects for a fine (and probably a coarse)
00200       // element will be needed
00201       fe = FEBase::build (dim, fe_type);
00202       fe_coarse = FEBase::build (dim, fe_type);
00203 
00204       // Any cached coarse element results have expired
00205       coarse = NULL;
00206       unsigned int cached_coarse_p_level = 0;
00207 
00208       const FEContinuity cont = fe->get_continuity();
00209       libmesh_assert (cont == DISCONTINUOUS || cont == C_ZERO ||
00210               cont == C_ONE);
00211 
00212       // Build an appropriate quadrature rule
00213       qrule = fe_type.default_quadrature_rule(dim);
00214 
00215       // Tell the refined finite element about the quadrature
00216       // rule.  The coarse finite element need not know about it
00217       fe->attach_quadrature_rule (qrule.get());
00218 
00219       // We will always do the integration
00220       // on the fine elements.  Get their Jacobian values, etc..
00221       JxW = &(fe->get_JxW());
00222       xyz_values = &(fe->get_xyz());
00223 
00224       // The shape functions
00225       phi = &(fe->get_phi());
00226       phi_coarse = &(fe_coarse->get_phi());
00227 
00228       // The shape function derivatives
00229       if (cont == C_ZERO || cont == C_ONE)
00230         {
00231           dphi = &(fe->get_dphi());
00232           dphi_coarse = &(fe_coarse->get_dphi());
00233         }
00234 
00235 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
00236       // The shape function second derivatives
00237       if (cont == C_ONE)
00238         {
00239           d2phi = &(fe->get_d2phi());
00240           d2phi_coarse = &(fe_coarse->get_d2phi());
00241         }
00242 #endif // defined (LIBMESH_ENABLE_SECOND_DERIVATIVES)
00243 
00244       // Iterate over all the active elements in the mesh
00245       // that live on this processor.
00246 
00247       MeshBase::const_element_iterator       elem_it  =
00248                       mesh.active_local_elements_begin();
00249       const MeshBase::const_element_iterator elem_end =
00250                       mesh.active_local_elements_end();
00251 
00252       for (; elem_it != elem_end; ++elem_it)
00253         {
00254           const Elem* elem = *elem_it;
00255 
00256           // We're only checking elements that are already flagged for h
00257           // refinement
00258           if (elem->refinement_flag() != Elem::REFINE)
00259             continue;
00260 
00261           const dof_id_type e_id = elem->id();
00262 
00263           // Find the projection onto the parent element,
00264           // if necessary
00265           if (elem->parent() &&
00266               (coarse != elem->parent() ||
00267                cached_coarse_p_level != elem->p_level()))
00268             {
00269               Uc.resize(0);
00270 
00271               coarse = elem->parent();
00272               cached_coarse_p_level = elem->p_level();
00273 
00274               unsigned int old_parent_level = coarse->p_level();
00275               (const_cast<Elem *>(coarse))->hack_p_level(elem->p_level());
00276 
00277               this->add_projection(system, coarse, var);
00278 
00279               (const_cast<Elem *>(coarse))->hack_p_level(old_parent_level);
00280 
00281               // Solve the h-coarsening projection problem
00282               Ke.cholesky_solve(Fe, Uc);
00283             }
00284 
00285           fe->reinit(elem);
00286 
00287           // Get the DOF indices for the fine element
00288           dof_map.dof_indices (elem, dof_indices, var);
00289 
00290           // The number of quadrature points
00291           const unsigned int n_qp = qrule->n_points();
00292 
00293           // The number of DOFS on the fine element
00294           const unsigned int n_dofs = 
00295             libmesh_cast_int<unsigned int>(dof_indices.size());
00296 
00297           // The number of nodes on the fine element
00298           const unsigned int n_nodes = elem->n_nodes();
00299 
00300           // The average element value (used as an ugly hack
00301           // when we have nothing p-coarsened to compare to)
00302           // Real average_val = 0.;
00303           Number average_val = 0.;
00304 
00305           // Calculate this variable's contribution to the p
00306           // refinement error
00307 
00308           if (elem->p_level() == 0)
00309             {
00310               unsigned int n_vertices = 0;
00311               for (unsigned int n = 0; n != n_nodes; ++n)
00312                 if (elem->is_vertex(n))
00313                   {
00314                     n_vertices++;
00315                     const Node * const node = elem->get_node(n);
00316                     average_val += system.current_solution
00317                       (node->dof_number(sys_num,var,0));
00318                   }
00319               average_val /= n_vertices;
00320             }
00321           else
00322             {
00323               unsigned int old_elem_level = elem->p_level();
00324               (const_cast<Elem *>(elem))->hack_p_level(old_elem_level - 1);
00325 
00326               fe_coarse->reinit(elem, &(qrule->get_points()));
00327 
00328               const unsigned int n_coarse_dofs =
00329                 libmesh_cast_int<unsigned int>(phi_coarse->size());
00330 
00331               (const_cast<Elem *>(elem))->hack_p_level(old_elem_level);
00332 
00333               Ke.resize(n_coarse_dofs, n_coarse_dofs);
00334               Ke.zero();
00335               Fe.resize(n_coarse_dofs);
00336               Fe.zero();
00337 
00338               // Loop over the quadrature points
00339               for (unsigned int qp=0; qp<qrule->n_points(); qp++)
00340                 {
00341                   // The solution value at the quadrature point
00342                   Number val = libMesh::zero;
00343                   Gradient grad;
00344                   Tensor hess;
00345 
00346                   for (unsigned int i=0; i != n_dofs; i++)
00347                     {
00348                       dof_id_type dof_num = dof_indices[i];
00349                       val += (*phi)[i][qp] *
00350                         system.current_solution(dof_num);
00351                       if (cont == C_ZERO || cont == C_ONE)
00352                         grad.add_scaled((*dphi)[i][qp], system.current_solution(dof_num));
00353                         // grad += (*dphi)[i][qp] *
00354                         //  system.current_solution(dof_num);
00355                       if (cont == C_ONE)
00356                         hess.add_scaled((*d2phi)[i][qp], system.current_solution(dof_num));
00357                         // hess += (*d2phi)[i][qp] *
00358                         //  system.current_solution(dof_num);
00359                     }
00360 
00361                   // The projection matrix and vector
00362                   for (unsigned int i=0; i != Fe.size(); ++i)
00363                     {
00364                       Fe(i) += (*JxW)[qp] *
00365                         (*phi_coarse)[i][qp]*val;
00366                       if (cont == C_ZERO || cont == C_ONE)
00367                         Fe(i) += (*JxW)[qp] *
00368                           grad * (*dphi_coarse)[i][qp];
00369                       if (cont == C_ONE)
00370                         Fe(i) += (*JxW)[qp] *
00371                           hess.contract((*d2phi_coarse)[i][qp]);
00372 
00373                       for (unsigned int j=0; j != Fe.size(); ++j)
00374                         {
00375                           Ke(i,j) += (*JxW)[qp] *
00376                             (*phi_coarse)[i][qp]*(*phi_coarse)[j][qp];
00377                           if (cont == C_ZERO || cont == C_ONE)
00378                             Ke(i,j) += (*JxW)[qp] *
00379                               (*dphi_coarse)[i][qp]*(*dphi_coarse)[j][qp];
00380                           if (cont == C_ONE)
00381                             Ke(i,j) += (*JxW)[qp] *
00382                               ((*d2phi_coarse)[i][qp].contract((*d2phi_coarse)[j][qp]));
00383                         }
00384                     }
00385                 }
00386 
00387               // Solve the p-coarsening projection problem
00388               Ke.cholesky_solve(Fe, Up);
00389             }
00390 
00391           // loop over the integration points on the fine element
00392           for (unsigned int qp=0; qp<n_qp; qp++)
00393             {
00394               Number value_error = 0.;
00395               Gradient grad_error;
00396               Tensor hessian_error;
00397               for (unsigned int i=0; i<n_dofs; i++)
00398                 {
00399                   const dof_id_type dof_num = dof_indices[i];
00400                   value_error += (*phi)[i][qp] *
00401                     system.current_solution(dof_num);
00402                   if (cont == C_ZERO || cont == C_ONE)
00403                     grad_error.add_scaled((*dphi)[i][qp], system.current_solution(dof_num));
00404                     // grad_error += (*dphi)[i][qp] *
00405                     //  system.current_solution(dof_num);
00406                   if (cont == C_ONE)
00407                     hessian_error.add_scaled((*d2phi)[i][qp], system.current_solution(dof_num));
00408                   // hessian_error += (*d2phi)[i][qp] *
00409                   //    system.current_solution(dof_num);
00410                 }
00411               if (elem->p_level() == 0)
00412                 {
00413                   value_error -= average_val;
00414                 }
00415               else
00416                 {
00417                   for (unsigned int i=0; i<Up.size(); i++)
00418                     {
00419                       value_error -= (*phi_coarse)[i][qp] * Up(i);
00420                       if (cont == C_ZERO || cont == C_ONE)
00421                         grad_error.subtract_scaled((*dphi_coarse)[i][qp], Up(i));
00422                         // grad_error -= (*dphi_coarse)[i][qp] * Up(i);
00423                       if (cont == C_ONE)
00424                         hessian_error.subtract_scaled((*d2phi_coarse)[i][qp], Up(i));
00425                         // hessian_error -= (*d2phi_coarse)[i][qp] * Up(i);
00426                     }
00427                 }
00428 
00429               p_error_per_cell[e_id] += static_cast<ErrorVectorReal>
00430                 (component_scale[var] *
00431                  (*JxW)[qp] * TensorTools::norm_sq(value_error));
00432               if (cont == C_ZERO || cont == C_ONE)
00433                 p_error_per_cell[e_id] += static_cast<ErrorVectorReal>
00434                   (component_scale[var] *
00435                    (*JxW)[qp] * grad_error.size_sq());
00436               if (cont == C_ONE)
00437                 p_error_per_cell[e_id] += static_cast<ErrorVectorReal>
00438                   (component_scale[var] *
00439                    (*JxW)[qp] * hessian_error.size_sq());
00440             }
00441 
00442           // Calculate this variable's contribution to the h
00443           // refinement error
00444 
00445           if (!elem->parent())
00446             {
00447               // For now, we'll always start with an h refinement
00448               h_error_per_cell[e_id] =
00449                 std::numeric_limits<ErrorVectorReal>::max() / 2;
00450             }
00451           else
00452             {
00453               FEInterface::inverse_map (dim, fe_type, coarse,
00454                 *xyz_values, coarse_qpoints);
00455 
00456               unsigned int old_parent_level = coarse->p_level();
00457               (const_cast<Elem *>(coarse))->hack_p_level(elem->p_level());
00458 
00459               fe_coarse->reinit(coarse, &coarse_qpoints);
00460 
00461               (const_cast<Elem *>(coarse))->hack_p_level(old_parent_level);
00462 
00463               // The number of DOFS on the coarse element
00464               unsigned int n_coarse_dofs =
00465                 libmesh_cast_int<unsigned int>(phi_coarse->size());
00466 
00467               // Loop over the quadrature points
00468               for (unsigned int qp=0; qp<n_qp; qp++)
00469                 {
00470                   // The solution difference at the quadrature point
00471                   Number value_error = libMesh::zero;
00472                   Gradient grad_error;
00473                   Tensor hessian_error;
00474 
00475                   for (unsigned int i=0; i != n_dofs; ++i)
00476                     {
00477                       const dof_id_type dof_num = dof_indices[i];
00478                       value_error += (*phi)[i][qp] *
00479                         system.current_solution(dof_num);
00480                       if (cont == C_ZERO || cont == C_ONE)
00481                         grad_error.add_scaled((*dphi)[i][qp], system.current_solution(dof_num));
00482                         // grad_error += (*dphi)[i][qp] *
00483                         //  system.current_solution(dof_num);
00484                       if (cont == C_ONE)
00485                         hessian_error.add_scaled((*d2phi)[i][qp], system.current_solution(dof_num));
00486                         // hessian_error += (*d2phi)[i][qp] *
00487                         //  system.current_solution(dof_num);
00488                     }
00489 
00490                   for (unsigned int i=0; i != n_coarse_dofs; ++i)
00491                     {
00492                       value_error -= (*phi_coarse)[i][qp] * Uc(i);
00493                       if (cont == C_ZERO || cont == C_ONE)
00494                         // grad_error -= (*dphi_coarse)[i][qp] * Uc(i);
00495                         grad_error.subtract_scaled((*dphi_coarse)[i][qp], Uc(i));
00496                       if (cont == C_ONE)
00497                         hessian_error.subtract_scaled((*d2phi_coarse)[i][qp], Uc(i));
00498                         // hessian_error -= (*d2phi_coarse)[i][qp] * Uc(i);
00499                     }
00500 
00501                   h_error_per_cell[e_id] += static_cast<ErrorVectorReal>
00502                     (component_scale[var] *
00503                      (*JxW)[qp] * TensorTools::norm_sq(value_error));
00504                   if (cont == C_ZERO || cont == C_ONE)
00505                     h_error_per_cell[e_id] += static_cast<ErrorVectorReal>
00506                       (component_scale[var] *
00507                        (*JxW)[qp] * grad_error.size_sq());
00508                   if (cont == C_ONE)
00509                     h_error_per_cell[e_id] += static_cast<ErrorVectorReal>
00510                       (component_scale[var] *
00511                        (*JxW)[qp] * hessian_error.size_sq());
00512                 }
00513 
00514             }
00515         }
00516     }
00517 
00518   // Now that we've got our approximations for p_error and h_error, let's see
00519   // if we want to switch any h refinement flags to p refinement
00520 
00521   // Iterate over all the active elements in the mesh
00522   // that live on this processor.
00523 
00524   MeshBase::element_iterator       elem_it  =
00525                   mesh.active_local_elements_begin();
00526   const MeshBase::element_iterator elem_end =
00527                   mesh.active_local_elements_end();
00528 
00529   for (; elem_it != elem_end; ++elem_it)
00530     {
00531       Elem* elem = *elem_it;
00532 
00533       // We're only checking elements that are already flagged for h
00534       // refinement
00535       if (elem->refinement_flag() != Elem::REFINE)
00536         continue;
00537 
00538       const dof_id_type e_id = elem->id();
00539 
00540       unsigned int dofs_per_elem = 0, dofs_per_p_elem = 0;
00541 
00542       // Loop over all the variables in the system
00543       for (unsigned int var=0; var<n_vars; var++)
00544         {
00545           // The type of finite element to use for this variable
00546           const FEType& fe_type = dof_map.variable_type (var);
00547 
00548           // FIXME: we're overestimating the number of DOFs added by h
00549           // refinement
00550           FEType elem_fe_type = fe_type;
00551           elem_fe_type.order =
00552             static_cast<Order>(fe_type.order + elem->p_level());
00553           dofs_per_elem +=
00554             FEInterface::n_dofs(dim, elem_fe_type, elem->type());
00555 
00556           elem_fe_type.order =
00557             static_cast<Order>(fe_type.order + elem->p_level() + 1);
00558           dofs_per_p_elem +=
00559             FEInterface::n_dofs(dim, elem_fe_type, elem->type());
00560         }
00561 
00562       const unsigned int new_h_dofs = dofs_per_elem *
00563         (elem->n_children() - 1);
00564 
00565       const unsigned int new_p_dofs = dofs_per_p_elem -
00566         dofs_per_elem;
00567 
00568 /*
00569 libMesh::err << "Cell " << e_id << ": h = " << elem->hmax()
00570               << ", p = " << elem->p_level() + 1 << "," << std::endl
00571               << "     h_error = " << h_error_per_cell[e_id]
00572               << ", p_error = " << p_error_per_cell[e_id] << std::endl
00573               << "     new_h_dofs = " << new_h_dofs
00574               << ", new_p_dofs = " << new_p_dofs << std::endl;
00575 */
00576       const Real p_value = 
00577         std::sqrt(p_error_per_cell[e_id]) * p_weight / new_p_dofs;
00578       const Real h_value =
00579         std::sqrt(h_error_per_cell[e_id]) /
00580         static_cast<Real>(new_h_dofs);
00581       if (p_value > h_value)
00582         {
00583           elem->set_p_refinement_flag(Elem::REFINE);
00584           elem->set_refinement_flag(Elem::DO_NOTHING);
00585         }
00586     }
00587 
00588   STOP_LOG("select_refinement()", "HPCoarsenTest");
00589 }


Member Data Documentation

The coarse element on which a solution projection is cached

Definition at line 109 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

Definition at line 137 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

std::vector<float> libMesh::HPSelector::component_scale [inherited]

This vector can be used to "scale" certain variables in a system. If the mask is not empty, the consideration given to each component's h and p error estimates will be scaled by component_scale[c].

Definition at line 77 of file hp_selector.h.

Referenced by select_refinement().

const std::vector<std::vector<RealTensor> >* libMesh::HPCoarsenTest::d2phi [protected]

Definition at line 126 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

const std::vector<std::vector<RealTensor> > * libMesh::HPCoarsenTest::d2phi_coarse [protected]

Definition at line 126 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

Global DOF indices for fine elements

Definition at line 114 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

const std::vector<std::vector<RealGradient> >* libMesh::HPCoarsenTest::dphi [protected]

Definition at line 125 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

const std::vector<std::vector<RealGradient> > * libMesh::HPCoarsenTest::dphi_coarse [protected]

Definition at line 125 of file hp_coarsentest.h.

Referenced by select_refinement().

Definition at line 148 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

The finite element objects for fine and coarse elements

Definition at line 119 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

Definition at line 119 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

const std::vector<Real>* libMesh::HPCoarsenTest::JxW [protected]

Mapping jacobians

Definition at line 131 of file hp_coarsentest.h.

Referenced by select_refinement().

Linear system for projections

Definition at line 147 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

Because the coarsening test seems to always choose p refinement, we're providing an option to make h refinement more likely

Definition at line 97 of file hp_coarsentest.h.

Referenced by select_refinement().

const std::vector<std::vector<Real> >* libMesh::HPCoarsenTest::phi [protected]

The shape functions and their derivatives

Definition at line 124 of file hp_coarsentest.h.

Referenced by select_refinement().

const std::vector<std::vector<Real> > * libMesh::HPCoarsenTest::phi_coarse [protected]

Definition at line 124 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

The quadrature rule for the fine element

Definition at line 142 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

Coefficients for projected coarse and projected p-derefined solutions

Definition at line 153 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

Definition at line 154 of file hp_coarsentest.h.

Referenced by select_refinement().

const std::vector<Point>* libMesh::HPCoarsenTest::xyz_values [protected]

Quadrature locations

Definition at line 136 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().


The documentation for this class was generated from the following files:

Site Created By: libMesh Developers
Last modified: February 05 2013 19:55:26 UTC

Hosted By:
SourceForge.net Logo