$extrastylesheet
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 }