/***********************************************************************
*
* ELMER, A Computational Fluid Dynamics Program.
*
* Copyright 1st April 1995 - , Center for Scientific Computing,
* Finland.
*
* All rights reserved. No part of this program may be used,
* reproduced or transmitted in any form or by any means
* without the written permission of CSC.
*
* Address: Center for Scientific Computing
* Tietotie 6, P.O. BOX 405
* 02101 Espoo, Finland
* Tel. +358 0 457 2001
* Telefax: +358 0 457 2302
* EMail: Jari.Jarvinen@csc.fi
************************************************************************/
/***********************************************************************
Program: ELMER Front
Module: ecif_inputThetis.cpp
Language: C++
Date: 01.10.98
Version: 1.00
Author(s): Martti Verho
Revisions:
Abstract: Implementation
************************************************************************/
#include "ecif_bodyElement.h"
#include "ecif_control.h"
#include "ecif_geometry.h"
#include "ecif_inputThetis.h"
#include "ecif_model.h"
#include "ecif_userinterface.h"
#include "ecif_timer.h"
extern char read_buffer[];
InputThetis::InputThetis(enum ecif_modelDimension m_dim,
ifstream& in_file, char* in_filename):
Input(m_dim, in_file, in_filename)
{
}
enum ecif_modelDimension
InputThetis::findModelDimension(ifstream& in_file) {
return modelDimension;
}
//---Create and update mesh tables
bool
InputThetis::processMeshFileData()
{
Timer timer;
double time, time1, time2;
UserInterface* gui = theControlCenter->getGui();
MeshElementTable* bt = model->getMeshBulkElements();
MeshElementTable* bet = model->getMeshBoundaryElements();
//---Create BULK element connections (neighor ids, sub element indices
timer.start(); time1 = 0;
gui->showMsg("---Creating volume element connections ...");
time2 = timer.getLapTime(WALL_TIME); time = time2 - time1; time1 = time2;
gui->showUsedTimeMsg(time, "---Creating volume element connections", (short)0, false);
//---Create bulk element edges
model->createMeshBulkElementEdges();
//---Find mesh boundary element neighbors
model->findMeshElementNeighbors(bet);
//---Create boundary element edges
model->createMeshBoundaryElementEdges();
//---Finish
timer.stop();
time = timer.getEndTime(WALL_TIME);
gui->showUsedTimeMsg(time, "Creating mesh bodies and boundaries", 1, true);
return modelDimension;
}
// Read nodes and elements from the Thetis Mesh File (.tmf)
bool
InputThetis::readMeshGeometry()
{
int i;
int nofNodes, nofElements;
int nofBodies;
int nofBoundaries;
int nofBoundaryElements; // Fem elements
Rc rc;
// Read header information
readFileLine(infile, read_buffer);
istrstream strmline(read_buffer);
if (! (strmline >> nofNodes >> maxExternalNodeId
>> nofElements >> maxExternalElementId
>> nofBodies
>> nofBoundaries
>> nofBoundaryElements
)
) {
cerr << endl << "ERROR: in reading mesh header info in InputThetis::readMeshGeoemtry";
return false;
}
//---Allocate basic tables in the model
model->allocateMeshBodies(nofBodies);
model->allocateMeshNodes(nofNodes, maxExternalNodeId);
model->allocateMeshInputElements(nofElements, maxExternalElementId);
//---Read nodes from the mesh input file
if ( ECIF_OK != readMeshNodes(nofNodes) )
return false;
//---Read volume elements from the mesh input file
// NOTE: model dimension known only after reading
// volume elements
if ( ECIF_OK != readMeshElements(nofElements) ) return false;
//---Read all boundary elements from the mesh input file
// NOTE: We cannot read Thetis boundary elements, because we do not know the
// material (body id) for them, tehy must be created from bulk faces!!!
//
//if ( ECIF_OK != readMeshBoundaryElements(nofBoundaryElements) ) return false;
model->setModelDimension(modelDimension);
if (modelDimension == ECIF_ND) return false;
model->setMeshNodes();
return true;
}
// Read a boundary element from the Thetis Mesh File and store it into the model.
bool
InputThetis::read_boundary()
{
UserInterface* gui = theControlCenter->getGui();
int i;
bool result_code = true;
int boundary_tag, external_body1_tag, external_body2_tag;
int nof_bndr_elements;
readFileLine(infile, read_buffer);
istrstream strmline(read_buffer);
if ( !(strmline >> boundary_tag
>> external_body1_tag >> external_body2_tag
>> nof_bndr_elements) ) {
gui->errMsg(1, "could not read boundary data in InputThetis::read_boundaries()");
return false;
}
int body1_tag = model->getBodyTagExt2Int(external_body1_tag);
int body2_tag = model->getBodyTagExt2Int(external_body2_tag);
int body1_lr = 0;
int body2_lr = 0;
// Check if boundary is already stored (as a normal model boundary!)
BodyElement* be;
if ( model->getDimension() == ECIF_2D )
be = model->getEdgeByTag(boundary_tag);
else
be = model->getFaceByTag(boundary_tag);
if (be != NULL) {
be->allocateMeshElements(nof_bndr_elements);
} else {
model->createBodyElement(boundary_tag, body1_tag, body1_lr, body2_tag, body2_lr, nof_bndr_elements);
}
return result_code;
}
// Read a boundary element from the Thetis Mesh File and store it into the model.
Rc
InputThetis::readMeshBoundaryElements(int nof_bndr_elements)
{
UserInterface* gui = theControlCenter->getGui();
bool result_code = true;
int sequence_nbr, bndr_tag;
int ext_parent1_id, ext_parent2_id;
int ext_body1_tag, ext_body2_tag;
int elem_type, nof_nodes;
meshElementCode elem_code;
static int ext_node_ids[MAX_NOF_BNDR_NODES];
char* strm_buffer = new char[BUFFER_LEN];
strstream strm(strm_buffer, BUFFER_LEN, ios::app);
short i;
for (int index = 0; index < nof_bndr_elements; index++) {
readFileLine(infile, read_buffer);
reset(strm);
strm << read_buffer << ends;
if ( !(strm >> sequence_nbr
>> bndr_tag
>> ext_parent1_id
>> ext_parent2_id
>> ext_body1_tag
>> ext_body2_tag
>> elem_type
)
) {
gui->errMsg(1, "could not read element data-1 in InputThetis::read_boundary_element()");
return ECIF_ERROR;
}
// Read nodes for the element (external ids!)
if ( !(strm >> nof_nodes) ) {
gui->errMsg(1, "could not read nof nodes per element in InputThetis::read_boundary_element()");
return ECIF_ERROR;
}
// NOTE: For boundary elements we have to convert id "manually", because
// they where not yet available when createMeshBodyTables (which
// converts bulk elem- and node-ids) was called
for (i = 0; i < nof_nodes; i++) {
if (!(strm >> ext_node_ids[i])) {
gui->errMsg(1, "could not read nodeId in InputThetis::read_boundary_element()");
return ECIF_ERROR;
}
}
// NOTE: We do not know the material id for the boundaries
// so they cannot be actually added like this!
// --> We do not read the boundary elements fromt the Thetis mesh file!!!
model->addMeshInputElement(elem_type,
index, NO_INDEX, bndr_tag,
ext_node_ids);
nofInputBoundaryElements++;
} // for all boundary elements
return ECIF_OK;
}
// Read an element from the Thetis Mesh File and store it into the model.
Rc
InputThetis::readMeshElements(int nof_elements)
{
UserInterface* gui = theControlCenter->getGui();
int external_id;
int material_id;
int elem_type;
meshElementCode elem_code;
int nof_nodes, nof_neighbors;
static int ext_node_ids[27];
static int ext_neighbor_ids[27];
char* strm_buffer = new char[BUFFER_LEN];
strstream strm(strm_buffer, BUFFER_LEN, ios::app);
short i;
for (int index = 0; index < nof_elements; index++) {
readFileLine(infile, read_buffer);
reset(strm);
strm << read_buffer << ends;
// Read element ids and code
if ( !(strm >> external_id
>> material_id
>> elem_type
)
) {
gui->errMsg(1, "could not read element ids data in InputThetis::read_element()");
return ECIF_ERROR;
}
// Read nodes for the element
if ( !(strm >> nof_nodes) ) {
gui->errMsg(1, "could not read nof nodes per element in InputThetis::read_element()");
return ECIF_ERROR;
}
for (i = 0; i < nof_nodes; i++) {
if ( !(strm >> ext_node_ids[i]) ) {
gui->errMsg(1, "could not read nodeId in InputThetis::read_element()");
return ECIF_ERROR;
}
}
// Read neigbour element for the element
if ( !(strm >> nof_neighbors) ) {
gui->errMsg(1, "could not read nof-neighbors in InputThetis::read_element()");
return ECIF_ERROR;
}
for (i = 0; i < nof_neighbors; i++) {
if ( !(strm >> ext_neighbor_ids[i]) ) {
gui->errMsg(1, "could not read neighborIds in InputThetis::read_element()");
return ECIF_ERROR;
}
}
model->addMeshInputElement(elem_type,
external_id, material_id, NO_INDEX,
ext_node_ids);
nofInputBulkElements++;
} // for all elements
//---Model dimension (based on the last element read!)
if (elem_type > 200 && elem_type < 300)
modelDimension = ECIF_1D;
else if (elem_type > 300 && elem_type < 500)
modelDimension = ECIF_2D;
else if (elem_type > 500 && elem_type < 900)
modelDimension = ECIF_3D;
else
modelDimension = ECIF_ND;
return ECIF_OK;
}
// Read a node from the Thetis Mesh File and store it into the model
Rc
InputThetis::readMeshNodes(int nof_nodes)
{
UserInterface* gui = theControlCenter->getGui();
int external_id;
static Point3 p;
// Init point buffer
p[0] = p[1] = p[2] = 0.0;
char* strm_buffer = new char[BUFFER_LEN];
strstream strm(strm_buffer, BUFFER_LEN, ios::app);
for (int index = 0; index < nof_nodes; index++) {
readFileLine(infile, read_buffer);
reset(strm);
strm << read_buffer << ends;
if ( !(strm >> external_id) ) {
gui->errMsg(1, "could not NodeId in InputThetis::read_node()");
return ECIF_ERROR;
}
for (int i = 0; i < 3; i++) {
if (!(strm >> p[i])) {
gui->errMsg(1, "could not read node coordinates in InputThetis::read_node()");
return ECIF_ERROR;
}
}
model->addMeshNode(index, external_id, p);
}
return ECIF_OK;
}
syntax highlighted by Code2HTML, v. 0.9.1