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