The easiest way to do what you want is by using matrix.zero_rows(). The way it
works is that you fill up a vector of dof indices that correspond to rows that
you want to zero and put a 1 on the diagonal. Then you just call
matrix.zero_rows(dofs_to_zero, 1). The second argument to the function is the
number you want to place on the diagonal (zero by default).
So.... fill up your matrix like normal, keeping track of rows you want to wipe
out. Close the matrix. Call zero_rows(). Close the matrix again.
A quick note on this... if you are using Petsc this will modify your nonzero
pattern (ie remove all off-diagonal nonzero entries for these rows). That's
not normally what you want because the next time you come around to fill the
matrix and you do some insertions on that row it will be incredibly slow
(because Petsc will have to reallocate those entries). You can get beyond this
by using something like:
MatSetOption(static_cast<PetscMatrix<Number> &>(my_matrix).mat(),
MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE);
That is the correct line for Petsc 3.1. If you are using a different version
there will most likely be a slightly different way to tell it to keep the
nonzero pattern. I recommend setting this each time before you start filling
the matrix up. Petsc seems to like to forget about this option.....
Derek
On May 10, 2011, at 5:10 PM, Omar Al-Abbasi wrote:
> Thank you all for all the suggestions you made.
> In fact I tried doing two seperate sweeps as Boyce suggested, but it seems
> that I am doing a mistake which leads to no change in mass matrix.
>
> This how I am doing that after the first sweep for assembling the matrices:
> .
> .
> .
> for ( ; el != end_el; ++el)
> {
> const Elem* elem = *el;
> dof_map.dof_indices (elem, dof_indices);
> fe->reinit (elem);
> Ke.resize (dof_indices.size(), dof_indices.size());
> Me.resize (dof_indices.size(), dof_indices.size());
>
> for (unsigned int side=0; side<elem->n_sides(); side++){
> if (elem->neighbor(side) == NULL)
> {
> const std::vector<std::vector<Real> >& phi_face =
> fe_face->get_phi();
> fe_face->reinit(elem, side);
> for (unsigned int i=0; i<phi_face.size(); i++){
> matrix_B.set(dof_indices[i],dof_indices[i],1.);
> } // end if (elem->neighbor(side) == NULL)
> } // end boundary condition section
> }
> }
>
> Also, what is the best way to loop over the nodes which live on the outer
> surface of the domain?
> Is it just the way I am doing it for (unsigned int side=0;
> side<elem->n_sides(); side++){
> if (elem->neighbor(side) == NULL)
> and then for (unsigned int i=0; i<phi_face.size(); i++){ ....
>
> Thanks again,
> Omar
> ------------------------------------------------------------------------------
> Achieve unprecedented app performance and reliability
> What every C/C++ and Fortran developer should know.
> Learn how Intel has extended the reach of its next-generation tools
> to help boost performance applications - inlcuding clusters.
> http://p.sf.net/sfu/intel-dev2devmay
> _______________________________________________
> Libmesh-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/libmesh-users
------------------------------------------------------------------------------
Achieve unprecedented app performance and reliability
What every C/C++ and Fortran developer should know.
Learn how Intel has extended the reach of its next-generation tools
to help boost performance applications - inlcuding clusters.
http://p.sf.net/sfu/intel-dev2devmay
_______________________________________________
Libmesh-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libmesh-users