📄 fem2d_poisson.cpp
字号:
// Parameters:
//
// Input, int NX, NY, controls the number of elements along the
// X and Y directions. The number of elements will be
// 2 * ( NX - 1 ) * ( NY - 1 ).
//
// Input, int NNODES, the number of local nodes per element.
//
// Input, int ELEMENT_NUM, the number of elements.
//
// Output, int ELEMENT_NODE[NNODES*ELEMENT_NUM];
// ELEMENT_NODE(I,J) is the index of the I-th node of the J-th element.
//
{
int c;
int e;
int element;
int i;
int j;
int n;
int ne;
int nw;
int s;
int se;
int sw;
int w;
element = 0;
for ( j = 1; j <= ny - 1; j++ )
{
for ( i = 1; i <= nx - 1; i++ )
{
sw = ( j - 1 ) * 2 * ( 2 * nx - 1 ) + 2 * i - 1;
w = sw + 1;
nw = sw + 2;
s = sw + 2 * nx - 1;
c = s + 1;
n = s + 2;
se = s + 2 * nx - 1;
e = se + 1;
ne = se + 2;
element = element + 1;
element_node[0+(element-1)*nnodes] = sw;
element_node[1+(element-1)*nnodes] = se;
element_node[2+(element-1)*nnodes] = nw;
element_node[3+(element-1)*nnodes] = s;
element_node[4+(element-1)*nnodes] = c;
element_node[5+(element-1)*nnodes] = w;
element = element + 1;
element_node[0+(element-1)*nnodes] = ne;
element_node[1+(element-1)*nnodes] = nw;
element_node[2+(element-1)*nnodes] = se;
element_node[3+(element-1)*nnodes] = n;
element_node[4+(element-1)*nnodes] = c;
element_node[5+(element-1)*nnodes] = e;
}
}
return;
}
//****************************************************************************80
int i4_max ( int i1, int i2 )
//****************************************************************************80
//
// Purpose:
//
// I4_MAX returns the maximum of two I4's.
//
// Modified:
//
// 13 October 1998
//
// Author:
//
// John Burkardt
//
// Parameters:
//
// Input, int I1, I2, are two ints to be compared.
//
// Output, int I4_MAX, the larger of I1 and I2.
//
//
{
if ( i2 < i1 )
{
return i1;
}
else
{
return i2;
}
}
//****************************************************************************80
int i4_min ( int i1, int i2 )
//****************************************************************************80
//
// Purpose:
//
// I4_MIN returns the smaller of two I4's.
//
// Modified:
//
// 13 October 1998
//
// Author:
//
// John Burkardt
//
// Parameters:
//
// Input, int I1, I2, two ints to be compared.
//
// Output, int I4_MIN, the smaller of I1 and I2.
//
//
{
if ( i1 < i2 )
{
return i1;
}
else
{
return i2;
}
}
//****************************************************************************80
void indx_set ( int nx, int ny, int node_num, int indx[], int *nunk )
//****************************************************************************80
//
// Purpose:
//
// INDX_SET assigns a boundary value index or unknown value index at each node.
//
// Discussion:
//
// Every finite element node will is assigned an index which
// indicates the finite element basis function and its coefficient
// which are associated with that node.
//
// Example:
//
// On a simple 5 by 5 grid, where the nodes are numbered starting
// at the lower left, and increasing in X first, we would have the
// following values of INDX:
//
// 21 22 23 24 25
// 16 17 18 19 20
// 11 12 13 14 15
// 6 7 8 9 10
// 1 2 3 4 5
//
// Modified:
//
// 17 May 2005
//
// Parameters:
//
// Input, int NX, NY, the number of elements in the X and Y directions.
//
// Input, int NODE_NUM, the number of nodes.
//
// Output, int INDX[NODE_NUM], the index of the unknown in the finite
// element linear system.
//
// Output, int *NUNK, the number of unknowns.
//
{
int i;
int in;
int j;
*nunk = 0;
in = 0;
for ( j = 1; j <= 2 * ny - 1; j++ )
{
for ( i = 1; i <= 2 * nx - 1; i++ )
{
in = in + 1;
*nunk = *nunk + 1;
indx[in-1] = *nunk;
}
}
return;
}
//****************************************************************************80
void nodes_plot ( char *file_name, int node_num, double node_xy[],
bool node_label )
//****************************************************************************80
//
// Purpose:
//
// NODES_PLOT plots a pointset.
//
// Modified:
//
// 27 September 2006
//
// Author:
//
// John Burkardt
//
// Parameters:
//
// Input, char *FILE_NAME, the name of the file to create.
//
// Input, int NODE_NUM, the number of nodes.
//
// Input, double NODE_XY[2*NODE_NUM], the nodes.
//
// Input, bool NODE_LABEL, is TRUE if the nodes are to be labeled.
//
{
int circle_size;
char *date_time;
int delta;
ofstream file_unit;
int i;
int node;
double x_max;
double x_min;
int x_ps;
int x_ps_max = 576;
int x_ps_max_clip = 594;
int x_ps_min = 36;
int x_ps_min_clip = 18;
double x_scale;
double y_max;
double y_min;
int y_ps;
int y_ps_max = 666;
int y_ps_max_clip = 684;
int y_ps_min = 126;
int y_ps_min_clip = 108;
double y_scale;
date_time = timestring ( );
//
// We need to do some figuring here, so that we can determine
// the range of the data, and hence the height and width
// of the piece of paper.
//
x_max = -r8_huge ( );
for ( node = 0; node < node_num; node++ )
{
if ( x_max < node_xy[0+node*2] )
{
x_max = node_xy[0+node*2];
}
}
x_min = r8_huge ( );
for ( node = 0; node < node_num; node++ )
{
if ( node_xy[0+node*2] < x_min )
{
x_min = node_xy[0+node*2];
}
}
x_scale = x_max - x_min;
x_max = x_max + 0.05 * x_scale;
x_min = x_min - 0.05 * x_scale;
x_scale = x_max - x_min;
y_max = -r8_huge ( );
for ( node = 0; node < node_num; node++ )
{
if ( y_max < node_xy[1+node*2] )
{
y_max = node_xy[1+node*2];
}
}
y_min = r8_huge ( );
for ( node = 0; node < node_num; node++ )
{
if ( node_xy[1+node*2] < y_min )
{
y_min = node_xy[1+node*2];
}
}
y_scale = y_max - y_min;
y_max = y_max + 0.05 * y_scale;
y_min = y_min - 0.05 * y_scale;
y_scale = y_max - y_min;
if ( x_scale < y_scale )
{
delta = r8_nint ( ( double ) ( x_ps_max - x_ps_min )
* ( y_scale - x_scale ) / ( 2.0 * y_scale ) );
x_ps_max = x_ps_max - delta;
x_ps_min = x_ps_min + delta;
x_ps_max_clip = x_ps_max_clip - delta;
x_ps_min_clip = x_ps_min_clip + delta;
x_scale = y_scale;
}
else if ( y_scale < x_scale )
{
delta = r8_nint ( ( double ) ( y_ps_max - y_ps_min )
* ( x_scale - y_scale ) / ( 2.0 * x_scale ) );
y_ps_max = y_ps_max - delta;
y_ps_min = y_ps_min + delta;
y_ps_max_clip = y_ps_max_clip - delta;
y_ps_min_clip = y_ps_min_clip + delta;
y_scale = x_scale;
}
file_unit.open ( file_name );
if ( !file_unit )
{
cout << "\n";
cout << "POINTS_PLOT - Fatal error!\n";
cout << " Could not open the output EPS file.\n";
exit ( 1 );
}
file_unit << "%!PS-Adobe-3.0 EPSF-3.0\n";
file_unit << "%%Creator: nodes_plot.C\n";
file_unit << "%%Title: " << file_name << "\n";
file_unit << "%%CreationDate: " << date_time << "\n";
delete [] date_time;
file_unit << "%%Pages: 1\n";
file_unit << "%%BoundingBox: "
<< x_ps_min << " "
<< y_ps_min << " "
<< x_ps_max << " "
<< y_ps_max << "\n";
file_unit << "%%Document-Fonts: Times-Roman\n";
file_unit << "%%LanguageLevel: 1\n";
file_unit << "%%EndComments\n";
file_unit << "%%BeginProlog\n";
file_unit << "/inch {72 mul} def\n";
file_unit << "%%EndProlog\n";
file_unit << "%%Page: 1 1\n";
file_unit << "save\n";
file_unit << "%\n";
file_unit << "% Set the RGB line color to very light gray.\n";
file_unit << "%\n";
file_unit << " 0.9000 0.9000 0.9000 setrgbcolor\n";
file_unit << "%\n";
file_unit << "% Draw a gray border around the page.\n";
file_unit << "%\n";
file_unit << "newpath\n";
file_unit << x_ps_min << " "
<< y_ps_min << " moveto\n";
file_unit << x_ps_max << " "
<< y_ps_min << " lineto\n";
file_unit << x_ps_max << " "
<< y_ps_max << " lineto\n";
file_unit << x_ps_min << " "
<< y_ps_max << " lineto\n";
file_unit << x_ps_min << " "
<< y_ps_min << " lineto\n";
file_unit << "stroke\n";
file_unit << "%\n";
file_unit << "% Set RGB line color to black.\n";
file_unit << "%\n";
file_unit << " 0.0000 0.0000 0.0000 setrgbcolor\n";
file_unit << "%\n";
file_unit << "% Set the font and its size:\n";
file_unit << "%\n";
file_unit << "/Times-Roman findfont\n";
file_unit << "0.50 inch scalefont\n";
file_unit << "setfont\n";
file_unit << "%\n";
file_unit << "% Print a title:\n";
file_unit << "%\n";
file_unit << "% 210 702 moveto\n";
file_unit << "%(Pointset) show\n";
file_unit << "%\n";
file_unit << "% Define a clipping polygon\n";
file_unit << "%\n";
file_unit << "newpath\n";
file_unit << x_ps_min_clip << " "
<< y_ps_min_clip << " moveto\n";
file_unit << x_ps_max_clip << " "
<< y_ps_min_clip << " lineto\n";
file_unit << x_ps_max_clip << " "
<< y_ps_max_clip << " lineto\n";
file_unit << x_ps_min_clip << " "
<< y_ps_max_clip << " lineto\n";
file_unit << x_ps_min_clip << " "
<< y_ps_min_clip << " lineto\n";
file_unit << "clip newpath\n";
//
// Draw the nodes.
//
if ( node_num <= 200 )
{
circle_size = 5;
}
else if ( node_num <= 500 )
{
circle_size = 4;
}
else if ( node_num <= 1000 )
{
circle_size = 3;
}
else if ( node_num <= 5000 )
{
circle_size = 2;
}
else
{
circle_size = 1;
}
file_unit << "%\n";
file_unit << "% Draw filled dots at each node:\n";
file_unit << "%\n";
file_unit << "% Set the color to blue:\n";
file_unit << "%\n";
file_unit << "0.000 0.150 0.750 setrgbcolor\n";
file_unit << "%\n";
for ( node = 0; node < node_num; node++ )
{
x_ps = ( int ) (
( ( x_max - node_xy[0+node*2] ) * ( double ) ( x_ps_min )
+ ( + node_xy[0+node*2] - x_min ) * ( double ) ( x_ps_max ) )
/ ( x_max - x_min ) );
y_ps = ( int ) (
( ( y_max - node_xy[1+node*2] ) * ( double ) ( y_ps_min )
+ ( node_xy[1+node*2] - y_min ) * ( double ) ( y_ps_max ) )
/ ( y_max - y_min ) );
file_unit << "newpath "
<< x_ps << " "
<< y_ps << " "
<< circle_size << " 0 360 arc closepath fill\n";
}
//
// Label the nodes.
//
file_unit << "%\n";
file_unit << "% Label the nodes:\n";
file_unit << "%\n";
file_unit << "% Set the color to darker blue:\n";
file_unit << "%\n";
file_unit << "0.000 0.250 0.850 setrgbcolor\n";
file_unit << "/Times-Roman findfont\n";
file_unit << "0.20 inch scalefont\n";
file_unit << "setfont\n";
file_unit << "%\n";
for ( node = 0; node < node_num; node++ )
{
x_ps = ( int ) (
( ( x_max - node_xy[0+node*2] ) * ( double ) ( x_ps_min )
+ ( + node_xy[0+node*2] - x_min ) * ( double ) ( x_ps_max ) )
/ ( x_max - x_min ) );
y_ps = ( int ) (
( ( y_max - node_xy[1+node*2] ) * ( double ) ( y_ps_min )
+ ( node_xy[1+node*2] - y_min ) * ( double ) ( y_ps_max ) )
/ ( y_max - y_min ) );
file_unit << "newpath "
<< x_ps << " "
<< y_ps + 5 << " moveto ("
<< node+1 << ") show\n";
}
file_unit << "%\n";
file_unit << "restore showpage\n";
file_unit << "%\n";
file_unit << "% End of page\n";
file_unit << "%\n";
file_unit << "%%Trailer\n";
file_unit << "%%EOF\n";
file_unit.close ( );
return;
}
//****************************************************************************80*
void nodes_write ( int node_num, double node_xy[], char *output_filename )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -