/***********************************************************************
*
* 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;
}
}
syntax highlighted by Code2HTML, v. 0.9.1