librelist archives

« back to archive

Fwd: dynamic data in p4est quadrant user data?

Fwd: dynamic data in p4est quadrant user data?

From:
Ethan Hereth
Date:
2014-08-27 @ 23:00
Hey folks,

I am using p4est in a C++ project. Today I tried to insert a
std::list<int> object into the p4est quadrant p.user_data. This code
compiled fine but I was unable to actually push_back any data to the
std::list; the executable would seg fault. I think the problem stems
from the fact this data is alloc/malloc'd instead of new'd?

So then, I tried using a std::list<int> pointer instead and new'ing it
in the quadrant initialization callback. This does work, or at least
is seems to so far, in that I can push_back to the std::list. The
problem comes when it is time to delete the new'd memory. I tried to
delete the memory with the following loop but I still have memory
leaks.

  for (p4est_topidx_t jt = p4est->first_local_tree; jt <=
p4est->last_local_tree; ++jt) {
    p4est_tree_t * tree = p4est_tree_array_index (p4est->trees, jt);
    sc_array_t * quadrants = &tree->quadrants;
    for (size_t zz = 0; zz < quadrants->elem_count; ++zz) {
      p4est_quadrant_t * q = p4est_quadrant_array_index (quadrants, zz);
      p4estQuadData_t * data = (p4estQuadData_t *) q->p.user_data;
      delete data->boundaryTags; /* <== This is the std::list I'm
trying to manage */
    }
  }

Using this approach the code seems to run in serial but will seg fault
if run in parallel. I suspect that this loop might be missing
quadrants somehow, maybe quadrants that were initialized earlier and
then became ancestors to quadrants created later?

I think I can come up with another way to do what I'm trying to do but
now I'm curious; am I just doing something really stupid or is this
even possible? If this is possible, what is the best way to go about
doing it?

Please bear in mind that I'm not a formally educated computer
scientist so it IS entirely possible that I'm just doing something
really stupid!

Thank you for your patience,

Ethan Alan Hereth
Research Associate

SimCenter: National Center for Computational Engineering
701 East M.L. King Boulevard
Chattanooga, TN 37411

423.425.5431
ethan-hereth@utc.edu
www.utc.edu/simcenter

Re: [p4est] Fwd: dynamic data in p4est quadrant user data?

From:
Tobin Isaac
Date:
2014-08-28 @ 02:18
Hi Ethan,

On August 27, 2014 6:00:01 PM CDT, Ethan Hereth 
<advocateddrummer@gmail.com> wrote:
>Hey folks,
>
>I am using p4est in a C++ project. Today I tried to insert a
>std::list<int> object into the p4est quadrant p.user_data. This code
>compiled fine but I was unable to actually push_back any data to the
>std::list; the executable would seg fault. I think the problem stems
>from the fact this data is alloc/malloc'd instead of new'd?

I can't know for sure without seeing your code, but it sounds like you set
user_data to point to a list that was only declared at the start of a 
function scope, not alloc'd or new'd. That reference becomes invalid at 
the end of the scope.

>
>So then, I tried using a std::list<int> pointer instead and new'ing it
>in the quadrant initialization callback. This does work, or at least
>is seems to so far, in that I can push_back to the std::list. The
>problem comes when it is time to delete the new'd memory. I tried to
>delete the memory with the following loop but I still have memory
>leaks.

The problem is probably that lists that were new'd for intermediate 
octants were not deleted.   A solution would be to use the _ext interface 
functions (p8est_refine_ext(), etc.), which take as an argument a 
p8est_replace_t callback function that allows you to transfer information 
from outgoing octants to incoming octants before the outgoing octants are 
destroyed.  You can delete the outgoing lists in this callback.

