[PATCH] Make two-arg where() work for Fields.
Richard Guenther
rguenth at tat.physik.uni-tuebingen.de
Thu Jan 23 16:21:55 UTC 2003
Just stumbled over the following patch in one of my repositories...
Ok?
Richard.
2003Jan23 Richard Guenther <richard.guenther at uni-tuebingen.de>
* src/Field/Field.h: add assign(,WhereProxy,), add necessary
specializations for ExpressionTraits, CombineExpressionTraits
and ConvertWhereProxy.
src/Field/tests/WhereTest.cpp: enable checking of two-argument
where() for Fields.
# This is a BitKeeper generated patch for the following project:
# Project Name: pooma/cheetah repository tracking CVS/tarball
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.25 -> 1.26
# r2/src/Field/Field.h 1.3 -> 1.5
# r2/src/Field/tests/WhereTest.cpp 1.1 -> 1.2
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/01/23 rguenth at bellatrix.tat.physik.uni-tuebingen.de 1.26
# Two-arg where() support for Fields.
# --------------------------------------------
#
diff -Nru a/r2/src/Field/Field.h b/r2/src/Field/Field.h
--- a/r2/src/Field/Field.h Thu Jan 23 17:18:40 2003
+++ b/r2/src/Field/Field.h Thu Jan 23 17:18:40 2003
@@ -146,6 +146,13 @@
assign(const Array<Dim2, T2, EngineTag2> &lhs,
const Field<Mesh, T, EngineTag> &rhs, const Op &op);
+template<class Mesh, class T, class EngineTag,
+ class F, class B, class Op>
+const Field<Mesh, T, EngineTag> &
+assign(const Field<Mesh, T, EngineTag> &lhs,
+ const WhereProxy<F, B> &rhs,
+ const Op &op);
+
//-----------------------------------------------------------------------------
// SubFieldView is used to implement the syntax f[i], which selects the
// ith SubField for field f.
@@ -2010,6 +2017,49 @@
//-----------------------------------------------------------------------------
+// Traits class for expressions containing fields.
+//-----------------------------------------------------------------------------
+
+struct ExpressionIsField { };
+
+template<class Mesh, class T, class EngineTag>
+struct ExpressionTraits<Field<Mesh, T, EngineTag> >
+{
+ typedef ExpressionIsField Type_t;
+};
+
+template<>
+struct CombineExpressionTraits<ExpressionIsField, ExpressionIsField>
+{
+ typedef ExpressionIsField Type_t;
+};
+
+template<>
+struct CombineExpressionTraits<ExpressionIsField, ExpressionIsScalar>
+{
+ typedef ExpressionIsField Type_t;
+};
+
+template<>
+struct CombineExpressionTraits<ExpressionIsScalar, ExpressionIsField>
+{
+ typedef ExpressionIsField Type_t;
+};
+
+template<>
+struct CombineExpressionTraits<ExpressionIsField, ExpressionIsArray>
+{
+ typedef ExpressionIsField Type_t;
+};
+
+template<>
+struct CombineExpressionTraits<ExpressionIsArray, ExpressionIsField>
+{
+ typedef ExpressionIsField Type_t;
+};
+
+
+//-----------------------------------------------------------------------------
// assign() function for Field assign-op array.
//-----------------------------------------------------------------------------
@@ -2138,6 +2188,28 @@
Evaluator<MainEvaluatorTag>().evaluate(lhs, op, rhs);
+ return lhs;
+}
+
+
+//-----------------------------------------------------------------------------
+// assign() function for Field assign-op WhereProxy.
+//-----------------------------------------------------------------------------
+
+template<class Tree>
+struct ConvertWhereProxy<ExpressionIsField, Tree>
+{
+ typedef MakeFieldReturn<Tree> Make_t;
+};
+
+template<class Mesh, class T, class EngineTag,
+ class F, class B, class Op>
+const Field<Mesh, T, EngineTag> &
+assign(const Field<Mesh, T, EngineTag> &lhs,
+ const WhereProxy<F, B> &rhs, const Op &op)
+{
+ assign(lhs, rhs.whereMask(), rhs.opMask(op));
+
return lhs;
}
diff -Nru a/r2/src/Field/tests/WhereTest.cpp b/r2/src/Field/tests/WhereTest.cpp
--- a/r2/src/Field/tests/WhereTest.cpp Thu Jan 23 17:18:40 2003
+++ b/r2/src/Field/tests/WhereTest.cpp Thu Jan 23 17:18:40 2003
@@ -111,26 +111,15 @@
Vector<2> line(1.0, 1.0);
+
+ // 3-arg where
+
a = where(dot(x, line) > 8.0, x.comp(0), x.comp(1));
// equivalent to:
// a = where(x.comp(0) + x.comp(1) > 8.0, x.comp(0), x.comp(1));
- // These fail to compile:
-
- // b = where(dot(x, line) > 8.0, x.comp(0));
- // c = where(dot(x, line) <= 8.0, x.comp(1));
-
- tester.out() << a << std::endl;
-
- // tester.out().setf(std::ios_base::fixed, std::ios_base::floatfield);
-
- // tester.out() << sum(a[0]) << std::endl;
- // tester.out() << sum(a[0] * x[0].comp(0)) << std::endl;
- // tester.out() << sum(a[0] * x[0].comp(1)) << std::endl;
- // tester.out() << sum(a[1]) << std::endl;
- // tester.out() << sum(a[1] * x[1].comp(0)) << std::endl;
- // tester.out() << sum(a[1] * x[1].comp(1)) << std::endl;
+ tester.out() << "where(dot(x, line) > 8.0, x.comp(0), x.comp(1))\n" << a << std::endl;
// Should verify these results by hand.
// These are basically regression tests.
@@ -141,6 +130,30 @@
tester.check("sum a[1]", sum(a[1]), 387.0);
tester.check("sum a[1]*x[1](0)", sum(a[1] * x[1].comp(0)), 2161.5);
tester.check("sum a[1]*x[1](1)", sum(a[1] * x[1].comp(1)), 1990.5);
+
+
+ // 2-arg where
+
+ b = where(dot(x, line) > 8.0, x.comp(0));
+ c = where(dot(x, line) <= 8.0, x.comp(1));
+
+ tester.out() << "where(dot(x, line) > 8.0, x.comp(0))" << b << std::endl;
+ tester.out() << "where(dot(x, line) <= 8.0, x.comp(1))" << c << std::endl;
+
+ // verify using 3-arg where verified above
+
+ tester.check("twoarg where result 0.0 part, centering zero",
+ all(where(dot(x.subField(0, 0), line) > 8.0,
+ c.subField(0, 0), b.subField(0, 0)) == 0.0));
+ tester.check("twoarg where result 0.0 part, centering one",
+ all(where(dot(x.subField(0, 1), line) > 8.0,
+ c.subField(0, 1), b.subField(0, 1)) == 0.0));
+ tester.check("twoarg where result dirtied part, centering zero",
+ all(where(dot(x.subField(0, 0), line) > 8.0,
+ b.subField(0, 0), c.subField(0, 0)) == a.subField(0, 0)));
+ tester.check("twoarg where result dirtied part, centering one",
+ all(where(dot(x.subField(0, 1), line) > 8.0,
+ b.subField(0, 1), c.subField(0, 1)) == a.subField(0, 1)));
int ret = tester.results("WhereTest");
Pooma::finalize();
More information about the pooma-dev
mailing list