/***********************************************************************
*
* 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_parameter.cpp
Language: C++
Date: 15.10.98
Version: 1.00
Author(s): Martti Verho
Revisions:
Abstract: Implementation
************************************************************************/
#include "ecif_body.h"
#include "ecif_control.h"
#include "ecif_model.h"
#include "ecif_parameter.h"
#include "ecif_parameterField.h"
#include "ecif_userinterface.h"
extern char PARAMETER_BUFFER[];
Model* Parameter::model = NULL;
// Constructors
Parameter::Parameter()
{
applyCount = 0;
changed = false;
copied = false;
dataString = NULL;
dataString_previous = NULL;
fields = NULL;
id = 0;
name = NULL;
nofFields = 0;
nofPreviousFields = 0;
parentId = NO_INDEX;
parentEmfTag = NO_INDEX;
parentEmfType = OT_NONE;
subParentEmfTag = NO_INDEX;
subParentEmfType = OT_NONE;
previousFields = NULL;
status = STATUS_OK;
updateFlag = false;
}
Parameter::Parameter(int p_id)
{
applyCount = 0;
changed = false;
copied = false;
dataString = NULL;
dataString_previous = NULL;
fields = NULL;
id = p_id;
name = NULL;
nofFields = 0;
nofPreviousFields = 0;
parentId = NO_INDEX;
parentEmfTag = NO_INDEX;
parentEmfType = OT_NONE;
subParentEmfTag = NO_INDEX;
subParentEmfType = OT_NONE;
previousFields = NULL;
status = STATUS_OK;
updateFlag = false;
}
Parameter::~Parameter()
{
delete [] dataString;
delete [] dataString_previous;
delete [] name;
delete_fields();
delete_previousFields();
}
void
Parameter::checkLastId(int pid)
{
int lid = getLastId();
if ( lid < pid ) {
setLastId(pid);
}
}
void
Parameter::create_fields()
{
UserInterface* gui = (UserInterface*)model->getGui();
char data_buffer[1025];
short data_buffer_len = 1025;
ParameterFieldInfo* pf_info;
short dim1, dim2, nof_variables;
char data_type; // "=" Numeric, ":" File name, "." Proc name
bool is_file_name, is_proc_name, is_quoted;
bool is_inactive;
short i;
char* name_buffer = new char[MAX_PARAMETER_FIELD_NAME_LENGTH];
char* field_name_buffer = new char[MAX_PARAMETER_FIELD_NAME_LENGTH];
char* name_part_buffer = new char[MAX_PARAMETER_FIELD_NAME_LENGTH];
char* index_part_buffer = new char[MAX_PARAMETER_FIELD_NAME_LENGTH];
char** var_name_buffers = new char*[MAX_NOF_PARAMETER_VARIABLES];
for (i = 0; i < MAX_NOF_PARAMETER_VARIABLES; i++) {
var_name_buffers[i] = new char[MAX_PARAMETER_FIELD_NAME_LENGTH];
}
char** data_strings = new char*[MAX_NOF_PARAMETER_DATA_STRINGS];
for (i = 0; i < MAX_NOF_PARAMETER_DATA_STRINGS; i++) {
data_strings[i] = NULL;
}
// Count nof fields in the parameter set
istrstream strm1(dataString);
nofFields = 0;
while (!strm1.eof()) {
strm1.getline(PARAMETER_BUFFER, PARAMETER_BUFFER_LEN, PARAMETER_FIELD_SEP);
nofFields++;
}
// Allocate parameter fields
fields = new ParameterField*[nofFields];
for (i = 0; i < nofFields; i++) {
fields[i] = NULL;
}
istrstream strm2(dataString);
// Read the parameter fields
short counter = 0;
while (!strm2.eof()) {
//----Extract one parameter field
strm2.getline(PARAMETER_BUFFER, PARAMETER_BUFFER_LEN, PARAMETER_FIELD_SEP);
//--This is the stream we use for reading!
istrstream strm(PARAMETER_BUFFER);
dim1 = dim2 = 0;
nof_variables = 0;
//--Read parameter name, type and possible (d1 d2) size info
extractFieldInfo(strm, field_name_buffer, var_name_buffers, data_type,
dim1, dim2, nof_variables, is_inactive);
//--Form parameter field info for the field
// Check if this is an indexed field like: Diffusivity(Oxygen)
bool has_pre_index = false;
bool has_post_index = false;
strstream fn_strm;
char* field_name = field_name_buffer;;
char* index_name = NULL;
if ( field_name_buffer[0] == INDEX_PRE_SEPARATOR ) {
has_pre_index = true;
// Jump over first '<' before reading index-name
char* tmp = field_name_buffer;
fn_strm << ++tmp;
fn_strm.getline(index_part_buffer, MAX_PARAMETER_FIELD_NAME_LENGTH, INDEX_POST_SEPARATOR);
fn_strm.getline(name_part_buffer, MAX_PARAMETER_FIELD_NAME_LENGTH);
index_name = index_part_buffer;
}
else if ( field_name_buffer[strlen(field_name_buffer) - 1] == INDEX_POST_SEPARATOR ) {
has_post_index = true;
fn_strm.getline(name_part_buffer, MAX_PARAMETER_FIELD_NAME_LENGTH, INDEX_PRE_SEPARATOR);
fn_strm.getline(index_part_buffer, MAX_PARAMETER_FIELD_NAME_LENGTH, INDEX_POST_SEPARATOR);
index_name = index_part_buffer;
}
// Get parameter field info by array and field name
pf_info = model->getParameterFieldInfo(getArrayName(), field_name);
// If an indexed field was found, store info about it
if ( pf_info != NULL && (has_pre_index || has_post_index) ) {
if (has_pre_index) {
pf_info->isPreIndexed = true;
} else {
pf_info->isPostIndexed = true;
}
// Index name
update_dyna_string(pf_info->guiIndex, index_name);
// Normal field
} else {
//--ERROR if unknown field
if (pf_info == NULL ) {
pf_info = new ParameterFieldInfo();
update_dyna_string(pf_info->guiName, "UNKNOWN_FIELD");
update_dyna_string(pf_info->valueType, "UNKNOWN DATATYPE");
}
}
// Check if we have a file-name or procedure name as data
is_file_name = false;
is_proc_name = false;
if (data_type == FILE_NAME_INDICATOR) {
is_file_name = true;
} else if (data_type == PROC_NAME_INDICATOR) {
is_proc_name = true;
}
pf_info->isFileName |= is_file_name;
pf_info->isProcName |= is_proc_name;
//--Read all DATA values "1.0;;2.0..." or "conduction;convection;..."
short nof_strings = 0;
bool append_data = false;
while (!strm.eof()) {
data_buffer[0] = '\0';
strm.getline( data_buffer, data_buffer_len, PARAMETER_DATA_SEP);
int len = strlen(data_buffer);
// NOTE: Matc-procedures do not have any Library name
// so the first item can (and must) be empty!!!
//
if (!is_proc_name && len == 0)
continue;
// Data still continues in the stream
if (append_data) {
int old_len = strlen(data_strings[nof_strings]);
char* tmp = new char[old_len + len + 3];
strcpy(tmp, data_strings[nof_strings]);
tmp[old_len] = ' ';
strcpy(tmp + old_len + 1, data_buffer);
delete data_strings[nof_strings];
data_strings[nof_strings] = tmp;
data_strings[old_len + len + 2] = '\0';
// New data
} else {
delete[] data_strings[nof_strings];
data_strings[nof_strings] = new char[1 + len];
strcpy(data_strings[nof_strings], data_buffer);
data_strings[nof_strings][len] = '\0';
}
// If current data was not read completely
if (len == data_buffer_len - 1 &&
!strm.eof() &&
PARAMETER_DATA_SEP != strm.peek() ) {
append_data = true;
// Data was read completely, inrease array index for the next data
} else {
append_data = false;
if ( nof_strings < MAX_NOF_PARAMETER_DATA_STRINGS - 1 ) {
nof_strings++;
}
}
} // end read values
// Set field sizes if they were not given in the input
// Dim1
// ====
if ( dim1 == 0 ) {
//--Array data
if ( pf_info->isArray ) {
//-String, dim1 alaways 1
if ( LibFront::in(pf_info->valueType, "string") ) {
dim1 = 1;
//-Numeric
} else {
dim1 = countNumbersInString(data_strings[0]) - nof_variables;
}
//--Scalar
} else {
dim1 = 1;
}
}
// Dim2
// ====
if ( dim2 == 0 ) {
//--Array data
if ( pf_info->isArray ) {
dim2 = nof_strings;
//--Scalar
} else {
dim2 = 1;
}
}
pf_info->isArray |= (dim1 > 1);
// Create a new parameter field from the input values
// ==================================================
ParameterField* pf;
pf = new ParameterField(pf_info, var_name_buffers,
dim1, dim2, nof_variables,
nof_strings, data_strings);
fields[counter++] = pf;
// If field is (intentionally!) empty or
// some alternative (scalar, table, proc) for the field
// is already stored, make it inactive (we just store it,
// we do not eg. output it to sif-file!)
if ( is_inactive || nof_strings == 0 || fieldInstanceExists(pf) ) {
pf->setIsActive(false);
}
} // End read parameter fields
delete[] name_buffer;
delete[] field_name_buffer;
delete[] name_part_buffer;
delete[] index_part_buffer;
for (i = 0; i < MAX_NOF_PARAMETER_VARIABLES; i++) {
delete[] var_name_buffers[i];
}
delete[] var_name_buffers;
for (i = 0; i < MAX_NOF_PARAMETER_DATA_STRINGS; i++) {
delete[] data_strings[i];
}
delete[] data_strings;
}
void
Parameter::extractFieldInfo(istrstream& strm,
char* field_name_buffer,
char** var_name_buffers,
char& data_type,
short& dim1, short& dim2,
short& nof_variables,
bool& is_inactive)
{
is_inactive = false;
// Possible inactive marker ("-")
if ( strm.peek() == '-' ) {
extractInactiveMarker(strm);
is_inactive = true;
}
// Possible description in the beginning (old format!)
if ( strm.peek() == '(' ) {
extractFieldSizeAndVars(strm, var_name_buffers, dim1, dim2, nof_variables);
}
extractFieldNameAndType(strm, field_name_buffer, data_type);
// Possible description after the name and before the data (new format!)
if ( strm.peek() == '(' ) {
extractFieldSizeAndVars(strm, var_name_buffers, dim1, dim2, nof_variables);
}
}
void
Parameter::extractInactiveMarker(istrstream& strm)
{
// Read inactive marker from the beginning of the field ("-")
strm.get();
}
void
Parameter::extractFieldNameAndType(istrstream& strm,
char* field_name_buffer,
char& data_type)
{
// Read field name and type (== =: =.)
strm.getline(field_name_buffer, MAX_PARAMETER_FIELD_NAME_LENGTH, '=');
data_type = strm.get();
}
void
Parameter::extractFieldSizeAndVars(istrstream& strm,
char** var_name_buffers,
short& dim1, short& dim2,
short& nof_variables)
{
dim1 = dim2 = 0;
nof_variables = 0;
const int buflen = 81;
char buffer[1 + buflen];
// Read dimension desrciption
// Format is: "( [variable name1 name2 ; dim1 dim2 )"
strm.get(); // Pick of "("
strm.getline(buffer , buflen, ')' );
bool has_variables = false;
// Check if there is a variable definition
for (int i = 0; i < strlen(buffer); i++) {
if ( isalpha(buffer[i]) ) {
has_variables = true;
break;
}
}
strstream strm1;
strm1 << buffer << ends;
strm1.getline(buffer, buflen, PARAMETER_DATA_SEP);
// We have either variable defs or size description
if ( strlen(buffer) > 0 ) {
strstream strm2;
strm2 << buffer << ends;
if (has_variables) {
strcpy(var_name_buffers[nof_variables++], strm2.str());
} else {
strm2 >> dim1;
if (!strm2.eof())
strm2 >> dim2;
}
}
strm1.getline(buffer, 81, PARAMETER_DATA_SEP);
// If we now have the size description
if (strlen(buffer) > 0) {
strstream strm3;
strm3 << buffer << ends;
strm3 >> dim1;
if (!strm3.eof())
strm3 >> dim2;
}
}
bool
Parameter::fieldInstanceExists(ParameterField* param_field)
{
// Check if argument field name matches with any other existing
for (int i = 0; i < nofFields; i++) {
ParameterField* pf = fields[i];
if ( pf == NULL || pf == param_field ) {
continue;
}
if ( 0 != strcmp(param_field->getGuiName(), pf->getGuiName()) ) {
continue;
}
const char* i1 = param_field->getGuiIndex();
const char* i2 = pf->getGuiIndex();
// No indexed fields, must be the same!
if ( i1 == NULL && i2 == NULL ) {
return true;
}
// One, but no both is NULL --> different fields
if ( i1 == NULL || i2 == NULL ) {
continue;
}
// Different index names --> different fields
if ( 0 != strcmp(i1, i2) ) {
continue;
}
// Same index names and index types --> must be the same!
if ( ( param_field->isPreIndexed() && pf->isPreIndexed() ) ||
( param_field->isPostIndexed() && pf->isPostIndexed() )
) {
return true;
}
}
// No matching field found
return false;
}
void
Parameter::delete_fields()
{
for (short i = 0; i < nofFields; i++) {
delete fields[i];
}
delete[] fields;
nofFields = 0;
fields = NULL;
}
void
Parameter::delete_previousFields()
{
for (short i = 0; i < nofPreviousFields; i++) {
delete previousFields[i];
}
delete[] previousFields;
nofPreviousFields = 0;
previousFields = NULL;
}
// If parameter has a "gui-name"-field (like "HEAT_EQUATION") defined,
// return the pointer to it, otherwise return NULL
ParameterField*
Parameter::getFieldByGuiName(const char* name, bool only_active)
{
for (short i = 0; i < nofFields; i++) {
ParameterField* pf = fields[i];
if ( LibFront::in(name, pf->getGuiName()) ) {
// Check activity (minus mark in the input data like |-TEMPERATUE=1000.0)
if ( only_active && !pf->isActiveInstance() ) {
return NULL;
} else {
return pf;
}
}
}
return NULL;
}
// If parameter has a "gui-name"-field (like "HEAT_EQUATION") defined,
// return the pointer to it, otherwise return NULL
ParameterField*
Parameter::getFieldByGuiName(const char* name, const char* index, bool is_pre_indexed, bool only_active)
{
if ( index == NULL ) {
return getFieldByGuiName(name, only_active);
}
for (short i = 0; i < nofFields; i++) {
ParameterField* pf = fields[i];
if ( LibFront::in(name, pf->getGuiName()) &&
LibFront::in(index, pf->getGuiIndex()) &&
( (is_pre_indexed && pf->isPreIndexed()) ||
(!is_pre_indexed && pf->isPostIndexed())
)
) {
// Check activity (minus mark in the input data like |-TEMPERATUE=1000.0)
if ( only_active && !pf->isActiveInstance() ) {
return NULL;
} else {
return pf;
}
}
}
return NULL;
}
// If parameter has a "sif-name"-field (like "Heat Equation") defined,
// return the pointer to it, otherwise return NULL
ParameterField*
Parameter::getFieldBySifName(const char* fname, bool only_active)
{
for (short i = 0; i < nofFields; i++) {
ParameterField* parameter_field = fields[i];
if ( LibFront::in(fname, parameter_field->getSifName()) ) {
// Check activity (minus mark in the input data like |-TEMPERATUE=1000.0)
if ( only_active && !parameter_field->isActiveInstance() ) {
return NULL;
} else {
return parameter_field;
}
}
}
return NULL;
}
// Check is the parameter has given boolean field
// and get its value if defined
// NOTE: Data is suppoused to be scalar!
bool
Parameter::getFieldValueBySifName(const char* name, bool& value, bool only_active)
{
ParameterField* pf = getFieldBySifName(name, only_active);
if (pf == NULL)
return false;
char** data_strings = pf->getDataStrings();
if ( 0 == strcmp(data_strings[0], "True") )
value = true;
else
value = false;
// Value found
return true;
}
// Check is the parameter has given boolean field
// and get its value if defined
// NOTE: Data can be a vector (but not array)
bool
Parameter::getFieldValueBySifName(const char* name, int& nof_values, bool*& values, bool only_active)
{
static char str[1024];
ParameterField* pf = getFieldBySifName(name, only_active);
if (pf == NULL) {
nof_values = 0;
values = NULL;
return false;
}
short d1, d2, nof_vars;
pf ->getDataDimension(d1, d2, nof_vars);
nof_values = d1;
values = new bool[nof_values];
char** data_strings = pf->getDataStrings();
strstream strm;
strm << data_strings[0] << ends;
for (int i = 0; i < nof_values; i++) {
strm >> str;
if ( 0 == strcmp(str, "True") )
values[i] = true;
else
values[i] = false;
}
// Value found
return true;
}
// Check is the parameter has given real field
// and get its value if defined
// NOTE: Data is suppoused to be scalar!
bool
Parameter::getFieldValueBySifName(const char* name, int max_buffer_len, char* buffer, bool only_active)
{
ParameterField* pf = getFieldBySifName(name, only_active);
if (pf == NULL)
return false;
char** data = pf->getDataStrings();
strncpy(buffer, (char*)data[0], max_buffer_len);
buffer[max_buffer_len] = '\0';
// Value found
return true;
}
// Check is the parameter has given integer field
// and get its value if defined
// NOTE: Data is suppoused to be scalar!
bool
Parameter::getFieldValueBySifName(const char* name, int& value, bool only_active)
{
ParameterField* pf = getFieldBySifName(name, only_active);
if (pf == NULL)
return false;
char** data = pf->getDataStrings();
if ( !LibFront::isNumber(data[0]) )
return false;
value = atol(data[0]);
// Value found
return true;
}
// Check is the parameter has given integer field
// and get its value if defined
// NOTE: Data can be vector!
bool
Parameter::getFieldValueBySifName(const char* name, int& nof_values, int*& values, bool only_active)
{
ParameterField* pf = getFieldBySifName(name, only_active);
if (pf == NULL) {
nof_values = 0;
values = NULL;
return false;
}
short d1, d2, nof_vars;
pf ->getDataDimension(d1, d2, nof_vars);
nof_values = d1;
values = new int[nof_values];
char** data_strings = pf->getDataStrings();
strstream strm;
strm << data_strings[0];
for (int i = 0; i < nof_values; i++) {
strm >> values[i];
}
// Value found
return true;
}
// Check is the parameter has given real field
// and get its value if defined
// NOTE: Data is suppoused to be scalar!
bool
Parameter::getFieldValueBySifName(const char* name, double& value, bool only_active)
{
ParameterField* pf = getFieldBySifName(name, only_active);
if (pf == NULL)
return false;
char** data = pf->getDataStrings();
if ( !LibFront::isNumber(data[0]) )
return false;
value = atof(data[0]);
// Value found
return true;
}
// Check is the parameter has given real field
// and get its value if defined
// NOTE: Data is suppoused to be scalar!
bool
Parameter::getFieldValueBySifName(const char* name, int& nof_values, double*& values, bool only_active)
{
ParameterField* pf = getFieldBySifName(name, only_active);
if (pf == NULL) {
nof_values = 0;
values = NULL;
return false;
}
short d1, d2, nof_vars;
pf ->getDataDimension(d1, d2, nof_vars);
nof_values = d1;
values = new double[nof_values];
char** data_strings = pf->getDataStrings();
strstream strm;
strm << data_strings[0];
for (int i = 0; i < nof_values; i++) {
strm >> values[i];
}
// Value found
return true;
}
// Check if there is any change in the data
void
Parameter::getValueState(bool& value_has_changed)
{
if (dataString == NULL && dataString_previous == NULL) {
value_has_changed = false;
return;
}
if (dataString == NULL || dataString_previous == NULL) {
value_has_changed = true;
return;
}
if ( 0 == strcmp(dataString, dataString_previous ) ) {
value_has_changed = false;
return;
}
value_has_changed = true;
}
// Find if the parameter's "field_name"-field was changed from the previous value
void
Parameter::getFieldValueStateBySifName(const char* name, bool& value_is_changed)
{
// If no change in the wholw parameter
// we can answer quickly1
if (!changed) {
value_is_changed = false;
return;
}
// Ok, we have to really check the field
bool has_value;
getFieldValueStateBySifName(name, has_value, value_is_changed);
changed = false; // We have been checked for the change
}
// Find if the parameter has "field_name"-field defined and check if the
// value was changed from the previous value
void
Parameter::getFieldValueStateBySifName(const char* name, bool& has_value, bool& value_is_changed)
{
ParameterField* pf = getFieldBySifName(name);
ParameterField* pf_previous = getPreviousFieldBySifName(name);
// Not at all the parameter field --> it is not "changed"
if (pf_previous == NULL && pf == NULL ) {
has_value = false;
value_is_changed = false;
return;
}
// Not more the parametrer field --> it is "changed"
if (pf == NULL ) {
has_value = false;
value_is_changed = true;
return;
}
// New parameter field --> it is "changed"
if (pf_previous == NULL) {
has_value = true;
value_is_changed = true;
return;
}
// Ok, we have the field, we test for a change
has_value = true;
value_is_changed = true;
// Compare previous and current
int nof_ds_previous = pf_previous->getNofDataStrings();
int nof_ds_current = pf->getNofDataStrings();
// If nof data strings has changed
// NOTE: This is certainly not reliable test !!!***!!!
if (nof_ds_previous != nof_ds_current) {
return;
}
// If string-pairs are not similar
// NOTE: again not reliable test !!!***!!!
char** ds_previous = pf_previous->getDataStrings();
char** ds_current = pf->getDataStrings();
for (int i = 0; i < nof_ds_current; i++) {
if ( !strcmp(ds_previous[i], ds_current[i]) )
return;
}
// Value was not (propably :-) changed!
value_is_changed = false;
}
int
Parameter::getParentEmfTag()
{
return parentEmfTag;
}
objectType
Parameter::getParentEmfType()
{
return parentEmfType;
}
int
Parameter::getSubParentEmfTag()
{
return subParentEmfTag;
}
objectType
Parameter::getSubParentEmfType()
{
return subParentEmfType;
}
// If parameter previous values has a "gui-name"-field (like "HEAT_EQUATION") defined,
// return the pointer to it, otherwise return NULL
ParameterField*
Parameter::getPreviousFieldByGuiName(const char* fname)
{
for (short i = 0; i < nofPreviousFields; i++) {
ParameterField* parameter_field = previousFields[i];
if ( LibFront::in(fname, parameter_field->getGuiName()) )
return parameter_field;
}
return NULL;
}
// If parameter previous values has a "sif-name"-field (like "Heat Equation") defined,
// return the pointer to it, otherwise return NULL
ParameterField*
Parameter::getPreviousFieldBySifName(const char* fname)
{
for (short i = 0; i < nofPreviousFields; i++) {
ParameterField* parameter_field = previousFields[i];
if ( LibFront::in(fname, parameter_field->getSifName()) )
return parameter_field;
}
return NULL;
}
// Check is the parameter has a "field_name"-field defined
// and that its value is "value"
bool
Parameter::hasFieldValueBySifName(const char* name, char* value)
{
ParameterField* pf = getFieldBySifName(name);
if (pf == NULL)
return false;
int nof_ds = pf->getNofDataStrings();
char** data_strings = pf->getDataStrings();
for (int i = 0; i < nof_ds; i++) {
if ( 0 == strcmp(value, data_strings[i]) ) {
return true;
}
}
return false;
}
// Check is the parameter is active
// Note: by default a parameter is active, unless
// it is flagged inactive with the EFN_ACTIVE field
//
bool
Parameter::IsActive()
{
ParameterField* pf = getFieldByGuiName("ACTIVE");
// If no field at all ==> is active!
if ( pf == NULL ) {
return true;
}
char** data = pf->getDataStrings();
if ( !LibFront::ncEqual((char*)data[0], "true") ) {
return false;
} else {
return true;
}
}
// Method prints parameter into output stream in Cadinterface format
// Output of parameter name and id number is controlled by: output_type flag
// The output format of the data is controlled by: data_as_string flag
ostream&
Parameter::output_emf(ostream& out, short indent_size, short indent_level,
bool output_type,
bool data_as_string,
bool data_as_fields)
{
short& is = indent_size;
short& il = indent_level;
char* QM = "\""; // quote-mark
if (output_type) {
LibFront::output_string(out, indent_size, indent_level++, getEmfName(), false);
out << ' ' << id << endl;
}
// Parent info if applicable
if ( NO_INDEX != getParentEmfTag() )
LibFront::output_scalar(out, is, il, "Parent", NULL, getParentEmfTag());
if ( NO_INDEX != getSubParentEmfTag() )
LibFront::output_scalar(out, is, il, "Sub Parent", NULL, getSubParentEmfTag());
if ( OT_NONE != getParentEmfType() )
LibFront::output_scalar(out, is, il, "Parent Type", NULL, model->objectType2Name(getParentEmfType()), true);
LibFront::output_scalar(out, is, il, "Name", NULL, name, true);
// These are not in use!
// Mve 06.02.00
#if 0
LibFront::output_scalar(out, is, il, EFN_APPLY_COUNT, applyCount);
if (attachMode != ECIF_IGNORE) {
LibFront::output_scalar(out, is, il, EFN_ATTACH_MODE, attachMode);
}
#endif
// Data
//-as string
if (data_as_string) {
LibFront::output_scalar(out, is, il, "Data", NULL, dataString, true);
}
//-as separate fields
if (data_as_fields) {
for (short i = 0; i < nofFields; i++) {
fields[i]->output_sif(out, indent_size, indent_level, NULL);
}
}
return out;
}
// Method prints all parameter's fields into output stream.
// Output of parameter (section) type and id number is
// controlled by output_type flag
ostream&
Parameter::output_sif(ostream& out, short indent_size, short indent_level, SifOutputControl& soc)
{
// 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);
out << endl;
}
// Fields
for (short i = 0; i < nofFields; i++) {
ParameterField* pf = fields[i];
// Check that field is active, contains data 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;
}
ostream&
Parameter::output_sif_name(ostream& out, short indent_size, short indent_level, SifOutputControl& soc,
bool quoted)
{
if (soc.outputName) {
if ( model->getSolverKeywordTypeGiven(soc.sectionName, "Name") ) {
LibFront::output_scalar(out, indent_size, indent_level, "Name =", NULL, name, quoted);
} else {
LibFront::output_scalar(out, indent_size, indent_level, "Name = String", NULL, name, quoted);
}
}
return out;
}
bool
Parameter::hasDefaultName()
{
// If name not given or is in default format
if ( name == NULL && name[0] == '\0' ) {
return false;
}
const char* base_nm = getGuiName();
if ( base_nm == NULL ) {
return false;
}
strstream strm;
strm << base_nm << id << ends;
if ( 0 == strcmp(name, strm.str()) ) {
return true;
} else {
return false;
}
}
// Method copies current value in to new values
// and marks parameter unchanged
void
Parameter::resetValue()
{
// make a copy of the current data for setValue()
int len = strlen(dataString);
char* copy_string = new char[1 + len];
strcpy(copy_string, dataString);
copy_string[len] = '\0';
copied = false; // We need this to force copy in setValue() !
setValue(copy_string);
changed = false; // Now we can mark data not changed!
delete[] copy_string;
}
// Method sets object attributes.
void
Parameter::setData(int pid, char* data_string, char* param_name)
{
id = pid;
setValue(data_string);
setName(param_name);
}
// Sets parameter data
void
Parameter::setData(int pid, int parent_id, char* data_string, char* param_name)
{
id = pid;
updateParentInfo(parent_id);
setValue(data_string);
setName(param_name);
}
void
Parameter::setName(char* param_name, char* default_name)
{
// Set default name
if ( param_name == NULL || param_name[0] == '\0' ) {
strstream strm;
strm << default_name << id << ends;
update_dyna_string(name, strm.str());
// Name given
} else {
update_dyna_string(name, param_name);
}
}
void
Parameter::setValue(char* data_string)
{
// Copy current values to previous values
if (dataString != NULL && !copied) {
// Data string
update_dyna_string(dataString_previous, dataString);
// Parameter fields
delete_previousFields();
previousFields = fields;
nofPreviousFields = nofFields;
fields = NULL;
nofFields = 0;
copied = true;
}
// Store new value string
update_dyna_string(dataString, data_string);
// Create new parameter fields
// NOTE: don't DELETE parameterFields because previousParameterFields
// are now pointing to this set!!!***!!!
if ( dataString != NULL && dataString[0] != '\0' ) {
create_fields();
}
if ( (dataString_previous == NULL) ||
(0 != strcmp(dataString, dataString_previous))
) {
changed = true;
}
}
// Set new object parent info
//
void
Parameter::updateParentInfo(int parent_id)
{
parentId = parent_id;
parentEmfTag = NO_INDEX;
parentEmfType = OT_NONE;
subParentEmfTag = NO_INDEX;
subParentEmfType = OT_NONE;
ModelObject* obj = model->getModelObjectById(parent_id);
if ( obj != NULL ) {
parentEmfTag = obj->Tag();
parentEmfType = obj->getObjectType();
}
}
// Normal case when the emf-parent info defines the actual
// parent object
//
// NOTE: GridParameter (due to Layers) and BoundaryConditions (due to Groups)
// behave differently
//
void
Parameter::updateParentId()
{
ModelObject* obj = model->getModelObjectByTag(parentEmfType, parentEmfTag);
if ( obj != NULL ) {
parentId = obj->Id();
}
}
syntax highlighted by Code2HTML, v. 0.9.1