>
>  for (p4est_topidx_t jt = p4est->first_local_tree; jt <=
>p4est->last_local_tree; ++jt) {
>    p4est_tree_t * tree = p4est_tree_array_index (p4est->trees, jt);
>    sc_array_t * quadrants = &tree->quadrants;
>    for (size_t zz = 0; zz < quadrants->elem_count; ++zz) {
>     p4est_quadrant_t * q = p4est_quadrant_array_index (quadrants, zz);
>      p4estQuadData_t * data = (p4estQuadData_t *) q->p.user_data;
>      delete data->boundaryTags; /* <== This is the std::list I'm
>trying to manage */
>    }
>  }
>
>Using this approach the code seems to run in serial but will seg fault
>if run in parallel. I suspect that this loop might be missing
>quadrants somehow, maybe quadrants that were initialized earlier and
>then became ancestors to quadrants created later?

Are you repartitioning after adapting the mesh? If so, the list pointers 
become invalid after repartitioning because you are new'ing your own data 
instead of using p4est's internal, fixed size data management.

If you can fit your data into a struct of fixed size by, e.g., using a 
fixed array instead of a list, then by using p4est's internal data 
management you can transfer the data automatically.  There is currently no
p4est function that transfers variable-length octant data when 
repartitioning.

Cheers,
  Toby
>
>I think I can come up with another way to do what I'm trying to do but
>now I'm curious; am I just doing something really stupid or is this
>even possible? If this is possible, what is the best way to go about
>doing it?
>
>Please bear in mind that I'm not a formally educated computer
>scientist so it IS entirely possible that I'm just doing something
>really stupid!
>
>Thank you for your patience,
>
>Ethan Alan Hereth
>Research Associate
>
>SimCenter: National Center for Computational Engineering
>701 East M.L. King Boulevard
>Chattanooga, TN 37411
>
>423.425.5431
>ethan-hereth@utc.edu
>www.utc.edu/simcenter

Re: [p4est] Fwd: dynamic data in p4est quadrant user data?

From:
Ethan Hereth
Date:
2014-08-28 @ 13:19
On Wed, Aug 27, 2014 at 10:18 PM, Tobin Isaac <tisaac@ices.utexas.edu> wrote:
> Hi Ethan,
>
> On August 27, 2014 6:00:01 PM CDT, Ethan Hereth 
<advocateddrummer@gmail.com> wrote:
>>Hey folks,
>>
>>I am using p4est in a C++ project. Today I tried to insert a
>>std::list<int> object into the p4est quadrant p.user_data. This code
>>compiled fine but I was unable to actually push_back any data to the
>>std::list; the executable would seg fault. I think the problem stems
>>from the fact this data is alloc/malloc'd instead of new'd?
>
> I can't know for sure without seeing your code, but it sounds like you 
set user_data to point to a list that was only declared at the start of a 
function scope, not alloc'd or new'd. That reference becomes invalid at 
the end of the scope.

While that does sound like something I'm likely to do, this time the
problem is something else. My issue comes from the fact that the
struct is not new'd and thus the std::list is not properly
initialized. In case you're interested, the following bit of code will
demonstrate this:

#include <stdlib.h>
#include <iostream>
#include <list>

typedef struct hiho {
  int a;
  double b;
  std::list<int> list;
} hiho_t;

