#include <assemblysystembase.h>
Public Member Functions | |
AssemblySystemBase () | |
~AssemblySystemBase () | |
Static Public Member Functions | |
static void | applyBoundaryValue (MapIntDouble &boundary_values, SparseMatrix< double > &matrix, double factor=1.0) |
static void | applyBoundaryValue (MapIntDouble &boundary_values, VecDouble &right_hand_side, double factor=1.0) |
static void | applyBoundaryValue (MapIntDouble &boundary_values, BlockVecDouble &right_hand_side, double factor=1.0) |
static void | applySymetricBoundaryValue (MapIntDouble &boundary_values, SparseMatrix< double > &matrix, VecDouble &right_hand_side) |
static void | applySymetricBoundaryValue (MapIntDouble &boundary_values, BlockMatrix &matrix, BlockVecDouble &sol, BlockVecDouble &right_hand_side) |
Basic class to assembly the finite element matrix
Definition at line 19 of file assemblysystembase.h.
AssemblySystemBase::AssemblySystemBase | ( | ) | [inline] |
Definition at line 26 of file assemblysystembase.h.
AssemblySystemBase::~AssemblySystemBase | ( | ) | [inline] |
Definition at line 27 of file assemblysystembase.h.
void AssemblySystemBase::applyBoundaryValue | ( | MapIntDouble & | boundary_values, | |
BlockVecDouble & | right_hand_side, | |||
double | factor = 1.0 | |||
) | [static] |
Definition at line 58 of file assemblysystembase.cpp.
void AssemblySystemBase::applyBoundaryValue | ( | MapIntDouble & | boundary_values, | |
VecDouble & | right_hand_side, | |||
double | factor = 1.0 | |||
) | [static] |
Definition at line 46 of file assemblysystembase.cpp.
void AssemblySystemBase::applyBoundaryValue | ( | MapIntDouble & | boundary_values, | |
SparseMatrix< double > & | matrix, | |||
double | factor = 1.0 | |||
) | [static] |
Definition at line 3 of file assemblysystembase.cpp.
00004 { 00005 // Require that diagonals are first 00006 // in each row 00007 00008 if (matrix.get_sparsity_pattern().optimize_diagonal()) 00009 { 00010 if (boundary_values.size() == 0) 00011 return; 00012 00013 00014 std::map<unsigned int,double>::const_iterator dof = boundary_values.begin(), 00015 endd = boundary_values.end(); 00016 const SparsityPattern &sparsity = matrix.get_sparsity_pattern(); 00017 const unsigned int *sparsity_rowstart = (const unsigned int*) sparsity.get_rowstart_indices(); 00018 for (; dof != endd; ++dof) 00019 { 00020 Assert (dof->first < matrix.m(), ExcInternalError()); 00021 const unsigned int dof_number = dof->first; 00022 const unsigned int last = sparsity_rowstart[dof_number+1]; 00023 for (unsigned int j=sparsity_rowstart[dof_number]+1; j<last; ++j) 00024 matrix.global_entry(j) = 0.; 00025 00026 matrix.set (dof_number, dof_number,factor); 00027 } 00028 } 00029 else 00030 { 00031 std::map<unsigned int,double>::const_iterator dof = boundary_values.begin(), 00032 endd = boundary_values.end(); 00033 for (; dof != endd; ++dof) 00034 { 00035 SparseMatrix<double>::iterator it = matrix.begin(dof->first); 00036 SparseMatrix<double>::iterator itend = matrix.end(dof->first); 00037 for (;it!=itend;it++) 00038 { 00039 it->value()=0.0; 00040 } 00041 if (factor != 0.0) matrix.set (dof->first,dof->first, factor); 00042 } 00043 00044 } 00045 }
void AssemblySystemBase::applySymetricBoundaryValue | ( | MapIntDouble & | boundary_values, | |
BlockMatrix & | matrix, | |||
BlockVecDouble & | sol, | |||
BlockVecDouble & | right_hand_side | |||
) | [static] |
Definition at line 224 of file assemblysystembase.cpp.
void AssemblySystemBase::applySymetricBoundaryValue | ( | MapIntDouble & | boundary_values, | |
SparseMatrix< double > & | matrix, | |||
VecDouble & | right_hand_side | |||
) | [static] |
Definition at line 79 of file assemblysystembase.cpp.
00080 { 00081 00082 // Require that diagonals are first 00083 // in each row 00084 assert (matrix.get_sparsity_pattern().optimize_diagonal()); 00085 assert (matrix.n() == right_hand_side.size()); 00086 // if no boundary values are to be applied 00087 // simply return 00088 if (boundary_values.size() == 0) 00089 return; 00090 00091 00092 const unsigned int n_dofs = matrix.m(); 00093 00094 // if a diagonal entry is zero 00095 // later, then we use another 00096 // number instead. take it to be 00097 // the first nonzero diagonal 00098 // element of the matrix, or 1 if 00099 // there is no such thing 00100 double first_nonzero_diagonal_entry = 1; 00101 for (unsigned int i=0; i<n_dofs; ++i) 00102 if (matrix.diag_element(i) != 0) 00103 { 00104 first_nonzero_diagonal_entry = matrix.diag_element(i); 00105 break; 00106 }; 00107 00108 00109 std::map<unsigned int,double>::const_iterator dof = boundary_values.begin(), 00110 endd = boundary_values.end(); 00111 const SparsityPattern &sparsity = matrix.get_sparsity_pattern(); 00112 const unsigned int *sparsity_rowstart = (const unsigned int*) (sparsity.get_rowstart_indices()); 00113 const unsigned int *sparsity_colnums = (const unsigned int*) (sparsity.get_column_numbers()); 00114 for (; dof != endd; ++dof) 00115 { 00116 Assert (dof->first < n_dofs, ExcInternalError()); 00117 00118 const unsigned int dof_number = dof->first; 00119 // for each boundary dof: 00120 00121 // set entries of this line 00122 // to zero except for the diagonal 00123 // entry. Note that the diagonal 00124 // entry is always the first one 00125 // for square matrices, i.e. 00126 // we shall not set 00127 // matrix.global_entry( 00128 // sparsity_rowstart[dof.first]) 00129 const unsigned int last = sparsity_rowstart[dof_number+1]; 00130 for (unsigned int j=sparsity_rowstart[dof_number]+1; j<last; ++j) 00131 matrix.global_entry(j) = 0.; 00132 00133 00134 // set right hand side to 00135 // wanted value: if main diagonal 00136 // entry nonzero, don't touch it 00137 // and scale rhs accordingly. If 00138 // zero, take the first main 00139 // diagonal entry we can find, or 00140 // one if no nonzero main diagonal 00141 // element exists. Normally, however, 00142 // the main diagonal entry should 00143 // not be zero. 00144 // 00145 // store the new rhs entry to make 00146 // the gauss step more efficient 00147 double new_rhs; 00148 if (matrix.diag_element(dof_number) != 0.0) 00149 { 00150 new_rhs = dof->second * matrix.diag_element(dof_number); 00151 right_hand_side(dof_number) = new_rhs; 00152 } 00153 else 00154 { 00155 matrix.set (dof_number, dof_number, 00156 first_nonzero_diagonal_entry); 00157 new_rhs = dof->second * first_nonzero_diagonal_entry; 00158 right_hand_side(dof_number) = new_rhs; 00159 } 00160 00161 00162 // store the only nonzero entry 00163 // of this line for the Gauss 00164 // elimination step 00165 const double diagonal_entry = matrix.diag_element(dof_number); 00166 00167 // we have to loop over all 00168 // rows of the matrix which 00169 // have a nonzero entry in 00170 // the column which we work 00171 // in presently. if the 00172 // sparsity pattern is 00173 // symmetric, then we can 00174 // get the positions of 00175 // these rows cheaply by 00176 // looking at the nonzero 00177 // column numbers of the 00178 // present row. we need not 00179 // look at the first entry, 00180 // since that is the 00181 // diagonal element and 00182 // thus the present row 00183 for (unsigned int j=sparsity_rowstart[dof_number]+1; j<last; ++j) 00184 { 00185 const unsigned int row = sparsity_colnums[j]; 00186 00187 // find the position of 00188 // element 00189 // (row,dof_number) 00190 const unsigned int * 00191 p = std::lower_bound(&sparsity_colnums[sparsity_rowstart[row]+1], 00192 &sparsity_colnums[sparsity_rowstart[row+1]], 00193 dof_number); 00194 00195 // check whether this line has 00196 // an entry in the regarding column 00197 // (check for ==dof_number and 00198 // != next_row, since if 00199 // row==dof_number-1, *p is a 00200 // past-the-end pointer but points 00201 // to dof_number anyway...) 00202 // 00203 // there should be such an entry! 00204 Assert ((*p == dof_number) && 00205 (p != &sparsity_colnums[sparsity_rowstart[row+1]]), 00206 ExcInternalError()); 00207 00208 const unsigned int global_entry 00209 = (p - &sparsity_colnums[sparsity_rowstart[0]]); 00210 00211 // correct right hand side 00212 right_hand_side(row) -= matrix.global_entry(global_entry) / 00213 diagonal_entry * new_rhs; 00214 00215 // set matrix entry to zero 00216 matrix.global_entry(global_entry) = 0.; 00217 }; 00218 00219 }; 00220 00221 }