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

faceSourceTemplates.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) 2009-2011 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 "faceSource.H"
00027 #include <finiteVolume/surfaceFields.H>
00028 #include <finiteVolume/volFields.H>
00029 #include <sampling/sampledSurface.H>
00030 
00031 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
00032 
00033 template<class Type>
00034 bool Foam::fieldValues::faceSource::validField(const word& fieldName) const
00035 {
00036     typedef GeometricField<Type, fvsPatchField, surfaceMesh> sf;
00037     typedef GeometricField<Type, fvPatchField, volMesh> vf;
00038 
00039     if (source_ != stSampledSurface && obr_.foundObject<sf>(fieldName))
00040     {
00041         return true;
00042     }
00043     else if (obr_.foundObject<vf>(fieldName))
00044     {
00045         return true;
00046     }
00047 
00048     return false;
00049 }
00050 
00051 
00052 template<class Type>
00053 Foam::tmp<Foam::Field<Type> > Foam::fieldValues::faceSource::setFieldValues
00054 (
00055     const word& fieldName
00056 ) const
00057 {
00058     typedef GeometricField<Type, fvsPatchField, surfaceMesh> sf;
00059     typedef GeometricField<Type, fvPatchField, volMesh> vf;
00060 
00061     if (source_ != stSampledSurface && obr_.foundObject<sf>(fieldName))
00062     {
00063         return filterField(obr_.lookupObject<sf>(fieldName), true);
00064     }
00065     else if (obr_.foundObject<vf>(fieldName))
00066     {
00067         if (surfacePtr_.valid())
00068         {
00069             return surfacePtr_().sample(obr_.lookupObject<vf>(fieldName));
00070         }
00071         else
00072         {
00073             return filterField(obr_.lookupObject<vf>(fieldName), true);
00074         }
00075     }
00076 
00077     return tmp<Field<Type> >(new Field<Type>(0));
00078 }
00079 
00080 
00081 template<class Type>
00082 Type Foam::fieldValues::faceSource::processValues
00083 (
00084     const Field<Type>& values,
00085     const scalarField& magSf,
00086     const scalarField& weightField
00087 ) const
00088 {
00089     Type result = pTraits<Type>::zero;
00090     switch (operation_)
00091     {
00092         case opSum:
00093         {
00094             result = sum(values);
00095             break;
00096         }
00097         case opAreaAverage:
00098         {
00099             result = sum(values*magSf)/sum(magSf);
00100             break;
00101         }
00102         case opAreaIntegrate:
00103         {
00104             result = sum(values*magSf);
00105             break;
00106         }
00107         case opWeightedAverage:
00108         {
00109             result = sum(values*weightField)/sum(weightField);
00110             break;
00111         }
00112         case opMin:
00113         {
00114             result = min(values);
00115             break;
00116         }
00117         case opMax:
00118         {
00119             result = max(values);
00120             break;
00121         }
00122         default:
00123         {
00124             // Do nothing
00125         }
00126     }
00127 
00128     return result;
00129 }
00130 
00131 
00132 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00133 
00134 template<class Type>
00135 bool Foam::fieldValues::faceSource::writeValues(const word& fieldName)
00136 {
00137     const bool ok = validField<Type>(fieldName);
00138 
00139     if (ok)
00140     {
00141         // Get (correctly oriented) field
00142         Field<Type> values = combineFields(setFieldValues<Type>(fieldName)());
00143 
00144         // Get unoriented magSf
00145         scalarField magSf;
00146 
00147         if (surfacePtr_.valid())
00148         {
00149             magSf = combineFields(surfacePtr_().magSf());
00150         }
00151         else
00152         {
00153             magSf = combineFields(filterField(mesh().magSf(), false)());
00154         }
00155 
00156         // Get (correctly oriented) weighting field
00157         scalarField weightField =
00158             combineFields(setFieldValues<scalar>(weightFieldName_)());
00159 
00160         if (Pstream::master())
00161         {
00162             Type result = processValues(values, magSf, weightField);
00163 
00164             if (valueOutput_)
00165             {
00166                 IOList<Type>
00167                 (
00168                     IOobject
00169                     (
00170                         fieldName + "_" + sourceTypeNames_[source_] + "-"
00171                             + sourceName_,
00172                         obr_.time().timeName(),
00173                         obr_,
00174                         IOobject::NO_READ,
00175                         IOobject::NO_WRITE
00176                     ),
00177                     values
00178                 ).write();
00179             }
00180 
00181             outputFilePtr_()<< tab << result;
00182 
00183             if (log_)
00184             {
00185                 Info<< "    " << operationTypeNames_[operation_]
00186                     << "(" << sourceName_ << ") for " << fieldName
00187                     <<  " = " << result << endl;
00188             }
00189         }
00190     }
00191 
00192     return ok;
00193 }
00194 
00195 
00196 template<class Type>
00197 Foam::tmp<Foam::Field<Type> > Foam::fieldValues::faceSource::filterField
00198 (
00199     const GeometricField<Type, fvPatchField, volMesh>& field,
00200     const bool applyOrientation
00201 ) const
00202 {
00203     tmp<Field<Type> > tvalues(new Field<Type>(faceId_.size()));
00204     Field<Type>& values = tvalues();
00205 
00206     forAll(values, i)
00207     {
00208         label faceI = faceId_[i];
00209         label patchI = facePatchId_[i];
00210         if (patchI >= 0)
00211         {
00212             values[i] = field.boundaryField()[patchI][faceI];
00213         }
00214         else
00215         {
00216             FatalErrorIn
00217             (
00218                 "fieldValues::faceSource::filterField"
00219                 "("
00220                     "const GeometricField<Type, fvPatchField, volMesh>&"
00221                 ") const"
00222             )   << type() << " " << name_ << ": "
00223                 << sourceTypeNames_[source_] << "(" << sourceName_ << "):"
00224                 << nl
00225                 << "    Unable to process internal faces for volume field "
00226                 << field.name() << nl << abort(FatalError);
00227         }
00228     }
00229 
00230     if (applyOrientation)
00231     {
00232         forAll(values, i)
00233         {
00234             values[i] *= faceSign_[i];
00235         }
00236     }
00237 
00238     return tvalues;
00239 }
00240 
00241 
00242 template<class Type>
00243 Foam::tmp<Foam::Field<Type> > Foam::fieldValues::faceSource::filterField
00244 (
00245     const GeometricField<Type, fvsPatchField, surfaceMesh>& field,
00246     const bool applyOrientation
00247 ) const
00248 {
00249     tmp<Field<Type> > tvalues(new Field<Type>(faceId_.size()));
00250     Field<Type>& values = tvalues();
00251 
00252     forAll(values, i)
00253     {
00254         label faceI = faceId_[i];
00255         label patchI = facePatchId_[i];
00256         if (patchI >= 0)
00257         {
00258             values[i] = field.boundaryField()[patchI][faceI];
00259         }
00260         else
00261         {
00262             values[i] = field[faceI];
00263         }
00264     }
00265 
00266     if (applyOrientation)
00267     {
00268         forAll(values, i)
00269         {
00270             values[i] *= faceSign_[i];
00271         }
00272     }
00273 
00274     return tvalues;
00275 }
00276 
00277 
00278 // ************************ vim: set sw=4 sts=4 et: ************************ //
00279 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines