1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 Reader module for Fieldview9 to read OpenFOAM mesh and data.
27 Creates new 'fvbin' type executable which needs to be installed in place
30 Implements a reader for combined mesh&results on an unstructured mesh.
32 See Fieldview Release 9 Reference Manual and coding in user/ directory
33 of the Fieldview release.
35 \*---------------------------------------------------------------------------*/
38 #include "IOobjectList.H"
39 #include "GeometricField.H"
40 #include "pointFields.H"
41 #include "volPointInterpolation.H"
42 #include "readerDatabase.H"
43 #include "wallPolyPatch.H"
45 #include "cellModeller.H"
47 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
51 // Define various Fieldview constants and prototypes
53 #include "fv_reader_tags.h"
55 static const int FVHEX = 2;
56 static const int FVPRISM = 3;
57 static const int FVPYRAMID = 4;
58 static const int FVTET = 1;
59 static const int ITYPE = 1;
61 unsigned int fv_encode_elem_header(int elem_type, int wall_info[]);
62 void time_step_get_value(float*, int, int*, float*, int*);
63 void fv_error_msg(const char*, const char*);
65 void reg_single_unstruct_reader
70 char*, int*, int*, int*, int*, int*, int*,
71 int[], int*, char[][80], int[], int*, char[][80], int*
75 int*, int*, int*, float[], int*, float[], int*
79 int create_tet(const int, const int[8], const int[]);
80 int create_pyramid(const int, const int[8], const int[]);
81 int create_prism(const int, const int[8], const int[]);
82 int create_hex(const int, const int[8], const int[]);
84 typedef unsigned char uChar;
85 extern uChar create_bndry_face_buffered
95 * just define empty readers here for ease of linking.
96 * Comment out if you have doubly defined linking error on this symbol
98 void ftn_register_data_readers()
102 * just define empty readers here for ease of linking.
103 * Comment out if you have doubly defined linking error on this symbol
105 void ftn_register_functions()
109 * just define empty readers here for ease of linking.
110 * Comment out if you have doubly defined linking error on this symbol
112 void register_functions()
116 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
120 // Storage for all OpenFOAM state (mainly database & mesh)
122 static readerDatabase db_;
125 // Write fv error message.
126 static void errorMsg(const string& msg)
128 fv_error_msg("Foam Reader", msg.c_str());
132 // Simple check if directory is valid case directory.
133 static bool validCase(const fileName& rootAndCase)
135 //if (isDir(rootAndCase/"system") && isDir(rootAndCase/"constant"))
136 if (isDir(rootAndCase/"constant"))
147 // Check whether case has topo changes by looking back from last time
148 // to first directory with polyMesh/cells.
149 static bool hasTopoChange(const instantList& times)
151 label lastIndex = times.size()-1;
153 const Time& runTime = db_.runTime();
155 // Only set time; do not update mesh.
156 runTime.setTime(times[lastIndex], lastIndex);
158 fileName facesInst(runTime.findInstance(polyMesh::meshSubDir, "faces"));
160 // See if cellInst is constant directory. Note extra .name() is for
161 // parallel cases when runTime.constant is '../constant'
162 if (facesInst != runTime.constant().name())
164 Info<< "Found cells file in " << facesInst << " so case has "
165 << "topological changes" << endl;
171 Info<< "Found cells file in " << facesInst << " so case has "
172 << "no topological changes" << endl;
179 static bool selectTime(const instantList& times, int* iret)
181 List<float> fvTimes(2*times.size());
185 fvTimes[2*timeI] = float(timeI);
186 fvTimes[2*timeI+1] = float(times[timeI].value());
195 time_step_get_value(fvTimes.begin(), times.size(), &istep, &time, iret);
199 errorMsg("Out of memory.");
210 errorMsg("Unspecified error.");
214 Info<< "Selected timeStep:" << istep << " time:" << scalar(time) << endl;
216 // Set time and load mesh.
217 db_.setTime(times[istep], istep);
223 // Gets (names of) all fields in all timesteps.
224 static void createFieldNames
227 const instantList& Times,
231 // From foamToFieldView9/getFieldNames.H:
233 HashSet<word> volScalarHash;
234 HashSet<word> volVectorHash;
235 HashSet<word> surfScalarHash;
236 HashSet<word> surfVectorHash;
242 const word& timeName = Times[timeI].name();
244 // Add all fields to hashtable
245 IOobjectList objects(runTime, timeName);
247 wordList vsNames(objects.names(volScalarField::typeName));
249 forAll(vsNames, fieldI)
251 volScalarHash.insert(vsNames[fieldI]);
254 wordList vvNames(objects.names(volVectorField::typeName));
256 forAll(vvNames, fieldI)
258 volVectorHash.insert(vvNames[fieldI]);
262 db_.setFieldNames(volScalarHash.toc(), volVectorHash.toc());
266 // Appends interpolated values of fieldName to vars array.
267 static void storeScalarField
269 const volPointInterpolation& pInterp,
270 const word& fieldName,
275 label nPoints = db_.mesh().nPoints();
276 label nTotPoints = nPoints + db_.polys().size();
282 db_.runTime().timeName(),
288 if (ioHeader.headerOk())
290 Info<< "Storing " << nTotPoints << " of interpolated " << fieldName
293 volScalarField field(ioHeader, db_.mesh());
295 pointScalarField psf(pInterp.interpolate(field));
299 vars[pointI++] = float(psf[i]);
302 const labelList& polys = db_.polys();
306 label cellI = polys[i];
308 vars[pointI++] = float(field[cellI]);
313 Info<< "Storing " << nTotPoints << " of dummy values of " << fieldName
316 for (label i = 0; i < nPoints; i++)
318 vars[pointI++] = 0.0;
321 const labelList& polys = db_.polys();
325 vars[pointI++] = 0.0;
331 // Appends interpolated values of fieldName to vars array.
332 static void storeVectorField
334 const volPointInterpolation& pInterp,
335 const word& fieldName,
340 label nPoints = db_.mesh().nPoints();
342 label nTotPoints = nPoints + db_.polys().size();
348 db_.runTime().timeName(),
354 if (ioHeader.headerOk())
356 Info<< "Storing " << nTotPoints << " of interpolated " << fieldName
359 volVectorField field(ioHeader, db_.mesh());
361 for (direction d = 0; d < vector::nComponents; d++)
363 tmp<volScalarField> tcomp = field.component(d);
364 const volScalarField& comp = tcomp();
366 pointScalarField psf(pInterp.interpolate(comp));
370 vars[pointI++] = float(psf[i]);
373 const labelList& polys = db_.polys();
377 label cellI = polys[i];
379 vars[pointI++] = float(comp[cellI]);
385 Info<< "Storing " << nTotPoints << " of dummy values of " << fieldName
388 for (direction d = 0; d < vector::nComponents; d++)
390 for (label i = 0; i < nPoints; i++)
392 vars[pointI++] = 0.0;
395 const labelList& polys = db_.polys();
399 vars[pointI++] = 0.0;
406 // Returns Fieldview face_type of mesh face faceI.
407 static label getFvType(const polyMesh& mesh, const label faceI)
409 return mesh.boundaryMesh().whichPatch(faceI) + 1;
413 // Returns Fieldview face_type of face f.
414 static label getFaceType
416 const polyMesh& mesh,
417 const labelList& faceLabels,
421 // Search in subset faceLabels of faces for index of face f.
422 const faceList& faces = mesh.faces();
424 forAll(faceLabels, i)
426 label faceI = faceLabels[i];
428 if (f == faces[faceI])
430 // Convert patch to Fieldview face_type.
431 return getFvType(mesh, faceI);
435 FatalErrorIn("getFaceType")
436 << "Cannot find face " << f << " in mesh face subset " << faceLabels
437 << abort(FatalError);
443 // Returns Fieldview face_types for set of faces
444 static labelList getFaceTypes
446 const polyMesh& mesh,
447 const labelList& cellFaces,
448 const faceList& cellShapeFaces
451 labelList faceLabels(cellShapeFaces.size());
453 forAll(cellShapeFaces, i)
455 faceLabels[i] = getFaceType(mesh, cellFaces, cellShapeFaces[i]);
462 * Callback for querying file contents. Taken from user/user_unstruct_combined.f
464 void user_query_file_function
467 char* fname, /* filename */
468 int* lenf, /* length of fName */
469 int* iunit, /* fortran unit to use */
470 int* max_grids, /* maximum number of grids allowed */
471 int* max_face_types,/* maximum number of face types allowed */
472 int* max_vars, /* maximum number of result variables allowed per */
476 int* num_grids, /* number of grids that will be read from data file */
477 int num_nodes[], /* (array of node counts for all grids) */
478 int* num_face_types, /* number of special face types */
479 char face_type_names[][80], /* array of face-type names */
480 int wall_flags[], /* array of flags for the "wall" behavior */
481 int* num_vars, /* number of result variables per grid point */
482 char var_names[][80], /* array of variable names */
483 int* iret /* return value */
486 fprintf(stderr, "\n** user_query_file_function\n");
488 string rootAndCaseString(fname, *lenf);
490 fileName rootAndCase(rootAndCaseString);
494 if (!validCase(rootAndCase))
496 setName = rootAndCase.name();
498 rootAndCase = rootAndCase.path();
500 word setDir = rootAndCase.name();
502 rootAndCase = rootAndCase.path();
504 word meshDir = rootAndCase.name();
506 rootAndCase = rootAndCase.path();
507 rootAndCase = rootAndCase.path();
512 && meshDir == polyMesh::typeName
513 && validCase(rootAndCase)
516 // Valid set (hopefully - cannot check contents of setName yet).
522 "Could not find system/ and constant/ directory in\n"
524 + "\nPlease select an OpenFOAM case directory."
534 fileName rootDir(rootAndCase.path());
536 fileName caseName(rootAndCase.name());
538 // handle trailing '/'
539 if (caseName.empty())
541 caseName = rootDir.name();
542 rootDir = rootDir.path();
545 Info<< "rootDir : " << rootDir << endl
546 << "caseName : " << caseName << endl
547 << "setName : " << setName << endl;
550 // Get/reuse database and mesh
553 bool caseChanged = db_.setRunTime(rootDir, caseName, setName);
560 instantList Times = db_.runTime().times();
562 // If topo case set database time and update mesh.
563 if (hasTopoChange(Times))
565 if (!selectTime(Times, iret))
570 else if (caseChanged)
572 // Load mesh (if case changed) to make sure we have nPoints etc.
578 // Set output variables
583 const fvMesh& mesh = db_.mesh();
585 label nTotPoints = mesh.nPoints() + db_.polys().size();
587 num_nodes[0] = nTotPoints;
589 Info<< "setting num_nodes:" << num_nodes[0] << endl;
591 Info<< "setting num_face_types:" << mesh.boundary().size() << endl;
593 *num_face_types = mesh.boundary().size();
595 if (*num_face_types > *max_face_types)
597 errorMsg("Too many patches. FieldView limit:" + name(*max_face_types));
605 forAll(mesh.boundaryMesh(), patchI)
607 const polyPatch& patch = mesh.boundaryMesh()[patchI];
609 strcpy(face_type_names[patchI], patch.name().c_str());
611 if (isA<wallPolyPatch>(patch))
613 wall_flags[patchI] = 1;
617 wall_flags[patchI] = 0;
619 Info<< "Patch " << patch.name() << " is wall:"
620 << wall_flags[patchI] << endl;
623 //- Find all volFields and add them to database
624 createFieldNames(db_.runTime(), Times, setName);
626 *num_vars = db_.volScalarNames().size() + 3*db_.volVectorNames().size();
628 if (*num_vars > *max_vars)
630 errorMsg("Too many variables. FieldView limit:" + name(*max_vars));
640 forAll(db_.volScalarNames(), i)
642 const word& fieldName = db_.volScalarNames()[i];
644 const word& fvName = db_.getFvName(fieldName);
646 strcpy(var_names[nameI++], fvName.c_str());
649 forAll(db_.volVectorNames(), i)
651 const word& fieldName = db_.volVectorNames()[i];
653 const word& fvName = db_.getFvName(fieldName);
655 strcpy(var_names[nameI++], (fvName + "x;" + fvName).c_str());
656 strcpy(var_names[nameI++], (fvName + "y").c_str());
657 strcpy(var_names[nameI++], (fvName + "z").c_str());
665 * Callback for reading timestep. Taken from user/user_unstruct_combined.f
667 void user_read_one_grid_function
669 int* iunit, /* in: fortran unit number */
670 int* igrid, /* in: grid number to read */
671 int* nodecnt, /* in: number of nodes to read */
672 float xyz[], /* out: coordinates of nodes: x1..xN y1..yN z1..zN */
673 int* num_vars, /* in: number of results per node */
674 float vars[], /* out: values per node */
675 int* iret /* out: return value */
678 fprintf(stderr, "\n** user_read_one_grid_function\n");
682 errorMsg("Illegal grid number " + Foam::name(*igrid));
690 instantList Times = db_.runTime().times();
692 // Set database time and update mesh.
693 // Note: this should not be nessecary here. We already have the correct
694 // time set and mesh loaded. This is only nessecary because Fieldview
695 // otherwise thinks the case is non-transient.
696 if (!selectTime(Times, iret))
702 const fvMesh& mesh = db_.mesh();
704 // With mesh now loaded check for change in number of points.
705 label nTotPoints = mesh.nPoints() + db_.polys().size();
707 if (*nodecnt != nTotPoints)
711 "nodecnt differs from number of points in mesh.\nnodecnt:"
712 + Foam::name(*nodecnt)
714 + Foam::name(nTotPoints)
726 != (db_.volScalarNames().size() + 3*db_.volVectorNames().size())
729 errorMsg("Illegal number of variables " + name(*num_vars));
740 const pointField& points = mesh.points();
743 int yIndex = xIndex + nTotPoints;
744 int zIndex = yIndex + nTotPoints;
746 // Add mesh points first.
747 forAll(points, pointI)
749 xyz[xIndex++] = points[pointI].x();
750 xyz[yIndex++] = points[pointI].y();
751 xyz[zIndex++] = points[pointI].z();
754 // Add cell centres of polys
755 const pointField& ctrs = mesh.cellCentres();
757 const labelList& polys = db_.polys();
761 label cellI = polys[i];
763 xyz[xIndex++] = ctrs[cellI].x();
764 xyz[yIndex++] = ctrs[cellI].y();
765 xyz[zIndex++] = ctrs[cellI].z();
770 // Define elements by calling fv routines
773 static const cellModel& tet = *(cellModeller::lookup("tet"));
774 static const cellModel& tetWedge = *(cellModeller::lookup("tetWedge"));
775 static const cellModel& pyr = *(cellModeller::lookup("pyr"));
776 static const cellModel& prism = *(cellModeller::lookup("prism"));
777 static const cellModel& wedge = *(cellModeller::lookup("wedge"));
778 static const cellModel& hex = *(cellModeller::lookup("hex"));
779 //static const cellModel& splitHex = *(cellModeller::lookup("splitHex"));
791 const cellShapeList& cellShapes = mesh.cellShapes();
792 const faceList& faces = mesh.faces();
793 const cellList& cells = mesh.cells();
794 const labelList& owner = mesh.faceOwner();
795 label nPoints = mesh.nPoints();
797 // Fieldview face_types array with all faces marked as internal.
798 labelList internalFaces(6, 0);
800 // Mark all cells next to boundary so we don't have to calculate
801 // wall_types for internal cells and can just pass internalFaces.
802 boolList wallCell(mesh.nCells(), false);
804 label nWallCells = 0;
806 for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
808 label cellI = owner[faceI];
810 if (!wallCell[cellI])
812 wallCell[cellI] = true;
820 forAll(cellShapes, cellI)
822 const cellShape& cellShape = cellShapes[cellI];
823 const cellModel& cellModel = cellShape.model();
824 const cell& cellFaces = cells[cellI];
828 if (cellModel == tet)
830 tetVerts[0] = cellShape[3] + 1;
831 tetVerts[1] = cellShape[0] + 1;
832 tetVerts[2] = cellShape[1] + 1;
833 tetVerts[3] = cellShape[2] + 1;
837 labelList faceTypes =
838 getFaceTypes(mesh, cellFaces, cellShape.faces());
840 tetFaces[0] = faceTypes[2];
841 tetFaces[1] = faceTypes[3];
842 tetFaces[2] = faceTypes[0];
843 tetFaces[3] = faceTypes[1];
845 istat = create_tet(ITYPE, tetVerts, tetFaces);
849 // All faces internal so use precalculated zero.
850 istat = create_tet(ITYPE, tetVerts, internalFaces.begin());
853 else if (cellModel == tetWedge)
855 prismVerts[0] = cellShape[0] + 1;
856 prismVerts[1] = cellShape[3] + 1;
857 prismVerts[2] = cellShape[4] + 1;
858 prismVerts[3] = cellShape[1] + 1;
859 prismVerts[4] = cellShape[4] + 1;
860 prismVerts[5] = cellShape[2] + 1;
864 labelList faceTypes =
865 getFaceTypes(mesh, cellFaces, cellShape.faces());
867 prismFaces[0] = faceTypes[1];
868 prismFaces[1] = faceTypes[2];
869 prismFaces[2] = faceTypes[3];
870 prismFaces[3] = faceTypes[0];
871 prismFaces[4] = faceTypes[3];
873 istat = create_prism(ITYPE, prismVerts, prismFaces);
877 istat = create_prism(ITYPE, prismVerts, internalFaces.begin());
880 else if (cellModel == pyr)
882 pyrVerts[0] = cellShape[0] + 1;
883 pyrVerts[1] = cellShape[1] + 1;
884 pyrVerts[2] = cellShape[2] + 1;
885 pyrVerts[3] = cellShape[3] + 1;
886 pyrVerts[4] = cellShape[4] + 1;
890 labelList faceTypes =
891 getFaceTypes(mesh, cellFaces, cellShape.faces());
893 pyrFaces[0] = faceTypes[0];
894 pyrFaces[1] = faceTypes[3];
895 pyrFaces[2] = faceTypes[2];
896 pyrFaces[3] = faceTypes[1];
897 pyrFaces[4] = faceTypes[4];
899 istat = create_pyramid(ITYPE, pyrVerts, pyrFaces);
903 istat = create_pyramid(ITYPE, pyrVerts, internalFaces.begin());
906 else if (cellModel == prism)
908 prismVerts[0] = cellShape[0] + 1;
909 prismVerts[1] = cellShape[3] + 1;
910 prismVerts[2] = cellShape[4] + 1;
911 prismVerts[3] = cellShape[1] + 1;
912 prismVerts[4] = cellShape[5] + 1;
913 prismVerts[5] = cellShape[2] + 1;
917 labelList faceTypes =
918 getFaceTypes(mesh, cellFaces, cellShape.faces());
920 prismFaces[0] = faceTypes[4];
921 prismFaces[1] = faceTypes[2];
922 prismFaces[2] = faceTypes[3];
923 prismFaces[3] = faceTypes[0];
924 prismFaces[4] = faceTypes[1];
926 istat = create_prism(ITYPE, prismVerts, prismFaces);
930 istat = create_prism(ITYPE, prismVerts, internalFaces.begin());
933 else if (cellModel == wedge)
935 hexVerts[0] = cellShape[0] + 1;
936 hexVerts[1] = cellShape[1] + 1;
937 hexVerts[2] = cellShape[0] + 1;
938 hexVerts[3] = cellShape[2] + 1;
939 hexVerts[4] = cellShape[3] + 1;
940 hexVerts[5] = cellShape[4] + 1;
941 hexVerts[6] = cellShape[6] + 1;
942 hexVerts[7] = cellShape[5] + 1;
946 labelList faceTypes =
947 getFaceTypes(mesh, cellFaces, cellShape.faces());
949 hexFaces[0] = faceTypes[2];
950 hexFaces[1] = faceTypes[3];
951 hexFaces[2] = faceTypes[0];
952 hexFaces[3] = faceTypes[1];
953 hexFaces[4] = faceTypes[4];
954 hexFaces[5] = faceTypes[5];
956 istat = create_hex(ITYPE, hexVerts, hexFaces);
960 istat = create_hex(ITYPE, hexVerts, internalFaces.begin());
963 else if (cellModel == hex)
965 hexVerts[0] = cellShape[0] + 1;
966 hexVerts[1] = cellShape[1] + 1;
967 hexVerts[2] = cellShape[3] + 1;
968 hexVerts[3] = cellShape[2] + 1;
969 hexVerts[4] = cellShape[4] + 1;
970 hexVerts[5] = cellShape[5] + 1;
971 hexVerts[6] = cellShape[7] + 1;
972 hexVerts[7] = cellShape[6] + 1;
976 labelList faceTypes =
977 getFaceTypes(mesh, cellFaces, cellShape.faces());
979 hexFaces[0] = faceTypes[0];
980 hexFaces[1] = faceTypes[1];
981 hexFaces[2] = faceTypes[4];
982 hexFaces[3] = faceTypes[5];
983 hexFaces[4] = faceTypes[2];
984 hexFaces[5] = faceTypes[3];
986 istat = create_hex(ITYPE, hexVerts, hexFaces);
990 istat = create_hex(ITYPE, hexVerts, internalFaces.begin());
995 forAll(cellFaces, cFaceI)
997 label faceI = cellFaces[cFaceI];
999 // Get Fieldview facetype (internal/on patch)
1000 label fvFaceType = getFvType(mesh, faceI);
1002 const face& f = faces[faceI];
1004 // Indices into storage
1008 // Storage for triangles and quads created by face
1009 // decomposition (sized for worst case)
1010 faceList quadFaces((f.size() - 2)/2);
1011 faceList triFaces(f.size() - 2);
1022 // Label of cell centre in fv point list.
1023 label polyCentrePoint = nPoints + nPolys;
1025 for (label i=0; i<nTris; i++)
1027 if (cellI == owner[faceI])
1029 tetVerts[0] = triFaces[i][0] + 1;
1030 tetVerts[1] = triFaces[i][1] + 1;
1031 tetVerts[2] = triFaces[i][2] + 1;
1032 tetVerts[3] = polyCentrePoint + 1;
1036 tetVerts[0] = triFaces[i][2] + 1;
1037 tetVerts[1] = triFaces[i][1] + 1;
1038 tetVerts[2] = triFaces[i][0] + 1;
1039 tetVerts[3] = polyCentrePoint + 1;
1042 if (wallCell[cellI])
1044 // Outside face is one without polyCentrePoint
1045 tetFaces[0] = fvFaceType;
1050 istat = create_tet(ITYPE, tetVerts, tetFaces);
1059 internalFaces.begin()
1064 for (label i=0; i<nQuads; i++)
1066 if (cellI == owner[faceI])
1068 pyrVerts[0] = quadFaces[i][3] + 1;
1069 pyrVerts[1] = quadFaces[i][2] + 1;
1070 pyrVerts[2] = quadFaces[i][1] + 1;
1071 pyrVerts[3] = quadFaces[i][0] + 1;
1072 pyrVerts[4] = polyCentrePoint + 1;
1077 pyrVerts[0] = quadFaces[i][0] + 1;
1078 pyrVerts[1] = quadFaces[i][1] + 1;
1079 pyrVerts[2] = quadFaces[i][2] + 1;
1080 pyrVerts[3] = quadFaces[i][3] + 1;
1081 pyrVerts[4] = polyCentrePoint + 1;
1084 if (wallCell[cellI])
1086 // Outside face is one without polyCentrePoint
1087 pyrFaces[0] = fvFaceType;
1093 istat = create_pyramid(ITYPE, pyrVerts, pyrFaces);
1102 internalFaces.begin()
1109 errorMsg("Error during adding cell " + name(cellI));
1122 errorMsg("Error during adding cell " + name(cellI));
1136 pointMesh pMesh(mesh);
1138 volPointInterpolation pInterp(mesh, pMesh);
1142 forAll(db_.volScalarNames(), i)
1144 const word& fieldName = db_.volScalarNames()[i];
1146 storeScalarField(pInterp, fieldName, vars, pointI);
1150 forAll(db_.volVectorNames(), i)
1152 const word& fieldName = db_.volVectorNames()[i];
1154 storeVectorField(pInterp, fieldName, vars, pointI);
1157 // Return without failure.
1162 void register_data_readers()
1166 ** You should edit this file to "register" a user-defined data
1167 ** reader with FIELDVIEW, if the user functions being registered
1168 ** here are written in C.
1169 ** You should edit "ftn_register_data_readers.f" if the user functions
1170 ** being registered are written in Fortran.
1171 ** In either case, the user functions being registered may call other
1172 ** functions written in either language (C or Fortran); only the
1173 ** language of the "query" and "read" functions referenced here matters
1176 ** The following shows a sample user-defined data reader being
1177 ** "registered" with FIELDVIEW.
1179 ** The "extern void" declarations should match the names of the
1180 ** query and grid-reading functions you are providing. It is
1181 ** strongly suggested that all such names begin with "user" so
1182 ** as not to conflict with global names in FIELDVIEW.
1184 ** You may call any combination of the data reader registration
1185 ** functions shown below ("register_two_file_reader" and/or
1186 ** "register_single_file_reader" and/or "register_single_unstruct_reader"
1187 ** and/or "register_double_unstruct_reader") as many times as you like,
1188 ** in order to create several different data readers. Each data reader
1189 ** should of course have different "query" and "read" functions, all of
1190 ** which should also appear in "extern void" declarations.
1195 ** like this for combined unstructured grids & results in a single file
1197 reg_single_unstruct_reader
1199 "Foam Reader", /* title you want for data reader */
1200 user_query_file_function, /* whatever you called this */
1201 user_read_one_grid_function /* whatever you called this */
1209 // ************************************************************************* //