diff --git a/CMakeLists.txt b/CMakeLists.txt
index d5dd50b3a6..09b6615107 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,8 +12,10 @@
if(APPLE)
# message("you need to have gcc-gfrotran installed using HomeBrew")
- set(CMAKE_C_COMPILER "/usr/local/bin/gcc-9")
- set(CMAKE_CXX_COMPILER "/usr/local/bin/g++-9")
+ # set(CMAKE_C_COMPILER "/usr/bin/gcc")
+ # set(CMAKE_CXX_COMPILER "/usr/bin/g++")
+ set(CMAKE_C_COMPILER "/usr/local/bin/gcc-10")
+ set(CMAKE_CXX_COMPILER "/usr/local/bin/g++-10")
set(CMAKE_Fortran_COMPILER "/usr/local/bin/gfortran")
# set(BLA_VENDOR "OpenBLAS")
# option(HUNTER_ENABLED "Enable Hunter package manager support" OFF)
@@ -23,12 +25,16 @@ endif()
+
+
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Build type (Release, Debug, RelWithDebugInfo, MinSizeRel)")
ENDIF()
PROJECT(Elmer Fortran C CXX)
-CMAKE_MINIMUM_REQUIRED(VERSION 2.8.9)
+
+# CMAKE_VERSION seems to require this in minimum
+CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)
IF(APPLE)
SET(CMAKE_MACOSX_RPATH 1)
@@ -122,8 +128,8 @@ MARK_AS_ADVANCED(ELMER_INSTALL_LIB_DIR)
ENABLE_TESTING()
-SET(ELMER_FEM_MAJOR_VERSION 8)
-SET(ELMER_FEM_MINOR_VERSION 4)
+SET(ELMER_FEM_MAJOR_VERSION 9)
+SET(ELMER_FEM_MINOR_VERSION 0)
SET(ELMER_FEM_VERSION
${ELMER_FEM_MAJOR_VERSION}.${ELMER_FEM_MINOR_VERSION})
@@ -178,13 +184,33 @@ IF(WITH_OpenMP)
OpenMP_Fortran_FLAGS
OpenMP_CXX_FLAGS
)
-
- FIND_PACKAGE(OpenMP REQUIRED)
+
# Add OpenMP flags to compilation flags
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
- SET(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${OpenMP_Fortran_FLAGS}")
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
+ # if(APPLE)
+ # if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ # set(OpenMP_C "${CMAKE_C_COMPILER}")
+ # set(OpenMP_C_FLAGS "-fopenmp=libomp -Wno-unused-command-line-argument")
+ # set(OpenMP_C_LIB_NAMES "libomp" "libgomp" "libiomp5")
+ # set(OpenMP_libomp_LIBRARY ${OpenMP_C_LIB_NAMES})
+ # set(OpenMP_libgomp_LIBRARY ${OpenMP_C_LIB_NAMES})
+ # set(OpenMP_libiomp5_LIBRARY ${OpenMP_C_LIB_NAMES})
+ # endif()
+ # if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ # set(OpenMP_CXX "${CMAKE_CXX_COMPILER}")
+ # set(OpenMP_CXX_FLAGS "-fopenmp=libomp -Wno-unused-command-line-argument")
+ # set(OpenMP_CXX_LIB_NAMES "libomp" "libgomp" "libiomp5")
+ # set(OpenMP_libomp_LIBRARY ${OpenMP_CXX_LIB_NAMES})
+ # set(OpenMP_libgomp_LIBRARY ${OpenMP_CXX_LIB_NAMES})
+ # set(OpenMP_libiomp5_LIBRARY ${OpenMP_CXX_LIB_NAMES})
+ # endif()
+ # else()
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
+ SET(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${OpenMP_Fortran_FLAGS}")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
+ # endif()
+ FIND_PACKAGE(OpenMP REQUIRED)
+
# Test compiler support for OpenMP 4.0 features used
INCLUDE(testOpenMP40)
IF(CMAKE_Fortran_COMPILER_SUPPORTS_OPENMP40)
@@ -199,6 +225,15 @@ IF(WITH_OpenMP)
ENDIF()
ENDIF()
+# Get rid of the annoying rank mismatch warning
+IF("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+ IF(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 9.9)
+ SET(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fallow-argument-mismatch")
+# SET(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -std=legacy")
+ ENDIF()
+ENDIF()
+
+
IF(WITH_MPI)
# Advanced properties
MARK_AS_ADVANCED(
diff --git a/ElmerGUI/Application/CMakeLists.txt b/ElmerGUI/Application/CMakeLists.txt
index 5dac55c4e9..f6ee9e0f89 100644
--- a/ElmerGUI/Application/CMakeLists.txt
+++ b/ElmerGUI/Application/CMakeLists.txt
@@ -102,6 +102,8 @@ SET(SOURCES src/bodypropertyeditor.cpp
twod/twodview.cpp
twod/curveeditor.cpp)
+ADD_DEFINITIONS(-DEG_PLUGIN)
+
IF(WITH_QWT)
SET(HEADERS ${HEADERS} src/convergenceview.h)
SET(SOURCES ${SOURCES} src/convergenceview.cpp)
diff --git a/ElmerGUI/Application/edf-extra/vectorhelmholtz.xml b/ElmerGUI/Application/edf-extra/vectorhelmholtz.xml
index 99c5d02bd4..42274f45e5 100644
--- a/ElmerGUI/Application/edf-extra/vectorhelmholtz.xml
+++ b/ElmerGUI/Application/edf-extra/vectorhelmholtz.xml
@@ -36,24 +36,24 @@
Material properties
- Inverse Relative Permeability
+ Relative Permittivity
String
- Give the inverse relative permeability compared to vacuum (real part).
+ Give the relative permittivity of medium (real part).
- Inverse Relative Permeability im
+ Relative Permittivity im
String
- Give the inverse relative permeability compared to vacuum (imag part).
+ Give the relative permittivity of medium (imag part).
- Relative Permittivity
+ Relative Reluctivity
String
- Give the relative permittivity of medium (real part).
+ Give the relative reluctivity of the medium (real part).
- Relative Permittivity im
+ Relative Reluctivity im
String
- Give the relative permittivity of medium (imag part).
+ Give the relative reluctivity of the medium (imag part).
@@ -308,7 +308,7 @@
Calculate Poynting Vector
- Calculate Div Poynting Vector
+ Calculate Div of Poynting Vector
Logical
Calculate Divergence of Poyntings vector
diff --git a/ElmerGUI/Application/plugins/egconvert.cpp b/ElmerGUI/Application/plugins/egconvert.cpp
index 7e5324dc2d..c40d26f4c8 100644
--- a/ElmerGUI/Application/plugins/egconvert.cpp
+++ b/ElmerGUI/Application/plugins/egconvert.cpp
@@ -31,16 +31,19 @@
#include
#include
#include
+#include
#include "egutils.h"
#include "egdef.h"
#include "egtypes.h"
#include "egmesh.h"
-#include "egnative.h"
#include "egconvert.h"
-#define getline fgets(line,MAXLINESIZE,in)
+#define GETLINE ioptr=fgets(line,MAXLINESIZE,in)
+#define GETLONGLINE ioptr=fgets(longline,LONGLINESIZE,in)
+static int linenumber;
+static char *ioptr;
static int Getrow(char *line1,FILE *io,int upper)
{
@@ -51,8 +54,9 @@ static int Getrow(char *line1,FILE *io,int upper)
line0[i] = ' ';
newline:
-
charend = fgets(line0,MAXLINESIZE,io);
+ linenumber += 1;
+
isend = (charend == NULL);
if(isend) return(1);
@@ -72,9 +76,6 @@ static int Getrow(char *line1,FILE *io,int upper)
return(0);
}
-
-
-
static int GetrowDouble(char *line1,FILE *io)
{
int i,isend;
@@ -84,8 +85,9 @@ static int GetrowDouble(char *line1,FILE *io)
line0[i] = ' ';
newline:
-
charend = fgets(line0,MAXLINESIZE,io);
+ linenumber += 1;
+
isend = (charend == NULL);
if(isend) return(1);
@@ -116,6 +118,8 @@ static int Comsolrow(char *line1,FILE *io)
line0[i] = ' ';
charend = fgets(line0,MAXLINESIZE,io);
+ linenumber += 1;
+
isend = (charend == NULL);
if(isend) return(1);
@@ -135,6 +139,7 @@ static void FindPointParents(struct FemType *data,struct BoundaryType *bound,
int sideind[MAXNODESD1],elemsides,side,sidenodes,hit,nohits;
int *elemhits;
+
info = TRUE;
sideelem = 0;
@@ -152,21 +157,24 @@ static void FindPointParents(struct FemType *data,struct BoundaryType *bound,
printf("Boundary types are in interval [%d, %d]\n",minboundary,maxboundary);
printf("Boundary nodes are in interval [%d, %d]\n",minnode,maxnode);
}
+
indx = Ivector(1,data->noknots);
+ printf("Allocating hit table of size: %d\n",data->noknots);
elemhits = Ivector(1,data->noknots);
for(i=1;i<=data->noknots;i++) elemhits[i] = 0;
+
for(elemind=1;elemind<=data->noelements;elemind++) {
elemtype = data->elementtypes[elemind];
elemsides = elemtype % 100;
-
+
for(i=0;itopology[elemind][i]] += 1;
+ j = data->topology[elemind][i];
+ elemhits[j] += 1;
}
}
-
for(boundarytype=minboundary;boundarytype <= maxboundary;boundarytype++) {
int boundfirst,bchits,bcsame,sideelemtype2;
int sideind2[MAXNODESD1];
@@ -187,17 +195,13 @@ static void FindPointParents(struct FemType *data,struct BoundaryType *bound,
elemsides = elemtype / 100;
if(elemsides == 8) elemsides = 6;
else if(elemsides == 5) elemsides = 4;
- else if(elemsides == 6) elemsides = 5;
-
- if(0) printf("ind=%d type=%d sides=%d\n",elemind,elemtype,elemsides);
-
+ else if(elemsides == 6 || elemsides == 7) elemsides = 5;
+
/* Check whether the bc nodes occupy every node in the selected side */
for(side=0;sidetopology[elemind][i]);
+ printf("\n");
+
+ hit = TRUE;
+ }
+
+
if(hit == TRUE) {
@@ -254,6 +275,10 @@ static void FindPointParents(struct FemType *data,struct BoundaryType *bound,
}
sideelem += 1;
+
+ if( sideelem > bound->nosides ) {
+ printf("There are more side elements than allocated for (%d vs. %d)\n",sideelem,bound->nosides);
+ }
bound->parent[sideelem] = elemind;
bound->side[sideelem] = side;
bound->parent2[sideelem] = 0;
@@ -275,7 +300,7 @@ static void FindPointParents(struct FemType *data,struct BoundaryType *bound,
if(info) printf("Found %d side elements formed by %d points.\n",
sideelem,boundarynodes);
- bound->nosides = sideelem;
+ bound->nosides = MIN( sideelem, bound->nosides );
return;
}
@@ -291,24 +316,26 @@ int LoadAbaqusInput(struct FemType *data,struct BoundaryType *bound,
results in ABAQUS format.
*/
{
- int noknots,noelements,elemcode,maxnodes,material;
- int mode,allocated,nvalue,nvalue2,maxknot,nosides;
- int boundarytype,boundarynodes,elsetactive;
- int *nodeindx = NULL,*boundindx = NULL;
-
+ int noknots,noelements,elemcode,maxnodes,material,maxelem,nodeoffset;
+ int mode,allocated,nvalue,nvalue2,maxknot,nosides,elemnodes,ncum;
+ int boundarytype,boundarynodes,elsetactive,elmatactive,cont;
+ int *nodeindx=NULL,*boundindx=NULL,*materials=NULL,*elemindx=NULL;
+ char *pstr;
char filename[MAXFILESIZE];
char line[MAXLINESIZE];
- int i,j,*ind = NULL;
+ int i,j,k,*ind=NULL;
FILE *in;
Real rvalues[MAXDOFS];
int ivalues[MAXDOFS],ivalues0[MAXDOFS];
-
+ int setmaterial;
+ int debug,firstline;
+ char entityname[MAXNAMESIZE];
strcpy(filename,prefix);
if ((in = fopen(filename,"r")) == NULL) {
AddExtension(prefix,filename,"inp");
if ((in = fopen(filename,"r")) == NULL) {
- printf("LoadAbaqusInput: opening of the ABAQUS-file '%s' wasn't succesfull !\n",
+ printf("LoadAbaqusInput: opening of the ABAQUS-file '%s' wasn't successful !\n",
filename);
return(1);
}
@@ -319,18 +346,23 @@ int LoadAbaqusInput(struct FemType *data,struct BoundaryType *bound,
allocated = FALSE;
maxknot = 0;
+ maxelem = 0;
elsetactive = FALSE;
-
+ elmatactive = FALSE;
+
/* Because the file format doesn't provide the number of elements
or nodes the results are read twice but registered only in the
second time. */
+ debug = FALSE;
+
omstart:
mode = 0;
maxnodes = 0;
noknots = 0;
noelements = 0;
+ nodeoffset = 0;
elemcode = 0;
boundarytype = 0;
boundarynodes = 0;
@@ -339,65 +371,170 @@ int LoadAbaqusInput(struct FemType *data,struct BoundaryType *bound,
for(;;) {
- /* getline; */
+ /* GETLINE; */
if (Getrow(line,in,TRUE)) goto end;
/* if(!line) goto end; */
/* if(strstr(line,"END")) goto end; */
- if(strstr(line,"**")) {
- if(info && !allocated) printf("comment: %s",line);
- }
- else if(strrchr(line,'*')) {
- if(strstr(line,"HEAD")) {
- mode = 1;
+
+ if(strrchr(line,'*')) {
+ if( mode == 2 ) {
+ printf("Number of nodes so far: %d\n",noknots);
}
- else if(strstr(line,"NODE")) {
- if(strstr(line,"SYSTEM=R")) data->coordsystem = COORD_CART2;
- if(strstr(line,"SYSTEM=C")) data->coordsystem = COORD_AXIS;
- if(strstr(line,"SYSTEM=P")) data->coordsystem = COORD_POLAR;
- mode = 2;
+ else if( mode == 3 ) {
+ printf("Number of elements so far: %d\n",noelements);
+ if(elmatactive) {
+ nodeoffset = noknots;
+ printf("Node offset is %d\n",nodeoffset);
+ }
}
- else if(strstr(line,"ELEMENT")) {
- if(!elsetactive) material++;
- if(strstr(line,"S3R") || strstr(line,"STRI3"))
- elemcode = 303;
- else if(strstr(line,"2D4") || strstr(line,"SP4") || strstr(line,"AX4")
- || strstr(line,"S4") || strstr(line,"CPE4"))
- elemcode = 404;
- else if(strstr(line,"2D8") || strstr(line,"AX8"))
- elemcode = 408;
- else if(strstr(line,"3D4"))
- elemcode = 504;
- else if(strstr(line,"3D5"))
- elemcode = 605;
- else if(strstr(line,"3D6"))
- elemcode = 706;
- else if(strstr(line,"3D8"))
- elemcode = 808;
- else if(strstr(line,"3D20"))
- elemcode = 820;
- else
- printf("Unknown element code: %s\n",line);
- if(maxnodes < elemcode%100) maxnodes = elemcode%100;
- mode = 3;
- if(1) printf("Loading elements of type %d starting from element %d.\n",
- elemcode,noelements);
+ if( strstr(line,"**") ) {
+ if( strstr(line,"**HWCOLOR") )
+ mode = 10;
+ else if( strstr(line,"**HWNAME") )
+ mode = 10;
+ else if( strstr(line,"**HMASSEM") )
+ mode = 10;
+ else if( strstr(line,"**HM_COMP") )
+ mode = 10;
+ else if( strstr(line,"**HM_PROP") )
+ mode = 10;
+ else
+ if(info && !allocated) printf("comment: %s",line);
+ }
+ else if(strstr(line,"HEAD")) {
+ mode = 1;
+ }
+ else if(strstr(line,"*NODE")) {
+ if(pstr = strstr(line,"NODE OUTPUT")) {
+ mode = 10;
+ }
+ else {
+ if(strstr(line,"SYSTEM=R")) data->coordsystem = COORD_CART2;
+ if(strstr(line,"SYSTEM=C")) data->coordsystem = COORD_AXIS;
+ if(strstr(line,"SYSTEM=P")) data->coordsystem = COORD_POLAR;
+ mode = 2;
+ }
}
- else if(strstr(line,"BOUNDARY") || strstr(line,"CLOAD")) {
+ else if(strstr(line,"*ELEMENT")) {
+ if(pstr = strstr(line,"ELEMENT OUTPUT")) {
+ mode = 10;
+ }
+ else {
+ if(!(elsetactive || elmatactive)) material++;
+ if(strstr(line,"S3") || strstr(line,"STRI3") || strstr(line,"M3D3"))
+ elemcode = 303;
+ else if(strstr(line,"2D4") || strstr(line,"SP4") || strstr(line,"AX4")
+ || strstr(line,"S4") || strstr(line,"CPE4"))
+ elemcode = 404;
+ else if(strstr(line,"2D8") || strstr(line,"AX8") || strstr(line,"DS8") )
+ elemcode = 408;
+ else if(strstr(line,"3D4"))
+ elemcode = 504;
+ else if(strstr(line,"3D5"))
+ elemcode = 605;
+ else if(strstr(line,"3D6"))
+ elemcode = 706;
+ else if(strstr(line,"3D15"))
+ elemcode = 715;
+ else if(strstr(line,"3D8"))
+ elemcode = 808;
+ else if(strstr(line,"3D20"))
+ elemcode = 820;
+ else
+ printf("Unknown element code: %s\n",line);
+
+ if(pstr = strstr(line,"ELSET=")) {
+ if(allocated) {
+ printf("Loading element set %d from %s",material,pstr+6);
+ }
+ }
+
+ elemnodes = elemcode % 100;
+ maxnodes = MAX( maxnodes, elemnodes);
+ mode = 3;
+ if(allocated) {
+ printf("Loading elements of type %d starting from element %d.\n",
+ elemcode,noelements);
+ if(!(elsetactive || elmatactive)) {
+ sscanf(pstr+6,"%s",entityname);
+ strcpy(data->bodyname[material],entityname);
+ data->bodynamesexist = TRUE;
+ data->boundarynamesexist = TRUE;
+ }
+ }
+
+ firstline = TRUE;
+ }
+ }
+ else if( strstr(line,"BOUNDARY") ) {
boundarytype++;
mode = 4;
+ if(allocated) {
+ printf("Treating keyword BOUNDARY\n");
+ }
+ }
+ else if( strstr(line,"SOLID SECTION") ) {
+ /* Have this here since solid section may include ELSET */
+ mode = 10;
}
- else if(strstr(line,"NSET")) {
+ else if( strstr(line,"MEMBRANE SECTION") ) {
+ /* Have this here since solid section may include ELSET */
+ mode = 10;
+ }
+ else if( strstr(line,"CLOAD") ) {
+
boundarytype++;
- mode = 5;
+ mode = 4;
+ if(allocated) {
+ printf("Treating keyword CLOAD\n");
+ }
+ }
+ else if(pstr = strstr(line,"NSET=")) {
+ if( strstr(line,"ELSET=") ) {
+ /* Skipping association of ELSET to NSET */
+ mode = 10;
+ }
+ else {
+ boundarytype++;
+ mode = 5;
+ if(allocated) {
+ printf("Loading boundary node set %d from: %s",boundarytype,pstr+5);
+ }
+ }
}
- else if(strstr(line,"ELSET")) {
+ else if(pstr = strstr(line,"ELSET=")) {
elsetactive = TRUE;
material += 1;
mode = 6;
+
+ if(allocated) {
+ printf("Loading element set %d from %s",material,pstr+6);
+ sscanf(pstr+6,"%s",entityname);
+ strcpy(data->bodyname[material],entityname);
+ data->bodynamesexist = TRUE;
+ data->boundarynamesexist = TRUE;
+ }
+ }
+ else if(pstr = strstr(line,"PART, NAME=")) {
+ elmatactive = TRUE;
+ material += 1;
+ mode = 6;
+
+ if(allocated) {
+ printf("Loading part name %d from %s",material,pstr+11);
+ sscanf(pstr+6,"%s",entityname);
+ strcpy(data->bodyname[material],entityname);
+ data->bodynamesexist = TRUE;
+ data->boundarynamesexist = TRUE;
+ }
+ }
+ else if(pstr = strstr(line,"HWCOLOR")) {
+ /* unused command */
+ mode = 0;
}
else {
if(!allocated) printf("unknown command: %s",line);
@@ -409,52 +546,118 @@ int LoadAbaqusInput(struct FemType *data,struct BoundaryType *bound,
switch (mode) {
case 1:
- if(info) printf("Loading Abacus input file:\n%s",line);
+ if(info) printf("Loading Abaqus input file:\n%s",line);
break;
- case 2:
+ case 2: /* NODE */
nvalue = StringToReal(line,rvalues,MAXNODESD2+1,',');
- i = (int)(rvalues[0]+0.5);
- if(i == 0) continue;
+
+ if(nvalue != 4) {
+ printf("line: %s\n",line);
+ printf("Invalid nvalue = %d\n",nvalue);
+ }
+
+ i = (int)(rvalues[0]+0.5);
noknots++;
+
if(allocated) {
- ind[i] = noknots;
- data->x[noknots] = rvalues[1];
- data->y[noknots] = rvalues[2];
- data->z[noknots] = rvalues[3];
+ if( debug && (i==1 || i==maxknot) ) {
+ printf("debug node: %i %d %.3le %.3le %.3le\n",i,noknots,rvalues[1],rvalues[2],rvalues[3]);
+ }
+
+ i = MAX( i, noknots );
+ if(i <= 0 || i > maxknot) {
+ printf("Invalid node index = %d\n",i);
+ }
+ else {
+ ind[i] = noknots;
+ data->x[noknots] = rvalues[1];
+ data->y[noknots] = rvalues[2];
+ data->z[noknots] = rvalues[3];
+ }
}
else {
if(maxknot < i) maxknot = i;
}
break;
- case 3:
+ case 3: /* ELEMENT */
noelements++;
-
- nvalue = StringToInteger(line,ivalues,MAXNODESD2+1,',');
+ nvalue = StringToIntegerNoZero(line,ivalues,elemnodes+1,',');
+
if(allocated) {
+ if( debug && firstline ) {
+ printf("debug elem: %d %d %d %d\n",noelements,ivalues[0],elemcode,material);
+ printf(" topo:");
+ for(i=0;ielementtypes[noelements] = elemcode;
+
data->material[noelements] = material;
for(i=0;itopology[noelements][i] = ivalues[i+1];
+
+ if( nodeoffset ) {
+ for(i=0;itopology[noelements][i] += nodeoffset;
+ }
+
+ }
+ else {
+ if( maxelem < ivalues[0] ) maxelem = ivalues[0];
}
+
+ ncum = nvalue-1;
- if(nvalue < elemcode % 100) {
+ /* Read 2nd line if needed */
+ if(ncum < elemnodes ) {
+ Getrow(line,in,TRUE);
+ nvalue = StringToIntegerNoZero(line,ivalues,elemnodes-ncum,',');
+ if(allocated) {
+ for(i=0;itopology[noelements][ncum+i] = ivalues[i];
+ }
+ ncum = ncum + nvalue;
+ }
+
+ /* Be prepared for 3rd line as well */
+ if(ncum < elemnodes ) {
Getrow(line,in,TRUE);
+ nvalue = StringToIntegerNoZero(line,ivalues,elemnodes-ncum,',');
if(allocated) {
- if(ivalues[nvalue-1] == 0) nvalue--;
- nvalue2 = StringToInteger(line,ivalues,MAXNODESD2+1,',');
- for(i=0;itopology[noelements][nvalue-1+i] = ivalues[i];
+ for(i=0;itopology[noelements][ncum+i] = ivalues[i];
+ }
+ ncum = ncum + nvalue;
+ }
+ if(ncum != elemnodes) printf("ncum = %d vs. %d\n",ncum,elemnodes);
+
+ if( allocated ) {
+ j = FALSE;
+ for(i=0;itopology[noelements][i]) j = TRUE;
+
+ if(j) {
+ printf("zero in this element\n");
+ printf("element = %d %d\n",noelements,elemnodes);
+ for(i=0;itopology[noelements][i]);
+ printf("\n");
}
}
+
break;
case 4:
- nvalue = StringToInteger(line,ivalues,MAXNODESD2+1,',');
+ nvalue = StringToInteger(line,ivalues,2,',');
- if(ivalues[0] == ivalues0[0] & ivalues[1] != ivalues0[1]) continue;
+ if(ivalues[0] == ivalues0[0] && ivalues[1] != ivalues0[1]) continue;
ivalues0[0] = ivalues[0];
ivalues0[1] = ivalues[1];
@@ -465,8 +668,8 @@ int LoadAbaqusInput(struct FemType *data,struct BoundaryType *bound,
}
break;
- case 5:
- nvalue = StringToInteger(line,ivalues,10,',');
+ case 5: /* NSET */
+ nvalue = StringToIntegerNoZero(line,ivalues,10,',');
if(allocated) {
for(i=0;imaterial[j] = material;
+ materials[j] = material;
}
}
break;
+ case 10:
+ /* Doing nothing */
+ break;
+
+
default:
printf("Unknown case: %d\n",mode);
}
@@ -500,10 +708,11 @@ int LoadAbaqusInput(struct FemType *data,struct BoundaryType *bound,
if(allocated == TRUE) {
- if(info) printf("The mesh was loaded from file %s.\n",filename);
+ int errcount,okcount;
- FindPointParents(data,bound,boundarynodes,nodeindx,boundindx,info);
+ if(info) printf("The mesh was loaded from file %s.\n",filename);
+
/* ABAQUS format does not expect that all numbers are used
when numbering the elements. Therefore the nodes must
be renumberred from 1 to noknots. */
@@ -511,17 +720,64 @@ int LoadAbaqusInput(struct FemType *data,struct BoundaryType *bound,
if(noknots != maxknot) {
if(info) printf("There are %d nodes but maximum index is %d.\n",
noknots,maxknot);
- if(info) printf("Renumbering elements\n");
- for(j=1;j<=noelements;j++)
- for(i=0;i < data->elementtypes[j]%100;i++)
- data->topology[j][i] = ind[data->topology[j][i]];
+ if(info) printf("Renumbering %d elements\n",noelements);
+ errcount = 0;
+ okcount = 0;
+ for(j=1;j<=noelements;j++) {
+ elemcode = data->elementtypes[j];
+ elemnodes = elemcode % 100;
+ for(i=0;i < elemnodes;i++) {
+ k = data->topology[j][i];
+ if(k<=0) {
+ printf("err elem ind: %d %d %d %d\n",j,elemcode,i,k);
+ errcount++;
+ }
+ else {
+ data->topology[j][i] = ind[k];
+ okcount++;
+ }
+ }
+ }
+ printf("There are %d positive and %d non-positive indexes in elements!\n",okcount,errcount);
+
+ if(info) printf("Renumbering %d nodes in node sets\n",boundarynodes);
+ errcount = 0;
+ okcount = 0;
+ for(j=1;j<=boundarynodes;j++) {
+ k = nodeindx[j];
+ if(k<=0 || k > maxknot) {
+ printf("err node set ind: %d %d\n",j,k);
+ errcount++;
+ }
+ else {
+ nodeindx[j] = ind[k];
+ okcount++;
+ }
+ }
+ printf("There are %d positive and %d non-positive indexes in node sets!\n",okcount,errcount);
}
+ if(elsetactive) {
+ for(i=1;i<=noelements;i++) {
+ j = elemindx[i];
+ data->material[i] = materials[j];
+ }
+ }
+
+ ElementsToBoundaryConditions(data,bound,FALSE,info);
+
free_ivector(ind,1,maxknot);
- free_Ivector(nodeindx,1,boundarynodes);
- free_Ivector(boundindx,1,boundarynodes);
+ free_ivector(materials,1,maxelem);
+ free_Ivector(elemindx,1,noelements);
+ if( boundarynodes > 0 ) {
+ printf("Number of nodes in boundary sets: %d\n",boundarynodes);
+ free_Ivector(nodeindx,1,boundarynodes);
+ free_Ivector(boundindx,1,boundarynodes);
+ }
+
fclose(in);
+
return(0);
}
@@ -529,19 +785,30 @@ int LoadAbaqusInput(struct FemType *data,struct BoundaryType *bound,
data->noknots = noknots;
data->noelements = noelements;
data->maxnodes = maxnodes;
- data->dim = 3;
+ data->dim = 3;
if(info) printf("Allocating for %d knots and %d %d-node elements.\n",
noknots,noelements,maxnodes);
AllocateKnots(data);
+
+ elemindx = Ivector(1,noelements);
+ for(i=1;i<=noelements;i++)
+ elemindx[i] = 0;
+
+ printf("Number of boundary nodes: %d\n",boundarynodes);
+ if( boundarynodes > 0 ) {
+ nodeindx = Ivector(1,boundarynodes);
+ boundindx = Ivector(1,boundarynodes);
+ }
- nosides = 2*boundarynodes;
- printf("There are %d boundary nodes, thus allocating %d elements\n",
- boundarynodes,nosides);
- AllocateBoundary(bound,nosides);
- nodeindx = Ivector(1,boundarynodes);
- boundindx = Ivector(1,boundarynodes);
-
+ printf("Maximum element index in file: %d\n",maxelem);
+ maxelem = MAX( maxelem, noelements );
+ materials = ivector(1,maxelem);
+ for(i=1;i<=maxelem;i++)
+ materials[i] = 0;
+
+ printf("Maximum node index in file: %d\n",maxknot);
+ maxknot = MAX( maxknot, noknots );
ind = ivector(1,maxknot);
for(i=1;i<=maxknot;i++)
ind[i] = 0;
@@ -551,6 +818,272 @@ int LoadAbaqusInput(struct FemType *data,struct BoundaryType *bound,
}
+static int ReadAbaqusField(FILE *in,char *buffer,int *argtype,int *argno)
+/* This subroutine reads the Abaqus file format and tries to make
+ sense out of it.
+ */
+{
+ int i,val,digits;
+ static int maxargno=0,mode=0;
+
+ val = fgetc(in);
+
+ if(val==EOF) return(-1);
+ if(val=='\n') val = fgetc(in);
+
+ if(val=='*') {
+ if(0) printf("start field\n");
+ if((*argno) != maxargno)
+ printf("The previous field was of wrong length, debugging time!\n");
+ (*argno) = 0;
+ mode = 0;
+ val = fgetc(in);
+ if(val=='\n') val = fgetc(in);
+ }
+
+ if(val=='I') {
+ for(i=0;i<2;i++) {
+ val = fgetc(in);
+ if(val=='\n') val = fgetc(in);
+ buffer[i] = val;
+ }
+ buffer[2] = '\0';
+ digits = atoi(buffer);
+ for(i=0;imaxnodes = 9;
+ data->dim = 3;
+
+ for(;;) {
+
+ mode = ReadAbaqusField(in,buffer,&argtype,&argno);
+ if(0) printf("%d %d: buffer: %s\n",argtype,argno,buffer);
+
+ switch (mode) {
+
+ case -1:
+ goto jump;
+
+ case 0:
+ break;
+
+ case 1921:
+ /* General info */
+ if(argno == 3) printf("Reading output file for Abaqus %s\n",buffer);
+ else if(argno == 4) printf("Created on %s",buffer);
+ else if(argno == 5) printf("%s",buffer);
+ else if(argno == 6) printf("%s\n",buffer);
+ else if(argno == 7) data->noelements = atoi(buffer);
+ else if(argno == 8 && allocated == FALSE) {
+ data->noknots = atoi(buffer);
+ allocated = TRUE;
+ AllocateKnots(data);
+ indx = Ivector(0,2 * data->noknots);
+ for(i=1;i<=2*data->noknots;i++)
+ indx[i] = 0;
+ }
+ break;
+
+ case 1900:
+ /* Element definition */
+ if(argno == 3) elemno = atoi(buffer);
+ else if(argno == 4) {
+ if(strstr(buffer,"2D4") || strstr(buffer,"SP4") || strstr(buffer,"AX4"))
+ data->elementtypes[elemno] = 404;
+ else if(strstr(buffer,"2D8") || strstr(buffer,"AX8") || strstr(buffer,"S8R5"))
+ data->elementtypes[elemno] = 408;
+ else if(strstr(buffer,"3D8"))
+ data->elementtypes[elemno] = 808;
+ else printf("Unknown element code: %s\n",buffer);
+ }
+ else if(argno >= 5)
+ data->topology[elemno][argno-5] = atoi(buffer);
+ break;
+
+ case 1901:
+ /* Node definition */
+ if(argno == 3) {
+ knotno++;
+ if(atoi(buffer) > 2*data->noknots)
+ printf("LoadAbaqusOutput: allocate more space for indx.\n");
+ else
+ indx[atoi(buffer)] = knotno;
+ }
+ if(argno == 4) sscanf(buffer,"%le",&(data->x[knotno]));
+ if(argno == 5) sscanf(buffer,"%le",&(data->y[knotno]));
+ if(argno == 6) sscanf(buffer,"%le",&(data->z[knotno]));
+ break;
+
+ case 1933:
+ /* Element set */
+ if(argno == 3) {
+ elset++;
+ strcpy(data->bodyname[elset],buffer);
+ }
+ case 1934:
+ /* Element set continuation */
+ if(argno > 3) {
+ elemno = atoi(buffer);
+ data->material[elemno] = elset;
+ }
+ break;
+
+ case 2001:
+ /* Just ignore */
+ break;
+
+ case 1:
+ if(argno == 3) knotno = indx[atoi(buffer)];
+ if(argno == 5) secno = atoi(buffer);
+ break;
+
+ case 2:
+ if(prevdog != mode) {
+ prevdog = mode;
+ nodogs++;
+ CreateVariable(data,nodogs,1,0.0,"Temperature",FALSE);
+ }
+ break;
+
+ /* Read vectors in nodes in elements */
+ case 11:
+ if(prevdog != mode) {
+ prevdog = mode;
+ nodogs++;
+ CreateVariable(data,nodogs,3,0.0,"Stress",FALSE);
+ }
+ case 12:
+ if(prevdog != mode) {
+ prevdog = mode;
+ nodogs++;
+ CreateVariable(data,nodogs,3,0.0,"Invariants",FALSE);
+ }
+ if(secno==1 && argno == 3) sscanf(buffer,"%le",&(data->dofs[nodogs][3*knotno-2]));
+ if(secno==1 && argno == 4) sscanf(buffer,"%le",&(data->dofs[nodogs][3*knotno-1]));
+ if(secno==1 && argno == 5) sscanf(buffer,"%le",&(data->dofs[nodogs][3*knotno]));
+ break;
+
+ /* Read vectors in nodes. */
+ case 101:
+ if(prevdog != mode) {
+ prevdog = mode;
+ nodogs++;
+ CreateVariable(data,nodogs,3,0.0,"Displacement",FALSE);
+ }
+ case 102:
+ if(prevdog != mode) {
+ prevdog = mode;
+ nodogs++;
+ CreateVariable(data,nodogs,3,0.0,"Velocity",FALSE);
+ }
+ if(argno == 3) knotno = indx[atoi(buffer)];
+ if(argno == 4) sscanf(buffer,"%le",&(data->dofs[nodogs][3*knotno-2]));
+ if(argno == 5) sscanf(buffer,"%le",&(data->dofs[nodogs][3*knotno-1]));
+ if(argno == 6) sscanf(buffer,"%le",&(data->dofs[nodogs][3*knotno]));
+ break;
+
+ default:
+ if(ignored != mode) {
+ printf("Record %d was ignored!\n",mode);
+ ignored = mode;
+ }
+ break;
+ }
+ }
+
+jump:
+
+ if(info) printf("Renumbering elements\n");
+ for(j=1;j<=data->noelements;j++)
+ for(i=0;i < data->elementtypes[j]%100;i++)
+ data->topology[j][i] = indx[data->topology[j][i]];
+
+ free_ivector(indx,0,2*data->noknots);
+
+ fclose(in);
+
+ if(info) printf("LoadAbacusInput: results were loaded from file %s.\n",filename);
+
+ return(0);
+}
+
+
int LoadNastranInput(struct FemType *data,struct BoundaryType *bound,
@@ -558,22 +1091,19 @@ int LoadNastranInput(struct FemType *data,struct BoundaryType *bound,
/* Load the grid from a format that in Nastran format
*/
{
- int noknots,noelements,elemcode,maxnodes,material;
- int mode,allocated,maxknot,minknot;
- int boundarytype,boundarynodes,nodes;
-
+ int noknots,noelements,maxnodes;
+ int allocated,maxknot,minknot,nodes;
char filename[MAXFILESIZE];
char line[MAXLINESIZE],*cp;
- int j,k=0;
+ int j,k;
FILE *in;
- int ivalues0[MAXDOFS];
strcpy(filename,prefix);
if ((in = fopen(filename,"r")) == NULL) {
AddExtension(prefix,filename,"nas");
if ((in = fopen(filename,"r")) == NULL) {
- printf("LoadNastranInput: opening of the Nastran file '%s' wasn't succesfull !\n",
+ printf("LoadNastranInput: opening of the Nastran file '%s' wasn't successful !\n",
filename);
return(1);
}
@@ -591,19 +1121,12 @@ int LoadNastranInput(struct FemType *data,struct BoundaryType *bound,
second time. */
omstart:
- mode = 0;
maxnodes = 0;
noknots = 0;
noelements = 0;
- elemcode = 0;
- boundarytype = 0;
- boundarynodes = 0;
- material = 0;
- ivalues0[0] = ivalues0[1] = 0;
-
for(;;) {
- /* getline; */
+ /* GETLINE; */
if (Getrow(line,in,TRUE)) goto end;
@@ -732,14 +1255,11 @@ int LoadNastranInput(struct FemType *data,struct BoundaryType *bound,
static void ReorderFidapNodes(struct FemType *data,int element,int nodes,int typeflag)
{
int i,oldtopology[MAXNODESD2],*topology,dim;
- int order203[]={1,3,2};
- int order306[]={1,3,5,2,4,6};
+ int order808[]={1,2,4,3,5,6,8,7};
int order408[]={1,3,5,7,2,4,6,8};
- int order409[]={1,3,5,7,2,4,6,8,9};
- int order510[]={1,3,6,10,2,5,4,7,8,9};
+ int order306[]={1,3,5,2,4,6};
+ int order203[]={1,3,2};
int order605[]={1,2,4,3,5};
- int order808[]={1,2,4,3,5,6,8,7};
- int order827[]={1,3,9,7,19,21,27,25,2,6,8,4,10,12,18,16,20,24,26,22,11,15,17,13,5,23,14};
dim = data->dim;
if(typeflag > 10) dim -= 1;
@@ -771,25 +1291,11 @@ static void ReorderFidapNodes(struct FemType *data,int element,int nodes,int typ
for(i=0;ielementtypes[element] = 409;
- for(i=0;ielementtypes[element] = 504;
}
- else if(nodes == 10) {
- data->elementtypes[element] = 510;
- for(i=0;ielementtypes[element] = 605;
for(i=0;ielementtypes[element] = 808;
- }
- else if(nodes == 27) {
- for(i=0;ielementtypes[element] = 827;
}
else {
printf("Unknown Fidap elementtype with %d nodes.\n",nodes);
@@ -820,7 +1318,6 @@ static void ReorderFidapNodes(struct FemType *data,int element,int nodes,int typ
}
else printf("ReorderFidapNodes: unknown dimension (%d)\n",data->dim);
- if(0) printf("dim = %d element = %d elemtype = %d\n",dim,element,data->elementtypes[element]);
}
@@ -833,7 +1330,7 @@ int LoadFidapInput(struct FemType *data,struct BoundaryType *boundaries,char *pr
Still under implementation
*/
{
- int noknots,noelements,dim,novel,elemcode,maxnodes;
+ int noknots,noelements,dim,novel,maxnodes;
int mode,maxknot,totelems,entity,maxentity;
char filename[MAXFILESIZE];
char line[MAXLINESIZE],entityname[MAXNAMESIZE];
@@ -849,7 +1346,7 @@ int LoadFidapInput(struct FemType *data,struct BoundaryType *boundaries,char *pr
if ((in = fopen(filename,"r")) == NULL) {
AddExtension(prefix,filename,"FDNEUT");
if ((in = fopen(filename,"r")) == NULL) {
- printf("LoadFidapInput: opening of the Fidap-file '%s' wasn't succesfull !\n",
+ printf("LoadFidapInput: opening of the Fidap-file '%s' wasn't successful !\n",
filename);
return(1);
}
@@ -862,17 +1359,14 @@ int LoadFidapInput(struct FemType *data,struct BoundaryType *boundaries,char *pr
noknots = 0;
noelements = 0;
dim = 0;
- elemcode = 0;
maxnodes = 4;
totelems = 0;
maxentity = 0;
for(;;) {
- isio = getline;
+ isio = GETLINE;
if(!isio) goto end;
- if(!line) goto end;
- if(line=="") goto end;
if(strstr(line,"END")) goto end;
/* Control information */
@@ -892,14 +1386,14 @@ int LoadFidapInput(struct FemType *data,struct BoundaryType *boundaries,char *pr
case 1:
if(info) printf("Loading FIDAP input file %s\n",filename);
- getline;
+ GETLINE;
if(info) printf("Name of the case: %s",line);
mode = 0;
break;
case 2:
- getline;
- if(0) printf("Reading the header info\n");
+ GETLINE;
+ if(0) printf("reading the header info\n");
sscanf(line,"%d%d%d%d%d",&noknots,&noelements,
&nogroups,&dim,&novel);
data->noknots = noknots;
@@ -916,7 +1410,7 @@ int LoadFidapInput(struct FemType *data,struct BoundaryType *boundaries,char *pr
AllocateKnots(data);
if(info) printf("Reading the nodes\n");
for(i=1;i<=noknots;i++) {
- getline;
+ GETLINE;
if (dim == 2)
sscanf(line,"%d%le%le",&knotno,
&(data->x[i]),&(data->y[i]));
@@ -952,7 +1446,7 @@ int LoadFidapInput(struct FemType *data,struct BoundaryType *boundaries,char *pr
while(val!=':');i++;
sscanf(&line[i],"%d",&typeflag);
- getline;
+ GETLINE;
i=0;
do val=line[i++];
while(val!=':');i++;
@@ -971,22 +1465,30 @@ int LoadFidapInput(struct FemType *data,struct BoundaryType *boundaries,char *pr
data->topology = topology;
}
- if(0) printf("Reading %d element topologies with %d nodes for %s\n",
+ if(info) printf("reading %d element topologies with %d nodes for %s\n",
elems,nodes,entityname);
for(entity=1;entity<=maxentity;entity++) {
+#if 0
+ k = strcmp(entityname,entitylist[entity]);
+#else
k = strcmp(entityname,data->bodyname[entity]);
+#endif
if(k == 0) break;
}
if(entity > maxentity) {
maxentity++;
+#if 0
+ strcpy(entitylist[entity],entityname);
+#else
strcpy(data->bodyname[entity],entityname);
+#endif
if(info) printf("Found new entity: %s\n",entityname);
}
for(i=totelems+1;i<=totelems+elems;i++) {
- getline;
+ GETLINE;
cp = line;
j = next_int(&cp);
@@ -1013,7 +1515,7 @@ int LoadFidapInput(struct FemType *data,struct BoundaryType *boundaries,char *pr
CreateVariable(data,2,dim,0.0,"Velocity",FALSE);
vel = data->dofs[2];
for(j=1;j<=noknots;j++) {
- getline;
+ GETLINE;
if(dim==2)
sscanf(line,"%le%le",&(vel[2*j-1]),&(vel[2*j]));
if(dim==3)
@@ -1027,7 +1529,7 @@ int LoadFidapInput(struct FemType *data,struct BoundaryType *boundaries,char *pr
CreateVariable(data,1,1,0.0,"Temperature",FALSE);
temp = data->dofs[1];
for(j=1;j<=noknots;j++) {
- getline;
+ GETLINE;
sscanf(line,"%le",&(temp[j]));
}
mode = 0;
@@ -1074,9 +1576,8 @@ int LoadFidapInput(struct FemType *data,struct BoundaryType *boundaries,char *pr
if(info) printf("Finished reading the Fidap neutral file\n");
-
ElementsToBoundaryConditions(data,boundaries,FALSE,TRUE);
- RenumberBoundaryTypes(data,boundaries,TRUE,0,info);
+ /* RenumberBoundaryTypes(data,boundaries,TRUE,0,info); */
return(0);
}
@@ -1086,21 +1587,32 @@ int LoadFidapInput(struct FemType *data,struct BoundaryType *boundaries,char *pr
static void ReorderAnsysNodes(struct FemType *data,int *oldtopology,
int element,int dim,int nodes)
{
- int i,*topology,elementtype = 0;
+ int i,*topology,elementtype;
int order820[]={1,2,3,4,5,6,7,8,9,10,11,12,17,18,19,20,13,14,15,16};
int order504[]={1,2,3,5};
int order306[]={1,2,3,5,6,8};
int order510[]={1,2,3,5,9,10,12,17,18,19};
int order613[]={1,2,3,4,5,9,10,11,12,17,18,19,20};
-
+ int order706[]={1,2,3,5,6,7};
+ int order715[]={1,2,3,5,6,7,9,10,12,17,18,19,13,14,16};
+
+ elementtype = 0;
if(dim == 3) {
if(nodes == 20) {
- if(oldtopology[2] == oldtopology[3]) elementtype = 510;
+ if(oldtopology[2] == oldtopology[3] &&
+ oldtopology[4] == oldtopology[5]) elementtype = 510;
+ else if(oldtopology[2] == oldtopology[3] &&
+ oldtopology[4] != oldtopology[5]) elementtype = 715;
else if(oldtopology[4] == oldtopology[5]) elementtype = 613;
else elementtype = 820;
}
if(nodes == 8) {
- if(oldtopology[2] == oldtopology[3]) elementtype = 504;
+ if(oldtopology[2] == oldtopology[3] &&
+ oldtopology[4] == oldtopology[7] &&
+ oldtopology[5] == oldtopology[7] &&
+ oldtopology[6] == oldtopology[7]) elementtype = 504;
+ else if(oldtopology[2] == oldtopology[3] &&
+ oldtopology[6] == oldtopology[7]) elementtype = 706;
else if(oldtopology[4] == oldtopology[5]) elementtype = 605;
else elementtype = 808;
}
@@ -1142,6 +1654,10 @@ static void ReorderAnsysNodes(struct FemType *data,int *oldtopology,
break;
case 504:
+ if(nodes == 4)
+ for(i=0;i 8) {
- getline;
+ GETLINE;
cp=line;
if(ansysnodes[k] == 10 && topology[2] != topology[3])
@@ -1380,12 +1916,20 @@ int LoadAnsysInput(struct FemType *data,struct BoundaryType *bound,
imax = 20;
for(i=8;ibodynamesexist = TRUE;
if(bound[0].nosides) {
@@ -1462,7 +2006,7 @@ int LoadAnsysInput(struct FemType *data,struct BoundaryType *bound,
sscanf(line,"%d%s%s%d",&bcind,&text[0],&text2[0],&sides);
if(strstr(text2,"BODY")) {
- getline;
+ GETLINE;
sscanf(line,"%d%d",&j,&bcind);
strcpy(data->bodyname[bcind],text);
}
@@ -1471,12 +2015,12 @@ int LoadAnsysInput(struct FemType *data,struct BoundaryType *bound,
for(i=1;i<=maxside;i++)
bctypes[i] = 0;
for(i=1;i<=sides;i++) {
- getline;
+ GETLINE;
sscanf(line,"%d%d",&j,&bcind);
bctypes[bcind] = TRUE;
}
- /* Find 1st unsed boundarytype */
+ /* Find 1st unused boundarytype */
for(i=1;i<=maxside;i++)
if(bctypes[i] && !bctypeused[i]) break;
@@ -1532,20 +2076,21 @@ int LoadAnsysInput(struct FemType *data,struct BoundaryType *bound,
free_Ivector(boundindx,1,boundarynodes);
free_Ivector(nodeindx,1,boundarynodes);
+ if(info) printf("Ansys mesh loaded succefully\n");
+
return(0);
}
-
-
static void ReorderFieldviewNodes(struct FemType *data,int *oldtopology,
int element,int dim,int nodes)
{
- int i,*topology,elementtype = 0;
+ int i,*topology,elementtype;
int order808[]={1,2,4,3,5,6,8,7};
int order706[]={1,4,6,2,3,5};
int order404[]={1,2,3,4};
+ elementtype = 0;
if(dim == 3) {
if(nodes == 8) elementtype = 808;
if(nodes == 6) elementtype = 706;
@@ -1559,6 +2104,7 @@ static void ReorderFieldviewNodes(struct FemType *data,int *oldtopology,
if(!elementtype) {
printf("Unknown elementtype in element %d (%d nodes, %d dim).\n",
element,nodes,dim);
+ bigerror("Cannot continue");
}
data->elementtypes[element] = elementtype;
@@ -1580,21 +2126,21 @@ int LoadFieldviewInput(struct FemType *data,struct BoundaryType *bound,char *pre
program by PointWise. This is a suitable format to read files created
by GridGen. */
{
- int noknots,noelements,elemcode,maxnodes;
- int mode,totelems,entity;
+ int noknots,noelements,maxnodes,mode;
char filename[MAXFILESIZE];
char line[MAXLINESIZE],*cp;
int i,j,k;
FILE *in;
Real x,y,z;
- int maxindx,sidenodes;
+ int maxindx;
char *isio;
- int nobound,nobulk = 0,maxsidenodes,*boundtypes = NULL,**boundtopos = NULL,*boundnodes = NULL,*origtopology;
+ int nobound=0,nobulk=0,maxsidenodes;
+ int *boundtypes=NULL,**boundtopos=NULL,*boundnodes=NULL,*origtopology=NULL;
if ((in = fopen(prefix,"r")) == NULL) {
AddExtension(prefix,filename,"dat");
if ((in = fopen(filename,"r")) == NULL) {
- printf("LoadFieldviewInput: opening of the Fieldview-file '%s' wasn't succesfull !\n",
+ printf("LoadFieldviewInput: opening of the Fieldview-file '%s' wasn't successful !\n",
filename);
return(1);
}
@@ -1604,29 +2150,21 @@ int LoadFieldviewInput(struct FemType *data,struct BoundaryType *bound,char *pre
data->dim = 3;
data->created = TRUE;
- entity = 0;
mode = 0;
noknots = 0;
noelements = 0;
- elemcode = 0;
-
maxnodes = 8;
maxsidenodes = 4;
maxindx = 0;
- sidenodes = 0;
data->maxnodes = maxnodes;
- totelems = 0;
-
for(;;) {
if(mode == 0) {
- isio = getline;
+ isio = GETLINE;
if(!isio) goto end;
- if(!line) goto end;
- if(line=="") goto end;
if(strstr(line,"END")) goto end;
/* Control information */
@@ -1671,7 +2209,7 @@ int LoadFieldviewInput(struct FemType *data,struct BoundaryType *bound,char *pre
case 6:
- getline;
+ GETLINE;
sscanf(line,"%d",&noknots);
data->noknots = noknots;
@@ -1682,7 +2220,7 @@ int LoadFieldviewInput(struct FemType *data,struct BoundaryType *bound,char *pre
data->z = Rvector(1,noknots);
for(i=1;i<=noknots;i++) {
- getline;
+ GETLINE;
sscanf(line,"%le%le%le",&x,&y,&z);
data->x[i] = x;
data->y[i] = y;
@@ -1693,7 +2231,7 @@ int LoadFieldviewInput(struct FemType *data,struct BoundaryType *bound,char *pre
case 7:
- getline;
+ GETLINE;
sscanf(line,"%d",&nobound);
if(info) printf("Loading %d boundary element definitions\n",nobound);
@@ -1703,7 +2241,7 @@ int LoadFieldviewInput(struct FemType *data,struct BoundaryType *bound,char *pre
boundnodes = Ivector(1,nobound);
for(i=1;i<=nobound;i++) {
- getline; cp=line;
+ GETLINE; cp=line;
boundtypes[i]= next_int(&cp);
maxsidenodes = next_int(&cp);
@@ -1730,7 +2268,7 @@ int LoadFieldviewInput(struct FemType *data,struct BoundaryType *bound,char *pre
data->elementtypes = Ivector(1,noelements);
for(i=0;;) {
- getline; cp=line;
+ GETLINE; cp=line;
if(strstr(line,"Variables")) mode = 9;
if(mode != 8) break;
@@ -1810,19 +2348,20 @@ int LoadTriangleInput(struct FemType *data,struct BoundaryType *bound,
FILE *in;
char *cp,line[MAXLINESIZE],elemfile[MAXFILESIZE],nodefile[MAXFILESIZE],
polyfile[MAXLINESIZE];
+ int *invrow,*invcol;
if(info) printf("Loading mesh in Triangle format from file %s.*\n",prefix);
sprintf(nodefile,"%s.node",prefix);
if ((in = fopen(nodefile,"r")) == NULL) {
- printf("LoadElmerInput: The opening of the nodes file %s failed!\n",nodefile);
+ printf("LoadTriangleInput: The opening of the nodes file %s failed!\n",nodefile);
return(1);
}
else
printf("Loading nodes from file %s\n",nodefile);
- getline;
+ GETLINE;
sscanf(line,"%d %d %d %d",&noknots,&dim,&nodeatts,&bcmarkers);
fclose(in);
@@ -1833,13 +2372,13 @@ int LoadTriangleInput(struct FemType *data,struct BoundaryType *bound,
sprintf(elemfile,"%s.ele",prefix);
if ((in = fopen(elemfile,"r")) == NULL) {
- printf("LoadElmerInput: The opening of the element file %s failed!\n",elemfile);
+ printf("LoadTriangleInput: The opening of the element file %s failed!\n",elemfile);
return(3);
}
else
printf("Loading elements from file %s\n",elemfile);
- getline;
+ GETLINE;
sscanf(line,"%d %d %d",&noelements,&maxnodes,&elematts);
fclose(in);
@@ -1859,9 +2398,9 @@ int LoadTriangleInput(struct FemType *data,struct BoundaryType *bound,
boundnodes[i] = 0;
in = fopen(nodefile,"r");
- getline;
+ GETLINE;
for(i=1; i <= noknots; i++) {
- getline;
+ GETLINE;
cp = line;
j = next_int(&cp);
if(j != i) printf("LoadTriangleInput: nodes i=%d j=%d\n",i,j);
@@ -1876,9 +2415,9 @@ int LoadTriangleInput(struct FemType *data,struct BoundaryType *bound,
fclose(in);
in = fopen(elemfile,"r");
- getline;
+ GETLINE;
for(i=1; i <= noelements; i++) {
- getline;
+ GETLINE;
cp = line;
data->elementtypes[i] = elementtype;
j = next_int(&cp);
@@ -1897,36 +2436,40 @@ int LoadTriangleInput(struct FemType *data,struct BoundaryType *bound,
sprintf(polyfile,"%s.poly",prefix);
if ((in = fopen(polyfile,"r")) == NULL) {
- printf("LoadElmerInput: The opening of the poly file %s failed!\n",polyfile);
+ printf("LoadTriangleInput: The opening of the poly file %s failed!\n",polyfile);
return(1);
}
else
printf("Loading nodes from file %s\n",polyfile);
{
- int bcelems,markers,ind1,ind2,bctype,j2,k2,hit = 0;
- int elemsides,sideind[2],side,elemind = 0;
+ int bcelems,markers,ind1,ind2,bctype,j2,k2,hit;
+ int elemsides,sideind[2],side,elemind=0;
bctype = 1;
elemsides = 3;
+ hit = FALSE;
- getline;
- getline;
+ GETLINE;
+ GETLINE;
sscanf(line,"%d %d",&bcelems,&markers);
CreateInverseTopology(data,info);
+ invrow = data->invtopo.rows;
+ invcol = data->invtopo.cols;
AllocateBoundary(bound,bcelems);
for(i=1;i<=bcelems;i++) {
- getline;
+ GETLINE;
if(markers)
sscanf(line,"%d %d %d %d",&j,&ind1,&ind2,&bctype);
else
sscanf(line,"%d %d %d",&j,&ind1,&ind2);
/* find an element which owns both the nodes */
+#if 0
for(j=1;j<=data->maxinvtopo;j++) {
hit = FALSE;
k = data->invtopo[j][ind1];
@@ -1943,6 +2486,24 @@ int LoadTriangleInput(struct FemType *data,struct BoundaryType *bound,
}
if(hit) break;
}
+#else
+ for(j=invrow[ind1-1];jelementtypes[i] = elementtype;
@@ -2096,16 +2656,16 @@ int LoadGidInput(struct FemType *data,struct BoundaryType *bound,
char *prefix,int info)
/* Load the grid from GID mesh format */
{
- int noknots,noelements,elemcode,maxnodes,material,foundsame;
- int mode,allocated,maxknot,nosides,sideelemtype;
- int boundarytype,materialtype,boundarynodes,side,parent,elemsides;
- int dim = 0, elemnodes = 0, elembasis = 0, elemtype = 0, bulkdone, usedmax = 0,hits;
+ int noknots,noelements,maxnodes,foundsame;
+ int mode,allocated,nosides,sideelemtype;
+ int boundarytype,side,parent,elemsides,materialtype=0;
+ int dim=0, elemnodes=0, elembasis=0, elemtype=0, bulkdone, usedmax=0,hits;
int minbulk,maxbulk,minbound,maxbound,label,debug;
- int *usedno = NULL, **usedelem = NULL;
+ int *usedno=NULL, **usedelem=NULL;
char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
int i,j,k,n,ind,inds[MAXNODESD2],sideind[MAXNODESD1];
FILE *in;
- Real x,y,z = 0;
+ Real x,y,z;
debug = FALSE;
@@ -2113,7 +2673,7 @@ int LoadGidInput(struct FemType *data,struct BoundaryType *bound,
if ((in = fopen(filename,"r")) == NULL) {
AddExtension(prefix,filename,"msh");
if ((in = fopen(filename,"r")) == NULL) {
- printf("LoadAbaqusInput: opening of the GID-file '%s' wasn't succesfull !\n",
+ printf("LoadGidInput: opening of the GID-file '%s' wasn't successful !\n",
filename);
return(1);
}
@@ -2123,7 +2683,6 @@ int LoadGidInput(struct FemType *data,struct BoundaryType *bound,
InitializeKnots(data);
allocated = FALSE;
- maxknot = 0;
/* Because the file format doesn't provide the number of elements
or nodes the results are read twice but registered only in the
@@ -2138,17 +2697,13 @@ int LoadGidInput(struct FemType *data,struct BoundaryType *bound,
maxnodes = 0;
noknots = 0;
noelements = 0;
- elemcode = 0;
boundarytype = 0;
- boundarynodes = 0;
- material = 0;
nosides = 0;
bulkdone = FALSE;
for(;;) {
if(Getrow(line,in,FALSE)) goto end;
- if(!line) goto end;
if(strstr(line,"MESH")) {
if(debug) printf("MESH\n");
@@ -2426,7 +2981,8 @@ static void ReorderComsolNodes(int elementtype,int *topo)
int i,tmptopo[MAXNODESD2];
int order404[]={1,2,4,3};
int order808[]={1,2,4,3,5,6,8,7};
-
+ int order605[]={1,2,4,3,5};
+
switch (elementtype) {
@@ -2444,6 +3000,14 @@ static void ReorderComsolNodes(int elementtype,int *topo)
topo[i] = tmptopo[order808[i]-1];
break;
+ case 605:
+ for(i=0;i maxnodes) maxnodes = elemnodes;
if(debug) printf("elemnodes=%d\n",elemnodes);
}
- else if(strstr(line,"# Mesh point coordinates")) {
+ else if(strstr(line,"# Mesh point coordinates") || strstr(line, "# Mesh vertex coordinates" )) {
printf("Loading %d coordinates\n",noknots);
for(i=1;i<=noknots;i++) {
@@ -2630,7 +3195,7 @@ int LoadComsolMesh(struct FemType *data,struct BoundaryType *bound,char *prefix,
if(!allocated) {
if(noknots == 0 || noelements == 0 || maxnodes == 0) {
- printf("Invalid mesh consits of %d knots and %d %d-node elements.\n",
+ printf("Invalid mesh consists of %d knots and %d %d-node elements.\n",
noknots,noelements,maxnodes);
fclose(in);
return(2);
@@ -2660,6 +3225,7 @@ int LoadComsolMesh(struct FemType *data,struct BoundaryType *bound,char *prefix,
}
+
static int GmshToElmerType(int gmshtype)
{
int elmertype = 0;
@@ -2705,7 +3271,6 @@ static int GmshToElmerType(int gmshtype)
case 15:
elmertype = 101;
break;
-
case 16:
elmertype = 408;
break;
@@ -2722,6 +3287,38 @@ static int GmshToElmerType(int gmshtype)
elmertype = 310;
break;
+ /* These are supported by Gmsh but not by ElmerSolver */
+ case 13:
+ elmertype = 718;
+ break;
+ case 14:
+ elmertype = 614;
+ break;
+ case 20:
+ elmertype = 309;
+ break;
+ case 22:
+ elmertype = 312;
+ break;
+ case 24:
+ elmertype = 315;
+ break;
+ case 25:
+ elmertype = 320;
+ break;
+ case 26:
+ elmertype = 204;
+ break;
+ case 27:
+ elmertype = 205;
+ break;
+ case 28:
+ elmertype = 206;
+ break;
+ case 29:
+ elmertype = 520;
+ break;
+
default:
printf("Gmsh element %d does not have an Elmer counterpart!\n",gmshtype);
}
@@ -2736,10 +3333,12 @@ static void GmshToElmerIndx(int elemtype,int *topology)
int reorder, *porder;
int order510[]={0,1,2,3,4,5,6,7,9,8};
- int order613[]={0,1,2,3,4,5,8,10,6,7,9,11,12};
- int order715[]={0,1,2,3,4,5,6,9,7,8,10,11,12,14,13};
- int order820[]={0,1,2,3,4,5,6,7,8,11,12,9,10,12,14,15,16,18,19,17};
-
+ int order614[]={0,1,2,3,4,5,8,10,6,7,9,11,12,13};
+ int order718[]={0,1,2,3,4,5,6,9,7,8,10,11,12,14,13,15,17,16};
+ int order820[]={0,1,2,3,4,5,6,7,8,11,13,9,10,12,14,15,16,18,19,17};
+ int order827[]={0,1,2,3,4,5,6,7,8,11,13,9,10,12,14,15,16,18,19,17,21,23,24,22,20,25,26};
+ /* {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26}; */
+
reorder = FALSE;
@@ -2751,20 +3350,26 @@ static void GmshToElmerIndx(int elemtype,int *topology)
break;
case 613:
+ case 614:
reorder = TRUE;
- porder = &order613[0];
+ porder = &order614[0];
break;
case 715:
+ case 718:
reorder = TRUE;
- porder = &order715[0];
+ porder = &order718[0];
break;
case 820:
reorder = TRUE;
porder = &order820[0];
break;
-
+
+ case 827:
+ reorder = TRUE;
+ porder = &order827[0];
+ break;
}
if( reorder ) {
@@ -2780,22 +3385,22 @@ static void GmshToElmerIndx(int elemtype,int *topology)
static int LoadGmshInput1(struct FemType *data,struct BoundaryType *bound,
char *filename,int info)
{
- int noknots = 0,noelements = 0,maxnodes,elematts,nodeatts,nosides,dim;
- int sideind[MAXNODESD1],elemind[MAXNODESD2],tottypes,elementtype,bcmarkers;
- int i,j,k,dummyint,*boundnodes,allocated,*revindx,maxindx;
- int elemno, gmshtype, regphys, regelem, elemnodes,maxelemtype,elemdim;
+ int noknots = 0,noelements = 0,maxnodes,dim;
+ int elemind[MAXNODESD2],elementtype;
+ int i,j,k,allocated,*revindx=NULL,maxindx;
+ int elemno, gmshtype, regphys, regelem, elemnodes,maxelemtype;
FILE *in;
char *cp,line[MAXLINESIZE];
if ((in = fopen(filename,"r")) == NULL) {
- printf("LoadElmerInput: The opening of the mesh file %s failed!\n",filename);
+ printf("LoadGmshInput: The opening of the mesh file %s failed!\n",filename);
return(1);
}
if(info) printf("Loading mesh in Gmsh format 1.0 from file %s\n",filename);
allocated = FALSE;
- dim = 3;
+ dim = data->dim;
maxnodes = 0;
maxindx = 0;
maxelemtype = 0;
@@ -2822,17 +3427,16 @@ static int LoadGmshInput1(struct FemType *data,struct BoundaryType *bound,
for(;;) {
if(Getrow(line,in,TRUE)) goto end;
- if(!line) goto end;
if(strstr(line,"END")) goto end;
if(strstr(line,"$NOD")) {
- getline;
+ GETLINE;
cp = line;
noknots = next_int(&cp);
for(i=1; i <= noknots; i++) {
- getline;
+ GETLINE;
cp = line;
j = next_int(&cp);
@@ -2846,7 +3450,7 @@ static int LoadGmshInput1(struct FemType *data,struct BoundaryType *bound,
maxindx = MAX(j,maxindx);
}
}
- getline;
+ GETLINE;
if(!strstr(line,"$ENDNOD")) {
printf("NOD section should end to string ENDNOD\n");
printf("%s\n",line);
@@ -2854,12 +3458,12 @@ static int LoadGmshInput1(struct FemType *data,struct BoundaryType *bound,
}
if(strstr(line,"$ELM")) {
- getline;
+ GETLINE;
cp = line;
noelements = next_int(&cp);
for(i=1; i <= noelements; i++) {
- getline;
+ GETLINE;
cp = line;
elemno = next_int(&cp);
@@ -2891,7 +3495,7 @@ static int LoadGmshInput1(struct FemType *data,struct BoundaryType *bound,
}
}
- getline;
+ GETLINE;
if(!strstr(line,"$ENDELM"))
printf("ELM section should end to string ENDELM\n");
}
@@ -2920,7 +3524,7 @@ static int LoadGmshInput1(struct FemType *data,struct BoundaryType *bound,
if(k <= 0 || k > maxindx)
printf("index out of bounds %d\n",k);
else if(revindx[k] <= 0)
- printf("unkonwn node %d %d in element %d\n",k,revindx[k],i);
+ printf("unknown node %d %d in element %d\n",k,revindx[k],i);
else
data->topology[i][j] = revindx[k];
}
@@ -2937,39 +3541,41 @@ static int LoadGmshInput1(struct FemType *data,struct BoundaryType *bound,
static int LoadGmshInput2(struct FemType *data,struct BoundaryType *bound,
- char *filename,int info)
+ char *filename,int usetaggeom, int info)
{
- int noknots = 0,noelements = 0,maxnodes,elematts,nodeatts,nosides,dim,notags;
- int sideind[MAXNODESD1],elemind[MAXNODESD2],tottypes,elementtype,bcmarkers;
- int i,j,k,dummyint,*boundnodes,allocated,*revindx,maxindx;
- int elemno, gmshtype, tagphys, taggeom, tagpart, elemnodes,maxelemtype,elemdim;
- int usetaggeom,tagmat,verno;
+ int noknots = 0,noelements = 0,nophysical = 0,maxnodes,dim,notags;
+ int elemind[MAXNODESD2],elementtype;
+ int i,j,k,allocated,*revindx=NULL,maxindx;
+ int elemno, gmshtype, tagphys=0, taggeom=0, tagpart, elemnodes,maxelemtype;
+ int tagmat,verno;
+ int physvolexist, physsurfexist;
FILE *in;
+ const char manifoldname[4][10] = {"point", "line", "surface", "volume"};
char *cp,line[MAXLINESIZE];
-
if ((in = fopen(filename,"r")) == NULL) {
- printf("LoadElmerInput: The opening of the mesh file %s failed!\n",filename);
+ printf("LoadGmshInput2: The opening of the mesh file %s failed!\n",filename);
return(1);
}
if(info) printf("Loading mesh in Gmsh format 2.0 from file %s\n",filename);
allocated = FALSE;
- dim = 3;
+ dim = data->dim;
maxnodes = 0;
maxindx = 0;
maxelemtype = 0;
+ physvolexist = FALSE;
+ physsurfexist = FALSE;
usetaggeom = FALSE;
-
+
omstart:
for(;;) {
if(Getrow(line,in,FALSE)) goto end;
- if(!line) goto end;
if(strstr(line,"$End")) continue;
if(strstr(line,"$MeshFormat")) {
- getline;
+ GETLINE;
cp = line;
verno = next_int(&cp);
@@ -2977,19 +3583,19 @@ static int LoadGmshInput2(struct FemType *data,struct BoundaryType *bound,
printf("Version number is not compatible with the parser: %d\n",verno);
}
- getline;
+ GETLINE;
if(!strstr(line,"$EndMeshFormat")) {
printf("$MeshFormat section should end to string $EndMeshFormat:\n%s\n",line);
}
}
else if(strstr(line,"$Nodes")) {
- getline;
+ GETLINE;
cp = line;
noknots = next_int(&cp);
for(i=1; i <= noknots; i++) {
- getline;
+ GETLINE;
cp = line;
j = next_int(&cp);
@@ -3003,19 +3609,19 @@ static int LoadGmshInput2(struct FemType *data,struct BoundaryType *bound,
maxindx = MAX(j,maxindx);
}
}
- getline;
+ GETLINE;
if(!strstr(line,"$EndNodes")) {
printf("$Nodes section should end to string $EndNodes:\n%s\n",line);
}
}
else if(strstr(line,"$Elements")) {
- getline;
+ GETLINE;
cp = line;
noelements = next_int(&cp);
for(i=1; i <= noelements; i++) {
- getline;
+ GETLINE;
cp = line;
elemno = next_int(&cp);
@@ -3056,19 +3662,37 @@ static int LoadGmshInput2(struct FemType *data,struct BoundaryType *bound,
}
}
- getline;
+ GETLINE;
if(!strstr(line,"$EndElements")) {
printf("$Elements section should end to string $EndElements:\n%s\n",line);
}
}
else if(strstr(line,"$PhysicalNames")) {
- if(info) printf("Physical names are not accounted for\n");
- getline;
+ GETLINE;
cp = line;
- i = next_int(&cp);
- for(;i>0;i--) getline;
+ nophysical = next_int(&cp);
+ for(i=0;iboundaryname[tagphys]);
+ else printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[dim-1],cp+1);
+ }
+ else if(gmshtype == dim) {
+ physvolexist = TRUE;
+ if(tagphys < MAXBODIES) sscanf(cp," \"%[^\"]\"",data->bodyname[tagphys]);
+ else printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[dim],cp+1);
+ }
+ else printf("Physical groups of dimension %d not supported in %d-dimensional mesh: "
+ "ignoring group %d %s",gmshtype,dim,tagphys,cp+1);
+ }
+ }
- getline;
+ GETLINE;
if(!strstr(line,"$EndPhysicalNames")) {
printf("$PhysicalNames section should end to string $EndPhysicalNames:\n%s\n",line);
}
@@ -3114,7 +3738,7 @@ static int LoadGmshInput2(struct FemType *data,struct BoundaryType *bound,
if(k <= 0 || k > maxindx)
printf("index out of bounds %d\n",k);
else if(revindx[k] <= 0)
- printf("unkonwn node %d %d in element %d\n",k,revindx[k],i);
+ printf("unknown node %d %d in element %d\n",k,revindx[k],i);
else
data->topology[i][j] = revindx[k];
}
@@ -3124,11 +3748,8 @@ static int LoadGmshInput2(struct FemType *data,struct BoundaryType *bound,
ElementsToBoundaryConditions(data,bound,FALSE,info);
- /* The geometric entities are rather randomly numbered */
- if( usetaggeom ) {
- RenumberBoundaryTypes(data,bound,TRUE,0,info);
- RenumberMaterialTypes(data,bound,info);
- }
+ data->bodynamesexist = physvolexist;
+ data->boundarynamesexist = physsurfexist;
if(info) printf("Successfully read the mesh from the Gmsh input file.\n");
@@ -3137,17 +3758,17 @@ static int LoadGmshInput2(struct FemType *data,struct BoundaryType *bound,
static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
- char *filename,int info)
+ char *filename,int usetaggeom, int info)
{
int noknots = 0,noelements = 0,nophysical = 0,maxnodes,dim,notags;
int elemind[MAXNODESD2],elementtype;
- int i,j,k,allocated,*revindx=NULL,maxindx;
- int elemno, gmshtype, tagphys=0, taggeom=0, tagpart, elemnodes,maxelemtype;
- int usetaggeom,tagmat,verno;
- int physvolexist, physsurfexist;
+ int i,j,k,l,allocated,*revindx=NULL,maxindx;
+ int elemno, gmshtype, tagphys=0, tagpart, elemnodes,maxelemtype;
+ int tagmat,verno;
+ int physvolexist, physsurfexist,**tagmap,tagsize,maxtag[4];
FILE *in;
const char manifoldname[4][10] = {"point", "line", "surface", "volume"};
- char *cp,line[MAXLINESIZE];
+ char *cp,line[MAXLINESIZE],longline[LONGLINESIZE];
if ((in = fopen(filename,"r")) == NULL) {
printf("LoadGmshInput4: The opening of the mesh file %s failed!\n",filename);
@@ -3160,10 +3781,12 @@ static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
maxnodes = 0;
maxindx = 0;
maxelemtype = 0;
- usetaggeom = FALSE;
physvolexist = FALSE;
physsurfexist = FALSE;
+ usetaggeom = TRUE; /* The default */
+ for(i=0;i<4;i++) maxtag[i] = 0;
+
omstart:
for(;;) {
@@ -3171,7 +3794,7 @@ static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
if(strstr(line,"$End")) continue;
if(strstr(line,"$MeshFormat")) {
- getline;
+ GETLINE;
cp = line;
verno = next_int(&cp);
@@ -3179,7 +3802,7 @@ static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
printf("Version number is not compatible with the parser: %d\n",verno);
}
- getline;
+ GETLINE;
if(!strstr(line,"$EndMeshFormat")) {
printf("$MeshFormat section should end to string $EndMeshFormat:\n%s\n",line);
}
@@ -3188,7 +3811,7 @@ static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
else if(strstr(line,"$Nodes")) {
int numEntityBlocks,tagEntity,dimEntity,parEntity,numNodes,ind;
- getline;
+ GETLINE;
cp = line;
numEntityBlocks = next_int(&cp);
@@ -3199,7 +3822,7 @@ static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
k = 0;
for(j=1; j <= numEntityBlocks; j++) {
- getline;
+ GETLINE;
cp = line;
tagEntity = next_int(&cp);
@@ -3208,7 +3831,7 @@ static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
numNodes = next_int(&cp);
for(i=1; i <= numNodes; i++) {
- getline;
+ GETLINE;
cp = line;
k += 1;
@@ -3224,7 +3847,7 @@ static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
}
}
}
- getline;
+ GETLINE;
if(!strstr(line,"$EndNodes")) {
printf("$Nodes section should end to string $EndNodes:\n%s\n",line);
@@ -3232,45 +3855,109 @@ static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
}
else if(strstr(line,"$Entities")) {
- int numPoints, numCurves, numSurfaces, numVolumes;
+ int numPoints, numCurves, numSurfaces, numVolumes, numEnt;
+ int tag,tagdim,nophys,phystag;
+ int nobound, idum;
+ Real rdum;
- getline;
+ usetaggeom = FALSE;
+
+ GETLINE;
cp = line;
numPoints = next_int(&cp);
numCurves = next_int(&cp);
numSurfaces = next_int(&cp);
numVolumes = next_int(&cp);
- if(allocated && info) printf("num entities: %d %d %d %d\n",numPoints,numCurves,numSurfaces,numVolumes);
-
- for(i=1; i <= numPoints; i++) {
- getline;
- cp = line;
- }
- for(i=1; i <= numCurves; i++) {
- getline;
- cp = line;
+ if(allocated) {
+ tagsize = 0;
+ for(tagdim=0;tagdim<=3;tagdim++)
+ tagsize = MAX( tagsize, maxtag[tagdim]);
+ if( tagsize > 0 ) {
+ tagmap = Imatrix(0,3,1,tagsize);
+ for(i=0;i<=3;i++)
+ for(j=1;j<=tagsize;j++)
+ tagmap[i][j] = 0;
+ }
}
+
+ for(tagdim=0;tagdim<=3;tagdim++) {
+
+ if( tagdim == 0 )
+ numEnt = numPoints;
+ else if( tagdim == 1 )
+ numEnt = numCurves;
+ else if( tagdim == 2 )
+ numEnt = numSurfaces;
+ else if( tagdim == 3 )
+ numEnt = numVolumes;
+
+ if(!allocated)
+ maxtag[tagdim] = 0;
+ else if( maxtag[tagdim] > 0 )
+ printf("Maximum original tag for %d %dDIM entities is %d\n",numEnt,tagdim,maxtag[tagdim]);
- for(i=1; i <= numSurfaces; i++) {
- getline;
- cp = line;
- }
- for(i=1; i <= numVolumes; i++) {
- getline;
- cp = line;
+ if(numEnt > 0 && !allocated) {
+ printf("Reading %d entities in %dD\n",numEnt,tagdim);
+ }
+
+ for(i=1; i <= numEnt; i++) {
+ GETLONGLINE;
+
+ // if( i==1 ) printf("1st line of dim %d with %d entries: %s\n",tagdim,numEnt,line);
+
+ if( tagdim == 0 ) continue;
+
+ cp = longline;
+ tag = next_int(&cp);
+
+ if(!allocated)
+ maxtag[tagdim] = MAX( maxtag[tagdim], tag );
+
+ for(j=1;j<=6;j++) rdum = next_real(&cp);
+ nophys = next_int(&cp);
+
+ if( nophys > 0 ) phystag = next_int(&cp);
+
+ if(allocated) tagmap[tagdim][tag] = phystag;
+
+
+ // The lines may be too long. So fill the string buffer until we get a newline.
+ j = k = 0;
+ for(;;) {
+ for(l=0;l 0 && !allocated) printf("Entity line %d has length %d.\n",i,k+j);
+
+ //for(j=2;j<=nophys;j++)
+ // idum = next_int(&cp);
+
+ //// if( tagdim == 0 ) continue;
+
+ //nobound = next_int(&cp);
+ // for(j=1;j<=nobound;j++)
+ // idum = next_int(&cp);
+ }
}
-
- getline;
- if(!strstr(line,"$EndEntities")) {
- printf("$Entities section should end to string $EndEntities:\n%s\n",line);
+
+ GETLONGLINE;
+ if(!strstr(longline,"$EndEntities")) {
+ printf("$Entities section should end to string $EndEntities:\n%s\n",longline);
}
}
else if(strstr(line,"$Elements")) {
int numEntityBlocks, numElements, tagEntity, dimEntity, typeEle, NumElements;
- getline;
+ GETLINE;
cp = line;
k = 0;
@@ -3282,72 +3969,94 @@ static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
for(j=1; j<= numEntityBlocks; j++ ) {
- getline;
+ GETLINE;
cp = line;
tagEntity = next_int(&cp);
dimEntity = next_int(&cp);
+
typeEle = next_int(&cp);
numElements = next_int(&cp);
-
+
elementtype = GmshToElmerType(typeEle);
elemnodes = elementtype % 100;
maxelemtype = MAX(maxelemtype,elementtype);
+ if( allocated && tagsize > 0 ) {
+ printf("Reading %d elements with tag %d of type %d\n", numElements, tagEntity, elementtype);
+ if( tagsize > 0 ) {
+ if( tagmap[dimEntity][tagEntity] ) {
+ printf("Mapping mesh tag %d to physical tag %d in %dDIM\n",tagEntity,tagmap[dimEntity][tagEntity],dimEntity);
+ tagEntity = tagmap[dimEntity][tagEntity];
+ }
+ else {
+ printf("Mesh tag %d is not associated to any physical tag!\n",tagEntity);
+ }
+ }
+ }
+
for(i=1; i <= numElements; i++) {
- getline;
+ GETLINE;
cp = line;
k += 1;
elemno = next_int(&cp);
-
+
if(allocated) {
data->elementtypes[k] = elementtype;
data->material[k] = tagEntity;
- for(j=0;jtopology[k][j] = elemind[j];
+ for(l=0;ltopology[k][l] = elemind[l];
}
}
}
- getline;
+ GETLINE;
if(!strstr(line,"$EndElements")) {
printf("$Elements section should end to string $EndElements:\n%s\n",line);
}
}
else if(strstr(line,"$PhysicalNames")) {
- getline;
+ GETLINE;
cp = line;
nophysical = next_int(&cp);
for(i=0;iboundaryname[tagphys]);
- else printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[dim-1],cp+1);
+ if(tagphys < MAXBCS) {
+ sscanf(cp," \"%[^\"]\"",data->boundaryname[tagphys]);
+ printf("Boundary name for physical group %d is: %s\n",tagphys,data->boundaryname[tagphys]);
+ }
+ else
+ printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[dim-1],cp+1);
}
else if(gmshtype == dim) {
physvolexist = TRUE;
- if(tagphys < MAXBODIES) sscanf(cp," \"%[^\"]\"",data->bodyname[tagphys]);
- else printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[dim],cp+1);
+ if(tagphys < MAXBODIES) {
+ sscanf(cp," \"%[^\"]\"",data->bodyname[tagphys]);
+ printf("Body name for physical group %d is: %s\n",tagphys,data->bodyname[tagphys]);
+ }
+ else
+ printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[dim],cp+1);
}
else printf("Physical groups of dimension %d not supported in %d-dimensional mesh: "
"ignoring group %d %s",gmshtype,dim,tagphys,cp+1);
}
}
- getline;
+ GETLINE;
if(!strstr(line,"$EndPhysicalNames")) {
printf("$PhysicalNames section should end to string $EndPhysicalNames:\n%s\n",line);
}
@@ -3356,13 +4065,13 @@ static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
int numPeriodicLinks;
if(allocated) printf("Reading periodic links but doing nothing with them!\n");
- getline;
+ GETLINE;
cp = line;
numPeriodicLinks = next_int(&cp);
for(i=1; i <= numPeriodicLinks; i++) {
- getline;
+ GETLINE;
}
- getline;
+ GETLINE;
if(!strstr(line,"$EndPeriodic")) {
printf("$Periodic section should end to string $EndPeriodic:\n%s\n",line);
}
@@ -3371,42 +4080,42 @@ static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
else if(strstr(line,"$PartitionedEntities")) {
if(allocated) printf("Reading partitioned entities but doing nothing with them!\n");
for(;;) {
- getline;
+ GETLINE;
if(strstr(line,"$EndPartitionedEntities")) break;
}
}
else if(strstr(line,"$NodeData")) {
if(allocated) printf("Reading node data but doing nothing with them!\n");
for(;;) {
- getline;
+ GETLINE;
if(strstr(line,"$EndNodeData")) break;
}
}
else if(strstr(line,"$ElementData")) {
if(allocated) printf("Reading element data but doing nothing with them!\n");
for(;;) {
- getline;
+ GETLINE;
if(strstr(line,"$EndElementData")) break;
}
}
else if(strstr(line,"$ElementNodeData")) {
if(allocated) printf("Reading element node data but doing nothing with them!\n");
for(;;) {
- getline;
+ GETLINE;
if(strstr(line,"$EndElementNodeData")) break;
}
}
else if(strstr(line,"$GhostElements")) {
if(allocated) printf("Reading ghost elements data but doing nothing with them!\n");
for(;;) {
- getline;
+ GETLINE;
if(strstr(line,"$EndGhostElements")) break;
}
}
else if(strstr(line,"$InterpolationScheme")) {
if(allocated) printf("Reading interpolation scheme but doing nothing with them!\n");
for(;;) {
- getline;
+ GETLINE;
if(strstr(line,"$EndInterpolationScheme")) break;
}
}
@@ -3454,7 +4163,7 @@ static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
if(k <= 0 || k > maxindx)
printf("index out of bounds %d\n",k);
else if(revindx[k] <= 0)
- printf("unkonwn node %d %d in element %d\n",k,revindx[k],i);
+ printf("unknown node %d %d in element %d\n",k,revindx[k],i);
else
data->topology[i][j] = revindx[k];
}
@@ -3464,785 +4173,2281 @@ static int LoadGmshInput4(struct FemType *data,struct BoundaryType *bound,
ElementsToBoundaryConditions(data,bound,FALSE,info);
- /* The geometric entities are rather randomly numbered */
- if( usetaggeom ) {
- RenumberBoundaryTypes(data,bound,TRUE,0,info);
- RenumberMaterialTypes(data,bound,info);
- }
data->bodynamesexist = physvolexist;
data->boundarynamesexist = physsurfexist;
-
+
+ if( tagsize > 0 ) free_Imatrix(tagmap,0,3,1,tagsize);
+
if(info) printf("Successfully read the mesh from the Gmsh input file.\n");
return(0);
}
-
-int LoadGmshInput(struct FemType *data,struct BoundaryType *bound,
- char *prefix,int info)
+static int LoadGmshInput41(struct FemType *data,struct BoundaryType *bound,
+ char *filename,int usetaggeom, int info)
{
+ int noknots = 0,noelements = 0,nophysical = 0,maxnodes,dim,notags;
+ int elemind[MAXNODESD2],elementtype;
+ int i,j,k,l,allocated,*revindx=NULL,maxindx;
+ int elemno, gmshtype, tagphys=0, tagpart, elemnodes,maxelemtype;
+ int tagmat,verno;
+ int physvolexist, physsurfexist,**tagmap,tagsize,maxtag[4];
FILE *in;
- char line[MAXLINESIZE],filename[MAXFILESIZE];
- int errno;
+ const char manifoldname[4][10] = {"point", "line", "surface", "volume"};
+ char *cp,line[MAXLINESIZE],longline[LONGLINESIZE];
- sprintf(filename,"%s",prefix);
if ((in = fopen(filename,"r")) == NULL) {
- sprintf(filename,"%s.msh",prefix);
- if ((in = fopen(filename,"r")) == NULL) {
- printf("LoadElmerInput: The opening of the mesh file %s failed!\n",filename);
- return(1);
- }
+ printf("The opening of the mesh file %s failed!\n",filename);
+ return(1);
}
+ if(info) printf("Loading mesh in Gmsh format 4.1 from file %s\n",filename);
- Getrow(line,in,FALSE);
+ allocated = FALSE;
+ dim = data->dim;
+ maxnodes = 0;
+ maxindx = 0;
+ maxelemtype = 0;
+ physvolexist = FALSE;
+ physsurfexist = FALSE;
+ usetaggeom = TRUE; /* The default */
+ for(i=0;i<4;i++) maxtag[i] = 0;
- if(info) {
- printf("Format chosen using the first line: %s",line);
- }
+omstart:
- if(strstr(line,"$")) {
- int verno;
- char *cp;
-
- Getrow(line,in,FALSE);
- cp = line;
- verno = next_int(&cp);
- fclose(in);
-
- if( verno == 4 )
- errno = LoadGmshInput4(data,bound,filename,info);
- else
- errno = LoadGmshInput2(data,bound,filename,info);
-
- } else {
- fclose(in);
- printf("*****************************************************\n");
- printf("The first line did not start with $, assuming Gmsh 1 format\n");
- printf("This version of Gmsh format is no longer supported\n");
- printf("Please use Gsmh 2 or 4 versions for output\n");
- printf("*****************************************************\n");
-
- errno = LoadGmshInput1(data,bound,filename,info);
- }
+ for(;;) {
+ if(Getrow(line,in,FALSE)) goto end;
+ if(strstr(line,"$End")) continue;
+
+ if(strstr(line,"$MeshFormat")) {
+ GETLINE;
+ cp = line;
+ verno = next_int(&cp);
- return(errno);
-}
+ if(verno != 4) {
+ printf("Version number is not compatible with the parser: %d\n",verno);
+ }
+ GETLINE;
+ if(!strstr(line,"$EndMeshFormat")) {
+ printf("$MeshFormat section should end to string $EndMeshFormat:\n%s\n",line);
+ }
+ }
+
+ else if(strstr(line,"$Nodes")) {
+ int numEntityBlocks,tagEntity,dimEntity,parEntity,numNodes,ind;
+ int minNodeTag, maxNodeTag, parTag;
+
+ GETLINE;
+ cp = line;
+ numEntityBlocks = next_int(&cp);
+ noknots = next_int(&cp);
+ minNodeTag = next_int(&cp);
+ maxNodeTag = next_int(&cp);
+
+ if(allocated && info) printf("Reading %d nodes in %d blocks.\n",noknots,numEntityBlocks);
+
+ k = 0;
+
+ for(j=1; j <= numEntityBlocks; j++) {
+ GETLINE;
+ cp = line;
+ dimEntity = next_int(&cp);
+ tagEntity = next_int(&cp);
+ parTag = next_int(&cp);
+ numNodes = next_int(&cp);
-static int UnvToElmerType(int unvtype)
-{
+ if( 0 && numNodes > 1 ) printf("Reading node block %d with %d nodes\n",j,numNodes);
+
+ for(i=1; i <= numNodes; i++) {
+ GETLINE;
+ cp = line;
+
+ ind = next_int(&cp);
+
+ if( 0 && numNodes > 1 ) printf("block %d node %d ind %d %d\n",j,i,ind,k+i);
+
+ if(allocated) {
+ if(maxindx > noknots) revindx[ind] = k+i;
+ }
+ else {
+ maxindx = MAX(ind,maxindx);
+ }
+ }
+
+ for(i=1; i <= numNodes; i++) {
+ GETLINE;
+ cp = line;
+
+ if(allocated) {
+ data->x[k+i] = next_real(&cp);
+ data->y[k+i] = next_real(&cp);
+ if(dim > 2) data->z[k+i] = next_real(&cp);
+ }
+ }
+ k += numNodes;
+ }
+ GETLINE;
+
+ if(!strstr(line,"$EndNodes")) {
+ printf("$Nodes section should end to string $EndNodes:\n%s\n",line);
+ }
+ }
+
+ else if(strstr(line,"$Entities")) {
+ int numPoints, numCurves, numSurfaces, numVolumes, numEnt;
+ int tag,tagdim,nophys,phystag;
+ int nobound, idum;
+ Real rdum;
+
+ usetaggeom = FALSE;
+
+ GETLINE;
+ cp = line;
+ numPoints = next_int(&cp);
+ numCurves = next_int(&cp);
+ numSurfaces = next_int(&cp);
+ numVolumes = next_int(&cp);
+
+ if(allocated) {
+ tagsize = 0;
+ for(tagdim=0;tagdim<=3;tagdim++)
+ tagsize = MAX( tagsize, maxtag[tagdim]);
+ if(info) printf("Allocating lookup table for tags of size %d\n",tagsize);
+ if( tagsize > 0 ) {
+ tagmap = Imatrix(0,3,1,tagsize);
+ for(i=0;i<=3;i++)
+ for(j=1;j<=tagsize;j++)
+ tagmap[i][j] = 0;
+ }
+ }
+
+ for(tagdim=0;tagdim<=3;tagdim++) {
+
+ if( tagdim == 0 )
+ numEnt = numPoints;
+ else if( tagdim == 1 )
+ numEnt = numCurves;
+ else if( tagdim == 2 )
+ numEnt = numSurfaces;
+ else if( tagdim == 3 )
+ numEnt = numVolumes;
+
+ if(!allocated)
+ maxtag[tagdim] = 0;
+ else if( maxtag[tagdim] > 0 )
+ printf("Maximum original tag for %d %dDIM entities is %d\n",numEnt,tagdim,maxtag[tagdim]);
+
+ if(numEnt > 0 && !allocated) printf("Reading %d entities in %dD\n",numEnt,tagdim);
+
+
+ for(i=1; i <= numEnt; i++) {
+ GETLONGLINE;
+
+ // if( i==1 ) printf("1st line of dim %d with %d entries: %s\n",tagdim,numEnt,line);
+
+ if( tagdim == 0 ) continue;
+
+ cp = longline;
+ tag = next_int(&cp);
+
+ if(!allocated)
+ maxtag[tagdim] = MAX( maxtag[tagdim], tag );
+
+ for(j=1;j<=6;j++) rdum = next_real(&cp);
+ nophys = next_int(&cp);
+
+ if( nophys > 0 )
+ phystag = next_int(&cp);
+ else
+ phystag = 0;
+
+ if(allocated) tagmap[tagdim][tag] = phystag;
+
+
+ // The lines may be too long. So fill the string buffer until we get a newline.
+ j = k = 0;
+ for(;;) {
+ for(l=0;l 0 && !allocated) printf("Entity line %d has length %d.\n",i,k+j);
+
+ //for(j=2;j<=nophys;j++)
+ // idum = next_int(&cp);
+
+ //// if( tagdim == 0 ) continue;
+
+ //nobound = next_int(&cp);
+ // for(j=1;j<=nobound;j++)
+ // idum = next_int(&cp);
+ }
+ }
+
+ GETLONGLINE;
+ if(!strstr(longline,"$EndEntities")) {
+ printf("$Entities section should end to string $EndEntities:\n%s\n",longline);
+ }
+ }
+
+ else if(strstr(line,"$Elements")) {
+ int numEntityBlocks, numElements, tagEntity, dimEntity, typeEle, NumElements;
+ int minElementTag, maxElementTag;
+
+ GETLINE;
+ cp = line;
+
+ k = 0;
+ numEntityBlocks = next_int(&cp);
+ noelements = next_int(&cp);
+ minElementTag = next_int(&cp);
+ maxElementTag = next_int(&cp);
+
+ if(allocated) printf("Reading %d elements in %d blocks.\n",noelements,numEntityBlocks);
+
+
+ for(j=1; j<= numEntityBlocks; j++ ) {
+
+ GETLINE;
+ cp = line;
+
+ dimEntity = next_int(&cp);
+ tagEntity = next_int(&cp);
+ typeEle = next_int(&cp);
+ numElements = next_int(&cp);
+
+ elementtype = GmshToElmerType(typeEle);
+ elemnodes = elementtype % 100;
+ maxelemtype = MAX(maxelemtype,elementtype);
+
+ if( allocated && tagsize > 0 ) {
+ printf("Reading %d elements with tag %d of type %d\n", numElements, tagEntity, elementtype);
+ if( tagsize > 0 ) {
+ if( tagmap[dimEntity][tagEntity] ) {
+ printf("Mapping mesh tag %d to physical tag %d in %dDIM\n",tagEntity,tagmap[dimEntity][tagEntity],dimEntity);
+ tagEntity = tagmap[dimEntity][tagEntity];
+ }
+ else {
+ printf("Mesh tag %d is not associated to any physical tag!\n",tagEntity);
+ }
+ }
+ }
+
+ for(i=1; i <= numElements; i++) {
+ GETLINE;
+ cp = line;
+
+ k += 1;
+
+ elemno = next_int(&cp);
+
+ if(allocated) {
+ data->elementtypes[k] = elementtype;
+ data->material[k] = tagEntity;
+ for(l=0;ltopology[k][l] = elemind[l];
+ }
+ }
+ }
+
+ GETLINE;
+ if(!strstr(line,"$EndElements")) {
+ printf("$Elements section should end to string $EndElements:\n%s\n",line);
+ }
+ }
+
+ else if(strstr(line,"$PhysicalNames")) {
+ GETLINE;
+ cp = line;
+ nophysical = next_int(&cp);
+ for(i=0;iboundaryname[tagphys]);
+ printf("Boundary name for physical group %d is: %s\n",tagphys,data->boundaryname[tagphys]);
+ }
+ else
+ printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[dim-1],cp+1);
+ }
+ else if(gmshtype == dim) {
+ physvolexist = TRUE;
+ if(tagphys < MAXBODIES) {
+ sscanf(cp," \"%[^\"]\"",data->bodyname[tagphys]);
+ printf("Body name for physical group %d is: %s\n",tagphys,data->bodyname[tagphys]);
+ }
+ else
+ printf("Index %d too high: ignoring physical %s %s",tagphys,manifoldname[dim],cp+1);
+ }
+ else printf("Physical groups of dimension %d not supported in %d-dimensional mesh: "
+ "ignoring group %d %s",gmshtype,dim,tagphys,cp+1);
+ }
+ }
+
+ GETLINE;
+ if(!strstr(line,"$EndPhysicalNames")) {
+ printf("$PhysicalNames section should end to string $EndPhysicalNames:\n%s\n",line);
+ }
+ }
+ else if(strstr(line,"$Periodic")) {
+ int numPeriodicLinks;
+ if(allocated) printf("Reading periodic links but doing nothing with them!\n");
+
+ GETLINE;
+ cp = line;
+ numPeriodicLinks = next_int(&cp);
+ for(i=1; i <= numPeriodicLinks; i++) {
+ GETLINE;
+ }
+ GETLINE;
+ if(!strstr(line,"$EndPeriodic")) {
+ printf("$Periodic section should end to string $EndPeriodic:\n%s\n",line);
+ }
+ }
+
+ else if(strstr(line,"$PartitionedEntities")) {
+ if(allocated) printf("Reading partitioned entities but doing nothing with them!\n");
+ for(;;) {
+ GETLINE;
+ if(strstr(line,"$EndPartitionedEntities")) break;
+ }
+ }
+ else if(strstr(line,"$NodeData")) {
+ if(allocated) printf("Reading node data but doing nothing with them!\n");
+ for(;;) {
+ GETLINE;
+ if(strstr(line,"$EndNodeData")) break;
+ }
+ }
+ else if(strstr(line,"$ElementData")) {
+ if(allocated) printf("Reading element data but doing nothing with them!\n");
+ for(;;) {
+ GETLINE;
+ if(strstr(line,"$EndElementData")) break;
+ }
+ }
+ else if(strstr(line,"$ElementNodeData")) {
+ if(allocated) printf("Reading element node data but doing nothing with them!\n");
+ for(;;) {
+ GETLINE;
+ if(strstr(line,"$EndElementNodeData")) break;
+ }
+ }
+ else if(strstr(line,"$GhostElements")) {
+ if(allocated) printf("Reading ghost elements data but doing nothing with them!\n");
+ for(;;) {
+ GETLINE;
+ if(strstr(line,"$EndGhostElements")) break;
+ }
+ }
+ else if(strstr(line,"$InterpolationScheme")) {
+ if(allocated) printf("Reading interpolation scheme but doing nothing with them!\n");
+ for(;;) {
+ GETLINE;
+ if(strstr(line,"$EndInterpolationScheme")) break;
+ }
+ }
+ else {
+ if(allocated) printf("Untreated command: %s",line);
+ }
+
+ }
+
+ end:
+
+
+ if(!allocated) {
+ if( noelements == 0 ) bigerror("No elements to load in Gmsh file!");
+ if( noknots == 0 ) bigerror("No nodes to load in Gmsh file!");
+
+ maxnodes = maxelemtype % 100;
+ InitializeKnots(data);
+ data->dim = dim;
+ data->maxnodes = maxnodes;
+ data->noelements = noelements;
+ data->noknots = noknots;
+
+ if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
+ AllocateKnots(data);
+
+ if(maxindx > noknots) {
+ revindx = Ivector(1,maxindx);
+ for(i=1;i<=maxindx;i++) revindx[i] = 0;
+ }
+ rewind(in);
+ allocated = TRUE;
+ goto omstart;
+ }
+
+ if(maxindx > noknots) {
+ printf("Renumbering the Gmsh nodes from %d to %d\n",maxindx,noknots);
+
+ for(i=1; i <= noelements; i++) {
+ elementtype = data->elementtypes[i];
+ elemnodes = elementtype % 100;
+
+ for(j=0;jtopology[i][j];
+ if(k <= 0 || k > maxindx)
+ printf("index out of bounds %d\n",k);
+ else if(revindx[k] <= 0)
+ printf("unknown node %d %d in element %d\n",k,revindx[k],i);
+ else
+ data->topology[i][j] = revindx[k];
+ }
+ }
+ free_Ivector(revindx,1,maxindx);
+ }
+
+ ElementsToBoundaryConditions(data,bound,FALSE,info);
+
+ data->bodynamesexist = physvolexist;
+ data->boundarynamesexist = physsurfexist;
+
+ if( tagsize > 0 ) free_Imatrix(tagmap,0,3,1,tagsize);
+
+ if(info) printf("Successfully read the mesh from the Gmsh input file.\n");
+
+ return(0);
+}
+
+int LoadGmshInput(struct FemType *data,struct BoundaryType *bound,
+ char *prefix,int info)
+{
+ FILE *in;
+ char line[MAXLINESIZE],filename[MAXFILESIZE];
+ int errnum,usetaggeom;
+
+ sprintf(filename,"%s",prefix);
+ if ((in = fopen(filename,"r")) == NULL) {
+ sprintf(filename,"%s.msh",prefix);
+ if ((in = fopen(filename,"r")) == NULL) {
+ printf("LoadGmshInput: The opening of the mesh file %s failed!\n",filename);
+ return(1);
+ }
+ }
+
+ Getrow(line,in,FALSE);
+
+ if(info) {
+ printf("Format chosen using the first line: %s",line);
+ }
+
+ if(strstr(line,"$")) {
+ int verno,minorno;
+ char *cp;
+
+ Getrow(line,in,FALSE);
+ cp = line;
+ verno = next_int(&cp);
+ cp++;
+ minorno = next_int(&cp);
+
+ if(info) printf("Gmsh version is %d.%d\n",verno,minorno);
+
+ fclose(in);
+
+ if( verno == 4 ) {
+ if( minorno == 0 )
+ errnum = LoadGmshInput4(data,bound,filename,usetaggeom,info);
+ else if( minorno == 1 )
+ errnum = LoadGmshInput41(data,bound,filename,usetaggeom,info);
+ else
+ printf("Minor version not yet supported, cannot continue!\n");
+ }
+ else {
+ errnum = LoadGmshInput2(data,bound,filename,usetaggeom,info);
+ }
+ } else {
+ fclose(in);
+ printf("*****************************************************\n");
+ printf("The first line did not start with $, assuming Gmsh 1 format\n");
+ printf("This version of Gmsh format is no longer supported\n");
+ printf("Please use Gsmh 2 or 4 versions for output\n");
+ printf("*****************************************************\n");
+
+ errnum = LoadGmshInput1(data,bound,filename,info);
+ }
+
+ if( info ) {
+ if( usetaggeom )
+ printf("Using geometric numbering of entities\n");
+ else
+ printf("Using physical numbering of entities\n");
+ }
+
+ return(errnum);
+}
+
+
+
+int LoadFvcomMesh(struct FemType *data,struct BoundaryType *bound,
+ char *filename,int info)
+{
+ int noknots = 0,noelements = 0,maxnodes,dim;
+ int elemind[MAXNODESD2],elementtype;
+ int i,j,k,allocated,*revindx=NULL,maxindx;
+ int elemnodes,maxelemtype,elemtype0,bclines;
+ int tagmat,bccount;
+ int *bcinds,*bctags,nbc,nbc0,bc_id;
+ FILE *in;
+ char *cp,line[MAXLINESIZE];
+
+
+ if ((in = fopen(filename,"r")) == NULL) {
+ printf("LoadFVCOMInput: The opening of the FVCOM mesh file %s failed!\n",filename);
+ return(1);
+ }
+ if(info) printf("Loading mesh in FVCOM format from file %s\n",filename);
+
+ allocated = FALSE;
+ dim = 2;
+ maxnodes = 0;
+ maxindx = 0;
+ maxelemtype = 303;
+
+ noelements = 0;
+ bclines = 0;
+
+
+omstart:
+
+ noelements = 0;
+ noknots = 0;
+ nbc = 0;
+ nbc0 = 1;
+ bclines = 0;
+ bccount = 0;
+
+ for(;;) {
+ if(Getrow(line,in,FALSE)) goto end;
+ if(line[0]=='\0') goto end;
+
+ if(memcmp(line,"E3T",3) == 0 ) {
+ noelements += 1;
+ if(allocated) {
+ cp = line+4;
+ i = next_int(&cp);
+ if(i != noelements ) printf("Invalid element number: %d %d\n",noelements,i);
+
+ data->elementtypes[i] = 303;
+ for(k=0;k<3;k++)
+ data->topology[i][k] = next_int(&cp);
+ data->material[i] = next_int(&cp);
+ }
+ }
+ else if(memcmp(line,"ND",2) == 0 ) {
+ noknots += 1;
+ if(allocated) {
+ cp = line+3;
+ i = next_int(&cp);
+ if(i != noknots ) printf("Invalid node number: %d %d\n",noknots,i);
+ data->x[i] = next_real(&cp);
+ data->y[i] = next_real(&cp);
+ if(dim > 2) data->z[i] = next_real(&cp);
+ }
+ }
+ else if(memcmp(line,"NS",2) == 0 ) {
+ bclines += 1;
+
+ if(allocated){
+ cp = line+3;
+
+ for(i=0;i<10;i++) {
+ j = next_int(&cp);
+
+ nbc += 1;
+ bcinds[nbc] = abs(j);
+
+ if( j < 0 ) {
+ bccount += 1;
+ bc_id = next_int(&cp);
+
+ for(k=nbc0;k<=nbc;k++)
+ bctags[k] = bc_id;
+
+ nbc0 = nbc+1;
+ break;
+ }
+ }
+ }
+ }
+ else if(memcmp(line,"MESH2D",6) == 0 ) {
+ if(!allocated) printf("Yes, we have MESH2D as we should\n");
+ }
+ else if(memcmp(line,"MESHNAME",8) == 0 ) {
+ if(!allocated) printf("Mesh name found but not used: %s\n",line+9);
+ }
+ }
+
+ end:
+
+
+ if(!allocated) {
+ maxnodes = maxelemtype % 100;
+ InitializeKnots(data);
+ data->dim = dim;
+ data->maxnodes = maxnodes;
+ data->noelements = noelements;
+ data->noknots = noknots;
+
+ if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
+ AllocateKnots(data);
+
+ printf("Number of BC lines: %d\n",bclines);
+ bcinds = Ivector(1,10*bclines);
+ bctags = Ivector(1,10*bclines);
+ for(i=1;i<=10*bclines;i++) bcinds[i] = bctags[i] = 0;
+
+ rewind(in);
+ allocated = TRUE;
+ goto omstart;
+ }
+
+ printf("Number of different BCs: %d\n",bccount);
+ printf("Number of BC nodes: %d\n",nbc);
+
+ NodesToBoundaryChain(data,bound,bcinds,bctags,nbc,bccount,info);
+
+ free_Ivector(bcinds,1,10*bclines);
+ free_Ivector(bctags,1,10*bclines);
+
+ if(info) printf("Successfully read the mesh from the FVCOM file!\n");
+
+ return(0);
+}
+
+
+int LoadGeoInput(struct FemType *data,struct BoundaryType *bound,
+ char *filename,int info)
+{
+ int noknots = 0,noelements = 0,maxnodes,dim;
+ int elemind[MAXNODESD2],elementtype;
+ int i,j,k,allocated,*revindx=NULL,maxindx;
+ int elemnodes,maxelemtype,elemtype0;
+ int tagmat;
+ FILE *in;
+ char *cp,line[MAXLINESIZE];
+
+
+ if ((in = fopen(filename,"r")) == NULL) {
+ printf("LoadGeoInput: The opening of the mesh file %s failed!\n",filename);
+ return(1);
+ }
+ if(info) printf("Loading mesh in geo format from file %s\n",filename);
+
+ allocated = FALSE;
+ dim = 3;
+ maxnodes = 0;
+ maxindx = 0;
+ maxelemtype = 0;
+
+omstart:
+
+
+ for(;;) {
+ if(Getrow(line,in,FALSE)) goto end;
+ if(line[0]=='\0') goto end;
+ if(strstr(line,"$End")) continue;
+
+ if(strstr(line,"TYPES")) {
+ if(!strstr(line,"ALL=TET04")) {
+ printf("Only all tets implemnted at the monment!\n");
+ return(1);
+ }
+ elemtype0 = 504;
+ GETLINE;
+ }
+ else if(strstr(line,"COORDINATES")) {
+ i = 0;
+ for(;;) {
+ GETLINE;
+ if( strstr(line,"END_COORDINATES")) break;
+ cp = line;
+ j = next_int(&cp);
+ i = i + 1;
+ if(allocated) {
+ if(maxindx > noknots) revindx[j] = i;
+ data->x[i] = next_real(&cp);
+ data->y[i] = next_real(&cp);
+ if(dim > 2) data->z[i] = next_real(&cp);
+ }
+ else {
+ maxindx = MAX(j,maxindx);
+ }
+ }
+ noknots = i;
+ }
+ else if(strstr(line,"ELEMENTS")) {
+ i = 0;
+ elementtype = elemtype0;
+ tagmat = 1;
+
+ for(;;) {
+ GETLINE;
+ if( strstr(line,"END_ELEMENTS")) break;
+ cp = line;
+ j = next_int(&cp);
+ i = i + 1;
+
+ if(allocated) {
+ elemnodes = elementtype % 100;
+ data->elementtypes[i] = elementtype;
+ data->material[i] = tagmat;
+ for(k=0;ktopology[i][k] = elemind[k];
+ }
+ else {
+ maxelemtype = MAX(maxelemtype,elementtype);
+ }
+ }
+ noelements = i;
+ }
+ else if ( strstr(line,"BOUNDARIES")) {
+ for(;;) {
+ GETLINE;
+ if( strstr(line,"END_BOUNDARIES")) break;
+
+ printf("Implement boundaries!\n");
+ }
+ }
+ }
+
+ end:
+
+
+ if(!allocated) {
+ maxnodes = maxelemtype % 100;
+ InitializeKnots(data);
+ data->dim = dim;
+ data->maxnodes = maxnodes;
+ data->noelements = noelements;
+ data->noknots = noknots;
+
+ if(info) printf("Allocating for %d knots and %d elements.\n",noknots,noelements);
+ AllocateKnots(data);
+
+ if(maxindx > noknots) {
+ revindx = Ivector(1,maxindx);
+ for(i=1;i<=maxindx;i++) revindx[i] = 0;
+ }
+ rewind(in);
+ allocated = TRUE;
+ goto omstart;
+ }
+
+ if(maxindx > noknots) {
+ printf("Renumbering the Geo nodes from %d to %d\n",maxindx,noknots);
+
+ for(i=1; i <= noelements; i++) {
+ elementtype = data->elementtypes[i];
+ elemnodes = elementtype % 100;
+
+ for(j=0;jtopology[i][j];
+ if(k <= 0 || k > maxindx)
+ printf("index out of bounds %d\n",k);
+ else if(revindx[k] <= 0)
+ printf("unknown node %d %d in element %d\n",k,revindx[k],i);
+ else
+ data->topology[i][j] = revindx[k];
+ }
+ }
+ free_Ivector(revindx,1,maxindx);
+ }
+
+ if(0) ElementsToBoundaryConditions(data,bound,FALSE,info);
+
+ if(info) printf("Successfully read the mesh from the Geo input file.\n");
+
+ return(0);
+}
+
+
+/* Mapping between the element type of Universal file format and
+ ElmerSolver element type. */
+static int UnvToElmerType(int unvtype)
+{
int elmertype;
- switch (unvtype) {
+ switch (unvtype) {
+
+ case 11:
+ case 21:
+ elmertype = 202;
+ break;
+
+ case 22:
+ case 23:
+ case 24:
+ elmertype = 203;
+ break;
+
+ case 41:
+ case 51:
+ case 61:
+ case 74:
+ case 81:
+ case 91:
+ elmertype = 303;
+ break;
+
+ case 42:
+ case 52:
+ case 62:
+ case 72:
+ case 82:
+ case 92:
+ elmertype = 306;
+ break;
+
+ case 43:
+ case 53:
+ case 63:
+ case 73:
+ case 93:
+ elmertype = 310;
+ break;
+
+ case 44:
+ case 54:
+ case 64:
+ case 71:
+ case 84:
+ case 94:
+ elmertype = 404;
+ break;
+
+ case 45:
+ case 46:
+ case 56:
+ case 66:
+ case 76:
+ case 96:
+ elmertype = 408;
+ break;
+
+ case 111:
+ elmertype = 504;
+ break;
+
+ case 118:
+ elmertype = 510;
+ break;
+
+ case 101:
+ case 112:
+ elmertype = 706;
+ break;
+
+ case 102:
+ case 113:
+ elmertype = 715;
+ break;
+
+ case 104:
+ case 115:
+ elmertype = 808;
+ break;
+
+ case 105:
+ case 116:
+ elmertype = 820;
+ break;
+
+ default:
+ elmertype = 0;
+ if(0) printf("Unknown elementtype in universal mesh format: %d\n",unvtype);
+ }
+
+ return(elmertype);
+}
+
+
+/* The Universal format supports something as "degenerated" elements.
+ This means that the same node is given multiple times in the element
+ topology */
+static int UnvRedundantIndexes(int nonodes,int *ind)
+{
+ int i,j,redundant;
+
+ redundant = FALSE;
+ for(i=0;ix[noknots] = next_real(&cp);
+ data->y[noknots] = next_real(&cp);
+ data->z[noknots] = next_real(&cp);
+ }
+ else {
+ if(nodeind != noknots) reordernodes = TRUE;
+ maxnodeind = MAX(maxnodeind,nodeind);
+ }
+ }
+ }
+
+ if( mode == 2412 ) {
+ minelemtype = INT_MAX;
+ maxelemtype = 0;
+
+ if(allocated && info) printf("Reading element topologies\n");
+ for(;;) {
+ Getrow(line,in,FALSE);
+ if( strstr(line,"-1")) {
+ if(info && !allocated) printf("Element type range in mesh [%d,%d]\n",minelemtype,maxelemtype);
+ goto nextline;
+ }
+
+ noelements += 1;
+ cp = line;
+ elid = next_int(&cp);
+ unvtype = next_int(&cp);
+ physind = next_int(&cp);
+ matind = next_int(&cp);
+ colorind = next_int(&cp);
+ nonodes = next_int(&cp);
+
+ if(!allocated ) {
+ if(0) printf("elem = %d %d %d %d\n",noelements,unvtype,physind,matind);
+ }
+
+ elmertype = UnvToElmerType(unvtype);
+ if(!elmertype) {
+ printf("Unknown elementtype %d %d %d %d %d %d %d\n",
+ noelements,elid,unvtype,physind,matind,colorind,nonodes);
+ printf("line %d: %s\n",linenumber,line);
+ bigerror("done");
+ }
+
+ if (!allocated) {
+ minphys = MIN( minphys, physind );
+ maxphys = MAX( maxphys, physind );
+ maxnodes = MAX(maxnodes, nonodes);
+ if(elid != noelements) reorderelements = TRUE;
+ maxelem = MAX(maxelem, elid);
+ }
+
+ /* For beam elements there is a stupid additional row filled with zeros? */
+ isbeam = ( elmertype / 100 == 2);
+ if(isbeam)Getrow(line,in,FALSE);
+
+ Getrow(line,in,FALSE);
+ cp = line;
+
+ if(elmertype == 510 )
+ lines = 1;
+ else if(elmertype == 820 )
+ lines = 2;
+ else
+ lines = 0;
+
+ if(allocated) {
+ if(reorderelements) u2eelem[elid] = noelements;
+
+ if(debug && !elementtypes[elmertype]) {
+ elementtypes[elmertype] = TRUE;
+ printf("new elementtype in elmer: %d (unv: %d)\n",elmertype,unvtype);
+ }
+
+ if(elmertype % 100 != nonodes) {
+ printf("nonodes = %d elemtype = %d elid = %d\n",nonodes,elmertype,elid);
+ nonodes = elmertype % 100;
+ }
+
+ data->elementtypes[noelements] = elmertype;
+ for(i=0;i 0 && i >= 8 ) {
+ if( i%8 == 0 ) {
+ Getrow(line,in,FALSE);
+ cp = line;
+ }
+ }
+ data->topology[noelements][i] = next_int(&cp);
+ }
+
+ UnvRedundantIndexes(nonodes,data->topology[noelements]);
+
+ UnvToElmerIndx(elmertype,data->topology[noelements]);
+
+ /* should this be physical property or material property? */
+ data->material[noelements] = physind + physoffset;
+ }
+ else {
+ minelemtype = MIN( minelemtype, elmertype );
+ maxelemtype = MAX( maxelemtype, elmertype );
+ for(i=1;i<=lines;i++) {
+ Getrow(line,in,FALSE);
+ }
+ }
+ }
+ }
+
+ if( mode == 2420 ) {
+ int partuid,coordlabel,coordtype;
+ Real coeff;
+ if(allocated && info) printf("Reading Coordinate system information\n");
+
+ Getrow(line,in,FALSE);
+ if( !allocated ) {
+ cp = line;
+ partuid = next_int(&cp);
+ printf("Part UID = %d\n",partuid);
+ }
+ Getrow(line,in,FALSE);
+ if(!allocated ) {
+ sscanf(line,"%s",entityname);
+ printf("Part name = %s\n",entityname);
+ }
+ Getrow(line,in,FALSE);
+ if( !allocated ) {
+ cp = line;
+ coordlabel = next_int(&cp);
+ coordtype = next_int(&cp);
+ if( coordtype != 0 ) {
+ printf("Coordinate system is not cartesian: %d\n",coordtype);
+ printf("Code some more if you want to consider this!\n");
+ }
+ }
+
+ Getrow(line,in,FALSE);
+ if(!allocated ) {
+ sscanf(line,"%s",entityname);
+ printf("Coord system name = %s\n",entityname);
+ }
+ for(i=1;i<=4;i++) {
+ Getrow(line,in,FALSE);
+ if( !allocated ) {
+ cp = line;
+ if(!cp) printf("Problem reading line %d for coordinate system\n",i);
+ for(j=1;j<= 3;j++) {
+ coeff = next_real(&cp);
+ if( i == j ) {
+ scaling[i] = coeff;
+ if( fabs(coeff) < 1.0e-20) {
+ printf("Scaling for component %d too small %le\n",i,coeff);
+ }
+ else if( fabs(coeff-1.0) ) {
+ doscaling = TRUE;
+ printf("Scaling component %d by %le\n",i,coeff);
+ }
+ }
+ else {
+ if(fabs(coeff) > 1.0e-20 ) {
+ printf("Transformation matrix is not diagonal %d%d: %e\n",i,j,coeff);
+ smallerror("Code some more...");
+ }
+ }
+ }
+ }
+ }
+ Getrow(line,in,FALSE);
+ if( strncmp(line," -1",6))
+ printf("Field 2420 should already be ending: %s\n",line);
+ goto nextline;
+ }
- case 11:
- case 21:
- elmertype = 202;
- break;
+ if( mode == 780 ) {
+ int physind2,matind2;
+ maxelemtype = 0;
+ minelemtype = 1000;
- case 22:
- case 23:
- elmertype = 203;
- break;
+ if(allocated && info) printf("Reading element groups in mode %d\n",mode);
+ for(;;) {
+ Getrow(line,in,FALSE);
+ if( !strncmp(line," -1",6)) goto nextline;
+
+ noelements += 1;
+ cp = line;
+ elid = next_int(&cp);
+ unvtype = next_int(&cp);
- case 41:
- case 51:
- case 61:
- case 74:
- case 81:
- case 91:
- elmertype = 303;
- break;
+ physind = next_int(&cp);
+ physind2 = next_int(&cp);
+ matind = next_int(&cp);
+ matind2 = next_int(&cp);
+ colorind = next_int(&cp);
+ nonodes = next_int(&cp);
+
+ if (!allocated) {
+ maxnodes = MAX(maxnodes, nonodes);
+ if(elid != noelements) reorderelements = TRUE;
+ maxelem = MAX(maxelem, elid);
+ minphys = MIN( minphys, physind );
+ maxphys = MAX( maxphys, physind );
+ }
+
+ if(unvtype == 11 || unvtype == 21) Getrow(line,in,FALSE);
+ Getrow(line,in,FALSE);
+ cp = line;
+ if(allocated) {
+ if(reorderelements) u2eelem[elid] = noelements;
- case 42:
- case 52:
- case 62:
- case 72:
- case 82:
- case 92:
- elmertype = 306;
- break;
+ elmertype = UnvToElmerType(unvtype);
+ maxelemtype = MAX( maxelemtype, elmertype );
+ minelemtype = MIN( minelemtype, elmertype );
- case 43:
- case 53:
- case 63:
- case 73:
- case 93:
- elmertype = 310;
- break;
+ if(debug && !elementtypes[elmertype]) {
+ elementtypes[elmertype] = TRUE;
+ printf("new elementtype in elmer: %d (unv: %d)\n",elmertype,unvtype);
+ }
- case 44:
- case 54:
- case 64:
- case 71:
- case 84:
- case 94:
- elmertype = 404;
- break;
+ if(elmertype % 100 != nonodes) {
+ printf("nonodes = %d elemtype = %d elid = %d\n",nonodes,elmertype,elid);
+ nonodes = elmertype % 100;
+ }
- case 45:
- case 46:
- case 56:
- case 66:
- case 76:
- case 96:
- elmertype = 408;
- break;
+ data->elementtypes[noelements] = elmertype;
+ for(i=0;itopology[noelements][i] = next_int(&cp);
- case 111:
- elmertype = 504;
- break;
+ UnvRedundantIndexes(nonodes,data->topology[noelements]);
- case 118:
- elmertype = 510;
- break;
+ UnvToElmerIndx(elmertype,data->topology[noelements]);
- case 112:
- elmertype = 706;
- break;
+ /* should this be physical property or material property? */
+ data->material[noelements] = physind + physoffset;
+ }
+ }
+ }
- case 113:
- elmertype = 715;
- break;
+ if( mode == 2467 || mode == 2435) {
+ if(allocated && info) printf("Reading element groups in mode %d\n",mode);
+
+ for(;;) {
+ Getrow(line,in,FALSE);
+ if( !strncmp(line," -1",6)) goto nextline;
+
+ cp = line;
+ nogroup = next_int(&cp);
+ maxelemtype = 0;
+ minelemtype = 1000;
+ for(i=1;i<=6;i++)
+ dummy = next_int(&cp);
+ noentities = next_int(&cp);
- case 115:
- elmertype = 808;
- break;
+ if(!allocated) {
+ mingroup = MIN( mingroup, nogroup );
+ maxgroup = MAX( maxgroup, nogroup );
+ }
- case 116:
- elmertype = 820;
- break;
+ Getrow(line,in,FALSE);
+ if( !strncmp(line," -1",6)) goto nextline;
+
+ /* Used for the empty group created by salome */
+ /* if( mode == 2467 && !strncmp(line," ",12)) continue; */
+
+ group++;
+ k = 0;
+ if(allocated) {
+ sscanf(line,"%s",entityname);
+ strcpy(data->bodyname[nogroup],entityname);
+ data->bodynamesexist = TRUE;
+ data->boundarynamesexist = TRUE;
- default:
- elmertype = 0;
- printf("Unknown elementtype in universal mesh format: %d\n",unvtype);
- }
+ if(info) printf("Reading %d:th group with index %d with %d entities: %s\n",
+ group,nogroup,noentities,entityname);
+ }
+ if(noentities == 0) Getrow(line,in,FALSE);
- return(elmertype);
-}
+ for(i=0;ielementtypes[ind];
+ maxelemtype = MAX( maxelemtype, elemcode );
+ minelemtype = MIN( minelemtype, elemcode );
+ data->material[ind] = nogroup;
+ }
+ }
+ else if(grouptype == 7) {
+ nopoints += 1;
+ if(allocated) {
+ elemcode = 101;
+ data->material[noelements+nopoints] = nogroup;
+ maxelemtype = MAX( maxelemtype, elemcode );
+ minelemtype = MIN( minelemtype, elemcode );
+ data->elementtypes[noelements+nopoints] = elemcode;
+ data->topology[noelements+nopoints][0] = ind;
+ }
+ }
+ else {
+ printf("unknown group type %d\n",grouptype);
+ }
+ }
+ if(allocated && info) {
+ printf("Element type range in group is [%d %d]\n",minelemtype,maxelemtype);
+ }
+
+ }
+ }
+
+ if( mode == 164 ) {
+ if(!allocated) printf("Units dataset content is currently omitted!\n");
+ for(;;) {
+ Getrow(line,in,FALSE);
+ if( !strncmp(line," -1",6))
+ goto nextline;
+ }
+ }
-static int UnvRedundantIndexes(int nonodes,int *ind)
-{
- int i,j,redundant;
-
- redundant = FALSE;
- for(i=0;inoknots = noknots;
+ data->noelements = noelements + nopoints;
+ data->maxnodes = maxnodes;
+ data->dim = dim;
+
+ if(info) {
+ printf("Allocating mesh with %d nodes and %d %d-node elements in %d dims.\n",
+ noknots,noelements,maxnodes,dim);
+ }
+ AllocateKnots(data);
+ allocated = TRUE;
+
+ /* Set an offset for physical indexes so that the defined groups and
+ existing physical indexes won't mix confusingly */
+ if( maxphys >= mingroup && minphys <= maxgroup ) {
+ physoffset = maxgroup - minphys + 1;
+ }
+ else {
+ physoffset = 0;
+ }
+ if(info) {
+ printf("Physical index interval is [%d,%d]\n",minphys,maxphys);
+ if( maxgroup )
+ printf("Group index interval is [%d,%d]\n",mingroup,maxgroup);
+ if(physoffset) printf("Using offset %d for physical indexes\n",physoffset);
+ }
- reorder = FALSE;
- switch (elemtype) {
-
- case 510:
- reorder = TRUE;
- porder = &order510[0];
- break;
+ goto omstart;
+ }
+ fclose(in);
- case 408:
- reorder = TRUE;
- porder = &order408[0];
- break;
+ /* If the physical index may be zero, then we have a risk that there is
+ an unset material index. Elmer does not like material indexes of zeros.
+ This could be made prettier as now the almost same thing is done twice. */
+ if( minphys + physoffset == 0 ) {
+ mingroup = INT_MAX;
+ maxgroup = 0;
+ for(i=1;i<=data->noelements;i++) {
+ mingroup = MIN( mingroup, data->material[i] );
+ maxgroup = MAX( maxgroup, data->material[i] );
+ }
+ if( mingroup == 0 ) {
+ if(info) {
+ if(!maxgroup) printf("No material groups were successfully applied\n");
+ printf("Unset elements were given material index %d\n",maxgroup+1);
+ }
+ for(i=1;i<=data->noelements;i++)
+ if(data->material[i] == 0) data->material[i] = maxgroup + 1;
+ }
+ }
- case 820:
- reorder = TRUE;
- porder = &order820[0];
- break;
-
+ /* Elmer likes that node indexes are given so that no integers are missed.
+ If this is not the case we need to do renumbering of nodes. */
+ if(reordernodes) {
+ printf("Reordering nodes continuously\n");
+ for(j=1;j<=noelements;j++)
+ for(i=0;ielementtypes[j]%100;i++)
+ data->topology[j][i] = u2eind[data->topology[j][i]];
+ free_Ivector(u2eind,1,maxnodeind);
+ }
+ if(reorderelements) {
+ free_Ivector(u2eelem,1,maxelem);
}
- if( reorder ) {
- nodes = elemtype % 100;
- for(i=0;ix;
+ else if( j == 2 )
+ coord = data->y;
+ else
+ coord = data->z;
+
+ if( fabs(scaling[j]-1.0) >= 1.0e-20 ) {
+ for(i=1;i<=noknots;i++)
+ coord[i] *= scaling[j];
+ }
+ }
}
+
+ /* This is here for debugging of the nodal order */
+ if(FALSE) for(j=1;j<=noelements;j++) {
+ int elemtype = data->elementtypes[j];
+ printf("element = %d\n",j);
+ for(i=0;elemtype%100;i++) {
+ k = data->topology[j][i];
+ printf("node i=%d %.3le %.3le %.3le\n",i,data->x[k],data->z[k],data->y[k]);
+ }
+ }
+
+
+ /* Until this far all elements have been listed as bulk elements.
+ Now separate the lower dimensional elements to be boundary elements. */
+ ElementsToBoundaryConditions(data,bound,TRUE,info);
+
+ if(info) printf("The Universal mesh was loaded from file %s.\n\n",filename);
+
+ return(0);
}
-int LoadUniversalMesh(struct FemType *data,struct BoundaryType *bound,
- char *prefix,int info)
- /* Load the grid in universal file format */
+
+int LoadCGsimMesh(struct FemType *data,char *prefix,int info)
+/* Load the mesh from postprocessing format of CGsim */
{
- int noknots,totknots,noelements,elemcode,maxnodes;
- int allocated,maxknot,dim,ind,lines;
- int reordernodes,reorderelements,nogroups,maxnodeind,maxelem,elid,unvtype,elmertype;
- int nonodes,group,grouptype,mode,nopoints,nodeind,matind,physind,colorind;
- int debug,mingroup,maxgroup,nogroup,noentities,dummy;
- int *u2eind,*u2eelem;
- int *elementtypes;
+ int noknots,noelements,maxnodes,material,allocated,dim,debug,thismat,thisknots,thiselems;
char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
- int i,j,k,l,n;
- char entityname[MAXNAMESIZE];
+ int i,j,inds[MAXNODESD2],savedofs;
+ Real dummyreal;
FILE *in;
strcpy(filename,prefix);
if ((in = fopen(filename,"r")) == NULL) {
- AddExtension(prefix,filename,"unv");
+ AddExtension(prefix,filename,"plt");
if ((in = fopen(filename,"r")) == NULL) {
- printf("LoadUniversalMesh: opening of the universal mesh file '%s' wasn't succesfull !\n",
+ printf("LoadCGsimMesh: opening of the CGsim mesh file '%s' wasn't successful !\n",
filename);
return(1);
}
}
-
- printf("Reading mesh from universal mesh file %s.\n",filename);
- InitializeKnots(data);
- dim = 3;
- allocated = FALSE;
- reordernodes = FALSE;
- reorderelements = FALSE;
+ printf("Reading mesh from CGsim mesh file %s.\n",filename);
+ InitializeKnots(data);
debug = FALSE;
- if( debug ){
- elementtypes = Ivector(0,820);
- for(i=0;i<=820;i++) elementtypes[i] = FALSE;
- }
-
- maxnodeind = 0;
- maxnodes = 0;
- maxelem = 0;
-
+ allocated = FALSE;
+ savedofs = FALSE;
omstart:
- if(info) {
- if(allocated)
- printf("Second round for reading data\n");
- else
- printf("First round for allocating data\n");
- }
-
+ maxnodes = 4;
noknots = 0;
noelements = 0;
- nogroups = 0;
- nopoints = 0;
- group = 0;
-
-
- for(;;) {
+ material = 0;
+ dim = 2;
+ thismat = 0;
- if(0) printf("line: %d %s\n",mode,line);
- nextline:
- if( !strncmp(line," -1",6)) mode = 0;
- if( Getrow(line,in,FALSE)) goto end;
- if(!line) goto end;
+ for(;;) {
+
+ if(Getrow(line,in,FALSE)) goto end;
+ if(line[0]=='\0') goto end;
+
+ cp = strstr(line,"ZONE");
+ if(!cp) continue;
- if( !strncmp(line," -1",6)) mode = 0;
- else if( !strncmp(line," 2411",6)) mode = 2411;
- else if( !strncmp(line," 2412",6)) mode = 2412;
- else if( !strncmp(line," 2467",6)) mode = 2467;
- else if( !strncmp(line," 2435",6)) mode = 2435;
- else if( !strncmp(line," 781",6)) mode = 781;
- else if( !strncmp(line," 780",6)) mode = 780;
- else if( allocated && strncmp(line," ",6)) printf("Unknown mode: %s",line);
+ thismat += 1;
+ cp = strstr(line," N=");
+ cp += 3;
+ thisknots = next_int(&cp);
+ cp = strstr(line,",E=");
+ cp += 3;
+ thiselems = next_int(&cp);
- if(debug && mode) printf("Current mode is %d\n",mode);
+ if(debug) {
+ printf("%s",line);
+ printf("thismat = %d knots = %d elems = %d\n",thismat,thisknots,thiselems);
+ }
- /* node definition */
- if( mode == 2411 || mode == 781 ) {
- if(debug) printf("Reading nodes in mode %d\n",mode);
- for(;;) {
- GetrowDouble(line,in);
- if( !strncmp(line," -1",6)) goto nextline;
+ for(i=1;i<=thisknots;i++) {
+ GETLINE;
+ if(allocated) {
cp = line;
- nodeind = next_int(&cp);
- /* Three other fields omitted: two coordinate systems and color */
- noknots += 1;
- GetrowDouble(line,in);
-
- if(allocated) {
- if(reordernodes) {
- if(u2eind[nodeind])
- printf("Reordering node %d already set (%d vs. %d)\n",
- nodeind,u2eind[nodeind],noknots);
- else
- u2eind[nodeind] = noknots;
- }
+ data->x[noknots+i] = next_real(&cp);
+ data->y[noknots+i] = next_real(&cp);
+ data->z[noknots+i] = 0.0;
- cp = line;
- data->x[noknots] = next_real(&cp);
- data->y[noknots] = next_real(&cp);
- data->z[noknots] = next_real(&cp);
+ if(savedofs == 1) {
+ for(j=1;j<=4;j++)
+ dummyreal = next_real(&cp);
+ data->dofs[1][noknots+i] = next_real(&cp);
}
- else {
- if(nodeind != noknots) reordernodes = TRUE;
- maxnodeind = MAX(maxnodeind,nodeind);
+ else if(savedofs == 5) {
+ for(j=1;j<=5;j++)
+ data->dofs[j][noknots+i] = next_real(&cp);
}
+
}
}
- if( mode == 2412 ) {
- if(debug) printf("Reading elements from field %d\n",mode);
- for(;;) {
- Getrow(line,in,FALSE);
- if( !strncmp(line," -1",6)) goto nextline;
-
- noelements += 1;
- cp = line;
- elid = next_int(&cp);
- unvtype = next_int(&cp);
- physind = next_int(&cp);
- matind = next_int(&cp);
- colorind = next_int(&cp);
- nonodes = next_int(&cp);
-
- if (!allocated) {
- maxnodes = MAX(maxnodes, nonodes);
- if(elid != noelements) reorderelements = TRUE;
- maxelem = MAX(maxelem, elid);
- }
-
- if(unvtype == 11 || unvtype == 21 || unvtype == 22 ) Getrow(line,in,FALSE);
- Getrow(line,in,FALSE);
+ for(i=1;i<=thiselems;i++) {
+ GETLINE;
+
+ if(allocated) {
cp = line;
+ for(j=0;j<4;j++)
+ inds[j] = next_int(&cp);
+ for(j=0;j<4;j++)
+ data->topology[noelements+i][j] = inds[j]+noknots;
+ if(inds[2] == inds[3])
+ data->elementtypes[noelements+i] = 303;
+ else
+ data->elementtypes[noelements+i] = 404;
+ data->material[noelements+i] = thismat;
+ }
+ }
+
+ noknots += thisknots;
+ noelements += thiselems;
+ }
+
+ end:
+
+ if(!allocated) {
+ if(noknots == 0 || noelements == 0 || maxnodes == 0) {
+ printf("Invalid mesh consists of %d knots and %d %d-node elements.\n",
+ noknots,noelements,maxnodes);
+ fclose(in);
+ return(2);
+ }
+
+ rewind(in);
+ data->noknots = noknots;
+ data->noelements = noelements;
+ data->maxnodes = maxnodes;
+ data->dim = dim;
+
+
+ if(info) {
+ printf("Allocating for %d knots and %d %d-node elements.\n",
+ noknots,noelements,maxnodes);
+ }
+ AllocateKnots(data);
+
+ if(savedofs == 1) {
+ CreateVariable(data,1,1,0.0,"Temperature",FALSE);
+ }
+ else if(savedofs == 5) {
+ CreateVariable(data,1,1,0.0,"dTdX",FALSE);
+ CreateVariable(data,2,1,0.0,"dTdY",FALSE);
+ CreateVariable(data,3,1,0.0,"Qx",FALSE);
+ CreateVariable(data,4,1,0.0,"Qy",FALSE);
+ CreateVariable(data,5,1,0.0,"Temperature",FALSE);
+ }
+
+ allocated = TRUE;
+ goto omstart;
+ }
+ fclose(in);
+
+ if(info) printf("The CGsim mesh was loaded from file %s.\n\n",filename);
+ return(0);
+}
+
+
+int FluxToElmerType(int nonodes, int dim) {
+ int elmertype;
- elmertype = UnvToElmerType(unvtype);
- if(!elmertype) {
- printf("Unknown elementtype %d %d %d %d %d %d\n",
- elid,unvtype,physind,matind,colorind,nonodes);
- printf("line: %s\n",line);
- bigerror("done");
- }
+ elmertype = 0;
+
+ if( dim == 2 ) {
+ switch( nonodes ) {
+ case 3:
+ elmertype = 203;
+ break;
+ case 6:
+ elmertype = 306;
+ break;
+ case 8:
+ elmertype = 408;
+ break;
+ }
+ }
+
+ if( !elmertype ) printf("FluxToElmerType could not deduce element type! (%d %d)\n",nonodes,dim);
- if(elmertype == 510 )
- lines = 1;
- else if(elmertype == 820 )
- lines = 2;
- else
- lines = 0;
+ return(elmertype);
+}
- if(allocated) {
- if(reorderelements) u2eelem[elid] = noelements;
- if(debug && !elementtypes[elmertype]) {
- elementtypes[elmertype] = TRUE;
- printf("new elementtype in elmer: %d (unv: %d)\n",elmertype,unvtype);
- }
- if(elmertype % 100 != nonodes) {
- printf("nonodes = %d elemtype = %d elid = %d\n",nonodes,elmertype,elid);
- nonodes = elmertype % 100;
- }
-
-
- data->elementtypes[noelements] = elmertype;
- for(i=0;i 0 && i >= 8 ) {
- if( i%8 == 0 ) {
- Getrow(line,in,FALSE);
- cp = line;
- }
- }
- data->topology[noelements][i] = next_int(&cp);
- }
- UnvRedundantIndexes(nonodes,data->topology[noelements]);
- UnvToElmerIndx(elmertype,data->topology[noelements]);
+int LoadFluxMesh(struct FemType *data,struct BoundaryType *bound,
+ char *prefix,int info)
+/* Load the mesh from format of Flux Cedrat in TRA format. */
+{
+ int noknots,noelements,maxnodes,dim,elmertype;
+ int nonodes,matind,noregions,mode;
+ int debug;
+ int *elementtypes;
+ char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
+ int i,j,k;
+ char entityname[MAXNAMESIZE];
+ FILE *in;
- /* should this be physical property or material property? */
- data->material[noelements] = physind;
- }
- else {
- for(i=1;i<=lines;i++)
- Getrow(line,in,FALSE);
- }
- }
+
+ strcpy(filename,prefix);
+ if ((in = fopen(filename,"r")) == NULL) {
+ AddExtension(prefix,filename,"TRA");
+ if ((in = fopen(filename,"r")) == NULL) {
+ printf("LoadFluxMesh: opening of the Flux mesh file '%s' wasn't successful !\n",
+ filename);
+ return(1);
}
+ }
+
+ printf("Reading 2D mesh from Flux mesh file %s.\n",filename);
+ InitializeKnots(data);
+ debug = FALSE;
+ linenumber = 0;
+ dim = 2;
+ noknots = 0;
+ noelements = 0;
+ mode = 0;
+ maxnodes = 8;
- if( mode == 780 ) {
- int physind2,matind2;
- if(debug) printf("Reading elements from field %d\n",mode);
- for(;;) {
- Getrow(line,in,FALSE);
- if( !strncmp(line," -1",6)) goto nextline;
-
- noelements += 1;
- cp = line;
- elid = next_int(&cp);
- unvtype = next_int(&cp);
- physind = next_int(&cp);
- physind2 = next_int(&cp);
- matind = next_int(&cp);
- matind2 = next_int(&cp);
- colorind = next_int(&cp);
- nonodes = next_int(&cp);
-
- if (!allocated) {
- maxnodes = MAX(maxnodes, nonodes);
- if(elid != noelements) reorderelements = TRUE;
- maxelem = MAX(maxelem, elid);
- }
-
- if(unvtype == 11 || unvtype == 21) Getrow(line,in,FALSE);
- Getrow(line,in,FALSE);
- cp = line;
- if(allocated) {
- if(reorderelements) u2eelem[elid] = noelements;
+ for(;;) {
- elmertype = UnvToElmerType(unvtype);
+ if(0) printf("line: %d %s\n",mode,line);
- if(debug && !elementtypes[elmertype]) {
- elementtypes[elmertype] = TRUE;
- printf("new elementtype in elmer: %d (unv: %d)\n",elmertype,unvtype);
- }
+ if( Getrow(line,in,FALSE)) goto end;
+ if(line[0]=='\0') goto end;
- if(elmertype % 100 != nonodes) {
- printf("nonodes = %d elemtype = %d elid = %d\n",nonodes,elmertype,elid);
- nonodes = elmertype % 100;
- }
+ if( strstr(line,"Number of nodes")) mode = 1;
+ else if( strstr(line,"Total number of elements")) mode = 2;
+ else if( strstr(line,"Total number of regions")) mode = 3;
- data->elementtypes[noelements] = elmertype;
- for(i=0;itopology[noelements][i] = next_int(&cp);
+ else if( strstr(line,"Description of elements")) mode = 10;
+ else if( strstr(line,"Coordinates of the nodes")) mode = 11;
+ else if( strstr(line,"Names of the regions")) mode = 12;
- UnvRedundantIndexes(nonodes,data->topology[noelements]);
+ else if( strstr(line,"Neighbouring element table")) mode = 13;
+ else if( strstr(line,"List of boundary nodes")) mode = 14;
+ else if( strstr(line,"Physical properties")) mode = 15;
+ else if( strstr(line,"Boundary conditions")) mode = 16;
+ else {
+ if(debug) printf("Unknown mode line %d: %s",linenumber,line);
+ mode = 0;
+ }
- UnvToElmerIndx(elmertype,data->topology[noelements]);
+ if(debug && mode) printf("Current mode is %d\n",mode);
- /* should this be physical property or material property? */
- data->material[noelements] = physind;
- }
- }
- }
+ switch( mode ) {
+ case 1:
+ noknots = atoi(line);
+ break;
- if( mode == 2467 || mode == 2435) {
- if(debug) printf("Reading groups in mode %d\n",mode);
-
- for(;;) {
+ case 2:
+ noelements = atoi(line);
+ break;
+
+ case 3:
+ noregions = atoi(line);
+ break;
+
+
+ case 10:
+ if(info) {
+ printf("Allocating mesh with %d nodes and %d %d-node elements in %d dims.\n",
+ noknots,noelements,maxnodes,dim);
+ }
+
+ data->noknots = noknots;
+ data->noelements = noelements;
+ data->maxnodes = maxnodes;
+ data->dim = dim;
+ AllocateKnots(data);
+
+ if(info) printf("Reading %d element topologies\n",noelements);
+ for(i=1;i<=noelements;i++) {
Getrow(line,in,FALSE);
- if( !strncmp(line," -1",6)) goto nextline;
-
cp = line;
- nogroup = next_int(&cp);
- for(i=1;i<=6;i++)
- dummy = next_int(&cp);
- noentities = next_int(&cp);
-
- Getrow(line,in,FALSE);
- if( !strncmp(line," -1",6)) goto nextline;
-
- /* Used for the empty group created by salome */
- /* if( mode == 2467 && !strncmp(line," ",12)) continue; */
+ j = next_int(&cp);
+ if( i != j ) {
+ printf("It seems that reordering of elements should be performed! (%d %d)\n",i,j);
+ }
+ nonodes = next_int(&cp);
+ matind = abs( next_int(&cp) );
- group++;
- k = 0;
- if(allocated) {
- sscanf(line,"%s",entityname);
- strcpy(data->bodyname[group],entityname);
- data->bodynamesexist = TRUE;
- data->boundarynamesexist = TRUE;
+ elmertype = FluxToElmerType( nonodes, dim );
+ data->elementtypes[i] = elmertype;
+ data->material[i] = matind;
- if(info) printf("Reading group %d with %d entities: %s\n",
- nogroup,noentities,entityname);
+ Getrow(line,in,FALSE);
+ cp = line;
+ for(k=0;ktopology[i][k] = next_int(&cp);
}
- if(noentities == 0) Getrow(line,in,FALSE);
-
- for(i=0;ix[i] = next_real(&cp);
+ data->y[i] = next_real(&cp);
+ if(dim == 3) data->z[i] = next_real(&cp);
+ }
+ break;
- if(ind == 0) continue;
- if( grouptype == 8 ) {
- if(allocated) {
- if(reorderelements) ind = u2eelem[ind];
- elemcode = data->elementtypes[ind];
- data->material[ind] = group;
- }
- }
- else if(grouptype == 7) {
- nopoints += 1;
- if(allocated) {
- elemcode = 101;
- data->material[noelements+nopoints] = group;
- data->elementtypes[noelements+nopoints] = elemcode;
- data->topology[noelements+nopoints][0] = ind;
- }
- }
- else {
- }
+ case 12:
+ if(info) printf("Reading %d names of regions\n",noregions);
+ for(i=1;i<=noregions;i++) {
+ Getrow(line,in,FALSE);
+ cp = line;
+ j = next_int(&cp);
+ if( i != j ) {
+ printf("It seems that reordering of regions should be performed! (%d %d)\n",i,j);
}
- if(k && allocated && info)
- printf("Found new group %d with elements %d: %s\n",group,elemcode,entityname);
-
+ sscanf(cp,"%s",entityname);
+ strcpy(data->bodyname[i],entityname);
}
- }
+ data->bodynamesexist = TRUE;
+ data->boundarynamesexist = TRUE;
+ break;
+
+ default:
+ if(debug) printf("unimplemented mode: %d\n",mode );
+ mode = 0;
+ break;
+ }
}
-end:
+ end:
+ fclose(in);
- exit;
- if(info) printf("Done reading\n");
+ /* Until this far all elements have been listed as bulk elements.
+ Now separate the lower dimensional elements to be boundary elements. */
+ ElementsToBoundaryConditions(data,bound,TRUE,info);
+
+ if(info) printf("The Flux mesh was loaded from file %s.\n\n",filename);
+
+ return(0);
+}
- if(!allocated) {
- if(reordernodes) {
- if(info) printf("Reordering %d nodes with indexes up to %d\n",noknots,maxnodeind);
- u2eind = Ivector(1,maxnodeind);
- for(i=1;i<=maxnodeind;i++) u2eind[i] = 0;
- }
- if(reorderelements) {
- if(info) printf("Reordering %d elements with indexes up to %d\n",noelements,maxelem);
- u2eelem = Ivector(1,maxelem);
- for(i=1;i<=maxelem;i++) u2eelem[i] = 0;
- }
+/* Mapping between the elemental node order of PF3 file format to
+ Elmer file format. */
+static void PF3ToElmerPermuteNodes(int elemtype,int *topology)
+{
+ int i=0, nodes=0, oldtopology[MAXNODESD2];
+ int reorder, *porder;
+ int debug;
+
+ int order303[] = {3,1,2}; //tri
+ int order306[] = {3,1,2,6,4,5}; //tri^2
+ int order404[] = {3,4,1,2}; //quad
+ int order408[] = {3,4,1,2,7,8,5,6}; //quad^2
+ int order504[] = {1,2,3,4}; //tetra
+ int order510[] = {1,2,3,4,5,8,6,7,10,9};//tetra^2
+ int order605[] = {3,2,1,4,5}; //pyramid
+ int order613[] = {3,2,1,4,5,7,6,9,8,12,11,10,13}; //pyramid^2
+ int order706[] = {6,4,5,3,1,2}; //wedge (prism)
+ int order715[] = {6,4,5,3,1,2,12,10,11,9,7,8,15,13,14}; //wedge^2 (prism^2)
+ int order808[] = {7,8,5,6,3,4,1,2}; //hexa
+ int order820[] = {7,8,5,6,3,4,1,2,15,16,13,14,19,20,17,18,11,12,9,10}; //hexa^2
+
+ debug = TRUE;
+
+ reorder = FALSE;
+
+ switch (elemtype) {
+
+ case 101:
+ //nothing to change here
+ break;
+
+ case 202:
+ //nothing to change here
+ break;
+
+ case 203:
+ //nothing to change here
+ break;
+
+ case 303:
+ reorder = TRUE;
+ porder = &order303[0];
+ break;
+
+ case 306:
+ reorder = TRUE;
+ porder = &order306[0];
+ break;
+
+ case 404:
+ reorder = TRUE;
+ porder = &order404[0];
+ break;
+
+ case 408:
+ reorder = TRUE;
+ porder = &order408[0];
+ break;
+
+ case 504:
+ reorder = TRUE;
+ porder = &order504[0];
+ break;
+
+ case 510:
+ reorder = TRUE;
+ porder = &order510[0];
+ break;
+
+ case 605:
+ reorder = TRUE;
+ porder = &order605[0];
+ break;
+
+ case 613:
+ reorder = TRUE;
+ porder = &order613[0];
+ break;
- if(noknots == 0 || noelements == 0 || maxnodes == 0) {
- printf("Invalid mesh consits of %d knots and %d %d-node elements.\n",
- noknots,noelements,maxnodes);
- fclose(in);
- return(2);
- }
+ case 706:
+ reorder = TRUE;
+ porder = &order706[0];
+ break;
- rewind(in);
- totknots = noknots;
- data->noknots = noknots;
- data->noelements = noelements + nopoints;
- data->maxnodes = maxnodes;
- data->dim = dim;
+ case 715:
+ reorder = TRUE;
+ porder = &order715[0];
+ break;
- if(info) {
- printf("Allocating for %d knots and %d %d-node elements in %d dims.\n",
- noknots,noelements,maxnodes,dim);
- }
- AllocateKnots(data);
- allocated = TRUE;
-
- goto omstart;
- }
- fclose(in);
+ case 808:
+ reorder = TRUE;
+ porder = &order808[0];
+ break;
+ case 820:
+ reorder = TRUE;
+ porder = &order820[0];
+ break;
- if(reordernodes) {
- for(j=1;j<=noelements;j++)
- for(i=0;ielementtypes[j]%100;i++)
- data->topology[j][i] = u2eind[data->topology[j][i]];
- free_Ivector(u2eind,1,maxnodeind);
+ default:
+ if(debug) printf("Warning : Unknown element type: %d\n",elemtype );
+ break;
}
- if(reorderelements) {
- free_Ivector(u2eelem,1,maxelem);
+
+ if( reorder ) {
+ nodes = elemtype % 100;
+ for(i=0;imaterial[1];
- for(i=1;i<=data->noelements;i++) {
- mingroup = MIN( mingroup, data->material[i]);
- maxgroup = MAX( maxgroup, data->material[i]);
+int FluxToElmerType3D(int nonodes, int dim) {
+ int elmertype;
+
+ elmertype = 0;
+
+ if( dim == 2 ) {
+ switch( nonodes ) {
+ case 3:
+ elmertype = 303;
+ break;
+ case 4:
+ elmertype = 404;
+ break;
+ case 6:
+ elmertype = 306;
+ break;
+ case 8:
+ elmertype = 408;
+ break;
+ }
}
- if(info) printf("The group interval is [%d,%d]\n",mingroup,maxgroup);
- if(mingroup == 0) {
- if(info) {
- if(!maxgroup) printf("No material groups were successfully applied\n");
- printf("Unset elements were given material index %d\n",maxgroup+1);
+
+ if( dim == 3 ) {
+ switch( nonodes ) {
+ case 4:
+ elmertype = 504;
+ break;
+ case 5:
+ elmertype = 605;
+ break;
+ case 6:
+ elmertype = 706;
+ break;
+ case 8:
+ elmertype = 808;
+ break;
+ case 10:
+ elmertype = 510;
+ break;
+ case 13:
+ elmertype = 613;
+ break;
+ case 15:
+ elmertype = 715;
+ break;
+ case 20:
+ elmertype = 820;
+ break;
}
- for(i=1;i<=data->noelements;i++)
- if(data->material[i] == 0) data->material[i] = maxgroup + 1;
}
- ElementsToBoundaryConditions(data,bound,TRUE,info);
-
- if(info) printf("The Universal mesh was loaded from file %s.\n\n",filename);
+ if( !elmertype ) printf("FluxToElmerType3D could not deduce element type! (%d %d)\n",nonodes,dim);
- return(0);
+ return(elmertype);
}
-
-
-int LoadCGsimMesh(struct FemType *data,char *prefix,int info)
-/* Load the mesh from postprocessing format of CGsim */
+int LoadFluxMesh3D(struct FemType *data,struct BoundaryType *bound,
+ char *prefix,int info)
+/* Load the mesh from format of Flux Cedrat in PF3 format. */
{
- int noknots,noelements,maxnodes,material,allocated,dim,debug,thismat,thisknots,thiselems;
+ int noknots,noelements,maxnodes,dim,elmertype;
+ int nonodes,matind,noregions,mode;
+ int dimplusone, maxlinenodes, nodecnt;
+ int debug;
+ int *elementtypes;
char filename[MAXFILESIZE],line[MAXLINESIZE],*cp;
- int i,j,inds[MAXNODESD2],savedofs;
- Real dummyreal;
+ int i,j,k;
+ char entityname[MAXNAMESIZE];
FILE *in;
-
strcpy(filename,prefix);
if ((in = fopen(filename,"r")) == NULL) {
- AddExtension(prefix,filename,"plt");
+ AddExtension(prefix,filename,"PF3");
if ((in = fopen(filename,"r")) == NULL) {
- printf("LoadCGsimMesh: opening of the CGsim mesh file '%s' wasn't succesfull !\n",
+ printf("LoadFluxMesh3D: opening of the Flux mesh file '%s' wasn't successful !\n",
filename);
return(1);
}
}
-
- printf("Reading mesh from CGsim mesh file %s.\n",filename);
+
+ printf("Reading 3D mesh from Flux mesh file %s.\n",filename);
InitializeKnots(data);
debug = FALSE;
- allocated = FALSE;
- savedofs = FALSE;
-
-omstart:
-
- maxnodes = 4;
+ linenumber = 0;
+ dim = 3;
noknots = 0;
noelements = 0;
- material = 0;
- dim = 2;
- thismat = 0;
-
+ mode = 0;
+ maxnodes = 20; // 15?
+ maxlinenodes = 12; //nodes can be located at several lines
- for(;;) {
-
+ for(;;) {
- if(Getrow(line,in,FALSE)) goto end;
- if(!line) goto end;
-
- cp = strstr(line,"ZONE");
- if(!cp) continue;
-
+ if(0) printf("line: %d %s\n",mode,line);
- thismat += 1;
- cp = strstr(line," N=");
- cp += 3;
- thisknots = next_int(&cp);
+ if( Getrow(line,in,FALSE)) goto end;
+ if(line[0]=='\0') goto end;
+ if( strstr(line,"==== DECOUPAGE TERMINE")) goto end;
- cp = strstr(line,",E=");
- cp += 3;
- thiselems = next_int(&cp);
+ if( strstr(line,"NOMBRE DE DIMENSIONS DU DECOUPAGE")) mode = 1;
+ else if( strstr(line,"NOMBRE D'ELEMENTS")) mode = 3;
+ else if( strstr(line,"NOMBRE DE POINTS")) mode = 2;
+ else if( strstr(line,"NOMBRE DE REGIONS")) mode = 4;
- if(debug) {
- printf("%s",line);
- printf("thismat = %d knots = %d elems = %d\n",thismat,thisknots,thiselems);
+ else if( strstr(line,"DESCRIPTEUR DE TOPOLOGIE DES ELEMENTS")) mode = 10;
+ else if( strstr(line,"COORDONNEES DES NOEUDS")) mode = 11;
+ else if( strstr(line,"NOMS DES REGIONS")) mode = 12;
+ else {
+ if(debug) printf("Unknown mode line %d: %s",linenumber,line);
+ mode = 0;
}
- for(i=1;i<=thisknots;i++) {
- getline;
+ if(debug && mode) printf("Current mode is %d\n",mode);
- if(allocated) {
- cp = line;
- data->x[noknots+i] = next_real(&cp);
- data->y[noknots+i] = next_real(&cp);
- data->z[noknots+i] = 0.0;
+ switch( mode ) {
+ case 1:
+ dim = atoi(line);
+ break;
- if(savedofs == 1) {
- for(j=1;j<=4;j++)
- dummyreal = next_real(&cp);
- data->dofs[1][noknots+i] = next_real(&cp);
- }
- else if(savedofs == 5) {
- for(j=1;j<=5;j++)
- data->dofs[j][noknots+i] = next_real(&cp);
+ case 2:
+ if( strstr(line,"NOMBRE DE POINTS D'INTEGRATION")) break;/* We are looking for the total number of nodes */
+ noknots = atoi(line);
+ break;
+
+ case 3:
+ i = atoi(line);
+ noelements = MAX(i,noelements); /* We are looking for the total number of elements */
+ break;
+
+ case 4:
+ i = atoi(line);
+ noregions = MAX(i,noregions); /* We are looking for the total number of regions */
+ break;
+
+
+ case 10:
+ if(info) {
+ printf("Allocating mesh with %d nodes and %d %d-node elements in %d dims.\n",
+ noknots,noelements,maxnodes,dim);
+ }
+
+ data->noknots = noknots;
+ data->noelements = noelements;
+ data->maxnodes = maxnodes;
+ data->dim = dim;
+ AllocateKnots(data);
+
+ if(info) printf("Reading %d element topologies\n",noelements);
+ for(i=1;i<=noelements;i++)
+ {
+ Getrow(line,in,FALSE);
+ cp = line;
+ j = next_int(&cp);
+ if( i != j ) {
+ printf("It seems that reordering of elements should be performed! (%d %d)\n",i,j);
}
+ next_int(&cp); //2 internal element type description
+ next_int(&cp); //3 internal element type description
+ matind = next_int(&cp); //4 number of the belonging region
+ dimplusone = next_int(&cp); //5 dimensiality 4-3D 3-2D
+ next_int(&cp); //6 zero here always
+ next_int(&cp); //7 internal element type description
+ nonodes = next_int(&cp); //8 number of nodes
+
+ elmertype = FluxToElmerType3D( nonodes, dimplusone-1 );
+ data->elementtypes[i] = elmertype;
+ data->material[i] = matind;
- }
- }
+ Getrow(line,in,FALSE);
+ cp = line;
+ nodecnt = 0;
+ for(k=0;k= maxlinenodes) {
+ nodecnt = 0;
+ Getrow(line,in,FALSE);
+ cp = line;
+ }
+ data->topology[i][k] = next_int(&cp);
+ nodecnt+=1;
+ }
+
+ PF3ToElmerPermuteNodes(elmertype,data->topology[noelements]);
+
+ }
+ break;
- if(allocated) {
+ case 11:
+ if(info) printf("Reading %d element nodes\n",noknots);
+ for(i=1;i<=noknots;i++) {
+ Getrow(line,in,FALSE);
cp = line;
- for(j=0;j<4;j++)
- inds[j] = next_int(&cp);
- for(j=0;j<4;j++)
- data->topology[noelements+i][j] = inds[j]+noknots;
- if(inds[2] == inds[3])
- data->elementtypes[noelements+i] = 303;
- else
- data->elementtypes[noelements+i] = 404;
- data->material[noelements+i] = thismat;
+ j = next_int(&cp);
+ if( i != j ) {
+ printf("It seems that reordering of nodes should be performed! (%d %d)\n",i,j);
+ }
+ data->x[i] = next_real(&cp);
+ data->y[i] = next_real(&cp);
+ data->z[i] = next_real(&cp);
}
- }
+ break;
- noknots += thisknots;
- noelements += thiselems;
- }
- end:
+ case 12:
+ if(info) printf("Reading %d names of regions\n",noregions);
+ for(i=1;i<=noregions;i++) {
+ Getrow(line,in,FALSE);
- if(!allocated) {
- if(noknots == 0 || noelements == 0 || maxnodes == 0) {
- printf("Invalid mesh consits of %d knots and %d %d-node elements.\n",
- noknots,noelements,maxnodes);
- fclose(in);
- return(2);
- }
+ /* currently we just cycle through this and get a new row */
+ if( strstr(line,"REGIONS SURFACIQUES")) Getrow(line,in,FALSE);
+ if( strstr(line,"REGIONS VOLUMIQUES")) Getrow(line,in,FALSE);
- rewind(in);
- data->noknots = noknots;
- data->noelements = noelements;
- data->maxnodes = maxnodes;
- data->dim = dim;
+ sscanf(line,"%s",entityname);
+ strcpy(data->bodyname[i],entityname);
+ }
+ data->bodynamesexist = TRUE;
+ data->boundarynamesexist = TRUE;
+ break;
-
- if(info) {
- printf("Allocating for %d knots and %d %d-node elements.\n",
- noknots,noelements,maxnodes);
- }
- AllocateKnots(data);
- if(savedofs == 1) {
- CreateVariable(data,1,1,0.0,"Temperature",FALSE);
- }
- else if(savedofs == 5) {
- CreateVariable(data,1,1,0.0,"dTdX",FALSE);
- CreateVariable(data,2,1,0.0,"dTdY",FALSE);
- CreateVariable(data,3,1,0.0,"Qx",FALSE);
- CreateVariable(data,4,1,0.0,"Qy",FALSE);
- CreateVariable(data,5,1,0.0,"Temperature",FALSE);
+ default:
+ if(debug) printf("unimplemented mode: %d\n",mode );
+ mode = 0;
+ break;
}
-
- allocated = TRUE;
- goto omstart;
}
+
+ end:
fclose(in);
- if(info) printf("The CGsim mesh was loaded from file %s.\n\n",filename);
+ /* Until this far all elements have been listed as bulk elements.
+ Now separate the lower dimensional elements to be boundary elements. */
+ ElementsToBoundaryConditions(data,bound,TRUE,info);
+
+ if(info) printf("The Flux 3D mesh was loaded from file %s.\n\n",filename);
+
return(0);
}
-
-
diff --git a/ElmerGUI/Application/plugins/egconvert.h b/ElmerGUI/Application/plugins/egconvert.h
index 0ab6e41697..92cc3bbcd0 100644
--- a/ElmerGUI/Application/plugins/egconvert.h
+++ b/ElmerGUI/Application/plugins/egconvert.h
@@ -1,15 +1,20 @@
-/* femfilein.h */
-/* Routines for importing existing FEM meshes */
-
-int LoadAbaqusInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
-int LoadFidapInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
-int LoadAnsysInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
-int LoadNastranInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
-int LoadFieldviewInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
-int LoadTriangleInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
-int LoadMeditInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
-int LoadComsolMesh(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
-int LoadGidInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
-int LoadGmshInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
-int LoadUniversalMesh(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
-int LoadCGsimMesh(struct FemType *data,char *prefix,int info);
+/* femfilein.h -> egconvert.h */
+/* Routines for importing meshes and data from other formats. */
+
+int LoadAbaqusInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
+int LoadAbaqusOutput(struct FemType *data,char *prefix,int info);
+int LoadFidapInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
+int LoadAnsysInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
+int LoadNastranInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
+int LoadFieldviewInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
+int LoadTriangleInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
+int LoadMeditInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
+int LoadComsolMesh(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
+int LoadGidInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
+int LoadGmshInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
+int LoadGeoInput(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
+int LoadFvcomMesh(struct FemType *data,struct BoundaryType *bound,char *filename,int info);
+int LoadUniversalMesh(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
+int LoadCGsimMesh(struct FemType *data,char *prefix,int info);
+int LoadFluxMesh(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
+int LoadFluxMesh3D(struct FemType *data,struct BoundaryType *bound,char *prefix,int info);
diff --git a/ElmerGUI/Application/plugins/egmain.cpp b/ElmerGUI/Application/plugins/egmain.cpp
index 0cff444939..8b21f6f17c 100644
--- a/ElmerGUI/Application/plugins/egmain.cpp
+++ b/ElmerGUI/Application/plugins/egmain.cpp
@@ -82,653 +82,7 @@ static int Inmethod;
int info=TRUE,nogrids=0,nomeshes=0,activemesh=0;
-const char *IOmethods[] = {
- /*0*/ "EG",
- /*1*/ "ELMERGRID",
- /*2*/ "ELMERSOLVER",
- /*3*/ "ELMERPOST",
- /*4*/ "ANSYS",
- /*5*/ "IDEAS",
- /*6*/ "NASTRAN",
- /*7*/ "FIDAP",
- /*8*/ "UNV",
- /*9*/ "COMSOL",
- /*10*/ "FIELDVIEW",
- /*11*/ "TRIANGLE",
- /*12*/ "MEDIT",
- /*13*/ "GID",
- /*14*/ "GMSH",
- /*15*/ "PARTITIONED",
- /*16*/ "CGSIM",
-};
-
-
-
-int InlineParameters(struct ElmergridType *eg,int argc,char *argv[],const char *IOmethods[],int first,int info)
-{
- int arg,i,dim;
- char command[MAXLINESIZE];
-
- dim = eg->dim;
-
- /* Type of input file */
- if(first > 3) {
- for(i=0;iinmethod = i;
- break;
- }
- }
- if(i>MAXFORMATS) eg->inmethod = atoi(argv[1]);
-
-
- /* Type of output file (fewer options) */
- strcpy(command,argv[2]);
- for(i=0;ioutmethod = i;
- break;
- }
- }
- if(i>MAXFORMATS) eg->outmethod = atoi(argv[2]);
-
- /* Name of output file */
- strcpy(eg->filesin[0],argv[3]);
- strcpy(eg->filesout[0],eg->filesin[0]);
- strcpy(eg->mapfile,eg->filesin[0]);
- }
-
-
- /* The optional inline parameters */
-
- for(arg=first;arg silent = TRUE;
- info = FALSE;
- }
-
- if(strcmp(argv[arg],"-in") ==0 ) {
- if(arg+1 >= argc) {
- printf("The secondary input file name is required as a parameter\n");
- return(1);
- }
- else {
- strcpy(eg->filesin[eg->nofilesin],argv[arg+1]);
- printf("A secondary input file %s will be loaded.\n",eg->filesin[eg->nofilesin]);
- eg->nofilesin++;
- }
- }
-
- if(strcmp(argv[arg],"-out") == 0) {
- if(arg+1 >= argc) {
- printf("The output name is required as a parameter\n");
- return(2);
- }
- else {
- strcpy(eg->filesout[0],argv[arg+1]);
- }
- }
-
- if(strcmp(argv[arg],"-decimals") == 0) {
- eg->decimals = atoi(argv[arg+1]);
- }
-
- if(strcmp(argv[arg],"-triangles") ==0) {
- eg->triangles = TRUE;
- printf("The rectangles will be split to triangles.\n");
- if(arg+1 < argc) {
- if(strcmp(argv[arg+1],"-")) {
- eg->triangleangle = atof(argv[arg+1]);
- }
- }
- }
-
- if(strcmp(argv[arg],"-merge") == 0) {
- if(arg+1 >= argc) {
- printf("Give a parameter for critical distance.\n");
- return(3);
- }
- else {
- eg->merge = TRUE;
- eg->cmerge = atof(argv[arg+1]);
- }
- }
-
- if(strcmp(argv[arg],"-relh") == 0) {
- if(arg+1 >= argc) {
- printf("Give a relative mesh density related to the specifications\n");
- return(3);
- }
- else {
- eg->relh = atof(argv[arg+1]);
- }
- }
-
- if(strcmp(argv[arg],"-order") == 0) {
- if(arg+dim >= argc) {
- printf("Give %d parameters for the order vector.\n",dim);
- return(4);
- }
- else {
- eg->order = TRUE;
- eg->corder[0] = atof(argv[arg+1]);
- eg->corder[1] = atof(argv[arg+2]);
- if(dim==3) eg->corder[2] = atof(argv[arg+3]);
- }
- }
-
- if(strcmp(argv[arg],"-autoorder") == 0) {
- eg->order = 2;
- }
-
- if(strcmp(argv[arg],"-halo") == 0) {
- eg->partitionhalo = TRUE;
- }
- if(strcmp(argv[arg],"-indirect") == 0) {
- eg->partitionindirect = TRUE;
- }
- if(strcmp(argv[arg],"-metisorder") == 0) {
- eg->order = 3;
- }
- if(strcmp(argv[arg],"-centralize") == 0) {
- eg->center = TRUE;
- }
- if(strcmp(argv[arg],"-scale") == 0) {
- if(arg+dim >= argc) {
- printf("Give %d parameters for the scaling.\n",dim);
- return(5);
- }
- else {
- eg->scale = TRUE;
- eg->cscale[0] = atof(argv[arg+1]);
- eg->cscale[1] = atof(argv[arg+2]);
- if(dim==3) eg->cscale[2] = atof(argv[arg+3]);
- }
- }
-
- if(strcmp(argv[arg],"-translate") == 0) {
- if(arg+dim >= argc) {
- printf("Give %d parameters for the translate vector.\n",dim);
- return(6);
- }
- else {
- eg->translate = TRUE;
- eg->ctranslate[0] = atof(argv[arg+1]);
- eg->ctranslate[1] = atof(argv[arg+2]);
- if(dim == 3) eg->ctranslate[2] = atof(argv[arg+3]);
- }
- }
-
- if(strcmp(argv[arg],"-saveinterval") == 0) {
- if(arg+dim >= argc) {
- printf("Give min, max and step for the interval.\n");
- return(7);
- }
- else {
- eg->saveinterval[0] = atoi(argv[arg+1]);
- eg->saveinterval[1] = atoi(argv[arg+2]);
- eg->saveinterval[2] = atoi(argv[arg+3]);
- }
- }
-
- if(strcmp(argv[arg],"-rotate") == 0 || strcmp(argv[arg],"-rotate") == 0) {
- if(arg+dim >= argc) {
- printf("Give three parameters for the rotation angles.\n");
- return(8);
- }
- else {
- eg->rotate = TRUE;
- eg->crotate[0] = atof(argv[arg+1]);
- eg->crotate[1] = atof(argv[arg+2]);
- eg->crotate[2] = atof(argv[arg+3]);
- }
- }
-
- if(strcmp(argv[arg],"-clone") == 0) {
- if(arg+dim >= argc) {
- printf("Give the number of clones in each %d directions.\n",dim);
- return(9);
- }
- else {
- eg->clone[0] = atoi(argv[arg+1]);
- eg->clone[1] = atoi(argv[arg+2]);
- if(dim == 3) eg->clone[2] = atoi(argv[arg+3]);
- }
- }
- if(strcmp(argv[arg],"-clonesize") == 0) {
- if(arg+dim >= argc) {
- printf("Give the clone size in each %d directions.\n",dim);
- return(10);
- }
- else {
- eg->clonesize[0] = atof(argv[arg+1]);
- eg->clonesize[1] = atof(argv[arg+2]);
- if(dim == 3) eg->clonesize[2] = atof(argv[arg+3]);
- }
- }
-
- if(strcmp(argv[arg],"-unite") == 0) {
- eg->unitemeshes = TRUE;
- printf("The meshes will be united.\n");
- }
-
- if(strcmp(argv[arg],"-names") == 0) {
- eg->usenames = TRUE;
- printf("Names will be conserved when possible\n");
- }
-
- if(strcmp(argv[arg],"-removelowdim") == 0) {
- eg->removelowdim = TRUE;
- printf("Lower dimensional boundaries will be removed\n");
- }
-
- if(strcmp(argv[arg],"-removeunused") == 0) {
- eg->removeunused = TRUE;
- printf("Nodes that do not appear in any element will be removed\n");
- }
-
- if(strcmp(argv[arg],"-autoclean") == 0) {
- eg->removelowdim = TRUE;
- eg->bulkorder = TRUE;
- eg->boundorder = TRUE;
- eg->removeunused = TRUE;
- printf("Lower dimensional boundaries will be removed\n");
- printf("Materials and boundaries will be renumbered\n");
- printf("Nodes that do not appear in any element will be removed\n");
- }
-
- if(strcmp(argv[arg],"-polar") == 0) {
- eg->polar = TRUE;
- printf("Making transformation to polar coordinates.\n");
- if(arg+1 >= argc) {
- printf("The preferred radius is required as a parameter\n");
- eg->polarradius = 1.0;
- }
- else {
- eg->polarradius = atoi(argv[arg+1]);
- }
- }
-
- if(strcmp(argv[arg],"-cylinder") == 0) {
- eg->cylinder = TRUE;
- printf("Making transformation from cylindrical to cartesian coordinates.\n");
- }
-
- if(strcmp(argv[arg],"-reduce") == 0) {
- if(arg+2 >= argc) {
- printf("Give two material for the interval.\n");
- return(12);
- }
- else {
- eg->reduce = TRUE;
- eg->reducemat1 = atoi(argv[arg+1]);
- eg->reducemat2 = atoi(argv[arg+2]);
- }
- }
- if(strcmp(argv[arg],"-increase") == 0) {
- eg->increase = TRUE;
- }
- if(strcmp(argv[arg],"-bulkorder") == 0) {
- eg->bulkorder = TRUE;
- }
- if(strcmp(argv[arg],"-boundorder") == 0) {
- eg->boundorder = TRUE;
- }
- if(strcmp(argv[arg],"-pelem") == 0) {
- for(i=arg+1;ipelemmap[3*eg->pelems+i-1-arg] = atoi(argv[i]);
- eg->pelems++;
- }
- if(strcmp(argv[arg],"-belem") == 0) {
- for(i=arg+1;ibelemmap[3*eg->belems+i-1-arg] = atoi(argv[i]);
- eg->belems++;
- }
- if(strcmp(argv[arg],"-partition") == 0) {
- if(arg+dim >= argc) {
- printf("The number of partitions in %d dims is required as parameters.\n",dim);
- return(13);
- }
- else {
- eg->partitions = 1;
- eg->partdim[0] = atoi(argv[arg+1]);
- eg->partdim[1] = atoi(argv[arg+2]);
- if(dim == 3) eg->partdim[2] = atoi(argv[arg+3]);
- eg->partitions = 1;
- for(i=0;i<3;i++) {
- if(eg->partdim[i] == 0) eg->partdim[i] = 1;
- eg->partitions *= eg->partdim[i];
- }
- eg->partopt = 0;
- if(arg+4 < argc)
- if(argv[arg+4][0] != '-') eg->partopt = atoi(argv[arg+4]);
-
- printf("The mesh will be partitioned with simple division to %d partitions.\n",
- eg->partitions);
- }
- }
- if(strcmp(argv[arg],"-partorder") == 0) {
- if(arg+dim >= argc) {
- printf("Give %d parameters for the order vector.\n",dim);
- return(14);
- }
- else {
- eg->partorder = 1;
- eg->partcorder[0] = atof(argv[arg+1]);
- eg->partcorder[1] = atof(argv[arg+2]);
- if(dim==3) eg->partcorder[2] = atof(argv[arg+3]);
- }
- }
-
- if(strcmp(argv[arg],"-metis") == 0) {
-#if HAVE_METIS
- if(arg+1 >= argc) {
- printf("The number of partitions is required as a parameter\n");
- return(15);
- }
- else {
- eg->metis = atoi(argv[arg+1]);
- printf("The mesh will be partitioned with Metis to %d partitions.\n",eg->metis);
- eg->partopt = 0;
- if(arg+2 < argc)
- if(argv[arg+2][0] != '-') eg->partopt = atoi(argv[arg+2]);
- }
-#else
- printf("This version of ElmerGrid was compiled without Metis library!\n");
-#endif
- }
-
- if(strcmp(argv[arg],"-periodic") == 0) {
- if(arg+dim >= argc) {
- printf("Give the periodic coordinate directions (e.g. 1 1 0)\n");
- return(16);
- }
- else {
- eg->periodicdim[0] = atoi(argv[arg+1]);
- eg->periodicdim[1] = atoi(argv[arg+2]);
- if(dim == 3) eg->periodicdim[2] = atoi(argv[arg+3]);
- }
- }
-
- if(strcmp(argv[arg],"-discont") == 0) {
- if(arg+1 >= argc) {
- printf("Give the discontinuous boundary conditions.\n");
- return(17);
- }
- else {
- eg->discontbounds[eg->discont] = atoi(argv[arg+1]);
- eg->discont++;
- }
- }
-
- if(strcmp(argv[arg],"-connect") == 0) {
- if(arg+1 >= argc) {
- printf("Give the connected boundary conditions.\n");
- return(10);
- }
- else {
- eg->connectbounds[eg->connect] = atoi(argv[arg+1]);
- eg->connect++;
- }
- }
-
- if(strcmp(argv[arg],"-boundbound") == 0) {
- for(i=arg+1;i<=arg+3 && iboundbound[3*eg->boundbounds+i-(1+arg)] = atoi(argv[i]);
- if((i-arg)%3 == 0) eg->boundbounds++;
- }
- }
- if(strcmp(argv[arg],"-bulkbound") == 0) {
- for(i=arg+1;i<=arg+3 && ibulkbound[3*eg->bulkbounds+i-(1+arg)] = atoi(argv[i]);
- if((i-arg)%3 == 0) eg->bulkbounds++;
- }
- }
- if(strcmp(argv[arg],"-boundtype") == 0) {
- for(i=arg+1;isidemap[3*eg->sidemappings+i-1-arg] = atoi(argv[i]);
- eg->sidemappings++;
- }
- if(strcmp(argv[arg],"-bulktype") == 0) {
- for(i=arg+1;ibulkmap[3*eg->bulkmappings+i-1-arg] = atoi(argv[i]);
- eg->bulkmappings++;
- }
-
- if(strcmp(argv[arg],"-layer") == 0) {
- if(arg+4 >= argc) {
- printf("Give four parameters for the layer: boundary, elements, thickness, ratio.\n");
- return(18);
- }
- else if(eg->layers == MAXBOUNDARIES) {
- printf("There can only be %d layers, sorry.\n",MAXBOUNDARIES);
- return(19);
- }
- else {
- eg->layerbounds[eg->layers] = atoi(argv[arg+1]);
- eg->layernumber[eg->layers] = atoi(argv[arg+2]);
- eg->layerthickness[eg->layers] = atof(argv[arg+3]);
- eg->layerratios[eg->layers] = atof(argv[arg+4]);
- eg->layerparents[eg->layers] = 0;
- eg->layers++;
- }
- }
-
- if(strcmp(argv[arg],"-layermove") == 0) {
- if(arg+1 >= argc) {
- printf("Give maximum number of Jacobi filters.\n");
- return(20);
- }
- else {
- eg->layermove = atoi(argv[arg+1]);
- }
- }
-
- /* This uses a very dirty trick where the variables related to argument -layer are used
- with a negative indexing */
- if(strcmp(argv[arg],"-divlayer") == 0) {
- if(arg+4 >= argc) {
- printf("Give four parameters for the layer: boundary, elements, relative thickness, ratio.\n");
- return(21);
- }
- else if(abs(eg->layers) == MAXBOUNDARIES) {
- printf("There can only be %d layers, sorry.\n",MAXBOUNDARIES);
- return(22);
- }
- else {
- eg->layerbounds[abs(eg->layers)] = atoi(argv[arg+1]);
- eg->layernumber[abs(eg->layers)] = atoi(argv[arg+2]);
- eg->layerthickness[abs(eg->layers)] = atof(argv[arg+3]);
- eg->layerratios[abs(eg->layers)] = atof(argv[arg+4]);
- eg->layerparents[abs(eg->layers)] = 0;
- eg->layers--;
- }
- }
-
- if(strcmp(argv[arg],"-3d") == 0) {
- eg->dim = dim = 3;
- }
- if(strcmp(argv[arg],"-2d") == 0) {
- eg->dim = dim = 2;
- }
- if(strcmp(argv[arg],"-1d") == 0) {
- eg->dim = dim = 1;
- }
-
- if(strcmp(argv[arg],"-isoparam") == 0) {
- eg->isoparam = TRUE;
- }
- if(strcmp(argv[arg],"-nobound") == 0) {
- eg->saveboundaries = FALSE;
- }
-
- /* The following keywords are not actively used */
-
- if(strcmp(argv[arg],"-map") ==0) {
- if(arg+1 >= argc) {
- printf("Give the name of the mapping file\n");
- return(23);
- }
- else {
- strcpy(eg->mapfile,argv[arg+1]);
- printf("Mapping file is %s\n",eg->mapfile);
- }
- }
- if(strcmp(argv[arg],"-bcoffset") == 0) {
- eg->bcoffset = atoi(argv[arg+1]);
- }
- if(strcmp(argv[arg],"-noelements") == 0) {
- eg->elements3d = atoi(argv[arg+1]);
- }
- if(strcmp(argv[arg],"-nonodes") == 0) {
- eg->nodes3d = atoi(argv[arg+1]);
- }
-
- if(strcmp(argv[arg],"-sidefind") == 0) {
- eg->findsides = 0;
- for(i=arg+1;isidebulk[i-1-arg] = atoi(argv[i]);
- eg->findsides++;
- }
- }
- if(strcmp(argv[arg],"-findbound") == 0) {
- eg->findsides = 0;
- for(i=arg+1;i+1sidebulk[i-1-arg] = atoi(argv[i]);
- eg->sidebulk[i-arg] = atoi(argv[i+1]);
- eg->findsides++;
- }
- }
- }
-
- {
- char *ptr1;
- ptr1 = strchr(eg->filesout[0], '.');
- if (ptr1) *ptr1 = '\0';
- ptr1 = strchr(eg->mapfile, '.');
- if (ptr1) *ptr1 = '\0';
- }
-
- return(0);
-}
-
-
#if EXE_MODE
-static void Goodbye()
-{
- printf("\nThank you for using Elmergrid!\n");
- printf("Send bug reports and feature wishes to peter.raback@csc.fi\n");
- exit(0);
-}
-
-static void Instructions()
-{
- printf("****************** Elmergrid ************************\n");
- printf("This program can create simple 2D structured meshes consisting of\n");
- printf("linear, quadratic or cubic rectangles or triangles. The meshes may\n");
- printf("also be extruded and revolved to create 3D forms. In addition many\n");
- printf("mesh formats may be imported into Elmer software. Some options have\n");
- printf("not been properly tested. Contact the author if you face problems.\n\n");
-
- printf("The program has two operation modes\n");
- printf("A) Command file mode which has the command file as the only argument\n");
- printf(" 'ElmerGrid commandfile.eg'\n\n");
-
- printf("B) Inline mode which expects at least three input parameters\n");
- printf(" 'ElmerGrid 1 3 test'\n\n");
- printf("The first parameter defines the input file format:\n");
- printf("1) .grd : Elmergrid file format\n");
- printf("2) .mesh.* : Elmer input format\n");
- printf("3) .ep : Elmer output format\n");
- printf("4) .ansys : Ansys input format\n");
- printf("5) .inp : Abaqus input format by Ideas\n");
- printf("6) .msh : Nastran format\n");
- printf("7) .FDNEUT : Gambit (Fidap) neutral file\n");
- printf("8) .unv : Universal mesh file format\n");
- printf("9) .mphtxt : Comsol Multiphysics mesh format\n");
- printf("10) .dat : Fieldview format\n");
- printf("11) .node,.ele: Triangle 2D mesh format\n");
- printf("12) .mesh : Medit mesh format\n");
- printf("13) .msh : GID mesh format\n");
- printf("14) .msh : Gmsh mesh format\n");
- printf("15) .ep.i : Partitioned ElmerPost format\n");
-
- printf("\nThe second parameter defines the output file format:\n");
- printf("1) .grd : ElmerGrid file format\n");
- printf("2) .mesh.* : ElmerSolver format (also partitioned .part format)\n");
- printf("3) .ep : ElmerPost format\n");
-
- printf("\nThe third parameter is the name of the input file.\n");
- printf("If the file does not exist, an example with the same name is created.\n");
- printf("The default output file name is the same with a different suffix.\n\n");
-
- printf("There are several additional in-line parameters that are\n");
- printf("taken into account only when applicable to the given format.\n");
-
- printf("-out str : name of the output file\n");
- printf("-in str : name of a secondary input file\n");
- printf("-silent : do not echo run time information\n");
- printf("-decimals : number of decimals in the saved mesh (eg. 8)\n");
- printf("-triangles : rectangles will be divided to triangles\n");
- printf("-relh real : give relative mesh density parameter for ElmerGrid meshing\n");
- printf("-merge real : merges nodes that are close to each other\n");
- printf("-order real[3] : reorder elements and nodes using c1*x+c2*y+c3*z\n");
- printf("-centralize : set the center of the mesh to origin\n");
- printf("-scale real[3] : scale the coordinates with vector real[3]\n");
- printf("-translate real[3] : translate the nodes with vector real[3]\n");
- printf("-rotate real[3] : rotate around the main axis with angles real[3]\n");
- printf("-clone int[3] : make ideantilcal copies of the mesh\n");
- printf("-clonesize real[3] : the size of the mesh to be cloned if larger to the original\n");
- printf("-unite : the meshes will be united\n");
- printf("-polar real : map 2D mesh to a cylindrical shell with given radius\n");
- printf("-cylinder : map 2D/3D cylindrical mesh to a cartesian mesh\n");
- printf("-reduce int[2] : reduce element order at material interval [int1 int2]\n");
- printf("-increase : increase element order from linear to quadratic\n");
- printf("-bcoffset int : add an offset to the boundary conditions\n");
- printf("-discont int : make the boundary to have secondary nodes\n");
- printf("-connect int : make the boundary to have internal connection among its elements\n");
- printf("-removelowdim : remove boundaries that are two ranks lower than highest dim\n");
- printf("-removeunused : remove nodes that are not used in any element\n");
- printf("-bulkorder : renumber materials types from 1 so that every number is used\n");
- printf("-boundorder : renumber boundary types from 1 so that every number is used\n");
- printf("-autoclean : this performs the united action of the three above\n");
- printf("-bulkbound int[3] : set the union of materials [int1 int2] to be boundary int3\n");
- printf("-boundbound int[3] : set the union of boundaries [int1 int2] to be boundary int3\n");
- printf("-bulktype int[3] : set material types in interval [int1 int2] to type int3\n");
- printf("-boundtype int[3] : set sidetypes in interval [int1 int2] to type int3\n");
- printf("-layer int[2] real[2]: make a boundary layer for given boundary\n");
- printf("-layermove int : apply Jacobi filter int times to move the layered mesh\n");
- printf("-divlayer int[2] real[2]: make a boundary layer for given boundary\n");
- printf("-3d / -2d / -1d : mesh is 3, 2 or 1-dimensional (applies to examples)\n");
- printf("-isoparam : ensure that higher order elements are convex\n");
- printf("-nobound : disable saving of boundary elements in ElmerPost format\n");
-
- printf("\nThe following keywords are related only to the parallel Elmer computations.\n");
- printf("-partition int[4] : the mesh will be partitioned in main directions\n");
- printf("-partorder real[3] : in the above method, the direction of the ordering\n");
-#if HAVE_METIS
- printf("-metis int[2] : the mesh will be partitioned with Metis\n");
-#endif
- printf("-halo : create halo for the partitioning\n");
- printf("-indirect : create indirect connections in the partitioning\n");
- printf("-periodic int[3] : decleare the periodic coordinate directions for parallel meshes\n");
- printf("-saveinterval int[3] : the first, last and step for fusing parallel data\n");
-
- if(0) printf("-names : conserve name information where applicable\n");
-}
-
-
-
-
-
-
-
static int PartitionMesh(int nofile)
{
/* Partititioning related stuff */
@@ -1007,7 +361,7 @@ int ConvertEgTypeToMeshType(struct FemType *dat,struct BoundaryType *bound,mesh_
printf("Implemented only for element dimensions 2 and 3 (not %d)\n",elemdim);
}
- printf("Done converting\n");
+ printf("Done converting mesh\n");
return(0);
}
@@ -1054,6 +408,7 @@ static int ImportMeshDefinition(int inmethod,int nofile,char *filename,int *nogr
*nogrids = 0;
if(!visited) {
+ printf("Initializing structures for max. %d meshes\n",MAXCASES);
for(k=0;k
#include
#include
#include
+#include
#include "egutils.h"
#include "egdef.h"
#include "egtypes.h"
-#include "egmesh.h"
#include "egnative.h"
+#include "egmesh.h"
#define DEBUG 0
@@ -65,7 +67,9 @@ void GetElementInfo(int element,struct FemType *data,
int GetElementDimension(int elementtype)
{
- int elemdim = 0;
+ int elemdim;
+
+ elemdim = 0;
switch (elementtype / 100) {
case 1:
@@ -91,6 +95,7 @@ int GetElementDimension(int elementtype)
return(elemdim);
}
+
int GetMaxElementType(struct FemType *data)
{
int i,maxelementtype;
@@ -127,6 +132,37 @@ int GetMaxElementDimension(struct FemType *data)
}
+int GetCoordinateDimension(struct FemType *data,int info)
+{
+ int i,j,noknots,coorddim;
+ int coordis;
+ Real *coord;
+ Real epsilon = 1.0e-20;
+
+ noknots = data->noknots;
+ coorddim = 0;
+
+ for(j=3;j>=1;j--) {
+ coordis = FALSE;
+ if( j==1 )
+ coord = data->x;
+ else if( j==2 )
+ coord = data->y;
+ else
+ coord = data->z;
+
+ for(i=1;i<=noknots;i++)
+ if( fabs( coord[i] ) > epsilon ) {
+ coordis = TRUE;
+ break;
+ }
+ if( coordis ) coorddim = MAX( coorddim, j );
+ }
+ if(info) printf("Coordinates defined in %d dimensions\n",coorddim);
+
+ return(coorddim);
+}
+
void GetElementSide(int element,int side,int normal,
struct FemType *data,int *ind,int *sideelemtype)
@@ -136,15 +172,21 @@ void GetElementSide(int element,int side,int normal,
elements.
*/
{
- int i,j,elemtype,*elemind,sides,ind2[MAXNODESD2];
+ int i,j,elemtype,*elemind=NULL,sides,ind2[MAXNODESD2];
+ /* if(element < 1 || element > data->noelements ) {
+ printf("Invalid index for element: %d\n",element);
+ bigerror("Cannot continue");
+ } */
+
elemtype = data->elementtypes[element];
elemind = data->topology[element];
sides = elemtype/100;
+ *sideelemtype = 0;
if(side < 0 && sides > 4)
side = -(side+1);
-
+
switch (elemtype) {
case 202:
case 203:
@@ -343,7 +385,7 @@ void GetElementSide(int element,int side,int normal,
break;
- case 706: /* Linear prism or vedge element */
+ case 706: /* Linear wedge element */
if(side < 3) {
*sideelemtype = 404;
ind[0] = elemind[side];
@@ -377,6 +419,45 @@ void GetElementSide(int element,int side,int normal,
}
break;
+ case 715: /* Quadratic wedge element */
+ if(side < 3) {
+ *sideelemtype = 408;
+ ind[0] = elemind[side];
+ ind[1] = elemind[(side+1)%3];
+ ind[2] = elemind[(side+1)%3+3];
+ ind[3] = elemind[side+3];
+ ind[4] = elemind[6+side];
+ ind[5] = elemind[12+(side+1)%3];
+ ind[6] = elemind[9+side];
+ ind[7] = elemind[12+side];
+ }
+ else if (side < 5) {
+ *sideelemtype = 306;
+ for(i=0;i<3;i++) {
+ ind[i] = elemind[3*(side-3)+i];
+ ind[i+3] = elemind[3*(side-3)+6+i];
+ }
+ }
+ else if(side < 14) {
+ *sideelemtype = 202;
+ if(side < 8) {
+ ind[0] = elemind[side-5];
+ ind[1] = elemind[(side-4)%3];
+ }
+ if(side < 11) {
+ ind[0] = elemind[3+side-8];
+ ind[1] = elemind[3+(side-7)%3];
+ }
+ else {
+ ind[0] = elemind[side-11];
+ ind[1] = elemind[3+side-11];
+ }
+ }
+ else if (side < 20) {
+ *sideelemtype = 101;
+ ind[0] = elemind[side-14];
+ }
+ break;
case 605: /* Linear pyramid */
if(side < 4) {
@@ -387,7 +468,7 @@ void GetElementSide(int element,int side,int normal,
}
else if (side < 5) {
*sideelemtype = 404;
- for(i=0;i<3;i++)
+ for(i=0;i<4;i++)
ind[i] = elemind[i];
}
else if(side < 13) {
@@ -420,9 +501,9 @@ void GetElementSide(int element,int side,int normal,
}
else if (side == 4) {
*sideelemtype = 408;
- for(i=0;i<3;i++)
+ for(i=0;i<4;i++)
ind[i] = elemind[i];
- for(i=0;i<3;i++)
+ for(i=0;i<4;i++)
ind[i+4] = elemind[i+5];
}
else if(side < 13) {
@@ -480,8 +561,8 @@ void GetElementSide(int element,int side,int normal,
break;
case 820: /* 2nd order brick */
- *sideelemtype = 408;
if(side < 4) {
+ *sideelemtype = 408;
ind[0] = elemind[side];
ind[1] = elemind[(side+1)%4];
ind[2] = elemind[(side+1)%4+4];
@@ -492,6 +573,7 @@ void GetElementSide(int element,int side,int normal,
ind[7] = elemind[12+side];
}
else if(side < 6) {
+ *sideelemtype = 408;
for(i=0;i<4;i++)
ind[i] = elemind[4*(side-4)+i];
for(i=0;i<4;i++)
@@ -500,8 +582,8 @@ void GetElementSide(int element,int side,int normal,
break;
case 827:
- *sideelemtype = 409;
if(side < 4) {
+ *sideelemtype = 409;
ind[0] = elemind[side];
ind[1] = elemind[(side+1)%4];
ind[2] = elemind[(side+1)%4+4];
@@ -513,6 +595,7 @@ void GetElementSide(int element,int side,int normal,
ind[8] = elemind[20+side];
}
else {
+ *sideelemtype = 409;
for(i=0;i<4;i++)
ind[i] = elemind[4*(side-4)+i];
for(i=0;i<4;i++)
@@ -523,6 +606,7 @@ void GetElementSide(int element,int side,int normal,
default:
printf("GetElementSide: unknown elementtype %d (elem=%d,side=%d)\n",elemtype,element,side);
+ bigerror("Cannot continue");
}
if(normal == -1) {
@@ -533,19 +617,99 @@ void GetElementSide(int element,int side,int normal,
for(i=0;i<=j;i++)
ind[i] = ind2[j-i];
}
-#if 0
- else if(normal != 1) {
- printf("GetElementSide: unknown option (normal=%d)\n",normal);
+ }
+}
+
+
+
+void GetBoundaryElement(int sideind,struct BoundaryType *bound,struct FemType *data,int *ind,int *sideelemtype)
+{
+ int element,side,normal,i,n;
+
+ if( sideind > bound->nosides ) {
+ *sideelemtype = 0;
+ printf("Side element index %d exceeds size of boundary (%d)\n",sideind,bound->nosides);
+ return;
+ }
+
+ element = bound->parent[sideind];
+
+
+ /*GetElementSide(elemind2,side,1,data,&sideind2[0],&sideelemtype2); */
+
+ if(element) {
+ side = bound->side[sideind];
+ normal = bound->normal[sideind];
+
+ GetElementSide(element,side,normal,data,ind,sideelemtype);
+ }
+ else {
+ *sideelemtype = bound->elementtypes[sideind];
+
+ n = *sideelemtype % 100;
+ for(i=0;itopology[sideind][i];
+
+ if(0) {
+ printf("sidelemtype = %d\n",*sideelemtype);
+ printf("ind = ");
+ for(i=0;ielementtypes[element];
basetype = elemtype / 100;
@@ -601,19 +765,19 @@ int GetElementGraph(int element,int edge,struct FemType *data,int *ind)
}
break;
case 7:
- if(side < 3) {
- ind[0] = elemind[side];
- ind[1] = elemind[(side+1)%3];
- }
- else if(side < 6) {
- ind[0] = elemind[side-3];
- ind[1] = elemind[side];
- }
- else if(side < 9) {
- ind[0] = elemind[side-3];
- ind[1] = elemind[3+(side+1)%3];
+ switch(side) {
+ case 0: ind[0]=elemind[0]; ind[1]=elemind[1]; break;
+ case 1: ind[0]=elemind[1]; ind[1]=elemind[2]; break;
+ case 2: ind[0]=elemind[2]; ind[1]=elemind[0]; break;
+ case 3: ind[0]=elemind[3]; ind[1]=elemind[4]; break;
+ case 4: ind[0]=elemind[4]; ind[1]=elemind[5]; break;
+ case 5: ind[0]=elemind[5]; ind[1]=elemind[3]; break;
+ case 6: ind[0]=elemind[0]; ind[1]=elemind[3]; break;
+ case 7: ind[0]=elemind[1]; ind[1]=elemind[4]; break;
+ case 8: ind[0]=elemind[2]; ind[1]=elemind[5]; break;
}
break;
+
case 8:
if(side < 4) {
ind[0] = elemind[side];
@@ -673,6 +837,7 @@ int GetElementGraph(int element,int edge,struct FemType *data,int *ind)
+
int CalculateIndexwidth(struct FemType *data,int indxis,int *indx)
{
int i,ind,nonodes,indexwidth;
@@ -702,9 +867,6 @@ int CalculateIndexwidth(struct FemType *data,int indxis,int *indx)
}
-
-
-
void InitializeKnots(struct FemType *data)
{
int i;
@@ -713,26 +875,39 @@ void InitializeKnots(struct FemType *data)
data->noknots = 0;
data->noelements = 0;
data->coordsystem = COORD_CART2;
+ data->numbering = NUMBER_XY;
data->created = FALSE;
data->variables = 0;
data->maxnodes = 0;
data->indexwidth = 0;
data->noboundaries = 0;
+ data->mapgeo = 1;
+ data->nocorners = 0;
data->boundarynamesexist = FALSE;
data->bodynamesexist = FALSE;
+ data->nodepermexist = FALSE;
+
data->nopartitions = 1;
data->partitionexist = FALSE;
data->periodicexist = FALSE;
- data->connectexist = FALSE;
+ data->nodeconnectexist = FALSE;
+ data->elemconnectexist = FALSE;
- data->dualexists = FALSE;
- data->invtopoexists = FALSE;
+ data->nodalexists = FALSE;
+ /* data->invtopoexists = FALSE; */
data->partitiontableexists = FALSE;
+ data->invtopo.created = FALSE;
+ data->nodalgraph2.created = FALSE;
+ data->dualgraph.created = FALSE;
+
+
for(i=0;iedofs[i] = 0;
+ data->bandwidth[i] = 0;
+ data->iterdofs[i] = 0;
strcpy(data->dofname[i],"");
}
@@ -1024,6 +1199,47 @@ static void MovePointPower(Real *lim,int points,Real *coords,
}
}
+/* Creates airfoil shapes */
+static void MovePointNACAairfoil(Real *lim,int points,Real *coords,
+ Real x,Real y,Real *dx,Real *dy)
+{
+ Real p,d,t,u;
+
+ if(y < lim[0] || y > lim[2]) return;
+ if(x < coords[0] || x > coords[1]) return;
+
+ if(0) {
+ printf("x=%.3e y=%.3e lim0=%.3e lim2=%.3e\n",x,y,lim[0],lim[2]);
+ printf("naca: %.3e %.3e %.3e\n",coords[0],coords[1],coords[2]);
+ }
+
+ t = x;
+ if(coords[1] > coords[0]) {
+ if(tcoords[1]) t = coords[1];
+ }
+ else {
+ if(t>coords[0]) t = coords[0];
+ if(tnocells = grid->nocells;
data->noelements = grid->noelements;
data->coordsystem = grid->coordsystem;
+ data->numbering = grid->numbering;
data->indexwidth = grid->maxwidth;
data->noknots = MAX(noknots,grid->noknots);
@@ -1140,7 +1357,7 @@ void CreateKnots(struct GridType *grid,struct CellType *cell,
maplim[3*k+2] = maplim[3*k+1] + grid->mappinglimits[2*k+1];
}
-
+ mode = 0;
if(grid->mappings)
for(level=0;level<10;level++) {
@@ -1194,6 +1411,10 @@ void CreateKnots(struct GridType *grid,struct CellType *cell,
MovePointAngle(&maplim[3*k],grid->mappingpoints[k],grid->mappingparams[k],
x,y,&dx,&dz);
break;
+ case 9:
+ MovePointNACAairfoil(&maplim[3*k],grid->mappingpoints[k],grid->mappingparams[k],
+ x,y,&dx,&dy);
+ break;
case -1:
@@ -1228,6 +1449,10 @@ void CreateKnots(struct GridType *grid,struct CellType *cell,
MovePointAngle(&maplim[3*k],grid->mappingpoints[k],grid->mappingparams[k],
y,x,&dy,&dz);
break;
+ case -9:
+ MovePointNACAairfoil(&maplim[3*k],grid->mappingpoints[k],grid->mappingparams[k],
+ y,x,&dy,&dx);
+ break;
}
@@ -1269,7 +1494,7 @@ void CreateKnots(struct GridType *grid,struct CellType *cell,
data->maxsize = sqrt(maxsize);
data->minsize = sqrt(minsize);
- if(info) printf("Maximum elementsize is %.3le and minimum %.3le.\n",
+ if(info) printf("Maximum elementsize is %.3e and minimum %.3e.\n",
data->maxsize,data->minsize);
}
@@ -1277,7 +1502,7 @@ void CreateKnots(struct GridType *grid,struct CellType *cell,
int CreateVariable(struct FemType *data,int variable,int unknowns,
- Real value, const char *dofname,int eorder)
+ Real value,const char *dofname,int eorder)
/* Create variables for the given data structure */
{
int i,info=FALSE;
@@ -1297,11 +1522,13 @@ int CreateVariable(struct FemType *data,int variable,int unknowns,
data->variables += 1;
data->edofs[variable] = unknowns;
data->alldofs[variable] = unknowns * data->noknots;
+ data->bandwidth[variable] = unknowns * data->indexwidth;
data->dofs[variable] = Rvector(1,timesteps * data->alldofs[variable]);
if(info) printf("Created variable %s with %d dofs.\n",
dofname,data->alldofs[variable]);
for(i=1;i<=data->alldofs[variable]*timesteps;i++)
data->dofs[variable][i] = value;
+ data->iterdofs[variable] = 1;
}
else if (data->edofs[variable] == unknowns) {
if(info) printf("CreateVariable: Variable %d exists with correct number of dofs!\n",
@@ -1313,6 +1540,17 @@ int CreateVariable(struct FemType *data,int variable,int unknowns,
return(2);
}
+
+ if(eorder) {
+ if (data->eorder[variable] == FALSE) {
+ data->eorder[variable] = TRUE;
+ data->order[variable] = Ivector(1,data->alldofs[variable]);
+ for(i=1;i<=data->alldofs[variable];i++)
+ data->order[variable][i] = i;
+ }
+ if(info) printf("Created index for variable %s.\n",dofname);
+ }
+
strcpy(data->dofname[variable],dofname);
return(0);
@@ -1341,128 +1579,17 @@ void DestroyKnots(struct FemType *data)
free_Rvector(data->x,1,data->noknots);
free_Rvector(data->y,1,data->noknots);
free_Rvector(data->z,1,data->noknots);
-
+
data->noknots = 0;
data->noelements = 0;
data->maxnodes = 0;
-}
-
-
-
-int FindParentSide(struct FemType *data,struct BoundaryType *bound,
- int sideelem,int sideelemtype,int *sideind)
-{
- int i,j,sideelemtype2,elemind,parent,normal;
- int elemsides = 0,side,sidenodes,nohits,hit,noparent, bulknodes;
- int sideind2[MAXNODESD1];
-
- hit = FALSE;
-
- for(parent=1;parent<=2;parent++) {
- if(parent == 1) {
- elemind = bound->parent[sideelem];
- noparent = (parent < 1);
- }
- else
- elemind = bound->parent2[sideelem];
-
- if(elemind > 0) {
- elemsides = data->elementtypes[elemind] / 100;
- bulknodes = data->elementtypes[elemind] % 100;
-
- if(elemsides == 8) elemsides = 6;
- else if(elemsides == 6) elemsides = 5;
- else if(elemsides == 5) elemsides = 4;
-
- for(normal=1;normal >= -1;normal -= 2) {
-
- for(side=0;side 300) break;
- if(sideelemtype2 < 200 && sideelemtype > 200) break;
- if(sideelemtype != sideelemtype2) continue;
-
- sidenodes = sideelemtype % 100;
-
- for(j=0;jside[sideelem] = side;
- bound->normal[sideelem] = normal;
- }
- else {
- bound->side2[sideelem] = side;
- }
- goto skip;
- }
- }
- }
- }
-
-
- /* this finding of sides does not guarantee that normals are oriented correctly */
- normal = 1;
- hit = FALSE;
-
- for(side=0;;side++) {
-
- GetElementSide(elemind,side,normal,data,&sideind2[0],&sideelemtype2);
-
- if(sideelemtype2 < 300 && sideelemtype > 300) break;
- if(sideelemtype2 < 200 && sideelemtype > 200) break;
- if(sideelemtype != sideelemtype2) continue;
-
- sidenodes = sideelemtype % 100;
-
- nohits = 0;
- for(j=0;jside[sideelem] = side;
- }
- else
- bound->side2[sideelem] = side;
- goto skip;
- }
-
- }
- }
-
- skip:
- if(!hit) {
- printf("FindParentSide: unsuccessful (elemtype=%d elemsides=%d parent=%d)\n",
- sideelemtype,elemsides,parent);
-
- printf("parents = %d %d\n",bound->parent[sideelem],bound->parent2[sideelem]);
-
- printf("sideind =");
- for(i=0;itopology[elemind][i]);
- printf("\n");
- }
-
- }
- return(0);
+ if(data->nocorners > 0)
+ free_Ivector(data->corners,1,2*data->nocorners);
}
-
int CreateBoundary(struct CellType *cell,struct FemType *data,
struct BoundaryType *bound,int material1,int material2,
int solidmat,int boundarytype,int info)
@@ -1477,65 +1604,69 @@ int CreateBoundary(struct CellType *cell,struct FemType *data,
by the flag 'solidmat'.
*/
{
- int side,more,elem,elemind[2],nosides,no,times;
+ int i,side,more,elem,elemind[2],nosides,no,times;
int sidemat,thismat,size,setpoint,dimsides,cellside;
if(data->dim == 1)
dimsides = 2;
else
dimsides = 4;
-
+
if(bound->created == TRUE) {
- printf("CreateBoundary: You tried to recreate the boundary!\n");
+ if(info) printf("CreateBoundary: You tried to recreate the boundary!\n");
return(1);
}
if(!data->created) {
- printf("CreateBoundary: You tried to create a boundary before the knots were made.");
+ if(info) printf("CreateBoundary: You tried to create a boundary before the knots were made.");
return(2);
}
if(material1 < 0 && material2 < 0) {
- printf("CreateBoundary: the material arguments are both negative");
+ if(info) printf("CreateBoundary: the material arguments are both negative");
return(3);
}
-
+
times = 0;
-
+
bound->created = FALSE;
bound->nosides = 0;
if(solidmat >= 2) solidmat -= 2;
-
- startpoint:
-
+
+startpoint:
+
/* Go through all elements which have a boundary with the given material, but
are not themself of that material. First only calculate their amount, then
allocate space and tabulate them. */
nosides = 0;
-
-
+
+
for(no=1; no <= data->nocells; no++)
for(side=0; side < dimsides; side++) {
-
+
if(data->dim == 1)
cellside = 3-2*side;
else
cellside = side;
-
+
setpoint = FALSE;
sidemat = cell[no].boundary[cellside];
thismat = cell[no].material;
-
+
/* The free boundary conditions are not allowed if the negative
keywords are used. */
-
+
/* Either material must be the one defined. */
if( material1 >= 0 && material1 != sidemat) continue;
if( material2 >= 0 && material2 != thismat) continue;
-
+#if 0
+ printf("mat=[%d %d] sidemat=%d thismat=%d side=%d\n",
+ material1,material2,sidemat,thismat,side);
+#endif
+
if( material2 == -((side+2)%4+1) && sidemat == material1 &&
sidemat != thismat) setpoint = TRUE;
if( material1 == -(side+1) && thismat == material2 &&
sidemat != thismat) setpoint = TRUE;
-
+
if( material1 == MAT_BIGGER && sidemat > material2 ) setpoint = TRUE;
if( material1 == MAT_SMALLER && sidemat < material2 ) setpoint = TRUE;
if( material1 == MAT_ANYTHING && sidemat != material2 ) setpoint = TRUE;
@@ -1543,28 +1674,35 @@ int CreateBoundary(struct CellType *cell,struct FemType *data,
if( material2 == MAT_SMALLER && thismat < material1 ) setpoint = TRUE;
if( material2 == MAT_ANYTHING && thismat != material1 ) setpoint = TRUE;
if( sidemat == material1 && thismat == material2 ) setpoint = TRUE;
-
+
if(setpoint == TRUE) {
-
+#if 0
+ printf("going through boundary %d vs. %d in cell %d\n",material1,material2,no);
+#endif
elem = 0;
do {
elem++;
nosides++;
more = GetSideInfo(cell,no,side,elem,elemind);
-
+
+#if 0
+ printf("elem=%d nosides=%d no=%d side=%d elemind=%d %d\n",
+ elem,nosides, no, side, elemind[0], elemind[1]);
+#endif
+
/* In the second round the values are tabulated. */
if(times) {
/* It is assumed that the material pointed by solidmat
determines the surface properties. */
-
+
bound->parent[nosides] = elemind[0];
bound->parent2[nosides] = elemind[1];
-
+
bound->side[nosides] = side;
bound->side2[nosides] = (side+dimsides/2)%dimsides;
-
+
bound->types[nosides] = boundarytype;
-
+
/* The direction of the surface normal must be included */
if(solidmat==FIRST) {
bound->material[nosides] = sidemat;
@@ -1579,11 +1717,11 @@ int CreateBoundary(struct CellType *cell,struct FemType *data,
} while(more);
}
- }
-
+ }
+
if(nosides == 0) {
- printf("No boundary between materials %d and %d exists.\n",
- material1,material2);
+ if(info) printf("No boundary between materials %d and %d exists.\n",
+ material1,material2);
return(0);
}
@@ -1603,6 +1741,8 @@ int CreateBoundary(struct CellType *cell,struct FemType *data,
bound->parent = Ivector(1,nosides);
bound->parent2 = Ivector(1,nosides);
bound->normal = Ivector(1,nosides);
+
+ bound->echain = FALSE;
bound->ediscont = FALSE;
goto startpoint;
@@ -1610,170 +1750,11 @@ int CreateBoundary(struct CellType *cell,struct FemType *data,
if(info) printf("%d element sides between materials %d and %d were located to type %d.\n",
nosides,material1,material2,boundarytype);
- return(0);
-}
-
-
-
-int CreateAllBoundaries(struct CellType *cell,struct FemType *data,
- struct BoundaryType *bound,int info)
-/* This subroutine creates all available boundaries */
-{
- int i,j,side,more,elem,elemind[2],nosides,no,times;
- int sidemat,thismat,size,setpoint,dimsides,cellside;
- int boundarytype,prevsidemat,prevthismat;
- int **bctypes,minmat,maxmat,maxtype;
-
-
- if(data->dim == 1)
- dimsides = 2;
- else
- dimsides = 4;
-
- if(bound->created == TRUE) {
- printf("CreateBoundary: You tried to recreate the boundary!\n");
- return(1);
- }
- if(!data->created) {
- printf("CreateBoundary: You tried to create a boundary before the knots were made.");
- return(2);
- }
-
- times = 0;
-
- bound->created = FALSE;
- bound->nosides = 0;
-
-
- maxmat = minmat = 0;
-
- for(no=1; no <= data->nocells; no++) {
- for(side=0; side < dimsides; side++) {
- if(data->dim == 1)
- cellside = 3-2*side;
- else
- cellside = side;
-
- sidemat = cell[no].boundary[cellside];
- thismat = cell[no].material;
-
- if(maxmat = 0) {
- maxmat = thismat;
- minmat = thismat;
- }
- maxmat = MAX(maxmat,thismat);
- maxmat = MAX(maxmat,sidemat);
- minmat = MIN(minmat,thismat);
- minmat = MIN(minmat,sidemat);
- }
- }
-
- bctypes = Imatrix(minmat,maxmat,minmat,maxmat);
- for(i=minmat;i<=maxmat;i++)
- for(j=minmat;j<=maxmat;j++)
- bctypes[i][j] = 0;
-
- boundarytype = 0;
- for(no=1; no <= data->nocells; no++) {
- for(side=0; side < dimsides; side++) {
- if(data->dim == 1)
- cellside = 3-2*side;
- else
- cellside = side;
-
- sidemat = cell[no].boundary[cellside];
- thismat = cell[no].material;
-
- if(sidemat == thismat) continue;
-
- if(bctypes[thismat][sidemat] == 0) {
- boundarytype += 1;
- bctypes[thismat][sidemat] = boundarytype;
- if(0) printf("type[%d %d] = %d\n",thismat,sidemat,boundarytype);
- }
- }
- }
- maxtype = boundarytype;
-
-
-
-startpoint:
- /* Go through all elements which have a boundary with the given material, but
- are not themself of that material. First only calculate their amount, then
- allocate space and tabulate them. */
- nosides = 0;
-
- for(no=1; no <= data->nocells; no++)
- for(side=0; side < dimsides; side++) {
-
- if(data->dim == 1)
- cellside = 3-2*side;
- else
- cellside = side;
-
- setpoint = FALSE;
- sidemat = cell[no].boundary[cellside];
- thismat = cell[no].material;
-
- if(sidemat == thismat) continue;
- boundarytype = bctypes[thismat][sidemat];
-
- elem = 0;
- do {
- elem++;
- nosides++;
- more = GetSideInfo(cell,no,side,elem,elemind);
-
- /* In the second round the values are tabulated. */
- if(times) {
- bound->parent[nosides] = elemind[0];
- bound->parent2[nosides] = elemind[1];
-
- bound->side[nosides] = side;
- bound->side2[nosides] = (side+dimsides/2)%dimsides;
-
- bound->types[nosides] = boundarytype;
- bound->normal[nosides] = 1;
- }
- } while(more);
-
- prevsidemat = sidemat;
- prevthismat = thismat;
- }
-
- if(nosides == 0) return(0);
-
- if(times == 0) {
- times++;
-
- /* Allocate space. This has sometimes led to strange errors.
- The allocation takes place only in the first loop. */
-
- bound->created = TRUE;
- bound->nosides = size = nosides;
- bound->coordsystem = data->coordsystem;
- bound->types = Ivector(1,nosides);
- bound->side = Ivector(1,nosides);
- bound->side2 = Ivector(1,nosides);
- bound->material = Ivector(1,nosides);
- bound->parent = Ivector(1,nosides);
- bound->parent2 = Ivector(1,nosides);
- bound->normal = Ivector(1,nosides);
- bound->ediscont = FALSE;
-
- goto startpoint;
- }
-
- free_Imatrix(bctypes,minmat,maxmat,minmat,maxmat);
-
- if(info) printf("%d boundary elements with %d types were automatically created\n",nosides,maxtype);
return(0);
}
-
-
int AllocateBoundary(struct BoundaryType *bound,int size)
{
int i;
@@ -1785,6 +1766,7 @@ int AllocateBoundary(struct BoundaryType *bound,int size)
bound->created = TRUE;
bound->nosides = size;
+ bound->echain = FALSE;
bound->ediscont = FALSE;
bound->material = Ivector(1,size);
@@ -1810,13 +1792,10 @@ int AllocateBoundary(struct BoundaryType *bound,int size)
-
-
-
int DestroyBoundary(struct BoundaryType *bound)
/* Destroys boundaries of various types. */
{
- int nosides;
+ int i,nosides;
if(!bound->created) {
return(1);
@@ -1846,12 +1825,35 @@ int DestroyBoundary(struct BoundaryType *bound)
+int CreateBoundaries(struct CellType *cell,struct FemType *data,
+ struct BoundaryType *boundaries,int info)
+{
+ int i,j;
+
+ j = 0;
+ if(data->noboundaries > 0)
+ for(i=0;inoboundaries;i++) {
+ while(boundaries[j].created) {
+ j++;
+ if(j >= MAXBOUNDARIES) {
+ printf("CreateBoundaries: too many boundaries %d\n",j);
+ return(1);
+ }
+ }
+ CreateBoundary(cell,data,&boundaries[j],
+ data->boundext[i],data->boundint[i],
+ data->boundsolid[i],data->boundtype[i],info);
+ }
+ return(0);
+}
+
+
int CreatePoints(struct CellType *cell,struct FemType *data,
struct BoundaryType *bound,
int param1,int param2,int pointmode,int pointtype,int info)
{
- int size,i,no,corner,times,elem = 0,node;
+ int size,i,no,corner,times,elem,node;
bound->created = FALSE;
bound->nosides = 0;
@@ -1922,7 +1924,7 @@ int CreatePoints(struct CellType *cell,struct FemType *data,
bound->parent[i] = elem;
node = data->topology[elem][corner];
- printf("Found node %d at (%.3lg, %.3lg)\n",node,data->x[node],data->y[node]);
+ if(info) printf("Found node %d at (%.3lg, %.3lg)\n",node,data->x[node],data->y[node]);
}
}
@@ -1940,17 +1942,18 @@ int CreatePoints(struct CellType *cell,struct FemType *data,
}
-static int CreateNewNodes(struct FemType *data,int *order,int material,int newknots,
- int info)
+
+int CreateNewNodes(struct FemType *data,int *order,int material,int newknots)
{
int i,j,k,l,lmax,ind;
int newsize,noknots,nonodes;
int *neworder;
- Real *newx,*newy,*newz,*newdofs[MAXDOFS];
+ Real *newx=NULL,*newy=NULL,*newz=NULL;
+ Real *newdofs[MAXDOFS];
noknots = data->noknots;
- if(info) printf("Creating %d new nodes for discoutinuous boundary.\n",newknots);
+ printf("Creating %d new nodes for discontinuous boundary.\n",newknots);
/* Allocate for the new nodes */
newsize = noknots+newknots;
@@ -1985,6 +1988,7 @@ static int CreateNewNodes(struct FemType *data,int *order,int material,int newkn
newx[j] = data->x[i];
newy[j] = data->y[i];
newz[j] = data->z[i];
+
for(k=1;kedofs[k])
for(l=1;l<=lmax;l++)
@@ -2046,11 +2050,12 @@ int SetDiscontinuousBoundary(struct FemType *data,struct BoundaryType *bound,
*/
{
int i,j,bc,ind,sideind[MAXNODESD1];
- int side,parent,newknots,doublesides,maxtype,newbc;
+ int side,parent,newnodes,doublesides,maxtype,newbc;
int newsuccess,noelements,nonodes,sideelemtype,sidenodes,disconttype;
- int *order;
+ int *order=NULL;
int mat1,mat2,par1,par2,mat1old,mat2old,material;
- static int hitsexist=FALSE,hitslength,*hits;
+ static int hitsexist=FALSE,hitslength,*hits=NULL;
+
if(boundtype < 0) {
newbc = TRUE;
@@ -2063,6 +2068,7 @@ int SetDiscontinuousBoundary(struct FemType *data,struct BoundaryType *bound,
mat1old = mat2old = 0;
doublesides = 0;
+ /* Compute the number of duplicate boundary elements */
for(bc=0;bc 0) material = mat1old;
- else if(mat2old > 0) material = mat2old;
+ if( mat1old > 0 && mat2old > 0 )
+ material = MIN( mat1old, mat2old );
+ else if(mat1old > 0)
+ material = mat1old;
+ else if(mat2old > 0)
+ material = mat2old;
else {
printf("SetDiscontinuousBoundary: impossible to make the boundary of several materials\n");
return(2);
}
+ if(info) {
+ printf("Creating discontinuous boundary between materials %d and %d\n",mat1old,mat2old);
+ printf("New set of nodes will be created for material %d\n",material);
+ }
+
+
noelements = data->noelements;
order = Ivector(1,data->noknots);
for(i=1;i<=data->noknots;i++)
order[i] = i;
+ /* Compute the endnodes by the fact that they have different number of
+ hits */
if(endnodes == 1) {
if(!hitsexist) {
- hitslength = (int) (1.1*data->noknots);
+ hitslength = 1.1*data->noknots;
hits = Ivector(1,hitslength);
hitsexist = TRUE;
}
else if(hitslength <= data->noknots) {
free_Ivector(hits,1,hitslength);
- hitslength = (int) (1.1*data->noknots);
+ hitslength = 1.1*data->noknots;
hits = Ivector(1,hitslength);
}
@@ -2123,7 +2139,7 @@ int SetDiscontinuousBoundary(struct FemType *data,struct BoundaryType *bound,
}
}
-
+ /* If requested create a secondary boundary at the other side */
if(newbc) {
maxtype = 0;
for(bc=0;bc 0) {
- newknots++;
- order[ind] = -newknots;
+ newnodes++;
+ order[ind] = -newnodes;
}
}
else if(endnodes == 0) {
if(order[ind] > 0)
order[ind] = 0;
else if(order[ind] == 0) {
- newknots++;
- order[ind] = -newknots;
+ newnodes++;
+ order[ind] = -newnodes;
}
}
else if(endnodes == 1) {
if(order[ind] > 0) {
if(hits[ind] < 4) {
- newknots++;
- order[ind] = -newknots;
+ newnodes++;
+ order[ind] = -newnodes;
}
else
order[ind] = 0;
}
else if(order[ind] == 0) {
- newknots++;
- order[ind] = -newknots;
+ newnodes++;
+ order[ind] = -newnodes;
}
}
@@ -2207,9 +2223,9 @@ int SetDiscontinuousBoundary(struct FemType *data,struct BoundaryType *bound,
}
}
- if(newknots == 0) return(3);
+ if(newnodes == 0) return(3);
- newsuccess = CreateNewNodes(data,order,material,newknots,info);
+ newsuccess = CreateNewNodes(data,order,material,newnodes);
return(newsuccess);
}
@@ -2304,26 +2320,43 @@ int FindPeriodicBoundary(struct FemType *data,struct BoundaryType *bound,
-int SetConnectedBoundary(struct FemType *data,struct BoundaryType *bound,
- int bctype,int connecttype,int info)
-/* Create connected boundary conditions for a given bctype */
+int SetConnectedNodes(struct FemType *data,struct BoundaryType *bound,
+ int bctype,int connecttype,int info)
+/* Mark node that are related to a boundary condition of a given bctype.
+ This may be used to create strong connections in the partitioning process. */
{
- int i,j,k,bc,sideelemtype,sidenodes;
- int sideind[MAXNODESD1];
+ int i,j,k,bc,sideelemtype,sidenodes,nodesset;
+ int sideind[MAXNODESD1],conflicts;
+
+ conflicts = 0;
+ nodesset = 0;
-
for(bc=0;bcconnectexist) {
- data->connect = Ivector(1,data->noknots);
+ if( bctype > 0 ) {
+ if(bound[bc].types[i] != bctype) continue;
+ }
+ else if( bctype == -1 ) {
+ if( !bound[bc].parent[i] ) continue;
+ }
+ else if( bctype == -2 ) {
+ if( !bound[bc].parent[i] ) continue;
+ if( !bound[bc].parent2[i] ) continue;
+ }
+ else if( bctype == -3 ) {
+ if( !bound[bc].parent[i] ) continue;
+ if( bound[bc].parent2[i] ) continue;
+ }
+
+ /* If the table pointing the connected nodes does not exist, create it */
+ if(!data->nodeconnectexist) {
+ data->nodeconnect = Ivector(1,data->noknots);
for(k=1;k<=data->noknots;k++)
- data->connect[k] = 0;
- data->connectexist = TRUE;
+ data->nodeconnect[k] = 0;
+ data->nodeconnectexist = TRUE;
}
GetElementSide(bound[bc].parent[i],bound[bc].side[i],bound[bc].normal[i],
@@ -2332,7 +2365,77 @@ int SetConnectedBoundary(struct FemType *data,struct BoundaryType *bound,
for(j=0;jconnect[k] = connecttype;
+ if( data->nodeconnect[k] != connecttype ) {
+ if( data->nodeconnect[k] ) conflicts += 1;
+ data->nodeconnect[k] = connecttype;
+ nodesset += 1;
+ }
+ }
+ }
+ }
+ if(info) printf("Setting connectivity group %d for %d nodes on boundary %d\n",
+ connecttype,nodesset,bctype);
+
+ if(conflicts) printf("The were %d conflicts in the connectivity set %d\n",
+ conflicts,connecttype);
+
+ return(0);
+}
+
+
+int SetConnectedElements(struct FemType *data,int info)
+/* Create connected boundary conditions for a given bctype */
+{
+ int i,j,k,nonodes,hit,nohits,con;
+ int *nodeconnect;
+
+ if(!data->nodeconnectexist) {
+ printf("Cannot create connected elements without connected nodes!\n");
+ return(1);
+ }
+ nodeconnect = data->nodeconnect;
+
+ /* Allocated space for the connected elements */
+ if(!data->elemconnectexist) {
+ printf("Created table for connected elements\n");
+ data->elemconnect = Ivector(1,data->noelements);
+ for(k=1;k<=data->noelements;k++)
+ data->elemconnect[k] = 0;
+ data->elemconnectexist = TRUE;
+
+ /* Go through all the elements and check which of the elements have
+ nodes that are related to a connected node */
+ nohits = 0;
+ for(i=1;i<=data->noelements;i++) {
+ nonodes = data->elementtypes[i] % 100;
+ hit = FALSE;
+ for(j=0;jtopology[i][j];
+ con = nodeconnect[k];
+ if( con ) {
+ data->elemconnect[i] = MAX( con, data->elemconnect[i] );
+ hit = TRUE;
+ }
+ }
+ if(hit) nohits++;
+ }
+
+ if(info) printf("Number of connected elements is %d (out of %d)\n",nohits,data->noelements);
+ data->elemconnectexist = nohits;
+ }
+
+ /* This is a little bit dirty. We set the connections to negative and use the unconnected
+ as a permutation. */
+ if( data->elemconnectexist ) {
+ if(info) printf("Use connected table as a permutation for creating dual graph!\n");
+ j = 0;
+ for(i=1;i<=data->noelements;i++) {
+ if( data->elemconnect[i] ) {
+ data->elemconnect[i] = -abs(data->elemconnect[i]);
+ }
+ else {
+ j++;
+ data->elemconnect[i] = j;
}
}
}
@@ -2342,15 +2445,84 @@ int SetConnectedBoundary(struct FemType *data,struct BoundaryType *bound,
+int FindCorners(struct GridType *grid,struct CellType *cell,
+ struct FemType *data,int info)
+/* Find the nodes in the mesh that are at material corners.
+ These nodes are often of special interest.
+ */
+{
+ int i,j,k,ind,cellno,elem;
+ int allocated,nocorners;
+
+ nocorners = 0;
+ allocated = FALSE;
+
+omstart:
+
+ if(nocorners > 0) {
+ data->corners = Ivector(1,2*nocorners);
+ data->nocorners = nocorners;
+ allocated = TRUE;
+ }
+
+ k = 0;
+
+ for(i=1;i<=grid->xcells+1;i++)
+ for(j=1;j<=grid->ycells+1;j++) {
+ if(grid->structure[j][i] == grid->structure[j][i-1] &&
+ grid->structure[j-1][i] == grid->structure[j-1][i-1])
+ continue;
+ if(grid->structure[j][i] == grid->structure[j-1][i] &&
+ grid->structure[j][i-1] == grid->structure[j-1][i-1])
+ continue;
+
+ /* point (i,j) must now be a corner */
+ if(cellno = grid->numbered[j][i]) {
+ elem = GetElementIndex(&(cell)[cellno],1,1);
+ ind = BOTLEFT;
+ }
+ else if(cellno = grid->numbered[j][i-1]) {
+ elem = GetElementIndex(&(cell)[cellno],cell[cellno].xelem,1);
+ ind = BOTRIGHT;
+ }
+ else if(cellno = grid->numbered[j-1][i]) {
+ elem = GetElementIndex(&(cell)[cellno],1,cell[cellno].yelem);
+ ind = TOPLEFT;
+ }
+ else if(cellno = grid->numbered[j-1][i-1]) {
+ elem = GetElementIndex(&(cell)[cellno],cell[cellno].xelem,cell[cellno].yelem);
+ ind = TOPRIGHT;
+ }
+ else continue;
+
+ /* ind is now the index of the corner knot */
+ k++;
+
+ if(allocated == FALSE) continue;
+ data->corners[2*k-1] = elem;
+ data->corners[2*k] = ind;
+
+ }
+
+ nocorners = k;
+
+ if(nocorners == 0) return(0);
+ if(allocated == FALSE) goto omstart;
+
+ if(info) printf("Found %d material corners.\n",nocorners);
+ return(0);
+}
+
int ElementsToTriangles(struct FemType *data,struct BoundaryType *bound,
Real critangle,int info)
/* Make triangles out of rectangular elements */
{
- int i,j,k,l,side = 0,elem,i1,isum = 0,sideelemtype;
+ int i,j,k,l,side,elem,i1,isum,sideelemtype;
int noelements,elementtype,triangles,noknots,nonodes,newelements,newtype,newmaxnodes;
- int **newtopo = NULL,*newmaterial = NULL,*newelementtypes = NULL,newnodes,*needed,*divisions,*division1;
+ int **newtopo=NULL,*newmaterial=NULL,*newelementtypes=NULL;
+ int newnodes,*needed=NULL,*divisions=NULL,*division1=NULL;
int sideind[MAXNODESD1], sideind2[MAXNODESD1];
int allocated,maxanglej,evenodd,newelem;
Real dx1,dx2,dy1,dy2,ds1,ds2;
@@ -2396,14 +2568,13 @@ int ElementsToTriangles(struct FemType *data,struct BoundaryType *bound,
dy2 = data->y[data->topology[i][(j+1)%4]] - data->y[data->topology[i][j]];
ds1 = sqrt(dx1*dx1+dy1*dy1);
ds2 = sqrt(dx2*dx2+dy2*dy2);
- angles[j] = (180.0/FM_PI) * acos((dx1*dx2+dy1*dy2)/(ds1*ds2));
- // angles[j] = (180.0/M_PI) * acos((dx1*dx2+dy1*dy2)/(ds1*ds2));
+ angles[j] = (180.0/M_PI) * acos((dx1*dx2+dy1*dy2)/(ds1*ds2));
/* Slightly favor divisions where corner is split */
if(needed[data->topology[i][j]] == 1) angles[j] *= 1.001;
if( abs(angles[j] > maxangle)) {
- maxangle = fabs(angles[j]);
+ maxangle = abs(angles[j]);
maxanglej = j;
}
}
@@ -2601,6 +2772,8 @@ int ElementsToTriangles(struct FemType *data,struct BoundaryType *bound,
continue;
}
+ isum = 0;
+ side = 0;
if(divisions[k] == 1) {
elem = division1[k]+1;
side = bound[j].side[i];
@@ -2712,13 +2885,16 @@ int CylinderCoordinates(struct FemType *data,int info)
int UniteMeshes(struct FemType *data1,struct FemType *data2,
struct BoundaryType *bound1,struct BoundaryType *bound2,
- int info)
+ int nooverlap, int info)
/* Unites two meshes for one larger mesh */
{
int i,j,k;
- int noelements,noknots,nonodes;
- int **newtopo,*newmaterial,*newelementtypes,maxnodes;
- Real *newx,*newy,*newz;
+ int noelements,noknots,nonodes,maxnodes;
+ int **newtopo=NULL,*newmaterial=NULL,*newelementtypes=NULL;
+ Real *newx=NULL,*newy=NULL,*newz=NULL;
+ int mat,usenames,*bodynameis,*boundarynameis,*bodyused,*boundaryused;
+ int bcmax1,bcmin2,bcoffset;
+ int bodymax1,bodymin2,bodyoffset;
noknots = data1->noknots + data2->noknots;
noelements = data1->noelements + data2->noelements;
@@ -2728,78 +2904,238 @@ int UniteMeshes(struct FemType *data1,struct FemType *data2,
if(0) printf("Uniting two meshes to %d nodes and %d elements.\n",noknots,noelements);
- for(j=0;j < MAXBOUNDARIES;j++) {
- if(!bound2[j].created) continue;
+ usenames = data1->bodynamesexist || data1->boundarynamesexist;
+ bcoffset = 0; bodyoffset = 0;
- for(k=j;k < MAXBOUNDARIES;k++)
- if(!bound1[k].created) break;
+ if( usenames ) {
+ bodynameis = Ivector(1,MAXBODIES);
+ boundarynameis = Ivector(1,MAXBCS);
+ bodyused = Ivector(1,MAXBODIES);
+ boundaryused = Ivector(1,MAXBCS);
-#if 0
- printf("k=%d j=%d\n",k,j);
-#endif
-
- bound1[k].created = bound2[j].created;
- bound1[k].nosides = bound2[j].nosides;
- bound1[k].coordsystem = bound2[j].coordsystem;
- bound1[k].side = bound2[j].side;
- bound1[k].side2 = bound2[j].side2;
- bound1[k].parent = bound2[j].parent;
- bound1[k].parent2 = bound2[j].parent2;
- bound1[k].material = bound2[j].material;
- bound1[k].types = bound2[j].types;
- bound1[k].normal = bound2[j].normal;
+ for(i=1;i<=MAXBODIES;i++)
+ bodynameis[i] = bodyused[i] = FALSE;
+ for(i=1;i<=MAXBCS;i++)
+ boundarynameis[i] = boundaryused[i] = FALSE;
- bound2[j].created = FALSE;
- bound2[j].nosides = 0;
+ /* First mark the original bodies and boundaries that maintain their index */
+ for(i=1;i<=data1->noelements;i++) {
+ mat = data1->material[i];
+ if( mat < MAXBODIES ) {
+ if(!bodynameis[mat]) {
+ bodynameis[mat] = -1;
+ bodyused[mat] = TRUE;
+ }
+ }
+ }
- for(i=1; i <= bound1[k].nosides; i++) {
- bound1[k].parent[i] += data1->noelements;
- if(bound1[k].parent2[i])
- bound1[k].parent2[i] += data1->noelements;
+ for(j=0;j < MAXBOUNDARIES;j++) {
+ if(!bound1[j].created) continue;
+ for(i=1; i <= bound1[k].nosides; i++) {
+ mat = bound1[j].types[i];
+ if( mat < MAXBCS ) {
+ if(!boundarynameis[mat]) {
+ boundarynameis[mat] = -1;
+ boundaryused[mat] = TRUE;
+ }
+ }
+ }
}
- }
- data1->maxnodes = maxnodes;
- newtopo = Imatrix(1,noelements,0,maxnodes-1);
- newmaterial = Ivector(1,noelements);
- newelementtypes = Ivector(1,noelements);
- newx = Rvector(1,noknots);
- newy = Rvector(1,noknots);
- newz = Rvector(1,noknots);
- for(i=1;i<=data1->noknots;i++) {
- newx[i] = data1->x[i];
- newy[i] = data1->y[i];
- newz[i] = data1->z[i];
- }
- for(i=1;i<=data2->noknots;i++) {
- newx[i+data1->noknots] = data2->x[i];
- newy[i+data1->noknots] = data2->y[i];
- newz[i+data1->noknots] = data2->z[i];
- }
+ /* Then mark the joined bodies and boundaries that are not conflicting */
+ for(i=1;i<=data2->noelements;i++) {
+ mat = data2->material[i];
+ if( mat < MAXBODIES ) {
+ if( !bodynameis[mat] ) {
+ bodynameis[mat] = mat;
+ bodyused[mat] = TRUE;
+ strcpy(data1->bodyname[mat],data2->bodyname[mat]);
+ }
+ }
+ }
+
+ for(j=0;j < MAXBOUNDARIES;j++) {
+ if(!bound2[j].created) continue;
+
+ for(i=1; i <= bound2[j].nosides; i++) {
+ mat = bound2[j].types[i];
+ if( mat < MAXBCS ) {
+ if( !boundarynameis[mat] ) {
+ boundarynameis[mat] = mat;
+ boundaryused[mat] = TRUE;
+ strcpy(data1->boundaryname[mat],data2->boundaryname[mat]);
+ }
+ }
+ }
+ }
+
+
+ /* And finally number the conflicting joinded bodies and BCs */
+ for(i=1;i<=data2->noelements;i++) {
+ mat = data2->material[i];
+ if( mat < MAXBODIES ) {
+ if( bodynameis[mat] == -1) {
+ for(k=1;kbodyname[k],data2->bodyname[mat]);
+ }
+ }
+ }
+
+ for(j=0;j < MAXBOUNDARIES;j++) {
+ if(!bound2[j].created) continue;
+ for(i=1; i <= bound2[j].nosides; i++) {
+ mat = bound2[j].types[i];
+
+ if( mat < MAXBCS ) {
+ if( boundarynameis[mat] == -1) {
+ for(k=1;kboundaryname[k],data2->boundaryname[mat]);
+ }
+ }
+ }
+ }
+
+ }
+ else if (nooverlap ) {
+ bcmax1 = 0;
+ for(j=0;j < MAXBOUNDARIES;j++) {
+ if(!bound1[j].created) continue;
+ for(i=1; i <= bound1[k].nosides; i++) {
+ mat = bound1[j].types[i];
+ bcmax1 = MAX( bcmax1, mat );
+ }
+ }
+
+ bcmin2 = 1000;
+ for(j=0;j < MAXBOUNDARIES;j++) {
+ if(!bound2[j].created) continue;
+
+ for(i=1; i <= bound2[j].nosides; i++) {
+ mat = bound2[j].types[i];
+ bcmin2 = MIN( bcmin2, mat );
+ }
+ }
+ bcoffset = MAX(0, bcmax1 - bcmin2 + 1);
+ if( info ) {
+ printf("Max(bc1) is %d and Min(bc2) is %d, using BC offset %d for mesh 2!\n",bcmax1,bcmin2,bcoffset);
+ }
+
+ bodymax1 = 0;
+ for(i=1;i<=data1->noelements;i++) {
+ mat = data1->material[i];
+ bodymax1 = MAX( bodymax1, mat );
+ }
+
+ bodymin2 = 1000;
+ for(i=1;i<=data2->noelements;i++) {
+ mat = data2->material[i];
+ bodymin2 = MIN( bodymin2, mat );
+ }
+ bodyoffset = MAX(0, bodymax1 - bodymin2 + 1);
+ if( info ) {
+ printf("Max(body1) is %d and Min(body2) is %d, using body offset %d for mesh 2!\n",bodymax1,bodymin2,bodyoffset);
+ }
+ }
+
+
+
+ for(j=0;j < MAXBOUNDARIES;j++) {
+ if(!bound2[j].created) continue;
+
+ for(k=j;k < MAXBOUNDARIES;k++)
+ if(!bound1[k].created) break;
+
+ bound1[k].created = bound2[j].created;
+ bound1[k].nosides = bound2[j].nosides;
+ bound1[k].coordsystem = bound2[j].coordsystem;
+ bound1[k].side = bound2[j].side;
+ bound1[k].side2 = bound2[j].side2;
+ bound1[k].parent = bound2[j].parent;
+ bound1[k].parent2 = bound2[j].parent2;
+ bound1[k].material = bound2[j].material;
+ bound1[k].echain = bound2[j].echain;
+ bound1[k].types = bound2[j].types;
+ bound1[k].normal = bound2[j].normal;
+
+ for(i=1; i <= bound1[k].nosides; i++) {
+ bound1[k].parent[i] += data1->noelements;
+ if(bound1[k].parent2[i])
+ bound1[k].parent2[i] += data1->noelements;
+
+ mat = bound2[j].types[i];
+ if( usenames ) {
+ if( mat < MAXBCS ) {
+ bound1[k].types[i] = boundarynameis[mat];
+ }
+ } else {
+ bound1[k].types[i] = bcoffset + mat;
+ }
+ }
+ }
+
+ data1->maxnodes = maxnodes;
+ newtopo = Imatrix(1,noelements,0,maxnodes-1);
+ newmaterial = Ivector(1,noelements);
+ newelementtypes = Ivector(1,noelements);
+ newx = Rvector(1,noknots);
+ newy = Rvector(1,noknots);
+ newz = Rvector(1,noknots);
+
+ for(i=1;i<=data1->noknots;i++) {
+ newx[i] = data1->x[i];
+ newy[i] = data1->y[i];
+ newz[i] = data1->z[i];
+ }
+ for(i=1;i<=data2->noknots;i++) {
+ newx[i+data1->noknots] = data2->x[i];
+ newy[i+data1->noknots] = data2->y[i];
+ newz[i+data1->noknots] = data2->z[i];
+ }
for(i=1;i<=data1->noelements;i++) {
- newmaterial[i] = data1->material[i];
+ mat = data1->material[i];
+ newmaterial[i] = mat;
newelementtypes[i] = data1->elementtypes[i];
nonodes = newelementtypes[i]%100;
for(j=0;jtopology[i][j];
}
for(i=1;i<=data2->noelements;i++) {
- newmaterial[i+data1->noelements] = data2->material[i];
+ mat = data2->material[i];
newelementtypes[i+data1->noelements] = data2->elementtypes[i];
nonodes = newelementtypes[i+data1->noelements]%100;
for(j=0;jnoelements][j] = data2->topology[i][j] + data1->noknots;
+
+ if( usenames ) {
+ if( mat < MAXBODIES ) {
+ newmaterial[i+data1->noelements] = bodynameis[mat];
+ }
+ }
+ else {
+ newmaterial[i+data1->noelements] = bodyoffset + mat;
+ }
}
free_Imatrix(data1->topology,1,data1->noelements,0,data1->maxnodes-1);
free_Ivector(data1->material,1,data1->noelements);
- free_Ivector(data1->elementtypes,1,data1->noelements);
free_Rvector(data1->x,1,data1->noknots);
free_Rvector(data1->y,1,data1->noknots);
free_Rvector(data1->z,1,data1->noknots);
- DestroyKnots(data2);
+ free_Imatrix(data2->topology,1,data2->noelements,0,data2->maxnodes-1);
+ free_Ivector(data2->material,1,data2->noelements);
+ free_Rvector(data2->x,1,data2->noknots);
+ free_Rvector(data2->y,1,data2->noknots);
+ free_Rvector(data2->z,1,data2->noknots);
data1->noelements = noelements;
data1->noknots = noknots;
@@ -2810,7 +3146,6 @@ int UniteMeshes(struct FemType *data1,struct FemType *data2,
data1->y = newy;
data1->z = newz;
-
if(info) printf("Two meshes were united to one with %d nodes and %d elements.\n",
noknots,noelements);
@@ -2823,22 +3158,32 @@ int CloneMeshes(struct FemType *data,struct BoundaryType *bound,
/* Unites two meshes for one larger mesh */
{
int i,j,k,l,m;
- int noelements,noknots,nonodes,totcopies,ind;
- int **newtopo,*newmaterial,*newelementtypes,maxnodes;
+ int noelements,noknots,nonodes,totcopies,ind,origdim;
+ int **newtopo=NULL,*newmaterial=NULL,*newelementtypes=NULL,maxnodes;
int maxmaterial,maxtype,ncopy,bndr,nosides;
- Real *newx,*newy,*newz;
+ Real *newx=NULL,*newy=NULL,*newz=NULL;
Real maxcoord[3],mincoord[3];
- int *vparent,*vparent2,*vside,*vside2,*vtypes,*vmaterial,*vnormal,*vdiscont = NULL;
+ int *vparent=NULL,*vparent2=NULL,*vside=NULL,*vside2=NULL;
+ int *vtypes=NULL,*vmaterial=NULL,*vnormal=NULL,*vdiscont=NULL;
- printf("CloneMeshes: copying the mesh to a matrix\n");
- if(diffmats) diffmats = 1;
-
+ if(info) printf("CloneMeshes: copying the mesh to a matrix\n");
+ if(diffmats) {
+ if(info) printf("CloneMeshes: giving each new entity new material and bc indexes\n");
+ }
+
+ origdim = data->dim;
totcopies = 1;
+ if( ncopies[2] > 1 ) {
+ data->dim = 3;
+ }
+ else {
+ ncopies[2] = 1;
+ }
+
for(i=0;idim;i++) {
if(ncopies[i] > 1) totcopies *= ncopies[i];
}
- if(data->dim == 2) ncopies[2] = 1;
maxcoord[0] = mincoord[0] = data->x[1];
maxcoord[1] = mincoord[1] = data->y[1];
@@ -2853,15 +3198,16 @@ int CloneMeshes(struct FemType *data,struct BoundaryType *bound,
if(data->z[i] < mincoord[2]) mincoord[2] = data->z[i];
}
- for(i=0;idim;i++) {
+ for(i=0;i meshsize[i]) meshsize[i] = maxcoord[i]-mincoord[i];
}
+ if(info) printf("Meshsize to be copied: %lg %lg %lg\n",meshsize[0],meshsize[1],meshsize[2]);
noknots = totcopies * data->noknots;
noelements = totcopies * data->noelements;
maxnodes = data->maxnodes;
- printf("Copying the mesh to %d identical domains.\n",totcopies);
+ if(info) printf("Copying the mesh to %d identical domains in %d-dim.\n",totcopies,data->dim);
data->maxnodes = maxnodes;
newtopo = Imatrix(1,noelements,0,maxnodes-1);
@@ -2871,12 +3217,11 @@ int CloneMeshes(struct FemType *data,struct BoundaryType *bound,
newy = Rvector(1,noknots);
newz = Rvector(1,noknots);
-
for(l=0;lnoknots;i++) {
- ncopy = j+k*ncopies[0]+k*l*ncopies[1];
+ ncopy = j+k*ncopies[0]+l*ncopies[0]*ncopies[1];
ind = i + ncopy*data->noknots;
newx[ind] = data->x[i] + j*meshsize[0];
@@ -2888,18 +3233,20 @@ int CloneMeshes(struct FemType *data,struct BoundaryType *bound,
}
maxmaterial = 0;
- for(i=1;i<=data->noelements;i++)
- if(data->material[i] > maxmaterial) maxmaterial = data->material[i];
+ if( diffmats ) {
+ for(i=1;i<=data->noelements;i++)
+ if(data->material[i] > maxmaterial) maxmaterial = data->material[i];
+ if(info ) printf("Material offset for cloning set to: %d\n",maxmaterial);
+ }
for(l=0;lnoelements;i++) {
- ncopy = j+k*ncopies[0]+k*l*ncopies[1];
+ ncopy = j+k*ncopies[0]+l*ncopies[1]*ncopies[0];
ind = i + ncopy*data->noelements;
newmaterial[ind] = data->material[i] + diffmats*maxmaterial*ncopy;
-
newelementtypes[ind] = data->elementtypes[i];
nonodes = newelementtypes[i]%100;
for(m=0;mnoelements;
@@ -2951,8 +3302,8 @@ int CloneMeshes(struct FemType *data,struct BoundaryType *bound,
vside2[ind] = bound[bndr].side2[i];
}
else {
- vparent2[ind] = 0;
- vside2[ind] = 0;
+ vparent2[ind] = 0.0;
+ vside2[ind] = 0.0;
}
vnormal[ind] = bound[bndr].normal[i];
@@ -2967,7 +3318,7 @@ int CloneMeshes(struct FemType *data,struct BoundaryType *bound,
}
}
}
-
+
bound[bndr].nosides = nosides;
bound[bndr].side = vside;
@@ -2990,11 +3341,18 @@ int CloneMeshes(struct FemType *data,struct BoundaryType *bound,
data->noknots = noknots;
data->topology = newtopo;
data->material = newmaterial;
+
data->elementtypes = newelementtypes;
data->x = newx;
data->y = newy;
data->z = newz;
+ if( data->bodynamesexist || data->boundarynamesexist ) {
+ printf("Cloning cannot treat names yet, omitting treatment of names for now!\n");
+ data->bodynamesexist = FALSE;
+ data->boundarynamesexist = FALSE;
+ }
+
if(info) printf("The mesh was copied to several identical meshes\n");
return(0);
@@ -3006,14 +3364,15 @@ int MirrorMeshes(struct FemType *data,struct BoundaryType *bound,
/* Makes a mirror image of a mesh and unites it with the original mesh */
{
int i,j,m;
- int noelements,noknots,nonodes,totcopies,ind;
- int **newtopo,*newmaterial,*newelementtypes,maxnodes;
+ int noelements,noknots,nonodes,totcopies,ind,maxnodes;
+ int **newtopo=NULL,*newmaterial=NULL,*newelementtypes=NULL;
int maxtype,bndr,nosides;
- Real *newx,*newy,*newz;
+ Real *newx=NULL,*newy=NULL,*newz=NULL;
Real maxcoord[3],mincoord[3];
int ind0,elem0,axis1,axis2,axis3,symmcount;
- int *vparent,*vparent2,*vside,*vside2,*vtypes,*vmaterial,*vnormal,*vdiscont = NULL;
+ int *vparent=NULL,*vparent2=NULL,*vside=NULL,*vside2=NULL;
+ int *vtypes=NULL,*vmaterial=NULL,*vnormal=NULL,*vdiscont=NULL;
printf("MirrorMeshes: making a symmetric mapping of the mesh\n");
@@ -3035,14 +3394,14 @@ int MirrorMeshes(struct FemType *data,struct BoundaryType *bound,
if(data->z[i] < mincoord[2]) mincoord[2] = data->z[i];
}
- for(i=0;idim;i++) {
+ for(i=0;i<3;i++) {
if(maxcoord[i]-mincoord[i] > meshsize[i]) meshsize[i] = maxcoord[i]-mincoord[i];
}
if(diffmats) diffmats = 1;
totcopies = 1;
- for(i=0;idim;i++)
+ for(i=0;i<3;i++)
if(symmaxis[i]) totcopies *= 2;
noknots = totcopies * data->noknots;
@@ -3071,7 +3430,7 @@ int MirrorMeshes(struct FemType *data,struct BoundaryType *bound,
newx[ind] = (1-2*axis1) * data->x[i];
newy[ind] = (1-2*axis2) * data->y[i];
- newz[ind] = (1-2*axis3)*data->z[i];
+ newz[ind] = (1-2*axis3) * data->z[i];
newmaterial[ind] = data->material[i];
newelementtypes[ind] = data->elementtypes[i];
@@ -3192,6 +3551,12 @@ int MirrorMeshes(struct FemType *data,struct BoundaryType *bound,
data->y = newy;
data->z = newz;
+ if( data->bodynamesexist || data->boundarynamesexist ) {
+ printf("Mirroring cannot treat names yet, omitting treatment of names for now!\n");
+ data->bodynamesexist = FALSE;
+ data->boundarynamesexist = FALSE;
+ }
+
if(info) printf("The mesh was copied to several identical meshes\n");
return(0);
@@ -3203,10 +3568,10 @@ static void ReorderAutomatic(struct FemType *data,int iterations,
int *origindx,Real corder[],int info)
{
int i,j,k,l,nonodes,maxnodes,noelements,noknots,minwidth,indexwidth;
- int **neighbours,*newrank,*newindx,*oldrank,*oldindx;
- int nocands = 0,*cands,ind,ind2,cantdo;
- int elemtype,indready,iter,*localorder,*localtmp,nolocal;
- Real *localdist,dx,dy,dz;
+ int **neighbours=NULL,*newrank=NULL,*newindx=NULL,*oldrank=NULL,*oldindx=NULL;
+ int nocands,*cands=NULL,ind,ind2,cantdo;
+ int elemtype,indready,iter,*localorder=NULL,*localtmp=NULL,nolocal;
+ Real *localdist=NULL,dx,dy,dz;
iterations = 3;
iter = 0;
@@ -3257,6 +3622,7 @@ static void ReorderAutomatic(struct FemType *data,int iterations,
for(j=1;j<=noelements;j++) {
elemtype = data->elementtypes[j];
nonodes = elemtype%100;
+ nocands = 0;
for(i=0;itopology[j][i];
@@ -3313,7 +3679,7 @@ static void ReorderAutomatic(struct FemType *data,int iterations,
localtmp[l] = ind;
dx = data->x[l] - data->x[ind];
dy = data->y[l] - data->y[ind];
- if(data->dim == 3) dz = data->z[l] - data->z[ind];
+ dz = data->z[l] - data->z[ind];
localdist[l] = corder[0]*fabs(dx) + corder[1]*fabs(dy) + corder[2]*fabs(dz);
}
}
@@ -3403,10 +3769,10 @@ void ReorderElements(struct FemType *data,struct BoundaryType *bound,
{
int i,j,k;
int noelements,noknots,nonodes,length;
- int **newtopology,*newmaterial,*newelementtypes;
- int *indx,*revindx,*elemindx,*revelemindx;
+ int **newtopology=NULL,*newmaterial=NULL,*newelementtypes=NULL;
+ int *indx=NULL,*revindx=NULL,*elemindx=NULL,*revelemindx=NULL;
int oldnoknots, oldnoelements;
- Real *newx,*newy,*newz,*arrange;
+ Real *newx=NULL,*newy=NULL,*newz=NULL,*arrange=NULL;
Real dx,dy,dz,cx,cy,cz,cbase;
noelements = oldnoelements = data->noelements;
@@ -3432,35 +3798,29 @@ void ReorderElements(struct FemType *data,struct BoundaryType *bound,
cz = corder[2];
}
else {
- Real xmin,xmax,ymin,ymax,zmin = 0,zmax = 0;
+ Real xmin,xmax,ymin,ymax,zmin,zmax;
xmin = xmax = data->x[1];
ymin = ymax = data->y[1];
- if(data->dim == 3) zmin = zmax = data->z[1];
+ zmin = zmax = data->z[1];
+
for(i=1;i<=data->noknots;i++) {
if(xmin > data->x[i]) xmin = data->x[i];
if(xmax < data->x[i]) xmax = data->x[i];
if(ymin > data->y[i]) ymin = data->y[i];
if(ymax < data->y[i]) ymax = data->y[i];
- if(data->dim == 3) {
- if(zmin > data->z[i]) zmin = data->z[i];
- if(zmax < data->z[i]) zmax = data->z[i];
- }
+ if(zmin > data->z[i]) zmin = data->z[i];
+ if(zmax < data->z[i]) zmax = data->z[i];
}
dx = xmax-xmin;
dy = ymax-ymin;
- if(data->dim == 3) dz = zmax-zmin;
- else dz = 0.0;
+ dz = zmax-zmin;
+
/* The second strategy seems to be better in many cases */
-#if 0
- cx = dx;
- cy = dy;
- cz = dz;
-#else
cbase = 100.0;
cx = pow(cbase,1.0*(dx>dy)+1.0*(dx>dz));
cy = pow(cbase,1.0*(dy>dx)+1.0*(dy>dz));
cz = pow(cbase,1.0*(dz>dx)+1.0*(dz>dx));
-#endif
+
corder[0] = cx;
corder[1] = cy;
corder[2] = cz;
@@ -3468,8 +3828,7 @@ void ReorderElements(struct FemType *data,struct BoundaryType *bound,
if(info) printf("Ordering with (%.3lg*x + %.3lg*y + %.3lg*z)\n",cx,cy,cz);
for(i=1;i<=noknots;i++) {
- arrange[i] = cx*data->x[i] + cy*data->y[i];
- if(data->dim == 3) arrange[i] += cz*data->z[i];
+ arrange[i] = cx*data->x[i] + cy*data->y[i] + cz*data->z[i];
}
SortIndex(noknots,arrange,indx);
@@ -3484,8 +3843,7 @@ void ReorderElements(struct FemType *data,struct BoundaryType *bound,
arrange[j] = 0.0;
for(i=0;itopology[j][i];
- arrange[j] += cx*data->x[k] + cy*data->y[k];
- if(data->dim == 3) arrange[j] += cz*data->z[k];
+ arrange[j] += cx*data->x[k] + cy*data->y[k] + cz*data->z[k];
}
}
@@ -3621,13 +3979,15 @@ int RemoveUnusedNodes(struct FemType *data,int info)
+
void RenumberBoundaryTypes(struct FemType *data,struct BoundaryType *bound,
int renumber, int bcoffset, int info)
{
- int i,j,k,l,doinit;
- int minbc=0,maxbc=0,*mapbc;
- int elemdim=0,elemtype=0,*mapdim,sideind[MAXNODESD1];
-
+ int i,j,k,doinit,isordered;
+ int minbc=0,maxbc=0,**mapbc;
+ int elemdim=0,elemtype=0,sideind[MAXNODESD1];
+ int bctype;
+
if(renumber) {
if(0) printf("Renumbering boundary types\n");
@@ -3646,49 +4006,87 @@ void RenumberBoundaryTypes(struct FemType *data,struct BoundaryType *bound,
}
if(doinit) return;
- mapbc = Ivector(minbc,maxbc);
- mapdim = Ivector(minbc,maxbc);
- for(i=minbc;i<=maxbc;i++) mapbc[i] = mapdim[i] = 0;
-
+ if(info) printf("Initial boundary interval [%d,%d]\n",minbc,maxbc);
+
+ mapbc = Imatrix(minbc,maxbc,0,2);
+ for(i=minbc;i<=maxbc;i++)
+ for(j=0;j<=2;j++)
+ mapbc[i][j] = 0;
+
for(j=0;j < MAXBOUNDARIES;j++) {
if(!bound[j].created) continue;
for(i=1;i<=bound[j].nosides;i++) {
GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],data,sideind,&elemtype);
+ if(!elemtype) printf("could not find boundary element: %d %d %d\n",i,j,bound[j].parent[i]);
elemdim = GetElementDimension(elemtype);
- mapbc[bound[j].types[i]] = TRUE;
- mapdim[bound[j].types[i]] = elemdim;
+ bctype = bound[j].types[i];
+
+ if(0) printf("type and dim: %d %d %d\n",elemtype,elemdim,bctype);
+
+ mapbc[bctype][elemdim] += 1;
}
}
-
+
+ if(0) {
+ for(i=minbc;i<=maxbc;i++)
+ for(j=0;j<=2;j++)
+ if(mapbc[i][j]) printf("bc map1: %d %d\n",i,mapbc[i][j]);
+ }
+
j = 0;
/* Give the larger dimension always a smaller BC type */
+ isordered = TRUE;
for(elemdim=2;elemdim>=0;elemdim--) {
for(i=minbc;i<=maxbc;i++) {
- if(mapdim[i] != elemdim) continue;
- if(mapbc[i]) {
- j++;
- mapbc[i] = j;
- }
+ if(!mapbc[i][elemdim]) continue;
+ j++;
+ if(i == j) {
+ printf("boundary index unaltered %d in %d %dD elements\n",i,mapbc[i][elemdim],elemdim);
+ }
+ else {
+ isordered = FALSE;
+ printf("boundary index changed %d -> %d in %d %dD elements\n",i,j,mapbc[i][elemdim],elemdim);
+ }
+ mapbc[i][elemdim] = j;
}
}
- if(maxbc - minbc >= j || minbc != 1) {
+ if(0) {
+ for(i=minbc;i<=maxbc;i++)
+ for(j=0;j<=2;j++)
+ if(mapbc[i][j]) printf("bc map2: %d %d\n",i,mapbc[i][j]);
+ }
+
+ if(isordered) {
+ if(info) printf("Numbering of boundary types is already ok\n");
+ }
+ else {
if(info) printf("Mapping boundary types from [%d %d] to [%d %d]\n",minbc,maxbc,1,j);
for(j=0;j < MAXBOUNDARIES;j++) {
if(!bound[j].created) continue;
for(i=1;i<=bound[j].nosides;i++) {
- bound[j].types[i] = mapbc[bound[j].types[i]];
+ GetElementSide(bound[j].parent[i],bound[j].side[i],bound[j].normal[i],data,sideind,&elemtype);
+ elemdim = GetElementDimension(elemtype);
+ bound[j].types[i] = mapbc[bound[j].types[i]][elemdim];
}
}
if(data->boundarynamesexist) {
+ char boundaryname0[MAXBCS][MAXNAMESIZE];
+
+ /* We need some temporal place is name mapping might not be unique */
+ for(j=minbc;j<=MIN(maxbc,MAXBODIES-1);j++)
+ strcpy(boundaryname0[j],data->boundaryname[j]);
+
for(j=minbc;j<=MIN(maxbc,MAXBODIES-1);j++) {
- if(mapbc[j])
- strcpy(data->boundaryname[mapbc[j]],data->boundaryname[j]);
+ for(elemdim=2;elemdim>=0;elemdim--) {
+ k = mapbc[j][elemdim];
+ if(k) strcpy(data->boundaryname[k],boundaryname0[j]);
+ }
}
}
}
- free_Ivector(mapbc,minbc,maxbc);
+ free_Imatrix(mapbc,minbc,maxbc,0,2);
}
if(bcoffset) {
@@ -3704,13 +4102,13 @@ void RenumberBoundaryTypes(struct FemType *data,struct BoundaryType *bound,
}
}
}
-}
+}
void RenumberMaterialTypes(struct FemType *data,struct BoundaryType *bound,int info)
{
- int i,j,k,l,noelements,doinit;
+ int i,j,noelements,doinit;
int minmat=0,maxmat=0,*mapmat;
if(0) printf("Setting new material types\n");
@@ -3731,16 +4129,23 @@ void RenumberMaterialTypes(struct FemType *data,struct BoundaryType *bound,int i
minmat = MIN(minmat,data->material[j]);
}
+ if(info) printf("Initial body interval [%d,%d]\n",minmat,maxmat);
+
mapmat = Ivector(minmat,maxmat);
for(i=minmat;i<=maxmat;i++) mapmat[i] = 0;
for(j=1;j<=noelements;j++)
- mapmat[data->material[j]] = TRUE;
+ mapmat[data->material[j]] += 1;
j = 0;
- for(i=minmat;i<=maxmat;i++)
- if(mapmat[i]) mapmat[i] = ++j;
-
+ for(i=minmat;i<=maxmat;i++) {
+ if(mapmat[i]) {
+ j++;
+ if(i != j) printf("body index changed %d -> %d in %d elements\n",i,j,mapmat[i]);
+ mapmat[i] = j;
+ }
+ }
+
if(maxmat - minmat >= j || minmat != 1) {
if(info) printf("Mapping material types from [%d %d] to [%d %d]\n",
minmat,maxmat,1,j);
@@ -3755,7 +4160,7 @@ void RenumberMaterialTypes(struct FemType *data,struct BoundaryType *bound,int i
}
}
else {
- if(info) printf("Materials ordered continuously between %d and %d\n",minmat,maxmat);
+ if(info) printf("Numbering of bodies is already ok\n");
}
free_Ivector(mapmat,minmat,maxmat);
}
@@ -3765,7 +4170,7 @@ void RenumberMaterialTypes(struct FemType *data,struct BoundaryType *bound,int i
int RemoveLowerDimensionalBoundaries(struct FemType *data,struct BoundaryType *bound,int info)
{
int i,j,noelements;
- int maxelemtype,maxelemdim,elemdim;
+ int elemtype,maxelemdim,minelemdim,elemdim;
int parent, side, sideind[MAXNODESD1],sideelemtype;
int nosides, oldnosides,newnosides;
@@ -3774,11 +4179,16 @@ int RemoveLowerDimensionalBoundaries(struct FemType *data,struct BoundaryType *b
noelements = data->noelements;
if(noelements < 1) return(1);
- maxelemtype = GetMaxElementType(data);
- maxelemdim = GetElementDimension(maxelemtype);
+ elemtype = GetMaxElementType(data);
+ maxelemdim = GetElementDimension(elemtype);
+ if(info) printf("Maximum elementtype is %d and dimension %d\n",elemtype,maxelemdim);
+
+ elemtype = GetMinElementType(data);
+ minelemdim = GetElementDimension(elemtype);
+ if(info) printf("Minimum elementtype is %d and dimension %d\n",elemtype,minelemdim);
- if(info) printf("Maximum elementtype is %d and dimension %d\n",maxelemtype,maxelemdim);
- if(maxelemdim < 2) return(2);
+ /* Nothing to remove if the bulk mesh has 1D elements */
+ if(minelemdim < 2) return(2);
oldnosides = 0;
newnosides = 0;
@@ -3792,14 +4202,11 @@ int RemoveLowerDimensionalBoundaries(struct FemType *data,struct BoundaryType *b
side = bound[j].side[i];
GetElementSide(parent,side,1,data,sideind,&sideelemtype);
- if(sideelemtype > 300)
- elemdim = 2;
- else if(sideelemtype > 200)
- elemdim = 1;
- else
- elemdim = 0;
+ elemdim = GetElementDimension(sideelemtype);
- if(maxelemdim - elemdim > 1) continue;
+ /* if(maxelemdim - elemdim > 1) continue; */
+ /* This was changed as we want to maintain 1D BCs of a hybrid 2D/3D mesh. */
+ if(minelemdim - elemdim > 1) continue;
nosides++;
if(nosides == i) continue;
@@ -3815,17 +4222,57 @@ int RemoveLowerDimensionalBoundaries(struct FemType *data,struct BoundaryType *b
}
if(info) printf("Removed %d (out of %d) less than %dD boundary elements\n",
- oldnosides-newnosides,oldnosides,maxelemdim);
+ oldnosides-newnosides,oldnosides,minelemdim-1);
return(0);
}
+int RemoveInternalBoundaries(struct FemType *data,struct BoundaryType *bound,int info)
+{
+ int i,j;
+ int parent,parent2;
+ int nosides,oldnosides,newnosides;
+
+ if(info) printf("Removing internal boundaries\n");
+
+ if( data->noelements < 1 ) return(1);
+
+ oldnosides = 0;
+ newnosides = 0;
+ for(j=0;j < MAXBOUNDARIES;j++) {
+ nosides = 0;
+ if(!bound[j].created) continue;
+ for(i=1;i<=bound[j].nosides;i++) {
+
+ oldnosides++;
+ parent = bound[j].parent[i];
+ parent2 = bound[j].parent2[i];
+
+ if( parent > 0 && parent2 > 0 ) continue;
+
+ nosides++;
+ if(nosides == i) continue;
+
+ bound[j].parent[nosides] = bound[j].parent[i];
+ bound[j].parent2[nosides] = bound[j].parent2[i];
+ bound[j].side[nosides] = bound[j].side[i];
+ bound[j].side2[nosides] = bound[j].side2[i];
+ bound[j].types[nosides] = bound[j].types[i];
+ }
+ bound[j].nosides = nosides;
+ newnosides += nosides;
+ }
+ if(info) printf("Removed %d (out of %d) internal boundary elements\n",
+ oldnosides-newnosides,oldnosides);
+ return(0);
+}
+#if 0
static void FindEdges(struct FemType *data,struct BoundaryType *bound,
int material,int sidetype,int info)
{
- int i,j,side,identical,element;
+ int i,j,side,identical,noelements,element;
int noknots,nomaterials,nosides,newbound;
int maxelementtype,maxedgenodes,elemedges,maxelemedges,edge,dosides;
int **edgetable,sideind[MAXNODESD1],sideelemtype,allocated;
@@ -3833,8 +4280,10 @@ static void FindEdges(struct FemType *data,struct BoundaryType *bound,
Real *arrange;
+ newbound = 0;
nomaterials = 0;
maxelementtype = 0;
+ noelements = data->noelements;
printf("FindEdges: Finding edges of bulk elements of type %d\n",material);
maxelementtype = GetMaxElementType(data);
@@ -3855,7 +4304,7 @@ static void FindEdges(struct FemType *data,struct BoundaryType *bound,
edgetable[i][j] = 0;
edge = 0;
- for(element=1;element<=data->noelements;element++) {
+ for(element=1;element<=noelements;element++) {
if(data->material[element] != material) continue;
elemedges = data->elementtypes[element]/100;
@@ -3892,18 +4341,6 @@ static void FindEdges(struct FemType *data,struct BoundaryType *bound,
SortIndex(noknots,arrange,indx);
-#if 0
- printf("noknots = %d\n",noknots);
- for(i=1;i<=noknots;i++)
- printf("indx[%d]=%d edge=%d arrange[%d] = %lg arrange[indx[%d]] = %lg\n",
- i,indx[i],edgetable[i][0],i,arrange[i],i,arrange[indx[i]]);
-#endif
-#if 0
- revindx = Ivector(1,data->noknots);
- for(i=1;i<=noknots;i++)
- revindx[indx[i]] = i;
-#endif
-
allocated = FALSE;
omstart:
@@ -3947,11 +4384,10 @@ static void FindEdges(struct FemType *data,struct BoundaryType *bound,
goto omstart;
}
-
free_Ivector(indx,1,noknots);
free_Imatrix(edgetable,1,maxelemedges*nomaterials,0,maxedgenodes+1);
}
-
+#endif
static int CompareIndexes(int elemtype,int *ind1,int *ind2)
{
@@ -3972,11 +4408,12 @@ static int CompareIndexes(int elemtype,int *ind1,int *ind2)
int FindNewBoundaries(struct FemType *data,struct BoundaryType *bound,
int *boundnodes,int suggesttype,int dimred,int info)
{
- int i,j,side,identical,element,lowerdim,dim,minedge = 0,maxedge = 0;
- int nonodes,nosides,newbound = 0;
+ int i,j,side,identical,element,lowerdim,dim,minedge,maxedge;
+ int noelements,noknots,nonodes,nosides,newbound;
int sideind[MAXNODESD1],sideind0[MAXNODESD1],sideelemtype,sideelemtype0,allocated;
- int noboundnodes,sameside,newtype = 0,elemtype;
+ int noboundnodes,sameside,newtype,elemtype;
+ newtype = 0;
allocated = FALSE;
dim = data->dim;
if(dimred)
@@ -3984,8 +4421,14 @@ int FindNewBoundaries(struct FemType *data,struct BoundaryType *bound,
else
lowerdim = dim-1;
+ noknots = data->noknots;
+ noelements = data->noelements;
noboundnodes = 0;
- for(i=1;i<=data->noknots;i++)
+ newbound = 0;
+ maxedge = 0;
+ minedge = 0;
+
+ for(i=1;i<=noknots;i++)
if(boundnodes[i]) noboundnodes++;
if(!noboundnodes) {
printf("FindNewBoundaries: no nonzero entries in boundnodes vector!\n");
@@ -3998,7 +4441,7 @@ int FindNewBoundaries(struct FemType *data,struct BoundaryType *bound,
omstart:
nosides = 0;
- for(element=1;element<=data->noelements;element++) {
+ for(element=1;element<=noelements;element++) {
elemtype = data->elementtypes[element];
if(dim == 1) {
@@ -4134,9 +4577,9 @@ int FindNewBoundaries(struct FemType *data,struct BoundaryType *bound,
int FindBulkBoundary(struct FemType *data,int mat1,int mat2,
int *boundnodes,int *noboundnodes,int info)
{
- int i,j,k = 0;
+ int i,j,k;
int nonodes,maxnodes,minnodes,material;
- Real ds,xmin = 0,xmax = 0,ymin = 0,ymax = 0,zmin = 0,zmax = 0,eps;
+ Real ds,xmin=0.0,xmax=0.0,ymin=0.0,ymax=0.0,zmin=0.0,zmax=0.0,eps;
int *visited,elemdim,*ind;
Real *anglesum,dx1,dx2,dy1,dy2,dz1,dz2,ds1,ds2,dotprod;
@@ -4214,7 +4657,7 @@ int FindBulkBoundary(struct FemType *data,int mat1,int mat2,
for(i=1;i<=data->noknots;i++) {
anglesum[i] /= 2.0 * FM_PI;
if(anglesum[i] > 0.99) visited[i] = 0;
- if(anglesum[i] > 1.01) printf("FindBulkBoundary: surpricingly large angle %.3le in node %d\n",anglesum[i],i);
+ if(anglesum[i] > 1.01) printf("FindBulkBoundary: surpricingly large angle %.3e in node %d\n",anglesum[i],i);
if(visited[i]) j++;
}
if(0) printf("There are %d boundary node candidates\n",j);
@@ -4279,28 +4722,23 @@ int FindBulkBoundary(struct FemType *data,int mat1,int mat2,
for(i=1;i<=data->noknots;i++)
if(visited[i]) {
if(j) {
- xmax = xmin = data->x[k];
- if(data->dim >= 2) ymax = ymin = data->y[k];
- if(data->dim >= 3) zmax = zmin = data->z[k];
+ xmax = xmin = data->x[i];
+ ymax = ymin = data->y[i];
+ zmax = zmin = data->z[i];
j = FALSE;
}
else {
if(data->x[i] > xmax) xmax = data->x[i];
if(data->x[i] < xmin) xmin = data->x[i];
- if(data->dim >= 2) {
- if(data->y[i] > ymax) ymax = data->y[i];
- if(data->y[i] < ymin) ymin = data->y[i];
- }
- if(data->dim >= 3) {
- if(data->z[i] > zmax) zmax = data->z[i];
- if(data->z[i] < zmin) zmin = data->z[i];
- }
+ if(data->y[i] > ymax) ymax = data->y[i];
+ if(data->y[i] < ymin) ymin = data->y[i];
+ if(data->z[i] > zmax) zmax = data->z[i];
+ if(data->z[i] < zmin) zmin = data->z[i];
}
}
- ds = (xmax-xmin)*(xmax-xmin);
- if(data->dim >= 2) ds += (ymax-ymin)*(ymax-ymin);
- if(data->dim >= 3) ds += (zmax-zmin)*(zmax-zmin);
+ ds = (xmax-xmin)*(xmax-xmin) +
+ (ymax-ymin)*(ymax-ymin) + (zmax-zmin)*(zmax-zmin);
ds = sqrt(ds);
eps = 1.0e-5 * ds;
@@ -4350,8 +4788,9 @@ int FindBoundaryBoundary(struct FemType *data,struct BoundaryType *bound,int mat
{
int i,j,k,l;
int hits,nonodes,nocorners,maxnodes,minnodes,elemtype,material,bounddim;
- Real ds,xmin,xmax,ymin = 0,ymax = 0,zmin = 0,zmax = 0,eps,dx1,dx2,dy1,dy2,dz1,dz2,ds1,ds2,dotprod;
- Real *anglesum = NULL;
+ Real ds,xmin=0.0,xmax=0.0,ymin=0.0,ymax=0.0,zmin=0.0,zmax=0.0;
+ Real eps,dx1,dx2,dy1,dy2,dz1,dz2,ds1,ds2,dotprod;
+ Real *anglesum=NULL;
int *visited,sideind[MAXNODESD2],elemind[MAXNODESD2];
eps = 1.0e-4;
@@ -4437,7 +4876,7 @@ int FindBoundaryBoundary(struct FemType *data,struct BoundaryType *bound,int mat
for(i=1;i<=data->noknots;i++) {
anglesum[i] /= 2.0 * FM_PI;
if(anglesum[i] > 0.99) visited[i] = 0;
- if(anglesum[i] > 1.01) printf("FindBulkBoundary: surpricingly large angle %.3le in node %d\n",anglesum[i],i);
+ if(anglesum[i] > 1.01) printf("FindBulkBoundary: surpricingly large angle %.3e in node %d\n",anglesum[i],i);
}
free_Rvector(anglesum,1,data->noknots);
@@ -4511,26 +4950,21 @@ int FindBoundaryBoundary(struct FemType *data,struct BoundaryType *bound,int mat
l = sideind[0];
xmax = xmin = data->x[l];
- if(data->dim >= 2) ymax = ymin = data->y[l];
- if(data->dim >= 3) zmax = zmin = data->z[l];
+ ymax = ymin = data->y[l];
+ zmax = zmin = data->z[l];
for(k=1;kx[l] > xmax) xmax = data->x[l];
if(data->x[l] < xmin) xmin = data->x[l];
- if(data->dim >= 2) {
- if(data->y[l] > ymax) ymax = data->y[l];
- if(data->y[l] < ymin) ymin = data->y[l];
- }
- if(data->dim >= 3) {
- if(data->z[l] > zmax) zmax = data->z[l];
- if(data->z[l] < zmin) zmin = data->z[l];
- }
+ if(data->y[l] > ymax) ymax = data->y[l];
+ if(data->y[l] < ymin) ymin = data->y[l];
+ if(data->z[l] > zmax) zmax = data->z[l];
+ if(data->z[l] < zmin) zmin = data->z[l];
}
- ds = (xmax-xmin)*(xmax-xmin);
- if(data->dim >= 2) ds += (ymax-ymin)*(ymax-ymin);
- if(data->dim >= 3) ds += (zmax-zmin)*(zmax-zmin);
+ ds = (xmax-xmin)*(xmax-xmin) +
+ (ymax-ymin)*(ymax-ymin) + (zmax-zmin)*(zmax-zmin);
ds = sqrt(ds);
eps = 1.0e-3 * ds;
@@ -4570,8 +5004,7 @@ int FindBoundaryBoundary(struct FemType *data,struct BoundaryType *bound,int mat
printf("FindBoundaryBoundary: unknown option %d for finding a side\n",mat2);
return(2);
}
-
-
+
*noboundnodes = 0;
for(i=1;i<=data->noknots;i++)
if(boundnodes[i]) *noboundnodes += 1;
@@ -4588,17 +5021,19 @@ int FindBoundaryBoundary(struct FemType *data,struct BoundaryType *bound,int mat
int IncreaseElementOrder(struct FemType *data,int info)
{
int i,j,side,element,maxcon,con,newknots,ind,ind2;
- int noelements,noknots,nonodes,maxnodes = 0,maxelemtype,hit,node,elemtype;
- int **newnodetable,inds[2],**newtopo;
- Real *newx,*newy,*newz;
+ int noelements,noknots,nonodes,maxnodes,maxelemtype,hit,node;
+ int elemtype;
+ int **newnodetable=NULL,inds[2],**newtopo=NULL;
+ Real *newx=NULL,*newy=NULL,*newz=NULL;
if(info) printf("Trying to increase the element order of current elements\n");
- CreateDualGraph(data,FALSE,info);
+ CreateNodalGraph(data,FALSE,info);
noknots = data->noknots;
noelements = data->noelements;
- maxcon = data->dualmaxconnections;
+ maxcon = data->nodalmaxconnections;
+ maxnodes = 0;
newnodetable = Imatrix(0,maxcon-1,1,noknots);
for(i=1;i<=noknots;i++)
@@ -4608,7 +5043,7 @@ int IncreaseElementOrder(struct FemType *data,int info)
newknots = 0;
for(i=1;i<=noknots;i++) {
for(j=0;jdualgraph[j][i];
+ con = data->nodalgraph[j][i];
if(con > i) {
newknots++;
newnodetable[j][i] = noknots + newknots;
@@ -4630,7 +5065,7 @@ int IncreaseElementOrder(struct FemType *data,int info)
}
for(i=1;i<=noknots;i++) {
for(j=0;jdualgraph[j][i];
+ con = data->nodalgraph[j][i];
ind = newnodetable[j][i];
if(con && ind) {
newx[ind] = 0.5*(data->x[i] + data->x[con]);
@@ -4688,7 +5123,7 @@ int IncreaseElementOrder(struct FemType *data,int info)
ind2 = inds[1];
}
for(j=0;jdualgraph[j][ind];
+ con = data->nodalgraph[j][ind];
if(con == ind2) {
node = newnodetable[j][ind];
@@ -4701,7 +5136,7 @@ int IncreaseElementOrder(struct FemType *data,int info)
data->elementtypes[element] = elemtype;
}
- DestroyDualGraph(data,info);
+ DestroyNodalGraph(data,info);
free_Rvector(data->x,1,data->noknots);
free_Rvector(data->y,1,data->noknots);
@@ -4724,38 +5159,226 @@ int IncreaseElementOrder(struct FemType *data,int info)
-
-
-static void CylindricalCoordinateTransformation(struct FemType *data,Real r1,Real r2,
- int rectangle)
+int IncreaseElementOrderOld(struct FemType *data,int info)
{
- int i,j,j2,ind1,ind2,nonodes1;
- Real x,y,r,f,z,q,x2,y2,z2,dx,dy,dz,eps,mult;
- int hits,trials,tests;
- int candidates,*candidatelist,*indx;
-
- if(rectangle) {
- printf("Rectangular geometry with r1=%.4lg for %d nodes.\n",
- r1,data->noknots);
- }
- else {
- printf("Cylindrical geometry with r1=%.4lg r2=%.4lg for %d nodes.\n",
- r1,r2,data->noknots);
- }
+ int i,j,side,element,noedges,elemtype,newnode;
+ int noelements,noknots,nosides,maxnodes;
+ int maxelementtype,maxedgenodes,elemedges,maxelemedges,edge,dosides;
+ int **edgetable=NULL,sideind[MAXNODESD1],sideelemtype,allocated;
+ int *indx=NULL,*identical=NULL,**newtopo=NULL;
+ Real *arrange=NULL,*newx=NULL,*newy=NULL,*newz=NULL;
+ if(info) printf("Trying to increase the element order of current elements\n");
+
+ maxelementtype = 0;
+ maxnodes = 0;
+ noedges = 0;
- for(i=1;i<=data->noknots;i++) {
- r = data->x[i];
- z = data->y[i];
- f = data->z[i];
+ noelements = data->noelements;
+ noknots = data->noknots;
- data->z[i] = z;
+ maxelementtype = GetMaxElementType(data);
- if(r >= r2) {
- data->x[i] = cos(f)*r;
- data->y[i] = sin(f)*r;
- }
- else if(r <= r2) {
+ if(maxelementtype/100 > 4) {
+ printf("IncreaseElementOrder: Implemented only for 2D elements!\n");
+ dosides = 0;
+ return(1);
+ }
+
+ if(maxelementtype/100 <= 2) maxedgenodes = 1;
+ else if(maxelementtype/100 <= 4) maxedgenodes = 2;
+ maxelemedges = maxelementtype/100;
+ allocated = FALSE;
+
+ edgeloop:
+
+ edge = 0;
+ for(element=1;element<=data->noelements;element++) {
+
+ elemedges = data->elementtypes[element]/100;
+
+ for(side=0;side sideind[1]) {
+ edgetable[edge][0] = sideind[0];
+ edgetable[edge][1] = sideind[1];
+ }
+ else {
+ edgetable[edge][1] = sideind[0];
+ edgetable[edge][0] = sideind[1];
+ }
+ }
+ }
+ }
+
+ if(!allocated) {
+ noedges = edge;
+ edgetable = Imatrix(1,noedges,0,maxedgenodes+1);
+ for(i=1;i<=noedges;i++)
+ for(j=0;j<=maxedgenodes+1;j++)
+ edgetable[i][j] = 0;
+ allocated = TRUE;
+ goto edgeloop;
+ }
+
+ printf("There are altogether %d edges in the elements\n",noedges);
+
+ arrange = Rvector(1,noedges);
+ for(i=1;i<=noedges;i++)
+ arrange[i] = 0.0;
+ for(i=1;i<=noedges;i++)
+ arrange[i] = edgetable[i][0];
+ indx = Ivector(1,noedges);
+
+ SortIndex(noedges,arrange,indx);
+
+#if 0
+ printf("noknots = %d\n",noknots);
+ for(i=1;i<=noknots;i++)
+ printf("indx[%d]=%d edge=%d arrange[%d] = %g arrange[indx[%d]] = %g\n",
+ i,indx[i],edgetable[i][0],i,arrange[i],i,arrange[indx[i]]);
+#endif
+#if 0
+ revindx = Ivector(1,data->noknots);
+ for(i=1;i<=noknots;i++)
+ revindx[indx[i]] = i;
+#endif
+
+ allocated = FALSE;
+ identical = Ivector(1,noedges);
+ for(i=1;i<=noedges;i++) identical[i] = 0;
+
+ nosides = 0;
+ for(i=1;i<=noedges;i++) {
+ if(identical[i] < 0) continue;
+ if(maxedgenodes == 1) {
+ for(j=i+1;j<=noedges && edgetable[indx[i]][0] == edgetable[indx[j]][0];j++)
+ identical[j] = -i;
+ }
+ else if(maxedgenodes == 2) {
+ for(j=i+1;j<=noedges && edgetable[indx[i]][0] == edgetable[indx[j]][0];j++)
+ if(edgetable[indx[i]][1] == edgetable[indx[j]][1])
+ identical[j] = -i;
+ }
+ identical[i] = ++nosides;
+ }
+
+ printf("There will be %d new nodes in the elements\n",nosides);
+
+ newx = Rvector(1,noknots+nosides);
+ newy = Rvector(1,noknots+nosides);
+ newz = Rvector(1,noknots+nosides);
+
+ for(i=1;i<=noknots;i++) {
+ newx[i] = data->x[i];
+ newy[i] = data->y[i];
+ newz[i] = data->z[i];
+ }
+
+ if(maxelementtype <= 303)
+ maxnodes = 6;
+ else if(maxelementtype == 404)
+ maxnodes = 8;
+ newtopo = Imatrix(1,noelements,0,maxnodes-1);
+
+ for(element=1;element<=noelements;element++) {
+ elemtype = data->elementtypes[element];
+ elemedges = elemtype/100;
+ for(i=0;itopology[element][i];
+ }
+
+
+ for(j=1;j<=noedges;j++) {
+ newnode = identical[j];
+ if(newnode < 0) newnode = identical[abs(newnode)];
+ if(newnode <= 0) printf("Newnode = %d Edge = %d\n",newnode,j);
+ newnode += noknots;
+
+ edge = indx[j];
+ element = edgetable[edge][maxedgenodes];
+ side = edgetable[edge][maxedgenodes+1];
+
+ GetElementSide(element,side,1,data,sideind,&sideelemtype);
+
+ elemtype = data->elementtypes[element];
+
+ newtopo[element][elemtype/100+side] = newnode;
+ if(elemtype == 303)
+ data->elementtypes[element] = 306;
+ else if(elemtype == 404)
+ data->elementtypes[element] = 408;
+
+ newx[newnode] = 0.5*(data->x[sideind[0]] + data->x[sideind[1]]);
+ newy[newnode] = 0.5*(data->y[sideind[0]] + data->y[sideind[1]]);
+ newz[newnode] = 0.5*(data->z[sideind[0]] + data->z[sideind[1]]);
+ }
+
+ free_Rvector(data->x,1,data->noknots);
+ free_Rvector(data->y,1,data->noknots);
+ free_Rvector(data->z,1,data->noknots);
+ free_Imatrix(data->topology,1,data->noelements,0,data->maxnodes);
+
+
+ data->x = newx;
+ data->y = newy;
+ data->z = newz;
+
+ data->topology = newtopo;
+ data->noknots += nosides;
+ data->maxnodes = maxnodes;
+
+ free_Ivector(indx,1,noedges);
+ free_Ivector(identical,1,noedges);
+ free_Imatrix(edgetable,1,noedges,0,maxedgenodes+1);
+
+ printf("Created extra nodes in the middle of the edges\n");
+
+ return(0);
+}
+
+
+
+
+static void CylindricalCoordinateTransformation(struct FemType *data,Real r1,Real r2,
+ int rectangle)
+{
+ int i,j,j2,ind1,ind2,nonodes1;
+ Real x,y,r,f,z,q,x2,y2,z2,dx,dy,dz,eps,mult;
+ int hits,trials,tests;
+ int candidates,*candidatelist=NULL,*indx=NULL;
+
+ if(rectangle) {
+ printf("Rectangular geometry with r1=%.4lg for %d nodes.\n",
+ r1,data->noknots);
+ }
+ else {
+ printf("Cylindrical geometry with r1=%.4lg r2=%.4lg for %d nodes.\n",
+ r1,r2,data->noknots);
+ }
+
+
+ for(i=1;i<=data->noknots;i++) {
+ r = data->x[i];
+ z = data->y[i];
+ f = data->z[i];
+
+ data->z[i] = z;
+
+ if(r >= r2) {
+ data->x[i] = cos(f)*r;
+ data->y[i] = sin(f)*r;
+ }
+ else if(r <= r2) {
mult = r/r1;
@@ -4938,12 +5561,12 @@ static void CylindricalCoordinateImprove(struct FemType *data,Real factor,
}
-static void CylindricalCoordinateCurve(struct FemType *data,
- Real zet,Real rad,Real angle)
+void CylindricalCoordinateCurve(struct FemType *data,
+ Real zet,Real rad,Real angle)
{
int i;
Real x,y,z;
- Real z0,z1,f0,f,z2,x2,r0;
+ Real z0,z1,f,f0,z2,x2,r0;
printf("Cylindrical coordinate curve, zet=%.3lg rad=%.3lg angle=%.3lg\n",
zet,rad,angle);
@@ -4954,26 +5577,38 @@ static void CylindricalCoordinateCurve(struct FemType *data,
z1 = z0+r0*f0;
for(i=1;i<=data->noknots;i++) {
- x = data->x[i];
- y = data->y[i];
- z = data->z[i];
-
- if(z <= z0) continue;
+ if(data->dim == 2) {
+ z = data->x[i];
+ x = data->y[i];
+ }
+ else {
+ x = data->x[i];
+ y = data->y[i];
+ z = data->z[i];
+ }
+
+ if(z <= z0) continue;
+
if(z >= z1) {
z2 = z0 + sin(f0)*(r0+x) + cos(f0)*(z-z1);
x2 = (cos(f0)-1.0)*r0 + cos(f0)*x - sin(f0)*(z-z1);
- data->z[i] = z2;
- data->x[i] = x2;
}
else {
f = (z-z0)/r0;
z2 = z0 + sin(f)*(r0+x);
x2 = (cos(f)-1.0)*r0 + cos(f)*x;
+ }
+
+ if( data->dim == 2) {
+ data->x[i] = z2;
+ data->y[i] = x2;
+ }
+ else {
data->z[i] = z2;
- data->x[i] = x2;
- }
-
+ data->x[i] = x2;
+ }
+
}
}
@@ -5120,13 +5755,15 @@ void SeparateCartesianBoundaries(struct FemType *data,struct BoundaryType *bound
void SeparateMainaxisBoundaries(struct FemType *data,struct BoundaryType *bound)
{
- int i,j,k,l,maxtype,addtype = 0,elemsides;
+ int i,j,k,l,maxtype,addtype,elemsides;
int sideelemtype,sideind[MAXNODESD1];
int axistype[4],axishit[4],axissum,axismax,done;
Real x,y,z,sx,sy,sz,sxx,syy,szz,dx,dy,dz;
Real eps=1.0e-6;
maxtype = 0;
+ addtype = 0;
+
for(j=0;jnoboundaries;j++) {
if(!bound[j].created) continue;
@@ -5231,7 +5868,6 @@ void SeparateMainaxisBoundaries(struct FemType *data,struct BoundaryType *bound)
if(!done) {
axissum = 0;
axismax = 0;
- addtype = 0;
for(k=0;k<4;k++) {
axissum += axishit[k];
@@ -5272,16 +5908,22 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
struct GridType *grid,
struct FemType *data,struct BoundaryType *bound,
int info)
+/* Create mesh from 2D mesh either by extrusion or by rotation.
+ Also create the additional boundaries using automated numbering. */
{
- int i,j,k,l,m,n,knot0,knot1,knot2 = 0,elem0,size,kmax,noknots,origtype;
- int nonodes3d,nonodes2d;
- int cellk,element,level,side,parent,parent2,layers,elemtype;
- int material,material2,ind1,ind2,*indx,*topo;
- int sideelemtype,sideind[MAXNODESD1],sidetype,maxsidetype,newbounds;
- int refmaterial1[10],refmaterial2[10],refsidetype[10],indxlength;
- Real z,*newx,*newy,*newz,corder[3];
+#define MAXNEWBC 200
+ int i,j,k,l,m,n,knot0,knot1,knot2,elem0,size,kmax,noknots,origtype;
+ int nonodes3d,nonodes2d,bclevel,bcset;
+ int cellk,element,level,side,parent,parent2,layers,elemtype,material_too_large;
+ int material,material2,ind1,ind2;
+ int *indx=NULL,*topo=NULL;
+ int sideelemtype,sideind[MAXNODESD1],sidetype,minsidetype,maxsidetype,cummaxsidetype,newbounds;
+ int refmaterial1[MAXNEWBC],refmaterial2[MAXNEWBC],refsidetype[MAXNEWBC],indxlength;
+ Real z,*newx=NULL,*newy=NULL,*newz=NULL,corder[3];
Real meanx,meany;
-
+ int layerbcoffset;
+ int usenames;
+
if(grid->rotate)
SetElementDivisionCylinder(grid,info);
else if(grid->dimension == 3)
@@ -5295,7 +5937,9 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
data->dim = 3;
- origtype = dataxy->elementtypes[1];
+ origtype = 0;
+ for(i=1;i<=dataxy->noelements;i++)
+ origtype = MAX( origtype, dataxy->elementtypes[i]);
if(origtype == 303)
elemtype = 706;
@@ -5309,7 +5953,7 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
printf("CreateKnotsExtruded: not implemented for elementtypes %d!\n",origtype);
return;
}
- if(info) printf("Elementtype %d extruded to type %d.\n",origtype,elemtype);
+ printf("Maxium elementtype %d extruded to type %d.\n",origtype,elemtype);
nonodes2d = origtype%100;
data->maxnodes = nonodes3d = elemtype%100;
@@ -5317,16 +5961,33 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
layers = 1;
else
layers = 2;
+
+ /* Initialize the 3D mesh structure */
data->noknots = noknots = dataxy->noknots*(layers*grid->totzelems+1);
data->noelements = dataxy->noelements * grid->totzelems;
data->coordsystem = dataxy->coordsystem;
+ data->numbering = dataxy->numbering;
data->noboundaries = dataxy->noboundaries;
data->maxsize = dataxy->maxsize;
data->minsize = dataxy->minsize;
data->partitionexist = FALSE;
data->periodicexist = FALSE;
- data->connectexist = FALSE;
+ data->nodeconnectexist = FALSE;
+ data->elemconnectexist = FALSE;
+
+ usenames = dataxy->bodynamesexist || dataxy->boundarynamesexist;
+ if( usenames ) {
+ if( grid->zmaterialmapexists ) {
+ printf("Cannot extrude names when there is a given material mapping!\n");
+ usenames = FALSE;
+ }
+ else {
+ if(info) printf("Trying to maintain entity names in extrusion\n");
+ }
+ }
+
+
maxsidetype = 0;
AllocateKnots(data);
@@ -5345,58 +6006,90 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
newbounds += grid->rotateblocks;
}
+ /* Initialize the boundaries of the 3D mesh */
for(j=0;jnoboundaries+newbounds;j++) {
- if(j < data->noboundaries)
- if(!boundxy[j].created) continue;
+ if(boundxy[j].created || j>=data->noboundaries) {
+ bound[j] = boundxy[j];
+ bound[j].created = TRUE;
- if(0) bound[j] = boundxy[j];
- bound[j].created = TRUE;
-
- if(j >= data->noboundaries)
- size = dataxy->noelements;
- else
size = bound[j].nosides = boundxy[j].nosides * grid->totzelems;
-
- bound[j].coordsystem = COORD_CART3;
- bound[j].side = Ivector(1,size);
- bound[j].side2 = Ivector(1,size);
- bound[j].material = Ivector(1,size);
- bound[j].parent = Ivector(1,size);
- bound[j].parent2 = Ivector(1,size);
- bound[j].types = Ivector(1,size);
- bound[j].normal = Ivector(1,size);
-
- for(i=1;i<=size;i++) {
- bound[j].types[i] = 0;
- bound[j].side[i] = 0;
- bound[j].side2[i] = 0;
- bound[j].parent[i] = 0;
- bound[j].parent2[i] = 0;
- bound[j].material[i] = 0;
- bound[j].normal[i] = 1;
+ if(j >= data->noboundaries) size = dataxy->noelements;
+
+ bound[j].coordsystem = COORD_CART3;
+ bound[j].side = Ivector(1,size);
+ bound[j].side2 = Ivector(1,size);
+ bound[j].material = Ivector(1,size);
+ bound[j].parent = Ivector(1,size);
+ bound[j].parent2 = Ivector(1,size);
+ bound[j].types = Ivector(1,size);
+ bound[j].normal = Ivector(1,size);
+
+ for(i=1;i<=size;i++) {
+ bound[j].types[i] = 0;
+ bound[j].side[i] = 0;
+ bound[j].side2[i] = 0;
+ bound[j].parent[i] = 0;
+ bound[j].parent2[i] = 0;
+ bound[j].material[i] = 0;
+ bound[j].normal[i] = 1;
+ }
}
}
-
+ if(info) printf("Allocated for %d new BC lists\n",j);
+
knot0 = 0;
knot1 = layers*dataxy->noknots;
- if(layers == 2) knot2 = dataxy->noknots;
+ if(layers == 2)
+ knot2 = dataxy->noknots;
+ else
+ knot2 = 0;
elem0 = 0;
level = 0;
+ material_too_large = 0;
-
+ /* Set the element topology of the extruded mesh */
for(cellk=1;cellk <= grid->zcells ;cellk++) {
kmax = grid->zelems[cellk];
-
+
for(k=1;k<=kmax; k++) {
if(0) printf("elem0=%d knot0=%d knot1=%d\n",elem0,knot0,knot1);
level++;
for(element=1;element <= dataxy->noelements;element++) {
- if(dataxy->material[element] < grid->zfirstmaterial[cellk]) continue;
- if(dataxy->material[element] > grid->zlastmaterial[cellk]) continue;
+
+ origtype = dataxy->elementtypes[element];
+ nonodes2d = origtype % 100;
+ if(origtype == 303)
+ elemtype = 706;
+ else if(origtype == 404)
+ elemtype = 808;
+ else if(origtype == 408)
+ elemtype = 820;
+ else if(origtype == 409)
+ elemtype = 827;
+
+ if( grid->zmaterialmapexists ) {
+ material = dataxy->material[element];
+ if(material > grid->maxmaterial ) {
+ material_too_large += 1;
+ continue;
+ }
+ material = grid->zmaterialmap[cellk][material];
+ if(material <= 0 ) continue;
+ }
+ else {
+ if(dataxy->material[element] < grid->zfirstmaterial[cellk]) continue;
+ if(dataxy->material[element] > grid->zlastmaterial[cellk]) continue;
+
+ if(grid->zmaterial[cellk])
+ material = grid->zmaterial[cellk];
+ else
+ material = dataxy->material[element];
+ }
+
if(grid->rotate) {
meanx = 0.0;
for(i=0;inoelements+element] = elem0;
-
- data->elementtypes[elem0] = elemtype;
-
- if(grid->zmaterial[cellk])
- data->material[elem0] = grid->zmaterial[cellk];
- else
- data->material[elem0] = dataxy->material[element];
+ indx[(level-1)*dataxy->noelements+element] = elem0;
+ data->elementtypes[elem0] = elemtype;
+ data->material[elem0] = material;
if(elemtype == 706) {
for(i=0;i<3;i++) {
@@ -5452,10 +6140,19 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
}
}
data->noelements = elem0;
- if(info) printf("Extruded mesh has %d elements in %d levels.\n",elem0,level);
+ printf("Extruded mesh has %d elements in %d levels.\n",elem0,level);
+ printf("Simple extrusion would have %d elements\n",level*dataxy->noelements);
+
+ if( material_too_large > 0 ) {
+ printf("Material index exceeded %d the size of material permutation table (%d)!\n",
+ material_too_large,grid->maxmaterial);
+ printf("Give the max material with > Extruded Max Material < , if needed\n");
+ }
+
+ if(elem0 == 0) bigerror("No use to continue with zero elements!");
- /* Set the element coordinates. */
+ /* Set the nodal coordinates of the extruded mesh. */
knot0 = 0;
for(cellk=1;cellk <= grid->zcells ;cellk++) {
@@ -5517,19 +6214,22 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
}
}
-
+ /* Perform cylindrical coordinate transformation */
if(grid->rotate)
CylindricalCoordinateTransformation(data,grid->rotateradius1,
grid->rotateradius2,grid->rotatecartesian);
- maxsidetype = 0;
+ cummaxsidetype = 0;
sidetype = 0;
-
-
- /* Extrude the 2D boundary conditions. */
+ /* Extrude the 2D boundary conditions. Initially BCs typically have parents with
+ different material. If due to selective extrusion they become the same then
+ the extruded BC does not have that component. */
for(j=0;jnoboundaries;j++) {
if(!bound[j].created) continue;
+
+ maxsidetype = 0;
+ minsidetype = INT_MAX;
side = 0;
level = 0;
@@ -5537,12 +6237,9 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
for(k=1;k<=grid->zelems[cellk]; k++) {
level++;
-#if 0
- printf("level=%d j=%d side=%d\n",level,j,side);
-#endif
-
for(i=1;i<=boundxy[j].nosides;i++){
-
+
+ /* Find the parent element indexes and the corresponding material indexes */
ind1 = (level-1)*dataxy->noelements + boundxy[j].parent[i];
parent = indx[ind1];
@@ -5559,17 +6256,17 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
if(parent2) material2 = data->material[parent2];
else material2 = 0;
-#if 0
- printf("ind=[%d %d] parent=[%d %d] material=[%d %d]\n",
- ind1,ind2,parent,parent2,material,material2);
-#endif
-
if((parent || parent2) && (material != material2)) {
side++;
+ if(!parent & !parent2) printf("no parent = %d %d %d %d %d\n",parent,parent2,ind1,ind2,level);
+
sidetype = boundxy[j].types[i];
bound[j].types[side] = sidetype;
+ maxsidetype = MAX( maxsidetype, sidetype );
+ minsidetype = MIN( minsidetype, sidetype );
+
if(parent) {
bound[j].parent[side] = parent;
bound[j].parent2[side] = parent2;
@@ -5589,83 +6286,135 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
}
}
bound[j].nosides = side;
- if(sidetype > maxsidetype) maxsidetype = sidetype;
- printf("Extruded BC %d of type %d was created with %d sides.\n",
- j,sidetype,side);
+ cummaxsidetype = MAX( maxsidetype, cummaxsidetype );
+
+ if(info) {
+ if(side)
+ printf("Extruded BCs list %d of types [%d,%d] has %d elements.\n",
+ j,minsidetype,maxsidetype,side);
+ else
+ printf("Extruded BCs list %d has no elements!\n",j);
+ }
+
}
+ bcset = dataxy->noboundaries-1;
+
+
+ if( usenames ) {
+ for(i=1;i< MAXBODIES;i++)
+ strcpy(data->bodyname[i],dataxy->bodyname[i]);
+ for(i=1;i< MAXBOUNDARIES;i++)
+ strcpy(data->boundaryname[i],dataxy->boundaryname[i]);
+ data->bodynamesexist = TRUE;
+ data->boundarynamesexist = TRUE;
+ }
+
+ /* Find the BCs that are created for constant z-levels.
+ Here number all parent combinations so that each pair gets
+ a new BC index. They are numbered by their order of appearance. */
+ layerbcoffset = grid->layerbcoffset;
+
if(grid->layeredbc) {
+ if( !layerbcoffset ) sidetype = maxsidetype;
+
/* Find the BCs between layers. */
if(grid->dimension == 3 || grid->rotatecartesian) {
side = 0;
level = 0;
- j--;
-
+ bclevel = 0;
+
+
+ /* Go through extruded cells */
for(cellk=1;cellk <= grid->zcells ;cellk++) {
int swap,redo;
redo = FALSE;
redolayer:
-
+ maxsidetype = 0;
+ minsidetype = INT_MAX;
+
+ /* Go through element layers within cells */
for(k=1;k<=grid->zelems[cellk]; k++) {
level++;
if(!(k == 1) && !(cellk == grid->zcells && k==grid->zelems[cellk])) continue;
+ /* Last cell in case of last just one element layer gives rise to two BCs */
if(cellk == grid->zcells && k == grid->zelems[cellk]) {
if(grid->zelems[cellk] == 1)
redo = TRUE;
- else
+ else {
level++;
+ }
}
-
- if(grid->rotatecartesian && cellk%2 == 1) continue;
+
+ if(grid->rotatecartesian && cellk % 2 == 1) continue;
if(grid->rotatecartesian && k != 1) continue;
-
- for(i=0;i<10;i++) {
- refmaterial1[i] = 0;
- refmaterial2[i] = 0;
- refsidetype[i] = 0;
+
+ /* If layred bc offset is defined then the BCs are numbered deterministically
+ otherwise there is a complicated method of defining the BC index so that
+ indexes would be used in order. */
+ if(!layerbcoffset) {
+ for(i=0;inoelements;i++){
- ind1 = (level-2)*dataxy->noelements+i;
+ origtype = dataxy->elementtypes[i];
+ nonodes2d = origtype % 100;
+
+ if(origtype == 303)
+ elemtype = 706;
+ else if(origtype == 404)
+ elemtype = 808;
+ else if(origtype == 408)
+ elemtype = 820;
+ else if(origtype == 409)
+ elemtype = 827;
+
+ /* Check the parent elements of the layers. Only create a BC if the parents are
+ different. */
+ ind1 = (level-2)*dataxy->noelements + i;
if(ind1 < 1)
parent = 0;
else
parent = indx[ind1];
- ind2 = (level-1)*dataxy->noelements+i;
+ ind2 = (level-1)*dataxy->noelements + i;
if(ind2 > indxlength)
parent2 = 0;
else
parent2 = indx[ind2];
+ /* If only 2nd parent is given swap the order */
if(parent == 0 && parent2 != 0) {
- parent = parent2;
+ parent = parent2;
parent2 = 0;
swap = 1;
}
- else
+ else {
swap = 0;
-
+ }
+
if(!parent) continue;
+ /* Get the materials related to the parents */
material = data->material[parent];
if(parent2)
material2 = data->material[parent2];
else
material2 = 0;
-#if 0
- printf("level=%d ind=[%d %d] parent=[%d %d] material=[%d %d] swap=%d\n",
- level,ind1,ind2,parent,parent2,material,material2,swap);
-#endif
-
if(grid->rotatecartesian && !material2) {
if(origtype == 303) GetElementSide(parent,4-swap,1,data,sideind,&sideelemtype);
else GetElementSide(parent,5-swap,1,data,sideind,&sideelemtype);
@@ -5693,89 +6442,118 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
for(n=0;nycells && grid->y[n]+1.0e-12 < meany;n++);
material2 = grid->structure[n][m+1];
}
-#if 0
- printf("cellk=%d meanx=%.3lg meany=%.3lg material2=%d m=%d n=%d\n",
- cellk,meanx,meany,material2,m,n);
-#endif
}
-
- if(material != material2) {
-
+ /* Create bc index only if the materials are different */
+ if(material != material2) {
side++;
- bound[j].nosides = side;
- bound[j].parent[side] = parent;
- bound[j].parent2[side] = parent2;
- bound[j].material[side] = material;
+
+ bound[bcset].nosides = side;
+ bound[bcset].parent[side] = parent;
+ bound[bcset].parent2[side] = parent2;
+ bound[bcset].material[side] = material;
if(origtype == 303) {
- bound[j].side[side] = 4-swap;
- bound[j].side2[side] = 3+swap;
+ bound[bcset].side[side] = 4-swap;
+ bound[bcset].side2[side] = 3+swap;
}
else {
- bound[j].side[side] = 5-swap;
- bound[j].side2[side] = 4+swap;
+ bound[bcset].side[side] = 5-swap;
+ bound[bcset].side2[side] = 4+swap;
}
- for(m=0;m<10;m++) {
- if(refmaterial1[m] == material && refmaterial2[m] == material2) {
- break;
- }
- else if(refmaterial1[m] == 0 && refmaterial2[m] == 0) {
- refmaterial1[m] = material;
- refmaterial2[m] = material2;
- sidetype++;
- refsidetype[m] = sidetype;
- break;
+ /* Simple and deterministic, and complex and continuous numbering */
+ if(layerbcoffset) {
+ sidetype = bclevel * layerbcoffset + dataxy->material[i];
+ bound[bcset].types[side] = sidetype;
+ maxsidetype = MAX( sidetype, maxsidetype );
+ minsidetype = MIN( sidetype, minsidetype );
+ }
+ else {
+ for(m=0;mboundaryname[refsidetype[m]],"%s%s",
+ dataxy->bodyname[dataxy->material[i]],"_Start");
+ else if( cellk == grid->zcells )
+ sprintf(data->boundaryname[refsidetype[m]],"%s%s",
+ dataxy->bodyname[dataxy->material[i]],"_End");
+ else
+ sprintf(data->boundaryname[refsidetype[m]],"%s%s%d",
+ dataxy->bodyname[dataxy->material[i]],"_Level",bclevel);
}
+
+
}
- bound[j].types[side] = refsidetype[m];
+
}
}
- printf("BC %d on layer %d was created with %d sides.\n",j,level,side);
- if(sidetype > maxsidetype) maxsidetype = sidetype;
+ if(info) {
+ if(side)
+ printf("Layer BCs list %d of types [%d,%d] has %d elements.\n",
+ bcset,minsidetype,maxsidetype,side);
+ else
+ printf("Layer BCs list %d has no elements!\n",bcset);
+ }
- if(redo == TRUE) goto redolayer;
+ if(redo == TRUE) {
+ goto redolayer;
+ }
}
}
- j++;
}
}
-
/* Create four additional boundaries that may be used to force
symmetry constraints. These are only created if the object
is only partially rotated. */
+ bcset++;
if(grid->rotate && grid->rotateblocks < 4) {
int o,p;
+ int blocks, maxradi,addtype;
+ Real eps,fii,rad,meanrad,maxrad,xc,yc,dfii,fii0,rads[4],fiis[4];
+
o = p = 0;
+ eps = 1.0e-3;
+ blocks = grid->rotateblocks;
for(element=1;element<=data->noelements;element++) {
- int blocks, maxradi = 0,addtype;
- Real eps,fii,rad,meanrad,maxrad,xc,yc,dfii,fii0,rads[4],fiis[4];
-
- eps = 1.0e-3;
- blocks = grid->rotateblocks;
for(side=0;side<6;side++) {
GetElementSide(element,side,1,data,&sideind[0],&sideelemtype);
-
+
meanrad = 0.0;
maxrad = 0.0;
+ maxradi = 0;
for(i=0;i<4;i++) {
xc = data->x[sideind[i]];
yc = data->y[sideind[i]];
rad = sqrt(yc*yc+xc*xc);
- //fii = 2*atan2(yc,xc)/M_PI; /* Map fii to [0 4] */
- fii = 2*atan2(yc,xc)/FM_PI; /* Map fii to [0 4] */
+ fii = 2*atan2(yc,xc)/M_PI; /* Map fii to [0 4] */
rads[i] = rad;
fiis[i] = fii;
@@ -5815,38 +6593,36 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
else
addtype = 3;
}
-
- if( addtype >= 0) {
- bound[j+addtype].nosides++;
- k = bound[j+addtype].nosides;
- bound[j+addtype].side[k] = side;
- bound[j+addtype].parent[k] = element;
- bound[j+addtype].types[k] = sidetype+addtype+1;
+
+ if( addtype >= 0) {
+ bound[bcset+addtype].nosides++;
+ k = bound[bcset+addtype].nosides;
+ bound[bcset+addtype].side[k] = side;
+ bound[bcset+addtype].parent[k] = element;
+ bound[bcset+addtype].types[k] = sidetype+addtype+1;
}
}
}
- printf("Symmetry BCs [%d %d %d %d] have [%d %d %d %d] sides.\n",
- j,j+1,j+2,j+3,bound[j].nosides,bound[j+1].nosides,
- bound[j+2].nosides,bound[j+3].nosides);
- for(l=0;l<4;l++) {
- if(bound[j+l].nosides == 0)
- bound[j+l].created = FALSE;
- else
- bound[j+l].created = TRUE;
+ for(addtype=0;addtype<4;addtype++) {
+ l = bcset+addtype;
+ if(bound[l].nosides == 0) {
+ bound[l].created = FALSE;
+ }
+ else {
+ bound[l].created = TRUE;
+ if(info) {
+ if(bound[l].nosides)
+ printf("Symmetry BCs list %d of type %d has %d elements.\n",
+ l,sidetype+addtype+1,bound[l].nosides);
+ else
+ printf("Symmetry BCs list %d has no elements!\n",l);
+ }
+ }
}
- j += 4;
- }
-
- data->noboundaries = j+1;
-
-#if 0
- for(i=0;inoboundaries = bcset+1;
/* Renumber the element nodes so that all integers are used.
@@ -5856,7 +6632,7 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
indx[i] = 0;
for(element=1;element<=data->noelements;element++) {
- nonodes3d = data->elementtypes[element]%100;
+ nonodes3d = data->elementtypes[element] % 100;
for(i=0;itopology[element][i]] = 1;
}
@@ -5887,20 +6663,19 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
data->noknots = j;
for(element=1;element<=data->noelements;element++) {
- nonodes3d = data->elementtypes[element]%100;
+ nonodes3d = data->elementtypes[element] % 100;
for(i=0;itopology[element][i] = indx[data->topology[element][i]];
}
}
-
if(grid->rotate) {
ReorderElements(data,bound,FALSE,corder,info);
CylindricalCoordinateImprove(data,grid->rotateimprove,
grid->rotateradius1,grid->rotateradius2);
- if(grid->rotatecurve)
+ if(0 && grid->rotatecurve)
CylindricalCoordinateCurve(data,grid->curvezet,
grid->curverad,grid->curveangle);
@@ -5915,6 +6690,31 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
data->noelements,data->noknots);
free_Ivector(indx,0,indxlength);
+
+
+ /* Enforce constant helicity for the mesh if requested */
+ if( grid->zhelicityexists ) {
+ Real helicity,fii,x,y,z,minz,maxz;
+
+ helicity = (M_PI/180.0)*grid->zhelicity;
+
+ minz = maxz = data->z[1];
+ for(i=1;i<=data->noknots;i++) {
+ minz = MIN(minz,data->z[i]);
+ maxz = MAX(maxz,data->z[i]);
+ }
+ for(i=1;i<=data->noknots;i++) {
+ x = data->x[i];
+ y = data->y[i];
+ z = data->z[i];
+ fii = helicity*(z-minz)/(maxz-minz);
+
+ data->x[i] = cos(fii)*x - sin(fii)*y;
+ data->y[i] = sin(fii)*x + cos(fii)*y;
+ }
+ if(info) printf("Applied helicity of %12.5le degrees\n",grid->zhelicity);
+ }
+
}
@@ -5922,8 +6722,9 @@ void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
void ReduceElementOrder(struct FemType *data,int matmin,int matmax)
/* Reduces the element order at material interval [matmin,matmax] */
{
- int i,j,element,material,elemcode1,elemcode2,maxnode,*indx,reduced;
- Real *newx,*newy,*newz;
+ int i,j,element,material,elemcode1,elemcode2,maxnode,reduced;
+ int *indx=NULL;
+ Real *newx=NULL,*newy=NULL,*newz=NULL;
indx = Ivector(0,data->noknots);
for(i=0;i<=data->noknots;i++)
@@ -5937,6 +6738,8 @@ void ReduceElementOrder(struct FemType *data,int matmin,int matmax)
if(material >= matmin && material <= matmax)
elemcode2 = 101*(elemcode1/100);
if(elemcode2 == 505) elemcode2 = 504; /* tetrahedron */
+ else if(elemcode2 == 606) elemcode2 = 605; /* pyramid */
+ else if(elemcode2 == 707) elemcode2 = 706; /* prism */
#if 0
printf("element=%d codes=[%d,%d]\n",element,elemcode1,elemcode2);
printf("mat=%d interval=[%d,%d]\n",material,matmin,matmax);
@@ -5993,8 +6796,8 @@ void MergeElements(struct FemType *data,struct BoundaryType *bound,
{
int i,j,k,l;
int noelements,noknots,newnoknots,nonodes;
- int *mergeindx,*doubles;
- Real *newx,*newy,*newz;
+ int *mergeindx=NULL,*doubles=NULL;
+ Real *newx=NULL,*newy=NULL,*newz=NULL;
Real cx,cy,cz,dx,dy,dz,cdist,dist;
ReorderElements(data,bound,manual,corder,TRUE);
@@ -6036,6 +6839,7 @@ void MergeElements(struct FemType *data,struct BoundaryType *bound,
dx = data->x[i] - data->x[j];
dy = data->y[i] - data->y[j];
dz = data->z[i] - data->z[j];
+
if(fabs(cx*dx+cy*dy+cz*dz) > eps) break;
dist = dx*dx + dy*dy + dz*dz;
@@ -6074,11 +6878,6 @@ void MergeElements(struct FemType *data,struct BoundaryType *bound,
newz[mergeindx[i]] = data->z[i];
}
-#if 0
- for(i=1;i<=noknots;i++)
- printf("i=%d indx=%d merge=%d\n",i,indx[i],mergeindx[i]);
-#endif
-
free_Rvector(data->x,1,data->noknots);
free_Rvector(data->y,1,data->noknots);
free_Rvector(data->z,1,data->noknots);
@@ -6161,21 +6960,124 @@ void MergeBoundaries(struct FemType *data,struct BoundaryType *bound,int *double
+void IsoparametricElements(struct FemType *data,struct BoundaryType *bound,
+ int bcstoo,int info)
+{
+ int i,j,k;
+ int noelements,noknots;
+ int element,side,sideelemtype,sidenodes,elemtype;
+ int *bcindx=NULL,*topo=NULL,sideind[MAXNODESD1];
+ Real *x=NULL,*y=NULL,*z=NULL;
+
+ noelements = data->noelements;
+ noknots = data->noknots;
+ x = data->x;
+ y = data->y;
+ z = data->z;
+
+ bcindx = Ivector(1,noknots);
+ for(i=1;i<=noknots;i++)
+ bcindx[i] = FALSE;
+
+ for(j=0;j < MAXBOUNDARIES;j++) {
+ if(!bound[j].created) continue;
+
+ for(i=1; i <= bound[j].nosides; i++) {
+ element = bound[j].parent[i];
+ side = bound[j].side[i];
+
+ GetElementSide(element,side,1,data,sideind,&sideelemtype);
+
+ sidenodes = sideelemtype%100;
+
+ for(k=0;kelementtypes[j];
+ topo = data->topology[j];
+
+ if(elemtype == 306) {
+ for(i=0;i<3;i++) {
+ if(!bcindx[topo[i+3]]) {
+ x[topo[i+3]] = 0.5*(x[topo[i]]+x[topo[(i+1)%3]]);
+ y[topo[i+3]] = 0.5*(y[topo[i]]+y[topo[(i+1)%3]]);
+ }
+ }
+
+ }
+ else if(elemtype == 310) {
+ for(i=0;i<3;i++) {
+ if(!bcindx[topo[2*i+3]]) {
+ x[topo[2*i+3]] = (2.0*x[topo[i]]+1.0*x[topo[(i+1)%3]])/3.0;
+ x[topo[2*i+4]] = (1.0*x[topo[i]]+2.0*x[topo[(i+1)%3]])/3.0;
+ y[topo[2*i+3]] = (2.0*y[topo[i]]+1.0*y[topo[(i+1)%3]])/3.0;
+ y[topo[2*i+4]] = (1.0*y[topo[i]]+2.0*y[topo[(i+1)%3]])/3.0;
+ }
+ }
+ x[topo[9]] = (x[topo[0]]+x[topo[1]]+x[topo[2]])/3.0;
+ y[topo[9]] = (y[topo[0]]+y[topo[1]]+y[topo[2]])/3.0;
+ }
+ else if(elemtype == 408 || elemtype == 409) {
+ for(i=0;i<4;i++) {
+ if(!bcindx[topo[i+4]]) {
+ x[topo[i+4]] = 0.5*(x[topo[i]]+x[topo[(i+1)%4]]);
+ y[topo[i+4]] = 0.5*(y[topo[i]]+y[topo[(i+1)%4]]);
+ }
+ }
+ if(elemtype == 409) {
+ x[topo[8]] = 0.25*(x[topo[0]]+x[topo[1]]+x[topo[2]]+x[topo[3]]);
+ y[topo[8]] = 0.25*(y[topo[0]]+y[topo[1]]+y[topo[2]]+y[topo[3]]);
+ }
+ }
+ else if(elemtype == 412 || elemtype == 416) {
+ for(i=0;i<4;i++) {
+ if(!bcindx[topo[2*i+4]]) {
+ x[topo[2*i+4]] = (2.0*x[topo[i]]+1.0*x[topo[(i+1)%4]])/3.0;
+ x[topo[2*i+5]] = (1.0*x[topo[i]]+2.0*x[topo[(i+1)%4]])/3.0;
+ y[topo[2*i+4]] = (2.0*y[topo[i]]+1.0*y[topo[(i+1)%4]])/3.0;
+ y[topo[2*i+5]] = (1.0*y[topo[i]]+2.0*y[topo[(i+1)%4]])/3.0;
+ }
+ }
+ if(elemtype == 416) {
+ Real xmean,ymean;
+ xmean = (x[topo[0]]+x[topo[1]]+x[topo[2]]+x[topo[3]])/4.0;
+ ymean = (y[topo[0]]+y[topo[1]]+y[topo[2]]+y[topo[3]])/4.0;
+ for(i=0;i<4;i++) {
+ x[topo[11+i]] = (2.*xmean + 1.0*x[i]) / 3.0;
+ y[topo[11+i]] = (2.*ymean + 1.0*y[i]) / 3.0;
+ }
+ }
+ }
+ else {
+ printf("IsoparamametricElements: Not implemented for elementtype %d\n",elemtype);
+ }
+ }
+
+ if(info) printf("The elements were forced to be isoparametric\n");
+}
+
+
void ElementsToBoundaryConditions(struct FemType *data,
struct BoundaryType *bound,int retainorphans,int info)
{
- int i,j,k,l,sideelemtype,sideelemtype2,elemind,elemind2,parent,sideelem,sameelem;
+ int i,j,k,l,sideelemtype,sideelemtype2,elemind,elemind2,sideelem,sameelem;
int sideind[MAXNODESD1],sideind2[MAXNODESD1],elemsides,side,hit,same,minelemtype;
int sidenodes,sidenodes2,maxelemtype,elemtype,elemdim,sideelements,material;
- int *moveelement,*parentorder,*possible,**invtopo;
+ int *moveelement=NULL,*parentorder=NULL,*possible=NULL,**invtopo=NULL;
int noelements,maxpossible,noknots,maxelemsides,twiceelem,sideelemdim;
- int debug,unmoved,removed,elemhits;
- int notfound,*notfounds;
+ int debug,unmoved,removed,elemhits,loopdim,elemdim2,lowdimbulk;
+ int notfound,*notfounds=NULL;
- if(info) printf("Making elements to boundary conditions\n");
-
+ if(info) {
+ printf("Moving bulk elements to boundary elements\n");
+ if(0) printf("Trying to retain orphans: %d\n",retainorphans);
+ }
+
for(j=0;j < MAXBOUNDARIES;j++)
bound[j].created = FALSE;
for(j=0;j < MAXBOUNDARIES;j++)
@@ -6191,8 +7093,11 @@ void ElementsToBoundaryConditions(struct FemType *data,
if(info) printf("Trailing bulk elementtype is %d\n",minelemtype);
elemdim = GetElementDimension(maxelemtype);
- if( elemdim - GetElementDimension(minelemtype) == 0) return;
-
+ if( elemdim - GetElementDimension(minelemtype) == 0) {
+ if(info) printf("No lower dimensional elements present!\n");
+ return;
+ }
+
moveelement = Ivector(1,noelements);
sideelements = 0;
@@ -6201,20 +7106,13 @@ void ElementsToBoundaryConditions(struct FemType *data,
unmoved = 0;
removed = 0;
notfound = 0;
+ lowdimbulk = 0;
for(i=1;i<=noelements;i++) {
moveelement[i] = FALSE;
- elemsides = data->elementtypes[i]/100;
-
- if(elemsides > 4)
- sideelemdim = 3;
- else if(elemsides > 2)
- sideelemdim = 2;
- else if(elemsides > 1)
- sideelemdim = 1;
- else if(elemsides == 1)
- sideelemdim = 0;
+ sideelemdim = GetElementDimension(data->elementtypes[i]);
+ /* Lower dimensional elements are candidates to become BC elements */
moveelement[i] = elemdim - sideelemdim;
if(moveelement[i]) sideelements++;
}
@@ -6224,10 +7122,13 @@ void ElementsToBoundaryConditions(struct FemType *data,
AllocateBoundary(bound,sideelements);
+ /* Compute maximum number of hits for inverse topology */
possible = Ivector(1,noknots);
for(i=1;i<=noknots;i++) possible[i] = 0;
for(elemind=1;elemind <= data->noelements;elemind++) {
- if(moveelement[elemind]) continue;
+ /* if(moveelement[elemind]) continue; */
+ elemtype = data->elementtypes[elemind];
+ if(elemtype < 200 ) continue;
for(i=0;ielementtypes[elemind]%100;i++) {
j = data->topology[elemind][i];
possible[j] += 1;
@@ -6236,11 +7137,12 @@ void ElementsToBoundaryConditions(struct FemType *data,
j = 1;
maxpossible = possible[1];
- for(i=1;i<=noknots;i++)
+ for(i=1;i<=noknots;i++) {
if(maxpossible < possible[i]) {
maxpossible = possible[i];
j = i;
}
+ }
if(info) printf("Node %d belongs to maximum of %d elements\n",j,maxpossible);
/* Make a table showing to which elements a node belongs to
@@ -6251,8 +7153,9 @@ void ElementsToBoundaryConditions(struct FemType *data,
invtopo[i][j] = 0;
for(elemind=1;elemind <= data->noelements;elemind++) {
- if(moveelement[elemind]) continue;
+ /* if(moveelement[elemind]) continue; */
elemtype = data->elementtypes[elemind];
+ if(elemtype < 200 ) continue;
for(i=0;itopology[elemind][i];
for(l=1;invtopo[k][l];l++);
@@ -6266,80 +7169,109 @@ void ElementsToBoundaryConditions(struct FemType *data,
debug = FALSE;
- for(elemind=1;elemind <= data->noelements;elemind++) {
-
- if(!moveelement[elemind]) continue;
+ /* Go through boundary element candidates starting from higher dimension */
+ for(loopdim=elemdim-1;loopdim>=0;loopdim--) {
- same = FALSE;
- sideelemtype = data->elementtypes[elemind];
+ if(0) printf("loopdim = %d\n",loopdim);
- sidenodes = sideelemtype % 100;
- for(i=0;itopology[elemind][i];
- elemhits = 0;
-
- for(l=1;l<=maxpossible;l++) {
- elemind2 = invtopo[sideind[0]][l];
-
- if(!elemind2) continue;
-
- elemtype = data->elementtypes[elemind2];
- hit = 0;
- for(i=0;itopology[elemind2][j]) hit++;
+ for(elemind=1;elemind <= data->noelements;elemind++) {
- if(hit < sidenodes) continue;
-
- if(hit > sidenodes) printf("Strange: elemhits %d vs. elemnodes %d\n",hit,sidenodes);
- if(hit >= sidenodes) elemhits++;
+ if(!moveelement[elemind]) continue;
- for(side=0;side<=100;side++) {
-
- if(debug) printf("elem1=%d l=%d elem2=%d side=%d\n",elemind,l,elemind2,side);
+ same = FALSE;
+ sideelemtype = data->elementtypes[elemind];
+
+ /* Only check the elements that have right dimension */
+ sideelemdim = GetElementDimension(sideelemtype);
+ if(sideelemdim != loopdim ) continue;
+
+ sidenodes = sideelemtype % 100;
+ for(i=0;itopology[elemind][i];
+ elemhits = 0;
- GetElementSide(elemind2,side,1,data,&sideind2[0],&sideelemtype2);
+ if(debug) printf("Finding elem: %d %d %d\n",elemind,sideelemtype,sideelemdim);
- if(debug) printf("elemtype=%d sidelemtype=%d %d\n",
- elemtype,sideelemtype,sideelemtype2);
+
+ for(l=1;l<=maxpossible;l++) {
+ elemind2 = invtopo[sideind[0]][l];
+
+ if(!elemind2) continue;
- if(sideelemtype2 == 0 ) break;
- if(sideelemtype2 < 300 && sideelemtype > 300) break;
- if(sideelemtype2 < 200 && sideelemtype > 200) break;
+ /* The parent should be an element that will not become BC element */
+ if(moveelement[elemind2]) continue;
+
+ elemtype = data->elementtypes[elemind2];
+ elemdim2 = GetElementDimension(elemtype);
- sidenodes2 = sideelemtype2 % 100;
- if(sidenodes != sidenodes2) continue;
- if(sidenodes2 == 1 && sidenodes > 1) break;
+ /* Owner element should have highger dimension */
+ if(elemdim2 <= sideelemdim ) continue;
hit = 0;
- for(i=0;itopology[elemind2][j]) hit++;
+
if(hit < sidenodes) continue;
+
+ if(hit > sidenodes) printf("Strange: elemhits %d vs. elemnodes %d\n",hit,sidenodes);
+ if(hit >= sidenodes) elemhits++;
+
+ for(side=0;side<=100;side++) {
+ if(0) printf("elem1=%d l=%d elem2=%d side=%d\n",elemind,l,elemind2,side);
+
+ GetElementSide(elemind2,side,1,data,&sideind2[0],&sideelemtype2);
+
+ if(0) printf("elemtype=%d sidelemtype=%d %d\n",
+ elemtype,sideelemtype,sideelemtype2);
+
+ if(sideelemtype2 == 0 ) break;
+ if(sideelemtype2 < 300 && sideelemtype > 300) break;
+ if(sideelemtype2 < 200 && sideelemtype > 200) break;
+
+ sidenodes2 = sideelemtype2 % 100;
+ if(sidenodes != sidenodes2) continue;
+ if(sidenodes2 == 1 && sidenodes > 1) break;
+
+ hit = 0;
+ for(i=0;iparent2[sideelem] = elemind2;
- bound->side2[sideelem] = side;
+ bound->side2[sideelem] = side;
+
+ if(debug) printf(" Found 2nd: %d %d %d\n",elemind,elemind2,side);
goto foundtwo;
}
else {
sideelem += 1;
same = TRUE;
- if(debug) printf("sideelem=%d %d %d\n",sideelem,side,elemind2);
+ if(debug) printf(" Found 1st: %d %d %d\n",elemind,elemind2,side);
+
bound->parent[sideelem] = elemind2;
bound->side[sideelem] = side;
bound->parent2[sideelem] = 0;
- bound->side2[sideelem] = 0;
+ bound->side2[sideelem] = 0;
material = data->material[elemind];
bound->types[sideelem] = material;
+
if(sidenodes == 2) {
if((sideind[0]-sideind[1])*(sideind2[0]-sideind2[1])<0)
bound->normal[sideelem] = -1;
@@ -6352,41 +7284,55 @@ void ElementsToBoundaryConditions(struct FemType *data,
strncpy(data->boundaryname[material],"bnry",4);
}
+ /* Only try to find two parents if the boundary element is one degree smaller than maximum dimension */
if(moveelement[elemind] > 1) goto foundtwo;
}
}
- }
-
- if(!same) {
-
- if(0) {
- printf("element: index = %d type = %d nodes = %d elemhits = %d\n",
- elemind,sideelemtype,sidenodes,elemhits);
- printf(" inds =");
- for(i=0;inosides = sideelem;
+
printf("Removing %d lower dimensional elements from the element list\n",removed);
if(notfound) {
printf("************************** WARNING **********************\n");
@@ -6427,12 +7378,11 @@ void ElementsToBoundaryConditions(struct FemType *data,
}
}
-
- bound->nosides = sideelem;
-
-
- /* Reorder remaining master elements */
+ /* Reorder remaining bulk elements */
parentorder = Ivector(1,noelements);
+ for(i=1;i<=noelements;i++)
+ parentorder[i] = 0;
+
j = 0;
for(i=1;i<=noelements;i++) {
if(moveelement[i] == 0) {
@@ -6440,25 +7390,35 @@ void ElementsToBoundaryConditions(struct FemType *data,
j++;
parentorder[i] = j;
- data->material[j] = data->material[i];
- data->elementtypes[j] = data->elementtypes[i];
-
- for(l=0;ltopology[j][l] = data->topology[i][l];
+
+ if(debug) printf("Bulk is: %d %d\n",i,j);
+
+ if( i != j ) {
+ data->material[j] = data->material[i];
+ data->elementtypes[j] = data->elementtypes[i];
+ for(l=0;ltopology[j][l] = data->topology[i][l];
+ }
}
- else
- parentorder[i] = 0;
}
data->noelements = j;
- if(info) printf("Parent elements were reordered up to indx %d.\n",j);
+ if(info) printf("Parent elements were reordered up to index %d.\n",j);
/* Reorder boundary to point at the new arrangement of master elements */
for(i=1;i<=bound->nosides;i++) {
- if(bound->parent[i]) bound->parent[i] = parentorder[bound->parent[i]];
+ if( !parentorder[bound->parent[i]] ) {
+ printf("Zero reorder: %d %d %d\n",i,bound->parent[i],bound->side[i]);
+ bigerror("Sorry folks!");
+ }
+
+ if(bound->parent[i]) bound->parent[i] = parentorder[bound->parent[i]];
if(bound->parent2[i]) bound->parent2[i] = parentorder[bound->parent2[i]];
- }
+
+ GetElementSide(bound->parent[i],bound->side[i],1,data,&sideind2[0],&sideelemtype2);
+ if(0) GetBoundaryElement(i,&bound[j],data,&sideind2[0],&sideelemtype2);
+ }
if(info) printf("Moved %d elements (out of %d) to new positions\n",j,noelements);
@@ -6469,21 +7429,256 @@ void ElementsToBoundaryConditions(struct FemType *data,
free_Imatrix(invtopo,1,noknots,1,maxpossible);
if(notfound) free_Ivector(notfounds,1,noelements);
- if(info) printf("All done\n");
+ if(0) printf("All done\n");
return;
}
+int SideAndBulkMappings(struct FemType *data,struct BoundaryType *bound,struct ElmergridType *eg,int info)
+{
+ int i,j,l,currenttype;
+
+
+ if(eg->sidemappings) {
+ for(l=0;lsidemappings;l++)
+ if(info) printf("Setting boundary types between %d and %d to %d\n",
+ eg->sidemap[3*l],eg->sidemap[3*l+1],eg->sidemap[3*l+2]);
+
+ for(j=0;j < MAXBOUNDARIES;j++) {
+ if(!bound[j].created) continue;
+
+ for(i=1; i <= bound[j].nosides; i++) {
+ if(currenttype = bound[j].types[i]) {
+ for(l=0;lsidemappings;l++) {
+ if(currenttype >= eg->sidemap[3*l] && currenttype <= eg->sidemap[3*l+1]) {
+ bound[j].types[i] = eg->sidemap[3*l+2];
+ currenttype = -1;
+ }
+ }
+ }
+ }
+ }
+ if(info) printf("Renumbering boundary types finished\n");
+ }
+
+ if(eg->bulkmappings) {
+ for(l=0;lbulkmappings;l++)
+ if(info) printf("Setting material types between %d and %d to %d\n",
+ eg->bulkmap[3*l],eg->bulkmap[3*l+1],eg->bulkmap[3*l+2]);
+ for(j=1;j<=data->noelements;j++) {
+ currenttype = data->material[j];
+ for(l=0;lbulkmappings;l++) {
+ if(currenttype >= eg->bulkmap[3*l] && currenttype <= eg->bulkmap[3*l+1]) {
+ data->material[j] = eg->bulkmap[3*l+2];
+ currenttype = -1;
+ }
+ }
+ }
+ if(info) printf("Renumbering material indexes finished\n");
+ }
+ return(0);
+}
+
+
+
+int SideAndBulkBoundaries(struct FemType *data,struct BoundaryType *bound,struct ElmergridType *eg,int info)
+{
+ int l;
+ int *boundnodes,noboundnodes;
+ boundnodes = Ivector(1,data->noknots);
+
+ if(eg->bulkbounds) {
+ for(l=0;lbulkbounds;l++) {
+ FindBulkBoundary(data,eg->bulkbound[3*l],eg->bulkbound[3*l+1],
+ boundnodes,&noboundnodes,info);
+ FindNewBoundaries(data,bound,boundnodes,eg->bulkbound[3*l+2],1,info);
+ }
+ }
+ if(eg->boundbounds) {
+ for(l=0;lboundbounds;l++) {
+ FindBoundaryBoundary(data,bound,eg->boundbound[3*l],eg->boundbound[3*l+1],
+ boundnodes,&noboundnodes,info);
+ FindNewBoundaries(data,bound,boundnodes,eg->boundbound[3*l+2],2,info);
+ }
+ }
+ free_Ivector(boundnodes,1,data->noknots);
+
+ return(0);
+}
+
+
+void NodesToBoundaryChain(struct FemType *data,struct BoundaryType *bound,
+ int *bcinds,int *bctags,int nbc,int bccount,
+ int info)
+{
+ int i,j,k,l,sideelemtype,sideelemtype2,elemind,elemind2,sideelem,sameelem;
+ int sideind[MAXNODESD1],sideind2[MAXNODESD1],elemsides,side,hit,same,minelemtype;
+ int sidenodes,sidenodes2,elemtype,elemdim,sideelements,material;
+ int *possible=NULL,**invtopo=NULL;
+ int noelements,maxpossible,noknots,twiceelem,sideelemdim;
+ int elemhits,bci;
+
+
+ if(info) printf("Creating boundary elements from boundary nodes\n");
+
+ for(j=0;j < MAXBOUNDARIES;j++)
+ bound[j].created = FALSE;
+ for(j=0;j < MAXBOUNDARIES;j++)
+ bound[j].nosides = 0;
+
+ noelements = data->noelements;
+ noknots = data->noknots;
+
+ sideelements = nbc - bccount;
+ printf("Expected number of BC elements: %d\n",sideelements);
+
+ AllocateBoundary(bound,sideelements);
+
+ /* Calculate how may times a node apppears */
+ possible = Ivector(1,noknots);
+ for(i=1;i<=noknots;i++) possible[i] = 0;
+ for(elemind=1;elemind <= data->noelements;elemind++) {
+ for(i=0;ielementtypes[elemind]%100;i++) {
+ j = data->topology[elemind][i];
+ possible[j] += 1;
+ }
+ }
+
+ j = 1;
+ maxpossible = possible[1];
+ for(i=1;i<=noknots;i++) {
+ if(maxpossible < possible[i]) {
+ maxpossible = possible[i];
+ j = i;
+ }
+ }
+ if(info) printf("Node %d belongs to maximum of %d elements\n",j,maxpossible);
+
+ /* Make a table showing to which elements a node belongs to
+ Include only the potential parents which are not to be moved to BCs. */
+ invtopo = Imatrix(1,noknots,1,maxpossible);
+
+ for(i=1;i<=noknots;i++)
+ for(j=1;j<=maxpossible;j++)
+ invtopo[i][j] = 0;
+
+ for(elemind=1;elemind <= data->noelements;elemind++) {
+ elemtype = data->elementtypes[elemind];
+ for(i=0;itopology[elemind][i];
+ for(l=1;invtopo[k][l];l++); /* Yes, this is really ok. We look for unset entry. */
+ invtopo[k][l] = elemind;
+ }
+ }
+
+ sideelem = 0;
+ sameelem = 0;
+ twiceelem = 0;
+
+ /* These are here by construction because we are looking for a chain of nodes
+ and trying to create 202 elements of them! */
+ sidenodes = 2;
+ sideelemtype = 202;
+
+ for(bci=1;bcielementtypes[elemind2];
+ hit = 0;
+ for(i=0;itopology[elemind2][j]) hit++;
+
+ /* We must have all hits to have a chance of finding bc */
+ if(hit < sidenodes) continue;
+
+ elemhits++;
+
+ /* Now find on which side the bc is */
+ for(side=0;side<3;side++) {
+ GetElementSide(elemind2,side,1,data,&sideind2[0],&sideelemtype2);
+ if( sideelemtype2 != sideelemtype ) printf("This should not happen!\n");
+
+ hit = 0;
+ for(i=0;iparent2[sideelem] = elemind2;
+ bound->side2[sideelem] = side;
+ goto foundtwo;
+ }
+ else {
+ /* We haven't found parents for this bc elements yet */
+ sideelem += 1;
+ same = TRUE;
+ bound->parent[sideelem] = elemind2;
+ bound->side[sideelem] = side;
+ bound->parent2[sideelem] = 0;
+ bound->side2[sideelem] = 0;
+ bound->types[sideelem] = material;
+ if(sidenodes == 2) {
+ if((sideind[0]-sideind[1])*(sideind2[0]-sideind2[1])<0)
+ bound->normal[sideelem] = -1;
+ }
+ }
+ }
+ }
+ foundtwo:
+ continue;
+ }
+
+ if(twiceelem) printf("Found %d sides that were multiply given\n",twiceelem);
+ if(sameelem) printf("Found %d side elements that have two parents.\n",sameelem);
+
+
+ if(sideelem == sideelements) {
+ printf("Found correctly %d side elements.\n",sideelem);
+ }
+ else {
+ printf("Found %d side elements, could have found %d\n",sideelem,sideelements);
+ }
+
+ bound->nosides = sideelem;
+
+ free_Ivector(possible,1,noknots);
+ free_Imatrix(invtopo,1,noknots,1,maxpossible);
+
+ return;
+}
+
+
+
int FindPeriodicNodes(struct FemType *data,int periodicdim[],int info)
{
int i,j,i2,j2,dim;
- int noknots,hit,tothits,dimvisited;
- int *topbot = NULL,*indxper;
- int botn,topn,*revindtop,*revindbot;
- Real eps,dist = 0,dx,dy,dz,coordmax,coordmin;
- Real *coord = NULL,*toparr,*botarr,epsmin;
+ int noknots,hit,tothits;
+ int *topbot=NULL,*indxper=NULL;
+ int botn,topn,*revindtop=NULL,*revindbot=NULL;
+ Real eps,dist,dx,dy,dz,coordmax,coordmin;
+ Real *coord=NULL,*toparr=NULL,*botarr=NULL,epsmin;
if(data->dim < 3) periodicdim[2] = 0;
@@ -6496,26 +7691,27 @@ int FindPeriodicNodes(struct FemType *data,int periodicdim[],int info)
noknots = data->noknots;
tothits = 0;
- dimvisited = FALSE;
data->periodicexist = TRUE;
indxper = Ivector(1,noknots);
data->periodic = indxper;
-
+ topbot = Ivector(1,noknots);
+
+
for(i=1;i<=noknots;i++)
indxper[i] = i;
-
+
for(dim=1;dim<=3;dim++) {
if(!periodicdim[dim-1]) continue;
- if(info) printf("Finding periodic nodes in dim=%d\n",dim);
-
+ if(info) printf("Finding periodic nodes in direction %d\n",dim);
+
if(dim==1) coord = data->x;
else if(dim==2) coord = data->y;
- else if(dim==3) coord = data->z;
-
+ else coord = data->z;
+
coordmax = coordmin = coord[1];
-
+
for(i=1;i<=data->noknots;i++) {
if(coordmax < coord[i]) coordmax = coord[i];
if(coordmin > coord[i]) coordmin = coord[i];
@@ -6525,10 +7721,6 @@ int FindPeriodicNodes(struct FemType *data,int periodicdim[],int info)
dim,coordmin,coordmax);
if(coordmax-coordmin < 1.0e-10) continue;
-
- if(!dimvisited) {
- topbot = Ivector(1,noknots);
- }
eps = 1.0e-5 * (coordmax-coordmin);
topn = botn = 0;
@@ -6572,7 +7764,6 @@ int FindPeriodicNodes(struct FemType *data,int periodicdim[],int info)
revindbot[botn] = i;
}
}
-
if(data->dim == 2) {
for(i=1;i<=botn;i++) {
@@ -6580,21 +7771,21 @@ int FindPeriodicNodes(struct FemType *data,int periodicdim[],int info)
hit = FALSE;
for(i2=1;i2<=topn;i2++) {
j2 = revindtop[i2];
- if(dim == 1) dist = fabs(data->y[j] - data->y[j2]);
- else if(dim == 2) dist = fabs(data->x[j] - data->x[j2]);
+ if(dim == 1)
+ dist = fabs(data->y[j] - data->y[j2]);
+ else
+ dist = fabs(data->x[j] - data->x[j2]);
if(dist < eps) {
hit = TRUE;
goto hit2d;
}
}
+
hit2d:
if(hit) {
tothits++;
if(indxper[j] == j) indxper[j2] = j;
else if(indxper[indxper[j]]==indxper[j]) {
-#if 0
- printf("case2: j=[%d %d] i=[%d %d]\n",j,j2,i,i2);
-#endif
indxper[j2] = indxper[j];
}
else {
@@ -6607,9 +7798,8 @@ int FindPeriodicNodes(struct FemType *data,int periodicdim[],int info)
}
}
}
-
- dx = dy = dz = 0.0;
- if(data->dim == 3) {
+ else if(data->dim == 3) {
+ dx = dy = dz = 0.0;
for(i=1;i<=botn;i++) {
j = revindbot[i];
hit = FALSE;
@@ -6625,7 +7815,7 @@ int FindPeriodicNodes(struct FemType *data,int periodicdim[],int info)
dx = data->x[j] - data->x[j2];
dz = data->z[j] - data->z[j2];
}
- else if(dim == 3) {
+ else {
dx = data->x[j] - data->x[j2];
dy = data->y[j] - data->y[j2];
}
@@ -6635,46 +7825,207 @@ int FindPeriodicNodes(struct FemType *data,int periodicdim[],int info)
}
}
- hit3d:
- if(hit) {
- tothits++;
+ hit3d:
+ if(hit) {
+ tothits++;
+ indxper[j2] = indxper[j];
+ }
+ else {
+ printf("The periodic counterpart for node %d was not found!\n",j);
+ }
+ }
+ }
+
+ free_Rvector(toparr,1,topn);
+ free_Rvector(botarr,1,botn);
+ free_Ivector(revindtop,1,topn);
+ free_Ivector(revindbot,1,botn);
+ }
+
+ if(info) printf("Found all in all %d periodic nodes.\n",tothits);
+
+ free_Ivector(topbot,1,noknots);
+
+ return(0);
+}
+
+
+
+
+int FindPeriodicParents(struct FemType *data,struct BoundaryType *bound,int info)
+{
+ int i,j,k,k2,l,l2,totsides,newsides,sidenodes,sideelemtype,side;
+ int noknots,maxhits,nodes,hits,hits2,targets,mappings,targetnode;
+ int parent,parent2,sideind[MAXNODESD1],sideind2[MAXNODESD1];
+ int **periodicparents=NULL, *periodichits=NULL,*periodictarget=NULL,*indexper=NULL;
+
+ totsides = 0;
+ newsides = 0;
+ targets = 0;
+ parent2 = 0;
+
+ if(info) printf("Finding secondary periodic parents for boundary elements\n");
+
+ if(!data->periodicexist) {
+ printf("FindPeriodicParents: Periodic nodes are not defined\n");
+ return(2);
+ }
+
+ indexper = data->periodic;
+
+ /* Set pointers that point to the periodic nodes */
+ noknots = data->noknots;
+ periodictarget = Ivector(1,noknots);
+ for(i=1;i<=noknots;i++)
+ periodictarget[i] = 0;
+
+ mappings = 0;
+ for(i=1;i<=noknots;i++) {
+ j = indexper[i];
+ if( j != i) {
+ mappings++;
+ periodictarget[j] = i;
+ }
+ }
+
+ if(0) for(i=1;i<=noknots;i++)
+ printf("indexes(%d) : %d %d\n",i,indexper[i],periodictarget[i]);
+
+
+ if(info) printf("Number of potential periodic mappings is %d\n",mappings);
+ for(i=1;i<=noknots;i++)
+ if(periodictarget[i]) targets++;
+ if(info) printf("Number of potential periodic targets is %d\n",targets);
+
+
+ /* Vector telling how many elements are associated with the periodic nodes */
+ maxhits = 0;
+ periodichits = Ivector(1,noknots);
+ for(i=1;i<=noknots;i++)
+ periodichits[i] = 0;
+
+ /* Create the matrix telling which elements are associated with the periodic nodes */
+ setparents:
+ for(j=1;j <= data->noelements;j++) {
+ nodes = data->elementtypes[j] % 100;
+ for(i=0;itopology[j][i];
+ if( k != indexper[k] ) {
+ periodichits[k] += 1;
+ if( maxhits > 0 ) {
+ periodicparents[k][periodichits[k]] = j;
+ }
+ }
+ }
+ }
+
+ if( maxhits == 0 ) {
+ for(i=1;i<=noknots;i++)
+ maxhits = MAX( maxhits, periodichits[i] );
+
+ printf("Maximum number of elements associated with periodic nodes is %d\n",maxhits);
+ periodicparents = Imatrix(1,noknots,1,maxhits);
+ for(i=1;i<=noknots;i++) {
+ periodichits[i] = 0;
+ for(j=1;j<=maxhits;j++)
+ periodicparents[i][j] = 0;
+ }
+ goto setparents;
+ }
+
+ for(j=0;jelementtypes[parent2];
+ elemsides = GetElementFaces(elemtype);
+
+ for(side=0;sidenoknots < 200) {
- for(i=1;i<=data->noknots;i++)
- if(i!=indxper[i]) printf("i=%d per=%d\n",i,indxper[i]);
- }
-#endif
+ free_Ivector(periodictarget,1,noknots);
+ free_Ivector(periodichits,1,noknots);
+ free_Imatrix(periodicparents,1,noknots,1,maxhits);
+ if(info) printf("Found %d secondary parents for %d potential sides.\n",newsides,totsides);
return(0);
}
-
int CreateBoundaryLayer(struct FemType *data,struct BoundaryType *bound,
int nolayers, int *layerbounds, int *layernumber,
Real *layerratios, Real *layerthickness, int *layerparents,
@@ -6682,30 +8033,32 @@ int CreateBoundaryLayer(struct FemType *data,struct BoundaryType *bound,
/* Create Boundary layers that may be used to solve accurately fluid
flow problems and similar equations. */
{
- int i,j,k,l,m,n,i2,i3,nonodes,maxbc,newbc = 0;
+ int i,j,k,l,m,n,i2,i3,nonodes,maxbc,newbc;
int noknots,noelements,elemindx,nodeindx,elemtype;
int oldnoknots,oldnoelements,maxelemtype,oldmaxnodes;
- int nonewnodes,nonewelements,dolayer,dim,order = 0,midpoints = 0;
+ int nonewnodes,nonewelements,dolayer,dim,order,midpoints;
int checkmaterials,parent,parent2,use2,second;
- Real dx = 0,dy = 0,ds,ratio,q,p,rectfactor;
- Real *newx,*newy,*newz,*oldx,*oldy,*elemwidth;
+ Real dx,dy,ds,ratio,q,p,rectfactor;
+ Real *newx=NULL,*newy=NULL,*newz=NULL,*oldx=NULL,*oldy=NULL,*elemwidth=NULL;
Real e1x,e1y,e2x,e2y;
int sideelemtype,ind[MAXNODESD2],sidebc[MAXNODESD1];
- int *layernode,*newelementtypes,**newtopo,**oldtopo;
- int *topomap,*newmaterial,*herit,*inside,*nonlin = NULL;
- int endbcs, *endparents = NULL, *endtypes = NULL, *endnodes = NULL, *endnodes2 = NULL, *endneighbours = NULL;
+ int *layernode=NULL,*newelementtypes=NULL,**newtopo=NULL,**oldtopo=NULL;
+ int *topomap=NULL,*newmaterial=NULL,*herit=NULL,*inside=NULL,*nonlin=NULL;
+ int endbcs, *endparents=NULL, *endtypes=NULL, *endnodes=NULL, *endnodes2=NULL, *endneighbours=NULL;
- if(maxfilters == 1) maxfilters = 1000;
- if(layereps > 0.1) layereps = 0.001;
- if(layereps < 1.0e-8) layereps = 0.001;
- rectfactor = 1.0e2;
+ if(0) printf("maxfilters=%d layereps=%.3e\n",maxfilters,layereps);
+ if(!maxfilters) maxfilters = 1000;
+ if(layereps < 1.0e-20) layereps = 1.0e-3;
+ rectfactor = 1.0e2;
+ midpoints = FALSE;
+ order = 1;
dim = data->dim;
maxelemtype = GetMaxElementType(data);
if(maxelemtype > 409) {
- printf("Subroutine implemented only up to 2nd degree!\n");
- return(2);
+ printf("Subroutine implemented only up to 2nd degree in 2D!\n");
+ bigerror("Cannot continue");
}
if(info) printf("Largest elementtype is %d\n",maxelemtype);
@@ -7296,9 +8649,9 @@ int CreateBoundaryLayer(struct FemType *data,struct BoundaryType *bound,
if(maxfilters) {
int method,iter;
- int ind1,ind2,ind3,*fixedx,*fixedy;
- Real *aidx,*aidy,*weights;
- Real maxerror = 0,minds,dx2 = 0,dy2 = 0,ds2,fii;
+ int ind1,ind2,ind3,*fixedx=NULL,*fixedy=NULL;
+ Real *aidx=NULL,*aidy=NULL,*weights=NULL;
+ Real maxerror=0.0,minds,dx2,dy2,ds2,fii;
/* There are three methods how to put the weight in the filter,
1) 1/s, 2) fii/s, 3) sin(fii)/s, the second option seems to be best. */
@@ -7511,8 +8864,8 @@ int CreateBoundaryLayer(struct FemType *data,struct BoundaryType *bound,
if(j <= oldnoelements && ds * ds2 < 1.0e-50) {
printf("problem elem %d and nodes %d (%d %d)\n",j,i2,i,i3);
- printf("dist ds=%.3le ds2=%.3le\n",ds,ds2);
- printf("coord: %.3le %.3le\n",oldx[oldtopo[j][i2]], oldy[oldtopo[j][i2]]);
+ printf("dist ds=%.3e ds2=%.3e\n",ds,ds2);
+ printf("coord: %.3e %.3e\n",oldx[oldtopo[j][i2]], oldy[oldtopo[j][i2]]);
continue;
}
@@ -7602,7 +8955,7 @@ int CreateBoundaryLayer(struct FemType *data,struct BoundaryType *bound,
}
if(info) {
- printf("Filtered the new node coordinates %d times with final error %.3le.\n",
+ printf("Filtered the new node coordinates %d times with final error %.3e.\n",
iter-1,maxerror);
}
@@ -7734,14 +9087,15 @@ int CreateBoundaryLayerDivide(struct FemType *data,struct BoundaryType *bound,
flow problems and similar equations. In this subroutine the boundary layer
is created by dividing the elements close to boundary. */
{
- int i,j,k,l,dim,maxbc,maxelemtype,dolayer,parent,nlayer = 0,sideelemtype,elemind,side;
+ int i,j,k,l,dim,maxbc,maxelemtype,dolayer,parent,nlayer,sideelemtype,elemind,side;
int noelements,noknots,oldnoknots,oldnoelements,oldmaxnodes,nonewnodes,nonewelements;
int maxcon,elemsides,elemdone,midpoints,order,bcnodes,elemhits,elemtype,goforit;
int ind[MAXNODESD2],baseind[2],topnode[2],basenode[2];
- int *layernode,*newelementtypes,**newtopo,**oldtopo,*newmaterial,**edgepairs,*sharednode;
+ int *layernode=NULL,*newelementtypes=NULL,**newtopo=NULL,**oldtopo=NULL;
+ int *newmaterial=NULL,**edgepairs=NULL,*sharednode=NULL;
Real dx[2],dy[2],x0[2],y0[2];
- Real *newx,*newy,*newz,*oldx,*oldy,*oldz;
- Real slayer = 0,qlayer = 0,ratio,q;
+ Real *newx=NULL,*newy=NULL,*newz=NULL,*oldx=NULL,*oldy=NULL,*oldz=NULL;
+ Real slayer,qlayer,ratio,q;
dim = data->dim;
@@ -7772,6 +9126,9 @@ int CreateBoundaryLayerDivide(struct FemType *data,struct BoundaryType *bound,
the numbder of nodes at the surface. */
maxbc = 0;
+ qlayer = 0.0;
+ slayer = 0.0;
+ nlayer = 0;
/* Go through the layers and check which ones are active */
for(j=0;jscale) {
if(info) printf("Scaling mesh with vector [%.3lg %.3lg %.3lg]\n",
@@ -8205,7 +9562,7 @@ int RotateTranslateScale(struct FemType *data,struct ElmergridType *eg,int info)
for(i=1;i<=data->noknots;i++) {
data->x[i] *= eg->cscale[0];
data->y[i] *= eg->cscale[1];
- if(data->dim == 3) data->z[i] *= eg->cscale[2];
+ data->z[i] *= eg->cscale[2];
}
if(0) printf("Scaling of mesh finished.\n");
}
@@ -8220,15 +9577,13 @@ int RotateTranslateScale(struct FemType *data,struct ElmergridType *eg,int info)
for(i=1;i<=data->noknots;i++) {
x = data->x[i];
- if(data->dim >= 2) y = data->y[i];
- else y = 0.0;
- if(data->dim >= 3) z = data->z[i];
- else z = 0.0;
+ y = data->y[i];
+ z = data->z[i];
xz = x*cos(cz) + y*sin(cz);
yz = -x*sin(cz) + y*cos(cz);
- if(data->dim == 3) {
+ if( fabs(cx) > 1.0e-8 || fabs(cy) > 1.0e-8 ) {
yx = yz*cos(cx) + z*sin(cx);
zx = -yz*sin(cx) + z*cos(cx);
@@ -8253,7 +9608,7 @@ int RotateTranslateScale(struct FemType *data,struct ElmergridType *eg,int info)
for(i=1;i<=data->noknots;i++) {
data->x[i] += eg->ctranslate[0];
data->y[i] += eg->ctranslate[1];
- if(data->dim == 3) data->z[i] += eg->ctranslate[2];
+ data->z[i] += eg->ctranslate[2];
}
if(0) printf("Translation of mesh finished.\n");
}
@@ -8261,28 +9616,26 @@ int RotateTranslateScale(struct FemType *data,struct ElmergridType *eg,int info)
if(eg->center) {
xmin = xmax = data->x[1];
ymin = ymax = data->y[1];
- if(data->dim == 3) zmin = zmax = data->z[1];
+ zmin = zmax = data->z[1];
for(i=1;i<=data->noknots;i++) {
xmax = MAX( xmax, data->x[i] );
xmin = MIN( xmin, data->x[i] );
ymax = MAX( ymax, data->y[i] );
ymin = MIN( ymin, data->y[i] );
- if(data->dim == 3) {
- zmax = MAX( zmax, data->z[i] );
- zmin = MIN( zmin, data->z[i] );
- }
+ zmax = MAX( zmax, data->z[i] );
+ zmin = MIN( zmin, data->z[i] );
}
cx = 0.5 * (xmin + xmax);
cy = 0.5 * (ymin + ymax);
- if(data->dim == 3) cz = 0.5 * (zmin + zmax);
-
- if(info) printf("Setting new center to %.3le %.3le %.3le\n",cx,cy,cz);
+ cz = 0.5 * (zmin + zmax);
+
+ if(info) printf("Setting new center to %.3e %.3e %.3e\n",cx,cy,cz);
for(i=1;i<=data->noknots;i++) {
data->x[i] -= cx;
data->y[i] -= cy;
- if(data->dim == 3) data->z[i] -= cz;
+ data->z[i] -= cz;
}
}
@@ -8291,15 +9644,17 @@ int RotateTranslateScale(struct FemType *data,struct ElmergridType *eg,int info)
-int CreateDualGraph(struct FemType *data,int full,int info)
+int CreateNodalGraph(struct FemType *data,int full,int info)
{
int i,j,k,l,m,totcon,noelements, noknots,elemtype,nonodes,hit,ind,ind2;
int maxcon,percon,edge;
- printf("Creating a dual graph of the finite element mesh\n");
+ printf("Creating a nodal graph of the finite element mesh\n");
- if(data->dualexists) {
- printf("The dual graph already exists! You should remove the old graph!\n");
+ if(data->nodalexists) {
+ printf("The nodal graph already exists!\n");
+ smallerror("Nodal graph not done");
+ return(1);
}
maxcon = 0;
@@ -8311,6 +9666,7 @@ int CreateDualGraph(struct FemType *data,int full,int info)
for(i=1;i<=noelements;i++) {
elemtype = data->elementtypes[i];
+ /* This sets only the connections resulting from element edges */
if(!full) {
int inds[2];
for(edge=0;;edge++) {
@@ -8321,38 +9677,39 @@ int CreateDualGraph(struct FemType *data,int full,int info)
hit = FALSE;
for(l=0;ldualgraph[l][ind] == ind2) hit = TRUE;
- if(data->dualgraph[l][ind] == 0) break;
+ if(data->nodalgraph[l][ind] == ind2) hit = TRUE;
+ if(data->nodalgraph[l][ind] == 0) break;
}
if(!hit) {
if(l >= maxcon) {
- data->dualgraph[maxcon] = Ivector(1,noknots);
+ data->nodalgraph[maxcon] = Ivector(1,noknots);
for(m=1;m<=noknots;m++)
- data->dualgraph[maxcon][m] = 0;
+ data->nodalgraph[maxcon][m] = 0;
maxcon++;
}
- data->dualgraph[l][ind] = ind2;
+ data->nodalgraph[l][ind] = ind2;
totcon++;
}
/* Make also so symmetric connection */
for(l=0;ldualgraph[l][ind2] == ind) hit = TRUE;
- if(data->dualgraph[l][ind2] == 0) break;
+ if(data->nodalgraph[l][ind2] == ind) hit = TRUE;
+ if(data->nodalgraph[l][ind2] == 0) break;
}
if(!hit) {
if(l >= maxcon) {
- data->dualgraph[maxcon] = Ivector(1,noknots);
+ data->nodalgraph[maxcon] = Ivector(1,noknots);
for(m=1;m<=noknots;m++)
- data->dualgraph[maxcon][m] = 0;
+ data->nodalgraph[maxcon][m] = 0;
maxcon++;
}
- data->dualgraph[l][ind2] = ind;
+ data->nodalgraph[l][ind2] = ind;
totcon++;
}
}
}
+ /* This sets all elemental connections */
else {
nonodes = data->elementtypes[i] % 100;
for(j=0;jdualgraph[l][ind] == ind2) hit = TRUE;
- if(data->dualgraph[l][ind] == 0) break;
+ if(data->nodalgraph[l][ind] == ind2) hit = TRUE;
+ if(data->nodalgraph[l][ind] == 0) break;
}
if(!hit) {
if(l >= maxcon) {
- data->dualgraph[maxcon] = Ivector(1,noknots);
+ data->nodalgraph[maxcon] = Ivector(1,noknots);
for(m=1;m<=noknots;m++)
- data->dualgraph[maxcon][m] = 0;
+ data->nodalgraph[maxcon][m] = 0;
maxcon++;
}
- data->dualgraph[l][ind] = ind2;
+ data->nodalgraph[l][ind] = ind2;
totcon++;
}
}
@@ -8382,6 +9739,7 @@ int CreateDualGraph(struct FemType *data,int full,int info)
}
+ /* This adds the periodic connections */
if( data->periodicexist ) {
for(ind=1;ind<=noknots;ind++) {
ind2 = data->periodic[ind];
@@ -8389,53 +9747,55 @@ int CreateDualGraph(struct FemType *data,int full,int info)
hit = FALSE;
for(l=0;ldualgraph[l][ind] == ind2) hit = TRUE;
- if(data->dualgraph[l][ind] == 0) break;
+ if(data->nodalgraph[l][ind] == ind2) hit = TRUE;
+ if(data->nodalgraph[l][ind] == 0) break;
}
if(!hit) {
if(l >= maxcon) {
- data->dualgraph[maxcon] = Ivector(1,noknots);
+ data->nodalgraph[maxcon] = Ivector(1,noknots);
for(m=1;m<=noknots;m++)
- data->dualgraph[maxcon][m] = 0;
+ data->nodalgraph[maxcon][m] = 0;
maxcon++;
}
- data->dualgraph[l][ind] = ind2;
+ data->nodalgraph[l][ind] = ind2;
totcon++;
percon++;
}
}
}
- data->dualmaxconnections = maxcon;
- data->dualexists = TRUE;
+ data->nodalmaxconnections = maxcon;
+ data->nodalexists = TRUE;
- if(info) printf("There are at maximum %d connections in dual graph.\n",maxcon);
- if(info) printf("There are at all in all %d connections in dual graph.\n",totcon);
- if(info && percon) printf("There are %d periodic connections in dual graph.\n",percon);
+ if(info) {
+ printf("There are at maximum %d connections in nodal graph.\n",maxcon);
+ printf("There are at all in all %d connections in nodal graph.\n",totcon);
+ if(percon) printf("There are %d periodic connections in nodal graph.\n",percon);
+ }
return(0);
}
-int DestroyDualGraph(struct FemType *data,int info)
+int DestroyNodalGraph(struct FemType *data,int info)
{
int i,maxcon, noknots;
- if(!data->dualexists) {
- printf("You tried to destroy a non-existing dual graph\n");
+ if(!data->nodalexists) {
+ printf("You tried to destroy a non-existing nodal graph\n");
return(1);
}
- maxcon = data->dualmaxconnections;
+ maxcon = data->nodalmaxconnections;
noknots = data->noknots;
for(i=0;idualgraph[i],1,noknots);
+ free_Ivector(data->nodalgraph[i],1,noknots);
- data->dualmaxconnections = 0;
- data->dualexists = FALSE;
+ data->nodalmaxconnections = 0;
+ data->nodalexists = FALSE;
- if(info) printf("The dual graph was destroyed\n");
+ if(info) printf("The nodal graph was destroyed\n");
return(0);
}
@@ -8443,162 +9803,341 @@ int DestroyDualGraph(struct FemType *data,int info)
int CreateInverseTopology(struct FemType *data,int info)
{
- int i,j,l,m,noelements,noknots,elemtype,nonodes,ind,maxcon;
+ int i,j,k,l,m,noelements,noknots,elemtype,nonodes,ind;
int *neededby,minneeded,maxneeded;
+ int step,totcon;
+ int *rows,*cols;
+ struct CRSType *invtopo;
- printf("Creating an inverse topology of the finite element mesh\n");
-
- if(data->invtopoexists) {
- printf("The inverse topology already exists!\n");
- smallerror("The inverse topology not done");
+ invtopo = &data->invtopo;
+ if(invtopo->created) {
+ if(0) printf("The inverse topology already exists!\n");
+ return(0);
}
- maxcon = 0;
+ printf("Creating an inverse topology of the finite element mesh\n");
+
noelements = data->noelements;
noknots = data->noknots;
neededby = Ivector(1,noknots);
- for(i=1;i<=noknots;i++)
- neededby[i] = 0;
+ totcon = 0;
- for(i=1;i<=noelements;i++) {
- elemtype = data->elementtypes[i];
- nonodes = data->elementtypes[i] % 100;
+ for(step=1;step<=2;step++) {
- for(j=0;jtopology[i][j];
+ for(i=1;i<=noknots;i++)
+ neededby[i] = 0;
- neededby[ind] += 1;
- l = neededby[ind];
+ for(i=1;i<=noelements;i++) {
+ elemtype = data->elementtypes[i];
+ nonodes = data->elementtypes[i] % 100;
+
+ for(j=0;jtopology[i][j];
- if(l > maxcon) {
- maxcon++;
- data->invtopo[maxcon] = Ivector(1,noknots);
- for(m=1;m<=noknots;m++)
- data->invtopo[maxcon][m] = 0;
+ if( step == 1 ) {
+ neededby[ind] += 1;
+ totcon += 1;
+ }
+ else {
+ k = rows[ind-1] + neededby[ind];
+ cols[k] = i-1;
+ neededby[ind] += 1;
+ }
}
- data->invtopo[l][ind] = i;
}
- }
-
+
+ if( step == 1 ) {
+ rows = Ivector( 0, noknots );
+ rows[0] = 0;
+ for(i=1;i<=noknots;i++)
+ rows[i] = rows[i-1] + neededby[i];
+
+ cols = Ivector( 0, totcon-1 );
+ for(i=0;icols = cols;
+ invtopo->rows = rows;
+ invtopo->colsize = totcon;
+ invtopo->rowsize = noknots;
+ invtopo->created = TRUE;
+ }
+ }
+
minneeded = maxneeded = neededby[1];
for(i=1;i<=noknots;i++) {
minneeded = MIN( minneeded, neededby[i]);
maxneeded = MAX( maxneeded, neededby[i]);
}
+
free_Ivector(neededby,1,noknots);
- if(info) printf("There are from %d to %d connections in the inverse topology.\n",minneeded,maxneeded);
- data->invtopoexists = TRUE;
- data->maxinvtopo = maxcon;
+ if(info) {
+ printf("There are from %d to %d connections in the inverse topology.\n",minneeded,maxneeded);
+ printf("Each node is in average in %.3f elements\n",1.0*totcon/noknots);
+ }
return(0);
}
-int MeshTypeStatistics(struct FemType *data,int info)
+int CreateDualGraph(struct FemType *data,int unconnected,int info)
{
- int i,elemtype,maxelemtype,minelemtype,*elemtypes;
+ int totcon,dcon,noelements,noknots,elemtype,nonodes,i,j,k,l,i2,m,ind,hit,ci,ci2;
+ int dualmaxcon,invmaxcon,showgraph,freeelements,step,orphanelements;
+ int *elemconnect,*neededby;
+ int *dualrow,*dualcol,dualsize,dualmaxelem,allocated;
+ int *invrow,*invcol;
+ struct CRSType *dualgraph;
- maxelemtype = minelemtype = data->elementtypes[1];
+ printf("Creating a dual graph of the finite element mesh\n");
- for(i=1;i<=data->noelements;i++) {
- elemtype = data->elementtypes[i];
- maxelemtype = MAX( maxelemtype, elemtype );
- minelemtype = MIN( minelemtype, elemtype );
+ dualgraph = &data->dualgraph;
+ if(dualgraph->created) {
+ printf("The dual graph already exists!\n");
+ return(1);
}
- elemtypes = Ivector(minelemtype,maxelemtype);
- for(i=minelemtype;i<=maxelemtype;i++)
- elemtypes[i] = 0;
+ CreateInverseTopology(data,info);
- for(i=1;i<=data->noelements;i++) {
- elemtype = data->elementtypes[i];
- elemtypes[elemtype] += 1;
+ noelements = data->noelements;
+ noknots = data->noknots;
+ freeelements = noelements;
+ orphanelements = 0;
+
+ /* If a dual graph only for the unconnected nodes is requested do that.
+ Basically the connected nodes are omitted in the graph. */
+ if( unconnected ) {
+ printf("Removing connected nodes from the dual graph\n");
+ if( data->nodeconnectexist ) {
+ if(info) printf("Creating connected elements list from the connected nodes\n");
+ SetConnectedElements(data,info);
+ }
+ if( data->elemconnectexist ) {
+ elemconnect = data->elemconnect;
+ freeelements -= data->elemconnectexist;
+ }
+ else {
+ unconnected = FALSE;
+ }
+ if(info) printf("List of unconnected elements created\n");
}
- if(info) {
- printf("Number of different elementtypes\n");
- for(i=minelemtype;i<=maxelemtype;i++)
- if(elemtypes[i]) printf("\t%d\t%d\n",i,elemtypes[i]);
- }
+ showgraph = FALSE;
+ if(showgraph) printf("elemental graph ij pairs\n");
- free_Ivector(elemtypes,minelemtype,maxelemtype);
- return(0);
-}
+ data->dualexists = TRUE;
+ dualmaxcon = 0;
+ dualmaxelem = 0;
+
+ invrow = data->invtopo.rows;
+ invcol = data->invtopo.cols;
+ /* This marker is used to identify the connections already accounted for */
+ neededby = Ivector(1,freeelements);
+ for(i=1;i<=freeelements;i++)
+ neededby[i] = 0;
+
+ allocated = FALSE;
+ omstart:
+ totcon = 0;
-int SideAndBulkMappings(struct FemType *data,struct BoundaryType *bound,struct ElmergridType *eg,int info)
-{
- int i,j,l,currenttype;
-
+ for(i=1;i<=noelements;i++) {
+ if(showgraph) printf("%d :: ",i);
- if(eg->sidemappings) {
- for(l=0;lsidemappings;l++)
- if(info) printf("Setting boundary types between %d and %d to %d\n",
- eg->sidemap[3*l],eg->sidemap[3*l+1],eg->sidemap[3*l+2]);
+ dcon = 0;
+ elemtype = data->elementtypes[i];
+ nonodes = data->elementtypes[i] % 100;
- for(j=0;j < MAXBOUNDARIES;j++) {
- if(!bound[j].created) continue;
+ if( unconnected ) {
+ ci = elemconnect[i];
+ if( ci < 0 ) continue;
+ }
+ else {
+ ci = i;
+ }
+ if(allocated) dualrow[ci-1] = totcon;
+
+ if(0) printf("i=%d %d\n",i,elemtype);
+
+ for(step=1;step<=2;step++) {
+ for(j=0;jtopology[i][j];
- for(i=1; i <= bound[j].nosides; i++) {
- if(currenttype = bound[j].types[i]) {
- for(l=0;lsidemappings;l++) {
- if(currenttype >= eg->sidemap[3*l] && currenttype <= eg->sidemap[3*l+1]) {
- bound[j].types[i] = eg->sidemap[3*l+2];
- currenttype = -1;
- }
+ if(0) printf("ind=%d\n",ind);
+
+
+ for(k=invrow[ind-1];k dualmaxcon ) {
+ dualmaxcon = dcon;
+ dualmaxelem = i;
}
}
- }
- }
- if(info) printf("Renumbering boundary types finished\n");
- }
-
- if(eg->bulkmappings) {
- for(l=0;lbulkmappings;l++)
- if(info) printf("Setting material types between %d and %d to %d\n",
- eg->bulkmap[3*l],eg->bulkmap[3*l+1],eg->bulkmap[3*l+2]);
- for(j=1;j<=data->noelements;j++) {
- currenttype = data->material[j];
- for(l=0;lbulkmappings;l++) {
- if(currenttype >= eg->bulkmap[3*l] && currenttype <= eg->bulkmap[3*l+1]) {
- data->material[j] = eg->bulkmap[3*l+2];
- currenttype = -1;
+ else {
+ neededby[ci2] = FALSE;
+ }
}
}
}
- if(info) printf("Renumbering material indexes finished\n");
+ if( dcon == 0 && allocated ) {
+ orphanelements += 1;
+ }
+ }
+
+ if(allocated) {
+ dualrow[dualsize] = totcon;
+ }
+ else {
+ dualsize = freeelements;
+ dualrow = Ivector(0,dualsize);
+ for(i=1;i<=dualsize;i++)
+ dualrow[i] = 0;
+
+ dualcol = Ivector(0,totcon-1);
+ for(i=0;icols = dualcol;
+ dualgraph->rows = dualrow;
+ dualgraph->rowsize = dualsize;
+ dualgraph->colsize = totcon;
+ dualgraph->created = TRUE;
+
+ allocated = TRUE;
+
+ goto omstart;
+ }
+
+ if( orphanelements ) {
+ printf("There are %d elements in the dual mesh that are not connected!\n",orphanelements);
+ if(unconnected) printf("The orphan elements are likely caused by the hybrid partitioning\n");
+ }
+
+
+#if 0
+ j = totcon; k = 0;
+ for(i=1;i<=dualsize;i++){
+ l = dualrow[i]-dualrow[i-1];
+ if(l <= 0 ) printf("row(%d) = %d %d %d\n",i,l,dualrow[i],dualrow[i-1]);
+ j = MIN(j,l);
+ k = MAX(k,l);
+ }
+ printf("range dualrow: %d %d\n",j,k);
+
+ j = totcon; k = 0;
+ for(i=0;icreated) {
+ if(0) printf("You tried to destroy a non-existing sparse matrix\n");
+ return(1);
}
+
+ free_Ivector( sp->rows, 0, sp->rowsize );
+ free_Ivector( sp->cols, 0, sp->colsize-1);
+ sp->rowsize = 0;
+ sp->colsize = 0;
+ sp->created = FALSE;
+
return(0);
}
+int DestroyInverseTopology(struct FemType *data,int info)
+{
+ DestroyCRSMatrix( &data->invtopo );
+}
-int SideAndBulkBoundaries(struct FemType *data,struct BoundaryType *bound,struct ElmergridType *eg,int info)
+int DestroyDualGraph(struct FemType *data,int info)
{
- int l;
- int *boundnodes,noboundnodes;
- boundnodes = Ivector(1,data->noknots);
-
- if(eg->bulkbounds) {
- for(l=0;lbulkbounds;l++) {
- FindBulkBoundary(data,eg->bulkbound[3*l],eg->bulkbound[3*l+1],
- boundnodes,&noboundnodes,info);
- FindNewBoundaries(data,bound,boundnodes,eg->bulkbound[3*l+2],1,info);
- }
+ DestroyCRSMatrix( &data->dualgraph );
+}
+
+
+
+
+int MeshTypeStatistics(struct FemType *data,int info)
+{
+ int i,elemtype,maxelemtype,minelemtype;
+ int *elemtypes=NULL;
+
+ maxelemtype = minelemtype = data->elementtypes[1];
+
+ for(i=1;i<=data->noelements;i++) {
+ elemtype = data->elementtypes[i];
+ maxelemtype = MAX( maxelemtype, elemtype );
+ minelemtype = MIN( minelemtype, elemtype );
}
- if(eg->boundbounds) {
- for(l=0;lboundbounds;l++) {
- FindBoundaryBoundary(data,bound,eg->boundbound[3*l],eg->boundbound[3*l+1],
- boundnodes,&noboundnodes,info);
- FindNewBoundaries(data,bound,boundnodes,eg->boundbound[3*l+2],2,info);
- }
+
+ elemtypes = Ivector(minelemtype,maxelemtype);
+ for(i=minelemtype;i<=maxelemtype;i++)
+ elemtypes[i] = 0;
+
+ for(i=1;i<=data->noelements;i++) {
+ elemtype = data->elementtypes[i];
+ elemtypes[elemtype] += 1;
}
- free_Ivector(boundnodes,1,data->noknots);
- return 0; // added by ML 19.03.2008
+ if(info) {
+ printf("Number of different elementtypes\n");
+ for(i=minelemtype;i<=maxelemtype;i++)
+ if(elemtypes[i]) printf("\t%d\t%d\n",i,elemtypes[i]);
+ }
+
+ free_Ivector(elemtypes,minelemtype,maxelemtype);
+ return(0);
}
diff --git a/ElmerGUI/Application/plugins/egmesh.h b/ElmerGUI/Application/plugins/egmesh.h
index 16b6b8e549..d1e1b85ee0 100644
--- a/ElmerGUI/Application/plugins/egmesh.h
+++ b/ElmerGUI/Application/plugins/egmesh.h
@@ -1,100 +1,110 @@
-/* femknot.h */
-/* This module includes utilities that operate on single knots. It builds
- structures where the knots can be saved, it finds boundaries,
- copies knots from structures to others and destroys structures that
- become obsolete. The routines mostly operate on structures
- FemType and BoundaryType. */
-
-int GetElementDimension(int elementtype);
-int GetMaxElementType(struct FemType *data);
-int GetMinElementType(struct FemType *data);
-int GetMaxElementDimension(struct FemType *data);
-void GetElementInfo(int element,struct FemType *data,
- Real *globalcoord,int *ind,int *material);
-void GetElementSide(int element,int side,int normal,
- struct FemType *data,int *ind,int *sideelemtype);
-void NumberVariables(struct FemType *data,int variable);
-int CalculateIndexwidth(struct FemType *data,int indxis,int *indx);
-
-void InitializeKnots(struct FemType *data);
-void AllocateKnots(struct FemType *data);
-void CreateKnots(struct GridType *grid,struct CellType *cell,
- struct FemType *data,int noknots,int info);
-
-int CreateVariable(struct FemType *data,int variable,int unknowns,
- Real value,const char *variablename,int eorder);
-void DestroyKnots(struct FemType *data);
-int FindParentSide(struct FemType *data,struct BoundaryType *bound,
- int sideelem,int sideelemtype,int *sideind);
-int CreateBoundary(struct CellType *cell,struct FemType *data,
- struct BoundaryType *bound,int material1,int material2,
- int solidmat,int boundarytype,int info);
-int CreateAllBoundaries(struct CellType *cell,struct FemType *data,
- struct BoundaryType *bound,int info);
-int AllocateBoundary(struct BoundaryType *bound,int size);
-int DestroyBoundary(struct BoundaryType *bound);
-int CreatePoints(struct CellType *cell,struct FemType *data,
- struct BoundaryType *bound,
- int param1,int param2,int pointmode,int pointtype,int info);
-int SetDiscontinuousBoundary(struct FemType *data,struct BoundaryType *bound,
- int boundtype,int endnodes,int info);
-int SetConnectedBoundary(struct FemType *data,struct BoundaryType *bound,
- int bctype,int connecttype,int info);
-int FindCorners(struct GridType *grid,struct CellType *cell,
- struct FemType *data,int info);
-
-int ConstantToBilinear(struct FemType *data,int var1,int var2);
-int ElementsToTriangles(struct FemType *data,struct BoundaryType *bound,
- Real critangle,int info);
-int IncreaseElementOrder(struct FemType *data,int info);
-int PolarCoordinates(struct FemType *data,Real rad,int info);
-int CylinderCoordinates(struct FemType *data,int info);
-int UniteMeshes(struct FemType *data1,struct FemType *data2,
- struct BoundaryType *bound1,struct BoundaryType *bound2,
- int info);
-int CloneMeshes(struct FemType *data,struct BoundaryType *bound,
- int *ncopies,Real *meshsize,int diffmats,int info);
-int MirrorMeshes(struct FemType *data,struct BoundaryType *bound,
- int *symmaxis,int diffmats,Real *meshsize,int symmbound,int info);
-void ReorderElements(struct FemType *data,struct BoundaryType *bound,
- int manual,Real corder[],int info);
-int RemoveUnusedNodes(struct FemType *data,int info);
-void RenumberBoundaryTypes(struct FemType *data,struct BoundaryType *bound,
- int renumber, int bcoffset, int info);
-void RenumberMaterialTypes(struct FemType *data,struct BoundaryType *bound,int info);
-void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
- struct GridType *grid,
- struct FemType *data,struct BoundaryType *bound,
- int info);
-void ReduceElementOrder(struct FemType *data,int matmin,int matmax);
-void IsoparametricElements(struct FemType *data,struct BoundaryType *bound,
- int bcstoo,int info);
-void MergeElements(struct FemType *data,struct BoundaryType *bound,
- int manual,Real corder[],Real eps,int mergebounds,int info);
-void MergeBoundaries(struct FemType *data,struct BoundaryType *bound,int *doubles,int info);
-void SeparateCartesianBoundaries(struct FemType *data,struct BoundaryType *bound,int info);
-void ElementsToBoundaryConditions(struct FemType *data,
- struct BoundaryType *bound,int retainorphans,int info);
-int FindPeriodicNodes(struct FemType *data,int periodicdim[],int info);
-int FindNewBoundaries(struct FemType *data,struct BoundaryType *bound,
- int *boundnodes,int suggesttype,int dimred,int info);
-int FindBulkBoundary(struct FemType *data,int mat1,int mat2,
- int *boundnodes,int *noboundnodes,int info);
-int FindBoundaryBoundary(struct FemType *data,struct BoundaryType *bound,int mat1,int mat2,
- int *boundnodes,int *noboundnodes,int info);
-int CreateBoundaryLayer(struct FemType *data,struct BoundaryType *bound,
- int nolayers, int *layerbounds, int *layernumber,
- Real *layerratios, Real *layerthickness, int *layerparents,
- int maxfilters, Real layereps, int info);
-int CreateBoundaryLayerDivide(struct FemType *data,struct BoundaryType *bound,
- int nolayers, int *layerbounds, int *layernumber,
- Real *layerratios, Real *layerthickness, int *layerparents,int info);
-int RotateTranslateScale(struct FemType *data,struct ElmergridType *eg,int info);
-int RemoveLowerDimensionalBoundaries(struct FemType *data,struct BoundaryType *bound,int info);
-
-int CreateDualGraph(struct FemType *data,int full,int info);
-int DestroyDualGraph(struct FemType *data,int info);
-int CreateInverseTopology(struct FemType *data,int info);
-int MeshTypeStatistics(struct FemType *data,int info);
-int SideAndBulkMappings(struct FemType *data,struct BoundaryType *bound,struct ElmergridType *eg,int info);
-int SideAndBulkBoundaries(struct FemType *data,struct BoundaryType *bound,struct ElmergridType *eg,int info);
+/* femknot.h -> egmesh.h */
+/* This module includes utilities that operate on single knots. It builds
+ structures where the knots can be saved, it finds boundaries,
+ copies knots from structures to others and destroys structures that
+ become obsolete. The routines mostly operate on structures
+ FemType and BoundaryType. */
+
+int GetElementDimension(int elementtype);
+int GetMaxElementType(struct FemType *data);
+int GetMinElementType(struct FemType *data);
+int GetMaxElementDimension(struct FemType *data);
+int GetCoordinateDimension(struct FemType *data,int info);
+void GetElementInfo(int element,struct FemType *data,
+ Real *globalcoord,int *ind,int *material);
+void GetBoundaryElement(int sideind,struct BoundaryType *bound,struct FemType *data,int *ind,int *sideelemtype);
+void GetElementSide(int element,int side,int normal,
+ struct FemType *data,int *ind,int *sideelemtype);
+int GetElementFaces(int elemtype);
+void NumberVariables(struct FemType *data,int variable);
+int CalculateIndexwidth(struct FemType *data,int indxis,int *indx);
+void InitializeKnots(struct FemType *data);
+void AllocateKnots(struct FemType *data);
+void CreateKnots(struct GridType *grid,struct CellType *cell,
+ struct FemType *data,int noknots,int info);
+int CreateVariable(struct FemType *data,int variable,int unknowns,
+ Real value,const char *variablename,int eorder);
+void DestroyKnots(struct FemType *data);
+int CreateBoundary(struct CellType *cell,struct FemType *data,
+ struct BoundaryType *bound,int material1,int material2,
+ int solidmat,int boundarytype,int info);
+int AllocateBoundary(struct BoundaryType *bound,int size);
+int DestroyBoundary(struct BoundaryType *bound);
+int CreateBoundaries(struct CellType *cell,struct FemType *data,
+ struct BoundaryType *boundaries,int info);
+int CreatePoints(struct CellType *cell,struct FemType *data,
+ struct BoundaryType *bound,
+ int param1,int param2,int pointmode,int pointtype,int info);
+int CreateNewNodes(struct FemType *data,int *order,int material,int newknots);
+int SetDiscontinuousBoundary(struct FemType *data,struct BoundaryType *bound,
+ int boundtype,int endnodes,int info);
+int SetConnectedNodes(struct FemType *data,struct BoundaryType *bound,
+ int bctype,int connecttype,int info);
+int SetConnectedElements(struct FemType *data,int info);
+int FindCorners(struct GridType *grid,struct CellType *cell,
+ struct FemType *data,int info);
+
+int ConstantToBilinear(struct FemType *data,int var1,int var2);
+int ElementsToTriangles(struct FemType *data,struct BoundaryType *bound,
+ Real critangle,int info);
+int IncreaseElementOrder(struct FemType *data,int info);
+int PolarCoordinates(struct FemType *data,Real rad,int info);
+int CylinderCoordinates(struct FemType *data,int info);
+int UniteMeshes(struct FemType *data1,struct FemType *data2,
+ struct BoundaryType *bound1,struct BoundaryType *bound2,
+ int nooverlap, int info);
+int CloneMeshes(struct FemType *data,struct BoundaryType *bound,
+ int *ncopies,Real *meshsize,int diffmats,int info);
+int MirrorMeshes(struct FemType *data,struct BoundaryType *bound,
+ int *symmaxis,int diffmats,Real *meshsize,int symmbound,int info);
+void ReorderElements(struct FemType *data,struct BoundaryType *bound,
+ int manual,Real corder[],int info);
+int RemoveUnusedNodes(struct FemType *data,int info);
+void RenumberBoundaryTypes(struct FemType *data,struct BoundaryType *bound,
+ int renumber, int bcoffset, int info);
+void RenumberMaterialTypes(struct FemType *data,struct BoundaryType *bound,int info);
+void CreateKnotsExtruded(struct FemType *dataxy,struct BoundaryType *boundxy,
+ struct GridType *grid,
+ struct FemType *data,struct BoundaryType *bound,
+ int info);
+void CylindricalCoordinateCurve(struct FemType *data,
+ Real zet,Real rad,Real angle);
+void ReduceElementOrder(struct FemType *data,int matmin,int matmax);
+void IsoparametricElements(struct FemType *data,struct BoundaryType *bound,
+ int bcstoo,int info);
+void MergeElements(struct FemType *data,struct BoundaryType *bound,
+ int manual,Real corder[],Real eps,int mergebounds,int info);
+void MergeBoundaries(struct FemType *data,struct BoundaryType *bound,int *doubles,int info);
+void SeparateCartesianBoundaries(struct FemType *data,struct BoundaryType *bound,int info);
+void ElementsToBoundaryConditions(struct FemType *data,
+ struct BoundaryType *bound,int retainorphans, int info);
+int SideAndBulkMappings(struct FemType *data,struct BoundaryType *bound,struct ElmergridType *eg,int info);
+int SideAndBulkBoundaries(struct FemType *data,struct BoundaryType *bound,struct ElmergridType *eg,int info);
+void NodesToBoundaryChain(struct FemType *data,struct BoundaryType *bound,
+ int *bcinds,int *bctags,int nbc,int bccount,
+ int info);
+int FindPeriodicNodes(struct FemType *data,int periodicdim[],int info);
+int FindPeriodicParents(struct FemType *data,struct BoundaryType *bound,int info);
+int FindNewBoundaries(struct FemType *data,struct BoundaryType *bound,
+ int *boundnodes,int suggesttype,int dimred,int info);
+int FindBulkBoundary(struct FemType *data,int mat1,int mat2,
+ int *boundnodes,int *noboundnodes,int info);
+int FindBoundaryBoundary(struct FemType *data,struct BoundaryType *bound,int mat1,int mat2,
+ int *boundnodes,int *noboundnodes,int info);
+int CreateBoundaryLayer(struct FemType *data,struct BoundaryType *bound,
+ int nolayers, int *layerbounds, int *layernumber,
+ Real *layerratios, Real *layerthickness, int *layerparents,
+ int maxfilters, Real layereps, int info);
+int CreateBoundaryLayerDivide(struct FemType *data,struct BoundaryType *bound,
+ int nolayers, int *layerbounds, int *layernumber,
+ Real *layerratios, Real *layerthickness, int *layerparents,int info);
+int RotateTranslateScale(struct FemType *data,struct ElmergridType *eg,int info);
+int RemoveLowerDimensionalBoundaries(struct FemType *data,struct BoundaryType *bound,int info);
+int RemoveInternalBoundaries(struct FemType *data,struct BoundaryType *bound,int info);
+int CreateNodalGraph(struct FemType *data,int full,int info);
+int DestroyNodalGraph(struct FemType *data,int info);
+int CreateDualGraph(struct FemType *data,int unconnected,int info);
+int DestroyDualGraph(struct FemType *data,int info);
+int CreateInverseTopology(struct FemType *data,int info);
+int DestroyInverseTopology(struct FemType *data,int info);
+int MeshTypeStatistics(struct FemType *data,int info);
diff --git a/ElmerGUI/Application/plugins/egnative.cpp b/ElmerGUI/Application/plugins/egnative.cpp
index e27573b3cf..de340b0ae4 100644
--- a/ElmerGUI/Application/plugins/egnative.cpp
+++ b/ElmerGUI/Application/plugins/egnative.cpp
@@ -1,4 +1,4 @@
-/*
+/*
ElmerGrid - A simple mesh generation and manipulation utility
Copyright (C) 1995- , CSC - IT Center for Science Ltd.
@@ -23,48 +23,309 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+/* -------------------------------: egnative.c :----------------------------
+ This module includes routines for I/O of native formats of Elmer.
+*/
- /* -----------------------: egnative.c :----------------------
-
- These subroutines are used to create the native mesh of ElmerGrid.
- */
-
-#include
#include
-#include
+#include
#include
+#include
#include
-#include
-#include
+#include
+
+#if HAVE_UNISTD_H
+#include
+#endif
+
#include
+#include
+#include
+#include
+#include
+#include
#include "egutils.h"
#include "egdef.h"
#include "egtypes.h"
-#include "egnative.h"
#include "egmesh.h"
+/* #include "egparallel.h" */
+#include "egnative.h"
+/*#include "../config.h"*/
+
+#define GETLINE ioptr=fgets(line,MAXLINESIZE,in)
+static char *ioptr;
+
+
+#define DEBUG 0
+
+
+int matcactive=FALSE, iodebug=FALSE;
+
+#define MAXINMETHODS 21
+const char *InMethods[] = {
+ /*0*/ "EG",
+ /*1*/ "ELMERGRID",
+ /*2*/ "ELMERSOLVER",
+ /*3*/ "ELMERPOST",
+ /*4*/ "ANSYS",
+ /*5*/ "IDEAS",
+ /*6*/ "ABAQUS",
+ /*7*/ "FIDAP",
+ /*8*/ "UNV",
+ /*9*/ "COMSOL",
+ /*10*/ "FIELDVIEW",
+ /*11*/ "TRIANGLE",
+ /*12*/ "MEDIT",
+ /*13*/ "GID",
+ /*14*/ "GMSH",
+ /*15*/ "PARTITIONED",
+ /*16*/ "FVCOM",
+ /*17*/ "NASTRAN",
+ /*18*/ "CGSIM",
+ /*19*/ "GEO",
+ /*20*/ "FLUX2D",
+ /*21*/ "FLUX3D",
+};
+
+
+#define MAXOUTMETHODS 5
+const char *OutMethods[] = {
+ /*0*/ "EG",
+ /*1*/ "ELMERGRID",
+ /*2*/ "ELMERSOLVER",
+ /*3*/ "ELMERPOST",
+ /*4*/ "GMSH",
+ /*5*/ "VTU",
+};
+
+
+void Instructions()
+{
+ printf("****************** Elmergrid ************************\n");
+ printf("This program can create simple 2D structured meshes consisting of\n");
+ printf("linear, quadratic or cubic rectangles or triangles. The meshes may\n");
+ printf("also be extruded and revolved to create 3D forms. In addition many\n");
+ printf("mesh formats may be imported into Elmer software. Some options have\n");
+ printf("not been properly tested. Contact the author if you face problems.\n\n");
+
+ printf("The program has two operation modes\n");
+ printf("A) Command file mode which has the command file as the only argument\n");
+ printf(" 'ElmerGrid commandfile.eg'\n\n");
+
+ printf("B) Inline mode which expects at least three input parameters\n");
+ printf(" 'ElmerGrid 1 3 test'\n\n");
+ printf("The first parameter defines the input file format:\n");
+ printf("1) .grd : ElmerGrid file format\n");
+ printf("2) .mesh.* : Elmer input format\n");
+ printf("3) .ep : Elmer output format\n");
+ printf("4) .ansys : Ansys input format\n");
+ printf("5) .inp : Abaqus input format by Ideas\n");
+ printf("6) .fil : Abaqus output format\n");
+ printf("7) .FDNEUT : Gambit (Fidap) neutral file\n");
+ printf("8) .unv : Universal mesh file format\n");
+ printf("9) .mphtxt : Comsol Multiphysics mesh format\n");
+ printf("10) .dat : Fieldview format\n");
+ printf("11) .node,.ele: Triangle 2D mesh format\n");
+ printf("12) .mesh : Medit mesh format\n");
+ printf("13) .msh : GID mesh format\n");
+ printf("14) .msh : Gmsh mesh format\n");
+ printf("15) .ep.i : Partitioned ElmerPost format\n");
+ printf("16) .2dm : 2D triangular FVCOM format\n");
+#if 0
+ printf("17) .msh : Nastran format\n");
+ printf("18) .msh : CGsim format\n");
+ printf("19) .geo : Geo format\n");
+ printf("20) .tra : Cedrat Flux 2D format\n");
+ printf("21) .pf3 : Cedrat Flux 3D format\n");
+#endif
+
+ printf("\nThe second parameter defines the output file format:\n");
+ printf("1) .grd : ElmerGrid file format\n");
+ printf("2) .mesh.* : ElmerSolver format (also partitioned .part format)\n");
+ printf("3) .ep : ElmerPost format\n");
+ printf("4) .msh : Gmsh mesh format\n");
+ printf("5) .vtu : VTK ascii XML format\n");
+#if 0
+ printf("5) .inp : Abaqus input format\n");
+ printf("7) .fidap : Fidap format\n");
+ printf("18) .ep : Fastcap input format.\n");
+#endif
+
+ printf("\nThe third parameter is the name of the input file.\n");
+ printf("If the file does not exist, an example with the same name is created.\n");
+ printf("The default output file name is the same with a different suffix.\n\n");
+
+ printf("There are several additional in-line parameters that are\n");
+ printf("taken into account only when applicable to the given format.\n");
+
+ printf("-out str : name of the output file\n");
+ printf("-in str : name of a secondary input file\n");
+ printf("-decimals : number of decimals in the saved mesh (eg. 8)\n");
+ printf("-relh real : give relative mesh density parameter for ElmerGrid meshing\n");
+ printf("-triangles : rectangles will be divided to triangles\n");
+ printf("-merge real : merges nodes that are close to each other\n");
+ printf("-order real[3] : reorder elements and nodes using c1*x+c2*y+c3*z\n");
+ printf("-centralize : set the center of the mesh to origin\n");
+ printf("-scale real[3] : scale the coordinates with vector real[3]\n");
+ printf("-translate real[3] : translate the nodes with vector real[3]\n");
+ printf("-rotate real[3] : rotate around the main axis with angles real[3]\n");
+ printf("-clone int[3] : make ideantilcal copies of the mesh\n");
+ printf("-clonesize real[3] : the size of the mesh to be cloned if larger to the original\n");
+ printf("-mirror int[3] : copy the mesh around the origin in coordinate directions\n");
+ printf("-cloneinds : when performing cloning should cloned entities be given new indexes\n");
+ printf("-unite : the meshes will be united\n");
+ printf("-unitenooverlap : the meshes will be united without overlap in entity numbering\n");
+ printf("-polar real : map 2D mesh to a cylindrical shell with given radius\n");
+ printf("-cylinder : map 2D/3D cylindrical mesh to a cartesian mesh\n");
+ printf("-reduce int[2] : reduce element order at material interval [int1 int2]\n");
+ printf("-increase : increase element order from linear to quadratic\n");
+ printf("-bcoffset int : add an offset to the boundary conditions\n");
+ printf("-discont int : make the boundary to have secondary nodes\n");
+ printf("-connect int : make the boundary to have internal connection among its elements\n");
+ printf("-removeintbcs : remove internal boundaries if they are not needed\n");
+ printf("-removelowdim : remove boundaries that are two ranks lower than highest dim\n");
+ printf("-removeunused : remove nodes that are not used in any element\n");
+ printf("-bulkorder : renumber materials types from 1 so that every number is used\n");
+ printf("-boundorder : renumber boundary types from 1 so that every number is used\n");
+ printf("-autoclean : this performs the united action of the four above\n");
+ printf("-bulkbound int[3] : set the intersection of materials [int1 int2] to be boundary int3\n");
+ printf("-boundbound int[3] : set the intersection of boundaries [int1 int2] to be boundary int3\n");
+ printf("-bulktype int[3] : set material types in interval [int1 int2] to type int3\n");
+ printf("-boundtype int[3] : set sidetypes in interval [int1 int2] to type int3\n");
+ printf("-layer int[2] real[2]: make a boundary layer for given boundary\n");
+ printf("-layermove int : apply Jacobi filter int times to move the layered mesh\n");
+ printf("-divlayer int[2] real[2]: make a boundary layer for given boundary\n");
+ printf("-3d / -2d / -1d : mesh is 3, 2 or 1-dimensional (applies to examples)\n");
+ printf("-isoparam : ensure that higher order elements are convex\n");
+ printf("-nonames : disable use of mesh.names even if it would be supported by the format\n");
+ printf("-nosave : disable saving part altogether\n");
+ printf("-nooverwrite : if mesh already exists don't overwrite it\n");
+ printf("-vtuone : start real node indexes in vtu file from one\n");
+ printf("-timer : show timer information\n");
+ printf("-infofile str : file for saving the timer and size information\n");
+
+ printf("\nKeywords are related to mesh partitioning for parallel ElmerSolver runs:\n");
+ printf("-partition int[3] : the mesh will be partitioned in cartesian main directions\n");
+ printf("-partorder real[3] : in the 'partition' method set the direction of the ordering\n");
+ printf("-parttol real : in the 'partition' method set the tolerance for ordering\n");
+ printf("-partcell int[3] : the mesh will be partitioned in cells of fixed sizes\n");
+ printf("-partcyl int[3] : the mesh will be partitioned in cylindrical main directions\n");
+#if USE_METIS
+ printf("-metiskway int : mesh will be partitioned with Metis using graph Kway routine\n");
+ printf("-metisrec int : mesh will be partitioned with Metis using graph Recursive routine\n");
+ printf("-metiscontig : enforce that the metis partitions are contiguous\n");
+ printf("-metisseed int : random number generator seed for Metis algorithms\n");
+#endif
+ printf("-partdual : use the dual graph in partition method (when available)\n");
+ printf("-halo : create halo for the partitioning for DG\n");
+ printf("-halobc : create halo for the partitioning at boundaries only\n");
+ printf("-haloz / -halor : create halo for the the special z- or r-partitioning\n");
+ printf("-halogreedy : create halo being greedy over the partition interfaces\n");
+ printf("-indirect : create indirect connections (102 elements) in the partitioning\n");
+ printf("-periodic int[3] : periodic coordinate directions for parallel & conforming meshes\n");
+ printf("-partoptim : apply aggressive optimization to node sharing\n");
+ printf("-partnobcoptim : do not apply optimization to bc ownership sharing\n");
+ printf("-partbw : minimize the bandwidth of partition-partion couplings\n");
+ printf("-parthypre : number the nodes continuously partitionwise\n");
+ printf("-partzbc : partition connected BCs separately to partitions in Z-direction\n");
+ printf("-partrbc : partition connected BCs separately to partitions in R-direction\n");
+#if USE_METIS
+ printf("-metisbc : partition connected BCs separately to partitions by Metis\n");
+#endif
+ printf("-partlayers int : extend boundary partitioning by element layers\n");
+
+ printf("\nKeywords are related to (nearly obsolete) ElmerPost format:\n");
+ printf("-partjoin int : number of ElmerPost partitions in the data to be joined\n");
+ printf("-saveinterval int[3] : the first, last and step for fusing parallel data\n");
+ printf("-nobound : disable saving of boundary elements in ElmerPost format\n");
+
+ if(0) printf("-names : conserve name information where applicable\n");
+}
+
+
+void Goodbye()
+{
+ printf("\nThank you for using Elmergrid!\n");
+ printf("Send bug reports and feature wishes to elmeradm@csc.fi\n");
+ exit(0);
+}
-int matcactive;
-#if HAVE_MATC
+
+#if USE_MATC
char *mtc_domath(const char *);
void mtc_init(FILE * input, FILE * output, FILE * error);
#endif
+static int Getline(char *line1,FILE *io)
+{
+ int i,isend;
+ char line0[MAXLINESIZE],*charend,*matcpntr,*matcpntr0;
+
+ for(i=0;ilayered = FALSE;
grid->layeredbc = TRUE;
+ grid->layerbcoffset = 0;
grid->triangles = FALSE;
grid->triangleangle = 0.0;
grid->partitions = FALSE;
grid->wantedelems = 0;
+ grid->wantedelems3d = 0;
+ grid->wantednodes3d = 0;
grid->limitdx = 0.0;
grid->limitdxverify = FALSE;
@@ -76,7 +337,7 @@ void InitGrid(struct GridType *grid)
grid->minxelems = grid->minyelems = 1;
grid->minzelems = 2;
grid->firstmaterial = 1;
- grid->lastmaterial = MAXMATERIALS;
+ grid->lastmaterial = MAXBODYID;
grid->autoratio = 1;
grid->xyratio = 1.0;
grid->xzratio = 1.0;
@@ -123,10 +384,14 @@ void InitGrid(struct GridType *grid)
grid->zdens[i] = 1.0;
grid->z[i] = 0.;
grid->zfirstmaterial[i] = 1;
- grid->zlastmaterial[i] = MAXMATERIALS;
+ grid->zlastmaterial[i] = MAXBODYID;
grid->zmaterial[i] = 0;
}
+ grid->zmaterialmapexists = FALSE;
+ grid->zhelicityexists = FALSE;
+ grid->zhelicity = 0.0;
+
/* Initializes the numbering of the cells. */
for(j=0;j<=MAXCELLS+1;j++)
for(i=0;i<=MAXCELLS+1;i++)
@@ -967,12 +1232,12 @@ void SetCellData(struct GridType *grid,struct CellType *cell,int info)
cell[cnew].neighbour[7] = grid->numbered[j+1][i-1];
}
- if(0) printf("%d cells were created.\n",grid->nocells);
+ if(info) printf("%d cells were created.\n",grid->nocells);
}
-int SetCellKnots(struct GridType *grid, struct CellType *cell,int info)
+static int SetCellKnots(struct GridType *grid, struct CellType *cell,int info)
/* Uses given mesh to number the knots present in the cells.
The knots are numbered independently of the cells from left
to right and up to down. Only the numbers of four knots at the
@@ -989,10 +1254,10 @@ int SetCellKnots(struct GridType *grid, struct CellType *cell,int info)
{
int i,j,level,center;
int degree,centernodes,sidenodes,nonodes;
- int cnew = 0,cup = 0,cleft = 0,cleftup = 0;
+ int cnew=0,cup=0,cleft=0,cleftup=0;
int elemno,knotno;
int maxwidth,width,numbering;
- int xcells,ycells,*yelems,*xelems;
+ int xcells,ycells,*yelems=NULL,*xelems=NULL;
numbering = grid->numbering;
nonodes = grid->nonodes;
@@ -1179,12 +1444,12 @@ int SetCellKnots(struct GridType *grid, struct CellType *cell,int info)
grid->noelements = elemno;
if(info) {
- printf("There are %d knots in %d %d-node elements.\n",knotno,elemno,nonodes);
+ printf("Numbered %d knots in %d %d-node elements.\n",knotno,elemno,nonodes);
if(numbering == NUMBER_XY)
- if(0) printf("Numbering order was and max levelwidth %d.\n",
+ printf("Numbering order was and max levelwidth %d.\n",
maxwidth);
else if(numbering == NUMBER_YX)
- if(0) printf("Numbering order was and max levelwidth %d.\n",
+ printf("Numbering order was and max levelwidth %d.\n",
maxwidth);
}
@@ -1193,7 +1458,7 @@ int SetCellKnots(struct GridType *grid, struct CellType *cell,int info)
-int SetCellKnots1D(struct GridType *grid, struct CellType *cell,int info)
+static int SetCellKnots1D(struct GridType *grid, struct CellType *cell,int info)
{
int i;
int degree,nonodes;
@@ -1259,6 +1524,26 @@ int SetCellKnots1D(struct GridType *grid, struct CellType *cell,int info)
+void CreateCells(struct GridType *grid,struct CellType **cell,int info)
+{
+ (*cell) = (struct CellType*)
+ malloc((size_t) (grid->nocells+1)*sizeof(struct CellType));
+
+ SetCellData(grid,*cell,info);
+
+ if(grid->dimension == 1)
+ SetCellKnots1D(grid,*cell,info);
+ else
+ SetCellKnots(grid,*cell,info);
+}
+
+
+void DestroyCells(struct CellType **cell)
+{
+ free(cell);
+}
+
+
int GetKnotIndex(struct CellType *cell,int i,int j)
/* Given the cell and knot indices gives the corresponding
@@ -1266,7 +1551,7 @@ int GetKnotIndex(struct CellType *cell,int i,int j)
range [0..n] and [0..m]. Requires only the structure CellType.
*/
{
- int ind,aid,maxj = 0;
+ int ind=0,aid=0,maxj=0;
if(cell->numbering == NUMBER_1D) {
ind = cell->left1st;
@@ -1285,6 +1570,10 @@ int GetKnotIndex(struct CellType *cell,int i,int j)
aid = j; j = i; i = aid;
maxj = cell->xelem;
}
+ else {
+ maxj = 0;
+ bigerror("GetKnotIndex: Unknown numbering scheme!");
+ }
if(j == 0)
ind = cell->left1st;
@@ -1360,7 +1649,7 @@ int GetElementIndices(struct CellType *cell,int i,int j,int *ind)
requires only the structure CellType.
*/
{
- int nonodes,numbering,elemind = 0;
+ int nonodes,numbering,elemind=0;
nonodes = cell->nonodes;
numbering = cell->numbering;
@@ -1420,7 +1709,7 @@ int GetElementIndices(struct CellType *cell,int i,int j,int *ind)
printf("GetElementIndices: not implemented for %d nodes.\n",nonodes);
}
- else if(numbering == NUMBER_YX) {
+ else if(numbering == NUMBER_YX) {
elemind = cell->elem1st+(j-1) + (i-1)*cell->elemwidth;
if(nonodes == 4) return(elemind);
@@ -1495,7 +1784,7 @@ int GetElementIndex(struct CellType *cell,int i,int j)
requires only the structure CellType.
*/
{
- int elemind = 0;
+ int elemind=0;
if(cell->numbering == NUMBER_XY)
elemind = cell->elem1st+(i-1) + (j-1)*cell->elemwidth;
@@ -1516,7 +1805,7 @@ int GetElementCoordinates(struct CellType *cell,int i,int j,
rectangular.
*/
{
- int k,nonodes,numbering,elemind = 0;
+ int k,nonodes,numbering,elemind=0;
Real xrat,yrat;
k = nonodes = cell->nonodes;
@@ -1927,53 +2216,12 @@ void SetElementDivisionCylinder(struct GridType *grid,int info)
-static int Getline(char *line1,FILE *io)
-{
- int i,isend;
- char line0[MAXLINESIZE],*charend;
-
- for(i=0;idimension = 2;
- if(strstr(params,"CARTESIAN 1D")) {
+ if(strstr(line,"CARTES") && strstr(line,"1D")) {
grid[k]->coordsystem = COORD_CART1;
grid[k]->dimension = 1;
}
- else if(strstr(params,"CARTESIAN 2D"))
+ else if(strstr(line,"CARTES") && strstr(line,"2D"))
grid[k]->coordsystem = COORD_CART2;
- else if(strstr(params,"AXISYMMETRIC"))
+ else if(strstr(line,"AXIS") && strstr(line,"2D"))
grid[k]->coordsystem = COORD_AXIS;
- else if(strstr(params,"POLAR"))
+ else if(strstr(line,"POLAR") && strstr(line,"2D"))
grid[k]->coordsystem = COORD_POLAR;
- else if(strstr(params,"CARTESIAN 3D")) {
+ else if(strstr(line,"CARTES") && strstr(line,"3D")) {
grid[k]->coordsystem = COORD_CART3;
grid[k]->dimension = 3;
}
- else printf("Unknown coordinate system: %s\n",params);
- if(0) printf("Defining the coordinate system (%d-DIM).\n",grid[k]->dimension);
- }
-
- else if(strstr(command,"SUBCELL DIVISIONS")) {
+ else if(strstr(line,"CYLINDRICAL")) {
+ grid[k]->coordsystem = COORD_CYL;
+ grid[k]->dimension = 3;
+ }
+ else printf("Unknown coordinate system: %s\n",line);
+ printf("Defining the coordinate system (%d-DIM).\n",grid[k]->dimension);
+
+ Getline(line,in);
+
if(grid[k]->dimension == 1) {
- sscanf(params,"%d",&(*grid)[k].xcells);
+ sscanf(line,"%d",&(*grid)[k].xcells);
grid[k]->ycells = 1;
}
- else if(grid[k]->dimension == 2)
- sscanf(params,"%d %d",&(*grid)[k].xcells,&(*grid)[k].ycells);
- else if(grid[k]->dimension == 3)
- sscanf(params,"%d %d %d",&(*grid)[k].xcells,&(*grid)[k].ycells,&(*grid)[k].zcells);
- if(grid[k]->xcells >= MAXCELLS || grid[k]->ycells >= MAXCELLS || grid[k]->zcells >= MAXCELLS) {
- printf("LoadElmergrid: Too many subcells [%d %d %d] vs. %d:\n",
+ if(grid[k]->dimension == 2)
+ sscanf(line,"%d %d",&(*grid)[k].xcells,&(*grid)[k].ycells);
+ if(grid[k]->dimension == 3)
+ sscanf(line,"%d %d %d",&(*grid)[k].xcells,&(*grid)[k].ycells,&(*grid)[k].zcells);
+ if(grid[k]->xcells >= MAXCELLS || grid[k]->ycells >= MAXCELLS ||
+ grid[k]->zcells >= MAXCELLS) {
+ printf("LoadGrid: Too many subcells [%d %d %d] vs. %d:\n",
grid[k]->xcells,grid[k]->ycells,grid[k]->zcells,MAXCELLS);
}
+
+ if(grid[k]->dimension == 1) {
+ printf("Loading [%d] subcell intervals in 1D\n",
+ grid[k]->xcells);
+ }
+ else if(grid[k]->dimension == 2) {
+ printf("Loading [%d %d] subcell intervals in 2D\n",
+ grid[k]->xcells,grid[k]->ycells);
+ } else {
+ printf("Loading [%d %d %d] subcell intervals in 3D\n",
+ grid[k]->xcells,grid[k]->ycells,grid[k]->zcells);
+ }
- /* Initialize the default structure with ones */
- for(j=grid[k]->ycells;j>=1;j--)
+
+ for(j=1;j<=grid[k]->dimension;j++) {
+ Getline(line,in);
+ cp=line;
+
+ if(j==1) for(i=0;i<=grid[k]->xcells;i++) grid[k]->x[i] = next_real(&cp);
+ if(j==2) for(i=0;i<=grid[k]->ycells;i++) grid[k]->y[i] = next_real(&cp);
+ if(j==3) for(i=0;i<=grid[k]->zcells;i++) grid[k]->z[i] = next_real(&cp);
+ }
+
+ printf("Loading material structure\n");
+
+ for(j=grid[k]->ycells;j>=1;j--) {
+
+ Getline(line,in);
+ cp=line;
+
for(i=1;i<=grid[k]->xcells;i++)
- grid[k]->structure[j][i] = 1;
- }
-
- else if(strstr(command,"MINIMUM ELEMENT DIVISION")) {
- if(0) printf("Loading minimum number of elements\n");
- if((*grid)[k].dimension == 1)
- sscanf(params,"%d",&(*grid)[k].minxelems);
- if((*grid)[k].dimension == 2)
- sscanf(params,"%d %d",&(*grid)[k].minxelems,&(*grid)[k].minyelems);
- if((*grid)[k].dimension == 3)
- sscanf(params,"%d %d %d",&(*grid)[k].minxelems,&(*grid)[k].minyelems,&(*grid)[k].minzelems);
- }
-
- else if(strstr(command,"SUBCELL LIMITS 1")) {
- if(0) printf("Loading [%d] subcell limits in X-direction\n",grid[k]->xcells+1);
- cp = params;
- for(i=0;i<=grid[k]->xcells;i++) grid[k]->x[i] = next_real(&cp);
- }
- else if(strstr(command,"SUBCELL LIMITS 2")) {
- if(0) printf("Loading [%d] subcell limits in Y-direction\n",grid[k]->ycells+1);
- cp = params;
- for(i=0;i<=grid[k]->ycells;i++) grid[k]->y[i] = next_real(&cp);
- }
- else if(strstr(command,"SUBCELL LIMITS 3")) {
- if(0) printf("Loading [%d] subcell limits in Z-direction\n",grid[k]->zcells+1);
- cp = params;
- for(i=0;i<=grid[k]->zcells;i++) grid[k]->z[i] = next_real(&cp);
- }
+ grid[k]->structure[j][i] = next_int(&cp);
+ }
- else if(strstr(command,"SUBCELL SIZES 1")) {
- if(0) printf("Loading [%d] subcell sizes in X-direction\n",grid[k]->xcells);
- cp = params;
- for(i=1;i<=grid[k]->xcells;i++) grid[k]->x[i] = next_real(&cp);
- for(i=1;i<=grid[k]->xcells;i++) grid[k]->x[i] = grid[k]->x[i-1] + grid[k]->x[i];
- }
- else if(strstr(command,"SUBCELL SIZES 2")) {
- if(0) printf("Loading [%d] subcell sizes in Y-direction\n",grid[k]->ycells);
- cp = params;
- for(i=1;i<=grid[k]->ycells;i++) grid[k]->y[i] = next_real(&cp);
- for(i=1;i<=grid[k]->ycells;i++) grid[k]->y[i] = grid[k]->y[i-1] + grid[k]->y[i];
- }
- else if(strstr(command,"SUBCELL SIZES 3")) {
- if(0) printf("Loading [%d] subcell sizes in Z-direction\n",grid[k]->zcells);
- cp = params;
- for(i=1;i<=grid[k]->zcells;i++) grid[k]->z[i] = next_real(&cp);
- for(i=1;i<=grid[k]->zcells;i++) grid[k]->z[i] = grid[k]->z[i-1] + grid[k]->z[i];
- }
-
- else if(strstr(command,"SUBCELL ORIGIN 1")) {
- for(i=0;ix[0] + grid[k]->x[grid[k]->xcells]);
- }
- else if(strstr(params,"LEFT") || strstr(params,"MIN") ) {
- raid = grid[k]->x[0];
- }
- else if(strstr(params,"RIGHT") || strstr(params,"MAX") ) {
- raid = grid[k]->x[grid[k]->xcells];
- }
- else {
- cp = params;
- raid = next_real(&cp);
- }
- for(i=0;i<=grid[k]->xcells;i++) grid[k]->x[i] -= raid;
- }
- else if(strstr(command,"SUBCELL ORIGIN 2")) {
- for(i=0;iy[0] + grid[k]->y[grid[k]->ycells]);
- }
- else if(strstr(params,"LEFT")) {
- raid = grid[k]->y[0];
- }
- else if(strstr(params,"RIGHT")) {
- raid = grid[k]->y[grid[k]->ycells];
- }
- else {
- cp = params;
- raid = next_real(&cp);
- }
- for(i=0;i<=grid[k]->ycells;i++) grid[k]->y[i] -= raid;
- }
- else if(strstr(command,"SUBCELL ORIGIN 3")) {
- for(i=0;iz[0] + grid[k]->z[grid[k]->zcells]);
- }
- else if(strstr(params,"LEFT")) {
- raid = grid[k]->z[0];
- }
- else if(strstr(params,"RIGHT")) {
- raid = grid[k]->z[grid[k]->zcells];
- }
- else {
- cp = params;
- raid = next_real(&cp);
- }
- for(i=0;i<=grid[k]->zcells;i++) grid[k]->z[i] -= raid;
- }
-
- else if(strstr(command,"MATERIAL STRUCTURE")) {
- if(0) printf("Loading material structure\n");
-
- /* Initialize the default structure with zeros */
- for(j=grid[k]->ycells;j>=1;j--)
- for(i=1;i<=grid[k]->xcells;i++)
- grid[k]->structure[j][i] = 0;
-
- for(j=grid[k]->ycells;j>=1;j--) {
- if(j < grid[k]->ycells) Getline(params,in);
- cp=params;
- for(i=1;i<=grid[k]->xcells;i++)
- grid[k]->structure[j][i] = next_int(&cp);
- }
minmat = maxmat = grid[k]->structure[1][1];
for(j=grid[k]->ycells;j>=1;j--)
for(i=1;i<=grid[k]->xcells;i++) {
@@ -2501,736 +2717,2985 @@ int LoadElmergrid(struct GridType **grid,int *nogrids,char *prefix,int info)
}
if(minmat < 0)
printf("LoadElmergrid: please use positive material indices.\n");
- if(maxmat > MAXMATERIALS)
- printf("LoadElmergrid: material indices larger to %d may create problems.\n",
- MAXMATERIALS);
- }
- else if(strstr(command,"MATERIALS INTERVAL")) {
- sscanf(params,"%d %d",&(*grid)[k].firstmaterial,&(*grid)[k].lastmaterial);
- }
-
- else if(strstr(command,"REVOLVE")) {
- if(strstr(command,"REVOLVE RADIUS")) {
- (*grid)[k].rotate = TRUE;
- sscanf(params,"%le",&(*grid)[k].rotateradius2);
+
+ mode = 0;
+ break;
+
+ case 3:
+ case 31:
+ case 32:
+
+ /* I don't know how to set this, luckily this piece of code should be obsolete */
+ l = 1;
+ for(i=grid[k]->mappings;imappings+l;i++) {
+ Getline(line,in);
+ cp=line;
+
+ grid[k]->mappingtype[i] = next_int(&cp);
+ if(mode == 32) grid[k]->mappingtype[i] += 50*SGN(grid[k]->mappingtype[i]);
+
+ grid[k]->mappingline[i] = next_int(&cp);
+ grid[k]->mappinglimits[2*i] = next_real(&cp);
+ grid[k]->mappinglimits[2*i+1] = next_real(&cp);
+ grid[k]->mappingpoints[i] = next_int(&cp);
+ grid[k]->mappingparams[i] = Rvector(0,grid[k]->mappingpoints[i]);
+ for(j=0;jmappingpoints[i];j++)
+ grid[k]->mappingparams[i][j] = next_real(&cp);
}
- else if(strstr(command,"REVOLVE BLOCKS")) {
- (*grid)[k].rotate = TRUE;
- sscanf(params,"%d",&(*grid)[k].rotateblocks);
+
+ printf("Loaded %d geometry mappings\n",l);
+ grid[k]->mappings += l;
+
+ mode = 0;
+ break;
+
+ case 4: /* NUMBERING */
+ if(strstr(line,"HORIZ")) grid[k]->numbering = NUMBER_XY;
+ if(strstr(line,"VERTI")) grid[k]->numbering = NUMBER_YX;
+ mode = 0;
+ break;
+
+ case 5: /* MESHING */
+ if((*nogrids) >= MAXCASES) {
+ printf("There are more grids than was allocated for!\n");
+ printf("Ignoring meshes starting from %d\n.",(*nogrids)+1);
+ goto end;
}
- else if(strstr(command,"REVOLVE IMPROVE")) {
- (*grid)[k].rotate = TRUE;
- sscanf(params,"%le",&(*grid)[k].rotateimprove);
+ (*nogrids)++;
+ printf("Loading element meshing no %d\n",*nogrids);
+ k = *nogrids - 1;
+ if(k > nogrids0) (*grid)[k] = (*grid)[k-1];
+ mode = 0;
+ break;
+
+ case 6: /* ELEMENTS */
+ sscanf(line,"%d",&(*grid)[k].wantedelems);
+ mode = 0;
+ break;
+
+ case 7: /* NODES */
+ sscanf(line,"%d",&(*grid)[k].nonodes);
+
+ (*grid)[k].elemmidpoints = FALSE;
+ if((*grid)[k].nonodes == 4)
+ (*grid)[k].elemorder = 1;
+ if((*grid)[k].nonodes == 8)
+ (*grid)[k].elemorder = 2;
+ if((*grid)[k].nonodes == 16)
+ (*grid)[k].elemorder = 3;
+
+ if((*grid)[k].nonodes == 9) {
+ (*grid)[k].elemorder = 2;
+ (*grid)[k].elemmidpoints = TRUE;
}
- else if(strstr(command,"REVOLVE RADIUS")) {
- sscanf(params,"%le",&(*grid)[k].polarradius);
+ if((*grid)[k].nonodes == 12) {
+ (*grid)[k].elemorder = 3;
+ (*grid)[k].elemmidpoints = TRUE;
}
- else if(strstr(command,"REVOLVE CURVE DIRECT")) {
- (*grid)[k].rotatecurve = TRUE;
- sscanf(params,"%le",&(*grid)[k].curvezet);
+
+
+ mode = 0;
+ break;
+
+ case 8: /* TRIANGLES */
+ (*grid)[k].triangles = TRUE;
+ mode = 0;
+ break;
+
+ case 17: /* SQUARES */
+ (*grid)[k].triangles = FALSE;
+ mode = 0;
+ break;
+
+ case 16: /* ELEMENTTYPE and ELEMENTCODE */
+ sscanf(line,"%d",&elemcode);
+ if(elemcode/100 == 2) {
+ (*grid)[k].triangles = FALSE;
+ (*grid)[k].nonodes = elemcode%100;
}
- else if(strstr(command,"REVOLVE CURVE RADIUS")) {
- (*grid)[k].rotatecurve = TRUE;
- sscanf(params,"%le",&(*grid)[k].curverad);
+ else if(elemcode/100 == 4) {
+ (*grid)[k].triangles = FALSE;
+ (*grid)[k].nonodes = elemcode%100;
}
- else if(strstr(command,"REVOLVE CURVE ANGLE")) {
- (*grid)[k].rotatecurve = TRUE;
- sscanf(params,"%le",&(*grid)[k].curveangle);
+ else if(elemcode/100 == 3) {
+ (*grid)[k].triangles = TRUE;
+ if(elemcode%100 == 3) (*grid)[k].nonodes = 4;
+ else if(elemcode%100 == 6) (*grid)[k].nonodes = 9;
+ else if(elemcode%100 == 10) (*grid)[k].nonodes = 16;
}
- }
- else if(strstr(command,"REDUCE ORDER INTERVAL")) {
- sscanf(params,"%d%d",&(*grid)[k].reduceordermatmin,
- &(*grid)[k].reduceordermatmax);
- }
-
- else if(strstr(command,"BOUNDARY DEFINITION")) {
- if(0) printf("Loading boundary conditions\n");
-
- for(i=0;i0) Getline(params,in);
- for(j=0;j 1)
+ for(i=0;i<=(*grid)[k].ycells;i++) (*grid)[k].y[i] *= scaling;
if((*grid)[k].dimension == 3)
- sscanf(params,"%le %le",&(*grid)[k].xyratio,&(*grid)[k].xzratio);
+ for(i=0;i<=(*grid)[k].ycells;i++) (*grid)[k].z[i] *= scaling;
+
+ (*grid)[k].rotateradius2 *= scaling;
+ (*grid)[k].curverad *= scaling;
+ (*grid)[k].curvezet *= scaling;
+ mode = 0;
+ break;
+
+ default:
+ if(0) printf("Unknown case: %s",line);
+ }
+
+ }
+
+end:
+
+ if(info) printf("Found %d divisions for grid\n",*nogrids);
+
+ for(k=nogrids0;k < (*nogrids) && kdimension = 2;
+ if(strstr(params,"CARTESIAN 1D")) {
+ grid[k]->coordsystem = COORD_CART1;
+ grid[k]->dimension = 1;
+ }
+ else if(strstr(params,"CARTESIAN 2D"))
+ grid[k]->coordsystem = COORD_CART2;
+ else if(strstr(params,"AXISYMMETRIC"))
+ grid[k]->coordsystem = COORD_AXIS;
+ else if(strstr(params,"POLAR"))
+ grid[k]->coordsystem = COORD_POLAR;
+ else if(strstr(params,"CARTESIAN 3D")) {
+ grid[k]->coordsystem = COORD_CART3;
+ grid[k]->dimension = 3;
+ }
+ else printf("Unknown coordinate system: %s\n",params);
+ if(info) printf("Defining the coordinate system (%d-DIM).\n",grid[k]->dimension);
+ }
+
+ else if(strstr(command,"SUBCELL DIVISIONS")) {
+ if(grid[k]->dimension == 1) {
+ sscanf(params,"%d",&(*grid)[k].xcells);
+ grid[k]->ycells = 1;
+ }
+ else if(grid[k]->dimension == 2)
+ sscanf(params,"%d %d",&(*grid)[k].xcells,&(*grid)[k].ycells);
+ else if(grid[k]->dimension == 3)
+ sscanf(params,"%d %d %d",&(*grid)[k].xcells,&(*grid)[k].ycells,&(*grid)[k].zcells);
+
+ if(grid[k]->xcells >= MAXCELLS || grid[k]->ycells >= MAXCELLS || grid[k]->zcells >= MAXCELLS) {
+ printf("LoadElmergrid: Too many subcells [%d %d %d] vs. %d:\n",
+ grid[k]->xcells,grid[k]->ycells,grid[k]->zcells,MAXCELLS);
+ }
+
+ /* Initialize the default structure with ones */
+ for(j=grid[k]->ycells;j>=1;j--)
+ for(i=1;i<=grid[k]->xcells;i++)
+ grid[k]->structure[j][i] = 1;
+ }
+
+ else if(strstr(command,"MINIMUM ELEMENT DIVISION")) {
+ if(info) printf("Loading minimum number of elements\n");
+
+ if((*grid)[k].dimension == 1)
+ sscanf(params,"%d",&(*grid)[k].minxelems);
+
+ if((*grid)[k].dimension == 2)
+ sscanf(params,"%d %d",&(*grid)[k].minxelems,&(*grid)[k].minyelems);
+
+ if((*grid)[k].dimension == 3)
+ sscanf(params,"%d %d %d",&(*grid)[k].minxelems,
+ &(*grid)[k].minyelems,&(*grid)[k].minzelems);
+ }
+
+ else if(strstr(command,"SUBCELL LIMITS 1")) {
+ if(info) printf("Loading %d subcell limits in X-direction\n",grid[k]->xcells+1);
+ cp = params;
+ for(i=0;i<=grid[k]->xcells;i++) {
+ grid[k]->x[i] = next_real(&cp);
+ if(i > 0 && grid[k]->x[i] < grid[k]->x[i-1]) {
+ printf("Subcell limits 1(%d): %12.6le %12.6le\n",i,grid[k]->x[i],grid[k]->x[i-1]);
+ bigerror("Values for limits 1 should be a growing series, existing\n");
+ }
+ }
+ }
+ else if(strstr(command,"SUBCELL LIMITS 2")) {
+ if(info) printf("Loading %d subcell limits in Y-direction\n",grid[k]->ycells+1);
+ cp = params;
+ for(i=0;i<=grid[k]->ycells;i++) {
+ grid[k]->y[i] = next_real(&cp);
+ if(i > 0 && grid[k]->y[i] < grid[k]->y[i-1]) {
+ printf("Subcell limits 2(%d): %12.6le %12.6le\n",i,grid[k]->y[i],grid[k]->y[i-1]);
+ bigerror("Values for limits should be a growing series, existing\n");
+ }
+ }
+ }
+ else if(strstr(command,"SUBCELL LIMITS 3")) {
+ if(info) printf("Loading %d subcell limits in Z-direction\n",grid[k]->zcells+1);
+ cp = params;
+ for(i=0;i<=grid[k]->zcells;i++) {
+ grid[k]->z[i] = next_real(&cp);
+ if(i > 0 && grid[k]->z[i] < grid[k]->z[i-1]) {
+ printf("Subcell limits 3(%d): %12.6le %12.6le\n",i,grid[k]->z[i],grid[k]->z[i-1]);
+ bigerror("Values for limits should be a growing series, existing\n");
+ }
+ }
+ }
+
+ else if(strstr(command,"SUBCELL SIZES 1")) {
+ if(info) printf("Loading %d subcell sizes in X-direction\n",grid[k]->xcells);
+ cp = params;
+ for(i=1;i<=grid[k]->xcells;i++) grid[k]->x[i] = next_real(&cp);
+ for(i=1;i<=grid[k]->xcells;i++) grid[k]->x[i] = grid[k]->x[i-1] + grid[k]->x[i];
+ }
+ else if(strstr(command,"SUBCELL SIZES 2")) {
+ if(info) printf("Loading %d subcell sizes in Y-direction\n",grid[k]->ycells);
+ cp = params;
+ for(i=1;i<=grid[k]->ycells;i++) grid[k]->y[i] = next_real(&cp);
+ for(i=1;i<=grid[k]->ycells;i++) grid[k]->y[i] = grid[k]->y[i-1] + grid[k]->y[i];
+ }
+ else if(strstr(command,"SUBCELL SIZES 3")) {
+ if(info) printf("Loading %d subcell sizes in Z-direction\n",grid[k]->zcells);
+ cp = params;
+ for(i=1;i<=grid[k]->zcells;i++) grid[k]->z[i] = next_real(&cp);
+ for(i=1;i<=grid[k]->zcells;i++) grid[k]->z[i] = grid[k]->z[i-1] + grid[k]->z[i];
+ }
+
+ else if(strstr(command,"SUBCELL ORIGIN 1")) {
+ for(i=0;ix[0] + grid[k]->x[grid[k]->xcells]);
+ }
+ else if(strstr(params,"LEFT") || strstr(params,"MIN") ) {
+ raid = grid[k]->x[0];
+ }
+ else if(strstr(params,"RIGHT") || strstr(params,"MAX") ) {
+ raid = grid[k]->x[grid[k]->xcells];
+ }
+ else {
+ cp = params;
+ raid = next_real(&cp);
+ }
+ for(i=0;i<=grid[k]->xcells;i++) grid[k]->x[i] -= raid;
+ }
+ else if(strstr(command,"SUBCELL ORIGIN 2")) {
+ for(i=0;iy[0] + grid[k]->y[grid[k]->ycells]);
+ }
+ else if(strstr(params,"LEFT")) {
+ raid = grid[k]->y[0];
+ }
+ else if(strstr(params,"RIGHT")) {
+ raid = grid[k]->y[grid[k]->ycells];
+ }
+ else {
+ cp = params;
+ raid = next_real(&cp);
+ }
+ for(i=0;i<=grid[k]->ycells;i++) grid[k]->y[i] -= raid;
+ }
+ else if(strstr(command,"SUBCELL ORIGIN 3")) {
+ for(i=0;iz[0] + grid[k]->z[grid[k]->zcells]);
+ }
+ else if(strstr(params,"LEFT")) {
+ raid = grid[k]->z[0];
+ }
+ else if(strstr(params,"RIGHT")) {
+ raid = grid[k]->z[grid[k]->zcells];
+ }
+ else {
+ cp = params;
+ raid = next_real(&cp);
+ }
+ for(i=0;i<=grid[k]->zcells;i++) grid[k]->z[i] -= raid;
+ }
+
+ else if(strstr(command,"MATERIAL STRUCTURE")) {
+ if(info) printf("Loading material structure\n");
+
+ /* Initialize the default structure with zeros */
+ for(j=grid[k]->ycells;j>=1;j--)
+ for(i=1;i<=grid[k]->xcells;i++)
+ grid[k]->structure[j][i] = 0;
+
+ for(j=grid[k]->ycells;j>=1;j--) {
+ if(j < grid[k]->ycells) Getline(params,in);
+ cp=params;
+ for(i=1;i<=grid[k]->xcells;i++)
+ grid[k]->structure[j][i] = next_int(&cp);
+ }
+ minmat = maxmat = grid[k]->structure[1][1];
+ for(j=grid[k]->ycells;j>=1;j--)
+ for(i=1;i<=grid[k]->xcells;i++) {
+ if(minmat > grid[k]->structure[j][i])
+ minmat = grid[k]->structure[j][i];
+ if(maxmat < grid[k]->structure[j][i])
+ maxmat = grid[k]->structure[j][i];
+ }
+ if(minmat < 0)
+ printf("LoadElmergrid: please use positive material indices.\n");
+ if(maxmat > MAXBODYID)
+ printf("LoadElmergrid: material indices larger to %d may create problems.\n",
+ MAXBODYID);
+ printf("LoadElmergrid: materials interval is [%d,%d]\n",minmat,maxmat);
+
+ grid[k]->maxmaterial = maxmat;
+ }
+ else if(strstr(command,"MATERIALS INTERVAL")) {
+ sscanf(params,"%d %d",&(*grid)[k].firstmaterial,&(*grid)[k].lastmaterial);
+ }
+
+ else if(strstr(command,"REVOLVE")) {
+ if(0) printf("revolve: %s %s\n",command,params);
+
+ if(strstr(command,"REVOLVE RADIUS")) {
+ (*grid)[k].rotate = TRUE;
+ sscanf(params,"%le",&(*grid)[k].rotateradius2);
+ }
+ else if(strstr(command,"REVOLVE BLOCKS")) {
+ (*grid)[k].rotate = TRUE;
+ sscanf(params,"%d",&(*grid)[k].rotateblocks);
+ }
+ else if(strstr(command,"REVOLVE IMPROVE")) {
+ (*grid)[k].rotate = TRUE;
+ sscanf(params,"%le",&(*grid)[k].rotateimprove);
+ }
+ else if(strstr(command,"REVOLVE RADIUS")) {
+ sscanf(params,"%le",&(*grid)[k].polarradius);
+ }
+ else if(strstr(command,"REVOLVE CURVE DIRECT")) {
+ (*grid)[k].rotatecurve = TRUE;
+ sscanf(params,"%le",&(*grid)[k].curvezet);
+ }
+ else if(strstr(command,"REVOLVE CURVE RADIUS")) {
+ (*grid)[k].rotatecurve = TRUE;
+ sscanf(params,"%le",&(*grid)[k].curverad);
+ }
+ else if(strstr(command,"REVOLVE CURVE ANGLE")) {
+ (*grid)[k].rotatecurve = TRUE;
+ sscanf(params,"%le",&(*grid)[k].curveangle);
+ }
+ }
+
+ else if(strstr(command,"REDUCE ORDER INTERVAL")) {
+ sscanf(params,"%d%d",&(*grid)[k].reduceordermatmin,
+ &(*grid)[k].reduceordermatmax);
+ }
+
+ else if(strstr(command,"BOUNDARY DEFINITION")) {
+ printf("Loading boundary conditions\n");
+
+ for(i=0;i0) Getline(params,in);
+ for(j=0;j1) Getline(params,in);
+ sscanf(params,"%d %d %d\n",
+ &(*grid)[k].zfirstmaterial[i],&(*grid)[k].zlastmaterial[i],&(*grid)[k].zmaterial[i]);
+ }
+ } */
+
+ else if(strstr(command,"GEOMETRY MAPPINGS")) {
+ if(k > 0) (*grid)[k].mappings = 0;
+
+ for(i=0;i(*grid)[k].mappings) Getline(params,in);
+
+ if(strstr(params,"END")) break;
+ cp=params;
+ (*grid)[k].mappingtype[i] = next_int(&cp);
+#if 0
+ (*grid)[k].mappingtype[i] += 50*SGN((*grid)[k].mappingtype[i]);
+#endif
+ (*grid)[k].mappingline[i] = next_int(&cp);
+ (*grid)[k].mappinglimits[2*i] = next_real(&cp);
+ (*grid)[k].mappinglimits[2*i+1] = next_real(&cp);
+ (*grid)[k].mappingpoints[i] = next_int(&cp);
+ (*grid)[k].mappingparams[i] = Rvector(0,(*grid)[k].mappingpoints[i]);
+ for(j=0;j<(*grid)[k].mappingpoints[i];j++)
+ (*grid)[k].mappingparams[i][j] = next_real(&cp);
+ }
+ printf("Loaded %d geometry mappings\n",i);
+ (*grid)[k].mappings = i;
+ }
+
+ else if(strstr(command,"END") ) {
+ if(0) printf("End of field\n");
+ }
+
+ else if(strstr(command,"START NEW MESH")) {
+ if((*nogrids) >= MAXCASES) {
+ printf("There are more grids than was allocated for!\n");
+ printf("Ignoring meshes starting from %d\n.",(*nogrids)+1);
+ goto end;
+ }
+ (*nogrids)++;
+ printf("\nLoading element meshing no %d\n",*nogrids);
+ k = *nogrids - 1;
+ if(k > nogrids0) (*grid)[k] = (*grid)[k-1];
+ }
+
+ else {
+ if(0) printf("Unknown command: %s",command);
+ }
+ }
+
+end:
+
+ if(info) printf("Found %d divisions for grid\n",*nogrids);
+
+ for(k=nogrids0;k < (*nogrids) && krelh = 1.0;
+ eg->inmethod = 0;
+ eg->outmethod = 0;
+ eg->silent = FALSE;
+ eg->nofilesin = 1;
+ eg->unitemeshes = FALSE;
+ eg->unitenooverlap = FALSE;
+ eg->triangles = FALSE;
+ eg->triangleangle = 0.0;
+ eg->rotate = FALSE;
+ eg->polar = FALSE;
+ eg->cylinder = FALSE;
+ eg->usenames = TRUE;
+ eg->layers = 0;
+ eg->layereps = 0.0;
+ eg->layermove = 0;
+ eg->partitions = 0;
+ eg->elements3d = 0;
+ eg->nodes3d = 0;
+ eg->metis = 0;
+ eg->metiscontig = FALSE;
+ eg->metisseed = 0;
+ eg->partopt = 0;
+ eg->partoptim = FALSE;
+ eg->partbcoptim = TRUE;
+ eg->partjoin = 0;
+ for(i=0;iparthalo[i] = FALSE;
+ eg->partitionindirect = FALSE;
+ eg->reduce = FALSE;
+ eg->increase = FALSE;
+ eg->translate = FALSE;
+ eg->isoparam = FALSE;
+ eg->removelowdim = FALSE;
+ eg->removeintbcs = FALSE;
+ eg->removeunused = FALSE;
+ eg->dim = 3;
+ eg->center = FALSE;
+ eg->scale = FALSE;
+ eg->order = FALSE;
+ eg->boundbounds = 0;
+ eg->saveinterval[0] = eg->saveinterval[1] = eg->saveinterval[2] = 0;
+ eg->bulkbounds = 0;
+ eg->partorder = FALSE;
+ eg->findsides = FALSE;
+ eg->parthypre = FALSE;
+ eg->partdual = FALSE;
+ eg->partbcz = 0;
+ eg->partbcr = 0;
+ eg->partbclayers = 1;
+ eg->partbcmetis = 0;
+ eg->partbw = FALSE;
+ eg->saveboundaries = TRUE;
+ eg->vtuone = FALSE;
+ eg->timeron = FALSE;
+ eg->nosave = FALSE;
+ eg->nooverwrite = FALSE;
+ eg->merge = FALSE;
+ eg->bcoffset = FALSE;
+ eg->periodic = 0;
+ eg->periodicdim[0] = 0;
+ eg->periodicdim[1] = 0;
+ eg->periodicdim[2] = 0;
+ eg->bulkorder = FALSE;
+ eg->boundorder = FALSE;
+ eg->sidemappings = 0;
+ eg->bulkmappings = 0;
+ eg->coordinatemap[0] = eg->coordinatemap[1] = eg->coordinatemap[2] = 0;
+ eg->clone[0] = eg->clone[1] = eg->clone[2] = 0;
+ eg->mirror[0] = eg->mirror[1] = eg->mirror[2] = 0;
+ eg->cloneinds = FALSE;
+ eg->mirrorbc = 0;
+ eg->decimals = 12;
+ eg->discont = 0;
+ eg->connect = 0;
+ eg->connectboundsnosets = 0;
+
+ eg->rotatecurve = FALSE;
+ eg->curverad = 0.5;
+ eg->curveangle = 90.0;
+ eg->curvezet = 0.0;
+ eg->parttol = 0.0;
+
+ for(i=0;isidebulk[i] = 0;
+}
+
+
+
+
+int InlineParameters(struct ElmergridType *eg,int argc,char *argv[],int first,int info)
+{
+ int arg,i,dim;
+ char command[MAXLINESIZE];
+
+ dim = eg->dim;
+
+ printf("Elmergrid reading in-line arguments\n");
+
+ /* Type of input file */
+ if(first > 3) {
+ for(i=0;iinmethod = i;
+ break;
+ }
+ }
+ if(i>MAXINMETHODS) eg->inmethod = atoi(argv[1]);
+
+
+ /* Type of output file (fewer options) */
+ strcpy(command,argv[2]);
+ for(i=0;ioutmethod = i;
+ break;
+ }
+ }
+ if(i>MAXOUTMETHODS) eg->outmethod = atoi(argv[2]);
+
+ /* Name of output file */
+ strcpy(eg->filesin[0],argv[3]);
+ strcpy(eg->filesout[0],eg->filesin[0]);
+ strcpy(eg->infofile,eg->filesin[0]);
+ }
+
+
+ /* The optional inline parameters */
+
+ for(arg=first;arg silent = TRUE;
+ info = FALSE;
+ }
+
+ if(strcmp(argv[arg],"-verbose") == 0) {
+ eg->silent = FALSE;
+ info = TRUE;
+ }
+
+ if(strcmp(argv[arg],"-in") ==0 ) {
+ if(arg+1 >= argc) {
+ printf("The secondary input file name is required as a parameter\n");
+ return(1);
+ }
+ else {
+ strcpy(eg->filesin[eg->nofilesin],argv[arg+1]);
+ printf("A secondary input file %s will be loaded.\n",eg->filesin[eg->nofilesin]);
+ eg->nofilesin++;
+ }
+ }
+
+ if(strcmp(argv[arg],"-out") == 0) {
+ if(arg+1 >= argc) {
+ printf("The output name is required as a parameter\n");
+ return(2);
+ }
+ else {
+ strcpy(eg->filesout[0],argv[arg+1]);
+ }
+ }
+
+
+ if(strcmp(argv[arg],"-decimals") == 0) {
+ eg->decimals = atoi(argv[arg+1]);
+ }
+
+ if(strcmp(argv[arg],"-triangles") ==0) {
+ eg->triangles = TRUE;
+ printf("The rectangles will be split to triangles.\n");
+ if(arg+1 < argc) {
+ if(strcmp(argv[arg+1],"-")) {
+ eg->triangleangle = atof(argv[arg+1]);
+ }
+ }
+ }
+
+ if(strcmp(argv[arg],"-merge") == 0) {
+ if(arg+1 >= argc) {
+ printf("Give a parameter for critical distance.\n");
+ return(3);
+ }
+ else {
+ eg->merge = TRUE;
+ eg->cmerge = atof(argv[arg+1]);
+ }
+ }
+
+ if(strcmp(argv[arg],"-relh") == 0) {
+ if(arg+1 >= argc) {
+ printf("Give a relative mesh density related to the specifications\n");
+ return(3);
+ }
+ else {
+ eg->relh = atof(argv[arg+1]);
+ }
+ }
+
+ if(strcmp(argv[arg],"-order") == 0) {
+ if(arg+dim >= argc) {
+ printf("Give %d parameters for the order vector.\n",dim);
+ return(4);
+ }
+ else {
+ eg->order = TRUE;
+ eg->corder[0] = atof(argv[arg+1]);
+ eg->corder[1] = atof(argv[arg+2]);
+ if(dim==3) eg->corder[2] = atof(argv[arg+3]);
+ }
+ }
+
+ if(strcmp(argv[arg],"-parttol") == 0) {
+ if(arg+1 >= argc) {
+ printf("Give a tolerance for gemetric partition algorithms\n");
+ return(3);
+ }
+ else {
+ eg->parttol = atof(argv[arg+1]);
+ }
+ }
+
+ if(strcmp(argv[arg],"-autoorder") == 0) {
+ eg->order = 2;
+ }
+
+ if(strcmp(argv[arg],"-halo") == 0) {
+ eg->parthalo[1] = TRUE;
+ }
+ if(strcmp(argv[arg],"-halobc") == 0) {
+ eg->parthalo[2] = TRUE;
+ }
+ if(strcmp(argv[arg],"-halodb") == 0) {
+ eg->parthalo[1] = TRUE;
+ eg->parthalo[2] = TRUE;
+ }
+ if(strcmp(argv[arg],"-haloz") == 0) {
+ eg->parthalo[3] = TRUE;
+ }
+ if(strcmp(argv[arg],"-halor") == 0) {
+ eg->parthalo[3] = TRUE;
+ }
+ if(strcmp(argv[arg],"-halogreedy") == 0) {
+ eg->parthalo[4] = TRUE;
+ }
+ if(strcmp(argv[arg],"-indirect") == 0) {
+ eg->partitionindirect = TRUE;
+ }
+ if(strcmp(argv[arg],"-metisorder") == 0) {
+ eg->order = 3;
+ }
+ if(strcmp(argv[arg],"-centralize") == 0) {
+ eg->center = TRUE;
+ }
+ if(strcmp(argv[arg],"-scale") == 0) {
+ if(arg+dim >= argc) {
+ printf("Give %d parameters for the scaling.\n",dim);
+ return(5);
+ }
+ else {
+ eg->scale = TRUE;
+ eg->cscale[0] = atof(argv[arg+1]);
+ eg->cscale[1] = atof(argv[arg+2]);
+ if(dim==3) eg->cscale[2] = atof(argv[arg+3]);
+ }
+ }
+
+ if(strcmp(argv[arg],"-translate") == 0) {
+ if(arg+dim >= argc) {
+ printf("Give %d parameters for the translate vector.\n",dim);
+ return(6);
+ }
+ else {
+ eg->translate = TRUE;
+ eg->ctranslate[0] = atof(argv[arg+1]);
+ eg->ctranslate[1] = atof(argv[arg+2]);
+ if(dim==3) eg->ctranslate[2] = atof(argv[arg+3]);
+ }
+ }
+
+ if(strcmp(argv[arg],"-saveinterval") == 0) {
+ if(arg+dim >= argc) {
+ printf("Give min, max and step for the interval.\n");
+ return(7);
+ }
+ else {
+ eg->saveinterval[0] = atoi(argv[arg+1]);
+ eg->saveinterval[1] = atoi(argv[arg+2]);
+ eg->saveinterval[2] = atoi(argv[arg+3]);
+ }
+ }
+
+ if(strcmp(argv[arg],"-rotate") == 0 || strcmp(argv[arg],"-rotate") == 0) {
+ if(arg+dim >= argc) {
+ printf("Give three parameters for the rotation angles.\n");
+ return(8);
+ }
+ else {
+ eg->rotate = TRUE;
+ eg->crotate[0] = atof(argv[arg+1]);
+ eg->crotate[1] = atof(argv[arg+2]);
+ eg->crotate[2] = atof(argv[arg+3]);
+ }
+ }
+
+ if(strcmp(argv[arg],"-clone") == 0) {
+ if(arg+dim >= argc) {
+ printf("Give the number of clones in each %d directions.\n",dim);
+ return(9);
+ }
+ else {
+ eg->clone[0] = atoi(argv[arg+1]);
+ eg->clone[1] = atoi(argv[arg+2]);
+ if(dim == 3) eg->clone[2] = atoi(argv[arg+3]);
+ }
+ }
+ if(strcmp(argv[arg],"-clonesize") == 0) {
+ if(arg+dim >= argc) {
+ printf("Give the clone size in each %d directions.\n",dim);
+ return(10);
+ }
+ else {
+ eg->clonesize[0] = atof(argv[arg+1]);
+ eg->clonesize[1] = atof(argv[arg+2]);
+ if(dim == 3) eg->clonesize[2] = atof(argv[arg+3]);
+ }
+ }
+ if(strcmp(argv[arg],"-cloneinds") == 0) {
+ eg->cloneinds = TRUE;
+ }
+ if(strcmp(argv[arg],"-mirror") == 0) {
+ if(arg+dim >= argc) {
+ printf("Give the symmetry of the coordinate directions, eg. 1 1 0\n");
+ }
+ else {
+ eg->mirror[0] = atoi(argv[arg+1]);
+ eg->mirror[1] = atoi(argv[arg+2]);
+ if(dim == 3) eg->mirror[2] = atoi(argv[arg+3]);
+ }
+ }
+ if(strcmp(argv[arg],"-mirrorbc") == 0) {
+ if(arg+1 >= argc) {
+ printf("Give the number of symmetry BC.\n");
+ return(11);
+ }
+ else {
+ eg->mirrorbc = atoi(argv[arg+1]);
+ }
+ }
+
+ if(strcmp(argv[arg],"-unite") == 0) {
+ eg->unitemeshes = TRUE;
+ printf("The meshes will be united.\n");
+ }
+ if(strcmp(argv[arg],"-unitenooverlap") == 0) {
+ eg->unitemeshes = TRUE;
+ eg->unitenooverlap = TRUE;
+ printf("The meshes will be united without overlap in BCs or bodies.\n");
+ }
+
+ if(strcmp(argv[arg],"-nonames") == 0) {
+ eg->usenames = FALSE;
+ printf("Names will be omitted even if they would exist\n");
+ }
+
+ if(strcmp(argv[arg],"-removelowdim") == 0) {
+ eg->removelowdim = TRUE;
+ printf("Lower dimensional boundaries will be removed\n");
+ }
+
+ if(strcmp(argv[arg],"-removeintbcs") == 0) {
+ eg->removeintbcs = TRUE;
+ printf("Lower dimensional boundaries will be removed\n");
+ }
+
+ if(strcmp(argv[arg],"-removeunused") == 0) {
+ eg->removeunused = TRUE;
+ printf("Nodes that do not appear in any element will be removed\n");
+ }
+
+ if(strcmp(argv[arg],"-autoclean") == 0) {
+ eg->removelowdim = TRUE;
+ eg->bulkorder = TRUE;
+ eg->boundorder = TRUE;
+ eg->removeunused = TRUE;
+ printf("Lower dimensional boundaries will be removed\n");
+ printf("Materials and boundaries will be renumbered\n");
+ printf("Nodes that do not appear in any element will be removed\n");
+ }
+
+ if(strcmp(argv[arg],"-polar") == 0) {
+ eg->polar = TRUE;
+ printf("Making transformation to polar coordinates.\n");
+ if(arg+1 >= argc) {
+ printf("The preferred radius is required as a parameter\n");
+ eg->polarradius = 1.0;
+ }
+ else {
+ eg->polarradius = atoi(argv[arg+1]);
+ }
+ }
+
+ if(strcmp(argv[arg],"-cylinder") == 0) {
+ eg->cylinder = TRUE;
+ printf("Making transformation from cylindrical to cartesian coordinates.\n");
+ }
+
+ if(strcmp(argv[arg],"-reduce") == 0) {
+ if(arg+2 >= argc) {
+ printf("Give two material for the interval.\n");
+ return(12);
+ }
+ else {
+ eg->reduce = TRUE;
+ eg->reducemat1 = atoi(argv[arg+1]);
+ eg->reducemat2 = atoi(argv[arg+2]);
+ }
+ }
+ if(strcmp(argv[arg],"-increase") == 0) {
+ eg->increase = TRUE;
+ }
+ if(strcmp(argv[arg],"-bulkorder") == 0) {
+ eg->bulkorder = TRUE;
+ }
+ if(strcmp(argv[arg],"-boundorder") == 0) {
+ eg->boundorder = TRUE;
+ }
+ if(strcmp(argv[arg],"-partition") == 0 ||
+ strcmp(argv[arg],"-partcell") == 0 ||
+ strcmp(argv[arg],"-partcyl") == 0 ) {
+ if(arg+dim >= argc) {
+ printf("The number of partitions in %d dims is required as parameters.\n",dim);
+ return(13);
+ }
+ else {
+ eg->partitions = 1;
+ eg->partdim[0] = atoi(argv[arg+1]);
+ eg->partdim[1] = atoi(argv[arg+2]);
+ if(dim == 3) eg->partdim[2] = atoi(argv[arg+3]);
+ eg->partitions = 1;
+ for(i=0;i<3;i++) {
+ if(eg->partdim[i] == 0) eg->partdim[i] = 1;
+ eg->partitions *= eg->partdim[i];
+ }
+ eg->partopt = -1;
+ if( strcmp(argv[arg],"-partition") == 0 ) {
+ if(arg+4 < argc)
+ if(argv[arg+4][0] != '-') eg->partopt = atoi(argv[arg+4]);
+ }
+ else if( strcmp( argv[arg],"-partcell") == 0 ) {
+ eg->partopt = 2;
+ } else if( strcmp( argv[arg],"-partcyl") == 0 ) {
+ eg->partopt = 3;
+ }
+
+ printf("The mesh will be partitioned geometrically to %d partitions.\n",
+ eg->partitions);
+ }
+ }
+ if(strcmp(argv[arg],"-partorder") == 0) {
+ if(arg+dim >= argc) {
+ printf("Give %d parameters for the order vector.\n",dim);
+ return(14);
+ }
+ else {
+ eg->partorder = 1;
+ eg->partcorder[0] = atof(argv[arg+1]);
+ eg->partcorder[1] = atof(argv[arg+2]);
+ if(dim==3) eg->partcorder[2] = atof(argv[arg+3]);
+ }
+ }
+ if(strcmp(argv[arg],"-partoptim") == 0) {
+ eg->partoptim = TRUE;
+ printf("Aggressive optimization will be applied to node sharing.\n");
+ }
+ if(strcmp(argv[arg],"-partnobcoptim") == 0) {
+ eg->partbcoptim = FALSE;
+ printf("Aggressive optimization will not be applied to parent element sharing.\n");
+ }
+ if(strcmp(argv[arg],"-partbw") == 0) {
+ eg->partbw = TRUE;
+ printf("Bandwidth will be optimized for partitions.\n");
+ }
+ if(strcmp(argv[arg],"-parthypre") == 0) {
+ eg->parthypre = TRUE;
+ printf("Numbering of partitions will be made continuous.\n");
+ }
+ if(strcmp(argv[arg],"-partdual") == 0) {
+ eg->partdual = TRUE;
+ printf("Using dual (elemental) graph in partitioning.\n");
+ }
+
+ if(strcmp(argv[arg],"-metis") == 0 ||
+ strcmp(argv[arg],"-metisrec") == 0 ||
+ strcmp(argv[arg],"-metiskway") == 0 ) {
+#if USE_METIS
+ if(arg+1 >= argc) {
+ printf("The number of partitions is required as a parameter\n");
+ return(15);
+ }
+ else {
+ eg->metis = atoi(argv[arg+1]);
+ printf("The mesh will be partitioned with Metis to %d partitions.\n",eg->metis);
+ eg->partopt = 0;
+ if(strcmp(argv[arg],"-metisrec") == 0)
+ eg->partopt = 2;
+ else if(strcmp(argv[arg],"-metiskway") == 0 )
+ eg->partopt = 3;
+ else if(arg+2 < argc)
+ if(argv[arg+2][0] != '-') eg->partopt = atoi(argv[arg+2]);
+ }
+#else
+ printf("This version of ElmerGrid was compiled without Metis library!\n");
+#endif
+ }
+
+ if(strcmp(argv[arg],"-metisseed") == 0 ) {
+ if(arg+1 >= argc) {
+ printf("The random number seed is required as parameter for -metisseed!\n");
+ return(15);
+ }
+ else {
+ eg->metisseed = atoi(argv[arg+1]);
+ printf("Seed for Metis partitioning routines: %d\n",eg->metisseed);
+ }
+ }
+
+ if(strcmp(argv[arg],"-partjoin") == 0) {
+ if(arg+1 >= argc) {
+ printf("The number of partitions is required as a parameter!\n");
+ return(15);
+ }
+ else {
+ eg->partjoin = atoi(argv[arg+1]);
+ printf("The results will joined using %d partitions.\n",eg->partjoin);
+ }
+ }
+
+ if(strcmp(argv[arg],"-partconnect") == 0 || strcmp(argv[arg],"-partzbc") == 0 ) {
+ if(arg+1 >= argc) {
+ printf("The number of 1D partitions is required as a parameter!\n");
+ return(15);
+ }
+ else {
+ eg->partbcz = atoi(argv[arg+1]);
+ printf("The connected BCs will be partitioned to %d partitions in Z.\n",eg->partbcz);
+ }
+ }
+
+ if(strcmp(argv[arg],"-partrbc") == 0 ) {
+ if(arg+1 >= argc) {
+ printf("The number of 1D partitions is required as a parameter!\n");
+ return(15);
+ }
+ else {
+ eg->partbcr = atoi(argv[arg+1]);
+ printf("The connected BCs will be partitioned to %d partitions in R.\n",eg->partbcr);
+ }
+ }
+
+ if(strcmp(argv[arg],"-partlayers") == 0) {
+ if(arg+1 >= argc) {
+ printf("The number of layers to be extended is required as a parameter\n");
+ return(15);
+ }
+ else {
+ eg->partbclayers = atoi(argv[arg+1]);
+ printf("The boundary partitioning will be extended by %d layers.\n",eg->partbclayers);
+ }
+ }
+
+ if(strcmp(argv[arg],"-metiscontig") == 0 ) {
+ eg->metiscontig = TRUE;
+ }
+
+ if(strcmp(argv[arg],"-metisconnect") == 0 || strcmp(argv[arg],"-metisbc") == 0 ) {
+ if(arg+1 >= argc) {
+ printf("The number of Metis partitions is required as a parameter\n");
+ return(15);
+ }
+ else {
+ eg->partbcmetis = atoi(argv[arg+1]);
+ printf("The connected BCs will be partitioned to %d partitions by Metis.\n",eg->partbcmetis);
+ }
+ }
+
+ if(strcmp(argv[arg],"-periodic") == 0) {
+ if(arg+dim >= argc) {
+ printf("Give the periodic coordinate directions (e.g. 1 1 0)\n");
+ return(16);
+ }
+ else {
+ eg->periodicdim[0] = atoi(argv[arg+1]);
+ eg->periodicdim[1] = atoi(argv[arg+2]);
+ if(dim == 3) eg->periodicdim[2] = atoi(argv[arg+3]);
+ }
+ }
+
+ if(strcmp(argv[arg],"-discont") == 0) {
+ if(arg+1 >= argc) {
+ printf("Give the discontinuous boundary conditions.\n");
+ return(17);
+ }
+ else {
+ eg->discontbounds[eg->discont] = atoi(argv[arg+1]);
+ eg->discont++;
+ }
+ }
+
+ if(strcmp(argv[arg],"-connect") == 0) {
+ if(arg+1 >= argc) {
+ printf("Give the connected boundary conditions.\n");
+ return(10);
+ }
+ else {
+ eg->connectboundsnosets += 1;
+ for(i=arg+1;iconnectbounds[eg->connect] = atoi(argv[i]);
+ eg->connectboundsset[eg->connect] = eg->connectboundsnosets;
+ eg->connect++;
+ }
+ }
+ }
+
+ if(strcmp(argv[arg],"-connectall") == 0) {
+ eg->connectboundsnosets += 1;
+ eg->connectbounds[eg->connect] = -1;
+ eg->connectboundsset[eg->connect] = eg->connectboundsnosets;
+ eg->connect++;
+ }
+
+ if(strcmp(argv[arg],"-connectint") == 0) {
+ eg->connectboundsnosets += 1;
+ eg->connectbounds[eg->connect] = -2;
+ eg->connectboundsset[eg->connect] = eg->connectboundsnosets;
+ eg->connect++;
+ }
+
+ if(strcmp(argv[arg],"-connectfree") == 0) {
+ eg->connectboundsnosets += 1;
+ eg->connectbounds[eg->connect] = -3;
+ eg->connectboundsset[eg->connect] = eg->connectboundsnosets;
+ eg->connect++;
+ }
+
+ if(strcmp(argv[arg],"-boundbound") == 0) {
+ for(i=arg+1;i<=arg+3 && iboundbound[3*eg->boundbounds+i-(1+arg)] = atoi(argv[i]);
+ if((i-arg)%3 == 0) eg->boundbounds++;
+ }
+ }
+ if(strcmp(argv[arg],"-bulkbound") == 0) {
+ for(i=arg+1;i<=arg+3 && ibulkbound[3*eg->bulkbounds+i-(1+arg)] = atoi(argv[i]);
+ if((i-arg)%3 == 0) eg->bulkbounds++;
+ }
+ }
+ if(strcmp(argv[arg],"-boundtype") == 0) {
+ for(i=arg+1;isidemap[3*eg->sidemappings+i-1-arg] = atoi(argv[i]);
+ eg->sidemappings++;
+ }
+ if(strcmp(argv[arg],"-bulktype") == 0) {
+ for(i=arg+1;ibulkmap[3*eg->bulkmappings+i-1-arg] = atoi(argv[i]);
+ eg->bulkmappings++;
+ }
+ if(strcmp(argv[arg],"-coordinatemap") == 0) {
+ if( arg+3 >= argc ) {
+ printf("Give three parameters for the index permutation\n");
+ return(18);
+ }
+ else {
+ for(i=0;i<3;i++)
+ eg->coordinatemap[i] = atoi(argv[arg+1+i]);
+ }
+ }
+ if(strcmp(argv[arg],"-layer") == 0) {
+ if(arg+4 >= argc) {
+ printf("Give four parameters for the layer: boundary, elements, thickness, ratio.\n");
+ return(18);
+ }
+ else if(eg->layers == MAXBOUNDARIES) {
+ printf("There can only be %d layers, sorry.\n",MAXBOUNDARIES);
+ return(19);
+ }
+ else {
+ eg->layerbounds[eg->layers] = atoi(argv[arg+1]);
+ eg->layernumber[eg->layers] = atoi(argv[arg+2]);
+ eg->layerthickness[eg->layers] = atof(argv[arg+3]);
+ eg->layerratios[eg->layers] = atof(argv[arg+4]);
+ eg->layerparents[eg->layers] = 0;
+ eg->layers++;
+ }
+ }
+
+ if(strcmp(argv[arg],"-layermove") == 0) {
+ if(arg+1 >= argc) {
+ printf("Give maximum number of Jacobi filters.\n");
+ return(20);
+ }
+ else {
+ eg->layermove = atoi(argv[arg+1]);
+ }
+ }
+
+ /* This uses a very dirty trick where the variables related to argument -layer are used
+ with a negative indexing */
+ if(strcmp(argv[arg],"-divlayer") == 0) {
+ if(arg+4 >= argc) {
+ printf("Give four parameters for the layer: boundary, elements, relative thickness, ratio.\n");
+ return(21);
+ }
+ else if(abs(eg->layers) == MAXBOUNDARIES) {
+ printf("There can only be %d layers, sorry.\n",MAXBOUNDARIES);
+ return(22);
+ }
+ else {
+ eg->layerbounds[abs(eg->layers)] = atoi(argv[arg+1]);
+ eg->layernumber[abs(eg->layers)] = atoi(argv[arg+2]);
+ eg->layerthickness[abs(eg->layers)] = atof(argv[arg+3]);
+ eg->layerratios[abs(eg->layers)] = atof(argv[arg+4]);
+ eg->layerparents[abs(eg->layers)] = 0;
+ eg->layers--;
+ }
+ }
+
+ if(strcmp(argv[arg],"-3d") == 0) {
+ eg->dim = dim = 3;
+ }
+ if(strcmp(argv[arg],"-2d") == 0) {
+ eg->dim = dim = 2;
+ }
+ if(strcmp(argv[arg],"-1d") == 0) {
+ eg->dim = dim = 1;
+ }
+
+ if(strcmp(argv[arg],"-isoparam") == 0) {
+ eg->isoparam = TRUE;
+ }
+ if(strcmp(argv[arg],"-nobound") == 0) {
+ eg->saveboundaries = FALSE;
+ }
+ if(strcmp(argv[arg],"-vtuone") == 0) {
+ eg->vtuone = TRUE;
+ }
+ if(strcmp(argv[arg],"-nosave") == 0) {
+ eg->nosave = TRUE;
+ }
+ if(strcmp(argv[arg],"-nooverwrite") == 0) {
+ eg->nooverwrite = TRUE;
+ }
+ if(strcmp(argv[arg],"-timer") == 0) {
+ eg->timeron = TRUE;
+ }
+
+ if(strcmp(argv[arg],"-infofile") == 0) {
+ eg->timeron = TRUE;
+ if(arg+1 >= argc) {
+ printf("The output name is required as a parameter\n");
+ return(2);
+ }
+ else {
+ strcpy(eg->infofile,argv[arg+1]);
+ }
+ }
+
+
+ /* The following keywords are not actively used */
+
+ if(strcmp(argv[arg],"-bcoffset") == 0) {
+ eg->bcoffset = atoi(argv[arg+1]);
+ }
+ if(strcmp(argv[arg],"-noelements") == 0) {
+ eg->elements3d = atoi(argv[arg+1]);
+ }
+ if(strcmp(argv[arg],"-nonodes") == 0) {
+ eg->nodes3d = atoi(argv[arg+1]);
+ }
+
+ if(strcmp(argv[arg],"-sidefind") == 0) {
+ eg->findsides = 0;
+ for(i=arg+1;isidebulk[i-1-arg] = atoi(argv[i]);
+ eg->findsides++;
+ }
+ }
+ if(strcmp(argv[arg],"-findbound") == 0) {
+ eg->findsides = 0;
+ for(i=arg+1;i+1sidebulk[i-1-arg] = atoi(argv[i]);
+ eg->sidebulk[i-arg] = atoi(argv[i+1]);
+ eg->findsides++;
+ }
+ }
+ }
+
+ {
+ int badpoint;
+ char *ptr1,*ptr2;
+ ptr1 = strrchr(eg->filesout[0], '.');
+ if(ptr1) {
+ badpoint=FALSE;
+ ptr2 = strrchr(eg->filesout[0], '/');
+ if(ptr2 && ptr2 > ptr1) badpoint = TRUE;
+ if(!badpoint) *ptr1 = '\0';
+ }
+ }
+
+ printf("Output will be saved to file %s.\n",eg->filesout[0]);
+
+ return(0);
+}
+
+
+
+
+int LoadCommands(char *prefix,struct ElmergridType *eg,
+ struct GridType *grid, int mode,int info)
+{
+ char filename[MAXFILESIZE];
+ char command[MAXLINESIZE],params[MAXLINESIZE],*cp;
+
+ FILE *in=NULL;
+ int i,j,iostat;
+
+ iodebug = FALSE;
+
+ if( mode == 0) {
+ if (in = fopen("ELMERGRID_STARTINFO","r")) {
+ iostat = fscanf(in,"%s",filename);
+ fclose(in);
+ printf("Using the file %s defined in ELMERGRID_STARTINFO\n",filename);
+ if ((in = fopen(filename,"r")) == NULL) {
+ printf("LoadCommands: opening of the file '%s' wasn't successful !\n",filename);
+ return(1);
+ }
+ else printf("Loading ElmerGrid commands from file '%s'.\n",filename);
+ }
+ else
+ return(2);
+ }
+ else if(mode == 1) {
+ AddExtension(prefix,filename,"eg");
+ if ((in = fopen(filename,"r")) == NULL) {
+ printf("LoadCommands: opening of the file '%s' wasn't successful !\n",filename);
+ return(3);
+ }
+ if(info) printf("Loading ElmerGrid commands from file '%s'.\n",filename);
+ }
+ else if(mode == 2) {
+ AddExtension(prefix,filename,"grd");
+ if ((in = fopen(filename,"r")) == NULL) {
+ printf("LoadCommands: opening of the file '%s' wasn't successful !\n",filename);
+ return(4);
+ }
+ if(info) printf("\nLoading ElmerGrid commands from file '%s'.\n",filename);
+ }
+
+
+
+ for(;;) {
+
+ if(GetCommand(command,params,in)) {
+ printf("Reached the end of command file\n");
+ goto end;
+ }
+
+ /* If the mode is the command file mode read also the file information from the command file. */
+
+ if(mode <= 1) {
+ if(strstr(command,"INPUT FILE")) {
+ sscanf(params,"%s",eg->filesin[0]);
+ }
+
+ else if(strstr(command,"OUTPUT FILE")) {
+ sscanf(params,"%s",eg->filesout[0]);
+ }
+
+ else if(strstr(command,"INPUT MODE")) {
+ for(j=0;jinmethod = i;
+ break;
+ }
+ }
+ if(i>MAXINMETHODS) sscanf(params,"%d",&eg->inmethod);
+ }
+
+ else if(strstr(command,"OUTPUT MODE")) {
+ for(j=0;joutmethod = i;
+ break;
+ }
+ }
+ if(i>MAXOUTMETHODS) sscanf(params,"%d",&eg->outmethod);
+ }
+ }
+ /* End of command file specific part */
+
+
+ if(strstr(command,"DECIMALS")) {
+ sscanf(params,"%d",&eg->decimals);
+ }
+ else if(strstr(command,"BOUNDARY OFFSET")) {
+ sscanf(params,"%d",&eg->bcoffset);
+ }
+ else if(strstr(command,"TRIANGLES CRITICAL ANGLE")) {
+ sscanf(params,"%le",&eg->triangleangle);
+ }
+ else if(strstr(command,"TRIANGLES")) {
+ for(j=0;jtriangles = TRUE;
+ }
+ else if(strstr(command,"MERGE NODES")) {
+ eg->merge = TRUE;
+ sscanf(params,"%le",&eg->cmerge);
+ }
+ else if(strstr(command,"UNITE")) {
+ for(j=0;junitemeshes = TRUE;
+ }
+ else if(strstr(command,"UNITENOOVERLAP")) {
+ for(j=0;junitemeshes = TRUE;
+ eg->unitenooverlap = TRUE;
+ }
+ }
+
+ else if(strstr(command,"ORDER NODES")) {
+ eg->order = TRUE;
+ if(eg->dim == 1)
+ sscanf(params,"%le",&eg->corder[0]);
+ else if(eg->dim == 2)
+ sscanf(params,"%le%le",&eg->corder[0],&eg->corder[1]);
+ else if(eg->dim == 3)
+ sscanf(params,"%le%le%le",&eg->corder[0],&eg->corder[1],&eg->corder[2]);
+ }
+ else if(strstr(command,"SCALE")) {
+ eg->scale = TRUE;
+ if(eg->dim == 1)
+ sscanf(params,"%le",&eg->cscale[0]);
+ else if(eg->dim == 2)
+ sscanf(params,"%le%le",&eg->cscale[0],&eg->cscale[1]);
+ else if(eg->dim == 3)
+ sscanf(params,"%le%le%le",&eg->cscale[0],&eg->cscale[1],&eg->cscale[2]);
+ }
+ else if(strstr(command,"CENTRALIZE")) {
+ eg->center = TRUE;
+ }
+ else if(strstr(command,"TRANSLATE")) {
+ eg->translate = TRUE;
+ if(eg->dim == 1)
+ sscanf(params,"%le",&eg->ctranslate[0]);
+ else if(eg->dim == 2)
+ sscanf(params,"%le%le",&eg->ctranslate[0],&eg->ctranslate[1]);
+ else if(eg->dim == 3)
+ sscanf(params,"%le%le%le",&eg->ctranslate[0],&eg->ctranslate[1],&eg->ctranslate[2]);
+ }
+ else if(strstr(command,"ROTATE MESH")) {
+ eg->rotate = TRUE;
+ sscanf(params,"%le%le%le",&eg->crotate[0],&eg->crotate[1],&eg->crotate[2]);
+ }
+ else if(strstr(command,"CLONE")) {
+ if(strstr(command,"CLONE SIZE")) {
+ if(eg->dim == 1)
+ sscanf(params,"%le",&eg->clonesize[0]);
+ else if(eg->dim == 2)
+ sscanf(params,"%le%le",&eg->clonesize[0],&eg->clonesize[1]);
+ else if(eg->dim == 3)
+ sscanf(params,"%le%le%le",&eg->clonesize[0],&eg->clonesize[1],&eg->clonesize[2]);
+ }
+ else {
+ if(eg->dim == 1)
+ sscanf(params,"%d",&eg->clone[0]);
+ else if(eg->dim == 2)
+ sscanf(params,"%d%d",&eg->clone[0],&eg->clone[1]);
+ else if(eg->dim == 3)
+ sscanf(params,"%d%d%d",&eg->clone[0],&eg->clone[1],&eg->clone[2]);
+ }
+ }
+ else if(strstr(command,"MERGE")) {
+ eg->merge = TRUE;
+ sscanf(params,"%le",&eg->cmerge);
+ }
+ else if(strstr(command,"MIRROR")) {
+ if(eg->dim == 1)
+ sscanf(params,"%d",&eg->mirror[0]);
+ else if(eg->dim == 2)
+ sscanf(params,"%d%d",&eg->mirror[0],&eg->mirror[1]);
+ else if(eg->dim == 3)
+ sscanf(params,"%d%d%d",&eg->mirror[0],&eg->mirror[1],&eg->mirror[2]);
+ }
+ else if(strstr(command,"POLAR RADIUS")) {
+ eg->polar = TRUE;
+ sscanf(params,"%le",&eg->polarradius);
+ }
+ else if(strstr(command,"CYLINDER")) {
+ for(j=0;jcylinder = TRUE;
+ }
+ else if(strstr(command,"REDUCE DEGREE")) {
+ eg->reduce = TRUE;
+ sscanf(params,"%d%d",&eg->reducemat1,&eg->reducemat2);
+ }
+ else if(strstr(command,"INCREASE DEGREE")) {
+ for(j=0;jincrease = TRUE;
+ }
+ else if(strstr(command,"METIS OPTION")) {
+#if USE_METIS
+ sscanf(params,"%d",&eg->partopt);
+#else
+ printf("This version of ElmerGrid was compiled without Metis library!\n");
+#endif
+ }
+ else if(strstr(command,"METIS")) {
+#if USE_METIS
+ sscanf(params,"%d",&eg->metis);
+#else
+ printf("This version of ElmerGrid was compiled without Metis library!\n");
+#endif
+ }
+ else if(strstr(command,"METISKWAY")) {
+#if USE_METIS
+ sscanf(params,"%d",&eg->metis);
+ eg->partopt = 3;
+#else
+ printf("This version of ElmerGrid was compiled without Metis library!\n");
+#endif
+ }
+ else if(strstr(command,"METISREC")) {
+#if USE_METIS
+ sscanf(params,"%d",&eg->metis);
+ eg->partopt = 2;
+#else
+ printf("This version of ElmerGrid was compiled without Metis library!\n");
+#endif
+ }
+ else if(strstr(command,"PARTITION DUAL")) {
+ for(j=0;jpartdual = TRUE;
+ }
+ else if(strstr(command,"PARTJOIN")) {
+ sscanf(params,"%d",&eg->partjoin);
+ }
+ else if(strstr(command,"PARTITION ORDER")) {
+ eg->partorder = 1;
+ if(eg->dim == 2) sscanf(params,"%le%le",&eg->partcorder[0],&eg->partcorder[1]);
+ if(eg->dim == 3) sscanf(params,"%le%le%le",&eg->partcorder[0],
+ &eg->partcorder[1],&eg->partcorder[2]);
+ }
+ else if(strstr(command,"PARTITION") || strstr(command,"PARTCYL") || strstr(command,"PARTCELL")) {
+ if(eg->dim == 2) sscanf(params,"%d%d",&eg->partdim[0],&eg->partdim[1]);
+ if(eg->dim == 3) sscanf(params,"%d%d%d",&eg->partdim[0],&eg->partdim[1],&eg->partdim[2]);
+ eg->partitions = 1;
+ for(i=0;idim;i++) {
+ if(eg->partdim[i] < 1) eg->partdim[i] = 1;
+ eg->partitions *= eg->partdim[i];
+ }
+ if( strstr(command,"PARTCYL") ) eg->partopt = 3;
+ if( strstr(command,"PARTCCELL") ) eg->partopt = 2;
+ }
+ else if(strstr(command,"PERIODIC")) {
+ if(eg->dim == 2) sscanf(params,"%d%d",&eg->periodicdim[0],&eg->periodicdim[1]);
+ if(eg->dim == 3) sscanf(params,"%d%d%d",&eg->periodicdim[0],
+ &eg->periodicdim[1],&eg->periodicdim[2]);
+ }
+ else if(strstr(command,"HALO")) {
+ for(j=0;jparthalo[1] = TRUE;
+ }
+ else if(strstr(command,"BOUNDARY HALO")) {
+ for(j=0;jparthalo[2] = TRUE;
+ }
+ else if(strstr(command,"EXTRUDED HALO")) {
+ for(j=0;jparthalo[3] = TRUE;
+ }
+ else if(strstr(command,"GREEDY HALO")) {
+ for(j=0;jparthalo[4] = TRUE;
+ }
+ else if(strstr(command,"PARTBW")) {
+ for(j=0;jpartbw = TRUE;
+ }
+ else if(strstr(command,"PARTHYPRE")) {
+ for(j=0;jparthypre = TRUE;
+ }
+ else if(strstr(command,"INDIRECT")) {
+ for(j=0;jpartitionindirect = TRUE;
+ }
+ else if(strstr(command,"BOUNDARY TYPE MAPPINGS")) {
+ for(i=0;i0) Getline(params,in);
+ for(j=0;jsidemap[3*i],&eg->sidemap[3*i+1],&eg->sidemap[3*i+2]);
+ }
+ printf("Found %d boundary type mappings\n",i);
+ eg->sidemappings = i;
+ }
+ else if(strstr(command,"BULK TYPE MAPPINGS")) {
+ for(i=0;i0) Getline(params,in);
+ for(j=0;jbulkmap[3*i],&eg->bulkmap[3*i+1],&eg->bulkmap[3*i+2]);
+ }
+ printf("Found %d bulk type mappings\n",i);
+ eg->bulkmappings = i;
+ }
+ else if(strstr(command,"COORDINATE MAPPING")) {
+ sscanf(params,"%d%d%d",&eg->coordinatemap[0],&eg->coordinatemap[1],&eg->coordinatemap[2]);
+ }
+ else if(strstr(command,"BOUNDARY BOUNDARY")) {
+ for(i=0;i0) Getline(params,in);
+ for(j=0;jboundbound[3*i+2],&eg->boundbound[3*i],&eg->boundbound[3*i+1]);
+ }
+ printf("Found %d boundary boundary definitions\n",i);
+ eg->boundbounds = i;
+ }
+ else if(strstr(command,"MATERIAL BOUNDARY")) {
+ for(i=0;i0) Getline(params,in);
+ for(j=0;jbulkbound[3*i+2],&eg->bulkbound[3*i],&eg->bulkbound[3*i+1]);
+ }
+ printf("Found %d material boundary definitions\n",i);
+ eg->bulkbounds = i;
+ }
+
+ else if(strstr(command,"RENUMBER BOUNDARY")) {
+ for(i=0;isidemap[3*i],&eg->sidemap[3*i+1],&eg->sidemap[3*i+2]);
+ }
+ printf("Found %d boundary mappings\n",i);
+ eg->sidemappings = i;
+ }
+ else if(strstr(command,"RENUMBER MATERIAL")) {
+ for(i=0;ibulkmap[3*i],&eg->bulkmap[3*i+1],&eg->bulkmap[3*i+2]);
+ }
+ printf("Found %d material mappings\n",i);
+ eg->bulkmappings = i;
}
-
- else if(strstr(command,"ELEMENT RATIOS 1")) {
- cp = params;
- for(i=1;i<=(*grid)[k].xcells;i++) (*grid)[k].xexpand[i] = next_real(&cp);
+
+ else if(strstr(command,"BOUNDARY LAYER")) {
+ if(strstr(command,"BOUNDARY LAYER MOVE")) {
+ sscanf(params,"%d",&eg->layermove);
+ }
+ else if(strstr(command,"BOUNDARY LAYER EPSILON")) {
+ sscanf(params,"%le",&eg->layereps);
+ }
+ else {
+ for(i=0;i0) Getline(params,in);
+ for(j=0;jlayerbounds[i] = next_int(&cp);
+ eg->layernumber[i] = next_int(&cp);
+ eg->layerthickness[i] = next_real(&cp);
+ eg->layerratios[i] = next_real(&cp);
+ eg->layerparents[i] = next_int(&cp);
+ }
+ printf("Found %d boundary layers\n",i);
+ eg->layers = i;
+ }
}
- else if(strstr(command,"ELEMENT RATIOS 2")) {
- cp = params;
- for(i=1;i<=(*grid)[k].ycells;i++) (*grid)[k].yexpand[i] = next_real(&cp);
+ else if(strstr(command,"REMOVE LOWER DIMENSIONAL BOUNDARIES")) {
+ for(j=0;jremovelowdim = TRUE;
}
- else if(strstr(command,"ELEMENT RATIOS 3")) {
- cp = params;
- for(i=1;i<=(*grid)[k].zcells;i++) (*grid)[k].zexpand[i] = next_real(&cp);
+ else if(strstr(command,"REMOVE INTERNAL BOUNDARIES")) {
+ for(j=0;jremoveintbcs = TRUE;
}
-
- else if(strstr(command,"ELEMENT DENSITIES 1")) {
- cp = params;
- for(i=1;i<=(*grid)[k].xcells;i++) (*grid)[k].xdens[i] = next_real(&cp);
+ else if(strstr(command,"REMOVE UNUSED NODES")) {
+ for(j=0;jremoveunused = TRUE;
}
- else if(strstr(command,"ELEMENT DENSITIES 2")) {
- cp = params;
- for(i=1;i<=(*grid)[k].ycells;i++) (*grid)[k].ydens[i] = next_real(&cp);
+ else if(strstr(command,"NO MESH NAMES")) {
+ for(j=0;jusenames = FALSE;
}
- else if(strstr(command,"ELEMENT DENSITIES 3")) {
- cp = params;
- for(i=1;i<=(*grid)[k].zcells;i++) (*grid)[k].zdens[i] = next_real(&cp);
+ else if(strstr(command,"REORDER MATERIAL")) {
+ for(j=0;jbulkorder = TRUE;
}
-
- else if(strstr(command,"ELEMENT DIVISIONS 1")) {
- cp = params;
- for(i=1;i<=(*grid)[k].xcells;i++) (*grid)[k].xelems[i] = next_int(&cp);
- (*grid)[k].autoratio = 0;
+ else if(strstr(command,"REORDER BOUNDARY")) {
+ for(j=0;jboundorder = TRUE;
}
- else if(strstr(command,"ELEMENT DIVISIONS 2")) {
- cp = params;
- for(i=1;i<=(*grid)[k].ycells;i++) (*grid)[k].yelems[i] = next_int(&cp);
- (*grid)[k].autoratio = 0;
+ else if(strstr(command,"DIMENSION")) {
+ sscanf(params,"%d",&eg->dim);
}
- else if(strstr(command,"ELEMENT DIVISIONS 3")) {
- cp = params;
- for(i=1;i<=(*grid)[k].zcells;i++) (*grid)[k].zelems[i] = next_int(&cp);
- (*grid)[k].autoratio = 0;
+ else if(strstr(command,"ISOPARAMETRIC")) {
+ for(j=0;jisoparam = TRUE;
}
-
- else if(strstr(command,"EXTRUDED STRUCTURE")) {
- for(i=1;i<=(*grid)[k].zcells;i++) {
- if(i>1) Getline(params,in);
- sscanf(params,"%d %d %d\n",
- &(*grid)[k].zfirstmaterial[i],&(*grid)[k].zlastmaterial[i],&(*grid)[k].zmaterial[i]);
- }
+ else if(strstr(command,"NO BOUNDARY")) {
+ for(j=0;jsaveboundaries = FALSE;
}
-
- else if(strstr(command,"GEOMETRY MAPPINGS")) {
- if(k > 0) (*grid)[k].mappings = 0;
-
+ else if(strstr(command,"LAYERED BOUNDARIES")) {
for(i=0;i(*grid)[k].mappings) Getline(params,in);
-
- if(strstr(params,"END")) break;
- cp=params;
- (*grid)[k].mappingtype[i] = next_int(&cp);
-#if 0
- (*grid)[k].mappingtype[i] += 50*SGN((*grid)[k].mappingtype[i]);
-#endif
- (*grid)[k].mappingline[i] = next_int(&cp);
- (*grid)[k].mappinglimits[2*i] = next_real(&cp);
- (*grid)[k].mappinglimits[2*i+1] = next_real(&cp);
- (*grid)[k].mappingpoints[i] = next_int(&cp);
- (*grid)[k].mappingparams[i] = Rvector(0,(*grid)[k].mappingpoints[i]);
- for(j=0;j<(*grid)[k].mappingpoints[i];j++)
- (*grid)[k].mappingparams[i][j] = next_real(&cp);
- }
- if(0) printf("Loaded %d geometry mappings\n",i);
- (*grid)[k].mappings = i;
+ if(strstr(params,"TRUE")) grid->layeredbc = 1;
+ if(strstr(params,"FALSE")) grid->layeredbc = 0;
}
+ else if(strstr(command,"EXTRUDED")) {
+ grid->dimension = 3;
- else if(strstr(command,"END") ) {
- if(0) printf("End of field\n");
- }
-
- else if(strstr(command,"START NEW MESH")) {
- if((*nogrids) >= MAXCASES) {
- printf("There are more grids than was allocated for!\n");
- printf("Ignoring meshes starting from %d\n.",(*nogrids)+1);
- goto end;
+ if(strstr(command,"EXTRUDED DIVISIONS")) {
+ sscanf(params,"%d",&grid->zcells);
+ }
+ if(strstr(command,"EXTRUDED BC OFFSET")) {
+ sscanf(params,"%d",&grid->layerbcoffset);
+ }
+ else if(strstr(command,"EXTRUDED LIMITS")) {
+ cp = params;
+ for(i=0;i<=grid->zcells;i++ ) {
+ grid->z[i] = next_real(&cp);
+ if(i > 0 && grid->z[i] < grid->z[i-1]) {
+ printf("Extruded limits %d: %12.6le %12.6le\n",i,grid->z[i],grid->z[i-1]);
+ bigerror("Values for limits should be a growing series, existing\n");
+ }
+ }
+ }
+ else if(strstr(command,"EXTRUDED SIZES")) {
+ cp = params;
+ for(i=1;i<=grid->zcells;i++) grid->z[i] = next_real(&cp);
+ for(i=1;i<=grid->zcells;i++) grid->z[i] = grid->z[i-1] + grid->z[i];
+ }
+ else if(strstr(command,"EXTRUDED ELEMENTS")) {
+ cp = params;
+ for(i=1;i<=grid->zcells;i++) grid->zelems[i] = next_int(&cp);
+ grid->autoratio = FALSE;
+ }
+ else if(strstr(command,"EXTRUDED RATIOS")) {
+ cp = params;
+ for(i=1;i<=grid->zcells;i++) grid->zexpand[i] = next_real(&cp);
+ }
+ else if(strstr(command,"EXTRUDED DENSITIES")) {
+ cp = params;
+ for(i=1;i<=grid->zcells;i++) grid->zdens[i] = next_real(&cp);
+ }
+ else if(strstr(command,"EXTRUDED STRUCTURE")) {
+ for(i=1;i<= grid->zcells;i++) {
+ if(i>1) Getline(params,in);
+ sscanf(params,"%d %d %d\n",
+ &grid->zfirstmaterial[i],&grid->zlastmaterial[i],&grid->zmaterial[i]);
+ }
+ }
+ else if(strstr(command,"EXTRUDED MAX MATERIAL")) {
+ sscanf(params,"%d",&grid->maxmaterial);
+ }
+ else if(strstr(command,"EXTRUDED MATERIAL MAPPINGS")) {
+ grid->zmaterialmap = Imatrix(1,grid->zcells,1,grid->maxmaterial);
+ for(i=1;i<=grid->zcells;i++) {
+ if(i>1) Getline(params,in);
+ cp = params;
+ for(j=1;j<=grid->maxmaterial;j++)
+ grid->zmaterialmap[i][j] = next_int(&cp);
+ }
+ grid->zmaterialmapexists = TRUE;
+ }
+ else if(strstr(command,"EXTRUDED HELICITY")) {
+ sscanf(params,"%le",&grid->zhelicity);
+ grid->zhelicityexists = TRUE;
}
- (*nogrids)++;
- if(0) printf("\nLoading element meshing no %d\n",*nogrids);
- k = *nogrids - 1;
- if(k > nogrids0) (*grid)[k] = (*grid)[k-1];
- }
- else {
- if(1) printf("Unknown command: %s",command);
}
}
end:
+ printf("Read commands from a file\n");
- if(0) printf("Found %d divisions for grid\n",*nogrids);
-
- for(k=nogrids0;k < (*nogrids) && krelh = 1.0;
- eg->inmethod = 0;
- eg->outmethod = 0;
- eg->silent = FALSE;
- eg->nofilesin = 1;
- eg->unitemeshes = FALSE;
- eg->triangles = FALSE;
- eg->triangleangle = 0.0;
- eg->rotate = FALSE;
- eg->polar = FALSE;
- eg->cylinder = FALSE;
- eg->usenames = FALSE;
- eg->layers = 0;
- eg->layereps = 0.0;
- eg->layermove = 0;
- eg->partitions = 0;
- eg->elements3d = 0;
- eg->nodes3d = 0;
- eg->metis = 0;
- eg->partitionhalo = FALSE;
- eg->partitionindirect = FALSE;
- eg->reduce = FALSE;
- eg->increase = FALSE;
- eg->translate = FALSE;
- eg->isoparam = FALSE;
- eg->removelowdim = FALSE;
- eg->removeunused = FALSE;
- eg->dim = 3;
- eg->center = FALSE;
- eg->scale = FALSE;
- eg->order = FALSE;
- eg->boundbounds = 0;
- eg->saveinterval[0] = eg->saveinterval[1] = eg->saveinterval[2] = 0;
- eg->bulkbounds = 0;
- eg->partorder = FALSE;
- eg->findsides = FALSE;
- eg->pelems = 0;
- eg->belems = 0;
- eg->saveboundaries = TRUE;
- eg->merge = FALSE;
- eg->bcoffset = FALSE;
- eg->periodic = 0;
- eg->periodicdim[0] = 0;
- eg->periodicdim[1] = 0;
- eg->periodicdim[2] = 0;
- eg->bulkorder = FALSE;
- eg->boundorder = FALSE;
- eg->sidemappings = 0;
- eg->bulkmappings = 0;
- eg->clone[0] = eg->clone[1] = eg->clone[2] = 0;
- eg->decimals = 12;
- eg->discont = 0;
- eg->connect = 0;
- eg->advancedmat = 0;
+ hit = FALSE;
+ elemsides = 0;
+ elemtype = 0;
+ hit1 = FALSE;
+ hit2 = FALSE;
+
+ debug = FALSE;
- for(i=0;isidebulk[i] = 0;
+ for(parent=1;parent<=2;parent++) {
+ if(parent == 1)
+ elemind = bound->parent[sideelem];
+ else
+ elemind = bound->parent2[sideelem];
+
+ if(elemind > 0) {
+ elemtype = data->elementtypes[elemind];
+ elemsides = elemtype / 100;
+
+ if(elemsides == 8) elemsides = 6;
+ else if(elemsides == 7) elemsides = 5;
+ else if(elemsides == 6) elemsides = 5;
+ else if(elemsides == 5) elemsides = 4;
+
+ for(normal=1;normal >= -1;normal -= 2) {
+
+ for(side=0;side 300) break;
+ if(sideelemtype2 < 200 && sideelemtype > 200) break;
+ if(sideelemtype != sideelemtype2) continue;
+
+ sidenodes = sideelemtype / 100;
+
+ for(j=0;jside[sideelem] = side;
+ bound->normal[sideelem] = normal;
+ }
+ else {
+ hit2 = TRUE;
+ bound->side2[sideelem] = side;
+ }
+ goto skip;
+ }
+ }
+ }
+ }
+
+
+ /* this finding of sides does not guarantee that normals are oriented correctly */
+ normal = 1;
+ hit = FALSE;
+
+ for(side=0;;side++) {
+
+ if(0) printf("side = %d\n",side);
+
+ GetElementSide(elemind,side,normal,data,&sideind2[0],&sideelemtype2);
+
+ if(sideelemtype2 == 0 ) break;
+ if(sideelemtype2 < 300 && sideelemtype > 300) break;
+ if(sideelemtype2 < 200 && sideelemtype > 200) break;
+ if(sideelemtype != sideelemtype2) continue;
+
+ sidenodes = sideelemtype % 100;
+
+ nohits = 0;
+ for(j=0;jside[sideelem] = side;
+ }
+ else {
+ hit2 = TRUE;
+ bound->side2[sideelem] = side;
+ }
+ goto skip;
+ }
+
+ }
+
+ skip:
+ if(!hit) {
+ printf("FindParentSide: cannot locate BC element in parent %d: %d\n",parent,elemind);
+ printf("BC elem %d of type %d with corner indexes: ",sideelem,sideelemtype);
+ for(i=0;i= 5 && j<=7 ) j = j-1;
+ for(i=0;itopology[elemind][i]);
+ printf("\n");
+ }
+ }
+ }
+
+ if(hit1 || hit2)
+ return(0);
+ else
+ return(1);
}
+static int Getnamerow(char *line,FILE *io,int upper)
+{
+ int i,isend;
+ char *charend;
+ charend = fgets(line,MAXLINESIZE,io);
+ isend = (charend == NULL);
+ if(isend)
+ return(1);
+ else
+ return(0);
+}
-int LoadCommands(char *prefix,struct ElmergridType *eg,
- struct GridType *grid, int mode,const char *IOmethods[],
- int info)
+
+
+int LoadElmerInput(struct FemType *data,struct BoundaryType *bound,
+ char *prefix,int nonames, int info)
+/* This procedure reads the mesh assuming ElmerSolver format.
+ */
{
- char filename[MAXFILESIZE],command[MAXLINESIZE],params[MAXLINESIZE],*cp;
+ int noknots,noelements,nosides,maxelemtype,maxnodes,nonodes;
+ int sideind[MAXNODESD1],tottypes,elementtype;
+ int i,j,k,l,dummyint,cdstat,fail;
+ int falseparents,noparents,bctopocreated;
+ int activeperm,activeelemperm,mini,maxi,minelem,maxelem,p1,p2;
+ int *nodeperm,*elemperm,*invperm,*invelemperm;
+ int iostat,noelements0;
+ FILE *in;
+ char line[MAXLINESIZE],line2[MAXLINESIZE],filename[MAXFILESIZE],directoryname[MAXFILESIZE];
+ char *ptr1,*ptr2;
- FILE *in = NULL;
- int i,j;
- if( mode == 0) {
- if (in = fopen("ELMERGRID_STARTINFO","r")) {
- fscanf(in,"%s",filename);
- fclose(in);
- printf("Using the file %s defined in ELMERGRID_STARTINFO\n",filename);
- if ((in = fopen(filename,"r")) == NULL) {
- printf("LoadCommands: opening of the file '%s' wasn't successful!\n",filename);
- return(1);
- }
- else printf("Loading ElmerGrid commands from file '%s'.\n",filename);
- }
- else
- return(2);
+ sprintf(directoryname,"%s",prefix);
+ cdstat = chdir(directoryname);
+
+ if(info) {
+ if(cdstat)
+ printf("Loading mesh in ElmerSolver format from root directory.\n");
+ else
+ printf("Loading mesh in ElmerSolver format from directory %s.\n",directoryname);
}
- if(mode == 1) {
- AddExtension(prefix,filename,"eg");
- if ((in = fopen(filename,"r")) == NULL) {
- printf("LoadCommands: opening of the file '%s' wasn't successful!\n",filename);
- return(3);
- }
- if(info) printf("Loading ElmerGrid commands from file '%s'.\n",filename);
+
+ InitializeKnots(data);
+
+
+ sprintf(filename,"%s","mesh.header");
+ if ((in = fopen(filename,"r")) == NULL) {
+ printf("LoadElmerInput: The opening of the header-file %s failed!\n",
+ filename);
+ return(1);
}
- else if(mode == 2) {
- AddExtension(prefix,filename,"grd");
- if ((in = fopen(filename,"r")) == NULL) {
- printf("LoadCommands: opening of the file '%s' wasn't successful!\n",filename);
- return(4);
- }
- if(info) printf("Loading ElmerGrid commands from file '%s'.\n",filename);
+ else
+ printf("Loading header from %s\n",filename);
+
+ GETLINE;
+ sscanf(line,"%d %d %d",&noknots,&noelements,&nosides);
+ GETLINE;
+ sscanf(line,"%d",&tottypes);
+
+ maxelemtype = 0;
+ maxnodes = 0;
+ for(i=1;i<=tottypes;i++) {
+ GETLINE;
+ sscanf(line,"%d",&dummyint);
+ maxelemtype = MAX( dummyint, maxelemtype );
+ j = maxelemtype % 100;
+ maxnodes = MAX( j, maxnodes );
}
+ printf("Maximum elementtype index is: %d\n",maxelemtype);
+ printf("Maximum number of nodes in element is: %d\n",maxnodes);
+ fclose(in);
+ data->dim = GetElementDimension(maxelemtype);
+ data->maxnodes = maxnodes;
+ data->noknots = noknots;
+ data->noelements = noelements0 = noelements;
- for(;;) {
- if(GetCommand(command,params,in)) {
- if(0) printf("Reached the end of command file\n");
- goto end;
- }
+ if(info) printf("Allocating for %d knots and %d elements.\n",
+ noknots,noelements);
+ AllocateKnots(data);
- /* If the mode is the command file mode read also the file information from the command file. */
- if(mode <= 1) {
- if(strstr(command,"INPUT FILE")) {
- sscanf(params,"%s", &(eg->filesin[0]));
- }
+ sprintf(filename,"%s","mesh.nodes");
+ if ((in = fopen(filename,"r")) == NULL) {
+ if(info) printf("LoadElmerInput: The opening of the nodes-file %s failed!\n",
+ filename);
+ bigerror("Cannot continue without nodes file!\n");
+ }
+ else
+ printf("Loading %d Elmer nodes from %s\n",noknots,filename);
+
+ activeperm = FALSE;
+ for(i=1; i <= noknots; i++) {
+ GETLINE;
+ sscanf(line,"%d %d %le %le %le",
+ &j, &dummyint, &(data->x[i]),&(data->y[i]),&(data->z[i]));
+ if(j != i && !activeperm) {
+ printf("LoadElmerInput: The node number (%d) at node %d is not compact, creating permutation\n",j,i);
+ activeperm = TRUE;
+ nodeperm = Ivector(1,noknots);
+ for(k=1;k