# include <math.h>
# include <stdlib.h>
# include <stdio.h>
# include <time.h>
# include <string.h>
int main ( int argc, char *argv[] );
char ch_cap ( char ch );
int ch_eqi ( char ch1, char ch2 );
int ch_to_digit ( char ch );
int file_column_count ( char *filename );
int file_row_count ( char *filename );
void gmsh_mesh1d_write ( char *gmsh_filename, int m, int node_num, double node_x[],
int element_order, int element_num, int element_node[] );
void gmsh_mesh2d_write ( char *gmsh_filename, int m, int node_num, double node_x[],
int element_order, int element_num, int element_node[] );
void gmsh_mesh3d_write ( char *gmsh_filename, int m, int node_num, double node_x[],
int element_order, int element_num, int element_node[] );
int i4_max ( int i1, int i2 );
int i4_min ( int i1, int i2 );
int *i4mat_data_read ( char *input_filename, int m, int n );
void i4mat_header_read ( char *input_filename, int *m, int *n );
int i4mat_max ( int m, int n, int a[] );
int i4mat_min ( int m, int n, int a[] );
void i4mat_transpose_print ( int m, int n, int a[], char *title );
void i4mat_transpose_print_some ( int m, int n, int a[], int ilo, int jlo,
int ihi, int jhi, char *title );
void mesh_base_one ( int node_num, int element_order, int element_num,
int element_node[] );
double *r8mat_data_read ( char *input_filename, int m, int n );
void r8mat_header_read ( char *input_filename, int *m, int *n );
void r8mat_transpose_print ( int m, int n, double a[], char *title );
void r8mat_transpose_print_some ( int m, int n, double a[], int ilo, int jlo,
int ihi, int jhi, char *title );
int s_len_trim ( char *s );
int s_to_i4 ( char *s, int *last, int *error );
int s_to_i4vec ( char *s, int n, int ivec[] );
double s_to_r8 ( char *s, int *lchar, int *error );
int s_to_r8vec ( char *s, int n, double rvec[] );
int s_word_count ( char *s );
void timestamp ( );
/******************************************************************************/
int main ( int argc, char *argv[] )
/******************************************************************************/
/*
Purpose:
MAIN is the main program for FEM_TO_GMSH.
Discussion:
FEM_TO_GMSH converts a 1D, 2D or 3D mesh from FEM to GMSH format.
Usage:
fem_to_gmsh prefix
where 'prefix' is the common filename prefix:
* 'prefix'_nodes.txt contains the node coordinates,
* 'prefix'_elements.txt contains the element node connectivity.
* 'prefix'.msh will contain the Gmsh version of the data.
Licensing:
This code is distributed under the GNU LGPL license.
Modified:
24 June 2019
Author:
John Burkardt
*/
{
char element_filename[255];
int *element_node;
int element_num;
int element_order;
char gmsh_filename[255];
int m;
char node_filename[255];
int node_num;
double *node_x;
char prefix[255];
timestamp ( );
printf ( "\n" );
printf ( "FEM_TO_GMSH\n" );
printf ( " C version:\n" );
printf ( " Convert a 1D, 2D or 3D mesh to Gmsh format.\n" );
printf ( "\n" );
printf ( " Read \"prefix\"_nodes.txt, node coordinates.\n" );
printf ( " Read \"prefix\"_elements.txt, 3 or 6 node element definitions.\n" );
printf ( "\n" );
printf ( " Create \"prefix\".msh, a corresponding Gmsh mesh file.\n" );
/*
Get the filename prefix.
*/
if ( argc <= 1 )
{
printf ( "\n" );
printf ( "FEM_TO_GMSH:\n" );
printf ( " Please enter the filename prefix.\n" );
scanf ( "%s", prefix );
}
else
{
strcpy ( prefix, argv[1] );
}
/*
Create the filenames.
*/
strcpy ( node_filename, prefix );
strcat ( node_filename, "_nodes.txt" );
strcpy ( element_filename, prefix );
strcat ( element_filename, "_elements.txt" );
strcpy ( gmsh_filename, prefix );
strcat ( gmsh_filename, ".msh" );
/*
Read the node data.
*/
r8mat_header_read ( node_filename, &m, &node_num );
printf ( "\n" );
printf ( " Read the header of \"%s\".\n", node_filename );
printf ( "\n" );
printf ( " Spatial dimension = %d\n", m );
printf ( " Number of nodes = %d\n", node_num );
node_x = r8mat_data_read ( node_filename, m, node_num );
printf ( "\n" );
printf ( " Read the data in \"%s\".\n", node_filename );
r8mat_transpose_print_some ( m, node_num, node_x, 1, 1, m, 5,
" Portion of node coordinate data:" );
/*
Read the element data.
*/
i4mat_header_read ( element_filename, &element_order, &element_num );
if ( m == 1 )
{
if ( element_order == 2 )
{
}
else
{
fprintf ( stderr, "\n" );
fprintf ( stderr, "FEM_TO_GMSH - Fatal error!\n" );
fprintf ( stderr, " 1D mesh data must use 2 nodes.\n" );
exit ( 1 );
}
}
else if ( m == 2 )
{
if ( element_order == 3 )
{
}
else if ( element_order == 6 )
{
}
else
{
fprintf ( stderr, "\n" );
fprintf ( stderr, "FEM_TO_GMSH - Fatal error!\n" );
fprintf ( stderr, " 2D mesh data must use 3 or 6 nodes.\n" );
exit ( 1 );
}
}
else if ( m == 3 )
{
if ( element_order == 4 )
{
}
else if ( element_order == 10 )
{
}
else if ( element_order == 20 )
{
}
else
{
fprintf ( stderr, "\n" );
fprintf ( stderr, "FEM_TO_GMSH - Fatal error!\n" );
fprintf ( stderr, " 3D mesh data must use 4, 10, or 20 nodes.\n" );
exit ( 1 );
}
}
printf ( "\n" );
printf ( " Read the header of \"%s\".\n", element_filename );
printf ( "\n" );
printf ( " Element order = %d\n", element_order );
printf ( " Number of elements = %d\n", element_num );
element_node = i4mat_data_read ( element_filename, element_order,
element_num );
printf ( "\n" );
printf ( " Read the data in \"%s\".\n", element_filename );
i4mat_transpose_print_some ( element_order, element_num, element_node,
1, 1, element_order, 10, " Initial portion of element data:" );
/*
Write out the Gmsh version of the data.
*/
if ( m == 1 )
{
gmsh_mesh1d_write ( gmsh_filename, m, node_num, node_x, element_order,
element_num, element_node );
}
else if ( m == 2 )
{
gmsh_mesh2d_write ( gmsh_filename, m, node_num, node_x, element_order,
element_num, element_node );
}
else if ( m == 3 )
{
gmsh_mesh3d_write ( gmsh_filename, m, node_num, node_x, element_order,
element_num, element_node );
}
printf ( "\n" );
printf ( " Created the GMSH file \"%s\".\n", gmsh_filename );
/*
Free memory.
*/
free ( element_node );
free ( node_x );
/*
Terminate.
*/
printf ( "\n" );
printf ( "FEM_TO_GMSH:\n" );
printf ( " Normal end of execution.\n" );
printf ( "\n" );
timestamp ( );
return 0;
}
/******************************************************************************/
char ch_cap ( char ch )
/******************************************************************************/
/*
Purpose:
CH_CAP capitalizes a single character.
Discussion:
This routine should be equivalent to the library "toupper" function.
Licensing:
This code is distributed under the GNU LGPL license.
Modified:
19 July 1998
Author:
John Burkardt
Parameters:
Input, char CH, the character to capitalize.
Output, char CH_CAP, the capitalized character.
*/
{
if ( 97 <= ch && ch <= 122 )
{
ch = ch - 32;
}
return ch;
}
/******************************************************************************/
int ch_eqi ( char ch1, char ch2 )
/******************************************************************************/
/*
Purpose:
CH_EQI is TRUE (1) if two characters are equal, disregarding case.
Licensing:
This code is distributed under the GNU LGPL license.
Modified:
13 June 2003
Author:
John Burkardt
Parameters:
Input, char CH1, CH2, the characters to compare.
Output, int CH_EQI, is TRUE (1) if the two characters are equal,
disregarding case and FALSE (0) otherwise.
*/
{
int value;
if ( 97 <= ch1 && ch1 <= 122 )
{
ch1