/***********************************************************************
*
* 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_bodyLayer.cpp
Language: C++
Date: 01.01.03
Version: 1.00
Author(s): Martti Verho
Revisions:
Abstract: Implementation
************************************************************************/
#include "ecif_bodyLayer.h"
#include "ecif_body.h"
#include "ecif_bodyElement.h"
#include "ecif_bodyElementLoop.h"
#include "ecif_model.h"
#include "ecif_parameter.h"
//Initialize static class variables.
int BodyLayer::last_tag = 0;
// BodyLayer class
// ===================
BodyLayer::BodyLayer()
{
tag = ++last_tag;
init();
initName();
}
BodyLayer::BodyLayer(ecif_BodyLayer_X& tx)
{
enum bodyLayerType tp;
if ( tx.tag == NO_INDEX ) {
tag = ++last_tag;
tp = IMPLICIT_LAYER;
} else {
tag = tx.tag;
tp = EXPLICIT_LAYER;
}
if (last_tag < tag) {
last_tag = tag;
}
init();
// NOTE: This must be set after init
type = tp;
int i;
if ( tx.is_open ) {
tplgType = OPEN_LAYER;
}
if ( tx.has_color ) {
colorIndex = ef_nodefault;
for (i = 0; i < 4; i++)
color[i] = tx.color[i];
} else {
colorIndex = DEFAULT_COLOR_INDEX;
}
bodyId = tx.body_id;
bodyTag = tx.body_tag;
update_dyna_string(name, tx.name);
int nof_ids;
int* gids;
int* mids;
int* xids;
// Possible grid parameter ids and mesh indices for layer-0
nof_ids = tx.nof_grid_param_ids;
gids = tx.grid_param_ids;
mids = tx.grid_param_mesh_indices;
setGridParameterData(nof_ids, gids, mids);
// Possible excluded mesh indices for layer-0
nof_ids = tx.nof_excluded_meshes;
xids = tx.excluded_mesh_indices;
setExcludedMeshData(nof_ids, xids);
}
BodyLayer::~BodyLayer()
{
delete[] gridParameterIds;
delete[] gridParameterMeshIndices;
delete[] excludedMeshIndices;
}
// Correct this !!!###!!!
bool
BodyLayer::acceptsStructuredMesh()
{
return false;
}
const Body*
BodyLayer::getBody()
{
return model->getBodyById(bodyId);
}
void
BodyLayer::getColor(Color4& clr)
{
for (int i = 0; i < 4; i++)
clr[i] = color[i];
}
int
BodyLayer::getGridParameterId(int mesh_index)
{
for (int i = 0; i < nofGridParameterIds; i++) {
if ( gridParameterMeshIndices[i] == mesh_index ) {
return gridParameterIds[i];
}
}
return NO_INDEX;
}
bool
BodyLayer::getMeshDensityValue(int mesh_index, char& dtype, double& dvalue)
{
if ( mesh_index < 0 || mesh_index >= model->getNofMeshes() )
return false;
dtype = ' ';
dvalue = 0;
// Check if parameter is defined for the mesh
for (int i = 0; i < nofGridParameterIds; i++) {
// Mesh found
if ( mesh_index == gridParameterMeshIndices[i] ) {
Parameter* param = model->getParameterById(ECIF_GRID_PARAMETER, gridParameterIds[i]);
if ( param == NULL )
return false;
// If value type given
char type[2] = " ";
if ( param->getFieldValueBySifName("Mesh Density Type", 1, (char*)type) ) {
double value;
// MeshH
if ( type[0] == 'H' && param->getFieldValueBySifName("Mesh H", value) ) {
dvalue = value;
dtype = 'H';
return true;
// Mesh R
} else if ( type[0] == 'R' && param->getFieldValueBySifName("Mesh R", value) ) {
dvalue = value;
dtype = 'R';
return true;
}
}
break;
}
} // for all parameters
return false;
}
// Correct this!!!###!!!
int
BodyLayer::getMeshQuadGridN(int mesh_index, int element_id)
{
if ( !acceptsStructuredMesh() ) return 0;
if ( mesh_index < 0 || mesh_index >= model->getNofMeshes() )
return 0;
Parameter* param = NULL;
for (int i = 0; i < nofGridParameterIds; i++) {
if ( gridParameterMeshIndices[i] == mesh_index ) {
param = model->getParameterById(ECIF_GRID_PARAMETER, gridParameterIds[i]);
break;
}
}
if ( param == NULL ) {
return 0;
}
char value_buffer[1 + 128];
// Check if Quadrilateral mesh defined for the grid layer
if ( !( param->getFieldValueBySifName("Mesh Element Type", 128, value_buffer) &&
LibFront::ncEqual(value_buffer, "Quad")
)
) {
return 0;
}
Body* body = model->getBodyById(bodyId);
if (body == NULL) return 0;
// Check element index
int index = NO_INDEX;
int layer = 0; // Correct this !!!###!!!
int be_index = 0;
while (true) {
BodyElement* be = body->getElement(layer, be_index++);
if (be==NULL) break;
if ( be->Id() == element_id ) {
index++;
break;
}
}
if ( index == NO_INDEX ) {
return 0;
}
int n;
bool found = false;
if ( index == 0 || index == 2 ) {
found = param->getFieldValueBySifName("Mesh Quadgrid N1", n);
} else if ( index == 1 || index == 3 ) {
found = param->getFieldValueBySifName("Mesh Quadgrid N2", n);
} else {
return 0;
}
if (found) {
return n;
}
return 0;
}
// Total number of mif-file layers which must be created
// from one body layer
//
int
BodyLayer::getNofMifLayers(const IdList* elem_loop_ids)
{
int count = 0;
// Nof geometries in the first element in the first
// loop defines number of mif layers
//
IdList::iterator itr = ((IdList*)elem_loop_ids)->begin();
int did = *itr;
int direction = (did < 0 )?-1:1;
BodyElementLoop* bel = model->getBodyElementLoopById(direction * did);
if ( bel != NULL ) {
BodyElement* be = bel->getElement(0);
if ( be != NULL ) {
count += be->getNofMifGeometries();
}
}
return count;
}
// Total number of mif-file layer loops which must be created
// for one mif-layer
// NOTE: This is for 'normal' cases when we have a single layer
//
int
BodyLayer::getNofMifLayerLoops(const IdList* elem_loop_ids)
{
int count = 0;
// The sum of Nof geometries in the first elements in each bodyelement loop
// defines the number of mif-layers loops
//
int nof_bels = elem_loop_ids->size();
IdList::iterator itr = ((IdList*)elem_loop_ids)->begin();
for (int i = 0; i < nof_bels; i++, itr++) {
int did = *itr;
int direction = (did < 0 )?-1:1;
BodyElementLoop* bel = model->getBodyElementLoopById(direction * did);
if ( bel != NULL ) {
BodyElement* be = bel->getElement(0);
if ( be != NULL ) {
count += be->getNofMifGeometries();
}
}
}
return count;
}
// Total number of mif-file layer loops which must be created
// for one mif-layer
// NOTE: This is for situations when we have a multigeometry
// element (as the first element in the first layer) creating
// multiple mif-layers.
// index: the multi-geometry (mif-layer index) index
//
int
BodyLayer::getNofMifLayerLoops(int gmtr_index, const IdList* elem_loop_ids)
{
int count = 0;
// Nof geometries in the first element in the first
// loop defines number of mif layers
//
int nof_bels = elem_loop_ids->size();
IdList::iterator itr = ((IdList*)elem_loop_ids)->begin();
for (int i = 0; i < nof_bels; i++, itr++) {
int did = *itr;
int direction = (did < 0 )?-1:1;
BodyElementLoop* bel = model->getBodyElementLoopById(direction * did);
if ( bel != NULL ) {
BodyElement* be = bel->getElement(0);
if ( be != NULL ) {
if ( NO_INDEX != be->getMifGeometryTag(gmtr_index) ) {
count += 1;
}
}
}
}
return count;
}
bool
BodyLayer::hasBody(int bd_id)
{
if ( bodyId == bd_id ) {
return true;
}
return false;
}
void
BodyLayer::initClass(Model* mdl)
{
BodyLayer::last_tag = 0;
}
void
BodyLayer::init()
{
int i;
model->addModelObject(this, OT_BODY_LAYER);
type = NONE_LAYER;
tplgType = CLOSED_LAYER;
name = NULL;
bodyId = NO_INDEX;
bodyTag = NO_INDEX;
colorIndex = DEFAULT_COLOR_INDEX;
for (i = 0; i< 4; i++) {
color[i] = colorValues[DEFAULT_COLOR_INDEX][i];
}
nofExcludedMeshes = 0;
excludedMeshIndices = NULL;
nofGridParameterIds = 0;
gridParameterMeshIndices = NULL;
gridParameterIds = NULL;
}
void
BodyLayer::initName()
{
if ( name == NULL || name[0] == '\0' ) {
strstream strm;
strm << "Layer" << tag << ends;
update_dyna_string(name, strm.str());
}
}
// If body layer excluded from the currently drawn mesh
bool
BodyLayer::isExcludedFromMesh(int mesh_index)
{
if ( mesh_index == NO_INDEX ) {
return false;
}
for (int i = 0; i < nofExcludedMeshes; i++) {
if ( excludedMeshIndices[i] == mesh_index ) {
return true;
break;
}
}
return false;
}
// Layer Front model file output
//
ostream&
BodyLayer::output_emf(ostream& out, short indent_size, short indent_level)
{
char* QM = "\"";
short is = indent_size;
short il = indent_level;
int nof_ids;
int* gids;
int* mids;
//--Excluded mesh indices
nof_ids = nofExcludedMeshes;
mids = excludedMeshIndices;
if ( nof_ids > 0 ) {
LibFront::output_vector(out, is, il, "Excluded Mesh Indices", NULL, nof_ids, mids, false);
}
//--GridParameter ids
nof_ids = nofGridParameterIds;
gids = gridParameterIds;
mids = gridParameterMeshIndices;
if ( nof_ids > 0 ) {
LibFront::output_vector(out, is, il, "Grid Parameter Ids", NULL, nof_ids, gids, false);
LibFront::output_vector(out, is, il, "Grid Parameter Mesh Indices", NULL, nof_ids, mids, false);
}
return out;
}
// Layer Mesh2D file output
//
ostream&
BodyLayer::output_mif(ostream& out, int& next_mif_id, const IdList* elem_loop_ids)
{
char* QM = "\"";
int i;
char value_buffer[1 + 128];
int mesh_index = model->getCurrentMeshIndex();
int pid = getGridParameterId(mesh_index);
Parameter* grid_param = model->getParameterById(ECIF_GRID_PARAMETER, pid);
char dtype;
double dvalue;
bool dgiven = getMeshDensityValue(mesh_index, dtype, dvalue);
bool is_open;
bool is_quadGrid;
if ( tplgType == OPEN_LAYER ) {
is_open = true;
} else {
is_open = false;
}
// Check if Quadrilateral elements
if ( grid_param != NULL &&
grid_param->getFieldValueBySifName("Mesh Element Type", 128, value_buffer) &&
LibFront::ncEqual(value_buffer, "Quad")
) {
is_quadGrid = true;
} else {
is_quadGrid = false;
}
int nof_mif_layers = getNofMifLayers(elem_loop_ids);
for (int layer = 0; layer < nof_mif_layers; layer++) {
// Layer id
// --------
indent(out, 4) << "LayerId: " << next_mif_id++ << endl;
// Layer mesh density value
// ------------------------
if ( dgiven && dvalue > 0 )
indent(out, 4) << dtype << ": " << dvalue << endl;
// Layer type (meshing method)
// ---------------------------
indent(out, 6) << "LayerType: ";
//-Structured grid
if ( is_quadGrid ) {
out << "QuadGrid";
indent(out, 6) << "GridSize: ";
grid_param->getFieldValueBySifName("Mesh Quadgrid N1", 128, value_buffer);
out << value_buffer << " ";
grid_param->getFieldValueBySifName("Mesh Quadgrid N2", 128, value_buffer);
out << value_buffer << endl;
//-Triangles
} else if ( grid_param != NULL &&
grid_param->getFieldValueBySifName("Mesh Layer Type", 128, value_buffer)
) {
out << value_buffer;
//-Open layer (1D body!)
} else if ( is_open ) {
out << "BoundaryMesh";
//-Default
} else {
out << "MovingFront";
}
out << endl;
// Background mesh stuff
// ---------------------
if ( !(is_open || is_quadGrid) ) {
//-Fixed nodes
indent(out, 6) << "FixedNodes: " << 0 << endl; // NOTE: Currently always 0!, MVe 16.02.00
//-Background mesh type
indent(out, 6) << "BGMesh: ";
//--Background mesh method specified
if ( grid_param != NULL &&
grid_param->getFieldValueBySifName("Mesh Bg Mesh", 128, value_buffer)
) {
//-External bg-mesh file
if ( LibFront::in(value_buffer, "External") ) {
//-File name given
if ( grid_param->getFieldValueBySifName("Mesh Bg Mesh File", 128, value_buffer) &&
value_buffer != NULL && value_buffer[0] != '\0'
) {
out << "External " << QM << value_buffer << QM;
//-File name missing, use default method!
} else {
out << "Delaunay";
}
//-Some of the predefined methods selected by the user
} else {
out << value_buffer;
}
//--Use default method (no bg mesh)
} else {
out << "Delaunay";
}
out << endl;
// Mesh seed (optional)
// --------------------
if ( grid_param != NULL &&
grid_param->getFieldValueBySifName("Mesh Seed Type", 128, value_buffer)
) {
// Only Implicit seed currently supported, MVe 16.02.99
if ( LibFront::ncEqual(value_buffer, "Implicit") &&
grid_param->getFieldValueBySifName("Mesh Seed Edge", 128, value_buffer)
) {
indent(out,6) << "Seed: Implicit" << endl;
indent(out,8) << "Edge: " << value_buffer << endl;
}
}
}
// Layer loops
// -----------
int nof_mif_loops = 0;
if ( nof_mif_layers == 1 ) {
nof_mif_loops = getNofMifLayerLoops(elem_loop_ids);
} else {
nof_mif_loops = getNofMifLayerLoops(layer, elem_loop_ids);
}
indent(out, 6) << "Loops: " << nof_mif_loops << endl;
int next_mif_loop = 1;
int nof_loops = ((IdList*)elem_loop_ids)->size();
IdList::iterator itr = ((IdList*)elem_loop_ids)->begin();
for (int loop = 0; loop < nof_loops; loop++, itr++) {
int did = *itr;
int direction = (did < 0 )?-1:1;
BodyElementLoop* bel = model->getBodyElementLoopById(direction * did);
if ( bel == NULL ) continue;
int nof_bel_mif_loops = 0;
if ( nof_mif_layers == 1 ) {
nof_bel_mif_loops = bel->getNofMifLoops(NO_INDEX);
} else {
nof_bel_mif_loops = bel->getNofMifLoops(layer);
}
for (int idx = 0; idx < nof_bel_mif_loops; idx++) {
// Print positions before and after printing fixed data
// (for getting the indent size for ids)
int pos1, pos2;
indent(out, 8) << "LoopId: " << next_mif_loop++ << endl;
indent(out, 10) << "Direction: " << direction << endl;
pos1 = out.tellp();
#if 0
indent(out, 10) << "Edges: " << bel->getNofElementMifTags(idx) << " ";
pos2 = out.tellp();
bel->outputDirectedElementMifTags(out, pos2 - pos1, idx);
#endif
#if 1
// Open layer are output in both directions:
// Edges: 6 1 2 3 -3 -2 -1
// Owing to Mesh2D disability to handle open bodies!!!
//
int factor = isOpen()?2:1;
// Output 'Edges: nof-edges'
if ( nof_mif_layers == 1 ) {
indent(out, 10) << "Edges: " << factor * bel->getNofElementMifTags(idx) << " ";
} else {
indent(out, 10) << "Edges: " << factor * bel->getNofElementMifTags(layer) << " ";
}
// Pick current output position
pos2 = out.tellp();
// Output edge tags
if ( nof_mif_layers == 1 ) {
bel->outputDirectedElementMifTags(out, isOpen(), pos2 - pos1, idx);
} else {
bel->outputDirectedElementMifTags(out, isOpen(), pos2 - pos1, layer);
}
#endif
out << endl;
}
}
}
return out;
}
void
BodyLayer::setBodyId(int body_id)
{
bodyId = body_id;
}
void
BodyLayer::setBodyTag(int body_tag)
{
bodyTag = body_tag;
}
void
BodyLayer::setColorIndex(colorIndices color_index)
{
// Set color index
colorIndex = color_index;
// Set actual color
for (int i = 0; i< 4; i++) {
color[i] = colorValues[color_index][i];
}
}
void
BodyLayer::setExcludedMeshData(int nof_indices, int* excluded_mesh_indices)
{
nofExcludedMeshes = nof_indices;
delete[] excludedMeshIndices;
excludedMeshIndices = NULL;
if ( nof_indices == 0 )
return;
excludedMeshIndices = new int[nof_indices];
for (int i = 0; i < nof_indices; i++) {
excludedMeshIndices[i] = excluded_mesh_indices[i];
}
}
void
BodyLayer::setGridParameterData(int nof_ids, int* gids, int* mesh_indices)
{
nofGridParameterIds = nof_ids;
delete[] gridParameterIds;
delete[] gridParameterMeshIndices;
gridParameterIds = NULL;
gridParameterMeshIndices = NULL;
if ( nof_ids == 0 )
return;
gridParameterIds = new int[nof_ids];
gridParameterMeshIndices = new int[nof_ids];
for (int i = 0; i < nof_ids; i++) {
gridParameterIds[i] = gids[i];
gridParameterMeshIndices[i] = mesh_indices[i];
}
}
void
BodyLayer::setGridParameterIds(int nof_ids, int* gids)
{
nofGridParameterIds = nof_ids;
delete[] gridParameterIds;
gridParameterIds = NULL;
if ( nof_ids == 0 )
return;
gridParameterIds = new int[nof_ids];
for (int i = 0; i < nof_ids; i++) {
gridParameterIds[i] = gids[i];
}
}
void
BodyLayer::setGridParameterMeshIndices(int nof_ids, int* mesh_indices)
{
delete[] gridParameterMeshIndices;
gridParameterMeshIndices = NULL;
if ( nof_ids == 0 )
return;
gridParameterMeshIndices = new int[nof_ids];
for (int i = 0; i < nof_ids; i++) {
gridParameterMeshIndices[i] = mesh_indices[i];
}
}
syntax highlighted by Code2HTML, v. 0.9.1