#ifndef MLIIO_H #define MLIIO_H #include "mli/mliConv.h" ///////////////////////////////////////////////////////////////////////////////////// // // This is a set of Matlab interface routines which allow data to // be loaded into tempus variables. The most common use is to specify // these routines as setting expressions to run variables and // parameters in the Runset editor. These routines may also be used // in input and parameter setting expressions for subsystems. // ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// // // mliLoad is used to load an mxArray and convert it to // almost any tempus data type except for Grids. // See mliLoadG to load a Grid. // // Usage: mliLoad(const char* fn, char* vn, const T dummy) // // where // // fn is the name of the mat-file from which data is to be loaded. // The .mat extension should be included. Use forware slashes (/) // rather than back-slashes to indicate directory paths. // // vn is the name of the variable to be loaded. // // dummy is a NULL variable of the type to be returned. dummy can be // float(), double(), int(), Complex(), // Vector(), Vector(), Vector(), Vector(), // Array(), Array(), Array(), Array() // // If the type is omitted, then a Matlab structure (mxArray*) is returned. // // Examples: // // To load the vector "v" from the file "data.mat" located // in the root directory, use the following expression: // // mliLoad("c:/data.mat", "v", Vector()) // // To load the the scalar value "f" from the file "inputs.mat" located // in the directory in which the simulation is run, use the following // expression: // // mliLoad("./inputs.mat", "f", float()) // // To load a complete Matlab data structure, "s" from "inputs.mat" use: // // mxArray* struct = mliLoad("./inputs.mat", "s") // // template // T mliLoad(const char* fn, char* vn, const T dummy); // ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// // // mliLoadG is used to load an mxArray and convert it to a Grid. // // Usage: mliLoadG(const char* fn, char* vn, const T dummy) // // where // // fn is the name of the mat-file from which data is to be loaded. // The .mat extension should be included. Use forware slashes (/) // rather than back-slashes to indicate directory paths. // // vn is the name of the variable to be loaded. // // dummy is a NULL variable of the base type to be returned. // dummy can be float(), double(), Complex(). // // The specified mat-file variable can take on two forms: // // 1. A structure having at least three fields: x, y, and g. // x is 1-dimensional vector giving the x coordinates. // y is 1-dimensional vector giving the y coordinates. // g specifies the grid values. If x is length nx and y is // length ny, g must be dimensioned nx x ny. // 2. A collection of seven variables, specifying the coordinate // grid and the grid values. Where var is the name of the variable // the collection is as follows: // varNX is the grid size in the x direction. // varNY is the grid size in the y direction. // varDX is the grid spacing in the x direction. // varDY is the grid spacing in the y direction. // varXC is the offset of the origin in x (usually zero). // varYC is the offset of the origin in y (usually zero). // // Examples: // // To load the structure "grd" from the file "grids.mat" located // in the root directory, use the following expression: // // mliLoadG("c:/grids.mat", "grd", float()) // // To load the structure "grdc" from the file "grids.mat" located // in the root directory, use the following expression: // // mliLoadG("c:/grids.mat", "grdc", Complex()) // // Alternatively, if a structure "grdc" did not exist, then the same // call would attempt to load the variables "grdc", "grdcNX", "grdcNY", // "grdcDX", "grdcDY", "grdcXC", and "grdcYC". // // template // TempGrid mliLoadG(const char* fn, char* vn, const T dummy, const float crs=1.0, const float zrs=1.0); // ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// // // mliSelect is used to load a particular element of a vector. // // Usage: mliSelect(const char* fn, char* vn, int ind, const T dummy) // // where // // fn is the name of the mat-file from which data is to be loaded. // The .mat extension should be included. Use forware slashes (/) // rather than back-slashes to indicate directory paths. // // vn is the name of the variable to be loaded and indexed. // // ind specifies the element of the variable to be returned. // // dummy is a NULL variable of the base type to be returned. // dummy can be int(), float(), double(), Complex() // // crs is an optional scale factor to be applied to the x and y coordinates. // // zrs is an optional scale factor to be applied to the grid values. // // Examples: // // To load the fifth element of the variable Cn2 from the file turb.mat: // // mliSelect("turb.mat", "cn2", 5, float()) // // To load Cn2(iloop) from the same file: // // mliSelect("turb.mat", "cn2", iloop, float()) // // template // T mliSelect(const char* fn, char* vn, int ind, const T dummy); // ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// // // mliSelect is used to load a particular element of a vector. // // Usage: mliSelect(const char* fn, char* vn, int ind, const T dummy) // // where // // fn is the name of the mat-file from which data is to be loaded. // The .mat extension should be included. Use forware slashes (/) // rather than back-slashes to indicate directory paths. // // vn is the name of the string array variable to be loaded and indexed // to determine the name of the grid variable to be loaded. // // ind specifies the index into the string array to be used to // determine the name of the grid variable to be loaded. // In Matlab notation, vn(ind,:) is used as the variable name. // // dummy is a NULL variable of the base type to be returned. // dummy can be int(), float(), double(), Complex() // // crs is an optional scale factor to be applied to the x and y coordinates. // // zrs is an optional scale factor to be applied to the grid values. // // Examples: // // To load the fifth element of the variable Cn2 from the file turb.mat: // // mliSelect("turb.mat", "cn2", 5, float()) // // To load Cn2(iloop) from the same file: // // mliSelect("turb.mat", "cn2", iloop, float()) // // template // TempGrid mliSelectG(const char* fn, char* vn, int ind, const T dummy, const float crs=1.0, const float zrs=1.0); // ///////////////////////////////////////////////////////////////////////////////////// // // End of comments for the user. Only code follows. // ///////////////////////////////////////////////////////////////////////////////////// MLI_API void mliLoadGridError(const char* fn, const char* vn); #ifndef NO_MATLAB template T mliLoad(const char* fn, const char* vn, const T dummy) { MATFile* mfp = matOpen(fn, "r"); if (mfp == NULL) { char msg[MLICONV_ERRSTR_LEN]; sprintf(msg, "Cannot open MATFile [%s] for reading variable [%s]", fn, vn); mliConvErrMsg(msg); } mxArray* mxp = matGetVariable(mfp, vn); if (mxp == NULL) { char msg[MLICONV_ERRSTR_LEN]; sprintf(msg, "Cannot read variable [%s] from MATFile [%s]", vn, fn); mliConvErrMsg(msg); } int ierr = matClose(mfp); if (ierr != 0) { char msg[MLICONV_ERRSTR_LEN]; sprintf(msg, "Trouble closing MATFile [%s] after reading variable [%s]", fn, vn); mliConvWarnMsg(msg); } T t; ierr = fromMxArray(mxp, t); if (ierr != 0) { char msg[MLICONV_ERRSTR_LEN]; sprintf(msg, "Cannot convert variable [%s] from MATFile [%s] to the proper type", vn, fn); mliConvErrMsg(msg); } mxDestroyArray(mxp); return t; } template Grid mliLoad(const char* fn, const char* vn, const Grid dummy) { mliLoadGridError(fn, vn); return Grid(); } MLI_API mxArray* mliLoad(const char* fn, const char* vn); template TempGrid mliLoadG(const char* fn, const char* vn, const T dummy, const float crs=1.0f, const float zrs=1.0) { MATFile* mfp = matOpen(fn, "r"); if (mfp == NULL) { char msg[MLICONV_ERRSTR_LEN]; sprintf(msg, "Cannot open MATFile [%s] for reading variable [%s]", fn, vn); mliConvErrMsg(msg); } mxArray* mxp = matGetVariable(mfp, vn); if (mxp == NULL) { char msg[MLICONV_ERRSTR_LEN]; sprintf(msg, "Cannot read variable [%s] from MATFile [%s]", vn, fn); mliConvErrMsg(msg); } int ierr = matClose(mfp); if (ierr != 0) { char msg[MLICONV_ERRSTR_LEN]; sprintf(msg, "Trouble closing MATFile [%s] after reading variable [%s]", fn, vn); mliConvWarnMsg(msg); } if (!mxIsStruct(mxp)) { char vnp[MLICONV_ERRSTR_LEN]; strcpy(vnp, vn); strcat(vnp, "DX"); float dx = mliLoad(fn, vnp, float()); strcpy(vnp, vn); strcat(vnp, "DY"); float dy = mliLoad(fn, vnp, float()); strcpy(vnp, vn); strcat(vnp, "XC"); float xc = mliLoad(fn, vnp, float()); strcpy(vnp, vn); strcat(vnp, "YC"); float yc = mliLoad(fn, vnp, float()); TempArray ta; fromMxArray(mxp, ta); TempGrid t(ta, dx*(ta.dim(0)-1), dy*(ta.dim(1)-1), xc, yc); if (crs != 1.0) t.rescale(crs); if (zrs != 1.0) t *= zrs; mxDestroyArray(mxp); return t; } else { TempGrid t; ierr = fromMxArray(mxp, t); if (ierr != 0) { char msg[MLICONV_ERRSTR_LEN]; sprintf(msg, "Cannot convert variable [%s] from MATFile [%s] to the proper type", vn, fn); mliConvErrMsg(msg); } if (crs != 1.0) t.rescale(crs); if (zrs != 1.0) t *= zrs; mxDestroyArray(mxp); return t; } } MLI_API double mliSelect(const char* fn, int ind, const char* vn); MLI_API double mliSelect(const char* fn, int ind0, int ind1, const char* vn); template T mliSelect(const char* fn, const char* vn, int ind, const T dummy) { mxArray* mxdum; mxArray* mxary = mliLoad(fn, vn, mxdum); char* vni = NULL; fromMxArray(mxary, vni, ind); mxDestroyArray(mxary); T t(mliLoad(fn, vni, dummy)); free(vni); return t; } template TempGrid mliSelectG(const char* fn, const char* vn, int ind, const T dummy, const float crs=1.0, const float zrs=1.0) { mxArray* mxdum; mxArray* mxary = mliLoad(fn, vn, mxdum); char* vni = NULL; fromMxArray(mxary, vni, ind); mxDestroyArray(mxary); TempGrid t(mliLoadG(fn, vni, dummy, crs, zrs)); free(vni); return t; } template T mliSelectC(const char* fn, const char* vn, int ind, const T dummy) { if (ind < 0) { mliConvErrMsg("T mliSelectC(...) called with negative index"); } mxArray* mxdum; mxArray* mxaryc = mliLoad(fn, vn, mxdum); if (!mxIsCell(mxaryc)) { mliConvErrMsg("T mliSelectC(...) called with for non-cell array"); } if (ind >= mxGetNumberOfElements(mxaryc)) { mliConvErrMsg("T mliSelectC(...) called with index exceeding the number of elements"); } mxArray* mxary = mxGetCell(mxaryc, ind+1); // T t(); XLY T t; fromMxArray(mxary, t); mxDestroyArray(mxaryc); return t; } template TempGrid mliSelectGC(const char* fn, const char* vn, int ind, const T dummy, const float crs=1.0, const float zrs=1.0) { if (ind < 0) { mliConvErrMsg("T mliSelectGC(...) called with negative index"); } mxArray* mxdum; mxArray* mxaryc = mliLoad(fn, vn, mxdum); if (!mxIsCell(mxaryc)) { mliConvErrMsg("T mliSelectGC(...) called with for non-cell array"); } if (ind >= mxGetNumberOfElements(mxaryc)) { mliConvErrMsg("T mliSelectGC(...) called with index exceeding the number of elements"); } mxArray* mxary = mxGetCell(mxaryc, ind+1); TempGrid t; fromMxArray(mxary, t); mxDestroyArray(mxaryc); if (crs != 1.0) t.rescale(crs); if (zrs != 1.0) t *= zrs; return t; } #endif #endif // MLIIO_H