int main(int argc, char *argv[])
{
  std::cout << "Hello World..." << std::endl;

  hiho_t a;

  std::cout << "****************************************" << std::endl;
  std::cout << "Normal..." << std::endl;
  a.a = 1;
  a.b = 42.0;
  a.list.push_back(1);
  a.list.push_back(2);
  a.list.push_back(3);
  a.list.push_back(4);

  std::cout << "a.a: " << a.a << std::endl;
  std::cout << "a.b: " << a.b << std::endl;

  std::cout << "a.list:";
  for (std::list<int>::iterator it=a.list.begin(); it != a.list.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << std::endl;

  hiho_t * b = (hiho_t *) malloc(sizeof(hiho_t));

  std::cout << "****************************************" << std::endl;
  std::cout << "Malloc..." << std::endl;
  b->a = 1;
  b->b = 42.0;
  b->list.push_back(1);
  b->list.push_back(2);
  b->list.push_back(3);
  b->list.push_back(4);

  std::cout << "b->a: " << b->a << std::endl;
  std::cout << "b->b: " << b->b << std::endl;

  std::cout << "b.list:";
  for (std::list<int>::iterator it=b->list.begin(); it != b->list.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << std::endl;

  free(b);

  hiho_t * c = new hiho_t;

  std::cout << "****************************************" << std::endl;
  std::cout << "New..." << std::endl;
  c->a = 1;
  c->b = 42.0;
  c->list.push_back(1);
  c->list.push_back(2);
  c->list.push_back(3);
  c->list.push_back(4);

  std::cout << "c->a: " << c->a << std::endl;
  std::cout << "c->b: " << c->b << std::endl;

  std::cout << "c.list:";
  for (std::list<int>::iterator it=c->list.begin(); it != c->list.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << std::endl;

  delete c;

  return 0;
}

This code will segfault at b->list.push_back(1) as b's memory was
malloc'd, not new'd. Comment out the hiho_t *b section and the code
works normally. This will probably not surprise you but it caught me
off guard.

>>
>>So then, I tried using a std::list<int> pointer instead and new'ing it
>>in the quadrant initialization callback. This does work, or at least
>>is seems to so far, in that I can push_back to the std::list. The
>>problem comes when it is time to delete the new'd memory. I tried to
>>delete the memory with the following loop but I still have memory
>>leaks.
>
> The problem is probably that lists that were new'd for intermediate 
octants were not deleted.   A solution would be to use the _ext interface 
functions (p8est_refine_ext(), etc.), which take as an argument a 
p8est_replace_t callback function that allows you to transfer information 
from outgoing octants to incoming octants before the outgoing octants are 
destroyed.  You can delete the outgoing lists in this callback.
>
>>
>>  for (p4est_topidx_t jt = p4est->first_local_tree; jt <=
>>p4est->last_local_tree; ++jt) {
>>    p4est_tree_t * tree = p4est_tree_array_index (p4est->trees, jt);
>>    sc_array_t * quadrants = &tree->quadrants;
>>    for (size_t zz = 0; zz < quadrants->elem_count; ++zz) {
>>     p4est_quadrant_t * q = p4est_quadrant_array_index (quadrants, zz);
>>      p4estQuadData_t * data = (p4estQuadData_t *) q->p.user_data;
>>      delete data->boundaryTags; /* <== This is the std::list I'm
>>trying to manage */
>>    }
>>  }
>>
>>Using this approach the code seems to run in serial but will seg fault
>>if run in parallel. I suspect that this loop might be missing
>>quadrants somehow, maybe quadrants that were initialized earlier and
>>then became ancestors to quadrants created later?
>
> Are you repartitioning after adapting the mesh? If so, the list pointers
become invalid after repartitioning because you are new'ing your own data 
instead of using p4est's internal, fixed size data management.
>
> If you can fit your data into a struct of fixed size by, e.g., using a 
fixed array instead of a list, then by using p4est's internal data 
management you can transfer the data automatically.  There is currently no
p4est function that transfers variable-length octant data when 
repartitioning.

I was afraid of that. for now I think I can use a constant sized
array, even though it's not the most general solution. I can probably
externalize the memory if I really need it to be dynamic but for now I
don't think it will be a problem.

Thanks for your help,

Ethan Alan
>
> Cheers,
>   Toby
>>
>>I think I can come up with another way to do what I'm trying to do but
>>now I'm curious; am I just doing something really stupid or is this
>>even possible? If this is possible, what is the best way to go about
>>doing it?
>>
>>Please bear in mind that I'm not a formally educated computer
>>scientist so it IS entirely possible that I'm just doing something
>>really stupid!
>>
>>Thank you for your patience,
>>
>>Ethan Alan Hereth
>>Research Associate
>>
>>SimCenter: National Center for Computational Engineering
>>701 East M.L. King Boulevard
>>Chattanooga, TN 37411
>>
>>423.425.5431
>>ethan-hereth@utc.edu
>>www.utc.edu/simcenter
>

Re: [p4est] Fwd: dynamic data in p4est quadrant user data?

From:
Tobin Isaac
Date:
2014-08-28 @ 14:06
On Thu, Aug 28, 2014 at 09:19:06AM -0400, Ethan Hereth wrote:
> On Wed, Aug 27, 2014 at 10:18 PM, Tobin Isaac <tisaac@ices.utexas.edu> wrote:
> > Hi Ethan,
> >
> > On August 27, 2014 6:00:01 PM CDT, Ethan Hereth 
<advocateddrummer@gmail.com> wrote:
> >>Hey folks,
> >>
> >>I am using p4est in a C++ project. Today I tried to insert a
> >>std::list<int> object into the p4est quadrant p.user_data. This code
> >>compiled fine but I was unable to actually push_back any data to the
> >>std::list; the executable would seg fault. I think the problem stems
> >>from the fact this data is alloc/malloc'd instead of new'd?
> >
> > I can't know for sure without seeing your code, but it sounds like you
set user_data to point to a list that was only declared at the start of a 
function scope, not alloc'd or new'd. That reference becomes invalid at 
the end of the scope.
> 
> While that does sound like something I'm likely to do, this time the
> problem is something else. My issue comes from the fact that the
> struct is not new'd and thus the std::list is not properly
> initialized. In case you're interested, the following bit of code will
> demonstrate this:
> 
> #include <stdlib.h>
> #include <iostream>
> #include <list>
> 
> typedef struct hiho {
>   int a;
>   double b;
>   std::list<int> list;
> } hiho_t;
> 
> int main(int argc, char *argv[])
> {
>   std::cout << "Hello World..." << std::endl;
> 
>   hiho_t a;
> 
>   std::cout << "****************************************" << std::endl;
>   std::cout << "Normal..." << std::endl;
>   a.a = 1;
>   a.b = 42.0;
>   a.list.push_back(1);
>   a.list.push_back(2);
>   a.list.push_back(3);
>   a.list.push_back(4);
> 
>   std::cout << "a.a: " << a.a << std::endl;
>   std::cout << "a.b: " << a.b << std::endl;
> 
>   std::cout << "a.list:";
>   for (std::list<int>::iterator it=a.list.begin(); it != a.list.end(); ++it)
>     std::cout << ' ' << *it;
>   std::cout << std::endl;
> 
>   hiho_t * b = (hiho_t *) malloc(sizeof(hiho_t));
> 
>   std::cout << "****************************************" << std::endl;
>   std::cout << "Malloc..." << std::endl;
>   b->a = 1;
>   b->b = 42.0;
>   b->list.push_back(1);
>   b->list.push_back(2);
>   b->list.push_back(3);
>   b->list.push_back(4);
> 
>   std::cout << "b->a: " << b->a << std::endl;
>   std::cout << "b->b: " << b->b << std::endl;
> 
>   std::cout << "b.list:";
>   for (std::list<int>::iterator it=b->list.begin(); it != b->list.end(); ++it)
>     std::cout << ' ' << *it;
>   std::cout << std::endl;
> 
>   free(b);
> 
>   hiho_t * c = new hiho_t;
> 
>   std::cout << "****************************************" << std::endl;
>   std::cout << "New..." << std::endl;
>   c->a = 1;
>   c->b = 42.0;
>   c->list.push_back(1);
>   c->list.push_back(2);
>   c->list.push_back(3);
>   c->list.push_back(4);
> 
>   std::cout << "c->a: " << c->a << std::endl;
>   std::cout << "c->b: " << c->b << std::endl;
> 
>   std::cout << "c.list:";
>   for (std::list<int>::iterator it=c->list.begin(); it != c->list.end(); ++it)
>     std::cout << ' ' << *it;
>   std::cout << std::endl;
> 
>   delete c;
> 
>   return 0;
> }
> 
> This code will segfault at b->list.push_back(1) as b's memory was
> malloc'd, not new'd. Comment out the hiho_t *b section and the code
> works normally. This will probably not surprise you but it caught me
> off guard.
> 
> >>
> >>So then, I tried using a std::list<int> pointer instead and new'ing it
> >>in the quadrant initialization callback. This does work, or at least
> >>is seems to so far, in that I can push_back to the std::list. The
> >>problem comes when it is time to delete the new'd memory. I tried to
> >>delete the memory with the following loop but I still have memory
> >>leaks.
> >
> > The problem is probably that lists that were new'd for intermediate 
octants were not deleted.   A solution would be to use the _ext interface 
functions (p8est_refine_ext(), etc.), which take as an argument a 
p8est_replace_t callback function that allows you to transfer information 
from outgoing octants to incoming octants before the outgoing octants are 
destroyed.  You can delete the outgoing lists in this callback.
> >
> >>
> >>  for (p4est_topidx_t jt = p4est->first_local_tree; jt <=
> >>p4est->last_local_tree; ++jt) {
> >>    p4est_tree_t * tree = p4est_tree_array_index (p4est->trees, jt);
> >>    sc_array_t * quadrants = &tree->quadrants;
> >>    for (size_t zz = 0; zz < quadrants->elem_count; ++zz) {
> >>     p4est_quadrant_t * q = p4est_quadrant_array_index (quadrants, zz);
> >>      p4estQuadData_t * data = (p4estQuadData_t *) q->p.user_data;
> >>      delete data->boundaryTags; /* <== This is the std::list I'm
> >>trying to manage */
> >>    }
> >>  }
> >>
> >>Using this approach the code seems to run in serial but will seg fault
> >>if run in parallel. I suspect that this loop might be missing
> >>quadrants somehow, maybe quadrants that were initialized earlier and
> >>then became ancestors to quadrants created later?
> >
> > Are you repartitioning after adapting the mesh? If so, the list 
pointers become invalid after repartitioning because you are new'ing your 
own data instead of using p4est's internal, fixed size data management.
> >
> > If you can fit your data into a struct of fixed size by, e.g., using a
fixed array instead of a list, then by using p4est's internal data 
management you can transfer the data automatically.  There is currently no
p4est function that transfers variable-length octant data when 
repartitioning.
> 
> I was afraid of that. for now I think I can use a constant sized
> array, even though it's not the most general solution. I can probably
> externalize the memory if I really need it to be dynamic but for now I
> don't think it will be a problem.

Here is how I would handle the transfer of variable-length octant
data.

1) Serialize the variable-length data from every octant into one send
buffer.

2) Add fields to your octant data struct that describe where the
octant's serialized data is: the MPI rank, the byte offset, and the
byte count.

3) Repartition as before.

