/*********************************************************************** * * 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_boundaryCondition.cpp Language: C++ Date: 01.10.98 Version: 1.00 Author(s): Martti Verho Revisions: Abstract: Implementation ************************************************************************/ #include "ecif_bodyElement.h" #include "ecif_bodyElementGroup.h" #include "ecif_boundaryCondition.h" #include "ecif_model.h" #include "ecif_parameterField.h" //Initialize static class variables. int BoundaryCondition::last_id = 0; Model* BoundaryCondition::model = NULL; // Constructors BoundaryCondition::BoundaryCondition() { nofTargetBoundaries = 0; targetBoundaryTags = NULL; targetBodyTag = NO_INDEX; } BoundaryCondition::BoundaryCondition(int p_id) : Parameter(p_id) { nofTargetBoundaries = 0; targetBoundaryTags = NULL; targetBodyTag = NO_INDEX; } BoundaryCondition::BoundaryCondition(int cid, int parent_id, char* data_string, char* param_name) { setData(cid, parent_id, data_string, param_name); nofTargetBoundaries = 0; targetBoundaryTags = NULL; targetBodyTag = NO_INDEX; } BoundaryCondition::~BoundaryCondition() { delete[] targetBoundaryTags; } // Parent object or emf-file info // const ModelObject* BoundaryCondition::getParentEmfObject() { ModelObject* obj = model->getModelObjectById(parentId); if ( obj == NULL ) return NULL; BodyElementGroup* beg = (BodyElementGroup*)obj; // For implicit groups we use the first element as the parent // if ( IMPLICIT_GROUP == beg->getGroupType() ) { int be_id = beg->getElementId(0); obj = model->getModelObjectById(be_id); } return obj; } bool BoundaryCondition::hasZeroVelocity() { ParameterField* pf; short dim1, dim2, nofVars; short dimension = (short)model->getDimension(); const char* fields[] = {"Velocity 1", "Velocity 2", "Velocity 3"}; // Loop all relevant velocity components for (short d = 0; d < dimension; d++) { pf = getFieldBySifName(fields[d]); // If component is not set if ( pf == NULL || 0 == pf->getNofDataStrings() ) return false; // If component is a procedure // NOTE: We do not trust procedures at all if ( pf->isProcedure() ) return true; // Get constraint data dims pf->getDataDimension(dim1, dim2, nofVars); // Get constraint data package char** data = pf->getDataStrings(); double value; // Check if velocity constraint value is zero // NOTE: One velocity component is scalar --> // no need to dim2 looping for (int i = 0; i < dim1; i++ ) { strstream strm; strm << data[i]; strm >> value; if ( value != 0 ) return false; } } // Ok, we really are a zero-velocity condition! return true; } void BoundaryCondition::initClass(Model* mdl) { BoundaryCondition::model = mdl; BoundaryCondition::last_id = 0; } // Boundary condition specific output-method for Solver input file ostream& BoundaryCondition::output_sif(ostream& out, short indent_size, short indent_level, SifOutputControl& soc) { char QM = '\"'; // Parameter type and id if (soc.outputType) { LibFront::output_string(out, indent_size, indent_level++, getSifName(), false); if (soc.outputId) out << ' ' << ID(); out << endl; } else { indent_level++; } // Output parameter name if (soc.outputName) { output_sif_name(out, indent_size, indent_level, soc); } // Target body tag // NOTE: This is only for virtual boundary group bc:s // if ( targetBodyTag != NO_INDEX ) { if ( model->getSolverKeywordTypeGiven(SIF_BOUNDARY_CONDITION, "Body Id") ) { LibFront::output_scalar(out, indent_size, indent_level, "Body Id = ", NULL, targetBodyTag); } else { LibFront::output_scalar(out, indent_size, indent_level, "Body Id = Integer ", NULL, targetBodyTag); } } // Target boundary tags if ( nofTargetBoundaries > 0 ) { strstream strm; if ( model->getSolverKeywordTypeGiven(SIF_BOUNDARY_CONDITION, "Target Boundaries") ) { strm << "Target Boundaries(" << nofTargetBoundaries << ") =" << ends; LibFront::output_vector(out, indent_size, indent_level, strm.str(), NULL, nofTargetBoundaries, targetBoundaryTags, false); } else { strm << "Target Boundaries(" << nofTargetBoundaries << ") = Integer" << ends; LibFront::output_vector(out, indent_size, indent_level, strm.str(), NULL, nofTargetBoundaries, targetBoundaryTags, false); } } out << endl; // Fields for (short i = 0; i < nofFields; i++) { ParameterField* pf = fields[i]; // Check that field exists and it should be output if ( !pf->isActiveInstance() || pf->getNofDataStrings() == 0 || ( !soc.outputAll && !pf->isSifOutputField() ) ) continue; pf->output_sif(out, indent_size, indent_level, soc.sectionName); } return out; } void BoundaryCondition::setName(char* param_name) { Parameter::setName(param_name, "Constraint"); } // Set parent object id (after reading from model emf-file) void BoundaryCondition::updateParentId() { // If parent object type is a normal boundary, replace the // parent object with the boundary-group object // if ( parentEmfType != OT_ELEMENT_GROUP ) { ModelObject* obj = model->getModelObjectByTag(parentEmfType, parentEmfTag); if ( obj != NULL ) { BodyElement* be = (BodyElement*)obj; parentEmfTag = be->getElementGroupTag(); parentEmfType = OT_ELEMENT_GROUP; } else { parentEmfTag = NO_INDEX; parentEmfType = OT_NONE; } } ModelObject* obj = model->getModelObjectByTag(parentEmfType, parentEmfTag); if ( obj != NULL ) { parentId = obj->Id(); } } // Update parent info from Gui // void BoundaryCondition::updateParentInfo(int parent_id) { // Set parent object's id // parentId = parent_id; BodyElementGroup* beg = model->getBodyElementGroupById(parent_id); if ( beg != NULL ) { // If parent object type is an implicit group use // the boundary element's tag if ( IMPLICIT_GROUP == beg->getGroupType() ) { const BodyElement* be = beg->getElement(0); parentEmfTag = be->Tag(); parentEmfType = be->getObjectType(); // Otherwise use group's own tag } else { parentEmfTag = beg->Tag(); parentEmfType = beg->getObjectType(); } } else { parentEmfTag = NO_INDEX; parentEmfType = OT_NONE; } } // Update target boundary tags for the boundary condition // void BoundaryCondition::updateTargetTags() { nofTargetBoundaries = 0; delete[] targetBoundaryTags; targetBoundaryTags = NULL; targetBodyTag = NO_INDEX; IdsSet be_tags; // Body elements // ============= int index = 0; while (true) { BodyElement* be = model->getBodyElement(index++); if ( be == NULL ) break; if ( id == be->getBoundaryConditionId() ) { be_tags.insert(be->getBoundaryTag()); if ( be->isBemBoundary() ) { int bd_tg = be->getParentTag(1); if ( bd_tg != NO_INDEX ) { targetBodyTag = bd_tg; } } } // Boundary's bc-id matches } // Loop all boundaries // Element groups // ============= index = 0; while (true) { BodyElementGroup* beg = model->getBodyElementGroup(index++); if (beg==NULL) break; if ( id == beg->getBoundaryConditionId() ) { for (int i = 0; i < beg->getNofElements(); i++) { const BodyElement* be = beg->getElement(i); if ( be != NULL ) { be_tags.insert(be->getBoundaryTag()); } } if ( beg->getGroupType() == VIRTUAL_GROUP ) { int bd_tg = beg->getParentTag(1); if ( bd_tg != NO_INDEX ) { targetBodyTag = bd_tg; } } } // Group's bc-id matched } // Loop boundary groups // Store data // ========== nofTargetBoundaries = be_tags.size(); targetBoundaryTags = new int[nofTargetBoundaries]; IdsSet::iterator itr = be_tags.begin(); for (int i = 0; i < nofTargetBoundaries; i++, itr++) { targetBoundaryTags[i] = *itr; } }