triangulation.signals.post_refinement :connection of a member function

36 views
Skip to first unread message

Simon

unread,
Jul 5, 2021, 4:56:49 PM7/5/21
to deal.II User Group

Dear all,

I am trying to modify my program in a way such that certain quantities are only updated if the underlying triangulation object changes during runtime (due to adaptivity). I want to call a specific member function of my Main Class 'Solid' if this happens. (Solid is the class which calls the typical functions like make_grid(), system_setup(),...)
The Triangulation<dim,spacedim> class offers a interface to the boost::signals2 library. I guess that is predestinated for my purpose.

Here is a snippet of my code:

//constructor of 'Solid'
:
dof_handler(triangulation),
/*many_more*/
qf_cell(degree+1),
n_q_points(qf_cell.size())
{
pointer_M = boost::make_shared<AnotherClass<dim>>(/*constructor of
                                                             AnotherClass */);
boost::signals2::connection tria_signal =
triangulation.signals.post_refinement.connect( boost::signals2::signal<void()>::slot_type(&AnotherClass<dim>::mark_for_update,  pointer_M .get()).track( pointer_M ) );
}

So the constructor of Solid initializes "pointer_M" which points to an object of "AnotherClass". The variable "tria_signal" in the line below is the one which causes the call of the member function &AnotherClass<dim>::mark_for_update.
The above code compiles and actually calls mark_for_update  from AnotherClass<dim> .

But what I'd like to achieve is that the signal triggers a member function of 'Solid', i.e. something like &Solid<dim>::call_this_function. So a naive approach is to simply replace &AnotherClass<dim>::mark_for_update  by &Solid<dim>::call_this_function . (Both functions take no parameters and return void).
Unfortunately this change produces two error messages.
(i) error: pointer to member type ‘void (Solid<2>::)()’ incompatible with object type ‘AnotherClass<2>’
(ii) error: return-statement with a value, in function returning 'void' [-fpermissive]

My understanding of the error message is that only member functions of 'AnotherClass' can be connected to the signal.
Is this true?
And can I modify the parameters of the connect function somehow to actually connect a member function of Solid?

As always, any input is appreciated! :-)

Best
Simon

      

Wolfgang Bangerth

unread,
Jul 5, 2021, 11:20:49 PM7/5/21
to dea...@googlegroups.com
On 7/5/21 2:56 PM, Simon wrote:
>
> So the constructor of Solid initializes "pointer_M" which points to an object
> of "AnotherClass". The variable "tria_signal" in the line below is the one
> which causes the call of the member function
> &*AnotherClass<dim>::mark_for_update.
> *
> The above code compiles and actually calls *mark_for_update*  from
> *AnotherClass<dim>* .
>
> But what I'd like to achieve is that the signal triggers a member function of
> 'Solid', i.e. something like &*Solid<dim>::call_this_function. *So a naive
> approach is to simply replace &*AnotherClass<dim>::mark_for_update*  by
> &*Solid<dim>::call_this_function* . (Both functions take no parameters and
> return void).
> Unfortunately this change produces two error messages.
> (i) error: pointer to member type ‘void (Solid<2>::)()’ incompatible with
> object type ‘AnotherClass<2>’
> (ii) error: return-statement with a value, in function returning 'void'
> [-fpermissive]
>
> My understanding of the error message is that only member functions of
> 'AnotherClass' can be connected to the signal.
> Is this true?
> And can I modify the parameters of the connect function somehow to actually
> connect a member function of Solid?

No, but you need to provide a 'this' pointer for the object you want to work
on. In the first case, this is pointer_M.get(). For a member function of the
current object, it would probably be 'this'.

Best
W.


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

Simon Wiesheier

unread,
Jul 6, 2021, 4:45:22 AM7/6/21
to dea...@googlegroups.com
Thank you very much! With that hint it works as expected.
Is it also possible to get a reference (pointer) to the Solid object within the constructor of 'AnotherClass', so without passing a solid reference to the latters constructor? 'this' would in this case refer to the instance of 'AnotherClass'.

