/***********************************************************************
*
* 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_bodyElementLoop.cpp
Language: C++
Date: 01.01.038
Version: 1.00
Author(s): Martti Verho
Revisions:
Abstract: Implementation
************************************************************************/
#include "ecif_bodyElementGroup.h"
#include "ecif_bodyElement.h"
#include "ecif_model.h"
#include "ecif_userinterface.h"
//Initialize static class variables.
int BodyElementGroup::last_tag = 0;
// BodyElementGroup class
// ====================
BodyElementGroup::BodyElementGroup()
{
tag = ++last_tag;
init();
//initName();
}
BodyElementGroup::BodyElementGroup(ecif_ElementGroup_X& tx, enum objectType elem_tp)
{
if ( tx.tag == NO_INDEX ) {
tag = ++last_tag;
} else {
tag = tx.tag;
}
if (last_tag < tag) {
last_tag = tag;
}
init();
elemType = elem_tp;
if ( tx.is_virtual ) {
groupType = VIRTUAL_GROUP;
}
update_dyna_string(name, tx.name);
// If name not defined
if ( name == NULL || name[0] == '\0' ) {
strstream strm;
strm << " Bg-" << tag << ends;
update_dyna_string(name, strm.str());
}
nofElements = tx.nof_elements;
elementTags = new int[nofElements];
elementIds = new int[nofElements];
for (int i = 0; i < nofElements; i++) {
elementTags[i] = tx.element_tags[i];
elementIds[i] = NO_INDEX;
}
boundaryConditionId = tx.boundary_cond_id;
boundaryParameterId = tx.boundary_param_id;
}
BodyElementGroup::~BodyElementGroup()
{
delete[] elementIds;
delete[] elementTags;
}
int
BodyElementGroup::addElement(int be_id)
{
// Element exists
if ( hasElement(be_id) ) return nofElements;
BodyElement* be = model->getBodyElementById(be_id);
// Add element
// Allocate new arries
// NOTE: Do not delete these!!!
int* tmp_ids = new int[nofElements+1];
int* tmp_tags = new int[nofElements+1];
// Copy old data
for (int i = 0; i < nofElements; i++) {
tmp_ids[i] = elementIds[i];
tmp_tags[i] = elementTags[i];
}
// Delete old data
delete[] elementIds;
delete[] elementTags;
// Add new info
tmp_ids[nofElements] = be_id;
tmp_tags[nofElements] = be->Tag();
// Update object data
nofElements++;
elementIds = tmp_ids;
elementTags = tmp_tags;
return nofElements;
}
bool
BodyElementGroup::check()
{
UserInterface* gui = (UserInterface*)model->getGui();
strstream strm1, strm2;
BodyElement* be = NULL;
bool is_first_bndr = true;
for (int i = 0; i < nofElements; i++) {
int elem_tag = elementTags[i];
switch (elemType) {
case OT_VERTEX:
be = model->getBodyElementByTag(OT_VERTEX, elem_tag);
break;
case OT_EDGE:
be = model->getBodyElementByTag(OT_EDGE, elem_tag);
break;
case OT_FACE:
be = model->getBodyElementByTag(OT_FACE, elem_tag);
break;
}
if ( be != NULL ) {
elementIds[i] = be->Id();
// For non-virtual groups:
// -set group info into member boundaries
// -set parent body info
// -check that elements are homogenous
if ( !isVirtual() ) {
be->setElementGroupTag(tag);
be->setElementGroupId(id);
// NOTE: Body info from the first element
// (boundaries must be homogenous in this respect!)
//
if ( is_first_bndr ) {
is_first_bndr = false;
parent1Id = be->getParentId(1);
parent2Id = be->getParentId(2);
parent1Layer = be->getParentLayer(1);
parent2Layer = be->getParentLayer(2);
parent1Tag = be->getParentTag(1);
parent2Tag = be->getParentTag(2);
} else if ( parent1Id != be->getParentId(1) ||
parent2Id != be->getParentId(2)
) {
strm1 << "***ERROR in Edge Group " << tag << ends;
strm2 << "---Edge " << be->Tag() << " is not similar to previous edges!" << ends;
gui->showMsg(strm1.str());
gui->showMsg(strm2.str());
return false;
}
}
// Error!
} else {
strm1 << "***ERROR in Edge Group " << tag << ends;
strm2 << "---Cannot find edge " << elem_tag << ends;
gui->showMsg(strm1.str());
gui->showMsg(strm2.str());
return false;
}
}
return true;
}
const BodyElement*
BodyElementGroup::getElement(int index)
{
if ( index < 0 || index >= nofElements ) return NULL;
int be_id = elementIds[index];
return model->getBodyElementById(be_id);
}
int
BodyElementGroup::getElementId(int index)
{
if ( index < 0 || index >= nofElements ) return NO_INDEX;
return elementIds[index];
}
int
BodyElementGroup::getElementTag(int index)
{
if ( index < 0 || index >= nofElements ) return NO_INDEX;
return elementTags[index];
}
int
BodyElementGroup::getParentId(short parent) const
{
if (parent == 1)
return parent1Id;
else if (parent == 2)
return parent2Id;
else
return NO_INDEX;
}
int
BodyElementGroup::getParentLayer(short parent) const
{
if (parent == 1)
return parent1Layer;
else if (parent == 2)
return parent2Layer;
else
return NO_INDEX;
}
int
BodyElementGroup::getParentTag(short parent) const
{
if (parent == 1)
return parent1Tag;
else if (parent == 2)
return parent2Tag;
else
return NO_INDEX;
}
bool
BodyElementGroup::hasElement(int bn_id)
{
for (int i = 0; i< nofElements; i++) {
if ( elementIds[i] == bn_id ) {
return true;
}
}
return false;
}
void
BodyElementGroup::initClass(Model* mdl)
{
BodyElementGroup::last_tag = 0;
}
void
BodyElementGroup::init()
{
int i;
model->addModelObject(this, OT_ELEMENT_GROUP);
elemType = OT_NONE;
groupType = EXPLICIT_GROUP;
parent1Id = NO_INDEX;
parent2Id = NO_INDEX;
parent1Layer = NO_INDEX;
parent2Layer = NO_INDEX;
parent1Tag = NO_INDEX;
parent2Tag = NO_INDEX;
name = NULL;
nofElements = 0;
elementIds = NULL;
elementTags = NULL;
boundaryConditionId = NO_INDEX;
boundaryParameterId = NO_INDEX;
}
void
BodyElementGroup::initName()
{
if ( name == NULL || name[0] == '\0' ) {
strstream strm;
strm << "Bg-" << tag << ends;
update_dyna_string(name, strm.str());
}
}
ostream&
BodyElementGroup::output_emf(ostream& out, short indent_size, short indent_level)
{
char* QM = "\"";
short is = indent_size;
short il = indent_level;
// Header: Element Group
LibFront::output_scalar(out, is, il, EMF_ELEMENT_GROUP, NULL, tag);
// Type (output only if virtual)
if ( isVirtual() ) {
LibFront::output_scalar(out, is, 1 + il, EMF_TYPE, NULL, "Virtual");
}
// Name
LibFront::output_scalar(out, is, 1 + il, EMF_NAME, NULL, name);
int count, i, nof_ids;
int* bids;
int* mids;
int* gids;
//--BodyElementGroup group type and element tags
if ( nofElements > 0 ) {
if ( elemType == OT_FACE ) {
LibFront::output_vector(out, is, 1 + il, "Faces", NULL, nofElements, elementTags, false);
} else if ( elemType == OT_EDGE ) {
LibFront::output_vector(out, is, 1 + il, "Edges", NULL, nofElements, elementTags, false);
} else if ( elemType == OT_VERTEX ) {
LibFront::output_vector(out, is, 1 + il, "Vertices", NULL, nofElements, elementTags, false);
} else {
LibFront::output_vector(out, is, 1 + il, EMF_ELEMENTS, NULL, nofElements, elementTags, false);
}
}
//--Boundary parameter id
if ( boundaryParameterId != NO_INDEX ) {
LibFront::output_scalar(out, is, 1 + il, EMF_BOUNDARY_PARAMETER, NULL, boundaryParameterId);
}
//--Boundary condition id
if ( boundaryConditionId != NO_INDEX ) {
LibFront::output_scalar(out, is, 1 + il, EMF_BOUNDARY_CONDITION, NULL, boundaryConditionId);
}
return out;
}
int
BodyElementGroup::removeElement(int be_id)
{
// Element does not exist
if ( !hasElement(be_id) ) return nofElements;
// Remove one element
int* tmp_ids = NULL;
int* tmp_tags = NULL;
// Allocate new arries
// NOTE: Do not delete these!!!
if ( nofElements > 1 ) {
tmp_ids = new int[nofElements-1];
tmp_tags = new int[nofElements-1];
// Copy old data, but skip be_id
for (int i = 0; i < nofElements; i++) {
if ( be_id == elementIds[i] ) continue;
tmp_ids[i] = elementIds[i];
tmp_tags[i] = elementTags[i];
}
}
// Delete old data
delete[] elementIds;
delete[] elementTags;
// Update object data
nofElements--;
elementIds = tmp_ids;
elementTags = tmp_tags;
return nofElements;
}
void
BodyElementGroup::setBoundaryConditionId(int bc_id)
{
boundaryConditionId = bc_id;
}
void
BodyElementGroup::setElementIdsAndTags(int nof_ids, int* bndr_ids, int* bndr_tags)
{
delete[] elementIds;
delete[] elementTags;
nofElements = nof_ids;
elementIds = new int[nofElements];
elementTags = new int[nofElements];
for (int i = 0; i < nofElements; i++) {
elementIds[i] = bndr_ids[i];
elementTags[i] = bndr_tags[i];
}
}
void
BodyElementGroup::setBoundaryParameterId(int pid)
{
boundaryParameterId = pid;
}
void
BodyElementGroup::setElementType(enum objectType et)
{
elemType = et;
}
void
BodyElementGroup::setType(enum elementGroupType gt)
{
groupType = gt;
}
void
BodyElementGroup::setParentId(short parent, int parent_id)
{
if (parent == 1)
parent1Id = parent_id;
else if (parent == 2)
parent2Id = parent_id;
}
void
BodyElementGroup::setParentLayer(short parent, int layer)
{
if (parent == 1)
parent1Layer = layer;
else if (parent == 2)
parent2Layer = layer;
}
void
BodyElementGroup::setParentTag(short parent, int parent_tag)
{
if (parent == 1)
parent1Tag = parent_tag;
else if (parent == 2)
parent2Tag = parent_tag;
}
syntax highlighted by Code2HTML, v. 0.9.1