FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

directMappedPatchBase.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "directMappedPatchBase.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028 #include <OpenFOAM/ListListOps.H>
00029 #include <meshTools/meshSearch.H>
00030 #include <meshTools/meshTools.H>
00031 #include <OpenFOAM/OFstream.H>
00032 #include <OpenFOAM/Random.H>
00033 #include <meshTools/treeDataFace.H>
00034 #include <meshTools/indexedOctree.H>
00035 #include <OpenFOAM/mapDistribute.H>
00036 
00037 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00038 
00039 namespace Foam
00040 {
00041     defineTypeNameAndDebug(directMappedPatchBase, 0);
00042 
00043     template<>
00044     const char* NamedEnum<directMappedPatchBase::sampleMode, 3>::names[] =
00045     {
00046         "nearestCell",
00047         "nearestPatchFace",
00048         "nearestFace"
00049     };
00050 
00051     const NamedEnum<directMappedPatchBase::sampleMode, 3>
00052         directMappedPatchBase::sampleModeNames_;
00053 }
00054 
00055 
00056 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00057 
00058 void Foam::directMappedPatchBase::collectSamples
00059 (
00060     pointField& samples,
00061     labelList& patchFaceProcs,
00062     labelList& patchFaces,
00063     pointField& patchFc
00064 ) const
00065 {
00066 
00067     // Collect all sample points and the faces they come from.
00068     List<pointField> globalFc(Pstream::nProcs());
00069     List<pointField> globalSamples(Pstream::nProcs());
00070     labelListList globalFaces(Pstream::nProcs());
00071 
00072     globalFc[Pstream::myProcNo()] = patch_.faceCentres();
00073     globalSamples[Pstream::myProcNo()] = globalFc[Pstream::myProcNo()]+offsets_;
00074     globalFaces[Pstream::myProcNo()] = identity(patch_.size());
00075 
00076     // Distribute to all processors
00077     Pstream::gatherList(globalSamples);
00078     Pstream::scatterList(globalSamples);
00079     Pstream::gatherList(globalFaces);
00080     Pstream::scatterList(globalFaces);
00081     Pstream::gatherList(globalFc);
00082     Pstream::scatterList(globalFc);
00083 
00084     // Rework into straight list
00085     samples = ListListOps::combine<pointField>
00086     (
00087         globalSamples,
00088         accessOp<pointField>()
00089     );
00090     patchFaces = ListListOps::combine<labelList>
00091     (
00092         globalFaces,
00093         accessOp<labelList>()
00094     );
00095     patchFc = ListListOps::combine<pointField>
00096     (
00097         globalFc,
00098         accessOp<pointField>()
00099     );
00100 
00101     patchFaceProcs.setSize(patchFaces.size());
00102     labelList nPerProc
00103     (
00104         ListListOps::subSizes
00105         (
00106             globalFaces,
00107             accessOp<labelList>()
00108         )
00109     );
00110     label sampleI = 0;
00111     forAll(nPerProc, procI)
00112     {
00113         for (label i = 0; i < nPerProc[procI]; i++)
00114         {
00115             patchFaceProcs[sampleI++] = procI;
00116         }
00117     }
00118 }
00119 
00120 
00121 // Find the processor/cell containing the samples. Does not account
00122 // for samples being found in two processors.
00123 void Foam::directMappedPatchBase::findSamples
00124 (
00125     const pointField& samples,
00126     labelList& sampleProcs,
00127     labelList& sampleIndices,
00128     pointField& sampleLocations
00129 ) const
00130 {
00131     // Lookup the correct region
00132     const polyMesh& mesh = sampleMesh();
00133 
00134     // All the info for nearest. Construct to miss
00135     List<nearInfo> nearest(samples.size());
00136 
00137     switch (mode_)
00138     {
00139         case NEARESTCELL:
00140         {
00141             if (samplePatch_.size() && samplePatch_ != "none")
00142             {
00143                 FatalErrorIn
00144                 (
00145                     "directMappedPatchBase::findSamples(const pointField&,"
00146                     " labelList&, labelList&, pointField&) const"
00147                 )   << "No need to supply a patch name when in "
00148                     << sampleModeNames_[mode_] << " mode." << exit(FatalError);
00149             }
00150 
00151             // Octree based search engine
00152             meshSearch meshSearchEngine(mesh, false);
00153 
00154             forAll(samples, sampleI)
00155             {
00156                 const point& sample = samples[sampleI];
00157 
00158                 label cellI = meshSearchEngine.findCell(sample);
00159 
00160                 if (cellI == -1)
00161                 {
00162                     nearest[sampleI].second().first() = Foam::sqr(GREAT);
00163                     nearest[sampleI].second().second() = Pstream::myProcNo();
00164                 }
00165                 else
00166                 {
00167                     const point& cc = mesh.cellCentres()[cellI];
00168 
00169                     nearest[sampleI].first() = pointIndexHit
00170                     (
00171                         true,
00172                         cc,
00173                         cellI
00174                     );
00175                     nearest[sampleI].second().first() = magSqr(cc-sample);
00176                     nearest[sampleI].second().second() = Pstream::myProcNo();
00177                 }
00178             }
00179             break;
00180         }
00181 
00182         case NEARESTPATCHFACE:
00183         {
00184             Random rndGen(123456);
00185 
00186             const polyPatch& pp = samplePolyPatch();
00187 
00188             if (pp.empty())
00189             {
00190                 forAll(samples, sampleI)
00191                 {
00192                     nearest[sampleI].second().first() = Foam::sqr(GREAT);
00193                     nearest[sampleI].second().second() = Pstream::myProcNo();
00194                 }
00195             }
00196             else
00197             {
00198                 // patch faces
00199                 const labelList patchFaces(identity(pp.size()) + pp.start());
00200 
00201                 treeBoundBox patchBb
00202                 (
00203                     treeBoundBox(pp.points(), pp.meshPoints()).extend
00204                     (
00205                         rndGen,
00206                         1E-4
00207                     )
00208                 );
00209                 patchBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
00210                 patchBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
00211 
00212                 indexedOctree<treeDataFace> boundaryTree
00213                 (
00214                     treeDataFace    // all information needed to search faces
00215                     (
00216                         false,      // do not cache bb
00217                         mesh,
00218                         patchFaces  // boundary faces only
00219                     ),
00220                     patchBb,        // overall search domain
00221                     8,              // maxLevel
00222                     10,             // leafsize
00223                     3.0             // duplicity
00224                 );
00225 
00226                 forAll(samples, sampleI)
00227                 {
00228                     const point& sample = samples[sampleI];
00229 
00230                     pointIndexHit& nearInfo = nearest[sampleI].first();
00231                     nearInfo = boundaryTree.findNearest
00232                     (
00233                         sample,
00234                         magSqr(patchBb.span())
00235                     );
00236 
00237                     if (!nearInfo.hit())
00238                     {
00239                         nearest[sampleI].second().first() = Foam::sqr(GREAT);
00240                         nearest[sampleI].second().second() =
00241                             Pstream::myProcNo();
00242                     }
00243                     else
00244                     {
00245                         point fc(pp[nearInfo.index()].centre(pp.points()));
00246                         nearInfo.setPoint(fc);
00247                         nearest[sampleI].second().first() = magSqr(fc-sample);
00248                         nearest[sampleI].second().second() =
00249                             Pstream::myProcNo();
00250                     }
00251                 }
00252             }
00253             break;
00254         }
00255 
00256         case NEARESTFACE:
00257         {
00258             if (samplePatch_.size() && samplePatch_ != "none")
00259             {
00260                 FatalErrorIn
00261                 (
00262                     "directMappedPatchBase::findSamples(const pointField&,"
00263                     " labelList&, labelList&, pointField&) const"
00264                 )   << "No need to supply a patch name when in "
00265                     << sampleModeNames_[mode_] << " mode." << exit(FatalError);
00266             }
00267 
00268             // Octree based search engine
00269             meshSearch meshSearchEngine(mesh, false);
00270 
00271             forAll(samples, sampleI)
00272             {
00273                 const point& sample = samples[sampleI];
00274 
00275                 label faceI = meshSearchEngine.findNearestFace(sample);
00276 
00277                 if (faceI == -1)
00278                 {
00279                     nearest[sampleI].second().first() = Foam::sqr(GREAT);
00280                     nearest[sampleI].second().second() = Pstream::myProcNo();
00281                 }
00282                 else
00283                 {
00284                     const point& fc = mesh.faceCentres()[faceI];
00285 
00286                     nearest[sampleI].first() = pointIndexHit
00287                     (
00288                         true,
00289                         fc,
00290                         faceI
00291                     );
00292                     nearest[sampleI].second().first() = magSqr(fc-sample);
00293                     nearest[sampleI].second().second() = Pstream::myProcNo();
00294                 }
00295             }
00296             break;
00297         }
00298 
00299         default:
00300         {
00301             FatalErrorIn("directMappedPatchBase::findSamples(..)")
00302                 << "problem." << abort(FatalError);
00303         }
00304     }
00305 
00306 
00307     // Find nearest.
00308     Pstream::listCombineGather(nearest, nearestEqOp());
00309     Pstream::listCombineScatter(nearest);
00310 
00311     if (debug)
00312     {
00313         Info<< "directMappedPatchBase::findSamples on mesh " << sampleRegion_
00314             << " : " << endl;
00315         forAll(nearest, sampleI)
00316         {
00317             label procI = nearest[sampleI].second().second();
00318             label localI = nearest[sampleI].first().index();
00319 
00320             Info<< "    " << sampleI << " coord:"<< samples[sampleI]
00321                 << " found on processor:" << procI
00322                 << " in local cell/face:" << localI
00323                 << " with cc:" << nearest[sampleI].first().rawPoint() << endl;
00324         }
00325     }
00326 
00327     // Check for samples not being found
00328     forAll(nearest, sampleI)
00329     {
00330         if (!nearest[sampleI].first().hit())
00331         {
00332             FatalErrorIn
00333             (
00334                 "directMappedPatchBase::findSamples"
00335                 "(const pointField&, labelList&"
00336                 ", labelList&, pointField&)"
00337             )   << "Did not find sample " << samples[sampleI]
00338                 << " on any processor of region " << sampleRegion_
00339                 << exit(FatalError);
00340         }
00341     }
00342 
00343 
00344     // Convert back into proc+local index
00345     sampleProcs.setSize(samples.size());
00346     sampleIndices.setSize(samples.size());
00347     sampleLocations.setSize(samples.size());
00348 
00349     forAll(nearest, sampleI)
00350     {
00351         sampleProcs[sampleI] = nearest[sampleI].second().second();
00352         sampleIndices[sampleI] = nearest[sampleI].first().index();
00353         sampleLocations[sampleI] = nearest[sampleI].first().hitPoint();
00354     }
00355 }
00356 
00357 
00358 void Foam::directMappedPatchBase::calcMapping() const
00359 {
00360     if (mapPtr_.valid())
00361     {
00362         FatalErrorIn("directMappedPatchBase::calcMapping() const")
00363             << "Mapping already calculated" << exit(FatalError);
00364     }
00365 
00366     if
00367     (
00368         gAverage(mag(offsets_)) <= ROOTVSMALL
00369      && mode_ == NEARESTPATCHFACE
00370      && sampleRegion_ == patch_.boundaryMesh().mesh().name()
00371      && samplePatch_ == patch_.name()
00372     )
00373     {
00374         WarningIn("directMappedPatchBase::calcMapping() const")
00375             << "Invalid offset " << offsets_ << endl
00376             << "Offset is the vector added to the patch face centres to"
00377             << " find the patch face supplying the data." << endl
00378             << "Setting it to " << offsets_
00379             << " on the same patch, on the same region"
00380             << " will find the faces themselves which does not make sense"
00381             << " for anything but testing." << endl
00382             << "patch_:" << patch_.name() << endl
00383             << "sampleRegion_:" << sampleRegion_ << endl
00384             << "mode_:" << sampleModeNames_[mode_] << endl
00385             << "samplePatch_:" << samplePatch_ << endl
00386             << "offsets_:" << offsets_ << endl;
00387     }
00388 
00389 
00390     // Get global list of all samples and the processor and face they come from.
00391     pointField samples;
00392     labelList patchFaceProcs;
00393     labelList patchFaces;
00394     pointField patchFc;
00395     collectSamples(samples, patchFaceProcs, patchFaces, patchFc);
00396 
00397     // Find processor and cell/face samples are in and actual location.
00398     labelList sampleProcs;
00399     labelList sampleIndices;
00400     pointField sampleLocations;
00401     findSamples(samples, sampleProcs, sampleIndices, sampleLocations);
00402 
00403 
00404     // Now we have all the data we need:
00405     // - where sample originates from (so destination when mapping):
00406     //   patchFaces, patchFaceProcs.
00407     // - cell/face sample is in (so source when mapping)
00408     //   sampleIndices, sampleProcs.
00409 
00410     //forAll(samples, i)
00411     //{
00412     //    Info<< i << " need data in region "
00413     //        << patch_.boundaryMesh().mesh().name()
00414     //        << " for proc:" << patchFaceProcs[i]
00415     //        << " face:" << patchFaces[i]
00416     //        << " at:" << patchFc[i] << endl
00417     //        << "Found data in region " << sampleRegion_
00418     //        << " at proc:" << sampleProcs[i]
00419     //        << " face:" << sampleIndices[i]
00420     //        << " at:" << sampleLocations[i]
00421     //        << nl << endl;
00422     //}
00423 
00424 
00425 
00426     if (debug && Pstream::master())
00427     {
00428         OFstream str
00429         (
00430             patch_.boundaryMesh().mesh().time().path()
00431           / patch_.name()
00432           + "_directMapped.obj"
00433         );
00434         Pout<< "Dumping mapping as lines from patch faceCentres to"
00435             << " sampled cell/faceCentres to file " << str.name() << endl;
00436 
00437         label vertI = 0;
00438 
00439         forAll(patchFc, i)
00440         {
00441             meshTools::writeOBJ(str, patchFc[i]);
00442             vertI++;
00443             meshTools::writeOBJ(str, sampleLocations[i]);
00444             vertI++;
00445             str << "l " << vertI-1 << ' ' << vertI << nl;
00446         }
00447     }
00448 
00449 
00452     //if (Pstream::master())
00453     //{
00454     //    const scalarField magOffset(mag(sampleLocations - patchFc));
00455     //    const scalar avgOffset(average(magOffset));
00456     //
00457     //    forAll(magOffset, sampleI)
00458     //    {
00459     //        if
00460     //        (
00461     //            mag(magOffset[sampleI]-avgOffset)
00462     //          > max(SMALL, 0.001*avgOffset)
00463     //        )
00464     //        {
00465     //            WarningIn("directMappedPatchBase::calcMapping() const")
00466     //                << "The actual cell/face centres picked up using offset "
00467     //                << offsets_ << " are not" << endl
00468     //                << "    on a single plane."
00469     //                << " This might give numerical problems." << endl
00470     //                << "    At patchface " << patchFc[sampleI]
00471     //                << " the sampled cell/face " << sampleLocations[sampleI]
00472     //                << endl
00473     //                << "    is not on a plane " << avgOffset
00474     //                << " offset from the patch." << endl
00475     //                << "    You might want to shift your plane offset."
00476     //                << " Set the debug flag to get a dump of sampled cells."
00477     //                << endl;
00478     //            break;
00479     //        }
00480     //    }
00481     //}
00482 
00483 
00484     // Determine schedule.
00485     mapPtr_.reset(new mapDistribute(sampleProcs, patchFaceProcs));
00486 
00487     // Rework the schedule from indices into samples to cell data to send,
00488     // face data to receive.
00489 
00490     labelListList& subMap = mapPtr_().subMap();
00491     labelListList& constructMap = mapPtr_().constructMap();
00492 
00493     forAll(subMap, procI)
00494     {
00495         subMap[procI] = UIndirectList<label>
00496         (
00497             sampleIndices,
00498             subMap[procI]
00499         );
00500         constructMap[procI] = UIndirectList<label>
00501         (
00502             patchFaces,
00503             constructMap[procI]
00504         );
00505 
00506         if (debug)
00507         {
00508             Pout<< "To proc:" << procI << " sending values of cells/faces:"
00509                 << subMap[procI] << endl;
00510             Pout<< "From proc:" << procI << " receiving values of patch faces:"
00511                 << constructMap[procI] << endl;
00512         }
00513     }
00514 
00515     // Redo constructSize
00516     mapPtr_().constructSize() = patch_.size();
00517 
00518     if (debug)
00519     {
00520         // Check that all elements get a value.
00521         PackedBoolList used(patch_.size());
00522         forAll(constructMap, procI)
00523         {
00524             const labelList& map = constructMap[procI];
00525 
00526             forAll(map, i)
00527             {
00528                 label faceI = map[i];
00529 
00530                 if (used[faceI] == 0)
00531                 {
00532                     used[faceI] = 1;
00533                 }
00534                 else
00535                 {
00536                     FatalErrorIn("directMappedPatchBase::calcMapping() const")
00537                         << "On patch " << patch_.name()
00538                         << " patchface " << faceI
00539                         << " is assigned to more than once."
00540                         << abort(FatalError);
00541                 }
00542             }
00543         }
00544         forAll(used, faceI)
00545         {
00546             if (used[faceI] == 0)
00547             {
00548                 FatalErrorIn("directMappedPatchBase::calcMapping() const")
00549                     << "On patch " << patch_.name()
00550                     << " patchface " << faceI
00551                     << " is never assigned to."
00552                     << abort(FatalError);
00553             }
00554         }
00555     }
00556 }
00557 
00558 
00559 // * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * * * * //
00560 
00561 Foam::directMappedPatchBase::directMappedPatchBase
00562 (
00563     const polyPatch& pp
00564 )
00565 :
00566     patch_(pp),
00567     sampleRegion_(patch_.boundaryMesh().mesh().name()),
00568     mode_(NEARESTPATCHFACE),
00569     samplePatch_("none"),
00570     uniformOffset_(true),
00571     offset_(vector::zero),
00572     offsets_(pp.size(), offset_),
00573     sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
00574     mapPtr_(NULL)
00575 {}
00576 
00577 
00578 Foam::directMappedPatchBase::directMappedPatchBase
00579 (
00580     const polyPatch& pp,
00581     const word& sampleRegion,
00582     const sampleMode mode,
00583     const word& samplePatch,
00584     const vectorField& offsets
00585 )
00586 :
00587     patch_(pp),
00588     sampleRegion_(sampleRegion),
00589     mode_(mode),
00590     samplePatch_(samplePatch),
00591     uniformOffset_(false),
00592     offsets_(offsets),
00593     sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
00594     mapPtr_(NULL)
00595 {}
00596 
00597 
00598 Foam::directMappedPatchBase::directMappedPatchBase
00599 (
00600     const polyPatch& pp,
00601     const word& sampleRegion,
00602     const sampleMode mode,
00603     const word& samplePatch,
00604     const vector& offset
00605 )
00606 :
00607     patch_(pp),
00608     sampleRegion_(sampleRegion),
00609     mode_(mode),
00610     samplePatch_(samplePatch),
00611     uniformOffset_(true),
00612     offset_(offset),
00613     offsets_(pp.size(), offset_),
00614     sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
00615     mapPtr_(NULL)
00616 {}
00617 
00618 
00619 Foam::directMappedPatchBase::directMappedPatchBase
00620 (
00621     const polyPatch& pp,
00622     const dictionary& dict
00623 )
00624 :
00625     patch_(pp),
00626     sampleRegion_
00627     (
00628         dict.lookupOrDefault
00629         (
00630             "sampleRegion",
00631             patch_.boundaryMesh().mesh().name()
00632         )
00633     ),
00634     mode_(sampleModeNames_.read(dict.lookup("sampleMode"))),
00635     samplePatch_(dict.lookup("samplePatch")),
00636     uniformOffset_(dict.found("offset")),
00637     offset_
00638     (
00639         uniformOffset_
00640       ? point(dict.lookup("offset"))
00641       : vector::zero
00642     ),
00643     offsets_
00644     (
00645         uniformOffset_
00646       ? pointField(pp.size(), offset_)
00647       : dict.lookup("offsets")
00648     ),
00649     sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
00650     mapPtr_(NULL)
00651 {}
00652 
00653 
00654 Foam::directMappedPatchBase::directMappedPatchBase
00655 (
00656     const polyPatch& pp,
00657     const directMappedPatchBase& dmp
00658 )
00659 :
00660     patch_(pp),
00661     sampleRegion_(dmp.sampleRegion_),
00662     mode_(dmp.mode_),
00663     samplePatch_(dmp.samplePatch_),
00664     uniformOffset_(dmp.uniformOffset_),
00665     offset_(dmp.offset_),
00666     offsets_(dmp.offsets_),
00667     sameRegion_(dmp.sameRegion_),
00668     mapPtr_(NULL)
00669 {}
00670 
00671 
00672 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00673 
00674 Foam::directMappedPatchBase::~directMappedPatchBase()
00675 {
00676     clearOut();
00677 }
00678 
00679 
00680 void Foam::directMappedPatchBase::clearOut()
00681 {
00682     mapPtr_.clear();
00683 }
00684 
00685 
00686 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00687 
00688 const Foam::polyMesh& Foam::directMappedPatchBase::sampleMesh() const
00689 {
00690     return patch_.boundaryMesh().mesh().time().lookupObject<polyMesh>
00691     (
00692         sampleRegion_
00693     );
00694 }
00695 
00696 
00697 const Foam::polyPatch& Foam::directMappedPatchBase::samplePolyPatch() const
00698 {
00699     const polyMesh& nbrMesh = sampleMesh();
00700 
00701     label patchI = nbrMesh.boundaryMesh().findPatchID(samplePatch_);
00702 
00703     if (patchI == -1)
00704     {
00705         FatalErrorIn("directMappedPatchBase::samplePolyPatch() ")
00706             << "Cannot find patch " << samplePatch_
00707             << " in region " << sampleRegion_ << endl
00708             << "Valid patches are " << nbrMesh.boundaryMesh().names()
00709             << exit(FatalError);
00710     }
00711 
00712     return nbrMesh.boundaryMesh()[patchI];
00713 }
00714 
00715 
00716 void Foam::directMappedPatchBase::write(Ostream& os) const
00717 {
00718     os.writeKeyword("sampleMode") << sampleModeNames_[mode_]
00719         << token::END_STATEMENT << nl;
00720     os.writeKeyword("sampleRegion") << sampleRegion_
00721         << token::END_STATEMENT << nl;
00722     os.writeKeyword("samplePatch") << samplePatch_
00723         << token::END_STATEMENT << nl;
00724     if (uniformOffset_)
00725     {
00726         os.writeKeyword("offset") << offset_ << token::END_STATEMENT << nl;
00727     }
00728     else
00729     {
00730         os.writeKeyword("offsets") << offsets_ << token::END_STATEMENT << nl;
00731     }
00732 }
00733 
00734 
00735 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines