/*********************************************************************** * * 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; }