> I have not been able to solve a similar problem in the following bit of
> code, This routine exports a slice of scalar data into a file.
I believe this is because you do not understand what "static" means. In
the first code I send you, the file is opened only once (when the event
is first executed i.e. at i = 0), the value of the corresponding file
pointer (fp) is kept between calls to the event (this is what "static"
means i.e. it means "keep this in static memory, don't keep this in the
"stack" or "dynamic memory" where it would be allocated when entering
the function and deallocated when leaving the function"). Note that this
is standard C, not Basilisk stuff.
Now in the code below, you see that you declare fpgrT and fpT also as
"static", however they both depend on time "t" and so _must_ be opened
every time the event is called (not just once at the beginning): so they
clearly are not "static".
What happens next? you close both files at the end of the event. The
next time the event is called, it will attempt to use the same file
pointer (remember that because they are static their value is kept
between calls), however this file is closed, hence the "segmentation
fault" error.
So "static" clearly does not do what you need for this type of output.
The problem you have here is that different processes hold the different
bits of data you need for "locate()" to work. i.e. "locate()" only
operates on the local processes not on all processes in parallel. So if
(xp,yp,zp) belongs to the subdomain allocated to processor, say, 2, all
the other processes will not be able to locate it and point.level will
bet set to -1 on these processes, the values you want to access (i.e.
T[] and grT[]) will thus be undefined.
Additionally, all the processes will try to write their data (undefined
or not) in the same file, more or less simulatenously, which will result
in a big mess. Also, you have no control in which order the processes
will write their data... Welcome to the world of asynchronous parallel
programming!
A simpler way of doing this is for example:
1- only output when point.level is not -1 (after locate).
2- output in separate files for each process (use sprintf and pid() for
the number of the process)
3- concatenate files (using a script after running the thing)
> sprintf(names,"./data/slicegrTt=%g.dat",t);
> staticFILE *fpgrT =fopen (names,"w");
> sprintf(names,"./data/sliceTt=%g.dat",t);
> staticFILE *fpT =fopen (names,"w");
> scalar grT[];
> doublezp =Z0+L0/2;
>
> for(doubleyp =Y0+(L0/pow(2,MAXLEVEL+1));yp<3;yp+=L0/(pow(2,MAXLEVEL)))
> {
> for(doublexp =X0+(L0/pow(2,MAXLEVEL+1));xp<L0
> ;xp+=(L0/pow(2,MAXLEVEL)))
> {
>
> Pointpoint =locate (xp,yp,zp);
> fprintf(fpgrT,"%g\t",grT[]);
> fprintf(fpT,"%g\t",T[]);
> }
> fprintf(fpgrT,"\n");
> fprintf(fpT,"\n");
>
> }
> fclose(fpgrT);
> fclose(fpT);
> |
>
> But i get an error when the inner loop variable (xp) exceeds a certain
> value: xp > L0/2. Furthermore, the code appears to crash on the
> "fprintf" command.
> I get this error massage:
>
> |
> [antoon-XPS-15-9550:10482]***Processreceived signal ***
> [antoon-XPS-15-9550:10482]Signal:Segmentationfault (11)
> [antoon-XPS-15-9550:10482]Signalcode:Addressnotmapped (1)
> [antoon-XPS-15-9550:10482]Failingat address:(nil)