Trilinos::MPI::Vector and inhomogeneous constraints

50 views
Skip to first unread message

Yiyang Zhang

unread,
Oct 25, 2017, 8:07:46 PM10/25/17
to deal.II User Group
Hello!

I have some general questions about deal.II. I am not sure if what I think is correct. Thank you for your help! 

i) Copy Trilinos::MPI::Vector
Consider using Trilinos to do MPI. Suppose the following vectors:
TrilinosWrappers::MPI::Vector distributed_sln_old (locally_owned_dofs, mpi_communicator), distributed_sln_new (locally_owned_dofs, mpi_communicator);
TrilinosWrappers::MPI::Vector locally_relevant_sln_with_ghost_old (locally_owned_dofs, locally_relevant_dofs, mpi_communicator),
      locally_relevant_sln_with_ghost_new (locally_owned_dofs, locally_relevant_dofs, mpi_communicator); //this is the local vector with ghost.

//Now we have four assignments:
locally_relevant_sln_with_ghost_new = distributed_sln_new; //This is commonly seen in the tutorials. I assume the locally_owned_dofs are copied, and the ghosts are properly updated.
distributed_sln_new = distributed_sln_old; //These two are all local vectors, so it is just a copy operation.
locally_relevant_sln_with_ghost_new = locally_relevant_sln_with_ghost_old; //This and the following one are rarely seen in the tutorials. Does this mean the vector is exactly copied? i.e. both locally_owned_dofs and the ghost_dofs are all copied?
distributed_sln_new = locally_relevant_sln_with_ghost_new; //Does this mean the locally_owned_dofs are copied, while the ghosts are neglected?

ii) ConstraintMatrix::distribute() and Newton's method
In a Newton's method solver, we have:

version A:
//...get the new newton_update vector from solving the equation
constraints.distribute(newton_update);
new_sln = old_sln + alpha* newton_update;

version B:
//...get the new newton_update vector from solving the equation
new_sln = old_sln + alpha* newton_update;
constraints.distribute(new_sln);

In the tutorials it seems version A is more commonly used. However, it seems to me that if there are inhomogeneous constraints, then only version B is correct. Is it right? I don't know how the distribute() function is implemented, but based on the documentation it seems version B is a more logical and universal way.

iii) solve system with inhomogeneous constraints
I have a problem with inhomogeneous constraints. I did some tests and it seems that sometimes the solver collapses due to convergence(?) while sometimes it doesn't, for example depending on the mesh.
May I ask, with inhomogeneous constraints, do I need to, say, choose different preconditioner, or providing the preconditioner with AdditionalData?

Best,
Yiyang

Bruno Turcksin

unread,
Oct 26, 2017, 9:19:57 AM10/26/17
to deal.II User Group
Yiyang,


On Wednesday, October 25, 2017 at 8:07:46 PM UTC-4, Yiyang Zhang wrote:
locally_relevant_sln_with_ghost_new = locally_relevant_sln_with_ghost_old; //This and the following one are rarely seen in the tutorials. Does this mean the vector is exactly copied? i.e. both locally_owned_dofs and the ghost_dofs are all copied?
Yes.
distributed_sln_new = locally_relevant_sln_with_ghost_new; //Does this mean the locally_owned_dofs are copied, while the ghosts are neglected?
That's correct.

ii) ConstraintMatrix::distribute() and Newton's method
In a Newton's method solver, we have:

version A:
//...get the new newton_update vector from solving the equation
constraints.distribute(newton_update);
new_sln = old_sln + alpha* newton_update;

version B:
//...get the new newton_update vector from solving the equation
new_sln = old_sln + alpha* newton_update;
constraints.distribute(new_sln);

In the tutorials it seems version A is more commonly used. However, it seems to me that if there are inhomogeneous constraints, then only version B is correct. Is it right? I don't know how the distribute() function is implemented, but based on the documentation it seems version B is a more logical and universal way.
Version A should work all the time. You impose the inhomogeneous constraints the first time you solve the problem, so now you don't want your newton_update to modify the solution where it is correct. So you impose _homogeneous_ constraints on your update, i.e, you add zero. Does that make sense?

iii) solve system with inhomogeneous constraints
I have a problem with inhomogeneous constraints. I did some tests and it seems that sometimes the solver collapses due to convergence(?) while sometimes it doesn't, for example depending on the mesh.
May I ask, with inhomogeneous constraints, do I need to, say, choose different preconditioner, or providing the preconditioner with AdditionalData?
 The fact that you use inhomogeneous constraints is not a reason on itself to change the preconditioner. However, different meshes may make the problem harder to solve. You may also have a hard time capturing boundary layer. Without knowing anything about your problem it is hard to say why a solver fails.

