/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . \*---------------------------------------------------------------------------*/ #include "FieldMapper.H" #include "FieldM.H" #include "dictionary.H" #include "contiguous.H" // * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * // template const char* const Foam::Field::typeName("Field"); // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template Foam::Field::Field() : List() {} template Foam::Field::Field(const label size) : List(size) {} template Foam::Field::Field(const label size, const Type& t) : List(size, t) {} template Foam::Field::Field ( const UList& mapF, const labelUList& mapAddressing ) : List(mapAddressing.size()) { map(mapF, mapAddressing); } template Foam::Field::Field ( const tmp>& tmapF, const labelUList& mapAddressing ) : List(mapAddressing.size()) { map(tmapF, mapAddressing); } template Foam::Field::Field ( const UList& mapF, const labelListList& mapAddressing, const scalarListList& mapWeights ) : List(mapAddressing.size()) { map(mapF, mapAddressing, mapWeights); } template Foam::Field::Field ( const tmp>& tmapF, const labelListList& mapAddressing, const scalarListList& mapWeights ) : List(mapAddressing.size()) { map(tmapF, mapAddressing, mapWeights); } template Foam::Field::Field ( const UList& mapF, const FieldMapper& mapper ) : List(mapper.size()) { map(mapF, mapper); } template Foam::Field::Field ( const UList& mapF, const FieldMapper& mapper, const Type& defaultValue ) : List(mapper.size(), defaultValue) { map(mapF, mapper); } template Foam::Field::Field ( const UList& mapF, const FieldMapper& mapper, const UList& defaultValues ) : List(defaultValues) { map(mapF, mapper); } template Foam::Field::Field ( const tmp>& tmapF, const FieldMapper& mapper ) : List(mapper.size()) { map(tmapF, mapper); } template Foam::Field::Field ( const tmp>& tmapF, const FieldMapper& mapper, const Type& defaultValue ) : List(mapper.size(), defaultValue) { map(tmapF, mapper); } template Foam::Field::Field ( const tmp>& tmapF, const FieldMapper& mapper, const UList& defaultValues ) : List(defaultValues) { map(tmapF, mapper); } template Foam::Field::Field(const Field& f) : refCount(), List(f) {} template Foam::Field::Field(Field& f, bool reuse) : List(f, reuse) {} template Foam::Field::Field(const Xfer>& f) : List(f) {} template Foam::Field::Field(const Xfer>& f) : List(f) {} template Foam::Field::Field(const UList& list) : List(list) {} // Construct as copy of tmp #ifndef NoConstructFromTmp template Foam::Field::Field(const tmp>& tf) : List(const_cast&>(tf()), tf.isTmp()) { tf.clear(); } #endif template Foam::Field::Field(Istream& is) : List(is) {} template Foam::Field::Field ( const word& keyword, const dictionary& dict, const label s ) { if (s) { ITstream& is = dict.lookup(keyword); // Read first token token firstToken(is); if (firstToken.isWord()) { if (firstToken.wordToken() == "uniform") { this->setSize(s); operator=(pTraits(is)); } else if (firstToken.wordToken() == "nonuniform") { is >> static_cast&>(*this); if (this->size() != s) { FatalIOErrorInFunction ( dict ) << "size " << this->size() << " is not equal to the given value of " << s << exit(FatalIOError); } } else { FatalIOErrorInFunction ( dict ) << "expected keyword 'uniform' or 'nonuniform', found " << firstToken.wordToken() << exit(FatalIOError); } } else { if (is.version() == 2.0) { IOWarningInFunction ( dict ) << "expected keyword 'uniform' or 'nonuniform', " "assuming deprecated Field format from " "Foam version 2.0." << endl; this->setSize(s); is.putBack(firstToken); operator=(pTraits(is)); } else { FatalIOErrorInFunction ( dict ) << "expected keyword 'uniform' or 'nonuniform', found " << firstToken.info() << exit(FatalIOError); } } } } template Foam::tmp> Foam::Field::clone() const { return tmp>(new Field(*this)); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template void Foam::Field::map ( const UList& mapF, const labelUList& mapAddressing ) { Field& f = *this; if (f.size() != mapAddressing.size()) { f.setSize(mapAddressing.size()); } if (mapF.size() > 0) { forAll(f, i) { label mapI = mapAddressing[i]; if (mapI >= 0) { f[i] = mapF[mapI]; } } } } template void Foam::Field::map ( const tmp>& tmapF, const labelUList& mapAddressing ) { map(tmapF(), mapAddressing); tmapF.clear(); } template void Foam::Field::map ( const UList& mapF, const labelListList& mapAddressing, const scalarListList& mapWeights ) { Field& f = *this; if (f.size() != mapAddressing.size()) { f.setSize(mapAddressing.size()); } if (mapWeights.size() != mapAddressing.size()) { FatalErrorInFunction << mapWeights.size() << " map size: " << mapAddressing.size() << abort(FatalError); } forAll(f, i) { const labelList& localAddrs = mapAddressing[i]; const scalarList& localWeights = mapWeights[i]; f[i] = pTraits::zero; forAll(localAddrs, j) { f[i] += localWeights[j]*mapF[localAddrs[j]]; } } } template void Foam::Field::map ( const tmp>& tmapF, const labelListList& mapAddressing, const scalarListList& mapWeights ) { map(tmapF(), mapAddressing, mapWeights); tmapF.clear(); } template void Foam::Field::map ( const UList& mapF, const FieldMapper& mapper ) { if ( mapper.direct() && notNull(mapper.directAddressing()) && mapper.directAddressing().size() ) { map(mapF, mapper.directAddressing()); } else if (!mapper.direct() && mapper.addressing().size()) { map(mapF, mapper.addressing(), mapper.weights()); } } template void Foam::Field::map ( const tmp>& tmapF, const FieldMapper& mapper ) { map(tmapF(), mapper); tmapF.clear(); } template void Foam::Field::autoMap ( const FieldMapper& mapper ) { if ( ( mapper.direct() && notNull(mapper.directAddressing()) && mapper.directAddressing().size() ) || (!mapper.direct() && mapper.addressing().size()) ) { Field fCpy(*this); map(fCpy, mapper); } else { this->setSize(mapper.size()); } } template void Foam::Field::rmap ( const UList& mapF, const labelUList& mapAddressing ) { Field& f = *this; forAll(mapF, i) { label mapI = mapAddressing[i]; if (mapI >= 0) { f[mapI] = mapF[i]; } } } template void Foam::Field::rmap ( const tmp>& tmapF, const labelUList& mapAddressing ) { rmap(tmapF(), mapAddressing); tmapF.clear(); } template void Foam::Field::rmap ( const UList& mapF, const labelUList& mapAddressing, const UList& mapWeights ) { Field& f = *this; f = pTraits::zero; forAll(mapF, i) { f[mapAddressing[i]] += mapF[i]*mapWeights[i]; } } template void Foam::Field::rmap ( const tmp>& tmapF, const labelUList& mapAddressing, const UList& mapWeights ) { rmap(tmapF(), mapAddressing, mapWeights); tmapF.clear(); } template void Foam::Field::negate() { TFOR_ALL_F_OP_OP_F(Type, *this, =, -, Type, *this) } template Foam::tmp::cmptType>> Foam::Field::component ( const direction d ) const { tmp> Component(new Field(this->size())); ::Foam::component(Component(), *this, d); return Component; } template void Foam::Field::replace ( const direction d, const UList& sf ) { TFOR_ALL_F_OP_FUNC_S_F(Type, *this, ., replace, const direction, d, cmptType, sf) } template void Foam::Field::replace ( const direction d, const tmp>& tsf ) { replace(d, tsf()); tsf.clear(); } template void Foam::Field::replace ( const direction d, const cmptType& c ) { TFOR_ALL_F_OP_FUNC_S_S(Type, *this, ., replace, const direction, d, cmptType, c) } template Foam::tmp> Foam::Field::T() const { tmp> transpose(new Field(this->size())); ::Foam::T(transpose(), *this); return transpose; } template void Foam::Field::writeEntry(const word& keyword, Ostream& os) const { os.writeKeyword(keyword); bool uniform = false; if (this->size() && contiguous()) { uniform = true; forAll(*this, i) { if (this->operator[](i) != this->operator[](0)) { uniform = false; break; } } } if (uniform) { os << "uniform " << this->operator[](0) << token::END_STATEMENT; } else { os << "nonuniform "; List::writeEntry(os); os << token::END_STATEMENT; } os << endl; } // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template void Foam::Field::operator=(const Field& rhs) { if (this == &rhs) { FatalErrorInFunction << "attempted assignment to self" << abort(FatalError); } List::operator=(rhs); } template void Foam::Field::operator=(const SubField& rhs) { List::operator=(rhs); } template void Foam::Field::operator=(const UList& rhs) { List::operator=(rhs); } template void Foam::Field::operator=(const tmp& rhs) { if (this == &(rhs())) { FatalErrorInFunction << "attempted assignment to self" << abort(FatalError); } // This is dodgy stuff, don't try it at home. Field* fieldPtr = rhs.ptr(); List::transfer(*fieldPtr); delete fieldPtr; } template void Foam::Field::operator=(const Type& t) { List::operator=(t); } template template void Foam::Field::operator=(const VectorSpace& vs) { TFOR_ALL_F_OP_S(Type, *this, =, VSType, vs) } #define COMPUTED_ASSIGNMENT(TYPE, op) \ \ template \ void Foam::Field::operator op(const UList& f) \ { \ TFOR_ALL_F_OP_F(Type, *this, op, TYPE, f) \ } \ \ template \ void Foam::Field::operator op(const tmp>& tf) \ { \ operator op(tf()); \ tf.clear(); \ } \ \ template \ void Foam::Field::operator op(const TYPE& t) \ { \ TFOR_ALL_F_OP_S(Type, *this, op, TYPE, t) \ } COMPUTED_ASSIGNMENT(Type, +=) COMPUTED_ASSIGNMENT(Type, -=) COMPUTED_ASSIGNMENT(scalar, *=) COMPUTED_ASSIGNMENT(scalar, /=) #undef COMPUTED_ASSIGNMENT // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // template Foam::Ostream& Foam::operator<<(Ostream& os, const Field& f) { os << static_cast&>(f); return os; } template Foam::Ostream& Foam::operator<<(Ostream& os, const tmp>& tf) { os << tf(); tf.clear(); return os; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #include "FieldFunctions.C" // ************************************************************************* //