Vector conversion problem: between dealii::PETScWrappers::MPI::Vector and a PETSc Vec

26 views
Skip to first unread message

Zhidong Brian Zhang

unread,
Dec 4, 2019, 11:42:45 AM12/4/19
to deal.II User Group
Dear, deal.ii colleagues,

A vector conversion problem has been troubled me for a long time.

It is the conversion between between dealii::PETScWrappers::MPI::Vector and a PETSc Vec.

I have some functions written based on PETSc directly. So that I would like to use them directly in deal.ii. However, I need to convert vectors between dealii's MPI vectors to PETSc's generic vectors.

Here is an simplified example:
Vec a;  // PETSc vector
VecDuplicate(x, &a);  // x is a dealii::PETScWrappers::MPI Vector generated previously
VecCopy(x, a);  
dealii
::PETScWrappers::MPI::Vector b(a);   // dealii MPI vector

I try to construct a dealii vector named with "b" based on PETSc Vector named "a". This should be OK in my opinion based on the constructor that is VectorBase (const Vec &v) in the deal.ii's document:
https://www.dealii.org/current/doxygen/deal.II/classPETScWrappers_1_1VectorBase.html#a08f6d7c4850e085271c225c5c19d7502


In addition, dealii::PETScWrappers::MPI::Vector is inherited from VectorBase, so the constructor VectorBase (const Vec &v) should be able to be called by dealii::PETScWrappers::MPI::Vector as well.

However, the error reported is:
no matching function for call to dealii::PETScWrappers::MPI::Vector::Vector(_p_Vec*&)


So may I get some information about this vector conversion problem?
Thank you very much in advance!

Zhidong Brian Zhang


BTW, I found some info in the following forum but it is related to Mat conversion between deal.ii and PETSc:

David Wells

unread,
Dec 4, 2019, 1:16:23 PM12/4/19
to deal.II User Group
Hi Zhidong,

In C++ constructors are not inherited, so this function call won't
work: it's not possible to create a PETScWrappers::MPI::Vector from a
Vec object directly.

I think that you can solve your problem by just using VectorBase: you
can create objects of this type directly that wrap around a Vec and
don't destroy it when they go out of scope. Would this work for you?

One alternative would be to always create PETScWrappers::MPI::Vector
objects (instead of ever explicitly creating a Vec) and then using the
conversion operator (part of VectorBase) to get the Vec out when you
need it.

Thanks,
David
> --
> The deal.II project is located at http://www.dealii.org/
> For mailing list/forum options, see https://groups.google.com/d/forum/dealii?hl=en
> ---
> You received this message because you are subscribed to the Google Groups "deal.II User Group" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to dealii+un...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/dealii/b013a870-32bd-4d91-884d-1b3fc2eff9a3%40googlegroups.com.

Zhidong Brian Zhang

unread,
Dec 4, 2019, 7:13:41 PM12/4/19
to deal.II User Group
Dear, David,


Thank you so much for your timely response! That is so helpful.

In C++ constructors are not inherited, so this function call won't
work: it's not possible to create a PETScWrappers::MPI::Vector from a
Vec object directly.
OK, now I understand. I thought PETScWrappers::MPI::Vector can construct VectorBase automatically.


I think that you can solve your problem by just using VectorBase: you
can create objects of this type directly that wrap around a Vec and
don't destroy it when they go out of scope. Would this work for you?
Yes, you are right, I can use VectorBase to wrap the PETSc Vec.


One alternative would be to always create PETScWrappers::MPI::Vector
objects (instead of ever explicitly creating a Vec) and then using the
conversion operator (part of VectorBase) to get the Vec out when you
need it.
Up to now, I always create PETScWrappers::MPI::Vector. And use "operator const Vec & () const" to get PETSc generic vector out:
Vec a; // PETSc generic vector
a
= x; // x is a PETScWrappers::MPI::Vector generated previously


In sum, I prefer to go with the second method. My basic reason is that I need to generate MPI vector by PETScWrappers::MPI::Vector. The simpilified workflow of my program is as follows,
1. I need build the parallel vector through PETScWrappers::MPI::Vector.
2. PETSc Vec is derived from PETScWrappers::MPI::Vector and is imported into my own functions (written based on PETSc).
3. My functions output updated PETSc Vec.
4. I update PETScWrappers::MPI::Vector based on the updated PETSc Vec.

The pesudo code is as follows,
Vec a;
a = x;

a = myfunctions(a); // my functions (written based on PETSc)

dealii::PETScWrappers::VectorBase b(a); // generate VectorBase from PETSc Vec
dealii::PETScWrappers::MPI::Vector c(opt->mpi_communicator, b, opt->locally_owned_cells.size()); // generate
PETScWrappers::MPI::Vector from VectorBase
x = c; // update the PETScWrappers::MPI::Vector that was generated previously


May I ask 2 further questions:
1. The function has been deprecated according to deal.ii official document: dealii::PETScWrappers::MPI::Vector c(opt->mpi_communicator, b, opt->locally_owned_cells.size()). I can run it successfully, but is there a walkaround of this because I don't want to use a deprecated function.

2. What is the basic idea behind creating the two classes: dealii::PETScWrappers::MPI::Vector and VectorBase? I mean why not only one (I am a newbie, sorry, no offense)? For my understanding is VectorBase is a wrapper of PETSc Vec and dealii::PETScWrappers::MPI::Vector is a wrapper of VectorBase.


Thank you so much for your guidance and help in advance!


Zhidong Brian Zhang
> To unsubscribe from this group and stop receiving emails from it, send an email to dea...@googlegroups.com.

David Wells

unread,
Dec 7, 2019, 5:50:05 PM12/7/19
to deal.II User Group
Hi Zhidong,

I am happy to help!

Unfortunately, this is a part of deal.II that has some older code that
has accumulated some inconsistencies over time. Both inconsistencies
stem from there, previously, being a third class PETScWrappers::Vector
which was a sequential PETSc vector: both PETScWrappers::Vector and
PETScWrappers::MPI::Vector inherited from PETScWrappers::VectorBase.
Here VectorBase contained most of the functionality that didn't use or
need MPI objects.

1. I don't think that there is a workaround - the problem with that
function is that one could pass in a serial PETSc vector which doesn't
make any sense. Its not quite equivalent, but the closest replacement
is to just create a MPI::Vector and then extract the Vec rather than
creating a Vec and then putting it in an MPI::Vector.
2. This is, mostly, a consequence of the historical design I mentioned
above: the end result is confusing because we have not completely
converted this class. Your understanding is correct except that
MPI::Vector is always a wrapper of VectorBase *where the Vec is a
parallel-distributed vector*.

Does this make sense?

Thanks,
David

Zhidong Brian Zhang

unread,
Dec 10, 2019, 1:33:40 PM12/10/19
to deal.II User Group
It makes much sense!

Right now, it works by using the deprecated function (generating MPI::Vector from VectorBase).

The program can run successfully, while I now need to work on improve the efficiency (Maybe I need to rewrite all my previous code).

Thank you so much for your help, David!

Zhidong Brian Zhang
Reply all
Reply to author
Forward
0 new messages