$extrastylesheet
dg_fem_context.C
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 #include "libmesh/dg_fem_context.h"
00019 #include "libmesh/dof_map.h"
00020 #include "libmesh/elem.h"
00021 #include "libmesh/fe_base.h"
00022 #include "libmesh/fe_interface.h"
00023 #include "libmesh/quadrature.h"
00024 #include "libmesh/system.h"
00025 
00026 namespace libMesh
00027 {
00028 
00029 DGFEMContext::DGFEMContext (const System &sys)
00030   : FEMContext(sys),
00031     _neighbor(NULL),
00032     _neighbor_dof_indices_var(sys.n_vars()),
00033     _dg_terms_active(false)
00034 {
00035   libmesh_experimental();
00036 
00037   unsigned int nv = sys.n_vars();
00038   libmesh_assert (nv);
00039 
00040   _neighbor_subresiduals.reserve(nv);
00041   _elem_elem_subjacobians.resize(nv);
00042   _elem_neighbor_subjacobians.resize(nv);
00043   _neighbor_elem_subjacobians.resize(nv);
00044   _neighbor_neighbor_subjacobians.resize(nv);
00045 
00046   for (unsigned int i=0; i != nv; ++i)
00047     {
00048       _neighbor_subresiduals.push_back(new DenseSubVector<Number>(_neighbor_residual));
00049       _elem_elem_subjacobians[i].reserve(nv);
00050       _elem_neighbor_subjacobians[i].reserve(nv);
00051       _neighbor_elem_subjacobians[i].reserve(nv);
00052       _neighbor_neighbor_subjacobians[i].reserve(nv);
00053 
00054       for (unsigned int j=0; j != nv; ++j)
00055         {
00056           _elem_elem_subjacobians[i].push_back
00057             (new DenseSubMatrix<Number>(_elem_elem_jacobian));
00058           _elem_neighbor_subjacobians[i].push_back
00059             (new DenseSubMatrix<Number>(_elem_neighbor_jacobian));
00060           _neighbor_elem_subjacobians[i].push_back
00061             (new DenseSubMatrix<Number>(_neighbor_elem_jacobian));
00062           _neighbor_neighbor_subjacobians[i].push_back
00063             (new DenseSubMatrix<Number>(_neighbor_neighbor_jacobian));
00064         }
00065     }
00066 
00067   _neighbor_side_fe_var.resize(nv);
00068   for (unsigned int i=0; i != nv; ++i)
00069     {
00070       FEType fe_type = sys.variable_type(i);
00071 
00072       if ( _neighbor_side_fe[fe_type] == NULL )
00073         {
00074           _neighbor_side_fe[fe_type] = FEAbstract::build(this->_dim, fe_type).release();
00075         }
00076       _neighbor_side_fe_var[i] = _neighbor_side_fe[fe_type];
00077     }
00078 }
00079 
00080 DGFEMContext::~DGFEMContext()
00081 {
00082 
00083   for (std::size_t i=0; i != _neighbor_subresiduals.size(); ++i)
00084     {
00085       delete _neighbor_subresiduals[i];
00086 
00087       for (std::size_t j=0; j != _elem_elem_subjacobians[i].size(); ++j)
00088         {
00089           delete _elem_elem_subjacobians[i][j];
00090           delete _elem_neighbor_subjacobians[i][j];
00091           delete _neighbor_elem_subjacobians[i][j];
00092           delete _neighbor_neighbor_subjacobians[i][j];
00093         }
00094     }
00095 
00096   // Delete the FE objects
00097   for (std::map<FEType, FEAbstract *>::iterator i = _neighbor_side_fe.begin();
00098        i != _neighbor_side_fe.end(); ++i)
00099     delete i->second;
00100   _neighbor_side_fe.clear();
00101 }
00102 
00103 void DGFEMContext::side_fe_reinit()
00104 {
00105   FEMContext::side_fe_reinit();
00106 
00107   // By default we assume that the DG terms are inactive
00108   // They are only active if neighbor_side_fe_reinit is called
00109   _dg_terms_active = false;
00110 }
00111 
00112 void DGFEMContext::neighbor_side_fe_reinit ()
00113 {
00114   // Call this *after* side_fe_reinit
00115 
00116   // Initialize all the neighbor side FE objects based on inverse mapping
00117   // the quadrature points on the current side
00118   std::vector<Point> qface_side_points;
00119   std::vector<Point> qface_neighbor_points;
00120   std::map<FEType, FEAbstract *>::iterator local_fe_end = _neighbor_side_fe.end();
00121   for (std::map<FEType, FEAbstract *>::iterator i = _neighbor_side_fe.begin();
00122        i != local_fe_end; ++i)
00123     {
00124       FEType neighbor_side_fe_type = i->first;
00125       FEAbstract* side_fe = _side_fe[this->get_dim()][neighbor_side_fe_type];
00126       qface_side_points = side_fe->get_xyz();
00127 
00128       FEInterface::inverse_map (this->get_dim(),
00129                                 neighbor_side_fe_type,
00130                                 &get_neighbor(),
00131                                 qface_side_points,
00132                                 qface_neighbor_points);
00133 
00134       i->second->reinit(&get_neighbor(), &qface_neighbor_points);
00135     }
00136 
00137   // Set boolean flag to indicate that the DG terms are active on this element
00138   _dg_terms_active = true;
00139 
00140   // Also, initialize data required for DG assembly on the current side,
00141   // analogously to FEMContext::pre_fe_reinit
00142 
00143   // Initialize the per-element data for elem.
00144   get_system().get_dof_map().dof_indices (&get_neighbor(), _neighbor_dof_indices);
00145 
00146   const unsigned int n_dofs = cast_int<unsigned int>
00147     (this->get_dof_indices().size());
00148   const unsigned int n_neighbor_dofs = cast_int<unsigned int>
00149     (_neighbor_dof_indices.size());
00150 
00151   // These resize calls also zero out the residual and jacobian
00152   _neighbor_residual.resize(n_neighbor_dofs);
00153   _elem_elem_jacobian.resize(n_dofs, n_dofs);
00154   _elem_neighbor_jacobian.resize(n_dofs, n_neighbor_dofs);
00155   _neighbor_elem_jacobian.resize(n_neighbor_dofs, n_dofs);
00156   _neighbor_neighbor_jacobian.resize(n_neighbor_dofs, n_neighbor_dofs);
00157 
00158   // Initialize the per-variable data for elem.
00159   {
00160     unsigned int sub_dofs = 0;
00161     for (unsigned int i=0; i != get_system().n_vars(); ++i)
00162       {
00163         get_system().get_dof_map().dof_indices (&get_neighbor(), _neighbor_dof_indices_var[i], i);
00164 
00165         const unsigned int n_dofs_var = cast_int<unsigned int>
00166           (_neighbor_dof_indices_var[i].size());
00167 
00168         _neighbor_subresiduals[i]->reposition
00169           (sub_dofs, n_dofs_var);
00170 
00171         for (unsigned int j=0; j != i; ++j)
00172           {
00173             const unsigned int n_dofs_var_j =
00174               cast_int<unsigned int>
00175               (this->get_dof_indices(j).size());
00176 
00177             _elem_elem_subjacobians[i][j]->reposition
00178               (sub_dofs, _neighbor_subresiduals[j]->i_off(),
00179                n_dofs_var, n_dofs_var_j);
00180             _elem_elem_subjacobians[j][i]->reposition
00181               (_neighbor_subresiduals[j]->i_off(), sub_dofs,
00182                n_dofs_var_j, n_dofs_var);
00183 
00184             _elem_neighbor_subjacobians[i][j]->reposition
00185               (sub_dofs, _neighbor_subresiduals[j]->i_off(),
00186                n_dofs_var, n_dofs_var_j);
00187             _elem_neighbor_subjacobians[j][i]->reposition
00188               (_neighbor_subresiduals[j]->i_off(), sub_dofs,
00189                n_dofs_var_j, n_dofs_var);
00190 
00191             _neighbor_elem_subjacobians[i][j]->reposition
00192               (sub_dofs, _neighbor_subresiduals[j]->i_off(),
00193                n_dofs_var, n_dofs_var_j);
00194             _neighbor_elem_subjacobians[j][i]->reposition
00195               (_neighbor_subresiduals[j]->i_off(), sub_dofs,
00196                n_dofs_var_j, n_dofs_var);
00197 
00198             _neighbor_neighbor_subjacobians[i][j]->reposition
00199               (sub_dofs, _neighbor_subresiduals[j]->i_off(),
00200                n_dofs_var, n_dofs_var_j);
00201             _neighbor_neighbor_subjacobians[j][i]->reposition
00202               (_neighbor_subresiduals[j]->i_off(), sub_dofs,
00203                n_dofs_var_j, n_dofs_var);
00204           }
00205         _elem_elem_subjacobians[i][i]->reposition
00206           (sub_dofs, sub_dofs,
00207            n_dofs_var,
00208            n_dofs_var);
00209         _elem_neighbor_subjacobians[i][i]->reposition
00210           (sub_dofs, sub_dofs,
00211            n_dofs_var,
00212            n_dofs_var);
00213         _neighbor_elem_subjacobians[i][i]->reposition
00214           (sub_dofs, sub_dofs,
00215            n_dofs_var,
00216            n_dofs_var);
00217         _neighbor_neighbor_subjacobians[i][i]->reposition
00218           (sub_dofs, sub_dofs,
00219            n_dofs_var,
00220            n_dofs_var);
00221         sub_dofs += n_dofs_var;
00222       }
00223     libmesh_assert_equal_to (sub_dofs, n_dofs);
00224   }
00225 
00226 }
00227 
00228 }