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