4) Use the serialization description of the received octants to set up
receive buffers and communicate.

5) Deserialize.

> 
> Thanks for your help,
> 
> Ethan Alan
> >
> > Cheers,
> >   Toby
> >>
> >>I think I can come up with another way to do what I'm trying to do but
> >>now I'm curious; am I just doing something really stupid or is this
> >>even possible? If this is possible, what is the best way to go about
> >>doing it?
> >>
> >>Please bear in mind that I'm not a formally educated computer
> >>scientist so it IS entirely possible that I'm just doing something
> >>really stupid!
> >>
> >>Thank you for your patience,
> >>
> >>Ethan Alan Hereth
> >>Research Associate
> >>
> >>SimCenter: National Center for Computational Engineering
> >>701 East M.L. King Boulevard
> >>Chattanooga, TN 37411
> >>
> >>423.425.5431
> >>ethan-hereth@utc.edu
> >>www.utc.edu/simcenter
> >
> 

Re: [p4est] Fwd: dynamic data in p4est quadrant user data?

From:
Ethan Hereth
Date:
2014-08-28 @ 14:29
On Thu, Aug 28, 2014 at 10:06 AM, Tobin Isaac <tisaac@ices.utexas.edu> wrote:
> On Thu, Aug 28, 2014 at 09:19:06AM -0400, Ethan Hereth wrote:
>> On Wed, Aug 27, 2014 at 10:18 PM, Tobin Isaac <tisaac@ices.utexas.edu> wrote:
>> > Hi Ethan,
>> >
>> > On August 27, 2014 6:00:01 PM CDT, Ethan Hereth 
<advocateddrummer@gmail.com> wrote:
>> >>Hey folks,
>> >>
>> >>I am using p4est in a C++ project. Today I tried to insert a
>> >>std::list<int> object into the p4est quadrant p.user_data. This code
>> >>compiled fine but I was unable to actually push_back any data to the
>> >>std::list; the executable would seg fault. I think the problem stems
>> >>from the fact this data is alloc/malloc'd instead of new'd?
>> >
>> > I can't know for sure without seeing your code, but it sounds like 
you set user_data to point to a list that was only declared at the start 
of a function scope, not alloc'd or new'd. That reference becomes invalid 
at the end of the scope.
>>
>> While that does sound like something I'm likely to do, this time the
>> problem is something else. My issue comes from the fact that the
>> struct is not new'd and thus the std::list is not properly
>> initialized. In case you're interested, the following bit of code will
>> demonstrate this:
>>
>> #include <stdlib.h>
>> #include <iostream>
>> #include <list>
>>
>> typedef struct hiho {
>>   int a;
>>   double b;
>>   std::list<int> list;
>> } hiho_t;
>>
>> int main(int argc, char *argv[])
>> {
>>   std::cout << "Hello World..." << std::endl;
>>
>>   hiho_t a;
>>
>>   std::cout << "****************************************" << std::endl;
>>   std::cout << "Normal..." << std::endl;
>>   a.a = 1;
>>   a.b = 42.0;
>>   a.list.push_back(1);
>>   a.list.push_back(2);
>>   a.list.push_back(3);
>>   a.list.push_back(4);
>>
>>   std::cout << "a.a: " << a.a << std::endl;
>>   std::cout << "a.b: " << a.b << std::endl;
>>
>>   std::cout << "a.list:";
>>   for (std::list<int>::iterator it=a.list.begin(); it != a.list.end(); ++it)
>>     std::cout << ' ' << *it;
>>   std::cout << std::endl;
>>
>>   hiho_t * b = (hiho_t *) malloc(sizeof(hiho_t));
>>
>>   std::cout << "****************************************" << std::endl;
>>   std::cout << "Malloc..." << std::endl;
>>   b->a = 1;
>>   b->b = 42.0;
>>   b->list.push_back(1);
>>   b->list.push_back(2);
>>   b->list.push_back(3);
>>   b->list.push_back(4);
>>
>>   std::cout << "b->a: " << b->a << std::endl;
>>   std::cout << "b->b: " << b->b << std::endl;
>>
>>   std::cout << "b.list:";
>>   for (std::list<int>::iterator it=b->list.begin(); it != b->list.end(); ++it)
>>     std::cout << ' ' << *it;
>>   std::cout << std::endl;
>>
>>   free(b);
>>
>>   hiho_t * c = new hiho_t;
>>
>>   std::cout << "****************************************" << std::endl;
>>   std::cout << "New..." << std::endl;
>>   c->a = 1;
>>   c->b = 42.0;
>>   c->list.push_back(1);
>>   c->list.push_back(2);
>>   c->list.push_back(3);
>>   c->list.push_back(4);
>>
>>   std::cout << "c->a: " << c->a << std::endl;
>>   std::cout << "c->b: " << c->b << std::endl;
>>
>>   std::cout << "c.list:";
>>   for (std::list<int>::iterator it=c->list.begin(); it != c->list.end(); ++it)
>>     std::cout << ' ' << *it;
>>   std::cout << std::endl;
>>
>>   delete c;
>>
>>   return 0;
>> }
>>
>> This code will segfault at b->list.push_back(1) as b's memory was
>> malloc'd, not new'd. Comment out the hiho_t *b section and the code
>> works normally. This will probably not surprise you but it caught me
>> off guard.
>>
>> >>
>> >>So then, I tried using a std::list<int> pointer instead and new'ing it
>> >>in the quadrant initialization callback. This does work, or at least
>> >>is seems to so far, in that I can push_back to the std::list. The
>> >>problem comes when it is time to delete the new'd memory. I tried to
>> >>delete the memory with the following loop but I still have memory
>> >>leaks.
>> >
>> > The problem is probably that lists that were new'd for intermediate 
octants were not deleted.   A solution would be to use the _ext interface 
functions (p8est_refine_ext(), etc.), which take as an argument a 
p8est_replace_t callback function that allows you to transfer information 
from outgoing octants to incoming octants before the outgoing octants are 
destroyed.  You can delete the outgoing lists in this callback.
>> >
>> >>
>> >>  for (p4est_topidx_t jt = p4est->first_local_tree; jt <=
>> >>p4est->last_local_tree; ++jt) {
>> >>    p4est_tree_t * tree = p4est_tree_array_index (p4est->trees, jt);
>> >>    sc_array_t * quadrants = &tree->quadrants;
>> >>    for (size_t zz = 0; zz < quadrants->elem_count; ++zz) {
>> >>     p4est_quadrant_t * q = p4est_quadrant_array_index (quadrants, zz);
>> >>      p4estQuadData_t * data = (p4estQuadData_t *) q->p.user_data;
>> >>      delete data->boundaryTags; /* <== This is the std::list I'm
>> >>trying to manage */
>> >>    }
>> >>  }
>> >>
>> >>Using this approach the code seems to run in serial but will seg fault
>> >>if run in parallel. I suspect that this loop might be missing
>> >>quadrants somehow, maybe quadrants that were initialized earlier and
>> >>then became ancestors to quadrants created later?
>> >
>> > Are you repartitioning after adapting the mesh? If so, the list 
pointers become invalid after repartitioning because you are new'ing your 
own data instead of using p4est's internal, fixed size data management.
>> >
>> > If you can fit your data into a struct of fixed size by, e.g., using 
a fixed array instead of a list, then by using p4est's internal data 
management you can transfer the data automatically.  There is currently no
p4est function that transfers variable-length octant data when 
repartitioning.
>>
>> I was afraid of that. for now I think I can use a constant sized
>> array, even though it's not the most general solution. I can probably
>> externalize the memory if I really need it to be dynamic but for now I
>> don't think it will be a problem.
>
> Here is how I would handle the transfer of variable-length octant
> data.
>
> 1) Serialize the variable-length data from every octant into one send
> buffer.
>
> 2) Add fields to your octant data struct that describe where the
> octant's serialized data is: the MPI rank, the byte offset, and the
> byte count.
>
> 3) Repartition as before.
>
> 4) Use the serialization description of the received octants to set up
> receive buffers and communicate.
>
> 5) Deserialize.
>

Thank you for that suggestion. For now I am going to just live with a
fixed size array but I'll keep that in mind if I decide I really must
have variable length data.

>>
>> Thanks for your help,
>>
>> Ethan Alan
>> >
>> > Cheers,
>> >   Toby
>> >>
>> >>I think I can come up with another way to do what I'm trying to do but
>> >>now I'm curious; am I just doing something really stupid or is this
>> >>even possible? If this is possible, what is the best way to go about
>> >>doing it?
>> >>
>> >>Please bear in mind that I'm not a formally educated computer
>> >>scientist so it IS entirely possible that I'm just doing something
>> >>really stupid!
>> >>
>> >>Thank you for your patience,
>> >>
>> >>Ethan Alan Hereth
>> >>Research Associate
>> >>
>> >>SimCenter: National Center for Computational Engineering
>> >>701 East M.L. King Boulevard
>> >>Chattanooga, TN 37411
>> >>
>> >>423.425.5431
>> >>ethan-hereth@utc.edu
>> >>www.utc.edu/simcenter
>> >
>>