mirror of
https://github.com/PhasicFlow/phasicFlow.git
synced 2025-07-08 03:07:03 +00:00
Zoltan is added as thirdParty package
This commit is contained in:
378
thirdParty/Zoltan/src/driver/dr_gnuplot.c
vendored
Normal file
378
thirdParty/Zoltan/src/driver/dr_gnuplot.c
vendored
Normal file
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* @HEADER
|
||||
*
|
||||
* ***********************************************************************
|
||||
*
|
||||
* Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
|
||||
* Copyright 2012 Sandia Corporation
|
||||
*
|
||||
* Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||
* the U.S. Government retains certain rights in this software.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Corporation nor the names of the
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Questions? Contact Karen Devine kddevin@sandia.gov
|
||||
* Erik Boman egboman@sandia.gov
|
||||
*
|
||||
* ***********************************************************************
|
||||
*
|
||||
* @HEADER
|
||||
*/
|
||||
|
||||
#include "dr_const.h"
|
||||
#include "dr_externs.h"
|
||||
#include "dr_util_const.h"
|
||||
#include "dr_par_util_const.h"
|
||||
#include "dr_err_const.h"
|
||||
#include "dr_output_const.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* if C++, define the rest of this header file as extern C */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void Zoltan_quicksort_pointer_inc_int_int(int*, int*, int*, int, int);
|
||||
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void printcoord(FILE *fp, int ndims, char *str, ELEM_INFO *elem)
|
||||
{
|
||||
switch (ndims) {
|
||||
case 1:
|
||||
fprintf(fp, "%s%e\n", str,
|
||||
elem->coord[0][0]);
|
||||
break;
|
||||
case 2:
|
||||
fprintf(fp, "%s%e %e\n", str,
|
||||
elem->coord[0][0], elem->coord[0][1]);
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
fprintf(fp, "%s%e %e %e\n", str,
|
||||
elem->coord[0][0], elem->coord[0][1], elem->coord[0][2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Purpose: Output the element assignments in gnuplot format. */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int output_gnu(const char *cmd_file,
|
||||
const char *tag,
|
||||
int Proc,
|
||||
int Num_Proc,
|
||||
PROB_INFO_PTR prob,
|
||||
PARIO_INFO_PTR pio_info,
|
||||
MESH_INFO_PTR mesh)
|
||||
/*
|
||||
* For 2D problems, output files that can be read by gnuplot for looking at
|
||||
* results.
|
||||
* We'll do 3D problems later.
|
||||
*
|
||||
* One gnuplot file is written for each part.
|
||||
* When number of part == number of processors, there is one file per
|
||||
* processor.
|
||||
*
|
||||
* For Chaco input files, the file written contains coordinates of owned
|
||||
* nodes and all nodes in that part connected to the owned nodes. When
|
||||
* drawn "with linespoints", the subdomains are drawn, but lines connecting the
|
||||
* subdomains are not drawn.
|
||||
*
|
||||
* For Nemesis input files, the file written contains the coordinates of
|
||||
* each node of owned elements. When drawn "with lines", the element outlines
|
||||
* for each owned element are drawn.
|
||||
*
|
||||
* In addition, processor 0 writes a gnuplot command file telling gnuplot how
|
||||
* to process the individual coordinate files written. This file can be used
|
||||
* with the gnuplot "load" command to simplify generation of the gnuplot.
|
||||
*/
|
||||
{
|
||||
/* Local declarations. */
|
||||
const char *yo = "output_gnu";
|
||||
char par_out_fname[FILENAME_MAX+1], ctemp[FILENAME_MAX+1];
|
||||
ELEM_INFO *current_elem, *nbor_elem;
|
||||
int nbor, num_nodes;
|
||||
const char *datastyle = NULL;
|
||||
int i, j, nelems;
|
||||
int prev_part = -1;
|
||||
int max_part = -1;
|
||||
float locMaxX = (float)INT_MIN;
|
||||
float locMinX = (float)INT_MAX;
|
||||
float locMaxY = (float)INT_MIN;
|
||||
float locMinY = (float)INT_MAX;
|
||||
float globMaxX = (float)INT_MIN;
|
||||
float globMinX = (float)INT_MAX;
|
||||
float globMaxY = (float)INT_MIN;
|
||||
float globMinY = (float)INT_MAX;
|
||||
int gmax_part = Num_Proc-1;
|
||||
int gnum_part = Num_Proc;
|
||||
int *parts = NULL;
|
||||
int *index = NULL;
|
||||
int *elem_index = NULL;
|
||||
FILE *fp = NULL;
|
||||
/***************************** BEGIN EXECUTION ******************************/
|
||||
|
||||
if(Output.Gnuplot < 0)
|
||||
{
|
||||
Gen_Error(0,
|
||||
"warning: 'gnuplot output' parameter set to invalid value.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEBUG_TRACE_START(Proc, yo);
|
||||
|
||||
if (mesh->eb_nnodes[0] == 0) {
|
||||
/* No coordinate information is available. */
|
||||
Gen_Error(0, "warning: cannot generate gnuplot data when no coordinate"
|
||||
" input is given.");
|
||||
DEBUG_TRACE_END(Proc, yo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build arrays of part number to sort by. Index and elem_index arrays
|
||||
* will be used even when plotting by processor numbers (for generality),
|
||||
* so build it regardless.
|
||||
*/
|
||||
nelems = mesh->num_elems - mesh->blank_count;
|
||||
|
||||
if (nelems > 0) {
|
||||
parts = (int *) malloc(3 * nelems * sizeof(int));
|
||||
index = parts + nelems;
|
||||
elem_index = index + nelems;
|
||||
for (j = 0, i = 0; i < mesh->elem_array_len; i++) {
|
||||
current_elem = &(mesh->elements[i]);
|
||||
if (current_elem->globalID != ZOLTAN_ID_INVALID) {
|
||||
|
||||
if (mesh->blank_count && (mesh->blank[i] == 1)) continue;
|
||||
|
||||
if (current_elem->my_part > max_part) max_part = current_elem->my_part;
|
||||
parts[j] = (Output.Plot_Partition ? current_elem->my_part : Proc);
|
||||
index[j] = j;
|
||||
elem_index[j] = i;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Output.Plot_Partition) {
|
||||
/* Sort by part numbers. Assumes # parts >= # proc. */
|
||||
if (nelems > 0)
|
||||
Zoltan_quicksort_pointer_inc_int_int(index, parts, NULL, 0, nelems-1);
|
||||
MPI_Allreduce(&max_part, &gmax_part, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
|
||||
gnum_part = gmax_part + 1;
|
||||
}
|
||||
|
||||
/* generate the parallel filename for this processor */
|
||||
strcpy(ctemp, pio_info->pexo_fname);
|
||||
strcat(ctemp, ".");
|
||||
strcat(ctemp, tag);
|
||||
strcat(ctemp, ".gnu");
|
||||
|
||||
|
||||
if (pio_info->file_type == CHACO_FILE ||
|
||||
pio_info->file_type == NO_FILE_POINTS ||
|
||||
pio_info->file_type == NO_FILE_TRIANGLES ||
|
||||
pio_info->file_type == HYPERGRAPH_FILE) {
|
||||
/*
|
||||
* For each node of Chaco graph, print the coordinates of the node.
|
||||
* Then, for each neighboring node on the processor, print the neighbor's
|
||||
* coordinates.
|
||||
*/
|
||||
datastyle = "points";
|
||||
for (i = 0; i < nelems; i++) {
|
||||
current_elem = &(mesh->elements[elem_index[index[i]]]);
|
||||
if (parts[index[i]] != prev_part) {
|
||||
if (fp != NULL) fclose(fp);
|
||||
gen_par_filename(ctemp, par_out_fname, pio_info,
|
||||
parts[index[i]], Num_Proc);
|
||||
fp = fopen(par_out_fname, "w");
|
||||
prev_part = parts[index[i]];
|
||||
}
|
||||
|
||||
/* Include the point itself, so that even if there are no edges,
|
||||
* the point will appear. */
|
||||
printcoord(fp, mesh->num_dims, "\n", current_elem);
|
||||
|
||||
/* save max and min x/y coords */
|
||||
if(current_elem->coord[0][0] < locMinX)
|
||||
{
|
||||
locMinX = current_elem->coord[0][0];
|
||||
}
|
||||
if(current_elem->coord[0][0] > locMaxX)
|
||||
{
|
||||
locMaxX = current_elem->coord[0][0];
|
||||
}
|
||||
if(current_elem->coord[0][1] < locMinY)
|
||||
{
|
||||
locMinY = current_elem->coord[0][1];
|
||||
}
|
||||
if(current_elem->coord[0][1] > locMaxY)
|
||||
{
|
||||
locMaxY = current_elem->coord[0][1];
|
||||
}
|
||||
|
||||
if (Output.Gnuplot>1)
|
||||
{
|
||||
datastyle = "linespoints";
|
||||
|
||||
for (j = 0; j < current_elem->nadj; j++) {
|
||||
if (current_elem->adj_proc[j] == Proc) { /* Nbor is on same proc */
|
||||
if (mesh->blank_count && (mesh->blank[current_elem->adj[j]] == 1))
|
||||
continue;
|
||||
if (!Output.Plot_Partition ||
|
||||
mesh->elements[current_elem->adj[j]].my_part ==
|
||||
current_elem->my_part) {
|
||||
/* Not plotting parts, or nbor is in same part */
|
||||
/* Plot the edge. Need to include current point and nbor point
|
||||
* for each edge. */
|
||||
printcoord(fp, mesh->num_dims, "\n", current_elem);
|
||||
nbor = current_elem->adj[j];
|
||||
nbor_elem = &(mesh->elements[nbor]);
|
||||
printcoord(fp, mesh->num_dims, "", nbor_elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MPI_Reduce(&locMinX,&globMinX,1,MPI_FLOAT,MPI_MIN,0,MPI_COMM_WORLD);
|
||||
MPI_Reduce(&locMinY,&globMinY,1,MPI_FLOAT,MPI_MIN,0,MPI_COMM_WORLD);
|
||||
MPI_Reduce(&locMaxX,&globMaxX,1,MPI_FLOAT,MPI_MAX,0,MPI_COMM_WORLD);
|
||||
MPI_Reduce(&locMaxY,&globMaxY,1,MPI_FLOAT,MPI_MAX,0,MPI_COMM_WORLD);
|
||||
|
||||
}
|
||||
else if (pio_info->file_type == NEMESIS_FILE) { /* Nemesis input file */
|
||||
/*
|
||||
* For each element of Nemesis input file, print the coordinates of its
|
||||
* nodes. No need to follow neighbors, as decomposition is by elements.
|
||||
*/
|
||||
double sum[2];
|
||||
|
||||
if (mesh->num_dims > 2) {
|
||||
Gen_Error(0,
|
||||
"warning: cannot generate gnuplot for 3D NEMESIS_FILE problems yet.");
|
||||
DEBUG_TRACE_END(Proc, yo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
datastyle = "lines";
|
||||
for (i = 0; i < nelems; i++) {
|
||||
current_elem = &(mesh->elements[elem_index[index[i]]]);
|
||||
if (parts[index[i]] != prev_part) {
|
||||
if (fp != NULL) fclose(fp);
|
||||
gen_par_filename(ctemp, par_out_fname, pio_info,
|
||||
parts[index[i]], Num_Proc);
|
||||
fp = fopen(par_out_fname, "w");
|
||||
prev_part = parts[index[i]];
|
||||
}
|
||||
num_nodes = mesh->eb_nnodes[current_elem->elem_blk];
|
||||
sum[0] = sum[1] = 0.0;
|
||||
for (j = 0; j < num_nodes; j++) {
|
||||
fprintf(fp, "%e %e\n",
|
||||
current_elem->coord[j][0], current_elem->coord[j][1]);
|
||||
sum[0] += current_elem->coord[j][0];
|
||||
sum[1] += current_elem->coord[j][1];
|
||||
}
|
||||
fprintf(fp, "%e %e\n", current_elem->coord[0][0],
|
||||
current_elem->coord[0][1]);
|
||||
fprintf(fp, "\n");
|
||||
/* Print small + in center of element */
|
||||
sum[0] /= num_nodes;
|
||||
sum[1] /= num_nodes;
|
||||
fprintf(fp, "%e %e\n", sum[0] - 0.001, sum[1]);
|
||||
fprintf(fp, "%e %e\n\n", sum[0] + 0.001, sum[1]);
|
||||
fprintf(fp, "%e %e\n", sum[0], sum[1] - 0.001);
|
||||
fprintf(fp, "%e %e\n\n", sum[0], sum[1] + 0.001);
|
||||
}
|
||||
}
|
||||
|
||||
if (nelems == 0 && !Output.Plot_Partition) {
|
||||
/* Open a file just so one exists; satisfies the gnuload file. */
|
||||
gen_par_filename(ctemp, par_out_fname, pio_info, Proc, Num_Proc);
|
||||
fp = fopen(par_out_fname, "w");
|
||||
}
|
||||
|
||||
if (fp != NULL) fclose(fp);
|
||||
safe_free((void **)(void *) &parts);
|
||||
|
||||
if (Proc == 0) {
|
||||
/* Write gnu master file with gnu commands for plotting */
|
||||
strcpy(ctemp, pio_info->pexo_fname);
|
||||
strcat(ctemp, ".");
|
||||
strcat(ctemp, tag);
|
||||
strcat(ctemp, ".gnuload");
|
||||
fp = fopen(ctemp, "w");
|
||||
fprintf(fp, "set nokey\n");
|
||||
fprintf(fp, "set nolabel\n");
|
||||
fprintf(fp, "set noxzeroaxis\n");
|
||||
fprintf(fp, "set noyzeroaxis\n");
|
||||
fprintf(fp, "set noxtics\n");
|
||||
fprintf(fp, "set noytics\n");
|
||||
fprintf(fp, "set style data %s\n", datastyle);
|
||||
|
||||
/* resize range so that there is a 5% border around data */
|
||||
fprintf(fp, "set xrange [%f:%f] \n ",globMinX-(globMaxX-globMinX)/20
|
||||
,globMaxX+(globMaxX-globMinX)/20);
|
||||
fprintf(fp, "set yrange [%f:%f] \n ",globMinY-(globMaxY-globMinY)/20
|
||||
,globMaxY+(globMaxY-globMinY)/20);
|
||||
|
||||
|
||||
if (mesh->num_dims < 3)
|
||||
fprintf(fp, "plot ");
|
||||
else
|
||||
fprintf(fp, "splot ");
|
||||
|
||||
strcpy(ctemp, pio_info->pexo_fname);
|
||||
strcat(ctemp, ".");
|
||||
strcat(ctemp, tag);
|
||||
strcat(ctemp, ".gnu");
|
||||
for (i = 0; i < gnum_part; i++) {
|
||||
gen_par_filename(ctemp, par_out_fname, pio_info, i, Num_Proc);
|
||||
fprintf(fp, "\"%s\"", par_out_fname);
|
||||
if (i != gnum_part-1) {
|
||||
fprintf(fp, ",\\\n");
|
||||
}
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
DEBUG_TRACE_END(Proc, yo);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* closing bracket for extern "C" */
|
||||
#endif
|
Reference in New Issue
Block a user