Best,

Bruno

Yiyang Zhang

unread,
Oct 26, 2017, 11:16:10 AM10/26/17
to deal.II User Group
Hello Bruno, 

Thank you for your quick reply!

ii) ConstraintMatrix::distribute() and Newton's method
In a Newton's method solver, we have:

version A:
//...get the new newton_update vector from solving the equation
constraints.distribute(newton_update);
new_sln = old_sln + alpha* newton_update;

version B:
//...get the new newton_update vector from solving the equation
new_sln = old_sln + alpha* newton_update;
constraints.distribute(new_sln);

In the tutorials it seems version A is more commonly used. However, it seems to me that if there are inhomogeneous constraints, then only version B is correct. Is it right? I don't know how the distribute() function is implemented, but based on the documentation it seems version B is a more logical and universal way.
Version A should work all the time. You impose the inhomogeneous constraints the first time you solve the problem, so now you don't want your newton_update to modify the solution where it is correct. So you impose _homogeneous_ constraints on your update, i.e, you add zero. Does that make sense?

I mean in the constraints objects, I also put the inhomogeneous constraints in, that is:

constraints.add_lines(....)
constraints.add_inhomogeneity(....)

Then, if I use version A, every time I solve the equation, I will add the inhomogeneity to the newton_update. Is it the case?

I assume what you means is putting the inhomogeneity directly into the initial solution, and then in the constraints object, we only have homogeneous constraints. Is this what you mean?

Best,
Yiyang

Wolfgang Bangerth

unread,
Oct 26, 2017, 11:23:43 AM10/26/17
to dea...@googlegroups.com
On 10/26/2017 09:16 AM, Yiyang Zhang wrote:
>
> I mean in the constraints objects, I also put the inhomogeneous
> constraints in, that is:
>
> constraints.add_lines(....)
> constraints.add_inhomogeneity(....)
>
> Then, if I use version A, every time I solve the equation, I will add
> the inhomogeneity to the newton_update. Is it the case?
>
> I assume what you means is putting the inhomogeneity directly into the
> initial solution, and then in the constraints object, we only have
> homogeneous constraints. Is this what you mean?
>

That is the correct way of doing things. step-15 does it that way, for
example.

Best
W.

--
------------------------------------------------------------------------
Wolfgang Bangerth email: bang...@colostate.edu
www: http://www.math.colostate.edu/~bangerth/

Yiyang Zhang

unread,
Oct 26, 2017, 11:50:44 AM10/26/17
to deal.II User Group
Hello Prof. Bangerth,

Thank you for your reply. I am sorry I didn't really follow...

Here are the two ways.
(i) 
set the inhomogeneity in the initial solution vector.
in the constraints object we only need to store homogeneous constraints: 
 
constraints.add_lines(....)

Then in the solve() function we have 
//...get the new newton_update vector from solving the equation
constraints
.distribute(newton_update);
new_sln
= old_sln + alpha* newton_update;


(ii)
do not touch the initial solution vector.
in the constraints object we add inhomogeneous constraints
constraints.add_lines(....)
constraints
.add_inhomogeneity(....)

then in the solve() function we have
//...get the new newton_update vector from solving the equation
new_sln
= old_sln + alpha* newton_update;
constraints
.distribute(new_sln);


It seems to me that both ways are fine.  Is there any particular reason that we prefer one than the other?

Best,
Yiyang

Wolfgang Bangerth

unread,
Oct 26, 2017, 12:00:39 PM10/26/17
to dea...@googlegroups.com
On 10/26/2017 09:50 AM, Yiyang Zhang wrote:
>
> It seems to me that both ways are fine.  Is there any particular reason
> that we prefer one than the other?

Yes, both ways are correct.

But you will need a constraint object to eliminate hanging node
constraints and boundary values from the newton_update equation before
you solve for the newton update, and these constraints need to be
homogeneous.

Since the constraints object you show for your second approach, that
means that you have to keep two constraints objects around. That's more
work, more memory, etc, so people usually prefer approach one.

Yiyang Zhang

unread,
Oct 26, 2017, 1:59:26 PM10/26/17
to deal.II User Group
Hello Prof. Bangerth,

Thank you for the answer! Now things are clear to me.

Best,
Yiyang
Reply all
Reply to author
Forward
0 new messages