FieldField: support different Field types for binary operators e.g. fvPatchField and fvsPatchField.

The Field type of the result is that of the LH argument so now

// Update the phi BCs from U before p BCs are updated
phi.boundaryField() = mesh.Sf().boundaryField() & U.boundaryField();

is possible.
This commit is contained in:
Henry
2013-06-20 10:08:51 +01:00
parent a38ff1757c
commit 958ee7336f
2 changed files with 373 additions and 287 deletions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -628,197 +628,245 @@ BINARY_TYPE_OPERATOR_FS(Type, Type, scalar, /, divide)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#define PRODUCT_OPERATOR(product, op, opFunc) \ #define PRODUCT_OPERATOR(product, op, opFunc) \
\ \
template<template<class> class Field, class Type1, class Type2> \ template \
void opFunc \ < \
( \ template<class> class Field1, \
FieldField<Field, typename product<Type1, Type2>::type>& f, \ template<class> class Field2, \
const FieldField<Field, Type1>& f1, \ class Type1, \
const FieldField<Field, Type2>& f2 \ class Type2 \
) \ > \
{ \ void opFunc \
forAll(f, i) \ ( \
{ \ FieldField<Field1, typename product<Type1, Type2>::type>& f, \
opFunc(f[i], f1[i], f2[i]); \ const FieldField<Field1, Type1>& f1, \
} \ const FieldField<Field2, Type2>& f2 \
} \ ) \
\ { \
template<template<class> class Field, class Type1, class Type2> \ forAll(f, i) \
tmp<FieldField<Field, typename product<Type1, Type2>::type> > \ { \
operator op \ opFunc(f[i], f1[i], f2[i]); \
( \ } \
const FieldField<Field, Type1>& f1, \ } \
const FieldField<Field, Type2>& f2 \ \
) \ template \
{ \ < \
typedef typename product<Type1, Type2>::type productType; \ template<class> class Field1, \
tmp<FieldField<Field, productType> > tRes \ template<class> class Field2, \
( \ class Type1, \
FieldField<Field, productType>::NewCalculatedType(f1) \ class Type2 \
); \ > \
opFunc(tRes(), f1, f2); \ tmp<FieldField<Field1, typename product<Type1, Type2>::type> > \
return tRes; \ operator op \
} \ ( \
\ const FieldField<Field1, Type1>& f1, \
template<template<class> class Field, class Type1, class Type2> \ const FieldField<Field2, Type2>& f2 \
tmp<FieldField<Field, typename product<Type1, Type2>::type> > \ ) \
operator op \ { \
( \ typedef typename product<Type1, Type2>::type productType; \
const FieldField<Field, Type1>& f1, \ tmp<FieldField<Field1, productType> > tRes \
const tmp<FieldField<Field, Type2> >& tf2 \ ( \
) \ FieldField<Field1, productType>::NewCalculatedType(f1) \
{ \ ); \
typedef typename product<Type1, Type2>::type productType; \ opFunc(tRes(), f1, f2); \
tmp<FieldField<Field, productType> > tRes \ return tRes; \
( \ } \
reuseTmpFieldField<Field, productType, Type2>::New(tf2) \ \
); \ template<template<class> class Field, class Type1, class Type2> \
opFunc(tRes(), f1, tf2()); \ tmp<FieldField<Field, typename product<Type1, Type2>::type> > \
reuseTmpFieldField<Field, productType, Type2>::clear(tf2); \ operator op \
return tRes; \ ( \
} \ const FieldField<Field, Type1>& f1, \
\ const tmp<FieldField<Field, Type2> >& tf2 \
template<template<class> class Field, class Type1, class Type2> \ ) \
tmp<FieldField<Field, typename product<Type1, Type2>::type> > \ { \
operator op \ typedef typename product<Type1, Type2>::type productType; \
( \ tmp<FieldField<Field, productType> > tRes \
const tmp<FieldField<Field, Type1> >& tf1, \ ( \
const FieldField<Field, Type2>& f2 \ reuseTmpFieldField<Field, productType, Type2>::New(tf2) \
) \ ); \
{ \ opFunc(tRes(), f1, tf2()); \
typedef typename product<Type1, Type2>::type productType; \ reuseTmpFieldField<Field, productType, Type2>::clear(tf2); \
tmp<FieldField<Field, productType> > tRes \ return tRes; \
( \ } \
reuseTmpFieldField<Field, productType, Type1>::New(tf1) \ \
); \ template \
opFunc(tRes(), tf1(), f2); \ < \
reuseTmpFieldField<Field, productType, Type1>::clear(tf1); \ template<class> class Field1, \
return tRes; \ template<class> class Field2, \
} \ class Type1, \
\ class Type2 \
template<template<class> class Field, class Type1, class Type2> \ > \
tmp<FieldField<Field, typename product<Type1, Type2>::type> > \ tmp<FieldField<Field, typename product<Type1, Type2>::type> > \
operator op \ operator op \
( \ ( \
const tmp<FieldField<Field, Type1> >& tf1, \ const FieldField<Field1, Type1>& f1, \
const tmp<FieldField<Field, Type2> >& tf2 \ const tmp<FieldField<Field2, Type2> >& tf2 \
) \ ) \
{ \ { \
typedef typename product<Type1, Type2>::type productType; \ typedef typename product<Type1, Type2>::type productType; \
tmp<FieldField<Field, productType> > tRes \ tmp<FieldField<Field1, productType> > tRes \
( \ ( \
reuseTmpTmpFieldField<Field, productType, Type1, Type1, Type2>::New \ FieldField<Field1, productType>::NewCalculatedType(f1) \
(tf1, tf2) \ ); \
); \ opFunc(tRes(), f1, tf2()); \
opFunc(tRes(), tf1(), tf2()); \ tf2.clear(); \
reuseTmpTmpFieldField<Field, productType, Type1, Type1, Type2>::clear \ return tRes; \
(tf1, tf2); \ } \
return tRes; \ \
} \ template \
\ < \
template \ template<class> class Field1, \
<template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \ template<class> class Field2, \
void opFunc \ class Type1, \
( \ class Type2 \
FieldField<Field, typename product<Type, Form>::type>& f, \ > \
const FieldField<Field, Type>& f1, \ tmp<FieldField<Field1, typename product<Type1, Type2>::type> > \
const VectorSpace<Form,Cmpt,nCmpt>& vs \ operator op \
) \ ( \
{ \ const tmp<FieldField<Field1, Type1> >& tf1, \
forAll(f, i) \ const FieldField<Field2, Type2>& f2 \
{ \ ) \
opFunc(f[i], f1[i], vs); \ { \
} \ typedef typename product<Type1, Type2>::type productType; \
} \ tmp<FieldField<Field1, productType> > tRes \
\ ( \
template \ reuseTmpFieldField<Field1, productType, Type1>::New(tf1) \
<template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \ ); \
tmp<FieldField<Field, typename product<Type, Form>::type> > \ opFunc(tRes(), tf1(), f2); \
operator op \ reuseTmpFieldField<Field1, productType, Type1>::clear(tf1); \
( \ return tRes; \
const FieldField<Field, Type>& f1, \ } \
const VectorSpace<Form,Cmpt,nCmpt>& vs \ \
) \ template \
{ \ < \
typedef typename product<Type, Form>::type productType; \ template<class> class Field1, \
tmp<FieldField<Field, productType> > tRes \ template<class> class Field2, \
( \ class Type1, \
FieldField<Field, productType>::NewCalculatedType(f1) \ class Type2 \
); \ > \
opFunc(tRes(), f1, static_cast<const Form&>(vs)); \ tmp<FieldField<Field1, typename product<Type1, Type2>::type> > \
return tRes; \ operator op \
} \ ( \
\ const tmp<FieldField<Field1, Type1> >& tf1, \
template \ const tmp<FieldField<Field2, Type2> >& tf2 \
<template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \ ) \
tmp<FieldField<Field, typename product<Type, Form>::type> > \ { \
operator op \ typedef typename product<Type1, Type2>::type productType; \
( \ tmp<FieldField<Field1, productType> > tRes \
const tmp<FieldField<Field, Type> >& tf1, \ ( \
const VectorSpace<Form,Cmpt,nCmpt>& vs \ reuseTmpTmpFieldField<Field1, productType, Type1, Type1, Type2>::New \
) \ (tf1, tf2) \
{ \ ); \
typedef typename product<Type, Form>::type productType; \ opFunc(tRes(), tf1(), tf2()); \
tmp<FieldField<Field, productType> > tRes \ reuseTmpTmpFieldField<Field1, productType, Type1, Type1, Type2>::clear \
( \ (tf1, tf2); \
reuseTmpFieldField<Field, productType, Type>::New(tf1) \ return tRes; \
); \ } \
opFunc(tRes(), tf1(), static_cast<const Form&>(vs)); \ \
reuseTmpFieldField<Field, productType, Type>::clear(tf1); \ template \
return tRes; \ <template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \
} \ void opFunc \
\ ( \
template \ FieldField<Field, typename product<Type, Form>::type>& f, \
<template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \ const FieldField<Field, Type>& f1, \
void opFunc \ const VectorSpace<Form,Cmpt,nCmpt>& vs \
( \ ) \
FieldField<Field, typename product<Form, Type>::type>& f, \ { \
const VectorSpace<Form,Cmpt,nCmpt>& vs, \ forAll(f, i) \
const FieldField<Field, Type>& f1 \ { \
) \ opFunc(f[i], f1[i], vs); \
{ \ } \
forAll(f, i) \ } \
{ \ \
opFunc(f[i], vs, f1[i]); \ template \
} \ <template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \
} \ tmp<FieldField<Field, typename product<Type, Form>::type> > \
\ operator op \
template \ ( \
<template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \ const FieldField<Field, Type>& f1, \
tmp<FieldField<Field, typename product<Form, Type>::type> > \ const VectorSpace<Form,Cmpt,nCmpt>& vs \
operator op \ ) \
( \ { \
const VectorSpace<Form,Cmpt,nCmpt>& vs, \ typedef typename product<Type, Form>::type productType; \
const FieldField<Field, Type>& f1 \ tmp<FieldField<Field, productType> > tRes \
) \ ( \
{ \ FieldField<Field, productType>::NewCalculatedType(f1) \
typedef typename product<Form, Type>::type productType; \ ); \
tmp<FieldField<Field, productType> > tRes \ opFunc(tRes(), f1, static_cast<const Form&>(vs)); \
( \ return tRes; \
FieldField<Field, productType>::NewCalculatedType(f1) \ } \
); \ \
opFunc(tRes(), static_cast<const Form&>(vs), f1); \ template \
return tRes; \ <template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \
} \ tmp<FieldField<Field, typename product<Type, Form>::type> > \
\ operator op \
template \ ( \
<template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \ const tmp<FieldField<Field, Type> >& tf1, \
tmp<FieldField<Field, typename product<Form, Type>::type> > \ const VectorSpace<Form,Cmpt,nCmpt>& vs \
operator op \ ) \
( \ { \
const VectorSpace<Form,Cmpt,nCmpt>& vs, \ typedef typename product<Type, Form>::type productType; \
const tmp<FieldField<Field, Type> >& tf1 \ tmp<FieldField<Field, productType> > tRes \
) \ ( \
{ \ reuseTmpFieldField<Field, productType, Type>::New(tf1) \
typedef typename product<Form, Type>::type productType; \ ); \
tmp<FieldField<Field, productType> > tRes \ opFunc(tRes(), tf1(), static_cast<const Form&>(vs)); \
( \ reuseTmpFieldField<Field, productType, Type>::clear(tf1); \
reuseTmpFieldField<Field, productType, Type>::New(tf1) \ return tRes; \
); \ } \
opFunc(tRes(), static_cast<const Form&>(vs), tf1()); \ \
reuseTmpFieldField<Field, productType, Type>::clear(tf1); \ template \
return tRes; \ <template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \
void opFunc \
( \
FieldField<Field, typename product<Form, Type>::type>& f, \
const VectorSpace<Form,Cmpt,nCmpt>& vs, \
const FieldField<Field, Type>& f1 \
) \
{ \
forAll(f, i) \
{ \
opFunc(f[i], vs, f1[i]); \
} \
} \
\
template \
<template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \
tmp<FieldField<Field, typename product<Form, Type>::type> > \
operator op \
( \
const VectorSpace<Form,Cmpt,nCmpt>& vs, \
const FieldField<Field, Type>& f1 \
) \
{ \
typedef typename product<Form, Type>::type productType; \
tmp<FieldField<Field, productType> > tRes \
( \
FieldField<Field, productType>::NewCalculatedType(f1) \
); \
opFunc(tRes(), static_cast<const Form&>(vs), f1); \
return tRes; \
} \
\
template \
<template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \
tmp<FieldField<Field, typename product<Form, Type>::type> > \
operator op \
( \
const VectorSpace<Form,Cmpt,nCmpt>& vs, \
const tmp<FieldField<Field, Type> >& tf1 \
) \
{ \
typedef typename product<Form, Type>::type productType; \
tmp<FieldField<Field, productType> > tRes \
( \
reuseTmpFieldField<Field, productType, Type>::New(tf1) \
); \
opFunc(tRes(), static_cast<const Form&>(vs), tf1()); \
reuseTmpFieldField<Field, productType, Type>::clear(tf1); \
return tRes; \
} }
PRODUCT_OPERATOR(typeOfSum, +, add) PRODUCT_OPERATOR(typeOfSum, +, add)

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -267,100 +267,138 @@ BINARY_TYPE_OPERATOR_FS(Type, Type, scalar, /, divide)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#define PRODUCT_OPERATOR(product, op, opFunc) \ #define PRODUCT_OPERATOR(product, op, opFunc) \
\ \
template<template<class> class Field, class Type1, class Type2> \ template \
void opFunc \ < \
( \ template<class> class Field1, \
FieldField<Field, typename product<Type1, Type2>::type>& f, \ template<class> class Field2, \
const FieldField<Field, Type1>& f1, \ class Type1, \
const FieldField<Field, Type2>& f2 \ class Type2 \
); \ > \
\ void opFunc \
template<template<class> class Field, class Type1, class Type2> \ ( \
tmp<FieldField<Field, typename product<Type1, Type2>::type> > \ FieldField<Field1, typename product<Type1, Type2>::type>& f, \
operator op \ const FieldField<Field1, Type1>& f1, \
( \ const FieldField<Field2, Type2>& f2 \
const FieldField<Field, Type1>& f1, \ ); \
const FieldField<Field, Type2>& f2 \ \
); \ template \
\ < \
template<template<class> class Field, class Type1, class Type2> \ template<class> class Field1, \
tmp<FieldField<Field, typename product<Type1, Type2>::type> > \ template<class> class Field2, \
operator op \ class Type1, \
( \ class Type2 \
const FieldField<Field, Type1>& f1, \ > \
const tmp<FieldField<Field, Type2> >& tf2 \ tmp<FieldField<Field1, typename product<Type1, Type2>::type> > \
); \ operator op \
\ ( \
template<template<class> class Field, class Type1, class Type2> \ const FieldField<Field1, Type1>& f1, \
tmp<FieldField<Field, typename product<Type1, Type2>::type> > \ const FieldField<Field2, Type2>& f2 \
operator op \ ); \
( \ \
const tmp<FieldField<Field, Type1> >& tf1, \ template<template<class> class Field, class Type1, class Type2> \
const FieldField<Field, Type2>& f2 \ tmp<FieldField<Field, typename product<Type1, Type2>::type> > \
); \ operator op \
\ ( \
template<template<class> class Field, class Type1, class Type2> \ const FieldField<Field, Type1>& f1, \
tmp<FieldField<Field, typename product<Type1, Type2>::type> > \ const tmp<FieldField<Field, Type2> >& tf2 \
operator op \ ); \
( \ \
const tmp<FieldField<Field, Type1> >& tf1, \ template \
const tmp<FieldField<Field, Type2> >& tf2 \ < \
); \ template<class> class Field1, \
\ template<class> class Field2, \
template \ class Type1, \
<template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \ class Type2 \
void opFunc \ > \
( \ tmp<FieldField<Field1, typename product<Type1, Type2>::type> > \
FieldField<Field, typename product<Type, Form>::type>& f, \ operator op \
const FieldField<Field, Type>& f1, \ ( \
const VectorSpace<Form,Cmpt,nCmpt>& vs \ const FieldField<Field1, Type1>& f1, \
); \ const tmp<FieldField<Field2, Type2> >& tf2 \
\ ); \
template \ \
<template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \ template \
tmp<FieldField<Field, typename product<Type, Form>::type> > \ < \
operator op \ template<class> class Field1, \
( \ template<class> class Field2, \
const FieldField<Field, Type>& f1, \ class Type1, \
const VectorSpace<Form,Cmpt,nCmpt>& vs \ class Type2 \
); \ > \
\ tmp<FieldField<Field1, typename product<Type1, Type2>::type> > \
template \ operator op \
<template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \ ( \
tmp<FieldField<Field, typename product<Type, Form>::type> > \ const tmp<FieldField<Field1, Type1> >& tf1, \
operator op \ const FieldField<Field2, Type2>& f2 \
( \ ); \
const tmp<FieldField<Field, Type> >& tf1, \ \
const VectorSpace<Form,Cmpt,nCmpt>& vs \ template \
); \ < \
\ template<class> class Field1, \
template \ template<class> class Field2, \
<template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \ class Type1, \
void opFunc \ class Type2 \
( \ > \
FieldField<Field, typename product<Form, Type>::type>& f, \ tmp<FieldField<Field1, typename product<Type1, Type2>::type> > \
const VectorSpace<Form,Cmpt,nCmpt>& vs, \ operator op \
const FieldField<Field, Type>& f1 \ ( \
); \ const tmp<FieldField<Field1, Type1> >& tf1, \
\ const tmp<FieldField<Field2, Type2> >& tf2 \
template \ ); \
<template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \ \
tmp<FieldField<Field, typename product<Form, Type>::type> > \ template \
operator op \ <template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \
( \ void opFunc \
const VectorSpace<Form,Cmpt,nCmpt>& vs, \ ( \
const FieldField<Field, Type>& f1 \ FieldField<Field, typename product<Type, Form>::type>& f, \
); \ const FieldField<Field, Type>& f1, \
\ const VectorSpace<Form,Cmpt,nCmpt>& vs \
template \ ); \
<template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \ \
tmp<FieldField<Field, typename product<Form, Type>::type> > \ template \
operator op \ <template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \
( \ tmp<FieldField<Field, typename product<Type, Form>::type> > \
const VectorSpace<Form,Cmpt,nCmpt>& vs, \ operator op \
const tmp<FieldField<Field, Type> >& tf1 \ ( \
const FieldField<Field, Type>& f1, \
const VectorSpace<Form,Cmpt,nCmpt>& vs \
); \
\
template \
<template<class> class Field, class Type, class Form, class Cmpt, int nCmpt> \
tmp<FieldField<Field, typename product<Type, Form>::type> > \
operator op \
( \
const tmp<FieldField<Field, Type> >& tf1, \
const VectorSpace<Form,Cmpt,nCmpt>& vs \
); \
\
template \
<template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \
void opFunc \
( \
FieldField<Field, typename product<Form, Type>::type>& f, \
const VectorSpace<Form,Cmpt,nCmpt>& vs, \
const FieldField<Field, Type>& f1 \
); \
\
template \
<template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \
tmp<FieldField<Field, typename product<Form, Type>::type> > \
operator op \
( \
const VectorSpace<Form,Cmpt,nCmpt>& vs, \
const FieldField<Field, Type>& f1 \
); \
\
template \
<template<class> class Field, class Form, class Cmpt, int nCmpt, class Type> \
tmp<FieldField<Field, typename product<Form, Type>::type> > \
operator op \
( \
const VectorSpace<Form,Cmpt,nCmpt>& vs, \
const tmp<FieldField<Field, Type> >& tf1 \
); );
PRODUCT_OPERATOR(typeOfSum, +, add) PRODUCT_OPERATOR(typeOfSum, +, add)