← Back to team overview

dolfin team mailing list archive

Re: Periodic BC's

 


Ivo Conradi wrote:
> I'm setting the slave rows to 1, -1. This is very fast. But I'm also
> copying the contents of the slave row to the corresponding master row.
> So in my 512x512 poisson testcase, I have 512 master/slave combinations.
> And in each master row I add (approx) 5 elements from te corresponding
> slave rows. So this means 512x5 set operations and twice as much get()
> operations. It seems that the set() is very slow, probably because
> sparse matrices aren't great for this work.
> 
> I got the compiler to accept a getRow() addition to GenericMatrix, but I
> don't know if this works using PETSc. The sparsity information doesn't
> help a lot in terms of speed though. Probably because the number of
> entries that needs to be inserted in the matrix is about the same.
>

The problem is that it is very expensive to insert new non-zero terms
into the middle of a compressed row matrix since this requires a lot of
data to be shifted. You could try making a copy of the matrix

  ublas_assembly_matrix Atemp(A.size(0), A.size(1));
  Atemp.assign(A);

  // Atemp is now a "vector of compressed vectors" matrix.
  // This matrix is fast the assemble and manipulate

  // Apply periodic boundary conditions to Atemp

  A.assign(Atemp);

The key to this operation is how fast uBlas can convert between
matrices. If this works, we can devise a better solution as DOLFIN
assembles into a ublas_assembly_matrix (which is fast) and then copies
this to a compressed row matrix. We could delay the conversion until
after the application of boundary conditions.

Garth


> Perhaps it's smarter to add the entries to the right row in the first
> place, rather than moving them around. That requires more of a
> programming effort though:)
> 
> Anyway, thanks for your help. 
> 
> regards,
> 
> Ivo 
> 
> On Tue, Nov 14, 2006 at 08:26:23AM +0100, Garth N. Wells wrote:
>> Great that it's working, even if it's not very fast yet.
>>
>> Are you using PETSc (--enable-petsc)? Also, are you manipulating many
>> terms in each row, or just two (adding just -1 and 1)? If you are adding
>> just -1 and 1 at two positions, this should be OK with uBlas. Use
>> ident(..) to zero the row and then add your terms using set(..).
>>
>> getRow() is unlikely to work as it returns a copy of the row, so you
>> won't be able to get your information back into the matrix. It's
>> difficult to get a reference to a row through GenericMatrix as the
>> different linear algebra backends have different data structures.
>>
>> If you need more, I would recommend deriving class from FEM and adding a
>> function to do what you need and use uBlas matrices and vectors rather
>> than Generic*. uBlas matrices are very good for this they are the
>> default if you don't enable PETSc. Make something like
>>
>>   class MyFEM : FEM
>>   {
>>     static void applyPeridocBC(uBlasSparseMatrix& A, uBlasVector& b,
>>             Mesh& mesh, FiniteElement& element, BoundaryCondition& bc);
>>   };
>>
>> With uBlas, you can get the a matrix to return a vector reference to a
>> particular row.
>>
>> Garth
>>
>> Ivo Conradi wrote:
>>> Thanks for the responses. I added some periodicity data to the mesh
>>> object and got the FEM to manipulate the matrix and vector (with
>>> GenericMatrix::get/set) to apply the periodic bc's.  This works, but
>>> unfortunately this is not very fast, because I don't use any sparsity
>>> information. 
>>>
>>> This is why I would like to know if it is possible to add a getRow()
>>> function to GenericMatrix.  As far as I know the derived classes
>>> support it and it would help me speed up things, but I have been unable
>>> to get it working.
>>>
>>> Any comments would be highly appreciated.
>>>
>>> regards,
>>>
>>> Ivo
>>>
>>> On Mon, Nov 13, 2006 at 09:28:07AM +0100, Johan Hoffman wrote:
>>>> You may for example apply your periodic bc by identifying "master and
>>>> slave" dofs on the two (if periodic in one direction) periodic boundaries;
>>>> so that when assembling, all contribution to the slave dofs are added to
>>>> the corresponding master dofs, and the slave dofs are then identified with
>>>> the master dofs (in the simplest way by using 1 and -1 in the rows of the
>>>> slave dofs; maybe not that pretty, but it works in many cases...).
>>> _______________________________________________
>>> DOLFIN-dev mailing list
>>> DOLFIN-dev@xxxxxxxxxx
>>> http://www.fenics.org/mailman/listinfo/dolfin-dev
>>>
> 




References