/////////////////////////////////////////////////////////////////////////////// /// Receive the feedback from CFD about the stop command /// ///\return 0 if no error occurred /////////////////////////////////////////////////////////////////////////////// int cfdReceiveFeedback( ) { int i = 0, imax = 10000, flag; // Wait for the feedback from FFD while(cosim->para->flag==0 && i<imax) { if(cosim->para->ffdError==1) { ModelicaError(cosim->ffd->msg); } else { Sleep(10000); i++; } } if(i<imax) { if(cosim->para->ffdError==1) { ModelicaError(cosim->ffd->msg); } else { ModelicaMessage("Successfully stopped the FFD simulation.\n"); flag = 0; } } else { ModelicaError("Error: Can not stop the FFD simulation in required time.\n"); } free(cosim->para); free(cosim->modelica); free(cosim->ffd); free(cosim); return flag; } // End of cfdReceiveFeedback()
void* allocateFileWriter( const char* instanceName, const char* fileName){ FileWriter* ID; FILE* fp; if ( FileWriterNames_n == 0 ){ /* Allocate memory for array of file names */ FileWriterNames = malloc(sizeof(char*)); InstanceNames = malloc(sizeof(char*)); if ( FileWriterNames == NULL || InstanceNames == NULL) ModelicaError("Not enough memory in fileWriterStructure.c for allocating FileWriterNames and InstanceNames."); } else{ /* Check if the file name is unique */ signed int index = fileWriterIsUnique(fileName); if (index>=0){ ModelicaFormatError("FileWriter %s writes to file %s which is already used by FileWriter %s.\nEach FileWriter must use a unique file name.", instanceName, fileName, InstanceNames[index]); } /* Reallocate memory for array of file names */ FileWriterNames = realloc(FileWriterNames, (FileWriterNames_n+1) * sizeof(char*)); InstanceNames = realloc(InstanceNames, (FileWriterNames_n+1) * sizeof(char*)); if ( FileWriterNames == NULL || InstanceNames == NULL ) ModelicaError("Not enough memory in fileWriterStructure.c for reallocating FileWriterNames and InstanceNames."); } /* Allocate memory for this file name */ FileWriterNames[FileWriterNames_n] = malloc((strlen(fileName)+1) * sizeof(char)); InstanceNames[FileWriterNames_n] = malloc((strlen(instanceName)+1) * sizeof(char)); if ( FileWriterNames[FileWriterNames_n] == NULL || InstanceNames[FileWriterNames_n] == NULL) ModelicaError("Not enough memory in fileWriterStructure.c for allocating FileWriterNames[] and InstanceNames[]."); /* Copy the file name */ strcpy(FileWriterNames[FileWriterNames_n], fileName); strcpy(InstanceNames[FileWriterNames_n], instanceName); FileWriterNames_n++; ID = (FileWriter*)malloc(sizeof(*ID)); if ( ID == NULL ) ModelicaFormatError("Not enough memory in fileWriterStructure.c for allocating ID of FileWriter %s.", instanceName); ID->fileWriterName = malloc((strlen(fileName)+1) * sizeof(char)); if ( ID->fileWriterName == NULL ) ModelicaFormatError("Not enough memory in fileWriterStructure.c for allocating ID->fileWriterName in FileWriter %s.", instanceName); strcpy(ID->fileWriterName, fileName); ID->instanceName = malloc((strlen(instanceName)+1) * sizeof(char)); if ( ID->instanceName == NULL ) ModelicaFormatError("Not enough memory in fileWriterStructure.c for allocating ID->instanceName in FileWriter %s.", instanceName); strcpy(ID->instanceName, instanceName); fp = fopen(fileName, "w"); if (fp == NULL) ModelicaFormatError("In fileWriterStructure.c: Failed to create empty file %s during initialisation.", fileName); if (fclose(fp)==EOF) ModelicaFormatError("In fileWriterStructure.c: Returned an error when closing %s.", fileName); return (void*)ID; }
///////////////////////////////////////////////////// // External function that exchanges a value with // an array. The array size is dynamically changed // as needed. // // Arguments // --------- // object: C structure for storage of the array // iX: index where x will be stored (1-based index) // x: value to be stored // iY: value to be returned (1-based index) // // Pierre Vigouroux, LBNL 7/18/2011 // svn-id=$Id$ ///////////////////////////////////////////////////// double exchangeValues(void* object, int iX, double x, int iY){ ExternalObjectStructure* table = (ExternalObjectStructure*) object; const int nInc = 10; int nTab=table->n; int nNew=iX-1+nInc; // temporary array used while increasing the size of table double *tab2=NULL; //////////////////////////////////////////// // Check input if (iX == 0 || iY == 0) ModelicaError("Index is one-based in exchangeValues.c."); //////////////////////////////////////////// // Manage memory. // // At first call, initialize storage if ( table->x == NULL ){ table->x= malloc( nNew * sizeof(double) ); if ( table->x == NULL ) ModelicaError("Out of memory in storeValue.c when allocating memory for table."); table->n = nNew; table->x[iX-1] = x; if (iX == iY) return x; else return 0; } if (iX > nTab){ // Assign more memory before storing the value tab2 = malloc( nTab * sizeof(double) ); if ( tab2 == NULL ) ModelicaError("Out of memory in storeValue.c when allocating memory for tab2."); // Copy the values of x in tab2 memcpy(tab2, table->x, nTab * sizeof(double) ); // Increase the size of x free(table->x); table->x = malloc(nNew * sizeof(double) ); if ( table->x == NULL ) ModelicaError("Out of memory in storeValue.c when allocating memory for table->x."); table->n = nNew; // Copy previous values memcpy(table->x, tab2, nTab * sizeof(double)); free(tab2); } //////////////////////////////////////////// // Store and return the data table->x[iX-1] = x; // printf ("returning: %4.2f", table->x[iY-1]); return table->x[iY-1]; };
// Error and warnings are sent to either the standard error output or // the native Modelica tool log and error window static void errorMessage_internal(char *errorMessage) { #if USE_MODELICA_FUNCTIONS ModelicaError(errorMessage); #else std::cerr << "\a" << errorMessage << std::endl << ERROR_MSG << std::endl; getchar(); exit(1); #endif }
/* Create the structure "table" and return pointer to "table". */ void* initArray() { ExternalObjectStructure* table = malloc(sizeof(ExternalObjectStructure)); if ( table == NULL ) ModelicaError("Not enough memory in initArray.c."); /* Number of elements in the array */ table->n=0; /* initialise nEle to 0 */ table->x=NULL; /* set the pointer to null */ return (void*) table; };
void* ED_createXML(const char* fileName) { XMLFile* xml = NULL; XmlParser xmlParser; XmlNodeRef root = XmlParser_parse_file(&xmlParser, fileName); if (root == NULL) { ModelicaFormatError("Cannot parse file \"%s\"\n", fileName); } xml = (XMLFile*)malloc(sizeof(XMLFile)); if (xml != NULL) { xml->fileName = _strdup(fileName); if (xml->fileName == NULL) { XmlNode_deleteTree(root); free(xml); ModelicaError("Memory allocation error\n"); return NULL; } xml->loc = ED_INIT_LOCALE; xml->root = root; } else { ModelicaError("Memory allocation error\n"); } return xml; }
static FILE* ModelicaStreams_openFileForWriting(const char* fileName) { /* Open text file for writing (with append) */ FILE* fp; /* Check fileName */ if ( strlen(fileName) == 0 ) { ModelicaError("fileName is an empty string.\n" "Opening of file is aborted\n"); } /* Open file */ fp = fopen(fileName, "a"); if ( fp == NULL ) { ModelicaFormatError("Not possible to open file \"%s\" for writing:\n" "%s\n", fileName, strerror(errno)); } return fp; }
static char* findValue(XmlNodeRef* root, const char* varName, const char* fileName) { char* token = NULL; char* buf = _strdup(varName); if (buf != NULL) { int elementError = 0; strcpy(buf, varName); token = strtok(buf, "."); if (token == NULL) { elementError = 1; } while (token != NULL && elementError == 0) { int i; int foundToken = 0; for (i = 0; i < XmlNode_getChildCount(*root); i++) { XmlNodeRef child = XmlNode_getChild(*root, i); if (XmlNode_isTag(child, token)) { *root = child; token = strtok(NULL, "."); foundToken = 1; break; } } if (foundToken == 0) { elementError = 1; } } free(buf); if (elementError == 1) { ModelicaFormatError("Error in line %i when reading element \"%s\" from file \"%s\"\n", XmlNode_getLine(*root), varName, fileName); } XmlNode_getValue(*root, &token); } else { ModelicaError("Memory allocation error\n"); } return token; }
void prependString(const char* fileName, const char* string){ char *origString; FILE *fOut; long fsize; /* read original file contents */ FILE *fr = fopen(fileName, "r"); if(fseek(fr, 0, SEEK_END)!=0) ModelicaFormatError("The file %s could not be read.", fileName); fsize = ftell(fr); if (fsize==-1) ModelicaFormatError("The file %s could not be read.", fileName); if(fseek(fr, 0, SEEK_SET)!=0) ModelicaFormatError("The file %s could not be read.", fileName); origString = malloc(fsize + 1); if ( origString == NULL ){ /* not enough memory is available: file too large */ ModelicaError("Not enough memory in fileWriterInit.c for prepending string."); } if (fread(origString, fsize, 1, fr)==0) ModelicaFormatError("The file %s could not be read.", fileName); fclose(fr); origString[fsize] = '\0'; /* write new contents */ fOut = fopen(fileName, "w"); /* prepended string */ if (fputs(string, fOut)==EOF) ModelicaFormatError("The file %s could not be written.", fileName); /* original data */ if (fputs(origString, fOut)==EOF) ModelicaFormatError("The file %s could not be written.", fileName); fclose(fOut); free(origString); }
/////////////////////////////////////////////////////////////////////////////// /// Start the cosimulation /// /// Allocate memory for the data exchange and launch CFD simulation /// ///\param cfdFilNam Name of the input file for the CFD simulation ///\param name Pointer to the names of surfaces and fluid ports ///\param A Pointer to the area of surfaces in the same order of name ///\param til Pointer to the tilt of surface in the same order of name ///\param bouCon Pointer to the type of thermal boundary condition in the /// same order of name ///\param nPorts Number of fluid ports ///\param portName Pointer to the name of fluid ports ///\param haveSensor Flag: 1->have sensor; 0->No sensor ///\param sensorName Pointer to the names of the sensors used in CFD ///\param haveShade Flag: 1->have shade; 0->no shade ///\param nSur Number of surfaces ///\param nSen Number of sensors ///\param nConExtWin Number of exterior construction with windows ///\param nXi Number of species ///\param nC Number of trace substances ///\param rho_start Density at initial state /// ///\return 0 if no error occurred /////////////////////////////////////////////////////////////////////////////// int cfdStartCosimulation(char *cfdFilNam, char **name, double *A, double *til, int *bouCon, int nPorts, char** portName, int haveSensor, char **sensorName, int haveShade, int nSur, int nSen, int nConExtWin, int nXi, int nC, double rho_start) { int i, nBou; /**************************************************************************** | For call FFD-DLL ****************************************************************************/ //Define loaded library handle #ifdef _MSC_VER //Windows HINSTANCE hinstLib; #else //Linux void *hinstLib; #endif //Define function type typedef int (*MYPROC)(CosimulationData *); MYPROC ProcAdd; cosim = (CosimulationData *) malloc(sizeof(CosimulationData)); cosim->para = (ParameterSharedData *) malloc(sizeof(ParameterSharedData)); cosim->modelica = (ModelicaSharedData *) malloc(sizeof(ModelicaSharedData)); cosim->ffd = (ffdSharedData *) malloc(sizeof(ffdSharedData)); /**************************************************************************** | allocate the memory and assign the data ****************************************************************************/ cosim->para->fileName = (char *) malloc(sizeof(char)*(strlen(cfdFilNam)+1)); strcpy(cosim->para->fileName, cfdFilNam); cosim->para->nSur = nSur; cosim->para->nSen = nSen; cosim->para->nConExtWin= nConExtWin; cosim->para->nPorts = nPorts; cosim->para->sha = haveShade; cosim->para->nC = nC; cosim->para->nXi = nXi; cosim->para->rho_start = rho_start; nBou = nSur + nPorts; cosim->para->name = (char**) malloc(nSur*sizeof(char *)); cosim->para->are = (REAL *) malloc(nSur*sizeof(REAL)); cosim->para->til = (REAL *) malloc(nSur*sizeof(REAL)); cosim->para->bouCon = (int *) malloc(nSur*sizeof(int)); for(i=0; i<nSur; i++) { cosim->para->name[i] = (char *)malloc(sizeof(char) *(strlen(name[i])+1)); strcpy(cosim->para->name[i], name[i]); cosim->para->are[i] = (REAL) A[i]; cosim->para->til[i] = (REAL) til[i]; cosim->para->bouCon[i] = bouCon[i]; } cosim->para->portName = (char**) malloc(nPorts*sizeof(char *)); for(i=0; i<nPorts; i++) { cosim->para->portName[i] = (char *)malloc(sizeof(char)*(strlen(portName[i])+1)); strcpy(cosim->para->portName[i], portName[i]); } if(haveSensor) { cosim->para->sensorName = (char **) malloc(nSen*sizeof(char *)); cosim->ffd->senVal = (REAL *) malloc(nSen*sizeof(REAL)); for(i=0; i<nSen; i++) { cosim->para->sensorName[i] = (char *)malloc(sizeof(char)*(strlen(sensorName[i])+1)); strcpy(cosim->para->sensorName[i], sensorName[i]); } } // Set the flag to initial value cosim->modelica->flag = 0; cosim->ffd->flag = 0; cosim->para->flag = 1; cosim->para->ffdError = 0; cosim->modelica->temHea = (REAL *) malloc(nSur*sizeof(REAL)); // Having a shade for window if(haveShade==1) { cosim->modelica->shaConSig = (REAL *) malloc(nConExtWin*sizeof(REAL)); cosim->modelica->shaAbsRad = (REAL *) malloc(nConExtWin*sizeof(REAL)); } cosim->modelica->mFloRatPor = (REAL *) malloc(nPorts*sizeof(REAL)); cosim->modelica->TPor = (REAL *) malloc(nPorts*sizeof(REAL)); cosim->modelica->XiPor = (REAL **) malloc(nPorts*sizeof(REAL *)); cosim->ffd->XiPor = (REAL **) malloc(nPorts*sizeof(REAL *)); for(i=0; i<nPorts; i++) { cosim->modelica->XiPor[i] = (REAL *) malloc(cosim->para->nXi*sizeof(REAL)); cosim->ffd->XiPor[i] = (REAL *) malloc(cosim->para->nXi*sizeof(REAL)); } cosim->modelica->CPor = (REAL **) malloc(nPorts*sizeof(REAL *)); cosim->ffd->CPor = (REAL **) malloc(nPorts*sizeof(REAL *)); for(i=0; i<nPorts; i++) { cosim->modelica->CPor[i] = (REAL *) malloc(cosim->para->nC*sizeof(REAL)); cosim->ffd->CPor[i] = (REAL *) malloc(cosim->para->nC*sizeof(REAL)); } cosim->ffd->temHea = (REAL *) malloc(nSur*sizeof(REAL)); if(haveShade==1) cosim->ffd->TSha = (REAL *) malloc(nConExtWin*sizeof(REAL)); cosim->ffd->TPor = (REAL *) malloc(nPorts*sizeof(REAL)); cosim->ffd->msg = (REAL *) malloc(400*sizeof(char)); /**************************************************************************** | Get a handle to the DLL module. ****************************************************************************/ #ifdef _MSC_VER //Windows #if _WIN64 hinstLib = LoadLibrary(TEXT("Resources/Library/win64/ffd.dll")); #elif _WIN32 hinstLib = LoadLibrary(TEXT("Resources/Library/win32/ffd.dll")); #else ModelicaError("Error: Failed to detect 32 or 64 bit Windows system in cfdStartCosimulation.c.\n"); #endif #elif __linux__ //Linux #if UINTPTR_MAX == 0xffffffff /* 32-bit */ hinstLib = dlopen("Resources/Library/linux32/libffd.so", RTLD_LAZY); #elif UINTPTR_MAX == 0xffffffffffffffff /* 64-bit */ hinstLib = dlopen("Resources/Library/linux64/libffd.so", RTLD_LAZY); #else ModelicaError("Error: Failed to detect 32 or 64 bit Linux system in cfdStartCosimulation.c.\n"); #endif #else /* Neither MSC nor Linux */ ModelicaError("Error: Unsupported operating system in cfdStartCosimulation.c.\n"); #endif // If the handle is valid, try to get the function address. if(hinstLib!=NULL) { #ifdef _MSC_VER ProcAdd = (MYPROC) GetProcAddress(hinstLib, "ffd_dll"); #else ProcAdd = (MYPROC) dlsym(hinstLib, "ffd_dll"); #endif } else { ModelicaError("Error: Could not find dll handle.\n"); } // If the function address is valid, call the function. if (ProcAdd!=NULL) { //call function: passing pointer of NAME struct ProcAdd(cosim); } else{ ModelicaError("Error: Could not find dll function address.\n"); } return 0; } // End of cfdStartCosimulation()
/* The usertab function needs to be in a separate object or clang/gcc optimize the code in such a way that the user-defined usertab gets sent the wrong input. NOTE: If a dummy usertab is included in your code, you may be unable to also provide a user-defined usertab. If you use dynamic linking this is sometimes possible: when the simulation executable provides a usertab object, it will be part of the table of loaded objects and when later loading the shared object version of ModelicaStandardTables, the dummy usertab will not be loaded by the dynamic linker; this is what can confuse C-compilers and why this function is in a separate file). The interface of usertab is defined in ModelicaStandardTables.c */ #include "ModelicaUtilities.h" #if defined(DUMMY_FUNCTION_USERTAB) #if (defined(__clang__) || defined(__GNUC__)) && !(defined(__apple_build_version__) || defined(__APPLE__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(__CYGWIN__)) int usertab(char* tableName, int nipo, int dim[], int* colWise, double** table) __attribute__ ((weak, alias ("dummy_usertab"))); #define USERTAB_NAME dummy_usertab #else #define USERTAB_NAME usertab #endif /* clang/gcc weak linking */ int USERTAB_NAME(char* tableName, int nipo, int dim[], int* colWise, double** table) { ModelicaError("Function \"usertab\" is not implemented\n"); return 1; /* Error */ }
// This implementation uses the native Modelica tool log and error window to report errors void errorMessage(char *errorMessage){ ModelicaError(errorMessage); }