⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jump_error_estimator.c

📁 一个用来实现偏微分方程中网格的计算库
💻 C
📖 第 1 页 / 共 2 页
字号:
// $Id: jump_error_estimator.C 2868 2008-06-16 17:00:33Z benkirk $// The libMesh Finite Element Library.// Copyright (C) 2002-2007  Benjamin S. Kirk, John W. Peterson  // This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version.  // This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU// Lesser General Public License for more details.  // You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA// C++ includes#include <algorithm> // for std::fill#include <cmath>    // for sqrt// Local Includes#include "libmesh_common.h"#include "jump_error_estimator.h"#include "dof_map.h"#include "error_vector.h"#include "fe.h"#include "fe_interface.h"#include "quadrature_gauss.h"#include "libmesh_logging.h"#include "elem.h"#include "mesh.h"#include "system.h"#include "dense_vector.h"//-----------------------------------------------------------------// JumpErrorEstimator implementationsvoid JumpErrorEstimator::initialize (const System&,				     ErrorVector&,				     bool){}void JumpErrorEstimator::estimate_error (const System& system,					 ErrorVector& error_per_cell,					 bool estimate_parent_error){  START_LOG("estimate_error()", "JumpErrorEstimator");  /*  Conventions for assigning the direction of the normal:    - e & f are global element ids    Case (1.) Elements are at the same level, e<f            Compute the flux jump on the face and	    add it as a contribution to error_per_cell[e]	    and error_per_cell[f]                     ----------------------		  |           |          |		  |           |    f     |		  |           |          |		  |    e      |---> n    | 		  |           |          |		  |           |          |                   ----------------------   Case (2.) The neighbor is at a higher level.             Compute the flux jump on e's face and	     add it as a contribution to error_per_cell[e]	     and error_per_cell[f]                   ----------------------		  |     |     |          |		  |     |  e  |---> n    |		  |     |     |          |		  |-----------|    f     | 		  |     |     |          |		  |     |     |          |		  |     |     |          |                   ----------------------  */     // The current mesh  const MeshBase& mesh = system.get_mesh();  // The dimensionality of the mesh  const unsigned int dim = mesh.mesh_dimension();    // The number of variables in the system  const unsigned int n_vars = system.n_vars();    // The DofMap for this system  const DofMap& dof_map = system.get_dof_map();  // Resize the error_per_cell vector to be  // the number of elements, initialize it to 0.  error_per_cell.resize (mesh.max_elem_id());  std::fill (error_per_cell.begin(), error_per_cell.end(), 0.);  // Declare a vector of floats which is as long as  // error_per_cell above, and fill with zeros.  This vector will be  // used to keep track of the number of edges (faces) on each active  // element which are either:  // 1) an internal edge  // 2) an edge on a Neumann boundary for which a boundary condition  //    function has been specified.  // The error estimator can be scaled by the number of flux edges (faces)  // which the element actually has to obtain a more uniform measure  // of the error.  Use floats instead of ints since in case 2 (above)  // f gets 1/2 of a flux face contribution from each of his  // neighbors  std::vector<float> n_flux_faces (error_per_cell.size());    // Check for the use of component_mask  this->convert_component_mask_to_scale();  // Check for a valid component_scale  if (!component_scale.empty())    {      if (component_scale.size() != n_vars)	{	  std::cerr << "ERROR: component_scale is the wrong size:"		    << std::endl		    << " component_scale.scale()=" << component_scale.size()		    << std::endl		    << " n_vars=" << n_vars		    << std::endl;	  libmesh_error();	}    }  else    {      // No specified scaling.  Scale all variables by one.      component_scale.resize (n_vars);      std::fill (component_scale.begin(), component_scale.end(), 1.0);    }    // Loop over all the variables in the system  for (var=0; var<n_vars; var++)    {      // Possibly skip this variable      if (!component_scale.empty())	if (component_scale[var] == 0.0) continue;      // The type of finite element to use for this variable      const FEType& fe_type = dof_map.variable_type (var);            // Finite element objects for the same face from      // different sides      fe_fine = FEBase::build (dim, fe_type);      fe_coarse = FEBase::build (dim, fe_type);      // Build an appropriate Gaussian quadrature rule      QGauss qrule (dim-1, fe_type.default_quadrature_order());      // Tell the finite element for the fine element about the quadrature      // rule.  The finite element for the coarse element need not know about it      fe_fine->attach_quadrature_rule (&qrule);            // By convention we will always do the integration      // on the face of element e.  We'll need its Jacobian values and      // physical point locations, at least      fe_fine->get_JxW();      fe_fine->get_xyz();      // Our derived classes may want to do some initialization here      this->initialize(system, error_per_cell, estimate_parent_error);            // The global DOF indices for elements e & f      std::vector<unsigned int> dof_indices_fine;      std::vector<unsigned int> dof_indices_coarse;            // Iterate over all the active elements in the mesh      // that live on this processor.      MeshBase::const_element_iterator       elem_it  = mesh.active_local_elements_begin();      const MeshBase::const_element_iterator elem_end = mesh.active_local_elements_end();       for (; elem_it != elem_end; ++elem_it)	{	  // e is necessarily an active element on the local processor	  const Elem* e = *elem_it;	  const unsigned int e_id = e->id();#ifdef ENABLE_AMR          // See if the parent of element e has been examined yet;          // if not, we may want to compute the estimator on it          const Elem* parent = e->parent();          // We only can compute and only need to compute on          // parents with all active children          bool compute_on_parent = true;          if (!parent || !estimate_parent_error)            compute_on_parent = false;          else            for (unsigned int c=0; c != parent->n_children(); ++c)              if (!parent->child(c)->active())                compute_on_parent = false;                       if (compute_on_parent &&              !error_per_cell[parent->id()])	    {              // Compute a projection onto the parent              DenseVector<Number> Uparent;              FEBase::coarsened_dof_values(*(system.solution),                                           dof_map, parent, Uparent,                                           var, false);	      // Loop over the neighbors of the parent	      for (unsigned int n_p=0; n_p<parent->n_neighbors(); n_p++)                {	          if (parent->neighbor(n_p) != NULL) // parent has a neighbor here		    {                      // Find the active neighbors in this direction                      std::vector<const Elem*> active_neighbors;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -