GiD PROBLEM TYPE: AN EXAMPLE

DEFINING A PROBLEM TYPE

This tutorial takes the user through the steps involved in carrying out a problem type using GiD. A problem type is a set of files configured by GiD so that the program can prepare data to be analyzed.

A simple example has been chosen which takes us through all the associated configuration files while using few code lines. Particular emphasis is given to the calculation of the center of masses on two-dimensional surfaces - a simple formulation both conceptually and numerically.

> > The tutorial is composed of the following steps:
> > - Starting the problem
> > - Creating the materials definition file
> > - Creating the general configurations file
> > - Creating the conditions definition file
> > - Creating the data format file
> > - Creating the calculating program file and the execution files
> > - Executing the calculating module and visualizing the results using GiD

By the end of the example, the user should be able to create a calculating module that will interpret the mesh generated in the GiD pre-process. The module will calculate values for each element of the mesh and store the values in a file in such a way that they can be read by the GiD post-process.

Gianfranco Rienzi

Lluís Font González

Table of contents

1. Introduction

1.1. The problem: center of masses

1.2. Interaction of GiD with the calculating module

2. Implementation

2.1. Creating the Subdirectory for the Problem Type

2.2. Creating the Materials File

2.3. Creating the General File

2.4. Creating the Conditions File

2.5. Creating the Data Format File (Template file)

2.6. Creating the Execution File of the Calculating Module

2.7. Creating the Execution File for the Problem Type

3. Executing the calculating module

3.1. Executing the calculation for an object made of homogeneous material

3.2. Executing the calculation for an object made of heterogeneous material

3.3. Executing the calculation for an object of heterogeneous material and subject to external point- weight

4. Appendix

4.1. The program code for the calculating module

Introduction

Our aim is to solve a problem that involves calculating the center of gravity (center of masses) of a 2D object. To do this, we need to develop a calculating module that can interact with GiD.

The problem: center of masses

The center of masses (xCM,yCM) of a two-dimensional body is defined as

where r (x,y) is the density of the material at point (x,y) and S is the surface of the body.

If we consider the N gravitational forces as pi =g mi, each one concentrated on point (xi,yi), the new center of masses will be modified as follows:

To solve the problem numerically, the integrals will be transformed into sums:

Each of the N elements is treated as concentrated weight whose mass N1 is defined as the product of the (surface) density times the surface of the element.

Interaction of GiD with the calculating module

The GiD preprocess makes a discretization of the object under study and generates a mesh of elements, each one of which is assigned a material and conditions. This preprocess information in GiD (mesh, materials, conditions) enables the calculating module to generate results. For the present example, the calculating module will find the distance of each element relative to the center of masses of the object.

> Finally, the results generated by the calculating module will be read and visualized in the GiD postprocess.

> > GiD must make adaptions to manage these data. Materials, boundary and/or load conditions, and problem data in general must be defined.

> > GiD configuration is accomplished through text formatted files. The following files are required:

> > > > .prb: configuration for the general parameter

> > > > .mat: configuration for materials and their properties

> > > > .cnd: configuration for the conditions imposed on the calculation

> > > .bas: (template file) the file for configuring the format of the interchange that mediates between GiD data and the calculating module. The file for interchanging the data exported by GiD has the extension .dat. This file stores the geometric and physical data of the problem.

> > > .bat: the file that can be executed in batches called up from GiD. This file initiates the calculating module.

> > The calculating module (in this example cmas2d.exe) solves the equations of the problem and saves the results in the results file. This module may be programmed in the language of your choice.

> > The GiD post-process reads the following files generated by the calculating module:

> > > project_name.flavia.res: results file. Each element of the mesh corresponds to a value.

> > > project_name.flavia.dat: file containing the postprocess 2D mesh. If this file does not exist, GiD uses the preprocess mesh in the postprocess.

> > Diagram depicting the files system:

NOTE: The .flavia.bon, .flavia.msh or .flavia.dat files contain the mesh used in the post-process. It only makes sense to create these files if the postprocess mesh is different from the preprocess mesh. If these files do not exist, the pre-process mesh is used. However, in this example, we will create a .flavia.dat file containing the same information as the preprocess mesh simply to illustrate its use and format.

NOTE: The latest version of GiD supports a new postprocess mesh format (extension .flavia.msh - same extension as the old format for 3D postprocess meshes) which can be 2D or 3D and which handles meshes of different element types: points, lines, triangles, quadrilaterals, tetrahedras and hexahedras (see the Reference Manual for more information). In this example we will not explain this new format and we will use the old file format for the 2D postprocess mesh (file .flavia.dat).

Implementation

Creating the Subdirectory for the Problem Type

1. Create the subdirectory "cmas2d.gid". This subdirectory has a .gid extension and will contain all the configuration files and calculating module files (.prb, .mat, .cnd, .bas, .bat, .exe).

NOTE: In Windows systems, if you want the problem type to appear in the GiD Dataà Problem type menu, create the subdirectory within "Problemtypes", located in the GiD folder - for instance, C:\GiDWin\Problemtypes\cmas2d.gid

> > Creating the Materials File

> > 1.Create the materials file "cmas2d.mat". This file stores the physical properties of the material under study for the problem type. In this case, defining the density will be sufficient.

> > 2.Enter the materials into the "cmas2d.mat" file using the following format:

NUMBER: Identifier of the material

MATERIAL: Name of the material (without spaces)

QUESTION: Property of the material. For this example, we are interested in the density of the material.

VALUE: Value of the property

...

END MATERIAL

...

> > 3.In GiD, the information pertaining to the "cmas2d.mat" file is managed in the materials window (Figure 1), which is located in Data->Materials.

cmas2d.mat

NUMBER: 1 MATERIAL: Air

QUESTION: Density

VALUE: 1.01

END MATERIAL

NUMBER: 2 MATERIAL: Steel

QUESTION: Density

VALUE: 7850

END MATERIAL

NUMBER:3 MATERIAL: Aluminium

QUESTION: Density

VALUE: 2650

END MATERIAL

NUMBER: 4 MATERIAL: Concrete

QUESTION: Density

VALUE: 2350

END MATERIAL

NUMBER: 5 MATERIAL: Water

QUESTION: Density

VALUE: 997

END MATERIAL

NUMBER: 6 MATERIAL: Sand

QUESTION: Density

VALUE: 1370

END MATERIAL

Figure 1 The GiD Materials window, for assigning materials

## Creating the General File

> > 1.Create the "cmas2d.prb" file. This file contains general information for the calculating module, such as the units system for the problem, or the type of resolution algorithm chosen.

> > 2.Enter the parameters of the general conditions in "cmas2d.prb" using the following format:

PROBLEM DATA

QUESTION: Name of the parameter. If the name is followed by the #CB# instruction, the parameter is a display-type menu. The options in the menu must then be entered between parentheses and separated by commas.
For example, Unit_System#CB#(SI,CGS,User).

VALUE: The default value of the parameter.

...

END GENERAL DATA

> > 3.In GiD, the information in the "cmas2d.prb" file is managed in the materials window (Figure 2), which is located in Data->Problem Data.

Cmas2d.prb PROBLEM DATA QUESTION: Unit_System#CB#(SI,CGS,User) VALUE: SI QUESTION: Title VALUE: Default_title END GENERAL DATA |
Figure 2 The GiD Problem Data window, for configuring of the general conditons of the cmas2d module

## Creating the Conditions File

> > 1.Create the "cmas2d.cnd" file, which specifies the boundary and/or load conditions of the problem type in question. In the present case, this file is where the concentrated weights on specific points of the geometry are indicated.

> > 2.Enter the boundary conditions using the following format:

NUMBER: Identifier of the condition

CONDITION: Name of the condition

CONDTYPE: Type of entity to which the condition is to be applied. This includes the parameters "over points," "over lines," "over surfaces," and "over volumes". In this example the condition is applied "over points."

CONDMESHTYPE: Type of entity of the mesh to which the condition is to be applied. The possible parameters are "over nodes" or "over elems". In this example, the condition is applied on nodes.

QUESTION: Name of the parameter of the condition

VALUE: Default value of the parameter

...

END CONDITION

...

> > 3.In GiD, the information in the "cmas2d.cnd" file is managed in the conditions window (Figure 3), which is found in Data->Conditions.

cmas2d.cnd NUMBER: 1 CONDITION: Point-Weight CONDTYPE: over points CONDMESHTYPE: over nodes QUESTION: Weight VALUE: 0 END CONDITION |
Figure 3 The GiD Conditions window, for assigning the cmas2d boundary and load conditions

## Creating the Data Format File (Template file)

> > 1.Create the "cmas2d.bas" file. This file will define the format of the .dat text file created by GiD. It will store the geometric and physical data of the problem. The .dat file will be the input to the calculating module.

> > NOTE: It is not necessary to have all the information registered in only one .bas file. Each .bas file has a corresponding .dat file.

> > 2.Write the "cmas2d.bas" file as follows:

> > The format of the .bas file is based on commands. A text not preceded by an asterisk is reproduced exactly the same in the .dat file created by GiD. A text preceded by an asterisk is interpreted as a command.

Example:

.bas file |  | .dat file
%%%% Problem Size %%%% Number of Elements & Nodes: *nelem *npoin |  | %%%% Problem Size %%%% Number of Elements & Nodes: 5379 4678

The contents of the "cmas2d.bas" file must be the following:

.bas file
================================================================== General Data File ================================================================== %%%%%%%%%%%%%%%%%% Problem Size %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Number of Elements & Nodes: *nelem *npoin
In this first part of the "cmas2d.bas" file, general information on the project is obtained.

*nelem: returns the total number of elements of the mesh.

*npoin: returns the total number of nodes of the mesh.

Coordinates: Node X Y *set elems(all) *loop nodes *format "%5i%14.5e%14.5e" *NodesNum *NodesCoord(1,real) *NodesCoord(2,real) *end nodes
This command effects a rundown of all the nodes of the mesh, listing their identifiers and coordinates.

*loop, *end: commands used to indicate the beginning and the end of the loop. The command *loop receives a parameter.

*loop nodes: the loop iterates on nodes

*loop elems: the loop iterates on elements

*loop materials: the loop iterates on assigned materials

*set elems(all): the command to include all the elements of the mesh when making the loop.

*format: the command to define the exit format for numerical experssions. This command must be followed by the numerical format expressed in C.

*NodesNum: returns the identifier of the present node

*NodesCoord: returns the coordinates of the present node

*NodesCoord (n, real): returns the coordinate x, y or z in terms of the value n:

n=1 returns the x coordinate

n=2 returns the y coordinate

n=3 returns the z coordinate

Conectivities: Element Node(1) Node(2) Node(3) Material *loop elems *format "%10i%10i%10i%10i%10i" *ElemsNum *ElemsConec *ElemsMat *end elems
This effects a rundown of all the elements of the mesh and provides a list of their identifiers, the nodes that form them, and their assigned material.

*ElemsNum: returns the identifier of the present element

*ElemsConec: returns the nodes of an element in a counterclockwise order

*ElemsMat: returns the number of the assigned material of the present element

Begin Materials Nº Materials= *nmats
This gives the total number of materials of the project

*nmats: returns the total number of materials

Mat. Density *loop materials *format "%4i%13.5e" *set var PROP1(real)=Operation(MatProp(Density,real)) *MatNum *PROP1 *end
This effects a rundown of all the materials of the project and provides a list of the identifiers and densities for each one.

*MatProp (density,real): returns the value of the property "density" of the material in a "real" format.

*Operation (expression): returns the result of an arithmetic expression. This operation must be expressed in C.

*Set var PROP1(real)=Operation(MatProp(Density, real)): assigns the value returned by MatProp (which is the value of the density of the material) to the variable PROP1 (a "real" variable).

*PROP1: returns the value of the variable PROP1.

*MatNum: returns the identifier of the present material

Point conditions *Set Cond Point-Weight *nodes *set var NFIX(int)=CondNumEntities(int) Concentrate Weights *NFIX
This provides the number of entities that have been assigned a particular condition.

*Set Cond Point-Weight *nodes: this command enables the user to select the condition to work with from that moment on. For the present example, select the condition "Point-Weight".

*CondNumEntities(int): returns the number of entites that have been assigned a certain condition.

*Set var NFIX(int)= CondNumEntities(int): assigns the value returned by the command CondNumEntities to the NFIX variable (an "int" variable).

*NFIX: returns the value of the NFIX variable.

Potencials Prescrits: Node Tipus Valor/Etiqueta *Set Cond Point-Weight *nodes *loop nodes *OnlyInCond *NodesNum *cond(1) *end
This effects a rundown of all the nodes assigned the condition "Point-Weight" and provides a list of their identifiers and the first "weight" field of the condition in each case.

*loop nodes *OnlyInCond: executes a loop that will effect a rundown of only the nodes that have been assigned a condition.

*cond(1): returns the number 1 field of a condition previously selected with the *set cond command. The field of the condition may also be selected using the name of the condition, for example cond(weight).

cmas2d.bas

==================================================================

General Data File

==================================================================

%%%%%%%%%%%%%%%%%% Problem Size %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Number of Elements & Nodes:

*nelem *npoin

%%%%%%%%%%%%%%%%%%% Mesh Database %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Coordinates:

Node X Y

*set elems(all)

*loop nodes

*format "%5i%14.5e%14.5e"

*NodesNum *NodesCoord(1,real) *NodesCoord(2,real)

*end nodes

.................................................................

Conectivities:

Element Node(1) Node(2) Node(3) Material

*loop elems

*format "%10i%10i%10i%10i%10i"

*ElemsNum *ElemsConec *ElemsMat

*end elems

.................................................................

Begin Materials

Nº Materials= *nmats

Mat. Density

.................................................................

*loop materials

*format "%4i%13.5e"

*set var PROP1(real)=Operation(MatProp(Density,real))

*MatNum *PROP1

*end

.................................................................

Point conditions

*Set Cond Point-Weight *nodes

*set var NFIX(int)=CondNumEntities(int)

Concentrate Weights

*NFIX

.................................................................

Potencials Prescrits:

Node Tipus

Valor/Etiqueta

*Set Cond Point-Weight *nodes

*loop nodes *OnlyInCond

*NodesNum *cond(1)

*end

.................................................................

> > Creating the Execution File of the Calculating Module

> > 1.Create the "cmas2d.c" file. This file contains the code of the execution program of the calculating module. This execution program reads the problem data provided by GiD, calculates the coordinates of the center of mass of the object and the distance of each element from this point. These results are saved in a text file with the extension .flavia.res.

> > 2.Compile and link the "cmas2d.c" file in order to obtain the executable cmas2d.exe file.

> > The calculating module (cmas2d.exe) reads and generates the files described below.

> > NOTE: The "cmas2d.c" code is explained in the appendix.

> > Creating the Execution File for the Problem Type

> > 1.Create the "cmas2d.bat" file. This file connects the data file(s) (.dat) to to calculating module (the cmas2d.exe program). When the GiD Calculate option is selected, it executes the .bat file for the problem type selected.

> > 2.When GiD executes the .bat file, it transfers three parameters in the following way:

> > > > (parameter 3) / *.bat (parameter 2) / (parameter 1)
> > > > parameter 1: project name
> > > > parameter 2: project directory
> > > > parameter 3: Problem type location directory

> > NOTE: The .bat file as used in Windows is explained below; the shell script for UNIX systems is also included with the documentation of this tutorial.

del %2\%1.boh del %2\%1.flavia.res del %2\%1.flavia.dat
This deletes results files from any previous calculations to avoid confusion.

rem OutputFile: $2/$1.boh
A comment line such as "rem OutputFile: file_name.log" means that the contents of the file indicated will be shown if the user clicks Output View in Calculate à Calculate window (Figure 4). In this example the .boh file is shown. This file contains the coordinates of the center of masses.

Figure 4 The Process window.

rem ErrorFile: $2/$1.err
A comment line such as "rem ErrorFile: file_name.err" means that the indicated file will contain the errors (if any). If the .err file is present at the end of the execution, a window comes up showing the error. The absence of the .err file indicates that the calculation is considered satisfactory. GiD automatically deletes the .err files before initiating a calculation to avoid confusion.

$3/cmas2d.exe $2/$1
Executing the cmas2d.exe file.

cmas2d.bat @ECHO OFF del %2\%1.boh del %2\%1.flavia.res del %2\%1.flavia.dat rem OutputFile: %2\%1.boh rem ErrorFile: %2\%1.err %3\cmas2d.exe %2\%1

> # Executing the calculating module

> In order to more easily understand the way the calculating module works, simple problems with limited practical use have been chosen. Although these problems do not exemplify the full potential of the GiD program, the user may intuit their answers and, therefore, compare the predicted results with those obtained in the simulations.

> > Executing the calculation for an object made of homogeneous material

> > 1.From the Files menu, select the option Read. Select the file “ToMesh2d.gid” and click Open.

Figure 5. Contents of the "ToMesh2d.gid" file.

> > 2.Choose the Data à Problem type à Cmas2d option.

> > 3.Choose Data à Materials. The materials window comes up (Figure 6). From the Materials menu in this window, choose the option Air.

Figure 6. The Materials window

> > 4.Click Assign à Surfaces and select all the surfaces. Press ESC when this step is finished.

> > 5.Choose the Meshing à Generate option.

> > 6.A window appears in which to enter the maximum element size for the mesh to be generated. Enter 2 and click OK. The mesh shown in Figure 7 will be obtained.

Figure 7. The mesh of the object

> > 7.Now the calculation may be initiated. Choose the Calculate option from the Calculate menu, thus executing the calculating module.

> > 8.Wait until a box appears informing that the calculation is finished. (Figure 8)

Figure 8 Process information box

> > 9.Choose the Files à Postprocess option.

> > 10.From the Windows menu, choose the View Results option (Figure 9). A window appears from which to visualize the results. By default, no result is visualized on entering the postprocess.

> > 11.From the View menu in the View Results window, choose the Contour Fill option.

Figure 9 The View Results window .

> > 12.From the Results menu, choose the MC-DISTANCE option. Click Apply. A graphic representation of the calculation is obtained. (See Figure 10)

Figure 10 Visualizing the distance (MC-DISTANCE) from the center of masses of the object
to each element, for an object of homogeneous material

> > 13.The results shown on the screen reproduce those we anticipated at the outset of the problem: the center of mass of an object made of homogeneous material coincides with its geometric center. The .boh file will provide the exact coordinates of this point.

> > Executing the calculation for an object made of heterogeneous material

> > 1.Choose the Files à preprocess option.

> > 2.Choose the Data à Materials option. The Materials window comes up. From the Materials menu in this window, choose Steel. (Figure 11)

Figure 11 The Materials window, with "Steel" selected

> > 3.Click Assign à Surfaces and select the surface indicated in Figure 12. Press ESC when this step is finished.

Figure 12 Assigning the material "Steel" to the surface indicated

> > 4.Choose the Meshing à Generate option.

> > 5.A window comes up in which to enter the maximum element size for the mesh to be generated. Enter 2 and click OK.

> > 6.Choose the Calculate option from the Calculate menu, thus executing the calculating module.

> > 7.Choose the Files à Postprocess option.

> > 8.Visualize the new results.

Figure 13 Visualizing the materials making up the object | Figure 14 Visualizing the distance (MC-DISTANCE) from the center of masses of the object to each element, for an object of heterogeneous material

> > 9.As anticipated, the center of masses is displaced toward the material with greater density.

> > Executing the calculation for an object of heterogeneous material and subject to external point- weight

> > 1.Choose the Files à preprocess option.

> > 2.Choose the Data à Conditions option. A window comes up in which to enter the conditions of the problem (Figure 15).

> > 3.Since the condition to enter acts on points, select over points from the Type menu in the Conditions window.

Figure 15 The Conditions window

> > 4.Enter the value 5e6 into the Weight box. Click Assign and select the point indicated in Figure 16. Press ESC when this step is finished.

Figure 16 The point subject to external weight

> > 5.Choose Meshing à Generate.

> > 6.A window comes up in which to enter the maximum element size for the mesh to be generated. Enter 2 and click OK.

> > 7.Choose the Calculate option from the Calculate menu, thus executing the calculating module.

> > 8.Choose the Files à Postprocess option.

> > 9.Visualize the new results.

Figure 17 Visualizing the distance (MC-DISTANCE) from the center of masses to each element, for an object of heterogeneous material subject to point weight

> > 10.Now the condition is external point weight. As anticipated, the new center of masses is displaced toward the point under weight.

> # Appendix

> The program code for the calculating module

> > 1.The structure of the program that calculates the center of masses (cmas2d.c) is the following:

> > NOTE: In this example, a code for the program will be developed in C. Nevertheless, any language of choice may be used.

2. The code of the program that calculates the center of masses (cmas2d.c) is the following:

#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <string.h> #include <math.h> #define MAXMAT 1000 #define MAXCND 1000 char projname[80]; int i, ielem, inod, icnd; double *x, *y int *N, *imat; int nodc[MAXCND]; double rho[MAXMAT], wval[MAXCND]; int Nelem, Nnod, Nmat, Ncnd; double x_CG, y_CG void input(void); void calculate(void); void output(void);

> Declaration of variables and constants used in the program.

void main (int argc, char *argv[]) { void input(void); void calculate(void); void output(void); strcpy (projname, argv[1]); input(); calculate(); output(); }

> The main program.

> The main program is called up from the cmas2d.bat file and has as parameters the name of the project. This name is stored in the variable projname.

> The main program calls up the input (), calculate () and output () functions.

> The input function reads the .dat file generated by GiD. The .dat file contains the information on the mesh. The calculate function processes the data read and generates the results. The output function creates the results files.

void input () { char filedat[80], sau1[80], sau2[80]; FILE* fp; Int aux,j; Void jumpline (FILE*); Strcpy(filedat, projname); Strcat(filedat,".dat"); fp = fopen(filedat, "r");

> The input() function.

> The first part of the input function links the project name with the .dat extension, thus obtaining the name of the file that is to be read. This file is opened in order to read.

> The jumpline(FILE*) function is declared. This function reads 80 bytes of the file that it receives as a parameter. It will also be used to jump lines of the text when reading the .dat file.

for (i=0; i<6; i++) jumpline (fp); fscanf(fp, "%d %d", &Nelem, &Nnod);

> The first six lines of the .dat file are jumped over since these are lines of information for the user (see .bas file). Then the total number of elements and nodes of the project are read and stored in the variables Nelem and Nnod respectively.

x=(double *) malloc((Nnod+1)*sizeof(double)); if (x==NULL) {error=1;}

y=(double *) malloc((Nnod+1)*sizeof(double)); if (y==NULL) {error=1;}

N= (int *) malloc((Nelem+1)*3*sizeof(int)); if (N==NULL) {error=1;}

imat=(int *) malloc((Nelem+1)*sizeof(int)); if (N==NULL) {error=1;}

if (error)

{

strcpy(fileerr, projname);

strcat(fileerr,".err");

ferr = fopen(fileerr, "w");

fprintf(ferr, "\n \n \n ***** ERROR: Not enough memory. ***** \n");

fprintf(ferr, "(Try to calculate with less elements)\n");

exit(1);

}

for (i=0; i<6; i++)

jumpline (fp);

> Space is reserved for storing the coordinates of the nodes (pointers x, y), the connectivities (pointer N), and the materials corresponding to each element (pointer imat).
> In case of error (insufficient memory), a file is created with the extension .err. This file contains information about the error and the program is aborted.
> The next six lines are jumped over.

/* reading the coordinates */ for (inod=1; inod<=Nnod; inod++) fscanf (fp, "%d %lf %lf", &aux, &x[inod], &y[inod]); for (i=0; i<6; i++) jumpline (fp);

> The coordinates of the nodes are read and stored in the x and y variables. The node identifier indexes the tables of coordinates.

/* reading connectivities */ for (ielem=1; ielem<=Nelem; ielem++){ fscanf (fp, "%d", &aux); for(j=0;j<3;j++) fscanf (fp, "%d", &N[(ielem-1)*3+j]); fscanf (fp, "%d", &imat[ielem]); if (imat[ielem]==0) {strcpy(fileerr, projname); strcat(fileerr,".err"); ferr = fopen(fileerr, "w"); fprintf(ferr,"\n \n \n **ERROR: Elements with no material!!**\n"); exit(1); } }

> The connectivities are read and the N variable is saved. This variable is a Nelem x 3- size table with two fields. The nodes (3 nodes) forming the element are saved in the first field. The element identifiers are saved in the second.
> All the elements are checked, ensuring that they have been assigned a material. If the identifier of the material is 0 (meaning that no material has been assigned to the element), an .err file is created containing information about the error and the program is aborted.

for (i=0; i<5; i++)

jumpline (fp);

fscanf(fp, "%s %s %d",sau1, sau2, &Nmat );

for (i=0; i<3; i++)

jumpline (fp);

/* reading density of each material */

for (i=1; i<=Nmat; i++)

fscanf (fp, "%d %lf", &aux, &rho[i]);

for (i=0; i<4; i++)

jumpline (fp);

/* reading conditions*/

fscanf(fp, "%d", &Ncnd);

for (i=0; i<6; i++)

jumpline (fp);

for (icnd=1; icnd<=Ncnd; icnd++)

{

fscanf (fp, "%d %lf", &nodc[icnd], &wval[icnd]);

jumpline (fp);

}

fclose (fp);

}

> Reading the remaining information in the .dat file.
> The total number of materials is read and stored in the Nmat variable.
> The density of each material are read and stored in the rho table. The material identifier indexes the densities.
> The total number of conditions is read and stored in the Ncnd variable.
> The nodes associated to a condition are read and stored in the nodc table indexed by the condition identifier. The value of the condition is stored in wval, another table indexed by the condition identifier.

void calculate () { double v,aux1,aux2,aux3; int n1, n2, n3; int mat; double x_CGi, y_CGi; double x_num=0, y_num=0, den=0;

> The calculate() function.

> This is the function that calculates the center of masses. Declaration of the local variables used in calculate().

for (ielem=1; ielem<=Nelem; ielem++)

{

n1= N[0+(ielem-1)*3];

n2= N[1+(ielem-1)*3];

n3= N[2+(ielem-1)*3];

/* Calculating the volume (volume is the area, provided we

are dealing with 3D surfaces) */

v=fabs(x[n1]*y[n2]+x[n2]*y[n3]+x[n3]*y[n1]-x[n1]*y[n3]-x[n2]*y[n1]- x[n3]*y[n2])/2;

/* The geometric center of the element is calculated */

x_CGi= (x[n1]+x[n2]+x[n3])/3;

y_CGi= (y[n1]+y[n2]+y[n3])/3;

/* sums are calculated*/

mat= imat[ielem];

x_num+= rho[mat]*v*x_CGi;

y_num+= rho[mat]*v*y_CGi;

den+= rho[mat]*v;

}

> Main loop of the calculating function.

> The identifier of the nodes of the present element are saved in n1, n2, n3.

> This loop makes a rundown of all the elements in the mesh. The volume is calculated for each element. (Here, the volume is the area, provided we are dealing with 3D surfaces.) The volume calculations are stored in the v variable.

> The geometric center of the element is calculated (coinciding with the center of gravity) and the coordinates are stored in the x_Cgi and y_Cgi variables.

> The numerator sums are calculated. When the loop is finished, the following sums are stored in the x_num and y_num variables:

> x_num =
> y_num =
> The denominator sum is calculated. When the loop is finished, the following sum is stored in the den variable:
> den =

/* point weights */ for (icnd=1; icnd<=Ncnd; icnd++) { inod= nodc[icnd]; x_num+= wval[icnd]*x[inod]; y_num+= wval[icnd]*y[inod]; den+= wval[icnd]; }

> Then, the calculations associated with point weights are run using a loop that makes a rundown of all the conditions.
> The results are added to the x_num, y_num,and den variables, as seen in the formulae:
> x_num = +
> y_num = +
> The value of point weights is added to the variable den.
> den = +

x_CG= (x_num/den); y_CG= (y_num/den); }

> Finally, the result of dividing the x_num and y_num variables by the den variable is stored in the x_CG and y_CG variables.
> x_CG = (x_num/den) à x_CG =
> y_CG = (y_num/den) à y_CG =

void output() { char filedat[80]; FILE *fp, *fptest; float raiz; double pot;

> The output() function.

> The output() function creates three files: .flavia.dat, .flavia.res, and .boh.

> The mesh of the project is stored in the .flavia.dat file. The mesh is a 2D surface.
> The results to be visualized in the GiD post-process are stored in the .flavia.res file. It is this file that stores the data which enables GiD to represent the distance of each point from the corresponding center of masses.
> The numeric value of the center of masses is saved in the .boh file. The accuracy of this value is directly proportionate to the element size.

strcpy(filedat, projname); strcat(filedat,".boh"); fptest = fopen(filedat, "w"); fprintf (fptest, "FILE: %s\n", projname); fprintf (fptest, "CMAS2D\n2D routine to calculate the mass center of an heterogeneus object. \n January 2000\t Rienzi Gianfranco\t\t\t\tCIMNE\n"); fprintf (fptest, "\n\n\t====> mass center: %lf %lf \n", x_CG, y_CG);

> Creating the .boh file.

> The extension .boh is suffixed to the name of the project and the file is created that will contain the numeric value of the position of the center of masses, which in turn is stored in the x_CG and y y_CG variables of the program.

/* writing .flavia.dat */

strcpy(filedat, projname);

strcat(filedat,".flavia.dat");

fp = fopen(filedat, "w");

fprintf (fp, "FILE: %s\n", projname);

fprintf (fp, "\n");

fprintf (fp, "CMAS\n");

fprintf (fp, "Routine to calculate the mass center of an object.\n");

fprintf (fp, "\t\t\t\t\tCIMNE\n");

fprintf (fp, "2000 G. Rienzi\n");

fprintf (fp, " %6d %6d 3\n", Nelem, Nnod);

fprintf (fp, "\t\tNODES\n");

for (inod=1; inod<=Nnod; inod++)

fprintf (fp, " %6d %14.6e %14.6e \n", inod, x[inod], y[inod]);

fprintf (fp, "\t\tCONECTIVITIES\n");

for (ielem=1; ielem<=Nelem; ielem++)

fprintf (fp, " %6d %6d %6d %6d %6d\n", ielem, N[0+(ielem-1)*3], N[1+(ielem-1)*3], N[2+(ielem-1)*3], imat[ielem]);

fclose (fp);

> Creating the .flavia.dat file.

> The .flavia.dat file contains information about a 2D surface. The .flavia.dat file has a particular format which must remain intact if GiD is to read it. The format of this file is the following:

> · There are 6 header lines for entering general information about the project. For this example, enter the following information:
> FILE: "project_name"
> CMAS
> Program for calculating the center of masses
> CIMNE
> 2000 G. Rienzi
> · Then enter the number of elements and nodes in the mesh using the following format:
> Number of elements (Nelem) number of nodes (Nnod) element type (3).
> A type-3 element means it is a three-node triangle.
> · The next line is for general information. For this example, enter the following text:
> NODES
> · Then list the coordinates of all the nodes using the following format:
> Identifier of the node (inod) x coordinate (x[inod]) y coordinate (y[inod])
> · The next line is for general information. For this example, enter the following text:
> CONECTIVITIES
> · To conclude, list the connectivities between nodes. For each element, list these variables:
> Identifier of the element (ielem)
> 1st node (N[0+(ielem-1)*3])
> 2nd node (N[1+(ielem-1)*3])
> 3rd node (N[2+(ielem-1)*3])
> material (imat[ielem])

/* writing .flavia.res */

strcpy(filedat, projname);

strcat(filedat,".flavia.res");

fp = fopen(filedat, "w");

fprintf (fp, "MC-DISTANCE 2 1 1 1 0\n");

for (inod=1; inod<=Nnod; inod++)

{

/* distance from the center of masses */

raiz= (x_CG-x[inod])*(x_CG-x[inod]) + (y_CG-y[inod])*(y_CG -y[inod]);

pot = sqrt ((double)raiz);

fprintf (fp, " %6d %14.6lf\n", inod, pot);

}

fclose (fp);

fclose (fptest);

free(x);

free(y);

free(N);

free(imat);

> Creating the .flavia.res file. The output data (results) are stored in this file.
> The format of the .flavia.res file is as follows:
> · On the first line, enter the variables defining the type of result. The first parameter of the line is the title appearing in the GiD post-process menu. For this example, the title MC-DISTANCE has been chosen.
> Then enter the values 2 1 1 1 0.
> The first parameter is the type of analysis: 2 corresponds to a load analysis.
> The second parameter is the number of steps in the calculation. In this example there is 1 step.
> The third parameter is the type of result: 1 corresponds to a scaler result.
> The fourth parameter is the position associated to the results: 1 means the results are associated to nodes.
> The fifth parameter is a description of each component: 0 means there is no description.
> · To conclude, list the results (distance from the center of masses) in the following format:
> Identifier of the node (inod) associated result (pot)

/* jumpline function */ void jumpline (FILE* filep) { char buffer[80]; fgets(buffer, 80, filep); }

Jumpline function.

Cmas2d.c

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <string.h>

#include <math.h>

#define MAXMAT 1000

#define MAXCND 1000

char projname[80];

int i, ielem, inod, icnd;

double *x, *y;

int *N, *imat;

int nodc[MAXCND];

double rho[MAXMAT], wval[MAXCND];

int Nelem, Nnod, Nmat, Ncnd;

double x_CG, y_CG;

void input(void);

void calculate(void);

void output(void);

void main (int argc, char *argv[])

{

strcpy (projname, argv[1]);

input();

calculate();

output();

}

void input ()

{

char filedat[80], sau1[80], sau2[80];

FILE* fp;

int aux,j;

void jumpline (FILE*);

strcpy(filedat, projname);

strcat(filedat,".dat");

fp = fopen(filedat, "r");

for (i=0; i<6; i++)

jumpline (fp);

fscanf(fp, "%d %d", &Nelem, &Nnod);

x=(double *) malloc((Nnod+1)*sizeof(double)); if (x==NULL) {error=1;}

y=(double *) malloc((Nnod+1)*sizeof(double)); if (y==NULL) {error=1;}

N= (int *) malloc((Nelem+1)*3*sizeof(int)); if (N==NULL) {error=1;}

imat=(int *) malloc((Nelem+1)*sizeof(int)); if (N==NULL) {error=1;}

if (error)

{

strcpy(fileerr, projname);

strcat(fileerr,".err");

ferr = fopen(fileerr, "w");

fprintf(ferr, "\n \n \n ***** ERROR: Not enough memory. ***** \n");

fprintf(ferr, "(Try to calculate with less elements)\n");

exit(1);

}

for (i=0; i<6; i++)

jumpline (fp);

/* reading the coordinates*/

for (inod=1; inod<=Nnod; inod++)

fscanf (fp, "%d %lf %lf", &aux, &x[inod], &y[inod]);

for (i=0; i<6; i++)

jumpline (fp);

/* reading connectivities */

for (ielem=1; ielem<=Nelem; ielem++){

fscanf (fp, "%d", &aux);

for(j=0;j<3;j++) fscanf (fp, "%d", &N[(ielem-1)*3+j]);

fscanf (fp, "%d", &imat[ielem]);

if (imat[ielem]==0)

{

strcpy(fileerr, projname);

strcat(fileerr,".err");

ferr = fopen(fileerr, "w");

fprintf(ferr, "\n \n \n **ERROR: Elements with no material!!** \n");

exit(1);

}

}

for (i=0; i<5; i++)

jumpline (fp);

fscanf(fp, "%s %s %d",sau1, sau2, &Nmat );

for (i=0; i<3; i++)

jumpline (fp);

/* reading density of each material */

for (i=1; i<=Nmat; i++)

fscanf (fp, "%d %lf", &aux, &rho[i]);

for (i=0; i<4; i++)

jumpline (fp);

/* reading conditions */

fscanf(fp, "%d", &Ncnd);

for (i=0; i<6; i++)

jumpline (fp);

for (icnd=1; icnd<=Ncnd; icnd++)

{

fscanf (fp, "%d %lf", &nodc[icnd], &wval[icnd]);

jumpline (fp);

}

fclose (fp);

}

void calculate ()

{

double v, aux1,aux2,aux3;

int n1, n2, n3;

int mat;

double x_CGi, y_CGi;

double x_num=0, y_num=0, den=0;

for (ielem=1; ielem<=Nelem; ielem++)

{

n1= N[0+(ielem-1)*3];

n2= N[1+(ielem-1)*3];

n3= N[2+(ielem-1)*3];

/* Calculating the volume (volume is the area,

provided we are dealing with 3D surfaces) */

v=fabs(x[n1]*y[n2]+x[n2]*y[n3]+x[n3]*y[n1]-x[n1]*y[n3]-x[n2]*y[n1]-x[n3]*y[n2])/2;

/* The geometric center of the element is calculated */

x_CGi= (x[n1]+x[n2]+x[n3])/3;

y_CGi= (y[n1]+y[n2]+y[n3])/3;

/* sums are calculated */

mat= imat[ielem];

x_num+= rho[mat]*v*x_CGi;

y_num+= rho[mat]*v*y_CGi;

den+= rho[mat]*v;

}

/* point weights */

for (icnd=1; icnd<=Ncnd; icnd++)

{

inod= nodc[icnd];

x_num+= wval[icnd]*x[inod];

y_num+= wval[icnd]*y[inod];

den+= wval[icnd];

}

x_CG= (x_num/den);

y_CG= (y_num/den);

}

void output()

{

char filedat[80];

FILE *fp, *fptest;

double raiz;

double pot;

strcpy(filedat, projname);

strcat(filedat,".boh");

fptest = fopen(filedat, "w");

fprintf (fptest, "FILE: %s\n", projname);

fprintf (fptest, "CMAS2D\n2D routine to calculate the mass center of an heterogeneus object.\nJanuary 2000\tRienzi Gianfranco\t\t\t\tCIMNE\n");

fprintf (fptest, "\n\n\t====> mass center: %lf %lf \n", x_CG, y_CG);

/* writing .flavia.dat */

strcpy(filedat, projname);

strcat(filedat,".flavia.dat");

fp = fopen(filedat, "w");

fprintf (fp, "FILE: %s\n", projname);

fprintf (fp, "CMAS\n");

fprintf (fp, "Routine to calculate the mass center of an object.\n");

fprintf (fp, "\t\t\t\t\tCIMNE\n");

fprintf (fp, "2000 G. Rienzi\n");

fprintf (fp, "\n");

fprintf (fp, " %6d %6d 3\n", Nelem, Nnod);

fprintf (fp, "\t\tNODES\n");

for (inod=1; inod<=Nnod; inod++)

fprintf (fp, " %6d %14.6e %14.6e\n", inod, x[inod], y[inod]);

fprintf (fp, "\t\tCONECTIVITIES\n");

for (ielem=1; ielem<=Nelem; ielem++){

fprintf (fp, " %6d %6d %6d %6d %6d\n", ielem, N[0+(ielem-1)*3], N[1+(ielem-1)*3], N[2+(ielem-1)*3], imat[ielem]);

}

fclose (fp);

/* writing .flavia.res */

strcpy(filedat, projname);

strcat(filedat,".flavia.res");

fp = fopen(filedat, "w");

fprintf (fp, "MC-DISTANCE 2 1 1 1 0\n");

for (inod=1; inod<=Nnod; inod++)

{

/* distance from the center of masses */

raiz= (x_CG-x[inod])*(x_CG-x[inod]) + (y_CG-y[inod])*(y_CG-y[inod]);

pot = sqrt (raiz);

fprintf (fp, " %6d %14.6lf\n", inod, pot);

}

fclose (fp);

fclose (fptest);

free(x);

free(y);

free(N);

free(imat);

}

/* jumpline function */

void jumpline (FILE* filep)

{

char buffer[80];

fgets(buffer, 80, filep);

}