00001 #include "assemblysystembase.h"
00002 #include <numerics/matrices.h>
00003 void AssemblySystemBase::applyBoundaryValue(MapIntDouble &boundary_values,SparseMatrix<double> &matrix,double factor)
00004 {
00005
00006
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 }
00046 void AssemblySystemBase::applyBoundaryValue(MapIntDouble &boundary_values,VecDouble &right_hand_side,double factor)
00047 {
00048
00049 if (boundary_values.size() == 0)
00050 return;
00051 std::map<unsigned int,double>::const_iterator dof = boundary_values.begin(),
00052 endd = boundary_values.end();
00053 for (; dof != endd; ++dof)
00054 {
00055 right_hand_side(dof->first) = dof->second*factor;
00056 }
00057 }
00058 void AssemblySystemBase::applyBoundaryValue(MapIntDouble &boundary_values,BlockVecDouble &right_hand_side,double factor)
00059 {
00060 if (boundary_values.size() == 0)
00061 return;
00062 std::map<unsigned int,double>::const_iterator dof = boundary_values.begin(),
00063 endd = boundary_values.end();
00064 for (; dof != endd; ++dof)
00065 {
00066 right_hand_side(dof->first) = dof->second*factor;
00067 }
00068
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 void AssemblySystemBase::applySymetricBoundaryValue(MapIntDouble &boundary_values,SparseMatrix<double> &matrix, VecDouble &right_hand_side)
00080 {
00081
00082
00083
00084 assert (matrix.get_sparsity_pattern().optimize_diagonal());
00085 assert (matrix.n() == right_hand_side.size());
00086
00087
00088 if (boundary_values.size() == 0)
00089 return;
00090
00091
00092 const unsigned int n_dofs = matrix.m();
00093
00094
00095
00096
00097
00098
00099
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
00120
00121
00122
00123
00124
00125
00126
00127
00128
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
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
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
00163
00164
00165 const double diagonal_entry = matrix.diag_element(dof_number);
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 for (unsigned int j=sparsity_rowstart[dof_number]+1; j<last; ++j)
00184 {
00185 const unsigned int row = sparsity_colnums[j];
00186
00187
00188
00189
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
00196
00197
00198
00199
00200
00201
00202
00203
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
00212 right_hand_side(row) -= matrix.global_entry(global_entry) /
00213 diagonal_entry * new_rhs;
00214
00215
00216 matrix.global_entry(global_entry) = 0.;
00217 };
00218
00219 };
00220
00221 }
00222
00223
00224 void AssemblySystemBase::applySymetricBoundaryValue(MapIntDouble &boundary_values,BlockMatrix &matrix, BlockVecDouble &sol,BlockVecDouble &right_hand_side)
00225 {
00226 MatrixTools::apply_boundary_values(boundary_values,matrix,sol,right_hand_side,true);
00227 }
00228
00229