sample data along a line in parallel

299 views
Skip to first unread message

Jack

unread,
Oct 9, 2018, 11:23:41 PM10/9/18
to basilisk-fr
Hi all,

I am a new learner of basilisk. recently I test a simple cavity flow case and sample the data along the central line when I run the code with single processor it goes well, however, in parallel the output data on the location of sample point is almost the HUGE. 

Can someone help me with solving this issue, or suggest any other way to  sample data along line in parallel? Thanks for the assistance.

Thanks very much,
Jack

My simplest code:
#include "grid/multigrid.h"
#include "navier-stokes/centered.h"

int main()
  origin (-0.5, -0.5);
  init_grid (64);
  const face vector muc[] = {1e-3,1e-3};
  mu = muc;
  DT = 0.1;
  CFL = 0.8;
  run();
}
u.t[top] = dirichlet(1);
u.t[bottom] = dirichlet(0);
u.t[left]   = dirichlet(0);
u.t[right]  = dirichlet(0);
u.n[top]    = dirichlet(0);
u.n[bottom] = dirichlet(0);
u.n[left]   = dirichlet(0);
u.n[right]  = dirichlet(0);

scalar un[];
event logfile (t += 0.1; i <= 10000) {
  double du = change (u.x, un);
  if (i > 0 && du < 1e-5)
    return 1; /* stop */
  fprintf (stderr, "%f %d %g\n", t, i, du);
}
event profiles (t = end)
{
  FILE *fp = fopen("uxProf", "w");
  for (double y = -0.5; y <= 0.5; y += 0.01)
    fprintf (fp, "%f\t%g\n", y, interpolate (u.x, 0, y));
  fprintf(fp,"\n");
  fclose (fp);
}
the strange uxProf file is:
0.390000 1e+30
0.400000 1e+30
0.410000 1e+30
0.420000 1e+30
0.430000 1e+30
0.440000 1e+30
0.450000 1e+30
0.460000 1e+30
0.470000 1e+30
0.480000 1e+30
0.490000 1e+30

7195
0.410000 0.425915
0.420000 0.435508
0.430000 0.445963
0.440000 0.464578
0.450000 0.493845
0.460000 0.535187
0.470000 0.615063
0.480000 0.716679
0.490000 0.852193

80000 1e+30
0.490000 1e+30



uxProf

Antoon van Hooft

unread,
Oct 10, 2018, 7:24:17 AM10/10/18
to basilisk-fr
Hallo Jack,

I am guessing you are using MPI for parallel computations:
There is little documentation on how to diagnose stuff and write it to a file when using MPI.

It may help if you read about MPI and the most easy-to-find online tutorials are all excellent.
For now, it is important to understand that with MPI, each thread runs your executable in a similar fashion and that the computational load is divided in basilisk by a domain decomposition.

this means that:
1) Only one thread can perform a interpolation on a given location and others will return "nodata" which is a macro for "HUGE" that is in turn is a macro for "1e30".
2) Only one thread should write a file. (although there are other options if you take proper care)
3) The threads for (1) and (2) are typically not the same.

You can learn how the existing basilisk output functions, that work with MPI, tackle these additional concerns:

Antoon

Jack

unread,
Oct 12, 2018, 12:48:56 AM10/12/18
to basilisk-fr
Thanks for your advice, I will learn the MPI in basilisk and try to realize a tool function.  And I think I can use the dump file every time step to sample data by the post-progress function. 

在 2018年10月10日星期三 UTC+8下午7:24:17,Antoon van Hooft写道:

Stephane Popinet

unread,
Oct 12, 2018, 2:01:57 AM10/12/18
to basil...@googlegroups.com
Hi Jack,

You could use:

void interpolate_array (scalar * list, coord * a, int n, double * v,
bool linear);

instead of interpolate().

interpolate_array() works in parallel.

cheers,

Stephane

Jack

unread,
Oct 14, 2018, 12:31:45 PM10/14/18
to basilisk-fr
Hi Stephane,
 
Thanks for your advice, I have added the interpolate_array function in my test code as follows. It goes well but the sampled data is also not well. And form the output file, I can find there is not only one processor output data.  And I don't know if I used this function in a wrong way ? 
event profiles (t = end)
{
  scalar * vname={u.x};
  int n =0;
  float start_p=-0.5;
  float end_p=0.5;
  float delta_p=0.01;

  n=fabs(end_p-start_p)/delta_p;
  coord a[n];

  for (int i = 0; i < n; i++){
    double y = start_p + i * delta_p;
    a[i].x=0;
    a[i].y=y;  
    a[i].z=0;
  }
  int len_l=list_len(vname);
  double v[n*len_l];
  interpolate_array(vname, a, n, v, false);
  
  FILE *fp = fopen("uyProf", "w");
 // for (double y = -0.5; y <= 0.5; y += 0.01)
 for ( int i = 0; i<n; i++)
    fprintf (fp, "%f\t%g\n", a[i].y, v[i]);
  fprintf(fp,"\n");
  fclose (fp);
}



在 2018年10月12日星期五 UTC+8下午2:01:57,Stephane Popinet写道:

Antoon van Hooft

unread,
Oct 19, 2018, 10:22:33 AM10/19/18
to basilisk-fr
Hallo Jack,

The sentence:  "interpolate_array() Works in parallel" is a criptic way of saying that the so-called "rank" or "ID" of the process ( "pid()" in basilisk ) with a (int) value of 0 (i.e the root) has access to the relevant data. Unlike regular "interpolate()", where the various versions of the data still need to be reduced. The next step is to also ensure that the writing of the file "works in parallel".
 
If you want to write the result to a file you only want the relevant pid() to do so.
This is the purpose of the
if (pid() == 0){
...
//Some code only the "root" carries out
...
}
statements you may have seen in the various output.h functions.

Noting that this strategy only holds for writing small files. 
 
Antoon
Reply all
Reply to author
Forward
0 new messages