The class 'AnotherClass' needs access to objects of type DoFHandler<dim> and CellDataStorage<typename T>. As for the DoFHandler<dim> the copy instructor, i.e something like 'dof_handler(dof_handler_from_solid)' will delete 'dof_handler_from_solid'. It actually doesn't delete it but throws an exception as it is also described in the documentation.
I checked a few source code files of the library how they manage the storage of large objects, for instance the GridTools::Cache<dim> class stores a triangulation like this:
SmartPointer<const Triangulation<dim>>      tria;
So I did this in the same way for the DoFHandler and the CellDataStorage object:
SmartPointer<const DoFHandler<dim>>         dof_handler;
...
Is this a efficient way to do that or is there a more sophisticated way to store the member variables? I asked myself why dealii did not just use the SmartPointers of the c++ standard library, namely std::shared_ptr<...>, std::unique_ptr<...>,....  I guess most of them also make sure that they don't become dangling pointers.

Thanks again!



--
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/bd80797b-029d-a63e-1124-52a69237bab5%40colostate.edu.

Wolfgang Bangerth

unread,
Jul 7, 2021, 12:35:52 AM7/7/21
to dea...@googlegroups.com
On 7/6/21 2:45 AM, Simon Wiesheier wrote:
>
> Is it also possible to get a reference (pointer) to the Solid object within
> the constructor of 'AnotherClass', so without passing a solid reference to the
> latters constructor? 'this' would in this case refer to the instance of
> 'AnotherClass'.
>
> The class 'AnotherClass' needs access to objects of type DoFHandler<dim> and
> CellDataStorage<typename T>. As for the DoFHandler<dim> the copy instructor,
> i.e something like 'dof_handler(dof_handler_from_solid)' will delete
> 'dof_handler_from_solid'. It actually doesn't delete it but throws an
> exception as it is also described in the documentation.
> I checked a few source code files of the library how they manage the storage
> of large objects, for instance the GridTools::Cache<dim> class stores a
> triangulation like this:
> SmartPointer<const Triangulation<dim>>      tria;
> So I did this in the same way for the DoFHandler and the CellDataStorage object:
> SmartPointer<const DoFHandler<dim>>         dof_handler;
> ...
> Is this a efficient way to do that or is there a more sophisticated way to
> store the member variables? I asked myself why dealii did not just use the
> SmartPointers of the c++ standard library, namely std::shared_ptr<...>,
> std::unique_ptr<...>,....  I guess most of them also make sure that they don't
> become dangling pointers.

All of this is possible with minimal pain by using "lambda functions" and
"captured variables". You might want to read up on them in a recent C++ book :-)

Cheers

Simon Wiesheier

unread,
Jul 7, 2021, 11:06:56 AM7/7/21
to dea...@googlegroups.com
I will look that up :-)

Just one last question:
In the constructed a class I store a DoFHandler and Triangulation object as member variables like this:
SmartPointer<const DoFHandler<dim>> dof_handler;
SmartPointer<const Triangulation<dim>> triangulation;

I created the instance at the same time when constructing the Solid instance (pM = boost::make_shared<.......>)
After a few loadsteps my solid triangulation changes and the DoFHandler as well (standard adaptivity).
The instance of the other class where I stored the just mentioned SmartPointers is "aware" of that, i.e. I don't update the SmartPointers after adaptivity.
Of course the (smart)pointer stores the address of the triangulation, but is it not possible that the the call "triangulation.execute_refinement()" makes the triangulation object too big so that it has to be reallocated at another adress (->address changes)?
So is that what I observe something like undefined behaviour or do calls like "dof_handler.distribute_dofs(fe)" or "triangulation.execute_refinement()" indeed don't change the address of the underlying triangulation (dof_handler) in memory?

Thank you very much again!



--
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.

Wolfgang Bangerth

unread,
Aug 2, 2021, 7:23:14 PM8/2/21
to dea...@googlegroups.com
On 7/7/21 9:06 AM, Simon Wiesheier wrote:
> Of course the (smart)pointer stores the address of the triangulation, but is
> it not possible that the the call "triangulation.execute_refinement()" makes
> the triangulation object too big so that it has to be reallocated at another
> adress (->address changes)?

This is not how C++ works. An object has an address, and that address never
changes as long as the object lives.

But that object can internally contain pointers to store information, and if
it requires more memory, then the object can change that pointer. But the
address of the object itself remains the same.


> So is that what I observe something like undefined behaviour or do calls like
> "dof_handler.distribute_dofs(fe)" or "triangulation.execute_refinement()"
> indeed don't change the address of the underlying triangulation (dof_handler)
> in memory?

Correct. They don't change.

Best
Reply all
Reply to author
Forward
0 new messages