[llvm-commits] CVS: llvm-test/MultiSource/Benchmarks/tramp3d-v4/Makefile README.txt tramp3d-v4.cpp
Chris Lattner
sabre at nondot.org
Wed Jan 17 22:29:02 PST 2007
Changes in directory llvm-test/MultiSource/Benchmarks/tramp3d-v4:
Makefile added (r1.1)
README.txt added (r1.1)
tramp3d-v4.cpp added (r1.1)
---
Log message:
Add the tramp3d-v4 benchmark.
---
Diffs of the changes: (+56097 -0)
Makefile | 9
README.txt | 8
tramp3d-v4.cpp |56080 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 56097 insertions(+)
Index: llvm-test/MultiSource/Benchmarks/tramp3d-v4/Makefile
diff -c /dev/null llvm-test/MultiSource/Benchmarks/tramp3d-v4/Makefile:1.1
*** /dev/null Thu Jan 18 00:28:57 2007
--- llvm-test/MultiSource/Benchmarks/tramp3d-v4/Makefile Thu Jan 18 00:28:47 2007
***************
*** 0 ****
--- 1,9 ----
+ LEVEL = ../../..
+
+ PROG = tramp3d-v4
+ CPPFLAGS =
+ LDFLAGS = -lstdc++
+ RUN_OPTIONS = --cartvis 1.0 0.0 --rhomin 1e-8 -n 25
+ FP_TOLERANCE := 0.00001
+
+ include ../../Makefile.multisrc
Index: llvm-test/MultiSource/Benchmarks/tramp3d-v4/README.txt
diff -c /dev/null llvm-test/MultiSource/Benchmarks/tramp3d-v4/README.txt:1.1
*** /dev/null Thu Jan 18 00:29:02 2007
--- llvm-test/MultiSource/Benchmarks/tramp3d-v4/README.txt Thu Jan 18 00:28:47 2007
***************
*** 0 ****
--- 1,8 ----
+
+ This is a template-intensive numerical program based on FreePOOMA, written by
+ Richard Guenther. The FreePOOMA parts are 3-clause BSD licensed, the rest is
+ put in the public domain by Richard.
+
+ For more info, see:
+ http://www.suse.de/~rguenther/tramp3d/
+
Index: llvm-test/MultiSource/Benchmarks/tramp3d-v4/tramp3d-v4.cpp
diff -c /dev/null llvm-test/MultiSource/Benchmarks/tramp3d-v4/tramp3d-v4.cpp:1.1
*** /dev/null Thu Jan 18 00:29:02 2007
--- llvm-test/MultiSource/Benchmarks/tramp3d-v4/tramp3d-v4.cpp Thu Jan 18 00:28:47 2007
***************
*** 0 ****
--- 1,56080 ----
+ #include <sys/time.h>
+ #include <time.h>
+ #include <fenv.h>
+ #include <cstdarg>
+ #include <complex>
+ #include <algorithm>
+ #include <limits>
+ #include <math.h>
+
+ namespace Smarts {
+ template<class T>
+ class IterateScheduler;
+ template<class T>
+ class Iterate;
+ template<class T>
+ class DataObject;
+ }
+ namespace Smarts {
+ class Runnable
+ {
+ public:
+ Runnable()
+ {
+ priority_m = 0;
+ }
+ Runnable(int)
+ {
+ priority_m = 0;
+ }
+ virtual ~Runnable() {}
+ inline int
+ priority() { return priority_m; }
+ inline void
+ priority(int _priority) { priority_m = _priority; }
+ virtual void execute()
+ {
+ run();
+ }
+ protected:
+ virtual void run() {}
+ private:
+ int priority_m;
+ };
+ typedef Runnable *RunnablePtr_t;
+ inline void add(RunnablePtr_t);
+ }
+ namespace Smarts {
+ class Stub
+ {
+ public:
+ enum Action { Read, Write };
+ };
+ template<> class Iterate<Stub>;
+ template<> class IterateScheduler<Stub>;
+ template<> class DataObject<Stub>;
+ template<>
+ class Iterate<Stub> : public Runnable
+ {
+ public:
+ inline Iterate(IterateScheduler<Stub> & scheduler, int affinity=-1);
+ virtual ~Iterate() {}
+ virtual void run() = 0;
+ int affinity() { return 0; }
+ int hintAffinity() { return 0; }
+ void affinity(int) {}
+ void hintAffinity(int) {}
+ void generation(int gen) { generation_m=gen; }
+ int generation() { return generation_m; }
+ protected:
+ IterateScheduler<Stub> &scheduler_m;
+ private:
+ int generation_m;
+ };
+ template<>
+ class IterateScheduler<Stub>
+ {
+ public:
+ inline
+ void beginGeneration() { generation_m++; }
+ inline
+ void endGeneration() {}
+ inline
+ void blockingEvaluate() {}
+ inline
+ void releaseIterates() { }
+ inline
+ IterateScheduler()
+ : generation_m(0)
+ { }
+ inline
+ ~IterateScheduler() {}
+ inline int generation() const { return generation_m; }
+ inline
+ void handOff(Iterate<Stub>* it)
+ {
+ it->run();
+ delete it;
+ }
+ protected:
+ private:
+ int generation_m;
+ };
+ inline Iterate<Stub>::Iterate(IterateScheduler<Stub> & scheduler, int)
+ : scheduler_m(scheduler)
+ {
+ generation(scheduler.generation());
+ }
+ template<>
+ class DataObject<Stub>
+ {
+ public:
+ inline DataObject(int=-1) {}
+ inline int affinity() const { return 0; };
+ inline void affinity(int) {}
+ inline void request(Iterate<Stub>&, Stub::Action) {}
+ inline void release(Stub::Action) {}
+ protected:
+ private:
+ };
+ inline void concurrency(int)
+ {
+ }
+ inline int concurrency()
+ {
+ return 1;
+ }
+ inline void wait()
+ {
+ }
+ inline void add(Runnable *runnable)
+ {
+ runnable->execute();
+ delete runnable;
+ }
+ }
+ namespace Pooma {
+ typedef Smarts::Stub SmartsTag_t;
+ }
+ namespace Pooma {
+ static const char schedulerVersion[] = "stub scheduler";
+ typedef Smarts::IterateScheduler<SmartsTag_t> Scheduler_t;
+ typedef Smarts::DataObject<SmartsTag_t> DataObject_t;
+ typedef Smarts::Iterate<SmartsTag_t> Iterate_t;
+ typedef Smarts::Runnable Runnable_t;
+ inline void addRunnable(Runnable_t *runnable)
+ {
+ Smarts::add(runnable);
+ }
+ }
+ namespace Pooma {
+ class Assertion
+ {
+ char *msg_m;
+ char *file_m;
+ int line_m;
+ public:
+ Assertion(const char *msg, const char *file, int line);
+ Assertion(const Assertion &a);
+ ~Assertion() { delete[] msg_m; delete [] file_m; }
+ Assertion &operator=(const Assertion &a);
+ const char *what() const { return msg_m; }
+ const char *file() const { return file_m; }
+ int line() const { return line_m; }
+ template<class OS>
+ void print(OS &os) const
+ {
+ os << "### POOMA Assertion Failure ###\n";
+ os << "### " << what() << "\n";
+ os << "### File " << file() << "; Line " << line();
+ }
+ };
+ void toss_cookies(const char *msg, const char *file, int line ...) __attribute__((noreturn));
+ }
+ template<bool B> struct PoomaCTAssert {};
+ template<> struct PoomaCTAssert<true> { static inline void test() {} };
+ template<class T1, class T2>
+ struct SameType
+ {
+ enum { same = false };
+ };
+ template<class T1>
+ struct SameType<T1, T1>
+ {
+ enum { same = true };
+ };
+ namespace Pooma {
+ class DummyMutex
+ {
+ public:
+ inline DummyMutex() { }
+ inline DummyMutex(const DummyMutex &) { }
+ inline DummyMutex &operator=(const DummyMutex &) { return *this; }
+ inline void lock() { }
+ inline void unlock() { }
+ };
+ typedef DummyMutex Mutex_t;
+ }
+ #include <iostream>
+ #include <map>
+ class InformStream;
+ class Inform
+ {
+ public:
+ typedef int ID_t;
+ typedef int Level_t;
+ typedef int Context_t;
+ enum { out, app };
+ enum { allContexts = (-1) };
+ enum { off = (-1), on = 0 };
+ Inform(const char *prefix = 0, Context_t outputContext = 0);
+ Inform(const char *prefix, const char *fname, int writemode,
+ Context_t outputContext = 0);
+ Inform(const char *prefix, std::ostream &outstream,
+ Context_t outputContext = 0);
+ ~Inform();
+ const std::string &prefix() const { return prefix_m; }
+ void setPrefix(const char *prefix = 0);
+ ID_t open(Context_t context = 0);
+ ID_t open(const char *fname, int writemode, Context_t context = 0);
+ ID_t open(std::ostream &outstream, Context_t context = 0);
+ void close(ID_t);
+ void close();
+ Level_t messageLevel() const { return level_m; }
+ Inform &setMessageLevel(Level_t newval) { level_m = newval; return *this; }
+ Level_t outputLevel(ID_t id = 0) const;
+ void setOutputLevel(Level_t newval, ID_t id);
+ void setOutputLevel(Level_t newval);
+ Context_t outputContext(ID_t id = 0) const;
+ void setOutputContext(Context_t outputContext, ID_t id);
+ void setOutputContext(Context_t outputContext);
+ inline static Context_t context() { return context_s; }
+ inline static Context_t numContexts() { return nContexts_s; }
+ static inline void setContext(Context_t c) { context_s = c; }
+ static inline void setNumContexts(Context_t n) { nContexts_s = n; }
+ void flush();
+ void print() { flush(); }
+ void output() { flush(); }
+ typedef std::ios_base::fmtflags FmtFlags_t;
+ std::ostream& stream() { return *message_m; }
+ FmtFlags_t
+ setf(FmtFlags_t setbits,FmtFlags_t field)
+ { return message_m->setf(setbits,field);}
+ FmtFlags_t
+ setf(FmtFlags_t f) { return message_m->setf(f); }
+ void unsetf(FmtFlags_t f) { message_m->unsetf(f); }
+ long flags() const { return message_m->flags(); }
+ long flags(FmtFlags_t f) { return message_m->flags(f); }
+ int width() const { return message_m->width(); }
+ int width(int w) { return message_m->width(w); }
+ char fill() const { return message_m->fill(); }
+ char fill(char c) { return message_m->fill(c); }
+ int precision() const { return message_m->precision(); }
+ int precision(int p) { return message_m->precision(p); }
+ void lock() const { mutex_m.lock(); }
+ void unlock() const { mutex_m.unlock(); }
+ private:
+ typedef std::map<ID_t, InformStream *> StreamList_t;
+ typedef StreamList_t::size_type Size_t;
+ typedef StreamList_t::value_type Value_t;
+ typedef StreamList_t::iterator iterator;
+ typedef StreamList_t::const_iterator const_iterator;
+ std::string prefix_m;
+ Context_t outputContext_m;
+ Level_t level_m;
+ StreamList_t streams_m;
+ std::ostringstream *message_m;
+ char *buffer_m;
+ static const unsigned int bufSize;
+ ID_t nextID_m;
+ mutable Pooma::Mutex_t mutex_m;
+ static Pooma::Mutex_t outputMutex_s;
+ static Context_t context_s;
+ static Context_t nContexts_s;
+ InformStream *findStream(ID_t) const;
+ void setup(const char *prefix);
+ };
+ namespace std {
+ extern Inform &endl(Inform &);
+ extern Inform &flush(Inform &);
+ extern Inform &lock(Inform &);
+ extern Inform &unlock(Inform &);
+ }
+ inline Inform &operator<<(Inform &o, Inform &(*d)(Inform &))
+ {
+ return d(o);
+ }
+ inline Inform &operator<<(Inform &o, std::ios_base &(*d)(std::ios_base &))
+ {
+ d(o.stream());
+ return o;
+ }
+ template<class T>
+ inline Inform &operator<<(Inform &o, const T &val)
+ {
+ o.stream() << val;
+ return o;
+ }
+ inline Inform &operator<<(Inform &o, const void *val)
+ {
+ Inform::FmtFlags_t oldformat =
+ o.setf(std::ios::hex, std::ios::basefield);
+ o.stream() << "0x" << reinterpret_cast<long>(val);
+ o.setf(oldformat, std::ios::basefield);
+ return o;
+ }
+ inline Inform &operator<<(Inform &o, const char *s)
+ {
+ o.stream() << s;
+ return o;
+ }
+ inline Inform &operator<<(Inform &o, const std::string &s)
+ {
+ o.stream() << s.c_str();
+ return o;
+ }
+ #include <iterator>
+ template <class T>
+ class InformIterator
+ {
+ public:
+ typedef std::output_iterator_tag iterator_category;
+ typedef void value_type;
+ typedef void difference_type;
+ typedef void pointer;
+ typedef void reference;
+ InformIterator(Inform &s) : out_m(&s), delim_m(0) { }
+ InformIterator(Inform &s, const char *d) : out_m(&s), delim_m(d) { }
+ InformIterator &operator=(const T &value)
+ {
+ *out_m << value;
+ if (delim_m != 0)
+ *out_m << delim_m;
+ return *this;
+ }
+ InformIterator &operator*() { return *this; }
+ InformIterator &operator++() { return *this; }
+ InformIterator &operator++(int) { return *this; }
+ private:
+ Inform *out_m;
+ const char *delim_m;
+ };
+ namespace Pooma {
+ class Options
+ {
+ public:
+ Options();
+ Options(int &argc, char ** argv);
+ Options(const Options &opts);
+ Options &operator=(const Options &opts);
+ ~Options();
+ int concurrency() const { return concurrency_m; }
+ void concurrency(int c)
+ {
+ ;
+ concurrency_m = c;
+ }
+ bool printInfo() const { return info_m; }
+ void printInfo(bool p) { info_m = p; }
+ bool printWarnings() const { return warn_m; }
+ void printWarnings(bool p) { warn_m = p; }
+ bool printErrors() const { return err_m; }
+ void printErrors(bool p) { err_m = p; }
+ const std::string &logfile() const { return logfile_m; }
+ void logfile(const std::string &s) { logfile_m = s; }
+ bool printStats() const { return stats_m; }
+ void printStats(bool p) { stats_m = p; }
+ int debug() const { return debug_m; }
+ void debug(int p) { debug_m = p; }
+ bool neverCompress() const { return neverCompress_m; }
+ void neverCompress(bool p) { neverCompress_m = p; }
+ bool deferredGuardFills() const { return deferredFills_m; }
+ void deferredGuardFills(bool p) { deferredFills_m = p; }
+ bool hardInit() const { return hardinit_m; }
+ void hardInit(bool p) { hardinit_m = p; }
+ bool hardRun() const { return hardrun_m; }
+ void hardRun(bool p) { hardrun_m = p; }
+ bool lockThreads() const { return lockthreads_m; }
+ void lockThreads(bool p) { lockthreads_m = p; }
+ bool blockingExpressions() const { return blockingExpressions_m; }
+ void blockingExpressions(bool p) { blockingExpressions_m = p; }
+ void usage();
+ void reset();
+ void parse(int &argc, char ** &argv);
+ private:
+ int concurrency_m;
+ bool info_m;
+ bool warn_m;
+ bool err_m;
+ std::string logfile_m;
+ bool stats_m;
+ int debug_m;
+ bool neverCompress_m;
+ bool deferredFills_m;
+ bool hardinit_m;
+ bool hardrun_m;
+ bool lockthreads_m;
+ bool blockingExpressions_m;
+ };
+ bool intArgument(int argc, char **argv, int pos, int &val);
+ bool stringArgument(int argc, char **argv, int pos, std::string &val);
+ bool doubleArgument(int argc, char **argv, int pos, double &val);
+ }
+ namespace Pooma {
+ typedef void (*AbortHandler_t)();
+ typedef int Context_t;
+ typedef int PatchID_t;
+ namespace Arch {
+ inline void dawdle() { }
+ inline void getCommandLineArguments(int &, char** &) { }
+ inline void initialize() { }
+ inline void finalize() { }
+ }
+ void incrementNumExpressions(long val = 1);
+ void incrementNumMultiPatchExpressions(long val = 1);
+ void incrementNumZBExpressions(long val = 1);
+ void incrementNumCompressedAssigns(long val = 1);
+ void incrementNumAssignsRequiringUnCompression(long val = 1);
+ void incrementNumInlineEvaluations(long val = 1);
+ void incrementNumLocalPatchesEvaluated(long val = 1);
+ void incrementNumReductions(long val = 1);
+ void incrementNumUnCompresses(long val = 1);
+ void incrementNumUnsuccessfulTryCompresses(long val = 1);
+ void incrementNumSuccessfulTryCompresses(long val = 1);
+ void incrementNumPolls(long val = 1);
+ extern Inform pinfo;
+ extern Inform pwarn;
+ extern Inform perr;
+ extern Inform pdebug;
+ bool initialize(int &argc, char ** &argv,
+ bool initRTS = true, bool getCLArgsArch = true, bool initArch = true);
+ bool initialize(Pooma::Options &opts, bool initRTS = true,
+ bool initArch = true);
+ bool finalize();
+ bool finalize(bool quitRTS, bool quitArch);
+ void pAbort(int errorcode = 0) __attribute__((noreturn));
+ void pAbort(const char *msg, int errorcode = 0) __attribute__((noreturn));
+ void stopHere();
+ AbortHandler_t abortHandler();
+ AbortHandler_t abortHandler(AbortHandler_t);
+ AbortHandler_t resetAbortHandler();
+ const char *version();
+ int majorVersion();
+ int minorVersion();
+ const char *buildDate();
+ bool printStats();
+ void printStats(bool on);
+ bool infoMessages();
+ void infoMessages(bool on);
+ bool warnMessages();
+ void warnMessages(bool on);
+ bool errorMessages();
+ void errorMessages(bool on);
+ void logMessages(const char *filename);
+ int debugLevel();
+ void debugLevel(int val);
+ bool neverCompress();
+ void neverCompress(bool p);
+ bool deferredGuardFills();
+ void deferredGuardFills(bool p);
+ extern Context_t myContext_g;
+ extern int numContexts_g;
+ extern int expression_g;
+ inline Context_t context() { return myContext_g; }
+ inline int contexts() { return numContexts_g; }
+ Scheduler_t &scheduler();
+ void blockAndEvaluate();
+ bool hardInit();
+ void hardInit(bool on);
+ bool hardRun();
+ void hardRun(bool on);
+ bool lockThreads();
+ void lockThreads(bool on);
+ bool blockingExpressions();
+ void blockingExpressions(bool on);
+ inline void beginExpression()
+ {
+ scheduler().beginGeneration();
+ }
+ inline void endExpression()
+ {
+ scheduler().endGeneration();
+ expression_g++;
+ if (blockingExpressions())
+ blockAndEvaluate();
+ }
+ inline int expression()
+ {
+ return expression_g;
+ }
+ inline void poll()
+ {
+ ;
+ }
+ }
+ template<int Dim, class T, class EngineTag> class Array;
+ template<int Dim, class T, class EngineTag> class Engine;
+ template<class Subject, class Sub1, bool SV>
+ struct View1Implementation;
+ template <class LayoutTag, class PatchTag>
+ struct MultiPatch;
+ template <class LayoutTag, class PatchTag, int Dim2>
+ struct MultiPatchView;
+ template<class Expr>
+ struct ExpressionTag;
+ template <int Dim, class T, class EngineTag>
+ class Engine;
+ template <class Engine, class SubDomain>
+ struct NewEngine
+ {
+ };
+ template <class Engine, class SubDomain>
+ struct NewEngineEngine
+ {
+ typedef Engine Type_t;
+ static inline
+ const Engine &apply(const Engine &e, const SubDomain &)
+ {
+ return e;
+ }
+ } ;
+ template <class Engine, class SubDomain>
+ struct NewEngineDomain
+ {
+ typedef SubDomain Type_t;
+ typedef const SubDomain &Return_t;
+ static inline
+ Return_t apply(const Engine &, const SubDomain &i)
+ {
+ return i;
+ }
+ } ;
+ template<class Eng, class Dom>
+ inline typename NewEngineEngine<Eng, Dom>::Type_t
+ newEngineEngine(const Eng &e, const Dom &dom)
+ {
+ return NewEngineEngine<Eng, Dom>::apply(e, dom);
+ }
+ template<class Eng, class Dom>
+ inline typename NewEngineDomain<Eng, Dom>::Type_t
+ newEngineDomain(const Eng &e, const Dom &dom)
+ {
+ return NewEngineDomain<Eng, Dom>::apply(e, dom);
+ }
+ struct EngineConstructTag
+ {
+ EngineConstructTag() { };
+ ~EngineConstructTag() { };
+ EngineConstructTag(const EngineConstructTag &) { };
+ EngineConstructTag &operator=(const EngineConstructTag &) { return *this; }
+ };
+ template<class T>
+ class Scalar
+ {
+ public:
+ inline
+ Scalar() { }
+ inline
+ Scalar(const T &t) : scalar_m(t) { }
+ template<class T1>
+ inline
+ explicit Scalar(const T1 &t) : scalar_m(t) { }
+ template<class Arg>
+ inline
+ Scalar(const Scalar<T> &s, const Arg &)
+ : scalar_m(s.scalar_m) { }
+ template<class Arg1, class Arg2>
+ inline
+ Scalar(const Scalar<T> &s, const Arg1 &, const Arg2 &)
+ : scalar_m(s.scalar_m) { }
+ inline
+ Scalar(const Scalar<T> &s) : scalar_m(s.scalar_m) { }
+ inline
+ const T &value() const { return scalar_m; }
+ inline
+ Scalar<T> &operator=(const Scalar<T> &rhs)
+ {
+ scalar_m = rhs.scalar_m;
+ return *this;
+ }
+ inline
+ Scalar<T> &operator=(const T &rhs)
+ {
+ scalar_m = rhs;
+ return *this;
+ }
+ private:
+ T scalar_m;
+ };
+ template<class T, class Op>
+ struct UnaryReturn {
+ typedef T Type_t;
+ };
+ template<class T1, class T2>
+ struct Promote { typedef T1 Type_t; };
+ template<>
+ struct Promote<bool, bool> {
+ typedef bool Type_t;
+ };
+ template<>
+ struct Promote<bool, char> {
+ typedef char Type_t;
+ };
+ template<>
+ struct Promote<bool, short> {
+ typedef short Type_t;
+ };
+ template<>
+ struct Promote<bool, int> {
+ typedef int Type_t;
+ };
+ template<>
+ struct Promote<bool, long> {
+ typedef long Type_t;
+ };
+ template<>
+ struct Promote<bool, float> {
+ typedef float Type_t;
+ };
+ template<>
+ struct Promote<bool, double> {
+ typedef double Type_t;
+ };
+ template<>
+ struct Promote<char, bool> {
+ typedef char Type_t;
+ };
+ template<>
+ struct Promote<char, char> {
+ typedef char Type_t;
+ };
+ template<>
+ struct Promote<char, short> {
+ typedef short Type_t;
+ };
+ template<>
+ struct Promote<char, int> {
+ typedef int Type_t;
+ };
+ template<>
+ struct Promote<char, long> {
+ typedef long Type_t;
+ };
+ template<>
+ struct Promote<char, float> {
+ typedef float Type_t;
+ };
+ template<>
+ struct Promote<char, double> {
+ typedef double Type_t;
+ };
+ template<>
+ struct Promote<short, bool> {
+ typedef short Type_t;
+ };
+ template<>
+ struct Promote<short, char> {
+ typedef short Type_t;
+ };
+ template<>
+ struct Promote<short, short> {
+ typedef short Type_t;
+ };
+ template<>
+ struct Promote<short, int> {
+ typedef int Type_t;
+ };
+ template<>
+ struct Promote<short, long> {
+ typedef long Type_t;
+ };
+ template<>
+ struct Promote<short, float> {
+ typedef float Type_t;
+ };
+ template<>
+ struct Promote<short, double> {
+ typedef double Type_t;
+ };
+ template<>
+ struct Promote<int, bool> {
+ typedef int Type_t;
+ };
+ template<>
+ struct Promote<int, char> {
+ typedef int Type_t;
+ };
+ template<>
+ struct Promote<int, short> {
+ typedef int Type_t;
+ };
+ template<>
+ struct Promote<int, int> {
+ typedef int Type_t;
+ };
+ template<>
+ struct Promote<int, long> {
+ typedef long Type_t;
+ };
+ template<>
+ struct Promote<int, float> {
+ typedef float Type_t;
+ };
+ template<>
+ struct Promote<int, double> {
+ typedef double Type_t;
+ };
+ template<>
+ struct Promote<long, bool> {
+ typedef long Type_t;
+ };
+ template<>
+ struct Promote<long, char> {
+ typedef long Type_t;
+ };
+ template<>
+ struct Promote<long, short> {
+ typedef long Type_t;
+ };
+ template<>
+ struct Promote<long, int> {
+ typedef long Type_t;
+ };
+ template<>
+ struct Promote<long, long> {
+ typedef long Type_t;
+ };
+ template<>
+ struct Promote<long, float> {
+ typedef float Type_t;
+ };
+ template<>
+ struct Promote<long, double> {
+ typedef double Type_t;
+ };
+ template<>
+ struct Promote<float, bool> {
+ typedef float Type_t;
+ };
+ template<>
+ struct Promote<float, char> {
+ typedef float Type_t;
+ };
+ template<>
+ struct Promote<float, short> {
+ typedef float Type_t;
+ };
+ template<>
+ struct Promote<float, int> {
+ typedef float Type_t;
+ };
+ template<>
+ struct Promote<float, long> {
+ typedef float Type_t;
+ };
+ template<>
+ struct Promote<float, float> {
+ typedef float Type_t;
+ };
+ template<>
+ struct Promote<float, double> {
+ typedef double Type_t;
+ };
+ template<>
+ struct Promote<double, bool> {
+ typedef double Type_t;
+ };
+ template<>
+ struct Promote<double, char> {
+ typedef double Type_t;
+ };
+ template<>
+ struct Promote<double, short> {
+ typedef double Type_t;
+ };
+ template<>
+ struct Promote<double, int> {
+ typedef double Type_t;
+ };
+ template<>
+ struct Promote<double, long> {
+ typedef double Type_t;
+ };
+ template<>
+ struct Promote<double, float> {
+ typedef double Type_t;
+ };
+ template<>
+ struct Promote<double, double> {
+ typedef double Type_t;
+ };
+ template<class T1, class T2, class Op>
+ struct BinaryReturn {
+ typedef typename Promote<T1, T2>::Type_t Type_t;
+ };
+ template<class T1, class T2, class T3, class Op>
+ struct TrinaryReturn {
+ typedef typename BinaryReturn<T2, T3, Op>::Type_t Type_t;
+ };
+ template<class T>
+ struct Reference
+ {
+ typedef T Type_t;
+ inline
+ Reference(const T &reference)
+ : reference_m(reference)
+ { }
+ inline
+ Reference(const Reference<T> &model)
+ : reference_m(model.reference())
+ { }
+ inline
+ const T &reference() const
+ {
+ return reference_m;
+ }
+ operator const T& () const { return reference_m; }
+ operator T& () const { return const_cast<T&>(reference_m); }
+ const T &reference_m;
+ };
+ template<class T>
+ struct DeReference
+ {
+ typedef const T &Return_t;
+ typedef T Type_t;
+ static inline Return_t apply(const T &a) { return a; }
+ };
+ template<class T>
+ struct DeReference<Reference<T> >
+ {
+ typedef const T &Return_t;
+ typedef T Type_t;
+ static inline Return_t apply(const Reference<T> &a) { return a.reference(); }
+ };
+ template<class Op, class Child>
+ class UnaryNode
+ {
+ public:
+ inline
+ typename DeReference<Child>::Return_t
+ child() const { return DeReference<Child>::apply(child_m); }
+ inline
+ UnaryNode(const Child &c)
+ : child_m(c) { }
+ inline
+ UnaryNode(const UnaryNode<Op, Child> &t)
+ : child_m(t.child()) { }
+ template<class OtherChild>
+ inline
+ UnaryNode(const UnaryNode<Op, OtherChild> &t)
+ : child_m(t.child()) { }
+ template<class OtherChild, class Arg>
+ inline
+ UnaryNode(const UnaryNode<Op, OtherChild> &t, const Arg &a)
+ : child_m(t.child(), a) { }
+ template<class OtherChild, class Arg1, class Arg2>
+ inline
+ UnaryNode(const UnaryNode<Op, OtherChild> &t,
+ const Arg1 &a1, const Arg2 &a2)
+ : child_m(t.child(), a1, a2)
+ { }
+ private:
+ Child child_m;
+ };
+ template<class Op, class Left, class Right>
+ class BinaryNode
+ {
+ public:
+ inline
+ typename DeReference<Left>::Return_t
+ left() const { return DeReference<Left>::apply(left_m); }
+ inline
+ typename DeReference<Right>::Return_t
+ right() const { return DeReference<Right>::apply(right_m); }
+ inline
+ BinaryNode(const Left &l, const Right &r)
+ : left_m(l), right_m(r)
+ { }
+ inline
+ BinaryNode(const BinaryNode<Op, Left, Right> &t)
+ : left_m(t.left()), right_m(t.right())
+ { }
+ template<class OtherLeft, class OtherRight>
+ inline
+ BinaryNode(const BinaryNode<Op, OtherLeft, OtherRight> &t)
+ : left_m(t.left()), right_m(t.right())
+ { }
+ template<class OtherLeft, class OtherRight, class Arg>
+ inline
+ BinaryNode(const BinaryNode<Op, OtherLeft, OtherRight> &t,
+ const Arg &a)
+ : left_m(t.left(), a), right_m(t.right(), a)
+ { }
+ template<class OtherLeft, class OtherRight, class Arg1, class Arg2>
+ inline
+ BinaryNode(const BinaryNode<Op, OtherLeft, OtherRight> &t,
+ const Arg1 &a1, const Arg2 &a2)
+ : left_m(t.left(), a1, a2), right_m(t.right(), a1, a2)
+ { }
+ private:
+ Left left_m;
+ Right right_m;
+ };
+ template< class Op, class Left, class Middle, class Right>
+ class TrinaryNode
+ {
+ public:
+ inline
+ typename DeReference<Left>::Return_t
+ left() const { return DeReference<Left>::apply(left_m); }
+ inline
+ typename DeReference<Right>::Return_t
+ right() const { return DeReference<Right>::apply(right_m); }
+ inline
+ typename DeReference<Middle>::Return_t
+ middle() const { return DeReference<Middle>::apply(middle_m); }
+ inline
+ TrinaryNode(const Left &l, const Middle &m, const Right &r)
+ : left_m(l), middle_m(m), right_m(r)
+ { }
+ inline
+ TrinaryNode(const TrinaryNode<Op, Left, Middle, Right> &t)
+ : left_m(t.left()), middle_m(t.middle()), right_m(t.right())
+ { }
+ template<class OtherLeft, class OtherMiddle, class OtherRight>
+ inline
+ TrinaryNode(const TrinaryNode<Op, OtherLeft, OtherMiddle, OtherRight> & t)
+ : left_m(t.left()), middle_m(t.middle()), right_m(t.right())
+ { }
+ template<class OtherLeft, class OtherMiddle, class OtherRight, class Arg>
+ inline
+ TrinaryNode(const TrinaryNode<Op, OtherLeft, OtherMiddle, OtherRight> &t,
+ const Arg &a)
+ : left_m(t.left(), a), middle_m(t.middle(), a), right_m(t.right(), a)
+ { }
+ template<class OtherLeft, class OtherMiddle, class OtherRight,
+ class Arg1, class Arg2>
+ inline
+ TrinaryNode(const TrinaryNode<Op, OtherLeft, OtherMiddle, OtherRight> &t,
+ const Arg1 &a1, const Arg2 &a2)
+ : left_m(t.left(), a1, a2),
+ middle_m(t.middle(), a1, a2) , right_m(t.right(), a1, a2)
+ { }
+ private:
+ Left left_m;
+ Middle middle_m;
+ Right right_m;
+ };
+ struct FnArcCos
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnArcCos >::Type_t
+ operator()(const T &a) const
+ {
+ return (acos(a));
+ }
+ };
+ struct FnArcSin
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnArcSin >::Type_t
+ operator()(const T &a) const
+ {
+ return (asin(a));
+ }
+ };
+ struct FnArcTan
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnArcTan >::Type_t
+ operator()(const T &a) const
+ {
+ return (atan(a));
+ }
+ };
+ struct FnCeil
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnCeil >::Type_t
+ operator()(const T &a) const
+ {
+ return (ceil(a));
+ }
+ };
+ struct FnCos
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnCos >::Type_t
+ operator()(const T &a) const
+ {
+ return (cos(a));
+ }
+ };
+ struct FnHypCos
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnHypCos >::Type_t
+ operator()(const T &a) const
+ {
+ return (cosh(a));
+ }
+ };
+ struct FnExp
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnExp >::Type_t
+ operator()(const T &a) const
+ {
+ return (exp(a));
+ }
+ };
+ struct FnFabs
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnFabs >::Type_t
+ operator()(const T &a) const
+ {
+ return (fabs(a));
+ }
+ };
+ struct FnFloor
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnFloor >::Type_t
+ operator()(const T &a) const
+ {
+ return (floor(a));
+ }
+ };
+ struct FnLog
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnLog >::Type_t
+ operator()(const T &a) const
+ {
+ return (log(a));
+ }
+ };
+ struct FnLog10
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnLog10 >::Type_t
+ operator()(const T &a) const
+ {
+ return (log10(a));
+ }
+ };
+ struct FnSin
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnSin >::Type_t
+ operator()(const T &a) const
+ {
+ return (sin(a));
+ }
+ };
+ struct FnHypSin
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnHypSin >::Type_t
+ operator()(const T &a) const
+ {
+ return (sinh(a));
+ }
+ };
+ struct FnSqrt
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnSqrt >::Type_t
+ operator()(const T &a) const
+ {
+ return (sqrt(a));
+ }
+ };
+ struct FnTan
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnTan >::Type_t
+ operator()(const T &a) const
+ {
+ return (tan(a));
+ }
+ };
+ struct FnHypTan
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnHypTan >::Type_t
+ operator()(const T &a) const
+ {
+ return (tanh(a));
+ }
+ };
+ struct OpUnaryMinus
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, OpUnaryMinus >::Type_t
+ operator()(const T &a) const
+ {
+ return (-a);
+ }
+ };
+ struct OpUnaryPlus
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, OpUnaryPlus >::Type_t
+ operator()(const T &a) const
+ {
+ return (+a);
+ }
+ };
+ struct OpBitwiseNot
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, OpBitwiseNot >::Type_t
+ operator()(const T &a) const
+ {
+ return (~a);
+ }
+ };
+ struct OpIdentity
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, OpIdentity >::Type_t
+ operator()(const T &a) const
+ {
+ return (a);
+ }
+ };
+ struct OpNot
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, OpNot >::Type_t
+ operator()(const T &a) const
+ {
+ return (!a);
+ }
+ };
+ template<class T >
+ struct UnaryReturn<T, OpNot > {
+ typedef bool Type_t;
+ };
+ template <class T1>
+ struct OpCast
+ {
+
+ template<class T2>
+ inline UnaryReturn<T2, OpCast<T1> >
+ operator()(const T2 &a) const
+ {
+ return T1(a);
+ }
+ };
+ template<class T1, class T2>
+ struct UnaryReturn<T2, OpCast<T1> > {
+ typedef T1 Type_t;
+ };
+ struct OpAdd
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpAdd >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a + b);
+ }
+ };
+ struct OpSubtract
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpSubtract >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a - b);
+ }
+ };
+ struct OpMultiply
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpMultiply >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a * b);
+ }
+ };
+ struct OpDivide
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpDivide >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a / b);
+ }
+ };
+ struct OpMod
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpMod >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a % b);
+ }
+ };
+ struct OpBitwiseAnd
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpBitwiseAnd >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a & b);
+ }
+ };
+ struct OpBitwiseOr
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpBitwiseOr >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a | b);
+ }
+ };
+ struct OpBitwiseXor
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpBitwiseXor >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a ^ b);
+ }
+ };
+ struct FnLdexp
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnLdexp >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (ldexp(a,b));
+ }
+ };
+ struct FnPow
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnPow >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (pow(a,b));
+ }
+ };
+ struct FnFmod
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnFmod >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (fmod(a,b));
+ }
+ };
+ struct FnArcTan2
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnArcTan2 >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (atan2(a,b));
+ }
+ };
+ struct OpLT
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpLT >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a < b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpLT > {
+ typedef bool Type_t;
+ };
+ struct OpLE
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpLE >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a <= b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpLE > {
+ typedef bool Type_t;
+ };
+ struct OpGT
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpGT >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a > b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpGT > {
+ typedef bool Type_t;
+ };
+ struct OpGE
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpGE >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a >= b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpGE > {
+ typedef bool Type_t;
+ };
+ struct OpEQ
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpEQ >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a == b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpEQ > {
+ typedef bool Type_t;
+ };
+ struct OpNE
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpNE >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a != b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpNE > {
+ typedef bool Type_t;
+ };
+ struct OpAnd
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpAnd >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a && b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpAnd > {
+ typedef bool Type_t;
+ };
+ struct OpOr
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpOr >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a || b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpOr > {
+ typedef bool Type_t;
+ };
+ struct OpLeftShift
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpLeftShift >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a << b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpLeftShift > {
+ typedef T1 Type_t;
+ };
+ struct OpRightShift
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpRightShift >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a >> b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpRightShift > {
+ typedef T1 Type_t;
+ };
+ struct OpAddAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpAddAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ (const_cast<T1 &>(a) += b); return const_cast<T1 &>(a);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpAddAssign > {
+ typedef T1 &Type_t;
+ };
+ struct OpSubtractAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpSubtractAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ (const_cast<T1 &>(a) -= b); return const_cast<T1 &>(a);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpSubtractAssign > {
+ typedef T1 &Type_t;
+ };
+ struct OpMultiplyAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpMultiplyAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ (const_cast<T1 &>(a) *= b); return const_cast<T1 &>(a);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpMultiplyAssign > {
+ typedef T1 &Type_t;
+ };
+ struct OpDivideAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpDivideAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ (const_cast<T1 &>(a) /= b); return const_cast<T1 &>(a);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpDivideAssign > {
+ typedef T1 &Type_t;
+ };
+ struct OpModAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpModAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ (const_cast<T1 &>(a) %= b); return const_cast<T1 &>(a);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpModAssign > {
+ typedef T1 &Type_t;
+ };
+ struct OpBitwiseOrAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpBitwiseOrAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ (const_cast<T1 &>(a) |= b); return const_cast<T1 &>(a);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpBitwiseOrAssign > {
+ typedef T1 &Type_t;
+ };
+ struct OpBitwiseAndAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpBitwiseAndAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ (const_cast<T1 &>(a) &= b); return const_cast<T1 &>(a);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpBitwiseAndAssign > {
+ typedef T1 &Type_t;
+ };
+ struct OpBitwiseXorAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpBitwiseXorAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ (const_cast<T1 &>(a) ^= b); return const_cast<T1 &>(a);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpBitwiseXorAssign > {
+ typedef T1 &Type_t;
+ };
+ struct OpLeftShiftAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpLeftShiftAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ (const_cast<T1 &>(a) <<= b); return const_cast<T1 &>(a);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpLeftShiftAssign > {
+ typedef T1 &Type_t;
+ };
+ struct OpRightShiftAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpRightShiftAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ (const_cast<T1 &>(a) >>= b); return const_cast<T1 &>(a);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpRightShiftAssign > {
+ typedef T1 &Type_t;
+ };
+ struct OpAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (const_cast<T1 &>(a) = b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpAssign > {
+ typedef T1 &Type_t;
+ };
+ struct FnWhere
+ {
+
+ template<class T1, class T2, class T3>
+ inline typename TrinaryReturn<T1, T2, T3, FnWhere >
+ ::Type_t
+ operator()(T1 &a, const T2 &b, const T3 &c) const
+ {
+ if (a) return b; else return c;
+ }
+ };
+ template<class LeafType, class LeafTag>
+ struct LeafFunctor
+ { };
+ template<class LeafType, class LeafTag>
+ inline
+ typename LeafFunctor<LeafType, LeafTag>::Type_t
+ leafFunctor(const LeafType &leaf, const LeafTag &tag)
+ {
+ return LeafFunctor<LeafType, LeafTag>::apply(leaf, tag);
+ }
+ struct EvalLeaf1
+ {
+ int i1_m;
+ inline EvalLeaf1(int i1) : i1_m(i1) { }
+ inline int val1() const { return i1_m; }
+ };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, EvalLeaf1>
+ {
+ typedef T Type_t;
+ inline static
+ const Type_t &apply(const Scalar<T> &s, const EvalLeaf1 &)
+ {
+ return s.value();
+ }
+ };
+ struct EvalLeaf2
+ {
+ int i1_m, i2_m;
+ inline EvalLeaf2(int i1, int i2) : i1_m(i1), i2_m(i2) { }
+ inline int val1() const { return i1_m; }
+ inline int val2() const { return i2_m; }
+ };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, EvalLeaf2>
+ {
+ typedef T Type_t;
+ inline static
+ const Type_t &apply(const Scalar<T> &s, const EvalLeaf2 &)
+ {
+ return s.value();
+ }
+ };
+ struct EvalLeaf3
+ {
+ int i1_m, i2_m, i3_m;
+ inline EvalLeaf3(int i1, int i2, int i3)
+ : i1_m(i1), i2_m(i2), i3_m(i3) { }
+ inline int val1() const { return i1_m; }
+ inline int val2() const { return i2_m; }
+ inline int val3() const { return i3_m; }
+ };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, EvalLeaf3>
+ {
+ typedef T Type_t;
+ inline static
+ const Type_t &apply(const Scalar<T> &s, const EvalLeaf3 &)
+ {
+ return s.value();
+ }
+ };
+ struct EvalLeaf4
+ {
+ int i1_m, i2_m, i3_m, i4_m;
+ inline EvalLeaf4(int i1, int i2, int i3, int i4)
+ : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4) { }
+ inline int val1() const { return i1_m; }
+ inline int val2() const { return i2_m; }
+ inline int val3() const { return i3_m; }
+ inline int val4() const { return i4_m; }
+ };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, EvalLeaf4>
+ {
+ typedef T Type_t;
+ inline static
+ const Type_t &apply(const Scalar<T> &s, const EvalLeaf4 &)
+ {
+ return s.value();
+ }
+ };
+ struct EvalLeaf5
+ {
+ int i1_m, i2_m, i3_m, i4_m, i5_m;
+ inline EvalLeaf5(int i1, int i2, int i3, int i4, int i5)
+ : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5) { }
+ inline int val1() const { return i1_m; }
+ inline int val2() const { return i2_m; }
+ inline int val3() const { return i3_m; }
+ inline int val4() const { return i4_m; }
+ inline int val5() const { return i5_m; }
+ };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, EvalLeaf5>
+ {
+ typedef T Type_t;
+ inline static
+ const Type_t &apply(const Scalar<T> &s, const EvalLeaf5 &)
+ {
+ return s.value();
+ }
+ };
+ struct EvalLeaf6
+ {
+ int i1_m, i2_m, i3_m, i4_m, i5_m, i6_m;
+ inline EvalLeaf6(int i1, int i2, int i3, int i4, int i5, int i6)
+ : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5), i6_m(i6) { }
+ inline int val1() const { return i1_m; }
+ inline int val2() const { return i2_m; }
+ inline int val3() const { return i3_m; }
+ inline int val4() const { return i4_m; }
+ inline int val5() const { return i5_m; }
+ inline int val6() const { return i6_m; }
+ };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, EvalLeaf6>
+ {
+ typedef T Type_t;
+ inline static
+ const Type_t &apply(const Scalar<T> &s, const EvalLeaf6 &)
+ {
+ return s.value();
+ }
+ };
+ struct EvalLeaf7
+ {
+ int i1_m, i2_m, i3_m, i4_m, i5_m, i6_m, i7_m;
+ inline EvalLeaf7(int i1, int i2, int i3, int i4, int i5, int i6,
+ int i7)
+ : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5), i6_m(i6), i7_m(i7) { }
+ inline int val1() const { return i1_m; }
+ inline int val2() const { return i2_m; }
+ inline int val3() const { return i3_m; }
+ inline int val4() const { return i4_m; }
+ inline int val5() const { return i5_m; }
+ inline int val6() const { return i6_m; }
+ inline int val7() const { return i7_m; }
+ };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, EvalLeaf7>
+ {
+ typedef T Type_t;
+ inline static
+ const Type_t &apply(const Scalar<T> &s, const EvalLeaf7 &)
+ {
+ return s.value();
+ }
+ };
+ struct IncrementLeaf
+ { };
+ template<class T>
+ struct LeafFunctor<T, IncrementLeaf>
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const T &cl, const IncrementLeaf &)
+ {
+ T &l = const_cast<T &>(cl);
+ ++l;
+ return 0;
+ }
+ };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, IncrementLeaf>
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const Scalar<T> &, const IncrementLeaf &)
+ {
+ return 0;
+ }
+ };
+ struct DecrementLeaf
+ { };
+ template<class T>
+ struct LeafFunctor<T, DecrementLeaf>
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const T &cl, const DecrementLeaf &)
+ {
+ T &l = const_cast<T &>(cl);
+ --l;
+ return 0;
+ }
+ };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, DecrementLeaf>
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const Scalar<T> &, const DecrementLeaf &)
+ {
+ return 0;
+ }
+ };
+ struct DereferenceLeaf
+ { };
+ template<class ForwardIterator>
+ struct LeafFunctor<ForwardIterator, DereferenceLeaf>
+ {
+ typedef typename std::iterator_traits<ForwardIterator>::value_type Type_t;
+ inline static
+ Type_t apply(const ForwardIterator &i, const DereferenceLeaf &)
+ {
+ return *i;
+ }
+ };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, DereferenceLeaf>
+ {
+ typedef T Type_t;
+ inline static
+ const Type_t &apply(const Scalar<T> &s, const DereferenceLeaf &)
+ {
+ return s.value();
+ }
+ };
+ template<class A, class Op, class Tag>
+ struct Combine1
+ {
+ typedef A Type_t;
+ inline static
+ Type_t combine(const A &a, const Tag &) { return a; }
+ };
+ template<class A, class B, class Op, class Tag>
+ struct Combine2
+ {
+ };
+ template<class A,class B,class C,class Op,class Tag>
+ struct Combine3
+ {
+ typedef typename Combine2<A, B, Op, Tag>::Type_t Type1_t;
+ typedef typename Combine2<Type1_t, C, Op, Tag>::Type_t Type_t;
+ inline static
+ Type_t combine(const A& a, const B& b, const C& c, const Tag& t)
+ {
+ return
+ Combine2<Type1_t, C,
+ Op, Tag>::combine(Combine2<A, B, Op, Tag>::combine(a,b,t),c,t);
+ }
+ };
+ template<class A, class Op, class Tag>
+ inline typename Combine1<A, Op, Tag>::Type_t
+ peteCombine(const A &a, const Op &, const Tag &t)
+ {
+ return Combine1<A, Op, Tag>::combine(a, t);
+ }
+ template<class A, class B, class Op, class Tag>
+ inline typename Combine2<A, B, Op, Tag>::Type_t
+ peteCombine(const A &a, const B &b, const Op &, const Tag &t)
+ {
+ return Combine2<A, B, Op, Tag>::combine(a, b, t);
+ }
+ template<class A, class B, class C, class Op, class Tag>
+ inline typename Combine3<A, B, C, Op, Tag>::Type_t
+ peteCombine(const A &a, const B &b, const C &c, const Op &, const Tag &t)
+ {
+ return Combine3<A, B, C, Op, Tag>::combine(a, b, c, t);
+ }
+ struct TreeCombine
+ {
+
+ };
+ template<class A, class Op>
+ struct Combine1<A, Op, TreeCombine >
+ {
+ typedef UnaryNode<Op, A> Type_t;
+ inline static
+ Type_t combine(const A &a, const TreeCombine &t)
+ {
+ return Type_t(a);
+ }
+ };
+ template<class A, class B, class Op>
+ struct Combine2<A, B, Op, TreeCombine >
+ {
+ typedef BinaryNode<Op, A, B> Type_t;
+ inline static
+ Type_t combine(const A &a, const B &b, const TreeCombine &t)
+ {
+ return Type_t(a, b);
+ }
+ };
+ template<class A, class B, class C, class Op>
+ struct Combine3<A, B, C, Op, TreeCombine >
+ {
+ typedef TrinaryNode<Op, A, B, C> Type_t;
+ inline static
+ Type_t combine(const A &a, const B &b, const C &c, const TreeCombine &t)
+ {
+ return Type_t(a, b, c);
+ }
+ };
+ struct OpCombine
+ {
+
+ };
+ template<class A,class Op>
+ struct Combine1<A, Op, OpCombine>
+ {
+ typedef typename UnaryReturn<A, Op>::Type_t Type_t;
+ inline static
+ Type_t combine(A a, OpCombine) { return Op()(a); }
+ };
+ template<class A,class B,class Op>
+ struct Combine2<A, B, Op, OpCombine>
+ {
+ typedef typename BinaryReturn<A, B, Op>::Type_t Type_t;
+ inline static
+ Type_t combine(A a, B b, OpCombine)
+ {
+ return Op()(a, b);
+ }
+ };
+ template<class A,class B,class C,class Op>
+ struct Combine3<A, B, C, Op, OpCombine>
+ {
+ typedef typename TrinaryReturn<A, B, C, Op>::Type_t Type_t;
+ inline static
+ Type_t combine(A a, B b, C c, OpCombine)
+ {
+ return Op()(a, b, c);
+ }
+ };
+ struct AndCombine
+ {
+
+ };
+ template<class Op>
+ struct Combine2<bool, bool, Op, AndCombine>
+ {
+ typedef bool Type_t;
+ inline static
+ Type_t combine(bool a, bool b, AndCombine)
+ {
+ return (a && b);
+ }
+ };
+ struct OrCombine
+ {
+
+ };
+ template<class Op>
+ struct Combine2<bool, bool, Op, OrCombine>
+ {
+ typedef bool Type_t;
+ inline static
+ Type_t combine(bool a, bool b, OrCombine)
+ {
+ return (a || b);
+ }
+ };
+ struct NullCombine
+ {
+
+ };
+ template<class Op>
+ struct Combine2<int, int, Op, NullCombine>
+ {
+ typedef int Type_t;
+ inline static
+ Type_t combine(int, int, NullCombine)
+ {
+ return 0;
+ }
+ };
+ struct SumCombine
+ {
+
+ };
+ template<class Op>
+ struct Combine2<int, int, Op, SumCombine>
+ {
+ typedef int Type_t;
+ inline static
+ Type_t combine(int a, int b, SumCombine)
+ {
+ return a + b;
+ }
+ };
+ template<class Expr, class FTag, class CTag>
+ struct ForEach
+ {
+ typedef typename LeafFunctor<Expr, FTag>::Type_t Type_t;
+ inline static
+ Type_t apply(const Expr &expr, const FTag &f, const CTag &)
+ {
+ return LeafFunctor<Expr, FTag>::apply(expr, f);
+ }
+ };
+ template<class Expr, class FTag, class CTag>
+ inline typename ForEach<Expr,FTag,CTag>::Type_t
+ forEach(const Expr &e, const FTag &f, const CTag &c)
+ {
+ return ForEach<Expr, FTag, CTag>::apply(e, f, c);
+ }
+ template<class Op, class A, class FTag, class CTag>
+ struct ForEach<UnaryNode<Op, A>, FTag, CTag>
+ {
+ typedef typename ForEach<A, FTag, CTag>::Type_t TypeA_t;
+ typedef typename Combine1<TypeA_t, Op, CTag>::Type_t Type_t;
+ inline static
+ Type_t apply(const UnaryNode<Op, A> &expr, const FTag &f,
+ const CTag &c)
+ {
+ return Combine1<TypeA_t, Op, CTag>::
+ combine(ForEach<A, FTag, CTag>::apply(expr.child(), f, c), c);
+ }
+ };
+ template<class Op, class A, class B, class FTag, class CTag>
+ struct ForEach<BinaryNode<Op, A, B>, FTag, CTag >
+ {
+ typedef typename ForEach<A, FTag, CTag>::Type_t TypeA_t;
+ typedef typename ForEach<B, FTag, CTag>::Type_t TypeB_t;
+ typedef typename Combine2<TypeA_t, TypeB_t, Op, CTag>::Type_t Type_t;
+ inline static
+ Type_t apply(const BinaryNode<Op, A, B> &expr, const FTag &f,
+ const CTag &c)
+ {
+ return Combine2<TypeA_t, TypeB_t, Op, CTag>::
+ combine(ForEach<A, FTag, CTag>::apply(expr.left(), f, c),
+ ForEach<B, FTag, CTag>::apply(expr.right(), f, c),
+ c);
+ }
+ };
+ template<class Op, class A, class B, class C, class FTag, class CTag>
+ struct ForEach<TrinaryNode<Op, A, B, C>, FTag, CTag >
+ {
+ typedef typename ForEach<A, FTag, CTag>::Type_t TypeA_t;
+ typedef typename ForEach<B, FTag, CTag>::Type_t TypeB_t;
+ typedef typename ForEach<C, FTag, CTag>::Type_t TypeC_t;
+ typedef typename Combine3<TypeA_t, TypeB_t, TypeC_t, Op, CTag>::Type_t
+ Type_t;
+ inline static
+ Type_t apply(const TrinaryNode<Op, A, B, C> &expr, const FTag &f,
+ const CTag &c)
+ {
+ return Combine3<TypeA_t, TypeB_t, TypeC_t, Op, CTag>::
+ combine(ForEach<A, FTag, CTag>::apply(expr.left(), f, c),
+ ForEach<B, FTag, CTag>::apply(expr.middle(), f, c),
+ ForEach<C, FTag, CTag>::apply(expr.right(), f, c),
+ c);
+ }
+ };
+ template<class T> class Expression;
+ template<class T, class FTag, class CTag>
+ struct ForEach<Expression<T>, FTag, CTag>
+ {
+ typedef typename ForEach<T, FTag, CTag>::Type_t Type_t;
+ inline static
+ Type_t apply(const Expression<T> &expr, const FTag &f,
+ const CTag &c)
+ {
+ return ForEach<T, FTag, CTag>::apply(expr.expression(), f, c);
+ }
+ };
+ template<class T> struct Reference;
+ template<class T, class FTag, class CTag>
+ struct ForEach<Reference<T>, FTag, CTag>
+ {
+ typedef typename ForEach<T, FTag, CTag>::Type_t Type_t;
+ inline static
+ Type_t apply(const Reference<T> &ref, const FTag &f,
+ const CTag &c)
+ {
+ return ForEach<T, FTag, CTag>::apply(ref.reference(), f, c);
+ }
+ };
+ template<class T>
+ class Expression
+ {
+ public:
+ typedef T Expression_t;
+ Expression(const T& expr) : expr_m(expr)
+ { }
+ const Expression_t& expression() const
+ {
+ return expr_m;
+ }
+ private:
+ T expr_m;
+ };
+ template<class T>
+ struct CreateLeaf
+ {
+ typedef Scalar<T> Leaf_t;
+ inline static
+ Leaf_t make(const T &a)
+ {
+ return Scalar<T>(a);
+ }
+ };
+ template<class T>
+ struct CreateLeaf<Expression<T> >
+ {
+ typedef typename Expression<T>::Expression_t Leaf_t;
+ inline static
+ const Leaf_t &make(const Expression<T> &a)
+ {
+ return a.expression();
+ }
+ };
+ template<class T>
+ struct MakeReturn
+ {
+ typedef Expression<T> Expression_t;
+ inline static
+ Expression_t make(const T &a) { return Expression_t(a); }
+ };
+ struct ErrorType
+ {
+ };
+ template<class Expr, class FTag, class CTag>
+ struct ForEachRef
+ {
+ typedef typename LeafFunctor<Expr, FTag>::Type_t Type_t;
+ inline static
+ const Type_t &apply(const Expr &expr, const FTag &f, const CTag &)
+ {
+ return LeafFunctor<Expr, FTag>::apply(expr, f);
+ }
+ };
+ template<class Expr, class FTag, class CTag>
+ inline const typename ForEachRef<Expr,FTag,CTag>::Type_t &
+ forEachRef(const Expr &e, const FTag &f, const CTag &c)
+ {
+ return ForEachRef<Expr, FTag, CTag>::apply(e, f, c);
+ }
+ template<class Op, class A, class FTag, class CTag>
+ struct ForEachRef<UnaryNode<Op, A>, FTag, CTag>
+ {
+ typedef typename ForEachRef<A, FTag, CTag>::Type_t TypeA_t;
+ typedef typename Combine1<TypeA_t, Op, CTag>::Type_t Type_t;
+ inline static
+ const Type_t &apply(const UnaryNode<Op, A> &expr, const FTag &f,
+ const CTag &c)
+ {
+ return Combine1<TypeA_t, Op, CTag>::
+ combine(ForEachRef<A, FTag, CTag>::apply(expr.child(), f, c),
+ c);
+ }
+ };
+ template<class Op, class A, class B, class FTag, class CTag>
+ struct ForEachRef<BinaryNode<Op, A, B>, FTag, CTag >
+ {
+ typedef typename ForEachRef<A, FTag, CTag>::Type_t TypeA_t;
+ typedef typename ForEachRef<B, FTag, CTag>::Type_t TypeB_t;
+ typedef typename Combine2<TypeA_t, TypeB_t, Op, CTag>::Type_t Type_t;
+ inline static
+ const Type_t &apply(const BinaryNode<Op, A, B> &expr, const FTag &f,
+ const CTag &c)
+ {
+ return Combine2<TypeA_t, TypeB_t, Op, CTag>::
+ combine(ForEachRef<A, FTag, CTag>::apply(expr.left(), f, c),
+ ForEachRef<B, FTag, CTag>::apply(expr.right(), f, c),
+ c);
+ }
+ };
+ template<class Op, class A, class B, class C, class FTag, class CTag>
+ struct ForEachRef<TrinaryNode<Op, A, B, C>, FTag, CTag >
+ {
+ typedef typename ForEachRef<A, FTag, CTag>::Type_t TypeA_t;
+ typedef typename ForEachRef<B, FTag, CTag>::Type_t TypeB_t;
+ typedef typename ForEachRef<C, FTag, CTag>::Type_t TypeC_t;
+ typedef typename Combine3<TypeA_t, TypeB_t, TypeC_t, Op, CTag>::Type_t
+ Type_t;
+ inline static
+ const Type_t &apply(const TrinaryNode<Op, A, B, C> &expr, const FTag &f,
+ const CTag &c)
+ {
+ return Combine3<TypeA_t, TypeB_t, TypeC_t, Op, CTag>::
+ combine(ForEachRef<A, FTag, CTag>::apply(expr.left(), f, c),
+ ForEachRef<B, FTag, CTag>::apply(expr.middle(), f, c),
+ ForEachRef<C, FTag, CTag>::apply(expr.right(), f, c),
+ c);
+ }
+ };
+ template<class T, class FTag, class CTag>
+ struct ForEachRef<Expression<T>, FTag, CTag>
+ {
+ typedef typename ForEachRef<T, FTag, CTag>::Type_t Type_t;
+ inline static
+ const Type_t &apply(const Expression<T> &expr, const FTag &f,
+ const CTag &c)
+ {
+ return ForEachRef<T, FTag, CTag>::apply(expr.expression(), f, c);
+ }
+ };
+ template<class T, class FTag, class CTag>
+ struct ForEachRef<Reference<T>, FTag, CTag>
+ {
+ typedef typename ForEachRef<T, FTag, CTag>::Type_t Type_t;
+ inline static
+ const Type_t &apply(const Reference<T> &ref, const FTag &f,
+ const CTag &c)
+ {
+ return ForEachRef<T, FTag, CTag>::apply(ref.reference(), f, c);
+ }
+ };
+ template<int Integer> class WrappedInt
+ {
+ public:
+ enum { val = Integer };
+
+ };
+ template<int Dim, class T, class EngineTag> class Engine;
+ template<class Eng, class Tag>
+ struct EngineFunctorDefault
+ { };
+ template<class Eng, class Tag>
+ struct EngineFunctor
+ {
+ typedef typename EngineFunctorDefault<Eng,Tag>::Type_t Type_t;
+ inline static
+ Type_t apply(const Eng &e, const Tag &t)
+ {
+ return EngineFunctorDefault<Eng,Tag>::apply(e,t);
+ }
+ };
+ template<class Eng, class Tag>
+ inline typename EngineFunctor<Eng,Tag>::Type_t
+ engineFunctor(const Eng &e, const Tag &tag)
+ {
+ return EngineFunctor<Eng,Tag>::apply(e,tag);
+ }
+ template<class T, class Tag>
+ struct EngineFunctorScalar
+ { };
+ template<class Tag>
+ struct EngineView;
+ template<class Node, class Tag>
+ struct LeafFunctor<Node, EngineView<Tag> >
+ {
+ };
+ template<class T, class Tag>
+ struct LeafFunctor<Scalar<T>, EngineView<Tag> >
+ {
+ typedef Scalar<T> Type_t;
+ static inline
+ Type_t apply(const Scalar<T> &s, const EngineView<Tag> &)
+ {
+ return s;
+ }
+ };
+ template<class Engine, class Tag>
+ struct DefaultEngineView;
+ template<int Dim, class T, class E, class Tag>
+ struct LeafFunctor<Engine<Dim, T, E>, EngineView<Tag> >
+ {
+ typedef Engine<Dim, T, E> Subject_t;
+ typedef DefaultEngineView<Subject_t, Tag> EngineView_t;
+ typedef typename EngineView_t::Type_t Type_t;
+ static inline
+ Type_t apply(const Subject_t &engine,
+ const EngineView<Tag> &tag)
+ {
+ return EngineView_t::apply(engine, tag);
+ }
+ };
+ template<class Tag>
+ struct ExpressionApply
+ {
+ inline
+ ExpressionApply(const Tag &tag)
+ : tag_m(tag)
+ {
+ }
+ template<class A>
+ void operator()(const A &a) const
+ {
+ forEach(a, *this, NullCombine());
+ }
+ const Tag &tag() const { return tag_m; }
+ const Tag &tag_m;
+ };
+ template<class A, class Tag>
+ inline void
+ expressionApply(const A &a, const Tag &tag)
+ {
+ forEach(a, ExpressionApply<Tag>(tag), NullCombine());
+ }
+ template<class Node, class Tag>
+ struct LeafFunctor<Node, ExpressionApply<Tag> >
+ {
+ };
+ template<class T, class Tag>
+ struct LeafFunctor<Scalar<T>, ExpressionApply<Tag> >
+ {
+ typedef int Type_t;
+ static inline
+ Type_t apply(const Scalar<T> &, const ExpressionApply<Tag> &)
+ {
+ return 0;
+ }
+ };
+ template<class Engine, class Tag>
+ struct DefaultExpressionApply;
+ template<int Dim, class T, class E, class Tag>
+ struct LeafFunctor<Engine<Dim, T, E>, ExpressionApply<Tag> >
+ {
+ typedef Engine<Dim, T, E> Subject_t;
+ typedef DefaultExpressionApply<Subject_t, Tag> ExpressionApply_t;
+ typedef int Type_t;
+ static inline
+ Type_t apply(const Subject_t &engine,
+ const ExpressionApply<Tag> &tag)
+ {
+ return ExpressionApply_t::apply(engine, tag);
+ }
+ };
+ namespace Pooma {
+ class NoInit
+ {
+ public:
+
+ };
+ }
+ template <class T> class DomainTraits;
+ template <class T>
+ struct SizeTypePromotion
+ {
+ typedef T Type_t;
+ };
+ template <>
+ struct SizeTypePromotion<int>
+ {
+ typedef long Type_t;
+ };
+ template <>
+ struct SizeTypePromotion<float>
+ {
+ typedef double Type_t;
+ };
+ template <int I>
+ struct Dom1Initialize {
+ template <class DT>
+ static inline void apply(typename DT::Storage_t& s)
+ {
+ Dom1Initialize<I-1>::template apply<DT>(s);
+ DomainTraits<typename DT::OneDomain_t>::initializeStorage(s[I].storage());
+ }
+ };
+ template <>
+ struct Dom1Initialize<0> {
+ template <class DT>
+ static inline void apply(typename DT::Storage_t& s)
+ {
+ DomainTraits<typename DT::OneDomain_t>::initializeStorage(s[0].storage());
+ }
+ };
+ template <class Domain>
+ struct WrapNoInit : public Domain
+ {
+ WrapNoInit() : Domain(Pooma::NoInit()) {}
+ };
+ template<class DomT, class T, int Dim>
+ struct DomainTraitsDomain
+ {
+ typedef typename SizeTypePromotion<T>::Type_t Size_t;
+ typedef T Element_t;
+ typedef DomT Domain_t;
+ typedef DomT NewDomain1_t;
+ enum { domain = true };
+ enum { dimensions = Dim };
+ static bool getIgnorable(const Domain_t &, int) { return false; }
+ };
+ template<class DomT, class T>
+ struct DomainTraitsDomain<DomT, T, 1>
+ {
+ typedef typename SizeTypePromotion<T>::Type_t Size_t;
+ typedef T Element_t;
+ typedef DomT Domain_t;
+ typedef DomT NewDomain1_t;
+ enum { domain = true };
+ enum { dimensions = 1 };
+ inline
+ static Element_t getFirst(const Domain_t &d) { return d.first(); }
+ inline
+ static Element_t getLast(const Domain_t &d) { return d.last(); }
+ inline
+ static Element_t getStride(const Domain_t &d) { return d.stride(); }
+ inline
+ static Size_t getLength(const Domain_t &d) { return d.length(); }
+ inline
+ static Size_t getSize(const Domain_t &d) { return d.size(); }
+ inline
+ static Element_t getMin(const Domain_t &d) { return d.min(); }
+ inline
+ static Element_t getMax(const Domain_t &d) { return d.max(); }
+ inline
+ static bool getEmpty(const Domain_t &d) { return d.empty(); }
+ inline
+ static int getLoop(const Domain_t &d) { return d.loop(); }
+ inline
+ static Element_t getElem(const Domain_t &d, int n) { return d.elem(n); }
+ inline
+ static bool getIgnorable(const Domain_t &, int) { return false; }
+ };
+ template<class DomT, class T, class NewDom1T>
+ struct DomainTraitsScalar
+ {
+ typedef DomT Domain_t;
+ typedef DomT OneDomain_t;
+ typedef NewDom1T NewDomain1_t;
+ typedef T PointDomain_t;
+ typedef T Element_t;
+ typedef int Size_t;
+ enum { domain = false };
+ enum { dimensions = 1,
+ sliceDimensions = 0 };
+ enum { loopAware = false };
+ enum { singleValued = true };
+ enum { unitStride = true };
+ enum { wildcard = false };
+ inline
+ static OneDomain_t getDomain(T d, int) { return OneDomain_t(d); }
+ inline
+ static PointDomain_t getPointDomain(T d, int) { return d; }
+ inline
+ static Element_t getFirst(const Element_t &d) { return d; }
+ inline
+ static Element_t getLast(const Element_t &d) { return d; }
+ inline
+ static int getStride(const Element_t &) { return 1; }
+ inline
+ static Size_t getLength(const Element_t &) { return 1; }
+ inline
+ static Size_t getSize(const Element_t &d) { return 1; }
+ inline
+ static Element_t getMin(const Element_t &d) { return d; }
+ inline
+ static Element_t getMax(const Element_t &d) { return d; }
+ inline
+ static bool getEmpty(const Element_t &) { return false; }
+ inline
+ static int getLoop(const Element_t &) { return 0; }
+ inline
+ static Element_t getElem(const Element_t &d, int) { return d; }
+ };
+ template<class T>
+ struct DomainTraits : public DomainTraitsScalar<T, T, T>
+ {
+ typedef DomainTraitsScalar<T, T, T> Base_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef typename Base_t::OneDomain_t OneDomain_t;
+ typedef typename Base_t::NewDomain1_t NewDomain1_t;
+ typedef typename Base_t::PointDomain_t PointDomain_t;
+ typedef typename Base_t::Element_t Element_t;
+ typedef typename Base_t::Size_t Size_t;
+ enum { domain = Base_t::domain };
+ enum { dimensions = Base_t::dimensions,
+ sliceDimensions = Base_t::sliceDimensions };
+ enum { loopAware = Base_t::loopAware };
+ enum { singleValued = Base_t::singleValued };
+ enum { unitStride = Base_t::unitStride };
+ enum { wildcard = Base_t::wildcard };
+ };
+ template<class T, int Dim>
+ struct DomainChangeDim {
+ typedef T OldType_t;
+ typedef T NewType_t;
+ enum { oldDim = Dim,
+ newDim = Dim };
+ };
+ template <class Dom, class Storage, class T1, class T2>
+ inline void
+ setDomain(const Dom&, Storage& data, const T1& beg, const T2& end) {
+ DomainTraits<Dom>::setDomain(data, beg, end);
+ }
+ template <int Dim> class Interval;
+ template <> class Interval<1>;
+ template <int Dim> class Loc;
+ template <> class Loc<1>;
+ template<>
+ struct DomainTraits<char>
+ : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
+ template<>
+ struct DomainTraits<unsigned char>
+ : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
+ template<>
+ struct DomainTraits<short>
+ : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
+ template<>
+ struct DomainTraits<unsigned short>
+ : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
+ template<>
+ struct DomainTraits<int>
+ : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
+ template<>
+ struct DomainTraits<unsigned int>
+ : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
+ template<>
+ struct DomainTraits<long>
+ : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
+ template<>
+ struct DomainTraits<unsigned long>
+ : public DomainTraitsScalar<Interval<1>, int, Loc<1> > { };
+ template<class T1, class T2, bool strided>
+ struct ContainsDomainSingle {
+ static bool contains(const T1 &a, const T2 &b) {
+ return (a.min() <= b.min() && a.max() >= b.max());
+ }
+ };
+ template<class T1, class T2>
+ struct ContainsDomainSingle<T1,T2,true> {
+ static bool contains(const T1 &a, const T2 &b) {
+ typedef typename DomainTraits<T1>::Element_t E1_t;
+ typedef typename DomainTraits<T2>::Element_t E2_t;
+ E1_t a0 = a.min();
+ E1_t a1 = a.max();
+ E1_t s = a.stride();
+ E2_t b0 = b.min();
+ E2_t b1 = b.max();
+ E2_t t = b.stride();
+ if (s < 0)
+ s = -s;
+ if (t < 0)
+ t = -t;
+ bool quicktest = (a0 <= b0 && a1 >= b1);
+ if (!quicktest || s == 1)
+ return quicktest;
+ return (t % s == 0) && ((b0-a0) % s == 0) && ((a1-b1) % s == 0);
+ }
+ };
+ template<class T1, class T2, int Dim>
+ struct ContainsDomain {
+ enum { strided = !DomainTraits<T1>::unitStride };
+ enum { n = Dim - 1 };
+ static bool contains(const T1 &a, const T2 &b) {
+ typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
+ typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
+ return ContainsDomainSingle<Dom1_t,Dom2_t,strided>::contains(
+ DomainTraits<T1>::getDomain(a,n), DomainTraits<T2>::getDomain(b,n)) &&
+ ContainsDomain<T1,T2,n>::contains(a,b);
+ }
+ };
+ template<class T1, class T2>
+ struct ContainsDomain<T1,T2,1> {
+ enum { strided = !DomainTraits<T1>::unitStride };
+ static bool contains(const T1 &a, const T2 &b) {
+ typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
+ typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
+ return ContainsDomainSingle<Dom1_t,Dom2_t,strided>::contains(
+ DomainTraits<T1>::getDomain(a,0), DomainTraits<T2>::getDomain(b,0));
+ }
+ };
+ template<class T1, class T2>
+ inline bool contains(const T1 &a, const T2 &b)
+ {
+ PoomaCTAssert<((int)DomainTraits<T1>::dimensions == DomainTraits<T2>::dimensions)>::test();
+ return ContainsDomain<T1,T2,DomainTraits<T1>::dimensions>::contains(a, b);
+ }
+ template<int Dim>
+ class Loc;
+ template<int Dim>
+ class Interval;
+ template<int Dim>
+ class Range;
+ template<class T>
+ class IndirectionList;
+ template<int Dim>
+ class Grid;
+ template<class T1,class T2 >
+ struct DomainArithOpsTraits
+ {
+ };
+ template <>
+ struct DomainArithOpsTraits< Loc<1> , Loc<1> >
+ {
+ typedef Loc<1> AddResult_t;
+ typedef Loc<1> SubResult_t;
+ typedef Loc<1> MultResult_t;
+ };
+ template<int Dim>
+ struct DomainArithOpsTraits<Loc<1> , Loc<Dim> >
+ {
+ typedef Loc<Dim> AddResult_t;
+ typedef Loc<Dim> SubResult_t;
+ typedef Loc<Dim> MultResult_t;
+ };
+ template<int Dim>
+ struct DomainArithOpsTraits<Loc<Dim> , Loc<1> >
+ {
+ typedef Loc<Dim> AddResult_t;
+ typedef Loc<Dim> SubResult_t;
+ typedef Loc<Dim> MultResult_t;
+ };
+ template<int Dim,int Dim2>
+ struct DomainArithOpsTraits<Loc<Dim> , Loc<Dim2> >
+ {
+ typedef Loc<Dim> AddResult_t;
+ typedef Loc<Dim> SubResult_t;
+ typedef Loc<Dim> MultResult_t;
+ };
+ template<int Dim>
+ struct DomainArithOpsTraits<Loc<1> , Interval<Dim> >
+ {
+ typedef Interval<Dim> AddResult_t;
+ typedef Range<Dim> SubResult_t;
+ typedef Range<Dim> MultResult_t;
+ };
+ template<int Dim>
+ struct DomainArithOpsTraits<Interval<Dim>, Loc<1> >
+ {
+ typedef Interval<Dim> AddResult_t;
+ typedef Interval<Dim> SubResult_t;
+ typedef Range<Dim> MultResult_t;
+ };
+ template<int Dim,int Dim2>
+ struct DomainArithOpsTraits<Loc<Dim> , Interval<Dim2> >
+ {
+ typedef Interval<Dim> AddResult_t;
+ typedef Range<Dim> SubResult_t;
+ typedef Range<Dim> MultResult_t;
+ };
+ template<int Dim,int Dim2>
+ struct DomainArithOpsTraits<Interval<Dim>, Loc<Dim2> >
+ {
+ typedef Interval<Dim> AddResult_t;
+ typedef Interval<Dim> SubResult_t;
+ typedef Range<Dim> MultResult_t;
+ };
+ template<int Dim>
+ struct DomainArithOpsTraits<Loc<1> , Range<Dim> >
+ {
+ typedef Range<Dim> AddResult_t;
+ typedef Range<Dim> SubResult_t;
+ typedef Range<Dim> MultResult_t;
+ };
+ template<int Dim>
+ struct DomainArithOpsTraits<Range<Dim>, Loc<1> >
+ {
+ typedef Range<Dim> AddResult_t;
+ typedef Range<Dim> SubResult_t;
+ typedef Range<Dim> MultResult_t;
+ };
+ template<int Dim,int Dim2>
+ struct DomainArithOpsTraits<Loc<Dim> , Range<Dim2> >
+ {
+ typedef Range<Dim> AddResult_t;
+ typedef Range<Dim> SubResult_t;
+ typedef Range<Dim> MultResult_t;
+ };
+ template<int Dim,int Dim2>
+ struct DomainArithOpsTraits<Range<Dim>, Loc<Dim2> >
+ {
+ typedef Range<Dim> AddResult_t;
+ typedef Range<Dim> SubResult_t;
+ typedef Range<Dim> MultResult_t;
+ };
+ template< >
+ struct DomainArithOpsTraits<Loc<1> , IndirectionList<int> >
+ {
+ typedef IndirectionList<int> AddResult_t;
+ typedef IndirectionList<int> SubResult_t;
+ typedef IndirectionList<int> MultResult_t;
+ };
+ template< >
+ struct DomainArithOpsTraits<IndirectionList<int>, Loc<1> >
+ {
+ typedef IndirectionList<int> AddResult_t;
+ typedef IndirectionList<int> SubResult_t;
+ typedef IndirectionList<int> MultResult_t;
+ };
+ template<int Dim>
+ struct DomainArithOpsTraits<Loc<1> , Grid<Dim> >
+ {
+ typedef Grid<Dim> AddResult_t;
+ typedef Grid<Dim> SubResult_t;
+ typedef Grid<Dim> MultResult_t;
+ };
+ template<int Dim>
+ struct DomainArithOpsTraits<Grid<Dim>, Loc<1> >
+ {
+ typedef Grid<Dim> AddResult_t;
+ typedef Grid<Dim> SubResult_t;
+ typedef Grid<Dim> MultResult_t;
+ };
+ template<int Dim,int Dim2>
+ struct DomainArithOpsTraits<Loc<Dim> , Grid<Dim2> >
+ {
+ typedef Grid<Dim> AddResult_t;
+ typedef Grid<Dim> SubResult_t;
+ typedef Grid<Dim> MultResult_t;
+ };
+ template<int Dim,int Dim2>
+ struct DomainArithOpsTraits<Grid<Dim>, Loc<Dim2> >
+ {
+ typedef Grid<Dim> AddResult_t;
+ typedef Grid<Dim> SubResult_t;
+ typedef Grid<Dim> MultResult_t;
+ };
+ template <class Dom>
+ class DomainIterator
+ {
+ public:
+ typedef DomainIterator<Dom> This_t;
+ typedef Dom Domain_t;
+ typedef typename Domain_t::AskDomain_t Value_t;
+ typedef std::input_iterator_tag iterator_category;
+ typedef Value_t value_type;
+ typedef ptrdiff_t difference_type;
+ typedef const Value_t* pointer;
+ typedef const Value_t& reference;
+ enum { dimensions = DomainTraits<Dom>::dimensions };
+ DomainIterator(const Dom &d, int size = 0)
+ : domain_m(d), loc_m(d.firsts()), index_m(domain_m.size()-size)
+ {
+ ;
+ for (int i=0; i < dimensions; ++i)
+ current_m[i] = 0;
+ }
+ DomainIterator(const This_t &model)
+ : domain_m(model.domain_m), loc_m(model.loc_m), index_m(model.index_m)
+ {
+ ;
+ for (int i=0; i < dimensions; ++i)
+ current_m[i] = model.current_m[i];
+ }
+ DomainIterator()
+ : index_m(0)
+ {
+ for (int i=0; i < dimensions; ++i)
+ current_m[i] = 0;
+ }
+ inline const Value_t &operator*() const
+ {
+ ;
+ return loc_m;
+ }
+ inline const Value_t *operator->() const
+ {
+ ;
+ return &loc_m;
+ }
+ inline bool operator==(const This_t &rhs) const
+ {
+ return (index_m == rhs.index_m);
+ }
+ inline bool operator!=(const This_t &rhs) const
+ {
+ return (index_m != rhs.index_m);
+ }
+ bool done() const
+ {
+ return (index_m == 0);
+ }
+ This_t &operator=(const This_t &model)
+ {
+ index_m = model.index_m;
+ domain_m = model.domain_m;
+ loc_m = model.loc_m;
+ for (int i=0; i < dimensions; ++i)
+ current_m[i] = model.current_m[i];
+ return *this;
+ }
+ This_t &operator++()
+ {
+ increment(WrappedInt<Domain_t::unitStride>());
+ return *this;
+ }
+ This_t operator++(int)
+ {
+ DomainIterator<Dom> save(*this);
+ increment(WrappedInt<Domain_t::unitStride>());
+ return save;
+ }
+ private:
+ Domain_t domain_m;
+ Value_t loc_m;
+ int current_m[dimensions];
+ int index_m;
+ void increment(const WrappedInt<true>&)
+ {
+ ;
+ --index_m;
+ ++(current_m[0]);
+ ++loc_m[0];
+ if (__builtin_expect(current_m[0] < domain_m[0].length(), 1))
+ return;
+ for (int i = 1; i < dimensions; ++i)
+ {
+ current_m[i-1] = 0;
+ loc_m[i-1] = domain_m[i-1].first();
+ ++(current_m[i]);
+ ++loc_m[i];
+ if (__builtin_expect(current_m[i] < domain_m[i].length(), 1))
+ return;
+ }
+ }
+ void increment(const WrappedInt<false>&)
+ {
+ ;
+ --index_m;
+ ++(current_m[0]);
+ if (__builtin_expect(current_m[0] < domain_m[0].length(), 1)) {
+ loc_m[0] = domain_m[0](current_m[0]);
+ return;
+ }
+ for (int i = 1; i < dimensions; ++i)
+ {
+ current_m[i-1] = 0;
+ loc_m[i-1] = domain_m[i-1].first();
+ ++(current_m[i]);
+ if (__builtin_expect(current_m[i] < domain_m[i].length(), 1)) {
+ loc_m[i] = domain_m[i](current_m[i]);
+ return;
+ }
+ }
+ }
+ };
+ template <class Dom>
+ class DomainBlockIterator
+ {
+ public:
+ typedef DomainBlockIterator<Dom> This_t;
+ typedef Dom Domain_t;
+ typedef typename Domain_t::OneDomain_t OneDomain_t;
+ typedef typename Domain_t::AskDomain_t Value_t;
+ typedef typename Domain_t::BlockDomain_t Block_t;
+ typedef typename Block_t::OneDomain_t OneBlock_t;
+ typedef typename OneDomain_t::iterator iterator;
+ typedef typename Domain_t::Element_t Element_t;
+ enum { dimensions = DomainTraits<Dom>::dimensions };
+ DomainBlockIterator()
+ : index_m(-1)
+ {
+ }
+ DomainBlockIterator(const Dom &d);
+ DomainBlockIterator(const This_t &model);
+ ~DomainBlockIterator()
+ {
+ }
+ inline const Block_t &operator*() const
+ {
+ ;
+ return block_m;
+ }
+ inline const Block_t *operator->() const
+ {
+ ;
+ return block_m;
+ }
+ inline const Value_t &point() const
+ {
+ ;
+ return loc_m;
+ }
+ inline int index() const
+ {
+ ;
+ return index_m;
+ }
+ inline bool operator==(const This_t &rhs) const
+ {
+ if (done() || rhs.done())
+ return (done() && rhs.done());
+ else
+ return (block_m == *rhs);
+ }
+ inline bool operator!=(const This_t &rhs) const
+ {
+ return !(operator==(rhs));
+ }
+ bool done() const
+ {
+ return (index_m < 0);
+ }
+ This_t &operator=(const This_t &model)
+ {
+ domain_m = model.domain_m;
+ loc_m = model.loc_m;
+ block_m = model.block_m;
+ index_m = model.index_m;
+ for (int i=0; i < dimensions; ++i)
+ current_m[i] = model.current_m[i];
+ return *this;
+ }
+ This_t &operator++()
+ {
+ increment();
+ return *this;
+ }
+ This_t operator++(int)
+ {
+ This_t save(*this);
+ increment();
+ return save;
+ }
+ private:
+ Domain_t domain_m;
+ iterator current_m[dimensions];
+ Value_t loc_m;
+ Block_t block_m;
+ int index_m;
+ void setDone()
+ {
+ index_m = (-1);
+ }
+ void increment();
+ };
+ template<class Dom>
+ DomainBlockIterator<Dom>::DomainBlockIterator(const Dom &d)
+ : domain_m(d), loc_m(0), index_m(0)
+ {
+ for (int i=0; i < dimensions; ++i)
+ {
+ if (d[i].begin() == d[i].end())
+ {
+ setDone();
+ break;
+ }
+ else
+ {
+ current_m[i] = d[i].begin();
+ iterator next = current_m[i];
+ Element_t a, b;
+ if (++next == d[i].end())
+ {
+ a = b = (*(current_m[i])).first();
+ }
+ else
+ {
+ a = (*(current_m[i])).first();
+ b = (*next).first();
+ }
+ if (b < a)
+ block_m[i] = OneBlock_t(b + 1, a);
+ else if (b == a)
+ block_m[i] = OneBlock_t(a, a);
+ else
+ block_m[i] = OneBlock_t(a, b - 1);
+ }
+ }
+ }
+ template<class Dom>
+ DomainBlockIterator<Dom>::DomainBlockIterator(const This_t &model)
+ : domain_m(model.domain_m), loc_m(model.loc_m),
+ block_m(model.block_m), index_m(model.index_m)
+ {
+ for (int i=0; i < dimensions; ++i)
+ current_m[i] = model.current_m[i];
+ }
+ template<class Dom>
+ void DomainBlockIterator<Dom>::increment()
+ {
+ ;
+ for (int i = 0; i < dimensions; ++i)
+ {
+ if (++(current_m[i]) == domain_m[i].end())
+ {
+ if (i >= dimensions-1)
+ {
+ setDone();
+ break;
+ }
+ }
+ else
+ {
+ iterator next = current_m[i];
+ if (++next == domain_m[i].end())
+ {
+ if (i < dimensions-1)
+ {
+ current_m[i] = domain_m[i].begin();
+ next = current_m[i];
+ Element_t a, b;
+ if (++next == domain_m[i].end())
+ {
+ a = b = (*(current_m[i])).first();
+ }
+ else
+ {
+ a = (*(current_m[i])).first();
+ b = (*next).first();
+ }
+ if (b < a)
+ block_m[i] = OneBlock_t(b + 1, a);
+ else if (b == a)
+ block_m[i] = OneBlock_t(a, a);
+ else
+ block_m[i] = OneBlock_t(a, b - 1);
+ loc_m[i] = 0;
+ }
+ else
+ {
+ setDone();
+ break;
+ }
+ }
+ else
+ {
+ Element_t a = (*(current_m[i])).first();
+ Element_t b = (*next).first();
+ if (b < a)
+ block_m[i] = OneBlock_t(b + 1, a);
+ else
+ block_m[i] = OneBlock_t(a, b - 1);
+ loc_m[i] = loc_m[i].first() + 1;
+ index_m++;
+ break;
+ }
+ }
+ }
+ }
+ template<class DT>
+ class DomainBase
+ {
+ public:
+ typedef typename DT::Domain_t Domain_t;
+ typedef typename DT::AskDomain_t AskDomain_t;
+ typedef typename DT::MultResult_t MultResult_t;
+ typedef typename DT::Storage_t Storage_t;
+ typedef DomainIterator<Domain_t> const_iterator;
+ typedef DomainIterator<Domain_t> iterator;
+ typedef DomainBlockIterator<Domain_t> const_blockIterator;
+ typedef DomainBlockIterator<Domain_t> blockIterator;
+ inline
+ DomainBase() {
+ PoomaCTAssert<(DT::dimensions > 0)>::test();
+ DT::initializeStorage(domain_m);
+ }
+ inline
+ DomainBase(const Pooma::NoInit &) {
+ PoomaCTAssert<(DT::dimensions > 0)>::test();
+ }
+ inline
+ Domain_t &unwrap() { return *static_cast<Domain_t *>(this); }
+ const Domain_t &unwrap() const {
+ return *static_cast<const Domain_t *>(this);
+ }
+ inline
+ AskDomain_t firsts() const {
+ AskDomain_t retval = Pooma::NoInit();
+ for (int i=0; i < DT::dimensions; ++i)
+ retval[i] = unwrap()[i].first();
+ return retval;
+ }
+ inline
+ AskDomain_t lasts() const {
+ AskDomain_t retval = Pooma::NoInit();
+ for (int i=0; i < DT::dimensions; ++i)
+ retval[i] = unwrap()[i].last();
+ return retval;
+ }
+ inline
+ AskDomain_t strides() const {
+ AskDomain_t retval = Pooma::NoInit();
+ for (int i=0; i < DT::dimensions; ++i)
+ retval[i] = unwrap()[i].stride();
+ return retval;
+ }
+ inline
+ AskDomain_t lengths() const {
+ AskDomain_t retval = Pooma::NoInit();
+ for (int i=0; i < DT::dimensions; ++i)
+ retval[i] = unwrap()[i].length();
+ return retval;
+ }
+ inline
+ AskDomain_t sizes() const {
+ AskDomain_t retval = Pooma::NoInit();
+ for (int i=0; i < DT::dimensions; ++i)
+ retval[i] = unwrap()[i].size();
+ return retval;
+ }
+ inline
+ AskDomain_t mins() const {
+ AskDomain_t retval = Pooma::NoInit();
+ for (int i=0; i < DT::dimensions; ++i)
+ retval[i] = unwrap()[i].min();
+ return retval;
+ }
+ inline
+ AskDomain_t maxes() const {
+ AskDomain_t retval = Pooma::NoInit();
+ for (int i=0; i < DT::dimensions; ++i)
+ retval[i] = unwrap()[i].max();
+ return retval;
+ }
+ inline
+ AskDomain_t loops() const {
+ AskDomain_t retval = Pooma::NoInit();
+ for (int i=0; i < DT::dimensions; ++i)
+ retval[i] = unwrap()[i].loop();
+ return retval;
+ }
+ Storage_t& storage() { return domain_m; }
+ const Storage_t& storage() const { return domain_m; }
+ MultResult_t operator-() const {
+ return (MultResult_t(unwrap()) * (-1));
+ }
+ const_iterator begin() const { return const_iterator(unwrap()); }
+ const_iterator end() const { return const_iterator(unwrap(),
+ unwrap().size()); }
+ const_blockIterator beginBlock() const{return const_blockIterator(unwrap());}
+ const_blockIterator endBlock() const { return const_blockIterator(); }
+ template<class Out>
+ void print(Out &o) const;
+ protected:
+ Storage_t domain_m;
+ private:
+ DomainBase(const DomainBase<DT> &);
+ void operator=(const DomainBase<DT> &);
+ };
+ template<class DT>
+ template<class Out>
+ void DomainBase<DT>::print(Out &o) const
+ {
+ const Domain_t &d = unwrap();
+ o << "[";
+ for (int i=0; i < DT::dimensions; ++i) {
+ o << d[i].first() << ":" << d[i].last() << ":" << d[i].stride();
+ if (i < (DT::dimensions-1))
+ o << ",";
+ }
+ o << "]";
+ }
+ template <class T1, class T2, bool SV>
+ struct DomPair {
+ static typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::AddResult_t
+ add(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
+ {
+ typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::AddResult_t
+ retval(d1.unwrap());
+ return (retval += d2.unwrap());
+ }
+ static typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::SubResult_t
+ sub(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
+ {
+ typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::SubResult_t
+ retval(d1.unwrap());
+ return (retval -= d2.unwrap());
+ }
+ static typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::MultResult_t
+ mult(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
+ {
+ typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::MultResult_t
+ retval(d1.unwrap());
+ return (retval *= d2.unwrap());
+ }
+ static typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::MultResult_t
+ div(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
+ {
+ typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::MultResult_t
+ retval(d1.unwrap());
+ return (retval /= d2.unwrap());
+ }
+ };
+ template <class T1, class T2>
+ struct DomPair<T1,T2,false> {
+ static typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::AddResult_t
+ add(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
+ {
+ typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::AddResult_t
+ retval(d2.unwrap());
+ return (retval += d1.unwrap());
+ }
+ static typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::SubResult_t
+ sub(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
+ {
+ typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::SubResult_t
+ retval(d2.unwrap());
+ retval = -retval;
+ return (retval += d1.unwrap());
+ }
+ static typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::MultResult_t
+ mult(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
+ {
+ typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::MultResult_t
+ retval(d2.unwrap());
+ return (retval *= d1.unwrap());
+ }
+ };
+ template<class T1, class T2>
+ inline typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::AddResult_t
+ operator+(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
+ {
+ return DomPair<T1,T2,T2::singleValued>::add(d1,d2);
+ }
+ template<class T1, class T2>
+ inline typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::SubResult_t
+ operator-(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
+ {
+ return DomPair<T1,T2,T2::singleValued>::sub(d1,d2);
+ }
+ template<class T1, class T2>
+ inline typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::MultResult_t
+ operator*(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
+ {
+ return DomPair<T1,T2,T2::singleValued>::mult(d1,d2);
+ }
+ template<class T1, class T2>
+ inline typename DomainArithOpsTraits<typename T1::Domain_t,
+ typename T2::Domain_t>::MultResult_t
+ operator/(const DomainBase<T1> &d1, const DomainBase<T2> &d2)
+ {
+ return DomPair<T1,T2,T2::singleValued>::div(d1,d2);
+ }
+ template<class T> inline bool operator==(char d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(unsigned char d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(short d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(unsigned short d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(int d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(unsigned int d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(long d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(unsigned long d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); } template<class T> inline bool operator==(float d1, const DomainBase<T> &d2) { return (d2.unwrap!
() == d1); } template<class T> inline bool operator==(double d1, const DomainBase<T> &d2) { return (d2.unwrap() == d1); }
+ template<class T> inline bool operator!=(char d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(unsigned char d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(short d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(unsigned short d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(int d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(unsigned int d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(long d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(unsigned long d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); } template<class T> inline bool operator!=(float d1, const DomainBase<T> &d2) { return (d2.unwrap!
() != d1); } template<class T> inline bool operator!=(double d1, const DomainBase<T> &d2) { return (d2.unwrap() != d1); }
+ template<class T> inline bool operator<(char d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(unsigned char d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(short d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(unsigned short d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(int d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(unsigned int d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(long d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(unsigned long d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } template<class T> inline bool operator<(float d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); } templ!
ate<class T> inline bool operator<(double d1, const DomainBase<T> &d2) { return (d2.unwrap() < d1); }
+ template<class T> inline bool operator>(char d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(unsigned char d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(short d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(unsigned short d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(int d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(unsigned int d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(long d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(unsigned long d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } template<class T> inline bool operator>(float d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); } templ!
ate<class T> inline bool operator>(double d1, const DomainBase<T> &d2) { return (d2.unwrap() > d1); }
+ template<class T> inline bool operator<=(char d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(unsigned char d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(short d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(unsigned short d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(int d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(unsigned int d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(long d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(unsigned long d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); } template<class T> inline bool operator<=(float d1, const DomainBase<T> &d2) { return (d2.unwrap!
() <= d1); } template<class T> inline bool operator<=(double d1, const DomainBase<T> &d2) { return (d2.unwrap() <= d1); }
+ template<class T> inline bool operator>=(char d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(unsigned char d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(short d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(unsigned short d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(int d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(unsigned int d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(long d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(unsigned long d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); } template<class T> inline bool operator>=(float d1, const DomainBase<T> &d2) { return (d2.unwrap!
() >= d1); } template<class T> inline bool operator>=(double d1, const DomainBase<T> &d2) { return (d2.unwrap() >= d1); }
+ template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, char d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(char d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, unsigned char d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(unsigned char d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, short d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(short d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); re!
turn (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, unsigned short d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(unsigned short d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, int d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(int d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, unsigned int d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(unsigned int d1, const DomainBase<T> &d2) { typename T:!
:AddResult_t retval(d2.unwrap()); return (retval += d1); } tem!
plate<cl
ass T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, long d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(long d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, unsigned long d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(unsigned long d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, float d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(float d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval !
+= d1); } template<class T> inline typename T::AddResult_t operator+(const DomainBase<T> &d1, double d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval += d2); } template<class T> inline typename T::AddResult_t operator+(double d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval += d1); }
+ template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, char d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(char d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, unsigned char d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(unsigned char d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, short d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(short d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); re!
turn (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, unsigned short d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(unsigned short d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, int d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(int d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, unsigned int d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(unsigned int d1, const DomainBase<T> &d2) { typename T:!
:AddResult_t retval(d2.unwrap()); return (retval -= d1); } tem!
plate<cl
ass T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, long d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(long d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, unsigned long d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(unsigned long d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, float d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(float d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval !
-= d1); } template<class T> inline typename T::AddResult_t operator-(const DomainBase<T> &d1, double d2) { typename T::AddResult_t retval(d1.unwrap()); return (retval -= d2); } template<class T> inline typename T::AddResult_t operator-(double d1, const DomainBase<T> &d2) { typename T::AddResult_t retval(d2.unwrap()); return (retval -= d1); }
+ template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, char d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(char d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, unsigned char d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(unsigned char d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, short d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(short d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.u!
nwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, unsigned short d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(unsigned short d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, int d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(int d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, unsigned int d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(unsigned int d1, const DomainBas!
e<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); retu!
rn (retv
al *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, long d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(long d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, unsigned long d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(unsigned long d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, float d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(float d1, const DomainBase<T> &d2) { typename T::MultResult_t !
retval(d2.unwrap()); return (retval *= d1); } template<class T> inline typename T::MultResult_t operator*(const DomainBase<T> &d1, double d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval *= d2); } template<class T> inline typename T::MultResult_t operator*(double d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval *= d1); }
+ template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, char d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(char d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, unsigned char d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(unsigned char d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, short d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(short d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.u!
nwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, unsigned short d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(unsigned short d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, int d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(int d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, unsigned int d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(unsigned int d1, const DomainBas!
e<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); retu!
rn (retv
al /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, long d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(long d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, unsigned long d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(unsigned long d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, float d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(float d1, const DomainBase<T> &d2) { typename T::MultResult_t !
retval(d2.unwrap()); return (retval /= d1); } template<class T> inline typename T::MultResult_t operator/(const DomainBase<T> &d1, double d2) { typename T::MultResult_t retval(d1.unwrap()); return (retval /= d2); } template<class T> inline typename T::MultResult_t operator/(double d1, const DomainBase<T> &d2) { typename T::MultResult_t retval(d2.unwrap()); return (retval /= d1); }
+ template<class D, class V>
+ inline void DomainToVector(const D &dom, V &vec)
+ {
+ for (int i=0; i < DomainTraits<D>::dimensions; ++i)
+ vec(i) = dom[i].first();
+ }
+ template<class V, class D>
+ inline void VectorToDomain(const V &vec, D &dom)
+ {
+ for (int i=0; i < DomainTraits<D>::dimensions; ++i)
+ dom[i] = DomainTraits<D>::OneDomain_t(vec(i), vec(i));
+ }
+ template<class DT>
+ std::ostream& operator<<(std::ostream &o, const DomainBase<DT> &dbase)
+ {
+ dbase.print(o);
+ return o;
+ }
+ template <int Dim, int C>
+ struct DomainDelta;
+ template <int Dim, int C>
+ struct DomainDelta;
+ template<int Dim, class DT>
+ class Domain : public DomainBase<DT>
+ {
+ typedef DomainBase<DT> Base_t;
+ public:
+ typedef typename DT::Size_t Size_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef typename DT::OneDomain_t OneDomain_t;
+ typedef typename Base_t::const_iterator const_iterator;
+ typedef typename Base_t::iterator iterator;
+ typedef typename Base_t::const_blockIterator const_blockIterator;
+ typedef typename Base_t::blockIterator blockIterator;
+ inline
+ Domain() {
+ PoomaCTAssert<(DT::dimensions == Dim && Dim > 0)>::test();
+ }
+ inline Domain(const Pooma::NoInit &d) : Base_t(d) {
+ PoomaCTAssert<(DT::dimensions == Dim && Dim > 0)>::test();
+ }
+ inline
+ ~Domain() { }
+ inline
+ const OneDomain_t &operator[](int d) const { return this->domain_m[d]; }
+ inline
+ OneDomain_t &operator[](int d) { return this->domain_m[d]; }
+ inline
+ Size_t size() const {
+ Size_t sz = this->domain_m[0].size();
+ for (int i = 1; i < Dim; i++)
+ sz *= this->domain_m[i].size();
+ return sz;
+ }
+ inline
+ bool empty() const {
+ for (int i = 0; i < Dim; i++)
+ if (this->domain_m[i].empty())
+ return true;
+ return false;
+ }
+ inline
+ bool initialized() const { return (!empty()); }
+ template<class T>
+ bool operator==(const T &d2) const {
+ PoomaCTAssert<(Dim == DomainTraits<T>::dimensions)>::test();
+ for (int i = 0; i < Dim; i++)
+ if (this->domain_m[i] != DomainTraits<T>::getDomain(d2, i))
+ return false;
+ return true;
+ }
+ template<class T>
+ bool operator<(const T &d2) const {
+ PoomaCTAssert<(Dim == DomainTraits<T>::dimensions)>::test();
+ for (int i = 0; i < Dim; i++)
+ if (this->domain_m[i] >= DomainTraits<T>::getDomain(d2, i))
+ return false;
+ return true;
+ }
+ template<class T>
+ bool operator!=(const T &d2) const {
+ PoomaCTAssert<(Dim == DomainTraits<T>::dimensions)>::test();
+ for (int i = 0; i < Dim; i++)
+ if (this->domain_m[i] != DomainTraits<T>::getDomain(d2, i))
+ return true;
+ return false;
+ }
+ template<class T>
+ bool operator>(const T &d2) const {
+ PoomaCTAssert<(Dim == DomainTraits<T>::dimensions)>::test();
+ for (int i = 0; i < Dim; i++)
+ if (this->domain_m[i] <= DomainTraits<T>::getDomain(d2, i))
+ return false;
+ return true;
+ }
+ template<class T>
+ bool operator<=(const T &d2) const {
+ PoomaCTAssert<(Dim == DomainTraits<T>::dimensions)>::test();
+ for (int i = 0; i < Dim; i++)
+ if (this->domain_m[i] > DomainTraits<T>::getDomain(d2, i))
+ return false;
+ return true;
+ }
+ template<class T>
+ bool operator>=(const T &d2) const {
+ PoomaCTAssert<(Dim == DomainTraits<T>::dimensions)>::test();
+ for (int i = 0; i < Dim; i++)
+ if (this->domain_m[i] < DomainTraits<T>::getDomain(d2, i))
+ return false;
+ return true;
+ }
+ Domain_t &operator++() {
+ for (int i=0; i<Dim; ++i)
+ this->domain_m[i] += this->domain_m[i].stride();
+ return this->unwrap();
+ }
+ Domain_t &operator--() {
+ for (int i=0; i<Dim; ++i)
+ this->domain_m[i] -= this->domain_m[i].stride();
+ return this->unwrap();
+ }
+ template<class T>
+ inline
+ Domain_t &operator+=(const T &d2)
+ {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == Dim || DomainTraits<T>::dimensions == 1 || Dim == 1)>::test();
+ int d = DomainTraits<T>::dimensions > Dim ?
+ DomainTraits<T>::dimensions : Dim;
+ for (int i = 0; i < d; i++)
+ this->domain_m[i] += DomainTraits<T>::getPointDomain(d2, i);
+ return this->unwrap();
+ }
+ template<class T>
+ inline
+ Domain_t &operator-=(const T &d2) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued)>::test();
+ PoomaCTAssert<(DomainTraits<T>::dimensions == Dim || DomainTraits<T>::dimensions == 1)>::test();
+ for (int i = 0; i < Dim; i++)
+ this->domain_m[i] -= DomainTraits<T>::getPointDomain(d2, i);
+ return this->unwrap();
+ }
+ template<class T>
+ inline
+ Domain_t &operator*=(const T &d2) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued)>::test();
+ PoomaCTAssert<(DomainTraits<T>::dimensions == Dim || DomainTraits<T>::dimensions == 1)>::test();
+ for (int i = 0; i < Dim; i++)
+ this->domain_m[i] *= DomainTraits<T>::getPointDomain(d2, i);
+ return this->unwrap();
+ }
+ template<class T>
+ inline
+ Domain_t &operator/=(const T &d2) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued)>::test();
+ PoomaCTAssert<(DomainTraits<T>::dimensions == Dim || DomainTraits<T>::dimensions == 1)>::test();
+ for (int i = 0; i < Dim; i++)
+ this->domain_m[i] /= DomainTraits<T>::getPointDomain(d2, i);
+ return this->unwrap();
+ }
+ template <int Dim2, int C>
+ inline
+ Domain_t &operator+=(const DomainDelta<Dim2, C>&)
+ {
+ if (C < Dim)
+ this->domain_m[C] += 1;
+ return this->unwrap();
+ }
+ template <int Dim2, int C>
+ inline
+ Domain_t &operator-=(const DomainDelta<Dim2, C>&)
+ {
+ if (C < Dim)
+ this->domain_m[C] -= 1;
+ return this->unwrap();
+ }
+ private:
+ Domain(const Domain<Dim,DT> &);
+ void operator=(const Domain<Dim,DT> &);
+ };
+ template<class DT, class ST, class T, class UT, bool wildcard>
+ struct SetDomainFunctor
+ {
+ inline
+ static void setDomain(ST &domain, const T &newdom) {
+ DT::setDomain(domain, newdom);
+ }
+ inline
+ static void setWildcardDomain(ST &domain, const UT &, const T &newdom) {
+ DT::setDomain(domain, newdom);
+ }
+ };
+ template<class DT, class ST, class T, class UT>
+ struct SetDomainFunctor<DT, ST, T, UT, true>
+ {
+ inline
+ static void setDomain(ST &, const T &) { }
+ inline
+ static void setWildcardDomain(ST &domain, const UT &u, const T &newdom) {
+ DT::setWildcardDomain(domain, u, newdom);
+ }
+ };
+ template<class DT>
+ class Domain<1, DT> : public DomainBase<DT>
+ {
+ typedef DomainBase<DT> Base_t;
+ public:
+ typedef typename DT::Size_t Size_t;
+ typedef typename DT::Element_t Element_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef typename Base_t::Storage_t Storage_t;
+ typedef typename Base_t::const_iterator const_iterator;
+ typedef typename Base_t::iterator iterator;
+ typedef typename Base_t::const_blockIterator const_blockIterator;
+ typedef typename Base_t::blockIterator blockIterator;
+ inline
+ Domain() { }
+ inline
+ Domain(const Pooma::NoInit &d) : Base_t(d) { }
+ inline
+ Domain_t &operator[](int) { return this->unwrap(); }
+ inline
+ const Domain_t &operator[](int) const { return this->unwrap(); }
+ inline
+ Element_t elem(int n) const { return DT::elem(this->domain_m, n); }
+ inline
+ Element_t operator()(int n) const { return DT::elem(this->domain_m, n); }
+ inline
+ Element_t first() const { return DT::first(this->domain_m); }
+ inline
+ Element_t last() const { return DT::last(this->domain_m); }
+ inline
+ Element_t stride() const { return DT::stride(this->domain_m); }
+ inline
+ Size_t length() const { return DT::length(this->domain_m); }
+ inline
+ Element_t min() const { return DT::min(this->domain_m); }
+ inline
+ Element_t max() const { return DT::max(this->domain_m); }
+ inline
+ Size_t size() const { return length(); }
+ inline
+ bool empty() const { return DT::empty(this->domain_m); }
+ inline
+ bool initialized() const { return (!empty()); }
+ inline
+ int loop() const { return DT::loop(this->domain_m); }
+ template<class T>
+ inline
+ void setDomain(const T &newdom) {
+ SetDomainFunctor<DT,Storage_t,T,T,DomainTraits<T>::wildcard>::
+ setDomain(this->domain_m, newdom);
+ }
+ template<class UT, class T>
+ inline
+ void setWildcardDomain(const UT &u, const T &newdom) {
+ SetDomainFunctor<DT,Storage_t,T,UT,DomainTraits<T>::wildcard>::
+ setWildcardDomain(this->domain_m, u, newdom);
+ }
+ inline
+ void setLoop(int newloop) { DT::setLoop(this->domain_m, newloop); }
+ template<class T>
+ bool operator==(const T &d2) const {
+ return DT::isEqualTo(this->domain_m, d2);
+ }
+ template<class T>
+ bool operator<(const T &d2) const {
+ return DT::isLessThan(this->domain_m, d2);
+ }
+ template<class T>
+ bool operator!=(const T &d2) const { return !(*this == d2); }
+ template<class T>
+ bool operator>(const T &d2) const { return !(*this < d2 || *this == d2); }
+ template<class T>
+ bool operator<=(const T &d2) const { return (*this < d2 || *this == d2); }
+ template<class T>
+ bool operator>=(const T &d2) const { return !(*this < d2); }
+ Domain_t &operator++() {
+ DT::addAccum(this->domain_m, DT::stride(this->domain_m));
+ return this->unwrap();
+ }
+ Domain_t &operator--() {
+ DT::subtractAccum(this->domain_m, DT::stride(this->domain_m));
+ return this->unwrap();
+ }
+ template<class T>
+ inline
+ Domain_t &operator+=(const T &d2) {
+ DT::addAccum(this->domain_m, d2);
+ return this->unwrap();
+ }
+ template<class T>
+ inline
+ Domain_t &operator-=(const T &d2) {
+ DT::subtractAccum(this->domain_m, d2);
+ return this->unwrap();
+ }
+ template<class T>
+ inline
+ Domain_t &operator*=(const T &d2) {
+ DT::multiplyAccum(this->domain_m, d2);
+ return this->unwrap();
+ }
+ template<class T>
+ inline
+ Domain_t &operator/=(const T &d2) {
+ DT::divideAccum(this->domain_m, d2);
+ return this->unwrap();
+ }
+ template <int Dim2, int C>
+ inline
+ Domain_t &operator+=(const DomainDelta<Dim2, C>&)
+ {
+ if (C == 0)
+ DT::addAccum(this->domain_m, 1);
+ return this->unwrap();
+ }
+ template <int Dim2, int C>
+ inline
+ Domain_t &operator-=(const DomainDelta<Dim2, C>&)
+ {
+ if (C == 0)
+ DT::subtractAccum(this->domain_m, 1);
+ return this->unwrap();
+ }
+ private:
+ Domain(const Domain<1,DT> &);
+ void operator=(const Domain<1,DT> &);
+ };
+ template <int Dim> class Loc;
+ template <> class Loc<1>;
+ template <int Dim> class Interval;
+ template <> class Interval<1>;
+ template <int Dim> class Range;
+ template <> class Range<1>;
+ template<int Dim>
+ struct DomainTraits< Interval<Dim> >
+ : public DomainTraitsDomain<Interval<Dim>, int, Dim>
+ {
+ typedef DomainTraitsDomain<Interval<Dim>, int, Dim> Base_t;
+ typedef typename Base_t::Element_t Element_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef typename Base_t::NewDomain1_t NewDomain1_t;
+ typedef Interval<1> OneDomain_t;
+ typedef Interval<1> PointDomain_t;
+ typedef Interval<Dim> BlockDomain_t;
+ typedef Loc<Dim> AskDomain_t;
+ typedef Interval<Dim> AddResult_t;
+ typedef Range<Dim> MultResult_t;
+ typedef WrapNoInit<OneDomain_t> Storage_t[Dim];
+ enum { domain = Base_t::domain };
+ enum { dimensions = Base_t::dimensions,
+ sliceDimensions = Dim };
+ enum { loopAware = false };
+ enum { singleValued = false };
+ enum { unitStride = true };
+ enum { wildcard = false };
+ inline
+ static OneDomain_t &getDomain(Domain_t &d, int n) { return d[n]; }
+ inline
+ static const OneDomain_t &getDomain(const Domain_t &d,int n) { return d[n]; }
+ inline
+ static PointDomain_t &getPointDomain(Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ inline
+ static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ inline
+ static void initializeStorage(Storage_t &dom) {
+ Dom1Initialize<Dim-1>::template apply<DomainTraits<Interval<Dim> > >(dom);
+ }
+ };
+ template<>
+ struct DomainTraits< Interval<1> >
+ : public DomainTraitsDomain<Interval<1>, int, 1>
+ {
+ typedef Interval<1> OneDomain_t;
+ typedef Interval<1> PointDomain_t;
+ typedef Interval<1> BlockDomain_t;
+ typedef Loc<1> AskDomain_t;
+ typedef Interval<1> AddResult_t;
+ typedef Range<1> MultResult_t;
+ typedef Element_t Storage_t[2];
+ enum { dimensions = 1,
+ sliceDimensions = 1 };
+ enum { loopAware = false };
+ enum { singleValued = false };
+ enum { unitStride = true };
+ enum { wildcard = false };
+ inline
+ static Element_t first(const Storage_t &d) { return d[0]; }
+ inline
+ static Element_t last(const Storage_t &d) { return d[0] + d[1] - 1; }
+ inline
+ static Element_t stride(const Storage_t &) { return 1; }
+ inline
+ static Element_t length(const Storage_t &d) { return d[1]; }
+ inline
+ static Element_t min(const Storage_t &d) { return d[0]; }
+ inline
+ static Element_t max(const Storage_t &d) { return d[0] + d[1] - 1; }
+ inline
+ static bool empty(const Storage_t &d) { return (d[1] < 1); }
+ inline
+ static int loop(const Storage_t &) { return 0; }
+ inline
+ static Element_t elem(const Storage_t &d, int n) { return d[0] + n; }
+ inline
+ static OneDomain_t &getDomain(Domain_t &d, int) { return d; }
+ inline
+ static const OneDomain_t &getDomain(const Domain_t &d, int) { return d; }
+ inline
+ static PointDomain_t &getPointDomain(Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ inline
+ static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ inline
+ static void initializeStorage(Storage_t &dom) {
+ dom[0] = 0;
+ dom[1] = 0;
+ }
+ template<class T>
+ inline
+ static void setDomain(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ ;
+ dom[0] = DomainTraits<T>::getFirst(newdom);
+ dom[1] = DomainTraits<T>::getLength(newdom);
+ }
+ template<class T1, class T2>
+ inline
+ static void setDomain(Storage_t &dom, const T1 &begval, const T2 &endval) {
+ PoomaCTAssert<(DomainTraits<T1>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<T2>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<T1>::singleValued)>::test();
+ PoomaCTAssert<(DomainTraits<T2>::singleValued)>::test();
+ dom[0] = begval;
+ dom[1] = (endval - begval + 1);
+ ;
+ }
+ inline
+ static void setLoop(Storage_t &, int) { }
+ template<class UT, class T>
+ inline
+ static void setWildcardDomain(Storage_t &dom, const UT &u, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::wildcard)>::test();
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<UT>::dimensions == 1)>::test();
+ dom[0] = newdom.first(u);
+ dom[1] = newdom.length(u);
+ }
+ template<class T>
+ static bool isLessThan(const Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ ;
+ return (dom[1] < DomainTraits<T>::getLength(newdom) ||
+ (dom[1] == DomainTraits<T>::getLength(newdom) &&
+ (dom[0] < DomainTraits<T>::getFirst(newdom) ||
+ (dom[0] == DomainTraits<T>::getFirst(newdom) &&
+ DomainTraits<T>::getStride(newdom) > 1))));
+ }
+ template<class T>
+ static bool isEqualTo(const Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ return ((dom[1] == 0 && DomainTraits<T>::getLength(newdom) == 0) ||
+ (dom[0] == DomainTraits<T>::getFirst(newdom) &&
+ dom[1] == DomainTraits<T>::getLength(newdom) &&
+ DomainTraits<T>::getStride(newdom) == 1));
+ }
+ template<class T>
+ inline
+ static void addAccum(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
+ dom[0] += DomainTraits<T>::getFirst(newdom);
+ }
+ template<class T>
+ inline
+ static void subtractAccum(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
+ dom[0] -= DomainTraits<T>::getFirst(newdom);
+ }
+ };
+ template<int Dim1, int Dim2>
+ struct DomainChangeDim<Interval<Dim1>, Dim2>
+ {
+ typedef Interval<Dim1> OldType_t;
+ typedef Interval<Dim2> NewType_t;
+ enum { oldDim = Dim1,
+ newDim = Dim2 };
+ };
+ template<int Dim> class Loc;
+ template<int Dim> class Interval;
+ template<int Dim> class Range;
+ template<int Dim> class Grid;
+ template<int Dim> class AllDomain;
+ template<int Dim> class LeftDomain;
+ template<int Dim> class RightDomain;
+ template<int Dim, int SliceDim> class SliceInterval;
+ template<int Dim, int SliceDim> class SliceRange;
+ template<int Dim, class T> class Region;
+ template<class T> class IndirectionList;
+ template<class RT, class CT, int DS>
+ struct CombineDomain {
+ enum { DRT = DomainTraits<RT>::dimensions };
+ enum { DCT = DomainTraits<CT>::dimensions };
+ static void combine(RT &rt, const CT& ct) {
+ PoomaCTAssert<(DS >= 0)>::test();
+ PoomaCTAssert<(DRT > (DS + DCT - 1))>::test();
+ for (int i=0; i < DCT; ++i)
+ DomainTraits<RT>::getDomain(rt, DS + i).setDomain(
+ DomainTraits<CT>::getDomain(ct, i));
+ }
+ };
+ template<class RT, class UT, class CT, int DS, int SliceDS,
+ bool incl, bool wc>
+ struct CombineSliceDomainWC {
+ enum { DRT = DomainTraits<RT>::dimensions };
+ enum { DCT = DomainTraits<CT>::dimensions };
+ static void combine(RT &rt, const UT &, const CT& ct) {
+ PoomaCTAssert<(DS >= 0)>::test();
+ PoomaCTAssert<(DRT > (DS + DCT - 1))>::test();
+ for (int i=0; i < DCT; ++i)
+ DomainTraits<RT>::getDomain(rt, DS + i).setDomain(
+ DomainTraits<CT>::getPointDomain(ct, i));
+ }
+ };
+ template<class RT, class UT, class CT, int DS, int SliceDS>
+ struct CombineSliceDomainWC<RT,UT,CT,DS,SliceDS,true,false> {
+ enum { DRT = DomainTraits<RT>::dimensions };
+ enum { DCT = DomainTraits<CT>::dimensions };
+ static void combine(RT &rt, const UT &, const CT& ct) {
+ PoomaCTAssert<(DS >= 0 && SliceDS >= 0)>::test();
+ PoomaCTAssert<(DRT > (DS + DCT - 1))>::test();
+ for (int i=0; i < DCT; ++i) {
+ DomainTraits<RT>::getDomain(rt, DS + i).setDomain(
+ DomainTraits<CT>::getPointDomain(ct, i));
+ DomainTraits<RT>::setIgnorable(rt, DS + i,
+ DomainTraits<CT>::getIgnorable(ct, i));
+ }
+ rt.setSliceFromTotal();
+ }
+ };
+ template<class RT, class UT, class CT, int DS, int SliceDS>
+ struct CombineSliceDomainWC<RT,UT,CT,DS,SliceDS,false,true> {
+ enum { DRT = DomainTraits<RT>::dimensions };
+ enum { DUT = DomainTraits<UT>::dimensions };
+ enum { DCT = DomainTraits<CT>::dimensions };
+ static void combine(RT &rt, const UT &u, const CT& ct) {
+ PoomaCTAssert<(DS >= 0)>::test();
+ PoomaCTAssert<(DRT > (DS + DCT - 1))>::test();
+ PoomaCTAssert<(DUT == DRT)>::test();
+ for (int i=0; i < DCT; ++i)
+ DomainTraits<RT>::getDomain(rt, DS + i).setWildcardDomain(
+ DomainTraits<UT>::getPointDomain(u, DS + i),
+ DomainTraits<CT>::getPointDomain(ct, i));
+ }
+ };
+ template<class RT, class UT, class CT, int DS, int SliceDS>
+ struct CombineSliceDomainWC<RT,UT,CT,DS,SliceDS,true,true> {
+ enum { DRT = DomainTraits<RT>::dimensions };
+ enum { DUT = DomainTraits<UT>::dimensions };
+ enum { DCT = DomainTraits<CT>::dimensions };
+ static void combine(RT &rt, const UT &u, const CT& ct) {
+ PoomaCTAssert<(DS >= 0 && SliceDS >= 0)>::test();
+ PoomaCTAssert<(DRT > (DS + DCT - 1))>::test();
+ PoomaCTAssert<((int)DUT == DRT)>::test();
+ for (int i=0; i < DCT; ++i) {
+ DomainTraits<RT>::getDomain(rt, DS + i).setWildcardDomain(
+ DomainTraits<UT>::getPointDomain(u, DS + i),
+ DomainTraits<CT>::getPointDomain(ct, i));
+ DomainTraits<RT>::getSliceDomain(rt, SliceDS + i).setWildcardDomain(
+ DomainTraits<UT>::getPointDomain(u, DS + i),
+ DomainTraits<CT>::getPointDomain(ct, i));
+ DomainTraits<RT>::cantIgnoreDomain(rt, DS + i);
+ }
+ }
+ };
+ template<class RT, class UT, class CT, int DS, int SliceDS, bool incl>
+ struct CombineSliceDomain {
+ static void combine(RT &rt, const UT &u, const CT& ct) {
+ CombineSliceDomainWC<RT,UT,CT,DS,SliceDS,incl,
+ DomainTraits<CT>::wildcard>::combine(rt, u, ct);
+ }
+ };
+ template<class T1, class T2, class TCombine, class TSCombine>
+ struct NewDomain2Base
+ {
+ typedef TCombine Type_t;
+ typedef TSCombine SliceType_t;
+ enum { S2 = DomainTraits<T1>::dimensions };
+ enum { DX1 = DomainTraits<T1>::sliceDimensions };
+ enum { DX2 = DomainTraits<T2>::sliceDimensions };
+ inline static Type_t combine(const T1 &a, const T2 &b)
+ {
+ Type_t retval = Pooma::NoInit();
+ return fill(retval, a, b);
+ }
+ template<class RT>
+ inline static RT &fill(RT &retval, const T1 &a, const T2 &b)
+ {
+ CombineDomain<RT,T1,0>::combine(retval,a);
+ CombineDomain<RT,T2,S2>::combine(retval,b);
+ return retval;
+ }
+ template<class UT>
+ inline static SliceType_t combineSlice(const UT &u,
+ const T1 &a, const T2 &b)
+ {
+ SliceType_t retval = Pooma::NoInit();
+ return fillSlice(retval, u, a, b);
+ }
+ template<class RT, class UT>
+ inline static RT &fillSlice(RT &retval, const UT &u,
+ const T1 &a, const T2 &b)
+ {
+ enum { RDX =
+ DomainTraits<RT>::dimensions > DomainTraits<RT>::sliceDimensions };
+ CombineSliceDomain<RT,UT,T1,0,0,(DX1>0 && RDX)>::
+ combine(retval,u,a);
+ CombineSliceDomain<RT,UT,T2,S2,DX1,(DX2>0 && RDX)>::
+ combine(retval,u,b);
+ return retval;
+ }
+ };
+ template<class T1, class T2>
+ struct AddNewDomain2Dimensions
+ {
+ enum { dimensions =
+ DomainTraits<T1>::dimensions + DomainTraits<T2>::dimensions };
+ };
+ template<class T1, class T2>
+ struct NewDomain2
+ : public NewDomain2Base<T1, T2,
+ Interval<AddNewDomain2Dimensions<T1,T2>::dimensions>,
+ Loc<AddNewDomain2Dimensions<T1,T2>::dimensions> >
+ { };
+ template <int D1, int D2> struct NewDomain2< Range<D1>, Range<D2> > : public NewDomain2Base< Range<D1>, Range<D2>, Range<D1+D2>, Range<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< Range<D1>, Loc<D2> > : public NewDomain2Base< Range<D1>, Loc<D2>, Range<D1+D2>, SliceRange<D1+D2,D1> > { }; template <int D1, int D2> struct NewDomain2< Loc<D2>, Range<D1> > : public NewDomain2Base< Loc<D2>, Range<D1>, Range<D1+D2>, SliceRange<D1+D2,D1> > { }; template <int D> struct NewDomain2< Range<D>, char > : public NewDomain2Base< Range<D>, char, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< char, Range<D> > : public NewDomain2Base< char, Range<D>, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Range<D>, unsigned char > : public NewDomain2Base< Range<D>, unsigned char, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< unsigned char, Range<D> > : public NewDomain2Base< unsigned char, Range<D>, Range<D+1!
>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Range<D>, short > : public NewDomain2Base< Range<D>, short, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< short, Range<D> > : public NewDomain2Base< short, Range<D>, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Range<D>, unsigned short > : public NewDomain2Base< Range<D>, unsigned short, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< unsigned short, Range<D> > : public NewDomain2Base< unsigned short, Range<D>, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Range<D>, int > : public NewDomain2Base< Range<D>, int, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< int, Range<D> > : public NewDomain2Base< int, Range<D>, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Range<D>, unsigned int > : public NewDomain2Base< Range<D>, unsigned int, Range<D+1>, SliceRange<D!
+1,D> > { }; template <int D> struct NewDomain2< unsigned int,!
Range<D
> > : public NewDomain2Base< unsigned int, Range<D>, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Range<D>, long > : public NewDomain2Base< Range<D>, long, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< long, Range<D> > : public NewDomain2Base< long, Range<D>, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Range<D>, unsigned long > : public NewDomain2Base< Range<D>, unsigned long, Range<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< unsigned long, Range<D> > : public NewDomain2Base< unsigned long, Range<D>, Range<D+1>, SliceRange<D+1,D> > { };
+ template <int D1, int D2> struct NewDomain2< Range<D1>, Interval<D2> > : public NewDomain2Base< Range<D1>, Interval<D2>, Range<D1+D2>, Range<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< Interval<D1>, Range<D2> > : public NewDomain2Base< Interval<D1>, Range<D2>, Range<D1+D2>, Range<D1+D2> > { };
+ template <int D1, int D2> struct NewDomain2< Range<D1>, AllDomain<D2> > : public NewDomain2Base< Range<D1>, AllDomain<D2>, Range<D1+D2>, Range<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< AllDomain<D1>, Range<D2> > : public NewDomain2Base< AllDomain<D1>, Range<D2>, Range<D1+D2>, Range<D1+D2> > { };
+ template <int D1, int D2> struct NewDomain2< Range<D1>, LeftDomain<D2> > : public NewDomain2Base< Range<D1>, LeftDomain<D2>, Range<D1+D2>, Range<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< LeftDomain<D1>, Range<D2> > : public NewDomain2Base< LeftDomain<D1>, Range<D2>, Range<D1+D2>, Range<D1+D2> > { };
+ template <int D1, int D2> struct NewDomain2< Range<D1>, RightDomain<D2> > : public NewDomain2Base< Range<D1>, RightDomain<D2>, Range<D1+D2>, Range<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< RightDomain<D1>, Range<D2> > : public NewDomain2Base< RightDomain<D1>, Range<D2>, Range<D1+D2>, Range<D1+D2> > { };
+ template <int D1, int DS1, int D2> struct NewDomain2< SliceRange<D1,DS1>, Loc<D2> > : public NewDomain2Base< SliceRange<D1,DS1>, Loc<D2>, SliceRange<D1+D2,DS1>, SliceRange<D1+D2,DS1> > { }; template <int D1, int DS1, int D2> struct NewDomain2< Loc<D2>, SliceRange<D1,DS1> > : public NewDomain2Base< Loc<D2>, SliceRange<D1,DS1>, SliceRange<D1+D2,DS1>, SliceRange<D1+D2,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, char > : public NewDomain2Base< SliceRange<D1,DS1>, char ,SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, unsigned char > : public NewDomain2Base< SliceRange<D1,DS1>, unsigned char, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< char, SliceRange<D1,DS1> > : public NewDomain2Base< char, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned char, SliceR!
ange<D1,DS1> > : public NewDomain2Base< unsigned char, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, short > : public NewDomain2Base< SliceRange<D1,DS1>, short ,SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, unsigned short > : public NewDomain2Base< SliceRange<D1,DS1>, unsigned short, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< short, SliceRange<D1,DS1> > : public NewDomain2Base< short, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned short, SliceRange<D1,DS1> > : public NewDomain2Base< unsigned short, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, int > : public NewDomain2Base< SliceRange<D1,DS1>, int ,S!
liceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int!
D1, int
DS1> struct NewDomain2< SliceRange<D1,DS1>, unsigned int > : public NewDomain2Base< SliceRange<D1,DS1>, unsigned int, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< int, SliceRange<D1,DS1> > : public NewDomain2Base< int, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned int, SliceRange<D1,DS1> > : public NewDomain2Base< unsigned int, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, long > : public NewDomain2Base< SliceRange<D1,DS1>, long ,SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceRange<D1,DS1>, unsigned long > : public NewDomain2Base< SliceRange<D1,DS1>, unsigned long, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< long, SliceRange<D1,DS1> > : public NewDomain2!
Base< long, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned long, SliceRange<D1,DS1> > : public NewDomain2Base< unsigned long, SliceRange<D1,DS1>, SliceRange<D1+1,DS1>, SliceRange<D1+1,DS1> > { };
+ template <int D1, int DS1, int D2> struct NewDomain2< SliceRange<D1,DS1>, Range<D2> > : public NewDomain2Base< SliceRange<D1,DS1>, Range<D2>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< Range<D2>, SliceRange<D1,DS1> > : public NewDomain2Base< Range<D2>, SliceRange<D1,DS1>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { };
+ template <int D1, int DS1, int D2> struct NewDomain2< SliceRange<D1,DS1>, Interval<D2> > : public NewDomain2Base< SliceRange<D1,DS1>, Interval<D2>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< Interval<D2>, SliceRange<D1,DS1> > : public NewDomain2Base< Interval<D2>, SliceRange<D1,DS1>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { };
+ template <int D1, int DS1, int D2> struct NewDomain2< SliceRange<D1,DS1>, AllDomain<D2> > : public NewDomain2Base< SliceRange<D1,DS1>, AllDomain<D2>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< AllDomain<D2>, SliceRange<D1,DS1> > : public NewDomain2Base< AllDomain<D2>, SliceRange<D1,DS1>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { };
+ template <int D1, int DS1, int D2> struct NewDomain2< SliceRange<D1,DS1>, LeftDomain<D2> > : public NewDomain2Base< SliceRange<D1,DS1>, LeftDomain<D2>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< LeftDomain<D2>, SliceRange<D1,DS1> > : public NewDomain2Base< LeftDomain<D2>, SliceRange<D1,DS1>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { };
+ template <int D1, int DS1, int D2> struct NewDomain2< SliceRange<D1,DS1>, RightDomain<D2> > : public NewDomain2Base< SliceRange<D1,DS1>, RightDomain<D2>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< RightDomain<D2>, SliceRange<D1,DS1> > : public NewDomain2Base< RightDomain<D2>, SliceRange<D1,DS1>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { };
+ template <int D1, int D2> struct NewDomain2< Interval<D1>, Interval<D2> > : public NewDomain2Base< Interval<D1>, Interval<D2>, Interval<D1+D2>, Interval<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< Interval<D1>, Loc<D2> > : public NewDomain2Base< Interval<D1>, Loc<D2>, Interval<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D1, int D2> struct NewDomain2< Loc<D2>, Interval<D1> > : public NewDomain2Base< Loc<D2>, Interval<D1>, Interval<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D> struct NewDomain2< Interval<D>, char > : public NewDomain2Base< Interval<D>, char, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< char, Interval<D> > : public NewDomain2Base< char, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< Interval<D>, unsigned char > : public NewDomain2Base< Interval<D>, unsigned char, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigne!
d char, Interval<D> > : public NewDomain2Base< unsigned char, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< Interval<D>, short > : public NewDomain2Base< Interval<D>, short, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< short, Interval<D> > : public NewDomain2Base< short, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< Interval<D>, unsigned short > : public NewDomain2Base< Interval<D>, unsigned short, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned short, Interval<D> > : public NewDomain2Base< unsigned short, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< Interval<D>, int > : public NewDomain2Base< Interval<D>, int, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< int, Interval<D> > : public NewDomain2Base< int, Interval<D>, Interval<D+1>, !
SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2!
< Interv
al<D>, unsigned int > : public NewDomain2Base< Interval<D>, unsigned int, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned int, Interval<D> > : public NewDomain2Base< unsigned int, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< Interval<D>, long > : public NewDomain2Base< Interval<D>, long, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< long, Interval<D> > : public NewDomain2Base< long, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< Interval<D>, unsigned long > : public NewDomain2Base< Interval<D>, unsigned long, Interval<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned long, Interval<D> > : public NewDomain2Base< unsigned long, Interval<D>, Interval<D+1>, SliceInterval<D+1,D> > { };
+ template <int D1, int D2> struct NewDomain2< Interval<D1>, AllDomain<D2> > : public NewDomain2Base< Interval<D1>, AllDomain<D2>, Interval<D1+D2>, Interval<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< AllDomain<D1>, Interval<D2> > : public NewDomain2Base< AllDomain<D1>, Interval<D2>, Interval<D1+D2>, Interval<D1+D2> > { };
+ template <int D1, int D2> struct NewDomain2< Interval<D1>, LeftDomain<D2> > : public NewDomain2Base< Interval<D1>, LeftDomain<D2>, Interval<D1+D2>, Interval<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< LeftDomain<D1>, Interval<D2> > : public NewDomain2Base< LeftDomain<D1>, Interval<D2>, Interval<D1+D2>, Interval<D1+D2> > { };
+ template <int D1, int D2> struct NewDomain2< Interval<D1>, RightDomain<D2> > : public NewDomain2Base< Interval<D1>, RightDomain<D2>, Interval<D1+D2>, Interval<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< RightDomain<D1>, Interval<D2> > : public NewDomain2Base< RightDomain<D1>, Interval<D2>, Interval<D1+D2>, Interval<D1+D2> > { };
+ template <int D1, int DS1, int D2> struct NewDomain2< SliceInterval<D1,DS1>, Loc<D2> > : public NewDomain2Base< SliceInterval<D1,DS1>, Loc<D2>, SliceInterval<D1+D2,DS1>, SliceInterval<D1+D2,DS1> > { }; template <int D1, int DS1, int D2> struct NewDomain2< Loc<D2>, SliceInterval<D1,DS1> > : public NewDomain2Base< Loc<D2>, SliceInterval<D1,DS1>, SliceInterval<D1+D2,DS1>, SliceInterval<D1+D2,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, char > : public NewDomain2Base< SliceInterval<D1,DS1>, char ,SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, unsigned char > : public NewDomain2Base< SliceInterval<D1,DS1>, unsigned char, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< char, SliceInterval<D1,DS1> > : public NewDomain2Base< char, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; templat!
e <int D1, int DS1> struct NewDomain2< unsigned char, SliceInterval<D1,DS1> > : public NewDomain2Base< unsigned char, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, short > : public NewDomain2Base< SliceInterval<D1,DS1>, short ,SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, unsigned short > : public NewDomain2Base< SliceInterval<D1,DS1>, unsigned short, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< short, SliceInterval<D1,DS1> > : public NewDomain2Base< short, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned short, SliceInterval<D1,DS1> > : public NewDomain2Base< unsigned short, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; tem!
plate <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS!
1>, int
> : public NewDomain2Base< SliceInterval<D1,DS1>, int ,SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, unsigned int > : public NewDomain2Base< SliceInterval<D1,DS1>, unsigned int, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< int, SliceInterval<D1,DS1> > : public NewDomain2Base< int, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned int, SliceInterval<D1,DS1> > : public NewDomain2Base< unsigned int, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, long > : public NewDomain2Base< SliceInterval<D1,DS1>, long ,SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< SliceInterval<D1,DS1>, unsigned long > : public NewDomain2!
Base< SliceInterval<D1,DS1>, unsigned long, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< long, SliceInterval<D1,DS1> > : public NewDomain2Base< long, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { }; template <int D1, int DS1> struct NewDomain2< unsigned long, SliceInterval<D1,DS1> > : public NewDomain2Base< unsigned long, SliceInterval<D1,DS1>, SliceInterval<D1+1,DS1>, SliceInterval<D1+1,DS1> > { };
+ template <int D1, int DS1, int D2> struct NewDomain2< SliceInterval<D1,DS1>, Interval<D2> > : public NewDomain2Base< SliceInterval<D1,DS1>, Interval<D2>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< Interval<D2>, SliceInterval<D1,DS1> > : public NewDomain2Base< Interval<D2>, SliceInterval<D1,DS1>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { };
+ template <int D1, int DS1, int D2> struct NewDomain2< SliceInterval<D1,DS1>, Range<D2> > : public NewDomain2Base< SliceInterval<D1,DS1>, Range<D2>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< Range<D2>, SliceInterval<D1,DS1> > : public NewDomain2Base< Range<D2>, SliceInterval<D1,DS1>, SliceRange<D1+D2,DS1+D2>, SliceRange<D1+D2,DS1+D2> > { };
+ template <int D1, int DS1, int D2> struct NewDomain2< SliceInterval<D1,DS1>, AllDomain<D2> > : public NewDomain2Base< SliceInterval<D1,DS1>, AllDomain<D2>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< AllDomain<D2>, SliceInterval<D1,DS1> > : public NewDomain2Base< AllDomain<D2>, SliceInterval<D1,DS1>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { };
+ template <int D1, int DS1, int D2> struct NewDomain2< SliceInterval<D1,DS1>, LeftDomain<D2> > : public NewDomain2Base< SliceInterval<D1,DS1>, LeftDomain<D2>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< LeftDomain<D2>, SliceInterval<D1,DS1> > : public NewDomain2Base< LeftDomain<D2>, SliceInterval<D1,DS1>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { };
+ template <int D1, int DS1, int D2> struct NewDomain2< SliceInterval<D1,DS1>, RightDomain<D2> > : public NewDomain2Base< SliceInterval<D1,DS1>, RightDomain<D2>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { }; template <int D1, int DS1, int D2> struct NewDomain2< RightDomain<D2>, SliceInterval<D1,DS1> > : public NewDomain2Base< RightDomain<D2>, SliceInterval<D1,DS1>, SliceInterval<D1+D2,DS1+D2>, SliceInterval<D1+D2,DS1+D2> > { };
+ template <int D1, int D2> struct NewDomain2< AllDomain<D1>, AllDomain<D2> > : public NewDomain2Base< AllDomain<D1>, AllDomain<D2>, AllDomain<D1+D2>, AllDomain<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< AllDomain<D1>, Loc<D2> > : public NewDomain2Base< AllDomain<D1>, Loc<D2>, AllDomain<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D1, int D2> struct NewDomain2< Loc<D2>, AllDomain<D1> > : public NewDomain2Base< Loc<D2>, AllDomain<D1>, AllDomain<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D> struct NewDomain2< AllDomain<D>, char > : public NewDomain2Base< AllDomain<D>, char, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< char, AllDomain<D> > : public NewDomain2Base< char, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< AllDomain<D>, unsigned char > : public NewDomain2Base< AllDomain<D>, unsigned char, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struc!
t NewDomain2< unsigned char, AllDomain<D> > : public NewDomain2Base< unsigned char, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< AllDomain<D>, short > : public NewDomain2Base< AllDomain<D>, short, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< short, AllDomain<D> > : public NewDomain2Base< short, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< AllDomain<D>, unsigned short > : public NewDomain2Base< AllDomain<D>, unsigned short, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned short, AllDomain<D> > : public NewDomain2Base< unsigned short, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< AllDomain<D>, int > : public NewDomain2Base< AllDomain<D>, int, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< int, AllDomain<D> > : public NewDomain!
2Base< int, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D>!
> { };
template <int D> struct NewDomain2< AllDomain<D>, unsigned int > : public NewDomain2Base< AllDomain<D>, unsigned int, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned int, AllDomain<D> > : public NewDomain2Base< unsigned int, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< AllDomain<D>, long > : public NewDomain2Base< AllDomain<D>, long, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< long, AllDomain<D> > : public NewDomain2Base< long, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< AllDomain<D>, unsigned long > : public NewDomain2Base< AllDomain<D>, unsigned long, AllDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned long, AllDomain<D> > : public NewDomain2Base< unsigned long, AllDomain<D>, AllDomain<D+1>, SliceInterval<D+1,D> > { };
+ template <int D1, int D2> struct NewDomain2< LeftDomain<D1>, LeftDomain<D2> > : public NewDomain2Base< LeftDomain<D1>, LeftDomain<D2>, LeftDomain<D1+D2>, LeftDomain<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< LeftDomain<D1>, Loc<D2> > : public NewDomain2Base< LeftDomain<D1>, Loc<D2>, LeftDomain<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D1, int D2> struct NewDomain2< Loc<D2>, LeftDomain<D1> > : public NewDomain2Base< Loc<D2>, LeftDomain<D1>, LeftDomain<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D> struct NewDomain2< LeftDomain<D>, char > : public NewDomain2Base< LeftDomain<D>, char, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< char, LeftDomain<D> > : public NewDomain2Base< char, LeftDomain<D>, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< LeftDomain<D>, unsigned char > : public NewDomain2Base< LeftDomain<D>, unsigned char, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; t!
emplate <int D> struct NewDomain2< unsigned char, LeftDomain<D> > : public NewDomain2Base< unsigned char, LeftDomain<D>, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< LeftDomain<D>, short > : public NewDomain2Base< LeftDomain<D>, short, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< short, LeftDomain<D> > : public NewDomain2Base< short, LeftDomain<D>, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< LeftDomain<D>, unsigned short > : public NewDomain2Base< LeftDomain<D>, unsigned short, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned short, LeftDomain<D> > : public NewDomain2Base< unsigned short, LeftDomain<D>, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< LeftDomain<D>, int > : public NewDomain2Base< LeftDomain<D>, int, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2<!
int, LeftDomain<D> > : public NewDomain2Base< int, LeftDomain!
<D>, Lef
tDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< LeftDomain<D>, unsigned int > : public NewDomain2Base< LeftDomain<D>, unsigned int, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned int, LeftDomain<D> > : public NewDomain2Base< unsigned int, LeftDomain<D>, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< LeftDomain<D>, long > : public NewDomain2Base< LeftDomain<D>, long, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< long, LeftDomain<D> > : public NewDomain2Base< long, LeftDomain<D>, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< LeftDomain<D>, unsigned long > : public NewDomain2Base< LeftDomain<D>, unsigned long, LeftDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned long, LeftDomain<D> > : public NewDomain2Base< unsigned long, LeftDomain<D>, LeftDomain<D+1>, SliceInterval!
<D+1,D> > { };
+ template <int D1, int D2> struct NewDomain2< RightDomain<D1>, RightDomain<D2> > : public NewDomain2Base< RightDomain<D1>, RightDomain<D2>, RightDomain<D1+D2>, RightDomain<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< RightDomain<D1>, Loc<D2> > : public NewDomain2Base< RightDomain<D1>, Loc<D2>, RightDomain<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D1, int D2> struct NewDomain2< Loc<D2>, RightDomain<D1> > : public NewDomain2Base< Loc<D2>, RightDomain<D1>, RightDomain<D1+D2>, SliceInterval<D1+D2,D1> > { }; template <int D> struct NewDomain2< RightDomain<D>, char > : public NewDomain2Base< RightDomain<D>, char, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< char, RightDomain<D> > : public NewDomain2Base< char, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< RightDomain<D>, unsigned char > : public NewDomain2Base< RightDomain<D>, unsigned char, RightDomain<D+1>, SliceInt!
erval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned char, RightDomain<D> > : public NewDomain2Base< unsigned char, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< RightDomain<D>, short > : public NewDomain2Base< RightDomain<D>, short, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< short, RightDomain<D> > : public NewDomain2Base< short, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< RightDomain<D>, unsigned short > : public NewDomain2Base< RightDomain<D>, unsigned short, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned short, RightDomain<D> > : public NewDomain2Base< unsigned short, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< RightDomain<D>, int > : public NewDomain2Base< RightDomain<D>, int, RightDomain<D+1>, SliceInterval<D+1,D> > {!
}; template <int D> struct NewDomain2< int, RightDomain<D> > !
: public
NewDomain2Base< int, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< RightDomain<D>, unsigned int > : public NewDomain2Base< RightDomain<D>, unsigned int, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned int, RightDomain<D> > : public NewDomain2Base< unsigned int, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< RightDomain<D>, long > : public NewDomain2Base< RightDomain<D>, long, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< long, RightDomain<D> > : public NewDomain2Base< long, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< RightDomain<D>, unsigned long > : public NewDomain2Base< RightDomain<D>, unsigned long, RightDomain<D+1>, SliceInterval<D+1,D> > { }; template <int D> struct NewDomain2< unsigned long, RightDomain<D> > : public NewDomain2Base< un!
signed long, RightDomain<D>, RightDomain<D+1>, SliceInterval<D+1,D> > { };
+ template <int D1, int D2> struct NewDomain2< AllDomain<D1>, LeftDomain<D2> > : public NewDomain2Base< AllDomain<D1>, LeftDomain<D2>, AllDomain<D1+D2>, AllDomain<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< LeftDomain<D1>, AllDomain<D2> > : public NewDomain2Base< LeftDomain<D1>, AllDomain<D2>, AllDomain<D1+D2>, AllDomain<D1+D2> > { };
+ template <int D1, int D2> struct NewDomain2< AllDomain<D1>, RightDomain<D2> > : public NewDomain2Base< AllDomain<D1>, RightDomain<D2>, AllDomain<D1+D2>, AllDomain<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< RightDomain<D1>, AllDomain<D2> > : public NewDomain2Base< RightDomain<D1>, AllDomain<D2>, AllDomain<D1+D2>, AllDomain<D1+D2> > { };
+ template <int D1, int D2> struct NewDomain2< LeftDomain<D1>, RightDomain<D2> > : public NewDomain2Base< LeftDomain<D1>, RightDomain<D2>, LeftDomain<D1+D2>, LeftDomain<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< RightDomain<D1>, LeftDomain<D2> > : public NewDomain2Base< RightDomain<D1>, LeftDomain<D2>, LeftDomain<D1+D2>, LeftDomain<D1+D2> > { };
+ template <int D1, int D2> struct NewDomain2< Grid<D1>, Grid<D2> > : public NewDomain2Base< Grid<D1>, Grid<D2>, Grid<D1+D2>, Grid<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< Grid<D1>, Loc<D2> > : public NewDomain2Base< Grid<D1>, Loc<D2>, Grid<D1+D2>, SliceRange<D1+D2,D1> > { }; template <int D1, int D2> struct NewDomain2< Loc<D2>, Grid<D1> > : public NewDomain2Base< Loc<D2>, Grid<D1>, Grid<D1+D2>, SliceRange<D1+D2,D1> > { }; template <int D> struct NewDomain2< Grid<D>, char > : public NewDomain2Base< Grid<D>, char, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< char, Grid<D> > : public NewDomain2Base< char, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Grid<D>, unsigned char > : public NewDomain2Base< Grid<D>, unsigned char, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< unsigned char, Grid<D> > : public NewDomain2Base< unsigned char, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > {!
}; template <int D> struct NewDomain2< Grid<D>, short > : public NewDomain2Base< Grid<D>, short, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< short, Grid<D> > : public NewDomain2Base< short, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Grid<D>, unsigned short > : public NewDomain2Base< Grid<D>, unsigned short, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< unsigned short, Grid<D> > : public NewDomain2Base< unsigned short, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Grid<D>, int > : public NewDomain2Base< Grid<D>, int, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< int, Grid<D> > : public NewDomain2Base< int, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Grid<D>, unsigned int > : public NewDomain2Base< Grid<D>, unsigned int, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomai!
n2< unsigned int, Grid<D> > : public NewDomain2Base< unsigned !
int, Gri
d<D>, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Grid<D>, long > : public NewDomain2Base< Grid<D>, long, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< long, Grid<D> > : public NewDomain2Base< long, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< Grid<D>, unsigned long > : public NewDomain2Base< Grid<D>, unsigned long, Grid<D+1>, SliceRange<D+1,D> > { }; template <int D> struct NewDomain2< unsigned long, Grid<D> > : public NewDomain2Base< unsigned long, Grid<D>, Grid<D+1>, SliceRange<D+1,D> > { };
+ template <int D1, int D2> struct NewDomain2< Grid<D1>, Range<D2> > : public NewDomain2Base< Grid<D1>, Range<D2>, Grid<D1+D2>, Grid<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< Range<D1>, Grid<D2> > : public NewDomain2Base< Range<D1>, Grid<D2>, Grid<D1+D2>, Grid<D1+D2> > { };
+ template <int D1, int D2> struct NewDomain2< Grid<D1>, Interval<D2> > : public NewDomain2Base< Grid<D1>, Interval<D2>, Grid<D1+D2>, Grid<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< Interval<D1>, Grid<D2> > : public NewDomain2Base< Interval<D1>, Grid<D2>, Grid<D1+D2>, Grid<D1+D2> > { };
+ template <int D1, int D2> struct NewDomain2< Grid<D1>, AllDomain<D2> > : public NewDomain2Base< Grid<D1>, AllDomain<D2>, Grid<D1+D2>, Grid<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< AllDomain<D1>, Grid<D2> > : public NewDomain2Base< AllDomain<D1>, Grid<D2>, Grid<D1+D2>, Grid<D1+D2> > { };
+ template <int D1, int D2> struct NewDomain2< Grid<D1>, LeftDomain<D2> > : public NewDomain2Base< Grid<D1>, LeftDomain<D2>, Grid<D1+D2>, Grid<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< LeftDomain<D1>, Grid<D2> > : public NewDomain2Base< LeftDomain<D1>, Grid<D2>, Grid<D1+D2>, Grid<D1+D2> > { };
+ template <int D1, int D2> struct NewDomain2< Grid<D1>, RightDomain<D2> > : public NewDomain2Base< Grid<D1>, RightDomain<D2>, Grid<D1+D2>, Grid<D1+D2> > { }; template <int D1, int D2> struct NewDomain2< RightDomain<D1>, Grid<D2> > : public NewDomain2Base< RightDomain<D1>, Grid<D2>, Grid<D1+D2>, Grid<D1+D2> > { };
+ template<int D>
+ struct NewDomain2< Grid<D>, IndirectionList<int> >
+ : public NewDomain2Base<Grid<D>,IndirectionList<int>,Grid<D+1>,Grid<D+1> >{};
+ template<int D>
+ struct NewDomain2< IndirectionList<int>, Grid<D> >
+ : public NewDomain2Base<IndirectionList<int>,Grid<D>,Grid<D+1>,Grid<D+1> >{};
+ template<int D1, int D2>
+ struct NewDomain2< Loc<D1>, Loc<D2> >
+ : public NewDomain2Base<Loc<D1>, Loc<D2>, Loc<D1+D2>, Loc<D1+D2> > { };
+ template <int D1, class T1, int D2, class T2> struct NewDomain2< Region<D1,T1>, Region<D2,T2> > : public NewDomain2Base< Region<D1,T1>, Region<D2,T2>, Region<D1+D2,T1>, Region<D1+D2,T1> > { };
+ template <int D1, class T1> struct NewDomain2< Region<D1,T1>, char > : public NewDomain2Base< Region<D1,T1>, char, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< char, Region<D1,T1> > : public NewDomain2Base< char, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
+ template <int D1, class T1> struct NewDomain2< Region<D1,T1>, unsigned char > : public NewDomain2Base< Region<D1,T1>, unsigned char, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< unsigned char, Region<D1,T1> > : public NewDomain2Base< unsigned char, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
+ template <int D1, class T1> struct NewDomain2< Region<D1,T1>, short > : public NewDomain2Base< Region<D1,T1>, short, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< short, Region<D1,T1> > : public NewDomain2Base< short, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
+ template <int D1, class T1> struct NewDomain2< Region<D1,T1>, unsigned short > : public NewDomain2Base< Region<D1,T1>, unsigned short, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< unsigned short, Region<D1,T1> > : public NewDomain2Base< unsigned short, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
+ template <int D1, class T1> struct NewDomain2< Region<D1,T1>, int > : public NewDomain2Base< Region<D1,T1>, int, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< int, Region<D1,T1> > : public NewDomain2Base< int, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
+ template <int D1, class T1> struct NewDomain2< Region<D1,T1>, unsigned int > : public NewDomain2Base< Region<D1,T1>, unsigned int, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< unsigned int, Region<D1,T1> > : public NewDomain2Base< unsigned int, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
+ template <int D1, class T1> struct NewDomain2< Region<D1,T1>, long > : public NewDomain2Base< Region<D1,T1>, long, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< long, Region<D1,T1> > : public NewDomain2Base< long, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
+ template <int D1, class T1> struct NewDomain2< Region<D1,T1>, unsigned long > : public NewDomain2Base< Region<D1,T1>, unsigned long, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< unsigned long, Region<D1,T1> > : public NewDomain2Base< unsigned long, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
+ template <int D1, class T1> struct NewDomain2< Region<D1,T1>, float > : public NewDomain2Base< Region<D1,T1>, float, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< float, Region<D1,T1> > : public NewDomain2Base< float, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
+ template <int D1, class T1> struct NewDomain2< Region<D1,T1>, double > : public NewDomain2Base< Region<D1,T1>, double, Region<D1+1,T1>, Region<D1+1,T1> > { }; template <int D1, class T1> struct NewDomain2< double, Region<D1,T1> > : public NewDomain2Base< double, Region<D1,T1>, Region<D1+1,T1>, Region<D1+1,T1> > { };
+ template <int D1, class T1, int D2> struct NewDomain2< Region<D1,T1>, Range<D2> > : public NewDomain2Base< Region<D1,T1>, Range<D2>, Region<D1+D2,T1>, Region<D1+D2,T1> > { }; template <int D1, class T1, int D2> struct NewDomain2< Range<D2>, Region<D1,T1> > : public NewDomain2Base< Range<D2>, Region<D1,T1>, Region<D1+D2,T1>, Region<D1+D2,T1> > { };
+ template <int D1, class T1, int D2> struct NewDomain2< Region<D1,T1>, Interval<D2> > : public NewDomain2Base< Region<D1,T1>, Interval<D2>, Region<D1+D2,T1>, Region<D1+D2,T1> > { }; template <int D1, class T1, int D2> struct NewDomain2< Interval<D2>, Region<D1,T1> > : public NewDomain2Base< Interval<D2>, Region<D1,T1>, Region<D1+D2,T1>, Region<D1+D2,T1> > { };
+ template <int D1, class T1, int D2> struct NewDomain2< Region<D1,T1>, Loc<D2> > : public NewDomain2Base< Region<D1,T1>, Loc<D2>, Region<D1+D2,T1>, Region<D1+D2,T1> > { }; template <int D1, class T1, int D2> struct NewDomain2< Loc<D2>, Region<D1,T1> > : public NewDomain2Base< Loc<D2>, Region<D1,T1>, Region<D1+D2,T1>, Region<D1+D2,T1> > { };
+ template <int D1, class T1, int D2> struct NewDomain2< Region<D1,T1>, AllDomain<D2> > : public NewDomain2Base< Region<D1,T1>, AllDomain<D2>, Region<D1+D2,T1>, Region<D1+D2,T1> > { }; template <int D1, class T1, int D2> struct NewDomain2< AllDomain<D2>, Region<D1,T1> > : public NewDomain2Base< AllDomain<D2>, Region<D1,T1>, Region<D1+D2,T1>, Region<D1+D2,T1> > { };
+ template <int D1, class T1, int D2> struct NewDomain2< Region<D1,T1>, LeftDomain<D2> > : public NewDomain2Base< Region<D1,T1>, LeftDomain<D2>, Region<D1+D2,T1>, Region<D1+D2,T1> > { }; template <int D1, class T1, int D2> struct NewDomain2< LeftDomain<D2>, Region<D1,T1> > : public NewDomain2Base< LeftDomain<D2>, Region<D1,T1>, Region<D1+D2,T1>, Region<D1+D2,T1> > { };
+ template <int D1, class T1, int D2> struct NewDomain2< Region<D1,T1>, RightDomain<D2> > : public NewDomain2Base< Region<D1,T1>, RightDomain<D2>, Region<D1+D2,T1>, Region<D1+D2,T1> > { }; template <int D1, class T1, int D2> struct NewDomain2< RightDomain<D2>, Region<D1,T1> > : public NewDomain2Base< RightDomain<D2>, Region<D1,T1>, Region<D1+D2,T1>, Region<D1+D2,T1> > { };
+ template <> struct NewDomain2<double, double> : public NewDomain2Base< double, double, Region<2,double>, Region<2,double> > { };
+ template <> struct NewDomain2<float, float> : public NewDomain2Base< float, float, Region<2,float>, Region<2,float> > { };
+ template <> struct NewDomain2<double, char> : public NewDomain2Base< double, char, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<char, double> : public NewDomain2Base< char, double, Region<2,double>, Region<2,double> > { };
+ template <> struct NewDomain2<double, unsigned char> : public NewDomain2Base< double, unsigned char, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<unsigned char, double> : public NewDomain2Base< unsigned char, double, Region<2,double>, Region<2,double> > { };
+ template <> struct NewDomain2<double, short> : public NewDomain2Base< double, short, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<short, double> : public NewDomain2Base< short, double, Region<2,double>, Region<2,double> > { };
+ template <> struct NewDomain2<double, unsigned short> : public NewDomain2Base< double, unsigned short, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<unsigned short, double> : public NewDomain2Base< unsigned short, double, Region<2,double>, Region<2,double> > { };
+ template <> struct NewDomain2<double, int> : public NewDomain2Base< double, int, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<int, double> : public NewDomain2Base< int, double, Region<2,double>, Region<2,double> > { };
+ template <> struct NewDomain2<double, unsigned int> : public NewDomain2Base< double, unsigned int, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<unsigned int, double> : public NewDomain2Base< unsigned int, double, Region<2,double>, Region<2,double> > { };
+ template <> struct NewDomain2<double, long> : public NewDomain2Base< double, long, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<long, double> : public NewDomain2Base< long, double, Region<2,double>, Region<2,double> > { };
+ template <> struct NewDomain2<double, unsigned long> : public NewDomain2Base< double, unsigned long, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<unsigned long, double> : public NewDomain2Base< unsigned long, double, Region<2,double>, Region<2,double> > { };
+ template <> struct NewDomain2<double, float> : public NewDomain2Base< double, float, Region<2,double>, Region<2,double> > { }; template <> struct NewDomain2<float, double> : public NewDomain2Base< float, double, Region<2,double>, Region<2,double> > { };
+ template <> struct NewDomain2<float, char> : public NewDomain2Base< float, char, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<char, float> : public NewDomain2Base< char, float, Region<2,float>, Region<2,float> > { };
+ template <> struct NewDomain2<float, unsigned char> : public NewDomain2Base< float, unsigned char, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<unsigned char, float> : public NewDomain2Base< unsigned char, float, Region<2,float>, Region<2,float> > { };
+ template <> struct NewDomain2<float, short> : public NewDomain2Base< float, short, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<short, float> : public NewDomain2Base< short, float, Region<2,float>, Region<2,float> > { };
+ template <> struct NewDomain2<float, unsigned short> : public NewDomain2Base< float, unsigned short, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<unsigned short, float> : public NewDomain2Base< unsigned short, float, Region<2,float>, Region<2,float> > { };
+ template <> struct NewDomain2<float, int> : public NewDomain2Base< float, int, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<int, float> : public NewDomain2Base< int, float, Region<2,float>, Region<2,float> > { };
+ template <> struct NewDomain2<float, unsigned int> : public NewDomain2Base< float, unsigned int, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<unsigned int, float> : public NewDomain2Base< unsigned int, float, Region<2,float>, Region<2,float> > { };
+ template <> struct NewDomain2<float, long> : public NewDomain2Base< float, long, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<long, float> : public NewDomain2Base< long, float, Region<2,float>, Region<2,float> > { };
+ template <> struct NewDomain2<float, unsigned long> : public NewDomain2Base< float, unsigned long, Region<2,float>, Region<2,float> > { }; template <> struct NewDomain2<unsigned long, float> : public NewDomain2Base< unsigned long, float, Region<2,float>, Region<2,float> > { };
+ template <int D1> struct NewDomain2< double, Loc<D1> > : public NewDomain2Base< double, Loc<D1>, Region<D1+1,double>, Region<D1+1,double> > { }; template <int D1> struct NewDomain2< Loc<D1>, double > : public NewDomain2Base< Loc<D1>, double, Region<D1+1,double>, Region<D1+1,double> > { };
+ template <int D1> struct NewDomain2< double, Interval<D1> > : public NewDomain2Base< double, Interval<D1>, Region<D1+1,double>, Region<D1+1,double> > { }; template <int D1> struct NewDomain2< Interval<D1>, double > : public NewDomain2Base< Interval<D1>, double, Region<D1+1,double>, Region<D1+1,double> > { };
+ template <int D1> struct NewDomain2< double, Range<D1> > : public NewDomain2Base< double, Range<D1>, Region<D1+1,double>, Region<D1+1,double> > { }; template <int D1> struct NewDomain2< Range<D1>, double > : public NewDomain2Base< Range<D1>, double, Region<D1+1,double>, Region<D1+1,double> > { };
+ template <int D1> struct NewDomain2< float, Loc<D1> > : public NewDomain2Base< float, Loc<D1>, Region<D1+1,float>, Region<D1+1,float> > { }; template <int D1> struct NewDomain2< Loc<D1>, float > : public NewDomain2Base< Loc<D1>, float, Region<D1+1,float>, Region<D1+1,float> > { };
+ template <int D1> struct NewDomain2< float, Interval<D1> > : public NewDomain2Base< float, Interval<D1>, Region<D1+1,float>, Region<D1+1,float> > { }; template <int D1> struct NewDomain2< Interval<D1>, float > : public NewDomain2Base< Interval<D1>, float, Region<D1+1,float>, Region<D1+1,float> > { };
+ template <int D1> struct NewDomain2< float, Range<D1> > : public NewDomain2Base< float, Range<D1>, Region<D1+1,float>, Region<D1+1,float> > { }; template <int D1> struct NewDomain2< Range<D1>, float > : public NewDomain2Base< Range<D1>, float, Region<D1+1,float>, Region<D1+1,float> > { };
+ template<class ND, class T>
+ struct NewDomainNBase
+ {
+ typedef typename ND::Type_t PrevType_t;
+ typedef typename ND::SliceType_t PrevSliceType_t;
+ typedef typename NewDomain2<PrevType_t,T>::Type_t Type_t;
+ typedef typename NewDomain2<PrevSliceType_t,T>::SliceType_t SliceType_t;
+ };
+ template<class T1>
+ struct NewDomain1
+ {
+ typedef typename DomainTraits<T1>::Domain_t Type_t;
+ typedef typename DomainTraits<T1>::NewDomain1_t SliceType_t;
+ enum { DX1 = DomainTraits<T1>::sliceDimensions };
+ inline static Type_t combine(const T1 &a)
+ {
+ Type_t retval = Pooma::NoInit();
+ return fill(retval, a);
+ }
+ template<class RT>
+ inline static RT &fill(RT &retval, const T1 &a)
+ {
+ CombineDomain<RT,T1,0>::combine(retval,a);
+ return retval;
+ }
+ template<class UT>
+ inline static SliceType_t combineSlice(const UT &u, const T1 &a)
+ {
+ SliceType_t retval = Pooma::NoInit();
+ return fillSlice(retval, u, a);
+ }
+ template<class RT, class UT>
+ inline static RT &fillSlice(RT &retval, const UT &u,
+ const T1 &a)
+ {
+ enum { RDX =
+ DomainTraits<RT>::dimensions > DomainTraits<RT>::sliceDimensions };
+ CombineSliceDomain<RT,UT,T1,0,0,(DX1>0 && RDX)>::combine(retval,u,a);
+ return retval;
+ }
+ };
+ template<class T1, class T2, class T3>
+ struct NewDomain3 : public NewDomainNBase<NewDomain2<T1,T2>, T3>
+ {
+ typedef typename NewDomainNBase<NewDomain2<T1,T2>, T3>::Type_t Type_t;
+ typedef typename NewDomainNBase<NewDomain2<T1,T2>, T3>::SliceType_t SliceType_t;
+ enum { S2 = DomainTraits<T1>::dimensions };
+ enum { S3 = S2 + DomainTraits<T2>::dimensions };
+ enum { DX1 = DomainTraits<T1>::sliceDimensions };
+ enum { DX2 = DomainTraits<T2>::sliceDimensions };
+ enum { DX3 = DomainTraits<T3>::sliceDimensions };
+ inline static Type_t combine(const T1 &a, const T2 &b, const T3 &c)
+ {
+ Type_t retval = Pooma::NoInit();
+ return fill(retval, a, b, c);
+ }
+ template<class RT>
+ inline static RT &fill(RT &retval,
+ const T1 &a, const T2 &b, const T3 &c)
+ {
+ CombineDomain<RT,T1,0>::combine(retval,a);
+ CombineDomain<RT,T2,S2>::combine(retval,b);
+ CombineDomain<RT,T3,S3>::combine(retval,c);
+ return retval;
+ }
+ template<class UT>
+ inline static SliceType_t combineSlice(const UT &u,
+ const T1 &a, const T2 &b, const T3 &c)
+ {
+ SliceType_t retval = Pooma::NoInit();
+ return fillSlice(retval, u, a, b, c);
+ }
+ template<class RT, class UT>
+ inline static RT &fillSlice(RT &retval, const UT &u,
+ const T1 &a, const T2 &b, const T3 &c)
+ {
+ enum { RDX =
+ DomainTraits<RT>::dimensions > DomainTraits<RT>::sliceDimensions };
+ CombineSliceDomain<RT,UT,T1,0,0,(DX1>0 && RDX)>::combine(retval,u,a);
+ CombineSliceDomain<RT,UT,T2,S2,DX1,(DX2>0 && RDX)>::combine(retval,u,b);
+ CombineSliceDomain<RT,UT,T3,S3,DX1+DX2,(DX3>0 && RDX)>::
+ combine(retval,u,c);
+ return retval;
+ }
+ };
+ template<class T1, class T2, class T3, class T4>
+ struct NewDomain4 : public NewDomainNBase<NewDomain3<T1,T2,T3>, T4>
+ {
+ typedef typename NewDomainNBase<NewDomain3<T1,T2,T3>, T4>::Type_t Type_t;
+ typedef typename NewDomainNBase<NewDomain3<T1,T2,T3>, T4>::SliceType_t
+ SliceType_t;
+ enum { S2 = DomainTraits<T1>::dimensions };
+ enum { S3 = S2 + DomainTraits<T2>::dimensions };
+ enum { S4 = S3 + DomainTraits<T3>::dimensions };
+ enum { DX1 = DomainTraits<T1>::sliceDimensions };
+ enum { DX2 = DomainTraits<T2>::sliceDimensions };
+ enum { DX3 = DomainTraits<T3>::sliceDimensions };
+ enum { DX4 = DomainTraits<T4>::sliceDimensions };
+ inline static Type_t combine(const T1 &a, const T2 &b, const T3 &c,
+ const T4 &d)
+ {
+ Type_t retval = Pooma::NoInit();
+ return fill(retval, a, b, c, d);
+ }
+ template<class RT>
+ inline static RT &fill(RT &retval,
+ const T1 &a, const T2 &b, const T3 &c,
+ const T4 &d)
+ {
+ CombineDomain<RT,T1,0>::combine(retval,a);
+ CombineDomain<RT,T2,S2>::combine(retval,b);
+ CombineDomain<RT,T3,S3>::combine(retval,c);
+ CombineDomain<RT,T4,S4>::combine(retval,d);
+ return retval;
+ }
+ template<class UT>
+ inline static SliceType_t combineSlice(const UT &u,
+ const T1 &a, const T2 &b, const T3 &c,
+ const T4 &d)
+ {
+ SliceType_t retval = Pooma::NoInit();
+ return fillSlice(retval, u, a, b, c, d);
+ }
+ template<class RT, class UT>
+ inline static RT &fillSlice(RT &retval, const UT &u,
+ const T1 &a, const T2 &b, const T3 &c,
+ const T4 &d)
+ {
+ enum { RDX =
+ DomainTraits<RT>::dimensions > DomainTraits<RT>::sliceDimensions };
+ CombineSliceDomain<RT,UT,T1,0,0,(DX1>0 && RDX)>::combine(retval,u,a);
+ CombineSliceDomain<RT,UT,T2,S2,DX1,(DX2>0 && RDX)>::combine(retval,u,b);
+ CombineSliceDomain<RT,UT,T3,S3,DX1+DX2,(DX3>0 && RDX)>::
+ combine(retval,u,c);
+ CombineSliceDomain<RT,UT,T4,S4,DX1+DX2+DX3,(DX4>0 && RDX)>::
+ combine(retval,u,d);
+ return retval;
+ }
+ };
+ template<class T1, class T2, class T3, class T4, class T5>
+ struct NewDomain5 : public NewDomainNBase<NewDomain4<T1,T2,T3,T4>, T5>
+ {
+ typedef typename NewDomainNBase<NewDomain4<T1,T2,T3,T4>, T5>::Type_t Type_t;
+ typedef typename NewDomainNBase<NewDomain4<T1,T2,T3,T4>, T5>::SliceType_t
+ SliceType_t;
+ enum { S2 = DomainTraits<T1>::dimensions };
+ enum { S3 = S2 + DomainTraits<T2>::dimensions };
+ enum { S4 = S3 + DomainTraits<T3>::dimensions };
+ enum { S5 = S4 + DomainTraits<T4>::dimensions };
+ enum { DX1 = DomainTraits<T1>::sliceDimensions };
+ enum { DX2 = DomainTraits<T2>::sliceDimensions };
+ enum { DX3 = DomainTraits<T3>::sliceDimensions };
+ enum { DX4 = DomainTraits<T4>::sliceDimensions };
+ enum { DX5 = DomainTraits<T5>::sliceDimensions };
+ inline static Type_t combine(const T1 &a, const T2 &b, const T3 &c,
+ const T4 &d, const T5 &e)
+ {
+ Type_t retval = Pooma::NoInit();
+ return fill(retval, a, b, c, d, e);
+ }
+ template<class RT>
+ inline static RT &fill(RT &retval,
+ const T1 &a, const T2 &b, const T3 &c,
+ const T4 &d, const T5 &e)
+ {
+ CombineDomain<RT,T1,0>::combine(retval,a);
+ CombineDomain<RT,T2,S2>::combine(retval,b);
+ CombineDomain<RT,T3,S3>::combine(retval,c);
+ CombineDomain<RT,T4,S4>::combine(retval,d);
+ CombineDomain<RT,T5,S5>::combine(retval,e);
+ return retval;
+ }
+ template<class UT>
+ inline static SliceType_t combineSlice(const UT &u,
+ const T1 &a, const T2 &b, const T3 &c,
+ const T4 &d, const T5 &e)
+ {
+ SliceType_t retval = Pooma::NoInit();
+ return fillSlice(retval, u, a, b, c, d, e);
+ }
+ template<class RT, class UT>
+ inline static RT &fillSlice(RT &retval, const UT &u,
+ const T1 &a, const T2 &b, const T3 &c,
+ const T4 &d, const T5 &e)
+ {
+ enum { RDX =
+ DomainTraits<RT>::dimensions > DomainTraits<RT>::sliceDimensions };
+ CombineSliceDomain<RT,UT,T1,0,0,(DX1>0 && RDX)>::combine(retval,u,a);
+ CombineSliceDomain<RT,UT,T2,S2,DX1,(DX2>0 && RDX)>::combine(retval,u,b);
+ CombineSliceDomain<RT,UT,T3,S3,DX1+DX2,(DX3>0 && RDX)>::
+ combine(retval,u,c);
+ CombineSliceDomain<RT,UT,T4,S4,DX1+DX2+DX3,(DX4>0 && RDX)>::
+ combine(retval,u,d);
+ CombineSliceDomain<RT,UT,T5,S5,DX1+DX2+DX3+DX4,(DX5>0 && RDX)>::
+ combine(retval,u,e);
+ return retval;
+ }
+ };
+ template<class T1, class T2, class T3, class T4, class T5, class T6>
+ struct NewDomain6 : public NewDomainNBase<NewDomain5<T1,T2,T3,T4,T5>, T6>
+ {
+ typedef typename
+ NewDomainNBase<NewDomain5<T1,T2,T3,T4,T5>, T6>::Type_t Type_t;
+ typedef typename
+ NewDomainNBase<NewDomain5<T1,T2,T3,T4,T5>, T6>::SliceType_t SliceType_t;
+ enum { S2 = DomainTraits<T1>::dimensions };
+ enum { S3 = S2 + DomainTraits<T2>::dimensions };
+ enum { S4 = S3 + DomainTraits<T3>::dimensions };
+ enum { S5 = S4 + DomainTraits<T4>::dimensions };
+ enum { S6 = S5 + DomainTraits<T5>::dimensions };
+ enum { DX1 = DomainTraits<T1>::sliceDimensions };
+ enum { DX2 = DomainTraits<T2>::sliceDimensions };
+ enum { DX3 = DomainTraits<T3>::sliceDimensions };
+ enum { DX4 = DomainTraits<T4>::sliceDimensions };
+ enum { DX5 = DomainTraits<T5>::sliceDimensions };
+ enum { DX6 = DomainTraits<T6>::sliceDimensions };
+ inline static Type_t combine(const T1 &a, const T2 &b,
+ const T3 &c, const T4 &d,
+ const T5 &e, const T6 &f)
+ {
+ Type_t retval = Pooma::NoInit();
+ return fill(retval, a, b, c, d, e, f);
+ }
+ template<class RT>
+ inline static RT &fill(RT &retval,
+ const T1 &a, const T2 &b,
+ const T3 &c, const T4 &d,
+ const T5 &e, const T6 &f)
+ {
+ CombineDomain<RT,T1,0>::combine(retval,a);
+ CombineDomain<RT,T2,S2>::combine(retval,b);
+ CombineDomain<RT,T3,S3>::combine(retval,c);
+ CombineDomain<RT,T4,S4>::combine(retval,d);
+ CombineDomain<RT,T5,S5>::combine(retval,e);
+ CombineDomain<RT,T6,S6>::combine(retval,f);
+ return retval;
+ }
+ template<class UT>
+ inline static SliceType_t combineSlice(const UT &u,
+ const T1 &a, const T2 &b,
+ const T3 &c, const T4 &d,
+ const T5 &e, const T6 &f)
+ {
+ SliceType_t retval = Pooma::NoInit();
+ return fillSlice(retval, u, a, b, c, d, e, f);
+ }
+ template<class RT, class UT>
+ inline static RT &fillSlice(RT &retval, const UT &u,
+ const T1 &a, const T2 &b, const T3 &c,
+ const T4 &d, const T5 &e, const T6 &f)
+ {
+ enum { RDX =
+ DomainTraits<RT>::dimensions > DomainTraits<RT>::sliceDimensions };
+ CombineSliceDomain<RT,UT,T1,0,0,(DX1>0 && RDX)>::combine(retval,u,a);
+ CombineSliceDomain<RT,UT,T2,S2,DX1,(DX2>0 && RDX)>::combine(retval,u,b);
+ CombineSliceDomain<RT,UT,T3,S3,DX1+DX2,(DX3>0 && RDX)>::
+ combine(retval,u,c);
+ CombineSliceDomain<RT,UT,T4,S4,DX1+DX2+DX3,(DX4>0 && RDX)>::
+ combine(retval,u,d);
+ CombineSliceDomain<RT,UT,T5,S5,DX1+DX2+DX3+DX4,(DX5>0 && RDX)>::
+ combine(retval,u,e);
+ CombineSliceDomain<RT,UT,T6,S6,DX1+DX2+DX3+DX4+DX5,(DX6>0 && RDX)>::
+ combine(retval,u,f);
+ return retval;
+ }
+ };
+ template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
+ struct NewDomain7 : public NewDomainNBase<NewDomain6<T1,T2,T3,T4,T5,T6>, T7>
+ {
+ typedef typename
+ NewDomainNBase<NewDomain6<T1,T2,T3,T4,T5,T6>, T7>::Type_t Type_t;
+ typedef typename
+ NewDomainNBase<NewDomain6<T1,T2,T3,T4,T5,T6>, T7>::SliceType_t SliceType_t;
+ enum { S2 = DomainTraits<T1>::dimensions };
+ enum { S3 = S2 + DomainTraits<T2>::dimensions };
+ enum { S4 = S3 + DomainTraits<T3>::dimensions };
+ enum { S5 = S4 + DomainTraits<T4>::dimensions };
+ enum { S6 = S5 + DomainTraits<T5>::dimensions };
+ enum { S7 = S6 + DomainTraits<T6>::dimensions };
+ enum { DX1 = DomainTraits<T1>::sliceDimensions };
+ enum { DX2 = DomainTraits<T2>::sliceDimensions };
+ enum { DX3 = DomainTraits<T3>::sliceDimensions };
+ enum { DX4 = DomainTraits<T4>::sliceDimensions };
+ enum { DX5 = DomainTraits<T5>::sliceDimensions };
+ enum { DX6 = DomainTraits<T6>::sliceDimensions };
+ enum { DX7 = DomainTraits<T7>::sliceDimensions };
+ inline static Type_t combine(const T1 &a, const T2 &b,
+ const T3 &c, const T4 &d,
+ const T5 &e, const T6 &f,
+ const T7 &g)
+ {
+ Type_t retval = Pooma::NoInit();
+ NewDomain7<T1,T2,T3,T4,T5,T6,T7>::fill(retval, a, b, c, d, e, f, g);
+ return fill(retval, a, b, c, d, e, f,g);
+ }
+ template<class RT>
+ inline static RT &fill(RT &retval,
+ const T1 &a, const T2 &b,
+ const T3 &c, const T4 &d,
+ const T5 &e, const T6 &f,
+ const T7 &g)
+ {
+ CombineDomain<RT,T1,0>::combine(retval,a);
+ CombineDomain<RT,T2,S2>::combine(retval,b);
+ CombineDomain<RT,T3,S3>::combine(retval,c);
+ CombineDomain<RT,T4,S4>::combine(retval,d);
+ CombineDomain<RT,T5,S5>::combine(retval,e);
+ CombineDomain<RT,T6,S6>::combine(retval,f);
+ CombineDomain<RT,T7,S7>::combine(retval,g);
+ return retval;
+ }
+ template<class UT>
+ inline static SliceType_t combineSlice(const UT &u,
+ const T1 &a, const T2 &b,
+ const T3 &c, const T4 &d,
+ const T5 &e, const T6 &f,
+ const T7 &g)
+ {
+ SliceType_t retval = Pooma::NoInit();
+ return fillSlice(retval, u, a, b, c, d, e, f, g);
+ }
+ template<class RT, class UT>
+ inline static RT &fillSlice(RT &retval, const UT &u,
+ const T1 &a, const T2 &b,
+ const T3 &c, const T4 &d,
+ const T5 &e, const T6 &f,
+ const T7 &g)
+ {
+ enum { RDX =
+ DomainTraits<RT>::dimensions > DomainTraits<RT>::sliceDimensions };
+ CombineSliceDomain<RT,UT,T1,0,0,(DX1>0 && RDX)>::combine(retval,u,a);
+ CombineSliceDomain<RT,UT,T2,S2,DX1,(DX2>0 && RDX)>::combine(retval,u,b);
+ CombineSliceDomain<RT,UT,T3,S3,DX1+DX2,(DX3>0 && RDX)>::
+ combine(retval,u,c);
+ CombineSliceDomain<RT,UT,T4,S4,DX1+DX2+DX3,(DX4>0 && RDX)>::
+ combine(retval,u,d);
+ CombineSliceDomain<RT,UT,T5,S5,DX1+DX2+DX3+DX4,(DX5>0 && RDX)>::
+ combine(retval,u,e);
+ CombineSliceDomain<RT,UT,T6,S6,DX1+DX2+DX3+DX4+DX5,(DX6>0 && RDX)>::
+ combine(retval,u,f);
+ CombineSliceDomain<RT,UT,T7,S7,DX1+DX2+DX3+DX4+DX5+DX6,(DX7>0 && RDX)>::
+ combine(retval,u,g);
+ return retval;
+ }
+ };
+ template<class Domain, class Sub>
+ struct TemporaryNewDomain1
+ {
+ typedef typename NewDomain1<Sub>::SliceType_t SliceType_t;
+ static inline
+ SliceType_t combineSlice(const Domain &d, const Sub &s)
+ {
+ return NewDomain1<Sub>::combineSlice(d, s);
+ }
+ };
+ template<class Domain, int N>
+ struct TemporaryNewDomain1<Domain, AllDomain<N> >
+ {
+ typedef Domain SliceType_t;
+ static inline
+ const SliceType_t &combineSlice(const Domain &d, const AllDomain<N> &)
+ {
+ return d;
+ }
+ };
+ template<int Dim>
+ class Interval : public Domain<Dim, DomainTraits<Interval<Dim> > >
+ {
+ typedef DomainTraits< Interval<Dim> > DT_t;
+ typedef Domain<Dim, DT_t> Base_t;
+ public:
+ typedef typename Base_t::iterator iterator;
+ typedef typename Base_t::const_iterator const_iterator;
+ typedef typename Base_t::blockIterator blockIterator;
+ typedef typename Base_t::const_blockIterator const_blockIterator;
+ typedef typename DT_t::Element_t Element_t;
+ typedef typename DT_t::Domain_t Domain_t;
+ typedef typename DT_t::OneDomain_t OneDomain_t;
+ typedef typename DT_t::BlockDomain_t BlockDomain_t;
+ typedef typename DT_t::AskDomain_t AskDomain_t;
+ typedef typename DT_t::AddResult_t AddResult_t;
+ typedef typename DT_t::MultResult_t MultResult_t;
+ typedef typename DT_t::Storage_t Storage_t;
+ enum { domain = DT_t::domain };
+ enum { dimensions = DT_t::dimensions,
+ sliceDimensions = DT_t::sliceDimensions };
+ enum { loopAware = DT_t::loopAware };
+ enum { singleValued = DT_t::singleValued };
+ enum { unitStride = DT_t::unitStride };
+ enum { wildcard = DT_t::wildcard };
+ Interval() { }
+ Interval(const Interval<Dim> &a)
+ : Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
+ NewDomain1<Interval<Dim> >::fill(*this, a);
+ }
+ Interval(const Pooma::NoInit &a)
+ : Domain<Dim, DomainTraits<Interval<Dim> > >(a)
+ { }
+ template<class T1>
+ explicit Interval(const T1 &a)
+ : Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
+ NewDomain1<T1>::fill(*this, a);
+ }
+ template<class T1, class T2>
+ Interval(const T1 &a, const T2 &b)
+ : Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
+ NewDomain2<T1,T2>::fill(*this, a, b);
+ }
+ template<class T1, class T2, class T3>
+ Interval(const T1 &a, const T2 &b, const T3 &c)
+ : Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
+ NewDomain3<T1,T2,T3>::fill(*this, a, b, c);
+ }
+ template<class T1, class T2, class T3, class T4>
+ Interval(const T1 &a, const T2 &b, const T3 &c, const T4 &d)
+ : Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
+ NewDomain4<T1,T2,T3,T4>::fill(*this, a, b, c, d);
+ }
+ template<class T1, class T2, class T3, class T4, class T5>
+ Interval(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e)
+ : Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
+ NewDomain5<T1,T2,T3,T4,T5>::fill(*this, a, b, c, d, e);
+ }
+ template<class T1, class T2, class T3, class T4, class T5,
+ class T6>
+ Interval(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
+ const T6 &f)
+ : Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
+ NewDomain6<T1,T2,T3,T4,T5,T6>::fill(*this, a, b, c, d, e, f);
+ }
+ template<class T1, class T2, class T3, class T4, class T5,
+ class T6, class T7>
+ Interval(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
+ const T6 &f, const T7 &g)
+ : Domain<Dim, DomainTraits<Interval<Dim> > >(Pooma::NoInit()) {
+ NewDomain7<T1,T2,T3,T4,T5,T6,T7>::fill(*this, a, b, c, d, e, f, g);
+ }
+ ~Interval() { }
+ template<class T>
+ Interval<Dim> &operator=(const T &newdom) {
+ return NewDomain1<T>::fill(*this, newdom);
+ }
+ Interval<Dim> &operator=(const Interval<Dim> &newdom) {
+ return NewDomain1<Interval<Dim> >::fill(*this, newdom);
+ }
+ protected:
+ private:
+ };
+ template<>
+ class Interval<1> : public Domain<1, DomainTraits<Interval<1> > >
+ {
+ typedef DomainTraits< Interval<1> > DT_t;
+ public:
+ typedef DT_t::Element_t Element_t;
+ typedef DT_t::Domain_t Domain_t;
+ typedef DT_t::OneDomain_t OneDomain_t;
+ typedef DT_t::BlockDomain_t BlockDomain_t;
+ typedef DT_t::AskDomain_t AskDomain_t;
+ typedef DT_t::AddResult_t AddResult_t;
+ typedef DT_t::MultResult_t MultResult_t;
+ typedef DT_t::Storage_t Storage_t;
+ enum { domain = DT_t::domain };
+ enum { dimensions = DT_t::dimensions,
+ sliceDimensions = DT_t::sliceDimensions };
+ enum { loopAware = DT_t::loopAware };
+ enum { singleValued = DT_t::singleValued };
+ enum { unitStride = DT_t::unitStride };
+ enum { wildcard = DT_t::wildcard };
+ Interval() { }
+ Interval(const Interval<1> &a)
+ : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
+ NewDomain1<Interval<1> >::fill(*this, a);
+ }
+ Interval(const Pooma::NoInit &a)
+ : Domain<1, DomainTraits<Interval<1> > >(a)
+ { }
+ template<class T1>
+ explicit Interval(const T1 &a)
+ : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
+ NewDomain1<T1>::fill(*this, a);
+ }
+ Interval(char a)
+ : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
+ DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Interval(unsigned char a)
+ : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
+ DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Interval(short a)
+ : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
+ DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Interval(unsigned short a)
+ : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
+ DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Interval(int a)
+ : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
+ DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Interval(unsigned int a)
+ : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
+ DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Interval(long a)
+ : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
+ DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Interval(unsigned long a)
+ : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
+ DomainTraits<Interval<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ template<class T1, class T2>
+ Interval(const T1 &m, const T2 &n);
+ template<class T1, class T2, class T3>
+ Interval(const T1 &m, const T2 &n, const T3 &s);
+ template<class T>
+ Interval<1> &operator=(const T &newdom) {
+ return NewDomain1<T>::fill(*this, newdom);
+ }
+ Interval<1> &operator=(const Interval<1> &newdom) {
+ return NewDomain1<Interval<1> >::fill(*this, newdom);
+ }
+ const OneDomain_t &operator[](int d) const { return *this; }
+ OneDomain_t &operator[](int d) { return *this; }
+ };
+ template <class T1, class T2>
+ inline
+ Interval<1>::Interval(const T1 &m, const T2 &n)
+ : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
+ DomainTraits<Interval<1> >::setDomain(domain_m, m, n);
+ }
+ template <class T1, class T2, class T3>
+ inline
+ Interval<1>::Interval(const T1 &m, const T2 &n, const T3 &s)
+ : Domain<1, DomainTraits<Interval<1> > >(Pooma::NoInit()) {
+ ;
+ DomainTraits<Interval<1> >::setDomain(domain_m, m, n);
+ }
+ template <int Dim> class Loc;
+ template <> class Loc<1>;
+ template <int Dim> class Interval;
+ template <> class Interval<1>;
+ template<int Dim>
+ struct DomainTraits< Loc<Dim> >
+ : public DomainTraitsDomain<Loc<Dim>, int, Dim>
+ {
+ typedef DomainTraitsDomain<Loc<Dim>, int, Dim> Base_t;
+ typedef typename Base_t::Element_t Element_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef typename Base_t::NewDomain1_t NewDomain1_t;
+ typedef Loc<1> OneDomain_t;
+ typedef Loc<1> PointDomain_t;
+ typedef Interval<Dim> BlockDomain_t;
+ typedef Loc<Dim> AskDomain_t;
+ typedef Loc<Dim> AddResult_t;
+ typedef Loc<Dim> MultResult_t;
+ typedef WrapNoInit<OneDomain_t> Storage_t[Dim];
+ enum { domain = Base_t::domain };
+ enum { dimensions = Base_t::dimensions,
+ sliceDimensions = 0 };
+ enum { loopAware = false };
+ enum { singleValued = true };
+ enum { unitStride = true };
+ enum { wildcard = false };
+ inline
+ static OneDomain_t &getDomain(Domain_t &d, int n) {
+ return d[n];
+ }
+ inline
+ static const OneDomain_t &getDomain(const Domain_t &d, int n) {
+ return d[n];
+ }
+ inline
+ static PointDomain_t &getPointDomain(Domain_t &d, int n) {
+ return d[n];
+ }
+ inline
+ static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
+ return d[n];
+ }
+ static void initializeStorage(Storage_t &dom) {
+ Dom1Initialize<Dim-1>::template apply<DomainTraits<Loc<Dim> > >(dom);
+ }
+ template<class T>
+ inline
+ static void addAccum(Storage_t &dom, const T &newdom)
+ {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && (DomainTraits<T>::dimensions == 1 || DomainTraits<T>::dimensions == dimensions ))>::test();
+ if (DomainTraits<T>::dimensions > 1)
+ for (int i = 0;i< DomainTraits<T>::dimensions ; ++i)
+ dom[i] += DomainTraits<T>::getFirst(newdom[i]);
+ else
+ for (int i = 0;i< dimensions ; ++i)
+ dom[i] += DomainTraits<T>::getFirst(newdom[0]);
+ }
+ template<class T>
+ inline
+ static void subtractAccum(Storage_t &dom, const T &newdom)
+ {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && (DomainTraits<T>::dimensions == 1 || DomainTraits<T>::dimensions == dimensions ))>::test();
+ if (DomainTraits<T>::dimensions > 1)
+ for (int i = 0;i< DomainTraits<T>::dimensions ; ++i)
+ dom[i] -= DomainTraits<T>::getFirst(newdom[i]);
+ else
+ for (int i = 0;i< dimensions ; ++i)
+ dom[i] -= DomainTraits<T>::getFirst(newdom);
+ }
+ template<class T>
+ static void multiplyAccum(Storage_t &dom, const T &newdom)
+ {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && (DomainTraits<T>::dimensions == 1 || DomainTraits<T>::dimensions == dimensions ))>::test();
+ if (DomainTraits<T>::dimensions > 1)
+ for (int i = 0;i< DomainTraits<T>::dimensions ; ++i)
+ dom[i] *= DomainTraits<T>::getFirst(newdom[i]);
+ else
+ for (int i = 0;i< dimensions ; ++i)
+ dom[i] *= DomainTraits<T>::getFirst(newdom);
+ }
+ template<class T>
+ static void divideAccum(Storage_t &dom, const T &newdom)
+ {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && (DomainTraits<T>::dimensions == 1 || DomainTraits<T>::dimensions == dimensions ))>::test();
+ if (DomainTraits<T>::dimensions > 1)
+ for (int i = 0;i< DomainTraits<T>::dimensions ; ++i)
+ dom[i] /= DomainTraits<T>::getFirst(newdom[i]);
+ else
+ for (int i = 0;i< dimensions ; ++i)
+ dom[i] /= DomainTraits<T>::getFirst(newdom);
+ }
+ };
+ template<>
+ struct DomainTraits< Loc<1> >
+ : public DomainTraitsDomain<Loc<1>, int, 1>
+ {
+ typedef Loc<1> OneDomain_t;
+ typedef Loc<1> PointDomain_t;
+ typedef Interval<1> BlockDomain_t;
+ typedef Loc<1> AskDomain_t;
+ typedef Loc<1> AddResult_t;
+ typedef Loc<1> MultResult_t;
+ typedef Element_t Storage_t;
+ enum { dimensions = 1,
+ sliceDimensions = 0 };
+ enum { loopAware = false };
+ enum { singleValued = true };
+ enum { unitStride = true };
+ enum { wildcard = false };
+ inline
+ static Element_t first(Storage_t d) { return d; }
+ inline
+ static Element_t last(Storage_t d) { return d; }
+ inline
+ static Element_t stride(Storage_t) { return 1; }
+ inline
+ static Element_t length(Storage_t) { return 1; }
+ inline
+ static Element_t min(Storage_t d) { return d; }
+ inline
+ static Element_t max(Storage_t d) { return d; }
+ inline
+ static bool empty(Storage_t) { return false; }
+ inline
+ static int loop(Storage_t) { return 0; }
+ inline
+ static Element_t elem(Storage_t d, int) { return d; }
+ inline
+ static OneDomain_t &getDomain(Domain_t &d, int) {
+ return d;
+ }
+ inline
+ static const OneDomain_t &getDomain(const Domain_t &d, int) {
+ return d;
+ }
+ inline
+ static PointDomain_t &getPointDomain(Domain_t &d, int) {
+ return d;
+ }
+ inline
+ static const PointDomain_t &getPointDomain(const Domain_t &d, int) {
+ return d;
+ }
+ inline
+ static void initializeStorage(Storage_t &dom) {
+ dom = 0;
+ }
+ template<class T>
+ inline
+ static void setDomain(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ ;
+ dom = DomainTraits<T>::getFirst(newdom);
+ }
+ inline
+ static void setLoop(Storage_t &, int) { }
+ template<class UT, class T>
+ inline
+ static void setWildcardDomain(Storage_t &dom, const UT &u, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::wildcard)>::test();
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<UT>::dimensions == 1)>::test();
+ dom = newdom.first(u);
+ }
+ template<class T>
+ static bool isLessThan(const Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ ;
+ return (dom < DomainTraits<T>::getFirst(newdom));
+ }
+ template<class T>
+ static bool isEqualTo(const Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ ;
+ return (dom == DomainTraits<T>::getFirst(newdom));
+ }
+ template<class T>
+ inline
+ static void addAccum(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
+ dom += DomainTraits<T>::getFirst(newdom);
+ }
+ template<class T>
+ inline
+ static void subtractAccum(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
+ dom -= DomainTraits<T>::getFirst(newdom);
+ }
+ template<class T>
+ static void multiplyAccum(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
+ dom *= DomainTraits<T>::getFirst(newdom);
+ }
+ template<class T>
+ static void divideAccum(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
+ dom /= DomainTraits<T>::getFirst(newdom);
+ }
+ };
+ template<int Dim1, int Dim2>
+ struct DomainChangeDim<Loc<Dim1>, Dim2>
+ {
+ typedef Loc<Dim1> OldType_t;
+ typedef Loc<Dim2> NewType_t;
+ enum { oldDim = Dim1,
+ newDim = Dim2 };
+ };
+ template <int dstIndex, int toGo>
+ struct FillLocStorage
+ {
+ template <int Dim, class T>
+ static inline
+ void fill(Loc<Dim> &loc, const T &a)
+ {
+ PoomaCTAssert<(dstIndex < Dim)>::test();
+ loc[dstIndex].setDomain(DomainTraits<T>::getPointDomain(a, DomainTraits<T>::dimensions-toGo-1));
+ FillLocStorage<dstIndex+1,toGo-1>::fill(loc, a);
+ }
+ };
+ template <int dstIndex>
+ struct FillLocStorage<dstIndex, 0>
+ {
+ template <int Dim, class T>
+ static inline
+ void fill(Loc<Dim> &loc, const T &a)
+ {
+ PoomaCTAssert<(dstIndex < Dim)>::test();
+ loc[dstIndex].setDomain(DomainTraits<T>::getPointDomain(a, DomainTraits<T>::dimensions-1));
+ }
+ };
+ template <int i>
+ struct FillAllLocStorage
+ {
+ template <int Dim, class T>
+ inline
+ static void fill(Loc<Dim> &loc, const T &a)
+ {
+ loc[Dim-i-1].setDomain(DomainTraits<T>::getPointDomain(a, 0));
+ FillAllLocStorage<i-1>::fill(loc, a);
+ }
+ };
+ template <>
+ struct FillAllLocStorage<0>
+ {
+ template <int Dim, class T>
+ inline
+ static void fill(Loc<Dim> &loc, const T &a)
+ {
+ loc[Dim-1].setDomain(DomainTraits<T>::getPointDomain(a, 0));
+ }
+ };
+ template<int Dim, class T1>
+ inline
+ void fillLocStorage(Loc<Dim> &loc, const T1 &a)
+ {
+ FillLocStorage<0, DomainTraits<T1>::dimensions-1>::fill(loc, a);
+ }
+ template<int Dim, class T1, class T2>
+ inline
+ void fillLocStorage(Loc<Dim> &loc, const T1 &a, const T2 &b)
+ {
+ fillLocStorage(loc, a);
+ FillLocStorage<DomainTraits<T1>::dimensions, DomainTraits<T2>::dimensions-1>::fill(loc, b);
+ }
+ template<int Dim, class T1, class T2, class T3>
+ inline
+ void fillLocStorage(Loc<Dim> &loc, const T1 &a, const T2 &b, const T3 &c)
+ {
+ fillLocStorage(loc, a, b);
+ FillLocStorage<DomainTraits<T1>::dimensions
+ + DomainTraits<T2>::dimensions,
+ DomainTraits<T3>::dimensions-1>::fill(loc, c);
+ }
+ template<int Dim, class T1, class T2, class T3, class T4>
+ inline
+ void fillLocStorage(Loc<Dim> &loc, const T1 &a, const T2 &b, const T3 &c,
+ const T4 &d)
+ {
+ fillLocStorage(loc, a, b, c);
+ FillLocStorage<DomainTraits<T1>::dimensions
+ + DomainTraits<T2>::dimensions
+ + DomainTraits<T3>::dimensions,
+ DomainTraits<T4>::dimensions-1>::fill(loc, d);
+ }
+ template<int Dim, class T1, class T2, class T3, class T4, class T5>
+ inline
+ void fillLocStorage(Loc<Dim> &loc, const T1 &a, const T2 &b, const T3 &c,
+ const T4 &d, const T5 &e)
+ {
+ fillLocStorage(loc, a, b, c, d);
+ FillLocStorage<DomainTraits<T1>::dimensions
+ + DomainTraits<T2>::dimensions
+ + DomainTraits<T3>::dimensions
+ + DomainTraits<T4>::dimensions,
+ DomainTraits<T5>::dimensions-1>::fill(loc, e);
+ }
+ template<int Dim, class T1, class T2, class T3, class T4, class T5, class T6>
+ inline
+ void fillLocStorage(Loc<Dim> &loc, const T1 &a, const T2 &b, const T3 &c,
+ const T4 &d, const T5 &e, const T6 &f)
+ {
+ fillLocStorage(loc, a, b, c, d, e);
+ FillLocStorage<DomainTraits<T1>::dimensions
+ + DomainTraits<T2>::dimensions
+ + DomainTraits<T3>::dimensions
+ + DomainTraits<T4>::dimensions
+ + DomainTraits<T5>::dimensions,
+ DomainTraits<T6>::dimensions-1>::fill(loc, f);
+ }
+ template<int Dim, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
+ inline
+ void fillLocStorage(Loc<Dim> &loc, const T1 &a, const T2 &b, const T3 &c,
+ const T4 &d, const T5 &e, const T6 &f, const T7 &g)
+ {
+ fillLocStorage(loc, a, b, c, d, e, f);
+ FillLocStorage<DomainTraits<T1>::dimensions
+ + DomainTraits<T2>::dimensions
+ + DomainTraits<T3>::dimensions
+ + DomainTraits<T4>::dimensions
+ + DomainTraits<T5>::dimensions
+ + DomainTraits<T6>::dimensions,
+ DomainTraits<T7>::dimensions-1>::fill(loc, g);
+ }
+ template<int Dim, class T, int DimT, bool wildcard>
+ struct CopyLocStorageImpl
+ {
+ inline
+ static void copy(Loc<Dim> &, const T &) { }
+ };
+ template<int Dim, class T, int DimT>
+ struct CopyLocStorageImpl<Dim, T, DimT, false>
+ {
+ inline
+ static void copy(Loc<Dim> &loc, const T &a) {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == DimT)>::test();
+ PoomaCTAssert<(DomainTraits<T>::dimensions <= Dim)>::test();
+ fillLocStorage(loc, a);
+ }
+ };
+ template<int Dim, class T>
+ struct CopyLocStorageImpl<Dim, T, 1, false>
+ {
+ inline
+ static void copy(Loc<Dim> &loc, const T &a) {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ FillAllLocStorage<Dim-1>::fill(loc, a);
+ }
+ };
+ template<int Dim, class T>
+ struct CopyLocStorage
+ {
+ inline
+ static void copy(Loc<Dim> &loc, const T &a) {
+ CopyLocStorageImpl<Dim, T, DomainTraits<T>::dimensions,
+ DomainTraits<T>::wildcard>::copy(loc, a);
+ }
+ };
+ template<int Dim>
+ class Loc : public Domain<Dim, DomainTraits<Loc<Dim> > >
+ {
+ typedef DomainTraits< Loc<Dim> > DT_t;
+ typedef Domain<Dim, DT_t> Base_t;
+ public:
+ typedef typename Base_t::iterator iterator;
+ typedef typename Base_t::const_iterator const_iterator;
+ typedef typename Base_t::blockIterator blockIterator;
+ typedef typename Base_t::const_blockIterator const_blockIterator;
+ typedef typename DT_t::Element_t Element_t;
+ typedef typename DT_t::Domain_t Domain_t;
+ typedef typename DT_t::OneDomain_t OneDomain_t;
+ typedef typename DT_t::BlockDomain_t BlockDomain_t;
+ typedef typename DT_t::AskDomain_t AskDomain_t;
+ typedef typename DT_t::AddResult_t AddResult_t;
+ typedef typename DT_t::MultResult_t MultResult_t;
+ typedef typename DT_t::Storage_t Storage_t;
+ enum { domain = DT_t::domain };
+ enum { dimensions = DT_t::dimensions,
+ sliceDimensions = DT_t::sliceDimensions };
+ enum { loopAware = DT_t::loopAware };
+ enum { singleValued = DT_t::singleValued };
+ enum { unitStride = DT_t::unitStride };
+ enum { wildcard = DT_t::wildcard };
+ inline
+ Loc() { }
+ inline
+ Loc(const Loc<Dim> &a)
+ : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
+ fillLocStorage(*this, a);
+ }
+ Loc(const Pooma::NoInit &a)
+ : Domain<Dim, DomainTraits<Loc<Dim> > >(a)
+ { }
+ template<class T1>
+ inline
+ explicit Loc(const T1 &a)
+ : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
+ CopyLocStorage<Dim, T1>::copy(*this, a);
+ }
+ template<class T1, class T2>
+ inline
+ Loc(const T1 &a, const T2 &b)
+ : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
+ PoomaCTAssert<(Dim >= (DomainTraits<T1>::dimensions + DomainTraits<T2>::dimensions))>::test();
+ fillLocStorage(*this, a, b);
+ }
+ template<class T1, class T2, class T3>
+ inline
+ Loc(const T1 &a, const T2 &b, const T3 &c)
+ : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
+ PoomaCTAssert<(Dim >= (DomainTraits<T1>::dimensions + DomainTraits<T2>::dimensions + DomainTraits<T3>::dimensions))>::test();
+ fillLocStorage(*this, a, b, c);
+ }
+ template<class T1, class T2, class T3, class T4>
+ inline
+ Loc(const T1 &a, const T2 &b, const T3 &c, const T4 &d)
+ : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
+ PoomaCTAssert<(Dim >= (DomainTraits<T1>::dimensions + DomainTraits<T2>::dimensions + DomainTraits<T3>::dimensions + DomainTraits<T4>::dimensions))>::test();
+ fillLocStorage(*this, a, b, c, d);
+ }
+ template<class T1, class T2, class T3, class T4, class T5>
+ inline
+ Loc(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e)
+ : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
+ PoomaCTAssert<(Dim >= (DomainTraits<T1>::dimensions + DomainTraits<T2>::dimensions + DomainTraits<T3>::dimensions + DomainTraits<T4>::dimensions + DomainTraits<T5>::dimensions))>::test();
+ fillLocStorage(*this, a, b, c, d, e);
+ }
+ template<class T1, class T2, class T3, class T4, class T5,
+ class T6>
+ inline
+ Loc(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
+ const T6 &f)
+ : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
+ PoomaCTAssert<(Dim >= (DomainTraits<T1>::dimensions + DomainTraits<T2>::dimensions + DomainTraits<T3>::dimensions + DomainTraits<T4>::dimensions + DomainTraits<T5>::dimensions + DomainTraits<T6>::dimensions))>::test();
+ fillLocStorage(*this, a, b, c, d, e, f);
+ }
+ template<class T1, class T2, class T3, class T4, class T5,
+ class T6, class T7>
+ inline
+ Loc(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
+ const T6 &f, const T7 &g)
+ : Domain<Dim, DomainTraits<Loc<Dim> > >(Pooma::NoInit()) {
+ PoomaCTAssert<(Dim >= (DomainTraits<T1>::dimensions + DomainTraits<T2>::dimensions + DomainTraits<T3>::dimensions + DomainTraits<T4>::dimensions + DomainTraits<T5>::dimensions + DomainTraits<T6>::dimensions + DomainTraits<T7>::dimensions))>::test();
+ fillLocStorage(*this, a, b, c, d, e, f, g);
+ }
+ inline
+ ~Loc() { }
+ template<class T>
+ inline
+ Loc<Dim> &operator=(const T &newdom) {
+ CopyLocStorage<Dim, T>::copy(*this, newdom);
+ return *this;
+ }
+ inline
+ Loc<Dim> &operator=(const Loc<Dim> &newdom) {
+ fillLocStorage(*this, newdom);
+ return *this;
+ }
+ template<class Out>
+ void print(Out &o) const;
+ protected:
+ private:
+ };
+ template<int Dim>
+ template<class Out>
+ void Loc<Dim>::print(Out &o) const
+ {
+ const Domain_t &d = this->unwrap();
+ o << "[";
+ for (int i=0; i < Dim; ++i) {
+ o << d[i].first();
+ if (i < (Dim-1))
+ o << ",";
+ }
+ o << "]";
+ }
+ template<>
+ class Loc<1> : public Domain<1, DomainTraits<Loc<1> > >
+ {
+ typedef DomainTraits< Loc<1> > DT_t;
+ public:
+ typedef DT_t::Element_t Element_t;
+ typedef DT_t::Domain_t Domain_t;
+ typedef DT_t::OneDomain_t OneDomain_t;
+ typedef DT_t::BlockDomain_t BlockDomain_t;
+ typedef DT_t::AskDomain_t AskDomain_t;
+ typedef DT_t::AddResult_t AddResult_t;
+ typedef DT_t::MultResult_t MultResult_t;
+ typedef DT_t::Storage_t Storage_t;
+ enum { domain = DT_t::domain };
+ enum { dimensions = DT_t::dimensions,
+ sliceDimensions = DT_t::sliceDimensions };
+ enum { loopAware = DT_t::loopAware };
+ enum { singleValued = DT_t::singleValued };
+ enum { unitStride = DT_t::unitStride };
+ enum { wildcard = DT_t::wildcard };
+ inline
+ Loc() { }
+ inline
+ Loc(const Loc<1> &a)
+ : Domain<1, DomainTraits<Loc<1> > >(Pooma::NoInit()) {
+ setDomain(a);
+ }
+ Loc(const Pooma::NoInit &a)
+ : Domain<1, DomainTraits<Loc<1> > >(a)
+ { }
+ template<class T1>
+ inline
+ explicit Loc(const T1 &a)
+ : Domain<1, DomainTraits<Loc<1> > >(Pooma::NoInit()) {
+ setDomain(DomainTraits<T1>::getPointDomain(a, 0));
+ }
+ template<class T1, class T2>
+ inline
+ Loc(const T1 &a, const T2 &b)
+ : Domain<1, DomainTraits<Loc<1> > >(Pooma::NoInit()) {
+ PoomaCTAssert<(DomainTraits<T1>::dimensions == 1 && DomainTraits<T2>::dimensions == 1 && DomainTraits<T1>::singleValued && DomainTraits<T2>::singleValued)>::test();
+ ;
+ setDomain(DomainTraits<T1>::getPointDomain(a, 0));
+ }
+ template<class T1, class T2, class T3>
+ inline
+ Loc(const T1 &a, const T2 &b, const T3 &c)
+ : Domain<1, DomainTraits<Loc<1> > >(Pooma::NoInit()) {
+ PoomaCTAssert<(DomainTraits<T1>::dimensions == 1 && DomainTraits<T2>::dimensions == 1 && DomainTraits<T3>::dimensions == 1 && DomainTraits<T1>::singleValued && DomainTraits<T2>::singleValued && DomainTraits<T3>::singleValued)>::test();
+ ;
+ setDomain(DomainTraits<T1>::getPointDomain(a, 0));
+ }
+ template<class T>
+ inline
+ Loc<1> &operator=(const T &newdom) {
+ setDomain(DomainTraits<T>::getPointDomain(newdom, 0));
+ return *this;
+ }
+ inline
+ Loc<1> &operator=(const Loc<1> &newdom) {
+ setDomain(newdom);
+ return *this;
+ }
+ const OneDomain_t &operator[](int d) const { return *this; }
+ OneDomain_t &operator[](int d) { return *this; }
+ template<class Out>
+ void print(Out &o) const;
+ };
+ template<class Out>
+ void Loc<1>::print(Out &o) const
+ {
+ const Domain_t &d = this->unwrap();
+ o << "[";
+ o << d[0].first();
+ o << "]";
+ }
+ template<int Dim>
+ std::ostream& operator<<(std::ostream &o, const Loc<Dim> &loc)
+ {
+ loc.print(o);
+ return o;
+ }
+ #include <vector>
+ class Pool
+ {
+ public:
+ Pool(size_t sz);
+ Pool();
+ ~Pool();
+ inline void* alloc()
+ {
+ outstandingAllocs_m += 1;
+ if ( head_m==0 )
+ grow();
+ Link *p = head_m;
+ memcpy(&head_m, &p->next_m, sizeof(head_m));
+ return p;
+ }
+ inline void free(void *b)
+ {
+ outstandingAllocs_m -= 1;
+ Link *p = (Link*)b;
+ p->next_m = head_m;
+ memcpy(&p->next_m, &head_m, sizeof(head_m));
+ head_m = p;
+ }
+ private:
+ struct Link { Link *next_m; };
+ enum { page=4096-8 };
+ enum { align = 8 };
+ enum { alignMask = align-1 };
+ static inline int blocksInPage(size_t sz)
+ {
+ return (page>sz)?(page/sz):1;
+ }
+ static inline size_t roundToAlign(size_t s)
+ {
+ if (s)
+ s = (s & ~alignMask) + ((s&alignMask)?align:0);
+ else
+ s = align;
+ return s;
+ }
+ void grow();
+ Link *head_m;
+ int outstandingAllocs_m;
+ size_t bsize_m;
+ size_t nblock_m;
+ std::vector<char*> chunks_m;
+ };
+ template<class T>
+ class Pooled
+ {
+ public:
+ inline void* operator new(size_t) { return pool_s.alloc(); }
+ inline void operator delete(void *p, size_t) { if (p) pool_s.free(p); }
+ inline void* operator new(size_t, void* ptr) { return ptr; }
+ inline void operator delete(void *, void *) { }
+ private:
+ static Pool pool_s;
+ };
+ template<class T>
+ Pool Pooled<T>::pool_s(sizeof(T));
+ template<class Dom, class OrigDom = Dom>
+ class Node : public Pooled<Node<Dom, OrigDom> >
+ {
+ public:
+ typedef Dom Domain_t;
+ typedef OrigDom AllocatedDomain_t;
+ typedef int Context_t;
+ typedef int ID_t;
+ typedef Node<Dom,OrigDom> This_t;
+ Node()
+ : local_m(-1), global_m(0), context_m(0), affinity_m(-1)
+ {
+ }
+ Node(const Domain_t &owned, const AllocatedDomain_t &allocated,
+ Context_t c, ID_t gid, ID_t lid = (-1))
+ : domain_m(owned), allocated_m(allocated),
+ local_m(lid), global_m(gid),
+ context_m(c), affinity_m(-1)
+ {
+ ;
+ ;
+ ;
+ }
+ Node(const Domain_t &d, Context_t c, ID_t gid, ID_t lid = (-1))
+ : domain_m(d), allocated_m(d),
+ local_m(lid), global_m(gid),
+ context_m(c), affinity_m(-1)
+ {
+ ;
+ ;
+ }
+ Node(int affinity, const Domain_t &owned, const AllocatedDomain_t &allocated,
+ Context_t c, ID_t gid, ID_t lid = (-1))
+ : domain_m(owned), allocated_m(allocated),
+ local_m(lid), global_m(gid), context_m(c),
+ affinity_m(affinity)
+ {
+ ;
+ ;
+ ;
+ }
+ Node(int affinity, const Domain_t &d,
+ Context_t c, ID_t gid, ID_t lid = (-1))
+ : domain_m(d), allocated_m(d),
+ local_m(lid), global_m(gid),
+ context_m(c), affinity_m(affinity)
+ {
+ ;
+ ;
+ }
+ Node(const This_t &n)
+ : domain_m(n.domain_m), allocated_m(n.allocated_m),
+ local_m(n.local_m), global_m(n.global_m),
+ context_m(n.context_m), affinity_m(n.affinity_m)
+ {
+ }
+ template<class ODom, class OAlloc>
+ Node(const Node<ODom,OAlloc> &n)
+ : domain_m(n.domain()), allocated_m(n.allocated()),
+ local_m(n.localID()), global_m(n.globalID()),
+ context_m(n.context()), affinity_m(n.affinity())
+ {
+ }
+ void initialize(const Domain_t &owned, const AllocatedDomain_t &allocated,
+ Context_t c, ID_t gid, ID_t lid = (-1))
+ {
+ ;
+ ;
+ domain_m = owned;
+ allocated_m = allocated;
+ context_m = c;
+ local_m = lid;
+ global_m = gid;
+ }
+ void initialize(const Domain_t &d, Context_t c, ID_t gid, ID_t lid = (-1))
+ {
+ ;
+ ;
+ domain_m = d;
+ allocated_m = d;
+ context_m = c;
+ local_m = lid;
+ global_m = gid;
+ }
+ ~Node()
+ {
+ }
+ inline const Domain_t &domain() const { return domain_m; }
+ inline const AllocatedDomain_t &allocated() const { return allocated_m; }
+ Context_t context() const { return context_m; }
+ ID_t localID() const { return local_m; }
+ ID_t globalID() const { return global_m; }
+ bool isLocal() const { return (local_m >= 0); }
+ int affinity() const { return affinity_m; }
+ int& affinity() { return affinity_m; }
+ int& context() { return context_m; }
+ int& localID() { return local_m; }
+ void setDomain(const Domain_t &dom) { domain_m = dom; }
+ Domain_t &domain() { return domain_m; }
+ void setAllocated(const AllocatedDomain_t &dom) { allocated_m = dom; }
+ AllocatedDomain_t &allocated() { return allocated_m; }
+ This_t &operator=(const This_t &n)
+ {
+ domain_m = n.domain();
+ allocated_m = n.allocated();
+ context_m = n.context();
+ local_m = n.localID();
+ global_m = n.globalID();
+ affinity_m = n.affinity();
+ return *this;
+ }
+ template<class ODom, class OAlloc>
+ This_t &operator=(const Node<ODom,OAlloc> &n)
+ {
+ domain_m = n.domain();
+ allocated_m = n.allocated();
+ context_m = n.context();
+ local_m = n.localID();
+ global_m = n.globalID();
+ affinity_m = n.affinity();
+ return *this;
+ }
+ This_t &operator=(const Domain_t &d)
+ {
+ domain_m = d;
+ return *this;
+ }
+ template<class Out>
+ void print(Out &o) const
+ {
+ o << "{" << domain();
+ o << ": allocated=" << allocated();
+ o << ", con=" << context();
+ o << ", aff=" << affinity();
+ o << ", gid=" << globalID();
+ o << ", lid=" << localID();
+ o << "}";
+ }
+ private:
+ enum { dim = DomainTraits<Dom>::dimensions };
+ enum { origDim = DomainTraits<OrigDom>::dimensions };
+ Domain_t domain_m;
+ AllocatedDomain_t allocated_m;
+ ID_t local_m;
+ ID_t global_m;
+ Context_t context_m;
+ int affinity_m;
+ };
+ template <class D, class A>
+ std::ostream &operator<<(std::ostream &o, const Node<D,A> &node)
+ {
+ node.print(o);
+ return o;
+ }
+ template<int Dim, class Dom, class OrigDom>
+ inline bool contains(const Interval<Dim> &i, const Node<Dom, OrigDom> &n)
+ {
+ return contains(i, n.domain());
+ }
+ template<class Dom, class OrigDom>
+ struct DomainTraits<Node<Dom, OrigDom> >
+ {
+ enum { singleValued = 0 };
+ };
+ template<class Domain, class Sub>
+ struct TemporaryNewDomain1;
+ template<class Domain, class OwnedDomain, class AllocatedDomain>
+ struct TemporaryNewDomain1<Domain, Node<OwnedDomain, AllocatedDomain> >
+ {
+ typedef Node<OwnedDomain,AllocatedDomain> SliceType_t;
+ static inline
+ const SliceType_t &combineSlice(const Domain &,
+ const Node<OwnedDomain,AllocatedDomain> &n)
+ {
+ return n;
+ }
+ };
+ #include <utility>
+ class GlobalIDDataBase
+ {
+ public:
+ typedef int LayoutID_t;
+ typedef int GlobalID_t;
+ typedef int NodeKey_t;
+ typedef std::map<LayoutID_t, GlobalID_t> Shared_t;
+ GlobalIDDataBase() { }
+ inline static
+ NodeKey_t nullNodeKey()
+ {
+ return -1;
+ }
+ NodeKey_t push(LayoutID_t layoutID, int context, GlobalID_t globalID);
+ NodeKey_t push(LayoutID_t layoutID,
+ int context,
+ GlobalID_t globalID,
+ NodeKey_t parentNode);
+ void shared(LayoutID_t idNew, LayoutID_t idOld);
+ GlobalID_t globalID(LayoutID_t layoutID, NodeKey_t key) const;
+ int context(LayoutID_t layoutID, NodeKey_t key) const;
+ int context(NodeKey_t key) const;
+ bool contextParticipates(int context, NodeKey_t key) const;
+ template<class OSTR>
+ inline void print(OSTR &ostr)
+ {
+ typedef std::vector<Pack> Store_t;
+ typedef typename Store_t::const_iterator Iterator_t;
+ Iterator_t p = data_m.begin();
+ for (; p != data_m.end(); ++p)
+ {
+ ostr << "(" << (*p).layoutID() << ","
+ << (*p).globalID() << ","
+ << (*p).context() << ","
+ << (*p).parent() << ")";
+ }
+ }
+ private:
+ struct Pack
+ {
+ Pack()
+ : layoutID_m(0), context_m(0), globalID_m(0), parent_m(0)
+ { }
+ inline
+ Pack(LayoutID_t layoutID, int context, GlobalID_t globalID,
+ NodeKey_t parent)
+ : layoutID_m(layoutID),
+ context_m(context),
+ globalID_m(globalID),
+ parent_m(parent)
+ { }
+ inline LayoutID_t layoutID() const { return layoutID_m; }
+ inline int context() const { return context_m; }
+ inline GlobalID_t globalID() const { return globalID_m; }
+ inline NodeKey_t parent() const { return parent_m; }
+ LayoutID_t layoutID_m;
+ int context_m;
+ GlobalID_t globalID_m;
+ NodeKey_t parent_m;
+ };
+ std::vector<Pack> data_m;
+ Shared_t shared_m;
+ };
+ class Unique
+ {
+ public:
+ typedef long Value_t;
+ Unique()
+ {
+ }
+ ~Unique()
+ {
+ }
+ static inline Value_t get()
+ {
+ mutex_s.lock();
+ Value_t retval = next_s++;
+ mutex_s.unlock();
+ return retval;
+ }
+ static inline Value_t lockedGet()
+ {
+ return get();
+ }
+ private:
+ static Value_t next_s;
+ static Pooma::Mutex_t mutex_s;
+ };
+ struct TouchesConstructNodePtr {
+ TouchesConstructNodePtr(){};
+ ~TouchesConstructNodePtr(){};
+ };
+ struct TouchesConstructNodeObj {
+ TouchesConstructNodeObj(){};
+ ~TouchesConstructNodeObj(){};
+ };
+ template<class Domain>
+ inline Node<Domain> *
+ touchesConstruct(const Domain &owned,
+ int affinity, int c, int gid, int lid,
+ const TouchesConstructNodePtr &)
+ {
+ return new Node<Domain>(affinity, owned, c, gid, lid);
+ }
+ template<class Domain, class AllocatedDomain>
+ inline Node<Domain,AllocatedDomain> *
+ touchesConstruct(const Domain &owned, const AllocatedDomain &allocated,
+ int affinity, int c, int gid, int lid,
+ const TouchesConstructNodePtr &)
+ {
+ return new Node<Domain,AllocatedDomain>
+ (affinity, owned, allocated, c, gid, lid);
+ }
+ template<class Domain>
+ inline Node<Domain>
+ touchesConstruct(const Domain &owned,
+ int affinity, int c, int gid, int lid,
+ const TouchesConstructNodeObj &)
+ {
+ return Node<Domain>(affinity, owned, c, gid, lid);
+ }
+ template<class Domain, class AllocatedDomain>
+ inline Node<Domain,AllocatedDomain>
+ touchesConstruct(const Domain &owned, const AllocatedDomain &allocated,
+ int affinity, int c, int gid, int lid,
+ const TouchesConstructNodeObj &)
+ {
+ return Node<Domain,AllocatedDomain>(affinity, owned, allocated, c, gid, lid);
+ }
+ template<int Dim> class INode;
+ template<int Dim>
+ struct TouchesConstructINode
+ {
+ typedef GlobalIDDataBase::NodeKey_t NodeKey_t;
+ typedef Unique::Value_t LayoutID_t;
+ TouchesConstructINode(LayoutID_t layoutID,
+ NodeKey_t parent,
+ GlobalIDDataBase *globalIDDataBase)
+ : layoutID_m(layoutID), parent_m(parent),
+ globalIDDataBase_m(globalIDDataBase)
+ { }
+ inline LayoutID_t layoutID() const { return layoutID_m; }
+ inline NodeKey_t parent() const { return parent_m; }
+ inline GlobalIDDataBase *globalIDDataBase() const
+ {
+ return globalIDDataBase_m;
+ }
+ LayoutID_t layoutID_m;
+ NodeKey_t parent_m;
+ GlobalIDDataBase *globalIDDataBase_m;
+ };
+ template <int Dim>
+ class INode
+ {
+ public:
+ typedef INode<Dim> This_t;
+ typedef Interval<Dim> Domain_t;
+ typedef GlobalIDDataBase::LayoutID_t LayoutID_t;
+ typedef GlobalIDDataBase::GlobalID_t GlobalID_t;
+ typedef GlobalIDDataBase::NodeKey_t NodeKey_t;
+ enum { dimensions = Dim };
+ inline INode() : domain_m(Pooma::NoInit()) { }
+ inline INode(const INode<Dim> &model)
+ : domain_m(model.domain_m),
+ globalIDDataBase_m(model.globalIDDataBase_m),
+ key_m(model.key_m)
+ { }
+ template<int D2, class Dom>
+ inline INode(const INode<D2> &model, const Dom &dom)
+ : domain_m(dom),
+ globalIDDataBase_m(model.globalIDDataBase()),
+ key_m(model.key())
+ { }
+ inline
+ INode(const Interval<Dim> &dom, LayoutID_t layoutID, int context,
+ GlobalID_t globalID,
+ GlobalIDDataBase *globalIDDataBase, NodeKey_t parent = -1)
+ : domain_m(dom),
+ globalIDDataBase_m(globalIDDataBase)
+ {
+ key_m = globalIDDataBase_m->push(layoutID, context, globalID, parent);
+ }
+ template<class Alloc>
+ inline
+ INode(const Node<Interval<Dim>, Alloc> &node, LayoutID_t layoutID,
+ GlobalIDDataBase *globalIDDataBase)
+ : domain_m(node.domain()),
+ globalIDDataBase_m(globalIDDataBase)
+ {
+ key_m = globalIDDataBase_m->push(layoutID, node.context(),
+ node.globalID());
+ }
+ inline
+ INode(const Interval<Dim> &dom, int context, GlobalID_t globalID,
+ const TouchesConstructINode<Dim> &tcin)
+ : domain_m(dom),
+ globalIDDataBase_m(tcin.globalIDDataBase())
+ {
+ key_m = globalIDDataBase_m->push(tcin.layoutID(), context, globalID,
+ tcin.parent());
+ }
+ inline
+ INode(const INode<Dim> &inode, int context, GlobalID_t globalID,
+ const TouchesConstructINode<Dim> &tcin)
+ : domain_m(inode.domain()),
+ globalIDDataBase_m(tcin.globalIDDataBase())
+ {
+ key_m = globalIDDataBase_m->push(tcin.layoutID(), context, globalID,
+ tcin.parent());
+ }
+ template<class Alloc>
+ inline
+ INode(const Node<Interval<Dim>, Alloc> &node, int context,
+ GlobalID_t globalID,
+ const TouchesConstructINode<Dim> &tcin)
+ : domain_m(node.domain()),
+ globalIDDataBase_m(tcin.globalIDDataBase())
+ {
+ key_m = globalIDDataBase_m->push(tcin.layoutID(), context, globalID,
+ tcin.parent());
+ }
+ inline INode(const Range<Dim> &range, int context, int globalID,
+ const TouchesConstructINode<Dim> &tcin)
+ : globalIDDataBase_m(tcin.globalIDDataBase())
+ {
+ key_m = globalIDDataBase_m->push(tcin.layoutID(), context, globalID,
+ tcin.parent());
+ int i;
+ for (i = 0; i < Dim; ++i)
+ {
+ domain_m[i] = Interval<1>(range[i].first(), range[i].last());
+ }
+ }
+ inline INode<Dim> &operator=(const INode<Dim> &rhs)
+ {
+ if (&rhs != this)
+ {
+ domain_m = rhs.domain();
+ globalIDDataBase_m = rhs.globalIDDataBase();
+ key_m = rhs.key();
+ }
+ return *this;
+ }
+ inline ~INode() { }
+ inline const Domain_t &domain() const { return domain_m; }
+ inline
+ GlobalID_t globalID(LayoutID_t id) const
+ {
+ ;
+ return globalIDDataBase_m->globalID(id, key_m);
+ }
+ inline int context() const
+ {
+ ;
+ return globalIDDataBase_m->context(key_m);
+ }
+ inline int context(LayoutID_t id) const
+ {
+ ;
+ return globalIDDataBase_m->context(id, key_m);
+ }
+ inline bool contextParticipates(int context) const
+ {
+ ;
+ return globalIDDataBase_m->contextParticipates(context, key_m);
+ }
+ inline
+ GlobalIDDataBase *globalIDDataBase() const { return globalIDDataBase_m; }
+ inline NodeKey_t key() const { return key_m; }
+ inline
+ TouchesConstructINode<Dim> touchesConstructINode(LayoutID_t layoutID)
+ {
+ return TouchesConstructINode<Dim>(layoutID, key_m, globalIDDataBase_m);
+ }
+ template<int Dim2>
+ inline static
+ TouchesConstructINode<Dim> touchesConstructINode(LayoutID_t layoutID,
+ const INode<Dim2> &inode)
+ {
+ return TouchesConstructINode<Dim>(layoutID, inode.key(),
+ inode.globalIDDataBase());
+ }
+ template<class Out>
+ void print(Out &o) const
+ {
+ o << "{" << domain();
+ o << ": key=" << key();
+ o << "}";
+ }
+ private:
+ Domain_t domain_m;
+ GlobalIDDataBase *globalIDDataBase_m;
+ NodeKey_t key_m;
+ };
+ template<int Dim>
+ inline INode<Dim> operator+(const INode<Dim> &inode, const Loc<Dim> &loc)
+ {
+ return INode<Dim>(inode, inode.domain() + loc);
+ }
+ template <int Dim>
+ std::ostream &operator<<(std::ostream &o, const INode<Dim> &inode)
+ {
+ inode.print(o);
+ return o;
+ }
+ template<int Dim>
+ inline bool contains(const Interval<Dim> &i, const INode<Dim> &n)
+ {
+ return contains(i, n.domain());
+ }
+ template<int Dim>
+ struct DomainTraits<INode<Dim> >
+ {
+ enum { singleValued = 0 };
+ };
+ template<class Domain, class Sub>
+ struct TemporaryNewDomain1;
+ template<class Domain, int N>
+ struct TemporaryNewDomain1<Domain, INode<N> >
+ {
+ typedef INode<N> SliceType_t;
+ static inline
+ const SliceType_t &combineSlice(const Domain &, const INode<N> &i)
+ {
+ return i;
+ }
+ };
+ template<class Domain, int Dim>
+ inline INode<Dim>
+ touchesConstruct(const Domain &d,
+ int, int context, int gid, int,
+ const TouchesConstructINode<Dim> &tcin)
+ {
+ return INode<Dim>(d, context, gid, tcin);
+ }
+ template<class Domain, class AllocatedDomain, int Dim>
+ inline INode<Dim>
+ touchesConstruct(const Domain &d, const AllocatedDomain &,
+ int, int context, int gid, int,
+ const TouchesConstructINode<Dim> & tcin)
+ {
+ return INode<Dim>(d, context, gid, tcin);
+ }
+ template <int Dim>
+ class GuardLayers
+ {
+ public:
+ explicit GuardLayers(int gcs = 0)
+ {
+ ;
+ for (int i = 0; i < Dim; ++i)
+ {
+ lower_m[i] = gcs;
+ upper_m[i] = gcs;
+ }
+ }
+ GuardLayers(int lower[Dim], int upper[Dim])
+ {
+ for (int i = 0; i < Dim; ++i)
+ {
+ ;
+ lower_m[i] = lower[i];
+ upper_m[i] = upper[i];
+ }
+ }
+ GuardLayers(const Loc<Dim> &lower, const Loc<Dim> &upper)
+ {
+ for (int i = 0; i < Dim; ++i)
+ {
+ ;
+ lower_m[i] = lower[i].first();
+ upper_m[i] = upper[i].first();
+ }
+ }
+ void initialize(const Loc<Dim> &lower, const Loc<Dim> &upper)
+ {
+ for (int i = 0; i < Dim; ++i)
+ {
+ ;
+ lower_m[i] = lower[i].first();
+ upper_m[i] = upper[i].first();
+ }
+ }
+ void initialize(const GuardLayers<Dim> &gl)
+ {
+ *this = gl;
+ }
+ int lower(int i) const
+ {
+ return lower_m[i];
+ }
+ int upper(int i) const
+ {
+ return upper_m[i];
+ }
+ int &lower(int i)
+ {
+ return lower_m[i];
+ }
+ int &upper(int i)
+ {
+ return upper_m[i];
+ }
+ bool operator==(const GuardLayers<Dim> &gcs) const
+ {
+ bool result = true;
+ for (int d = 0; d < Dim; ++d)
+ {
+ result = result && lower_m[d] == gcs.lower_m[d];
+ result = result && upper_m[d] == gcs.upper_m[d];
+ }
+ return result;
+ }
+ bool operator==(int gcw) const
+ {
+ bool result = true;
+ for (int d = 0; d < Dim; ++d)
+ {
+ result = result && lower_m[d] == gcw;
+ result = result && upper_m[d] == gcw;
+ }
+ return result;
+ }
+ bool operator!=(const GuardLayers<Dim> &gcs) const
+ {
+ return !operator==(gcs);
+ }
+ bool operator!=(int gcw) const
+ {
+ return !operator==(gcw);
+ }
+ GuardLayers<Dim> operator-(const GuardLayers<Dim> &gcs)
+ {
+ GuardLayers<Dim> result;
+ for (int d = 0; d < Dim; ++d)
+ {
+ result.lower(d) = lower_m[d] - gcs.lower_m[d];
+ ;
+ result.upper(d) = upper_m[d] - gcs.upper_m[d];
+ ;
+ }
+ return result;
+ }
+ GuardLayers<Dim> operator-(int dw)
+ {
+ GuardLayers<Dim> result;
+ for (int d = 0; d < Dim; ++d)
+ {
+ result.lower(d) = lower_m[d] - dw;
+ ;
+ result.upper(d) = upper_m[d] - dw;
+ ;
+ }
+ return result;
+ }
+ inline static void
+ addGuardLayers(Interval<Dim> &dom, const GuardLayers<Dim> &gcs)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() - gcs.lower(d);
+ int b = dom[d].last() + gcs.upper(d);
+ dom[d] = Interval<1>(a,b);
+ }
+ }
+ Interval<Dim> addGuardLayersToDomain(const Interval<Dim> &d) const
+ {
+ Interval<Dim> dom(d);
+ addGuardLayers(dom, *this);
+ return dom;
+ }
+ template <class Ostream>
+ void print(Ostream &ostr) const
+ {
+ ostr << "GuardLayers<" << Dim << "> [";
+ for (int d = 0; d < Dim; ++d)
+ {
+ ostr << "l: " << lower_m[d] << ", u: " << upper_m[d];
+ if (d != Dim - 1)
+ ostr << "; ";
+ }
+ ostr << "]";
+ }
+ private:
+ int lower_m[Dim];
+ int upper_m[Dim];
+ };
+ template<int Dim>
+ inline Interval<Dim>
+ grow(const Interval<Dim> &dom, const GuardLayers<Dim> &gcs)
+ {
+ Interval<Dim> ret = Pooma::NoInit();
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() - gcs.lower(d);
+ int b = dom[d].last() + gcs.upper(d);
+ ret[d] = Interval<1>(a,b);
+ }
+ return ret;
+ }
+ template<int Dim>
+ inline Interval<Dim>
+ shrink(const Interval<Dim> &dom, const GuardLayers<Dim> &gcs)
+ {
+ Interval<Dim> ret = Pooma::NoInit();
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() + gcs.lower(d);
+ int b = dom[d].last() - gcs.upper(d);
+ ret[d] = Interval<1>(a,b);
+ }
+ return ret;
+ }
+ template<int Dim>
+ std::ostream &operator<<(std::ostream &ostr,
+ const GuardLayers<Dim> &gl)
+ {
+ gl.print(ostr);
+ return ostr;
+ }
+ template <int Dim> class Loc;
+ template <> class Loc<1>;
+ template <int Dim> class Interval;
+ template <> class Interval<1>;
+ template <int Dim> class Range;
+ template <> class Range<1>;
+ template<int Dim>
+ struct DomainTraits< Range<Dim> >
+ : public DomainTraitsDomain<Range<Dim>, int, Dim>
+ {
+ typedef DomainTraitsDomain<Range<Dim>, int, Dim> Base_t;
+ typedef typename Base_t::Element_t Element_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef typename Base_t::NewDomain1_t NewDomain1_t;
+ typedef Range<1> OneDomain_t;
+ typedef Range<1> PointDomain_t;
+ typedef Interval<Dim> BlockDomain_t;
+ typedef Loc<Dim> AskDomain_t;
+ typedef Range<Dim> AddResult_t;
+ typedef Range<Dim> MultResult_t;
+ typedef WrapNoInit<OneDomain_t> Storage_t[Dim];
+ enum { domain = Base_t::domain };
+ enum { dimensions = Base_t::dimensions,
+ sliceDimensions = Dim };
+ enum { loopAware = false };
+ enum { singleValued = false };
+ enum { unitStride = false };
+ enum { wildcard = false };
+ static OneDomain_t &getDomain(Domain_t &d, int n) { return d[n]; }
+ static const OneDomain_t &getDomain(const Domain_t &d,int n) { return d[n]; }
+ static PointDomain_t &getPointDomain(Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ static void initializeStorage(Storage_t &dom) {
+ Dom1Initialize<Dim-1>::template apply<DomainTraits<Range<Dim> > >(dom);
+ }
+ };
+ template<>
+ struct DomainTraits< Range<1> >
+ : public DomainTraitsDomain<Range<1>, int, 1>
+ {
+ typedef Range<1> OneDomain_t;
+ typedef Range<1> PointDomain_t;
+ typedef Interval<1> BlockDomain_t;
+ typedef Loc<1> AskDomain_t;
+ typedef Range<1> AddResult_t;
+ typedef Range<1> MultResult_t;
+ typedef Element_t Storage_t[3];
+ enum { dimensions = 1,
+ sliceDimensions = 1 };
+ enum { loopAware = false };
+ enum { singleValued = false };
+ enum { unitStride = false };
+ enum { wildcard = false };
+ static Element_t first(const Storage_t &d) { return d[0]; }
+ static Element_t last(const Storage_t &d) { return d[0] + (d[1]-1)*d[2]; }
+ static Element_t stride(const Storage_t &d) { return d[2]; }
+ static Element_t length(const Storage_t &d) { return d[1]; }
+ static Element_t min(const Storage_t &d) {
+ return (d[2] > 0 ? d[0] : d[0] + (d[1]-1)*d[2]);
+ }
+ static Element_t max(const Storage_t &d) {
+ return (d[2] < 0 ? d[0] : d[0] + (d[1]-1)*d[2]);
+ }
+ static bool empty(const Storage_t &d) { return (d[1] < 1); }
+ static int loop(const Storage_t &) { return 0; }
+ static Element_t elem(const Storage_t &d, int n) { return d[0] + n*d[2]; }
+ static OneDomain_t &getDomain(Domain_t &d, int) { return d; }
+ static const OneDomain_t &getDomain(const Domain_t &d, int) { return d; }
+ static PointDomain_t &getPointDomain(Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ static void initializeStorage(Storage_t &dom) {
+ dom[0] = 0;
+ dom[1] = 0;
+ dom[2] = 1;
+ }
+ template<class T>
+ static void setDomain(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ dom[0] = DomainTraits<T>::getFirst(newdom);
+ dom[1] = DomainTraits<T>::getLength(newdom);
+ dom[2] = DomainTraits<T>::getStride(newdom);
+ }
+ template<class T1, class T2>
+ static void setDomain(Storage_t &dom, const T1 &begval, const T2 &endval) {
+ PoomaCTAssert<(DomainTraits<T1>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<T2>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<T1>::singleValued)>::test();
+ PoomaCTAssert<(DomainTraits<T2>::singleValued)>::test();
+ Element_t strideval = (endval < begval ? -1 : 1);
+ dom[0] = begval;
+ dom[1] = (endval - begval)/strideval + 1;
+ dom[2] = strideval;
+ }
+ template<class T1, class T2, class T3>
+ static void setDomain(Storage_t &dom, const T1 &begval, const T2 &endval,
+ const T3 &strideval) {
+ PoomaCTAssert<(DomainTraits<T1>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<T2>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<T3>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<T1>::singleValued)>::test();
+ PoomaCTAssert<(DomainTraits<T2>::singleValued)>::test();
+ PoomaCTAssert<(DomainTraits<T3>::singleValued)>::test();
+ dom[0] = begval;
+ dom[1] = (endval - begval)/strideval + 1;
+ dom[2] = strideval;
+ }
+ static void setLoop(Storage_t &, int) { }
+ template<class UT, class T>
+ static void setWildcardDomain(Storage_t &dom, const UT &u, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::wildcard)>::test();
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<UT>::dimensions == 1)>::test();
+ dom[0] = newdom.first(u);
+ dom[1] = newdom.length(u);
+ dom[2] = newdom.stride(u);
+ }
+ template<class T>
+ static bool isLessThan(const Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ ;
+ return (dom[1] < DomainTraits<T>::getLength(newdom) ||
+ (dom[1] == DomainTraits<T>::getLength(newdom) &&
+ (dom[0] < DomainTraits<T>::getFirst(newdom) ||
+ (dom[0] == DomainTraits<T>::getFirst(newdom) &&
+ dom[2] < DomainTraits<T>::getStride(newdom)))));
+ }
+ template<class T>
+ static bool isEqualTo(const Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ return ((dom[1] == 0 && DomainTraits<T>::getLength(newdom) == 0) ||
+ (dom[0] == DomainTraits<T>::getFirst(newdom) &&
+ dom[1] == DomainTraits<T>::getLength(newdom) &&
+ dom[2] == DomainTraits<T>::getStride(newdom)));
+ }
+ template<class T>
+ static void addAccum(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
+ dom[0] += DomainTraits<T>::getFirst(newdom);
+ }
+ template<class T>
+ static void subtractAccum(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
+ dom[0] -= DomainTraits<T>::getFirst(newdom);
+ }
+ template<class T>
+ static void multiplyAccum(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
+ dom[0] *= DomainTraits<T>::getFirst(newdom);
+ dom[2] *= DomainTraits<T>::getFirst(newdom);
+ }
+ template<class T>
+ static void divideAccum(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
+ dom[0] /= DomainTraits<T>::getFirst(newdom);
+ dom[2] /= DomainTraits<T>::getFirst(newdom);
+ }
+ };
+ template<int Dim1, int Dim2>
+ struct DomainChangeDim<Range<Dim1>, Dim2>
+ {
+ typedef Range<Dim1> OldType_t;
+ typedef Range<Dim2> NewType_t;
+ enum { oldDim = Dim1,
+ newDim = Dim2 };
+ };
+ template <int Dim> class Range;
+ template<int Dim>
+ inline
+ void fillRangeScalar(Range<Dim> &r, const int &a);
+ template<int Dim>
+ class Range : public Domain<Dim, DomainTraits<Range<Dim> > >
+ {
+ typedef DomainTraits< Range<Dim> > DT_t;
+ typedef Domain<Dim, DT_t> Base_t;
+ public:
+ typedef typename Base_t::iterator iterator;
+ typedef typename Base_t::const_iterator const_iterator;
+ typedef typename Base_t::blockIterator blockIterator;
+ typedef typename Base_t::const_blockIterator const_blockIterator;
+ typedef typename DT_t::Element_t Element_t;
+ typedef typename DT_t::Domain_t Domain_t;
+ typedef typename DT_t::OneDomain_t OneDomain_t;
+ typedef typename DT_t::BlockDomain_t BlockDomain_t;
+ typedef typename DT_t::AskDomain_t AskDomain_t;
+ typedef typename DT_t::AddResult_t AddResult_t;
+ typedef typename DT_t::MultResult_t MultResult_t;
+ typedef typename DT_t::Storage_t Storage_t;
+ enum { domain = DT_t::domain };
+ enum { dimensions = DT_t::dimensions,
+ sliceDimensions = DT_t::sliceDimensions };
+ enum { loopAware = DT_t::loopAware };
+ enum { singleValued = DT_t::singleValued };
+ enum { unitStride = DT_t::unitStride };
+ enum { wildcard = DT_t::wildcard };
+ Range() { }
+ Range(const Range<Dim> &a)
+ : Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
+ NewDomain1<Range<Dim> >::fill(*this, a);
+ }
+ Range(const Pooma::NoInit &a)
+ : Domain<Dim, DomainTraits<Range<Dim> > >(a)
+ { }
+ template<class T1>
+ explicit Range(const T1 &a)
+ : Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
+ NewDomain1<T1>::fill(*this, a);
+ }
+ template<class T1, class T2>
+ Range(const T1 &a, const T2 &b)
+ : Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
+ NewDomain2<T1,T2>::fill(*this, a, b);
+ }
+ template<class T1, class T2, class T3>
+ Range(const T1 &a, const T2 &b, const T3 &c)
+ : Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
+ NewDomain3<T1,T2,T3>::fill(*this, a, b, c);
+ }
+ template<class T1, class T2, class T3, class T4>
+ Range(const T1 &a, const T2 &b, const T3 &c, const T4 &d)
+ : Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
+ NewDomain4<T1,T2,T3,T4>::fill(*this, a, b, c, d);
+ }
+ template<class T1, class T2, class T3, class T4, class T5>
+ Range(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e)
+ : Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
+ NewDomain5<T1,T2,T3,T4,T5>::fill(*this, a, b, c, d, e);
+ }
+ template<class T1, class T2, class T3, class T4, class T5,
+ class T6>
+ Range(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
+ const T6 &f)
+ : Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
+ NewDomain6<T1,T2,T3,T4,T5,T6>::fill(*this, a, b, c, d, e, f);
+ }
+ template<class T1, class T2, class T3, class T4, class T5,
+ class T6, class T7>
+ Range(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
+ const T6 &f, const T7 &g)
+ : Domain<Dim, DomainTraits<Range<Dim> > >(Pooma::NoInit()) {
+ NewDomain7<T1,T2,T3,T4,T5,T6,T7>::fill(*this, a, b, c, d, e, f, g);
+ }
+ ~Range() { }
+ template<class T>
+ Range<Dim> &operator=(const T &newdom) {
+ return NewDomain1<T>::fill(*this, newdom);
+ }
+ Range<Dim> &operator=(const Range<Dim> &newdom) {
+ return NewDomain1<Range<Dim> >::fill(*this, newdom);
+ }
+ Range<Dim> &operator=(const int a) {
+ fillRangeScalar(*this,a);
+ return *this;
+ }
+ protected:
+ private:
+ };
+ template<>
+ class Range<1> : public Domain<1, DomainTraits<Range<1> > >
+ {
+ typedef DomainTraits< Range<1> > DT_t;
+ public:
+ typedef DT_t::Element_t Element_t;
+ typedef DT_t::Domain_t Domain_t;
+ typedef DT_t::OneDomain_t OneDomain_t;
+ typedef DT_t::BlockDomain_t BlockDomain_t;
+ typedef DT_t::AskDomain_t AskDomain_t;
+ typedef DT_t::AddResult_t AddResult_t;
+ typedef DT_t::MultResult_t MultResult_t;
+ typedef DT_t::Storage_t Storage_t;
+ enum { domain = DT_t::domain };
+ enum { dimensions = DT_t::dimensions,
+ sliceDimensions = DT_t::sliceDimensions };
+ enum { loopAware = DT_t::loopAware };
+ enum { singleValued = DT_t::singleValued };
+ enum { unitStride = DT_t::unitStride };
+ enum { wildcard = DT_t::wildcard };
+ Range() { }
+ Range(const Range<1> &a)
+ : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
+ NewDomain1<Range<1> >::fill(*this, a);
+ }
+ Range(const Pooma::NoInit &a)
+ : Domain<1, DomainTraits<Range<1> > >(a)
+ { }
+ template<class T1>
+ explicit Range(const T1 &a)
+ : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
+ NewDomain1<T1>::fill(*this, a);
+ }
+ Range(char a)
+ : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
+ ;
+ DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Range(unsigned char a)
+ : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
+ ;
+ DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Range(short a)
+ : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
+ ;
+ short s = (a < 0 ? -1 : 1);
+ DomainTraits<Range<1> >::setDomain(domain_m, 0, a - s);
+ }
+ Range(unsigned short a)
+ : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
+ ;
+ DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Range(int a)
+ : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
+ ;
+ int s = (a < 0 ? -1 : 1);
+ DomainTraits<Range<1> >::setDomain(domain_m, 0, a - s);
+ }
+ Range(unsigned int a)
+ : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
+ ;
+ DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Range(long a)
+ : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
+ ;
+ long s = (a < 0 ? -1 : 1);
+ DomainTraits<Range<1> >::setDomain(domain_m, 0, a - s);
+ }
+ Range(unsigned long a)
+ : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
+ ;
+ DomainTraits<Range<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ template<class T1, class T2>
+ Range(const T1 &m, const T2 &n);
+ template<class T1, class T2, class T3>
+ Range(const T1 &m, const T2 &n, const T3 &s);
+ template<class T>
+ Range<1> &operator=(const T &newdom) {
+ return NewDomain1<T>::fill(*this, newdom);
+ }
+ Range<1> &operator=(const Range<1> &newdom) {
+ return NewDomain1<Range<1> >::fill(*this, newdom);
+ }
+ const OneDomain_t &operator[](int d) const { return *this; }
+ OneDomain_t &operator[](int d) { return *this; }
+ };
+ template <class T1, class T2>
+ inline
+ Range<1>::Range(const T1 &m, const T2 &n)
+ : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
+ DomainTraits<Range<1> >::setDomain(domain_m, m, n);
+ }
+ template <class T1, class T2, class T3>
+ inline
+ Range<1>::Range(const T1 &m, const T2 &n, const T3 &s)
+ : Domain<1, DomainTraits<Range<1> > >(Pooma::NoInit()) {
+ DomainTraits<Range<1> >::setDomain(domain_m, m, n, s);
+ }
+ template<int Dim>
+ inline
+ void fillRangeScalar(Range<Dim> &r, const int &a)
+ {
+ for (int i=0; i < Dim; ++i)
+ r[i]=Range<1>(a);
+ }
+ class ObserverEvent
+ {
+ public:
+ typedef Unique::Value_t ID_t;
+ ObserverEvent(int event)
+ : event_m(event), ID_m(Unique::get())
+ {
+ }
+ ObserverEvent(const ObserverEvent &oe)
+ : event_m(oe.event_m), ID_m(oe.ID_m)
+ {
+ }
+ ObserverEvent &operator=(const ObserverEvent &oe)
+ {
+ event_m = oe.event();
+ ID_m = oe.ID();
+ return *this;
+ }
+ virtual ~ObserverEvent()
+ {
+ }
+ inline int event() const
+ {
+ return event_m;
+ }
+ inline ID_t ID() const
+ {
+ return ID_m;
+ }
+ static inline ID_t nullID()
+ {
+ return (-1);
+ }
+ private:
+ int event_m;
+ ID_t ID_m;
+ };
+ template<class Obj>
+ inline bool checkDynamicID(Obj &, ObserverEvent::ID_t)
+ {
+ return true;
+ }
+ template<class T>
+ class Observer
+ {
+ public:
+ Observer()
+ {
+ }
+ virtual ~Observer()
+ {
+ }
+ virtual void notify(T &observed, const ObserverEvent &event) = 0;
+ inline void notify(T &observed, int event)
+ {
+ notify(observed, ObserverEvent(event));
+ }
+ };
+ template<class T>
+ class SingleObserver
+ {
+ public:
+ SingleObserver() { }
+ virtual ~SingleObserver() { }
+ virtual void notify(const T &observed, const ObserverEvent &event) = 0;
+ inline void notify(const T &observed, int event)
+ {
+ notify(observed, ObserverEvent(event));
+ }
+ };
+ template<class T>
+ class Observable
+ {
+ public:
+ enum { deleteEvent = 0 };
+ Observable(T &o) : observed_m(o), count_m(0)
+ {
+ }
+ ~Observable()
+ {
+ notify(deleteEvent);
+ }
+ int observers() const
+ {
+ return count_m;
+ }
+ void attach(Observer<T> *o)
+ {
+ mutex_m.lock();
+ observers_m.push_back(o);
+ count_m += 1;
+ mutex_m.unlock();
+ }
+ void attach(Observer<T> &o)
+ {
+ attach(&o);
+ }
+ void detach(Observer<T> *o)
+ {
+ mutex_m.lock();
+ for (int i=0; i < count_m; ++i) {
+ if (observers_m[i] == o) {
+ count_m -= 1;
+ observers_m.erase(observers_m.begin() + i);
+ break;
+ }
+ }
+ mutex_m.unlock();
+ }
+ void detach(Observer<T> &o)
+ {
+ detach(&o);
+ }
+ inline void notify(int event)
+ {
+ for (int i=0; i < count_m; ++i)
+ observers_m[i]->notify(observed_m, event);
+ }
+ inline void notify(const ObserverEvent &event)
+ {
+ for (int i=0; i < count_m; ++i)
+ observers_m[i]->notify(observed_m, event);
+ }
+ private:
+ T &observed_m;
+ std::vector<Observer<T> *> observers_m;
+ int count_m;
+ Pooma::Mutex_t mutex_m;
+ Observable();
+ Observable(const Observable<T> &);
+ Observable<T> &operator=(const Observable<T> &);
+ };
+ template<class T>
+ class SingleObservable
+ {
+ public:
+ enum { deleteEvent = 0 };
+ SingleObservable() : observer_m(0)
+ {
+ }
+ ~SingleObservable()
+ {
+ notify(T(),0);
+ }
+ void attach(SingleObserver<T> *o)
+ {
+ ;
+ observer_m = o;
+ }
+ void attach(SingleObserver<T> &o)
+ {
+ attach(&o);
+ }
+ void detach()
+ {
+ observer_m = 0;
+ }
+ inline void notify(const T& value, int event)
+ {
+ if (observer_m != 0)
+ observer_m->notify(value, event);
+ }
+ inline void notify(const T& value, const ObserverEvent &event)
+ {
+ if (observer_m != 0)
+ observer_m->notify(value, event);
+ }
+ private:
+ SingleObserver<T> *observer_m;
+ SingleObservable(const SingleObservable<T> &);
+ SingleObservable<T> &operator=(const SingleObservable<T> &);
+ };
+ template <class T>
+ struct ElementProperties
+ {
+ typedef T This_t;
+ enum { hasTrivialDefaultConstructor = false };
+ enum { hasTrivialDestructor = false };
+ enum { concrete = false };
+ enum { basicType = false };
+ static void construct(This_t * addr)
+ {
+ new (addr) This_t();
+ }
+ static void construct(This_t * addr, const This_t & model)
+ {
+ new (addr) This_t(model);
+ }
+ static This_t * clone(const This_t &model)
+ {
+ return new This_t(model);
+ }
+ static void destruct(This_t * addr)
+ {
+ addr->~This_t();
+ }
+ };
+ template <class T>
+ struct TrivialElementPropertiesBase
+ {
+ typedef T This_t;
+ enum { hasTrivialDefaultConstructor = true };
+ enum { hasTrivialDestructor = true };
+ enum { concrete = true };
+ static void construct(This_t * addr, const This_t & model)
+ {
+ new (addr) This_t(model);
+ }
+ static This_t * clone(const This_t &model)
+ {
+ return new This_t(model);
+ }
+ static void construct(This_t *addr)
+ {
+ new (addr) This_t();
+ }
+ static void destruct(This_t *)
+ {
+ if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("TrivialElementProperties<T>::destruct(addr) not allowed!", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Utilities/ElementProperties.h", 213);
+ }
+ };
+ template <class T>
+ struct TrivialElementProperties : public TrivialElementPropertiesBase<T>
+ {
+ enum { basicType = false };
+ };
+ template <class T>
+ struct BasicTypeProperties : public TrivialElementPropertiesBase<T>
+ {
+ enum { basicType = true };
+ };
+ template <class T>
+ struct MakeOwnCopyProperties
+ {
+ typedef T This_t;
+ enum { hasTrivialDefaultConstructor = false };
+ enum { hasTrivialDestructor = false };
+ enum { concrete = false };
+ enum { basicType = false };
+ static void construct(This_t * addr)
+ {
+ new (addr) This_t;
+ addr->makeOwnCopy();
+ }
+ static void construct(This_t * addr, const This_t & model)
+ {
+ new (addr) This_t(model);
+ addr->makeOwnCopy();
+ }
+ static This_t * clone(const This_t &model)
+ {
+ This_t * temp = new This_t(model);
+ temp->makeOwnCopy();
+ return temp;
+ }
+ static void destruct(This_t * addr)
+ {
+ addr->~This_t();
+ }
+ };
+ template <>
+ struct ElementProperties<bool> : public BasicTypeProperties<bool>
+ { };
+ template <>
+ struct ElementProperties<char> : public BasicTypeProperties<char>
+ { };
+ template <>
+ struct ElementProperties<unsigned char>
+ : public BasicTypeProperties<unsigned char>
+ { };
+ template <>
+ struct ElementProperties<short> : public BasicTypeProperties<short>
+ { };
+ template <>
+ struct ElementProperties<unsigned short>
+ : public BasicTypeProperties<unsigned short>
+ { };
+ template <>
+ struct ElementProperties<int> : public BasicTypeProperties<int>
+ { };
+ template <>
+ struct ElementProperties<unsigned int>
+ : public BasicTypeProperties<unsigned int>
+ { };
+ template <>
+ struct ElementProperties<long> : public BasicTypeProperties<long>
+ { };
+ template <>
+ struct ElementProperties<long long> : public BasicTypeProperties<long long>
+ { };
+ template <>
+ struct ElementProperties<unsigned long>
+ : public BasicTypeProperties<unsigned long>
+ { };
+ template <>
+ struct ElementProperties<float> : public BasicTypeProperties<float>
+ { };
+ template <>
+ struct ElementProperties<double> : public BasicTypeProperties<double>
+ { };
+ namespace std {
+ template <class Float> class complex;
+ }
+ template <class FloatType>
+ struct ElementProperties<std::complex<FloatType> >
+ : public TrivialElementProperties<std::complex<FloatType> >
+ { };
+ class RefCounted
+ {
+ public:
+ RefCounted()
+ : count_m(0)
+ { }
+ RefCounted(const RefCounted &)
+ : count_m(0)
+ { }
+ ~RefCounted() { }
+ bool isShared() const;
+ void addReference();
+ void removeReference();
+ bool removeRefAndCheckGarbage();
+ void lock() const
+ {
+ mutex_m.lock();
+ }
+ void unlock() const
+ {
+ mutex_m.unlock();
+ }
+ int count() const;
+ int countUnlocked() const;
+ private:
+ RefCounted & operator=(const RefCounted &);
+ int count_m;
+ mutable Pooma::Mutex_t mutex_m;
+ };
+ inline bool
+ RefCounted::isShared() const
+ {
+ mutex_m.lock();
+ bool test = count_m > 1;
+ mutex_m.unlock();
+ return test;
+ }
+ inline void
+ RefCounted::addReference()
+ {
+ mutex_m.lock();
+ ++count_m;
+ mutex_m.unlock();
+ }
+ inline void
+ RefCounted::removeReference()
+ {
+ mutex_m.lock();
+ --count_m;
+ ;
+ mutex_m.unlock();
+ }
+ inline bool
+ RefCounted::removeRefAndCheckGarbage()
+ {
+ mutex_m.lock();
+ ;
+ bool test = --count_m == 0;
+ mutex_m.unlock();
+ return test;
+ }
+ inline int
+ RefCounted::count() const
+ {
+ mutex_m.lock();
+ int count = count_m;
+ mutex_m.unlock();
+ return count;
+ }
+ inline int
+ RefCounted::countUnlocked() const
+ {
+ return count_m;
+ }
+ template <class T>
+ class Shared : public RefCounted
+ {
+ public:
+ Shared(const T &d) : data_m(d) {};
+ Shared(const Shared<T> & model)
+ : data_m(model.data_m)
+ { }
+ Shared<T> & operator=(const Shared<T> &model)
+ {
+ if (&model == this) return *this;
+ data_m = model.data_m;
+ return *this;
+ }
+ Shared<T> & operator=(const T & d)
+ {
+ data_m = d;
+ return *this;
+ }
+ inline
+ T &data() { return data_m; }
+ inline
+ const T &data() const { return data_m; }
+ bool operator==(const Shared<T> &rhs) const
+ { return data_m == rhs.data_m; }
+ bool operator!=(const Shared<T> &rhs) const
+ { return data_m != rhs.data_m; }
+ protected:
+ T data_m;
+ };
+ template <class T>
+ class RefCountedPtr
+ {
+ public:
+ typedef RefCountedPtr<T> This_t;
+ typedef T Pointee_t;
+ RefCountedPtr() : ptr_m(0) { }
+ RefCountedPtr(T * const pT)
+ : ptr_m(pT)
+ { if (isValid()) ptr_m->addReference(); }
+ RefCountedPtr(const This_t &model)
+ : ptr_m(model.ptr_m)
+ { if (isValid()) ptr_m->addReference(); }
+ ~RefCountedPtr();
+ RefCountedPtr & operator=(const RefCountedPtr &);
+ RefCountedPtr & operator=(T *);
+ inline T * operator->() const { return ptr_m; }
+ inline T & operator*() const { return *ptr_m; }
+ bool operator==(const This_t& a) const
+ { return ptr_m == a.ptr_m; }
+ bool operator!=(const This_t& a) const
+ { return ptr_m != a.ptr_m; }
+ void invalidate();
+ inline bool isValid() const { return ptr_m != 0; }
+ inline bool isShared() const { return ptr_m->isShared(); }
+ inline int count() const { return ptr_m->count(); }
+ RefCountedPtr<T> & makeOwnCopy();
+ inline T * rawPointer() { return ptr_m; }
+ inline const T * rawPointer() const { return ptr_m; }
+ private:
+ template <class T2, bool val, class Controller>
+ friend class RefCountedBlockPtr;
+ T * ptr_m;
+ };
+ template <class T>
+ inline void RefCountedPtr<T>::invalidate()
+ {
+ if ( isValid() && ptr_m->removeRefAndCheckGarbage() )
+ delete ptr_m;
+ ptr_m = 0;
+ }
+ template <class T>
+ inline RefCountedPtr<T>::~RefCountedPtr()
+ {
+ invalidate();
+ }
+ template <class T>
+ inline RefCountedPtr<T> &
+ RefCountedPtr<T>::operator=(const RefCountedPtr<T>& rhs)
+ {
+ if (ptr_m != rhs.ptr_m)
+ {
+ if ( isValid() && ptr_m->removeRefAndCheckGarbage() )
+ delete ptr_m;
+ ptr_m = rhs.ptr_m;
+ if ( isValid() ) ptr_m->addReference();
+ }
+ return *this;
+ }
+ template <class T>
+ inline RefCountedPtr<T> &
+ RefCountedPtr<T>::operator=(T *pp)
+ {
+ if (ptr_m != pp)
+ {
+ if ( isValid() && ptr_m->removeRefAndCheckGarbage() )
+ delete ptr_m;
+ ptr_m = pp;
+ if ( isValid() ) ptr_m->addReference();
+ }
+ return *this;
+ }
+ template <class T>
+ inline RefCountedPtr<T> &
+ RefCountedPtr<T>::makeOwnCopy()
+ {
+ if ( isValid() && ptr_m->isShared() )
+ {
+ T * temp = ElementProperties<T>::clone(*ptr_m);
+ ptr_m->removeReference();
+ ptr_m = temp;
+ ptr_m->addReference();
+ }
+ return *this;
+ }
+ template <class T>
+ class RefBlockController : public RefCounted
+ {
+ public:
+ struct NoInitTag
+ {
+ NoInitTag() { }
+ NoInitTag(const NoInitTag &) { }
+ NoInitTag & operator=(const NoInitTag &) { return *this; }
+ };
+ explicit
+ RefBlockController(size_t size)
+ : pBegin_m(0), pEnd_m(0), pEndOfStorage_m(0), dealloc_m(false)
+ {
+ reallocateStorage(size, false);
+ if (!ElementProperties<T>::hasTrivialDefaultConstructor)
+ {
+ for (T * pt = begin(); pt != end(); ++pt)
+ ElementProperties<T>::construct(pt);
+ }
+ }
+ RefBlockController(size_t size, const T & model)
+ : pBegin_m(0), pEnd_m(0), pEndOfStorage_m(0), dealloc_m(false)
+ {
+ reallocateStorage(size, false);
+ for (T * pt = begin(); pt != end(); ++pt)
+ ElementProperties<T>::construct(pt, model);
+ }
+ RefBlockController(size_t size, const NoInitTag &)
+ : pBegin_m(0), pEnd_m(0), pEndOfStorage_m(0), dealloc_m(false)
+ {
+ reallocateStorage(size, false);
+ }
+ RefBlockController(T *p, size_t size)
+ : pBegin_m(p), pEnd_m(p+size), pEndOfStorage_m(p+size), dealloc_m(false)
+ { }
+ RefBlockController(const RefBlockController &model)
+ : pBegin_m(0), pEnd_m(0), pEndOfStorage_m(0), dealloc_m(false)
+ {
+ size_t allocatedSize = model.pEndOfStorage_m - model.pBegin_m;
+ size_t size = model.end() - model.begin();
+ reallocateStorage(allocatedSize, false);
+ pEnd_m = pBegin_m + size;
+ T * pOld = model.begin();
+ T * pNew = begin();
+ while (pNew != end())
+ {
+ ElementProperties<T>::construct(pNew++,*pOld++);
+ }
+ }
+ ~RefBlockController()
+ {
+ deleteStorage();
+ }
+ bool resize(size_t newsize, const NoInitTag &)
+ {
+ T *pNewEnd = pBegin_m + newsize;
+ if (pNewEnd <= pEndOfStorage_m)
+ {
+ pEnd_m = pNewEnd;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ bool resize(size_t newsize)
+ {
+ bool success = resize(newsize,NoInitTag());
+ if (!ElementProperties<T>::hasTrivialDefaultConstructor)
+ if (success)
+ for (T * pt = begin(); pt != end(); ++pt)
+ ElementProperties<T>::construct(pt);
+ return success;
+ }
+ bool resize(size_t newsize, const T &model)
+ {
+ bool success = resize(newsize,NoInitTag());
+ if (success)
+ for (T * pt = begin(); pt != end(); ++pt)
+ ElementProperties<T>::construct(pt, model);
+ return success;
+ }
+ T *resizeAndCopy(size_t newsize)
+ {
+ size_t oldsize = size();
+ if (!resize(newsize, NoInitTag()))
+ {
+ reallocateStorage(newsize, true);
+ if (newsize > oldsize)
+ for (T *pt = begin() + oldsize; pt != end(); ++pt)
+ ElementProperties<T>::construct(pt);
+ }
+ return begin();
+ }
+ T *resizeAndCopy(size_t newsize, const T &model)
+ {
+ size_t oldsize = size();
+ if (!resize(newsize, NoInitTag()))
+ {
+ reallocateStorage(newsize, true);
+ if (newsize > oldsize)
+ for (T *pt = begin() + oldsize; pt != end(); ++pt)
+ ElementProperties<T>::construct(pt, model);
+ }
+ return begin();
+ }
+ T *resizeAndCopy(size_t newsize, const NoInitTag &)
+ {
+ if (!resize(newsize, NoInitTag()))
+ {
+ reallocateStorage(newsize, true);
+ }
+ return begin();
+ }
+ inline T *begin() const
+ {
+ return pBegin_m;
+ }
+ inline T *end() const
+ {
+ return pEnd_m;
+ }
+ inline size_t size() const
+ {
+ return static_cast<size_t>(pEnd_m - pBegin_m);
+ }
+ inline size_t capacity() const
+ {
+ return static_cast<size_t>(pEndOfStorage_m - pBegin_m);
+ }
+ inline bool empty() const
+ {
+ return pEnd_m == pBegin_m;
+ }
+ inline bool isMine() const
+ {
+ return dealloc_m;
+ }
+ inline bool checkDeref(const T *p) const
+ {
+ return ((pBegin_m <= p) && (p < pEnd_m));
+ }
+ private:
+ void deleteStorage()
+ {
+ if (isMine() && pBegin_m != 0)
+ {
+ if (!ElementProperties<T>::hasTrivialDestructor)
+ for (T *pt = begin(); pt != end(); ++pt)
+ ElementProperties<T>::destruct(pt);
+ char *tmp = reinterpret_cast<char *>(pBegin_m);
+ delete [] tmp;
+ }
+ }
+ void reallocateStorage(size_t newsize, bool copyold = false)
+ {
+ T *pBeginNew = 0;
+ T *pEndNew = 0;
+ T *pEndOfStorageNew = 0;
+ if (newsize > 0)
+ {
+ int nsize = newsize * sizeof(T);
+ char *tmp = new char[nsize];
+ pBeginNew = reinterpret_cast<T *>(tmp);
+ pEndNew = pBeginNew + newsize;
+ pEndOfStorageNew = pBeginNew + (nsize / sizeof(T));
+ if (copyold)
+ {
+ T * pOld = begin();
+ T * pNew = pBeginNew;
+ while (pOld != end() && pNew != pEndNew)
+ ElementProperties<T>::construct(pNew++,*pOld++);
+ }
+ }
+ deleteStorage();
+ pBegin_m = pBeginNew;
+ pEnd_m = pEndNew;
+ pEndOfStorage_m = pEndOfStorageNew;
+ dealloc_m = true;
+ }
+ T *pBegin_m;
+ T *pEnd_m;
+ T *pEndOfStorage_m;
+ bool dealloc_m;
+ };
+ template <class T,
+ bool BoundsChecked=false,
+ class Controller=RefBlockController<T> >
+ class RefCountedBlockPtr
+ {
+ public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef T value_type;
+ typedef ptrdiff_t difference_type;
+ typedef T* pointer;
+ typedef T& reference;
+ typedef T Element_t;
+ typedef T Pointee_t;
+ typedef ptrdiff_t Offset_t;
+ typedef RefCountedBlockPtr<T,BoundsChecked,Controller> This_t;
+ typedef RefCountedBlockPtr<T,!BoundsChecked,Controller> That_t;
+ struct NoInitTag
+ {
+ NoInitTag() { }
+ NoInitTag(const NoInitTag &) { }
+ NoInitTag & operator=(const NoInitTag &) { return *this; }
+ };
+ inline RefCountedBlockPtr()
+ : offset_m(0)
+ { }
+ inline explicit RefCountedBlockPtr(size_t size)
+ : offset_m(0),
+ blockControllerPtr_m(new Controller(size))
+ { }
+ inline RefCountedBlockPtr(size_t size, const T & model)
+ : offset_m(0),
+ blockControllerPtr_m(new Controller(size,model))
+ { }
+ inline RefCountedBlockPtr(size_t size, const NoInitTag &)
+ : offset_m(0),
+ blockControllerPtr_m(new Controller(size,
+ typename Controller::NoInitTag()))
+ {
+ blockControllerPtr_m->resize(0,typename Controller::NoInitTag());
+ }
+ inline RefCountedBlockPtr(T *p, size_t size)
+ : offset_m(0),
+ blockControllerPtr_m(new Controller(p, size))
+ { }
+ inline RefCountedBlockPtr(const This_t & model)
+ : offset_m(model.offset_m),
+ blockControllerPtr_m(model.blockControllerPtr_m)
+ { }
+ inline RefCountedBlockPtr(const That_t & model)
+ : offset_m(model.offset_m),
+ blockControllerPtr_m(model.blockControllerPtr_m)
+ { }
+ inline RefCountedBlockPtr(const This_t & model, Offset_t offset)
+ : offset_m(model.offset_m + offset),
+ blockControllerPtr_m(model.blockControllerPtr_m)
+ { }
+ inline ~RefCountedBlockPtr() {}
+ inline This_t & operator=(const This_t & rhs)
+ {
+ blockControllerPtr_m = rhs.blockControllerPtr_m;
+ offset_m = rhs.offset_m;
+ return *this;
+ }
+ inline This_t & operator=(const That_t & rhs)
+ {
+ blockControllerPtr_m = rhs.blockControllerPtr_m;
+ offset_m = rhs.offset_m;
+ return *this;
+ }
+ template<class T1, bool BoundsChecked1, class Controller1>
+ inline bool operator==(
+ const RefCountedBlockPtr<T1, BoundsChecked1, Controller1>&) const
+ {
+ return false;
+ }
+ template<class T1, bool BoundsChecked1, class Controller1>
+ inline bool operator!=(
+ const RefCountedBlockPtr<T1, BoundsChecked1, Controller1>&) const
+ {
+ return true;
+ }
+ inline bool operator==(const This_t& a) const
+ {
+ return (beginPointer() == a.beginPointer() && offset() == a.offset());
+ }
+ inline bool operator!=(const This_t& a) const
+ {
+ return (beginPointer() != a.beginPointer() || offset() != a.offset());
+ }
+ inline bool operator<(const This_t& a) const
+ {
+ ;
+ return offset() < a.offset();
+ }
+ inline bool operator>(const This_t& a) const
+ {
+ ;
+ return offset() > a.offset();
+ }
+ inline bool operator<=(const This_t& a) const
+ {
+ ;
+ return offset() <= a.offset();
+ }
+ inline bool operator>=(const This_t& a) const
+ {
+ ;
+ return offset() >= a.offset();
+ }
+ inline bool operator==(const That_t& a) const
+ {
+ return (beginPointer() == a.beginPointer() && offset() == a.offset());
+ }
+ inline bool operator!=(const That_t& a) const
+ {
+ return (beginPointer() != a.beginPointer() || offset() != a.offset());
+ }
+ inline T& operator*() const
+ {
+ T *p = currentPointer();
+ boundsAssert(p);
+ return *p;
+ }
+ inline T& operator[](Offset_t i) const
+ {
+ T *p = currentPointer() + i;
+ boundsAssert(p);
+ return *p;
+ }
+ inline T *operator->() const
+ {
+ T *p = currentPointer();
+ boundsAssert(p);
+ return p;
+ }
+ inline This_t & operator++()
+ {
+ ++offset_m;
+ return *this;
+ }
+ inline This_t & operator--()
+ {
+ --offset_m;
+ return *this;
+ }
+ inline This_t operator++(int)
+ {
+ This_t save(*this);
+ ++offset_m;
+ return save;
+ }
+ inline This_t operator--(int)
+ {
+ This_t save(*this);
+ --offset_m;
+ return save;
+ }
+ inline void operator+=(Offset_t i)
+ {
+ offset_m += i;
+ }
+ inline void operator-=(Offset_t i)
+ {
+ offset_m -= i;
+ }
+ inline This_t operator+(Offset_t i) const
+ {
+ This_t ret(*this);
+ ret += i;
+ return ret;
+ }
+ inline This_t operator-(Offset_t i) const
+ {
+ This_t ret(*this);
+ ret -= i;
+ return ret;
+ }
+ inline This_t begin() const
+ {
+ return This_t(*this, -offset_m);
+ }
+ inline This_t end() const
+ {
+ return This_t(*this, size() - offset_m);
+ }
+ void reserve(size_t size)
+ {
+ ;
+ typedef typename Controller::NoInitTag NoInit_t;
+ blockControllerPtr_m = new Controller(size, NoInit_t());
+ blockControllerPtr_m->resize(0,NoInit_t());
+ offset_m = 0;
+ }
+ bool resize(size_t size, const NoInitTag &)
+ {
+ ;
+ typedef typename Controller::NoInitTag NoInit_t;
+ return blockControllerPtr_m->resize(size, NoInit_t());
+ }
+ bool resize(size_t size)
+ {
+ ;
+ return blockControllerPtr_m->resize(size);
+ }
+ bool resize(size_t size, const T &model)
+ {
+ ;
+ return blockControllerPtr_m->resize(size, model);
+ }
+ void resizeAndCopy(size_t size, const NoInitTag &)
+ {
+ ;
+ typedef typename Controller::NoInitTag NoInit_t;
+ blockControllerPtr_m->resizeAndCopy(size, NoInit_t());
+ }
+ void resizeAndCopy(size_t size)
+ {
+ ;
+ blockControllerPtr_m->resizeAndCopy(size);
+ }
+ void resizeAndCopy(size_t size, const T &model)
+ {
+ ;
+ blockControllerPtr_m->resizeAndCopy(size, model);
+ }
+ void invalidate()
+ {
+ blockControllerPtr_m.invalidate();
+ offset_m = 0;
+ }
+ This_t & makeOwnCopy()
+ {
+ blockControllerPtr_m.makeOwnCopy();
+ return *this;
+ }
+ inline Offset_t offset() const
+ {
+ return offset_m;
+ }
+ inline bool isValid() const
+ {
+ return blockControllerPtr_m.isValid();
+ }
+ inline bool isShared() const
+ {
+ return blockControllerPtr_m.isShared();
+ }
+ inline int count() const
+ {
+ return isValid() ? blockControllerPtr_m.count() : 0;
+ }
+ inline size_t size() const
+ {
+ return isValid() ? blockControllerPtr_m->size() : 0;
+ }
+ inline size_t capacity() const
+ {
+ return isValid() ? blockControllerPtr_m->capacity() : 0;
+ }
+ inline bool empty() const
+ {
+ return isValid() ? blockControllerPtr_m->empty() : true;
+ }
+ inline bool isAtBeginning() const
+ {
+ return (offset() == 0);
+ }
+ inline bool isMine() const
+ {
+ return isValid() ? blockControllerPtr_m->isMine() : true;
+ }
+ inline T *beginPointer() const
+ {
+ ;
+ return blockControllerPtr_m->begin();
+ }
+ inline T *endPointer() const
+ {
+ ;
+ return blockControllerPtr_m->end();
+ }
+ inline T *currentPointer() const
+ {
+ return beginPointer() + offset();
+ }
+ protected:
+ friend class RefCountedBlockPtr<T,!BoundsChecked,Controller>;
+ RefCountedBlockPtr(Controller *con)
+ : offset_m(0), blockControllerPtr_m(con)
+ { }
+ inline void boundsAssert(T *p) const
+ {
+ if (BoundsChecked)
+ {
+ if (__builtin_expect(!!(isValid() && blockControllerPtr_m->checkDeref(p)), true)) {} else Pooma::toss_cookies("RefCountedBlockPtr: Bounds Violation.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Utilities/RefCountedBlockPtr.h", 1038);
+ }
+ }
+ Offset_t offset_m;
+ RefCountedPtr<Controller> blockControllerPtr_m;
+ };
+ template <class T, bool C1, bool C2, class Controller>
+ inline ptrdiff_t
+ operator-(const RefCountedBlockPtr<T,C1,Controller> &first,
+ const RefCountedBlockPtr<T,C2,Controller> &second)
+ {
+ return first.currentPointer() - second.currentPointer();
+ }
+ template <class T> class SingleObserver;
+ template <class T>
+ class DataBlockController
+ : public RefBlockController<T>
+ {
+ public:
+ typedef Pooma::DataObject_t DataObject_t;
+ typedef SingleObservable<int> Observable_t;
+ typedef RefBlockController<T> Base_t;
+ typedef typename RefBlockController<T>::NoInitTag NoInitTag;
+ typedef ObserverEvent::ID_t DynamicID_t;
+ explicit
+ DataBlockController(size_t size)
+ : Base_t(size), dataObjectPtr_m(new DataObject_t(-1)), owned_m(true),
+ dynamicID_m(ObserverEvent::nullID())
+ { }
+ DataBlockController(size_t size, const T & model)
+ : Base_t(size,model), dataObjectPtr_m(new DataObject_t(-1)), owned_m(true),
+ dynamicID_m(ObserverEvent::nullID())
+ { }
+ DataBlockController(T *p, size_t size)
+ : Base_t(p,size), dataObjectPtr_m(new DataObject_t(-1)), owned_m(true),
+ dynamicID_m(ObserverEvent::nullID())
+ { }
+ DataBlockController(size_t size, const NoInitTag &tag)
+ : Base_t(size,tag), dataObjectPtr_m(new DataObject_t(-1)), owned_m(true),
+ dynamicID_m(ObserverEvent::nullID())
+ { }
+ struct WithAffinity
+ {
+ WithAffinity() { }
+ WithAffinity(const WithAffinity&) { }
+ WithAffinity &operator=(const WithAffinity &) { return *this; }
+ };
+ DataBlockController(size_t size, int affinity, const WithAffinity &)
+ : Base_t(size), dataObjectPtr_m(new DataObject_t(affinity)), owned_m(true),
+ dynamicID_m(ObserverEvent::nullID())
+ { }
+ DataBlockController(size_t size, int affinity, const WithAffinity &,
+ const NoInitTag &tag)
+ : Base_t(size,tag), dataObjectPtr_m(new DataObject_t(affinity)),
+ owned_m(true),
+ dynamicID_m(ObserverEvent::nullID())
+ { }
+ DataBlockController(size_t size, DataObject_t &dobj)
+ : Base_t(size), dataObjectPtr_m(&dobj), owned_m(false),
+ dynamicID_m(ObserverEvent::nullID())
+ { }
+ DataBlockController(size_t size, const T& model, DataObject_t &dobj)
+ : Base_t(size,model), dataObjectPtr_m(&dobj), owned_m(false),
+ dynamicID_m(ObserverEvent::nullID())
+ { }
+ DataBlockController(size_t size, DataObject_t &dobj, const NoInitTag &tag)
+ : Base_t(size,tag), dataObjectPtr_m(&dobj), owned_m(false),
+ dynamicID_m(ObserverEvent::nullID())
+ { }
+ DataBlockController(const DataBlockController &model)
+ : Base_t(model),
+ dataObjectPtr_m(model.dataObjectPtr_m ?
+ new DataObject_t(model.affinity()) : 0),
+ owned_m(model.dataObjectPtr_m ? true : false),
+ observable_m(),
+ dynamicID_m(ObserverEvent::nullID())
+ { }
+ DataBlockController(const DataBlockController &model, DataObject_t &dobj)
+ : Base_t(model), observable_m(), owned_m(false),
+ dataObjectPtr_m(&dobj),
+ dynamicID_m(ObserverEvent::nullID())
+ { }
+ ~DataBlockController()
+ {
+ if (owned_m) delete dataObjectPtr_m;
+ }
+ void attach(SingleObserver<int> *o)
+ {
+ observable_m.attach(o);
+ }
+ void detach()
+ {
+ observable_m.detach();
+ }
+ inline DataObject_t* dataObject() const
+ {
+ return dataObjectPtr_m;
+ }
+ inline void dataObject(DataObject_t *obj)
+ {
+ if (owned_m) delete dataObjectPtr_m;
+ owned_m = false;
+ dataObjectPtr_m = obj;
+ }
+ inline int affinity() const
+ {
+ return dataObjectPtr_m->affinity();
+ }
+ inline void affinity(int affin)
+ {
+ dataObjectPtr_m->affinity(affin);
+ }
+ enum Notifier { addViewEvent, removeViewEvent };
+ inline void notifyOnDestruct()
+ {
+ observable_m.notify(0,removeViewEvent);
+ }
+ inline void notifyOnConstruct()
+ {
+ observable_m.notify(0,addViewEvent);
+ }
+ DynamicID_t dynamicID() const
+ {
+ return dynamicID_m;
+ }
+ void setDynamicID(DynamicID_t id)
+ {
+ dynamicID_m = id;
+ }
+ private:
+ mutable DataObject_t *dataObjectPtr_m;
+ bool owned_m;
+ Observable_t observable_m;
+ DynamicID_t dynamicID_m;
+ };
+ template <class T,
+ bool BoundsChecked=false>
+ class DataBlockPtr
+ : public RefCountedBlockPtr<T,BoundsChecked,DataBlockController<T> >
+ {
+ public:
+ typedef T Pointee_t;
+ typedef T Element_t;
+ typedef DataBlockPtr<T,BoundsChecked> This_t;
+ typedef Pooma::DataObject_t DataObject_t;
+ typedef SingleObservable<int> Observable_t;
+ typedef DataBlockPtr<T,!BoundsChecked> That_t;
+ typedef DataBlockController<T> Controller_t;
+ typedef RefCountedBlockPtr<T,BoundsChecked,Controller_t> RCBPtr_t;
+ typedef typename Controller_t::DynamicID_t DynamicID_t;
+ typedef typename RCBPtr_t::NoInitTag NoInitTag;
+ DataBlockPtr() : RCBPtr_t()
+ { }
+ explicit DataBlockPtr(size_t size)
+ : RCBPtr_t(size)
+ { }
+ DataBlockPtr(size_t size, const NoInitTag &tag)
+ : RCBPtr_t(size,tag)
+ { }
+ DataBlockPtr(int size, const T& model)
+ : RCBPtr_t(size,model)
+ { }
+ DataBlockPtr(T* foreignData, int size)
+ : RCBPtr_t(foreignData,size)
+ { }
+ typedef typename Controller_t::WithAffinity WithAffinity_t;
+ DataBlockPtr(int size, int affin, const WithAffinity_t&)
+ : RCBPtr_t(new Controller_t(size,affin,WithAffinity_t()))
+ { }
+ DataBlockPtr(int size, int affin, const WithAffinity_t&,
+ const NoInitTag &tag)
+ : RCBPtr_t(new Controller_t(size,affin,WithAffinity_t(),tag))
+ { }
+ DataBlockPtr(int size, DataObject_t &dobj)
+ : RCBPtr_t(new Controller_t(size,dobj))
+ { }
+ DataBlockPtr(int size, const T& model, DataObject_t &dobj)
+ : RCBPtr_t(new Controller_t(size,model,dobj))
+ { }
+ DataBlockPtr(int size, DataObject_t &dobj, const NoInitTag &tag)
+ : RCBPtr_t(new Controller_t(size,dobj,tag))
+ { }
+ DataBlockPtr(const This_t& model)
+ : RCBPtr_t(model)
+ {
+ if (this->isValid()) this->blockControllerPtr_m->notifyOnConstruct();
+ }
+ DataBlockPtr(const This_t& model, DataObject_t &dobj)
+ : RCBPtr_t(new Controller_t(model, dobj))
+ {
+ if (this->isValid()) this->blockControllerPtr_m->notifyOnConstruct();
+ }
+ DataBlockPtr(const That_t& model)
+ : RCBPtr_t(model)
+ {
+ if (this->isValid()) this->blockControllerPtr_m->notifyOnConstruct();
+ }
+ DataBlockPtr(const RCBPtr_t& model)
+ : RCBPtr_t(model)
+ {
+ if (this->isValid()) this->blockControllerPtr_m->notifyOnConstruct();
+ }
+ DataBlockPtr(const This_t& model, ptrdiff_t offset)
+ : RCBPtr_t(model,offset)
+ {
+ if (this->isValid()) this->blockControllerPtr_m->notifyOnConstruct();
+ }
+ ~DataBlockPtr()
+ {
+ if (this->isValid()) this->blockControllerPtr_m->notifyOnDestruct();
+ }
+ This_t & operator=(const This_t & rhs)
+ {
+ if (this != &rhs)
+ {
+ if (rhs.isValid()) rhs.blockControllerPtr_m->notifyOnConstruct();
+ if (this->isValid()) this->blockControllerPtr_m->notifyOnDestruct();
+ RCBPtr_t::operator=(rhs);
+ }
+ return *this;
+ }
+ This_t & operator=(const That_t & rhs)
+ {
+ if (this != &rhs)
+ {
+ if (rhs.isValid()) rhs.blockControllerPtr_m->notifyOnConstruct();
+ if (this->isValid()) this->blockControllerPtr_m->notifyOnDestruct();
+ RCBPtr_t::operator=(rhs);
+ }
+ return *this;
+ }
+ This_t & operator++()
+ { RCBPtr_t::operator++(); return *this; }
+ This_t & operator--()
+ { RCBPtr_t::operator--(); return *this; }
+ This_t operator++(int)
+ {
+ This_t tmp(*this);
+ RCBPtr_t::operator++();
+ return tmp;
+ }
+ This_t operator--(int)
+ {
+ This_t tmp(*this);
+ RCBPtr_t::operator--();
+ return tmp;
+ }
+ This_t operator+(ptrdiff_t i) const
+ {
+ This_t ret(*this);
+ ret += i;
+ return ret;
+ }
+ This_t operator-(ptrdiff_t i) const
+ {
+ This_t ret(*this);
+ ret -= i;
+ return ret;
+ }
+ This_t begin() const
+ { return RCBPtr_t::begin(); }
+ This_t end() const
+ { return RCBPtr_t::end(); }
+ void attach(SingleObserver<int> *o)
+ {
+ this->blockControllerPtr_m->attach(o);
+ }
+ void detach()
+ {
+ this->blockControllerPtr_m->detach();
+ }
+ inline DataObject_t* dataObject() const
+ {
+ return this->blockControllerPtr_m->dataObject();
+ }
+ inline void dataObject(DataObject_t *obj)
+ {
+ this->blockControllerPtr_m->dataObject(obj);
+ }
+ inline int affinity() const
+ {
+ return this->blockControllerPtr_m->affinity();
+ }
+ inline void affinity(int affin)
+ {
+ this->blockControllerPtr_m->affinity(affin);
+ }
+ bool sameDataObject(const DataBlockPtr<T>& x) const
+ {
+ return dataObject() == x.dataObject();
+ }
+ void lockRefCount() const { this->blockControllerPtr_m->lock(); }
+ void unlockRefCount() const { this->blockControllerPtr_m->unlock(); }
+ DynamicID_t dynamicID() const
+ {
+ return this->isValid() ?
+ this->blockControllerPtr_m->dynamicID() :
+ ObserverEvent::nullID();
+ }
+ void setDynamicID(DynamicID_t id)
+ {
+ ;
+ this->blockControllerPtr_m->setDynamicID(id);
+ }
+ private:
+ friend class DataBlockPtr<T,!BoundsChecked>;
+ };
+ template <class T, bool C1, bool C2>
+ ptrdiff_t operator-(const DataBlockPtr<T,C1> &first,
+ const DataBlockPtr<T,C2> &second)
+ {
+ return first.currentPointer() - second.currentPointer();
+ }
+ template<class T>
+ class IndirectionList
+ {
+ public:
+ typedef IndirectionList<T> This_t;
+ typedef T Element_t;
+ typedef IndirectionList<T> Domain_t;
+ typedef DataBlockPtr<T> Storage_t;
+ typedef long Size_t;
+ enum { dimensions = 1 };
+ enum { loopAware = false };
+ enum { singleValued = false };
+ enum { unitStride = false };
+ IndirectionList()
+ : size_m(0)
+ {
+ }
+ IndirectionList(const This_t &a)
+ : iList_m(a.iList_m), size_m(a.size_m)
+ {
+ }
+ IndirectionList(int num) : iList_m(num), size_m(num) { ; }
+ IndirectionList(long num) : iList_m(num), size_m(num) { ; }
+ IndirectionList(unsigned int num) : iList_m(num), size_m(num) { }
+ IndirectionList(unsigned long num) : iList_m(num), size_m(num) { }
+ template<class T1>
+ IndirectionList(const T1 &first, const T1 &stride, Size_t num)
+ : iList_m(num), size_m(num)
+ {
+ ;
+ T1 val = first;
+ for (Size_t i=0; i < num; ++i)
+ {
+ iList_m[i] = val;
+ val += stride;
+ }
+ }
+ template<class T1>
+ explicit IndirectionList(const T1 &a)
+ : iList_m(a.engine().dataBlock()), size_m(a.domain().size())
+ {
+ }
+ ~IndirectionList()
+ {
+ }
+ This_t &operator=(const This_t &newilist)
+ {
+ iList_m = newilist.iList_m;
+ size_m = newilist.size_m;
+ return *this;
+ }
+ template<class T1>
+ This_t &operator=(const T1 &a)
+ {
+ iList_m = a.engine().dataBlock();
+ size_m = a.domain().size();
+ return *this;
+ }
+ This_t &operator[](int i)
+ {
+ ;
+ return *this;
+ }
+ const This_t &operator[](int i) const
+ {
+ ;
+ return *this;
+ }
+ const T &operator()(Size_t i1) const
+ {
+ return iList_m[i1];
+ }
+ T &operator()(Size_t i1)
+ {
+ return iList_m[i1];
+ }
+ Size_t length() const
+ {
+ return size_m;
+ }
+ T first() const
+ {
+ return iList_m[0];
+ }
+ T last() const
+ {
+ return iList_m[size_m-1];
+ }
+ T stride() const
+ {
+ return T(0);
+ }
+ T min() const
+ {
+ T result = iList_m[0];
+ for (Size_t i=1; i<size_m; ++i)
+ result = (iList_m[i] < result) ? iList_m[i] : result;
+ return result;
+ }
+ T max() const
+ {
+ T result = iList_m[0];
+ for (Size_t i=1; i<size_m; ++i)
+ result = (result < iList_m[i]) ? iList_m[i] : result;
+ return result;
+ }
+ Size_t size() const
+ {
+ return size_m;
+ }
+ bool empty() const
+ {
+ return (size() == 0);
+ }
+ bool initialized() const
+ {
+ return (!empty());
+ }
+ template<class T1>
+ This_t &operator+=(const T1 &val)
+ {
+ Size_t n = size();
+ if (n > 0)
+ {
+ iList_m.makeOwnCopy();
+ for (Size_t i=0; i < n; ++i)
+ iList_m[i] += val;
+ }
+ return *this;
+ }
+ template<class T1>
+ This_t &operator-=(const T1 &val)
+ {
+ Size_t n = size();
+ if (n > 0)
+ {
+ iList_m.makeOwnCopy();
+ for (Size_t i=0; i < n; ++i)
+ iList_m[i] -= val;
+ }
+ return *this;
+ }
+ template<class T1>
+ This_t &operator*=(const T1 &val)
+ {
+ Size_t n = size();
+ if (n > 0)
+ {
+ iList_m.makeOwnCopy();
+ for (Size_t i=0; i < n; ++i)
+ iList_m[i] *= val;
+ }
+ return *this;
+ }
+ template<class T1>
+ This_t &operator/=(const T1 &val)
+ {
+ Size_t n = size();
+ if (n > 0)
+ {
+ iList_m.makeOwnCopy();
+ for (Size_t i=0; i < n; ++i)
+ iList_m[i] /= val;
+ }
+ return *this;
+ }
+ template<class Out>
+ void print(Out &o) const;
+ private:
+ Storage_t iList_m;
+ Size_t size_m;
+ };
+ template<class T>
+ template<class Out>
+ void IndirectionList<T>::print(Out &o) const
+ {
+ o << "[";
+ for (Size_t i=0; i < size(); ++i)
+ {
+ o << (*this)(i);
+ if (i < (size() - 1))
+ o << ",";
+ }
+ o << "]";
+ }
+ template<class T>
+ std::ostream& operator<<(std::ostream &o, const IndirectionList<T> &list)
+ {
+ list.print(o);
+ return o;
+ }
+ namespace Pooma {
+ template <class Iter>
+ class IteratorPairDomain
+ {
+ public:
+ typedef IteratorPairDomain<Iter> This_t;
+ typedef Iter iterator;
+ typedef std::iterator_traits<Iter> IterTraits_t;
+ typedef typename IterTraits_t::value_type Element_t;
+ typedef typename IterTraits_t::reference ElementRef_t;
+ typedef long Size_t;
+ enum { dimensions = 1 };
+ enum { loopAware = false };
+ enum { singleValued = false };
+ enum { unitStride = false };
+ IteratorPairDomain() : size_m(0) { }
+ IteratorPairDomain(Iter begin, Iter end)
+ : begin_m(begin), end_m(end)
+ {
+ size_m = std::distance(begin_m,end_m);
+ }
+ IteratorPairDomain(const This_t &a)
+ : begin_m(a.begin_m), end_m(a.end_m), size_m(a.size_m)
+ { }
+ template <class OtherIter>
+ IteratorPairDomain(const IteratorPairDomain<OtherIter> &a)
+ : begin_m(a.begin()), end_m(a.end()), size_m(a.size())
+ { }
+ This_t &operator=(const This_t &model)
+ {
+ begin_m = model.begin_m;
+ end_m = model.end_m;
+ size_m = model.size_m;
+ return *this;
+ }
+ This_t &operator[](int i)
+ {
+ ;
+ return *this;
+ }
+ const This_t &operator[](int i) const
+ {
+ ;
+ return *this;
+ }
+ Element_t operator()(Size_t i) const
+ {
+ ;
+ Iter pos = begin_m;
+ std::advance(pos,i);
+ return *pos;
+ }
+ ElementRef_t operator()(Size_t i)
+ {
+ ;
+ Iter pos = begin_m;
+ std::advance(pos,i);
+ return *pos;
+ }
+ Size_t length() const { return size_m; }
+ Size_t size() const { return size_m; }
+ bool empty() const { return size_m == 0; }
+ bool initialized() const { return size_m != 0; }
+ Element_t first() const { return *begin_m; }
+ Element_t last() const
+ {
+ Iter lpos = begin_m;
+ std::advance(lpos,size_m-1);
+ return *lpos;
+ }
+ Element_t min() const
+ {
+ Iter pos = begin_m;
+ Element_t result = *pos++;
+ for (Size_t i = 1; i < size_m; ++i)
+ {
+ if (*pos < result) result = *pos;
+ ++pos;
+ }
+ return result;
+ }
+ Element_t max() const
+ {
+ Iter pos = begin_m;
+ Element_t result = *pos++;
+ for (Size_t i = 1; i < size_m; ++i)
+ {
+ if (result < *pos) result = *pos;
+ ++pos;
+ }
+ return result;
+ }
+ Iter begin() const { return begin_m; }
+ Iter end() const { return end_m; }
+ template <class Out>
+ void print(Out &o) const;
+ private:
+ Iter begin_m;
+ Iter end_m;
+ Size_t size_m;
+ };
+ template <class Iter>
+ template <class Out>
+ void IteratorPairDomain<Iter>::print(Out &o) const
+ {
+ o << "[";
+ Iter pos = begin_m;
+ o << *pos++;
+ for (Size_t i = 1; i < size_m; ++i)
+ {
+ o << "," << *pos++;
+ }
+ o << "]";
+ }
+ template <class Iter>
+ std::ostream&
+ operator<<(std::ostream &o, const IteratorPairDomain<Iter> &list)
+ {
+ list.print(o);
+ return o;
+ }
+ }
+ using Pooma::IteratorPairDomain;
+ struct DynamicEvents
+ {
+ enum EventCode {
+ create = 1000,
+ extend,
+ destroyInterval, destroyRange, destroyList, destroyIterList,
+ copyInterval, copyRange, copyList,
+ copyPatchList,
+ sync,
+ unknownEvent };
+ static bool isDynamic(int eventcode)
+ {
+ return eventcode >= DynamicEvents::create &&
+ eventcode < DynamicEvents::unknownEvent;
+ }
+ enum { backfill = 100, shiftup, unknownMethod };
+ typedef int PatchID_t;
+ typedef int CreateSize_t;
+ };
+ struct BackFill
+ {
+ enum { code = DynamicEvents::backfill };
+ BackFill(){};
+ };
+ struct ShiftUp
+ {
+ enum { code = DynamicEvents::shiftup };
+ ShiftUp(){};
+ };
+ template<class T>
+ struct DynamicEventType
+ {
+ enum { destroyCode = DynamicEvents::destroyList };
+ enum { copyCode = DynamicEvents::copyList };
+ enum { dimensions = 1 };
+ typedef IndirectionList<int> Domain_t;
+ };
+ template <>
+ struct DynamicEventType<IteratorPairDomain<const int*> >
+ {
+ enum { destroyCode = DynamicEvents::destroyIterList };
+ enum { copyCode = DynamicEvents::copyList };
+ enum { dimensions = 1 };
+ typedef IteratorPairDomain<const int*> Domain_t;
+ };
+ template <>
+ struct DynamicEventType<IteratorPairDomain<int*> >
+ {
+ enum { destroyCode = DynamicEvents::destroyIterList };
+ enum { copyCode = DynamicEvents::copyList };
+ enum { dimensions = 1 };
+ typedef IteratorPairDomain<const int*> Domain_t;
+ };
+ template<>
+ struct DynamicEventType< IndirectionList< IndirectionList<int> > >
+ {
+ enum { destroyCode = DynamicEvents::unknownEvent };
+ enum { copyCode = DynamicEvents::copyPatchList };
+ enum { dimensions = 1 };
+ typedef IndirectionList< IndirectionList<int> > Domain_t;
+ };
+ template<int Dim>
+ struct DynamicEventType< Interval<Dim> >
+ {
+ enum { destroyCode = DynamicEvents::destroyInterval };
+ enum { copyCode = DynamicEvents::copyInterval };
+ enum { dimensions = Dim };
+ typedef Interval<Dim> Domain_t;
+ };
+ template<int Dim>
+ struct DynamicEventType< Range<Dim> >
+ {
+ enum { destroyCode = DynamicEvents::destroyRange };
+ enum { copyCode = DynamicEvents::copyRange };
+ enum { dimensions = Dim };
+ typedef Range<Dim> Domain_t;
+ };
+ template<int Dim>
+ struct DynamicEventType< Loc<Dim> >
+ {
+ enum { destroyCode = DynamicEvents::destroyInterval };
+ enum { copyCode = DynamicEvents::copyInterval };
+ enum { dimensions = Dim };
+ typedef Interval<Dim> Domain_t;
+ };
+ template<>
+ struct DynamicEventType<int>
+ {
+ enum { destroyCode = DynamicEvents::destroyInterval };
+ enum { copyCode = DynamicEvents::copyInterval };
+ enum { dimensions = 1 };
+ typedef Interval<1> Domain_t;
+ };
+ class CreateEvent : public ObserverEvent
+ {
+ public:
+ typedef DynamicEvents::PatchID_t PatchID_t;
+ typedef DynamicEvents::CreateSize_t CreateSize_t;
+ CreateEvent(CreateSize_t num, PatchID_t p)
+ : ObserverEvent(DynamicEvents::create),
+ amount_m(num), patch_m(p)
+ {
+ }
+ virtual ~CreateEvent()
+ {
+ }
+ inline CreateSize_t amount() const
+ {
+ return amount_m;
+ }
+ inline PatchID_t patch() const
+ {
+ return patch_m;
+ }
+ private:
+ CreateSize_t amount_m;
+ PatchID_t patch_m;
+ };
+ template<class Dom>
+ class DestroyEvent : public ObserverEvent
+ {
+ public:
+ typedef DynamicEvents::PatchID_t PatchID_t;
+ typedef DynamicEvents::CreateSize_t CreateSize_t;
+ typedef typename DynamicEventType<Dom>::Domain_t Domain_t;
+ template<class D>
+ DestroyEvent(const D &d, PatchID_t p, int method)
+ : ObserverEvent(DynamicEventType<Dom>::destroyCode),
+ domain_m(d), patch_m(p), method_m(method)
+ {
+ PoomaCTAssert<(DynamicEventType<Dom>::dimensions == 1)>::test();
+ }
+ virtual ~DestroyEvent()
+ {
+ }
+ inline const Domain_t &domain() const
+ {
+ return domain_m;
+ }
+ inline PatchID_t patch() const
+ {
+ return patch_m;
+ }
+ inline int method() const
+ {
+ return method_m;
+ }
+ private:
+ Domain_t domain_m;
+ PatchID_t patch_m;
+ int method_m;
+ };
+ template<class Dom>
+ class CopyEvent : public ObserverEvent
+ {
+ public:
+ typedef DynamicEvents::PatchID_t PatchID_t;
+ typedef DynamicEvents::CreateSize_t CreateSize_t;
+ typedef typename DynamicEventType<Dom>::Domain_t Domain_t;
+ CopyEvent(const Dom &d, PatchID_t fromp, PatchID_t top)
+ : ObserverEvent(DynamicEventType<Dom>::copyCode),
+ domain_m(d), from_m(fromp), to_m(top)
+ {
+ PoomaCTAssert<(DynamicEventType<Dom>::dimensions == 1)>::test();
+ }
+ template<class D>
+ CopyEvent(const D &d, PatchID_t fromp, PatchID_t top)
+ : ObserverEvent(DynamicEventType<Dom>::copyCode),
+ domain_m(d), from_m(fromp), to_m(top)
+ {
+ PoomaCTAssert<(DynamicEventType<Dom>::dimensions == 1)>::test();
+ }
+ virtual ~CopyEvent()
+ {
+ }
+ inline const Domain_t &domain() const
+ {
+ return domain_m;
+ }
+ inline PatchID_t fromPatch() const
+ {
+ return from_m;
+ }
+ inline PatchID_t toPatch() const
+ {
+ return to_m;
+ }
+ private:
+ Domain_t domain_m;
+ PatchID_t from_m;
+ PatchID_t to_m;
+ };
+ class CopyPatchEvent : public ObserverEvent
+ {
+ public:
+ typedef DynamicEvents::PatchID_t PatchID_t;
+ typedef DynamicEvents::CreateSize_t CreateSize_t;
+ typedef IndirectionList< IndirectionList<int> > Domain_t;
+ typedef IndirectionList<int> IDList_t;
+ CopyPatchEvent(const Domain_t &domlists, const IDList_t &fromlist,
+ PatchID_t top, bool create)
+ : ObserverEvent(DynamicEvents::copyPatchList),
+ lists_m(domlists), from_m(fromlist), to_m(top), create_m(create)
+ {
+ }
+ virtual ~CopyPatchEvent()
+ {
+ }
+ inline const Domain_t &domainLists() const
+ {
+ return lists_m;
+ }
+ inline const IDList_t &fromPatch() const
+ {
+ return from_m;
+ }
+ inline PatchID_t toPatch() const
+ {
+ return to_m;
+ }
+ inline bool create() const
+ {
+ return create_m;
+ }
+ private:
+ Domain_t lists_m;
+ IDList_t from_m;
+ PatchID_t to_m;
+ bool create_m;
+ };
+ class SyncEvent : public ObserverEvent
+ {
+ public:
+ SyncEvent()
+ : ObserverEvent(DynamicEvents::sync)
+ {
+ }
+ virtual ~SyncEvent()
+ {
+ }
+ private:
+ };
+ template<int Dim>
+ class ContextMapper
+ {
+ public:
+ typedef Interval<Dim> Domain_t;
+ typedef Node<Domain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ ContextMapper(){};
+ virtual ~ContextMapper(){};
+ virtual void map(const List_t & templist) const = 0;
+ void setAffinity(const List_t & templist) const;
+ };
+ template<int Dim>
+ void ContextMapper<Dim>::setAffinity(const List_t & templist) const
+ {
+ int affinityMax = Smarts::concurrency();
+ int idMax = 0;
+ typename List_t::const_iterator start = templist.begin();
+ typename List_t::const_iterator end = templist.end();
+ for ( ; start != end ; ++start)
+ if((*start)->context()==Pooma::context())
+ {
+ (*start)->localID()=idMax;
+ ++idMax;
+ }
+ start = templist.begin();
+ for ( ; start != end ; ++start)
+ {
+ if((*start)->context()==Pooma::context())
+ (*start)->affinity() = static_cast<int>
+ ( affinityMax * ( (*start)->localID()
+ / static_cast<double>(idMax) ) );
+ }
+ return;
+ }
+ template<int Dim>
+ class LocalMapper
+ : public ContextMapper<Dim>
+ {
+ public:
+ typedef Interval<Dim> Domain_t;
+ typedef Node<Domain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ template<class Partitioner>
+ LocalMapper(const Partitioner &)
+ {}
+ LocalMapper()
+ {}
+ void map(const List_t & templist) const;
+ };
+ template<int Dim>
+ void LocalMapper<Dim>::map(const List_t & templist) const
+ {
+ int idMax = templist.size();
+ int naff = Smarts::concurrency();
+ for (int i = 0; i< templist.size(); ++i)
+ {
+ templist[i]->context() = -1;
+ templist[i]->localID() = i;
+ templist[i]->affinity() = static_cast<int>( ( naff * ( i /
+ static_cast<double>(idMax) ) ) );
+ }
+ }
+ template<int Dim>
+ class DefaultTPmapper
+ : public ContextMapper<Dim>
+ {
+ public:
+ typedef Interval<Dim> Domain_t;
+ typedef Node<Domain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ template<class Partitioner>
+ DefaultTPmapper(const Partitioner & gp)
+ {
+ }
+ void map(const List_t & templist) const;
+ private:
+ };
+ template<int Dim>
+ void DefaultTPmapper<Dim>::map(const List_t & templist) const
+ {
+ int ncontexts = Pooma::contexts();
+ int npc = templist.size()/ncontexts;
+ if (templist.size()%ncontexts!=0) ++npc;
+ typename List_t::const_iterator start = templist.begin();
+ typename List_t::const_iterator end = templist.end();
+ int c = 0;
+ int p = 0;
+ for ( ; start!=end ; ++start)
+ {
+ (*start)->context() = p;
+ if(p == Pooma::context())
+ (*start)->localID() = c;
+ ++c;
+ if (c > npc)
+ {
+ ++p;
+ c = 0;
+ }
+ }
+ int affinityMax = Smarts::concurrency();
+ int idMax = 0;
+ start = templist.begin();
+ for ( ; start != end ; ++start)
+ if((*start)->context()==Pooma::context())
+ {
+ (*start)->localID()=idMax;
+ ++idMax;
+ }
+ start = templist.begin();
+ for ( ; start != end ; ++start)
+ {
+ if((*start)->context()==Pooma::context())
+ (*start)->affinity() = static_cast<int>( affinityMax *
+ ( (*start)->localID() /
+ static_cast<double>(idMax) ) );
+ }
+ }
+ template<int Dim>
+ class TilePartition
+ {
+ public:
+ typedef LocalMapper<Dim> DefaultMapper_t;
+ typedef Interval<Dim> Domain_t;
+ typedef std::vector<Domain_t> PatchList_t;
+ typedef Node<Domain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ enum { uniform = false };
+ enum { gridded = false };
+ enum { tile = true };
+ enum { general = true };
+ enum { dimensions = Dim };
+ TilePartition()
+ : hasInternalGuards_m(false),
+ hasExternalGuards_m(false),
+ num_m(0),
+ internalGuards_m(0),
+ externalGuards_m(0)
+ {
+ }
+ TilePartition(const PatchList_t &pList)
+ : hasInternalGuards_m(false),
+ hasExternalGuards_m(false),
+ internalGuards_m(0),
+ externalGuards_m(0),
+ tile_m(pList)
+ {
+ num_m = pList.size();
+ }
+ TilePartition(const PatchList_t &pList,
+ const GuardLayers<Dim> &gcs)
+ : hasInternalGuards_m(true),
+ hasExternalGuards_m(false),
+ internalGuards_m(gcs),
+ externalGuards_m(gcs),
+ tile_m(pList)
+ {
+ num_m = tile_m.size();
+ }
+ TilePartition(const PatchList_t &pList,
+ const GuardLayers<Dim> &igcs,
+ const GuardLayers<Dim> &egcs)
+ : hasInternalGuards_m(true),
+ hasExternalGuards_m(true),
+ internalGuards_m(igcs),
+ externalGuards_m(egcs),
+ tile_m(pList)
+ {
+ num_m = tile_m.size();
+ }
+ TilePartition(const TilePartition<Dim> & b)
+ : hasInternalGuards_m(b.hasInternalGuards_m),
+ hasExternalGuards_m(b.hasExternalGuards_m),
+ internalGuards_m(b.internalGuards_m),
+ externalGuards_m(b.externalGuards_m),
+ tile_m(b.tile_m),
+ num_m(b.num_m)
+ {
+ }
+ ~TilePartition() { }
+ TilePartition<Dim> &operator=(const TilePartition<Dim> &g)
+ {
+ if (this != &g)
+ {
+ hasInternalGuards_m = g.hasInternalGuards_m;
+ hasExternalGuards_m = g.hasExternalGuards_m;
+ internalGuards_m = g.internalGuards_m;
+ externalGuards_m = g.externalGuards_m;
+ tile_m = const_cast<TilePartition<Dim>&>(g).tileList();
+ num_m = g.maxSize();
+ if (!hasInternalGuards_m)
+ internalGuards_m = GuardLayers<Dim>(0);
+ if (!hasExternalGuards_m)
+ externalGuards_m = GuardLayers<Dim>(0);
+ }
+ return *this;
+ }
+ int maxSize() const { return num_m; }
+ PatchList_t tileList() { return tile_m; }
+ bool hasGuards() const { return hasInternalGuards_m||hasExternalGuards_m; }
+ bool hasCustomEdgeGuards() const
+ {
+ if (hasInternalGuards_m&&!hasExternalGuards_m) return true;
+ if (!hasInternalGuards_m&&hasExternalGuards_m) return true;
+ if (hasInternalGuards_m&&hasExternalGuards_m
+ &&(internalGuards_m!=externalGuards_m)) return true;
+ return false;
+ }
+ bool hasInternalGuards() const { return hasInternalGuards_m; }
+ bool hasExternalGuards() const { return hasExternalGuards_m;}
+ const GuardLayers<Dim> &internalGuards() const
+ {
+ return internalGuards_m;
+ }
+ const GuardLayers<Dim> &externalGuards() const
+ {
+ return externalGuards_m;
+ }
+ template<class D>
+ int partition(const D &bbox,List_t &all,const ContextMapper<Dim> &cmapper) const;
+ template<class D>
+ int partition(const D &bbox,List_t &all) const
+ {
+ return partition(bbox,all,LocalMapper<Dim>(*this));
+ }
+ template<class Out>
+ void print(Out &o) const;
+ private:
+ bool hasInternalGuards_m;
+ bool hasExternalGuards_m;
+ GuardLayers<Dim> internalGuards_m;
+ GuardLayers<Dim> externalGuards_m;
+ int num_m;
+ PatchList_t tile_m;
+ };
+ template<int Dim>
+ template<class D>
+ int TilePartition<Dim>::partition(const D &bbox, List_t &all,
+ const ContextMapper<Dim> &cmapper) const
+ {
+ typedef typename DomainTraits<Domain_t>::Element_t Element_t;
+ PoomaCTAssert<(Dim == DomainTraits<Domain_t>::dimensions)>::test();
+ typename PatchList_t::const_iterator start = tile_m.begin();
+ typename PatchList_t::const_iterator end = tile_m.end();
+ while (start!=end)
+ {
+ Domain_t o = Pooma::NoInit();
+ o = * start;
+ Domain_t oo = o;
+ Domain_t a = Pooma::NoInit();
+ a = * start;
+ if (hasInternalGuards()||hasExternalGuards())
+ {
+ for (int i=0;i<Dim;i++)
+ {
+ if (oo[i].first() == bbox[i].first())
+ {
+ if (hasExternalGuards())
+ {
+ o[i]=Interval<1>(o[i].first()-externalGuards().lower(i),
+ o[i].last());
+ a[i]=Interval<1>(a[i].first()-externalGuards().lower(i),
+ a[i].last());
+ }
+ if (hasInternalGuards() && oo[i].last() != bbox[i].last() )
+ a[i]=Interval<1>(a[i].first(),
+ a[i].last()+internalGuards().upper(i));
+ }
+ if (oo[i].last()== bbox[i].last())
+ {
+ if (hasExternalGuards())
+ {
+ o[i]=Interval<1>(o[i].first(),
+ o[i].last()+externalGuards().upper(i));
+ a[i]=Interval<1>(a[i].first(),
+ a[i].last()+externalGuards().upper(i));
+ }
+ if (hasInternalGuards()&&(oo[i].first() != bbox[i].first()))
+ a[i]=Interval<1>(a[i].first()-internalGuards().lower(i),
+ a[i].last());
+ }
+ if (oo[i].first()!=bbox[i].first() &&
+ oo[i].last() != bbox[i].last() &&
+ hasInternalGuards())
+ a[i]=Interval<1>(o[i].first()-internalGuards().lower(i),
+ o[i].last()+internalGuards().upper(i));
+ }
+ }
+ Value_t * node = new Value_t(o,a,-1,all.size(),-1);
+ all.push_back(node);
+ ++start;
+ }
+ cmapper.map(all);
+ return all.size();
+ }
+ template<int Dim>
+ template<class Out>
+ void TilePartition<Dim>::print(Out &o) const
+ {
+ int i;
+ o << "TilePartition<" << Dim << ">:" << std::endl;
+ o << " hasInternalGuards_m hasExternalGuards_m = ";
+ o << hasInternalGuards_m<< " "<<hasExternalGuards_m<< std::endl;
+ o << " internalGuards_m:" << std::endl;
+ o << " upper ";
+ for (i=0; i < Dim; ++i)
+ o << internalGuards_m.upper(i) << " ";
+ o << std::endl;
+ o << " lower ";
+ for (i=0; i < Dim; ++i)
+ o << internalGuards_m.lower(i) << " ";
+ o << std::endl;
+ o << " externalGuards_m:" << std::endl;
+ o << " upper ";
+ for (i=0; i < Dim; ++i)
+ o << externalGuards_m.upper(i) << " ";
+ o << std::endl;
+ o << " lower ";
+ for (i=0; i < Dim; ++i)
+ o << externalGuards_m.lower(i) << " ";
+ o << std::endl;
+ o << " num_m = " << num_m << std::endl;
+ }
+ template <int Dim>
+ std::ostream &operator<<(std::ostream &o, const TilePartition<Dim> &gp)
+ {
+ gp.print(o);
+ return o;
+ }
+ extern
+ bool findLeftCommonEndpoint(int a0, int a1, int s, int b0, int b1, int t,
+ int &endpoint);
+ extern
+ bool findIntersectionEndpoints(int a0, int a1, int s, int b0, int b1, int t,
+ int &i0, int &i1, int &is);
+ template<class T1, class T2, class T3, int Dim, bool strided>
+ struct IntersectDomainSingle {
+ static void intersect(const T1 &a, const T2 &b, T3 &c) {
+ typedef typename DomainTraits<T1>::Element_t E1_t;
+ typedef typename DomainTraits<T2>::Element_t E2_t;
+ E1_t a0 = a.min();
+ E1_t a1 = a.max();
+ E2_t b0 = b.min();
+ E2_t b1 = b.max();
+ if (a1 < b0 || a0 > b1)
+ return;
+ if (b0 > a0)
+ a0 = b0;
+ if (b1 < a1)
+ a1 = b1;
+ typedef typename DomainTraits<T3>::OneDomain_t Dom_t;
+ c[Dim-1] = Dom_t(a0, a1);
+ }
+ };
+ template<class T1, class T2, class T3, int Dim>
+ struct IntersectDomainSingle<T1,T2,T3,Dim,true> {
+ static void intersect(const T1 &a, const T2 &b, T3 &c) {
+ typedef typename DomainTraits<T1>::Element_t E1_t;
+ typedef typename DomainTraits<T2>::Element_t E2_t;
+ E1_t s = a.stride();
+ E2_t t = b.stride();
+ if (s == 1 && t == 1) {
+ IntersectDomainSingle<T1,T2,T3,Dim,false>::intersect(a,b,c);
+ return;
+ }
+ E1_t a0 = a.min();
+ E1_t a1 = a.max();
+ E2_t b0 = b.min();
+ E2_t b1 = b.max();
+ if (a1 < b0 || a0 > b1)
+ return;
+ int i1, i2, is;
+ if (findIntersectionEndpoints(a0, a1, s, b0, b1, t, i1, i2, is)) {
+ typedef typename DomainTraits<T3>::OneDomain_t Dom_t;
+ if (s < 0)
+ c[Dim-1] = Dom_t(i2, i1, -is);
+ else
+ c[Dim-1] = Dom_t(i1, i2, is);
+ }
+ }
+ };
+ template<class T1, class T2, class T3, int Dim>
+ struct IntersectDomain {
+ enum { strided =
+ !DomainTraits<T1>::unitStride || !DomainTraits<T2>::unitStride };
+ static void intersect(const T1 &a, const T2 &b, T3 &c) {
+ typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
+ typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
+ IntersectDomainSingle<Dom1_t,Dom2_t,T3,Dim,strided>::intersect(
+ DomainTraits<T1>::getDomain(a,Dim-1),
+ DomainTraits<T2>::getDomain(b,Dim-1), c);
+ IntersectDomain<T1,T2,T3,Dim-1>::intersect(a,b,c);
+ }
+ };
+ template<class T1, class T2, class T3>
+ struct IntersectDomain<T1,T2,T3,1> {
+ enum { strided =
+ !DomainTraits<T1>::unitStride || !DomainTraits<T2>::unitStride };
+ static void intersect(const T1 &a, const T2 &b, T3 &c) {
+ typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
+ typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
+ IntersectDomainSingle<Dom1_t,Dom2_t,T3,1,strided>::intersect(
+ DomainTraits<T1>::getDomain(a,0), DomainTraits<T2>::getDomain(b,0), c);
+ }
+ };
+ template<class T1, class T2>
+ struct IntersectReturnType {
+ typedef typename NewDomain2<T1,T2>::Type_t Combine_t;
+ typedef typename
+ DomainChangeDim<Combine_t,DomainTraits<T1>::dimensions>::NewType_t Type_t;
+ };
+ template<class T1, class T2>
+ inline typename IntersectReturnType<T1,T2>::Type_t
+ intersect(const T1 &a, const T2 &b)
+ {
+ typedef typename IntersectReturnType<T1,T2>::Type_t T3;
+ PoomaCTAssert<((int)DomainTraits<T1>::dimensions == DomainTraits<T2>::dimensions)>::test();
+ T3 c;
+ IntersectDomain<T1,T2,T3,DomainTraits<T1>::dimensions>::intersect(a, b, c);
+ return c;
+ }
+ template<int TotalDim, int SliceDim> class SliceRange;
+ template<int TotalDim, int SliceDim>
+ struct DomainTraits< SliceRange<TotalDim,SliceDim> >
+ {
+ enum { domain = true };
+ enum { dimensions = TotalDim,
+ sliceDimensions = SliceDim };
+ enum { unitStride = false };
+ enum { singleValued = false };
+ enum { wildcard = false };
+ typedef SliceRange<TotalDim,SliceDim> Domain_t;
+ typedef SliceRange<TotalDim,SliceDim> NewDomain1_t;
+ typedef Range<SliceDim> SliceDomain_t;
+ typedef Range<TotalDim> TotalDomain_t;
+ typedef Range<1> OneDomain_t;
+ typedef Range<1> PointDomain_t;
+ static OneDomain_t &getDomain(Domain_t &d, int n) {
+ return d.totalDomain()[n];
+ }
+ static const OneDomain_t &getDomain(const Domain_t &d,int n) {
+ return d.totalDomain()[n];
+ }
+ static OneDomain_t &getSliceDomain(Domain_t &d, int n) {
+ return d.sliceDomain()[n];
+ }
+ static const OneDomain_t &getSliceDomain(const Domain_t &d, int n) {
+ return d.sliceDomain()[n];
+ }
+ static PointDomain_t &getPointDomain(Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ static void cantIgnoreDomain(Domain_t &d, int n) {
+ d.cantIgnoreDomain(n);
+ }
+ static bool getIgnorable(const Domain_t &d, int n) {
+ return d.ignorable(n);
+ }
+ static void setIgnorable(Domain_t &d, int n, bool i) {
+ d.ignorable(n) = i;
+ }
+ };
+ template<class DT>
+ class SliceDomain
+ {
+ public:
+ typedef typename DT::Domain_t Domain_t;
+ typedef typename DT::SliceDomain_t SliceDomain_t;
+ typedef typename DT::TotalDomain_t TotalDomain_t;
+ SliceDomain()
+ : slice_m(Pooma::NoInit()),
+ domain_m(Pooma::NoInit()) {
+ PoomaCTAssert<(DT::sliceDimensions <= DT::dimensions)>::test();
+ for (int d = 0; d < DT::dimensions; ++d)
+ ignore_m[d] = true;
+ }
+ SliceDomain(const Pooma::NoInit &e)
+ : slice_m(e), domain_m(e) {
+ PoomaCTAssert<(DT::sliceDimensions <= DT::dimensions)>::test();
+ for (int d = 0; d < DT::dimensions; ++d)
+ ignore_m[d] = true;
+ }
+ SliceDomain(const SliceDomain<DT> &sd)
+ : slice_m(sd.slice_m),
+ domain_m(sd.domain_m) {
+ PoomaCTAssert<(DT::sliceDimensions <= DT::dimensions)>::test();
+ for (int d = 0; d < DT::dimensions; ++d)
+ ignore_m[d] = sd.ignore_m[d];
+ }
+ template <class DTO>
+ SliceDomain(const SliceDomain<DTO> &sd)
+ : slice_m(sd.sliceDomain()),
+ domain_m(sd.totalDomain()) {
+ PoomaCTAssert<(DT::sliceDimensions <= DT::dimensions)>::test();
+ for (int d = 0; d < DT::dimensions; ++d)
+ ignore_m[d] = sd.ignorable(d);
+ }
+ Domain_t &unwrap() { return *static_cast<Domain_t *>(this); }
+ const Domain_t &unwrap() const {
+ return *static_cast<const Domain_t *>(this);
+ }
+ ~SliceDomain() { }
+ const SliceDomain_t &sliceDomain() const { return slice_m; }
+ SliceDomain_t &sliceDomain() { return slice_m; }
+ const TotalDomain_t &totalDomain() const { return domain_m; }
+ TotalDomain_t &totalDomain() { return domain_m; }
+ void cantIgnoreDomain(int d)
+ {
+ ;
+ ignore_m[d] = false;
+ }
+ bool &ignorable(int d)
+ {
+ ;
+ return ignore_m[d];
+ }
+ bool ignorable(int d) const
+ {
+ ;
+ return ignore_m[d];
+ }
+ SliceDomain<DT> &operator=(const SliceDomain<DT> &sd) {
+ slice_m = sd.slice_m;
+ domain_m = sd.domain_m;
+ for (int d = 0; d < DT::dimensions; ++d)
+ ignore_m[d] = sd.ignore_m[d];
+ return *this;
+ }
+ void setSliceFromTotal() {
+ for (int d = 0, dt = 0; d < DT::dimensions; ++d)
+ if (!ignore_m[d])
+ slice_m[dt++] = domain_m[d];
+ }
+ template<class Out>
+ void print(Out &o) const;
+ private:
+ SliceDomain_t slice_m;
+ TotalDomain_t domain_m;
+ bool ignore_m[DT::dimensions];
+ };
+ template<class DT>
+ template<class Out>
+ void SliceDomain<DT>::print(Out &o) const
+ {
+ o << totalDomain() << "==>" << sliceDomain();
+ }
+ template <class T1, class T2> inline typename T1::Domain_t operator+(const SliceDomain<T1> &d1, const DomainBase<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2.unwrap(); ret.setSliceFromTotal(); return ret; } template <class T1, class T2> inline typename T1::Domain_t operator+(const SliceDomain<T1> &d1, const SliceDomain<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2.unwrap().totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, un!
signed char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(unsigned char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(short d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, unsigned short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> i!
nline typename T::Domain_t operator+(unsigned short d1, const !
SliceDom
ain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, unsigned int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(unsigned int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <cla!
ss T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, unsigned long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(unsigned long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, float d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2!
; ret.setSliceFromTotal(); return ret; } template <class T> in!
line typ
ename T::Domain_t operator+(float d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(const SliceDomain<T> &d1, double d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() += d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator+(double d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 + ret.totalDomain(); ret.setSliceFromTotal(); return ret; }
+ template <class T1, class T2> inline typename T1::Domain_t operator-(const SliceDomain<T1> &d1, const DomainBase<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2.unwrap(); ret.setSliceFromTotal(); return ret; } template <class T1, class T2> inline typename T1::Domain_t operator-(const SliceDomain<T1> &d1, const SliceDomain<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2.unwrap().totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, un!
signed char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(unsigned char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(short d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, unsigned short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> i!
nline typename T::Domain_t operator-(unsigned short d1, const !
SliceDom
ain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, unsigned int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(unsigned int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <cla!
ss T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, unsigned long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(unsigned long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, float d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2!
; ret.setSliceFromTotal(); return ret; } template <class T> in!
line typ
ename T::Domain_t operator-(float d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(const SliceDomain<T> &d1, double d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() -= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator-(double d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 - ret.totalDomain(); ret.setSliceFromTotal(); return ret; }
+ template <class T1, class T2> inline typename T1::Domain_t operator*(const SliceDomain<T1> &d1, const DomainBase<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2.unwrap(); ret.setSliceFromTotal(); return ret; } template <class T1, class T2> inline typename T1::Domain_t operator*(const SliceDomain<T1> &d1, const SliceDomain<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2.unwrap().totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, un!
signed char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(unsigned char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(short d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, unsigned short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> i!
nline typename T::Domain_t operator*(unsigned short d1, const !
SliceDom
ain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, unsigned int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(unsigned int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <cla!
ss T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, unsigned long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(unsigned long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, float d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2!
; ret.setSliceFromTotal(); return ret; } template <class T> in!
line typ
ename T::Domain_t operator*(float d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(const SliceDomain<T> &d1, double d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() *= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator*(double d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 * ret.totalDomain(); ret.setSliceFromTotal(); return ret; }
+ template <class T1, class T2> inline typename T1::Domain_t operator/(const SliceDomain<T1> &d1, const DomainBase<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2.unwrap(); ret.setSliceFromTotal(); return ret; } template <class T1, class T2> inline typename T1::Domain_t operator/(const SliceDomain<T1> &d1, const SliceDomain<T2> &d2) { typename T1::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2.unwrap().totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, un!
signed char d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(unsigned char d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(short d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, unsigned short d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> i!
nline typename T::Domain_t operator/(unsigned short d1, const !
SliceDom
ain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, unsigned int d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(unsigned int d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <cla!
ss T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, unsigned long d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(unsigned long d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, float d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2!
; ret.setSliceFromTotal(); return ret; } template <class T> in!
line typ
ename T::Domain_t operator/(float d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(const SliceDomain<T> &d1, double d2) { typename T::Domain_t ret(d1.unwrap()); ret.totalDomain() /= d2; ret.setSliceFromTotal(); return ret; } template <class T> inline typename T::Domain_t operator/(double d1, const SliceDomain<T> &d2) { typename T::Domain_t ret(d2.unwrap()); ret.totalDomain() = d2 / ret.totalDomain(); ret.setSliceFromTotal(); return ret; }
+ template<class DT>
+ std::ostream& operator<<(std::ostream &o, const SliceDomain<DT> &dbase) {
+ dbase.print(o);
+ return o;
+ }
+ template<int Dim, int SliceDim>
+ class SliceRange
+ : public SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > >
+ {
+ public:
+ SliceRange() { }
+ SliceRange(const Pooma::NoInit &e)
+ : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > >(e) { }
+ SliceRange(const SliceRange<Dim,SliceDim> &nd)
+ : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > >(nd) {
+ }
+ SliceRange(const SliceInterval<Dim,SliceDim> &nd)
+ : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > >(nd) {
+ }
+ template <class Base, class D1>
+ SliceRange(const Base &baseDomain, const D1 &d1)
+ : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > > (
+ Pooma::NoInit())
+ {
+ typedef NewDomain1<D1> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SliceType_t;
+ PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
+ NewDomain_t::fillSlice(*this, baseDomain, d1);
+ }
+ template <class Base, class D1, class D2>
+ SliceRange(const Base &baseDomain, const D1 &d1, const D2 &d2)
+ : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > > (
+ Pooma::NoInit())
+ {
+ typedef NewDomain2<D1,D2> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SliceType_t;
+ PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
+ PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
+ NewDomain_t::fillSlice(*this, baseDomain, d1, d2);
+ }
+ template <class Base, class D1, class D2, class D3>
+ SliceRange(const Base &baseDomain, const D1 &d1, const D2 &d2, const D3 &d3)
+ : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > > (
+ Pooma::NoInit())
+ {
+ typedef NewDomain3<D1,D2,D3> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SliceType_t;
+ PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
+ PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
+ NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3);
+ }
+ template <class Base, class D1, class D2, class D3,
+ class D4>
+ SliceRange(const Base &baseDomain, const D1 &d1, const D2 &d2, const D3 &d3,
+ const D4 &d4)
+ : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > > (
+ Pooma::NoInit())
+ {
+ typedef NewDomain4<D1,D2,D3,D4> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SliceType_t;
+ PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
+ PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
+ NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4);
+ }
+ template <class Base, class D1, class D2, class D3,
+ class D4, class D5>
+ SliceRange(const Base &baseDomain, const D1 &d1, const D2 &d2, const D3 &d3,
+ const D4 &d4, const D5 &d5)
+ : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > > (
+ Pooma::NoInit())
+ {
+ typedef NewDomain5<D1,D2,D3,D4,D5> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SliceType_t;
+ PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
+ PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
+ NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4, d5);
+ }
+ template <class Base, class D1, class D2, class D3,
+ class D4, class D5, class D6>
+ SliceRange(const Base &baseDomain, const D1 &d1, const D2 &d2, const D3 &d3,
+ const D4 &d4, const D5 &d5, const D6 &d6)
+ : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > > (
+ Pooma::NoInit())
+ {
+ typedef NewDomain6<D1,D2,D3,D4,D5,D6> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SliceType_t;
+ PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
+ PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
+ NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4, d5, d6);
+ }
+ template <class Base, class D1, class D2, class D3,
+ class D4, class D5, class D6, class D7>
+ SliceRange(const Base &baseDomain, const D1 &d1, const D2 &d2, const D3 &d3,
+ const D4 &d4, const D5 &d5, const D6 &d6, const D7 &d7)
+ : SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > > (
+ Pooma::NoInit())
+ {
+ typedef NewDomain7<D1,D2,D3,D4,D5,D6,D7> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SliceType_t;
+ PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
+ PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
+ NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4, d5, d6, d7);
+ }
+ ~SliceRange() { }
+ SliceRange<Dim,SliceDim> &
+ operator=(const SliceRange<Dim,SliceDim> &nd) {
+ SliceDomain<DomainTraits<SliceRange<Dim,SliceDim> > >::operator=(nd);
+ return *this;
+ }
+ protected:
+ private:
+ };
+ template<class T, int Dim, bool strided>
+ struct SplitDomainSingle {
+ static void split(const T &a, int axis, T &b, T &c) {
+ typedef typename DomainTraits<T>::Element_t E1_t;
+ typedef typename DomainTraits<T>::OneDomain_t OneDomain_t;
+ if (axis != (Dim - 1)) {
+ b[Dim-1] = a[Dim-1];
+ c[Dim-1] = a[Dim-1];
+ } else if (a[Dim-1].length() < 2) {
+ b[Dim-1] = a[Dim-1];
+ } else {
+ E1_t a0 = a[Dim-1].first();
+ E1_t a1 = a[Dim-1].last();
+ E1_t mid = a0 + a[Dim-1].length()/2;
+ b[Dim-1] = OneDomain_t(a0, mid-1);
+ c[Dim-1] = OneDomain_t(mid, a1);
+ }
+ }
+ static void split(const T &a, int axis, int leftLength, T &b, T &c) {
+ typedef typename DomainTraits<T>::Element_t E1_t;
+ typedef typename DomainTraits<T>::OneDomain_t OneDomain_t;
+ if (axis != (Dim - 1)) {
+ b[Dim-1] = a[Dim-1];
+ c[Dim-1] = a[Dim-1];
+ } else if (a[Dim-1].length() < 2) {
+ b[Dim-1] = a[Dim-1];
+ } else {
+ E1_t a0 = a[Dim-1].first();
+ E1_t a1 = a[Dim-1].last();
+ E1_t mid = a0 + leftLength;
+ b[Dim-1] = OneDomain_t(a0, mid-1);
+ c[Dim-1] = OneDomain_t(mid, a1);
+ }
+ }
+ static void split(const T &a, T &b, T &c) { split(a, Dim-1, b, c); }
+ };
+ template<class T, int Dim>
+ struct SplitDomainSingle<T,Dim,true> {
+ static void split(const T &a, int axis, T &b, T &c) {
+ typedef typename DomainTraits<T>::Element_t E1_t;
+ typedef typename DomainTraits<T>::OneDomain_t OneDomain_t;
+ if (axis != (Dim - 1)) {
+ b[Dim-1] = a[Dim-1];
+ c[Dim-1] = a[Dim-1];
+ } else if (a[Dim-1].length() < 2) {
+ b[Dim-1] = a[Dim-1];
+ } else {
+ E1_t a0 = a[Dim-1].first();
+ E1_t a1 = a[Dim-1].last();
+ E1_t s = a[Dim-1].stride();
+ E1_t mid = a0 + (a[Dim-1].length()/2 * s);
+ b[Dim-1] = OneDomain_t(a0, mid - s, s);
+ c[Dim-1] = OneDomain_t(mid, a1, s);
+ }
+ }
+ static void split(const T &a, int axis, int leftLength, T &b, T &c) {
+ typedef typename DomainTraits<T>::Element_t E1_t;
+ typedef typename DomainTraits<T>::OneDomain_t OneDomain_t;
+ if (axis != (Dim - 1)) {
+ b[Dim-1] = a[Dim-1];
+ c[Dim-1] = a[Dim-1];
+ } else if (a[Dim-1].length() < 2) {
+ b[Dim-1] = a[Dim-1];
+ } else {
+ E1_t a0 = a[Dim-1].first();
+ E1_t a1 = a[Dim-1].last();
+ E1_t s = a[Dim-1].stride();
+ E1_t mid = a0 + (leftLength * s);
+ b[Dim-1] = OneDomain_t(a0, mid - s, s);
+ c[Dim-1] = OneDomain_t(mid, a1, s);
+ }
+ }
+ static void split(const T &a, T &b, T &c) { split(a, Dim-1, b, c); }
+ };
+ template<int Dim, bool strided>
+ struct SplitDomainSingle<int,Dim,strided> {
+ static void split(int a, int, int &b, int &c) {
+ b = a;
+ c = 0;
+ }
+ static void split(int a, int, int, int &b, int &c) {
+ b = a;
+ c = 0;
+ }
+ static void split(int a, int &b, int &c) {
+ b = a;
+ c = 0;
+ }
+ };
+ template<class T, int Dim>
+ struct SplitDomain {
+ enum { strided = !DomainTraits<T>::unitStride };
+ static void split(const T &a, T &b, T &c) {
+ SplitDomainSingle<T,Dim,strided>::split(a, b, c);
+ SplitDomain<T,Dim-1>::split(a, b, c);
+ }
+ static void split(const T &a, int axis, T &b, T &c) {
+ SplitDomainSingle<T,Dim,strided>::split(a, axis, b, c);
+ SplitDomain<T,Dim-1>::split(a, axis, b, c);
+ }
+ static void split(const T &a, int axis, int leftLength, T &b, T &c) {
+ SplitDomainSingle<T,Dim,strided>::split(a, axis, leftLength, b, c);
+ SplitDomain<T,Dim-1>::split(a, axis, leftLength, b, c);
+ }
+ };
+ template<class T>
+ struct SplitDomain<T,1> {
+ enum { strided = !DomainTraits<T>::unitStride };
+ static void split(const T &a, T &b, T &c) {
+ SplitDomainSingle<T,1,strided>::split(a, b, c);
+ }
+ static void split(const T &a, int axis, T &b, T &c) {
+ SplitDomainSingle<T,1,strided>::split(a, axis, b, c);
+ }
+ static void split(const T &a, int axis, int leftLength, T &b, T &c) {
+ SplitDomainSingle<T,1,strided>::split(a, axis, leftLength, b, c);
+ }
+ };
+ template<class T>
+ inline void split(const T &a, T &b, T &c)
+ {
+ SplitDomain<T,DomainTraits<T>::dimensions>::split(a, b, c);
+ }
+ template<class T>
+ inline void split(const T &a, int axis, T &b, T &c)
+ {
+ SplitDomain<T,DomainTraits<T>::dimensions>::split(a, axis, b, c);
+ }
+ template<class T>
+ inline void split(const T &a, int axis, int leftLength, T &b, T &c)
+ {
+ SplitDomain<T,DomainTraits<T>::dimensions>::split(a, axis, leftLength, b, c);
+ }
+ template<class T1, class T2, bool strided>
+ struct TouchesDomainSingle {
+ static bool touches(const T1 &a, const T2 &b) {
+ return (a.min() <= b.max() && a.max() >= b.min());
+ }
+ };
+ template<class T1, class T2>
+ struct TouchesDomainSingle<T1,T2,true> {
+ static bool touches(const T1 &a, const T2 &b) {
+ bool quicktest = TouchesDomainSingle<T1,T2,false>::touches(a, b);
+ if (!quicktest || a.stride() == 1 || a.stride() == (-1) ||
+ b.stride() == 1 || b.stride() == (-1)) {
+ return quicktest;
+ }
+ int endpoint = 0;
+ return findLeftCommonEndpoint(a.min(), a.max(), a.stride(),
+ b.min(), b.max(), b.stride(), endpoint);
+ }
+ };
+ template<class T1, class T2, int Dim>
+ struct TouchesDomain {
+ enum { strided =
+ !DomainTraits<T1>::unitStride && !DomainTraits<T2>::unitStride };
+ static bool touches(const T1 &a, const T2 &b) {
+ typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
+ typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
+ return TouchesDomainSingle<Dom1_t,Dom2_t,strided>::touches(
+ DomainTraits<T1>::getDomain(a,Dim-1),
+ DomainTraits<T2>::getDomain(b,Dim-1)) &&
+ TouchesDomain<T1,T2,Dim-1>::touches(a,b);
+ }
+ };
+ template<class T1, class T2>
+ struct TouchesDomain<T1,T2,1> {
+ enum { strided =
+ !DomainTraits<T1>::unitStride && !DomainTraits<T2>::unitStride };
+ static bool touches(const T1 &a, const T2 &b) {
+ typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
+ typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
+ return TouchesDomainSingle<Dom1_t,Dom2_t,strided>::touches(
+ DomainTraits<T1>::getDomain(a,0), DomainTraits<T2>::getDomain(b,0));
+ }
+ };
+ template<class T1, class T2, int Dim1, int Dim2>
+ inline bool touches2(const T1 &, const T2 &, const WrappedInt<Dim1> &,
+ const WrappedInt<Dim2> &)
+ {
+ return false;
+ }
+ template<class T1, class T2, int Dim>
+ inline bool touches2(const T1 &a, const T2 &b, const WrappedInt<Dim> &,
+ const WrappedInt<Dim> &)
+ {
+ return TouchesDomain<T1,T2,Dim>::touches(a, b);
+ }
+ template<class T1, class T2>
+ inline bool touches(const T1 &a, const T2 &b)
+ {
+ if (a.empty() || b.empty())
+ return false;
+ else
+ return touches2(a, b, WrappedInt<DomainTraits<T1>::dimensions>(),
+ WrappedInt<DomainTraits<T2>::dimensions>());
+ }
+ #include <list>
+ template<class Dom, class T>
+ class DomainMapNode : public Pooled<DomainMapNode<Dom,T> >
+ {
+ public:
+ typedef Dom Domain_t;
+ typedef T Data_t;
+ typedef std::pair<Domain_t,Data_t> Value_t;
+ typedef std::list<Value_t> List_t;
+ typedef DomainMapNode<Dom,T> Node_t;
+ typedef typename List_t::iterator iterator;
+ DomainMapNode(const Domain_t &d, Node_t *p = 0)
+ : domain_m(d), left_m(0), right_m(0), parent_m(p) {
+ }
+ ~DomainMapNode() {
+ if (left_m != 0)
+ delete left_m;
+ if (right_m != 0)
+ delete right_m;
+ }
+ const Domain_t &domain() const { return domain_m; }
+ iterator begin() { return list_m.begin(); }
+ iterator end() { return list_m.end(); }
+ void insert(const Value_t &v) {
+ ;
+ if (left_m == 0)
+ {
+ Domain_t leftdom, rightdom;
+ split(domain_m, leftdom, rightdom);
+ left_m = new Node_t(leftdom, this);
+ right_m = new Node_t(rightdom, this);
+ }
+ if (contains(v.first, domain_m))
+ {
+ list_m.push_back(v);
+ }
+ else if (contains(left_m->domain_m, v.first))
+ {
+ left_m->insert(v);
+ }
+ else if (contains(right_m->domain_m, v.first))
+ {
+ right_m->insert(v);
+ }
+ else
+ {
+ list_m.push_back(v);
+ }
+ }
+ Node_t *nextRightNode() {
+ Node_t *y, *p = this;
+ if (p->right_m != 0) {
+ p = p->right_m;
+ while (p->left_m != 0)
+ p = p->left_m;
+ } else {
+ for (y=p->parent_m; y != 0 && p == y->right_m; y=y->parent_m)
+ p = y;
+ p = y;
+ }
+ return p;
+ }
+ Node_t *nextRightTouchNode(const Domain_t &d) {
+ Node_t *p = this;
+ Node_t *y = right_m;
+ if (y != 0 && touches(d, y->domain_m)) {
+ p = y;
+ for (y=y->left_m; y != 0 && touches(d, y->domain_m); y=y->left_m)
+ p = y;
+ } else {
+ for (y=p->parent_m; y != 0 && p == y->right_m; y=y->parent_m)
+ p = y;
+ p = y;
+ }
+ return p;
+ }
+ Node_t *findLeftNode() {
+ Node_t *p = this;
+ while (p->left_m != 0)
+ p = p->left_m;
+ while (p != 0 && p->begin() == p->end())
+ p = p->nextRightNode();
+ return p;
+ }
+ Node_t *findLeftTouchNode(const Domain_t &d) {
+ Node_t *y, *p = this;
+ for (y=p->left_m; y != 0 && touches(d, y->domain_m); y=y->left_m)
+ p = y;
+ return p;
+ }
+ private:
+ Domain_t domain_m;
+ Node_t *left_m, *right_m, *parent_m;
+ List_t list_m;
+ };
+ template<class Dom, class T>
+ class DomainMapIterator
+ {
+ public:
+ typedef Dom Domain_t;
+ typedef DomainMapNode<Dom,T> Node_t;
+ typedef typename Node_t::Data_t Value_t;
+ typedef typename Node_t::iterator NodeIter_t;
+ DomainMapIterator() : node_m(0) { }
+ DomainMapIterator(Node_t *n, NodeIter_t i) : node_m(n), iter_m(i) { }
+ ~DomainMapIterator() { }
+ Node_t *getNode() const { return node_m; }
+ NodeIter_t getIter() const { return iter_m; }
+ bool operator==(const DomainMapIterator<Dom,T> &dmi) {
+ return (node_m == dmi.node_m && (node_m == 0 || iter_m == dmi.iter_m));
+ }
+ bool operator!=(const DomainMapIterator<Dom,T> &dmi) {
+ return !(*this == dmi);
+ }
+ Value_t &operator*() {
+ ;
+ return (*iter_m).second;
+ }
+ Domain_t &domain() {
+ ;
+ return (*iter_m).first;
+ }
+ DomainMapIterator<Dom,T> &operator++() {
+ ;
+ if ((++iter_m) == node_m->end()) {
+ do {
+ node_m = node_m->nextRightNode();
+ } while (node_m != 0 && (iter_m=node_m->begin()) == node_m->end());
+ }
+ return *this;
+ }
+ private:
+ Node_t *node_m;
+ NodeIter_t iter_m;
+ };
+ template<class Dom, class T>
+ class DomainMapConstIterator
+ {
+ public:
+ typedef Dom Domain_t;
+ typedef DomainMapNode<Dom,T> Node_t;
+ typedef typename Node_t::Data_t Value_t;
+ typedef typename Node_t::iterator NodeIter_t;
+ DomainMapConstIterator() : node_m(0) { }
+ DomainMapConstIterator(Node_t *n, NodeIter_t i)
+ : node_m(n), iter_m(i) { }
+ DomainMapConstIterator(const DomainMapIterator<Dom,T> &dmi)
+ : node_m(dmi.getNode()), iter_m(dmi.getIter()) { }
+ ~DomainMapConstIterator() { }
+ bool operator==(const DomainMapConstIterator<Dom,T> &dmi) {
+ return (node_m == dmi.node_m && (node_m == 0 || iter_m == dmi.iter_m));
+ }
+ bool operator!=(const DomainMapConstIterator<Dom,T> &dmi) {
+ return !(*this == dmi);
+ }
+ Value_t operator*() {
+ ;
+ return (*iter_m).second;
+ }
+ Domain_t domain() {
+ ;
+ return (*iter_m).first;
+ }
+ DomainMapConstIterator<Dom,T> &operator++() {
+ ;
+ if ((++iter_m) == node_m->end()) {
+ do {
+ node_m = node_m->nextRightNode();
+ } while (node_m != 0 && (iter_m=node_m->begin()) == node_m->end());
+ }
+ return *this;
+ }
+ private:
+ Node_t *node_m;
+ NodeIter_t iter_m;
+ };
+ template<class Dom, class T>
+ class DomainMapTouchIterator
+ {
+ public:
+ typedef Dom Domain_t;
+ typedef DomainMapNode<Dom,T> Node_t;
+ typedef typename Node_t::Data_t Value_t;
+ typedef typename Node_t::iterator NodeIter_t;
+ DomainMapTouchIterator() : node_m(0) { }
+ DomainMapTouchIterator(Node_t *n, NodeIter_t i, const Domain_t &d)
+ : node_m(n), iter_m(i), domain_m(d) { }
+ ~DomainMapTouchIterator() { }
+ bool operator==(const DomainMapTouchIterator<Dom,T> &dmi) {
+ return (node_m == dmi.node_m && (node_m == 0 || iter_m == dmi.iter_m));
+ }
+ bool operator!=(const DomainMapTouchIterator<Dom,T> &dmi) {
+ return !(*this == dmi);
+ }
+ Value_t &operator*() {
+ ;
+ return (*iter_m).second;
+ }
+ Domain_t &domain() {
+ ;
+ return (*iter_m).first;
+ }
+ DomainMapTouchIterator<Dom,T> &operator++() {
+ ;
+ while ((++iter_m) != node_m->end()) {
+ if (touches(domain_m, (*iter_m).first))
+ return *this;
+ }
+ do {
+ if ((node_m = node_m->nextRightTouchNode(domain_m)) != 0)
+ for (iter_m = node_m->begin(); iter_m != node_m->end(); ++iter_m)
+ if (touches(domain_m, (*iter_m).first))
+ return *this;
+ } while (node_m != 0);
+ return *this;
+ }
+ private:
+ Node_t *node_m;
+ NodeIter_t iter_m;
+ Domain_t domain_m;
+ };
+ template<class Dom, class T>
+ class DomainMap
+ {
+ public:
+ typedef Dom Domain_t;
+ typedef Dom key_type;
+ typedef T Data_t;
+ typedef T mapped_type;
+ typedef std::pair<Domain_t,Data_t> Value_t;
+ typedef std::pair<Domain_t,Data_t> value_type;
+ typedef DomainMapIterator<Domain_t,Data_t> iterator;
+ typedef DomainMapConstIterator<Domain_t,Data_t> const_iterator;
+ typedef DomainMapTouchIterator<Domain_t,Data_t> touch_iterator;
+ typedef std::pair<touch_iterator,touch_iterator> Touch_t;
+ typedef std::pair<touch_iterator,touch_iterator> touch_type;
+ typedef long Size_t;
+ typedef long size_type;
+ DomainMap() : size_m(0), root_m(0) { }
+ DomainMap(const Domain_t &d) : size_m(0), root_m(0) {
+ initialize(d);
+ }
+ void initialize(const Domain_t &d) {
+ ;
+ root_m = new Node_t(d);
+ }
+ ~DomainMap() {
+ if (root_m != 0)
+ delete root_m;
+ }
+ iterator begin() { return left_m; }
+ iterator end() { return iterator(); }
+ const_iterator begin() const { return const_iterator(left_m); }
+ const_iterator end() const { return const_iterator(); }
+ Size_t size() const { return size_m; }
+ Touch_t touch(const Domain_t &d) const {
+ Node_t *p = root_m;
+ if (p != 0)
+ {
+ p = p->findLeftTouchNode(d);
+ do
+ {
+ for (NodeIter_t a = p->begin(); a != p->end(); ++a)
+ if (touches(d, (*a).first))
+ return Touch_t(touch_iterator(p, a, d), touch_iterator());
+ p = p->nextRightTouchNode(d);
+ } while (p != 0);
+ }
+ return Touch_t(touch_iterator(), touch_iterator());
+ }
+ void insert(const Value_t &v) {
+ ;
+ root_m->insert(v);
+ size_m++;
+ }
+ void update() {
+ Node_t *leftnode;
+ if (root_m != 0 && size_m > 0 && (leftnode=root_m->findLeftNode()) != 0)
+ left_m = iterator(leftnode, leftnode->begin());
+ else
+ left_m = iterator();
+ }
+ void clear() {
+ if (root_m != 0) {
+ Node_t *newroot = new Node_t(root_m->domain());
+ delete root_m;
+ root_m = newroot;
+ size_m = 0;
+ update();
+ }
+ }
+ void zap() {
+ if (root_m != 0)
+ delete root_m;
+ size_m = 0;
+ root_m = 0;
+ }
+ template<class Out>
+ void print(Out &o) const;
+ void print() const;
+ private:
+ typedef DomainMapNode<Domain_t,Data_t> Node_t;
+ typedef typename Node_t::iterator NodeIter_t;
+ Size_t size_m;
+ Node_t *root_m;
+ iterator left_m;
+ DomainMap(const DomainMap<Domain_t,Data_t> &);
+ DomainMap<Domain_t,Data_t> &operator=(const DomainMap<Domain_t,Data_t> &);
+ };
+ template<class Dom, class T>
+ template<class Out>
+ void DomainMap<Dom, T>::print(Out &o) const
+ {
+ if (size() < 1 || root_m == 0)
+ {
+ o << "DomainMap: empty.";
+ }
+ else
+ {
+ o << "DomainMap: Total domain = " << root_m->domain();
+ o << ", touching domains:\n";
+ Touch_t touchiters = touch(root_m->domain());
+ while (touchiters.first != touchiters.second)
+ {
+ o << " " << touchiters.first.domain() << " ==> ";
+ o << *(touchiters.first) << "\n";
+ ++(touchiters.first);
+ }
+ }
+ }
+ template<class Dom, class T>
+ void DomainMap<Dom, T>::print() const
+ {
+ if (size() < 1 || root_m == 0)
+ {
+ std::cout << "DomainMap: empty.";
+ }
+ else
+ {
+ std::cout << "DomainMap: Total domain = " << root_m->domain();
+ std::cout << ", touching domains:\n";
+ Touch_t touchiters = touch(root_m->domain());
+ while (touchiters.first != touchiters.second)
+ {
+ std::cout << " " << touchiters.first.domain() << " ==> ";
+ std::cout << *(touchiters.first) << "\n";
+ ++(touchiters.first);
+ }
+ }
+ }
+ template <class Dom, class T>
+ std::ostream &operator<<(std::ostream &o, const DomainMap<Dom, T> &dmap)
+ {
+ dmap.print(o);
+ return o;
+ }
+ template <class T>
+ class ConstDerefIterator;
+ template <class T>
+ class DerefIterator
+ {
+ public:
+ typedef T Value_t;
+ typedef std::vector<T*> List_t;
+ typedef DerefIterator<Value_t> iterator;
+ typedef ConstDerefIterator<Value_t> const_iterator;
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef Value_t value_type;
+ typedef ptrdiff_t difference_type;
+ typedef Value_t* pointer;
+ typedef Value_t& reference;
+ friend class ConstDerefIterator<T>;
+ friend iterator operator+ (const difference_type n, const iterator &iter)
+ {
+ return iterator(iter.p_m + n);
+ }
+ protected:
+ typename List_t::iterator p_m;
+ public:
+ inline DerefIterator() { }
+ inline DerefIterator(typename List_t::iterator x) : p_m(x) { }
+ inline reference operator*() const {
+ return **p_m;
+ }
+ inline pointer operator->() const {
+ return *p_m;
+ }
+ inline iterator &operator++() {
+ ++p_m;
+ return *this;
+ }
+ inline iterator operator++(int) {
+ iterator tmp = *this;
+ ++p_m;
+ return tmp;
+ }
+ inline iterator &operator--() {
+ --p_m;
+ return *this;
+ }
+ inline iterator operator--(int) {
+ iterator tmp = *this;
+ --p_m;
+ return tmp;
+ }
+ inline iterator &operator+=(const difference_type i) {
+ p_m += i;
+ return *this;
+ }
+ inline iterator &operator-=(const difference_type i) {
+ p_m -= i;
+ return *this;
+ }
+ inline iterator operator+(const difference_type i) const {
+ return iterator(p_m + i);
+ }
+ inline iterator operator-(const difference_type i) const {
+ return iterator(p_m - i);
+ }
+ inline difference_type operator-(const iterator &x) const {
+ return p_m - x.p_m;
+ }
+ inline difference_type operator-(const const_iterator &x) const {
+ return p_m - x.p_m;
+ }
+ inline reference operator[](const difference_type i) const {
+ return **(p_m + i);
+ }
+ inline bool operator==(const iterator &x) const {
+ return p_m == x.p_m;
+ }
+ inline bool operator==(const const_iterator &x) const {
+ return p_m == x.p_m;
+ }
+ inline bool operator<(const iterator &x) const {
+ return p_m < x.p_m;
+ }
+ inline bool operator<(const const_iterator &x) const {
+ return p_m < x.p_m;
+ }
+ inline bool operator!= (const iterator &y) const
+ { return ! (*this == y); }
+ inline bool operator> (const iterator &y) const
+ { return (y < *this); }
+ inline bool operator<= (const iterator &y) const
+ { return ! (y < *this); }
+ inline bool operator>= (const iterator &y) const
+ { return ! (*this < y); }
+ inline bool operator!= (const const_iterator &y) const
+ { return ! (*this == y); }
+ inline bool operator> (const const_iterator &y) const
+ { return (y < *this); }
+ inline bool operator<= (const const_iterator &y) const
+ { return ! (y < *this); }
+ inline bool operator>= (const const_iterator &y) const
+ { return ! (*this < y); }
+ };
+ template <class T>
+ class ConstDerefIterator
+ {
+ public:
+ typedef T Value_t;
+ typedef std::vector<T*> List_t;
+ typedef DerefIterator<Value_t> iterator;
+ typedef ConstDerefIterator<Value_t> const_iterator;
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef Value_t value_type;
+ typedef ptrdiff_t difference_type;
+ typedef const Value_t* pointer;
+ typedef const Value_t& reference;
+ friend class DerefIterator<T>;
+ friend const_iterator operator+ (const difference_type n,
+ const const_iterator &iter)
+ {
+ return const_iterator(iter.p_m + n);
+ }
+ protected:
+ typename List_t::const_iterator p_m;
+ public:
+ inline ConstDerefIterator() { }
+ inline ConstDerefIterator(const typename List_t::const_iterator &x) : p_m(x) { }
+ inline ConstDerefIterator(const typename List_t::iterator &x) : p_m(x) { }
+ inline ConstDerefIterator(const iterator &x) : p_m(x.p_m) { }
+ inline ConstDerefIterator(const const_iterator &x) : p_m(x.p_m) { }
+ inline reference operator*() const {
+ return **p_m;
+ }
+ inline pointer operator->() const {
+ return *p_m;
+ }
+ inline const_iterator &operator++() {
+ ++p_m;
+ return *this;
+ }
+ inline const_iterator operator++(int) {
+ const_iterator tmp = *this;
+ ++p_m;
+ return tmp;
+ }
+ inline const_iterator &operator--() {
+ --p_m;
+ return *this;
+ }
+ inline const_iterator operator--(int) {
+ const_iterator tmp = *this;
+ --p_m;
+ return tmp;
+ }
+ inline const_iterator &operator+=(const difference_type i) {
+ p_m += i;
+ return *this;
+ }
+ inline const_iterator &operator-=(const difference_type i) {
+ p_m -= i;
+ return *this;
+ }
+ inline const_iterator operator+(const difference_type i) const {
+ return const_iterator(p_m + i);
+ }
+ inline const_iterator operator-(const difference_type i) const {
+ return const_iterator(p_m - i);
+ }
+ inline difference_type operator-(const const_iterator &x) const {
+ return p_m - x.p_m;
+ }
+ inline difference_type operator-(const iterator &x)
+ const {
+ return p_m - x.p_m;
+ }
+ inline reference operator[](const difference_type i) const {
+ return **(p_m + i);
+ }
+ inline bool operator==(const const_iterator &x) const {
+ return p_m == x.p_m;
+ }
+ inline bool operator==(const iterator &x) const {
+ return p_m == x.p_m;
+ }
+ inline bool operator<(const const_iterator &x) const {
+ return p_m < x.p_m;
+ }
+ inline bool operator<(const iterator &x) const {
+ return p_m < x.p_m;
+ }
+ inline bool operator!= (const const_iterator &y) const
+ { return ! (*this == y); }
+ inline bool operator> (const const_iterator &y) const
+ { return (y < *this); }
+ inline bool operator<= (const const_iterator &y) const
+ { return ! (y < *this); }
+ inline bool operator>= (const const_iterator &y) const
+ { return ! (*this < y); }
+ inline bool operator!= (const iterator &y) const
+ { return ! (*this == y); }
+ inline bool operator> (const iterator &y) const
+ { return (y < *this); }
+ inline bool operator<= (const iterator &y) const
+ { return ! (y < *this); }
+ inline bool operator>= (const iterator &y) const
+ { return ! (*this < y); }
+ };
+ template<int Dim, int Dim2>
+ class ViewIndexer
+ {
+ public:
+ typedef ViewIndexer<Dim, Dim2> This_t;
+ typedef Interval<Dim> Domain_t;
+ typedef Range<Dim2> BaseDomain_t;
+ typedef Loc<Dim2> Mask_t;
+ ViewIndexer() { }
+ template<class DT>
+ ViewIndexer(const SliceDomain<DT> &dom)
+ : domain_m(Pooma::NoInit()), baseDomain_m(dom.totalDomain())
+ {
+ PoomaCTAssert<(Dim == DT::sliceDimensions)>::test();
+ PoomaCTAssert<(Dim2 == DT::dimensions)>::test();
+ int dt, d;
+ const typename DT::TotalDomain_t &domain = dom.totalDomain();
+ for (d = 0, dt = 0; dt < Dim2; ++dt)
+ {
+ if (!dom.ignorable(dt))
+ {
+ ;
+ offset_m[d] = domain[dt].first();
+ stride_m[d] = domain[dt].stride();
+ domain_m[d] = Interval<1>(domain[dt].length());
+ ind_m[d] = dt;
+ ++d;
+ }
+ else
+ {
+ ;
+ mask_m[dt] = domain[dt].first();
+ }
+ }
+ }
+ template<class DT>
+ ViewIndexer(const ViewIndexer<Dim, Dim2> &orig,
+ const Domain<Dim, DT> &dom)
+ : domain_m(Pooma::NoInit()),
+ baseDomain_m(Pooma::NoInit()),
+ mask_m(orig.mask())
+ {
+ baseDomain_m = orig.baseDomain();
+ const typename DT::Domain_t &domain = dom.unwrap();
+ for (int d = 0; d < Dim; ++d)
+ {
+ offset_m[d] = orig.offset(d) + orig.stride(d) *
+ domain[d].first();
+ stride_m[d] = orig.stride(d) * domain[d].stride();
+ domain_m[d] = Interval<1>(domain[d].length());
+ ind_m[d] = orig.indirection(d);
+ }
+ localToBase(domain_m, baseDomain_m);
+ }
+ template<int OrigDim, class DT>
+ ViewIndexer(const ViewIndexer<OrigDim, Dim2> &orig,
+ const SliceDomain<DT> &dom)
+ : domain_m(Pooma::NoInit()),
+ baseDomain_m(orig.baseDomain()), mask_m(orig.mask())
+ {
+ PoomaCTAssert<(DT::sliceDimensions == Dim)>::test();
+ PoomaCTAssert<(DT::dimensions == OrigDim)>::test();
+ int dt, d;
+ const typename DT::TotalDomain_t &domain = dom.totalDomain();
+ for (d = 0, dt = 0; dt < OrigDim; ++dt)
+ {
+ if (!dom.ignorable(dt))
+ {
+ ;
+ offset_m[d] = orig.offset(dt) + orig.stride(dt) *
+ domain[dt].first();
+ stride_m[d] = orig.stride(dt) * domain[dt].stride();
+ domain_m[d] = Interval<1>(domain[dt].length());
+ ind_m[d] = orig.indirection(dt);
+ baseDomain_m[ind_m[d]] = Range<1>(
+ offset_m[d],
+ offset_m[d] + stride_m[d] * domain_m[d].last(),
+ stride_m[d]);
+ ++d;
+ }
+ else
+ {
+ ;
+ int m = orig.offset(dt) + orig.stride(dt) *
+ domain[dt].first();
+ mask_m[orig.indirection(dt)] = m;
+ baseDomain_m[orig.indirection(dt)] =
+ Range<1>(m, m, 1);
+ }
+ }
+ }
+ ViewIndexer(const This_t &model)
+ : domain_m(model.domain()), baseDomain_m(model.baseDomain()),
+ mask_m(model.mask())
+ {
+ for (int d = 0; d < Dim; d++)
+ {
+ ind_m[d] = model.indirection(d);
+ offset_m[d] = model.offset(d);
+ stride_m[d] = model.stride(d);
+ }
+ }
+ This_t &operator=(const This_t &rhs)
+ {
+ domain_m = rhs.domain();
+ baseDomain_m = rhs.baseDomain();
+ mask_m = rhs.mask();
+ for (int d = 0; d < Dim; d++)
+ {
+ ind_m[d] = rhs.indirection(d);
+ offset_m[d] = rhs.offset(d);
+ stride_m[d] = rhs.stride(d);
+ }
+ return *this;
+ }
+ const Domain_t &domain() const { return domain_m; }
+ const Domain_t &innerDomain() const { return domain_m; }
+ const BaseDomain_t &baseDomain() const { return baseDomain_m; }
+ int indirection(int i) const { return ind_m[i]; }
+ const Mask_t &mask() const { return mask_m; }
+ int offset(int i) const { return offset_m[i]; }
+ int stride(int i) const { return stride_m[i]; }
+ void translate(const Loc<Dim> &loc, Loc<Dim2> &oloc) const
+ {
+ oloc = mask_m;
+ for (int d = 0; d < Dim; d++)
+ oloc[ind_m[d]] = Loc<1>(offset_m[d] + stride_m[d] * loc[d].first());
+ }
+ void translate(int i0, Loc<Dim2> &loc) const
+ {
+ loc = mask_m;
+ loc[ind_m[0]] = offset_m[0] + stride_m[0] * i0;
+ }
+ void translate(int i0, int i1, Loc<Dim2> &loc) const
+ {
+ loc = mask_m;
+ loc[ind_m[0]] = offset_m[0] + stride_m[0] * i0;
+ loc[ind_m[1]] = offset_m[1] + stride_m[1] * i1;
+ }
+ void translate(int i0, int i1, int i2,
+ Loc<Dim2> &loc) const
+ {
+ loc = mask_m;
+ loc[ind_m[0]] = offset_m[0] + stride_m[0] * i0;
+ loc[ind_m[1]] = offset_m[1] + stride_m[1] * i1;
+ loc[ind_m[2]] = offset_m[2] + stride_m[2] * i2;
+ }
+ void translate(int i0, int i1, int i2, int i3,
+ Loc<Dim2> &loc) const
+ {
+ loc = mask_m;
+ loc[ind_m[0]] = offset_m[0] + stride_m[0] * i0;
+ loc[ind_m[1]] = offset_m[1] + stride_m[1] * i1;
+ loc[ind_m[2]] = offset_m[2] + stride_m[2] * i2;
+ loc[ind_m[3]] = offset_m[3] + stride_m[3] * i3;
+ }
+ void translate(int i0, int i1, int i2, int i3,
+ int i4, Loc<Dim2> &loc) const
+ {
+ loc = mask_m;
+ loc[ind_m[0]] = offset_m[0] + stride_m[0] * i0;
+ loc[ind_m[1]] = offset_m[1] + stride_m[1] * i1;
+ loc[ind_m[2]] = offset_m[2] + stride_m[2] * i2;
+ loc[ind_m[3]] = offset_m[3] + stride_m[3] * i3;
+ loc[ind_m[4]] = offset_m[4] + stride_m[4] * i4;
+ }
+ void translate(int i0, int i1, int i2, int i3,
+ int i4, int i5, Loc<Dim2> &loc) const
+ {
+ loc = mask_m;
+ loc[ind_m[0]] = offset_m[0] + stride_m[0] * i0;
+ loc[ind_m[1]] = offset_m[1] + stride_m[1] * i1;
+ loc[ind_m[2]] = offset_m[2] + stride_m[2] * i2;
+ loc[ind_m[3]] = offset_m[3] + stride_m[3] * i3;
+ loc[ind_m[4]] = offset_m[4] + stride_m[4] * i4;
+ loc[ind_m[5]] = offset_m[5] + stride_m[5] * i5;
+ }
+ void translate(int i0, int i1, int i2, int i3,
+ int i4, int i5, int i6, Loc<Dim2> &loc) const
+ {
+ loc = mask_m;
+ loc[ind_m[0]] = offset_m[0] + stride_m[0] * i0;
+ loc[ind_m[1]] = offset_m[1] + stride_m[1] * i1;
+ loc[ind_m[2]] = offset_m[2] + stride_m[2] * i2;
+ loc[ind_m[3]] = offset_m[3] + stride_m[3] * i3;
+ loc[ind_m[4]] = offset_m[4] + stride_m[4] * i4;
+ loc[ind_m[5]] = offset_m[5] + stride_m[5] * i5;
+ loc[ind_m[6]] = offset_m[6] + stride_m[6] * i6;
+ }
+ template<class DT>
+ BaseDomain_t &localToBase(const Domain<Dim, DT> &dlocal,
+ BaseDomain_t &base) const
+ {
+ base = baseDomain_m;
+ const typename DT::Domain_t &local = dlocal.unwrap();
+ for (int d = 0; d < Dim; d++)
+ {
+ base[ind_m[d]] = Range<1>(
+ offset_m[d] + stride_m[d] * local[d].first(),
+ offset_m[d] + stride_m[d] * local[d].last(),
+ stride_m[d] * local[d].stride());
+ }
+ return base;
+ }
+ template<class DT>
+ SliceRange<Dim2, Dim> &localToBase(const Domain<Dim, DT> &dlocal,
+ SliceRange<Dim2, Dim> &base) const
+ {
+ base.totalDomain() = baseDomain_m;
+ const typename DT::Domain_t &local = dlocal.unwrap();
+ for (int d = 0; d < Dim; d++)
+ {
+ Range<1> r(
+ offset_m[d] + stride_m[d] * local[d].first(),
+ offset_m[d] + stride_m[d] * local[d].last(),
+ stride_m[d] * local[d].stride());
+ base.totalDomain()[ind_m[d]] = r;
+ base.sliceDomain()[d] = r;
+ base.cantIgnoreDomain(ind_m[d]);
+ }
+ return base;
+ }
+ Interval<Dim> &baseToLocal(const BaseDomain_t &base,
+ Interval<Dim> &local) const
+ {
+ int j;
+ for (int d = 0; d < Dim; d++)
+ {
+ j = ind_m[d];
+ local[d] = Interval<1>(
+ (base[j].first() - offset_m[d]) / stride_m[d],
+ (base[j].last() - offset_m[d]) / stride_m[d]);
+ ;
+ }
+ return local;
+ }
+ Range<Dim> &baseToLocal(const BaseDomain_t &base,
+ Range<Dim> &local) const
+ {
+ int j;
+ for (int d = 0; d < Dim; d++)
+ {
+ j = ind_m[d];
+ local[d] = Range<1>(
+ (base[j].first() - offset_m[d]) / stride_m[d],
+ (base[j].last() - offset_m[d]) / stride_m[d],
+ base[j].stride() / stride_m[d]);
+ }
+ return local;
+ }
+ Interval<Dim> &baseToLocalInterval(const Interval<Dim2> &base,
+ Interval<Dim> &local) const
+ {
+ int j;
+ for (int d = 0; d < Dim; d++)
+ {
+ j = ind_m[d];
+ local[d] = Interval<1>((base[j].first() - offset_m[d]) / stride_m[d],
+ (base[j].last() - offset_m[d]) / stride_m[d]);
+ ;
+ ;
+ }
+ return local;
+ }
+ private:
+ Domain_t domain_m;
+ BaseDomain_t baseDomain_m;
+ int stride_m[Dim], offset_m[Dim];
+ int ind_m[Dim];
+ Mask_t mask_m;
+ };
+ template<int Dim>
+ class ViewIndexer<Dim, Dim>
+ {
+ public:
+ typedef ViewIndexer<Dim, Dim> This_t;
+ typedef Interval<Dim> Domain_t;
+ typedef Range<Dim> BaseDomain_t;
+ typedef Loc<Dim> Mask_t;
+ ViewIndexer() { }
+ template<class DT>
+ ViewIndexer(const Domain<Dim, DT> &dom)
+ : domain_m(Pooma::NoInit()), baseDomain_m(dom.unwrap())
+ {
+ const typename DT::Domain_t &domain = dom.unwrap();
+ for (int d = 0; d < Dim; ++d)
+ {
+ offset_m[d] = domain[d].first();
+ stride_m[d] = domain[d].stride();
+ domain_m[d] = Interval<1>(domain[d].length());
+ }
+ }
+ template<class DT>
+ ViewIndexer(const ViewIndexer<Dim, Dim> &orig,
+ const Domain<Dim, DT> &dom)
+ : domain_m(Pooma::NoInit()),
+ baseDomain_m(dom.unwrap()),
+ mask_m(orig.mask())
+ {
+ const typename DT::Domain_t &domain = dom.unwrap();
+ for (int d = 0; d < Dim; ++d)
+ {
+ offset_m[d] = orig.offset(d) + orig.stride(d) *
+ domain[d].first();
+ stride_m[d] = orig.stride(d) * domain[d].stride();
+ domain_m[d] = Interval<1>(domain[d].length());
+ }
+ localToBase(domain_m, baseDomain_m);
+ }
+ ViewIndexer(const This_t &model)
+ : domain_m(model.domain()), baseDomain_m(model.baseDomain()),
+ mask_m(model.mask())
+ {
+ for (int d = 0; d < Dim; d++)
+ {
+ offset_m[d] = model.offset(d);
+ stride_m[d] = model.stride(d);
+ }
+ }
+ This_t &operator=(const This_t &rhs)
+ {
+ domain_m = rhs.domain();
+ baseDomain_m = rhs.baseDomain();
+ mask_m = rhs.mask();
+ for (int d = 0; d < Dim; d++)
+ {
+ offset_m[d] = rhs.offset(d);
+ stride_m[d] = rhs.stride(d);
+ }
+ return *this;
+ }
+ const Domain_t &domain() const { return domain_m; }
+ const Domain_t &innerDomain() const { return domain_m; }
+ const BaseDomain_t &baseDomain() const { return baseDomain_m; }
+ int indirection(int i) const { return i; }
+ const Mask_t &mask() const { return mask_m; }
+ int offset(int i) const { return offset_m[i]; }
+ int stride(int i) const { return stride_m[i]; }
+ void translate(const Loc<Dim> &loc, Loc<Dim> &oloc) const
+ {
+ for (int d = 0; d < Dim; d++)
+ oloc[d] = Loc<1>(offset_m[d] + stride_m[d] * loc[d].first());
+ }
+ void translate(int i0, Loc<Dim> &loc) const
+ {
+ loc[0] = offset_m[0] + stride_m[0] * i0;
+ }
+ void translate(int i0, int i1, Loc<Dim> &loc) const
+ {
+ loc[0] = offset_m[0] + stride_m[0] * i0;
+ loc[1] = offset_m[1] + stride_m[1] * i1;
+ }
+ void translate(int i0, int i1, int i2,
+ Loc<Dim> &loc) const
+ {
+ loc[0] = offset_m[0] + stride_m[0] * i0;
+ loc[1] = offset_m[1] + stride_m[1] * i1;
+ loc[2] = offset_m[2] + stride_m[2] * i2;
+ }
+ void translate(int i0, int i1, int i2, int i3,
+ Loc<Dim> &loc) const
+ {
+ loc[0] = offset_m[0] + stride_m[0] * i0;
+ loc[1] = offset_m[1] + stride_m[1] * i1;
+ loc[2] = offset_m[2] + stride_m[2] * i2;
+ loc[3] = offset_m[3] + stride_m[3] * i3;
+ }
+ void translate(int i0, int i1, int i2, int i3,
+ int i4, Loc<Dim> &loc) const
+ {
+ loc[0] = offset_m[0] + stride_m[0] * i0;
+ loc[1] = offset_m[1] + stride_m[1] * i1;
+ loc[2] = offset_m[2] + stride_m[2] * i2;
+ loc[3] = offset_m[3] + stride_m[3] * i3;
+ loc[4] = offset_m[4] + stride_m[4] * i4;
+ }
+ void translate(int i0, int i1, int i2, int i3,
+ int i4, int i5, Loc<Dim> &loc) const
+ {
+ loc[0] = offset_m[0] + stride_m[0] * i0;
+ loc[1] = offset_m[1] + stride_m[1] * i1;
+ loc[2] = offset_m[2] + stride_m[2] * i2;
+ loc[3] = offset_m[3] + stride_m[3] * i3;
+ loc[4] = offset_m[4] + stride_m[4] * i4;
+ loc[5] = offset_m[5] + stride_m[5] * i5;
+ }
+ void translate(int i0, int i1, int i2, int i3,
+ int i4, int i5, int i6, Loc<Dim> &loc) const
+ {
+ loc[0] = offset_m[0] + stride_m[0] * i0;
+ loc[1] = offset_m[1] + stride_m[1] * i1;
+ loc[2] = offset_m[2] + stride_m[2] * i2;
+ loc[3] = offset_m[3] + stride_m[3] * i3;
+ loc[4] = offset_m[4] + stride_m[4] * i4;
+ loc[5] = offset_m[5] + stride_m[5] * i5;
+ loc[6] = offset_m[6] + stride_m[6] * i6;
+ }
+ template<class DT>
+ BaseDomain_t &localToBase(const Domain<Dim, DT> &dlocal,
+ BaseDomain_t &base) const
+ {
+ const typename DT::Domain_t &local = dlocal.unwrap();
+ for (int d = 0; d < Dim; d++)
+ {
+ base[d] = Range<1>(
+ offset_m[d] + stride_m[d] * local[d].first(),
+ offset_m[d] + stride_m[d] * local[d].last(),
+ stride_m[d] * local[d].stride());
+ }
+ return base;
+ }
+ template<class DT>
+ SliceRange<Dim, Dim> &localToBase(const Domain<Dim, DT> &dlocal,
+ SliceRange<Dim, Dim> &base) const
+ {
+ base.totalDomain() = baseDomain_m;
+ const typename DT::Domain_t &local = dlocal.unwrap();
+ for (int d = 0; d < Dim; d++)
+ {
+ Range<1> r(
+ offset_m[d] + stride_m[d] * local[d].first(),
+ offset_m[d] + stride_m[d] * local[d].last(),
+ stride_m[d] * local[d].stride());
+ base.totalDomain()[d] = r;
+ base.sliceDomain()[d] = r;
+ base.cantIgnoreDomain(d);
+ }
+ return base;
+ }
+ Interval<Dim> &baseToLocal(const BaseDomain_t &base,
+ Interval<Dim> &local) const
+ {
+ for (int d = 0; d < Dim; d++)
+ {
+ local[d] = Interval<1>(
+ (base[d].first() - offset_m[d]) / stride_m[d],
+ (base[d].last() - offset_m[d]) / stride_m[d]);
+ ;
+ }
+ return local;
+ }
+ Range<Dim> &baseToLocal(const BaseDomain_t &base,
+ Range<Dim> &local) const
+ {
+ for (int d = 0; d < Dim; d++)
+ {
+ local[d] = Range<1>(
+ (base[d].first() - offset_m[d]) / stride_m[d],
+ (base[d].last() - offset_m[d]) / stride_m[d],
+ base[d].stride() / stride_m[d]);
+ }
+ return local;
+ }
+ Interval<Dim> &baseToLocalInterval(const Interval<Dim> &base,
+ Interval<Dim> &local) const
+ {
+ for (int d = 0; d < Dim; d++)
+ {
+ local[d] = Interval<1>((base[d].first() - offset_m[d]) / stride_m[d],
+ (base[d].last() - offset_m[d]) / stride_m[d]);
+ ;
+ ;
+ }
+ return local;
+ }
+ private:
+ Domain_t domain_m;
+ BaseDomain_t baseDomain_m;
+ int stride_m[Dim], offset_m[Dim];
+ Mask_t mask_m;
+ };
+ template<int Dim>
+ class ContiguousMapper
+ : public ContextMapper<Dim>
+ {
+ public:
+ typedef Interval<Dim> Domain_t;
+ typedef Node<Domain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ template<class Partitioner>
+ ContiguousMapper(const Partitioner & gp,
+ const Loc<Dim> &nblocks)
+ : blocks_m(gp.blocks())
+ {
+ }
+ template<class Partitioner>
+ ContiguousMapper(const Partitioner & gp)
+ : blocks_m(gp.blocks())
+ {
+ }
+ ContiguousMapper(const Loc<Dim> & blocks)
+ : blocks_m(blocks)
+ {
+ }
+ void map(const List_t & templist) const;
+ Loc<Dim> blocks_m;
+ };
+ template<int Dim>
+ void ContiguousMapper<Dim>::map(const List_t & templist) const
+ {
+ int idx[Dim];
+ for (int i = 0;i<Dim;++i)
+ idx[i]=0;
+ int strides[Dim];
+ strides[Dim-1] = 1;
+ for ( int i=Dim-2; i>=0; --i)
+ strides[i] = strides[i+1]*blocks_m[i+1].last();
+ int npatch = 1;
+ for (int i=0; i<Dim; ++i)
+ npatch *= blocks_m[i].first();
+ int ncontexts = Pooma::contexts();
+ int npc = npatch/ncontexts;
+ int remainder = npatch - (npc*ncontexts);
+ int pcontext = 0;
+ int c = 0;
+ int patchdone = 0;
+ int patchleft = npatch;
+ int incriment[Dim];
+ for (int i =0 ; i<Dim; ++i) incriment[i] = 1;
+ while ( true )
+ {
+ int allIdx = 0;
+ for ( int i = 0 ; i < Dim ; ++i)
+ allIdx += idx[i]*strides[i];
+ (*templist[allIdx]).context() = pcontext;
+ ++c;
+ ++patchdone;
+ --patchleft;
+ if(c >= npc )
+ {
+ if (c == npc && remainder >0 &&
+ ((idx[0]-1 >= 0 && idx[0]+1<=(blocks_m[0].first()-1)) ||
+ (patchleft - ((npc+1)*(ncontexts-(pcontext+1))) >=0 )) )
+ --remainder;
+ else
+ {
+ c = 0;
+ ++pcontext;
+ }
+ }
+ bool t = true;
+ for ( int i = 0 ; i < Dim ; ++i)
+ {
+ t = t && (
+ idx[i] == (blocks_m[i]-1) && incriment[i] == 1
+ ||
+ idx[i] == 0 && incriment[i] == -1);
+ }
+ if (t)
+ break;
+ idx[0] += incriment[0];
+ for ( int i = 0 ; i < Dim ; ++i)
+ {
+ if ( idx[i] > blocks_m[i].last()-1)
+ {
+ idx[i+1]+=incriment[i+1];
+ idx[i]=blocks_m[i].last()-1;
+ incriment[i] *= -1;
+ }
+ else if (idx[i]<0)
+ {
+ idx[i+1]+=incriment[i+1];
+ idx[i]=0;
+ incriment[i] *= -1;
+ }
+ else
+ break;
+ }
+ }
+ ContextMapper<Dim>::setAffinity(templist);
+ }
+ template <int Dim>
+ class BisectionMapper
+ : public ContextMapper<Dim>
+ {
+ public:
+ typedef Interval<Dim> Domain_t;
+ typedef Node<Domain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ template<class Partitioner>
+ BisectionMapper(const Partitioner & gp,
+ const Loc<Dim> &nblocks)
+ : blocks_m(gp.blocks())
+ {
+ }
+ template<class Partitioner>
+ BisectionMapper(const Partitioner & gp)
+ : blocks_m(gp.blocks())
+ {
+ }
+ BisectionMapper(const Loc<Dim>& blocks)
+ : blocks_m(blocks)
+ {
+ }
+ void map(const List_t & templist) const;
+ Loc<Dim> blocks_m;
+ };
+ template <int Dim>
+ void BisectionMapper<Dim>::map(const List_t & templist) const
+ {
+ int ncontexts = Pooma::contexts();
+ int npatch = 1;
+ for (int i =0;i<Dim; ++i)
+ npatch*=blocks_m[i].first();
+ std::list<Domain_t> bvec;
+ Domain_t allb;
+ for (int i = 0; i<Dim; ++i)
+ allb[i]=Interval<1>(0,blocks_m[i].first()-1);
+ bvec.push_back(allb);
+ while ( bvec.size() < ncontexts )
+ {
+ int s = 0;
+ typename std::list<Domain_t>::iterator bstart = bvec.begin();
+ typename std::list<Domain_t>::iterator bend = bvec.end();
+ typename std::list<Domain_t>::iterator bpatch;
+ for ( ; bstart != bend ; ++bstart)
+ {
+ if (s < (*bstart).size() )
+ {
+ bpatch = bstart;
+ s = (*bstart).size();
+ }
+ }
+ int d = 0;
+ int sd = 0;
+ for (int i = 0; i<Dim; ++i)
+ {
+ if ( sd < (*bpatch)[i].size() )
+ {
+ d = i;
+ sd = (*bpatch)[i].size();
+ }
+ }
+ Domain_t hi(*bpatch),lo(*bpatch);
+ int lopoint = hi[d].first();
+ int hipoint = hi[d].last();
+ int mid = lopoint + ( (hipoint - lopoint)/2);
+ if (lopoint<=mid)
+ lo[d] = Interval<1>(lopoint,mid);
+ else
+ lo[d] = Interval<1>(lopoint,lopoint);
+ if ( hipoint>=mid+1)
+ hi[d] = Interval<1>(mid+1,hipoint);
+ else
+ hi[d] = Interval<1>(hipoint,hipoint);
+ bvec.erase(bpatch++);
+ bvec.insert(bpatch,lo);
+ bvec.insert(bpatch,hi);
+ }
+ int strides[Dim];
+ strides[0] = 1;
+ for ( int i=1; i<Dim; ++i)
+ strides[i] = strides[i-1]*blocks_m[i-1].first();
+ typename std::list<Domain_t>::iterator start = bvec.begin();
+ typename std::list<Domain_t>::iterator end = bvec.end();
+ int pcontext = 0;
+ for ( ; start != end ; ++start)
+ {
+ int idx[Dim],mi[Dim],mx[Dim];
+ for ( int i = 0 ; i < Dim ; ++i)
+ {
+ idx[i] = mi[i] = (*start)[i].first();
+ mx[i] = (*start)[i].last();
+ }
+ while ( idx[Dim-1] <= mx[Dim-1] )
+ {
+ int allIdx = 0;
+ for ( int i = 0 ; i < Dim ; ++i)
+ allIdx += idx[i]*strides[i];
+ (*templist[allIdx]).context() = pcontext;
+ ++idx[0];
+ for ( int i = 0 ; i < Dim ; ++i)
+ {
+ if ( idx[i] > mx[i] )
+ {
+ if ( i!=(Dim-1) )
+ {
+ ++idx[i+1];
+ idx[i]=mi[i];
+ }
+ else
+ ++idx[i];
+ }
+ else
+ break;
+ }
+ }
+ ++pcontext;
+ }
+ this->setAffinity(templist);
+ }
+ class UniformMapper
+ : public ContextMapper<1>
+ {
+ public:
+ typedef Interval<1> Domain_t;
+ typedef Node<Domain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ template <class Partitioner>
+ inline
+ UniformMapper(const Partitioner& gp)
+ : blocks_m(gp.blocks())
+ {
+ }
+ inline
+ UniformMapper(const Loc<1>& blocks)
+ : blocks_m(blocks)
+ {
+ }
+ inline
+ UniformMapper(int blocks = 1)
+ : blocks_m(blocks)
+ {
+ }
+ virtual ~UniformMapper(){}
+ void map(const List_t&) const;
+ private:
+ Loc<1> blocks_m;
+ };
+ template<int Dim>
+ class DistributedMapper
+ : public ContextMapper<Dim>
+ {
+ public:
+ typedef Interval<Dim> Domain_t;
+ typedef Node<Domain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ template<class Partitioner>
+ DistributedMapper(const Partitioner & gp)
+ : blocks_m(gp.blocks())
+ {
+ }
+ void map(const List_t & templist) const;
+ void uniformMap(const Loc<1> &blocks,
+ const List_t &templist,
+ const WrappedInt<1>&) const
+ {
+ UniformMapper(blocks).map(templist);
+ }
+ template <int D>
+ void uniformMap(const Loc<D> &,
+ const List_t &,
+ const WrappedInt<D>&) const
+ {
+ ;
+ }
+ private:
+ Loc<Dim> blocks_m;
+ };
+ template<int Dim>
+ void DistributedMapper<Dim>::map(const List_t & templist) const
+ {
+ int ncontexts = Pooma::contexts();
+ int npc = templist.size()/ncontexts;
+ if(ncontexts> templist.size())
+ {
+ npc = 1;
+ ncontexts = templist.size();
+ }
+ if (Dim == 1)
+ {
+ uniformMap(blocks_m,templist,WrappedInt<Dim>());
+ }
+ else if(npc<3)
+ {
+ ContiguousMapper<Dim>(blocks_m).map(templist);
+ }
+ else
+ {
+ BisectionMapper<Dim>(blocks_m).map(templist);
+ }
+ return;
+ }
+ template<int Dim>
+ class UniformGridPartition
+ {
+ public:
+ typedef LocalMapper<Dim> DefaultMapper_t;
+ typedef Interval<Dim> Domain_t;
+ typedef Node<Domain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ enum { uniform = true };
+ enum { gridded = true };
+ enum { tile = false };
+ enum { general = false };
+ enum { dimensions = Dim };
+ UniformGridPartition();
+ UniformGridPartition(const GuardLayers<Dim> &gcs);
+ UniformGridPartition(const Loc<Dim> &a);
+ UniformGridPartition(const Loc<Dim> &a,
+ const GuardLayers<Dim> &gcs );
+ UniformGridPartition(const Loc<Dim> &a,
+ const GuardLayers<Dim> &igcs,
+ const GuardLayers<Dim> &egcs);
+ UniformGridPartition(const UniformGridPartition<Dim> &b);
+ ~UniformGridPartition() { }
+ UniformGridPartition<Dim> &
+ operator=(const UniformGridPartition<Dim> &g)
+ {
+ if (this != &g)
+ {
+ blocks_m = g.blocks();
+ hasGuards_m = g.hasGuards_m;
+ hasCustomEdgeGuards_m = g.hasCustomEdgeGuards_m;
+ internalGuards_m = g.internalGuards_m;
+ externalGuards_m = g.externalGuards_m;
+ num_m = g.maxSize();
+ }
+ return *this;
+ }
+ int maxSize() const { return num_m; }
+ const Loc<Dim> &blocks() const { return blocks_m; }
+ bool hasGuards() const
+ {
+ ;
+ return hasGuards_m;
+ }
+ bool hasInternalGuards() const
+ {
+ return hasGuards_m && internalGuards_m != 0;
+ }
+ bool hasExternalGuards() const
+ {
+ return hasGuards_m && externalGuards_m != 0;
+ }
+ const GuardLayers<Dim> &internalGuards() const
+ {
+ return internalGuards_m;
+ }
+ const GuardLayers<Dim> &externalGuards() const
+ {
+ return externalGuards_m;
+ }
+ template<class D>
+ int partition(const D &domain,
+ List_t & all,
+ const ContextMapper<Dim>& cmapper) const;
+ template<class D>
+ int partition(const D &domain, List_t & list) const
+ {
+ return partition(domain,list,DefaultMapper_t(*this));
+ }
+ protected:
+ Loc<Dim> blocks_m;
+ bool hasGuards_m;
+ bool hasCustomEdgeGuards_m;
+ GuardLayers<Dim> internalGuards_m;
+ GuardLayers<Dim> externalGuards_m;
+ int num_m;
+ void calcNum()
+ {
+ num_m = blocks_m[0].first();
+ for (int d = 1; d < Dim; ++d)
+ {
+ num_m *= blocks_m[d].first();
+ }
+ }
+ };
+ template<int Dim>
+ template<class D>
+ int UniformGridPartition<Dim>::partition(const D &domain,
+ List_t & all,
+ const ContextMapper<Dim>& cmapper) const
+ {
+ typedef typename DomainTraits<Domain_t>::Element_t Element_t;
+ PoomaCTAssert<(Dim == DomainTraits<D>::dimensions)>::test();
+ PoomaCTAssert<(Dim == DomainTraits<Domain_t>::dimensions)>::test();
+ PoomaCTAssert<(DomainTraits<D>::unitStride == 1)>::test();
+ PoomaCTAssert<(DomainTraits<Domain_t>::unitStride == 1)>::test();
+ ;
+ Element_t origin[Dim];
+ Element_t sizes[Dim];
+ Interval<Dim> bdomain = Pooma::NoInit();
+ int i;
+ for (i = 0; i < Dim; ++i)
+ {
+ if (!domain.empty())
+ {
+ int gcwidth =
+ (internalGuards_m.lower(i) > internalGuards_m.upper(i)) ?
+ internalGuards_m.lower(i) : internalGuards_m.upper(i);
+ if (__builtin_expect(!!((domain[i].length() % blocks()[i].first()) == 0), true)) {} else Pooma::toss_cookies("All the blocks in a grid must be the same size.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Partition/UniformGridPartition.h", 369);
+ origin[i] = domain[i].first();
+ sizes[i] = domain[i].length() / blocks()[i].first();
+ if (__builtin_expect(!!(sizes[i] >= gcwidth), true)) {} else Pooma::toss_cookies("Block sizes too small for guard layer specification.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Partition/UniformGridPartition.h", 375);
+ }
+ bdomain[i] = Interval<1>(blocks()[i].first());
+ }
+ typename Interval<Dim>::const_iterator it = bdomain.begin();
+ while (it != bdomain.end())
+ {
+ Domain_t owned;
+ GuardLayers<Dim> iguards(0);
+ GuardLayers<Dim> eguards(0);
+ if (!domain.empty())
+ {
+ Loc<Dim> pos = *it;
+ for (i = 0; i < Dim; ++i)
+ {
+ int position = pos[i].first();
+ Element_t a = origin[i] + sizes[i]*position;
+ Element_t b = a + sizes[i] - 1;
+ typedef typename
+ DomainTraits<Domain_t>::OneDomain_t OneDomain_t;
+ owned[i] = OneDomain_t(a, b);
+ }
+ if (hasGuards_m)
+ {
+ iguards = internalGuards_m;
+ for (int d = 0; d < Dim; ++d)
+ {
+ int position = pos[d].first();
+ if ( position == bdomain[d].first() )
+ {
+ eguards.lower(d) = externalGuards_m.lower(d);
+ iguards.lower(d) = 0;
+ }
+ if ( position == bdomain[d].last() )
+ {
+ eguards.upper(d) = externalGuards_m.upper(d);
+ iguards.upper(d) = 0;
+ }
+ }
+ }
+ }
+ typename Value_t::ID_t gid = all.size();
+ typename Value_t::ID_t lid = (-1);
+ GuardLayers<Dim>::addGuardLayers(owned,eguards);
+ Domain_t allocated = owned;
+ GuardLayers<Dim>::addGuardLayers(allocated,iguards);
+ Value_t *node = new Value_t(owned, allocated, -1, gid, lid);
+ all.push_back(node);
+ ++it;
+ }
+ cmapper.map(all);
+ return num_m;
+ }
+ template <int Dim>
+ inline UniformGridPartition<Dim>::
+ UniformGridPartition()
+ : hasGuards_m(false),
+ hasCustomEdgeGuards_m(false),
+ num_m(1)
+ {
+ blocks_m = 1;
+ }
+ template <int Dim>
+ inline UniformGridPartition<Dim>::
+ UniformGridPartition(const GuardLayers<Dim> &gcs)
+ : hasGuards_m(gcs != 0),
+ hasCustomEdgeGuards_m(gcs != 0),
+ externalGuards_m(gcs),
+ num_m(1)
+ {
+ blocks_m = 1;
+ }
+ template <int Dim>
+ inline UniformGridPartition<Dim>::
+ UniformGridPartition(const Loc<Dim> &a)
+ : blocks_m(a),
+ hasGuards_m(false),
+ hasCustomEdgeGuards_m(false)
+ {
+ calcNum();
+ }
+ template <int Dim>
+ inline UniformGridPartition<Dim>::
+ UniformGridPartition(const Loc<Dim> &a,
+ const GuardLayers<Dim> &gcs)
+ : blocks_m(a),
+ hasGuards_m(gcs != 0),
+ hasCustomEdgeGuards_m(false),
+ internalGuards_m(gcs),
+ externalGuards_m(gcs)
+ {
+ calcNum();
+ }
+ template <int Dim>
+ inline UniformGridPartition<Dim>::
+ UniformGridPartition(const Loc<Dim> &a,
+ const GuardLayers<Dim> &igcs,
+ const GuardLayers<Dim> &egcs)
+ : blocks_m(a),
+ hasGuards_m(igcs != 0 || egcs != 0),
+ hasCustomEdgeGuards_m(igcs != egcs),
+ internalGuards_m(igcs),
+ externalGuards_m(egcs)
+ {
+ calcNum();
+ }
+ template <int Dim>
+ inline UniformGridPartition<Dim>::
+ UniformGridPartition(const UniformGridPartition<Dim> &b)
+ : blocks_m(b.blocks_m),
+ hasGuards_m(b.hasGuards_m),
+ hasCustomEdgeGuards_m(b.hasCustomEdgeGuards_m),
+ internalGuards_m(b.internalGuards_m),
+ externalGuards_m(b.externalGuards_m),
+ num_m(b.num_m)
+ { }
+ struct ReplicatedTag {};
+ struct DistributedTag {};
+ template <class LayoutTag, int Dim>
+ struct MultiPatchLayoutTraits {};
+ template <int Dim>
+ class LayoutBaseData
+ {
+ public:
+ typedef Interval<Dim> Domain_t;
+ typedef Interval<Dim> BaseDomain_t;
+ typedef int Context_t;
+ typedef Unique::Value_t ID_t;
+ typedef Node<Domain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ struct GCFillInfo
+ {
+ GCFillInfo(const Domain_t &dom, int ownedID, int guardID, int face=-1)
+ : domain_m(dom), ownedID_m(ownedID), guardID_m(guardID), face_m(face) { }
+ GCFillInfo() { if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("Shouldn't get here!", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Layout/LayoutBase.h", 126); }
+ Domain_t domain_m;
+ int ownedID_m;
+ int guardID_m;
+ int face_m;
+ Domain_t & domain() { return domain_m;}
+ int & ownedID() { return ownedID_m;}
+ int & guardID() { return guardID_m;}
+ };
+ typedef GCFillInfo GCFillInfo_t;
+ typedef typename std::vector<GCFillInfo>::const_iterator FillIterator_t;
+ LayoutBaseData()
+ :
+ ID_m(Unique::get()),
+ domain_m(Interval<Dim>()),
+ innerdomain_m(Interval<Dim>()),
+ hasInternalGuards_m(false),
+ hasExternalGuards_m(false),
+ internalGuards_m(0),
+ externalGuards_m(0)
+ {
+ }
+ LayoutBaseData(bool hasIG, bool hasEG,
+ GuardLayers_t eg, GuardLayers_t ig,
+ Domain_t d, Domain_t id)
+ :
+ ID_m(Unique::get()),
+ domain_m(d),
+ innerdomain_m(id),
+ hasInternalGuards_m(hasIG),
+ hasExternalGuards_m(hasEG),
+ internalGuards_m(ig),
+ externalGuards_m(eg)
+ {
+ }
+ ~LayoutBaseData()
+ {
+ }
+ inline const Domain_t & domain(int i) const
+ {
+ ;
+ return all_m[i]->allocated();
+ }
+ inline const Domain_t & ownedDomain(int i) const
+ {
+ ;
+ return all_m[i]->domain();
+ }
+ inline const Domain_t & allocatedDomain(int i) const
+ {
+ ;
+ return all_m[i]->allocated();
+ }
+ inline const GuardLayers_t& internalGuards() const
+ {
+ return internalGuards_m;
+ }
+ inline const GuardLayers_t& externalGuards() const
+ {
+ return externalGuards_m;
+ }
+ inline List_t &nodeListGlobal()
+ {
+ return all_m;
+ }
+ inline List_t &nodeListLocal()
+ {
+ return local_m;
+ }
+ inline List_t &nodeListRemote()
+ {
+ return remote_m;
+ }
+ inline bool initialized() const { return all_m.size() > 0; }
+ inline int first(int d) const { return firsti_m[d]; }
+ inline int firsts(int d) const { return firste_m[d]; }
+ inline const Loc<Dim>& blocks() const { return blocks_m; }
+ FillIterator_t beginFillList() const
+ {
+ return gcFillList_m.begin();
+ }
+ FillIterator_t endFillList() const
+ {
+ return gcFillList_m.end();
+ }
+ ID_t ID_m;
+ Domain_t domain_m;
+ Domain_t innerdomain_m;
+ List_t all_m;
+ List_t local_m;
+ List_t remote_m;
+ bool hasInternalGuards_m;
+ bool hasExternalGuards_m;
+ GuardLayers_t internalGuards_m;
+ GuardLayers_t externalGuards_m;
+ std::vector<GCFillInfo> gcFillList_m;
+ int firste_m[Dim];
+ int firsti_m[Dim];
+ Loc<Dim> blocks_m;
+ };
+ template <int Dim, class LBD>
+ class LayoutBase
+ {
+ public:
+ typedef LayoutBaseData<Dim> LayoutData_t;
+ typedef typename LayoutData_t::Domain_t Domain_t;
+ typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
+ typedef typename LayoutData_t::Context_t Context_t;
+ typedef typename LayoutData_t::ID_t ID_t;
+ typedef typename LayoutData_t::Value_t Value_t;
+ typedef typename LayoutData_t::List_t List_t;
+ typedef LayoutBase<Dim,LBD> This_t;
+ typedef Observable<This_t> Observable_t;
+ typedef DerefIterator<Value_t> iterator;
+ typedef ConstDerefIterator<Value_t> const_iterator;
+ typedef typename LayoutData_t::GCFillInfo_t GCFillInfo_t;
+ typedef typename
+ std::vector<GCFillInfo_t>::const_iterator FillIterator_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ enum { supportsGuards = true };
+ LayoutBase(LBD * Ldata)
+ : pdata_m(Ldata)
+ {
+ }
+ LayoutBase(RefCountedPtr<LBD> pdata)
+ : pdata_m(pdata)
+ {
+ }
+ ~LayoutBase()
+ {
+ }
+ inline ID_t ID() const
+ {
+ return pdata_m->ID_m;
+ }
+ inline ID_t baseID() const
+ {
+ return pdata_m->ID_m;
+ }
+ inline bool initialized() const
+ {
+ return (sizeGlobal() > 0);
+ }
+ template <class DT>
+ BaseDomain_t &localToBase(const Domain<Dim, DT> &dlocal,
+ BaseDomain_t &base) const
+ {
+ return pdata_m->indexer_m.localToBase(dlocal,base);
+ }
+ inline const Domain_t &domain() const
+ {
+ return pdata_m->domain_m;
+ }
+ inline const Domain_t &innerDomain() const
+ {
+ return pdata_m->innerdomain_m;
+ }
+ inline const Domain_t &baseDomain() const
+ {
+ return pdata_m->domain_m;
+ }
+ inline const Domain_t &domain(int i) const
+ {
+ return pdata_m->domain(i);
+ }
+ inline const Domain_t &ownedDomain(int i) const
+ {
+ return pdata_m->ownedDomain(i);
+ }
+ inline const Domain_t &allocatedDomain(int i) const
+ {
+ return pdata_m->allocatedDomain(i);
+ }
+ inline const List_t & nodeListGlobal() const
+ {
+ return pdata_m->nodeListGlobal();
+ }
+ inline const List_t &nodeListLocal() const
+ {
+ return pdata_m->nodeListLocal();
+ }
+ inline const List_t &nodeListRemote() const
+ {
+ return pdata_m->nodeListRemote();
+ }
+ inline GuardLayers_t internalGuards() const
+ {
+ return pdata_m->internalGuards();
+ }
+ inline GuardLayers_t externalGuards() const
+ {
+ return pdata_m->externalGuards();
+ }
+ inline int first(int d) const { return pdata_m->first(d); }
+ inline Loc<Dim> blocks() const { return pdata_m->blocks(); }
+ inline const Domain_t patchDomain(int lid) const
+ {
+ return nodeListLocal()[lid]->domain();
+ }
+ inline int localToGlobalPatchID(int lid) const
+ {
+ return nodeListLocal()[lid]->globalID();
+ }
+ int globalID(const Loc<Dim> &loc) const
+ { return pdata_m->globalID(loc); }
+ int globalID(int i0) const
+ { return pdata_m->globalID(i0); }
+ int globalID(int i0, int i1) const
+ { return pdata_m->globalID(i0,i1); }
+ int globalID(int i0, int i1, int i2) const
+ { return pdata_m->globalID(i0,i1,i2); }
+ int globalID(int i0, int i1, int i2, int i3) const
+ { return pdata_m->globalID(i0,i1,i2,i3); }
+ int globalID(int i0, int i1, int i2, int i3, int i4) const
+ { return pdata_m->globalID(i0,i1,i2,i3,i4); }
+ int globalID(int i0, int i1, int i2, int i3, int i4, int i5) const
+ { return pdata_m->globalID(i0,i1,i2,i3,i4,i5); }
+ int globalID(int i0, int i1, int i2,int i3, int i4, int i5, int i6) const
+ { return pdata_m->globalID(i0,i1,i2,i3,i4,i5,i6); }
+ template <class Partitioner>
+ bool repartition(const Partitioner &gp,const ContextMapper<Dim> &cmap)
+ {
+ return pdata_m->repartition(gp,cmap);
+ }
+ template <class Partitioner>
+ bool repartition(const Partitioner &gp)
+ {
+ typename Partitioner::DefaultMapper_t cmap(gp);
+ return pdata_m->repartition(gp,cmap);
+ }
+ template <class L>
+ inline bool operator==(const L &layout) const
+ {
+ return (baseID() == layout.baseID() &&
+ baseDomain() == layout.baseDomain());
+ }
+ template <class L>
+ inline bool operator!=(const L &layout) const
+ {
+ return !(*this == layout);
+ }
+ inline iterator beginGlobal()
+ {
+ return iterator(pdata_m->all_m.begin());
+ }
+ inline iterator endGlobal()
+ {
+ return iterator(pdata_m->all_m.end());
+ }
+ inline const_iterator beginGlobal() const
+ {
+ return const_iterator(pdata_m->all_m.begin());
+ }
+ inline const_iterator endGlobal() const
+ {
+ return const_iterator(pdata_m->all_m.end());
+ }
+ inline int sizeGlobal() const
+ {
+ return pdata_m->all_m.size();
+ }
+ inline iterator beginLocal()
+ {
+ return iterator(pdata_m->local_m.begin());
+ }
+ inline iterator endLocal()
+ {
+ return iterator(pdata_m->local_m.end());
+ }
+ inline const_iterator beginLocal() const
+ {
+ return const_iterator(pdata_m->local_m.begin());
+ }
+ inline const_iterator endLocal() const
+ {
+ return const_iterator(pdata_m->local_m.end());
+ }
+ inline int sizeLocal() const
+ {
+ return pdata_m->local_m.size();
+ }
+ inline iterator beginRemote()
+ {
+ return iterator(pdata_m->remote_m.begin());
+ }
+ inline iterator endRemote()
+ {
+ return iterator(pdata_m->remote_m.end());
+ }
+ inline const_iterator beginRemote() const
+ {
+ return const_iterator(pdata_m->remote_m.begin());
+ }
+ inline const_iterator endRemote() const
+ {
+ return const_iterator(pdata_m->remote_m.end());
+ }
+ inline int sizeRemote() const
+ {
+ return pdata_m->remote_m.size();
+ }
+ FillIterator_t beginFillList() const
+ {
+ return pdata_m->beginFillList();
+ }
+ FillIterator_t endFillList() const
+ {
+ return pdata_m->endFillList();
+ }
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touches(const OtherDomain &d, OutIter o, const ConstructTag &ctag) const
+ {
+ return pdata_m->touches(d,o,ctag);
+ }
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touchesAlloc(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const
+ {
+ return pdata_m->touchesAlloc(d, o, ctag);
+ }
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ inline int touchesLocal(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const
+ {
+ return pdata_m->touchesLocal(d, o, ctag);
+ }
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ inline int touchesAllocLocal(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const
+ {
+ return pdata_m->touchesAllocLocal(d, o, ctag);
+ }
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ inline int touchesRemote(const OtherDomain & d, OutIter o,
+ const ConstructTag &ctag) const
+ {
+ return pdata_m->touchesRemote(d,o,ctag);
+ }
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ inline int touchesAllocRemote(const OtherDomain &d, OutIter o,
+ const ConstructTag & ctag) const
+ {
+ return pdata_m->touchesAllocRemote(d,o,ctag);
+ }
+ template <class OtherDomain, class OutIter>
+ inline int touches(const OtherDomain &d, OutIter o) const
+ {
+ return touches(d, o, TouchesConstructNodeObj());
+ }
+ template <class OtherDomain, class OutIter>
+ inline int touchesLocal(const OtherDomain &d, OutIter o) const
+ {
+ return touchesLocal(d, o, TouchesConstructNodeObj());
+ }
+ template <class OtherDomain, class OutIter>
+ inline int touchesRemote(const OtherDomain &d, OutIter o) const
+ {
+ return touchesRemote(d, o, TouchesConstructNodeObj());
+ }
+ template <class OtherDomain, class OutIter>
+ int touchesAlloc(const OtherDomain &d, OutIter o) const
+ {
+ return touchesAlloc(d, o, TouchesConstructNodeObj());
+ }
+ template <class OtherDomain, class OutIter>
+ int touchesAllocLocal(const OtherDomain &d, OutIter o) const
+ {
+ return touchesAllocLocal(d, o, TouchesConstructNodeObj());
+ }
+ template <class OtherDomain, class OutIter>
+ int touchesAllocRemote(const OtherDomain &d, OutIter o) const
+ {
+ return touchesAllocRemote(d, o, TouchesConstructNodeObj());
+ }
+ template <int Dim1, int Dim2, class lbd>
+ friend class LayoutBaseView;
+ friend class LayoutBaseData<Dim>;
+ RefCountedPtr<LBD> pdata_m;
+ };
+ template <int Dim, int Dim2, class L>
+ class LayoutBaseViewData
+ {
+ public:
+ typedef L Layout_t;
+ typedef Interval<Dim> Domain_t;
+ typedef Range<Dim2> BaseDomain_t;
+ typedef int Context_t;
+ typedef Unique::Value_t ID_t;
+ typedef typename Layout_t::Domain_t AllocatedDomain_t;
+ typedef ViewIndexer<Dim,Dim2> Indexer_t;
+ typedef Node<Domain_t,AllocatedDomain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ LayoutBaseViewData()
+ : id_m(Unique::get())
+ { }
+ template<class DT>
+ LayoutBaseViewData(const L & layout, const Domain<Dim,DT> & dom)
+ : id_m(Unique::get()), layout_m(layout),
+ internalGuards_m(layout.internalGuards()),
+ externalGuards_m(layout.externalGuards()),
+ indexer_m(dom),
+ subdomainsComputed_m(false)
+ {
+ PoomaCTAssert<(Dim == Dim2)>::test();
+ ;
+ ;
+ }
+ template <class DT>
+ LayoutBaseViewData(const L &layout, const SliceDomain<DT> &dom)
+ : id_m(Unique::get()), layout_m(layout), indexer_m(dom),
+ subdomainsComputed_m(false)
+ {
+ PoomaCTAssert<(Dim == DT::sliceDimensions)>::test();
+ PoomaCTAssert<(Dim2 == DT::dimensions)>::test();
+ ;
+ ;
+ int dt, d;
+ for (d = 0, dt = 0; dt < Dim2; ++dt)
+ {
+ if (!dom.ignorable(dt))
+ {
+ internalGuards_m.lower(d) = layout_m.internalGuards().lower(dt);
+ internalGuards_m.upper(d) = layout_m.internalGuards().upper(dt);
+ externalGuards_m.lower(d) = layout_m.externalGuards().lower(dt);
+ externalGuards_m.upper(d) = layout_m.externalGuards().upper(dt);
+ ;
+ ++d;
+ }
+ }
+ }
+ template <class DT,class LV>
+ LayoutBaseViewData(const L &layout,
+ const LV & viewLayout,
+ const Indexer_t & indexer,
+ const Domain<Dim, DT> &dom,
+ GuardLayers_t ig,
+ GuardLayers_t eg)
+ :
+ id_m(Unique::get()),
+ layout_m(layout),
+ internalGuards_m(ig),
+ externalGuards_m(eg),
+ indexer_m(indexer, dom),
+ subdomainsComputed_m(false)
+ {
+ ;
+ ;
+ }
+ template <class DT,class LV>
+ LayoutBaseViewData(const L &layout,
+ const LV &viewLayout,
+ const Indexer_t indexer,
+ const SliceDomain<DT> &dom)
+ : id_m(Unique::get()), layout_m(layout),
+ indexer_m(indexer),
+ subdomainsComputed_m(false)
+ {
+ PoomaCTAssert<((int)DT::sliceDimensions == Dim)>::test();
+ PoomaCTAssert<((int)DT::dimensions == LV::dimensions)>::test();
+ ;
+ ;
+ int dt, d;
+ for (d = 0, dt = 0; dt < LV::dimensions ; ++dt)
+ {
+ if (!dom.ignorable(dt))
+ {
+ internalGuards_m.lower(d) = viewLayout.internalGuards().lower(dt);
+ internalGuards_m.upper(d) = viewLayout.internalGuards().upper(dt);
+ externalGuards_m.lower(d) = viewLayout.externalGuards().lower(dt);
+ externalGuards_m.upper(d) = viewLayout.externalGuards().upper(dt);
+ ;
+ ++d;
+ }
+ }
+ }
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touches(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const
+ {
+ BaseDomain_t bd = Pooma::NoInit();
+ indexer_m.localToBase(d, bd);
+ std::vector<Node<BaseDomain_t,AllocatedDomain_t> > tnodes;
+ int count = layout_m.touches(bd, std::back_inserter(tnodes));
+ Range<Dim> ld = Pooma::NoInit();
+ for (int i = 0; i < count; i++)
+ {
+ *o++ =
+ touchesConstruct(indexer_m.baseToLocal(tnodes[i].domain(), ld),
+ tnodes[i].allocated(),
+ tnodes[i].affinity(), tnodes[i].context(),
+ tnodes[i].globalID(), tnodes[i].localID(), ctag);
+ }
+ return count;
+ }
+ void computeSubdomains() const
+ {
+ if (subdomainsComputed_m)
+ return;
+ std::vector<Node<BaseDomain_t,AllocatedDomain_t> > tnodes;
+ int count = layout_m.touches(indexer_m.baseDomain(),
+ std::back_inserter(tnodes));
+ Domain_t ld = Pooma::NoInit();
+ for (int i = 0; i < count; ++i)
+ {
+ Value_t *pt =
+ touchesConstruct(indexer_m.baseToLocal(tnodes[i].domain(), ld),
+ tnodes[i].allocated(),
+ tnodes[i].affinity(),tnodes[i].context(),
+ tnodes[i].globalID(),tnodes[i].localID(),
+ TouchesConstructNodePtr());
+ all_m.push_back(pt);
+ if (pt->context() == Pooma::context()
+ ||pt->context() == -1 )
+ local_m.push_back(pt);
+ else
+ remote_m.push_back(pt);
+ }
+ subdomainsComputed_m = true;
+ }
+ ID_t id_m;
+ L layout_m;
+ GuardLayers_t internalGuards_m;
+ GuardLayers_t externalGuards_m;
+ Indexer_t indexer_m;
+ mutable List_t all_m;
+ mutable List_t local_m;
+ mutable List_t remote_m;
+ mutable bool subdomainsComputed_m;
+ };
+ template <int Dim, int Dim2, class lvd>
+ class LayoutBaseView
+ {
+ public:
+ enum { dimensions = Dim };
+ typedef lvd LayoutData_t;
+ typedef typename LayoutData_t::Domain_t Domain_t;
+ typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
+ typedef typename LayoutData_t::Context_t Context_t;
+ typedef typename LayoutData_t::ID_t ID_t;
+ typedef typename LayoutData_t::Layout_t Layout_t;
+ typedef typename LayoutData_t::AllocatedDomain_t AllocatedDomain_t;
+ typedef typename LayoutData_t::Value_t Value_t;
+ typedef typename LayoutData_t::List_t List_t;
+ typedef typename LayoutData_t::Indexer_t Indexer_t;
+ typedef typename LayoutData_t::GuardLayers_t GuardLayers_t;
+ typedef LayoutBaseView<Dim, Dim2, lvd> This_t;
+ typedef LayoutBaseView<Dim, Dim2, lvd> ViewLayout_t;
+ typedef DerefIterator<Value_t> iterator;
+ typedef ConstDerefIterator<Value_t> const_iterator;
+ LayoutBaseView(LayoutData_t * lvdp)
+ : pdata_m(lvdp)
+ {}
+ LayoutBaseView(const RefCountedPtr<LayoutData_t> & pdata)
+ : pdata_m(pdata)
+ {}
+ inline ID_t ID() const { return pdata_m->id_m; }
+ inline ID_t baseID() const { return pdata_m->layout_m.baseID(); }
+ inline bool initialized() const { return true; }
+ inline const Domain_t &domain() const
+ {
+ return pdata_m->indexer_m.domain();
+ }
+ inline const Domain_t &innerDomain() const
+ {
+ return pdata_m->indexer_m.innerDomain();
+ }
+ inline const BaseDomain_t &baseDomain() const
+ {
+ return pdata_m->indexer_m.baseDomain();
+ }
+ inline const Layout_t &baseLayout() const
+ {
+ return pdata_m->layout_m;
+ }
+ template <class DT>
+ BaseDomain_t &localToBase(const Domain<Dim, DT> &dlocal,
+ BaseDomain_t &base) const
+ {
+ return pdata_m->indexer_m.localToBase(dlocal,base);
+ }
+ template <class DT>
+ SliceRange<Dim2, Dim> &localToBase(const Domain<Dim, DT> &dlocal,
+ SliceRange<Dim2, Dim> &base) const
+ {
+ return pdata_m->indexer_m.localToBase(dlocal,base);
+ }
+ inline GuardLayers_t internalGuards() const
+ {
+ return pdata_m->internalGuards_m;
+ }
+ inline GuardLayers_t externalGuards() const
+ {
+ return pdata_m->externalGuards_m;
+ }
+ inline int first(int) const { return 0; }
+ template <class L>
+ inline bool operator==(const L &layout) const
+ {
+ return (baseID() == layout.baseID() &&
+ baseDomain() == layout.baseDomain());
+ }
+ template <class L>
+ inline bool operator!=(const L &layout) const
+ {
+ return !(*this == layout);
+ }
+ inline int
+ globalID(const Loc<Dim> &loc, Loc<Dim2> &oloc) const
+ {
+ pdata_m->indexer_m.translate(loc,oloc);
+ return pdata_m->layout_m.globalID(oloc);
+ }
+ inline int
+ globalID(int i0, Loc<Dim2> &loc) const
+ {
+ pdata_m->indexer_m.translate(i0,loc);
+ return pdata_m->layout_m.globalID(loc);
+ }
+ inline int
+ globalID(int i0, int i1, Loc<Dim2> &loc) const
+ {
+ pdata_m->indexer_m.translate(i0,i1,loc);
+ return pdata_m->layout_m.globalID(loc);
+ }
+ inline int
+ globalID(int i0, int i1, int i2, Loc<Dim2> &loc) const
+ {
+ pdata_m->indexer_m.translate(i0,i1,i2,loc);
+ return pdata_m->layout_m.globalID(loc);
+ }
+ inline int
+ globalID(int i0, int i1, int i2, int i3,
+ Loc<Dim2> &loc) const
+ {
+ pdata_m->indexer_m.translate(i0,i1,i2,i3,loc);
+ return pdata_m->layout_m.globalID(loc);
+ }
+ inline int
+ globalID(int i0, int i1, int i2, int i3,
+ int i4, Loc<Dim2> &loc) const
+ {
+ pdata_m->indexer_m.translate(i0,i1,i2,i3,i4,loc);
+ return pdata_m->layout_m.globalID(loc);
+ }
+ inline int
+ globalID(int i0, int i1, int i2, int i3,
+ int i4, int i5, Loc<Dim2> &loc) const
+ {
+ pdata_m->indexer_m.translate(i0,i1,i2,i3,i4,i5,loc);
+ return pdata_m->layout_m.globalID(loc);
+ }
+ inline int
+ globalID(int i0, int i1, int i2, int i3,
+ int i4, int i5, int i6, Loc<Dim2> &loc) const
+ {
+ pdata_m->indexer_m.translate(i0,i1,i2,i3,i4,i5,i6,loc);
+ return pdata_m->layout_m.globalID(loc);
+ }
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touches(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const
+ {
+ return pdata_m->touches(d,o,ctag);
+ }
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ inline int touchesLocal(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const {
+ return pdata_m->touches(d, o, ctag);
+ }
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ inline int touchesRemote(const OtherDomain &, OutIter,
+ const ConstructTag &) const {
+ return 0;
+ }
+ template <class OtherDomain, class OutIter>
+ inline int touches(const OtherDomain &d, OutIter o) const {
+ return touches(d, o, TouchesConstructNodeObj());
+ }
+ template <class OtherDomain, class OutIter>
+ inline int touchesLocal(const OtherDomain &d, OutIter o) const {
+ return touchesLocal(d, o, TouchesConstructNodeObj());
+ }
+ template <class OtherDomain, class OutIter>
+ inline int touchesRemote(const OtherDomain &d, OutIter o) const {
+ return touchesRemote(d, o, TouchesConstructNodeObj());
+ }
+ inline iterator beginGlobal() {
+ computeSubdomains();
+ return iterator(pdata_m->all_m.begin());
+ }
+ inline iterator endGlobal() {
+ computeSubdomains();
+ return iterator(pdata_m->all_m.end());
+ }
+ inline const_iterator beginGlobal() const {
+ computeSubdomains();
+ return const_iterator(pdata_m->all_m.begin());
+ }
+ inline const_iterator endGlobal() const {
+ computeSubdomains();
+ return const_iterator(pdata_m->all_m.end());
+ }
+ inline int sizeGlobal() const {
+ computeSubdomains();
+ return pdata_m->all_m.size();
+ }
+ inline iterator beginLocal() {
+ computeSubdomains();
+ return iterator(pdata_m->local_m.begin());
+ }
+ inline iterator endLocal() {
+ computeSubdomains();
+ return iterator(pdata_m->local_m.end());
+ }
+ inline const_iterator beginLocal() const {
+ computeSubdomains();
+ return const_iterator(pdata_m->local_m.begin());
+ }
+ inline const_iterator endLocal() const {
+ computeSubdomains();
+ return const_iterator(pdata_m->local_m.end());
+ }
+ inline int sizeLocal() const {
+ computeSubdomains();
+ return pdata_m->local_m.size();
+ }
+ inline iterator beginRemote() {
+ computeSubdomains();
+ return iterator(pdata_m->remote_m.begin());
+ }
+ inline iterator endRemote() {
+ computeSubdomains();
+ return iterator(pdata_m->remote_m.end());
+ }
+ inline const_iterator beginRemote() const {
+ computeSubdomains();
+ return const_iterator(pdata_m->remote_m.begin());
+ }
+ inline const_iterator endRemote() const {
+ computeSubdomains();
+ return const_iterator(pdata_m->remote_m.end());
+ }
+ inline int sizeRemote() const {
+ computeSubdomains();
+ return pdata_m->remote_m.size();
+ }
+ template <int OtherDim, int OtherDim2, class OtherLayoutData>
+ friend class LayoutBaseView;
+ template <int OtherDim, int OtherDim2, class OtherLayout>
+ friend class LayoutBaseViewData;
+ void computeSubdomains() const { pdata_m->computeSubdomains(); }
+ RefCountedPtr<LayoutData_t> pdata_m;
+ };
+ template <int Dim> class SparseTileLayoutData;
+ template <int Dim> class SparseTileLayout;
+ template <int Dim, int Dim2> class SparseTileLayoutViewData;
+ template <int Dim, int Dim2> class SparseTileLayoutView;
+ struct SparseTileTag { };
+ template <int Dim>
+ struct MultiPatchLayoutTraits<SparseTileTag,Dim>
+ {
+ typedef SparseTileLayout<Dim> Layout_t;
+ template <int ViewDim>
+ struct View
+ {
+ typedef SparseTileLayoutView<ViewDim,Dim> Layout_t;
+ };
+ };
+ template<int Dim>
+ class SparseTileLayoutData
+ : public LayoutBaseData<Dim>,
+ public RefCounted,
+ public Observable< SparseTileLayoutData<Dim> >
+ {
+ public:
+ typedef SparseTileLayoutData<Dim> This_t;
+ typedef Observable<This_t> Observable_t;
+ typedef Interval<Dim> Domain_t;
+ typedef Interval<Dim> BaseDomain_t;
+ typedef Interval<Dim> AllocatedDomain_t;
+ typedef int Context_t;
+ typedef Unique::Value_t ID_t;
+ typedef Node<Domain_t,AllocatedDomain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ typedef std::map<int,Value_t> Map_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ typedef std::pair<int,int> pidx_t;
+ typedef typename DynamicEvents::PatchID_t PatchID_t;
+ typedef typename DynamicEvents::CreateSize_t CreateSize_t;
+ typedef BaseDomain_t SubPatch_t;
+ typedef std::vector<SubPatch_t> PatchList_t;
+ typedef typename LayoutBaseData<Dim>::GCFillInfo_t GCFillInfo_t;
+ typedef typename std::vector<GCFillInfo_t>::const_iterator FillIterator_t;
+ struct GCBorderFillInfo
+ {
+ GCBorderFillInfo(const Domain_t &dom, int patchID)
+ : domain_m(dom), patchID_m(patchID)
+ {
+ }
+ GCBorderFillInfo()
+ {
+ if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("Shouldn't get here!", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Layout/SparseTileLayout.h", 173);
+ }
+ Domain_t domain_m;
+ int patchID_m;
+ inline const Domain_t& domain() const { return domain_m; }
+ int patchID() const { return patchID_m;}
+ };
+ typedef GCBorderFillInfo GCBorderFillInfo_t;
+ typedef typename std::vector<GCBorderFillInfo>::const_iterator
+ BorderFillIterator_t;
+ enum { dimensions = Dim };
+ enum { repartitionEvent = 1 };
+ enum { dynamic = false };
+ SparseTileLayoutData();
+ SparseTileLayoutData(const Domain_t &,
+ const PatchList_t &,
+ const ContextMapper<Dim> &);
+ SparseTileLayoutData(const Domain_t &boundingbox,
+ const GuardLayers_t & globalGL,
+ const PatchList_t & PatchList,
+ const ContextMapper<Dim> &);
+ SparseTileLayoutData(const Domain_t &boundingbox,
+ const GuardLayers_t & internalGL,
+ const GuardLayers_t & externalGL,
+ const PatchList_t & PatchList,
+ const ContextMapper<Dim> &);
+ SparseTileLayoutData(const Domain_t &boundingbox);
+ SparseTileLayoutData(const Domain_t &boundingbox,
+ const GuardLayers_t & globalGL);
+ SparseTileLayoutData(const Domain_t &boundingbox,
+ const GuardLayers_t & internalGL,
+ const GuardLayers_t & externalGL);
+ template <class Partitioner>
+ SparseTileLayoutData(const Domain_t &bbox,
+ const Partitioner & gpar,
+ const ContextMapper<Dim> &cmap);
+ ~SparseTileLayoutData() ;
+ void initialize(const Domain_t &bbox);
+ void initialize(const Domain_t &bbox,
+ const GuardLayers_t & globalGL);
+ void initialize(const Domain_t &bbox,
+ const GuardLayers_t & internalGL,
+ const GuardLayers_t & externalGL);
+ void initialize(const Domain_t &bbox,
+ const PatchList_t &plist,
+ const ContextMapper<Dim> &cmap);
+ void initialize(const Domain_t &bbox,
+ const GuardLayers_t & globalGL,
+ const PatchList_t &plist,
+ const ContextMapper<Dim> &cmap);
+ void initialize(const Domain_t &bbox,
+ const GuardLayers_t & internalGL,
+ const GuardLayers_t & externalGL,
+ const PatchList_t &plist,
+ const ContextMapper<Dim> &cmap);
+ template <class Partitioner>
+ void initialize(const Domain_t &bbox,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> &cmap);
+ void syncPatch();
+ void calcMaps();
+ void calcAllocMaps() ;
+ BorderFillIterator_t beginBorderFillList() const
+ {
+ return gcBorderFillList_m.begin();
+ }
+ BorderFillIterator_t endBorderFillList() const
+ {
+ return gcBorderFillList_m.end();
+ }
+ int globalID(const Loc<Dim> &loc) const;
+ int globalID(int) const;
+ int globalID(int,int) const;
+ int globalID(int,int,int) const;
+ int globalID(int,int,int,int) const;
+ int globalID(int,int,int,int,int) const;
+ int globalID(int,int,int,int,int,int) const;
+ int globalID(int,int,int,int,int,int,int) const;
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touches(const OtherDomain &d,
+ OutIter o,
+ const ConstructTag &ctag) const;
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touchesAlloc(const OtherDomain &d,
+ OutIter o,
+ const ConstructTag &ctag) const;
+ template<class Out>
+ void print(Out & o) const;
+ private:
+ void calcGCFillList();
+ void calcDomains();
+ void calcMaps() const;
+ void calcAllocMaps() const;
+ std::vector<GCBorderFillInfo> gcBorderFillList_m;
+ mutable DomainMap<Interval<Dim>,pidx_t> map_m;
+ mutable DomainMap<Interval<Dim>,pidx_t> mapAloc_m;
+ };
+ template <int Dim>
+ class SparseTileLayout : public LayoutBase<Dim,SparseTileLayoutData<Dim> >,
+ public Observable<SparseTileLayout<Dim> >,
+ public Observer<SparseTileLayoutData<Dim> >
+ {
+ public:
+ enum { dimensions = Dim };
+ enum { repartitionEvent = 1 };
+ enum { dynamic = true };
+ typedef SparseTileLayout<Dim> This_t;
+ typedef Observable<This_t> Observable_t;
+ typedef SparseTileLayoutData<Dim> LayoutData_t;
+ typedef typename LayoutData_t::Domain_t Domain_t;
+ typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
+ typedef typename LayoutData_t::Context_t Context_t;
+ typedef typename LayoutData_t::ID_t ID_t;
+ typedef typename LayoutData_t::Value_t Value_t;
+ typedef typename LayoutData_t::List_t List_t;
+ typedef DynamicEvents::PatchID_t PatchID_t;
+ typedef DynamicEvents::CreateSize_t CreateSize_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ typedef typename LayoutData_t::SubPatch_t SubPatch_t;
+ typedef typename LayoutData_t::PatchList_t PatchList_t;
+ typedef DerefIterator<Value_t> iterator;
+ typedef ConstDerefIterator<Value_t> const_iterator;
+ typedef typename LayoutData_t::GCFillInfo_t GCFillInfo_t;
+ typedef typename LayoutData_t::FillIterator_t FillIterator_t;
+ typedef typename LayoutData_t::BorderFillIterator_t BorderFillIterator_t;
+ SparseTileLayout();
+ SparseTileLayout(const Domain_t &boundingbox);
+ SparseTileLayout(const Domain_t &boundingbox,
+ const GuardLayers_t & globalGL);
+ SparseTileLayout(const Domain_t &boundingbox,
+ const GuardLayers_t & internalGL,
+ const GuardLayers_t & externalGL);
+ SparseTileLayout(Domain_t & boundingbox,
+ const PatchList_t &patchlist,
+ const ReplicatedTag &);
+ SparseTileLayout(const Domain_t &boundingbox,
+ const GuardLayers_t & globalGL,
+ const PatchList_t & PatchList,
+ const ReplicatedTag &);
+ SparseTileLayout(const Domain_t &boundingbox,
+ const GuardLayers_t & internalGL,
+ const GuardLayers_t & externalGL,
+ const PatchList_t & PatchList,
+ const ReplicatedTag &);
+ template<class Partitioner>
+ SparseTileLayout(const Domain_t &bbox,
+ const Partitioner &gpar,
+ const ReplicatedTag &);
+ SparseTileLayout(Domain_t & boundingbox,
+ const PatchList_t &patchlist,
+ const DistributedTag &);
+ SparseTileLayout(const Domain_t &boundingbox,
+ const GuardLayers_t & globalGL,
+ const PatchList_t & PatchList,
+ const DistributedTag &);
+ SparseTileLayout(const Domain_t &boundingbox,
+ const GuardLayers_t & internalGL,
+ const GuardLayers_t & externalGL,
+ const PatchList_t & PatchList,
+ const DistributedTag &);
+ template<class Partitioner>
+ SparseTileLayout(const Domain_t &bbox,
+ const Partitioner &gpar,
+ const DistributedTag &);
+ template<class Partitioner>
+ SparseTileLayout(const Domain_t &bbox,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> &cmap);
+ SparseTileLayout(const This_t &);
+ This_t &
+ operator=(const This_t &model)
+ {
+ if (this != &model)
+ {
+ this->pdata_m->detach(*this);
+ this->pdata_m = model.pdata_m;
+ this->pdata_m->attach(*this);
+ }
+ return *this;
+ }
+ ~SparseTileLayout()
+ {
+ this->pdata_m->detach(*this);
+ }
+ void initialize(const Domain_t & a);
+ void initialize(const Domain_t &,
+ const GuardLayers_t &);
+ void initialize(const Domain_t &,
+ const GuardLayers_t &,
+ const PatchList_t & );
+ template<class Partitioner>
+ void initialize(const Domain_t &bbox,
+ const Partitioner &gpar);
+ BorderFillIterator_t beginBorderFillList() const
+ {
+ return this->pdata_m->beginBorderFillList();
+ }
+ BorderFillIterator_t endBorderFillList() const
+ {
+ return this->pdata_m->endBorderFillList();
+ }
+ void syncPatch();
+ virtual void notify(LayoutData_t &d, const ObserverEvent &event)
+ {
+ ;
+ Observable_t::notify(event);
+ }
+ template <class Ostream>
+ void print(Ostream &ostr) const {
+ this->pdata_m->print(ostr);
+ }
+ template <int Dim1, int Dim2>
+ friend class SparseTileLayoutView;
+ friend class SparseTileLayoutData<Dim>;
+ };
+ template <int Dim, int Dim2>
+ class SparseTileLayoutViewData
+ : public LayoutBaseViewData<Dim, Dim2, SparseTileLayout<Dim2> >,
+ public RefCounted
+ {
+ public:
+ typedef SparseTileLayout<Dim2> Layout_t;
+ typedef SparseTileLayoutView<Dim, Dim2> ViewLayout_t;
+ typedef Interval<Dim> Domain_t;
+ typedef Range<Dim2> BaseDomain_t;
+ typedef int Context_t;
+ typedef Unique::Value_t ID_t;
+ typedef typename Layout_t::Domain_t AllocatedDomain_t;
+ typedef ViewIndexer<Dim,Dim2> Indexer_t;
+ typedef Node<Domain_t,AllocatedDomain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ typedef SparseTileLayoutViewData<Dim,Dim2> LayoutData_t;
+ SparseTileLayoutViewData() { }
+ template <class DT>
+ inline SparseTileLayoutViewData(const Layout_t &layout, const Domain<Dim, DT> &dom)
+ : LayoutBaseViewData<Dim,Dim2,SparseTileLayout<Dim2> >(layout,dom)
+ {
+ PoomaCTAssert<(Dim == Dim2)>::test();
+ ;
+ ;
+ }
+ template <class DT>
+ inline SparseTileLayoutViewData(const Layout_t &layout, const SliceDomain<DT> &dom)
+ :LayoutBaseViewData<Dim,Dim2,SparseTileLayout<Dim2> >(layout,dom)
+ {
+ PoomaCTAssert<(Dim == DT::sliceDimensions)>::test();
+ PoomaCTAssert<(Dim2 == DT::dimensions)>::test();
+ ;
+ ;
+ int dt, d;
+ for (d = 0, dt = 0; dt < Dim2; ++dt)
+ {
+ if (!dom.ignorable(dt))
+ {
+ this->internalGuards_m.lower(d) = this->layout_m.internalGuards().lower(dt);
+ this->internalGuards_m.upper(d) = this->layout_m.internalGuards().upper(dt);
+ this->externalGuards_m.lower(d) = this->layout_m.externalGuards().lower(dt);
+ this->externalGuards_m.upper(d) = this->layout_m.externalGuards().upper(dt);
+ ;
+ ++d;
+ }
+ }
+ }
+ template <class DT>
+ SparseTileLayoutViewData(const ViewLayout_t &layout, const Domain<Dim, DT> &dom)
+ : LayoutBaseViewData<Dim,Dim2,SparseTileLayout<Dim2> >(
+ layout.pdata_m->layout_m,
+ layout,
+ layout.pdata_m->indexer_m,
+ dom,
+ layout.internalGuards(),
+ layout.externalGuards())
+ {
+ ;
+ ;
+ }
+ template <int OrigDim, class DT>
+ SparseTileLayoutViewData(const SparseTileLayoutView<OrigDim, Dim2> &layout,
+ const SliceDomain<DT> &dom)
+ : LayoutBaseViewData<Dim,Dim2,SparseTileLayout<Dim2> >(
+ layout.pdata_m->layout_m,
+ layout,
+ Indexer_t(layout.pdata_m->indexer_m,dom),
+ dom)
+ {
+ PoomaCTAssert<(DT::sliceDimensions == Dim)>::test();
+ PoomaCTAssert<(DT::dimensions == OrigDim)>::test();
+ ;
+ ;
+ int dt, d;
+ for (d = 0, dt = 0; dt < OrigDim; ++dt)
+ {
+ if (!dom.ignorable(dt))
+ {
+ this->internalGuards_m.lower(d) = layout.internalGuards().lower(dt);
+ this->internalGuards_m.upper(d) = layout.internalGuards().upper(dt);
+ this->externalGuards_m.lower(d) = layout.externalGuards().lower(dt);
+ this->externalGuards_m.upper(d) = layout.externalGuards().upper(dt);
+ ;
+ ++d;
+ }
+ }
+ }
+ ~SparseTileLayoutViewData()
+ {
+ typename List_t::iterator a;
+ for (a = this->all_m.begin(); a != this->all_m.end(); ++a)
+ delete (*a);
+ }
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touches(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const
+ {
+ BaseDomain_t bd = Pooma::NoInit();
+ this->indexer_m.localToBase(d, bd);
+ std::vector<Node<BaseDomain_t,AllocatedDomain_t> > tnodes;
+ int count = this->layout_m.touches(bd, std::back_inserter(tnodes));
+ Range<Dim> ld = Pooma::NoInit();
+ for (int i = 0; i < count; i++)
+ {
+ *o++ =
+ touchesConstruct(this->indexer_m.baseToLocal(tnodes[i].domain(), ld),
+ tnodes[i].allocated(),
+ tnodes[i].affinity(),tnodes[i].context(),
+ tnodes[i].globalID(), tnodes[i].localID(), ctag);
+ }
+ return count;
+ }
+ void computeSubdomains() const
+ {
+ if (this->subdomainsComputed_m)
+ return;
+ std::vector<Node<BaseDomain_t,AllocatedDomain_t> > tnodes;
+ int count = this->layout_m.touches(this->indexer_m.baseDomain(),
+ std::back_inserter(tnodes));
+ Domain_t ld = Pooma::NoInit();
+ for (int i = 0; i < count; i++)
+ {
+ Value_t *pt =
+ touchesConstruct(this->indexer_m.baseToLocal(tnodes[i].domain(), ld),
+ tnodes[i].allocated(),
+ tnodes[i].affinity(),tnodes[i].context(),
+ tnodes[i].globalID(),tnodes[i].localID(),
+ TouchesConstructNodePtr());
+ this->all_m.push_back(pt);
+ }
+ this->subdomainsComputed_m = true;
+ }
+ };
+ template <int Dim, int Dim2>
+ class SparseTileLayoutView
+ : public LayoutBaseView<Dim, Dim2, SparseTileLayoutViewData<Dim,Dim2> >
+ {
+ public:
+ enum { dimensions = Dim };
+ typedef SparseTileLayoutViewData<Dim, Dim2> LayoutData_t;
+ typedef typename LayoutData_t::Domain_t Domain_t;
+ typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
+ typedef typename LayoutData_t::Context_t Context_t;
+ typedef typename LayoutData_t::ID_t ID_t;
+ typedef typename LayoutData_t::Layout_t Layout_t;
+ typedef typename LayoutData_t::AllocatedDomain_t AllocatedDomain_t;
+ typedef typename LayoutData_t::Value_t Value_t;
+ typedef typename LayoutData_t::List_t List_t;
+ typedef typename LayoutData_t::Indexer_t Indexer_t;
+ typedef typename LayoutData_t::GuardLayers_t GuardLayers_t;
+ typedef SparseTileLayoutView<Dim, Dim2> This_t;
+ typedef SparseTileLayoutView<Dim, Dim2> ViewLayout_t;
+ typedef LayoutBaseView<Dim,Dim2,LayoutData_t> Base_t;
+ typedef DerefIterator<Value_t> iterator;
+ typedef ConstDerefIterator<Value_t> const_iterator;
+ SparseTileLayoutView()
+ : Base_t(new LayoutData_t())
+ { }
+ template <class DT>
+ SparseTileLayoutView(const Layout_t &layout, const Domain<Dim2, DT> &dom)
+ : LayoutBaseView<Dim,Dim2,SparseTileLayoutViewData<Dim,Dim2> >
+ (new SparseTileLayoutViewData<Dim,Dim2>(layout,dom))
+ { }
+ template <class DT>
+ SparseTileLayoutView(const Layout_t &layout, const SliceDomain<DT> &dom)
+ : LayoutBaseView<Dim,Dim2,SparseTileLayoutViewData<Dim,Dim2> >
+ (new SparseTileLayoutViewData<Dim,Dim2>(layout,dom))
+ { }
+ template <class DT>
+ SparseTileLayoutView(const ViewLayout_t &layout, const Domain<Dim, DT> &dom)
+ : LayoutBaseView<Dim,Dim2,SparseTileLayoutViewData<Dim,Dim2> >
+ (new SparseTileLayoutViewData<Dim,Dim2>(layout,dom))
+ { }
+ template <int OldViewDim, class DT>
+ SparseTileLayoutView(const SparseTileLayoutView<OldViewDim, Dim2> &layout,
+ const SliceDomain<DT> &dom)
+ : LayoutBaseView<Dim,Dim2,SparseTileLayoutViewData<Dim,Dim2> >
+ (new SparseTileLayoutViewData<Dim,Dim2>(layout,dom))
+ { }
+ inline SparseTileLayoutView(const This_t &model)
+ : LayoutBaseView<Dim,Dim2,SparseTileLayoutViewData<Dim,Dim2> >
+ (model.pdata_m)
+ { }
+ inline This_t &operator=(const This_t &model)
+ {
+ if (this != &model)
+ {
+ this->pdata_m = model.pdata_m;
+ }
+ return *this;
+ }
+ inline ~SparseTileLayoutView()
+ { }
+ template <class Ostream>
+ void print(Ostream &ostr) const
+ {
+ ostr << "SparseTileLayoutView " << this->ID() << " on global domain "
+ << this->domain() << ":" << '\n';
+ ostr << " Base ID: " << this->baseID() << '\n';
+ ostr << " Base domain: " << this->baseDomain() << '\n';
+ ostr << " Total subdomains: " << this->sizeGlobal() << '\n';
+ ostr << " Local subdomains: " << this->sizeLocal() << '\n';
+ ostr << " Remote subdomains: " << this->sizeRemote() << '\n';
+ const_iterator a;
+ for (a = this->beginGlobal(); a != this->endGlobal(); ++a)
+ ostr << " Global subdomain = " << *a << '\n';
+ for (a = this->beginLocal(); a != this->endLocal(); ++a)
+ ostr << " Local subdomain = " << *a << '\n';
+ for (a = this->beginRemote(); a != this->endRemote(); ++a)
+ ostr << " Remote subdomain = " << *a << '\n';
+ }
+ template <int OtherDim, int OtherDim2>
+ friend class SparseTileLayoutView;
+ template <int OtherDim, int OtherDim2>
+ friend class SparseTileLayoutViewData;
+ void computeSubdomains() const { this->pdata_m->computeSubdomains(); }
+ };
+ template <int Dim>
+ struct NewDomain1<SparseTileLayout<Dim> >
+ {
+ typedef SparseTileLayout<Dim> &Type_t;
+ inline static Type_t combine(const SparseTileLayout<Dim> &a)
+ {
+ return const_cast<Type_t>(a);
+ }
+ };
+ template <int Dim, int Dim2>
+ struct NewDomain1<SparseTileLayoutView<Dim, Dim2> >
+ {
+ typedef SparseTileLayoutView<Dim, Dim2> &Type_t;
+ inline static Type_t combine(const SparseTileLayoutView<Dim, Dim2> &a)
+ {
+ return const_cast<Type_t>(a);
+ }
+ };
+ template <int Dim>
+ std::ostream &operator<<(std::ostream &ostr,
+ const SparseTileLayout<Dim> &layout)
+ {
+ layout.print(ostr);
+ return ostr;
+ }
+ template <int Dim, int Dim2>
+ std::ostream &operator<<(std::ostream &ostr,
+ const SparseTileLayoutView<Dim, Dim2> &layout)
+ {
+ layout.print(ostr);
+ return ostr;
+ }
+ template<int Dim> struct IsValid;
+ template<class LayoutTag, class PatchTag> struct MultiPatch;
+ template<class LayoutTag, class PatchTag, int Dim2> struct MultiPatchView;
+ template<class Expr> struct ExpressionTag;
+ template<class Eng, class Tag> struct EngineFunctor;
+ template<class Object,class Dom,class PatchTag>
+ inline bool isValidLocation(const Object & e,
+ Dom & domain,
+ MultiPatch<SparseTileTag,PatchTag> &)
+ {
+ typedef typename Object::Domain_t domain_t;
+ typedef Node<domain_t,domain_t> node_t;
+ std::vector<node_t> v;
+ int count = e.engine().layout().touches(domain,std::back_inserter(v));
+ return (count!=0);
+ }
+ template<class Object,class Dom,class PatchTag,int Dim2>
+ inline bool isValidLocation(const Object & e,
+ Dom & domain,
+ MultiPatchView<SparseTileTag,
+ PatchTag,
+ Dim2> &)
+ {
+ typedef typename Object::Domain_t domain_t;
+ typedef Node<domain_t,domain_t> node_t;
+ std::vector<node_t> v;
+ int count = e.engine().layout().touches(domain,std::back_inserter(v));
+ return (count!=0);
+ }
+ template<class Object,class Dom,class expr>
+ inline bool isValidLocation(const Object & e,
+ Dom & domain,
+ ExpressionTag<expr> &)
+ {
+ typedef typename Object::Domain_t domain_t;
+ typedef Node<domain_t,domain_t> node_t;
+ std::vector<node_t> v;
+ typedef typename Object::Engine_t Engine_t;
+ IsValid<Engine_t::dimensions> l(domain);
+ EngineFunctor<Engine_t, IsValid<Engine_t::dimensions> > ef;
+ return ef.apply(e.engine(),l);
+ }
+ template <int Dim> class Loc;
+ template <> class Loc<1>;
+ template <int Dim> class Interval;
+ template <> class Interval<1>;
+ template <int Dim> class Grid;
+ template <> class Grid<1>;
+ template<int Dim>
+ struct DomainTraits< Grid<Dim> >
+ : public DomainTraitsDomain<Grid<Dim>, int, Dim>
+ {
+ typedef DomainTraitsDomain<Grid<Dim>, int, Dim> Base_t;
+ typedef typename Base_t::Element_t Element_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef typename Base_t::NewDomain1_t NewDomain1_t;
+ typedef Grid<1> OneDomain_t;
+ typedef Grid<1> PointDomain_t;
+ typedef Interval<Dim> BlockDomain_t;
+ typedef Loc<Dim> AskDomain_t;
+ typedef Grid<Dim> AddResult_t;
+ typedef Grid<Dim> MultResult_t;
+ typedef OneDomain_t Storage_t[Dim];
+ enum { domain = Base_t::domain };
+ enum { dimensions = Base_t::dimensions,
+ sliceDimensions = Dim };
+ enum { loopAware = false };
+ enum { singleValued = false };
+ enum { unitStride = false };
+ enum { wildcard = false };
+ static OneDomain_t &getDomain(Domain_t &d, int n) { return d[n]; }
+ static const OneDomain_t &getDomain(const Domain_t &d,int n) { return d[n]; }
+ static PointDomain_t &getPointDomain(Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ static void initializeStorage(Storage_t &dom) { }
+ };
+ template<>
+ struct DomainTraits< Grid<1> >
+ : public DomainTraitsDomain<Grid<1>, int, 1>
+ {
+ typedef Grid<1> OneDomain_t;
+ typedef Grid<1> PointDomain_t;
+ typedef Interval<1> BlockDomain_t;
+ typedef Loc<1> AskDomain_t;
+ typedef Grid<1> AddResult_t;
+ typedef Grid<1> MultResult_t;
+ typedef IndirectionList<Element_t> Storage_t;
+ enum { dimensions = 1,
+ sliceDimensions = 1 };
+ enum { loopAware = false };
+ enum { singleValued = false };
+ enum { unitStride = false };
+ enum { wildcard = false };
+ static Element_t first(const Storage_t &d) { return d.first(); }
+ static Element_t last(const Storage_t &d) { return d.last(); }
+ static Element_t stride(const Storage_t &d) { return d.stride(); }
+ static Element_t length(const Storage_t &d) { return d.length(); }
+ static Element_t min(const Storage_t &d) { return d.min(); }
+ static Element_t max(const Storage_t &d) { return d.max(); }
+ static bool empty(const Storage_t &d) { return d.empty(); }
+ static int loop(const Storage_t &) { return 0; }
+ static Element_t elem(const Storage_t &d, int n) { return d(n); }
+ static OneDomain_t &getDomain(Domain_t &d, int) { return d; }
+ static const OneDomain_t &getDomain(const Domain_t &d, int) { return d; }
+ static PointDomain_t &getPointDomain(Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ static void initializeStorage(Storage_t &) { }
+ template<class T>
+ static void setDomain(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ dom = Storage_t(DomainTraits<T>::getFirst(newdom),
+ DomainTraits<T>::getStride(newdom),
+ DomainTraits<T>::getLength(newdom));
+ }
+ template<int Dim>
+ static void setDomain(Storage_t &dom, const Grid<Dim> &newdom) {
+ PoomaCTAssert<(Dim == 1)>::test();
+ dom = newdom.storage();
+ }
+ template<class T1, class T2>
+ static void setDomain(Storage_t &dom, const T1 &begval, const T2 &endval) {
+ PoomaCTAssert<(DomainTraits<T1>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<T2>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<T1>::singleValued)>::test();
+ PoomaCTAssert<(DomainTraits<T2>::singleValued)>::test();
+ Element_t strideval = (endval < begval ? -1 : 1);
+ dom = Storage_t(begval, strideval, (endval - begval)/strideval + 1);
+ }
+ template<class T1, class T2, class T3>
+ static void setDomain(Storage_t &dom, const T1 &begval, const T2 &endval,
+ const T3 &strideval) {
+ PoomaCTAssert<(DomainTraits<T1>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<T2>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<T3>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<T1>::singleValued)>::test();
+ PoomaCTAssert<(DomainTraits<T2>::singleValued)>::test();
+ PoomaCTAssert<(DomainTraits<T3>::singleValued)>::test();
+ dom = Storage_t(begval, strideval, (endval - begval)/strideval + 1);
+ }
+ static void setDomain(Storage_t &dom, const Storage_t &newdom) {
+ dom = newdom;
+ }
+ static void setLoop(Storage_t &, int) { }
+ template<class UT, class T>
+ static void setWildcardDomain(Storage_t &dom, const UT &u, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::wildcard)>::test();
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<UT>::dimensions == 1)>::test();
+ dom = Storage_t(newdom.first(u), newdom.stride(u), newdom.length(u));
+ }
+ template<class T>
+ static bool isLessThan(const Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ ;
+ return (dom.first() < DomainTraits<T>::getFirst(newdom) ||
+ (dom.first() == DomainTraits<T>::getFirst(newdom) &&
+ (dom.last() < DomainTraits<T>::getLast(newdom) ||
+ (dom.last() == DomainTraits<T>::getLast(newdom) &&
+ dom.length() < DomainTraits<T>::getLength(newdom)))));
+ }
+ template<class T>
+ static bool isEqualTo(const Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::dimensions == 1)>::test();
+ return ((dom.empty() && DomainTraits<T>::getEmpty(newdom)) ||
+ (dom.first() == DomainTraits<T>::getFirst(newdom) &&
+ dom.last() == DomainTraits<T>::getLast(newdom) &&
+ dom.length() == DomainTraits<T>::getLength(newdom)));
+ }
+ template<class T>
+ static void addAccum(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
+ dom += DomainTraits<T>::getFirst(newdom);
+ }
+ template<class T>
+ static void subtractAccum(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
+ dom -= DomainTraits<T>::getFirst(newdom);
+ }
+ template<class T>
+ static void multiplyAccum(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
+ dom *= DomainTraits<T>::getFirst(newdom);
+ }
+ template<class T>
+ static void divideAccum(Storage_t &dom, const T &newdom) {
+ PoomaCTAssert<(DomainTraits<T>::singleValued && DomainTraits<T>::dimensions == 1)>::test();
+ dom /= DomainTraits<T>::getFirst(newdom);
+ }
+ };
+ template<int Dim1, int Dim2>
+ struct DomainChangeDim<Grid<Dim1>, Dim2>
+ {
+ typedef Grid<Dim1> OldType_t;
+ typedef Grid<Dim2> NewType_t;
+ enum { oldDim = Dim1,
+ newDim = Dim2 };
+ };
+ template<int Dim>
+ class Grid : public Domain<Dim, DomainTraits<Grid<Dim> > >
+ {
+ typedef DomainTraits< Grid<Dim> > DT_t;
+ typedef Domain<Dim, DT_t> Base_t;
+ public:
+ typedef typename Base_t::iterator iterator;
+ typedef typename Base_t::const_iterator const_iterator;
+ typedef typename Base_t::blockIterator blockIterator;
+ typedef typename Base_t::const_blockIterator const_blockIterator;
+ typedef typename DT_t::Element_t Element_t;
+ typedef typename DT_t::Domain_t Domain_t;
+ typedef typename DT_t::OneDomain_t OneDomain_t;
+ typedef typename DT_t::BlockDomain_t BlockDomain_t;
+ typedef typename DT_t::AskDomain_t AskDomain_t;
+ typedef typename DT_t::AddResult_t AddResult_t;
+ typedef typename DT_t::MultResult_t MultResult_t;
+ typedef typename DT_t::Storage_t Storage_t;
+ enum { domain = DT_t::domain };
+ enum { dimensions = DT_t::dimensions,
+ sliceDimensions = DT_t::sliceDimensions };
+ enum { loopAware = DT_t::loopAware };
+ enum { singleValued = DT_t::singleValued };
+ enum { unitStride = DT_t::unitStride };
+ enum { wildcard = DT_t::wildcard };
+ Grid() { }
+ Grid(const Grid<Dim> &a) {
+ NewDomain1<Grid<Dim> >::fill(*this, a);
+ }
+ template<class T1>
+ explicit Grid(const T1 &a) {
+ NewDomain1<T1>::fill(*this, a);
+ }
+ template<class T1, class T2>
+ Grid(const T1 &a, const T2 &b) {
+ NewDomain2<T1,T2>::fill(*this, a, b);
+ }
+ template<class T1, class T2, class T3>
+ Grid(const T1 &a, const T2 &b, const T3 &c) {
+ NewDomain3<T1,T2,T3>::fill(*this, a, b, c);
+ }
+ template<class T1, class T2, class T3, class T4>
+ Grid(const T1 &a, const T2 &b, const T3 &c, const T4 &d) {
+ NewDomain4<T1,T2,T3,T4>::fill(*this, a, b, c, d);
+ }
+ template<class T1, class T2, class T3, class T4, class T5>
+ Grid(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e) {
+ NewDomain5<T1,T2,T3,T4,T5>::fill(*this, a, b, c, d, e);
+ }
+ template<class T1, class T2, class T3, class T4, class T5,
+ class T6>
+ Grid(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
+ const T6 &f) {
+ NewDomain6<T1,T2,T3,T4,T5,T6>::fill(*this, a, b, c, d, e, f);
+ }
+ template<class T1, class T2, class T3, class T4, class T5,
+ class T6, class T7>
+ Grid(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
+ const T6 &f, const T7 &g) {
+ NewDomain7<T1,T2,T3,T4,T5,T6,T7>::fill(*this, a, b, c, d, e, f, g);
+ }
+ ~Grid() { }
+ template<class T>
+ Grid<Dim> &operator=(const T &newdom) {
+ return NewDomain1<T>::fill(*this, newdom);
+ }
+ Grid<Dim> &operator=(const Grid<Dim> &newdom) {
+ return NewDomain1<Grid<Dim> >::fill(*this, newdom);
+ }
+ template<class Out>
+ void print(Out &o) const;
+ protected:
+ private:
+ };
+ template<int Dim>
+ template<class Out>
+ void Grid<Dim>::print(Out &o) const
+ {
+ iterator p = this->begin();
+ iterator pend = this->end();
+ o << "[";
+ while (p != pend)
+ {
+ o << *p;
+ ++p;
+ if (p != pend)
+ o << ",";
+ }
+ o << "]";
+ }
+ template<>
+ class Grid<1> : public Domain<1, DomainTraits<Grid<1> > >
+ {
+ typedef DomainTraits< Grid<1> > DT_t;
+ public:
+ typedef DT_t::Element_t Element_t;
+ typedef DT_t::Domain_t Domain_t;
+ typedef DT_t::OneDomain_t OneDomain_t;
+ typedef DT_t::BlockDomain_t BlockDomain_t;
+ typedef DT_t::AskDomain_t AskDomain_t;
+ typedef DT_t::AddResult_t AddResult_t;
+ typedef DT_t::MultResult_t MultResult_t;
+ typedef DT_t::Storage_t Storage_t;
+ enum { domain = DT_t::domain };
+ enum { dimensions = DT_t::dimensions,
+ sliceDimensions = DT_t::sliceDimensions };
+ enum { loopAware = DT_t::loopAware };
+ enum { singleValued = DT_t::singleValued };
+ enum { unitStride = DT_t::unitStride };
+ enum { wildcard = DT_t::wildcard };
+ Grid() { }
+ Grid(const Grid<1> &a) {
+ NewDomain1<Grid<1> >::fill(*this, a);
+ }
+ template<class T1>
+ explicit Grid(const T1 &a) {
+ NewDomain1<T1>::fill(*this, a);
+ }
+ Grid(char a) {
+ ;
+ DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Grid(unsigned char a) {
+ ;
+ DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Grid(short a) {
+ ;
+ short s = (a < 0 ? -1 : 1);
+ DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - s);
+ }
+ Grid(unsigned short a) {
+ ;
+ DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Grid(int a) {
+ ;
+ int s = (a < 0 ? -1 : 1);
+ DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - s);
+ }
+ Grid(unsigned int a) {
+ ;
+ DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ Grid(long a) {
+ ;
+ long s = (a < 0 ? -1 : 1);
+ DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - s);
+ }
+ Grid(unsigned long a) {
+ ;
+ DomainTraits<Grid<1> >::setDomain(domain_m, 0, a - 1);
+ }
+ template<class T1, class T2>
+ Grid(const T1 &m, const T2 &n);
+ template<class T1, class T2, class T3>
+ Grid(const T1 &m, const T2 &n, const T3 &s);
+ ~Grid() { }
+ template<class T>
+ Grid<1> &operator=(const T &newdom) {
+ return NewDomain1<T>::fill(*this, newdom);
+ }
+ Grid<1> &operator=(const Grid<1> &newdom) {
+ return NewDomain1<Grid<1> >::fill(*this, newdom);
+ }
+ template<class Out>
+ void print(Out &o) const;
+ };
+ template <class T1, class T2>
+ inline
+ Grid<1>::Grid(const T1 &m, const T2 &n) {
+ DomainTraits<Grid<1> >::setDomain(domain_m, m, n);
+ }
+ template <class T1, class T2, class T3>
+ inline
+ Grid<1>::Grid(const T1 &m, const T2 &n, const T3 &s) {
+ DomainTraits<Grid<1> >::setDomain(domain_m, m, n, s);
+ }
+ template<class Out>
+ void Grid<1>::print(Out &o) const
+ {
+ iterator p = begin();
+ iterator pend = end();
+ o << "[";
+ while (p != pend)
+ {
+ o << *p;
+ ++p;
+ if (p != pend)
+ o << ",";
+ }
+ o << "]";
+ }
+ template<int Dim>
+ std::ostream& operator<<(std::ostream &o, const Grid<Dim> &grid)
+ {
+ grid.print(o);
+ return o;
+ }
+ template <int Dim, class T> class Region;
+ template <class T> class Region<1,T>;
+ template<int Dim, class T>
+ struct DomainTraits< Region<Dim,T> >
+ : public DomainTraitsDomain<Region<Dim,T>, T, Dim>
+ {
+ typedef DomainTraitsDomain<Region<Dim,T>, T, Dim> Base_t;
+ typedef typename Base_t::Element_t Element_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef typename Base_t::NewDomain1_t NewDomain1_t;
+ typedef Region<1,T> OneDomain_t;
+ typedef Region<1,T> PointDomain_t;
+ typedef Region<Dim,T> BlockDomain_t;
+ typedef Region<Dim,T> AskDomain_t;
+ typedef Region<Dim,T> AddResult_t;
+ typedef Region<Dim,T> MultResult_t;
+ typedef WrapNoInit<OneDomain_t> Storage_t[Dim];
+ enum { domain = Base_t::domain };
+ enum { dimensions = Base_t::dimensions,
+ sliceDimensions = Dim };
+ enum { loopAware = false };
+ enum { singleValued = false };
+ enum { unitStride = true };
+ enum { wildcard = false };
+ static OneDomain_t &getDomain(Domain_t &d, int n) { return d[n]; }
+ static const OneDomain_t &getDomain(const Domain_t &d,int n) { return d[n]; }
+ static PointDomain_t &getPointDomain(Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ static void initializeStorage(Storage_t &dom) {
+ Dom1Initialize<Dim-1>::template apply<DomainTraits<Region<Dim, T> > >(dom);
+ }
+ };
+ template<class T>
+ struct DomainTraits< Region<1,T> >
+ : public DomainTraitsDomain<Region<1,T>, T, 1>
+ {
+ typedef DomainTraitsDomain<Region<1,T>, T, 1> Base_t;
+ typedef typename Base_t::Element_t Element_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef Region<1,T> OneDomain_t;
+ typedef Region<1,T> BlockDomain_t;
+ typedef Region<1,T> AskDomain_t;
+ typedef Region<1,T> AddResult_t;
+ typedef Region<1,T> MultResult_t;
+ typedef Element_t Storage_t[2];
+ typedef Element_t IteratorStorage_t[2];
+ enum { domain = Base_t::domain };
+ enum { dimensions = Base_t::dimensions,
+ sliceDimensions = 1 };
+ enum { loopAware = false };
+ enum { singleValued = false };
+ enum { unitStride = true };
+ enum { wildcard = false };
+ static Element_t first(const Storage_t &d) { return d[0]; }
+ static Element_t last(const Storage_t &d) { return d[0] + d[1]; }
+ static Element_t stride(const Storage_t &d) { return d[1]; }
+ static Element_t length(const Storage_t &d) { return d[1]; }
+ static Element_t min(const Storage_t &d) {
+ return (length(d) >= 0 ? first(d) : last(d));
+ }
+ static Element_t max(const Storage_t &d) {
+ return (length(d) >= 0 ? last(d) : first(d));
+ }
+ static bool empty(const Storage_t &d) { return false; }
+ static int loop(const Storage_t &) { return 0; }
+ static Element_t elem(const Storage_t &d, int n) { return d[0] + n*d[1]; }
+ static OneDomain_t &getDomain(Domain_t &d, int) { return d; }
+ static const OneDomain_t &getDomain(const Domain_t &d, int) { return d; }
+ static void initializeStorage(Storage_t &dom) {
+ dom[0] = 0;
+ dom[1] = 0;
+ }
+ template<class DT>
+ static void setDomain(Storage_t &dom, const DT &newdom) {
+ PoomaCTAssert<(DomainTraits<DT>::dimensions == 1)>::test();
+ dom[0] = DomainTraits<DT>::getFirst(newdom);
+ dom[1] = DomainTraits<DT>::getLast(newdom) - dom[0];
+ }
+ static void setDomain(Storage_t &dom, Element_t begval, Element_t endval) {
+ dom[0] = begval;
+ dom[1] = (endval - begval);
+ }
+ static void setLoop(Storage_t &, int) { }
+ template<class UT, class DT>
+ static void setWildcardDomain(Storage_t &dom, const UT &u, const DT &newdom)
+ {
+ PoomaCTAssert<(DomainTraits<DT>::wildcard)>::test();
+ PoomaCTAssert<(DomainTraits<DT>::dimensions == 1)>::test();
+ PoomaCTAssert<(DomainTraits<UT>::dimensions == 1)>::test();
+ dom[0] = newdom.first(u);
+ dom[1] = newdom.last(u) - dom[0];
+ }
+ template<class DT>
+ static bool isLessThan(const Storage_t &dom, const DT &newdom) {
+ PoomaCTAssert<(DomainTraits<DT>::dimensions == 1)>::test();
+ return (dom[1] < DomainTraits<DT>::getLength(newdom) ||
+ (dom[1] == DomainTraits<DT>::getLength(newdom) &&
+ dom[0] < DomainTraits<DT>::getFirst(newdom)));
+ }
+ template<class DT>
+ static bool isEqualTo(const Storage_t &dom, const DT &newdom) {
+ PoomaCTAssert<(DomainTraits<DT>::dimensions == 1)>::test();
+ return (dom[0] == DomainTraits<DT>::getFirst(newdom) &&
+ dom[1] == DomainTraits<DT>::getLength(newdom));
+ }
+ template<class DT>
+ static void addAccum(Storage_t &dom, const DT &newdom) {
+ PoomaCTAssert<(DomainTraits<DT>::singleValued)>::test();
+ PoomaCTAssert<(DomainTraits<DT>::dimensions == 1)>::test();
+ dom[0] += DomainTraits<DT>::getFirst(newdom);
+ }
+ template<class DT>
+ static void subtractAccum(Storage_t &dom, const DT &newdom) {
+ PoomaCTAssert<(DomainTraits<DT>::singleValued)>::test();
+ PoomaCTAssert<(DomainTraits<DT>::dimensions == 1)>::test();
+ dom[0] -= DomainTraits<DT>::getFirst(newdom);
+ }
+ template<class DT>
+ static void multiplyAccum(Storage_t &dom, const DT &newdom) {
+ PoomaCTAssert<(DomainTraits<DT>::singleValued && DomainTraits<DT>::dimensions == 1)>::test();
+ dom[0] *= DomainTraits<DT>::getFirst(newdom);
+ dom[1] *= DomainTraits<DT>::getFirst(newdom);
+ }
+ template<class DT>
+ static void divideAccum(Storage_t &dom, const DT &newdom) {
+ PoomaCTAssert<(DomainTraits<DT>::singleValued && DomainTraits<DT>::dimensions == 1)>::test();
+ dom[0] /= DomainTraits<DT>::getFirst(newdom);
+ dom[1] /= DomainTraits<DT>::getFirst(newdom);
+ }
+ static void initializeIterator(const Storage_t &d, IteratorStorage_t &i) {
+ i[0] = d[0];
+ i[1] = d[1];
+ }
+ static void initializeIterator(const Storage_t &d1, const Storage_t &d2,
+ IteratorStorage_t &i) {
+ i[0] = d1[0] + d2[1] + d2[1];
+ i[1] = d2[1];
+ }
+ static void copyIterator(IteratorStorage_t d, IteratorStorage_t &i) {
+ i[0] = d[0];
+ i[1] = d[1];
+ }
+ static Element_t currentIterator(IteratorStorage_t i) { return i[0]; }
+ static bool compareIterator(IteratorStorage_t a, IteratorStorage_t b) {
+ return (a[0] == b[0] && a[1] == b[1]);
+ }
+ static void incrementIterator(IteratorStorage_t &i) { i[0] += i[1]; }
+ static void decrementIterator(IteratorStorage_t &i) { i[0] -= i[1]; }
+ };
+ template<int Dim1, int Dim2, class T>
+ struct DomainChangeDim<Region<Dim1,T>, Dim2>
+ {
+ typedef Region<Dim1,T> OldType_t;
+ typedef Region<Dim2,T> NewType_t;
+ enum { oldDim = Dim1,
+ newDim = Dim2 };
+ };
+ template<int Dim, class T = double>
+ class Region : public Domain<Dim, DomainTraits<Region<Dim,T> > >
+ {
+ typedef DomainTraits< Region<Dim,T> > DT_t;
+ typedef Domain<Dim, DT_t> Base_t;
+ public:
+ typedef typename Base_t::iterator iterator;
+ typedef typename Base_t::const_iterator const_iterator;
+ typedef typename Base_t::blockIterator blockIterator;
+ typedef typename Base_t::const_blockIterator const_blockIterator;
+ typedef typename DT_t::Element_t Element_t;
+ typedef typename DT_t::Domain_t Domain_t;
+ typedef typename DT_t::OneDomain_t OneDomain_t;
+ typedef typename DT_t::BlockDomain_t BlockDomain_t;
+ typedef typename DT_t::AskDomain_t AskDomain_t;
+ typedef typename DT_t::AddResult_t AddResult_t;
+ typedef typename DT_t::MultResult_t MultResult_t;
+ typedef typename DT_t::Storage_t Storage_t;
+ enum { domain = DT_t::domain };
+ enum { dimensions = DT_t::dimensions,
+ sliceDimensions = DT_t::sliceDimensions };
+ enum { loopAware = DT_t::loopAware };
+ enum { singleValued = DT_t::singleValued };
+ enum { unitStride = DT_t::unitStride };
+ enum { wildcard = DT_t::wildcard };
+ Region() { }
+ Region(const Pooma::NoInit &e)
+ : Domain<Dim, DomainTraits<Region<Dim,T> > >(e) {
+ }
+ Region(const Region<Dim,T> &a)
+ : Domain<Dim, DomainTraits<Region<Dim,T> > >(Pooma::NoInit()) {
+ NewDomain1<Region<Dim,T> >::fill(*this, a);
+ }
+ template<class T1>
+ explicit Region(const T1 &a)
+ : Domain<Dim, DomainTraits<Region<Dim,T> > >(Pooma::NoInit()) {
+ NewDomain1<T1>::fill(*this, a);
+ }
+ template<class T1, class T2>
+ Region(const T1 &a, const T2 &b)
+ : Domain<Dim, DomainTraits<Region<Dim,T> > >(Pooma::NoInit()) {
+ NewDomain2<T1,T2>::fill(*this, a, b);
+ }
+ template<class T1, class T2, class T3>
+ Region(const T1 &a, const T2 &b, const T3 &c)
+ : Domain<Dim, DomainTraits<Region<Dim,T> > >(Pooma::NoInit()) {
+ NewDomain3<T1,T2,T3>::fill(*this, a, b, c);
+ }
+ template<class T1, class T2, class T3, class T4>
+ Region(const T1 &a, const T2 &b, const T3 &c, const T4 &d)
+ : Domain<Dim, DomainTraits<Region<Dim,T> > >(Pooma::NoInit()) {
+ NewDomain4<T1,T2,T3,T4>::fill(*this, a, b, c, d);
+ }
+ template<class T1, class T2, class T3, class T4, class T5>
+ Region(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e)
+ : Domain<Dim, DomainTraits<Region<Dim,T> > >(Pooma::NoInit()) {
+ NewDomain5<T1,T2,T3,T4,T5>::fill(*this, a, b, c, d, e);
+ }
+ template<class T1, class T2, class T3, class T4, class T5,
+ class T6>
+ Region(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
+ const T6 &f)
+ : Domain<Dim, DomainTraits<Region<Dim,T> > >(Pooma::NoInit()) {
+ NewDomain6<T1,T2,T3,T4,T5,T6>::fill(*this, a, b, c, d, e, f);
+ }
+ template<class T1, class T2, class T3, class T4, class T5,
+ class T6, class T7>
+ Region(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
+ const T6 &f, const T7 &g)
+ : Domain<Dim, DomainTraits<Region<Dim,T> > >(Pooma::NoInit()) {
+ NewDomain7<T1,T2,T3,T4,T5,T6,T7>::fill(*this, a, b, c, d, e, f, g);
+ }
+ ~Region() { }
+ template<class T1>
+ Region<Dim,T> &operator=(const T1 &newdom) {
+ return NewDomain1<T1>::fill(*this, newdom);
+ }
+ Region<Dim,T> &operator=(const Region<Dim,T> &newdom) {
+ return NewDomain1<Region<Dim,T> >::fill(*this, newdom);
+ }
+ protected:
+ private:
+ };
+ template<class T>
+ class Region<1,T> : public Domain<1, DomainTraits<Region<1,T> > >
+ {
+ typedef DomainTraits< Region<1,T> > DT_t;
+ typedef Domain<1, DT_t> Base_t;
+ public:
+ typedef typename Base_t::iterator iterator;
+ typedef typename Base_t::const_iterator const_iterator;
+ typedef typename Base_t::blockIterator blockIterator;
+ typedef typename Base_t::const_blockIterator const_blockIterator;
+ typedef typename DT_t::Element_t Element_t;
+ typedef typename DT_t::Domain_t Domain_t;
+ typedef typename DT_t::OneDomain_t OneDomain_t;
+ typedef typename DT_t::BlockDomain_t BlockDomain_t;
+ typedef typename DT_t::AskDomain_t AskDomain_t;
+ typedef typename DT_t::AddResult_t AddResult_t;
+ typedef typename DT_t::MultResult_t MultResult_t;
+ typedef typename DT_t::Storage_t Storage_t;
+ enum { domain = DT_t::domain };
+ enum { dimensions = DT_t::dimensions,
+ sliceDimensions = DT_t::sliceDimensions };
+ enum { loopAware = DT_t::loopAware };
+ enum { singleValued = DT_t::singleValued };
+ enum { unitStride = DT_t::unitStride };
+ enum { wildcard = DT_t::wildcard };
+ Region() { }
+ Region(const Pooma::NoInit &e)
+ : Domain<1, DomainTraits<Region<1,T> > >(e) {
+ }
+ Region(const Region<1,T> &a)
+ : Domain<1, DomainTraits<Region<1,T> > >(Pooma::NoInit()) {
+ NewDomain1<Region<1,T> >::fill(*this, a);
+ }
+ template<class T1>
+ explicit Region(const T1 &a)
+ : Domain<1, DomainTraits<Region<1,T> > >(Pooma::NoInit()) {
+ NewDomain1<T1>::fill(*this, a);
+ }
+ Region(Element_t n)
+ : Domain<1, DomainTraits<Region<1,T> > >(Pooma::NoInit()) {
+ DomainTraits<Region<1,T> >::setDomain(this->domain_m, 0, n);
+ }
+ Region(Element_t m, Element_t n)
+ : Domain<1, DomainTraits<Region<1,T> > >(Pooma::NoInit()) {
+ DomainTraits<Region<1,T> >::setDomain(this->domain_m, m, n);
+ }
+ Region(Element_t m, Element_t n, Element_t)
+ : Domain<1, DomainTraits<Region<1,T> > >(Pooma::NoInit()) {
+ DomainTraits<Region<1,T> >::setDomain(this->domain_m, m, n);
+ }
+ template<class T1>
+ Region<1,T> &operator=(const T1 &newdom) {
+ return NewDomain1<T1>::fill(*this, newdom);
+ }
+ Region<1,T> &operator=(const Region<1,T> &newdom) {
+ return NewDomain1<Region<1,T> >::fill(*this, newdom);
+ }
+ const OneDomain_t &operator[](int d) const { return *this; }
+ OneDomain_t &operator[](int d) { return *this; }
+ };
+ template <int Dim, int C>
+ struct DomainDelta;
+ struct DomainDeltaStorage {};
+ template <int Dim, int C>
+ struct DomainTraits< DomainDelta<Dim, C> >
+ : public DomainTraitsDomain<DomainDelta<Dim, C>, int, Dim>
+ {
+ typedef DomainTraitsDomain<DomainDelta<Dim, C>, int, Dim> Base_t;
+ typedef typename Base_t::Element_t Element_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef typename Base_t::NewDomain1_t NewDomain1_t;
+ typedef DomainDelta<1, C> OneDomain_t;
+ typedef DomainDelta<1, C> PointDomain_t;
+ typedef DomainDelta<Dim, C> BlockDomain_t;
+ typedef DomainDelta<Dim, C> AskDomain_t;
+ typedef Loc<Dim> AddResult_t;
+ typedef Loc<Dim> MultResult_t;
+ typedef DomainDeltaStorage Storage_t;
+ enum { domain = Base_t::domain };
+ enum { dimensions = Base_t::dimensions,
+ sliceDimensions = 0 };
+ enum { loopAware = false };
+ enum { singleValued = true };
+ enum { unitStride = true };
+ enum { wildcard = false };
+ inline static void initializeStorage(Storage_t &dom) { }
+ inline static OneDomain_t getDomain(const Domain_t &d, int) { return OneDomain_t(); }
+ inline static PointDomain_t getPointDomain(const Domain_t &d, int) { return PointDomain_t(); }
+ };
+ template <int Dim, int C>
+ class DomainDelta : public Domain<Dim, DomainTraits<DomainDelta<Dim, C> > > {
+ public:
+ enum { component = C };
+ inline DomainDelta()
+ : Domain<Dim, DomainTraits<DomainDelta<Dim, C> > >(Pooma::NoInit()) {}
+ inline DomainDelta(const DomainDelta<Dim, C>&)
+ : Domain<Dim, DomainTraits<DomainDelta<Dim, C> > >(Pooma::NoInit()) {}
+ inline DomainDelta(const Pooma::NoInit &a)
+ : Domain<Dim, DomainTraits<DomainDelta<Dim, C> > >(a) {}
+ inline ~DomainDelta() {}
+ inline DomainDelta<Dim, C> &operator=(const DomainDelta<Dim, C>&) { return *this; }
+ };
+ template<class T, int Dim, int C>
+ inline typename T::AddResult_t
+ operator+(const DomainBase<T> &d1, const DomainDelta<Dim, C> &d2) {
+ typename T::AddResult_t retval(d1.unwrap());
+ return (retval += d2);
+ }
+ template<class T, int Dim, int C>
+ inline typename T::AddResult_t
+ operator-(const DomainBase<T> &d1, const DomainDelta<Dim, C> &d2) {
+ typename T::AddResult_t retval(d1.unwrap());
+ return (retval -= d2);
+ }
+ template<int Dim>
+ class AllDomain
+ {
+ public:
+ typedef AllDomain<Dim> Domain_t;
+ typedef AllDomain<Dim> NewDomain1_t;
+ typedef AllDomain<1> OneDomain_t;
+ typedef int Element_t;
+ enum { dimensions = Dim };
+ AllDomain() {
+ PoomaCTAssert<(Dim > 0)>::test();
+ }
+ AllDomain(const AllDomain<Dim> &) {
+ PoomaCTAssert<(Dim > 0)>::test();
+ }
+ ~AllDomain() { }
+ OneDomain_t operator[](int) const { return OneDomain_t(); }
+ void setDomain(const AllDomain<Dim> &) { }
+ template<class T>
+ typename DomainTraits<T>::Element_t first(const T &u) const {
+ return u.first();
+ }
+ int first(int u) const { return u; }
+ template<class T>
+ typename DomainTraits<T>::Element_t length(const T &u) const {
+ return u.length();
+ }
+ int length(int) const { return 1; }
+ template<class T>
+ typename DomainTraits<T>::Element_t stride(const T &u) const {
+ return u.stride();
+ }
+ int stride(int) const { return 1; }
+ AllDomain<Dim> &operator=(const AllDomain<Dim> &) { return *this; }
+ protected:
+ private:
+ };
+ template<int Dim>
+ struct DomainTraits< AllDomain<Dim> >
+ {
+ typedef AllDomain<Dim> Domain_t;
+ typedef AllDomain<Dim> NewDomain1_t;
+ typedef AllDomain<1> OneDomain_t;
+ typedef AllDomain<1> PointDomain_t;
+ typedef AllDomain<Dim> AskDomain_t;
+ enum { domain = true };
+ enum { dimensions = Dim,
+ sliceDimensions = Dim };
+ enum { wildcard = true };
+ enum { singleValued = false };
+ static OneDomain_t getDomain(const Domain_t &, int) {
+ return OneDomain_t();
+ }
+ static PointDomain_t getPointDomain(const Domain_t &, int) {
+ return PointDomain_t();
+ }
+ };
+ template<int Dim>
+ class LeftDomain
+ {
+ public:
+ typedef LeftDomain<Dim> Domain_t;
+ typedef LeftDomain<1> OneDomain_t;
+ typedef int Element_t;
+ enum { dimensions = Dim };
+ LeftDomain() : endpoints_m(Pooma::NoInit()) { PoomaCTAssert<(Dim > 0)>::test(); }
+ LeftDomain(const LeftDomain<Dim> &d) : endpoints_m(d.endpoints_m) {
+ PoomaCTAssert<(Dim > 0)>::test();
+ }
+ template<class T1>
+ explicit LeftDomain(const T1 &a)
+ : endpoints_m(a) { PoomaCTAssert<(Dim > 0)>::test(); }
+ template<class T1, class T2>
+ LeftDomain(const T1 &a, const T2 &b)
+ : endpoints_m(a,b) { PoomaCTAssert<(Dim > 0)>::test(); }
+ template<class T1, class T2, class T3>
+ LeftDomain(const T1 &a, const T2 &b, const T3 &c)
+ : endpoints_m(a,b,c) { PoomaCTAssert<(Dim > 0)>::test(); }
+ template<class T1, class T2, class T3, class T4>
+ LeftDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d)
+ : endpoints_m(a,b,c,d) { PoomaCTAssert<(Dim > 0)>::test(); }
+ template<class T1, class T2, class T3, class T4, class T5>
+ LeftDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e)
+ : endpoints_m(a,b,c,d,e) { PoomaCTAssert<(Dim > 0)>::test(); }
+ template<class T1, class T2, class T3, class T4, class T5,
+ class T6>
+ LeftDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
+ const T6 &f)
+ : endpoints_m(a,b,c,d,e,f) { PoomaCTAssert<(Dim > 0)>::test(); }
+ template<class T1, class T2, class T3, class T4, class T5,
+ class T6, class T7>
+ LeftDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
+ const T6 &f, const T7 &g)
+ : endpoints_m(a,b,c,d,e,f,g) { PoomaCTAssert<(Dim > 0)>::test(); }
+ ~LeftDomain() { }
+ OneDomain_t operator[](int n) const { return OneDomain_t(endpoints_m[n]); }
+ void setDomain(const LeftDomain<Dim> &d) { endpoints_m = d.endpoints_m; }
+ template<class T>
+ typename DomainTraits<T>::Element_t first(const T &u) const {
+ return u.first();
+ }
+ int first(int u) const { return u; }
+ template<class T>
+ typename DomainTraits<T>::Element_t length(const T &u) const {
+ PoomaCTAssert<(Dim == 1)>::test();
+ T dom(u.first(), endpoints_m[0].first(), u.stride());
+ return dom.length();
+ }
+ int length(int u) const {
+ PoomaCTAssert<(Dim == 1)>::test();
+ Interval<1> dom(u, endpoints_m[0].first());
+ return dom.length();
+ }
+ template<class T>
+ typename DomainTraits<T>::Element_t stride(const T &u) const {
+ return u.stride();
+ }
+ int stride(int) const { return 1; }
+ LeftDomain<Dim> &operator=(const LeftDomain<Dim> &d) {
+ endpoints_m = d.endpoints_m;
+ return *this;
+ }
+ protected:
+ private:
+ Loc<Dim> endpoints_m;
+ };
+ template<int Dim>
+ struct DomainTraits< LeftDomain<Dim> >
+ {
+ typedef LeftDomain<Dim> Domain_t;
+ typedef LeftDomain<1> OneDomain_t;
+ typedef LeftDomain<1> PointDomain_t;
+ typedef LeftDomain<Dim> AskDomain_t;
+ enum { domain = true };
+ enum { dimensions = Dim,
+ sliceDimensions = Dim };
+ enum { wildcard = true };
+ enum { singleValued = false };
+ static OneDomain_t getDomain(const Domain_t &d, int n) {
+ return d[n];
+ }
+ static PointDomain_t getPointDomain(const Domain_t &d, int n) {
+ return d[n];
+ }
+ };
+ template<int Dim>
+ class RightDomain
+ {
+ public:
+ typedef RightDomain<Dim> Domain_t;
+ typedef RightDomain<1> OneDomain_t;
+ typedef int Element_t;
+ enum { dimensions = Dim };
+ RightDomain() : endpoints_m(Pooma::NoInit()) { PoomaCTAssert<(Dim > 0)>::test(); }
+ RightDomain(const RightDomain<Dim> &d) : endpoints_m(d.endpoints_m) {
+ PoomaCTAssert<(Dim > 0)>::test();
+ }
+ template<class T1>
+ explicit RightDomain(const T1 &a)
+ : endpoints_m(a) { PoomaCTAssert<(Dim > 0)>::test(); }
+ template<class T1, class T2>
+ RightDomain(const T1 &a, const T2 &b)
+ : endpoints_m(a,b) { PoomaCTAssert<(Dim > 0)>::test(); }
+ template<class T1, class T2, class T3>
+ RightDomain(const T1 &a, const T2 &b, const T3 &c)
+ : endpoints_m(a,b,c) { PoomaCTAssert<(Dim > 0)>::test(); }
+ template<class T1, class T2, class T3, class T4>
+ RightDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d)
+ : endpoints_m(a,b,c,d) { PoomaCTAssert<(Dim > 0)>::test(); }
+ template<class T1, class T2, class T3, class T4, class T5>
+ RightDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e)
+ : endpoints_m(a,b,c,d,e) { PoomaCTAssert<(Dim > 0)>::test(); }
+ template<class T1, class T2, class T3, class T4, class T5,
+ class T6>
+ RightDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
+ const T6 &f)
+ : endpoints_m(a,b,c,d,e,f) { PoomaCTAssert<(Dim > 0)>::test(); }
+ template<class T1, class T2, class T3, class T4, class T5,
+ class T6, class T7>
+ RightDomain(const T1 &a, const T2 &b, const T3 &c, const T4 &d, const T5 &e,
+ const T6 &f, const T7 &g)
+ : endpoints_m(a,b,c,d,e,f,g) { PoomaCTAssert<(Dim > 0)>::test(); }
+ ~RightDomain() { }
+ OneDomain_t operator[](int n) const { return OneDomain_t(endpoints_m[n]); }
+ void setDomain(const RightDomain<Dim> &d) { endpoints_m = d.endpoints_m; }
+ template<class T>
+ typename DomainTraits<T>::Element_t first(const T &u) const {
+ return endpoints_m[0].first();
+ }
+ int first(int u) const { return u; }
+ template<class T>
+ typename DomainTraits<T>::Element_t length(const T &u) const {
+ PoomaCTAssert<(Dim == 1)>::test();
+ T dom(endpoints_m[0].first(), u.last(), u.stride());
+ return dom.length();
+ }
+ int length(int u) const {
+ PoomaCTAssert<(Dim == 1)>::test();
+ Interval<1> dom(endpoints_m[0].first(), u);
+ return dom.length();
+ }
+ template<class T>
+ typename DomainTraits<T>::Element_t stride(const T &u) const {
+ return u.stride();
+ }
+ int stride(int) const { return 1; }
+ RightDomain<Dim> &operator=(const RightDomain<Dim> &d) {
+ endpoints_m = d.endpoints_m;
+ return *this;
+ }
+ protected:
+ private:
+ Loc<Dim> endpoints_m;
+ };
+ template<int Dim>
+ struct DomainTraits< RightDomain<Dim> >
+ {
+ typedef RightDomain<Dim> Domain_t;
+ typedef RightDomain<1> OneDomain_t;
+ typedef RightDomain<1> PointDomain_t;
+ typedef RightDomain<Dim> AskDomain_t;
+ enum { domain = true };
+ enum { dimensions = Dim,
+ sliceDimensions = Dim };
+ enum { wildcard = true };
+ enum { singleValued = false };
+ static OneDomain_t getDomain(const Domain_t &d, int n) {
+ return d[n];
+ }
+ static PointDomain_t getPointDomain(const Domain_t &d, int n) {
+ return d[n];
+ }
+ };
+ template<class T1, class T2, class T3, int Dim, bool strided>
+ struct EquivSubsetDomainSingle {
+ static void equiv(const T1 &a, const T2 &b, T3 &d) {
+ d[Dim-1] += (b.first() - a.first());
+ }
+ };
+ template<class T1, class T2, class T3, int Dim>
+ struct EquivSubsetDomainSingle<T1,T2,T3,Dim,true> {
+ static void equiv(const T1 &a, const T2 &b, T3 &d) {
+ typedef typename DomainTraits<T3>::Element_t E3_t;
+ E3_t m = b.stride() / a.stride();
+ ;
+ E3_t k = b.first() - m * a.first();
+ d[Dim-1] *= m;
+ d[Dim-1] += k;
+ }
+ };
+ template<class T1, class T2, class T3, int Dim>
+ struct EquivSubsetDomain {
+ enum { strided = !DomainTraits<T3>::unitStride };
+ static void equiv(const T1 &a, const T2 &b, T3 &c) {
+ typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
+ typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
+ EquivSubsetDomainSingle<Dom1_t,Dom2_t,T3,Dim,strided>::equiv(
+ DomainTraits<T1>::getDomain(a,Dim-1),
+ DomainTraits<T2>::getDomain(b,Dim-1), c);
+ EquivSubsetDomain<T1,T2,T3,Dim-1>::equiv(a,b,c);
+ }
+ };
+ template<class T1, class T2, class T3>
+ struct EquivSubsetDomain<T1,T2,T3,1> {
+ enum { strided = !DomainTraits<T3>::unitStride };
+ static void equiv(const T1 &a, const T2 &b, T3 &c) {
+ typedef typename DomainTraits<T1>::OneDomain_t Dom1_t;
+ typedef typename DomainTraits<T2>::OneDomain_t Dom2_t;
+ EquivSubsetDomainSingle<Dom1_t,Dom2_t,T3,1,strided>::equiv(
+ DomainTraits<T1>::getDomain(a,0), DomainTraits<T2>::getDomain(b,0), c);
+ }
+ };
+ template<class T1, class T2, class T3>
+ struct EquivSubsetReturnType {
+ typedef typename NewDomain3<T1,T2,T3>::Type_t Combine_t;
+ typedef typename
+ DomainChangeDim<Combine_t,DomainTraits<T1>::dimensions>::NewType_t Type_t;
+ };
+ template<class T1, class T2, class T3>
+ inline typename EquivSubsetReturnType<T1,T2,T3>::Type_t
+ equivSubset(const T1 &a, const T2 &b, const T3 &c)
+ {
+ typedef typename EquivSubsetReturnType<T1,T2,T3>::Type_t T4;
+ PoomaCTAssert<((int)DomainTraits<T1>::dimensions == DomainTraits<T2>::dimensions)>::test();
+ PoomaCTAssert<((int)DomainTraits<T1>::dimensions == DomainTraits<T3>::dimensions)>::test();
+ T4 d = c;
+ EquivSubsetDomain<T1,T2,T4,DomainTraits<T1>::dimensions>::equiv(a, b, d);
+ return d;
+ }
+ namespace Pooma {
+ class Tester
+ {
+ public:
+ Tester();
+ Tester(int argc, char **argv);
+ ~Tester();
+ inline Inform &out()
+ {
+ return inform_m;
+ }
+ inline bool ok() const
+ {
+ return ok_m;
+ }
+ inline int returnValue() const
+ {
+ return (ok() ? 0 : 1);
+ }
+ inline bool check(bool val)
+ {
+ ok_m = (ok_m && val);
+ if (!ok_m && abort_m)
+ {
+ if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("Check failed!", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Utilities/Tester.h", 163);
+ }
+ return val;
+ }
+ inline bool check(const char *str, bool val)
+ {
+ check(val);
+ if (str != 0)
+ out() << "Checking " << str;
+ else
+ out() << "Checking";
+ out() << ": check = " << val << ", updated status = " << ok_m;
+ out() << std::endl;
+ return val;
+ }
+ template<class T>
+ bool check(const char *str, const T &val, const T &correct)
+ {
+ bool res = check(val == correct);
+ if (str != 0)
+ out() << "Checking " << str;
+ else
+ out() << "Checking";
+ out() << ": val = " << val << ", correct = " << correct
+ << ", updated status = " << ok_m;
+ out() << std::endl;
+ return res;
+ }
+ template<class T>
+ bool check(const char *str, const T &val, const T &correct,
+ const T &tol)
+ {
+ bool res = check(std::abs(val - correct) < tol);
+ if (str != 0)
+ out() << "Checking " << str;
+ else
+ out() << "Checking";
+ out() << ": val = " << val << ", correct = " << correct
+ << ", updated status = " << ok_m;
+ out() << std::endl;
+ return res;
+ }
+ inline void set(bool val)
+ {
+ ok_m = val;
+ }
+ inline void setQuiet(bool quiet) {
+ quiet_m = quiet;
+ if (!verbose_m || quiet_m) {
+ out().setOutputLevel(Inform::off);
+ } else {
+ out().setOutputLevel(Inform::on);
+ }
+ }
+ inline void setVerbose(bool verbose) {
+ verbose_m = verbose;
+ if (!verbose_m || quiet_m) {
+ out().setOutputLevel(Inform::off);
+ } else {
+ out().setOutputLevel(Inform::on);
+ }
+ }
+ inline bool verbose() { return verbose_m; }
+ inline void setPrefix(char *prefix) { out().setPrefix(prefix); }
+ int results(const char *msg = 0) const;
+ void exceptionHandler(const char *msg = 0);
+ void exceptionHandler(const Assertion &asrt);
+ private:
+ bool ok_m;
+ bool quiet_m;
+ Inform inform_m;
+ bool verbose_m;
+ bool abort_m;
+ void parse(int argc, char **argv);
+ };
+ }
+ template <int Dim>
+ std::vector<Interval<Dim> >
+ DomainRemoveOverlap(const Interval<Dim> & s,const Interval<Dim> &r)
+ {
+ typedef Interval<Dim> Domain_t;
+ typedef std::vector<Domain_t> DomainList_t;
+ DomainList_t result,temp;
+ result.push_back(s);
+ for (int i=0;i<Dim;++i)
+ {
+ typename DomainList_t::iterator start = result.begin();
+ typename DomainList_t::iterator end = result.end();
+ for ( ; start!=end; ++start)
+ {
+ if (touches( (*start)[i], Loc<1>(r[i].min())))
+ {
+ Domain_t lower=*start,upper=*start;
+ if(r[i].min()-1>=lower[i].min())
+ {
+ lower[i] = Interval<1>(lower[i].min(),r[i].min()-1);
+ temp.push_back(lower);
+ } upper[i] = Interval<1>(r[i].min(),upper[i].max());
+ temp.push_back(upper);
+ }
+ else
+ temp.push_back(*start);
+ }
+ result = temp;
+ temp.clear();
+ start = result.begin();
+ end = result.end();
+ for ( ; start!=end; ++start)
+ {
+ if (touches( (*start)[i], Loc<1>(r[i].max())))
+ {
+ Domain_t lower=*start,upper=*start;
+ lower[i] = Interval<1>(lower[i].min(),r[i].max());
+ temp.push_back(lower);
+ if( r[i].max()+1 <= upper[i].max())
+ {
+ upper[i] = Interval<1>(r[i].max()+1,upper[i].max());
+ temp.push_back(upper);
+ }
+ }
+ else
+ temp.push_back(*start);
+ }
+ result=temp;
+ temp.clear();
+ }
+ typename DomainList_t::iterator start = result.begin();
+ typename DomainList_t::iterator end = result.end();
+ for ( ; start!=end ; ++start)
+ {
+ if (!touches(*start,r ) )
+ temp.push_back(*start);
+ }
+ return temp;
+ }
+ template <int Dim>
+ Grid<Dim> makeRGrid(const Interval<Dim> & gdom, const Loc<Dim> & blocks);
+ template<int Dim>
+ class UniformGridPartition;
+ template<int Dim>
+ class GridPartition
+ {
+ public:
+ typedef LocalMapper<Dim> DefaultMapper_t;
+ typedef Interval<Dim> Domain_t;
+ typedef Node<Domain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ enum { uniform = false };
+ enum { gridded = true };
+ enum { tile = false };
+ enum { general = false };
+ enum { dimensions = Dim };
+ GridPartition(const Grid<Dim> &g)
+ : hasInternalGuards_m(false),
+ hasExternalGuards_m(false),
+ internalGuards_m(0),
+ externalGuards_m(0),
+ grid_m(g)
+ {
+ num_m=1;
+ for (int i=0;i<Dim;i++)
+ {
+ blocks_m[i] = Loc<1>(grid_m[i].size()-1);
+ num_m*=blocks_m[i].first();
+ }
+ }
+ GridPartition(const Grid<Dim> &g,
+ const GuardLayers<Dim> &gcs)
+ : hasInternalGuards_m(true),
+ hasExternalGuards_m(true),
+ internalGuards_m(gcs),
+ externalGuards_m(gcs),
+ grid_m(g)
+ {
+ num_m=1;
+ for (int i=0;i<Dim;i++)
+ {
+ blocks_m[i] = Loc<1>(grid_m[i].size()-1);
+ num_m*=blocks_m[i].first();
+ }
+ }
+ GridPartition(const Grid<Dim> &g,
+ const GuardLayers<Dim> &igcs,
+ const GuardLayers<Dim> &egcs)
+ : hasInternalGuards_m(true),
+ hasExternalGuards_m(true),
+ internalGuards_m(igcs),
+ externalGuards_m(egcs),
+ grid_m(g)
+ {
+ num_m=1;
+ for (int i=0;i<Dim;i++)
+ {
+ blocks_m[i] = Loc<1>(grid_m[i].size()-1);
+ num_m*=(grid_m[i].size()-1);
+ }
+ }
+ GridPartition()
+ : hasInternalGuards_m(false),
+ hasExternalGuards_m(false),
+ internalGuards_m(0),
+ externalGuards_m(0),
+ num_m(1)
+ {
+ for (int i=0;i<Dim;++i)
+ blocks_m[i]=Loc<1>(1);
+ }
+ GridPartition(const Loc<Dim> &a)
+ : blocks_m(a),
+ hasInternalGuards_m(false),
+ hasExternalGuards_m(false),
+ internalGuards_m(0),
+ externalGuards_m(0)
+ {
+ num_m = blocks_m[0].first();
+ for (int d=1; d < Dim; ++d)
+ num_m *= blocks_m[d].first();
+ }
+ GridPartition(const Loc<Dim> &a,
+ const GuardLayers<Dim> &gcs)
+ : blocks_m(a),
+ hasInternalGuards_m(true),
+ hasExternalGuards_m(true),
+ internalGuards_m(gcs),
+ externalGuards_m(gcs)
+ {
+ num_m = blocks_m[0].first();
+ for (int d=1; d < Dim; ++d)
+ num_m *= blocks_m[d].first();
+ }
+ GridPartition(const Loc<Dim> &a,
+ const GuardLayers<Dim> &igcs,
+ const GuardLayers<Dim> &egcs)
+ : blocks_m(a),
+ hasInternalGuards_m(true),
+ hasExternalGuards_m(true),
+ internalGuards_m(igcs),
+ externalGuards_m(egcs)
+ {
+ num_m = blocks_m[0].first();
+ for (int d=1; d < Dim; ++d)
+ num_m *= blocks_m[d].first();
+ }
+ GridPartition(const GridPartition<Dim> & b)
+ : blocks_m(b.blocks_m),
+ hasInternalGuards_m(b.hasInternalGuards_m),
+ hasExternalGuards_m(b.hasExternalGuards_m),
+ internalGuards_m(b.internalGuards_m),
+ externalGuards_m(b.externalGuards_m),
+ num_m(b.num_m),
+ grid_m(b.grid_m)
+ {
+ }
+ GridPartition(const UniformGridPartition<Dim> & b)
+ : blocks_m(b.blocks_m),
+ hasInternalGuards_m(b.hasInternalGuards_m),
+ hasExternalGuards_m(b.hasExternalGuards_m),
+ internalGuards_m(b.internalGuards_m),
+ externalGuards_m(b.externalGuards_m),
+ num_m(b.num_m)
+ {}
+ ~GridPartition() { }
+ GridPartition<Dim> &operator=(const GridPartition<Dim> &g)
+ {
+ if (this != &g)
+ {
+ hasInternalGuards_m = g.hasInternalGuards_m;
+ hasExternalGuards_m = g.hasExternalGuards_m;
+ internalGuards_m = g.internalGuards_m;
+ externalGuards_m = g.externalGuards_m;
+ blocks_m = g.blocks();
+ num_m = g.maxSize();
+ grid_m = g.grid();
+ if (!hasInternalGuards_m)
+ internalGuards_m = GuardLayers<Dim>(0);
+ if (!hasExternalGuards_m)
+ externalGuards_m = GuardLayers<Dim>(0);
+ }
+ return *this;
+ }
+ int maxSize() const { return num_m; }
+ const Loc<Dim> &blocks() const { return blocks_m; }
+ bool hasGuards() const { return hasInternalGuards_m||hasExternalGuards_m; }
+ bool hasCustomEdgeGuards() const
+ {
+ if (hasInternalGuards_m&&!hasExternalGuards_m) return true;
+ if (!hasInternalGuards_m&&hasExternalGuards_m) return true;
+ if (hasInternalGuards_m&&hasExternalGuards_m
+ &&(internalGuards_m!=externalGuards_m)) return true;
+ return false;
+ }
+ bool hasInternalGuards() const { return hasInternalGuards_m; }
+ bool hasExternalGuards() const { return hasExternalGuards_m;}
+ const Grid<Dim> &grid() const { return grid_m;}
+ const GuardLayers<Dim> &internalGuards() const
+ {
+ return internalGuards_m;
+ }
+ const GuardLayers<Dim> &externalGuards() const
+ {
+ return externalGuards_m;
+ }
+ template<class D>
+ int partition(const D &domain,
+ List_t & all,
+ const ContextMapper<Dim> &cmapper ) const;
+ template<class D>
+ int partition(const D &domain,
+ List_t & all) const
+ {
+ return partition(domain,all,DefaultMapper_t(*this));
+ }
+ template<class Out>
+ void print(Out &o) const;
+ private:
+ Loc<Dim> blocks_m;
+ bool hasInternalGuards_m;
+ bool hasExternalGuards_m;
+ GuardLayers<Dim> internalGuards_m;
+ GuardLayers<Dim> externalGuards_m;
+ int num_m;
+ Grid<Dim> grid_m;
+ };
+ template<int Dim>
+ template<class D>
+ int GridPartition<Dim>::partition(const D &domain,
+ List_t & all,
+ const ContextMapper<Dim> &cmapper ) const
+ {
+ typedef typename DomainTraits<Domain_t>::Element_t Element_t;
+ PoomaCTAssert<(Dim == DomainTraits<D>::dimensions)>::test();
+ PoomaCTAssert<(Dim == DomainTraits<Domain_t>::dimensions)>::test();
+ Grid<Dim> tgrid = grid();
+ if (domain.empty())
+ {
+ int np = 1;
+ for (int i=0;i<Dim;++i)
+ np*=blocks()[i].first();
+ int start=0;
+ Domain_t o;
+ Domain_t a;
+ while (start<np)
+ {
+ int gid = all.size();
+ int lid = -1;
+ Value_t *node = new Value_t(o, a, -1, gid, lid);
+ all.push_back(node);
+ ++start;
+ }
+ cmapper.map(all);
+ return maxSize();
+ }
+ if (tgrid.empty()&&!domain.empty() )
+ {
+ tgrid = makeRGrid(domain,blocks_m);
+ }
+ typename Grid<Dim>::blockIterator start = tgrid.beginBlock();
+ typename Grid<Dim>::blockIterator end = tgrid.endBlock();
+ while (start!=end)
+ {
+ Loc<Dim> idx = start.point();
+ Domain_t o = Pooma::NoInit();
+ o = * start;
+ Domain_t a = Pooma::NoInit();
+ a = * start;
+ if (hasInternalGuards()||hasExternalGuards())
+ {
+ for (int i=0;i<Dim;i++)
+ {
+ if (idx[i]==0)
+ {
+ if (hasExternalGuards())
+ {
+ o[i]=Interval<1>(o[i].first()-externalGuards().lower(i),
+ o[i].last());
+ a[i]=Interval<1>(a[i].first()-externalGuards().lower(i),
+ a[i].last());
+ }
+ if (hasInternalGuards() && idx[i]!=(blocks()[i].first()-1))
+ a[i]=Interval<1>(a[i].first(),
+ a[i].last()+internalGuards().upper(i));
+ }
+ if (idx[i]==blocks()[i].first()-1)
+ {
+ if (hasExternalGuards())
+ {
+ o[i]=Interval<1>(o[i].first(),
+ o[i].last()+externalGuards().upper(i));
+ a[i]=Interval<1>(a[i].first(),
+ a[i].last()+externalGuards().upper(i));
+ }
+ if (hasInternalGuards()&&(idx[i]!=0))
+ a[i]=Interval<1>(a[i].first()-internalGuards().lower(i),
+ a[i].last());
+ }
+ if (idx[i]!=0&&
+ idx[i]!=(blocks()[i].first()-1)&&
+ hasInternalGuards())
+ a[i]=Interval<1>(o[i].first()-internalGuards().lower(i),
+ o[i].last()+internalGuards().upper(i));
+ }
+ }
+ int gid = all.size();
+ int lid = -1;
+ Value_t *node = new Value_t(o, a, -1, gid, lid);
+ all.push_back(node);
+ ++start;
+ }
+ cmapper.map(all);
+ return maxSize();
+ }
+ template<int Dim>
+ template<class Out>
+ void GridPartition<Dim>::print(Out &o) const
+ {
+ int i;
+ o << "GridPartition<" << Dim << ">:" << std::endl;
+ o << " blocks_m = " << blocks_m << std::endl;
+ o << " hasInternalGuards_m hasExternalGuards_m = ";
+ o << hasInternalGuards_m<< " "<<hasExternalGuards_m<< std::endl;
+ o << " internalGuards_m:" << std::endl;
+ o << " upper ";
+ for (i=0; i < Dim; ++i)
+ o << internalGuards_m.upper(i) << " ";
+ o << std::endl;
+ o << " lower ";
+ for (i=0; i < Dim; ++i)
+ o << internalGuards_m.lower(i) << " ";
+ o << std::endl;
+ o << " externalGuards_m:" << std::endl;
+ o << " upper ";
+ for (i=0; i < Dim; ++i)
+ o << externalGuards_m.upper(i) << " ";
+ o << std::endl;
+ o << " lower ";
+ for (i=0; i < Dim; ++i)
+ o << externalGuards_m.lower(i) << " ";
+ o << std::endl;
+ o << " num_m = " << num_m << std::endl;
+ o << " grid_m = ";
+ if (grid_m.empty() )
+ o << "(empty)" << std::endl;
+ else
+ o << grid_m << std::endl;
+ }
+ template <int Dim>
+ std::ostream &operator<<(std::ostream &o, const GridPartition<Dim> &gp)
+ {
+ gp.print(o);
+ return o;
+ }
+ template <int Dim>
+ Grid<Dim> makeRGrid(const Interval<Dim> &gdom, const Loc<Dim> &blocks)
+ {
+ Grid<Dim> ret;
+ for (int i=0;i<Dim;++i)
+ {
+ if (gdom[i].size()%blocks[i].first()==0&& !gdom[i].empty())
+ {
+ ret[i]=Grid<1>(Range<1>(gdom[i].first(),
+ gdom[i].last()+1,
+ (int) gdom[i].size()/blocks[i].first()));
+ }
+ else if (!gdom[i].empty() )
+ {
+ IndirectionList<int> rret(blocks[i].first()+1);
+ rret(0) = gdom[i].first();
+ for (int j = 1;j<blocks[i].first()+1;++j)
+ {
+ int temp = (int) gdom[i].size()/blocks[i].first();
+ rret(j)= rret(j-1) + temp ;
+ rret(j) += (j > (blocks[i].first() -
+ (gdom[i].size()- temp*blocks[i].first()) ) );
+ }
+ ret[i]=Grid<1>(rret);
+ }
+ else
+ {
+ }
+ }
+ return ret;
+ }
+ template <typename T>
+ std::vector<T> makeRBlocksFactor(T number)
+ {
+ std::vector<T> factors;
+ for (T f=2; f<number; f++) {
+ while (number % f == 0) {
+ factors.push_back(f);
+ number /= f;
+ }
+ }
+ if (number != 1)
+ factors.push_back(number);
+ return factors;
+ }
+ template <int Dim>
+ Loc<Dim> makeRBlocks(const Interval<Dim>& domain, int nodes)
+ {
+ typedef typename std::vector<int>::reverse_iterator riterator_t;
+ std::vector<int> df[Dim];
+ std::vector<int> nf;
+ for (int i=0; i<Dim; i++)
+ df[i] = makeRBlocksFactor<int>(domain[i].size());
+ nf = makeRBlocksFactor<int>(nodes);
+ int setup[Dim];
+ for (int i=0; i<Dim; i++)
+ setup[i] = 1;
+ int sdi[Dim];
+ for (int i=0; i<Dim; i++)
+ sdi[i] = i;
+ for (riterator_t ni = nf.rbegin(); ni < nf.rend(); ni++) {
+ bool changed;
+ do {
+ changed = false;
+ for (int i=0; i<Dim-1; i++)
+ if (domain[sdi[i]].size()/setup[sdi[i]]
+ < domain[sdi[i+1]].size()/setup[sdi[i+1]]) {
+ std::swap(sdi[i+1], sdi[i]);
+ changed = true;
+ }
+ } while (changed);
+ int i = sdi[0];
+ riterator_t di;
+ for (di = df[i].rbegin(); di < df[i].rend(); di++) {
+ if ((*di) == (*ni)) {
+ setup[i] *= (*ni);
+ break;
+ }
+ }
+ if (di == df[i].rend())
+ setup[i] *= (*ni);
+ }
+ Loc<Dim> result;
+ for (int i=0; i<Dim; i++)
+ result[i] = setup[i];
+ return result;
+ }
+ template<int Dim>
+ SparseTileLayoutData<Dim>::SparseTileLayoutData()
+ : Observable<SparseTileLayoutData>(*this)
+ {
+ }
+ template<int Dim>
+ SparseTileLayoutData<Dim>::SparseTileLayoutData(const Domain_t &boundingbox,
+ const PatchList_t & PatchList,
+ const ContextMapper<Dim> &cmap)
+ : LayoutBaseData<Dim>(false,false,
+ GuardLayers_t(0),GuardLayers_t(0),
+ boundingbox,boundingbox),
+ Observable<SparseTileLayoutData>(*this)
+ {
+ this->blocks_m = Loc<Dim>();
+ initialize(boundingbox,PatchList,cmap);
+ }
+ template<int Dim>
+ SparseTileLayoutData<Dim>::SparseTileLayoutData(const Domain_t &boundingbox,
+ const GuardLayers_t & globalGL,
+ const PatchList_t & PatchList,
+ const ContextMapper<Dim> &cmap)
+ : LayoutBaseData<Dim>(true,true,
+ globalGL,globalGL,
+ boundingbox,boundingbox),
+ Observable<SparseTileLayoutData>(*this)
+ {
+ this->blocks_m = Loc<Dim>();
+ initialize(boundingbox,globalGL,PatchList,cmap);
+ }
+ template<int Dim>
+ SparseTileLayoutData<Dim>::SparseTileLayoutData(const Domain_t &boundingbox,
+ const GuardLayers_t & internalGL,
+ const GuardLayers_t & externalGL,
+ const PatchList_t & PatchList,
+ const ContextMapper<Dim> &cmap)
+ : LayoutBaseData<Dim>(true,true,
+ internalGL,externalGL,
+ boundingbox,boundingbox),
+ Observable<SparseTileLayoutData>(*this)
+ {
+ this->blocks_m = Loc<Dim>();
+ initialize(boundingbox,internalGL,externalGL,PatchList,cmap );
+ }
+ template<int Dim>
+ SparseTileLayoutData<Dim>::SparseTileLayoutData(const Domain_t &boundingbox)
+ : LayoutBaseData<Dim>(false, false,
+ GuardLayers_t(),GuardLayers_t(),
+ boundingbox,boundingbox),
+ Observable<SparseTileLayoutData>(*this)
+ {
+ this->blocks_m = Loc<Dim>();
+ initialize(boundingbox);
+ }
+ template<int Dim>
+ SparseTileLayoutData<Dim>::SparseTileLayoutData(const Domain_t &boundingbox,
+ const GuardLayers_t & internalGL,
+ const GuardLayers_t & externalGL)
+ : LayoutBaseData<Dim>(true, true,
+ internalGL,externalGL,
+ boundingbox,boundingbox),
+ Observable<SparseTileLayoutData>(*this)
+ {
+ this->blocks_m = Loc<Dim>();
+ initialize(boundingbox,internalGL,externalGL);
+ }
+ template<int Dim>
+ template<class Partitioner>
+ SparseTileLayoutData<Dim>::SparseTileLayoutData(const Domain_t &bbox,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> &cmap)
+ : LayoutBaseData<Dim>(false,false,
+ GuardLayers_t(0),GuardLayers_t(0),
+ bbox,bbox),
+ Observable<SparseTileLayoutData>(*this)
+ {
+ this->blocks_m = Loc<Dim>();
+ if (gpar.hasInternalGuards() && gpar.maxSize() > 1)
+ {
+ this->hasInternalGuards_m = true;
+ this->internalGuards_m = gpar.internalGuards();
+ }
+ if (gpar.hasExternalGuards())
+ {
+ this->hasExternalGuards_m = true;
+ this->externalGuards_m = gpar.externalGuards();
+ GuardLayers<Dim>::addGuardLayers(this->domain_m,this->externalGuards_m);
+ }
+ initialize(bbox, gpar,cmap);
+ }
+ template<int Dim>
+ SparseTileLayoutData<Dim>::~SparseTileLayoutData()
+ {
+ for (typename List_t::iterator a = this->all_m.begin(); a != this->all_m.end(); ++a)
+ delete (*a);
+ }
+ template<int Dim>
+ void SparseTileLayoutData<Dim>::syncPatch()
+ {
+ typename List_t::iterator start = this->all_m.begin();
+ typename List_t::iterator end = this->all_m.end();
+ for ( ; start != end ; ++start)
+ if ( (*start)->context() == Pooma::context()
+ ||(*start)->context() == -1 )
+ this->local_m.push_back(*start);
+ else
+ this->remote_m.push_back(*start);
+ calcMaps();
+ calcAllocMaps();
+ calcGCFillList();
+ }
+ template<int Dim>
+ void SparseTileLayoutData<Dim>::calcMaps()
+ {
+ if (!this->initialized())
+ return;
+ map_m.zap();
+ map_m.initialize(this->domain_m);
+ typename List_t::const_iterator start = this->all_m.begin();
+ typename List_t::const_iterator end = this->all_m.end();
+ int i=0;
+ for ( ; start != end ; ++start, ++i )
+ {
+ pidx_t tmp((*start)->globalID(),i);
+ typename DomainMap<Domain_t,pidx_t>::Value_t val((*start)->domain(),tmp);
+ map_m.insert(val);
+ }
+ map_m.update();
+ }
+ template<int Dim>
+ void SparseTileLayoutData<Dim>::calcAllocMaps()
+ {
+ if (!this->initialized())
+ return;
+ mapAloc_m.zap();
+ mapAloc_m.initialize(this->domain_m);
+ typename List_t::const_iterator start = this->all_m.begin();
+ typename List_t::const_iterator end = this->all_m.end();
+ int i=0;
+ for ( ; start!=end ; ++start , ++i)
+ {
+ pidx_t tmp((*start)->globalID(),i);
+ typename DomainMap<Domain_t,pidx_t>::Value_t val((*start)->allocated(),tmp);
+ mapAloc_m.insert(val);
+ }
+ mapAloc_m.update();
+ }
+ template<int Dim>
+ void SparseTileLayoutData<Dim>::initialize(const Domain_t &gdom)
+ {
+ this->blocks_m = Loc<Dim>();
+ int i;
+ if (this->all_m.size() > 0)
+ {
+ for (i=0; i < this->all_m.size(); ++i)
+ delete this->all_m[i];
+ this->all_m.clear();
+ this->local_m.clear();
+ this->remote_m.clear();
+ }
+ for(i=0;i<Dim;++i)
+ this->firste_m[i] = this->firsti_m[i] = this->domain_m[i].first();
+ this->domain_m = gdom;
+ this->innerdomain_m = gdom;
+ this->hasInternalGuards_m = this->hasExternalGuards_m = false;
+ this->internalGuards_m = this->externalGuards_m = GuardLayers_t();
+ }
+ template<int Dim>
+ void SparseTileLayoutData<Dim>::initialize(const Domain_t &gdom,
+ const GuardLayers_t & globalGL)
+ {
+ this->blocks_m = Loc<Dim>();
+ int i;
+ if (this->all_m.size() > 0)
+ {
+ for (i=0; i < this->all_m.size(); ++i)
+ delete this->all_m[i];
+ this->all_m.clear();
+ this->local_m.clear();
+ this->remote_m.clear();
+ }
+ this->domain_m = gdom;
+ this->innerdomain_m = gdom;
+ for(i=0;i<Dim;++i)
+ this->firsti_m[i] = this->domain_m[i].first();
+ this->hasInternalGuards_m = this->hasExternalGuards_m=true;
+ this->internalGuards_m = this->externalGuards_m = globalGL;
+ GuardLayers<Dim>::addGuardLayers(this->domain_m, this->externalGuards_m);
+ for(i=0;i<Dim;++i)
+ this->firste_m[i]=this->domain_m[i].first();
+ }
+ template<int Dim>
+ void SparseTileLayoutData<Dim>::initialize(const Domain_t &gdom,
+ const GuardLayers_t & internalGL,
+ const GuardLayers_t & externalGL)
+ {
+ this->blocks_m = Loc<Dim>();
+ int i;
+ if (this->all_m.size() > 0)
+ {
+ for (i=0; i < this->all_m.size(); ++i)
+ delete this->all_m[i];
+ this->all_m.clear();
+ this->local_m.clear();
+ this->remote_m.clear();
+ }
+ this->domain_m = gdom;
+ this->innerdomain_m = gdom;
+ for(i=0;i<Dim;++i)
+ this->firsti_m[i]=this->domain_m[i].first();
+ this->hasInternalGuards_m = this->hasExternalGuards_m = true;
+ this->internalGuards_m = internalGL;
+ this->externalGuards_m = externalGL;
+ GuardLayers<Dim>::addGuardLayers(this->domain_m, this->externalGuards_m);
+ for(i=0;i<Dim;++i)
+ this->firste_m[i] = this->domain_m[i].first();
+ }
+ template<int Dim>
+ void SparseTileLayoutData<Dim>::initialize(const Domain_t &bbox,
+ const PatchList_t &plist,
+ const ContextMapper<Dim> &cmap)
+ {
+ this->blocks_m = Loc<Dim>();
+ initialize(bbox);
+ TilePartition<Dim> gpar(plist);
+ gpar.partition(bbox,this->all_m,cmap);
+ syncPatch();
+ }
+ template<int Dim>
+ void SparseTileLayoutData<Dim>::initialize(const Domain_t &bbox,
+ const GuardLayers_t & globalGL,
+ const PatchList_t &plist,
+ const ContextMapper<Dim> &cmap)
+ {
+ this->blocks_m = Loc<Dim>();
+ initialize(bbox,globalGL);
+ TilePartition<Dim> gpar(bbox,plist,globalGL);
+ gpar.partition(bbox,this->all_m,cmap);
+ syncPatch();
+ }
+ template<int Dim>
+ void SparseTileLayoutData<Dim>::initialize(const Domain_t &bbox,
+ const GuardLayers_t & internalGL,
+ const GuardLayers_t & externalGL,
+ const PatchList_t &plist,
+ const ContextMapper<Dim> &cmap)
+ {
+ this->blocks_m = Loc<Dim>();
+ initialize(bbox,internalGL,externalGL);
+ TilePartition<Dim> gpar(bbox,plist,internalGL,externalGL);
+ gpar.partition(bbox,this->all_m,cmap);
+ syncPatch();
+ }
+ template<int Dim>
+ template<class Partitioner>
+ void SparseTileLayoutData<Dim>::initialize(const Domain_t &bbox,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> &cmap)
+ {
+ this->blocks_m = Loc<Dim>();
+ initialize(bbox,gpar.internalGuards(),gpar.externalGuards());
+ gpar.partition(bbox,this->all_m,cmap);
+ syncPatch();
+ }
+ template<int Dim>
+ void SparseTileLayoutData<Dim>::calcGCFillList()
+ {
+ if(!this->initialized() || !this->hasInternalGuards_m)
+ return;
+ this->gcFillList_m.clear();
+ gcBorderFillList_m.clear();
+ typedef Node<Domain_t,AllocatedDomain_t> NNode_t;
+ typedef std::vector<NNode_t> TouchList_t;
+ TouchList_t tlist;
+ typename List_t::iterator start = this->all_m.begin();
+ typename List_t::iterator end = this->all_m.end();
+ for ( ; start!=end; ++start)
+ {
+ touches((*start)->allocated(),
+ std::back_inserter(tlist),
+ TouchesConstructNodeObj());
+ typename TouchList_t::iterator GCLstart = tlist.begin();
+ typename TouchList_t::iterator GCLend = tlist.end();
+ for( ; GCLstart != GCLend ;++GCLstart)
+ {
+ if(GCLstart->globalID() == (*start)->globalID())
+ {
+ tlist.erase(GCLstart);
+ break;
+ }
+ }
+ GCLstart = tlist.begin();
+ GCLend = tlist.end();
+ for ( ; GCLstart!=GCLend ; ++GCLstart )
+ {
+ this->gcFillList_m.push_back(GCFillInfo_t((*GCLstart).domain(),
+ (*GCLstart).globalID(),
+ (*start)->globalID()));
+ }
+ tlist.clear();
+ }
+ std::vector<GCBorderFillInfo> bfv;
+ start = this->all_m.begin();
+ for ( ; start!=this->all_m.end(); ++start)
+ {
+ for(int d=0;d<Dim;++d)
+ {
+ Domain_t gcdom( (*start)->allocated());
+ int max = (*start)->allocated()[d].last();
+ int min = max - this->internalGuards_m.upper(d) + 1;
+ gcdom[d] = Interval<1>(min, max);
+ gcdom = intersect(this->innerdomain_m,gcdom);
+ if (gcdom.size()>0)
+ {
+ bfv.push_back(GCBorderFillInfo(gcdom, (*start)->globalID() ));
+ }
+ gcdom = (*start)->allocated();
+ min = (*start)->allocated()[d].first();
+ max = min + this->internalGuards_m.lower(d) -1;
+ gcdom[d] = Interval<1>(min, max);
+ gcdom = intersect(this->innerdomain_m,gcdom);
+ if (gcdom.size() > 0)
+ {
+ bfv.push_back(GCBorderFillInfo(gcdom,(*start)->globalID()));
+ }
+ }
+ }
+ std::vector<Domain_t> temp2,temp3,temp4;
+ std::vector<GCBorderFillInfo> temp;
+ BorderFillIterator_t bst = bfv.begin();
+ BorderFillIterator_t ben = bfv.end();
+ for ( ; bst != ben ; ++bst)
+ {
+ FillIterator_t gst = this->beginFillList();
+ FillIterator_t gen = this->endFillList();
+ temp2.clear();
+ temp2.push_back(bst->domain());
+ for ( ; gst!=gen ; ++gst )
+ {
+ typename std::vector<Domain_t>::iterator ts = temp2.begin();
+ for ( ; ts != temp2.end() ; ++ts )
+ {
+ temp3 = DomainRemoveOverlap(*ts,gst->domain_m);
+ temp4.insert(temp4.end(),temp3.begin(),temp3.end());
+ }
+ temp2 = temp4;
+ temp4.clear();
+ }
+ typename std::vector<Domain_t>::iterator ts = temp2.begin();
+ for( ; ts != temp2.end(); ++ts)
+ temp.push_back(GCBorderFillInfo(*ts, bst->patchID() ));
+ }
+ gcBorderFillList_m = temp;
+ }
+ template<int Dim>
+ int SparseTileLayoutData<Dim>::globalID(const Loc<Dim> &loc) const
+ {
+ ;
+ DomainMapTouchIterator<Interval<Dim>,pidx_t> dmti =
+ (map_m.touch(Interval<Dim>(loc))).first;
+ DomainMapTouchIterator<Interval<Dim>,pidx_t> baditerator;
+ if (__builtin_expect(!!(dmti!=baditerator), true)) {} else Pooma::toss_cookies("Bad location requested in SparseTileLayout", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Layout/SparseTileLayout.cpp", 538);
+ return (*dmti).first;
+ }
+ template <int Dim>
+ int SparseTileLayoutData<Dim>::globalID(int i0) const
+ {
+ ;
+ Loc<Dim> loc;
+ loc[0] = i0;
+ return globalID(loc);
+ }
+ template <int Dim>
+ int SparseTileLayoutData<Dim>::globalID(int i0, int i1) const
+ {
+ ;
+ Loc<Dim> loc;
+ loc[0] = i0;
+ loc[1] = i1;
+ return globalID(loc);
+ }
+ template <int Dim>
+ int SparseTileLayoutData<Dim>::globalID(int i0, int i1, int i2) const
+ {
+ ;
+ Loc<Dim> loc;
+ loc[0] = i0;
+ loc[1] = i1;
+ loc[2] = i2;
+ return globalID(loc);
+ }
+ template <int Dim>
+ int SparseTileLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3) const
+ {
+ ;
+ Loc<Dim> loc;
+ loc[0] = i0;
+ loc[1] = i1;
+ loc[2] = i2;
+ loc[3] = i3;
+ return globalID(loc);
+ }
+ template <int Dim>
+ int SparseTileLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
+ int i4) const
+ {
+ ;
+ Loc<Dim> loc;
+ loc[0] = i0;
+ loc[1] = i1;
+ loc[2] = i2;
+ loc[3] = i3;
+ loc[4] = i4;
+ return globalID(loc);
+ }
+ template <int Dim>
+ int SparseTileLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
+ int i4, int i5) const
+ {
+ ;
+ Loc<Dim> loc;
+ loc[0] = i0;
+ loc[1] = i1;
+ loc[2] = i2;
+ loc[3] = i3;
+ loc[4] = i4;
+ loc[5] = i5;
+ return globalID(loc);
+ }
+ template <int Dim>
+ int SparseTileLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
+ int i4, int i5, int i6) const
+ {
+ ;
+ Loc<Dim> loc;
+ loc[0] = i0;
+ loc[1] = i1;
+ loc[2] = i2;
+ loc[3] = i3;
+ loc[4] = i4;
+ loc[5] = i5;
+ loc[6] = i6;
+ return globalID(loc);
+ }
+ template<int Dim>
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int SparseTileLayoutData<Dim>::touches(const OtherDomain &fulld,
+ OutIter o,
+ const ConstructTag &ctag) const
+ {
+ typedef typename
+ IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
+ OutDomain_t d = intersect(this->domain_m, fulld);
+ if (d.empty())
+ return 0;
+ OutDomain_t outDomain = Pooma::NoInit();
+ typedef Node<OutDomain_t,Domain_t> OutNode_t;
+ typename DomainMap<Interval<Dim>,pidx_t>::Touch_t dmti =
+ map_m.touch(Interval<Dim>(d));
+ typename DomainMap<Interval<Dim>,pidx_t>::touch_iterator a;
+ int count = 0;
+ for( a = dmti.first ;a != dmti.second; ++a)
+ {
+ int nodeListIndex = (*a).second;
+ outDomain = intersect(a.domain(), fulld);
+ ;
+ *o = touchesConstruct(outDomain,
+ this->all_m[nodeListIndex]->allocated(),
+ this->all_m[nodeListIndex]->affinity(),
+ this->all_m[nodeListIndex]->context(),
+ this->all_m[nodeListIndex]->globalID(),
+ this->all_m[nodeListIndex]->localID(),
+ ctag);
+ ++count;
+ }
+ return count;
+ }
+ template<int Dim>
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int SparseTileLayoutData<Dim>::touchesAlloc(const OtherDomain &fulld,
+ OutIter o,
+ const ConstructTag &ctag) const
+ {
+ int i;
+ typedef typename
+ IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
+ OutDomain_t d = intersect(this->domain_m, fulld);
+ if (d.empty())
+ return 0;
+ OutDomain_t outDomain = Pooma::NoInit();
+ typedef Node<OutDomain_t,Domain_t> OutNode_t;
+ typename DomainMap<Interval<Dim>,pidx_t>::Touch_t dmti = map_m.touch(d);
+ typename DomainMap<Interval<Dim>,pidx_t>::touch_iterator a;
+ int count = 0;
+ for( a = dmti.first ;a != dmti.second; ++a)
+ {
+ int nodeListIndex = (*a).second;
+ outDomain = intersect(a.domain(), fulld);
+ ;
+ *o = touchesConstruct(outDomain,
+ this->all_m[nodeListIndex]->allocated(),
+ this->all_m[nodeListIndex]->affinity(),
+ this->all_m[nodeListIndex]->context(),
+ this->all_m[nodeListIndex]->globalID(),
+ this->all_m[nodeListIndex]->localID(),
+ ctag);
+ ++count;
+ }
+ return count;
+ }
+ template<int Dim>
+ template<class Out>
+ void SparseTileLayoutData<Dim>::print(Out & o) const
+ {
+ int i;
+ o<< " SparseTileLayoutData<"<<Dim<<">: "<<std::endl;
+ o<< " ID_m " << this->ID_m << std::endl;
+ o<< " domain_m " << this->domain_m <<std::endl;
+ o<< " innerdomain_m " << this->innerdomain_m <<std::endl;
+ o<< " all_m : " << std::endl;
+ typename List_t::const_iterator start = this->all_m.begin();
+ typename List_t::const_iterator end = this->all_m.end();
+ for ( ; start!=end ; ++start)
+ o<< (*start)->globalID()<<" "<<
+ (*start)->domain()<<" "<<
+ (*start)->allocated()<<" "
+ <<std::endl;
+ o<< " local_m : " << std::endl;
+ start = this->local_m.begin();
+ end = this->local_m.end();
+ for ( ; start!=end ; ++start)
+ o<< (*start)->globalID()<<" "<<
+ (*start)->localID()<<" " <<
+ (*start)->domain()<<" "<<
+ (*start)->allocated()<<" "
+ <<std::endl;
+ o<< " firste_m[Dim] " ;
+ for ( i=0;i<Dim;++i) o<< this->firste_m[i]<<" ";
+ o<< std::endl;
+ o<< " firsti_m[Dim] " ;
+ for ( i=0;i<Dim;++i) o<< this->firsti_m[i]<<" ";
+ o<< std::endl;
+ o<< " hasInternalGuards_m, hasExternalGuards_m " <<
+ this->hasInternalGuards_m <<" " << this->hasExternalGuards_m <<std::endl;
+ o<< " internalGuards_m " ;
+ for ( i=0;i<Dim;++i)
+ o<< this->internalGuards_m.upper(i)<<"-"<<this->internalGuards_m.lower(i)<<" ";
+ o<<std::endl;
+ o<< " externalGuards_m " ;
+ for ( i=0;i<Dim;++i)
+ o<< this->externalGuards_m.upper(i)<<"-"<<this->externalGuards_m.lower(i)<<" ";
+ o<<std::endl;
+ FillIterator_t gstart = this->gcFillList_m.begin();
+ FillIterator_t gend = this->gcFillList_m.end();
+ o<< " gcFillList_m " <<std::endl;
+ for( ; gstart!=gend ; ++gstart)
+ o<<" "
+ <<gstart->domain_m<<" "
+ <<gstart->ownedID_m<<" "
+ <<gstart->guardID_m<<std::endl;
+ BorderFillIterator_t bgstart = gcBorderFillList_m.begin();
+ BorderFillIterator_t bgend = gcBorderFillList_m.end();
+ o<< " gcBorderFillList_m " <<std::endl;
+ for( ; bgstart!=bgend ; ++bgstart)
+ o<<" "
+ <<bgstart->domain()<<" "
+ <<bgstart->patchID()<<std::endl;
+ }
+ template<int Dim>
+ void SparseTileLayout<Dim>::syncPatch()
+ {
+ this->pdata_m->syncPatch();
+ }
+ template<int Dim>
+ SparseTileLayout<Dim>::SparseTileLayout()
+ : LayoutBase<Dim,SparseTileLayoutData<Dim> >(new LayoutData_t()),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template<int Dim>
+ SparseTileLayout<Dim>::SparseTileLayout(Domain_t & boundingbox,
+ const PatchList_t &patchlist,
+ const ReplicatedTag &)
+ : LayoutBase<Dim,SparseTileLayoutData<Dim> >
+ (new LayoutData_t(boundingbox,patchlist,LocalMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template<int Dim>
+ SparseTileLayout<Dim>::SparseTileLayout(Domain_t & boundingbox,
+ const PatchList_t &patchlist,
+ const DistributedTag &)
+ : LayoutBase<Dim,SparseTileLayoutData<Dim> >
+ (new LayoutData_t(boundingbox,patchlist,DistributedMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template<int Dim>
+ SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &boundingbox,
+ const GuardLayers_t & globalGL,
+ const PatchList_t & patchlist,
+ const DistributedTag &)
+ : LayoutBase<Dim,SparseTileLayoutData<Dim> >
+ (new LayoutData_t(boundingbox,globalGL,patchlist,DistributedMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template<int Dim>
+ SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &boundingbox,
+ const GuardLayers_t & globalGL,
+ const PatchList_t & patchlist,
+ const ReplicatedTag &)
+ : LayoutBase<Dim,SparseTileLayoutData<Dim> >
+ (new LayoutData_t(boundingbox,globalGL,patchlist,LocalMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template<int Dim>
+ SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &boundingbox,
+ const GuardLayers_t & internalGL,
+ const GuardLayers_t & externalGL,
+ const PatchList_t & patchlist,
+ const DistributedTag &)
+ : LayoutBase<Dim,SparseTileLayoutData<Dim> >
+ (new LayoutData_t(boundingbox,
+ internalGL,
+ externalGL,
+ patchlist,
+ DistributedMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template<int Dim>
+ SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &boundingbox,
+ const GuardLayers_t & internalGL,
+ const GuardLayers_t & externalGL,
+ const PatchList_t & patchlist,
+ const ReplicatedTag &)
+ : LayoutBase<Dim,SparseTileLayoutData<Dim> >
+ (new LayoutData_t(boundingbox,
+ internalGL,
+ externalGL,
+ patchlist,
+ LocalMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template<int Dim>
+ SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &boundingbox)
+ : LayoutBase<Dim,SparseTileLayoutData<Dim> >
+ (new LayoutData_t(boundingbox)),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template<int Dim>
+ SparseTileLayout<Dim>:: SparseTileLayout(const Domain_t &boundingbox,
+ const GuardLayers_t & globalGL)
+ : LayoutBase<Dim,SparseTileLayoutData<Dim> >
+ (new LayoutData_t(boundingbox,globalGL)),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template<int Dim>
+ SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &boundingbox,
+ const GuardLayers_t & internalGL,
+ const GuardLayers_t & externalGL)
+ : LayoutBase<Dim,SparseTileLayoutData<Dim> >
+ (new LayoutData_t(boundingbox,internalGL,externalGL)),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ template <class Partitioner>
+ SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &bbox,
+ const Partitioner &gpar,
+ const DistributedTag &)
+ : LayoutBase<Dim,SparseTileLayoutData<Dim> >
+ (new LayoutData_t(bbox, gpar,DistributedMapper<Dim>(gpar))),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ template <class Partitioner>
+ SparseTileLayout<Dim>::SparseTileLayout(const Domain_t &bbox,
+ const Partitioner &gpar,
+ const ReplicatedTag &)
+ : LayoutBase<Dim,SparseTileLayoutData<Dim> >
+ (new LayoutData_t(bbox, gpar,LocalMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template<int Dim>
+ SparseTileLayout<Dim>::SparseTileLayout(const This_t &model)
+ : LayoutBase<Dim,SparseTileLayoutData<Dim> >(model.pdata_m),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template<int Dim >
+ struct IsValid
+ {
+ IsValid(Loc<Dim> loc) : loc_m(loc) { }
+ typedef AndCombine Combine_t;
+ Loc<Dim> loc_m;
+ };
+ template<class T, int Dim>
+ struct EngineFunctorScalar<T, IsValid<Dim> >
+ {
+ typedef bool Type_t;
+ static inline
+ Type_t apply(const T &, const IsValid<Dim> &)
+ {
+ return true;
+ }
+ };
+ template<class Engine, int Dim>
+ struct EngineFunctorDefault<Engine, IsValid<Dim> >
+ {
+ typedef bool Type_t;
+ static inline
+ Type_t apply(const Engine &, const IsValid<Dim> &)
+ {
+ return true;
+ }
+ };
+ template<int Dim,class T,class ptag>
+ struct EngineFunctor<Engine<Dim, T,MultiPatch<SparseTileTag,ptag> >, IsValid<Dim> >
+ {
+ typedef Engine<Dim,T,MultiPatch<SparseTileTag,ptag> > Engine_t;
+ typedef bool Type_t;
+ static inline
+ Type_t apply(const Engine_t &e, const IsValid<Dim> &f)
+ {
+ typedef typename Engine_t::Domain_t domain_t;
+ typedef Node<domain_t,domain_t> node_t;
+ std::vector<node_t> v;
+ int count = e.layout().touches(f.loc_m,std::back_inserter(v));
+ return (count!=0);
+ }
+ };
+ template<class Object,class Dom,class tag>
+ inline bool isValidLocation(const Object &,
+ const Dom &,
+ const tag &)
+ {
+ return true;
+ }
+ #include <iomanip>
+ class PrintArray;
+ template<class S, class A, int Dim, class DomainType>
+ struct PerformPrintArray
+ {
+ static void print(const PrintArray &, S &, const A &, const DomainType &);
+ };
+ template<class S, class A, class DomainType>
+ struct PerformPrintArray<S, A, 1, DomainType>
+ {
+ static void print(const PrintArray &, S &, const A &, const DomainType &);
+ };
+ class PrintArray
+ {
+ public:
+ PrintArray(int domainWidth = 3, int dataWidth = 10,
+ int dataPrecision = 4, int carReturn = -1,
+ bool scientific = false, int spacing = 1)
+ : domainwidth_m(domainWidth), datawidth_m(dataWidth),
+ dataprecision_m(dataPrecision), carreturn_m(carReturn),
+ spacing_m(spacing), scientific_m(scientific)
+ {
+ ;
+ ;
+ ;
+ ;
+ }
+ PrintArray(const PrintArray &a)
+ : domainwidth_m(a.domainwidth_m), datawidth_m(a.datawidth_m),
+ dataprecision_m(a.dataprecision_m), carreturn_m(a.carreturn_m),
+ scientific_m(a.scientific_m)
+ {
+ }
+ ~PrintArray()
+ {
+ }
+ template<class S, class A, class DomainType>
+ void print(S &s, const A &a, const DomainType &d) const
+ {
+ Pooma::blockAndEvaluate();
+ PerformPrintArray<S,A,A::dimensions,DomainType>::print(*this, s, a, d);
+ }
+ template<class S, class A>
+ void print(S &s, const A &a) const
+ {
+ Pooma::blockAndEvaluate();
+ PerformPrintArray<S, A, A::dimensions, typename A::Domain_t>::
+ print(*this, s, a, a.totalDomain());
+ }
+ int domainWidth() const
+ {
+ return domainwidth_m;
+ }
+ void setDomainWidth(int val)
+ {
+ domainwidth_m = val;
+ ;
+ }
+ int dataWidth() const
+ {
+ return datawidth_m;
+ }
+ void setDataWidth(int val)
+ {
+ datawidth_m = val;
+ ;
+ }
+ int dataPrecision() const
+ {
+ return dataprecision_m;
+ }
+ void setDataPrecision(int val)
+ {
+ dataprecision_m = val;
+ ;
+ }
+ int carReturn() const
+ {
+ return carreturn_m;
+ }
+ void setCarReturn(int val)
+ {
+ carreturn_m = val;
+ }
+ bool scientific() const
+ {
+ return scientific_m;
+ }
+ void setScientific(bool val)
+ {
+ scientific_m = val;
+ }
+ int spacing() const
+ {
+ return spacing_m;
+ }
+ void setSpacing(int val)
+ {
+ spacing_m = val;
+ ;
+ }
+ void setFormatParameters(PrintArray &pa) {
+ domainwidth_m = pa.domainWidth();
+ datawidth_m = pa.dataWidth();
+ dataprecision_m = pa.dataPrecision();
+ carreturn_m = pa.carReturn();
+ spacing_m = pa.spacing();
+ scientific_m = pa.scientific();
+ }
+ private:
+ int domainwidth_m;
+ int datawidth_m;
+ int dataprecision_m;
+ int carreturn_m;
+ int spacing_m;
+ bool scientific_m;
+ };
+ template<class S, class A, class DomainType>
+ void
+ PerformPrintArray<S,A,1,DomainType>::print(const PrintArray &p, S &s,
+ const A &a, const DomainType &d)
+ {
+ PoomaCTAssert<(A::dimensions == 1)>::test();
+ typedef DomainType Domain_t;
+ typedef typename Domain_t::const_iterator Iterator_t;
+ Domain_t domain(d);
+ Iterator_t griditer = domain.begin();
+ Iterator_t enditer = domain.end();
+ if (domain.size() == 1) {
+ s << "(";
+ if (domain[0].first() < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << domain[0].first();
+ s << ")";
+ s.fill(' ');
+ s << " = ";
+ if (p.scientific())
+ s.setf(std::ios::scientific);
+ s.precision(p.dataPrecision());
+ s.width(p.dataWidth());
+ s << a.read(*griditer);
+ s << std::endl;
+ return;
+ }
+ s << "(";
+ if (domain[0].first() < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << domain[0].first() << ":";
+ if (domain[0].last() < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << domain[0].last() << ":";
+ if (domain[0].stride() < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << domain[0].stride() << ") = ";
+ s.fill(' ');
+ int i, printed = 0;
+ while (griditer != enditer)
+ {
+ int spacing = 0;
+ if (printed > 0)
+ {
+ spacing = p.spacing();
+ if (p.carReturn() >= 0 && printed >= p.carReturn())
+ {
+ s << std::endl;
+ spacing = 3*p.domainWidth() + 7;
+ printed = 0;
+ }
+ }
+ for (i=0; i < spacing; ++i)
+ s << " ";
+ if (p.scientific())
+ s.setf(std::ios::scientific);
+ s.precision(p.dataPrecision());
+ s.width(p.dataWidth());
+ s << a.read(*griditer);
+ ++griditer;
+ ++printed;
+ }
+ s << std::endl;
+ }
+ template<class S, class A, int Dim, class DomainType>
+ void
+ PerformPrintArray<S,A,Dim,DomainType>::print(const PrintArray &p, S &s,
+ const A &a, const DomainType &d)
+ {
+ int i, j, k;
+ PoomaCTAssert<(A::dimensions == Dim && Dim > 1)>::test();
+ typedef DomainType Domain_t;
+ typedef typename Domain_t::Element_t Element_t;
+ typedef typename Domain_t::const_iterator Iterator_t;
+ Domain_t domain(d);
+ Iterator_t griditer = domain.begin();
+ Iterator_t enditer = domain.end();
+ if (domain.size() == 1) {
+ s << "(";
+ if (domain[0].first() < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << domain[0].first();
+ for (int d = 1; d < Dim; d++) {
+ s << ",";
+ if (domain[d].first() < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << domain[d].first();
+ }
+ s << ")";
+ s.fill(' ');
+ s << " = ";
+ if (p.scientific())
+ s.setf(std::ios::scientific);
+ s.precision(p.dataPrecision());
+ s.width(p.dataWidth());
+ s << a.read(*griditer);
+ s << std::endl;
+ return;
+ }
+ Element_t x0 = domain[0].first();
+ Element_t x1 = domain[0].last();
+ Element_t xs = domain[0].stride();
+ Element_t y0 = domain[1].first();
+ Element_t y1 = domain[1].last();
+ Element_t ys = domain[1].stride();
+ if (Dim > 2) {
+ s << std::endl << "~~~~~~~~~~~~~~ ";
+ s << "(" << domain[0].first() << ":" << domain[0].last()
+ << ":" << domain[0].stride();
+ for (int d = 1; d < Dim; d++) {
+ s << "," << domain[d].first() << ":" << domain[d].last() << ":"
+ << domain[d].stride();
+ }
+ s << ")" << " ~~~~~~~~~~~~~~" << std::endl;
+ }
+ while (griditer != enditer)
+ {
+ if (Dim > 2) {
+ s << std::endl << "(" << domain[0].first() << ":" << domain[0].last()
+ << ":" << domain[0].stride() << "," << domain[1].first() << ":"
+ << domain[1].last() << ":" << domain[1].stride();
+ for (i=2; i < Dim; ++i)
+ s << "," << (*griditer)[i].first();
+ s << "):" << std::endl;
+ s << "----------------------------------------------------"
+ << std::endl;
+ }
+ for (j=y0; j <= y1; j += ys)
+ {
+ s << "(";
+ if (x0 < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << x0 << ":";
+ if (x1 < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << x1 << ":";
+ if (xs < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << xs;
+ for (i=1; i < Dim; ++i)
+ {
+ s.fill(' ');
+ s << ",";
+ if ((*griditer)[i].first() < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << (*griditer)[i].first();
+ }
+ s << ")";
+ s.fill(' ');
+ s << " = ";
+ int printed = 0;
+ for (i=x0; i <= x1; i += xs)
+ {
+ int spacing = 0;
+ if (printed > 0)
+ {
+ spacing = p.spacing();
+ if (p.carReturn() >= 0 && printed >= p.carReturn())
+ {
+ s << std::endl;
+ spacing = (Dim + 2)*p.domainWidth() + 2 + Dim + 4;
+ printed = 0;
+ }
+ }
+ for (k=0; k < spacing; ++k)
+ s << ' ';
+ if (p.scientific())
+ s.setf(std::ios::scientific);
+ s.precision(p.dataPrecision());
+ s.width(p.dataWidth());
+ typedef typename A::Engine_t::Tag_t Etag_t;
+ Etag_t tag;
+ if(isValidLocation(a,*griditer,tag))
+ s << a.read(*griditer);
+ else
+ s<< ".";
+ ++griditer;
+ ++printed;
+ }
+ s << std::endl;
+ }
+ }
+ }
+ template<class NewDomain, bool sv>
+ struct CombineDomainOpt;
+ template<class NewDomain>
+ struct CombineDomainOpt<NewDomain, true>
+ {
+ typedef typename NewDomain::SliceType_t Type_t;
+ template<class Array, class Sub1>
+ inline static
+ Type_t make(const Array &, const Sub1 &s1)
+ {
+ return Type_t(s1);
+ }
+ template<class Array, class Sub1, class Sub2>
+ inline static
+ Type_t make(const Array &, const Sub1 &s1, const Sub2 &s2)
+ {
+ return Type_t(s1, s2);
+ }
+ template<class Array, class Sub1, class Sub2, class Sub3>
+ inline static
+ Type_t make(const Array &,
+ const Sub1 &s1, const Sub2 &s2, const Sub3 &s3)
+ {
+ return Type_t(s1, s2, s3);
+ }
+ template<class Array, class Sub1, class Sub2, class Sub3,
+ class Sub4>
+ inline static
+ Type_t make(const Array &,
+ const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4)
+ {
+ return Type_t(s1, s2, s3, s4);
+ }
+ template<class Array, class Sub1, class Sub2, class Sub3,
+ class Sub4, class Sub5>
+ inline static
+ Type_t make(const Array &,
+ const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4, const Sub5 &s5)
+ {
+ return Type_t(s1, s2, s3, s4, s5);
+ }
+ template<class Array, class Sub1, class Sub2, class Sub3,
+ class Sub4, class Sub5, class Sub6>
+ inline static
+ Type_t make(const Array &,
+ const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4, const Sub5 &s5, const Sub6 &s6)
+ {
+ return Type_t(s1, s2, s3, s4, s5, s6);
+ }
+ template<class Array, class Sub1, class Sub2, class Sub3,
+ class Sub4, class Sub5, class Sub6, class Sub7>
+ inline static
+ Type_t make(const Array &,
+ const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4, const Sub5 &s5, const Sub6 &s6,
+ const Sub7 &s7)
+ {
+ return Type_t(s1, s2, s3, s4, s5, s6, s7);
+ }
+ };
+ template<class NewDomain>
+ struct CombineDomainOpt<NewDomain, false>
+ {
+ typedef typename NewDomain::SliceType_t Type_t;
+ template<class Array, class Sub1>
+ inline static
+ Type_t make(const Array &a, const Sub1 &s1)
+ {
+ return NewDomain::combineSlice(a.totalDomain(), s1);
+ }
+ template<class Array, class Sub1, class Sub2>
+ inline static
+ Type_t make(const Array &a, const Sub1 &s1, const Sub2 &s2)
+ {
+ return NewDomain::combineSlice(a.totalDomain(), s1, s2);
+ }
+ template<class Array, class Sub1, class Sub2, class Sub3>
+ inline static
+ Type_t make(const Array &a,
+ const Sub1 &s1, const Sub2 &s2, const Sub3 &s3)
+ {
+ return NewDomain::combineSlice(a.totalDomain(), s1, s2, s3);
+ }
+ template<class Array, class Sub1, class Sub2, class Sub3,
+ class Sub4>
+ inline static
+ Type_t make(const Array &a,
+ const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4)
+ {
+ return NewDomain::combineSlice(a.totalDomain(), s1, s2, s3, s4);
+ }
+ template<class Array, class Sub1, class Sub2, class Sub3,
+ class Sub4, class Sub5>
+ inline static
+ Type_t make(const Array &a,
+ const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4, const Sub5 &s5)
+ {
+ return NewDomain::combineSlice(a.totalDomain(), s1, s2, s3, s4, s5);
+ }
+ template<class Array, class Sub1, class Sub2, class Sub3,
+ class Sub4, class Sub5, class Sub6>
+ inline static
+ Type_t make(const Array &a,
+ const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4, const Sub5 &s5, const Sub6 &s6)
+ {
+ return NewDomain::combineSlice(a.totalDomain(),
+ s1, s2, s3, s4, s5, s6);
+ }
+ template<class Array, class Sub1, class Sub2, class Sub3,
+ class Sub4, class Sub5, class Sub6, class Sub7>
+ inline static
+ Type_t make(const Array &a,
+ const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4, const Sub5 &s5, const Sub6 &s6,
+ const Sub7 &s7)
+ {
+ return NewDomain::combineSlice(a.totalDomain(),
+ s1, s2, s3, s4, s5, s6, s7);
+ }
+ };
+ template <class Tag>
+ struct Remote;
+ template<bool Block>
+ struct DataObjectApply
+ { };
+ template<>
+ struct DataObjectApply<false>
+ {
+ template<class Engine,class Functor>
+ inline static
+ typename Functor::Type_t
+ apply(const Engine&, const Functor& functor)
+ {
+ return functor.defaultValue();
+ }
+ };
+ template<>
+ struct DataObjectApply<true>
+ {
+ template<class Engine, class Functor>
+ inline static
+ typename Functor::Type_t
+ apply(const Engine& engine, const Functor& functor)
+ {
+ return functor(engine.dataObject());
+ }
+ template<int Dim, class T, class Tag, class Functor>
+ inline static
+ typename Functor::Type_t
+ apply(const Engine<Dim, T, Remote<Tag> >& engine, const Functor& functor)
+ {
+ if (engine.engineIsLocal())
+ return functor(engine.localEngine().dataObject());
+ else
+ return functor.defaultValue();
+ }
+ };
+ template<class RequestType>
+ class DataObjectRequest
+ {};
+ template<class Eng, class RequestType>
+ struct EngineFunctorDefault<Eng, DataObjectRequest<RequestType> >
+ {
+ enum { hasDataObject = Eng::hasDataObject };
+ typedef typename DataObjectRequest<RequestType>::Type_t Type_t;
+ static inline
+ Type_t apply(const Eng &e, const DataObjectRequest<RequestType> &request)
+ {
+ return DataObjectApply<hasDataObject>::apply(e, request);
+ }
+ };
+ template<class RequestType,class T>
+ struct EngineFunctorScalar<T, DataObjectRequest<RequestType> >
+ {
+ typedef typename DataObjectRequest<RequestType>::Type_t Type_t;
+ inline static
+ Type_t apply(const T &, const DataObjectRequest<RequestType> &tag)
+ {
+ return tag.defaultValue();
+ }
+ };
+ struct BlockAffinity { };
+ struct AffinityCombine
+ {
+ AffinityCombine() { }
+ AffinityCombine(const AffinityCombine &) { }
+ };
+ template<class Op>
+ struct Combine2<int, int, Op, AffinityCombine>
+ {
+ typedef int Type_t;
+ inline static
+ Type_t combine(int a, int b, AffinityCombine)
+ {
+ return a;
+ }
+ };
+ template<>
+ class DataObjectRequest<BlockAffinity>
+ {
+ public:
+ typedef int Type_t;
+ typedef AffinityCombine Combine_t;
+ DataObjectRequest() { }
+ inline Type_t operator()(Pooma::DataObject_t* obj) const
+ {
+ return obj->affinity();
+ }
+ inline Type_t defaultValue() const
+ {
+ return (-1);
+ }
+ };
+ template<int TotalDim, int SliceDim> class SliceInterval;
+ template<int TotalDim, int SliceDim>
+ struct DomainTraits< SliceInterval<TotalDim,SliceDim> >
+ {
+ enum { domain = true };
+ enum { dimensions = TotalDim,
+ sliceDimensions = SliceDim };
+ enum { unitStride = true };
+ enum { singleValued = false };
+ enum { wildcard = false };
+ typedef SliceInterval<TotalDim,SliceDim> Domain_t;
+ typedef SliceInterval<TotalDim,SliceDim> NewDomain1_t;
+ typedef Interval<SliceDim> SliceDomain_t;
+ typedef Interval<TotalDim> TotalDomain_t;
+ typedef Interval<1> OneDomain_t;
+ typedef Interval<1> PointDomain_t;
+ static OneDomain_t &getDomain(Domain_t &d, int n) {
+ return d.totalDomain()[n];
+ }
+ static const OneDomain_t &getDomain(const Domain_t &d,int n) {
+ return d.totalDomain()[n];
+ }
+ static OneDomain_t &getSliceDomain(Domain_t &d, int n) {
+ return d.sliceDomain()[n];
+ }
+ static const OneDomain_t &getSliceDomain(const Domain_t &d, int n) {
+ return d.sliceDomain()[n];
+ }
+ static PointDomain_t &getPointDomain(Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ static const PointDomain_t &getPointDomain(const Domain_t &d, int n) {
+ return getDomain(d, n);
+ }
+ static void cantIgnoreDomain(Domain_t &d, int n) {
+ d.cantIgnoreDomain(n);
+ }
+ static bool getIgnorable(const Domain_t &d, int n) {
+ return d.ignorable(n);
+ }
+ static void setIgnorable(Domain_t &d, int n, bool i) {
+ d.ignorable(n) = i;
+ }
+ };
+ template<int Dim, int SliceDim>
+ class SliceInterval
+ : public SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > >
+ {
+ public:
+ SliceInterval() { }
+ SliceInterval(const Pooma::NoInit &d)
+ : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > >(d) { }
+ SliceInterval(const SliceInterval<Dim,SliceDim> &nd)
+ : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > >(nd) {
+ }
+ template <class Base, class D1, class D2>
+ SliceInterval(const Base &baseDomain, const D1 &d1, const D2 &d2)
+ : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > > (
+ Pooma::NoInit())
+ {
+ typedef NewDomain2<D1,D2> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SliceType_t;
+ PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
+ PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
+ NewDomain_t::fillSlice(*this, baseDomain, d1, d2);
+ }
+ template <class Base, class D1, class D2, class D3>
+ SliceInterval(const Base &baseDomain, const D1 &d1, const D2 &d2,
+ const D3 &d3)
+ : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > > (
+ Pooma::NoInit())
+ {
+ typedef NewDomain3<D1,D2,D3> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SliceType_t;
+ PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
+ PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
+ NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3);
+ }
+ template <class Base, class D1, class D2, class D3,
+ class D4>
+ SliceInterval(const Base &baseDomain, const D1 &d1, const D2 &d2,
+ const D3 &d3, const D4 &d4)
+ : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > > (
+ Pooma::NoInit())
+ {
+ typedef NewDomain4<D1,D2,D3,D4> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SliceType_t;
+ PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
+ PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
+ NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4);
+ }
+ template <class Base, class D1, class D2, class D3,
+ class D4, class D5>
+ SliceInterval(const Base &baseDomain, const D1 &d1, const D2 &d2,
+ const D3 &d3, const D4 &d4, const D5 &d5)
+ : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > > (
+ Pooma::NoInit())
+ {
+ typedef NewDomain5<D1,D2,D3,D4,D5> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SliceType_t;
+ PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
+ PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
+ NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4, d5);
+ }
+ template <class Base, class D1, class D2, class D3,
+ class D4, class D5, class D6>
+ SliceInterval(const Base &baseDomain, const D1 &d1, const D2 &d2,
+ const D3 &d3, const D4 &d4, const D5 &d5, const D6 &d6)
+ : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > > (
+ Pooma::NoInit())
+ {
+ typedef NewDomain6<D1,D2,D3,D4,D5,D6> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SliceType_t;
+ PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
+ PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
+ NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4, d5, d6);
+ }
+ template <class Base, class D1, class D2, class D3,
+ class D4, class D5, class D6, class D7>
+ SliceInterval(const Base &baseDomain, const D1 &d1, const D2 &d2,
+ const D3 &d3, const D4 &d4, const D5 &d5, const D6 &d6,
+ const D7 &d7)
+ : SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > > (
+ Pooma::NoInit())
+ {
+ typedef NewDomain7<D1,D2,D3,D4,D5,D6,D7> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SliceType_t;
+ PoomaCTAssert<(DomainTraits<SliceType_t>::dimensions == Dim)>::test();
+ PoomaCTAssert<(DomainTraits<SliceType_t>::sliceDimensions == SliceDim)>::test();
+ NewDomain_t::fillSlice(*this, baseDomain, d1, d2, d3, d4, d5, d6, d7);
+ }
+ ~SliceInterval() { }
+ SliceInterval<Dim,SliceDim> &
+ operator=(const SliceInterval<Dim,SliceDim> &nd) {
+ SliceDomain<DomainTraits<SliceInterval<Dim,SliceDim> > >::operator=(nd);
+ return *this;
+ }
+ protected:
+ private:
+ };
+ struct DomainTag { };
+ template<int Dim>
+ class DomainLayout
+ {
+ public:
+ typedef DomainLayout<Dim> This_t;
+ typedef Interval<Dim> Domain_t;
+ typedef Node<Domain_t> Value_t;
+ typedef DynamicEvents::PatchID_t PatchID_t;
+ typedef DynamicEvents::CreateSize_t CreateSize_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ typedef Value_t *iterator;
+ typedef const Value_t *const_iterator;
+ enum { dimensions = Dim };
+ enum { dynamic = false };
+ inline DomainLayout()
+ {
+ }
+ explicit DomainLayout(const Domain_t &dom)
+ : node_m(0, dom, Pooma::context(), 0, 0)
+ {
+ }
+ DomainLayout(const Domain_t &dom, const GuardLayers_t &g)
+ : node_m(0, dom, grow(dom, g), Pooma::context(), 0, 0)
+ {
+ }
+ explicit DomainLayout(const Value_t &node)
+ : node_m(node)
+ {
+ }
+ DomainLayout(const This_t &layout)
+ : node_m(layout.node_m)
+ {
+ }
+ void initialize(const Domain_t &dom)
+ {
+ node_m = Value_t(0, dom, Pooma::context(), 0, 0);
+ }
+ void initialize(const Domain_t &dom, const GuardLayers_t &g)
+ {
+ node_m = Value_t(0, dom, grow(dom, g), Pooma::context(), 0, 0);
+ }
+ void initialize(const This_t &layout)
+ {
+ node_m = layout.node_m;
+ }
+ inline ~DomainLayout()
+ {
+ }
+ inline bool initialized() const
+ {
+ return domain().initialized();
+ }
+ inline int first(int d) const { return innerDomain()[d].first(); }
+ inline Value_t &node()
+ {
+ return node_m;
+ }
+ inline const Value_t &node() const
+ {
+ return node_m;
+ }
+ inline Loc<Dim> blocks() const { return Loc<Dim>(1); }
+ inline const Domain_t &domain() const
+ {
+ return node_m.allocated();
+ }
+ inline const Domain_t &innerDomain() const
+ {
+ return node_m.domain();
+ }
+ inline const Domain_t &allocated() const
+ {
+ return node_m.allocated();
+ }
+ inline GuardLayers_t internalGuards() const
+ {
+ return GuardLayers_t(0);
+ }
+ inline GuardLayers_t externalGuards() const
+ {
+ GuardLayers_t gl;
+ for (int i = 0; i < Dim; i++)
+ {
+ gl.lower(i) = node_m.domain()[i].min() - node_m.allocated()[i].min();
+ gl.upper(i) = node_m.allocated()[i].max() - node_m.domain()[i].max();
+ }
+ return gl;
+ }
+ inline const Domain_t &domain(int i) const
+ {
+ ;
+ return node_m.allocated();
+ }
+ inline const Domain_t &ownedDomain(int i) const
+ {
+ ;
+ return node_m.domain();
+ }
+ inline const Domain_t &allocatedDomain(int i) const
+ {
+ ;
+ return node_m.allocated();
+ }
+ template<class L>
+ inline bool operator==(const L &layout) const
+ {
+ return (domain() == layout.domain());
+ }
+ template<class L>
+ inline bool operator!=(const L &layout) const
+ {
+ return !(*this == layout);
+ }
+ inline iterator begin()
+ {
+ return &node_m;
+ }
+ inline iterator end()
+ {
+ return &node_m + 1;
+ }
+ inline const_iterator begin() const
+ {
+ return &node_m;
+ }
+ inline const_iterator end() const
+ {
+ return &node_m + 1;
+ }
+ inline long size() const
+ {
+ return 1;
+ }
+ inline iterator beginLocal()
+ {
+ return begin();
+ }
+ inline iterator endLocal()
+ {
+ return end();
+ }
+ inline const_iterator beginLocal() const
+ {
+ return begin();
+ }
+ inline const_iterator endLocal() const
+ {
+ return end();
+ }
+ inline long sizeLocal() const
+ {
+ return size();
+ }
+ inline iterator beginGlobal()
+ {
+ return begin();
+ }
+ inline iterator endGlobal()
+ {
+ return end();
+ }
+ inline const_iterator beginGlobal() const
+ {
+ return begin();
+ }
+ inline const_iterator endGlobal() const
+ {
+ return end();
+ }
+ inline long sizeGlobal() const
+ {
+ return size();
+ }
+ inline iterator beginRemote()
+ {
+ return iterator(0);
+ }
+ inline iterator endRemote()
+ {
+ return iterator(0);
+ }
+ inline const_iterator beginRemote() const
+ {
+ return const_iterator(0);
+ }
+ inline const_iterator endRemote() const
+ {
+ return const_iterator(0);
+ }
+ inline long sizeRemote() const
+ {
+ return 0;
+ }
+ inline int globalID(const Loc<Dim> &loc) const
+ {
+ ;
+ return 0;
+ }
+ inline int globalID(int i1) const
+ {
+ return globalID(Loc<1>(i1));
+ }
+ inline int globalID(int i1, int i2) const
+ {
+ return globalID(Loc<2>(i1, i2));
+ }
+ inline int globalID(int i1, int i2, int i3) const
+ {
+ return globalID(Loc<3>(i1, i2, i3));
+ }
+ inline int globalID(int i1, int i2, int i3, int i4) const
+ {
+ return globalID(Loc<4>(i1, i2, i3, i4));
+ }
+ inline int globalID(int i1, int i2, int i3, int i4, int i5) const
+ {
+ return globalID(Loc<5>(i1, i2, i3, i4, i5));
+ }
+ inline int globalID(int i1, int i2, int i3, int i4, int i5,
+ int i6) const
+ {
+ return globalID(Loc<6>(i1, i2, i3, i4, i5, i6));
+ }
+ inline int globalID(int i1, int i2, int i3, int i4, int i5,
+ int i6, int i7) const
+ {
+ return globalID(Loc<7>(i1, i2, i3, i4, i5, i6, i7));
+ }
+ template<class OtherDomain, class OutIter, class ConstructTag>
+ int touches(const OtherDomain &d, OutIter o, ConstructTag ctag) const;
+ template<class OtherDomain, class OutIter, class ConstructTag>
+ inline int touchesLocal(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const
+ {
+ return touches(d, o, ctag);
+ }
+ template<class OtherDomain, class OutIter, class ConstructTag>
+ inline int touchesRemote(const OtherDomain &, OutIter,
+ const ConstructTag &) const
+ {
+ return 0;
+ }
+ template<class OtherDomain, class OutIter>
+ inline int touches(const OtherDomain &d, OutIter o) const
+ {
+ return touches(d, o, TouchesConstructNodeObj());
+ }
+ template<class OtherDomain, class OutIter>
+ inline int touchesLocal(const OtherDomain &d, OutIter o) const
+ {
+ return touchesLocal(d, o, TouchesConstructNodeObj());
+ }
+ template<class OtherDomain, class OutIter>
+ inline int touchesRemote(const OtherDomain &d, OutIter o) const
+ {
+ return touchesRemote(d, o, TouchesConstructNodeObj());
+ }
+ template<class Out>
+ void print(Out &o) const
+ {
+ o << "DomainLayout: Node = " << node_m;
+ }
+ private:
+ Value_t node_m;
+ };
+ template<int Dim>
+ template<class OtherDomain, class OutIter, class ConstructTag>
+ int DomainLayout<Dim>::touches(const OtherDomain &d, OutIter o,
+ ConstructTag ctag) const
+ {
+ int i, count = 0;
+ typedef typename IntersectReturnType<Domain_t,OtherDomain>::Type_t
+ OutDomain_t;
+ typedef Node<OutDomain_t> OutNode_t;
+ OutDomain_t outDomain = intersect(d, domain());
+ if (!outDomain.empty())
+ {
+ ++count;
+ *o = touchesConstruct(outDomain,
+ node().affinity(),
+ node().context(),
+ node().globalID(),
+ node().localID(),
+ ctag);
+ }
+ return count;
+ }
+ template <int Dim>
+ std::ostream &operator<<(std::ostream &o, const DomainLayout<Dim> &layout)
+ {
+ layout.print(o);
+ return o;
+ }
+ template<int Dim>
+ struct NewDomain1< DomainLayout<Dim> >
+ {
+ typedef DomainLayout<Dim> &Type_t;
+ inline static Type_t combine(const DomainLayout<Dim> &a)
+ {
+ return const_cast<Type_t>(a);
+ }
+ };
+ namespace Pooma {
+ template <int Dim> class BrickViewBase;
+ template <int pos, int max>
+ struct OffsetCalc
+ {
+ template <class Dom>
+ static inline int apply(const Dom& dom, const int *strides_m)
+ {
+ return dom[pos].first()*strides_m[pos]
+ + OffsetCalc<pos+1,max>::apply(dom, strides_m);
+ }
+ };
+ template <int end>
+ struct OffsetCalc<end, end>
+ {
+ template <class Dom>
+ static inline int apply(const Dom& dom, const int *strides_m)
+ {
+ return dom[end].first()*strides_m[end];
+ }
+ };
+ template <>
+ struct OffsetCalc<1, 0>
+ {
+ template <class Dom>
+ static inline int apply(const Dom& dom, const int *strides_m)
+ {
+ return 0;
+ }
+ };
+ template <int Dim>
+ class BrickBase
+ {
+ public:
+ typedef Interval<Dim> Domain_t;
+ typedef DomainLayout<Dim> Layout_t;
+ typedef BrickBase<Dim> This_t;
+ enum { dimensions = Dim };
+ enum { brick = true };
+ enum { zeroBased = false };
+ explicit BrickBase(bool compressible = false)
+ : compressibleBase_m(compressible)
+ { }
+ explicit BrickBase(const Domain_t &dom, bool compressible = false)
+ : layout_m(dom), compressibleBase_m(compressible)
+ {
+ init();
+ }
+ explicit BrickBase(const Node<Domain_t> &node, bool compressible = false)
+ : layout_m(node), compressibleBase_m(compressible)
+ {
+ init();
+ }
+ explicit BrickBase(const Layout_t &layout, bool compressible = false)
+ : layout_m(layout), compressibleBase_m(compressible)
+ {
+ init();
+ }
+ ~BrickBase() {}
+ inline const Domain_t &domain() const { return layout_m.domain(); }
+ inline const Layout_t &layout() const { return layout_m; }
+ inline const int *strides() const { return &strides_m[0]; }
+ inline const int *originalStrides() const { return &ostrides_m[0]; }
+ int first(int i) const { return layout_m.domain()[i].first(); }
+ bool compressibleBase() const { return compressibleBase_m; }
+ template <class Domain>
+ inline int offset(const Domain &dom) const
+ { return off_m + offset0(dom); }
+ template <class Domain>
+ inline int offset0(const Domain &dom) const
+ {
+ PoomaCTAssert<(Domain::dimensions == Dim)>::test();
+ return dom[0].first() + OffsetCalc<1, Dim-1>::apply(dom, strides_m);
+ }
+ template <class Domain>
+ inline int offsetC(const Domain &dom) const
+ {
+ PoomaCTAssert<(Domain::dimensions == Dim)>::test();
+ return OffsetCalc<0, Dim-1>::apply(dom, strides_m);
+ }
+ inline int offset() const
+ { return off_m; }
+ inline int baseOffset() const
+ { return off_m; }
+ inline int offset(int i0) const
+ { return off_m + i0; }
+ inline int offset(int i0, int i1) const
+ { return off_m + i0 + i1*strides_m[1]; }
+ inline int offset(int i0, int i1, int i2) const
+ { return off_m + i0 + i1*strides_m[1] + i2*strides_m[2]; }
+ inline int offset(int i0, int i1, int i2, int i3) const
+ { return off_m + i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]; }
+ inline int offset(int i0, int i1, int i2, int i3, int i4) const
+ { return off_m + i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]
+ + i4*strides_m[4]; }
+ inline int offset(int i0, int i1, int i2, int i3, int i4, int i5) const
+ { return off_m + i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]
+ + i4*strides_m[4] + i5*strides_m[5]; }
+ inline int offset(int i0, int i1, int i2, int i3, int i4, int i5, int i6)
+ const
+ { return off_m + i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]
+ + i4*strides_m[4] + i5*strides_m[5] + i6*strides_m[6]; }
+ inline int offset0(int i0) const
+ { return i0; }
+ inline int offset0(int i0, int i1) const
+ { return i0 + i1*strides_m[1]; }
+ inline int offset0(int i0, int i1, int i2) const
+ { return i0 + i1*strides_m[1] + i2*strides_m[2]; }
+ inline int offset0(int i0, int i1, int i2, int i3) const
+ { return i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]; }
+ inline int offset0(int i0, int i1, int i2, int i3, int i4) const
+ { return i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]
+ + i4*strides_m[4]; }
+ inline int offset0(int i0, int i1, int i2, int i3, int i4, int i5) const
+ { return i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]
+ + i4*strides_m[4] + i5*strides_m[5]; }
+ inline int offset0(int i0, int i1, int i2, int i3, int i4, int i5, int i6)
+ const
+ { return i0 + i1*strides_m[1] + i2*strides_m[2] + i3*strides_m[3]
+ + i4*strides_m[4] + i5*strides_m[5] + i6*strides_m[6]; }
+ inline int offsetC(int i0) const
+ { return i0*strides_m[0]; }
+ inline int offsetC(int i0, int i1) const
+ { return i0*strides_m[0] + i1*strides_m[1]; }
+ inline int offsetC(int i0, int i1, int i2) const
+ { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]; }
+ inline int offsetC(int i0, int i1, int i2, int i3) const
+ { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
+ + i3*strides_m[3]; }
+ inline int offsetC(int i0, int i1, int i2, int i3, int i4) const
+ { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
+ + i3*strides_m[3] + i4*strides_m[4]; }
+ inline int offsetC(int i0, int i1, int i2, int i3, int i4, int i5) const
+ { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
+ + i3*strides_m[3] + i4*strides_m[4] + i5*strides_m[5]; }
+ inline int offsetC(int i0, int i1, int i2, int i3, int i4, int i5, int i6)
+ const
+ { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
+ + i3*strides_m[3] + i4*strides_m[4] + i5*strides_m[5]
+ + i6*strides_m[6]; }
+ protected:
+ void init()
+ {
+ strides_m[0] = 1;
+ ostrides_m[0] = 1;
+ off_m = -domain()[0].first();
+ for (int d = 1; d < Dim; ++d) {
+ strides_m[d] = strides_m[d-1]*domain()[d-1].length();
+ ostrides_m[d] = strides_m[d];
+ off_m -= domain()[d].first()*strides_m[d];
+ }
+ }
+ void zeroStrides()
+ { for (int d = 0; d < Dim; ++d) strides_m[d] = 0; }
+ void restoreStrides()
+ { for (int d = 0; d < Dim; ++d) strides_m[d] = ostrides_m[d]; }
+ Layout_t layout_m;
+ int strides_m[Dim];
+ int ostrides_m[Dim];
+ int off_m;
+ bool compressibleBase_m;
+ };
+ template <int Dim>
+ class BrickViewBase
+ {
+ public:
+ enum { dimensions = Dim };
+ enum { zeroBased = true };
+ typedef Interval<Dim> Domain_t;
+ typedef DomainLayout<Dim> Layout_t;
+ BrickViewBase() {}
+ typedef BrickViewBase<Dim> This_t;
+ BrickViewBase(const This_t &bvbase, bool compressible)
+ {
+ *this = bvbase;
+ compressibleBase_m = compressible;
+ if (!compressible) restoreStrides();
+ }
+ BrickViewBase(const BrickBase<Dim> &base, bool compressible)
+ {
+ *this = BrickViewBase<Dim>(base, base.domain());
+ compressibleBase_m = compressible;
+ if (!compressible) restoreStrides();
+ }
+ BrickViewBase(const BrickBase<Dim> &bbase, const Interval<Dim> &dom)
+ : domain_m(Pooma::NoInit()),
+ baseOffset_m(bbase.offset()),
+ compressibleBase_m(bbase.compressibleBase())
+ {
+ viewInit(bbase, dom);
+ }
+ BrickViewBase(const BrickBase<Dim> &bbase, const Range<Dim> &dom)
+ : domain_m(Pooma::NoInit()),
+ baseOffset_m(bbase.offset()),
+ compressibleBase_m(bbase.compressibleBase())
+ {
+ viewInit(bbase, dom);
+ }
+ BrickViewBase(const This_t &bvbase, const Interval<Dim> &domain)
+ : domain_m(Pooma::NoInit()),
+ baseOffset_m(bvbase.baseOffset()),
+ compressibleBase_m(bvbase.compressibleBase())
+ {
+ viewInit(bvbase, domain);
+ }
+ BrickViewBase(const This_t &bvbase, const Range<Dim> &domain)
+ : domain_m(Pooma::NoInit()),
+ baseOffset_m(bvbase.baseOffset()),
+ compressibleBase_m(bvbase.compressibleBase())
+ {
+ viewInit(bvbase, domain);
+ }
+ template<int BaseDim>
+ BrickViewBase(const BrickBase<BaseDim> &bbase,
+ const SliceRange<BaseDim,Dim> &dom)
+ : domain_m(Pooma::NoInit()),
+ baseOffset_m(bbase.offset()),
+ compressibleBase_m(bbase.compressibleBase())
+ {
+ sliceInit(bbase.originalStrides(), dom);
+ }
+ template<int BaseDim>
+ BrickViewBase(const BrickBase<BaseDim> &bbase,
+ const SliceInterval<BaseDim,Dim> &dom)
+ : domain_m(Pooma::NoInit()),
+ baseOffset_m(bbase.offset()),
+ compressibleBase_m(bbase.compressibleBase())
+ {
+ sliceInit(bbase.originalStrides(), SliceRange<BaseDim,Dim>(dom));
+ }
+ template<int SliceDim>
+ BrickViewBase(const BrickBase<SliceDim> &bbase,
+ const SliceInterval<Dim,SliceDim> &dom,
+ const Interval<Dim> &totalDomain)
+ : domain_m(Pooma::NoInit()),
+ baseOffset_m(bbase.offset()),
+ compressibleBase_m(bbase.compressibleBase())
+ {
+ sliceInit(bbase.originalStrides(), dom, totalDomain);
+ }
+ template<int SliceDim>
+ BrickViewBase(const BrickViewBase<SliceDim> &bvbase,
+ const SliceInterval<Dim,SliceDim> &dom,
+ const Interval<Dim> &totalDomain)
+ : domain_m(Pooma::NoInit()),
+ baseOffset_m(bvbase.baseOffset())
+ {
+ sliceInit(bvbase, dom, totalDomain);
+ }
+ template <int BaseDim>
+ BrickViewBase(const BrickViewBase<BaseDim> &bvbase,
+ const SliceRange<BaseDim,Dim> &dom)
+ : domain_m(Pooma::NoInit()),
+ baseOffset_m(bvbase.baseOffset())
+ {
+ sliceInit(bvbase, dom);
+ }
+ template <int BaseDim>
+ BrickViewBase(const BrickViewBase<BaseDim> &bvbase,
+ const SliceInterval<BaseDim,Dim> &dom)
+ : domain_m(Pooma::NoInit()),
+ baseOffset_m(bvbase.baseOffset())
+ {
+ sliceInit(bvbase, SliceRange<BaseDim,Dim>(dom));
+ }
+ ~BrickViewBase() {}
+ inline const Domain_t &domain() const { return domain_m; }
+ inline Layout_t layout() const { return Layout_t(domain_m); }
+ inline const int *strides() const { return &strides_m[0]; }
+ inline const int *originalStrides() const { return &ostrides_m[0]; }
+ inline int first(int) const { return 0; }
+ bool compressibleBase() const { return compressibleBase_m; }
+ int baseOffset() const { return baseOffset_m; }
+ template <class Domain>
+ inline int offset(const Domain &dom) const
+ {
+ PoomaCTAssert<(Domain::dimensions == Dim)>::test();
+ return OffsetCalc<0, Dim-1>::apply(dom, strides_m);
+ }
+ inline int offset(int i0) const
+ { return i0*strides_m[0]; }
+ inline int offset(int i0, int i1) const
+ { return i0*strides_m[0] + i1*strides_m[1]; }
+ inline int offset(int i0, int i1, int i2) const
+ { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]; }
+ inline int offset(int i0, int i1, int i2, int i3) const
+ { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
+ + i3*strides_m[3]; }
+ inline int offset(int i0, int i1, int i2, int i3, int i4) const
+ { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
+ + i3*strides_m[3] + i4*strides_m[4]; }
+ inline int offset(int i0, int i1, int i2, int i3, int i4, int i5) const
+ { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
+ + i3*strides_m[3] + i4*strides_m[4] + i5*strides_m[5]; }
+ inline int offset(int i0, int i1, int i2, int i3, int i4, int i5, int i6)
+ const
+ { return i0*strides_m[0] + i1*strides_m[1] + i2*strides_m[2]
+ + i3*strides_m[3] + i4*strides_m[4] + i5*strides_m[5]
+ + i6*strides_m[6]; }
+ template <class Domain>
+ inline int offsetU(const Domain &dom) const
+ {
+ PoomaCTAssert<(Domain::dimensions == Dim)>::test();
+ return dom[0].first() + OffsetCalc<1, Dim-1>::apply(dom, strides_m);
+ }
+ inline int offsetU(int i0) const
+ { return i0; }
+ inline int offsetU(int i0, int i1) const
+ { return i0 + i1*strides_m[1]; }
+ inline int offsetU(int i0, int i1, int i2) const
+ { return i0 + i1*strides_m[1] + i2*strides_m[2]; }
+ inline int offsetU(int i0, int i1, int i2, int i3) const
+ { return i0 + i1*strides_m[1] + i2*strides_m[2]
+ + i3*strides_m[3]; }
+ inline int offsetU(int i0, int i1, int i2, int i3, int i4) const
+ { return i0 + i1*strides_m[1] + i2*strides_m[2]
+ + i3*strides_m[3] + i4*strides_m[4]; }
+ inline int offsetU(int i0, int i1, int i2, int i3, int i4, int i5) const
+ { return i0 + i1*strides_m[1] + i2*strides_m[2]
+ + i3*strides_m[3] + i4*strides_m[4] + i5*strides_m[5]; }
+ inline int offsetU(int i0, int i1, int i2, int i3, int i4, int i5, int i6)
+ const
+ { return i0 + i1*strides_m[1] + i2*strides_m[2]
+ + i3*strides_m[3] + i4*strides_m[4] + i5*strides_m[5]
+ + i6*strides_m[6]; }
+ protected:
+ void zeroStrides()
+ { for (int d = 0; d < Dim; ++d) strides_m[d] = 0; }
+ void restoreStrides()
+ { for (int d = 0; d < Dim; ++d) strides_m[d] = ostrides_m[d]; }
+ template<int BaseDim>
+ void sliceInit(const int *baseStrides,
+ const SliceRange<BaseDim,Dim> &dom);
+ template<int SliceDim>
+ void sliceInit(const int *baseStrides,
+ const SliceInterval<Dim,SliceDim> &dom,
+ const Interval<Dim> &totalDomain);
+ template<int BaseDim>
+ void sliceInit(const BrickViewBase<BaseDim>&, const SliceRange<BaseDim, Dim>&);
+ template<int SliceDim>
+ void sliceInit(const BrickViewBase<SliceDim>&, const SliceInterval<Dim, SliceDim>&,
+ const Interval<Dim> &totalDomain);
+ void viewInit(const This_t &, const Range<Dim> &domain);
+ void viewInit(const BrickBase<Dim> &bbase, const Range<Dim> &domain);
+ void viewInit(const This_t &bvbase, const Interval<Dim> &domain)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ domain_m[d] = Interval<1>(domain[d].length());
+ strides_m[d] = bvbase.ostrides_m[d];
+ ostrides_m[d] = strides_m[d];
+ baseOffset_m += domain[d].first() * bvbase.ostrides_m[d];
+ }
+ }
+ void viewInit(const BrickBase<Dim> &bbase, const Interval<Dim> &domain)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ domain_m[d] = Interval<1>(domain[d].length());
+ strides_m[d] = bbase.originalStrides()[d];
+ ostrides_m[d] = strides_m[d];
+ baseOffset_m += domain[d].first() * bbase.originalStrides()[d];
+ }
+ }
+ Domain_t domain_m;
+ int strides_m[Dim];
+ int ostrides_m[Dim];
+ int baseOffset_m;
+ bool compressibleBase_m;
+ };
+ template <int Dim>
+ void
+ BrickViewBase<Dim>::
+ viewInit(const This_t &bvbase, const Range<Dim> &domain)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ domain_m[d] = Interval<1>(domain[d].length());
+ strides_m[d] = bvbase.ostrides_m[d] * domain[d].stride();
+ baseOffset_m += domain[d].first() * bvbase.ostrides_m[d];
+ }
+ for (int d = 0; d < Dim; ++d)
+ ostrides_m[d] = strides_m[d];
+ }
+ template <int Dim>
+ void
+ BrickViewBase<Dim>::
+ viewInit(const BrickBase<Dim> &bbase, const Range<Dim> &domain)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ domain_m[d] = Interval<1>(domain[d].length());
+ strides_m[d] = bbase.originalStrides()[d] * domain[d].stride();
+ ostrides_m[d] = strides_m[d];
+ baseOffset_m += domain[d].first() * bbase.originalStrides()[d];
+ }
+ }
+ template <int Dim>
+ template<int BaseDim>
+ void
+ BrickViewBase<Dim>::
+ sliceInit(const int *baseStrides,
+ const SliceRange<BaseDim,Dim> &dom)
+ {
+ typedef typename SliceRange<BaseDim,Dim>::TotalDomain_t TotalDomain_t;
+ const TotalDomain_t &domain = dom.totalDomain();
+ int d = 0;
+ for (int dt = 0; dt < BaseDim; ++dt)
+ {
+ if (!dom.ignorable(dt))
+ {
+ ;
+ domain_m[d] = Interval<1>(domain[dt].length());
+ strides_m[d] = baseStrides[dt] * domain[dt].stride();
+ ++d;
+ }
+ baseOffset_m += domain[dt].first() * baseStrides[dt];
+ }
+ ;
+ for (int d = 0; d < Dim; ++d)
+ ostrides_m[d] = strides_m[d];
+ }
+ template <int Dim>
+ template<int SliceDim>
+ void
+ BrickViewBase<Dim>::
+ sliceInit(const int *baseStrides,
+ const SliceInterval<Dim,SliceDim> &dom,
+ const Interval<Dim> &domain)
+ {
+ int dt = 0;
+ for (int d = 0; d < Dim; ++d)
+ {
+ domain_m[d] = Interval<1>(domain[d].length());
+ if (!dom.ignorable(d))
+ {
+ ;
+ strides_m[d] = baseStrides[dt];
+ baseOffset_m += domain[dt].first() * baseStrides[dt];
+ ++dt;
+ } else {
+ strides_m[d] = 0;
+ }
+ }
+ ;
+ for (int d = 0; d < Dim; ++d)
+ ostrides_m[d] = strides_m[d];
+ }
+ template <int Dim>
+ template<int SliceDim>
+ void
+ BrickViewBase<Dim>::
+ sliceInit(const BrickViewBase<SliceDim>& bvbase,
+ const SliceInterval<Dim,SliceDim> &dom,
+ const Interval<Dim> &domain)
+ {
+ int dt = 0;
+ for (int d = 0; d < Dim; ++d)
+ {
+ domain_m[d] = Interval<1>(domain[d].length());
+ if (!dom.ignorable(d))
+ {
+ ;
+ strides_m[d] = bvbase.originalStrides()[dt];
+ baseOffset_m += domain[dt].first() * bvbase.originalStrides()[dt];
+ ++dt;
+ } else {
+ strides_m[d] = 0;
+ }
+ }
+ ;
+ for (int d = 0; d < Dim; ++d)
+ ostrides_m[d] = strides_m[d];
+ }
+ template <int Dim>
+ template<int BaseDim>
+ void
+ BrickViewBase<Dim>::
+ sliceInit(const BrickViewBase<BaseDim>& bvbase, const SliceRange<BaseDim, Dim>& dom)
+ {
+ typedef typename SliceRange<BaseDim,Dim>::TotalDomain_t TotalDomain_t;
+ const TotalDomain_t &totDomain = dom.totalDomain();
+ int d, dt;
+ for (dt = 0, d = 0; dt < BaseDim; ++dt)
+ {
+ if (!dom.ignorable(dt))
+ {
+ ;
+ domain_m[d] = Interval<1>(totDomain[dt].length());
+ strides_m[d] = bvbase.originalStrides()[dt] * totDomain[dt].stride();
+ ++d;
+ }
+ baseOffset_m += totDomain[dt].first() * bvbase.originalStrides()[dt];
+ }
+ ;
+ for (int d = 0; d < Dim; ++d)
+ ostrides_m[d] = strides_m[d];
+ }
+ }
+ class Inform;
+ namespace Pooma {
+ class StatisticsData
+ {
+ friend class Statistics;
+ public:
+ const std::string &description() const { return data_m.first; }
+ long value() const { return data_m.second; }
+ void increment(long val = 1) { data_m.second += val; }
+ private:
+ StatisticsData(const char *description, long initialValue = 0)
+ : data_m(description, initialValue)
+ { }
+ ~StatisticsData() { }
+ std::pair<std::string, long> data_m;
+ };
+ class Statistics {
+ private:
+ static long defaultFilter(long val);
+ public:
+ Statistics();
+ ~Statistics();
+ void print(Inform &, long (*filter)(long) = defaultFilter);
+ StatisticsData *add(const char *description, long initval = 0)
+ {
+ StatisticsData *sd = new StatisticsData(description, initval);
+ statList_m.push_back(sd);
+ return sd;
+ }
+ private:
+ std::vector<StatisticsData *> statList_m;
+ };
+ }
+ template <class T> class SingleObserver;
+ template <class T>
+ class CompressibleBlock
+ {
+ public:
+ typedef CompressibleBlock<T> This_t;
+ typedef T Element_t;
+ typedef Pooma::DataObject_t DataObject_t;
+ enum Notifier
+ {
+ notifyDestruct = 0,
+ notifyUncompress = 1,
+ notifyCompress = 2
+ };
+ CompressibleBlock()
+ : controller_m(0)
+ { }
+ explicit CompressibleBlock(int size)
+ : controller_m(new CompressibleBlockController(size))
+ { }
+ CompressibleBlock(int size, int affinity)
+ : controller_m(new CompressibleBlockController(size,affinity))
+ { }
+ CompressibleBlock(int size, int affinity, const T& model)
+ : controller_m(new CompressibleBlockController(size,affinity,model))
+ { }
+ CompressibleBlock(const CompressibleBlock &block)
+ : controller_m(block.controller_m)
+ { }
+ ~CompressibleBlock()
+ {
+ ;
+ }
+ inline int size() const
+ {
+ return controller_m.size();
+ }
+ inline int capacity() const
+ {
+ return controller_m.capacity();
+ }
+ inline bool resize(int newsize,
+ const typename DataBlockPtr<T>::NoInitTag &)
+ {
+ return controller_m->resize(newsize,DataBlockPtr<T>::NoInitTag());
+ }
+ inline void setSize(int newsize)
+ {
+ controller_m->setSize(newsize);
+ }
+ inline DataObject_t* dataObject() const
+ {
+ ;
+ return controller_m->dataObject();
+ }
+ inline int affinity() const
+ {
+ ;
+ return controller_m->dataObject()->affinity();
+ }
+ inline bool compressed() const
+ {
+ ;
+ return controller_m->compressed();
+ }
+ inline T* data()
+ {
+ ;
+ return controller_m->data();
+ }
+ inline void uncompress() const
+ {
+ ;
+ controller_m->uncompress();
+ }
+ void tryCompress()
+ {
+ ;
+ controller_m->tryCompress();
+ }
+ inline DataBlockPtr<T> view() const
+ {
+ ;
+ return controller_m->view();
+ };
+ DataBlockPtr<T> dataBlock() const
+ {
+ ;
+ return controller_m->dataBlock();
+ }
+ void makeOwnCopy()
+ {
+ controller_m.makeOwnCopy();
+ }
+ void invalidate()
+ {
+ controller_m.invalidate();
+ }
+ inline bool isControllerPtrValid() const
+ {
+ return controller_m.isValid();
+ }
+ inline bool isControllerValid() const
+ {
+ return controller_m.isValid() && controller_m->isValid();
+ }
+ inline bool isControllerValidUnlocked() const
+ {
+ return controller_m.isValid() && controller_m->isValidUnlocked();
+ }
+ inline bool isShared() const
+ {
+ return controller_m.isShared();
+ }
+ bool operator!=(const This_t& a) const
+ {
+ return controller_m != a.controller_m;
+ }
+ bool operator==(const This_t& a) const
+ {
+ return controller_m == a.controller_m;
+ }
+ void attach(Observer<T*> *o)
+ {
+ ;
+ controller_m->attach(o);
+ }
+ void detach(Observer<T*> *o)
+ {
+ ;
+ controller_m->detach(o);
+ }
+ void lock() const
+ {
+ controller_m->lock();
+ }
+ void unlock() const
+ {
+ controller_m->unlock();
+ }
+ static int randomTries() { return CompressibleBlockController::randomTries(); }
+ private:
+ class CompressibleBlockController
+ : public SingleObserver<int>,
+ public Observable<T*>,
+ public RefCounted
+ {
+ public:
+ typedef CompressibleBlockController This_t;
+ typedef T Element_t;
+ typedef Pooma::DataObject_t DataObject_t;
+ CompressibleBlockController()
+ : Observable<T*>(ptr_m),
+ size_m(0),
+ compressible_m(true),
+ ptr_m(0),
+ dataObject_m(-1),
+ ucOffset_m(-1),
+ viewcount_m(0),
+ countUncompressed_m(0)
+ {
+ ElementProperties<T>::construct(&compressedData_m);
+ if (Pooma::neverCompress())
+ {
+ compressible_m = false;
+ }
+ }
+ explicit
+ CompressibleBlockController(int size)
+ : Observable<T*>(ptr_m),
+ compressible_m(true),
+ countUncompressed_m(0),
+ viewcount_m(0),
+ dataObject_m(-1),
+ size_m(size),
+ ptr_m(&compressedData_m),
+ ucOffset_m(-1)
+ {
+ ElementProperties<T>::construct(&compressedData_m);
+ if (Pooma::neverCompress())
+ {
+ viewcount_m = 1;
+ compressible_m = false;
+ countUncompressed_m = 1;
+ block_m = DataBlockPtr<T>(size_m,dataObject_m);
+ ptr_m = block_m.currentPointer();
+ block_m.attach(this);
+ }
+ }
+ CompressibleBlockController(int size, int affinity)
+ : Observable<T*>(ptr_m),
+ compressible_m(true),
+ countUncompressed_m(0),
+ viewcount_m(0),
+ dataObject_m(affinity),
+ size_m(size),
+ ptr_m(&compressedData_m),
+ ucOffset_m(-1)
+ {
+ ElementProperties<T>::construct(&compressedData_m);
+ if (Pooma::neverCompress())
+ {
+ viewcount_m = 1;
+ compressible_m = false;
+ countUncompressed_m = 1;
+ block_m = DataBlockPtr<T>(size_m,dataObject_m);
+ ptr_m = block_m.currentPointer();
+ block_m.attach(this);
+ }
+ }
+ CompressibleBlockController(int size, int affinity, const T& value)
+ : Observable<T*>(ptr_m),
+ compressible_m(true),
+ countUncompressed_m(0),
+ viewcount_m(0),
+ dataObject_m(affinity),
+ size_m(size),
+ ptr_m(&compressedData_m),
+ ucOffset_m(-1)
+ {
+ ElementProperties<T>::construct(&compressedData_m,value);
+ if (Pooma::neverCompress())
+ {
+ viewcount_m = 1;
+ compressible_m = false;
+ countUncompressed_m = 1;
+ block_m = DataBlockPtr<T>(size_m,value,dataObject_m);
+ ptr_m = block_m.currentPointer();
+ block_m.attach(this);
+ }
+ }
+ CompressibleBlockController(const CompressibleBlockController& model)
+ : Observable<T*>(ptr_m),
+ compressible_m(!Pooma::neverCompress()),
+ viewcount_m(0),
+ dataObject_m(model.dataObject_m.affinity()),
+ size_m(model.size_m),
+ ucOffset_m(model.ucOffset_m)
+ {
+ model.lock();
+ bool modelCompressed = model.compressed();
+ compressedData_m = model.compressedData_m;
+ block_m = model.block_m;
+ if (!modelCompressed)
+ {
+ --model.viewcount_m;
+ }
+ model.unlock();
+ if (modelCompressed)
+ {
+ ;
+ ptr_m = &compressedData_m;
+ countUncompressed_m = 0;
+ }
+ else
+ {
+ block_m.makeOwnCopy();
+ ptr_m = block_m.currentPointer();
+ block_m.dataObject(&dataObject_m);
+ countUncompressed_m = 1;
+ ++viewcount_m;
+ block_m.attach(this);
+ }
+ ;
+ }
+ ~CompressibleBlockController()
+ {
+ ;
+ ;
+ ;
+ if (!compressed())
+ {
+ block_m.detach();
+ }
+ }
+ inline size_t size() const
+ {
+ return block_m.size();
+ }
+ inline size_t capacity() const
+ {
+ return block_m.capacity();
+ }
+ inline void setSize(size_t size)
+ {
+ size_m = size;
+ }
+ inline bool resize(size_t newsize,
+ const typename DataBlockPtr<T>::NoInitTag &)
+ {
+ ;
+ if (block_m.capacity() >= newsize)
+ {
+ block_m.resize(newsize, DataBlockPtr<T>::NoInitTag());
+ size_m = block_m.size();
+ }
+ else
+ {
+ size_t nsize = newsize * sizeof(T);
+ size_t n_ext = nsize/sizeof(T);
+ DataBlockPtr<T> newdata(n_ext,dataObject_m);
+ newdata.resize(newsize, DataBlockPtr<T>::NoInitTag());
+ T * pOld = block_m.beginPointer();
+ T * pNew = newdata.beginPointer();
+ const T * const pEnd = pNew + block_m.size();
+ while (pNew != pEnd)
+ {
+ ElementProperties<T>::construct(pNew++,*pOld++);
+ }
+ block_m = newdata;
+ ptr_m = block_m.currentPointer();
+ size_m = newsize;
+ }
+ return true;
+ }
+ inline void uncompress()
+ {
+ lock();
+ uncompressUnlocked();
+ unlock();
+ }
+ void uncompressUnlocked()
+ {
+ if (compressed())
+ {
+ ;
+ ;
+ ++countUncompressed_m;
+ block_m = DataBlockPtr<T>(size_m,dataObject_m);
+ ++viewcount_m;
+ ;
+ ptr_m = block_m.currentPointer();
+ block_m.attach(this);
+ T *ptr = block_m.beginPointer();
+ const T *const end = block_m.endPointer();
+ while (ptr != end)
+ {
+ ElementProperties<T>::construct(ptr++,compressedData_m);
+ }
+ Observable<T*>::notify(notifyUncompress);
+ ;
+ }
+ }
+ inline void tryCompress()
+ {
+ if (!Pooma::neverCompress())
+ {
+ lock();
+ tryCompressUnlocked();
+ unlock();
+ }
+ }
+ void tryCompressUnlocked()
+ {
+ if (!compressed() && compressible_m && !Pooma::neverCompress())
+ {
+ ;
+ int size = block_m.size();
+ bool failed = false;
+ ;
+ if (ucOffset_m > -1 && ucOffset_m < size)
+ {
+ if (block_m[ucOffset_m] != block_m[0]) failed = true;
+ }
+ if (!failed)
+ {
+ for (int i = 0; i < randomTries(); ++i)
+ {
+ int elem = rand() % size;
+ if (block_m[elem] != block_m[0])
+ {
+ failed = true;
+ ucOffset_m = elem;
+ break;
+ }
+ }
+ }
+ if (!failed)
+ {
+ const T *const begin = block_m.beginPointer();
+ const T *const end = block_m.endPointer();
+ const T * ptr;
+ for (ptr = begin; ptr != end; ++ptr)
+ {
+ if (*ptr != *begin) break;
+ }
+ if (ptr == end)
+ {
+ block_m.detach();
+ block_m.invalidate();
+ --viewcount_m;
+ ;
+ compressedData_m = *begin;
+ ptr_m = &compressedData_m;
+ Observable<T*>::notify(notifyCompress);
+ ;
+ return;
+ }
+ else
+ {
+ ucOffset_m = ptr - begin;
+ }
+ }
+ ;
+ }
+ }
+ DataBlockPtr<T> view()
+ {
+ lock();
+ if (compressed())
+ {
+ uncompressUnlocked();
+ }
+ compressible_m = false;
+ unlock();
+ return block_m;
+ }
+ DataBlockPtr<T> dataBlock()
+ {
+ return block_m;
+ }
+ inline T* data()
+ {
+ return ptr_m;
+ }
+ bool compressed() const
+ {
+ return ptr_m == &compressedData_m;
+ }
+ DataObject_t* dataObject()
+ {
+ return &dataObject_m;
+ }
+ void lock() const
+ {
+ mutex_m.lock();
+ }
+ void unlock() const
+ {
+ mutex_m.unlock();
+ }
+ bool isValidUnlocked()
+ {
+ return compressed() || block_m.isValid();
+ }
+ bool isValid()
+ {
+ lock();
+ bool valid = isValidUnlocked();
+ unlock();
+ return valid;
+ }
+ static int randomTries() { return randomTries_s; }
+ private:
+ virtual void notify(const int& , const ObserverEvent &event)
+ {
+ switch (event.event())
+ {
+ case DataBlockController<T>::addViewEvent:
+ viewmutex_m.lock();
+ ++viewcount_m;
+ viewmutex_m.unlock();
+ break;
+ case DataBlockController<T>::removeViewEvent:
+ viewmutex_m.lock();
+ --viewcount_m;
+ if (viewcount_m == 1 && !Pooma::neverCompress())
+ {
+ lock();
+ compressible_m = true;
+ tryCompressUnlocked();
+ unlock();
+ }
+ viewmutex_m.unlock();
+ break;
+ default:
+ if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("Invalid event code sent to CompressibleBlockController::notify()", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Engine/CompressibleBlock.h", 954);
+ }
+ }
+ bool compressible_m;
+ int countUncompressed_m;
+ DataBlockPtr<T> block_m;
+ mutable int viewcount_m;
+ mutable Pooma::Mutex_t viewmutex_m;
+ DataObject_t dataObject_m;
+ int size_m;
+ T compressedData_m;
+ T *ptr_m;
+ int ucOffset_m;
+ mutable Pooma::Mutex_t mutex_m;
+ enum { randomTries_s = 20 };
+ };
+ RefCountedPtr<CompressibleBlockController> controller_m;
+ };
+ struct CompressibleBrick { };
+ struct CompressibleBrickView { };
+ template <int Dim, class T>
+ class Engine<Dim, T, CompressibleBrickView>;
+ template <int D1, int D2> class SliceInterval;
+ template <int D1, int D2> class SliceRange;
+ template <int Dim, class T>
+ class Engine<Dim, T, CompressibleBrick>
+ : public Pooma::BrickBase<Dim>, public Observer<T*>
+ {
+ public:
+ typedef Engine<Dim,T,CompressibleBrick> This_t;
+ typedef Engine<Dim,T,CompressibleBrick> Engine_t;
+ typedef Pooma::BrickBase<Dim> Base_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef DomainLayout<Dim> Layout_t;
+ typedef T Element_t;
+ typedef T& ElementRef_t;
+ typedef CompressibleBrick Tag_t;
+ enum { brick = true };
+ enum { dimensions = Dim };
+ enum { hasDataObject = true };
+ enum { dynamic = false };
+ enum { zeroBased = false };
+ enum { multiPatch = false };
+ Engine() : data0_m(0) { }
+ explicit Engine(const Domain_t &domain);
+ Engine(const Domain_t &domain, const T &elementModel);
+ explicit Engine(const Layout_t &layout);
+ explicit Engine(const Node<Domain_t> &node);
+ Engine(const Engine_t &model);
+ ~Engine();
+ Engine_t &operator=(const Engine_t &model);
+ ElementRef_t operator()(int) const;
+ ElementRef_t operator()(int, int) const;
+ ElementRef_t operator()(int, int, int) const;
+ ElementRef_t operator()(int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int, int, int) const;
+ Element_t read(int) const;
+ Element_t read(int, int) const;
+ Element_t read(int, int, int) const;
+ Element_t read(int, int, int, int) const;
+ Element_t read(int, int, int, int, int) const;
+ Element_t read(int, int, int, int, int, int) const;
+ Element_t read(int, int, int, int, int, int, int) const;
+ ElementRef_t operator()(const Loc<Dim> &) const;
+ Element_t read(const Loc<Dim> &) const;
+ inline const Domain_t &domain() const
+ {
+ return this->layout_m.domain();
+ }
+ Engine_t &makeOwnCopy();
+ Pooma::DataObject_t *dataObject() const { return cblock_m.dataObject(); }
+ DataBlockPtr<T> dataBlock() const { return cblock_m.view(); }
+ CompressibleBlock<T> cblock() const { return cblock_m; }
+ bool compressed() const;
+ long elementsCompressed() const;
+ void tryCompress() { cblock_m.tryCompress(); }
+ void uncompress() { cblock_m.uncompress(); }
+ T compressedRead() const;
+ T& compressedReadWrite() const;
+ bool compressedBrickIsWholeView() const { return true; }
+ private:
+ CompressibleBlock<T> cblock_m;
+ T *data0_m;
+ mutable Pooma::Mutex_t mutex_m;
+ inline void lock() const { mutex_m.lock(); }
+ inline void unlock() const { mutex_m.unlock(); }
+ virtual void notify(T* &data, const ObserverEvent &event);
+ void resetDataAndStrides();
+ void init();
+ };
+ template <int Dim, class T>
+ class Engine<Dim,T,CompressibleBrickView>
+ : public Pooma::BrickViewBase<Dim>, public Observer<T*>
+ {
+ public:
+ typedef Engine<Dim,T,CompressibleBrickView> This_t;
+ typedef Engine<Dim,T,CompressibleBrickView> Engine_t;
+ typedef Pooma::BrickViewBase<Dim> Base_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef DomainLayout<Dim> Layout_t;
+ typedef T Element_t;
+ typedef T& ElementRef_t;
+ typedef CompressibleBrickView Tag_t;
+ enum { dimensions = Dim };
+ enum { hasDataObject = true };
+ enum { dynamic = false };
+ enum { zeroBased = true };
+ enum { multiPatch = false };
+ Engine() : data0_m(0) { }
+ Engine(const Engine_t &model);
+ Engine(const Engine_t &model, const EngineConstructTag &);
+ template <class DT>
+ Engine(const Engine<Dim,T,CompressibleBrick> &e, const Domain<Dim, DT> &dom)
+ : Base_t(e, dom.unwrap()), cblock_m(e.cblock()),
+ entire_m(e.domain() == dom.unwrap())
+ {
+ init();
+ }
+ template <class Domain>
+ Engine(const Engine<Dim,T,CompressibleBrick> &e, const Node<Domain> &node)
+ : Base_t(e, node.domain()), cblock_m(e.cblock()),
+ entire_m(e.domain() == node.domain())
+ {
+ init();
+ }
+ Engine(const Engine<Dim,T,CompressibleBrick> &e, const INode<Dim> &inode)
+ : Base_t(e, inode.domain()), cblock_m(e.cblock()),
+ entire_m(e.domain() == inode.domain())
+ {
+ init();
+ }
+ template <class DT, int Dim2>
+ Engine(const Engine<Dim2,T,CompressibleBrick> &e, const SliceDomain<DT> &dom)
+ : Base_t(e, dom.unwrap()), cblock_m(e.cblock()),
+ entire_m(e.domain() == dom.totalDomain())
+ {
+ init();
+ }
+ template <class DT>
+ Engine(const This_t &e, const Domain<Dim, DT> &dom)
+ : Base_t(e, dom.unwrap()), cblock_m(e.cblock()),
+ entire_m(e.entire_m && e.domain() == dom.unwrap())
+ {
+ init();
+ }
+ Engine(const This_t &e, const INode<Dim> &inode)
+ : Base_t(e, inode.domain()), cblock_m(e.cblock()),
+ entire_m(e.entire_m && e.domain() == inode.domain())
+ {
+ init();
+ }
+ template <int OrigDim, class DT>
+ Engine(const Engine<OrigDim,T,CompressibleBrickView> &e,
+ const SliceDomain<DT> &dom)
+ : Base_t(e, dom.unwrap()), cblock_m(e.cblock()),
+ entire_m(e.entire_m && e.domain() == dom.totalDomain())
+ {
+ init();
+ }
+ ~Engine();
+ Engine_t &operator=(const Engine_t &model);
+ ElementRef_t operator()(int) const;
+ ElementRef_t operator()(int, int) const;
+ ElementRef_t operator()(int, int, int) const;
+ ElementRef_t operator()(int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int, int, int) const;
+ Element_t read(int) const;
+ Element_t read(int, int) const;
+ Element_t read(int, int, int) const;
+ Element_t read(int, int, int, int) const;
+ Element_t read(int, int, int, int, int) const;
+ Element_t read(int, int, int, int, int, int) const;
+ Element_t read(int, int, int, int, int, int, int) const;
+ ElementRef_t operator()(const Loc<Dim> &) const;
+ Element_t read(const Loc<Dim> &) const;
+ inline const Domain_t &domain() const
+ {
+ return this->domain_m;
+ }
+ DataBlockPtr<T> dataBlock() const { return cblock_m.view(); }
+ inline
+ Pooma::DataObject_t *dataObject() const { return cblock_m.dataObject(); }
+ CompressibleBlock<T> cblock() const { return cblock_m; }
+ bool compressed() const { return cblock_m.compressed(); }
+ T compressedRead() const;
+ T& compressedReadWrite() const;
+ bool compressedBrickIsWholeView() const { return entire_m; }
+ long elementsCompressed() const;
+ private:
+ void lock() const { mutex_m.lock(); }
+ void unlock() const { mutex_m.unlock(); }
+ virtual void notify(T* &data, const ObserverEvent &event)
+ {
+ switch (event.event())
+ {
+ default:
+ case CompressibleBlock<T>::notifyDestruct:
+ ;
+ break;
+ case CompressibleBlock<T>::notifyUncompress:
+ lock();
+ this->restoreStrides();
+ data0_m = data + this->baseOffset();
+ unlock();
+ break;
+ case CompressibleBlock<T>::notifyCompress:
+ lock();
+ this->zeroStrides();
+ data0_m = data;
+ unlock();
+ break;
+ }
+ }
+ void init()
+ {
+ cblock_m.lock();
+ resetDataAndStrides();
+ ;
+ cblock_m.attach(this);
+ cblock_m.unlock();
+ }
+ void resetDataAndStrides()
+ {
+ if (cblock_m.compressed())
+ {
+ this->zeroStrides();
+ data0_m = cblock_m.data();
+ }
+ else
+ {
+ this->restoreStrides();
+ data0_m = cblock_m.data() + this->baseOffset();
+ }
+ }
+ CompressibleBlock<T> cblock_m;
+ T *data0_m;
+ bool entire_m;
+ mutable Pooma::Mutex_t mutex_m;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,CompressibleBrick>, Interval<Dim> >
+ {
+ typedef Engine<Dim,T,CompressibleBrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,CompressibleBrick>, Range<Dim> >
+ {
+ typedef Engine<Dim,T,CompressibleBrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,CompressibleBrick>,Node<Interval<Dim> > >
+ {
+ typedef Engine<Dim,T,CompressibleBrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,CompressibleBrick>,INode<Dim> >
+ {
+ typedef Engine<Dim,T,CompressibleBrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,CompressibleBrickView>, Interval<Dim> >
+ {
+ typedef Engine<Dim,T,CompressibleBrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,CompressibleBrickView>, Range<Dim> >
+ {
+ typedef Engine<Dim,T,CompressibleBrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,CompressibleBrickView>,
+ Node<Interval<Dim> > >
+ {
+ typedef Engine<Dim,T,CompressibleBrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,CompressibleBrickView>,INode<Dim> >
+ {
+ typedef Engine<Dim,T,CompressibleBrickView> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<Dim,T,CompressibleBrick>,SliceInterval<Dim,SliceDim> >
+ {
+ typedef Engine<SliceDim,T,CompressibleBrickView> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<Dim,T,CompressibleBrick>,SliceRange<Dim,SliceDim> >
+ {
+ typedef Engine<SliceDim,T,CompressibleBrickView> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<Dim,T,CompressibleBrickView>,
+ SliceInterval<Dim,SliceDim> >
+ {
+ typedef Engine<SliceDim,T,CompressibleBrickView> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<Dim,T,CompressibleBrickView>,
+ SliceRange<Dim,SliceDim> >
+ {
+ typedef Engine<SliceDim,T,CompressibleBrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct ElementProperties<Engine<Dim, T, CompressibleBrick> >
+ : public MakeOwnCopyProperties<Engine<Dim, T, CompressibleBrick> >
+ { };
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrick>::
+ read(const Loc<Dim> &loc) const
+ {
+ return data0_m[this->offsetC(loc)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrick>::
+ read(int i1) const
+ {
+ ;
+ return data0_m[this->offsetC(i1)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrick>::
+ read(int i1, int i2) const
+ {
+ ;
+ return data0_m[this->offsetC(i1,i2)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrick>::
+ read(int i1, int i2, int i3) const
+ {
+ ;
+ return data0_m[this->offsetC(i1,i2,i3)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrick>::
+ read(int i1, int i2, int i3, int i4) const
+ {
+ ;
+ return data0_m[this->offsetC(i1,i2,i3,i4)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrick>::
+ read(int i1, int i2, int i3, int i4, int i5) const
+ {
+ ;
+ return data0_m[this->offsetC(i1,i2,i3,i4,i5)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrick>::
+ read(int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ ;
+ return data0_m[this->offsetC(i1,i2,i3,i4,i5,i6)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrick>::
+ read(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
+ {
+ ;
+ return data0_m[this->offsetC(i1,i2,i3,i4,i5,i6,i7)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrick>::
+ operator()(const Loc<Dim> &loc) const
+ {
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offsetC(loc)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrick>::
+ operator()(int i1) const
+ {
+ ;
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offsetC(i1)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrick>::
+ operator()(int i1, int i2) const
+ {
+ ;
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offsetC(i1,i2)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrick>::
+ operator()(int i1, int i2, int i3) const
+ {
+ ;
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offsetC(i1,i2,i3)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrick>::
+ operator()(int i1, int i2, int i3, int i4) const
+ {
+ ;
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offsetC(i1,i2,i3,i4)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrick>::
+ operator()(int i1, int i2, int i3, int i4, int i5) const
+ {
+ ;
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offsetC(i1,i2,i3,i4,i5)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrick>::
+ operator()(int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ ;
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offsetC(i1,i2,i3,i4,i5,i6)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrick>::
+ operator()(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
+ {
+ ;
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offsetC(i1,i2,i3,i4,i5,i6,i7)];
+ }
+ template <int Dim, class T>
+ inline bool
+ Engine<Dim,T,CompressibleBrick>::
+ compressed() const
+ {
+ ;
+ return cblock_m.compressed();
+ }
+ template <int Dim, class T>
+ inline T
+ Engine<Dim,T,CompressibleBrick>::
+ compressedRead() const
+ {
+ ;
+ ;
+ return *data0_m;
+ }
+ template <int Dim, class T>
+ inline T&
+ Engine<Dim,T,CompressibleBrick>::
+ compressedReadWrite() const
+ {
+ ;
+ ;
+ return *data0_m;
+ }
+ template <int Dim, class T>
+ inline bool compressed(const Engine<Dim, T, CompressibleBrick> &e)
+ {
+ return e.compressed();
+ }
+ template <int Dim, class T>
+ inline long elementsCompressed(const Engine<Dim, T, CompressibleBrick> &e)
+ {
+ return e.elementsCompressed();
+ }
+ template <int Dim, class T>
+ inline void compress(Engine<Dim, T, CompressibleBrick> &e)
+ {
+ e.tryCompress();
+ }
+ template <int Dim, class T>
+ inline void uncompress(Engine<Dim, T, CompressibleBrick> &e)
+ {
+ e.uncompress();
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrickView>::
+ read(const Loc<Dim> &loc) const
+ {
+ return data0_m[this->offset(loc)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrickView>::
+ read(int i1) const
+ {
+ ;
+ return data0_m[this->offset(i1)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrickView>::
+ read(int i1, int i2) const
+ {
+ ;
+ return data0_m[this->offset(i1,i2)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrickView>::
+ read(int i1, int i2, int i3) const
+ {
+ ;
+ return data0_m[this->offset(i1,i2,i3)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrickView>::
+ read(int i1, int i2, int i3, int i4) const
+ {
+ ;
+ return data0_m[this->offset(i1,i2,i3,i4)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrickView>::
+ read(int i1, int i2, int i3, int i4, int i5) const
+ {
+ ;
+ return data0_m[this->offset(i1,i2,i3,i4,i5)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrickView>::
+ read(int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ ;
+ return data0_m[this->offset(i1,i2,i3,i4,i5,i6)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrickView>::
+ read(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
+ {
+ ;
+ return data0_m[this->offset(i1,i2,i3,i4,i5,i6,i7)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrickView>::
+ operator()(const Loc<Dim> &loc) const
+ {
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offset(loc)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrickView>::
+ operator()(int i1) const
+ {
+ ;
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offset(i1)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrickView>::
+ operator()(int i1, int i2) const
+ {
+ ;
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offset(i1,i2)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrickView>::
+ operator()(int i1, int i2, int i3) const
+ {
+ ;
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offset(i1,i2,i3)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrickView>::
+ operator()(int i1, int i2, int i3, int i4) const
+ {
+ ;
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offset(i1,i2,i3,i4)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrickView>::
+ operator()(int i1, int i2, int i3, int i4, int i5) const
+ {
+ ;
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offset(i1,i2,i3,i4,i5)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrickView>::
+ operator()(int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ ;
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offset(i1,i2,i3,i4,i5,i6)];
+ }
+ template <int Dim, class T>
+ inline T & Engine<Dim,T,CompressibleBrickView>::
+ operator()(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
+ {
+ ;
+ if (cblock_m.compressed()) cblock_m.uncompress();
+ return data0_m[this->offset(i1,i2,i3,i4,i5,i6,i7)];
+ }
+ template <int Dim, class T>
+ inline T Engine<Dim,T,CompressibleBrickView>::
+ compressedRead() const
+ {
+ ;
+ return *data0_m;
+ }
+ template <int Dim, class T>
+ inline T& Engine<Dim,T,CompressibleBrickView>::
+ compressedReadWrite() const
+ {
+ ;
+ return *data0_m;
+ }
+ template <int Dim, class T>
+ inline
+ bool compressed(const Engine<Dim,T,CompressibleBrickView> &e)
+ {
+ return e.compressed();
+ }
+ template <int Dim, class T>
+ inline
+ long elementsCompressed(const Engine<Dim,T,CompressibleBrickView> &e)
+ {
+ return e.elementsCompressed();
+ }
+ template <int Dim, class T>
+ Engine<Dim,T,CompressibleBrick>::Engine(const Domain_t &domain)
+ : Base_t(domain), cblock_m(domain.size())
+ {
+ init();
+ }
+ template <int Dim, class T>
+ Engine<Dim,T,CompressibleBrick>::Engine(const Node<Domain_t> &node)
+ : Base_t(node.allocated()),
+ cblock_m(node.allocated().size(), node.affinity())
+ {
+ init();
+ }
+ template <int Dim, class T>
+ Engine<Dim,T,CompressibleBrick>::Engine(const Layout_t &layout)
+ : Base_t(layout.domain()), cblock_m(layout.domain().size())
+ {
+ init();
+ }
+ template <int Dim, class T>
+ Engine<Dim,T,CompressibleBrick>::Engine(const Domain_t &domain, const T& model)
+ : Base_t(domain), cblock_m(domain.size(),-1,model)
+ {
+ init();
+ }
+ template <int Dim, class T>
+ Engine<Dim,T,CompressibleBrick>::
+ Engine(const Engine<Dim,T,CompressibleBrick> &modelEngine)
+ : cblock_m(modelEngine.cblock_m)
+ {
+ cblock_m.lock();
+ data0_m = modelEngine.data0_m;
+ Base_t::operator=(modelEngine);
+ if (cblock_m.isControllerValidUnlocked()) cblock_m.attach(this);
+ cblock_m.unlock();
+ }
+ template <int Dim, class T>
+ Engine<Dim,T,CompressibleBrick> &
+ Engine<Dim,T,CompressibleBrick>::
+ operator=(const Engine<Dim,T,CompressibleBrick> &modelEngine)
+ {
+ if (this != &modelEngine)
+ {
+ ;
+ modelEngine.cblock_m.lock();
+ if (cblock_m.isControllerPtrValid())
+ {
+ cblock_m.lock();
+ if (cblock_m.isControllerValidUnlocked())
+ {
+ cblock_m.detach(this);
+ }
+ cblock_m.unlock();
+ }
+ cblock_m = modelEngine.cblock_m;
+ lock();
+ data0_m = modelEngine.data0_m;
+ Base_t::operator=(modelEngine);
+ unlock();
+ if (cblock_m.isControllerValidUnlocked()) cblock_m.attach(this);
+ cblock_m.unlock();
+ }
+ return *this;
+ }
+ template <int Dim, class T>
+ void Engine<Dim,T,CompressibleBrick>::init()
+ {
+ resetDataAndStrides();
+ ;
+ cblock_m.attach(this);
+ }
+ template <int Dim, class T>
+ Engine<Dim,T,CompressibleBrick>::~Engine()
+ {
+ if (data0_m)
+ {
+ cblock_m.lock();
+ if (cblock_m.isControllerValidUnlocked())
+ {
+ cblock_m.detach(this);
+ }
+ cblock_m.unlock();
+ }
+ }
+ template <int Dim, class T>
+ Engine<Dim,T,CompressibleBrick> &Engine<Dim,T,CompressibleBrick>::makeOwnCopy()
+ {
+ if (cblock_m.isControllerValidUnlocked() && cblock_m.isShared())
+ {
+ cblock_m.detach(this);
+ cblock_m.makeOwnCopy();
+ cblock_m.attach(this);
+ data0_m = cblock_m.data() + (cblock_m.compressed() ? 0 : this->baseOffset());
+ }
+ return *this;
+ }
+ template <int Dim, class T>
+ void Engine<Dim,T,CompressibleBrick>::
+ notify(T* &data, const ObserverEvent &event)
+ {
+ switch (event.event())
+ {
+ default:
+ case CompressibleBlock<T>::notifyDestruct:
+ ;
+ break;
+ case CompressibleBlock<T>::notifyUncompress:
+ lock();
+ this->restoreStrides();
+ data0_m = data + this->baseOffset();
+ unlock();
+ break;
+ case CompressibleBlock<T>::notifyCompress:
+ lock();
+ this->zeroStrides();
+ data0_m = data;
+ unlock();
+ break;
+ }
+ }
+ template <int Dim, class T>
+ void Engine<Dim,T,CompressibleBrick>::resetDataAndStrides()
+ {
+ if (cblock_m.compressed())
+ {
+ this->zeroStrides();
+ data0_m = cblock_m.data();
+ }
+ else
+ {
+ this->restoreStrides();
+ data0_m = cblock_m.data() + this->baseOffset();
+ }
+ }
+ template <int Dim, class T>
+ long Engine<Dim,T,CompressibleBrick>::
+ elementsCompressed() const
+ {
+ if (compressed())
+ return domain().size();
+ else
+ return 0L;
+ }
+ template <int Dim, class T>
+ Engine<Dim,T,CompressibleBrickView>::
+ ~Engine()
+ {
+ cblock_m.lock();
+ if (cblock_m.isControllerValidUnlocked())
+ {
+ cblock_m.detach(this);
+ }
+ cblock_m.unlock();
+ }
+ template <int Dim, class T>
+ Engine<Dim,T,CompressibleBrickView> &
+ Engine<Dim,T,CompressibleBrickView>::
+ operator=(const Engine<Dim,T,CompressibleBrickView> &modelEngine)
+ {
+ if (this != &modelEngine)
+ {
+ ;
+ modelEngine.cblock_m.lock();
+ if (cblock_m.isControllerPtrValid())
+ {
+ cblock_m.lock();
+ if (cblock_m.isControllerValidUnlocked())
+ {
+ cblock_m.detach(this);
+ }
+ cblock_m.unlock();
+ }
+ cblock_m = modelEngine.cblock_m;
+ entire_m = modelEngine.entire_m;
+ lock();
+ data0_m = modelEngine.data0_m;
+ Base_t::operator=(modelEngine);
+ unlock();
+ if (cblock_m.isControllerValidUnlocked()) cblock_m.attach(this);
+ cblock_m.unlock();
+ }
+ return *this;
+ }
+ template <int Dim, class T>
+ Engine<Dim,T,CompressibleBrickView>::
+ Engine(const Engine<Dim,T,CompressibleBrickView> &modelEngine)
+ : cblock_m(modelEngine.cblock_m),
+ entire_m(modelEngine.entire_m)
+ {
+ cblock_m.lock();
+ data0_m = modelEngine.data0_m;
+ Base_t::operator=(modelEngine);
+ if (cblock_m.isControllerValidUnlocked()) cblock_m.attach(this);
+ cblock_m.unlock();
+ }
+ template <int Dim, class T>
+ Engine<Dim,T,CompressibleBrickView>::
+ Engine(const Engine<Dim,T,CompressibleBrickView> &modelEngine,
+ const EngineConstructTag &)
+ : cblock_m(modelEngine.cblock_m),
+ entire_m(modelEngine.entire_m)
+ {
+ cblock_m.lock();
+ data0_m = modelEngine.data0_m;
+ Base_t::operator=(modelEngine);
+ if (cblock_m.isControllerValidUnlocked()) cblock_m.attach(this);
+ cblock_m.unlock();
+ }
+ template <int Dim, class T>
+ long Engine<Dim,T,CompressibleBrickView>::
+ elementsCompressed() const
+ {
+ if (compressed())
+ return domain().size();
+ else
+ return 0L;
+ }
+ template <int Dim> class Range;
+ struct Brick {};
+ struct BrickView {};
+ struct BrickViewU {};
+ template <int Dim, class T>
+ class Engine<Dim,T,BrickView>;
+ template <int Dim, class T>
+ class Engine<Dim,T,Brick> : public Pooma::BrickBase<Dim>
+ {
+ public:
+ typedef Engine<Dim,T,Brick> This_t;
+ typedef Engine<Dim,T,Brick> Engine_t;
+ typedef Pooma::BrickBase<Dim> Base_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef DomainLayout<Dim> Layout_t;
+ typedef T Element_t;
+ typedef T& ElementRef_t;
+ typedef Brick Tag_t;
+ enum { brick = true };
+ enum { dimensions = Dim };
+ enum { hasDataObject = true };
+ enum { dynamic = false };
+ enum { zeroBased = false };
+ enum { multiPatch = false };
+ Engine() { }
+ explicit Engine(const Domain_t &domain);
+ Engine(const Domain_t &domain, const T &elementModel);
+ explicit Engine(const Layout_t &layout);
+ explicit Engine(const Node<Domain_t> &node);
+ Engine(T * foreignData, const Domain_t &domain);
+ Engine(const This_t &model)
+ : Base_t(model), dataBlock_m(model.dataBlock_m),
+ data_m(model.data_m)
+ {}
+ ~Engine() {}
+ This_t &operator=(const This_t &model)
+ {
+ if (this == &model)
+ return *this;
+ Base_t::operator=(model);
+ dataBlock_m = model.dataBlock_m;
+ data_m = model.data_m;
+ ;
+ return *this;
+ }
+ Element_t read(const Loc<Dim> &loc) const
+ {
+ return data_m[this->offset(loc)];
+ }
+ ElementRef_t operator()(const Loc<Dim> &loc) const
+ {
+ return data_m[this->offset(loc)];
+ }
+ Element_t read(int i1) const
+ {
+ PoomaCTAssert<(Dim == 1)>::test();
+ return data_m[this->offset(i1)];
+ }
+ Element_t read(int i1, int i2) const
+ {
+ PoomaCTAssert<(Dim == 2)>::test();
+ return data_m[this->offset(i1,i2)];
+ }
+ Element_t read(int i1, int i2, int i3) const
+ {
+ PoomaCTAssert<(Dim == 3)>::test();
+ return data_m[this->offset(i1,i2,i3)];
+ }
+ Element_t read(int i1, int i2, int i3, int i4) const
+ {
+ PoomaCTAssert<(Dim == 4)>::test();
+ return data_m[this->offset(i1,i2,i3,i4)];
+ }
+ Element_t read(int i1, int i2, int i3, int i4, int i5) const
+ {
+ PoomaCTAssert<(Dim == 5)>::test();
+ return data_m[this->offset(i1,i2,i3,i4,i5)];
+ }
+ Element_t read(int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ PoomaCTAssert<(Dim == 6)>::test();
+ return data_m[this->offset(i1,i2,i3,i4,i5,i6)];
+ }
+ Element_t read(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
+ {
+ PoomaCTAssert<(Dim == 7)>::test();
+ return data_m[this->offset(i1,i2,i3,i4,i5,i6,i7)];
+ }
+ ElementRef_t operator()(int i1) const
+ {
+ PoomaCTAssert<(Dim == 1)>::test();
+ return data_m[this->offset(i1)];
+ }
+ ElementRef_t operator()(int i1, int i2) const
+ {
+ PoomaCTAssert<(Dim == 2)>::test();
+ return data_m[this->offset(i1,i2)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3) const
+ {
+ PoomaCTAssert<(Dim == 3)>::test();
+ return data_m[this->offset(i1,i2,i3)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3, int i4) const
+ {
+ PoomaCTAssert<(Dim == 4)>::test();
+ return data_m[this->offset(i1,i2,i3,i4)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5) const
+ {
+ PoomaCTAssert<(Dim == 5)>::test();
+ return data_m[this->offset(i1,i2,i3,i4,i5)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ PoomaCTAssert<(Dim == 6)>::test();
+ return data_m[this->offset(i1,i2,i3,i4,i5,i6)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
+ {
+ PoomaCTAssert<(Dim == 7)>::test();
+ return data_m[this->offset(i1,i2,i3,i4,i5,i6,i7)];
+ }
+ Engine_t &makeOwnCopy();
+ inline
+ Pooma::DataObject_t *dataObject() const { return dataBlock_m.dataObject(); }
+ DataBlockPtr<T> dataBlock() { return dataBlock_m; }
+ const DataBlockPtr<T> & dataBlock() const { return dataBlock_m; }
+ bool isShared() const { return dataBlock_m.isValid() && dataBlock_m.count() > 1; }
+ private:
+ DataBlockPtr<T> dataBlock_m;
+ T *data_m;
+ };
+ template <int Dim, class T>
+ Engine<Dim,T,Brick>::Engine(const Domain_t &dom)
+ : Base_t(dom), dataBlock_m(dom.size()), data_m(dataBlock_m.currentPointer())
+ { }
+ template <int Dim, class T>
+ Engine<Dim,T,Brick>::Engine(const Node<Domain_t> &node)
+ : Base_t(node),
+ dataBlock_m(node.allocated().size(), node.affinity(),
+ typename DataBlockPtr<T>::WithAffinity_t()),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ template <int Dim, class T>
+ Engine<Dim,T,Brick>::Engine(const Layout_t &layout)
+ : Base_t(layout), dataBlock_m(layout.domain().size()),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ template <int Dim, class T>
+ Engine<Dim,T,Brick>::Engine(const Domain_t &dom, const T& model)
+ : Base_t(dom), dataBlock_m(dom.size(), model),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ template <int Dim, class T>
+ Engine<Dim,T,Brick>::Engine(T * foreignData, const Domain_t &dom)
+ : Base_t(dom), dataBlock_m(foreignData, dom.size()),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ template <int Dim, class T>
+ Engine<Dim,T,Brick> &Engine<Dim,T,Brick>::makeOwnCopy()
+ {
+ if (dataBlock_m.isValid() && dataBlock_m.count() > 1)
+ {
+ ;
+ dataBlock_m.makeOwnCopy();
+ data_m = dataBlock_m.currentPointer();
+ }
+ return *this;
+ }
+ template <int Dim, class T>
+ class Engine<Dim,T,BrickView>
+ : public Pooma::BrickViewBase<Dim>
+ {
+ public:
+ typedef Engine<Dim,T,BrickView> This_t;
+ typedef Engine<Dim,T,BrickView> Engine_t;
+ typedef Pooma::BrickViewBase<Dim> Base_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef DomainLayout<Dim> Layout_t;
+ typedef T Element_t;
+ typedef T& ElementRef_t;
+ typedef BrickView Tag_t;
+ enum { dimensions = Dim };
+ enum { hasDataObject = true };
+ enum { dynamic = false };
+ enum { zeroBased = true };
+ enum { multiPatch = false };
+ Engine()
+ : Base_t(), dataBlock_m(), data_m(0)
+ {}
+ Engine(const This_t &model)
+ : Base_t(model), dataBlock_m(model.dataBlock_m),
+ data_m(dataBlock_m.currentPointer())
+ {}
+ Engine(const This_t &model, const EngineConstructTag &)
+ : Base_t(model), dataBlock_m(model.dataBlock_m),
+ data_m(dataBlock_m.currentPointer())
+ {}
+ template <class DT>
+ Engine(const Engine<Dim,T,Brick> &e, const Domain<Dim, DT> &dom)
+ : Base_t(e, dom.unwrap()), dataBlock_m(e.dataBlock(), e.offset(dom.unwrap())),
+ data_m(dataBlock_m.currentPointer())
+ {
+ ;
+ }
+ template<int Dim2>
+ Engine(const Engine<Dim2,T,Brick> &e, const SliceRange<Dim2,Dim> &dom)
+ : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
+ data_m(dataBlock_m.currentPointer())
+ {
+ ;
+ }
+ template<int Dim2>
+ Engine(const Engine<Dim2,T,Brick> &e, const SliceInterval<Dim2,Dim> &dom)
+ : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
+ data_m(dataBlock_m.currentPointer())
+ {
+ ;
+ }
+ template <int Dim2>
+ Engine(const Engine<Dim2,T,Brick> &e, const SliceInterval<Dim,Dim2> &dom,
+ const Interval<Dim> &totalDomain)
+ : Base_t(e, dom, totalDomain), dataBlock_m(e.dataBlock(), e.offset(dom.sliceDomain())),
+ data_m(dataBlock_m.currentPointer())
+ {
+ }
+ template <int Dim2>
+ Engine(const Engine<Dim2,T,BrickView> &e, const SliceInterval<Dim,Dim2> &dom,
+ const Interval<Dim> &totalDomain)
+ : Base_t(e, dom, totalDomain), dataBlock_m(e.dataBlock(), e.offset(dom.sliceDomain())),
+ data_m(dataBlock_m.currentPointer())
+ {
+ }
+ template <int Dim2>
+ Engine(const Engine<Dim2,T,BrickViewU> &e, const SliceInterval<Dim,Dim2> &dom,
+ const Interval<Dim> &totalDomain)
+ : Base_t(e, dom, totalDomain), dataBlock_m(e.dataBlock(), e.offset(dom.sliceDomain())),
+ data_m(dataBlock_m.currentPointer())
+ {
+ }
+ template <class DT>
+ Engine(const This_t &e, const Domain<Dim, DT> &d)
+ : Base_t(e, d.unwrap()), dataBlock_m(e.dataBlock(), e.offset(d.unwrap())),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ template <class DT>
+ Engine(const Engine<Dim,T,BrickViewU> &e, const Domain<Dim, DT> &d)
+ : Base_t(e, d.unwrap()), dataBlock_m(e.dataBlock(), e.offset(d.unwrap())),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ Engine(const This_t &e, const INode<Dim> &inode)
+ : Base_t(e,inode.domain()), dataBlock_m(e.dataBlock(), e.offset(inode.domain())),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ Engine(const Engine<Dim,T,BrickViewU> &e, const INode<Dim> &inode)
+ : Base_t(e,inode.domain()), dataBlock_m(e.dataBlock(), e.offset(inode.domain())),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ template <int ODim>
+ Engine(const Engine<ODim,T,BrickView> &e,
+ const SliceRange<ODim,Dim> &dom)
+ : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ template <int ODim>
+ Engine(const Engine<ODim,T,BrickViewU> &e,
+ const SliceRange<ODim,Dim> &dom)
+ : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ template <int ODim>
+ Engine(const Engine<ODim,T,BrickView> &e,
+ const SliceInterval<ODim,Dim> &dom)
+ : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ template <int ODim>
+ Engine(const Engine<ODim,T,BrickViewU> &e,
+ const SliceInterval<ODim,Dim> &dom)
+ : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ explicit Engine(const Engine<Dim,T,CompressibleBrick> &);
+ explicit Engine(const Engine<Dim,T,CompressibleBrickView> &);
+ ~Engine() {}
+ This_t &operator=(const This_t &model)
+ {
+ if (this == &model)
+ return *this;
+ Base_t::operator=(model);
+ dataBlock_m = model.dataBlock_m;
+ data_m = model.data_m;
+ return *this;
+ }
+ Element_t read(const Loc<Dim> &loc) const
+ {
+ return data_m[this->offset(loc)];
+ }
+ ElementRef_t operator()(const Loc<Dim> &loc) const
+ {
+ return data_m[this->offset(loc)];
+ }
+ Element_t read(int i1) const
+ {
+ PoomaCTAssert<(Dim == 1)>::test();
+ return data_m[this->offset(i1)];
+ }
+ Element_t read(int i1, int i2) const
+ {
+ PoomaCTAssert<(Dim == 2)>::test();
+ return data_m[this->offset(i1,i2)];
+ }
+ Element_t read(int i1, int i2, int i3) const
+ {
+ PoomaCTAssert<(Dim == 3)>::test();
+ return data_m[this->offset(i1,i2,i3)];
+ }
+ Element_t read(int i1, int i2, int i3, int i4) const
+ {
+ PoomaCTAssert<(Dim == 4)>::test();
+ return data_m[this->offset(i1,i2,i3,i4)];
+ }
+ Element_t read(int i1, int i2, int i3, int i4, int i5) const
+ {
+ PoomaCTAssert<(Dim == 5)>::test();
+ return data_m[this->offset(i1,i2,i3,i4,i5)];
+ }
+ Element_t read(int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ PoomaCTAssert<(Dim == 6)>::test();
+ return data_m[this->offset(i1,i2,i3,i4,i5,i6)];
+ }
+ Element_t read(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
+ {
+ PoomaCTAssert<(Dim == 7)>::test();
+ return data_m[this->offset(i1,i2,i3,i4,i5,i6,i7)];
+ }
+ ElementRef_t operator()(int i1) const
+ {
+ PoomaCTAssert<(Dim == 1)>::test();
+ return data_m[this->offset(i1)];
+ }
+ ElementRef_t operator()(int i1, int i2) const
+ {
+ PoomaCTAssert<(Dim == 2)>::test();
+ return data_m[this->offset(i1,i2)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3) const
+ {
+ PoomaCTAssert<(Dim == 3)>::test();
+ return data_m[this->offset(i1,i2,i3)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3, int i4) const
+ {
+ PoomaCTAssert<(Dim == 4)>::test();
+ return data_m[this->offset(i1,i2,i3,i4)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5) const
+ {
+ PoomaCTAssert<(Dim == 5)>::test();
+ return data_m[this->offset(i1,i2,i3,i4,i5)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ PoomaCTAssert<(Dim == 6)>::test();
+ return data_m[this->offset(i1,i2,i3,i4,i5,i6)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
+ {
+ PoomaCTAssert<(Dim == 7)>::test();
+ return data_m[this->offset(i1,i2,i3,i4,i5,i6,i7)];
+ }
+ DataBlockPtr<T> dataBlock() { return dataBlock_m; }
+ const DataBlockPtr<T> &dataBlock() const { return dataBlock_m; }
+ inline
+ Pooma::DataObject_t *dataObject() const { return dataBlock_m.dataObject(); }
+ private:
+ DataBlockPtr<T> dataBlock_m;
+ T *data_m;
+ };
+ template <int Dim, class T>
+ Engine<Dim,T,BrickView>::
+ Engine(const Engine<Dim,T,CompressibleBrick> &model)
+ : Base_t(model, false)
+ {
+ dataBlock_m = DataBlockPtr<T>(model.dataBlock(),this->baseOffset());
+ data_m = dataBlock_m.currentPointer();
+ }
+ template <int Dim, class T>
+ Engine<Dim,T,BrickView>::
+ Engine(const Engine<Dim,T,CompressibleBrickView> &model)
+ : Base_t(model, false)
+ {
+ dataBlock_m = DataBlockPtr<T>(model.dataBlock(),this->baseOffset());
+ data_m = dataBlock_m.currentPointer();
+ }
+ template <int Dim, class T>
+ class Engine<Dim,T,BrickViewU>
+ : public Pooma::BrickViewBase<Dim>
+ {
+ public:
+ typedef Engine<Dim,T,BrickViewU> This_t;
+ typedef Engine<Dim,T,BrickViewU> Engine_t;
+ typedef Pooma::BrickViewBase<Dim> Base_t;
+ typedef typename Base_t::Domain_t Domain_t;
+ typedef DomainLayout<Dim> Layout_t;
+ typedef T Element_t;
+ typedef T& ElementRef_t;
+ typedef BrickViewU Tag_t;
+ enum { dimensions = Dim };
+ enum { hasDataObject = true };
+ enum { dynamic = false };
+ enum { zeroBased = true };
+ enum { multiPatch = false };
+ Engine()
+ : Base_t(), dataBlock_m(), data_m(0)
+ {}
+ Engine(const This_t &model)
+ : Base_t(model), dataBlock_m(model.dataBlock_m),
+ data_m(dataBlock_m.currentPointer())
+ {}
+ Engine(const This_t &model, const EngineConstructTag &)
+ : Base_t(model), dataBlock_m(model.dataBlock_m),
+ data_m(dataBlock_m.currentPointer())
+ {}
+ template <class ETag, class DT>
+ Engine(const Engine<Dim,T,ETag> &e, const Domain<Dim, DT> &dom)
+ : Base_t(e, dom.unwrap()), dataBlock_m(e.dataBlock(), e.offset(dom.unwrap())),
+ data_m(dataBlock_m.currentPointer())
+ {
+ ;
+ }
+ template<int Dim2>
+ Engine(const Engine<Dim2,T,Brick> &e, const SliceRange<Dim2,Dim> &dom)
+ : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
+ data_m(dataBlock_m.currentPointer())
+ {
+ ;
+ }
+ template<int Dim2>
+ Engine(const Engine<Dim2,T,Brick> &e, const SliceInterval<Dim2,Dim> &dom)
+ : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
+ data_m(dataBlock_m.currentPointer())
+ {
+ ;
+ }
+ template <class DT>
+ Engine(const This_t &e, const Domain<Dim, DT> &d)
+ : Base_t(e, d.unwrap()), dataBlock_m(e.dataBlock(), e.offset(d.unwrap())),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ Engine(const This_t &e, const INode<Dim> &inode)
+ : Base_t(e,inode.domain()), dataBlock_m(e.dataBlock(), e.offset(inode.domain())),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ template <int ODim>
+ Engine(const Engine<ODim,T,BrickView> &e,
+ const SliceRange<ODim,Dim> &dom)
+ : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ template <int ODim>
+ Engine(const Engine<ODim,T,BrickViewU> &e,
+ const SliceInterval<ODim,Dim> &dom)
+ : Base_t(e, dom), dataBlock_m(e.dataBlock(), e.offset(dom.totalDomain())),
+ data_m(dataBlock_m.currentPointer())
+ { }
+ explicit Engine(const Engine<Dim,T,CompressibleBrick> &);
+ explicit Engine(const Engine<Dim,T,CompressibleBrickView> &);
+ ~Engine() {}
+ This_t &operator=(const This_t &model)
+ {
+ if (this == &model)
+ return *this;
+ Base_t::operator=(model);
+ dataBlock_m = model.dataBlock_m;
+ data_m = model.data_m;
+ return *this;
+ }
+ Element_t read(const Loc<Dim> &loc) const
+ {
+ return data_m[this->offsetU(loc)];
+ }
+ ElementRef_t operator()(const Loc<Dim> &loc) const
+ {
+ return data_m[this->offsetU(loc)];
+ }
+ Element_t read(int i1) const
+ {
+ PoomaCTAssert<(Dim == 1)>::test();
+ return data_m[this->offsetU(i1)];
+ }
+ Element_t read(int i1, int i2) const
+ {
+ PoomaCTAssert<(Dim == 2)>::test();
+ return data_m[this->offsetU(i1,i2)];
+ }
+ Element_t read(int i1, int i2, int i3) const
+ {
+ PoomaCTAssert<(Dim == 3)>::test();
+ return data_m[this->offsetU(i1,i2,i3)];
+ }
+ Element_t read(int i1, int i2, int i3, int i4) const
+ {
+ PoomaCTAssert<(Dim == 4)>::test();
+ return data_m[this->offsetU(i1,i2,i3,i4)];
+ }
+ Element_t read(int i1, int i2, int i3, int i4, int i5) const
+ {
+ PoomaCTAssert<(Dim == 5)>::test();
+ return data_m[this->offsetU(i1,i2,i3,i4,i5)];
+ }
+ Element_t read(int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ PoomaCTAssert<(Dim == 6)>::test();
+ return data_m[this->offsetU(i1,i2,i3,i4,i5,i6)];
+ }
+ Element_t read(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
+ {
+ PoomaCTAssert<(Dim == 7)>::test();
+ return data_m[this->offsetU(i1,i2,i3,i4,i5,i6,i7)];
+ }
+ ElementRef_t operator()(int i1) const
+ {
+ PoomaCTAssert<(Dim == 1)>::test();
+ return data_m[this->offsetU(i1)];
+ }
+ ElementRef_t operator()(int i1, int i2) const
+ {
+ PoomaCTAssert<(Dim == 2)>::test();
+ return data_m[this->offsetU(i1,i2)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3) const
+ {
+ PoomaCTAssert<(Dim == 3)>::test();
+ return data_m[this->offsetU(i1,i2,i3)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3, int i4) const
+ {
+ PoomaCTAssert<(Dim == 4)>::test();
+ return data_m[this->offsetU(i1,i2,i3,i4)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5) const
+ {
+ PoomaCTAssert<(Dim == 5)>::test();
+ return data_m[this->offsetU(i1,i2,i3,i4,i5)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ PoomaCTAssert<(Dim == 6)>::test();
+ return data_m[this->offsetU(i1,i2,i3,i4,i5,i6)];
+ }
+ ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
+ {
+ PoomaCTAssert<(Dim == 7)>::test();
+ return data_m[this->offsetU(i1,i2,i3,i4,i5,i6,i7)];
+ }
+ DataBlockPtr<T> dataBlock() { return dataBlock_m; }
+ const DataBlockPtr<T> &dataBlock() const { return dataBlock_m; }
+ inline
+ Pooma::DataObject_t *dataObject() const { return dataBlock_m.dataObject(); }
+ private:
+ DataBlockPtr<T> dataBlock_m;
+ T *data_m;
+ };
+ template <int Dim, class T>
+ Engine<Dim,T,BrickViewU>::
+ Engine(const Engine<Dim,T,CompressibleBrick> &model)
+ : Base_t(model, false)
+ {
+ dataBlock_m = DataBlockPtr<T>(model.dataBlock(),this->baseOffset());
+ data_m = dataBlock_m.currentPointer();
+ }
+ template <int Dim, class T>
+ Engine<Dim,T,BrickViewU>::
+ Engine(const Engine<Dim,T,CompressibleBrickView> &model)
+ : Base_t(model, false)
+ {
+ dataBlock_m = DataBlockPtr<T>(model.dataBlock(),this->baseOffset());
+ data_m = dataBlock_m.currentPointer();
+ }
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,Brick>, Interval<Dim> >
+ {
+ typedef Engine<Dim,T,BrickViewU> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,Brick>, Range<Dim> >
+ {
+ typedef Engine<Dim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,Brick>, Node<Interval<Dim> > >
+ {
+ typedef Engine<Dim,T,BrickViewU> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,Brick>, INode<Dim> >
+ {
+ typedef Engine<Dim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<Dim,T,Brick>, SliceInterval<Dim,SliceDim> >
+ {
+ typedef Engine<SliceDim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<Dim,T,Brick>, SliceRange<Dim,SliceDim> >
+ {
+ typedef Engine<SliceDim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<SliceDim,T,Brick>, SliceInterval<Dim,SliceDim> >
+ {
+ typedef Engine<Dim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<SliceDim,T,BrickView>, SliceInterval<Dim,SliceDim> >
+ {
+ typedef Engine<Dim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<SliceDim,T,BrickViewU>, SliceInterval<Dim,SliceDim> >
+ {
+ typedef Engine<Dim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,BrickView>, Interval<Dim> >
+ {
+ typedef Engine<Dim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,BrickView>, Range<Dim> >
+ {
+ typedef Engine<Dim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,BrickView>, Node<Interval<Dim> > >
+ {
+ typedef Engine<Dim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,BrickView>, INode<Dim> >
+ {
+ typedef Engine<Dim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<Dim,T,BrickView>, SliceInterval<Dim,SliceDim> >
+ {
+ typedef Engine<SliceDim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<Dim,T,BrickView>, SliceRange<Dim,SliceDim> >
+ {
+ typedef Engine<SliceDim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,BrickViewU>, Interval<Dim> >
+ {
+ typedef Engine<Dim,T,BrickViewU> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,BrickViewU>, Range<Dim> >
+ {
+ typedef Engine<Dim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,BrickViewU>, Node<Interval<Dim> > >
+ {
+ typedef Engine<Dim,T,BrickViewU> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim,T,BrickViewU>, INode<Dim> >
+ {
+ typedef Engine<Dim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<Dim,T,BrickViewU>, SliceInterval<Dim,SliceDim> >
+ {
+ typedef Engine<SliceDim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<Dim,T,BrickViewU>, SliceRange<Dim,SliceDim> >
+ {
+ typedef Engine<SliceDim,T,BrickView> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngineDomain<Engine<Dim,T,Brick>, Node<Interval<Dim> > >
+ {
+ typedef Interval<Dim> Type_t;
+ typedef const Interval<Dim> &Return_t;
+ static inline
+ Return_t apply(const Engine<Dim,T,Brick> &,
+ const Node<Interval<Dim> > &node)
+ {
+ return node.domain();
+ }
+ };
+ template <int Dim, class T>
+ struct NewEngineDomain<Engine<Dim,T,Brick>, INode<Dim> >
+ {
+ typedef Interval<Dim> Type_t;
+ typedef const Interval<Dim> &Return_t;
+ static inline
+ Return_t apply(const Engine<Dim,T,Brick> &,
+ const INode<Dim> &inode)
+ {
+ return inode.domain();
+ }
+ };
+ template <int Dim, class T>
+ struct NewEngineDomain<Engine<Dim,T,BrickView>, Node<Interval<Dim> > >
+ {
+ typedef Interval<Dim> Type_t;
+ typedef const Interval<Dim> &Return_t;
+ static inline
+ Return_t apply(const Engine<Dim,T,BrickView> &,
+ const Node<Interval<Dim> > &node)
+ {
+ return node.domain();
+ }
+ };
+ template <int Dim, class T>
+ struct NewEngineDomain<Engine<Dim,T,BrickView>, INode<Dim> >
+ {
+ typedef Interval<Dim> Type_t;
+ typedef const Interval<Dim> &Return_t;
+ static inline
+ Return_t apply(const Engine<Dim,T,BrickView> &,
+ const INode<Dim> &inode)
+ {
+ return inode.domain();
+ }
+ };
+ template <int Dim, class T>
+ struct NewEngineDomain<Engine<Dim,T,BrickViewU>, Node<Interval<Dim> > >
+ {
+ typedef Interval<Dim> Type_t;
+ typedef const Interval<Dim> &Return_t;
+ static inline
+ Return_t apply(const Engine<Dim,T,BrickViewU> &,
+ const Node<Interval<Dim> > &node)
+ {
+ return node.domain();
+ }
+ };
+ template <int Dim, class T>
+ struct NewEngineDomain<Engine<Dim,T,BrickViewU>, INode<Dim> >
+ {
+ typedef Interval<Dim> Type_t;
+ typedef const Interval<Dim> &Return_t;
+ static inline
+ Return_t apply(const Engine<Dim,T,BrickViewU> &,
+ const INode<Dim> &inode)
+ {
+ return inode.domain();
+ }
+ };
+ template <int Dim, class T>
+ struct ElementProperties<Engine<Dim, T, Brick> >
+ : public MakeOwnCopyProperties<Engine<Dim, T, Brick> >
+ { };
+ template <class Expr>
+ inline bool compressed(const Expr &expr)
+ {
+ return false;
+ }
+ template <class Expr>
+ double compressedFraction(const Expr &expr)
+ {
+ return static_cast<double>(elementsCompressed(expr)) / expr.domain().size();
+ }
+ template <class Expr>
+ inline long elementsCompressed(const Expr &expr)
+ {
+ return 0L;
+ }
+ template <class Expr>
+ inline void compress(Expr &)
+ { }
+ template <class Expr>
+ inline void uncompress(Expr &)
+ { }
+ struct ConstantFunction
+ { };
+ template<int Dim, class T>
+ class Engine<Dim, T, ConstantFunction>
+ {
+ public:
+ typedef ConstantFunction Tag_t;
+ typedef Engine<Dim, T, ConstantFunction> This_t;
+ typedef This_t Engine_t;
+ typedef Interval<Dim> Domain_t;
+ typedef DomainLayout<Dim> Layout_t;
+ typedef T Element_t;
+ typedef ErrorType ElementRef_t;
+ enum { dimensions = Dim };
+ enum { hasDataObject = false };
+ enum { dynamic = false };
+ enum { zeroBased = false };
+ enum { multiPatch = false };
+ Engine() { }
+ explicit Engine(const Domain_t &domain, T val = T())
+ : val_m(val), domain_m(domain)
+ {
+ for (int d = 0; d < Dim; ++d)
+ firsts_m[d] = domain[d].first();
+ }
+ template<class Layout>
+ explicit Engine(const Layout &layout, T val = T())
+ : val_m(val), domain_m(layout.domain())
+ {
+ for (int d = 0; d < Dim; ++d)
+ firsts_m[d] = domain_m[d].first();
+ }
+ Engine(const Engine<Dim, T, ConstantFunction> &model)
+ : val_m(model.constant()), domain_m(model.domain())
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ firsts_m[d] = model.firsts_m[d];
+ }
+ }
+ template<class DT>
+ Engine(const Engine<Dim, T, ConstantFunction> &e, const Domain<Dim, DT> &dom)
+ : val_m(e.constant()), domain_m(Pooma::NoInit())
+ {
+ const typename DT::Domain_t &domain = dom.unwrap();
+ for (int d = 0; d < Dim; ++d)
+ {
+ domain_m[d] = Interval<1>(domain[d].length());
+ firsts_m[d] = 0;
+ }
+ }
+ template<int Dim2, class DT>
+ Engine(const Engine<Dim2, T, ConstantFunction> &e,
+ const SliceDomain<DT> &dom)
+ : val_m(e.constant()), domain_m(Pooma::NoInit())
+ {
+ PoomaCTAssert<(DT::sliceDimensions == Dim)>::test();
+ PoomaCTAssert<(DT::dimensions == Dim2)>::test();
+ const typename DT::SliceDomain_t &domain = dom.sliceDomain();
+ for (int d = 0; d < Dim; ++d)
+ {
+ domain_m[d] = Interval<1>(domain[d].length());
+ firsts_m[d] = 0;
+ }
+ }
+ template<class Domain>
+ Engine(const Engine<Dim, T, ConstantFunction> &e, const Node<Domain> &node)
+ : val_m(e.constant()), domain_m(Pooma::NoInit())
+ {
+ PoomaCTAssert<(Domain::dimensions == Dim)>::test();
+ const Domain &domain = node.domain();
+ for (int d = 0; d < Dim; ++d)
+ {
+ domain_m[d] = Interval<1>(domain[d].length());
+ firsts_m[d] = 0;
+ }
+ }
+ Engine(const Engine<Dim, T, ConstantFunction> &e, const INode<Dim> &inode)
+ : val_m(e.constant()), domain_m(Pooma::NoInit())
+ {
+ const typename INode<Dim>::Domain_t &domain = inode.domain();
+ for (int d = 0; d < Dim; ++d)
+ {
+ domain_m[d] = Interval<1>(domain[d].length());
+ firsts_m[d] = 0;
+ }
+ }
+ inline Element_t read(int) const
+ {
+ return val_m;
+ }
+ inline Element_t read(int, int) const
+ {
+ return val_m;
+ }
+ inline Element_t read(int, int, int) const
+ {
+ return val_m;
+ }
+ inline Element_t read(int, int, int, int) const
+ {
+ return val_m;
+ }
+ inline Element_t read(int, int, int, int, int) const
+ {
+ return val_m;
+ }
+ inline Element_t read(int, int, int, int, int, int) const
+ {
+ return val_m;
+ }
+ inline Element_t read(int, int, int, int, int, int, int) const
+ {
+ return val_m;
+ }
+ inline Element_t read(const Loc<Dim> &) const
+ {
+ return val_m;
+ }
+ const Domain_t &domain() const { return domain_m; }
+ inline Layout_t layout() const { return Layout_t(domain_m); }
+ inline int first(int i) const
+ {
+ ;
+ return firsts_m[i];
+ }
+ T constant() const { return val_m; }
+ void setConstant(T val) { val_m = val; }
+ private:
+ T val_m;
+ Domain_t domain_m;
+ int firsts_m[Dim];
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim, T, ConstantFunction>, Interval<Dim> >
+ {
+ typedef Engine<Dim, T, ConstantFunction> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim, T, ConstantFunction>, Range<Dim> >
+ {
+ typedef Engine<Dim, T, ConstantFunction> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<Dim,T,ConstantFunction>, SliceInterval<Dim,SliceDim> >
+ {
+ typedef Engine<SliceDim,T,ConstantFunction> Type_t;
+ };
+ template <int Dim, class T, int SliceDim>
+ struct NewEngine<Engine<Dim,T,ConstantFunction>, SliceRange<Dim,SliceDim> >
+ {
+ typedef Engine<SliceDim,T,ConstantFunction> Type_t;
+ };
+ template <int Dim, class T, class Domain>
+ struct NewEngine<Engine<Dim, T, ConstantFunction>, Node<Domain> >
+ {
+ typedef Engine<Dim, T, ConstantFunction> Type_t;
+ };
+ template <int Dim, class T>
+ struct NewEngine<Engine<Dim, T, ConstantFunction>, INode<Dim> >
+ {
+ typedef Engine<Dim, T, ConstantFunction> Type_t;
+ };
+ struct ErrorDomain
+ {
+ };
+ struct NullDomain
+ {
+ };
+ template<class D>
+ bool contains(const NullDomain &, const D &)
+ {
+ return true;
+ }
+ template<class Inter>
+ struct IntersectorTag
+ {
+ inline IntersectorTag(Inter &i) : intersector_m(i) { }
+ Inter &intersector_m;
+ };
+ template<class Eng, class Intersect>
+ struct DefaultExpressionApply<Eng, IntersectorTag<Intersect> >
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const Eng &,
+ const ExpressionApply<IntersectorTag<Intersect> > &)
+ {
+ PoomaCTAssert<(!(Eng::multiPatch))>::test();
+ return true;
+ }
+ };
+ struct AssertEquals
+ {
+ AssertEquals(int ignore = 0) : ignore_m(ignore) { }
+ int ignore_m;
+ };
+ template<class Op>
+ struct Combine2<int, int, Op, AssertEquals>
+ {
+ typedef int Type_t;
+ inline static
+ Type_t combine(const int &a, const int &b, const AssertEquals &ae)
+ {
+ int ret = a;
+ if ((a != ae.ignore_m) && (b != ae.ignore_m))
+ {
+ ;
+ }
+ else
+ {
+ if (b != ae.ignore_m) return ret = b;
+ }
+ return ret;
+ }
+ };
+ template<class Thing>
+ struct View0
+ {
+ };
+ template<class Thing, class Sub>
+ struct View1
+ {
+ };
+ template<class Thing, class Sub1, class Sub2>
+ struct View2
+ {
+ };
+ template<class Thing, class Sub1, class Sub2, class Sub3>
+ struct View3
+ {
+ };
+ template<class Thing, class Sub1, class Sub2, class Sub3, class Sub4>
+ struct View4
+ {
+ };
+ template<class Thing, class Sub1, class Sub2, class Sub3, class Sub4,
+ class Sub5>
+ struct View5
+ {
+ };
+ template<class Thing, class Sub1, class Sub2, class Sub3, class Sub4,
+ class Sub5, class Sub6>
+ struct View6
+ {
+ };
+ template<class Thing, class Sub1, class Sub2, class Sub3, class Sub4,
+ class Sub5, class Sub6, class Sub7>
+ struct View7
+ {
+ };
+ template<class Components, class Object>
+ struct ComponentView;
+ struct EnginePatch
+ {
+ typedef TreeCombine Combine_t;
+ typedef int PatchID_t;
+ explicit EnginePatch(PatchID_t patch) : patch_m(patch) { }
+ PatchID_t patch_m;
+ };
+ template<class Eng>
+ struct EngineFunctorDefault<Eng, EnginePatch>
+ {
+ typedef Eng Type_t;
+ inline static
+ const Type_t &apply(const Eng &e, const EnginePatch &)
+ {
+ PoomaCTAssert<(!(Eng::multiPatch))>::test();
+ return e;
+ }
+ };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, EnginePatch>
+ {
+ typedef Scalar<T> Type_t;
+ inline static
+ Type_t apply(const Scalar<T> &scalar, const EnginePatch &)
+ {
+ return scalar;
+ }
+ };
+ template<class Container>
+ struct Patch
+ {
+ };
+ template<class Container>
+ struct PatchView
+ {
+ typedef typename Patch<Container>::Type_t Patch_t;
+ typedef typename Patch_t::Domain_t Dom_t;
+ typedef typename View1<Patch_t, Dom_t>::Type_t Type_t;
+ inline static
+ Type_t make(const Container &subject, int i)
+ {
+ return subject.patchLocal(i)();
+ }
+ };
+ template<class Node>
+ struct LeafFunctor<Node, EnginePatch>
+ {
+ typedef typename PatchView<Node>::Type_t Type_t;
+ inline static
+ Type_t apply(const Node &node, const EnginePatch &tag)
+ {
+ return node.patchLocal(tag.patch_m)();
+ }
+ };
+ struct EngineNumPatches
+ {
+ typedef AssertEquals Combine_t;
+ };
+ template<class Eng>
+ struct EngineFunctorDefault<Eng, EngineNumPatches>
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const Eng &, const EngineNumPatches &)
+ {
+ PoomaCTAssert<(!(Eng::multiPatch))>::test();
+ return 1;
+ }
+ };
+ template<class T>
+ struct EngineFunctorScalar<T, EngineNumPatches>
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const T &, const EngineNumPatches &)
+ {
+ return 0;
+ }
+ };
+ template <int Dim>
+ class DomainLayout;
+ template<int Dim>
+ struct EvalLeaf { };
+ template<class T, int Dim>
+ struct LeafFunctor<Scalar<T>, EvalLeaf<Dim> >
+ {
+ typedef T Type_t;
+ inline static
+ Type_t apply(const Scalar<T> &s, const EvalLeaf<Dim> &)
+ {
+ return s.value();
+ }
+ };
+ template<int Dim, class T, class E>
+ struct LeafFunctor<Engine<Dim, T, E>, EvalLeaf<Dim> >
+ {
+ typedef T Type_t;
+ inline static
+ Type_t apply(const Engine<Dim, T, E> &e, const EvalLeaf<Dim> &t)
+ {
+ return t.eval(e);
+ }
+ };
+ template<>
+ struct EvalLeaf<1>
+ {
+ int i1_m;
+ inline EvalLeaf(int i1)
+ : i1_m(i1)
+ { }
+ inline EvalLeaf(const Loc<1> &loc)
+ : i1_m(loc[0].first())
+ { }
+ inline int val1() const { return i1_m; }
+ template<class Engine>
+ inline typename Engine::Element_t eval(const Engine &e) const
+ {
+ return e.read(val1());
+ }
+ };
+ template<>
+ struct EvalLeaf<2>
+ {
+ int i1_m, i2_m;
+ inline EvalLeaf(int i1, int i2)
+ : i1_m(i1), i2_m(i2)
+ { }
+ inline EvalLeaf(const Loc<2> &loc)
+ : i1_m(loc[0].first()), i2_m(loc[1].first())
+ { }
+ inline int val1() const { return i1_m; }
+ inline int val2() const { return i2_m; }
+ template<class Engine>
+ inline typename Engine::Element_t eval(const Engine &e) const
+ {
+ return e.read(val1(), val2());
+ }
+ };
+ template<>
+ struct EvalLeaf<3>
+ {
+ int i1_m, i2_m, i3_m;
+ inline EvalLeaf(int i1, int i2, int i3)
+ : i1_m(i1), i2_m(i2), i3_m(i3)
+ { }
+ inline EvalLeaf(const Loc<3> &loc)
+ : i1_m(loc[0].first()), i2_m(loc[1].first()), i3_m(loc[2].first())
+ { }
+ inline int val1() const { return i1_m; }
+ inline int val2() const { return i2_m; }
+ inline int val3() const { return i3_m; }
+ template<class Engine>
+ inline typename Engine::Element_t eval(const Engine &e) const
+ {
+ return e.read(val1(), val2(), val3());
+ }
+ };
+ template<>
+ struct EvalLeaf<4>
+ {
+ int i1_m, i2_m, i3_m, i4_m;
+ inline EvalLeaf(int i1, int i2, int i3, int i4)
+ : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4)
+ { }
+ inline EvalLeaf(const Loc<4> &loc)
+ : i1_m(loc[0].first()), i2_m(loc[1].first()), i3_m(loc[2].first()),
+ i4_m(loc[3].first())
+ { }
+ inline int val1() const { return i1_m; }
+ inline int val2() const { return i2_m; }
+ inline int val3() const { return i3_m; }
+ inline int val4() const { return i4_m; }
+ template<class Engine>
+ inline typename Engine::Element_t eval(const Engine &e) const
+ {
+ return e.read(val1(), val2(), val3(), val4());
+ }
+ };
+ template<>
+ struct EvalLeaf<5>
+ {
+ int i1_m, i2_m, i3_m, i4_m, i5_m;
+ inline EvalLeaf(int i1, int i2, int i3, int i4, int i5)
+ : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5)
+ { }
+ inline EvalLeaf(const Loc<5> &loc)
+ : i1_m(loc[0].first()), i2_m(loc[1].first()), i3_m(loc[2].first()),
+ i4_m(loc[3].first()), i5_m(loc[4].first())
+ { }
+ inline int val1() const { return i1_m; }
+ inline int val2() const { return i2_m; }
+ inline int val3() const { return i3_m; }
+ inline int val4() const { return i4_m; }
+ inline int val5() const { return i5_m; }
+ template<class Engine>
+ inline typename Engine::Element_t eval(const Engine &e) const
+ {
+ return e.read(val1(), val2(), val3(), val4(), val5());
+ }
+ };
+ template<>
+ struct EvalLeaf<6>
+ {
+ int i1_m, i2_m, i3_m, i4_m, i5_m, i6_m;
+ inline EvalLeaf(int i1, int i2, int i3, int i4, int i5, int i6)
+ : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5), i6_m(i6)
+ { }
+ inline EvalLeaf(const Loc<6> &loc)
+ : i1_m(loc[0].first()), i2_m(loc[1].first()), i3_m(loc[2].first()),
+ i4_m(loc[3].first()), i5_m(loc[4].first()), i6_m(loc[5].first())
+ { }
+ inline int val1() const { return i1_m; }
+ inline int val2() const { return i2_m; }
+ inline int val3() const { return i3_m; }
+ inline int val4() const { return i4_m; }
+ inline int val5() const { return i5_m; }
+ inline int val6() const { return i6_m; }
+ template<class Engine>
+ inline typename Engine::Element_t eval(const Engine &e) const
+ {
+ return e.read(val1(), val2(), val3(), val4(), val5(), val6());
+ }
+ };
+ template<>
+ struct EvalLeaf<7>
+ {
+ int i1_m, i2_m, i3_m, i4_m, i5_m, i6_m, i7_m;
+ inline EvalLeaf(int i1, int i2, int i3, int i4, int i5, int i6, int i7)
+ : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5), i6_m(i6), i7_m(i7)
+ { }
+ inline EvalLeaf(const Loc<7> &loc)
+ : i1_m(loc[0].first()), i2_m(loc[1].first()), i3_m(loc[2].first()),
+ i4_m(loc[3].first()), i5_m(loc[4].first()), i6_m(loc[5].first()),
+ i7_m(loc[6].first())
+ { }
+ inline int val1() const { return i1_m; }
+ inline int val2() const { return i2_m; }
+ inline int val3() const { return i3_m; }
+ inline int val4() const { return i4_m; }
+ inline int val5() const { return i5_m; }
+ inline int val6() const { return i6_m; }
+ inline int val7() const { return i7_m; }
+ template<class Engine>
+ inline typename Engine::Element_t eval(const Engine &e) const
+ {
+ return e.read(val1(), val2(), val3(), val4(), val5(), val6(), val7());
+ }
+ };
+ template<class Domain>
+ struct ViewFunctorTag
+ {
+ const Domain &domain_m;
+ inline ViewFunctorTag(const Domain &domain) : domain_m(domain) { }
+ };
+ template<class T, class Domain>
+ struct LeafFunctor<Scalar<T>, ViewFunctorTag<Domain> >
+ {
+ typedef Scalar<T> Type_t;
+ inline static
+ Type_t apply(const Scalar<T> &s, const ViewFunctorTag<Domain> &)
+ {
+ return s;
+ }
+ };
+ struct DomainFunctorTag { };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, DomainFunctorTag>
+ {
+ typedef NullDomain Type_t;
+ inline static
+ Type_t apply(const Scalar<T> &, const DomainFunctorTag &)
+ {
+ return NullDomain();
+ }
+ };
+ template<class T>
+ struct LeafFunctor<T, DomainFunctorTag>
+ {
+ typedef typename T::Domain_t Type_t;
+ inline static
+ Type_t apply(const T &leaf, const DomainFunctorTag &)
+ {
+ return leaf.domain();
+ }
+ };
+ template<class Domain1, class Domain2, class Op>
+ struct Combine2<Domain1, Domain2, Op, DomainFunctorTag>
+ {
+ typedef ErrorDomain Type_t;
+ inline static
+ Type_t combine(const Domain1 &, const Domain2 &, const DomainFunctorTag &)
+ {
+ return ErrorDomain();
+ }
+ };
+ template<class Domain, class Op>
+ struct Combine2<Domain, Domain, Op, DomainFunctorTag>
+ {
+ typedef Domain Type_t;
+ inline static
+ Type_t combine(const Domain &a, const Domain &, const DomainFunctorTag &)
+ {
+ return a;
+ }
+ };
+ template<class Domain, class Op>
+ struct Combine2<Domain, NullDomain, Op, DomainFunctorTag>
+ {
+ typedef Domain Type_t;
+ inline static
+ Type_t combine(const Domain &a, const NullDomain &,
+ const DomainFunctorTag &)
+ {
+ return a;
+ }
+ };
+ template<class Domain,class Op>
+ struct Combine2<NullDomain, Domain, Op, DomainFunctorTag>
+ {
+ typedef Domain Type_t;
+ inline static
+ Type_t combine(const NullDomain &, const Domain &b,
+ const DomainFunctorTag &)
+ {
+ return b;
+ }
+ };
+ template<class Tag>
+ struct EngineFunctorTag
+ {
+ EngineFunctorTag() : tag_m() { }
+ EngineFunctorTag(const Tag &tag) : tag_m(tag) { }
+ inline const Tag &tag() const
+ {
+ return tag_m;
+ }
+ Tag tag_m;
+ };
+ template<class Expr>
+ struct ExpressionTag
+ {
+ typedef Expr Expression_t;
+ };
+ template<int Dim, class T, class Expr>
+ class Engine<Dim, T, ExpressionTag<Expr> >
+ {
+ public:
+ typedef Engine<Dim, T, ExpressionTag<Expr> > Engine_t;
+ typedef ExpressionTag<Expr> Tag_t;
+ typedef T Element_t;
+ typedef ErrorType ElementRef_t;
+ typedef typename ForEach<Expr, DomainFunctorTag, DomainFunctorTag>::Type_t
+ Domain_t;
+ typedef Expr Expression_t;
+ typedef DomainLayout<Dim> Layout_t;
+ enum { dimensions = Dim };
+ enum { multiPatch = true };
+ enum { hasDataObject = true };
+ enum { dynamic = false };
+ enum { zeroBased = true };
+ inline Engine(const Expr &expr) : expr_m(expr),
+ domain_m(forEach(expr_m, DomainFunctorTag(), DomainFunctorTag())) { }
+ inline Engine(const Engine_t &engine) : expr_m(engine.expression()),
+ domain_m(engine.domain()) { }
+ template<int Dim2, class T2, class Expr2, class Initializer>
+ inline Engine(const Engine<Dim2, T2, ExpressionTag<Expr2> > &e,
+ const Initializer &i)
+ : expr_m(e.expression(), i),
+ domain_m(forEach(expr_m, DomainFunctorTag(), DomainFunctorTag()))
+ { }
+ template<int Dim2, class T2, class Expr2, class I1, class I2>
+ inline Engine(const Engine<Dim2, T2, ExpressionTag<Expr2> > &e,
+ const I1 &i1, const I2 &i2)
+ : expr_m(e.expression(), i1, i2),
+ domain_m(forEach(expr_m, DomainFunctorTag(), DomainFunctorTag()))
+ { }
+ template<class Expr2>
+ explicit inline Engine(const Engine<Dim,T,ExpressionTag<Expr2> > &e)
+ : expr_m(e.expression()),
+ domain_m(forEach(expr_m, DomainFunctorTag(), DomainFunctorTag()))
+ { }
+ inline const Expression_t &expression() const { return expr_m; }
+ inline Expression_t &expression() { return expr_m; }
+ Engine_t &makeOwnCopy();
+ inline Element_t read(int i0) const
+ {
+ return forEach(expr_m, EvalLeaf<1>(i0), OpCombine());
+ }
+ inline Element_t read(int i0, int i1) const
+ {
+ return forEach(expr_m, EvalLeaf<2>(i0, i1), OpCombine());
+ }
+ inline Element_t read(int i0, int i1, int i2) const
+ {
+ return forEach(expr_m, EvalLeaf<3>(i0, i1, i2), OpCombine());
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3) const
+ {
+ return forEach(expr_m, EvalLeaf<4>(i0, i1, i2, i3),
+ OpCombine());
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3, int i4) const
+ {
+ return forEach(expr_m, EvalLeaf<5>(i0, i1, i2, i3, i4),
+ OpCombine());
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3, int i4, int i5) const
+ {
+ return forEach(expr_m, EvalLeaf<6>(i0, i1, i2, i3, i4, i5),
+ OpCombine());
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3, int i4, int i5,
+ int i6) const
+ {
+ return forEach(expr_m, EvalLeaf<7>(i0, i1, i2, i3, i4, i5, i6),
+ OpCombine());
+ }
+ inline Element_t read(const Loc<Dim> &loc) const
+ {
+ return forEach(expr_m, EvalLeaf<Dim>(loc), OpCombine());
+ }
+ inline const Domain_t& domain() const
+ {
+ return domain_m;
+ }
+ inline Layout_t layout() const { return Layout_t(domain()); }
+ inline int first(int) const
+ {
+ return 0;
+ }
+ template<class RequestType>
+ inline
+ typename DataObjectRequest<RequestType>::Type_t
+ dataObjectRequest(const DataObjectRequest<RequestType>& f) const
+ {
+ typedef DataObjectRequest<RequestType> Tag_t;
+ typedef EngineFunctorTag<Tag_t> Functor_t;
+ typedef typename Tag_t::Combine_t Combine_t;
+ return forEach(expr_m,Functor_t(f),Combine_t());
+ }
+ private:
+ Expr expr_m;
+ Domain_t domain_m;
+ };
+ template<int Dim, class T, class Expr, class Domain>
+ struct NewEngine<Engine<Dim, T, ExpressionTag<Expr> >, Domain>
+ {
+ typedef ViewFunctorTag<Domain> FTag_t;
+ typedef typename ForEach<Expr, FTag_t, TreeCombine>::Type_t ExprView_t;
+ typedef Engine<Dim, T, ExpressionTag<ExprView_t> > Type_t;
+ };
+ template <int Dim, class T, class Expr, int SliceDim>
+ struct NewEngine<Engine<Dim, T, ExpressionTag<Expr> >,
+ SliceInterval<Dim,SliceDim> >
+ {
+ typedef ViewFunctorTag<SliceInterval<Dim,SliceDim> > FTag_t;
+ typedef typename ForEach<Expr, FTag_t, TreeCombine>::Type_t ExprView_t;
+ typedef Engine<SliceDim, T, ExpressionTag<ExprView_t> > Type_t;
+ };
+ template <int Dim, class T, class Expr, int SliceDim>
+ struct NewEngine<Engine<Dim,T,ExpressionTag<Expr> >,
+ SliceRange<Dim,SliceDim> >
+ {
+ typedef ViewFunctorTag<SliceRange<Dim,SliceDim> > FTag_t;
+ typedef typename ForEach<Expr, FTag_t, TreeCombine>::Type_t ExprView_t;
+ typedef Engine<SliceDim, T, ExpressionTag<ExprView_t> > Type_t;
+ };
+ template<class Node, class Tag>
+ struct LeafFunctor<Node, EngineFunctorTag<Tag> >
+ {
+ };
+ template<class T, class Tag>
+ struct LeafFunctor<Scalar<T>, EngineFunctorTag<Tag> >
+ {
+ typedef typename EngineFunctorScalar<T,Tag>::Type_t Type_t;
+ inline static
+ Type_t apply(const Scalar<T> &scalar, const EngineFunctorTag<Tag> &tag)
+ {
+ return EngineFunctorScalar<T,Tag>::apply(scalar.value(), tag.tag());
+ }
+ };
+ template<int Dim, class T, class E, class Tag>
+ struct LeafFunctor<Engine<Dim, T, E>, EngineFunctorTag<Tag> >
+ {
+ typedef Engine<Dim, T, E> Engine_t;
+ typedef typename EngineFunctor<Engine_t, Tag>::Type_t Type_t;
+ inline static
+ Type_t apply(const Engine_t &engine,
+ const EngineFunctorTag<Tag> &tag)
+ {
+ return EngineFunctor<Engine_t, Tag>::apply(engine, tag.tag());
+ }
+ };
+ template<int Dim, class T, class Expr, class Tag>
+ struct EngineFunctor<Engine<Dim,T,ExpressionTag<Expr> >,Tag>
+ {
+ typedef EngineFunctorTag<Tag> Functor_t;
+ typedef typename Tag::Combine_t Combine_t;
+ typedef typename ForEach<Expr,Functor_t,Combine_t>::Type_t Type_t;
+ inline static
+ Type_t apply(const Engine<Dim, T, ExpressionTag<Expr> > &engine,
+ const Tag &tag)
+ {
+ return forEach(engine.expression(), Functor_t(tag), Combine_t());
+ }
+ };
+ template<int Dim, class T, class Expr>
+ struct EngineFunctor<Engine<Dim, T, ExpressionTag<Expr> >, EnginePatch>
+ {
+ typedef typename EnginePatch::Combine_t Combine_t;
+ typedef typename ForEach<Expr, EnginePatch, Combine_t>::Type_t NewExpr_t;
+ typedef Engine<Dim, T, ExpressionTag<NewExpr_t> > Type_t;
+ inline static
+ Type_t apply(const Engine<Dim, T, ExpressionTag<Expr> > &engine,
+ const EnginePatch &tag)
+ {
+ return Type_t(forEach(engine.expression(), tag, Combine_t()));
+ }
+ };
+ template<int Dim, class T, class Expr, class Tag>
+ struct LeafFunctor<Engine<Dim, T, ExpressionTag<Expr> >, EngineView<Tag> >
+ {
+ typedef EngineView<Tag> Functor_t;
+ typedef typename Functor_t::Combine_t Combine_t;
+ typedef typename ForEach<Expr, Functor_t, Combine_t>::Type_t NewExpr_t;
+ typedef Engine<Dim, T, ExpressionTag<NewExpr_t> > Type_t;
+ inline static
+ Type_t apply(const Engine<Dim, T, ExpressionTag<Expr> > &engine,
+ const EngineView<Tag> &tag)
+ {
+ return Type_t(forEach(engine.expression(), tag, Combine_t()));
+ }
+ };
+ template<int Dim, class T, class Expr, class Tag>
+ struct LeafFunctor<Engine<Dim, T, ExpressionTag<Expr> >, ExpressionApply<Tag> >
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const Engine<Dim, T, ExpressionTag<Expr> > &engine,
+ const ExpressionApply<Tag> &tag)
+ {
+ return forEach(engine.expression(), tag, NullCombine());
+ }
+ };
+ template<class Components>
+ class ComponentWrapper
+ {
+ public:
+ explicit ComponentWrapper(const Components &c) : c_m(c) { }
+ const Components &components() const { return c_m; }
+ private:
+ const Components &c_m;
+ };
+ template<class T, class Components>
+ struct ComponentAccess
+ {
+ typedef T Element_t;
+ typedef T &ElementRef_t;
+ static inline ElementRef_t indexRef(T &v, const Components &)
+ {
+ return v;
+ }
+ static inline Element_t index(const T &v, const Components &)
+ {
+ return v;
+ }
+ };
+ template<class Engine>
+ struct NotifyEngineWrite
+ {
+ NotifyEngineWrite(){}
+ ~NotifyEngineWrite(){}
+ inline static void
+ notify(const Engine &)
+ {
+ PoomaCTAssert<(!(Engine::multiPatch))>::test();
+ }
+ };
+ template<class Engine>
+ inline
+ void notifyEngineWrite(const Engine &e)
+ {
+ NotifyEngineWrite<Engine>::notify(e);
+ }
+ template<class Engine>
+ inline
+ void notifyEngineWrite(const Engine &, const WrappedInt<false> &)
+ {
+ }
+ template<class Engine>
+ inline
+ void notifyEngineWrite(const Engine &e, const WrappedInt<true> &)
+ {
+ NotifyEngineWrite<Engine>::notify(e);
+ }
+ template <int Dim> class DomainLayout;
+ template<class Eng, class Components>
+ struct CompFwd { };
+ template<int Dim, class T, class Eng, class Components>
+ class Engine<Dim, T, CompFwd<Eng, Components> >
+ {
+ public:
+ typedef Engine<Dim, T, Eng> This_t;
+ typedef This_t Engine_t;
+ typedef Eng ElemEngine_t;
+ typedef typename Eng::Element_t FwdElement_t;
+ typedef ComponentAccess<FwdElement_t, Components> CompAccess_t;
+ typedef typename CompAccess_t::Element_t Element_t;
+ typedef typename CompAccess_t::ElementRef_t ElementRef_t;
+ typedef typename Eng::Domain_t Domain_t;
+ typedef CompFwd<Eng, Components> Tag_t;
+ typedef typename Eng::Layout_t Layout_t;
+ enum { dimensions = Eng::dimensions };
+ enum { hasDataObject = Eng::hasDataObject };
+ enum { dynamic = false };
+ enum { zeroBased = Eng::zeroBased };
+ enum { multiPatch = Eng::multiPatch };
+ Engine()
+ : engine_m(), components_m()
+ { }
+ Engine(const Eng &e, const Components &l)
+ : engine_m(e), components_m(l)
+ { }
+ Engine(const This_t &e)
+ : engine_m(e.elemEngine()), components_m(e.components()) { }
+ template<class OtherEng, class Domain>
+ Engine(const Engine< Dim, T, CompFwd<OtherEng, Components> > &e,
+ const Domain &domain)
+ : engine_m(NewEngineEngine<OtherEng,Domain>::apply(e.elemEngine(),domain),
+ NewEngineDomain<OtherEng,Domain>::apply(e.elemEngine(),domain)),
+ components_m(e.components()) { }
+ ~Engine() { }
+ inline ElementRef_t operator()(const Loc<dimensions> &eloc) const
+ {
+ return CompAccess_t::indexRef(elemEngine()(eloc), components());
+ }
+ inline ElementRef_t operator()(int i1) const
+ {
+ return CompAccess_t::indexRef(elemEngine()(i1), components());
+ }
+ inline ElementRef_t operator()(int i1, int i2) const
+ {
+ return CompAccess_t::indexRef(elemEngine()(i1, i2), components());
+ }
+ inline ElementRef_t operator()(int i1, int i2, int i3) const
+ {
+ return CompAccess_t::indexRef(elemEngine()(i1, i2, i3),
+ components());
+ }
+ inline ElementRef_t operator()(int i1, int i2, int i3, int i4) const
+ {
+ return CompAccess_t::indexRef(elemEngine()(i1, i2, i3, i4),
+ components());
+ }
+ inline ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5) const
+ {
+ return CompAccess_t::indexRef(elemEngine()(i1, i2, i3, i4, i5),
+ components());
+ }
+ inline ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5,
+ int i6) const
+ {
+ return CompAccess_t::indexRef(elemEngine()(i1, i2, i3, i4, i5, i6),
+ components());
+ }
+ inline ElementRef_t operator()(int i1, int i2, int i3, int i4, int i5,
+ int i6, int i7) const
+ {
+ return CompAccess_t::indexRef(elemEngine()(i1, i2, i3, i4, i5, i6, i7),
+ components());
+ }
+ inline Element_t read(const Loc<dimensions> &eloc) const
+ {
+ return CompAccess_t::index(elemEngine().read(eloc), components());
+ }
+ inline Element_t read(int i1) const
+ {
+ return CompAccess_t::index(elemEngine().read(i1), components());
+ }
+ inline Element_t read(int i1, int i2) const
+ {
+ return CompAccess_t::index(elemEngine().read(i1, i2), components());
+ }
+ inline Element_t read(int i1, int i2, int i3) const
+ {
+ return CompAccess_t::index(elemEngine().read(i1, i2, i3),
+ components());
+ }
+ inline Element_t read(int i1, int i2, int i3, int i4) const
+ {
+ return CompAccess_t::index(elemEngine().read(i1, i2, i3, i4),
+ components());
+ }
+ inline Element_t read(int i1, int i2, int i3, int i4, int i5) const
+ {
+ return CompAccess_t::index(elemEngine().read(i1, i2, i3, i4, i5),
+ components());
+ }
+ inline Element_t read(int i1, int i2, int i3, int i4, int i5,
+ int i6) const
+ {
+ return CompAccess_t::index(elemEngine().read(i1, i2, i3, i4, i5, i6),
+ components());
+ }
+ inline Element_t read(int i1, int i2, int i3, int i4, int i5,
+ int i6, int i7) const
+ {
+ return CompAccess_t::index(elemEngine().read(i1, i2, i3, i4, i5, i6, i7),
+ components());
+ }
+ inline const Layout_t& layout() const
+ {
+ return elemEngine().layout();
+ }
+ inline Layout_t& layout()
+ {
+ return elemEngine().layout();
+ }
+ inline const Domain_t& domain() const { return elemEngine().domain(); }
+ inline int first(int i) const
+ {
+ return elemEngine().first(i);
+ }
+ This_t &makeOwnCopy()
+ {
+ elemEngine().makeOwnCopy();
+ return *this;
+ }
+ Eng &elemEngine() { return engine_m; }
+ const Eng &elemEngine() const { return engine_m; }
+ const Components &components() const { return components_m; }
+ private:
+ Eng engine_m;
+ Components components_m;
+ };
+ template <int Dim, class T, class Eng, class Components, class Domain>
+ struct NewEngine<Engine<Dim, T, CompFwd<Eng, Components> >, Domain>
+ {
+ typedef typename NewEngine<Eng, Domain>::Type_t NewEngine_t;
+ typedef Engine<NewEngine_t::dimensions, T, CompFwd<NewEngine_t, Components> > Type_t;
+ };
+ template<int Dim, class T, class Eng, class Components, class EFTag>
+ struct EngineFunctor<Engine<Dim, T, CompFwd<Eng, Components> >, EFTag>
+ {
+ typedef typename EngineFunctor<Eng, EFTag>::Type_t Type_t;
+ static Type_t
+ apply(const Engine<Dim, T, CompFwd<Eng, Components> > &engine,
+ const EFTag &tag)
+ {
+ return engineFunctor(engine.elemEngine(), tag);
+ }
+ };
+ template <int D, class T, class E, class Comp, class Tag>
+ struct LeafFunctor<Engine<D, T, CompFwd<E, Comp> >, EngineView<Tag> >
+ {
+ typedef LeafFunctor<E, EngineView<Tag> > LeafFunctor_t;
+ typedef typename LeafFunctor_t::Type_t NewViewed_t;
+ typedef Engine<D, T, CompFwd<NewViewed_t, Comp> > Type_t;
+ static
+ Type_t apply(const Engine<D, T, CompFwd<E, Comp> > &engine,
+ const EngineView<Tag> &tag)
+ {
+ return Type_t(LeafFunctor_t::apply(engine.elemEngine(), tag),
+ engine.components());
+ }
+ };
+ template <int D, class T, class E, class Comp, class Tag>
+ struct LeafFunctor<Engine<D, T, CompFwd<E, Comp> >, ExpressionApply<Tag> >
+ {
+ typedef LeafFunctor<E, ExpressionApply<Tag> > LeafFunctor_t;
+ typedef int Type_t;
+ static
+ Type_t apply(const Engine<D, T, CompFwd<E, Comp> > &engine,
+ const ExpressionApply<Tag> &tag)
+ {
+ return LeafFunctor_t::apply(engine.elemEngine(), tag);
+ }
+ };
+ template<int Dim, class T, class Eng, class Components>
+ struct NotifyEngineWrite<Engine<Dim,T,CompFwd<Eng,Components> > >
+ {
+ inline static void
+ notify(const Engine<Dim,T,CompFwd<Eng,Components> > &engine)
+ {
+ typedef typename Engine<Dim, T,
+ CompFwd<Eng, Components> >::ElemEngine_t Engine_t;
+ NotifyEngineWrite<Engine_t>::notify(engine.elemEngine());
+ }
+ };
+ template <int D, class T, class E, class Comp>
+ struct EngineFunctor<Engine<D, T, CompFwd<E, Comp> >, EnginePatch>
+ {
+ typedef typename EngineFunctor<E, EnginePatch>::Type_t NewViewed_t;
+ typedef Engine<D, T, CompFwd<NewViewed_t, Comp> > Type_t;
+ static
+ Type_t apply(const Engine<D, T, CompFwd<E, Comp> > &engine,
+ const EnginePatch &tag)
+ {
+ return Type_t(engineFunctor(engine.elemEngine(), tag),
+ engine.components());
+ }
+ };
+ struct WriteRequest {};
+ struct ReadRequest {};
+ struct WriteRelease {};
+ struct ReadRelease {};
+ struct CountBlocks {};
+ template<>
+ class DataObjectRequest<WriteRequest>
+ {
+ public:
+ typedef int Type_t;
+ typedef NullCombine Combine_t;
+ DataObjectRequest(Pooma::Iterate_t& iterate)
+ : iterate_m(iterate),
+ lhs1_m(NULL), lhs2_m(NULL)
+ { }
+ inline Type_t operator()(Pooma::DataObject_t* obj) const
+ {
+ if ((obj != lhs1_m) && (obj != lhs2_m))
+ {
+ if (lhs1_m == NULL)
+ {
+ lhs1_m = obj;
+ }
+ else
+ {
+ if (lhs2_m == NULL)
+ {
+ lhs2_m = obj;
+ }
+ else
+ {
+ ;
+ }
+ }
+ obj->request(iterate_m,Pooma::SmartsTag_t::Write);
+ }
+ return 0;
+ }
+ inline Type_t defaultValue() const
+ {
+ return 0;
+ }
+ Pooma::DataObject_t* dataObject1() const { return lhs1_m; }
+ Pooma::DataObject_t* dataObject2() const { return lhs2_m; }
+ Pooma::Iterate_t& iterate() const { return iterate_m; }
+ private:
+ mutable Pooma::Iterate_t& iterate_m;
+ mutable Pooma::DataObject_t* lhs1_m;
+ mutable Pooma::DataObject_t* lhs2_m;
+ };
+ template<>
+ class DataObjectRequest<ReadRequest>
+ {
+ public:
+ typedef int Type_t;
+ typedef NullCombine Combine_t;
+ DataObjectRequest(const DataObjectRequest<WriteRequest>& write)
+ : iterate_m(write.iterate()),
+ lhs1_m(write.dataObject1()),
+ lhs2_m(write.dataObject2())
+ { }
+ DataObjectRequest(Pooma::Iterate_t& iterate)
+ : iterate_m(iterate),
+ lhs1_m(NULL), lhs2_m(NULL)
+ { }
+ inline Type_t operator()(Pooma::DataObject_t* obj) const
+ {
+ if ((lhs1_m != obj) && (lhs2_m != obj))
+ {
+ obj->request(iterate_m, Pooma::SmartsTag_t::Read);
+ }
+ return 0;
+ }
+ inline Type_t defaultValue() const
+ {
+ return 0;
+ }
+ private:
+ Pooma::Iterate_t& iterate_m;
+ Pooma::DataObject_t* lhs1_m;
+ Pooma::DataObject_t* lhs2_m;
+ };
+ template<>
+ class DataObjectRequest<WriteRelease>
+ {
+ public:
+ typedef int Type_t;
+ typedef NullCombine Combine_t;
+ DataObjectRequest()
+ : lhs1_m(NULL), lhs2_m(NULL)
+ { }
+ inline Type_t operator()(Pooma::DataObject_t* obj) const
+ {
+ if ((obj != lhs1_m) && (obj != lhs2_m))
+ {
+ if (lhs1_m == NULL)
+ {
+ lhs1_m = obj;
+ }
+ else
+ {
+ if (lhs2_m == NULL)
+ {
+ lhs2_m = obj;
+ }
+ else
+ {
+ ;
+ }
+ }
+ obj->release(Pooma::SmartsTag_t::Write);
+ }
+ return 0;
+ }
+ inline Type_t defaultValue() const
+ {
+ return 0;
+ }
+ Pooma::DataObject_t* dataObject1() const { return lhs1_m; }
+ Pooma::DataObject_t* dataObject2() const { return lhs2_m; }
+ private:
+ mutable Pooma::DataObject_t* lhs1_m;
+ mutable Pooma::DataObject_t* lhs2_m;
+ };
+ template<>
+ class DataObjectRequest<ReadRelease>
+ {
+ public:
+ typedef int Type_t;
+ typedef NullCombine Combine_t;
+ DataObjectRequest()
+ : lhs1_m(NULL), lhs2_m(NULL)
+ { }
+ DataObjectRequest(const DataObjectRequest<WriteRelease>& write)
+ : lhs1_m(write.dataObject1()), lhs2_m(write.dataObject2())
+ { }
+ inline Type_t operator()(Pooma::DataObject_t* obj) const
+ {
+ if ((lhs1_m != obj) && (lhs2_m != obj))
+ {
+ obj->release(Pooma::SmartsTag_t::Read);
+ }
+ return 0;
+ }
+ inline Type_t defaultValue() const
+ {
+ return 0;
+ }
+ private:
+ Pooma::DataObject_t* lhs1_m;
+ Pooma::DataObject_t* lhs2_m;
+ };
+ template<>
+ class DataObjectRequest<CountBlocks>
+ {
+ public:
+ typedef int Type_t;
+ typedef SumCombine Combine_t;
+ DataObjectRequest() { }
+ inline Type_t operator()(Pooma::DataObject_t*) const
+ {
+ return 1;
+ }
+ inline Type_t defaultValue() const
+ {
+ return 0;
+ }
+ };
+ template<class Eng, class Tag>
+ struct DefaultExpressionApply<Eng, DataObjectRequest<Tag> >
+ {
+ enum { hasDataObject = Eng::hasDataObject };
+ inline static
+ int apply(const Eng &e,
+ const ExpressionApply<DataObjectRequest<Tag> > &request)
+ {
+ DataObjectApply<hasDataObject>::apply(e, request.tag());
+ return 0;
+ }
+ };
+ template<int Dim> class DomainLayout;
+ template<class A1,class A2>
+ struct IndirectionTag
+ { };
+ template<int Dim,class T,class A1,class A2>
+ class Engine<Dim,T,IndirectionTag<A1,A2> >
+ {
+ public:
+ typedef IndirectionTag<A1,A2> Tag_t;
+ typedef Engine<Dim,T,Tag_t> Engine_t;
+ typedef typename A1::Element_t Element_t;
+ typedef typename A1::ElementRef_t ElementRef_t;
+ typedef typename A2::Domain_t Domain_t;
+ typedef DomainLayout<Dim> Layout_t;
+ typedef typename A1::Engine_t Engine1_t;
+ typedef typename A2::Engine_t Engine2_t;
+ enum { dimensions = Dim };
+ enum { hasDataObject = Engine1_t::hasDataObject ||
+ Engine2_t::hasDataObject };
+ enum { multiPatch = Engine1_t::multiPatch ||
+ Engine2_t::multiPatch };
+ enum { dynamic = false };
+ enum { zeroBased = Engine2_t::zeroBased };
+ inline
+ Engine(const A1 &array1,const A2 &array2)
+ : array1_m(array1),array2_m(array2)
+ {
+ PoomaCTAssert<(A2::dimensions == Dim)>::test();
+ }
+ inline
+ Engine(const Engine_t &engine)
+ : array1_m(engine.array1()),array2_m(engine.array2())
+ { }
+ template<int OtherDim,class OtherA2, class Domain>
+ inline
+ Engine(const Engine<OtherDim,T,IndirectionTag<A1,OtherA2> > &e,
+ const Domain &d)
+ : array1_m(e.array1()),array2_m(e.array2(),d)
+ {
+ PoomaCTAssert<(A2::dimensions == Dim)>::test();
+ }
+ inline const A1 &array1() const { return array1_m; }
+ inline A1 &array1() { return array1_m; }
+ inline const A2 &array2() const { return array2_m; }
+ inline A2 &array2() { return array2_m; }
+ inline Element_t read(int i0) const
+ {
+ return array1_m.read(array2_m.read(i0));
+ }
+ inline Element_t read(int i0, int i1) const
+ {
+ return array1_m.read(array2_m.read(i0,i1));
+ }
+ inline Element_t read(int i0, int i1,int i2) const
+ {
+ return array1_m.read(array2_m.read(i0,i1,i2));
+ }
+ inline Element_t read(int i0, int i1,int i2,int i3) const
+ {
+ return array1_m.read(array2_m.read(i0,i1,i2,i3));
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3, int i4) const
+ {
+ return array1_m.read(array2_m.read(i0,i1,i2,i3,i4));
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3, int i4, int i5) const
+ {
+ return array1_m.read(array2_m.read(i0,i1,i2,i3,i4,i5));
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3, int i4, int i5,
+ int i6) const
+ {
+ return array1_m.read(array2_m.read(i0,i1,i2,i3,i4,i5,i6));
+ }
+ template<class Domain>
+ inline Element_t read(const Domain &loc) const
+ {
+ return array1_m.read(array2_m.read(loc));
+ }
+ inline ElementRef_t operator()(int i0) const
+ {
+ return array1_m(array2_m.read(i0));
+ }
+ inline ElementRef_t operator()(int i0, int i1) const
+ {
+ return array1_m(array2_m.read(i0,i1));
+ }
+ inline ElementRef_t operator()(int i0, int i1,int i2) const
+ {
+ return array1_m(array2_m.read(i0,i1,i2));
+ }
+ inline ElementRef_t operator()(int i0, int i1,int i2,int i3) const
+ {
+ return array1_m(array2_m.read(i0,i1,i2,i3));
+ }
+ inline ElementRef_t operator()(int i0, int i1, int i2, int i3, int i4) const
+ {
+ return array1_m(array2_m.read(i0,i1,i2,i3,i4));
+ }
+ inline ElementRef_t operator()(int i0, int i1, int i2, int i3, int i4,
+ int i5) const
+ {
+ return array1_m(array2_m.read(i0,i1,i2,i3,i4,i5));
+ }
+ inline ElementRef_t operator()(int i0, int i1, int i2, int i3, int i4,
+ int i5, int i6) const
+ {
+ return array1_m(array2_m.read(i0,i1,i2,i3,i4,i5,i6));
+ }
+ template<class Domain>
+ inline ElementRef_t operator()(const Domain &loc) const
+ {
+ return array1_m(array2_m.read(loc));
+ }
+ inline const Domain_t& domain() const
+ {
+ return array2_m.domain();
+ }
+ inline int first(int i) const
+ {
+ return array2_m.first(i);
+ }
+ private:
+ A1 array1_m;
+ A2 array2_m;
+ };
+ template<int Dim,class T,class A1,class A2,class Domain>
+ struct NewEngine<Engine<Dim,T,IndirectionTag<A1,A2> >,Domain>
+ {
+ typedef typename View1<A2,Domain>::Type_t NewA2_t;
+ enum { newDim = NewA2_t::dimensions };
+ typedef Engine<newDim,T,IndirectionTag<A1,NewA2_t> > Type_t;
+ };
+ template<int Dim, class T, class A1, class A2, class RequestType>
+ struct EngineFunctor<Engine<Dim, T, IndirectionTag<A1, A2> >,
+ DataObjectRequest<RequestType> >
+ {
+ typedef typename DataObjectRequest<RequestType>::Type_t Type_t;
+ typedef typename DataObjectRequest<RequestType>::Combine_t Combine_t;
+ static Type_t
+ apply(const Engine<Dim, T, IndirectionTag<A1, A2> > &engine,
+ const DataObjectRequest<RequestType> &tag)
+ {
+ return Combine2<Type_t,Type_t,OpAdd,
+ Combine_t>::combine(
+ engineFunctor(engine.array1().engine(), tag),
+ engineFunctor(engine.array2().engine(), tag),
+ Combine_t()
+ );
+ }
+ };
+ template<int Dim, class T, class A1, class A2>
+ struct EngineFunctor<Engine<Dim, T, IndirectionTag<A1, A2> >,
+ DataObjectRequest<WriteRequest> >
+ {
+ typedef typename DataObjectRequest<WriteRequest>::Type_t Type_t;
+ static Type_t
+ apply(const Engine<Dim, T, IndirectionTag<A1, A2> > &engine,
+ const DataObjectRequest<WriteRequest> &tag)
+ {
+ engineFunctor(engine.array1().engine(), tag);
+ return engineFunctor(engine.array2().engine(),
+ DataObjectRequest<ReadRequest>(tag));
+ }
+ };
+ template<int Dim, class T, class A1, class A2>
+ struct EngineFunctor<Engine<Dim, T, IndirectionTag<A1, A2> >,
+ DataObjectRequest<WriteRelease> >
+ {
+ typedef typename DataObjectRequest<WriteRelease>::Type_t Type_t;
+ static Type_t
+ apply(const Engine<Dim, T, IndirectionTag<A1, A2> > &engine,
+ const DataObjectRequest<WriteRelease> &tag)
+ {
+ engineFunctor(engine.array1().engine(), tag);
+ return engineFunctor(engine.array2().engine(),
+ DataObjectRequest<ReadRelease>(tag));
+ }
+ };
+ struct Brick;
+ struct BrickView;
+ struct CompressibleBrick;
+ struct CompressibleBrickView;
+ template<class Eng, class Components> struct CompFwd;
+ template<class A1,class A2> struct IndirectionTag;
+ struct ConstantFunction;
+ template<class Expr> struct ExpressionTag;
+ template<class Stencil, class Expression> struct StencilEngine;
+ struct Compressible
+ {
+ typedef AndCombine Combine_t;
+ };
+ struct Compressed
+ {
+ typedef AndCombine Combine_t;
+ };
+ struct CompressedRead
+ {
+ typedef OpCombine Combine_t;
+ };
+ struct CompressedReadWrite
+ {
+ };
+ struct CompressedBrickIsWholeView
+ {
+ };
+ struct UnCompressedViewEngine
+ {
+ };
+ template<int A, int B, class Op>
+ struct Combine2<WrappedInt<A>, WrappedInt<B>, Op, AndCombine>
+ {
+ enum { val = A && B };
+ typedef WrappedInt<val> Type_t;
+ inline static
+ Type_t combine(WrappedInt<A> , WrappedInt<B>, AndCombine)
+ {
+ return Type_t();
+ }
+ };
+ template<class T>
+ struct EngineFunctorScalar<T, Compressible >
+ {
+ typedef WrappedInt<true> Type_t;
+ static Type_t apply(const T &, const Compressible &)
+ {
+ return Type_t();
+ }
+ };
+ template<class T>
+ struct EngineFunctorScalar<T, Compressed >
+ {
+ typedef bool Type_t;
+ static Type_t apply(const T &, const Compressed &)
+ {
+ return true;
+ }
+ };
+ template<class T>
+ struct EngineFunctorScalar<T, CompressedRead >
+ {
+ typedef T Type_t;
+ static inline
+ Type_t apply(const T& s, const CompressedRead &)
+ {
+ return s;
+ }
+ };
+ template<class Engine>
+ struct EngineFunctorDefault<Engine,Compressible>
+ {
+ typedef WrappedInt<false> Type_t;
+ };
+ template<class Engine>
+ struct EngineFunctorDefault<Engine,Compressed>
+ {
+ typedef bool Type_t;
+ static inline
+ Type_t apply(const Engine &, const Compressed &)
+ {
+ return false;
+ }
+ };
+ template<int Dim,class T>
+ struct EngineFunctor<Engine<Dim,T,CompressibleBrick>,Compressible>
+ {
+ typedef WrappedInt<true> Type_t;
+ };
+ template<int Dim,class T>
+ struct EngineFunctor<Engine<Dim,T,CompressibleBrick>,Compressed>
+ {
+ typedef Engine<Dim,T,CompressibleBrick> Engine_t;
+ typedef bool Type_t;
+ static inline
+ Type_t apply(const Engine_t &e, const Compressed &)
+ {
+ return e.compressed();
+ }
+ };
+ template<int Dim,class T>
+ struct EngineFunctor<Engine<Dim,T,CompressibleBrick>,CompressedRead>
+ {
+ typedef Engine<Dim,T,CompressibleBrick> Engine_t;
+ typedef T Type_t;
+ static inline
+ Type_t apply(const Engine_t &e, const CompressedRead &)
+ {
+ return e.compressedRead();
+ }
+ };
+ template<int Dim,class T>
+ struct EngineFunctor<Engine<Dim,T,CompressibleBrick>,CompressedReadWrite>
+ {
+ typedef Engine<Dim,T,CompressibleBrick> Engine_t;
+ typedef T &Type_t;
+ static inline
+ Type_t apply(const Engine_t &e, const CompressedReadWrite &)
+ {
+ return e.compressedReadWrite();
+ }
+ };
+ template<int Dim, class T>
+ struct EngineFunctor<Engine<Dim,T,CompressibleBrick>,
+ CompressedBrickIsWholeView>
+ {
+ typedef Engine<Dim,T,CompressibleBrick> Engine_t;
+ typedef bool Type_t;
+ static inline
+ bool apply(const Engine_t &e, const CompressedBrickIsWholeView &)
+ {
+ return e.compressedBrickIsWholeView();
+ }
+ };
+ template<int Dim, class T>
+ struct EngineFunctor<Engine<Dim,T,CompressibleBrick>,UnCompressedViewEngine>
+ {
+ typedef Engine<Dim,T,CompressibleBrick> Engine_t;
+ typedef Engine<Dim,T,BrickView> Type_t;
+ static inline
+ Type_t apply(const Engine_t &e, const UnCompressedViewEngine &)
+ {
+ return Type_t(e);
+ }
+ };
+ template<int Dim, class T>
+ struct EngineFunctor<Engine<Dim,T,CompressibleBrickView>,Compressible>
+ {
+ typedef WrappedInt<true> Type_t;
+ };
+ template<int Dim, class T>
+ struct EngineFunctor<Engine<Dim,T,CompressibleBrickView >,Compressed>
+ {
+ typedef Engine<Dim,T,CompressibleBrickView > Engine_t;
+ typedef bool Type_t;
+ static inline
+ Type_t apply(const Engine_t &e, const Compressed &)
+ {
+ return e.compressed();
+ }
+ };
+ template<int Dim, class T>
+ struct EngineFunctor<Engine<Dim,T,CompressibleBrickView >,CompressedRead>
+ {
+ typedef Engine<Dim,T,CompressibleBrickView > Engine_t;
+ typedef T Type_t;
+ static inline
+ Type_t apply(const Engine_t &e, const CompressedRead &)
+ {
+ return e.compressedRead();
+ }
+ };
+ template<int Dim, class T>
+ struct EngineFunctor<Engine<Dim,T,CompressibleBrickView >,
+ CompressedReadWrite>
+ {
+ typedef Engine<Dim,T,CompressibleBrickView > Engine_t;
+ typedef T &Type_t;
+ static inline
+ Type_t apply(const Engine_t &e, const CompressedReadWrite &)
+ {
+ return e.compressedReadWrite();
+ }
+ };
+ template<int Dim, class T>
+ struct EngineFunctor<Engine<Dim,T,CompressibleBrickView >,
+ CompressedBrickIsWholeView>
+ {
+ typedef Engine<Dim,T,CompressibleBrickView > Engine_t;
+ typedef bool Type_t;
+ static inline
+ bool apply(const Engine_t &e, const CompressedBrickIsWholeView &)
+ {
+ return e.compressedBrickIsWholeView();
+ }
+ };
+ template<int Dim, class T>
+ struct EngineFunctor<Engine<Dim,T,CompressibleBrickView >,
+ UnCompressedViewEngine>
+ {
+ typedef Engine<Dim,T,CompressibleBrickView > Engine_t;
+ typedef Engine<Dim,T,BrickView> Type_t;
+ static inline
+ Type_t apply(const Engine_t &e, const UnCompressedViewEngine &)
+ {
+ return Type_t(e);
+ }
+ };
+ template<int Dim,class T>
+ struct EngineFunctor<Engine<Dim,T,ConstantFunction>,Compressible>
+ {
+ typedef WrappedInt<true> Type_t;
+ static inline
+ Type_t apply(const Engine<Dim,T,ConstantFunction> &, const Compressible &)
+ {
+ return WrappedInt<true>();
+ }
+ };
+ template<int Dim,class T>
+ struct EngineFunctor<Engine<Dim,T,ConstantFunction>,Compressed>
+ {
+ typedef bool Type_t;
+ static inline
+ Type_t apply(const Engine<Dim,T,ConstantFunction> &, const Compressed &)
+ {
+ return true;
+ }
+ };
+ template<int Dim,class T>
+ struct EngineFunctor<Engine<Dim,T,ConstantFunction>,CompressedRead>
+ {
+ typedef T Type_t;
+ static inline
+ Type_t apply(const Engine<Dim,T,ConstantFunction> &e,
+ const CompressedRead &)
+ {
+ return e.constant();
+ }
+ };
+ template<int Dim, class T, class Eng, class Components>
+ struct EngineFunctor<Engine<Dim,T,CompFwd<Eng, Components> >,Compressible>
+ {
+ typedef typename EngineFunctor<Eng,Compressible>::Type_t Comp_t;
+ enum { compressible = Comp_t::val };
+ typedef WrappedInt<compressible> Type_t;
+ };
+ template<int Dim, class T, class Eng, class Components>
+ struct EngineFunctor<Engine<Dim,T,CompFwd<Eng, Components> >,CompressedRead>
+ {
+ typedef Engine<Dim,T,CompFwd<Eng, Components> > Engine_t;
+ typedef typename Engine_t::CompAccess_t CompAccess_t;
+ typedef typename CompAccess_t::Element_t Type_t;
+ static inline
+ Type_t apply(const Engine_t &e, const CompressedRead &tag)
+ {
+ return CompAccess_t::index(engineFunctor(e.elemEngine(),tag),
+ e.components());
+ }
+ };
+ template<int Dim, class T, class Eng, class Components>
+ struct EngineFunctor<Engine<Dim,T,CompFwd<Eng, Components> >,CompressedReadWrite>
+ {
+ typedef Engine<Dim,T,CompFwd<Eng, Components> > Engine_t;
+ typedef typename Engine_t::CompAccess_t CompAccess_t;
+ typedef typename CompAccess_t::ElementRef_t Type_t;
+ static inline
+ Type_t apply(const Engine_t &e, const CompressedReadWrite &tag)
+ {
+ return CompAccess_t::indexRef(engineFunctor(e.elemEngine(),tag),
+ e.components());
+ }
+ };
+ template<int Dim, class T, class Eng, class Components>
+ struct EngineFunctor<Engine<Dim,T,CompFwd<Eng, Components> >,
+ UnCompressedViewEngine>
+ {
+ typedef Engine<Dim,T,CompFwd<Eng, Components> > Engine_t;
+ typedef typename EngineFunctor<Eng,
+ UnCompressedViewEngine>::Type_t CompEngine_t;
+ typedef Engine<Dim,T,CompFwd<CompEngine_t, Components> > Type_t;
+ static inline
+ Type_t apply(const Engine_t &e,const UnCompressedViewEngine &tag)
+ {
+ return Type_t(engineFunctor(e.elemEngine(), tag), e.components());
+ }
+ };
+ template<class Expr> struct CreateLeaf;
+ struct ErrorKernelTag
+ {
+ ErrorKernelTag(){}
+ ~ErrorKernelTag(){}
+ };
+ struct InlineKernelTag
+ {
+ InlineKernelTag(){}
+ ~InlineKernelTag(){}
+ };
+ struct CompressibleKernelTag
+ {
+ CompressibleKernelTag(){}
+ ~CompressibleKernelTag(){}
+ };
+ struct CompressibleViewKernelTag
+ {
+ CompressibleViewKernelTag(){}
+ ~CompressibleViewKernelTag(){}
+ };
+ template<bool lhsComp,bool rhsComp>
+ struct CompressibleKernel
+ {
+ CompressibleKernel(){}
+ ~CompressibleKernel(){}
+ };
+ template<>
+ struct CompressibleKernel<false,false>
+ {
+ CompressibleKernel(){}
+ ~CompressibleKernel(){}
+ typedef InlineKernelTag Kernel_t;
+ };
+ template<>
+ struct CompressibleKernel<false,true>
+ {
+ CompressibleKernel(){}
+ ~CompressibleKernel(){}
+ typedef InlineKernelTag Kernel_t;
+ };
+ template<>
+ struct CompressibleKernel<true,false>
+ {
+ CompressibleKernel(){}
+ ~CompressibleKernel(){}
+ typedef CompressibleViewKernelTag Kernel_t;
+ };
+ template<>
+ struct CompressibleKernel<true,true>
+ {
+ CompressibleKernel(){}
+ ~CompressibleKernel(){}
+ typedef CompressibleKernelTag Kernel_t;
+ };
+ template<class Expr>
+ struct KernelTag1
+ {
+ KernelTag1(){}
+ ~KernelTag1(){}
+ typedef typename Expr::Engine_t ExprEngine_t;
+ typedef typename EngineFunctor<ExprEngine_t, Compressible>::Type_t Expr_t;
+ enum { exprComp = Expr_t::val };
+ typedef typename CompressibleKernel<exprComp,exprComp>::Kernel_t Kernel_t;
+ };
+ template<class LHS,class RHS>
+ struct KernelTag
+ {
+ KernelTag(){}
+ ~KernelTag(){}
+ typedef typename LHS::Engine_t LHSEngine_t;
+ typedef typename RHS::Engine_t RHSEngine_t;
+ typedef typename EngineFunctor<LHSEngine_t,Compressible>::Type_t LHST_t;
+ typedef typename EngineFunctor<RHSEngine_t,Compressible>::Type_t RHST_t;
+ enum { lhsComp = LHST_t::val };
+ enum { rhsComp = RHST_t::val };
+ typedef typename CompressibleKernel<lhsComp,rhsComp>::Kernel_t Kernel_t;
+ };
+ template<class KernelTag>
+ struct KernelEvaluator;
+ template<>
+ struct KernelEvaluator<InlineKernelTag>
+ {
+ template<class LHS,class Op,class RHS,class Domain>
+ static /*__attribute__((leafify))*/
+ void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
+ const Domain& domain)
+ {
+ PoomaCTAssert<(Domain::unitStride)>::test();
+ for (int i=0; i<Domain::dimensions; ++i)
+ ;
+ evaluate(lhs,op,rhs,domain,
+ WrappedInt<Domain::dimensions>());
+ ;
+ }
+ template<class LHS,class Op,class RHS>
+ inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs)
+ {
+ evaluate(lhs,op,rhs,lhs.domain());
+ }
+ template<class LHS,class Op,class RHS,class Domain>
+ inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
+ const Domain& domain,WrappedInt<1>)
+ {
+ LHS localLHS(lhs);
+ RHS localRHS(rhs);
+ int e0 = domain[0].length();
+ ;
+ #pragma omp parallel for if (e0 > 512)
+ for (int i0=0; i0<e0; ++i0)
+ op(localLHS(i0),localRHS.read(i0));
+ }
+ template<class LHS,class Op,class RHS,class Domain>
+ inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
+ const Domain& domain,WrappedInt<2>)
+ {
+ LHS localLHS(lhs);
+ RHS localRHS(rhs);
+ int e0 = domain[0].length();
+ int e1 = domain[1].length();
+ #pragma omp parallel for
+ for (int i1=0; i1<e1; ++i1) {
+ ;
+ for (int i0=0; i0<e0; ++i0)
+ op(localLHS(i0,i1),localRHS.read(i0,i1));
+ }
+ }
+ template<class LHS,class Op,class RHS,class Domain>
+ inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
+ const Domain& domain,WrappedInt<3>)
+ {
+ LHS localLHS(lhs);
+ RHS localRHS(rhs);
+ int e0 = domain[0].length();
+ int e1 = domain[1].length();
+ int e2 = domain[2].length();
+ #pragma omp parallel for
+ for (int i2=0; i2<e2; ++i2)
+ for (int i1=0; i1<e1; ++i1) {
+ ;
+ for (int i0=0; i0<e0; ++i0)
+ op(localLHS(i0,i1,i2),localRHS.read(i0,i1,i2));
+ }
+ }
+ template<class LHS,class Op,class RHS,class Domain>
+ inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
+ const Domain& domain,WrappedInt<4>)
+ {
+ LHS localLHS(lhs);
+ RHS localRHS(rhs);
+ int e0 = domain[0].length();
+ int e1 = domain[1].length();
+ int e2 = domain[2].length();
+ int e3 = domain[3].length();
+ #pragma omp parallel for
+ for (int i3=0; i3<e3; ++i3)
+ for (int i2=0; i2<e2; ++i2)
+ for (int i1=0; i1<e1; ++i1) {
+ ;
+ for (int i0=0; i0<e0; ++i0)
+ op(localLHS(i0,i1,i2,i3),localRHS.read(i0,i1,i2,i3));
+ }
+ }
+ template<class LHS,class Op,class RHS,class Domain>
+ inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
+ const Domain& domain,WrappedInt<5>)
+ {
+ LHS localLHS(lhs);
+ RHS localRHS(rhs);
+ int e0 = domain[0].length();
+ int e1 = domain[1].length();
+ int e2 = domain[2].length();
+ int e3 = domain[3].length();
+ int e4 = domain[4].length();
+ #pragma omp parallel for
+ for (int i4=0; i4<e4; ++i4)
+ for (int i3=0; i3<e3; ++i3)
+ for (int i2=0; i2<e2; ++i2)
+ for (int i1=0; i1<e1; ++i1) {
+ ;
+ for (int i0=0; i0<e0; ++i0)
+ op(localLHS(i0,i1,i2,i3,i4),localRHS.read(i0,i1,i2,i3,i4));
+ }
+ }
+ template<class LHS,class Op,class RHS,class Domain>
+ inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
+ const Domain& domain,WrappedInt<6>)
+ {
+ LHS localLHS(lhs);
+ RHS localRHS(rhs);
+ int e0 = domain[0].length();
+ int e1 = domain[1].length();
+ int e2 = domain[2].length();
+ int e3 = domain[3].length();
+ int e4 = domain[4].length();
+ int e5 = domain[5].length();
+ #pragma omp parallel for
+ for (int i5=0; i5<e5; ++i5)
+ for (int i4=0; i4<e4; ++i4)
+ for (int i3=0; i3<e3; ++i3)
+ for (int i2=0; i2<e2; ++i2)
+ for (int i1=0; i1<e1; ++i1) {
+ ;
+ for (int i0=0; i0<e0; ++i0)
+ op(localLHS(i0,i1,i2,i3,i4,i5),
+ localRHS.read(i0,i1,i2,i3,i4,i5));
+ }
+ }
+ template<class LHS,class Op,class RHS,class Domain>
+ inline static void evaluate(const LHS& lhs,const Op& op,const RHS& rhs,
+ const Domain& domain,WrappedInt<7>)
+ {
+ LHS localLHS(lhs);
+ RHS localRHS(rhs);
+ int e0 = domain[0].length();
+ int e1 = domain[1].length();
+ int e2 = domain[2].length();
+ int e3 = domain[3].length();
+ int e4 = domain[4].length();
+ int e5 = domain[5].length();
+ int e6 = domain[6].length();
+ #pragma omp parallel for
+ for (int i6=0; i6<e6; ++i6)
+ for (int i5=0; i5<e5; ++i5)
+ for (int i4=0; i4<e4; ++i4)
+ for (int i3=0; i3<e3; ++i3)
+ for (int i2=0; i2<e2; ++i2)
+ for (int i1=0; i1<e1; ++i1) {
+ ;
+ for (int i0=0; i0<e0; ++i0)
+ op(localLHS(i0,i1,i2,i3,i4,i5,i6),
+ localRHS.read(i0,i1,i2,i3,i4,i5,i6));
+ }
+ }
+ private:
+ };
+ template<>
+ struct KernelEvaluator<CompressibleViewKernelTag>
+ {
+ template<class LHS, class Op, class RHS>
+ static void evaluate(const LHS &lhs, const Op &op, const RHS &rhs)
+ {
+ KernelEvaluator<InlineKernelTag>().
+ evaluate(engineFunctor(lhs, UnCompressedViewEngine()),
+ op, rhs);
+ ;
+ }
+ };
+ template<>
+ struct KernelEvaluator<CompressibleKernelTag>
+ {
+ template<class LHS, class Op, class RHS>
+ static void evaluate(const LHS &lhs, const Op &op, const RHS &rhs)
+ {
+ typedef typename LHS::Element_t LHST_t;
+ typedef typename RHS::Element_t RHST_t;
+ if (engineFunctor(lhs, Compressed()) &&
+ engineFunctor(rhs, Compressed()))
+ {
+ LHST_t &l = engineFunctor(lhs, CompressedReadWrite());
+ LHST_t test = l;
+ RHST_t r = engineFunctor(rhs, CompressedRead());
+ op(test, r);
+ if (test != l)
+ {
+ if (engineFunctor(lhs, CompressedBrickIsWholeView()))
+ {
+ l = test;
+ ;
+ }
+ else
+ {
+ KernelEvaluator<CompressibleViewKernelTag>::
+ evaluate(lhs, op, rhs);
+ }
+ }
+ else
+ {
+ ;
+ }
+ }
+ else
+ {
+ KernelEvaluator<CompressibleViewKernelTag>::evaluate(lhs, op, rhs);
+ }
+ }
+ };
+ struct Brick;
+ struct BrickView;
+ struct BrickViewU;
+ struct CompressibleBrick;
+ struct CompressibleBrickView;
+ struct Dynamic;
+ struct DynamicView;
+ template<class LayoutTag, class PatchTag>
+ struct MultiPatch;
+ template<class LayoutTag, class PatchTag, int Dim2>
+ struct MultiPatchView;
+ template<class Functor>
+ struct IndexFunction;
+ template<int Dim2, class Functor>
+ struct IndexFunctionView;
+ template<class Eng, class Components>
+ struct CompFwd;
+ template<class A1,class A2>
+ struct IndirectionTag;
+ struct ConstantFunction;
+ template<class Expr>
+ struct ExpressionTag;
+ template<class Tag>
+ struct Remote;
+ struct DistributedTag;
+ struct ReplicatedTag;
+ struct ScalarEngineTag
+ {
+ ScalarEngineTag() {}
+ ~ScalarEngineTag() {}
+ };
+ struct MainEvaluatorTag
+ {
+ MainEvaluatorTag() {}
+ ~MainEvaluatorTag() {}
+ };
+ struct SinglePatchEvaluatorTag
+ {
+ SinglePatchEvaluatorTag() {}
+ ~SinglePatchEvaluatorTag() {}
+ };
+ struct MultiPatchEvaluatorTag
+ {
+ MultiPatchEvaluatorTag() {}
+ ~MultiPatchEvaluatorTag() {}
+ };
+ struct RemoteSinglePatchEvaluatorTag
+ {
+ RemoteSinglePatchEvaluatorTag() {}
+ ~RemoteSinglePatchEvaluatorTag() {}
+ };
+ struct RemoteMultiPatchEvaluatorTag
+ {
+ RemoteMultiPatchEvaluatorTag() {}
+ ~RemoteMultiPatchEvaluatorTag() {}
+ };
+ struct EvaluatorTypeTag
+ {
+ EvaluatorTypeTag() {}
+ ~EvaluatorTypeTag() {}
+ };
+ struct EvaluatorCombineTag
+ {
+ EvaluatorCombineTag() {}
+ ~EvaluatorCombineTag() {}
+ };
+ template<class EngineTag>
+ struct EvaluatorEngineTraits
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ };
+ template<>
+ struct EvaluatorEngineTraits<ScalarEngineTag>
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef SinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorEngineTraits<ConstantFunction>
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef SinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<class Functor>
+ struct EvaluatorEngineTraits<IndexFunction<Functor> >
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef SinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<int Dim2, class Functor>
+ struct EvaluatorEngineTraits<IndexFunctionView<Dim2, Functor> >
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef SinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorEngineTraits<Brick>
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef SinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorEngineTraits<BrickView>
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef SinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorEngineTraits<BrickViewU>
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef SinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorEngineTraits<CompressibleBrick>
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef SinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorEngineTraits<CompressibleBrickView>
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef SinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorEngineTraits<Dynamic>
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef SinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorEngineTraits<DynamicView>
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef SinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<class A1,class A2>
+ struct EvaluatorEngineTraits<IndirectionTag<A1,A2> >
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef SinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<class Tag>
+ struct EvaluatorEngineTraits<Remote<Tag> >
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef RemoteSinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<class LayoutTag, class PatchTag>
+ struct EvaluatorEngineTraits<MultiPatch<LayoutTag, PatchTag> >
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef MultiPatchEvaluatorTag Evaluator_t;
+ };
+ template<class LayoutTag, class PatchTag, int Dim2>
+ struct EvaluatorEngineTraits<MultiPatchView<LayoutTag, PatchTag, Dim2> >
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef MultiPatchEvaluatorTag Evaluator_t;
+ };
+ template<class LayoutTag, class Tag>
+ struct EvaluatorEngineTraits<MultiPatch<LayoutTag, Remote<Tag> > >
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef RemoteMultiPatchEvaluatorTag Evaluator_t;
+ };
+ template<class LayoutTag, class Tag, int Dim2>
+ struct EvaluatorEngineTraits<MultiPatchView<LayoutTag, Remote<Tag>, Dim2> >
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef RemoteMultiPatchEvaluatorTag Evaluator_t;
+ };
+ template<class Eng, class Components>
+ struct EvaluatorEngineTraits<CompFwd<Eng, Components> >
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef EvaluatorEngineTraits<typename Eng::Tag_t> ET;
+ typedef typename ET::Evaluator_t Evaluator_t;
+ };
+ template<class Expr>
+ struct EvaluatorEngineTraits<ExpressionTag<Expr> >
+ {
+ EvaluatorEngineTraits() {}
+ ~EvaluatorEngineTraits() {}
+ typedef typename ForEach<Expr, EvaluatorTypeTag,
+ EvaluatorCombineTag>::Type_t Evaluator_t;
+ };
+ template<class ETag>
+ struct DistributionTraits
+ {
+ enum { remote = false };
+ typedef ReplicatedTag LayoutTag_t;
+ };
+ template<class ETag>
+ struct DistributionTraits<Remote<ETag> >
+ {
+ enum { remote = true };
+ typedef DistributedTag LayoutTag_t;
+ };
+ template<class Eval1, class Eval2>
+ struct EvaluatorCombine
+ {
+ EvaluatorCombine() {}
+ ~EvaluatorCombine() {}
+ typedef RemoteMultiPatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorCombine<SinglePatchEvaluatorTag,
+ MultiPatchEvaluatorTag>
+ {
+ EvaluatorCombine() {}
+ ~EvaluatorCombine() {}
+ typedef MultiPatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorCombine<MultiPatchEvaluatorTag,
+ SinglePatchEvaluatorTag>
+ {
+ EvaluatorCombine() {}
+ ~EvaluatorCombine() {}
+ typedef MultiPatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorCombine<RemoteSinglePatchEvaluatorTag,
+ MultiPatchEvaluatorTag>
+ {
+ EvaluatorCombine() {}
+ ~EvaluatorCombine() {}
+ typedef RemoteMultiPatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorCombine<MultiPatchEvaluatorTag,
+ RemoteSinglePatchEvaluatorTag>
+ {
+ EvaluatorCombine() {}
+ ~EvaluatorCombine() {}
+ typedef RemoteMultiPatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorCombine<RemoteSinglePatchEvaluatorTag,
+ SinglePatchEvaluatorTag>
+ {
+ EvaluatorCombine() {}
+ ~EvaluatorCombine() {}
+ typedef RemoteSinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorCombine<SinglePatchEvaluatorTag,
+ RemoteSinglePatchEvaluatorTag>
+ {
+ EvaluatorCombine() {}
+ ~EvaluatorCombine() {}
+ typedef RemoteSinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorCombine<MultiPatchEvaluatorTag,
+ MultiPatchEvaluatorTag>
+ {
+ EvaluatorCombine() {}
+ ~EvaluatorCombine() {}
+ typedef MultiPatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorCombine<RemoteSinglePatchEvaluatorTag,
+ RemoteSinglePatchEvaluatorTag>
+ {
+ EvaluatorCombine() {}
+ ~EvaluatorCombine() {}
+ typedef RemoteSinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<>
+ struct EvaluatorCombine<SinglePatchEvaluatorTag,
+ SinglePatchEvaluatorTag>
+ {
+ EvaluatorCombine() {}
+ ~EvaluatorCombine() {}
+ typedef SinglePatchEvaluatorTag Evaluator_t;
+ };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, EvaluatorTypeTag>
+ {
+ LeafFunctor() {}
+ ~LeafFunctor() {}
+ typedef typename EvaluatorEngineTraits<ScalarEngineTag>::Evaluator_t Type_t;
+ };
+ template<class A>
+ struct LeafFunctor<A, EvaluatorTypeTag>
+ {
+ LeafFunctor() {}
+ ~LeafFunctor() {}
+ typedef typename
+ EvaluatorEngineTraits<typename A::Engine_t::Tag_t>::Evaluator_t Type_t;
+ };
+ template<class Eval1,class Eval2,class Op>
+ struct Combine2<Eval1, Eval2, Op, EvaluatorCombineTag>
+ {
+ Combine2() {}
+ ~Combine2() {}
+ typedef typename EvaluatorCombine<Eval1, Eval2>::Evaluator_t Type_t;
+ };
+ template<class Expr>
+ struct EvaluatorTag1
+ {
+ EvaluatorTag1() {}
+ ~EvaluatorTag1() {}
+ typedef typename LeafFunctor<Expr, EvaluatorTypeTag>::Type_t Evaluator_t;
+ };
+ template<class LHS, class RHS>
+ struct EvaluatorTag
+ {
+ EvaluatorTag() {}
+ ~EvaluatorTag() {}
+ typedef typename LeafFunctor<LHS, EvaluatorTypeTag>::Type_t LHSEval_t;
+ typedef typename LeafFunctor<RHS, EvaluatorTypeTag>::Type_t RHSEval_t;
+ typedef typename EvaluatorCombine<LHSEval_t, RHSEval_t>::Evaluator_t
+ Evaluator_t;
+ };
+ template<class LHS,class Op,class RHS,class EvalTag>
+ class ExpressionKernel : public Pooma::Iterate_t
+ {
+ public:
+ typedef ExpressionKernel<LHS,Op,RHS,EvalTag> This_t;
+ ExpressionKernel(const LHS&,const Op&,const RHS&);
+ virtual ~ExpressionKernel();
+ virtual void /*__attribute__((leafify))*/ run();
+ private:
+ LHS lhs_m;
+ Op op_m;
+ RHS rhs_m;
+ };
+ template<class LHS,class Op,class RHS,class EvalTag>
+ ExpressionKernel<LHS,Op,RHS,EvalTag>::
+ ExpressionKernel(const LHS& lhs,const Op& op,const RHS& rhs)
+ : Pooma::Iterate_t(Pooma::scheduler()),
+ lhs_m(lhs), op_m(op), rhs_m(rhs)
+ {
+ hintAffinity(engineFunctor(lhs, DataObjectRequest<BlockAffinity>()));
+ DataObjectRequest<WriteRequest> writeReq(*this);
+ engineFunctor(lhs_m, writeReq);
+ DataObjectRequest<ReadRequest> readReq(writeReq);
+ engineFunctor(rhs_m, readReq);
+ }
+ template<class LHS,class Op,class RHS,class EvalTag>
+ ExpressionKernel<LHS,Op,RHS,EvalTag>::~ExpressionKernel()
+ {
+ DataObjectRequest<WriteRelease> writeReq;
+ engineFunctor(lhs_m, writeReq);
+ DataObjectRequest<ReadRelease> readReq(writeReq);
+ engineFunctor(rhs_m, readReq);
+ }
+ template<class LHS,class Op,class RHS,class EvalTag>
+ void
+ ExpressionKernel<LHS,Op,RHS,EvalTag>::run()
+ {
+ KernelEvaluator<EvalTag>::evaluate(lhs_m,op_m,rhs_m);
+ }
+ template<class LHS,class Op,class RHS,class EvalTag>
+ inline static
+ ExpressionKernel<LHS,Op,RHS,EvalTag>*
+ generateKernel(const LHS& lhs, const Op& op, const RHS& rhs, const EvalTag&)
+ {
+ return new ExpressionKernel<LHS,Op,RHS,EvalTag>(lhs, op, rhs);
+ }
+ template<int Dim>
+ class IntersectorData
+ : public RefCounted
+ {
+ public:
+ typedef IntersectorData<Dim> This_t;
+ typedef std::vector<int> IDContainer_t;
+ typedef Range<7> BaseDomain_t;
+ typedef std::vector<BaseDomain_t> BaseDomainContainer_t;
+ typedef INode<Dim> INode_t;
+ typedef std::vector<INode_t> INodeContainer_t;
+ typedef typename INodeContainer_t::const_iterator const_iterator;
+ typedef Unique::Value_t LayoutID_t;
+ enum { dimensions = Dim };
+ inline IntersectorData() { }
+ inline ~IntersectorData() { }
+ template<class Engine>
+ void intersect(const Engine &engine)
+ {
+ typedef typename Engine::Layout_t Layout_t;
+ const Layout_t &layout(engine.layout());
+ int n = ids_m.size();
+ for (int i = 0; i < n; ++i)
+ {
+ if (ids_m[i] == layout.ID())
+ return;
+ if (baseIDs_m[i] == layout.baseID()
+ && sameBaseDomain(i, layout.baseDomain()))
+ {
+ shared(layout.ID(),ids_m[i]);
+ return;
+ }
+ }
+ touches(layout);
+ }
+ template<class Engine, int Dim2>
+ bool intersect(const Engine &engine, const GuardLayers<Dim2> &guard,
+ GuardLayers<Dim2> &usedGuards)
+ {
+ PoomaCTAssert<(Engine::dimensions == Dim)>::test();
+ typedef typename Engine::Layout_t Layout_t;
+ const Layout_t &layout(engine.layout());
+ int n = ids_m.size();
+ for (int i = 0; i < n; ++i)
+ {
+ if (ids_m[i] == layout.ID())
+ return false;
+ if (baseIDs_m[i] == layout.baseID()
+ && sameBaseDomain(i, layout.baseDomain(), guard))
+ {
+ shared(layout.ID(),ids_m[i]);
+ if (baseDims_m[i] < Dim2)
+ return true;
+ bool used = false;
+ for (int j = 0; j < Dim2; j++)
+ {
+ usedGuards.lower(j) = std::max(0, baseDomains_m[i][j].first() - layout.baseDomain()[j].first());
+ if (usedGuards.lower(j) != 0)
+ used = true;
+ usedGuards.upper(j) = std::max(0, layout.baseDomain()[j].last() - baseDomains_m[i][j].last());
+ if (usedGuards.upper(j) != 0)
+ used = true;
+ }
+ return used;
+ }
+ }
+ touches(layout);
+ return false;
+ }
+ template<int Dim2>
+ bool sameBaseDomain(int i, const Range<Dim2> &domain,
+ const GuardLayers<Dim2> &guard)
+ {
+ if (baseDims_m[i] != Dim2)
+ return false;
+ for (int j = 0; j < Dim2; j++)
+ {
+ if (baseDomains_m[i][j].stride() != domain[j].stride()) return false;
+ if (baseDomains_m[i][j].first() > domain[j].first() + guard.lower(j))
+ return false;
+ if (baseDomains_m[i][j].last() < domain[j].last() - guard.upper(j))
+ return false;
+ }
+ return true;
+ }
+ template<int Dim2>
+ bool sameBaseDomain(int i, const Range<Dim2> &domain)
+ {
+ if (baseDims_m[i] != Dim2)
+ return false;
+ for (int j = 0; j < Dim2; j++)
+ if (baseDomains_m[i][j] != domain[j]) return false;
+ return true;
+ }
+ template<int Dim2>
+ bool sameBaseDomain(int i, const Interval<Dim2> &domain,
+ const GuardLayers<Dim2> & guard)
+ {
+ if (baseDims_m[i] != Dim2)
+ return false;
+ for (int j = 0; j < Dim2; j++)
+ {
+ if (baseDomains_m[i][j].stride() != 1) return false;
+ if (baseDomains_m[i][j].first() > domain[j].first() + guard.lower(j))
+ return false;
+ if (baseDomains_m[i][j].last() < domain[j].last() - guard.upper(j))
+ return false;
+ }
+ return true;
+ }
+ template<int Dim2>
+ void pushBaseDomain(const Range<Dim2> &domain)
+ {
+ int i = baseDomains_m.size();
+ baseDims_m.push_back(Dim2);
+ baseDomains_m.push_back(BaseDomain_t());
+ for (int j = 0; j < Dim2; j++)
+ baseDomains_m[i][j] =
+ Range<1>(domain[j].first(), domain[j].last(), domain[j].stride());
+ }
+ template<int Dim2>
+ bool sameBaseDomain(int i, const Interval<Dim2> &domain)
+ {
+ if (baseDims_m[i] != Dim2)
+ return false;
+ for (int j = 0; j < Dim2; j++)
+ if (baseDomains_m[i][j] != domain[j]) return false;
+ return true;
+ }
+ template<int Dim2>
+ void pushBaseDomain(const Interval<Dim2> &domain)
+ {
+ int i = baseDomains_m.size();
+ baseDims_m.push_back(Dim2);
+ baseDomains_m.push_back(BaseDomain_t());
+ for (int j = 0; j < Dim2; j++)
+ baseDomains_m[i][j] =
+ Range<1>(domain[j].first(), domain[j].last(), domain[j].stride());
+ }
+ template<class Layout>
+ void touches(const Layout &l)
+ {
+ int n = ids_m.size();
+ ids_m.push_back(l.ID());
+ baseIDs_m.push_back(l.baseID());
+ pushBaseDomain(l.baseDomain());
+ if (n == 0)
+ {
+ typename Layout::const_iterator p = l.beginGlobal();
+ while (p != l.endGlobal())
+ {
+ if (! (*p).domain().empty())
+ inodes_m.push_back(INode_t(*p,l.ID(),
+ &(gidStore_m)));
+ ++p;
+ }
+ }
+ else
+ {
+ int ni = inodes_m.size();
+ for (int i = 0; i < ni; i++)
+ l.touches(inodes_m[i].domain(),
+ std::back_inserter(inodes_m),
+ inodes_m[i].touchesConstructINode(l.ID())
+ );
+ inodes_m.erase(inodes_m.begin(),
+ inodes_m.begin() + ni);
+ }
+ }
+ inline
+ void shared(LayoutID_t id1, LayoutID_t id2)
+ {
+ gidStore_m.shared(id1,id2);
+ }
+ IntersectorData(const This_t &);
+ This_t &operator=(const This_t &);
+ IDContainer_t ids_m, baseIDs_m, baseDims_m;
+ BaseDomainContainer_t baseDomains_m;
+ INodeContainer_t inodes_m;
+ GlobalIDDataBase gidStore_m;
+ };
+ template<int Dim>
+ class Intersector
+ {
+ public:
+ typedef IntersectorData<Dim> IntersectorData_t;
+ typedef Intersector<Dim> This_t;
+ typedef typename IntersectorData_t::IDContainer_t IDContainer_t;
+ typedef typename IntersectorData_t::BaseDomain_t BaseDomain_t;
+ typedef typename IntersectorData_t::BaseDomainContainer_t
+ BaseDomainContainer_t;
+ typedef typename IntersectorData_t::INode_t INode_t;
+ typedef typename IntersectorData_t::INodeContainer_t INodeContainer_t;
+ typedef typename IntersectorData_t::const_iterator const_iterator;
+ typedef RefCountedPtr<IntersectorData_t> DataPtr_t;
+ enum { dimensions = Dim };
+ Intersector()
+ : pdata_m(new IntersectorData_t())
+ { }
+ Intersector(const This_t &model)
+ : pdata_m(model.pdata_m)
+ { }
+ This_t &operator=(const This_t &model)
+ {
+ if (this != &model)
+ pdata_m = model.pdata_m;
+ return *this;
+ }
+ ~Intersector() { }
+ inline DataPtr_t &data() { return pdata_m; }
+ inline const DataPtr_t &data() const { return pdata_m; }
+ inline const_iterator begin() const { return data()->inodes_m.begin(); }
+ inline const_iterator end() const { return data()->inodes_m.end(); }
+ inline int size() const { return data()->inodes_m.size(); }
+ template<class Engine>
+ inline
+ void intersect(const Engine &l)
+ {
+ data()->intersect(l);
+ }
+ template<class Engine, int Dim2>
+ inline
+ bool intersect(const Engine &l, const GuardLayers<Dim2> &guard, GuardLayers<Dim2> &usedGuards)
+ {
+ return (data()->intersect(l,guard,usedGuards));
+ }
+ private:
+ DataPtr_t pdata_m;
+ };
+ template <class EvalTag>
+ struct Evaluator
+ {
+ };
+ template <>
+ struct Evaluator<MainEvaluatorTag>
+ {
+ Evaluator() { }
+ ~Evaluator() { }
+ template <class LHS, class RHS, class Op>
+ void evaluate(const LHS& lhs, const Op& op, const RHS& rhs) const
+ {
+ typedef typename EvaluatorTag<LHS, RHS>::Evaluator_t Eval_t;
+ Evaluator<Eval_t> evaluator;
+ Pooma::beginExpression();
+ evaluator.evaluate(lhs(), op, rhs());
+ notifyEngineWrite(lhs.engine());
+ Pooma::endExpression();
+ ;
+ }
+ template <class LHS, class RHS, class Op>
+ void evaluateZeroBased(const LHS& lhs, const Op& op, const RHS& rhs) const
+ {
+ typedef typename EvaluatorTag<LHS, RHS>::Evaluator_t Eval_t;
+ Evaluator<Eval_t> evaluator;
+ Pooma::beginExpression();
+ evaluator.evaluate(lhs, op, rhs);
+ notifyEngineWrite(lhs.engine());
+ Pooma::endExpression();
+ ;
+ }
+ };
+ template <>
+ struct Evaluator<SinglePatchEvaluatorTag>
+ {
+ Evaluator() { }
+ ~Evaluator() { }
+ template <class LHS, class RHS, class Op>
+ void evaluate(const LHS& lhs, const Op& op, const RHS& rhs) const
+ {
+ typedef typename KernelTag<LHS,RHS>::Kernel_t Kernel_t;
+ Pooma::Iterate_t *iterate = ::generateKernel(lhs, op, rhs, Kernel_t());
+ Pooma::scheduler().handOff(iterate);
+ }
+ };
+ template <>
+ struct Evaluator<MultiPatchEvaluatorTag>
+ {
+ Evaluator() { }
+ ~Evaluator() { }
+ template <class LHS, class RHS, class Op>
+ void evaluate(const LHS& lhs, const Op& op, const RHS& rhs) const
+ {
+ typedef Intersector<LHS::dimensions> Inter_t;
+ Inter_t inter;
+ expressionApply(lhs, IntersectorTag<Inter_t>(inter));
+ expressionApply(rhs, IntersectorTag<Inter_t>(inter));
+ typename Inter_t::const_iterator i = inter.begin();
+ while (i != inter.end())
+ {
+ Evaluator<SinglePatchEvaluatorTag>().evaluate(lhs(*i), op, rhs(*i));
+ ++i;
+ }
+ ;
+ ;
+ }
+ };
+ template<class T>
+ struct MaskAssign
+ {
+ MaskAssign() { }
+ MaskAssign(bool q) : cond_m(q) { }
+ MaskAssign(bool q, const T& v) : cond_m(q), value_m(v) { }
+ ~MaskAssign() { }
+ inline bool defined() const { return cond_m; }
+ inline const T &value() const { return value_m; }
+ inline bool operator!=(const MaskAssign<T> &other) const
+ {
+ if (defined())
+ {
+ return ((other.defined() != defined()) || (other.value() != value()));
+ }
+ else
+ {
+ return other.defined();
+ }
+ }
+ MaskAssign(const MaskAssign<T> &) { }
+ MaskAssign<T> &operator=(const MaskAssign<T> &) { return *this; }
+ bool cond_m;
+ T value_m;
+ };
+ template<class Op>
+ struct OpMask
+ {
+ OpMask() { }
+ OpMask(const Op &op) : op_m(op) { }
+ ~OpMask() { }
+ template<class T1, class T2>
+ inline void
+ operator()(T1 &a, const MaskAssign<T2> &b) const
+ {
+ if (b.defined())
+ {
+ op_m(a, b.value());
+ }
+ }
+ template<class T1, class T2>
+ inline void
+ operator()(T1 &a, const T2 &b) const
+ {
+ op_m(a, b);
+ }
+ Op op_m;
+ };
+ template<class T1, class T2, class Op>
+ struct BinaryReturn<T1, T2, OpMask<Op> >
+ {
+ typedef T1 &Type_t;
+ };
+ #ifdef _OPENMP
+ #include <omp.h>
+ #endif
+ template <class Op, class T>
+ struct ReductionTraits;
+ template <class Op, class T>
+ struct ReductionTraits<OpMask<Op>, T>
+ {
+ static T identity() { return ReductionTraits<Op, T>::identity(); }
+ };
+ struct WhereMask
+ {
+ WhereMask() { }
+ WhereMask(const WhereMask &) { }
+ WhereMask &operator=(const WhereMask &) { return *this; }
+ ~WhereMask() { }
+ };
+ template<class T1, class T2>
+ struct BinaryReturn<T1, T2, WhereMask>
+ {
+ typedef MaskAssign<T2> Type_t;
+ };
+ template<class A, class B, class FTag>
+ struct ForEach< BinaryNode<WhereMask, A, B>, FTag, OpCombine >
+ {
+ typedef typename ForEach<A,FTag,OpCombine>::Type_t TypeA_t;
+ typedef typename ForEach<B,FTag,OpCombine>::Type_t TypeB_t;
+ typedef MaskAssign<TypeB_t> Type_t;
+ inline
+ static Type_t
+ apply(const BinaryNode<WhereMask,A,B>& expr,
+ const FTag &f, const OpCombine &c)
+ {
+ bool mask = forEach(expr.left(), f, c);
+ if ( mask )
+ {
+ return Type_t(mask, forEach(expr.right(), f, c));
+ }
+ else
+ {
+ return Type_t(mask);
+ }
+ }
+ };
+ struct FarLeftTag;
+ template<class A, class B>
+ struct ForEach< BinaryNode<WhereMask, A, B>, FarLeftTag, FarLeftTag >
+ {
+ typedef typename ForEach<B,FarLeftTag,FarLeftTag>::Type_t Type_t;
+ inline
+ static Type_t
+ apply(const BinaryNode<WhereMask,A,B>& expr,
+ const FarLeftTag &f, const FarLeftTag &c)
+ {
+ return forEach(expr.right(), f, c);
+ }
+ };
+ template<class A, class T>
+ struct ForEach< BinaryNode<WhereMask, A, Scalar<T> >, FarLeftTag, FarLeftTag >
+ {
+ typedef typename ForEach<A,FarLeftTag,FarLeftTag>::Type_t Type_t;
+ inline
+ static Type_t
+ apply(const BinaryNode<WhereMask,A,Scalar<T> >& expr,
+ const FarLeftTag &f, const FarLeftTag &c)
+ {
+ return forEach(expr.left(), f, c);
+ }
+ };
+ template<class A, class B>
+ struct ForEachRef< BinaryNode<WhereMask, A, B>, FarLeftTag, FarLeftTag >
+ {
+ typedef typename ForEach<B,FarLeftTag,FarLeftTag>::Type_t Type_t;
+ inline
+ static const Type_t&
+ apply(const BinaryNode<WhereMask,A,B>& expr,
+ const FarLeftTag &f, const FarLeftTag &c)
+ {
+ return forEachRef(expr.right(), f, c);
+ }
+ };
+ template<class A, class T>
+ struct ForEachRef< BinaryNode<WhereMask, A, Scalar<T> >, FarLeftTag, FarLeftTag >
+ {
+ typedef typename ForEach<A,FarLeftTag,FarLeftTag>::Type_t Type_t;
+ inline
+ static const Type_t&
+ apply(const BinaryNode<WhereMask,A,Scalar<T> >& expr,
+ const FarLeftTag &f, const FarLeftTag &c)
+ {
+ return forEachRef(expr.left(), f, c);
+ }
+ };
+ template<class T>
+ struct ExpressionTraits
+ {
+ typedef void Type_t;
+ };
+ struct ExpressionIsScalar { };
+ template<class T>
+ struct ExpressionTraits<Scalar<T> >
+ {
+ typedef ExpressionIsScalar Type_t;
+ };
+ template<class A, class B>
+ struct CombineExpressionTraits
+ { };
+ template<class T>
+ struct ExpressionTraits<Reference<T> >
+ {
+ typedef typename ExpressionTraits<T>::Type_t Type_t;
+ };
+ template<class Op, class Child>
+ struct ExpressionTraits<UnaryNode<Op, Child> >
+ {
+ typedef typename ExpressionTraits<Child>::Type_t Type_t;
+ };
+ template<class Op, class Left, class Right>
+ struct ExpressionTraits<BinaryNode<Op, Left, Right> >
+ {
+ typedef typename ExpressionTraits<Left>::Type_t Left_t;
+ typedef typename ExpressionTraits<Right>::Type_t Right_t;
+ typedef typename CombineExpressionTraits<Left_t, Right_t>::Type_t Type_t;
+ };
+ template<class Op, class Left, class Middle, class Right>
+ struct ExpressionTraits<TrinaryNode<Op, Left, Middle, Right> >
+ {
+ typedef typename ExpressionTraits<Left>::Type_t Left_t;
+ typedef typename ExpressionTraits<Middle>::Type_t Middle_t;
+ typedef typename ExpressionTraits<Right>::Type_t Right_t;
+ typedef typename CombineExpressionTraits<Left_t, Right_t>::Type_t Temp_t;
+ typedef typename CombineExpressionTraits<Temp_t, Middle_t>::Type_t Type_t;
+ };
+ template<class ETrait, class Tree>
+ struct ConvertWhereProxy
+ { };
+ template<class F, class B>
+ struct WhereProxy
+ {
+ template <class Cond, class Val, class F1, class B1>
+ struct WhereProxyTraits {
+ enum { dimensions = F1::dimensions };
+ typedef typename ForEach<Val, EvalLeaf<dimensions>, OpCombine>::Type_t Element_t;
+ };
+ template <class Cond, class T, class F1, class B1>
+ struct WhereProxyTraits<Cond, Scalar<T>, F1, B1> {
+ enum { dimensions = F1::dimensions };
+ typedef T Element_t;
+ };
+ template <class Val, class T, class F1, class B1>
+ struct WhereProxyTraits<Scalar<T>, Val, F1, B1> {
+ enum { dimensions = B1::dimensions };
+ typedef typename ForEach<Val, EvalLeaf<dimensions>, OpCombine>::Type_t Element_t;
+ };
+ template <class T1, class T2, class F1, class B1>
+ struct WhereProxyTraits<Scalar<T1>, Scalar<T2>, F1, B1> {
+ };
+ WhereProxy(const F& f, const B& b) : f_m(f), b_m(b) { }
+ typedef BinaryNode<WhereMask,
+ typename CreateLeaf<F>::Leaf_t,
+ typename CreateLeaf<B>::Leaf_t> Tree_t;
+ typedef typename ExpressionTraits<Tree_t>::Type_t ETrait_t;
+ typedef typename ConvertWhereProxy<ETrait_t,Tree_t>::Make_t MakeFromTree_t;
+ typedef typename MakeFromTree_t::Expression_t WhereMask_t;
+ typedef typename WhereProxyTraits<typename CreateLeaf<F>::Leaf_t,
+ typename CreateLeaf<B>::Leaf_t, F, B>::Element_t Element_t;
+ inline WhereMask_t
+ whereMask() const
+ {
+ return MakeFromTree_t::make(Tree_t(CreateLeaf<F>::make(f_m),
+ CreateLeaf<B>::make(b_m)));
+ }
+ template<class Op>
+ inline OpMask<Op>
+ opMask(const Op &op) const
+ {
+ return OpMask<Op>(op);
+ }
+ inline const F &flag() { return f_m; }
+ inline const B &value() { return b_m; }
+ const F &f_m;
+ const B &b_m;
+ };
+ template<class F, class B>
+ inline WhereProxy<F,B>
+ where(const F &f, const B &b)
+ {
+ return WhereProxy<F,B>(f,b);
+ }
+ template<int D,class T,class E> class Vector;
+ template<int DR, int DC, class T, class E> class TinyMatrix;
+ template<int D, class T, class E> class Tensor;
+ template<int D, class T, class EngineTag> class Tensor;
+ template<class OutputEngineTag, int D, class T, class EngineTag>
+ Tensor<D, T, OutputEngineTag>
+ symmetrize(const Tensor<D, T, EngineTag> &x);
+ struct FnReal
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnReal >::Type_t
+ operator()(const T &a) const
+ {
+ return (real(a));
+ }
+ };
+ struct FnImag
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnImag >::Type_t
+ operator()(const T &a) const
+ {
+ return (imag(a));
+ }
+ };
+ struct FnAbs
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnAbs >::Type_t
+ operator()(const T &a) const
+ {
+ return (std::abs(a));
+ }
+ };
+ struct FnArg
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnArg >::Type_t
+ operator()(const T &a) const
+ {
+ return (arg(a));
+ }
+ };
+ struct FnNorm
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnNorm >::Type_t
+ operator()(const T &a) const
+ {
+ return (norm(a));
+ }
+ };
+ struct FnConj
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnConj >::Type_t
+ operator()(const T &a) const
+ {
+ return (conj(a));
+ }
+ };
+ struct FnPow2
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnPow2 >::Type_t
+ operator()(const T &a) const
+ {
+ return (a*a);
+ }
+ };
+ struct FnPow3
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnPow3 >::Type_t
+ operator()(const T &a) const
+ {
+ return (a*a*a);
+ }
+ };
+ struct FnPow4
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnPow4 >::Type_t
+ operator()(const T &a) const
+ {
+ return (a*a*a*a);
+ }
+ };
+ struct FnMagnitude
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnMagnitude >::Type_t
+ operator()(const T &a) const
+ {
+ return (magnitude(a));
+ }
+ };
+ struct FnTrace
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnTrace >::Type_t
+ operator()(const T &a) const
+ {
+ return (trace(a));
+ }
+ };
+ struct FnDet
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnDet >::Type_t
+ operator()(const T &a) const
+ {
+ return (det(a));
+ }
+ };
+ struct FnTranspose
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnTranspose >::Type_t
+ operator()(const T &a) const
+ {
+ return (transpose(a));
+ }
+ };
+ template<class OutputSymmetry>
+ struct FnSymmetrize
+ {
+
+ template<class T>
+ inline typename UnaryReturn<T, FnSymmetrize<OutputSymmetry> >::Type_t
+ operator()(const T &a) const
+ {
+ return (symmetrize<OutputSymmetry>(a));
+ }
+ };
+ struct FnDot
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnDot >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return dot(a,b);
+ }
+ };
+ struct FnPolar
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnPolar >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (polar(a,b));
+ }
+ };
+ struct FnOuterProduct
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnOuterProduct >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (outerProduct(a,b));
+ }
+ };
+ struct FnOuterProductAsTinyMatrix
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnOuterProductAsTinyMatrix >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (outerProductAsTinyMatrix(a,b));
+ }
+ };
+ struct FnDotDot
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnDotDot >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (dotdot(a,b));
+ }
+ };
+ struct FnMin
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnMin >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return
+ std::min(a, b)
+ ;
+ }
+ };
+ struct FnMax
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnMax >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return
+ std::max(a, b)
+ ;
+ }
+ };
+ struct OpLT2
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpLT2 >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a < b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpLT2 > {
+ typedef bool Type_t;
+ };
+ struct OpLE2
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpLE2 >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a <= b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpLE2 > {
+ typedef bool Type_t;
+ };
+ struct OpGT2
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpGT2 >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a > b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpGT2 > {
+ typedef bool Type_t;
+ };
+ struct OpGE2
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpGE2 >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a >= b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpGE2 > {
+ typedef bool Type_t;
+ };
+ struct OpEQ2
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpEQ2 >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a == b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpEQ2 > {
+ typedef bool Type_t;
+ };
+ struct OpNE2
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, OpNE2 >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ return (a != b);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, OpNE2 > {
+ typedef bool Type_t;
+ };
+ struct FnMinAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnMinAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ const_cast<T1 &>(a) = std::min(a, b)
+ ;
+ return const_cast<T1 &>(a);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, FnMinAssign > {
+ typedef T1 &Type_t;
+ };
+ struct FnMaxAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnMaxAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ const_cast<T1 &>(a) = std::max(a, b)
+ ;
+ return const_cast<T1 &>(a);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, FnMaxAssign > {
+ typedef T1 &Type_t;
+ };
+ struct FnAndAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnAndAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ const_cast<T1 &>(a) = (a && b);
+ return const_cast<T1 &>(a);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, FnAndAssign > {
+ typedef bool Type_t;
+ };
+ struct FnOrAssign
+ {
+
+ template<class T1, class T2>
+ inline typename BinaryReturn<T1, T2, FnOrAssign >::Type_t
+ operator()(const T1 &a, const T2 &b) const
+ {
+ const_cast<T1 &>(a) = (a || b);
+ return const_cast<T1 &>(a);
+ }
+ };
+ template<class T1, class T2 >
+ struct BinaryReturn<T1, T2, FnOrAssign > {
+ typedef bool Type_t;
+ };
+ namespace std {
+ template<class T> class complex;
+ }
+ using std::complex;
+ template<class T>
+ struct UnaryReturn< complex<T>, FnConj >
+ {
+ typedef complex<T> Type_t;
+ };
+ template<class T>
+ struct UnaryReturn<complex<T>, FnReal>
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct UnaryReturn<complex<T>, FnImag>
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct UnaryReturn<complex<T>, FnArg>
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct UnaryReturn<complex<T>, FnNorm>
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct UnaryReturn<T, FnAbs>
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct UnaryReturn<complex<T>, FnAbs>
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct Promote<complex<T>, complex<T> >
+ {
+ typedef complex<T> Type_t;
+ };
+ template<class T>
+ struct Promote<complex<T>, T>
+ {
+ typedef complex<T> Type_t;
+ };
+ template<class T>
+ struct Promote<T, complex<T> >
+ {
+ typedef complex<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn<complex<T>, int, FnPow>
+ {
+ typedef complex<T> Type_t;
+ };
+ template<class T>
+ struct UnaryReturn<T, FnPow2>
+ {
+ typedef typename BinaryReturn<T, T, OpMultiply>::Type_t Type_t;
+ };
+ template<class T>
+ struct UnaryReturn<T, FnPow3>
+ {
+ typedef typename BinaryReturn<T, T, OpMultiply>::Type_t Type_t;
+ };
+ template<class T>
+ struct UnaryReturn<T, FnPow4>
+ {
+ typedef typename BinaryReturn<T, T, OpMultiply>::Type_t Type_t;
+ };
+ template<class T, class A> struct LeafFunctor;
+ template<class T> class Scalar;
+ template<int D>
+ class ConformTag
+ {
+ public:
+ template<class Domain>
+ ConformTag(const Domain& domain)
+ {
+ for (int i=0; i<D; ++i)
+ lengths_m[i] = domain[i].length();
+ }
+ int length(int i) const { return lengths_m[i]; }
+ private:
+ int lengths_m[D];
+ };
+ template<class Domain>
+ bool conforms(const Domain &d, const ConformTag<1> &ct)
+ {
+ return d.length() == ct.length(0);
+ }
+ template<class Domain>
+ bool conforms(const Domain &d, const ConformTag<2> &ct)
+ {
+ return (d[0].length() == ct.length(0))
+ && (d[1].length() == ct.length(1));
+ }
+ template<class Domain>
+ bool conforms(const Domain &d, const ConformTag<3> &ct)
+ {
+ return (d[0].length() == ct.length(0))
+ && (d[1].length() == ct.length(1))
+ && (d[2].length() == ct.length(2));
+ }
+ template<class Domain>
+ bool conforms(const Domain &d, const ConformTag<4> &ct)
+ {
+ return (d[0].length() == ct.length(0))
+ && (d[1].length() == ct.length(1))
+ && (d[2].length() == ct.length(2))
+ && (d[3].length() == ct.length(3));
+ }
+ template<class Domain>
+ bool conforms(const Domain &d, const ConformTag<5> &ct)
+ {
+ return (d[0].length() == ct.length(0))
+ && (d[1].length() == ct.length(1))
+ && (d[2].length() == ct.length(2))
+ && (d[3].length() == ct.length(3))
+ && (d[4].length() == ct.length(4));
+ }
+ template<class Domain>
+ bool conforms(const Domain &d, const ConformTag<6> &ct)
+ {
+ return (d[0].length() == ct.length(0))
+ && (d[1].length() == ct.length(1))
+ && (d[2].length() == ct.length(2))
+ && (d[3].length() == ct.length(3))
+ && (d[3].length() == ct.length(4))
+ && (d[5].length() == ct.length(5));
+ }
+ template<class Domain>
+ bool conforms(const Domain &d, const ConformTag<7> &ct)
+ {
+ return (d[0].length() == ct.length(0))
+ && (d[1].length() == ct.length(1))
+ && (d[2].length() == ct.length(2))
+ && (d[3].length() == ct.length(3))
+ && (d[3].length() == ct.length(4))
+ && (d[5].length() == ct.length(5))
+ && (d[6].length() == ct.length(6));
+ }
+ template<int D, class T>
+ struct LeafFunctor<Scalar<T>, ConformTag<D> >
+ {
+ typedef bool Type_t;
+ static Type_t apply(const Scalar<T> &, const ConformTag<D> &)
+ {
+ return true;
+ }
+ };
+ template<class T, class A> struct LeafFunctor;
+ struct PerformUpdateTag {};
+ template<class Node>
+ struct LeafFunctor<Node, PerformUpdateTag>
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const Node &, const PerformUpdateTag &)
+ {
+ return 0;
+ }
+ };
+ template<class T>
+ class ModelElement
+ {
+ public:
+ explicit ModelElement(const T &e) : e_m(e) { }
+ ModelElement(const ModelElement<T> &m) : e_m(m.e_m) { }
+ const T &element() const { return e_m; }
+ private:
+ const T &e_m;
+ };
+ template<class T>
+ inline ModelElement<T> modelElement(const T &elem)
+ {
+ return ModelElement<T>(elem);
+ }
+ template<class T, class A> struct LeafFunctor;
+ template<class T> class Scalar;
+ struct NotifyPreReadTag { };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, NotifyPreReadTag>
+ {
+ typedef bool Type_t;
+ static Type_t apply(const Scalar<T> &, const NotifyPreReadTag &)
+ {
+ return true;
+ }
+ };
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnArcCos,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ acos(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnArcCos,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnArcSin,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ asin(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnArcSin,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnArcTan,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ atan(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnArcTan,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnCeil,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ ceil(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnCeil,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnCos,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ cos(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnCos,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnHypCos,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ cosh(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnHypCos,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnExp,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ exp(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnExp,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnFabs,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ fabs(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnFabs,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnFloor,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ floor(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnFloor,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnLog,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ log(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnLog,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnLog10,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ log10(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnLog10,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnSin,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ sin(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnSin,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnHypSin,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ sinh(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnHypSin,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnSqrt,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ sqrt(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnSqrt,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnTan,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ tan(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnTan,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnHypTan,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ tanh(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnHypTan,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<OpUnaryMinus,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ operator-(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<OpUnaryMinus,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<OpUnaryPlus,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ operator+(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<OpUnaryPlus,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<OpBitwiseNot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ operator~(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<OpBitwiseNot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<OpIdentity,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ PETE_identity(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<OpIdentity,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<OpNot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ operator!(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<OpNot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<UnaryNode<OpCast<T1>,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ peteCast(const T1&, const Array<D2,T2,E2> & l)
+ {
+ typedef UnaryNode<OpCast<T1>,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D2,T2,E2> >::make(l)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpLT,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLT,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpLE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<=(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpGT,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGT,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpGE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>=(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&&(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator||(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpLeftShift,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<<(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLeftShift,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpRightShift,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>>(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpRightShift,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator+(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator-(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator*(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator/(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator%(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator&(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator|(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator^(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ ldexp(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ pow(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ fmod(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ atan2(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpLT,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator<(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpLT,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpLE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator<=(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpLE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpGT,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator>(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpGT,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpGE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator>=(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpGE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator==(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator!=(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator&&(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator||(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpLeftShift,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator<<(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpLeftShift,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpRightShift,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator>>(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpRightShift,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMod,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnPow,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpLT,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLT,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpLE,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<=(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLE,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpGT,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGT,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpGE,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>=(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGE,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpNE,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpAnd,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&&(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAnd,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpOr,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator||(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpOr,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2,class T3>
+ inline typename MakeReturn<TrinaryNode<FnWhere,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t,
+ typename CreateLeaf<T3 >::Leaf_t> >::Expression_t
+ where(const Array<D1,T1,E1> & c,const T2 & t,const T3 & f)
+ {
+ typedef TrinaryNode<FnWhere,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t,
+ typename CreateLeaf<T3 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(c),
+ CreateLeaf<T2 >::make(t),
+ CreateLeaf<T3 >::make(f)));
+ }
+ template<int D, class T, class EngineTag> class Tensor;
+ template<class OutputEngineTag, int D, class T, class EngineTag>
+ Tensor<D, T, OutputEngineTag>
+ symmetrize(const Tensor<D, T, EngineTag> &x);
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnReal,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ real(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnReal,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnImag,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ imag(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnImag,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnAbs,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ abs(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnAbs,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnArg,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ arg(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnArg,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnNorm,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ norm(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnNorm,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnConj,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ conj(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnConj,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnPow2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ pow2(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnPow2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnPow3,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ pow3(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnPow3,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnPow4,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ pow4(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnPow4,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnMagnitude,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ magnitude(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnMagnitude,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnTrace,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ trace(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnTrace,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnDet,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ det(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnDet,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnTranspose,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ transpose(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnTranspose,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<class OutputSymmetry,int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnSymmetrize<OutputSymmetry>,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ symmetrize(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnSymmetrize<OutputSymmetry>,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnPolar,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ polar(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPolar,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnOuterProduct,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ outerProduct(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnOuterProduct,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ outerProductAsTinyMatrix(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnDotDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ dotdot(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDotDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnMin,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ min(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnMin,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnMax,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ max(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnMax,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpLT2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ LT(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLT2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpLE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ LE(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpGT2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ GT(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGT2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpGE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ GE(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpEQ2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ EQ(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpNE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ NE(const Array<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ dot(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<FnPolar,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ polar(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnPolar,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<FnOuterProduct,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ outerProduct(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnOuterProduct,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ outerProductAsTinyMatrix(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<FnDotDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ dotdot(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnDotDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<FnMin,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ min(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnMin,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<FnMax,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ max(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnMax,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpLT2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ LT(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpLT2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpLE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ LE(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpLE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpGT2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ GT(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpGT2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpGE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ GE(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpGE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpEQ2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ EQ(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpEQ2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class T2>
+ inline typename MakeReturn<BinaryNode<OpNE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ NE(const Array<D1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpNE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnDot,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnPolar,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ polar(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPolar,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnOuterProduct,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ outerProduct(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnOuterProduct,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ outerProductAsTinyMatrix(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnDotDot,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ dotdot(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDotDot,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnMin,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ min(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnMin,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnMax,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ max(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnMax,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpLT2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ LT(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLT2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpLE2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ LE(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLE2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpGT2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ GT(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGT2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpGE2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ GE(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGE2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpEQ2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ EQ(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class T1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpNE2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ NE(const T1 & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<BinaryNode<FnMin,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ min(const Array<D1,T1,E1> & l,const Array<D1,T1,E1> & r)
+ {
+ typedef BinaryNode<FnMin,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D1,T1,E1> >::make(r)));
+ }
+ template<int D1,class T1,class E1>
+ inline typename MakeReturn<BinaryNode<FnMax,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ max(const Array<D1,T1,E1> & l,const Array<D1,T1,E1> & r)
+ {
+ typedef BinaryNode<FnMax,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D1,T1,E1> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const Array<D1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const Array<D1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const Array<D1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpMod,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnDot,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnPow,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const Vector<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const Tensor<D1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeReturn<BinaryNode<OpNE,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const TinyMatrix<DR1,DC1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<int Dim, class T, class EngineTag>
+ struct CreateLeaf<Array<Dim, T, EngineTag> >
+ {
+ typedef Array<Dim, T, EngineTag> Input_t;
+ typedef Reference<Input_t> Leaf_t;
+ typedef Leaf_t Return_t;
+ inline static
+ Return_t make(const Input_t &a)
+ {
+ return Leaf_t(a);
+ }
+ };
+ template<int Dim, class T, class Expr>
+ struct CreateLeaf<Array<Dim, T, ExpressionTag<Expr> > >
+ {
+ typedef Array<Dim, T, ExpressionTag<Expr> > Input_t;
+ typedef Expr Leaf_t;
+ typedef const Leaf_t &Return_t;
+ inline static
+ Return_t make(const Input_t &a)
+ {
+ return a.engine().expression();
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct CreateLeaf<Scalar<Array<Dim, T, EngineTag> > >
+ {
+ typedef Scalar<Array<Dim, T, EngineTag> > Input_t;
+ typedef Scalar<ErrorType> Leaf_t;
+ typedef Leaf_t Return_t;
+ inline static
+ Return_t make(const Input_t &)
+ {
+ return ErrorType();
+ }
+ };
+ template<class Op,class Leaf>
+ struct MakeReturn<UnaryNode<Op,Leaf> >
+ {
+ typedef UnaryNode<Op,Leaf> Tree_t;
+ typedef typename ForEach<Tree_t,
+ DomainFunctorTag, DomainFunctorTag>::Type_t Domain_t;
+ enum { dim = Domain_t::dimensions };
+ typedef typename UnaryReturn<typename ForEach<Leaf,
+ EvalLeaf<dim>,OpCombine>::Type_t,
+ Op>::Type_t T_t;
+ typedef Engine<dim,T_t,ExpressionTag<Tree_t> > Engine_t;
+ typedef Array<dim,T_t,ExpressionTag<Tree_t > > Expression_t;
+ inline static
+ Expression_t make(const Tree_t &tree)
+ {
+ return Expression_t(Engine_t(tree));
+ }
+ };
+ template<class Op,class Left,class Right>
+ struct MakeReturn<BinaryNode<Op,Left,Right> >
+ {
+ typedef BinaryNode<Op,Left,Right> Tree_t;
+ typedef typename ForEach<Tree_t,
+ DomainFunctorTag, DomainFunctorTag>::Type_t Domain_t;
+ enum { dim = Domain_t::dimensions };
+ typedef typename BinaryReturn<typename ForEach<Left,
+ EvalLeaf<dim>,OpCombine>::Type_t,
+ typename ForEach<Right,EvalLeaf<dim>,OpCombine>::Type_t,
+ Op>::Type_t T_t;
+ typedef Engine<dim,T_t,ExpressionTag<Tree_t> > Engine_t;
+ typedef Array<dim,T_t,ExpressionTag<Tree_t > > Expression_t;
+ inline static
+ Expression_t make(const Tree_t &tree)
+ {
+ return Expression_t(Engine_t(tree));
+ }
+ };
+ template<class Op,class Cl,class Tr,class Fl>
+ struct MakeReturn<TrinaryNode<Op,Cl,Tr,Fl> >
+ {
+ typedef TrinaryNode<Op,Cl,Tr,Fl> Tree_t;
+ typedef typename ForEach<Tree_t,
+ DomainFunctorTag, DomainFunctorTag>::Type_t Domain_t;
+ enum { dim = Domain_t::dimensions };
+ typedef typename TrinaryReturn<typename ForEach<Cl,
+ EvalLeaf<dim>,OpCombine>::Type_t,
+ typename ForEach<Tr,EvalLeaf<dim>,OpCombine>::Type_t,
+ typename ForEach<Fl,EvalLeaf<dim>,OpCombine>::Type_t,
+ Op>::Type_t T_t;
+ typedef Engine<dim,T_t,ExpressionTag<Tree_t> > Engine_t;
+ typedef Array<dim,T_t,ExpressionTag<Tree_t > > Expression_t;
+ inline static
+ Expression_t make(const Tree_t &tree)
+ {
+ return Expression_t(Engine_t(tree));
+ }
+ };
+ template<class Op, class T>
+ struct ReductionTraits {
+ };
+ template<class T>
+ struct ReductionTraits<OpAddAssign, T> {
+ static inline T identity() { return T(0); }
+ };
+ template<class T>
+ struct ReductionTraits<OpMultiplyAssign, T> {
+ static inline T identity() { return T(1); }
+ };
+ template<class T>
+ struct ReductionTraits<FnMinAssign, T> {
+ static inline T identity() { return std::numeric_limits<T>::max(); }
+ };
+ template<class T>
+ struct ReductionTraits<FnMaxAssign, T> {
+ static inline T identity() { return std::numeric_limits<T>::min(); }
+ };
+ template<class T>
+ struct ReductionTraits<FnOrAssign, T> {
+ static inline T identity() { return T(false); }
+ };
+ template<class T>
+ struct ReductionTraits<FnAndAssign, T> {
+ static inline T identity() { return T(true); }
+ };
+ template<class T>
+ struct ReductionTraits<OpBitwiseOrAssign, T> {
+ static inline T identity() { return T(); }
+ };
+ template<class T>
+ struct ReductionTraits<OpBitwiseAndAssign, T> {
+ static inline T identity() { return ~T(); }
+ };
+ #ifndef _OPENMP
+ template<class T>
+ struct PartialReduction {
+ static inline void init() {}
+ inline void storePartialResult(const T& result)
+ {
+ answer = result;
+ }
+ template <class Op>
+ inline void reduce(T& ret, const Op&)
+ {
+ ret = answer;
+ }
+ T answer;
+ };
+ #else
+ template<class T>
+ struct PartialReduction {
+ static inline void init()
+ {
+ if (!answer)
+ answer = new T[omp_get_max_threads()];
+ }
+ inline void storePartialResult(const T& result)
+ {
+ int n = omp_get_thread_num();
+ answer[n] = result;
+ if (n == 0)
+ num_threads = omp_get_num_threads();
+ }
+ template <class Op>
+ inline void reduce(T& ret, const Op& op)
+ {
+ T res = answer[0];
+ for (int i = 1; i<num_threads; ++i)
+ op(res, answer[i]);
+ ret = res;
+ }
+ int num_threads;
+ static T *answer;
+ };
+ template <class T>
+ T *PartialReduction<T>::answer = NULL;
+ #endif
+ template<class KernelTag>
+ struct ReductionEvaluator;
+ template<>
+ struct ReductionEvaluator<InlineKernelTag>
+ {
+ template<class T, class Op, class Expr>
+ static /*__attribute__((leafify))*/
+ void evaluate(T &ret, const Op &op, const Expr &e)
+ {
+ typedef typename Expr::Domain_t Domain_t;
+ PoomaCTAssert<(Domain_t::unitStride)>::test();
+ for (int i=0; i<Domain_t::dimensions; ++i)
+ ;
+ PartialReduction<T>::init();
+ evaluate(ret, op, e, e.domain(),
+ WrappedInt<Domain_t::dimensions>());
+ }
+ template<class T, class Op, class Expr, class Domain>
+ inline static void evaluate(T &ret, const Op &op, const Expr &e,
+ const Domain &domain, WrappedInt<1>)
+ {
+ Expr localExpr(e);
+ int e0 = domain[0].length();
+ PartialReduction<T> reduction;
+ #pragma omp parallel if (e0 > 512)
+ {
+ T answer = ReductionTraits<Op, T>::identity();
+ ;
+ #pragma omp for nowait
+ for (int i0 = 0; i0 < e0; ++i0)
+ op(answer, localExpr.read(i0));
+ reduction.storePartialResult(answer);
+ }
+ reduction.reduce(ret, op);
+ }
+ template<class T, class Op, class Expr, class Domain>
+ inline static void evaluate(T &ret, const Op &op, const Expr &e,
+ const Domain &domain, WrappedInt<2>)
+ {
+ Expr localExpr(e);
+ int e0 = domain[0].length();
+ int e1 = domain[1].length();
+ PartialReduction<T> reduction;
+ #pragma omp parallel
+ {
+ T answer = ReductionTraits<Op, T>::identity();
+ #pragma omp for nowait
+ for (int i1 = 0; i1 < e1; ++i1) {
+ ;
+ for (int i0 = 0; i0 < e0; ++i0)
+ op(answer, localExpr.read(i0, i1));
+ }
+ reduction.storePartialResult(answer);
+ }
+ reduction.reduce(ret, op);
+ }
+ template<class T, class Op, class Expr, class Domain>
+ inline static void evaluate(T &ret, const Op &op, const Expr &e,
+ const Domain &domain, WrappedInt<3>)
+ {
+ Expr localExpr(e);
+ int e0 = domain[0].length();
+ int e1 = domain[1].length();
+ int e2 = domain[2].length();
+ PartialReduction<T> reduction;
+ #pragma omp parallel
+ {
+ T answer = ReductionTraits<Op, T>::identity();
+ #pragma omp for nowait
+ for (int i2 = 0; i2 < e2; ++i2)
+ for (int i1 = 0; i1 < e1; ++i1) {
+ ;
+ for (int i0 = 0; i0 < e0; ++i0)
+ op(answer, localExpr.read(i0, i1, i2));
+ }
+ reduction.storePartialResult(answer);
+ }
+ reduction.reduce(ret, op);
+ }
+ template<class T, class Op, class Expr, class Domain>
+ inline static void evaluate(T &ret, const Op &op, const Expr &e,
+ const Domain &domain, WrappedInt<4>)
+ {
+ Expr localExpr(e);
+ int e0 = domain[0].length();
+ int e1 = domain[1].length();
+ int e2 = domain[2].length();
+ int e3 = domain[3].length();
+ PartialReduction<T> reduction;
+ #pragma omp parallel
+ {
+ T answer = ReductionTraits<Op, T>::identity();
+ #pragma omp for nowait
+ for (int i3 = 0; i3 < e3; ++i3)
+ for (int i2 = 0; i2 < e2; ++i2)
+ for (int i1 = 0; i1 < e1; ++i1) {
+ ;
+ for (int i0 = 0; i0 < e0; ++i0)
+ op(answer, localExpr.read(i0, i1, i2, i3));
+ }
+ reduction.storePartialResult(answer);
+ }
+ reduction.reduce(ret, op);
+ }
+ template<class T, class Op, class Expr, class Domain>
+ inline static void evaluate(T &ret, const Op &op, const Expr &e,
+ const Domain &domain, WrappedInt<5>)
+ {
+ Expr localExpr(e);
+ int e0 = domain[0].length();
+ int e1 = domain[1].length();
+ int e2 = domain[2].length();
+ int e3 = domain[3].length();
+ int e4 = domain[4].length();
+ PartialReduction<T> reduction;
+ #pragma omp parallel
+ {
+ T answer = ReductionTraits<Op, T>::identity();
+ #pragma omp for nowait
+ for (int i4 = 0; i4 < e4; ++i4)
+ for (int i3 = 0; i3 < e3; ++i3)
+ for (int i2 = 0; i2 < e2; ++i2)
+ for (int i1 = 0; i1 < e1; ++i1) {
+ ;
+ for (int i0 = 0; i0 < e0; ++i0)
+ op(answer, localExpr.read(i0, i1, i2, i3, i4));
+ }
+ reduction.storePartialResult(answer);
+ }
+ reduction.reduce(ret, op);
+ }
+ template<class T, class Op, class Expr, class Domain>
+ inline static void evaluate(T &ret, const Op &op, const Expr &e,
+ const Domain &domain, WrappedInt<6>)
+ {
+ Expr localExpr(e);
+ int e0 = domain[0].length();
+ int e1 = domain[1].length();
+ int e2 = domain[2].length();
+ int e3 = domain[3].length();
+ int e4 = domain[4].length();
+ int e5 = domain[5].length();
+ PartialReduction<T> reduction;
+ #pragma omp parallel
+ {
+ T answer = ReductionTraits<Op, T>::identity();
+ #pragma omp for nowait
+ for (int i5 = 0; i5 < e5; ++i5)
+ for (int i4 = 0; i4 < e4; ++i4)
+ for (int i3 = 0; i3 < e3; ++i3)
+ for (int i2 = 0; i2 < e2; ++i2)
+ for (int i1 = 0; i1 < e1; ++i1) {
+ ;
+ for (int i0 = 0; i0 < e0; ++i0)
+ op(answer, localExpr.read(i0, i1, i2, i3, i4, i5));
+ }
+ reduction.storePartialResult(answer);
+ }
+ reduction.reduce(ret, op);
+ }
+ template<class T, class Op, class Expr, class Domain>
+ inline static void evaluate(T &ret, const Op &op, const Expr &e,
+ const Domain &domain, WrappedInt<7>)
+ {
+ Expr localExpr(e);
+ int e0 = domain[0].length();
+ int e1 = domain[1].length();
+ int e2 = domain[2].length();
+ int e3 = domain[3].length();
+ int e4 = domain[4].length();
+ int e5 = domain[5].length();
+ int e6 = domain[6].length();
+ PartialReduction<T> reduction;
+ #pragma omp parallel
+ {
+ T answer = ReductionTraits<Op, T>::identity();
+ #pragma omp for nowait
+ for (int i6 = 0; i6 < e6; ++i6)
+ for (int i5 = 0; i5 < e5; ++i5)
+ for (int i4 = 0; i4 < e4; ++i4)
+ for (int i3 = 0; i3 < e3; ++i3)
+ for (int i2 = 0; i2 < e2; ++i2)
+ for (int i1 = 0; i1 < e1; ++i1) {
+ ;
+ for (int i0 = 0; i0 < e0; ++i0)
+ op(answer, localExpr.read(i0, i1, i2, i3, i4, i5, i6));
+ }
+ reduction.storePartialResult(answer);
+ }
+ reduction.reduce(ret, op);
+ }
+ };
+ template<class T, class Op>
+ struct CompressibleReduce
+ {
+ template<class T1>
+ inline static void evaluate(T &ret, const Op &, const T1 &val, int)
+ {
+ ret = static_cast<T>(val);
+ }
+ };
+ template<class T>
+ struct CompressibleReduce<T, OpAddAssign>
+ {
+ template<class T1>
+ inline static void evaluate(T &ret, const OpAddAssign &, const T1 &val,
+ int n)
+ {
+ ret = static_cast<T>(n * val);
+ }
+ };
+ template<class T>
+ struct CompressibleReduce<T, OpMultiplyAssign>
+ {
+ template<class T1>
+ inline static void evaluate(T &ret, const OpMultiplyAssign &, const T1 &val,
+ int n)
+ {
+ ret = static_cast<T>(val);
+ while (--n > 0)
+ ret *= static_cast<T>(val);
+ }
+ };
+ template<>
+ struct ReductionEvaluator<CompressibleKernelTag>
+ {
+ template<class T, class Op, class Expr>
+ inline static void evaluate(T &ret, const Op &op, const Expr &e)
+ {
+ if (engineFunctor(e, Compressed()))
+ {
+ CompressibleReduce<T, Op>::
+ evaluate(ret, op, engineFunctor(e, CompressedRead()),
+ e.domain().size());
+ }
+ else
+ {
+ ReductionEvaluator<InlineKernelTag>::evaluate(ret, op, e);
+ }
+ }
+ };
+ namespace Pooma {
+ class CountingSemaphore
+ {
+ public:
+ CountingSemaphore() { }
+ CountingSemaphore(const CountingSemaphore &) { }
+ CountingSemaphore &operator=(const CountingSemaphore &) { return *this; }
+ void wait() const { }
+ int count() const { return 0; }
+ int height() const { return 0; }
+ void height(int) { }
+ void raise_height(int) { }
+ void incr() { }
+ CountingSemaphore &operator++() { incr(); return *this; }
+ int operator+=(int) { return 0; }
+ };
+ }
+ template<class T, class Op, class Expr, class KernelTag>
+ class ReductionKernel : public Pooma::Iterate_t
+ {
+ public:
+ typedef ReductionKernel<T, Op, Expr, KernelTag> This_t;
+ ReductionKernel(T &ret, const Op &op, const Expr &e,
+ Pooma::CountingSemaphore &csem);
+ virtual ~ReductionKernel();
+ virtual void /*__attribute__((leafify))*/ run();
+ private:
+ T &ret_m;
+ Op op_m;
+ Expr expr_m;
+ Pooma::CountingSemaphore &csem_m;
+ };
+ template<class T, class Op, class Expr, class KernelTag>
+ ReductionKernel<T, Op, Expr, KernelTag>::
+ ReductionKernel(T &ret, const Op &op, const Expr &e,
+ Pooma::CountingSemaphore &csem)
+ : Pooma::Iterate_t(Pooma::scheduler()),
+ ret_m(ret), op_m(op), expr_m(e), csem_m(csem)
+ {
+ DataObjectRequest<ReadRequest> readReq(*this);
+ engineFunctor(expr_m, readReq);
+ }
+ template<class T, class Op, class Expr, class KernelTag>
+ ReductionKernel<T, Op, Expr, KernelTag>::~ReductionKernel()
+ {
+ DataObjectRequest<ReadRelease> readRelease;
+ engineFunctor(expr_m, readRelease);
+ csem_m.incr();
+ }
+ template<class T, class Op, class Expr, class KernelTag>
+ void ReductionKernel<T, Op, Expr, KernelTag>::run()
+ {
+ ReductionEvaluator<KernelTag>::evaluate(ret_m, op_m, expr_m);
+ }
+ template <class EvalTag>
+ struct Reduction
+ { };
+ template <>
+ struct Reduction<MainEvaluatorTag>
+ {
+ Reduction() { }
+ ~Reduction() { }
+ template <class Expr>
+ static inline bool checkValidity(const Expr &e, WrappedInt<false>)
+ {
+ return true;
+ }
+ template <class Expr>
+ static inline bool checkValidity(const Expr &e, WrappedInt<true>)
+ {
+ return e.centeringSize() == 1 && e.numMaterials() == 1;
+ }
+ template<class T, class Op, class Cond, class Expr>
+ void evaluate(T &ret, const Op &op, const WhereProxy<Cond, Expr> &w) const
+ {
+ evaluate(ret, w.opMask(op), w.whereMask());
+ }
+ template<class T, class Op, class Expr>
+ void evaluate(T &ret, const Op &op, const Expr &e) const
+ {
+ typedef typename EvaluatorTag1<Expr>::Evaluator_t Evaluator_t;
+ Pooma::scheduler().beginGeneration();
+ ;
+ forEach(e, PerformUpdateTag(), NullCombine());
+ Reduction<Evaluator_t>().evaluate(ret, op, e());
+ Pooma::scheduler().endGeneration();
+ ;
+ }
+ };
+ template <>
+ struct Reduction<SinglePatchEvaluatorTag>
+ {
+ Reduction() { }
+ ~Reduction() { }
+ template<class T, class Op, class Expr>
+ void evaluate(T &ret, const Op &op, const Expr &e,
+ Pooma::CountingSemaphore &csem) const
+ {
+ typedef typename KernelTag1<Expr>::Kernel_t Kernel_t;
+ Pooma::Iterate_t *iterate =
+ new ReductionKernel<T, Op, Expr, Kernel_t>(ret, op, e, csem);
+ Pooma::scheduler().handOff(iterate);
+ }
+ template<class T, class Op, class Expr>
+ void evaluate(T &ret, const Op &op, const Expr &e) const
+ {
+ Pooma::CountingSemaphore csem;
+ csem.height(1);
+ evaluate(ret, op, e, csem);
+ csem.wait();
+ }
+ };
+ template <>
+ struct Reduction<MultiPatchEvaluatorTag>
+ {
+ Reduction() { }
+ ~Reduction() { }
+ template<class T, class Op, class Expr>
+ void evaluate(T &ret, const Op &op, const Expr &e) const
+ {
+ typedef Intersector<Expr::dimensions> Inter_t;
+ Inter_t inter;
+ expressionApply(e, IntersectorTag<Inter_t>(inter));
+ const int n = inter.size();
+ Pooma::CountingSemaphore csem;
+ csem.height(n);
+ T *vals = new T[n];
+ typename Inter_t::const_iterator i = inter.begin();
+ int j = 0;
+ while (j < n)
+ {
+ Reduction<SinglePatchEvaluatorTag>().
+ evaluate(vals[j], op, e(*i), csem);
+ ++i; ++j;
+ }
+ csem.wait();
+ ret = vals[0];
+ for (j = 1; j < n; j++)
+ op(ret, vals[j]);
+ delete [] vals;
+ }
+ };
+ template<class Subject>
+ typename Subject::Element_t sum(const Subject &s)
+ {
+ typename Subject::Element_t ret;
+ Reduction<MainEvaluatorTag>().evaluate(ret, OpAddAssign(), s);
+ return ret;
+ }
+ template<class Subject>
+ typename Subject::Element_t prod(const Subject &s)
+ {
+ typename Subject::Element_t ret;
+ Reduction<MainEvaluatorTag>().evaluate(ret, OpMultiplyAssign(), s);
+ return ret;
+ }
+ template<class Subject>
+ typename Subject::Element_t min(const Subject &s)
+ {
+ typename Subject::Element_t ret;
+ Reduction<MainEvaluatorTag>().evaluate(ret, FnMinAssign(), s);
+ return ret;
+ }
+ template<class Subject>
+ typename Subject::Element_t max(const Subject &s)
+ {
+ typename Subject::Element_t ret;
+ Reduction<MainEvaluatorTag>().evaluate(ret, FnMaxAssign(), s);
+ return ret;
+ }
+ template<class Subject>
+ bool all(const Subject &s)
+ {
+ bool ret;
+ Reduction<MainEvaluatorTag>().evaluate(ret, FnAndAssign(), s);
+ return ret;
+ }
+ template<class Subject>
+ bool any(const Subject &s)
+ {
+ bool ret;
+ Reduction<MainEvaluatorTag>().evaluate(ret, FnOrAssign(), s);
+ return ret;
+ }
+ template<class Subject>
+ typename Subject::Element_t bitOr(const Subject &s)
+ {
+ typename Subject::Element_t ret;
+ Reduction<MainEvaluatorTag>().evaluate(ret, OpBitwiseOrAssign(), s);
+ return ret;
+ }
+ template<class Subject>
+ typename Subject::Element_t bitAnd(const Subject &s)
+ {
+ typename Subject::Element_t ret;
+ Reduction<MainEvaluatorTag>().evaluate(ret, OpBitwiseAndAssign(), s);
+ return ret;
+ }
+ template<int Dim, class T, class EngineTag,
+ int OtherDim, class OtherT, class OtherEngineTag, class Op>
+ inline const Array<Dim, T, EngineTag> &
+ assign(const Array<Dim, T, EngineTag> &lhs,
+ const Array<OtherDim, OtherT, OtherEngineTag> &rhs,
+ const Op &op);
+ template<int Dim, class T, class EngineTag, class T1, class Op>
+ inline const Array<Dim, T, EngineTag> &
+ assign(const Array<Dim, T, EngineTag> &lhs, const T1 &rhs, const Op &op);
+ template<class Subject, class Sub1, bool SV>
+ struct View1Implementation;
+ template<int Dim, class T, class EngineTag, class Domain>
+ struct View1Implementation<Array<Dim, T, EngineTag>, Domain, true>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ template<class S1, class Combine>
+ inline static
+ Type_t make(const Subject_t &a, const S1 &s1,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1));
+ return a.engine()(s);
+ }
+ template<class S1, class S2, class Combine>
+ inline static
+ Type_t make(const Subject_t &a,
+ const S1 &s1, const S2 &s2,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2));
+ return a.engine()(s);
+ }
+ template<class S1, class S2, class S3,
+ class Combine>
+ inline static
+ Type_t make(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3));
+ return a.engine()(s);
+ }
+ template<class S1, class S2, class S3, class S4,
+ class Combine>
+ inline static
+ Type_t make(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3, s4));
+ return a.engine()(s);
+ }
+ template<class S1, class S2, class S3, class S4, class S5,
+ class Combine>
+ inline static
+ Type_t make(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4, const S5 &s5,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3, s4, s5));
+ return a.engine()(s);
+ }
+ template<class S1, class S2, class S3, class S4, class S5,
+ class S6, class Combine>
+ inline static
+ Type_t make(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4, const S5 &s5, const S6 &s6,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3, s4, s5, s6));
+ return a.engine()(s);
+ }
+ template<class S1, class S2, class S3, class S4, class S5,
+ class S6, class S7, class Combine>
+ inline static
+ Type_t make(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4, const S5 &s5, const S6 &s6,
+ const S7 &s7,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3, s4, s5, s6, s7));
+ return a.engine()(s);
+ }
+ template<class S1, class Combine>
+ inline static
+ ReadType_t makeRead(const Subject_t &a, const S1 &s1,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1));
+ return a.engine().read(s);
+ }
+ template<class S1, class S2, class Combine>
+ inline static
+ ReadType_t makeRead(const Subject_t &a,
+ const S1 &s1, const S2 &s2,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2));
+ return a.engine().read(s);
+ }
+ template<class S1, class S2, class S3,
+ class Combine>
+ inline static
+ ReadType_t makeRead(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3));
+ return a.engine().read(s);
+ }
+ template<class S1, class S2, class S3, class S4,
+ class Combine>
+ inline static
+ ReadType_t makeRead(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3, s4));
+ return a.engine().read(s);
+ }
+ template<class S1, class S2, class S3, class S4, class S5,
+ class Combine>
+ inline static
+ ReadType_t makeRead(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4, const S5 &s5,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3, s4, s5));
+ return a.engine().read(s);
+ }
+ template<class S1, class S2, class S3, class S4, class S5,
+ class S6, class Combine>
+ inline static
+ ReadType_t makeRead(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4, const S5 &s5, const S6 &s6,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3, s4, s5, s6));
+ return a.engine().read(s);
+ }
+ template<class S1, class S2, class S3, class S4, class S5,
+ class S6, class S7, class Combine>
+ inline static
+ ReadType_t makeRead(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4, const S5 &s5, const S6 &s6,
+ const S7 &s7,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3, s4, s5, s6, s7));
+ return a.engine().read(s);
+ }
+ };
+ template<int Dim, class T, class EngineTag, class Domain>
+ struct View1Implementation<Array<Dim, T, EngineTag>, Domain, false>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Engine_t Engine_t;
+ typedef typename NewEngine<Engine_t, Domain>::Type_t NewEngine_t;
+ enum { newDim = NewEngine_t::dimensions };
+ typedef typename NewEngine_t::Tag_t NewEngineTag_t;
+ typedef Array<newDim, T, NewEngineTag_t> Type_t;
+ typedef Type_t ReadType_t;
+ typedef NewEngineEngine<Engine_t, Domain> NewEE_t;
+ typedef NewEngineDomain<Engine_t, Domain> NewED_t;
+ template<class S1, class Combine>
+ static
+ Type_t make(const Subject_t &a, const S1 &s1,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1));
+ return Type_t(
+ NewEE_t::apply(a.engine(), s),
+ NewED_t::apply(a.engine(), s));
+ }
+ template<class S1, class S2, class Combine>
+ static
+ Type_t make(const Subject_t &a, const S1 &s1,
+ const S2 &s2, const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2));
+ return Type_t(
+ NewEE_t::apply(a.engine(), s),
+ NewED_t::apply(a.engine(), s));
+ }
+ template<class S1, class S2, class S3,
+ class Combine>
+ static
+ Type_t make(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3));
+ return Type_t(
+ NewEE_t::apply(a.engine(), s),
+ NewED_t::apply(a.engine(), s));
+ }
+ template<class S1, class S2, class S3, class S4,
+ class Combine>
+ static
+ Type_t make(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3, s4));
+ return Type_t(
+ NewEE_t::apply(a.engine(), s),
+ NewED_t::apply(a.engine(), s));
+ }
+ template<class S1, class S2, class S3, class S4, class S5,
+ class Combine>
+ static
+ Type_t make(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4, const S5 &s5,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3, s4, s5));
+ return Type_t(
+ NewEE_t::apply(a.engine(), s),
+ NewED_t::apply(a.engine(), s));
+ }
+ template<class S1, class S2, class S3, class S4, class S5,
+ class S6, class Combine>
+ static
+ Type_t make(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4, const S5 &s5, const S6 &s6,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3, s4, s5, s6));
+ return Type_t(
+ NewEE_t::apply(a.engine(), s),
+ NewED_t::apply(a.engine(), s));
+ }
+ template<class S1, class S2, class S3, class S4, class S5,
+ class S6, class S7, class Combine>
+ static
+ Type_t make(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4, const S5 &s5, const S6 &s6,
+ const S7 &s7,
+ const Combine &)
+ {
+ Domain s(Combine::make(a, s1, s2, s3, s4, s5, s6, s7));
+ return Type_t(
+ NewEE_t::apply(a.engine(), s),
+ NewED_t::apply(a.engine(), s));
+ }
+ template<class S1, class Combine>
+ inline static
+ Type_t makeRead(const Subject_t &a, const S1 &s1,
+ const Combine &c)
+ {
+ return make(a, s1, c);
+ }
+ template<class S1, class S2, class Combine>
+ inline static
+ Type_t makeRead(const Subject_t &a, const S1 &s1,
+ const S2 &s2, const Combine &c)
+ {
+ return make(a, s1, s2, c);
+ }
+ template<class S1, class S2, class S3,
+ class Combine>
+ inline static
+ Type_t makeRead(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const Combine &c)
+ {
+ return make(a, s1, s2, s3, c);
+ }
+ template<class S1, class S2, class S3, class S4,
+ class Combine>
+ inline static
+ Type_t makeRead(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4, const Combine &c)
+ {
+ return make(a, s1, s2, s3, s4, c);
+ }
+ template<class S1, class S2, class S3, class S4, class S5,
+ class Combine>
+ inline static
+ Type_t makeRead(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4, const S5 &s5, const Combine &c)
+ {
+ return make(a, s1, s2, s3, s4, s5, c);
+ }
+ template<class S1, class S2, class S3, class S4, class S5,
+ class S6,
+ class Combine>
+ inline static
+ Type_t makeRead(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4, const S5 &s5, const S6 &s6,
+ const Combine &c)
+ {
+ return make(a, s1, s2, s3, s4, s5, s6, c);
+ }
+ template<class S1, class S2, class S3, class S4, class S5,
+ class S6, class S7,
+ class Combine>
+ inline static
+ Type_t makeRead(const Subject_t &a,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const S4 &s4, const S5 &s5, const S6 &s6,
+ const S7 &s7, const Combine &c)
+ {
+ return make(a, s1, s2, s3, s4, s5, s6, s7, c);
+ }
+ };
+ template<int Dim, class T, class EngineTag, class Domain>
+ struct View1<Array<Dim, T, EngineTag>, Domain>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Domain_t Domain_t;
+ typedef TemporaryNewDomain1<Domain_t, Domain> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SDomain_t;
+ enum { sv = DomainTraits<SDomain_t>::singleValued };
+ typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
+ typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
+ typedef typename Dispatch_t::Type_t Type_t;
+ typedef typename Dispatch_t::ReadType_t ReadType_t;
+ inline static
+ Type_t make(const Subject_t &a, const Domain &s1)
+ {
+ return Dispatch_t::make(a, s1, Combine_t());
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &a, const Domain &s1)
+ {
+ return Dispatch_t::makeRead(a, s1, Combine_t());
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct View0<Array<Dim, T, EngineTag> >
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Engine_t Engine_t;
+ typedef typename Subject_t::Domain_t Domain_t;
+ typedef typename NewEngine<Engine_t, Domain_t>::Type_t NewEngine_t;
+ enum { newDim = NewEngine_t::dimensions };
+ typedef typename NewEngine_t::Tag_t NewEngineTag_t;
+ typedef Array<newDim, T, NewEngineTag_t> Type_t;
+ typedef Type_t ReadType_t;
+ static Type_t make(const Subject_t &a)
+ {
+ typedef NewEngineEngine<Engine_t, Domain_t> NewEE_t;
+ typedef NewEngineDomain<Engine_t, Domain_t> NewED_t;
+ return Type_t(
+ NewEE_t::apply(a.engine(), a.engine().domain()),
+ NewED_t::apply(a.engine(), a.engine().domain()));
+ }
+ inline static ReadType_t makeRead(const Subject_t &a)
+ {
+ return make(a);
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct View1<Array<Dim, T, EngineTag>, int>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ inline static
+ Type_t make(const Subject_t &a, int s1)
+ {
+ return a.engine()(s1);
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &a, int s1)
+ {
+ return a.engine().read(s1);
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct View1<Array<Dim, T, EngineTag>, Loc<Dim> >
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ inline static
+ Type_t make(const Subject_t &a, const Loc<Dim>& s1)
+ {
+ ;
+ return a.engine()(s1);
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &a, const Loc<Dim>& s1)
+ {
+ ;
+ return a.engine().read(s1);
+ }
+ };
+ template<int D1, class T1, class E1, int D2, class T2, class E2>
+ struct View1<Array<D1, T1, E1>, Array<D2, T2, E2> >
+ {
+ typedef Array<D1, T1, E1> Array1_t;
+ typedef Array<D2, T2, E2> Array2_t;
+ typedef IndirectionTag<Array1_t, Array2_t> Tag_t;
+ typedef Array<D2, T1, Tag_t> Type_t;
+ typedef Type_t ReadType_t;
+ static
+ Type_t make(const Array1_t &a, const Array2_t &s)
+ {
+ return Type_t(a, s);
+ }
+ inline static
+ Type_t makeRead(const Array1_t &a, const Array2_t &s)
+ {
+ return make(a, s);
+ }
+ };
+ template<int Dim, class T, class EngineTag,
+ class Sub1, class Sub2>
+ struct View2<Array<Dim, T, EngineTag>, Sub1, Sub2>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Domain_t Domain_t;
+ typedef NewDomain2<Sub1, Sub2> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SDomain_t;
+ enum { sv = DomainTraits<SDomain_t>::singleValued };
+ typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
+ typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
+ typedef typename Dispatch_t::Type_t Type_t;
+ typedef typename Dispatch_t::ReadType_t ReadType_t;
+ inline static
+ Type_t make(const Subject_t &a, const Sub1 &s1, const Sub2 &s2)
+ {
+ return Dispatch_t::make(a, s1, s2, Combine_t());
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &a, const Sub1 &s1, const Sub2 &s2)
+ {
+ return Dispatch_t::makeRead(a, s1, s2, Combine_t());
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct View2<Array<Dim, T, EngineTag>, int, int>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ inline static
+ Type_t make(const Subject_t &a, int s1, int s2)
+ {
+ return a.engine()(s1, s2);
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &a, int s1, int s2)
+ {
+ return a.engine().read(s1, s2);
+ }
+ };
+ template<int Dim, class T, class EngineTag,
+ class Sub1, class Sub2, class Sub3>
+ struct View3<Array<Dim, T, EngineTag>, Sub1, Sub2, Sub3>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Domain_t Domain_t;
+ typedef NewDomain3<Sub1, Sub2, Sub3> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SDomain_t;
+ enum { sv = DomainTraits<SDomain_t>::singleValued };
+ typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
+ typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
+ typedef typename Dispatch_t::Type_t Type_t;
+ typedef typename Dispatch_t::ReadType_t ReadType_t;
+ inline static
+ Type_t make(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
+ const Sub3 &s3)
+ {
+ return Dispatch_t::make(a, s1, s2, s3, Combine_t());
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
+ const Sub3 &s3)
+ {
+ return Dispatch_t::makeRead(a, s1, s2, s3, Combine_t());
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct View3<Array<Dim, T, EngineTag>, int, int, int>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ inline static
+ Type_t make(const Subject_t &a, int s1, int s2, int s3)
+ {
+ return a.engine()(s1, s2, s3);
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &a, int s1, int s2, int s3)
+ {
+ return a.engine().read(s1, s2, s3);
+ }
+ };
+ template<int Dim, class T, class EngineTag,
+ class Sub1, class Sub2, class Sub3, class Sub4>
+ struct View4<Array<Dim, T, EngineTag>,
+ Sub1, Sub2, Sub3, Sub4>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Domain_t Domain_t;
+ typedef NewDomain4<Sub1, Sub2, Sub3, Sub4> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SDomain_t;
+ enum { sv = DomainTraits<SDomain_t>::singleValued };
+ typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
+ typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
+ typedef typename Dispatch_t::Type_t Type_t;
+ typedef typename Dispatch_t::ReadType_t ReadType_t;
+ inline static
+ Type_t make(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
+ const Sub3 &s3, const Sub4 &s4)
+ {
+ return Dispatch_t::make(a, s1, s2, s3, s4, Combine_t());
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
+ const Sub3 &s3, const Sub4 &s4)
+ {
+ return Dispatch_t::makeRead(a, s1, s2, s3, s4, Combine_t());
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct View4<Array<Dim, T, EngineTag>, int, int, int, int>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ inline static
+ Type_t make(const Subject_t &a, int s1, int s2, int s3, int s4)
+ {
+ return a.engine()(s1, s2, s3, s4);
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &a, int s1, int s2, int s3, int s4)
+ {
+ return a.engine().read(s1, s2, s3, s4);
+ }
+ };
+ template<int Dim, class T, class EngineTag,
+ class Sub1, class Sub2, class Sub3, class Sub4, class Sub5>
+ struct View5<Array<Dim, T, EngineTag>,
+ Sub1, Sub2, Sub3, Sub4, Sub5>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Domain_t Domain_t;
+ typedef NewDomain5<Sub1, Sub2, Sub3, Sub4, Sub5> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SDomain_t;
+ enum { sv = DomainTraits<SDomain_t>::singleValued };
+ typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
+ typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
+ typedef typename Dispatch_t::Type_t Type_t;
+ typedef typename Dispatch_t::ReadType_t ReadType_t;
+ inline static
+ Type_t make(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
+ const Sub3 &s3, const Sub4 &s4, const Sub5 &s5)
+ {
+ return Dispatch_t::make(a, s1, s2, s3, s4, s5, Combine_t());
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
+ const Sub3 &s3, const Sub4 &s4, const Sub5 &s5)
+ {
+ return Dispatch_t::makeRead(a, s1, s2, s3, s4, s5, Combine_t());
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct View5<Array<Dim, T, EngineTag>, int, int, int, int, int>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ inline static
+ ReadType_t makeRead(const Subject_t &a, int s1, int s2, int s3,
+ int s4, int s5)
+ {
+ return a.engine().read(s1, s2, s3, s4, s5);
+ }
+ inline static
+ Type_t make(const Subject_t &a, int s1, int s2, int s3, int s4, int s5)
+ {
+ return a.engine()(s1, s2, s3, s4, s5);
+ }
+ };
+ template<int Dim, class T, class EngineTag,
+ class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
+ class Sub6>
+ struct View6<Array<Dim, T, EngineTag>,
+ Sub1, Sub2, Sub3, Sub4, Sub5, Sub6>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Domain_t Domain_t;
+ typedef NewDomain6<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SDomain_t;
+ enum { sv = DomainTraits<SDomain_t>::singleValued };
+ typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
+ typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
+ typedef typename Dispatch_t::Type_t Type_t;
+ typedef typename Dispatch_t::ReadType_t ReadType_t;
+ inline static
+ Type_t make(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
+ const Sub3 &s3, const Sub4 &s4, const Sub5 &s5, const Sub6 &s6)
+ {
+ return Dispatch_t::make(a, s1, s2, s3, s4, s5, s6, Combine_t());
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
+ const Sub3 &s3, const Sub4 &s4, const Sub5 &s5, const Sub6 &s6)
+ {
+ return Dispatch_t::makeRead(a, s1, s2, s3, s4, s5, s6, Combine_t());
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct View6<Array<Dim, T, EngineTag>, int, int, int, int, int, int>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ inline static
+ Type_t make(const Subject_t &a, int s1, int s2, int s3, int s4, int s5,
+ int s6)
+ {
+ return a.engine()(s1, s2, s3, s4, s5, s6);
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &a, int s1, int s2, int s3,
+ int s4, int s5, int s6)
+ {
+ return a.engine().read(s1, s2, s3, s4, s5, s6);
+ }
+ };
+ template<int Dim, class T, class EngineTag,
+ class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
+ class Sub6, class Sub7>
+ struct View7<Array<Dim, T, EngineTag>,
+ Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Domain_t Domain_t;
+ typedef NewDomain7<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>
+ NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SDomain_t;
+ enum { sv = DomainTraits<SDomain_t>::singleValued };
+ typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
+ typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
+ typedef typename Dispatch_t::Type_t Type_t;
+ typedef typename Dispatch_t::ReadType_t ReadType_t;
+ inline static
+ Type_t make(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
+ const Sub3 &s3, const Sub4 &s4, const Sub5 &s5, const Sub6 &s6,
+ const Sub7 &s7)
+ {
+ return Dispatch_t::make(a, s1, s2, s3, s4, s5, s6, s7, Combine_t());
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &a, const Sub1 &s1, const Sub2 &s2,
+ const Sub3 &s3, const Sub4 &s4, const Sub5 &s5, const Sub6 &s6,
+ const Sub7 &s7)
+ {
+ return Dispatch_t::makeRead(a, s1, s2, s3, s4, s5, s6, s7,
+ Combine_t());
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct View7<Array<Dim, T, EngineTag>, int, int, int, int, int, int, int>
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ inline static
+ Type_t make(const Subject_t &a, int s1, int s2, int s3, int s4, int s5,
+ int s6, int s7)
+ {
+ return a.engine()(s1, s2, s3, s4, s5, s6, s7);
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &a, int s1, int s2, int s3,
+ int s4, int s5, int s6, int s7)
+ {
+ return a.engine().read(s1, s2, s3, s4, s5, s6, s7);
+ }
+ };
+ template <class Subject, class Domain>
+ struct ReverseSliceView;
+ template <int SliceDim, class T, class EngineTag, int Dim>
+ struct ReverseSliceView<Array<SliceDim, T, EngineTag>, SliceInterval<Dim, SliceDim> >
+ {
+ typedef Array<SliceDim, T, EngineTag> Subject_t;
+ typedef SliceInterval<Dim, SliceDim> Domain_t;
+ typedef typename NewEngine<typename Subject_t::Engine_t, Domain_t>::Type_t NewEngine_t;
+ typedef Array<Dim, T, typename NewEngine_t::Tag_t> Type_t;
+ inline static
+ Type_t make(const Subject_t &a, const SliceInterval<Dim, SliceDim>& dom,
+ const Interval<Dim>& totalDom)
+ {
+ return Type_t(NewEngine_t(a.engine(), dom, totalDom));
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct Patch<Array<Dim, T, EngineTag> >
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Engine_t OldEngine_t;
+ typedef typename EngineFunctor<OldEngine_t, EnginePatch>::Type_t Engine_t;
+ typedef Array<Dim, T, typename Engine_t::Tag_t> Type_t;
+ inline static
+ Type_t make(const Subject_t &subject, int i)
+ {
+ return Type_t(engineFunctor(subject.engine(), EnginePatch(i)));
+ }
+ };
+ template<class Components, int Dim, class T, class EngineTag>
+ struct ComponentView<Components, Array<Dim, T, EngineTag> >
+ {
+ typedef Array<Dim, T, EngineTag> Subject_t;
+ typedef Engine<Dim, T, EngineTag> Engine_t;
+ typedef typename Engine_t::Element_t Element_t;
+ typedef typename ComponentAccess<Element_t, Components>::Element_t NewT_t;
+ typedef CompFwd<Engine_t, Components> NewEngineTag_t;
+ typedef Array<Dim, NewT_t, NewEngineTag_t> Type_t;
+ inline static
+ Type_t make(const Subject_t &a, const Components &c)
+ {
+ return Type_t(a, ComponentWrapper<Components>(c));
+ }
+ };
+ template<int Dim, class T = double,
+ class EngineTag = Brick>
+ class Array
+ {
+ public:
+ typedef Array<Dim, T, EngineTag> This_t;
+ typedef Engine<Dim, T, EngineTag> Engine_t;
+ typedef EngineTag EngineTag_t;
+ typedef typename Engine_t::Element_t Element_t;
+ typedef typename Engine_t::ElementRef_t ElementRef_t;
+ typedef typename Engine_t::Domain_t Domain_t;
+ typedef typename Engine_t::Layout_t Layout_t;
+ enum { dimensions = Engine_t::dimensions };
+ enum { rank = Engine_t::dimensions };
+ enum { hasRelations = false };
+ Array() { }
+ inline explicit Array(const Engine_t &modelEngine)
+ : engine_m(modelEngine)
+ { }
+ template<int Dim2, class T2, class EngineTag2, class Initializer>
+ inline Array(const Engine<Dim2, T2, EngineTag2> &engine,
+ const Initializer &init)
+ : engine_m(engine, init)
+ { }
+ template<int D1, class T1, class E1, int D2, class T2, class E2>
+ inline Array(const Array<D1, T1, E1> &a1, const Array<D2, T2, E2> &a2)
+ : engine_m(a1, a2)
+ { }
+ inline Array(const This_t &model)
+ : engine_m(model.engine())
+ { }
+ template<int OtherDim, class OtherT, class OtherEngineTag>
+ inline explicit Array(const Array<OtherDim, OtherT, OtherEngineTag> &model)
+ : engine_m(model.engine())
+ { }
+ template<int OtherDim, class OtherT, class OtherEngineTag, class OtherDomain>
+ inline Array(const Array<OtherDim, OtherT, OtherEngineTag> &model,
+ const OtherDomain &domain)
+ : engine_m(NewEngineEngine<Engine<OtherDim,OtherT,OtherEngineTag>,
+ OtherDomain>::apply(model.engine(),domain),
+ NewEngineDomain<Engine<OtherDim,OtherT,OtherEngineTag>,
+ OtherDomain>::apply(model.engine(),domain))
+ { }
+ template <class OtherT, class OtherEngineTag, class Components>
+ Array(const Array<Dim, OtherT, OtherEngineTag> &a,
+ const ComponentWrapper<Components>& c)
+ : engine_m(a.engine(), c.components())
+ { }
+ template<class Sub1>
+ explicit Array(const Sub1 &s1)
+ : engine_m(NewDomain1<Sub1>::combine(s1))
+ { }
+ template<class Sub1, class Sub2>
+ Array(const Sub1 &s1, const Sub2 &s2)
+ : engine_m(NewDomain2<Sub1, Sub2>::combine(s1, s2))
+ { }
+ template<class Sub1, class Sub2, class Sub3>
+ Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3)
+ : engine_m(NewDomain3<Sub1, Sub2, Sub3>::combine(s1, s2, s3))
+ { }
+ template<class Sub1, class Sub2, class Sub3, class Sub4>
+ Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4)
+ : engine_m(NewDomain4<Sub1, Sub2, Sub3, Sub4>::
+ combine(s1, s2, s3, s4))
+ { }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5>
+ Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
+ const Sub5 &s5)
+ : engine_m(NewDomain5<Sub1, Sub2, Sub3, Sub4, Sub5>::
+ combine(s1, s2, s3, s4, s5))
+ { }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
+ class Sub6>
+ Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
+ const Sub5 &s5, const Sub6 &s6)
+ : engine_m(NewDomain6<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6>::
+ combine(s1, s2, s3, s4, s5, s6))
+ { }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
+ class Sub6, class Sub7>
+ Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
+ const Sub5 &s5, const Sub6 &s6, const Sub7 &s7)
+ : engine_m(NewDomain7<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>::
+ combine(s1, s2, s3, s4, s5, s6, s7))
+ { }
+ template<class Sub1>
+ Array(const Sub1 &s1, const ModelElement<Element_t> &model)
+ : engine_m(NewDomain1<Sub1>::combine(s1), model.element())
+ { }
+ template<class Sub1, class Sub2>
+ Array(const Sub1 &s1, const Sub2 &s2,
+ const ModelElement<Element_t> &model)
+ : engine_m(NewDomain2<Sub1, Sub2>::combine(s1, s2), model.element())
+ { }
+ template<class Sub1, class Sub2, class Sub3>
+ Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const ModelElement<Element_t> &model)
+ : engine_m(NewDomain3<Sub1, Sub2, Sub3>::combine(s1, s2, s3),
+ model.element())
+ { }
+ template<class Sub1, class Sub2, class Sub3, class Sub4>
+ Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
+ const ModelElement<Element_t> &model)
+ : engine_m(NewDomain4<Sub1, Sub2, Sub3, Sub4>::
+ combine(s1, s2, s3, s4), model.element())
+ { }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5>
+ Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
+ const Sub5 &s5, const ModelElement<Element_t> &model)
+ : engine_m(NewDomain5<Sub1, Sub2, Sub3, Sub4, Sub5>::
+ combine(s1, s2, s3, s4, s5), model.element())
+ { }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
+ class Sub6>
+ Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
+ const Sub5 &s5, const Sub6 &s6, const ModelElement<Element_t> &model)
+ : engine_m(NewDomain6<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6>::
+ combine(s1, s2, s3, s4, s5, s6), model.element())
+ { }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
+ class Sub6, class Sub7>
+ Array(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
+ const Sub5 &s5, const Sub6 &s6, const Sub7 &s7,
+ const ModelElement<Element_t> &model)
+ : engine_m(NewDomain7<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>::
+ combine(s1, s2, s3, s4, s5, s6, s7), model.element())
+ { }
+ void initialize(const Engine_t &modelEngine)
+ {
+ engine_m = modelEngine;
+ }
+ template<int Dim2, class T2, class EngineTag2, class Initializer>
+ void initialize(const Engine<Dim2, T2, EngineTag2> &engine,
+ const Initializer &init)
+ {
+ engine_m = Engine_t(engine, init);
+ }
+ void initialize(const This_t &model)
+ {
+ engine_m = model.engine();
+ }
+ template<int OtherDim, class OtherT, class OtherEngineTag>
+ void initialize(const Array<OtherDim, OtherT, OtherEngineTag> &model)
+ {
+ engine_m = Engine_t(model.engine());
+ }
+ template<int OtherDim, class OtherT, class OtherEngineTag, class OtherDomain>
+ void initialize(const Array<OtherDim, OtherT, OtherEngineTag> &model,
+ const OtherDomain &domain)
+ {
+ engine_m = Engine_t(
+ NewEngineEngine<Engine<OtherDim,OtherT,OtherEngineTag>, OtherDomain>::
+ apply(model.engine(),domain),
+ NewEngineDomain<Engine<OtherDim,OtherT,OtherEngineTag>, OtherDomain>::
+ apply(model.engine(),domain));
+ }
+ template<class Sub1>
+ void initialize(const Sub1 &s1)
+ {
+ engine_m = Engine_t(NewDomain1<Sub1>::combine(s1));
+ }
+ template<class Sub1, class Sub2>
+ void initialize(const Sub1 &s1, const Sub2 &s2)
+ {
+ engine_m = Engine_t(NewDomain2<Sub1, Sub2>::combine(s1, s2));
+ }
+ template<class Sub1, class Sub2, class Sub3>
+ void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3)
+ {
+ engine_m = Engine_t(NewDomain3<Sub1, Sub2, Sub3>::combine(s1, s2, s3));
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4>
+ void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4)
+ {
+ engine_m = Engine_t(NewDomain4<Sub1, Sub2, Sub3, Sub4>::
+ combine(s1, s2, s3, s4));
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5>
+ void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
+ const Sub5 &s5)
+ {
+ engine_m = Engine_t(NewDomain5<Sub1, Sub2, Sub3, Sub4, Sub5>::
+ combine(s1, s2, s3, s4, s5));
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
+ class Sub6>
+ void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
+ const Sub5 &s5, const Sub6 &s6)
+ {
+ engine_m = Engine_t(NewDomain6<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6>::
+ combine(s1, s2, s3, s4, s5, s6));
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
+ class Sub6, class Sub7>
+ void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4, const Sub5 &s5, const Sub6 &s6, const Sub7 &s7)
+ {
+ engine_m =
+ Engine_t(NewDomain7<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>::
+ combine(s1, s2, s3, s4, s5, s6, s7));
+ }
+ template<class Sub1>
+ void initialize(const Sub1 &s1, const ModelElement<Element_t> &model)
+ {
+ engine_m = Engine_t(NewDomain1<Sub1>::combine(s1), model.element());
+ }
+ template<class Sub1, class Sub2>
+ void initialize(const Sub1 &s1, const Sub2 &s2,
+ const ModelElement<Element_t> &model)
+ {
+ engine_m = Engine_t(NewDomain2<Sub1, Sub2>::combine(s1, s2),
+ model.element());
+ }
+ template<class Sub1, class Sub2, class Sub3>
+ void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const ModelElement<Element_t> &model)
+ {
+ engine_m = Engine_t(NewDomain3<Sub1, Sub2, Sub3>::combine(s1, s2, s3),
+ model.element());
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4>
+ void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
+ const ModelElement<Element_t> &model)
+ {
+ engine_m = Engine_t(NewDomain4<Sub1, Sub2, Sub3, Sub4>::
+ combine(s1, s2, s3, s4), model.element());
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5>
+ void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
+ const Sub5 &s5, const ModelElement<Element_t> &model)
+ {
+ engine_m = Engine_t(NewDomain5<Sub1, Sub2, Sub3, Sub4, Sub5>::
+ combine(s1, s2, s3, s4, s5), model.element());
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
+ class Sub6>
+ void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3, const Sub4 &s4,
+ const Sub5 &s5, const Sub6 &s6, const ModelElement<Element_t> &model)
+ {
+ engine_m = Engine_t(NewDomain6<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6>::
+ combine(s1, s2, s3, s4, s5, s6), model.element());
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
+ class Sub6, class Sub7>
+ void initialize(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4, const Sub5 &s5, const Sub6 &s6, const Sub7 &s7,
+ const ModelElement<Element_t> &model)
+ {
+ engine_m =
+ Engine_t(NewDomain7<Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>::
+ combine(s1, s2, s3, s4, s5, s6, s7), model.element());
+ }
+ ~Array()
+ { }
+ inline typename Patch<This_t>::Type_t
+ patchLocal(int i) const
+ {
+ return Patch<This_t>::make(*this, i);
+ }
+ inline int
+ numPatchesLocal() const
+ {
+ return engineFunctor(engine_m, EngineNumPatches());
+ }
+ inline const Domain_t& domain() const
+ {
+ return engine_m.domain();
+ }
+ inline Domain_t physicalDomain() const
+ {
+ return engine_m.layout().innerDomain();
+ }
+ inline const Domain_t& totalDomain() const
+ {
+ return engine_m.domain();
+ }
+ inline typename Engine_t::Layout_t layout() const
+ {
+ return engine_m.layout();
+ }
+ typename View0<This_t>::ReadType_t
+ read() const
+ {
+ typedef View0<This_t> Ret_t;
+ return Ret_t::makeRead(*this);
+ }
+ template<class Sub1>
+ inline typename View1<This_t, Sub1>::ReadType_t
+ read(const Sub1 &s1) const
+ {
+ typedef View1<This_t, Sub1> Ret_t;
+ return Ret_t::makeRead(*this, s1);
+ }
+ template<class Sub1, class Sub2>
+ inline typename View2<This_t, Sub1, Sub2>::ReadType_t
+ read(const Sub1 &s1, const Sub2 &s2) const
+ {
+ typedef View2<This_t, Sub1, Sub2> Ret_t;
+ return Ret_t::makeRead(*this, s1, s2);
+ }
+ template<class Sub1, class Sub2, class Sub3>
+ inline typename View3<This_t, Sub1, Sub2, Sub3>::ReadType_t
+ read(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3) const
+ {
+ typedef View3<This_t, Sub1, Sub2, Sub3> Ret_t;
+ return Ret_t::makeRead(*this, s1, s2, s3);
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4>
+ inline typename View4<This_t, Sub1, Sub2, Sub3, Sub4>::ReadType_t
+ read(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4) const
+ {
+ typedef View4<This_t, Sub1, Sub2, Sub3, Sub4> Ret_t;
+ return Ret_t::makeRead(*this, s1, s2, s3, s4);
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5>
+ inline typename View5<This_t, Sub1, Sub2, Sub3, Sub4, Sub5>::ReadType_t
+ read(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4, const Sub5 &s5) const
+ {
+ typedef View5<This_t, Sub1, Sub2, Sub3, Sub4, Sub5> Ret_t;
+ return Ret_t::makeRead(*this, s1, s2, s3, s4, s5);
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
+ class Sub6>
+ inline typename View6<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6>::ReadType_t
+ read(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4, const Sub5 &s5, const Sub6 &s6) const
+ {
+ typedef View6<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6> Ret_t;
+ return Ret_t::makeRead(*this, s1, s2, s3, s4, s5, s6);
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
+ class Sub6, class Sub7>
+ inline typename
+ View7<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>::ReadType_t
+ read(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4, const Sub5 &s5, const Sub6 &s6, const Sub7 &s7) const
+ {
+ typedef View7<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7> Ret_t;
+ return Ret_t::makeRead(*this, s1, s2, s3, s4, s5, s6, s7);
+ }
+ typename View0<This_t>::Type_t
+ operator()() const
+ {
+ typedef View0<This_t> Ret_t;
+ return Ret_t::make(*this);
+ }
+ template<class Sub1>
+ inline typename View1<This_t,Sub1>::Type_t
+ operator()(const Sub1 &s1) const
+ {
+ typedef View1<This_t, Sub1> Ret_t;
+ return Ret_t::make(*this, s1);
+ }
+ template<class Sub1, class Sub2>
+ inline typename View2<This_t, Sub1, Sub2>::Type_t
+ operator()(const Sub1 &s1, const Sub2 &s2) const
+ {
+ typedef View2<This_t, Sub1, Sub2> Ret_t;
+ return Ret_t::make(*this, s1, s2);
+ }
+ template<class Sub1, class Sub2, class Sub3>
+ inline typename View3<This_t, Sub1, Sub2, Sub3>::Type_t
+ operator()(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3) const
+ {
+ typedef View3<This_t, Sub1, Sub2, Sub3> Ret_t;
+ return Ret_t::make(*this, s1, s2, s3);
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4>
+ inline typename View4<This_t, Sub1, Sub2, Sub3, Sub4>::Type_t
+ operator()(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4) const
+ {
+ typedef View4<This_t, Sub1, Sub2, Sub3, Sub4> Ret_t;
+ return Ret_t::make(*this, s1, s2, s3, s4);
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5>
+ inline typename View5<This_t, Sub1, Sub2, Sub3, Sub4, Sub5>::Type_t
+ operator()(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4, const Sub5 &s5) const
+ {
+ typedef View5<This_t, Sub1, Sub2, Sub3, Sub4, Sub5> Ret_t;
+ return Ret_t::make(*this, s1, s2, s3, s4, s5);
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
+ class Sub6>
+ inline typename
+ View6<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6>::Type_t
+ operator()(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4, const Sub5 &s5, const Sub6 &s6) const
+ {
+ typedef View6<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6> Ret_t;
+ return Ret_t::make(*this, s1, s2, s3, s4, s5, s6);
+ }
+ template<class Sub1, class Sub2, class Sub3, class Sub4, class Sub5,
+ class Sub6, class Sub7>
+ inline typename
+ View7<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7>::Type_t
+ operator()(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3,
+ const Sub4 &s4, const Sub5 &s5, const Sub6 &s6, const Sub7 &s7) const
+ {
+ typedef View7<This_t, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6, Sub7> Ret_t;
+ return Ret_t::make(*this, s1, s2, s3, s4, s5, s6, s7);
+ }
+ inline typename ComponentView<Loc<1>, This_t>::Type_t
+ comp(int i1) const
+ {
+ return ComponentView<Loc<1>, This_t>::make(*this, Loc<1>(i1));
+ }
+ inline typename ComponentView<Loc<2>, This_t>::Type_t
+ comp(int i1, int i2) const
+ {
+ return ComponentView<Loc<2>, This_t>::make(*this, Loc<2>(i1, i2));
+ }
+ inline typename ComponentView<Loc<3>, This_t>::Type_t
+ comp(int i1, int i2, int i3) const
+ {
+ return ComponentView<Loc<3>, This_t>::make(*this, Loc<3>(i1, i2, i3));
+ }
+ inline typename ComponentView<Loc<4>, This_t>::Type_t
+ comp(int i1, int i2, int i3, int i4) const
+ {
+ return ComponentView<Loc<4>, This_t>::make(*this,
+ Loc<4>(i1, i2, i3, i4));
+ }
+ inline typename ComponentView<Loc<5>, This_t>::Type_t
+ comp(int i1, int i2, int i3, int i4, int i5) const
+ {
+ return ComponentView<Loc<5>, This_t>::make(*this,
+ Loc<5>(i1, i2, i3, i4, i5));
+ }
+ inline typename ComponentView<Loc<6>, This_t>::Type_t
+ comp(int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ return ComponentView<Loc<6>, This_t>::make(*this,
+ Loc<6>(i1, i2, i3, i4, i5, i6));
+ }
+ inline typename ComponentView<Loc<7>, This_t>::Type_t
+ comp(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
+ {
+ return ComponentView<Loc<7>, This_t>::make(*this,
+ Loc<7>(i1, i2, i3, i4, i5, i6, i7));
+ }
+ template<class Components>
+ inline typename ComponentView<Components, This_t>::Type_t
+ comp(const Components &components) const
+ {
+ return ComponentView<Components, This_t>::make(*this, components);
+ }
+ inline void makeOwnCopy()
+ { engine_m.makeOwnCopy(); }
+ inline int first(int d) const
+ {
+ return engine_m.first(d);
+ }
+ inline int last(int d) const
+ {
+ return engine_m.domain()[d].last();
+ }
+ inline int length(int d) const
+ {
+ return engine_m.domain()[d].length();
+ }
+ inline Loc<Dim> firsts() const
+ {
+ return engine_m.domain().firsts();
+ }
+ inline Loc<Dim> lasts() const
+ {
+ return engine_m.domain().lasts();
+ }
+ inline Loc<Dim> lengths() const
+ {
+ return engine_m.domain().lengths();
+ }
+ inline long size() const
+ {
+ return engine_m.domain().size();
+ }
+ This_t &operator=(const Array<Dim, T, EngineTag> &rhs)
+ {
+ assign(*this, rhs, OpAssign());
+ return *this;
+ }
+ const This_t &operator=(const Array<Dim, T, EngineTag> &rhs) const
+ {
+ return assign(*this, rhs, OpAssign());
+ }
+ template<class T1>
+ const This_t &operator=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpAssign());
+ }
+ template<class T1>
+ const This_t &operator+=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpAddAssign());
+ }
+ template<class T1>
+ const This_t &operator-=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpSubtractAssign());
+ }
+ template<class T1>
+ const This_t &operator*=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpMultiplyAssign());
+ }
+ template<class T1>
+ const This_t &operator/=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpDivideAssign());
+ }
+ template<class T1>
+ const This_t &operator%=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpModAssign());
+ }
+ template<class T1>
+ const This_t &operator|=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpBitwiseOrAssign());
+ }
+ template<class T1>
+ const This_t &operator&=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpBitwiseAndAssign());
+ }
+ template<class T1>
+ const This_t &operator^=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpBitwiseXorAssign());
+ }
+ template<class T1>
+ const This_t &operator<<=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpLeftShiftAssign());
+ }
+ template<class T1>
+ const This_t &operator>>=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpRightShiftAssign());
+ }
+ inline Engine_t &engine()
+ { return engine_m; }
+ inline const Engine_t &engine() const
+ { return engine_m; }
+ private:
+ Engine_t engine_m;
+ };
+ template<int Dim, class T, class EngineTag>
+ struct LeafFunctor<Array<Dim, T, EngineTag>, DomainFunctorTag>
+ {
+ typedef typename Engine<Dim, T, EngineTag>::Domain_t Type_t;
+ static Type_t apply(const Array<Dim, T, EngineTag> &a,
+ const DomainFunctorTag &)
+ {
+ return a.domain();
+ }
+ };
+ template<int Dim, class T, class EngineTag, class Domain>
+ struct LeafFunctor<Array<Dim, T, EngineTag>, ViewFunctorTag<Domain> >
+ {
+ typedef typename View1<Array<Dim, T, EngineTag>, Domain>::Type_t Type_t;
+ inline static Type_t apply(const Array<Dim, T, EngineTag> &a,
+ const ViewFunctorTag<Domain> &t)
+ {
+ typedef View1<Array<Dim, T, EngineTag>, Domain> Ret_t;
+ return Ret_t::make(a, t.domain_m + a.firsts());
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct LeafFunctor<Array<Dim, T, EngineTag>, EvalLeaf<Dim> >
+ {
+ typedef typename Array<Dim, T, EngineTag>::Element_t Type_t;
+ inline static
+ Type_t apply(const Array<Dim, T, EngineTag> &a, const EvalLeaf<Dim> &t)
+ {
+ return t.eval(a.engine());
+ }
+ };
+ template<int Dim, class T, class E, class Tag>
+ struct LeafFunctor<Array<Dim, T, E>, EngineView<Tag> >
+ {
+ typedef LeafFunctor<Engine<Dim, T, E>, EngineView<Tag> > LeafFunctor_t;
+ typedef typename LeafFunctor_t::Type_t NewEngine_t;
+ typedef typename NewEngine_t::Tag_t NewTag_t;
+ typedef Array<Dim, T, NewTag_t> Type_t;
+ inline static
+ Type_t apply(const Array<Dim, T, E> &array,
+ const EngineView<Tag> &tag)
+ {
+ return Type_t(LeafFunctor_t::apply(array.engine(), tag));
+ }
+ };
+ template<int Dim, class T, class E, class Tag>
+ struct LeafFunctor<Array<Dim, T, E>, ExpressionApply<Tag> >
+ {
+ typedef LeafFunctor<Engine<Dim, T, E>, ExpressionApply<Tag> > LeafFunctor_t;
+ typedef int Type_t;
+ inline static
+ Type_t apply(const Array<Dim, T, E> &array,
+ const ExpressionApply<Tag> &tag)
+ {
+ return LeafFunctor_t::apply(array.engine(), tag);
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct LeafFunctor<Array<Dim, T, EngineTag>, ConformTag<Dim> >
+ {
+ typedef bool Type_t;
+ static Type_t apply(const Array<Dim, T, EngineTag> &array,
+ const ConformTag<Dim> &ct)
+ {
+ return conforms(array.domain(), ct);
+ }
+ };
+ template<int Dim1, int Dim2, class T, class EngineTag>
+ struct LeafFunctor<Array<Dim1, T, EngineTag>, ConformTag<Dim2> >
+ {
+ typedef bool Type_t;
+ static Type_t apply(const Array<Dim1, T, EngineTag> &,
+ const ConformTag<Dim2> &)
+ {
+ return false;
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct LeafFunctor<Array<Dim, T, EngineTag>, NotifyPreReadTag>
+ {
+ typedef bool Type_t;
+ static Type_t apply(const Array<Dim, T, EngineTag> &a,
+ const NotifyPreReadTag &)
+ {
+ return true;
+ }
+ };
+ template<int Dim, class T, class E, class Tag>
+ struct LeafFunctor<Array<Dim, T, E>, EngineFunctorTag<Tag> >
+ {
+ typedef typename Array<Dim,T,E>::Engine_t Engine_t;
+ typedef typename EngineFunctor<Engine_t,Tag>::Type_t Type_t;
+ inline static
+ Type_t apply(const Array<Dim, T, E> &array, const EngineFunctorTag<Tag> &tag)
+ {
+ return EngineFunctor<Engine_t,Tag>::apply(array.engine(), tag.tag());
+ }
+ };
+ template<int Dim, class T, class E, class Tag>
+ struct EngineFunctor<Array<Dim, T, E>, Tag>
+ {
+ typedef typename EngineFunctor<Engine<Dim, T, E>, Tag>::Type_t Type_t;
+ inline static
+ Type_t apply(const Array<Dim, T, E> &array,
+ const Tag &tag)
+ {
+ return engineFunctor(array.engine(), tag);
+ }
+ };
+ template <int Dim, class T, class EngineTag>
+ std::ostream &operator<<(std::ostream &o,
+ const Array<Dim, T, EngineTag> &ca)
+ {
+ Pooma::blockAndEvaluate();
+ PrintArray().print(o, ca);
+ return o;
+ }
+ template <int Dim, class T, class EngineTag>
+ std::fstream &operator<<(std::fstream &f,
+ const Array<Dim, T, EngineTag> &ca)
+ {
+ Pooma::blockAndEvaluate();
+ PrintArray().print(f, ca);
+ return f;
+ }
+ struct ExpressionIsArray { };
+ template<int Dim, class T, class EngineTag>
+ struct ExpressionTraits<Array<Dim, T, EngineTag> >
+ {
+ typedef ExpressionIsArray Type_t;
+ };
+ template<>
+ struct CombineExpressionTraits<ExpressionIsArray, ExpressionIsArray>
+ {
+ typedef ExpressionIsArray Type_t;
+ };
+ template<>
+ struct CombineExpressionTraits<ExpressionIsArray, ExpressionIsScalar>
+ {
+ typedef ExpressionIsArray Type_t;
+ };
+ template<>
+ struct CombineExpressionTraits<ExpressionIsScalar, ExpressionIsArray>
+ {
+ typedef ExpressionIsArray Type_t;
+ };
+ template<int Dim, class T, class EngineTag,
+ int OtherDim, class OtherT, class OtherEngineTag, class Op>
+ inline const Array<Dim, T, EngineTag> &
+ assign(const Array<Dim, T, EngineTag> &lhs,
+ const Array<OtherDim, OtherT, OtherEngineTag> &rhs,
+ const Op &op)
+ {
+ ;
+ Evaluator<MainEvaluatorTag>().evaluate(lhs, op, rhs);
+ return lhs;
+ }
+ template<int Dim, class T, class EngineTag, class T1, class Op>
+ inline const Array<Dim, T, EngineTag> &
+ assign(const Array<Dim, T, EngineTag> &lhs, const T1 &rhs, const Op &op)
+ {
+ Array<Dim, T1, ConstantFunction> rhsExpr(lhs.domain());
+ rhsExpr.engine().setConstant(rhs);
+ Evaluator<MainEvaluatorTag>().evaluate(lhs, op, rhsExpr);
+ return lhs;
+ }
+ template<class Tree>
+ struct ConvertWhereProxy<ExpressionIsArray, Tree>
+ {
+ typedef MakeReturn<Tree> Make_t;
+ };
+ template<int Dim, class T, class EngineTag, class F, class B, class Op>
+ inline const Array<Dim, T, EngineTag> &
+ assign(const Array<Dim, T, EngineTag> &lhs,
+ const WhereProxy<F,B> &rhs,
+ const Op &op)
+ {
+ assign(lhs, rhs.whereMask(), rhs.opMask(op));
+ return lhs;
+ }
+ template<int Dim, class T, class EngineTag>
+ inline long
+ elementsCompressed(const Array<Dim, T, EngineTag> &a)
+ {
+ return elementsCompressed(a.engine());
+ }
+ template<int Dim, class T, class EngineTag>
+ inline bool
+ compressed(const Array<Dim, T, EngineTag> &a)
+ {
+ return compressed(a.engine());
+ }
+ template<int Dim, class T, class EngineTag>
+ inline void
+ compress(Array<Dim, T, EngineTag> &a)
+ {
+ compress(a.engine());
+ }
+ template<int Dim, class T, class EngineTag>
+ inline void
+ uncompress(Array<Dim, T, EngineTag> &a)
+ {
+ uncompress(a.engine());
+ }
+ template <int Dim, class T, class EngineTag>
+ struct ElementProperties< Array<Dim, T, EngineTag> >
+ : public MakeOwnCopyProperties< Array<Dim, T, EngineTag> >
+ { };
+ template <int Dim> class UniformGridLayout;
+ template <int Dim, int Dim2> class UniformGridLayoutView;
+ struct UniformTag { };
+ template <int Dim>
+ struct MultiPatchLayoutTraits<UniformTag,Dim>
+ {
+ typedef UniformGridLayout<Dim> Layout_t;
+ template <int ViewDim>
+ struct View
+ {
+ typedef UniformGridLayoutView<ViewDim,Dim> Layout_t;
+ };
+ };
+ template <int Dim>
+ class UniformGridLayoutData
+ : public LayoutBaseData<Dim>,
+ public RefCounted,
+ public Observable<UniformGridLayoutData<Dim> >
+ {
+ public:
+ typedef Interval<Dim> Domain_t;
+ typedef Interval<Dim> BaseDomain_t;
+ typedef int Context_t;
+ typedef Unique::Value_t ID_t;
+ typedef Node<Domain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ typedef typename LayoutBaseData<Dim>::GCFillInfo GCFillInfo_t;
+ typedef typename std::vector<GCFillInfo_t>::const_iterator FillIterator_t;
+ enum { dimensions = Dim };
+ enum { repartitionEvent = 1 };
+ enum { dynamic = false };
+ UniformGridLayoutData();
+ template <class Partitioner>
+ UniformGridLayoutData(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> & cmap );
+ void initialize(const Domain_t& idom,
+ const List_t& nodes,
+ const Loc<Dim>& blocks,
+ bool hasIG, bool hasEG,
+ const GuardLayers_t& ig,
+ const GuardLayers_t& eg);
+ ~UniformGridLayoutData()
+ {
+ typename List_t::iterator a;
+ for (a = this->all_m.begin(); a != this->all_m.end(); ++a)
+ delete (*a);
+ }
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touches(const OtherDomain &d, OutIter o, const ConstructTag &ctag) const;
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touchesLocal(const OtherDomain &d,
+ OutIter o,
+ const ConstructTag &ctag) const;
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touchesRemote(const OtherDomain &d,
+ OutIter o,
+ const ConstructTag &ctag) const;
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touchesAlloc(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const;
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touchesAllocLocal(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const;
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touchesAllocRemote(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const;
+ friend class UniformGridLayout<Dim>;
+ int globalID(const Loc<Dim> &loc) const;
+ int globalID(int) const;
+ int globalID(int,int) const;
+ int globalID(int,int,int) const;
+ int globalID(int,int,int,int) const;
+ int globalID(int,int,int,int,int) const;
+ int globalID(int,int,int,int,int,int) const;
+ int globalID(int,int,int,int,int,int,int) const;
+ template <class Partitioner>
+ void partition(const Partitioner &, const ContextMapper<Dim>& cmap);
+ template <class Partitioner>
+ bool repartition(const Partitioner &,const ContextMapper<Dim>&);
+ void calcGCFillList();
+ int blockstride_m[Dim];
+ int blocksizes_m[Dim];
+ Interval<Dim> allDomain_m;
+ };
+ template <int Dim>
+ class UniformGridLayout : public LayoutBase<Dim,UniformGridLayoutData<Dim> >,
+ public Observable<UniformGridLayout<Dim> >,
+ public Observer<UniformGridLayoutData<Dim> >
+ {
+ public:
+ typedef UniformGridLayoutData<Dim> LayoutData_t;
+ typedef typename LayoutData_t::Domain_t Domain_t;
+ typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
+ typedef typename LayoutData_t::Context_t Context_t;
+ typedef typename LayoutData_t::ID_t ID_t;
+ typedef typename LayoutData_t::Value_t Value_t;
+ typedef typename LayoutData_t::List_t List_t;
+ typedef UniformGridLayout<Dim> This_t;
+ typedef Observable<This_t> Observable_t;
+ typedef DerefIterator<Value_t> iterator;
+ typedef ConstDerefIterator<Value_t> const_iterator;
+ typedef typename LayoutData_t::GCFillInfo_t GCFillInfo_t;
+ typedef typename
+ std::vector<GCFillInfo_t>::const_iterator FillIterator_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ enum { dimensions = Dim };
+ enum { repartitionEvent = LayoutData_t::repartitionEvent };
+ enum { dynamic = false };
+ UniformGridLayout();
+ UniformGridLayout(const Domain_t &,
+ const DistributedTag &);
+ UniformGridLayout(const Domain_t &,
+ const GuardLayers_t &,
+ const DistributedTag &);
+ UniformGridLayout(const Domain_t &,
+ const Loc<Dim> &,
+ const DistributedTag &);
+ UniformGridLayout(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,
+ const DistributedTag &);
+ UniformGridLayout(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,
+ const GuardLayers_t &,
+ const DistributedTag &);
+ UniformGridLayout(const Domain_t &,
+ const ReplicatedTag &);
+ UniformGridLayout(const Domain_t &,
+ const GuardLayers_t &,
+ const ReplicatedTag &);
+ UniformGridLayout(const Domain_t &,
+ const Loc<Dim> &,
+ const ReplicatedTag &);
+ UniformGridLayout(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,
+ const ReplicatedTag &);
+ UniformGridLayout(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,
+ const GuardLayers_t &,
+ const ReplicatedTag &);
+ template <class Partitioner>
+ UniformGridLayout(const Domain_t &,
+ const Partitioner &,
+ const ContextMapper<Dim> & );
+ template <class Partitioner>
+ UniformGridLayout(const Domain_t &,
+ const Partitioner &,
+ const DistributedTag &);
+ template <class Partitioner>
+ UniformGridLayout(const Domain_t &,
+ const Partitioner &,
+ const ReplicatedTag &);
+ UniformGridLayout(const This_t &);
+ This_t &operator=(const This_t &);
+ inline ~UniformGridLayout()
+ {
+ this->pdata_m->detach(*this);
+ }
+ void initialize(const Domain_t &,
+ const DistributedTag &);
+ void initialize(const Domain_t &,
+ const ReplicatedTag &);
+ void initialize(const Domain_t &,
+ const GuardLayers_t &,
+ const DistributedTag &);
+ void initialize(const Domain_t &,
+ const GuardLayers_t &,
+ const ReplicatedTag &);
+ void initialize(const Domain_t &,
+ const Loc<Dim> &,
+ const DistributedTag &);
+ void initialize(const Domain_t &,
+ const Loc<Dim> &,
+ const ReplicatedTag &);
+ void initialize(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,
+ const DistributedTag & );
+ void initialize(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,
+ const ReplicatedTag & );
+ void initialize(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,
+ const GuardLayers_t &,
+ const DistributedTag &);
+ void initialize(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,
+ const GuardLayers_t &,
+ const ReplicatedTag &);
+ template <class Partitioner>
+ void initialize(const Domain_t &,
+ const Partitioner &,
+ const DistributedTag &);
+ template <class Partitioner>
+ void initialize(const Domain_t &,
+ const Partitioner &,
+ const ReplicatedTag &);
+ template <class Partitioner>
+ void initialize(const Domain_t &,
+ const Partitioner &,
+ const ContextMapper<Dim> &);
+ void initialize(const Domain_t& idom,
+ const List_t& nodes,
+ const Loc<Dim>& blocks,
+ bool hasIG, bool hasEG,
+ const GuardLayers_t& ig,
+ const GuardLayers_t& eg);
+ virtual void notify(LayoutData_t &d, const ObserverEvent &event)
+ {
+ ;
+ Observable_t::notify(event);
+ }
+ template <class Ostream>
+ void print(Ostream &ostr) const;
+ template <int Dim1, int Dim2>
+ friend class UniformGridLayoutView;
+ friend class UniformGridLayoutData<Dim>;
+ };
+ template <int Dim, int Dim2>
+ class UniformGridLayoutViewData
+ : public LayoutBaseViewData<Dim, Dim2, UniformGridLayout<Dim2> >,
+ public RefCounted
+ {
+ public:
+ typedef UniformGridLayout<Dim2> Layout_t;
+ typedef UniformGridLayoutView<Dim, Dim2> ViewLayout_t;
+ typedef LayoutBaseViewData<Dim,Dim2,Layout_t> Base_t;
+ typedef Interval<Dim> Domain_t;
+ typedef Range<Dim2> BaseDomain_t;
+ typedef int Context_t;
+ typedef Unique::Value_t ID_t;
+ typedef typename Layout_t::Domain_t AllocatedDomain_t;
+ typedef ViewIndexer<Dim,Dim2> Indexer_t;
+ typedef Node<Domain_t,AllocatedDomain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ enum { dim = Dim };
+ enum { dim2 = Dim2};
+ UniformGridLayoutViewData() { };
+ template <class DT>
+ inline
+ UniformGridLayoutViewData(const Layout_t &layout, const Domain<Dim, DT> &dom)
+ : LayoutBaseViewData<Dim,Dim2,UniformGridLayout<Dim2> >(layout,dom)
+ {
+ }
+ template <class DT>
+ inline
+ UniformGridLayoutViewData(const Layout_t &layout, const SliceDomain<DT> &dom)
+ :LayoutBaseViewData<Dim,Dim2,UniformGridLayout<Dim2> >(layout,dom)
+ {
+ }
+ template <class DT>
+ UniformGridLayoutViewData(const ViewLayout_t &layout,
+ const Domain<Dim, DT> &dom)
+ : LayoutBaseViewData<Dim,Dim2,UniformGridLayout<Dim2> >(
+ layout.pdata_m->layout_m,
+ layout,
+ layout.pdata_m->indexer_m,
+ dom,
+ layout.internalGuards(),
+ layout.externalGuards())
+ {
+ }
+ template <int OrigDim, class DT>
+ UniformGridLayoutViewData(const UniformGridLayoutView<OrigDim,Dim2> &layout,
+ const SliceDomain<DT> &dom)
+ : LayoutBaseViewData<Dim,Dim2,UniformGridLayout<Dim2> >(
+ layout.pdata_m->layout_m,
+ layout,
+ Indexer_t(layout.pdata_m->indexer_m,dom),
+ dom)
+ {
+ }
+ ~UniformGridLayoutViewData()
+ {
+ typename List_t::iterator a;
+ for (a = this->all_m.begin(); a != this->all_m.end(); ++a)
+ delete (*a);
+ }
+ };
+ template <int Dim, int Dim2>
+ class UniformGridLayoutView
+ : public LayoutBaseView<Dim, Dim2, UniformGridLayoutViewData<Dim,Dim2> >
+ {
+ public:
+ enum { dimensions = Dim };
+ enum { dim = Dim };
+ enum { dim2 = Dim2};
+ typedef UniformGridLayoutViewData<Dim, Dim2> LayoutData_t;
+ typedef typename LayoutData_t::Domain_t Domain_t;
+ typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
+ typedef typename LayoutData_t::Context_t Context_t;
+ typedef typename LayoutData_t::ID_t ID_t;
+ typedef typename LayoutData_t::Layout_t Layout_t;
+ typedef typename LayoutData_t::AllocatedDomain_t AllocatedDomain_t;
+ typedef typename LayoutData_t::Value_t Value_t;
+ typedef typename LayoutData_t::List_t List_t;
+ typedef typename LayoutData_t::Indexer_t Indexer_t;
+ typedef typename LayoutData_t::GuardLayers_t GuardLayers_t;
+ typedef UniformGridLayoutView<Dim, Dim2> This_t;
+ typedef UniformGridLayoutView<Dim, Dim2> ViewLayout_t;
+ typedef LayoutBaseView<Dim,Dim2,LayoutData_t> Base_t;
+ typedef DerefIterator<Value_t> iterator;
+ typedef ConstDerefIterator<Value_t> const_iterator;
+ UniformGridLayoutView()
+ : Base_t(new LayoutData_t())
+ { }
+ template <class DT>
+ UniformGridLayoutView(const Layout_t &layout, const Domain<Dim2, DT> &dom)
+ : LayoutBaseView<Dim,Dim2,UniformGridLayoutViewData<Dim,Dim2> >
+ (new UniformGridLayoutViewData<Dim,Dim2>(layout,dom))
+ { }
+ template <class DT>
+ UniformGridLayoutView(const Layout_t &layout, const SliceDomain<DT> &dom)
+ : LayoutBaseView<Dim,Dim2,UniformGridLayoutViewData<Dim,Dim2> >
+ (new UniformGridLayoutViewData<Dim,Dim2>(layout,dom))
+ { }
+ template <class DT>
+ UniformGridLayoutView(const ViewLayout_t &layout, const Domain<Dim, DT> &dom)
+ : LayoutBaseView<Dim,Dim2,UniformGridLayoutViewData<Dim,Dim2> >
+ (new UniformGridLayoutViewData<Dim,Dim2>(layout,dom))
+ { }
+ template <int OldViewDim, class DT>
+ UniformGridLayoutView(const UniformGridLayoutView<OldViewDim, Dim2> &layout,
+ const SliceDomain<DT> &dom)
+ : LayoutBaseView<Dim,Dim2,UniformGridLayoutViewData<Dim,Dim2> >
+ (new UniformGridLayoutViewData<Dim,Dim2>(layout,dom))
+ { }
+ inline UniformGridLayoutView(const This_t &model)
+ : LayoutBaseView<Dim,
+ Dim2,
+ UniformGridLayoutViewData<Dim,Dim2> >(model.pdata_m)
+ { }
+ inline This_t &operator=(const This_t &model)
+ {
+ if (this != &model)
+ {
+ this->pdata_m = model.pdata_m;
+ }
+ return *this;
+ }
+ inline ~UniformGridLayoutView()
+ { }
+ template <class Ostream>
+ void print(Ostream &ostr) const;
+ template <int OtherDim, int OtherDim2>
+ friend class UniformGridLayoutView;
+ template <int OtherDim, int OtherDim2>
+ friend class UniformGridLayoutViewData;
+ };
+ template <int Dim>
+ struct NewDomain1<UniformGridLayout<Dim> >
+ {
+ typedef UniformGridLayout<Dim> &Type_t;
+ inline static Type_t combine(const UniformGridLayout<Dim> &a)
+ {
+ return const_cast<Type_t>(a);
+ }
+ };
+ template <int Dim, int Dim2>
+ struct NewDomain1<UniformGridLayoutView<Dim, Dim2> >
+ {
+ typedef UniformGridLayoutView<Dim, Dim2> &Type_t;
+ inline static Type_t combine(const UniformGridLayoutView<Dim, Dim2> &a)
+ {
+ return const_cast<Type_t>(a);
+ }
+ };
+ template <int Dim>
+ std::ostream &operator<<(std::ostream &ostr,
+ const UniformGridLayout<Dim> &layout)
+ {
+ layout.print(ostr);
+ return ostr;
+ }
+ template <int Dim, int Dim2>
+ std::ostream &operator<<(std::ostream &ostr,
+ const UniformGridLayoutView<Dim, Dim2> &layout)
+ {
+ layout.print(ostr);
+ return ostr;
+ }
+ template <int Dim>
+ inline UniformGridLayoutData<Dim>::
+ UniformGridLayoutData()
+ : Observable<UniformGridLayoutData>(*this)
+ {
+ for (int i = 0; i < Dim; ++i)
+ blockstride_m[i] = blocksizes_m[i] = 0;
+ }
+ template <int Dim>
+ template <class Partitioner>
+ UniformGridLayoutData<Dim>::
+ UniformGridLayoutData(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> & cmap )
+ : LayoutBaseData<Dim>(false,
+ false,
+ GuardLayers_t(0),
+ GuardLayers_t(0),
+ gdom,
+ gdom),
+ Observable<UniformGridLayoutData>(*this)
+ {
+ if (gpar.hasInternalGuards() && gpar.maxSize() > 1)
+ {
+ this->hasInternalGuards_m = true;
+ this->internalGuards_m = gpar.internalGuards();
+ }
+ if (gpar.hasExternalGuards())
+ {
+ this->hasExternalGuards_m = true;
+ this->externalGuards_m = gpar.externalGuards();
+ GuardLayers<Dim>::addGuardLayers(this->domain_m,this->externalGuards_m);
+ }
+ partition(gpar,cmap);
+ }
+ template <int Dim>
+ template <class Partitioner>
+ void UniformGridLayoutData<Dim>::partition(const Partitioner &gpar,
+ const ContextMapper<Dim> &cmap)
+ {
+ int i;
+ PoomaCTAssert<(Partitioner::uniform)>::test();
+ ;
+ ;
+ ;
+ ;
+ ;
+ this->blocks_m = gpar.blocks();
+ blockstride_m[0] = 1;
+ int blocks[Dim];
+ for (i = 0; i < Dim; ++i)
+ {
+ this->firsti_m[i] = this->innerdomain_m[i].first();
+ this->firste_m[i] = this->domain_m[i].first();
+ blocks[i] = gpar.blocks()[i].first();
+ allDomain_m[i] = Interval<1>(blocks[i]);
+ blocksizes_m[i] = this->innerdomain_m[i].length() / blocks[i];
+ if (i > 0)
+ blockstride_m[i] = blockstride_m[i-1] * blocks[i-1];
+ }
+ gpar.partition(this->innerdomain_m, this->all_m, cmap);
+ typename List_t::const_iterator start = this->all_m.begin();
+ typename List_t::const_iterator end = this->all_m.end();
+ for ( ; start!=end ; ++start)
+ {
+ if ( (*start)->context() == Pooma::context()
+ || (*start)->context() == -1 )
+ {
+ (*start)->localID() = this->local_m.size();
+ this->local_m.push_back(*start);
+ }
+ else
+ this->remote_m.push_back(*start);
+ }
+ if (this->hasInternalGuards_m)
+ {
+ this->gcFillList_m.clear();
+ calcGCFillList();
+ }
+ }
+ template<int Dim>
+ void UniformGridLayoutData<Dim>::initialize(const Domain_t& idom,
+ const List_t& nodes,
+ const Loc<Dim>& ublocks,
+ bool hasIG, bool hasEG,
+ const GuardLayers_t& ig,
+ const GuardLayers_t& eg)
+ {
+ int i;
+ if (this->all_m.size() > 0)
+ {
+ for (i=0; i < this->all_m.size(); ++i)
+ delete this->all_m[i];
+ this->all_m.clear();
+ this->local_m.clear();
+ this->remote_m.clear();
+ }
+ this->domain_m = idom;
+ this->innerdomain_m = idom;
+ this->hasInternalGuards_m = hasIG;
+ if (this->hasInternalGuards_m)
+ {
+ this->internalGuards_m = ig;
+ }
+ this->hasExternalGuards_m = (hasEG && ! this->domain_m.empty());
+ if (this->hasExternalGuards_m)
+ {
+ this->externalGuards_m = eg;
+ GuardLayers<Dim>::addGuardLayers(this->domain_m, this->externalGuards_m);
+ }
+ this->blocks_m = ublocks;
+ blockstride_m[0] = 1;
+ int blocks[Dim];
+ for (i = 0; i < Dim; ++i)
+ {
+ this->firsti_m[i] = this->innerdomain_m[i].first();
+ this->firste_m[i] = this->domain_m[i].first();
+ blocks[i] = ublocks[i].first();
+ allDomain_m[i] = Interval<1>(blocks[i]);
+ blocksizes_m[i] = this->innerdomain_m[i].length() / blocks[i];
+ if (i > 0)
+ blockstride_m[i] = blockstride_m[i-1] * blocks[i-1];
+ }
+ this->all_m= nodes;
+ typename List_t::iterator start = this->all_m.begin();
+ typename List_t::iterator end = this->all_m.end();
+ for ( ; start!=end ;++start )
+ {
+ if( (*start)->context() == Pooma::context() ||
+ (*start)->context() == -1 )
+ this->local_m.push_back(*start);
+ else
+ this->remote_m.push_back(*start);
+ }
+ if (this->hasInternalGuards_m)
+ {
+ this->gcFillList_m.clear();
+ calcGCFillList();
+ }
+ }
+ template <int Dim>
+ void UniformGridLayoutData<Dim>::calcGCFillList()
+ {
+ int d, p;
+ int numPatches = this->all_m.size();
+ this->gcFillList_m.reserve(2*Dim*this->local_m.size());
+ for (d = 0; d < Dim; ++d)
+ {
+ if (this->internalGuards_m.lower(d) > 0)
+ {
+ typename Interval<Dim>::iterator pos = allDomain_m.begin();
+ for (p = 0; p < numPatches; ++p, ++pos)
+ {
+ if ( (*pos)[d].first() == allDomain_m[d].last() ) continue;
+ int sourceID = p;
+ int destID = p + blockstride_m[d];
+ ;
+ ;
+ Domain_t gcdom(this->all_m[p]->allocated());
+ int max = this->all_m[p]->domain()[d].last();
+ int min = max - this->internalGuards_m.lower(d) + 1;
+ gcdom[d] = Interval<1>(min,max);
+ if (
+ this->all_m[sourceID]->context() == -1 ||
+ this->all_m[sourceID]->context() == Pooma::context() ||
+ this->all_m[destID]->context() == Pooma::context()
+ )
+ this->gcFillList_m.push_back(GCFillInfo_t(gcdom,sourceID,destID,d*2));
+ }
+ }
+ if (this->internalGuards_m.upper(d) > 0)
+ {
+ typename Interval<Dim>::iterator pos = allDomain_m.begin();
+ for (p = 0; p < numPatches; ++p, ++pos)
+ {
+ if ( (*pos)[d].first() == allDomain_m[d].first() ) continue;
+ int sourceID = p;
+ int destID = p - blockstride_m[d];
+ ;
+ Domain_t gcdom(this->all_m[p]->allocated());
+ int min = this->all_m[p]->domain()[d].first();
+ int max = min + this->internalGuards_m.upper(d) - 1;
+ gcdom[d] = Interval<1>(min,max);
+ if (
+ this->all_m[sourceID]->context() == -1 ||
+ this->all_m[sourceID]->context() == Pooma::context() ||
+ this->all_m[destID]->context() == Pooma::context()
+ )
+ this->gcFillList_m.push_back(GCFillInfo_t(gcdom,sourceID,destID,d*2+1));
+ }
+ }
+ }
+ }
+ template <int Dim>
+ template <class Partitioner>
+ bool UniformGridLayoutData<Dim>::
+ repartition(const Partitioner &p,
+ const ContextMapper<Dim>& cmap)
+ {
+ ;
+ for (int i = 0; i < this->all_m.size(); ++i)
+ delete this->all_m[i];
+ this->all_m.clear();
+ this->local_m.clear();
+ this->remote_m.clear();
+ partition(p,cmap);
+ if (this->hasInternalGuards_m)
+ {
+ this->gcFillList_m.clear();
+ calcGCFillList();
+ }
+ this->notify(repartitionEvent);
+ return true;
+ }
+ template <int Dim>
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int UniformGridLayoutData<Dim>::touches(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const
+ {
+ int i, count = 0;
+ ;
+ ;
+ Interval<Dim> box = Pooma::NoInit();
+ for (i = 0; i < Dim; ++i)
+ {
+ int a, b;
+ if (!this->hasExternalGuards_m)
+ {
+ a = (d[i].min() - this->firsti_m[i]) / blocksizes_m[i];
+ b = (d[i].max() - this->firsti_m[i]) / blocksizes_m[i];
+ }
+ else
+ {
+ a = b = 0;
+ int pos = d[i].min();
+ int last = this->innerdomain_m[i].last();
+ int del = pos - this->firsti_m[i];
+ if (del >= 0)
+ if (pos <= last)
+ a = del / blocksizes_m[i];
+ else
+ a = allDomain_m[i].last();
+ pos = d[i].max();
+ del = pos - this->firsti_m[i];
+ if (del >= 0)
+ if (pos <= last)
+ b = del / blocksizes_m[i];
+ else
+ b = allDomain_m[i].last();
+ }
+ box[i] = Interval<1>(a, b);
+ }
+ typedef typename
+ IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
+ OutDomain_t outDomain = Pooma::NoInit();
+ typedef Node<OutDomain_t,Domain_t> OutNode_t;
+ typename Interval<Dim>::const_iterator boxiter = box.begin();
+ while (boxiter != box.end())
+ {
+ int indx = (*boxiter)[0].first();
+ for (i = 1; i < Dim; ++i)
+ indx += blockstride_m[i] * (*boxiter)[i].first();
+ ;
+ outDomain = intersect(d, this->all_m[indx]->domain());
+ ;
+ *o = touchesConstruct(outDomain,
+ this->all_m[indx]->allocated(),
+ this->all_m[indx]->affinity(),
+ this->all_m[indx]->context(),
+ this->all_m[indx]->globalID(),
+ this->all_m[indx]->localID(),
+ ctag);
+ ++o;
+ ++count;
+ ++boxiter;
+ }
+ return count;
+ }
+ template <int Dim>
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int UniformGridLayoutData<Dim>::touchesLocal(const OtherDomain &d,
+ OutIter o,
+ const ConstructTag &ctag) const
+ {
+ int i, count = 0;
+ ;
+ ;
+ Interval<Dim> box = Pooma::NoInit();
+ for (i = 0; i < Dim; ++i)
+ {
+ int a, b;
+ if (!this->hasExternalGuards_m)
+ {
+ a = (d[i].min() - this->firsti_m[i]) / blocksizes_m[i];
+ b = (d[i].max() - this->firsti_m[i]) / blocksizes_m[i];
+ }
+ else
+ {
+ a = b = 0;
+ int pos = d[i].min();
+ int last = this->innerdomain_m[i].last();
+ int del = pos - this->firsti_m[i];
+ if (del >= 0)
+ if (pos <= last)
+ a = del / blocksizes_m[i];
+ else
+ a = allDomain_m[i].last();
+ pos = d[i].max();
+ del = pos - this->firsti_m[i];
+ if (del >= 0)
+ if (pos <= last)
+ b = del / blocksizes_m[i];
+ else
+ b = allDomain_m[i].last();
+ }
+ box[i] = Interval<1>(a, b);
+ }
+ typedef typename
+ IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
+ OutDomain_t outDomain = Pooma::NoInit();
+ typedef Node<OutDomain_t,Domain_t> OutNode_t;
+ typename Interval<Dim>::const_iterator boxiter = box.begin();
+ while (boxiter != box.end())
+ {
+ int indx = (*boxiter)[0].first();
+ for (i = 1; i < Dim; ++i)
+ indx += blockstride_m[i] * (*boxiter)[i].first();
+ ;
+ outDomain = intersect(d, this->local_m[indx]->domain());
+ ;
+ *o = touchesConstruct(outDomain,
+ this->local_m[indx]->allocated(),
+ this->local_m[indx]->affinity(),
+ this->local_m[indx]->context(),
+ this->local_m[indx]->globalID(),
+ this->local_m[indx]->localID(),
+ ctag);
+ ++o;
+ ++count;
+ ++boxiter;
+ }
+ return count;
+ }
+ template <int Dim>
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int UniformGridLayoutData<Dim>::touchesRemote(const OtherDomain &d,
+ OutIter o,
+ const ConstructTag &ctag) const
+ {
+ int i, count = 0;
+ ;
+ ;
+ Interval<Dim> box = Pooma::NoInit();
+ for (i = 0; i < Dim; ++i)
+ {
+ int a, b;
+ if (!this->hasExternalGuards_m)
+ {
+ a = (d[i].min() - this->firsti_m[i]) / blocksizes_m[i];
+ b = (d[i].max() - this->firsti_m[i]) / blocksizes_m[i];
+ }
+ else
+ {
+ a = b = 0;
+ int pos = d[i].min();
+ int last = this->innerdomain_m[i].last();
+ int del = pos - this->firsti_m[i];
+ if (del >= 0)
+ if (pos <= last)
+ a = del / blocksizes_m[i];
+ else
+ a = allDomain_m[i].last();
+ pos = d[i].max();
+ del = pos - this->firsti_m[i];
+ if (del >= 0)
+ if (pos <= last)
+ b = del / blocksizes_m[i];
+ else
+ b = allDomain_m[i].last();
+ }
+ box[i] = Interval<1>(a, b);
+ }
+ typedef typename
+ IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
+ OutDomain_t outDomain = Pooma::NoInit();
+ typedef Node<OutDomain_t,Domain_t> OutNode_t;
+ typename Interval<Dim>::const_iterator boxiter = box.begin();
+ while (boxiter != box.end())
+ {
+ int indx = (*boxiter)[0].first();
+ for (i = 1; i < Dim; ++i)
+ indx += blockstride_m[i] * (*boxiter)[i].first();
+ ;
+ outDomain = intersect(d, this->remote_m[indx]->domain());
+ ;
+ *o = touchesConstruct(outDomain,
+ this->remote_m[indx]->allocated(),
+ this->remote_m[indx]->affinity(),
+ this->remote_m[indx]->context(),
+ this->remote_m[indx]->globalID(),
+ this->remote_m[indx]->localID(),
+ ctag);
+ ++o;
+ ++count;
+ ++boxiter;
+ }
+ return count;
+ }
+ template <int Dim>
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int UniformGridLayoutData<Dim>::touchesAlloc(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const
+ {
+ if (!this->hasInternalGuards_m) return touches(d,o,ctag);
+ int i, count = 0;
+ ;
+ ;
+ Interval<Dim> box = Pooma::NoInit();
+ for (i = 0; i < Dim; ++i)
+ {
+ int a, b;
+ if (!this->hasExternalGuards_m)
+ {
+ a = (d[i].min() - this->firsti_m[i]) / blocksizes_m[i];
+ b = (d[i].max() - this->firsti_m[i]) / blocksizes_m[i];
+ }
+ else
+ {
+ a = b = 0;
+ int pos = d[i].min();
+ int last = this->innerdomain_m[i].last();
+ int del = pos - this->firsti_m[i];
+ if (del >= 0)
+ if (pos <= last)
+ a = del / blocksizes_m[i];
+ else
+ a = allDomain_m[i].last();
+ pos = d[i].max();
+ del = pos - this->firsti_m[i];
+ if (del >= 0)
+ if (pos <= last)
+ b = del / blocksizes_m[i];
+ else
+ b = allDomain_m[i].last();
+ }
+ if (a > 0) --a;
+ if (b < allDomain_m[i].last()) ++b;
+ box[i] = Interval<1>(a, b);
+ }
+ typedef typename
+ IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
+ OutDomain_t outDomain = Pooma::NoInit();
+ typedef Node<OutDomain_t,Domain_t> OutNode_t;
+ typename Interval<Dim>::const_iterator boxiter = box.begin();
+ while (boxiter != box.end())
+ {
+ int indx = (*boxiter)[0].first();
+ for (i = 1; i < Dim; ++i)
+ indx += blockstride_m[i] * (*boxiter)[i].first();
+ ;
+ outDomain = intersect(d, this->all_m[indx]->allocated());
+ if (!outDomain.empty())
+ {
+ *o = touchesConstruct(outDomain,
+ this->all_m[indx]->allocated(),
+ this->all_m[indx]->affinity(),
+ this->all_m[indx]->context(),
+ this->all_m[indx]->globalID(),
+ this->all_m[indx]->localID(),
+ ctag);
+ }
+ ++o;
+ ++count;
+ ++boxiter;
+ }
+ return count;
+ }
+ template <int Dim>
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int UniformGridLayoutData<Dim>::touchesAllocLocal(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const
+ {
+ if (!this->hasInternalGuards_m) return touches(d,o,ctag);
+ int i, count = 0;
+ ;
+ ;
+ Interval<Dim> box = Pooma::NoInit();
+ for (i = 0; i < Dim; ++i)
+ {
+ int a, b;
+ if (!this->hasExternalGuards_m)
+ {
+ a = (d[i].min() - this->firsti_m[i]) / blocksizes_m[i];
+ b = (d[i].max() - this->firsti_m[i]) / blocksizes_m[i];
+ }
+ else
+ {
+ a = b = 0;
+ int pos = d[i].min();
+ int last = this->innerdomain_m[i].last();
+ int del = pos - this->firsti_m[i];
+ if (del >= 0)
+ if (pos <= last)
+ a = del / blocksizes_m[i];
+ else
+ a = allDomain_m[i].last();
+ pos = d[i].max();
+ del = pos - this->firsti_m[i];
+ if (del >= 0)
+ if (pos <= last)
+ b = del / blocksizes_m[i];
+ else
+ b = allDomain_m[i].last();
+ }
+ if (a > 0) --a;
+ if (b < allDomain_m[i].last()) ++b;
+ box[i] = Interval<1>(a, b);
+ }
+ typedef typename
+ IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
+ OutDomain_t outDomain = Pooma::NoInit();
+ typedef Node<OutDomain_t,Domain_t> OutNode_t;
+ typename Interval<Dim>::const_iterator boxiter = box.begin();
+ while (boxiter != box.end())
+ {
+ int indx = (*boxiter)[0].first();
+ for (i = 1; i < Dim; ++i)
+ indx += blockstride_m[i] * (*boxiter)[i].first();
+ ;
+ outDomain = intersect(d, this->local_m[indx]->allocated());
+ if (!outDomain.empty())
+ {
+ *o = touchesConstruct(outDomain,
+ this->local_m[indx]->allocated(),
+ this->local_m[indx]->affinity(),
+ this->local_m[indx]->context(),
+ this->local_m[indx]->globalID(),
+ this->local_m[indx]->localID(),
+ ctag);
+ }
+ ++o;
+ ++count;
+ ++boxiter;
+ }
+ return count;
+ }
+ template <int Dim>
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int UniformGridLayoutData<Dim>::touchesAllocRemote(const OtherDomain &d, OutIter o,
+ const ConstructTag &ctag) const
+ {
+ if (!this->hasInternalGuards_m) return touches(d,o,ctag);
+ int i, count = 0;
+ ;
+ ;
+ Interval<Dim> box = Pooma::NoInit();
+ for (i = 0; i < Dim; ++i)
+ {
+ int a, b;
+ if (!this->hasExternalGuards_m)
+ {
+ a = (d[i].min() - this->firsti_m[i]) / blocksizes_m[i];
+ b = (d[i].max() - this->firsti_m[i]) / blocksizes_m[i];
+ }
+ else
+ {
+ a = b = 0;
+ int pos = d[i].min();
+ int last = this->innerdomain_m[i].last();
+ int del = pos - this->firsti_m[i];
+ if (del >= 0)
+ if (pos <= last)
+ a = del / blocksizes_m[i];
+ else
+ a = allDomain_m[i].last();
+ pos = d[i].max();
+ del = pos - this->firsti_m[i];
+ if (del >= 0)
+ if (pos <= last)
+ b = del / blocksizes_m[i];
+ else
+ b = allDomain_m[i].last();
+ }
+ if (a > 0) --a;
+ if (b < allDomain_m[i].last()) ++b;
+ box[i] = Interval<1>(a, b);
+ }
+ typedef typename
+ IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
+ OutDomain_t outDomain = Pooma::NoInit();
+ typedef Node<OutDomain_t,Domain_t> OutNode_t;
+ typename Interval<Dim>::const_iterator boxiter = box.begin();
+ while (boxiter != box.end())
+ {
+ int indx = (*boxiter)[0].first();
+ for (i = 1; i < Dim; ++i)
+ indx += blockstride_m[i] * (*boxiter)[i].first();
+ ;
+ outDomain = intersect(d, this->remote_m[indx]->allocated());
+ if (!outDomain.empty())
+ {
+ *o = touchesConstruct(outDomain,
+ this->remote_m[indx]->allocated(),
+ this->remote_m[indx]->affinity(),
+ this->remote_m[indx]->context(),
+ this->remote_m[indx]->globalID(),
+ this->remote_m[indx]->localID(),
+ ctag);
+ }
+ ++o;
+ ++count;
+ ++boxiter;
+ }
+ return count;
+ }
+ template <int Dim>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout()
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >
+ (new LayoutData_t()),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout(const Domain_t &gdom,
+ const DistributedTag& t)
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ UniformGridPartition<Dim>(),
+ DistributedMapper<Dim>(UniformGridPartition<Dim>()))),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout(const Domain_t &gdom,
+ const ReplicatedTag & t)
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ UniformGridPartition<Dim>(),
+ LocalMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout(const Domain_t &gdom,
+ const GuardLayers_t &gcs,
+ const DistributedTag &)
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ UniformGridPartition<Dim>(gcs),
+ DistributedMapper<Dim>(UniformGridPartition<Dim>(gcs)))),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout(const Domain_t &gdom,
+ const GuardLayers_t &gcs,
+ const ReplicatedTag & )
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ UniformGridPartition<Dim>(gcs),
+ LocalMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const DistributedTag & )
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ UniformGridPartition<Dim>(blocks),
+ DistributedMapper<Dim>(
+ UniformGridPartition<Dim>(blocks)))),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const ReplicatedTag & t)
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ UniformGridPartition<Dim>(blocks),
+ LocalMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &igcs,
+ const DistributedTag &)
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ UniformGridPartition<Dim>(blocks,igcs),
+ DistributedMapper<Dim>(
+ UniformGridPartition<Dim>(blocks,igcs)))),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &igcs,
+ const ReplicatedTag &)
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ UniformGridPartition<Dim>(blocks,igcs),
+ LocalMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &igcs,
+ const GuardLayers_t &egcs,
+ const DistributedTag &)
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ UniformGridPartition<Dim>(blocks,igcs,egcs),
+ DistributedMapper<Dim>(
+ UniformGridPartition<Dim>(blocks,igcs,egcs)))),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &igcs,
+ const GuardLayers_t &egcs,
+ const ReplicatedTag &t)
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ UniformGridPartition<Dim>(blocks,igcs,egcs),
+ LocalMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ template <class Partitioner>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const DistributedTag & )
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >
+ (new LayoutData_t(gdom,gpar,DistributedMapper<Dim>(gpar))),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ template <class Partitioner>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const ReplicatedTag &)
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >
+ (new LayoutData_t(gdom,gpar,LocalMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ template <class Partitioner>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> & cmap)
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >
+ (new LayoutData_t(gdom,gpar,cmap)),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ inline UniformGridLayout<Dim>::
+ UniformGridLayout(const This_t &model)
+ : LayoutBase<Dim,UniformGridLayoutData<Dim> >(model.pdata_m),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ inline UniformGridLayout<Dim> & UniformGridLayout<Dim>::
+ operator=(const This_t &model)
+ {
+ if (this != &model)
+ {
+ this->pdata_m->detach(*this);
+ this->pdata_m = model.pdata_m;
+ this->pdata_m->attach(*this);
+ }
+ return *this;
+ }
+ template <int Dim>
+ inline void
+ UniformGridLayout<Dim>::
+ initialize(const Domain_t &gdom,
+ const DistributedTag &)
+ {
+ ;
+ this->pdata_m->domain_m = gdom;
+ this->pdata_m->innerdomain_m = gdom;
+ this->pdata_m->partition(UniformGridPartition<Dim>(),
+ DistributedMapper<Dim>(UniformGridPartition<Dim>()));
+ }
+ template <int Dim>
+ inline void
+ UniformGridLayout<Dim>::
+ initialize(const Domain_t &gdom,
+ const ReplicatedTag &)
+ {
+ ;
+ this->pdata_m->domain_m = gdom;
+ this->pdata_m->innerdomain_m = gdom;
+ this->pdata_m->partition(UniformGridPartition<Dim>(),
+ LocalMapper<Dim>());
+ }
+ template <int Dim>
+ inline void
+ UniformGridLayout<Dim>::
+ initialize(const Domain_t &gdom,
+ const GuardLayers_t &gcs,
+ const DistributedTag &)
+ {
+ ;
+ this->pdata_m->innerdomain_m = gdom;
+ this->pdata_m->domain_m = gdom;
+ this->pdata_m->partition(UniformGridPartition<Dim>(gcs),
+ DistributedMapper<Dim>(UniformGridPartition<Dim>(gcs) ));
+ }
+ template <int Dim>
+ inline void
+ UniformGridLayout<Dim>::
+ initialize(const Domain_t &gdom,
+ const GuardLayers_t &gcs,
+ const ReplicatedTag &)
+ {
+ ;
+ this->pdata_m->innerdomain_m = gdom;
+ this->pdata_m->domain_m = gdom;
+ this->pdata_m->partition(UniformGridPartition<Dim>(gcs),
+ LocalMapper<Dim>());
+ }
+ template <int Dim>
+ inline void
+ UniformGridLayout<Dim>::
+ initialize(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const DistributedTag &)
+ {
+ ;
+ this->pdata_m->innerdomain_m = gdom;
+ this->pdata_m->domain_m = gdom;
+ this->pdata_m->partition(UniformGridPartition<Dim>(blocks),
+ DistributedMapper<Dim>(UniformGridPartition<Dim>(blocks)));
+ }
+ template <int Dim>
+ inline void
+ UniformGridLayout<Dim>::
+ initialize(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const ReplicatedTag &)
+ {
+ ;
+ this->pdata_m->innerdomain_m = gdom;
+ this->pdata_m->domain_m = gdom;
+ this->pdata_m->partition(UniformGridPartition<Dim>(blocks),
+ LocalMapper<Dim>());
+ }
+ template <int Dim>
+ inline void
+ UniformGridLayout<Dim>::
+ initialize(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &gcs,
+ const DistributedTag &)
+ {
+ ;
+ this->pdata_m->innerdomain_m = gdom;
+ this->pdata_m->domain_m = gdom;
+ this->pdata_m->partition(UniformGridPartition<Dim>(blocks, gcs),
+ DistributedMapper<Dim>(
+ UniformGridPartition<Dim>(blocks, gcs)));
+ }
+ template <int Dim>
+ inline void
+ UniformGridLayout<Dim>::
+ initialize(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &gcs,
+ const ReplicatedTag &)
+ {
+ ;
+ this->pdata_m->innerdomain_m = gdom;
+ this->pdata_m->domain_m = gdom;
+ this->pdata_m->partition(UniformGridPartition<Dim>(blocks, gcs),
+ LocalMapper<Dim>());
+ }
+ template <int Dim>
+ inline void
+ UniformGridLayout<Dim>::
+ initialize(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &igcs,
+ const GuardLayers_t &egcs,
+ const DistributedTag &)
+ {
+ ;
+ this->pdata_m->innerdomain_m = gdom;
+ this->pdata_m->domain_m = gdom;
+ this->pdata_m->partition(UniformGridPartition<Dim>(blocks, igcs, egcs),
+ DistributedMapper<Dim>(
+ UniformGridPartition<Dim>(blocks, igcs, egcs)));
+ }
+ template <int Dim>
+ inline void
+ UniformGridLayout<Dim>::
+ initialize(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &igcs,
+ const GuardLayers_t &egcs,
+ const ReplicatedTag &)
+ {
+ ;
+ this->pdata_m->innerdomain_m = gdom;
+ this->pdata_m->domain_m = gdom;
+ this->pdata_m->blocks_m = blocks;
+ this->pdata_m->partition(UniformGridPartition<Dim>(blocks, igcs, egcs),
+ LocalMapper<Dim>());
+ }
+ template <int Dim>
+ template <class Partitioner>
+ inline void
+ UniformGridLayout<Dim>::
+ initialize(const Domain_t &gdom,
+ const Partitioner &p,
+ const DistributedTag &)
+ {
+ ;
+ this->pdata_m->innerdomain_m = gdom;
+ this->pdata_m->domain_m = gdom;
+ this->pdata_m->blocks_m = p.blocks();
+ this->pdata_m->partition(p,DistributedMapper<Dim>(p));
+ }
+ template <int Dim>
+ template <class Partitioner>
+ inline void
+ UniformGridLayout<Dim>::
+ initialize(const Domain_t &gdom,
+ const Partitioner &p,
+ const ReplicatedTag &)
+ {
+ ;
+ this->pdata_m->innerdomain_m = gdom;
+ this->pdata_m->domain_m = gdom;
+ this->pdata_m->blocks_m = p.blocks();
+ this->pdata_m->partition(p,LocalMapper<Dim>());
+ }
+ template <int Dim>
+ template <class Partitioner>
+ inline void
+ UniformGridLayout<Dim>::
+ initialize(const Domain_t &gdom,
+ const Partitioner &p,
+ const ContextMapper<Dim> &cmap)
+ {
+ ;
+ this->pdata_m->innerdomain_m = gdom;
+ this->pdata_m->domain_m = gdom;
+ this->pdata_m->blocks_m = p.blocks();
+ this->pdata_m->partition(p,cmap);
+ }
+ template <int Dim>
+ void UniformGridLayout<Dim>::initialize(const Domain_t& idom,
+ const List_t& nodes,
+ const Loc<Dim>& blocks,
+ bool hasIG, bool hasEG,
+ const GuardLayers_t& ig,
+ const GuardLayers_t& eg)
+ {
+ this->pdata_m->initialize(idom,nodes,blocks,hasIG,hasEG,ig,eg);
+ }
+ template <int Dim>
+ inline int
+ UniformGridLayoutData<Dim>::globalID(const Loc<Dim> &loc) const
+ {
+ ;
+ int currloc;
+ if (!this->hasExternalGuards_m)
+ {
+ currloc = (loc[0].first() - this->firsti_m[0]) / blocksizes_m[0];
+ for (int d = 1; d < Dim; ++d)
+ currloc += blockstride_m[d] *
+ ((loc[d].first() - this->firsti_m[d]) / blocksizes_m[d]);
+ }
+ else
+ {
+ currloc = 0;
+ for (int d = 0; d < Dim; ++d)
+ {
+ int l = loc[d].first();
+ if (l >= this->firsti_m[d])
+ {
+ if (l <= this->innerdomain_m[d].last())
+ {
+ currloc += blockstride_m[d] *
+ ((l - this->firsti_m[d]) / blocksizes_m[d]);
+ }
+ else
+ {
+ currloc += blockstride_m[d] * allDomain_m[d].last();
+ }
+ }
+ }
+ }
+ ;
+ return currloc;
+ }
+ template <int Dim>
+ inline int
+ UniformGridLayoutData<Dim>::globalID(int i0) const
+ {
+ ;
+ ;
+ int currloc;
+ if (!this->hasExternalGuards_m)
+ {
+ currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
+ }
+ else
+ {
+ currloc = 0;
+ if (i0 >= this->firsti_m[0]) {
+ if (i0 <= this->innerdomain_m[0].last())
+ currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
+ else
+ currloc = allDomain_m[0].last();
+ }
+ }
+ ;
+ return currloc;
+ }
+ template <int Dim>
+ inline int
+ UniformGridLayoutData<Dim>::globalID(int i0, int i1) const
+ {
+ ;
+ ;
+ ;
+ int currloc;
+ if (!this->hasExternalGuards_m)
+ {
+ currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0]
+ + blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1]);
+ }
+ else
+ {
+ currloc = 0;
+ if (i0 >= this->firsti_m[0]) {
+ if (i0 <= this->innerdomain_m[0].last())
+ currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
+ else
+ currloc = allDomain_m[0].last();
+ }
+ if (i1 >= this->firsti_m[1]) {
+ if (i1 <= this->innerdomain_m[1].last())
+ currloc += blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1]);
+ else
+ currloc += blockstride_m[1] * allDomain_m[1].last();
+ }
+ }
+ ;
+ return currloc;
+ }
+ template <int Dim>
+ inline int
+ UniformGridLayoutData<Dim>::globalID(int i0, int i1, int i2) const
+ {
+ ;
+ ;
+ ;
+ ;
+ int currloc;
+ if (!this->hasExternalGuards_m)
+ {
+ currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0]
+ + blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1])
+ + blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2]);
+ }
+ else
+ {
+ currloc = 0;
+ if (i0 >= this->firsti_m[0]) {
+ if (i0 <= this->innerdomain_m[0].last())
+ currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
+ else
+ currloc = allDomain_m[0].last();
+ }
+ if (i1 >= this->firsti_m[1]) {
+ if (i1 <= this->innerdomain_m[1].last())
+ currloc += blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1]);
+ else
+ currloc += blockstride_m[1] * allDomain_m[1].last();
+ }
+ if (i2 >= this->firsti_m[2]) {
+ if (i2 <= this->innerdomain_m[2].last())
+ currloc += blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2]);
+ else
+ currloc += blockstride_m[2] * allDomain_m[2].last();
+ }
+ }
+ ;
+ return currloc;
+ }
+ template <int Dim>
+ inline int
+ UniformGridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3) const
+ {
+ ;
+ ;
+ ;
+ ;
+ ;
+ int currloc;
+ if (!this->hasExternalGuards_m)
+ {
+ currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0]
+ + blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1])
+ + blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2])
+ + blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3]);
+ }
+ else
+ {
+ currloc = 0;
+ if (i0 >= this->firsti_m[0]) {
+ if (i0 <= this->innerdomain_m[0].last())
+ currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
+ else
+ currloc = allDomain_m[0].last();
+ }
+ if (i1 >= this->firsti_m[1]) {
+ if (i1 <= this->innerdomain_m[1].last())
+ currloc += blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1]);
+ else
+ currloc += blockstride_m[1] * allDomain_m[1].last();
+ }
+ if (i2 >= this->firsti_m[2]) {
+ if (i2 <= this->innerdomain_m[2].last())
+ currloc += blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2]);
+ else
+ currloc += blockstride_m[2] * allDomain_m[2].last();
+ }
+ if (i3 >= this->firsti_m[3]) {
+ if (i3 <= this->innerdomain_m[3].last())
+ currloc += blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3]);
+ else
+ currloc += blockstride_m[3] * allDomain_m[3].last();
+ }
+ }
+ ;
+ return currloc;
+ }
+ template <int Dim>
+ inline int
+ UniformGridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
+ int i4) const
+ {
+ ;
+ ;
+ ;
+ ;
+ ;
+ ;
+ int currloc;
+ if (!this->hasExternalGuards_m)
+ {
+ currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0]
+ + blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1])
+ + blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2])
+ + blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3])
+ + blockstride_m[4] * ((i4 - this->firsti_m[4]) / blocksizes_m[4]);
+ }
+ else
+ {
+ currloc = 0;
+ if (i0 >= this->firsti_m[0]) {
+ if (i0 <= this->innerdomain_m[0].last())
+ currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
+ else
+ currloc = allDomain_m[0].last();
+ }
+ if (i1 >= this->firsti_m[1]) {
+ if (i1 <= this->innerdomain_m[1].last())
+ currloc += blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1]);
+ else
+ currloc += blockstride_m[1] * allDomain_m[1].last();
+ }
+ if (i2 >= this->firsti_m[2]) {
+ if (i2 <= this->innerdomain_m[2].last())
+ currloc += blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2]);
+ else
+ currloc += blockstride_m[2] * allDomain_m[2].last();
+ }
+ if (i3 >= this->firsti_m[3]) {
+ if (i3 <= this->innerdomain_m[3].last())
+ currloc += blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3]);
+ else
+ currloc += blockstride_m[3] * allDomain_m[3].last();
+ }
+ if (i4 >= this->firsti_m[4]) {
+ if (i4 <= this->innerdomain_m[4].last())
+ currloc += blockstride_m[4] * ((i4 - this->firsti_m[4]) / blocksizes_m[4]);
+ else
+ currloc += blockstride_m[4] * allDomain_m[4].last();
+ }
+ }
+ ;
+ return currloc;
+ }
+ template <int Dim>
+ inline int
+ UniformGridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
+ int i4, int i5) const
+ {
+ ;
+ ;
+ ;
+ ;
+ ;
+ ;
+ ;
+ int currloc;
+ if (!this->hasExternalGuards_m)
+ {
+ currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0]
+ + blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1])
+ + blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2])
+ + blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3])
+ + blockstride_m[4] * ((i4 - this->firsti_m[4]) / blocksizes_m[4])
+ + blockstride_m[5] * ((i5 - this->firsti_m[5]) / blocksizes_m[5]);
+ }
+ else
+ {
+ currloc = 0;
+ if (i0 >= this->firsti_m[0]) {
+ if (i0 <= this->innerdomain_m[0].last())
+ currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
+ else
+ currloc = allDomain_m[0].last();
+ }
+ if (i1 >= this->firsti_m[1]) {
+ if (i1 <= this->innerdomain_m[1].last())
+ currloc += blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1]);
+ else
+ currloc += blockstride_m[1] * allDomain_m[1].last();
+ }
+ if (i2 >= this->firsti_m[2]) {
+ if (i2 <= this->innerdomain_m[2].last())
+ currloc += blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2]);
+ else
+ currloc += blockstride_m[2] * allDomain_m[2].last();
+ }
+ if (i3 >= this->firsti_m[3]) {
+ if (i3 <= this->innerdomain_m[3].last())
+ currloc += blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3]);
+ else
+ currloc += blockstride_m[3] * allDomain_m[3].last();
+ }
+ if (i4 >= this->firsti_m[4]) {
+ if (i4 <= this->innerdomain_m[4].last())
+ currloc += blockstride_m[4] * ((i4 - this->firsti_m[4]) / blocksizes_m[4]);
+ else
+ currloc += blockstride_m[4] * allDomain_m[4].last();
+ }
+ if (i5 >= this->firsti_m[5]) {
+ if (i5 <= this->innerdomain_m[5].last())
+ currloc += blockstride_m[5] * ((i5 - this->firsti_m[5]) / blocksizes_m[5]);
+ else
+ currloc += blockstride_m[5] * allDomain_m[5].last();
+ }
+ }
+ ;
+ return currloc;
+ }
+ template <int Dim>
+ inline int
+ UniformGridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
+ int i4, int i5, int i6) const
+ {
+ ;
+ ;
+ ;
+ ;
+ ;
+ ;
+ ;
+ ;
+ int currloc;
+ if (!this->hasExternalGuards_m)
+ {
+ currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0]
+ + blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1])
+ + blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2])
+ + blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3])
+ + blockstride_m[4] * ((i4 - this->firsti_m[4]) / blocksizes_m[4])
+ + blockstride_m[5] * ((i5 - this->firsti_m[5]) / blocksizes_m[5])
+ + blockstride_m[6] * ((i6 - this->firsti_m[6]) / blocksizes_m[6]);
+ }
+ else
+ {
+ currloc = 0;
+ if (i0 >= this->firsti_m[0]) {
+ if (i0 <= this->innerdomain_m[0].last())
+ currloc = (i0 - this->firsti_m[0]) / blocksizes_m[0];
+ else
+ currloc = allDomain_m[0].last();
+ }
+ if (i1 >= this->firsti_m[1]) {
+ if (i1 <= this->innerdomain_m[1].last())
+ currloc += blockstride_m[1] * ((i1 - this->firsti_m[1]) / blocksizes_m[1]);
+ else
+ currloc += blockstride_m[1] * allDomain_m[1].last();
+ }
+ if (i2 >= this->firsti_m[2]) {
+ if (i2 <= this->innerdomain_m[2].last())
+ currloc += blockstride_m[2] * ((i2 - this->firsti_m[2]) / blocksizes_m[2]);
+ else
+ currloc += blockstride_m[2] * allDomain_m[2].last();
+ }
+ if (i3 >= this->firsti_m[3]) {
+ if (i3 <= this->innerdomain_m[3].last())
+ currloc += blockstride_m[3] * ((i3 - this->firsti_m[3]) / blocksizes_m[3]);
+ else
+ currloc += blockstride_m[3] * allDomain_m[3].last();
+ }
+ if (i4 >= this->firsti_m[4]) {
+ if (i4 <= this->innerdomain_m[4].last())
+ currloc += blockstride_m[4] * ((i4 - this->firsti_m[4]) / blocksizes_m[4]);
+ else
+ currloc += blockstride_m[4] * allDomain_m[4].last();
+ }
+ if (i5 >= this->firsti_m[5]) {
+ if (i5 <= this->innerdomain_m[5].last())
+ currloc += blockstride_m[5] * ((i5 - this->firsti_m[5]) / blocksizes_m[5]);
+ else
+ currloc += blockstride_m[5] * allDomain_m[5].last();
+ }
+ if (i6 >= this->firsti_m[6]) {
+ if (i6 <= this->innerdomain_m[6].last())
+ currloc += blockstride_m[6] * ((i6 - this->firsti_m[6]) / blocksizes_m[6]);
+ else
+ currloc += blockstride_m[6] * allDomain_m[6].last();
+ }
+ }
+ ;
+ return currloc;
+ }
+ template <int Dim>
+ template <class Ostream>
+ void UniformGridLayout<Dim>::print(Ostream &ostr) const
+ {
+ ostr << "UniformGridLayout " << this->ID() << " on global domain "
+ << this->domain() << ":" << '\n';
+ ostr << " Total subdomains: " << this->sizeGlobal() << '\n';
+ ostr << " Local subdomains: " << this->sizeLocal() << '\n';
+ ostr << " Remote subdomains: " << this->sizeRemote() << '\n';
+ ostr << " Grid blocks: " << this->blocks() << '\n';
+ typename UniformGridLayout<Dim>::const_iterator a;
+ for (a = this->beginGlobal(); a != this->endGlobal(); ++a)
+ ostr << " Global subdomain = " << *a << '\n';
+ for (a = this->beginLocal(); a != this->endLocal(); ++a)
+ ostr << " Local subdomain = " << *a << '\n';
+ for (a = this->beginRemote(); a != this->endRemote(); ++a)
+ ostr << " Remote subdomain = " << *a << '\n';
+ }
+ template <int Dim, int Dim2>
+ template <class Ostream>
+ void UniformGridLayoutView<Dim, Dim2>::print(Ostream &ostr) const
+ {
+ ostr << "UniformGridLayoutView " << this->ID() << " on global domain "
+ << this->domain() << ":" << '\n';
+ ostr << " Base ID: " << this->baseID() << '\n';
+ ostr << " Base domain: " << this->baseDomain() << '\n';
+ ostr << " Total subdomains: " << this->sizeGlobal() << '\n';
+ ostr << " Local subdomains: " << this->sizeLocal() << '\n';
+ ostr << " Remote subdomains: " << this->sizeRemote() << '\n';
+ const_iterator a;
+ for (a = this->beginGlobal(); a != this->endGlobal(); ++a)
+ ostr << " Global subdomain = " << *a << '\n';
+ for (a = this->beginLocal(); a != this->endLocal(); ++a)
+ ostr << " Local subdomain = " << *a << '\n';
+ for (a = this->beginRemote(); a != this->endRemote(); ++a)
+ ostr << " Remote subdomain = " << *a << '\n';
+ }
+ template <class DT> class SliceDomain;
+ template<class Tag> struct Remote;
+ template <class LayoutTag, class PatchTag>
+ struct MultiPatch
+ {
+ MultiPatch(){}
+ ~MultiPatch(){}
+ };
+ template <class LayoutTag, class PatchTag, int Dim2>
+ struct MultiPatchView
+ {
+ MultiPatchView(){}
+ ~MultiPatchView(){}
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ class Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >;
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ class Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag,Dim2> >;
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ struct NewEngine<
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
+ Interval<Dim> >
+ {
+ typedef Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim> > Type_t;
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ struct NewEngine<
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
+ Range<Dim> >
+ {
+ typedef Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim> > Type_t;
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag, class Domain>
+ struct NewEngine<
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
+ Node<Domain> >
+ {
+ typedef typename
+ NewEngine<Engine<Dim, T, PatchTag>, Node<Domain> >::Type_t Type_t;
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag, class Domain>
+ struct NewEngineEngine<
+ Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> >,
+ Node<Domain> >
+ {
+ typedef Engine<Dim,T,PatchTag> &Type_t;
+ static inline Engine<Dim,T,PatchTag> &
+ apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &e,
+ const Node<Domain> &i)
+ {
+ return e.globalPatch(i);
+ }
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag, class Domain>
+ struct NewEngineDomain<
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
+ Node<Domain> >
+ {
+ typedef const Domain &Type_t;
+ static inline const Domain &
+ apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &,
+ const Node<Domain> &i)
+ {
+ return i.domain();
+ }
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ struct NewEngine<
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
+ INode<Dim> >
+ {
+ typedef typename
+ NewEngine<Engine<Dim, T, PatchTag>, Interval<Dim> >::Type_t Type_t;
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ struct NewEngineEngine<
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
+ INode<Dim> >
+ {
+ typedef Engine<Dim,T,PatchTag> &Type_t;
+ static inline Engine<Dim,T,PatchTag> &
+ apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &e,
+ const INode<Dim> &i)
+ {
+ return e.globalPatch(i);
+ }
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ struct NewEngineDomain<
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
+ INode<Dim> >
+ {
+ typedef const Interval<Dim> &Type_t;
+ static inline const Interval<Dim> &
+ apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &,
+ const INode<Dim> &i)
+ {
+ return i.domain();
+ }
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag, int SliceDim>
+ struct NewEngine<
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
+ SliceInterval<Dim,SliceDim> >
+ {
+ typedef
+ Engine<SliceDim, T, MultiPatchView<LayoutTag, PatchTag, Dim> > Type_t;
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag, int SliceDim>
+ struct NewEngine<
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
+ SliceRange<Dim,SliceDim> >
+ {
+ typedef
+ Engine<SliceDim, T, MultiPatchView<LayoutTag, PatchTag, Dim> > Type_t;
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ struct NewEngine<
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >,
+ Interval<Dim> >
+ {
+ typedef
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> > Type_t;
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ struct NewEngine<
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >,
+ Range<Dim> >
+ {
+ typedef
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> > Type_t;
+ };
+ template <int Dim, class T,
+ class LayoutTag, class PatchTag, int Dim2, class Domain>
+ struct NewEngine<
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >,
+ Node<Domain> >
+ {
+ typedef typename
+ NewEngine<Engine<Dim2, T, PatchTag>, SliceRange<Dim2, Dim> >::Type_t
+ Type_t;
+ };
+ template <int Dim, class T,
+ class LayoutTag, class PatchTag, class Domain>
+ struct NewEngine<
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim> >,
+ Node<Domain> >
+ {
+ typedef typename
+ NewEngine<Engine<Dim, T, PatchTag>, Range<Dim> >::Type_t
+ Type_t;
+ };
+ template <int Dim, class T,
+ class LayoutTag, class PatchTag, int Dim2, class Domain>
+ struct NewEngineEngine<
+ Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag, Dim2> >,
+ Node<Domain> >
+ {
+ typedef typename NewEngine<
+ Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag, Dim2> >,
+ Node<Domain> >::Type_t Type_t;
+ static inline Type_t
+ apply(const Engine<Dim,T,MultiPatchView<LayoutTag,PatchTag,Dim2> > &e,
+ const Node<Domain> &i)
+ {
+ return e.globalPatch(i);
+ }
+ };
+ template <int Dim, class T,
+ class LayoutTag, class PatchTag, int Dim2, class Domain>
+ struct NewEngineDomain<
+ Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag, Dim2> >,
+ Node<Domain> >
+ {
+ typedef EngineConstructTag Type_t;
+ static inline EngineConstructTag
+ apply(const Engine<Dim,T,MultiPatchView<LayoutTag,PatchTag,Dim2> > &,
+ const Node<Domain> &)
+ {
+ return EngineConstructTag();
+ }
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ struct NewEngine<
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >,
+ INode<Dim> >
+ {
+ typedef typename
+ NewEngine<Engine<Dim2, T, PatchTag>, SliceRange<Dim2, Dim> >::Type_t
+ Type_t;
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ struct NewEngine<
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim> >,
+ INode<Dim> >
+ {
+ typedef typename
+ NewEngine<Engine<Dim, T, PatchTag>, Range<Dim> >::Type_t
+ Type_t;
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ struct NewEngineEngine<
+ Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag, Dim2> >,
+ INode<Dim> >
+ {
+ typedef typename NewEngine<
+ Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag, Dim2> >,
+ INode<Dim> >::Type_t Type_t;
+ static inline Type_t
+ apply(const Engine<Dim,T,MultiPatchView<LayoutTag,PatchTag,Dim2> > &e,
+ const INode<Dim> &i)
+ {
+ return e.globalPatch(i);
+ }
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ struct NewEngineDomain<
+ Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag, Dim2> >,
+ INode<Dim> >
+ {
+ typedef EngineConstructTag Type_t;
+ static inline EngineConstructTag
+ apply(const Engine<Dim,T,MultiPatchView<LayoutTag,PatchTag,Dim2> > &,
+ const INode<Dim> &)
+ {
+ return EngineConstructTag();
+ }
+ };
+ template <int Dim, class T,
+ class LayoutTag, class PatchTag, int Dim2, int SliceDim>
+ struct NewEngine<
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >,
+ SliceInterval<Dim, SliceDim> >
+ {
+ typedef
+ Engine<SliceDim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> > Type_t;
+ };
+ template <int Dim, class T,
+ class LayoutTag, class PatchTag, int Dim2, int SliceDim>
+ struct NewEngine<
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >,
+ SliceRange<Dim, SliceDim> >
+ {
+ typedef
+ Engine<SliceDim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> > Type_t;
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ class Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> > :
+ public Observer<typename MultiPatchLayoutTraits<LayoutTag,Dim>::Layout_t>
+ {
+ public:
+ typedef MultiPatch<LayoutTag,PatchTag> Tag_t;
+ typedef Engine<Dim,T,Tag_t> This_t;
+ typedef Engine<Dim,T,Tag_t> Engine_t;
+ typedef Interval<Dim> Domain_t;
+ typedef T Element_t;
+ typedef PatchTag PatchTag_t;
+ typedef Engine<Dim, T, PatchTag> PatchEngine_t;
+ typedef typename PatchEngine_t::ElementRef_t ElementRef_t;
+ typedef RefCountedBlockPtr<PatchEngine_t> PatchContainer_t;
+ typedef MultiPatchLayoutTraits<LayoutTag,Dim> LayoutTraits_t;
+ typedef typename LayoutTraits_t::Layout_t Layout_t;
+ typedef Layout_t Observable_t;
+ typedef DynamicEvents::PatchID_t PatchID_t;
+ typedef DynamicEvents::CreateSize_t CreateSize_t;
+ typedef ObserverEvent::ID_t DynamicID_t;
+ typedef typename NewEngine<PatchEngine_t, Domain_t>::Type_t PatchView_t;
+ enum { brick = false };
+ enum { dimensions = Dim };
+ enum { hasDataObject = false };
+ enum { dynamic = PatchEngine_t::dynamic };
+ enum { zeroBased = false };
+ enum { multiPatch = true };
+ Engine();
+ explicit Engine(const Layout_t &layout);
+ Engine(const Engine_t &model);
+ ~Engine();
+ Engine_t &operator=(const Engine_t &model);
+ Element_t read(const Loc<Dim> &) const;
+ ElementRef_t operator()(const Loc<Dim> &) const;
+ Element_t read(int) const;
+ Element_t read(int, int) const;
+ Element_t read(int, int, int) const;
+ Element_t read(int, int, int, int) const;
+ Element_t read(int, int, int, int, int) const;
+ Element_t read(int, int, int, int, int, int) const;
+ Element_t read(int, int, int, int, int, int, int) const;
+ ElementRef_t operator()(int) const;
+ ElementRef_t operator()(int, int) const;
+ ElementRef_t operator()(int, int, int) const;
+ ElementRef_t operator()(int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int, int, int) const;
+ inline PatchEngine_t &globalPatch(const INode<Dim> &inode) const
+ {
+ int gid = inode.globalID(layout_m.ID());
+ PatchEngine_t &pengine = data()[gid];
+ ;
+ return pengine;
+ }
+ template<class Domain>
+ inline PatchEngine_t &globalPatch(const Node<Domain> &node) const
+ {
+ int gid = node.globalID();
+ PatchEngine_t &pengine = data()[gid];
+ ;
+ return pengine;
+ }
+ inline PatchEngine_t &globalPatch(PatchID_t gpatchID) const
+ {
+ return data()[gpatchID];
+ }
+ inline PatchEngine_t &localPatch(PatchID_t lpatchID) const
+ {
+ int gID = (layout_m.nodeListLocal()[lpatchID])->globalID();
+ return data()[gID];
+ }
+ inline bool patchEmpty(PatchID_t patch) const
+ {
+ return data()[patch].domain().empty();
+ }
+ inline const Layout_t &layout() const
+ {
+ return layout_m;
+ }
+ inline Layout_t &layout()
+ {
+ return layout_m;
+ }
+ inline const Domain_t &domain() const
+ {
+ return layout().domain();
+ }
+ inline const Domain_t &innerDomain() const
+ {
+ return layout().innerDomain();
+ }
+ inline int first(int d) const
+ {
+ return layout().first(d);
+ }
+ inline bool initialized() const
+ {
+ return layout().initialized();
+ }
+ inline const PatchContainer_t &data() const
+ {
+ return data_m;
+ }
+ Engine_t &makeOwnCopy();
+ inline void fillGuards(const GuardLayers<Dim>& g) const
+ {
+ fillGuardsHandler(g, WrappedInt<Layout_t::supportsGuards>());
+ }
+ inline void fillGuards() const
+ {
+ fillGuards(layout().internalGuards());
+ }
+ inline void fillGuardsHandler(const GuardLayers<Dim>&, const WrappedInt<false>&) const { };
+ void fillGuardsHandler(const GuardLayers<Dim>&, const WrappedInt<true>&) const ;
+ void setGuards(const T &val) const;
+ void accumulateFromGuards() const;
+ inline int dirty() const { return *pDirty_m; }
+ inline void setDirty() const
+ {
+ *pDirty_m = (1<<(Dim*2))-1;
+ }
+ inline void clearDirty(int face = -1) const
+ {
+ if (face == -1)
+ *pDirty_m = 0;
+ else {
+ ;
+ *pDirty_m &= ~(1<<face);
+ }
+ }
+ inline bool isDirty(int face = -1) const
+ {
+ if (face == -1)
+ return *pDirty_m != 0;
+ else {
+ ;
+ return *pDirty_m & (1<<face);
+ }
+ }
+ virtual void notify(Observable_t &observed, const ObserverEvent &event);
+ void dynamicHandler(Observable_t &, const ObserverEvent &,
+ const WrappedInt<false> &);
+ void dynamicHandler(Observable_t &, const ObserverEvent &,
+ const WrappedInt<true> &);
+ inline void create(CreateSize_t num, PatchID_t localPatchID = (-1))
+ {
+ layout().create(num, localPatchID);
+ }
+ template<class Dom, class DeleteMethod>
+ inline void destroy(const Dom &killlist, const DeleteMethod &method)
+ {
+ layout().destroy(killlist, method);
+ }
+ template<class Dom>
+ inline void destroy(const Dom &killlist)
+ {
+ layout().destroy(killlist, BackFill());
+ }
+ template<class Dom, class DeleteMethod>
+ inline void destroy(const Dom &killlist, PatchID_t frompatch,
+ const DeleteMethod &method)
+ {
+ layout().destroy(killlist, frompatch, method);
+ }
+ template<class Dom>
+ inline void copy(const Dom &domain, PatchID_t topatch = (-1))
+ {
+ layout().copy(domain, topatch);
+ }
+ template<class Dom>
+ inline void copy(const Dom &killlist,
+ PatchID_t frompatch, PatchID_t topatch)
+ {
+ layout().copy(killlist, frompatch, topatch);
+ }
+ inline void copy(const IndirectionList< IndirectionList<int> > &domlists,
+ const IndirectionList< int > &fromlist,
+ PatchID_t topatch,
+ bool docreate)
+ {
+ layout().copy(domlists, fromlist, topatch, docreate);
+ }
+ void sync()
+ {
+ layout().sync();
+ }
+ private:
+ void performCreate(CreateSize_t num, PatchID_t patch,
+ DynamicID_t did);
+ template<class Dom, class DeleteMethod>
+ void performDestroy(const Dom &killlist, PatchID_t patch,
+ const DeleteMethod &method,
+ DynamicID_t did);
+ template<class Dom>
+ void performCopy(const Dom &domain, PatchID_t frompatch, PatchID_t topatch,
+ DynamicID_t did);
+ void performPatchCopy(const IndirectionList< IndirectionList<int> > &dlists,
+ const IndirectionList< int > &fromlist,
+ PatchID_t topatch,
+ bool docreate,
+ DynamicID_t did);
+ template <class Node, class Counter>
+ class PatchAllocator : public Pooma::Runnable_t
+ {
+ public:
+ PatchAllocator(PatchEngine_t &dest, const Node &node, Counter &c)
+ : Pooma::Runnable_t(node.affinity()), dest_m(dest),
+ node_m(node), counter_m(c)
+ {
+ }
+ ~PatchAllocator() { }
+ void run()
+ {
+ dest_m = PatchEngine_t(node_m);
+ ++counter_m;
+ }
+ private:
+ PatchEngine_t &dest_m;
+ const Node &node_m;
+ Counter &counter_m;
+ };
+ Layout_t layout_m;
+ PatchContainer_t data_m;
+ int *pDirty_m;
+ };
+ template <int D1, int D2>
+ struct SubDomainTraits
+ {
+ typedef SliceRange<D1,D2> LocalToBase_t;
+ typedef Range<D1> TotalDomain_t;
+ inline static
+ TotalDomain_t totalDomain(const LocalToBase_t &d)
+ {
+ return d.totalDomain();
+ }
+ };
+ template <int D1>
+ struct SubDomainTraits<D1, D1>
+ {
+ typedef Range<D1> LocalToBase_t;
+ typedef Range<D1> TotalDomain_t;
+ inline static
+ TotalDomain_t totalDomain(const LocalToBase_t &dom)
+ {
+ return dom;
+ }
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ class Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag,Dim2> >
+ {
+ public:
+ typedef MultiPatchView<LayoutTag, PatchTag, Dim2> Tag_t;
+ typedef Engine<Dim,T,Tag_t> This_t;
+ typedef Engine<Dim,T,Tag_t> Engine_t;
+ typedef Engine<Dim2,T,MultiPatch<LayoutTag,PatchTag> > ViewedEngine_t;
+ typedef Interval<Dim> Domain_t;
+ typedef T Element_t;
+ typedef PatchTag PatchTag_t;
+ typedef Engine<Dim2, T, PatchTag_t> PatchEngine_t;
+ typedef typename PatchEngine_t::ElementRef_t ElementRef_t;
+ typedef RefCountedBlockPtr<PatchEngine_t> PatchContainer_t;
+ typedef MultiPatchLayoutTraits<LayoutTag,Dim2> ViewedLayoutTraits_t;
+ typedef typename ViewedLayoutTraits_t::Layout_t ViewedLayout_t;
+ typedef typename ViewedLayoutTraits_t::template View<Dim>
+ NestedViewTraits_t;
+ typedef typename NestedViewTraits_t::Layout_t Layout_t;
+ enum { dimensions = Dim };
+ enum { hasDataObject = false };
+ enum { dynamic = PatchEngine_t::dynamic };
+ enum { zeroBased = true };
+ enum { multiPatch = true };
+ Engine() { }
+ template<class DT>
+ Engine(const ViewedEngine_t &engine, const Domain<Dim2, DT> &domain)
+ : layout_m(engine.layout(), domain),
+ baseEngine_m(engine)
+ { }
+ template<class DT>
+ Engine(const ViewedEngine_t &engine, const SliceDomain<DT> &domain)
+ : layout_m(engine.layout(), domain),
+ baseEngine_m(engine)
+ { }
+ template<class DT>
+ Engine(const This_t &engine, const Domain<Dim, DT> &domain)
+ : layout_m(engine.layout(), domain),
+ baseEngine_m(engine.baseEngine_m)
+ { }
+ template<int OrigDim, class DT>
+ Engine(const Engine<OrigDim, T, Tag_t> &engine,
+ const SliceDomain<DT> &domain)
+ : layout_m(engine.layout(), domain),
+ baseEngine_m(engine.baseEngine())
+ { }
+ Engine(const Engine_t &model);
+ ~Engine();
+ Engine_t &operator=(const Engine_t &model);
+ Element_t read(const Loc<Dim> &) const;
+ ElementRef_t operator()(const Loc<Dim> &) const;
+ Element_t read(int) const;
+ Element_t read(int, int) const;
+ Element_t read(int, int, int) const;
+ Element_t read(int, int, int, int) const;
+ Element_t read(int, int, int, int, int) const;
+ Element_t read(int, int, int, int, int, int) const;
+ Element_t read(int, int, int, int, int, int, int) const;
+ ElementRef_t operator()(int) const;
+ ElementRef_t operator()(int, int) const;
+ ElementRef_t operator()(int, int, int) const;
+ ElementRef_t operator()(int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int, int, int) const;
+ typename NewEngine<This_t, INode<Dim> >::Type_t
+ globalPatch(const INode<Dim> &inode) const
+ {
+ typedef SubDomainTraits<Dim2, Dim> SubDomainTraits_t;
+ typedef typename SubDomainTraits_t::LocalToBase_t LocalToBase_t;
+ int gid = inode.globalID(layout_m.ID());
+ PatchEngine_t &pengine = data()[gid];
+ LocalToBase_t bdom = Pooma::NoInit();
+ layout_m.localToBase(inode.domain(), bdom);
+ ;
+ typedef typename NewEngine<This_t,INode<Dim> >::Type_t Ret_t;
+ return Ret_t(pengine, bdom);
+ }
+ template<class Domain>
+ typename NewEngine<This_t, Node<Domain> >::Type_t
+ globalPatch(const Node<Domain> &node) const
+ {
+ typedef SubDomainTraits<Dim2, Dim> SubDomainTraits_t;
+ typedef typename SubDomainTraits_t::LocalToBase_t LocalToBase_t;
+ LocalToBase_t bdom = Pooma::NoInit();
+ layout_m.localToBase(node.domain(), bdom);
+ int gid = node.globalID();
+ PatchEngine_t &pengine = data()[gid];
+ ;
+ typedef typename NewEngine<This_t,Node<Domain> >::Type_t Ret_t;
+ return Ret_t(pengine, bdom);
+ }
+ inline Layout_t &layout()
+ {
+ return layout_m;
+ }
+ inline const Layout_t &layout() const
+ {
+ return layout_m;
+ }
+ inline const Domain_t &domain() const
+ {
+ return layout().domain();
+ }
+ inline const Domain_t &innerDomain() const
+ {
+ return layout().innerDomain();
+ }
+ inline int first(int) const
+ {
+ return 0;
+ }
+ inline bool initialized() const
+ {
+ return layout().initialized();
+ }
+ inline void fillGuards() const
+ {
+ baseEngine_m.fillGuards();
+ }
+ inline void fillGuards(const GuardLayers<Dim2>& g) const
+ {
+ baseEngine_m.fillGuards(g);
+ }
+ inline void setGuards(const T &val) const
+ {
+ baseEngine_m.setGuards(val);
+ }
+ inline void accumulateFromGuards() const
+ {
+ baseEngine_m.accumulateFromGuards();
+ }
+ inline void setDirty() const
+ {
+ baseEngine_m.setDirty();
+ }
+ inline void clearDirty(int face=-1) const
+ {
+ baseEngine_m.clearDirty(face);
+ }
+ inline bool isDirty(int face=-1) const
+ {
+ return baseEngine_m.isDirty(face);
+ }
+ inline const PatchContainer_t &data() const
+ {
+ return baseEngine_m.data();
+ }
+ template<int D1, class T1>
+ inline bool sameController(const Engine<D1, T1, Tag_t> &e) const
+ {
+ return block() == e.block();
+ }
+ PatchContainer_t block() const
+ {
+ return baseEngine_m.data();
+ }
+ inline const ViewedEngine_t &baseEngine() const
+ {
+ return baseEngine_m;
+ }
+ private:
+ Layout_t layout_m;
+ ViewedEngine_t baseEngine_m;
+ };
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(const Loc<Dim> &loc) const
+ {
+ return data()[layout_m.globalID(loc)].read(loc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(int i0) const
+ {
+ return data()[layout_m.globalID(i0)].read(i0);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(int i0, int i1) const
+ {
+ return data()[layout_m.globalID(i0, i1)].read(i0, i1);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(int i0, int i1, int i2)
+ const
+ {
+ return data()[layout_m.globalID(i0, i1, i2)].read(i0, i1, i2);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(int i0, int i1, int i2,
+ int i3) const
+ {
+ return data()[layout_m.globalID(i0, i1, i2, i3)].read(i0, i1, i2, i3);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(int i0, int i1, int i2,
+ int i3, int i4) const
+ {
+ return data()[layout_m.globalID(i0, i1, i2, i3, i4)].read
+ (i0, i1, i2, i3, i4);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(int i0, int i1, int i2,
+ int i3, int i4, int i5) const
+ {
+ return data()[layout_m.globalID(i0, i1, i2, i3, i4, i5)].read
+ (i0, i1, i2, i3, i4, i5);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::Element_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::read(int i0, int i1, int i2,
+ int i3, int i4, int i5, int i6) const
+ {
+ return data()[layout_m.globalID(i0, i1, i2, i3, i4, i5, i6)].read
+ (i0, i1, i2, i3, i4, i5, i6);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(const Loc<Dim> &loc)
+ const
+ {
+ return data()[layout_m.globalID(loc)](loc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(int i0) const
+ {
+ return data()[layout_m.globalID(i0)](i0);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(int i0,
+ int i1) const
+ {
+ return data()[layout_m.globalID(i0, i1)](i0, i1);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(int i0, int i1,
+ int i2) const
+ {
+ return data()[layout_m.globalID(i0, i1, i2)](i0, i1, i2);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(int i0, int i1,
+ int i2, int i3) const
+ {
+ return data()[layout_m.globalID(i0, i1, i2, i3)](i0, i1, i2, i3);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(int i0, int i1,
+ int i2, int i3, int i4) const
+ {
+ return data()[layout_m.globalID(i0, i1, i2, i3, i4)]
+ (i0, i1, i2, i3, i4);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(int i0, int i1,
+ int i2, int i3, int i4, int i5) const
+ {
+ return data()[layout_m.globalID(i0, i1, i2, i3, i4, i5)]
+ (i0, i1, i2, i3, i4, i5);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag>
+ inline typename Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::ElementRef_t
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::operator()(int i0, int i1,
+ int i2, int i3, int i4, int i5, int i6) const
+ {
+ return data()[layout_m.globalID(i0, i1, i2, i3, i4, i5, i6)]
+ (i0, i1, i2, i3, i4, i5, i6);
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ inline void Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::
+ dynamicHandler(Observable_t &, const ObserverEvent &,
+ const WrappedInt<false> &)
+ {
+ if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("This patch engine does not support dynamic events!", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Engine/MultiPatchEngine.h", 1460);
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ Engine(const Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >
+ &modelEngine)
+ : layout_m(modelEngine.layout_m),
+ baseEngine_m(modelEngine.baseEngine_m)
+ { }
+ template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> > &
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ operator=(const Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >
+ &rhs)
+ {
+ if (&rhs == this) return *this;
+ layout_m = rhs.layout_m;
+ baseEngine_m = rhs.baseEngine_m;
+ return *this;
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ Engine<Dim, T, MultiPatchView<LayoutTag,PatchTag,Dim2> >::
+ ~Engine()
+ { }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline
+ typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ read(const Loc<Dim> &loc) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(loc, gloc);
+ return data()[o].read(gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline
+ typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::read(int i0) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(i0, gloc);
+ return data()[o].read(gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline
+ typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ read(int i0, int i1) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(i0, i1, gloc);
+ return data()[o].read(gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline
+ typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ read(int i0, int i1, int i2) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(i0, i1, i2, gloc);
+ return data()[o].read(gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline
+ typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ read(int i0, int i1, int i2, int i3) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(i0, i1, i2, i3, gloc);
+ return data()[o].read(gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline
+ typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ read(int i0, int i1, int i2, int i3, int i4) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(i0, i1, i2, i3, i4, gloc);
+ return data()[o](gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline
+ typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ read(int i0, int i1, int i2, int i3, int i4, int i5) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(i0, i1, i2, i3, i4, i5, gloc);
+ return data()[o].read(gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline
+ typename Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::Element_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ read(int i0, int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(i0, i1, i2, i3, i4, i5, i6, gloc);
+ return data()[o].read(gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline typename
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ operator()(const Loc<Dim> &loc) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(loc, gloc);
+ return data()[o](gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline typename
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ operator()(int i0) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(i0, gloc);
+ return data()[o](gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline typename
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ operator()(int i0, int i1) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(i0, i1, gloc);
+ return data()[o](gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline typename
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ operator()(int i0, int i1, int i2) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(i0, i1, i2, gloc);
+ return data()[o](gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline typename
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ operator()(int i0, int i1, int i2, int i3) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(i0, i1, i2, i3, gloc);
+ return data()[o](gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline typename
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ operator()(int i0, int i1, int i2, int i3, int i4) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(i0, i1, i2, i3, i4, gloc);
+ return data()[o](gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline typename
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ operator()(int i0, int i1, int i2, int i3, int i4, int i5) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(i0, i1, i2, i3, i4, i5, gloc);
+ return data()[o](gloc);
+ }
+ template<int Dim, class T, class LayoutTag, class PatchTag, int Dim2>
+ inline typename
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::ElementRef_t
+ Engine<Dim, T, MultiPatchView<LayoutTag, PatchTag, Dim2> >::
+ operator()(int i0, int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ Loc<Dim2> gloc = Pooma::NoInit();
+ int o = layout_m.globalID(i0, i1, i2, i3, i4, i5, i6, gloc);
+ return data()[o](gloc);
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag, class Intersect>
+ struct LeafFunctor<Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
+ ExpressionApply<IntersectorTag<Intersect> > >
+ {
+ typedef int Type_t;
+ static Type_t
+ apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &engine,
+ const ExpressionApply<IntersectorTag<Intersect> > &tag)
+ {
+ GuardLayers<Dim> usedGuards;
+ bool useGuards =
+ tag.tag().intersector_m.intersect(engine,
+ engine.layout().internalGuards(), usedGuards);
+ if (useGuards)
+ engine.fillGuards(usedGuards);
+ return 0;
+ }
+ };
+ template <int Dim, class T, class LT, class PatchTag, int BD,
+ class Intersect>
+ struct LeafFunctor<Engine<Dim, T, MultiPatchView<LT,PatchTag,BD> >,
+ ExpressionApply<IntersectorTag<Intersect> > >
+ {
+ typedef int Type_t;
+ static Type_t
+ apply(const Engine<Dim,T,MultiPatchView<LT,PatchTag,BD> > &engine,
+ const ExpressionApply<IntersectorTag<Intersect> > &tag)
+ {
+ typedef typename MultiPatchLayoutTraits<LT,Dim>::Layout_t Layout_t;
+ return applyHandler(engine, tag, WrappedInt<Layout_t::supportsGuards>());
+ }
+ inline static Type_t
+ applyHandler(const Engine<Dim,T,MultiPatchView<LT,PatchTag,BD> > &engine,
+ const ExpressionApply<IntersectorTag<Intersect> > &tag,
+ const WrappedInt<true> &)
+ {
+ GuardLayers<BD> usedGuards;
+ bool useGuards =
+ tag.tag().intersector_m.
+ intersect(engine,
+ engine.layout().baseLayout().internalGuards(), usedGuards);
+ if (useGuards)
+ engine.fillGuards(usedGuards);
+ return 0;
+ }
+ inline static Type_t
+ applyHandler(const Engine<Dim,T,MultiPatchView<LT,PatchTag,BD> > &engine,
+ const ExpressionApply<IntersectorTag<Intersect> > &tag,
+ const WrappedInt<false> &)
+ {
+ tag.tag().intersector_m.intersect(engine);
+ return 0;
+ }
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ struct EngineFunctor<Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
+ EnginePatch >
+ {
+ typedef Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> > Subject_t;
+ typedef Engine<Dim,T,PatchTag> Type_t;
+ static inline
+ Type_t apply(const Subject_t &engine, const EnginePatch &tag)
+ {
+ return engine.localPatch(tag.patch_m);
+ }
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ struct EngineFunctor<Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
+ EngineNumPatches >
+ {
+ typedef int Type_t;
+ static inline
+ Type_t apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &engine,
+ const EngineNumPatches &)
+ {
+ return engine.layout().sizeLocal();
+ }
+ };
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ struct NotifyEngineWrite<Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> > >
+ {
+ inline static void
+ notify(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &engine)
+ {
+ engine.setDirty();
+ }
+ };
+ template <int Dim, class T, class LT, class PatchTag, int BD>
+ struct NotifyEngineWrite<Engine<Dim, T, MultiPatchView<LT,PatchTag,BD> > >
+ {
+ inline static void
+ notify(const Engine<Dim,T,MultiPatchView<LT,PatchTag,BD> > &engine)
+ {
+ engine.setDirty();
+ }
+ };
+ template<class PatchEngine>
+ inline
+ PatchEngine &localPatchEngine(PatchEngine &e)
+ {
+ return e;
+ }
+ class TagGenerator
+ {
+ public:
+ TagGenerator()
+ : send_m(1), receive_m(1)
+ {
+ send_m[0] = 0;
+ receive_m[0] = 0;
+ }
+ TagGenerator(int n)
+ : send_m(n), receive_m(n)
+ {
+ int i;
+ for (i = 0; i < n; ++i)
+ {
+ send_m[i] = 0;
+ receive_m[i] = 0;
+ }
+ }
+ int send(int otherContext)
+ {
+ ;
+ int tag = send_m[otherContext];
+ send_m[otherContext]++;
+ return tag;
+ }
+ int receive(int otherContext)
+ {
+ ;
+ int tag = receive_m[otherContext];
+ receive_m[otherContext]++;
+ return tag;
+ }
+ private:
+ std::vector<int> send_m;
+ std::vector<int> receive_m;
+ };
+ namespace Pooma {
+ extern int expectedMessages_g;
+ void initializeCheetahHelpers(int contexts);
+ void finalizeCheetahHelpers();
+ int sendTag(int context);
+ int receiveTag(int context);
+ inline void addIncomingMessage()
+ {
+ expectedMessages_g++;
+ }
+ inline void gotIncomingMessage()
+ {
+ expectedMessages_g--;
+ }
+ inline bool incomingMessages()
+ {
+ return (expectedMessages_g > 0);
+ }
+ }
+ class Full;
+ template<int D, class T, class E> class Vector;
+ template<int D, class T, class E> class VectorEngine;
+ template<class V, int I>
+ struct VectorElem
+ {
+ typedef V Element_t;
+ typedef const V& ConstElementRef_t;
+ typedef V& ElementRef_t;
+ static const V& get(const V& x) { return x; }
+ static V& get( V& x) { return x; }
+ };
+ template<int D, class T, class E, int I>
+ struct VectorEngineElem
+ {
+ typedef VectorEngine<D,T,E> V;
+ typedef typename V::Element_t Element_t;
+ typedef typename V::ConstElementRef_t ConstElementRef_t;
+ typedef typename V::ElementRef_t ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return x(I); }
+ static ElementRef_t get( V& x) { return x(I); }
+ };
+ template<int D, class T, class E, int I>
+ struct VectorElem< Vector<D,T,E> , I >
+ {
+ typedef Vector<D,T,E> V;
+ typedef VectorEngineElem<D,T,E,I> VE;
+ typedef typename VE::Element_t Element_t;
+ typedef typename VE::ConstElementRef_t ConstElementRef_t;
+ typedef typename VE::ElementRef_t ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return VE::get(x.engine()); }
+ static ElementRef_t get(V& x) { return VE::get(x.engine()); }
+ };
+ template<class V1, class V2, class Op, int B, int L>
+ struct VectorAssign
+ {
+ static void apply(V1& v1, const V2& v2, Op op)
+ {
+ PoomaCTAssert<(L>1)>::test();
+ VectorAssign<V1,V2,Op,B,L/2>::apply(v1,v2,op);
+ VectorAssign<V1,V2,Op,B+L/2,L-L/2>::apply(v1,v2,op);
+ }
+ };
+ template<class V1, class V2, class Op, int B>
+ struct VectorAssign<V1,V2,Op,B,0>
+ {
+ static void apply(V1&, const V2&, Op) {}
+ };
+ template<class V1, class V2, class Op, int B>
+ struct VectorAssign<V1,V2,Op,B,1>
+ {
+ static void apply(V1& v1, const V2& v2, Op op)
+ {
+ op(VectorElem<V1,B>::get(v1),VectorElem<V2,B>::get(v2));
+ }
+ };
+ template<class V1, class V2, class Op, int B>
+ struct VectorAssign<V1,V2,Op,B,2>
+ {
+ static void apply(V1& v1, const V2& v2, Op op)
+ {
+ op(VectorElem<V1,B >::get(v1), VectorElem<V2,B >::get(v2));
+ op(VectorElem<V1,B+1>::get(v1), VectorElem<V2,B+1>::get(v2));
+ }
+ };
+ template<class V1, class V2, class Op, int B>
+ struct VectorAssign<V1,V2,Op,B,3>
+ {
+ static void apply(V1& v1, const V2& v2, Op op)
+ {
+ op(VectorElem<V1,B >::get(v1), VectorElem<V2,B >::get(v2));
+ op(VectorElem<V1,B+1>::get(v1), VectorElem<V2,B+1>::get(v2));
+ op(VectorElem<V1,B+2>::get(v1), VectorElem<V2,B+2>::get(v2));
+ }
+ };
+ template<class V1, class V2, class Op>
+ class BinaryVectorOp;
+ template<int D, class T, class V1, class V2, class Op>
+ class VectorEngine<D,T, BinaryVectorOp<V1,V2,Op> >
+ {
+ public:
+ enum { dimensions=1 };
+ enum { d1=D };
+ typedef T Element_t;
+ typedef BinaryVectorOp<V1,V2,Op> EngineTag_t;
+ typedef T ConstElementRef_t;
+ typedef T ElementRef_t;
+ typedef VectorEngine<D,T, BinaryVectorOp<V1,V2,Op> > This_t;
+ VectorEngine(const V1& v1, const V2& v2)
+ : v1_m(v1), v2_m(v2) {}
+ Element_t operator()(int i) const
+ {
+ return Op()(v1_m(i), v2_m(i));
+ }
+ template<int DD,class TT, class EE, int I>
+ friend struct VectorEngineElem;
+ private:
+ const V1& v1_m;
+ const V2& v2_m;
+ };
+ template<int D, class T, class V1, class V2, class Op, int I>
+ struct VectorEngineElem<D,T,BinaryVectorOp<V1,V2,Op>, I >
+ {
+ typedef VectorEngine<D,T,BinaryVectorOp<V1,V2,Op> > V;
+ typedef typename VectorElem<V1,I>::Element_t T1;
+ typedef typename VectorElem<V2,I>::Element_t T2;
+ typedef typename BinaryReturn<T1,T2,Op>::Type_t Element_t;
+ typedef Element_t ElementRef_t;
+ typedef Element_t ConstElementRef_t;
+ static Element_t get(const V& x)
+ {
+ return Op()(
+ VectorElem<V1,I>::get(x.v1_m),
+ VectorElem<V2,I>::get(x.v2_m));
+ }
+ };
+ template<class V1, class Op>
+ class UnaryVectorOp;
+ template<int D, class T, class V1, class Op>
+ class VectorEngine<D,T,UnaryVectorOp<V1,Op> >
+ {
+ public:
+ enum { dimensions=1 };
+ enum { d1 = D };
+ typedef T Element_t;
+ typedef UnaryVectorOp<V1,Op> EngineTag_t;
+ typedef T ConstElementRef_t;
+ typedef T ElementRef_t;
+ typedef VectorEngine<D,T, UnaryVectorOp<V1,Op> > This_t;
+ explicit VectorEngine(const V1& v1)
+ : v1_m(v1) {}
+ Element_t operator()(int i) const
+ {
+ return Op()(v1_m(i));
+ }
+ template<int DD,class TT, class EE, int I>
+ friend struct VectorEngineElem;
+ private:
+ const V1& v1_m;
+ };
+ template<int D, class T, class V1, class Op, int I>
+ struct VectorEngineElem<D,T,UnaryVectorOp<V1,Op>, I>
+ {
+ typedef VectorEngine<D,T,UnaryVectorOp<V1,Op> > V;
+ typedef typename VectorElem<V1,I>::Element_t T1;
+ typedef typename UnaryReturn<T1,Op>::Type_t Element_t;
+ typedef Element_t ElementRef_t;
+ typedef Element_t ConstElementRef_t;
+ static Element_t get(const V& x)
+ {
+ return Op()(VectorElem<V1,I>::get(x.v1_m));
+ }
+ };
+ template<int D, class T, class E> class Vector;
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnArcCos > { typedef Vector< D, typename UnaryReturn<T,FnArcCos>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnArcCos >::Type_t acos( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnArcCos>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnArcCos> > Expr_t; typedef typename UnaryReturn<V1,FnArcCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnArcSin > { typedef Vector< D, typename UnaryReturn<T,FnArcSin>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnArcSin >::Type_t asin( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnArcSin>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnArcSin> > Expr_t; typedef typename UnaryReturn<V1,FnArcSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnArcTan > { typedef Vector< D, typename UnaryReturn<T,FnArcTan>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnArcTan >::Type_t atan( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnArcTan>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnArcTan> > Expr_t; typedef typename UnaryReturn<V1,FnArcTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnCeil > { typedef Vector< D, typename UnaryReturn<T,FnCeil>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnCeil >::Type_t ceil( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnCeil>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnCeil> > Expr_t; typedef typename UnaryReturn<V1,FnCeil>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnCos > { typedef Vector< D, typename UnaryReturn<T,FnCos>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnCos >::Type_t cos( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnCos>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnCos> > Expr_t; typedef typename UnaryReturn<V1,FnCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnHypCos > { typedef Vector< D, typename UnaryReturn<T,FnHypCos>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnHypCos >::Type_t cosh( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnHypCos>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnHypCos> > Expr_t; typedef typename UnaryReturn<V1,FnHypCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnExp > { typedef Vector< D, typename UnaryReturn<T,FnExp>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnExp >::Type_t exp( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnExp>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnExp> > Expr_t; typedef typename UnaryReturn<V1,FnExp>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnFabs > { typedef Vector< D, typename UnaryReturn<T,FnFabs>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnFabs >::Type_t fabs( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnFabs>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnFabs> > Expr_t; typedef typename UnaryReturn<V1,FnFabs>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnFloor > { typedef Vector< D, typename UnaryReturn<T,FnFloor>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnFloor >::Type_t floor( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnFloor>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnFloor> > Expr_t; typedef typename UnaryReturn<V1,FnFloor>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnLog > { typedef Vector< D, typename UnaryReturn<T,FnLog>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnLog >::Type_t log( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnLog>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnLog> > Expr_t; typedef typename UnaryReturn<V1,FnLog>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnLog10 > { typedef Vector< D, typename UnaryReturn<T,FnLog10>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnLog10 >::Type_t log10( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnLog10>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnLog10> > Expr_t; typedef typename UnaryReturn<V1,FnLog10>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnSin > { typedef Vector< D, typename UnaryReturn<T,FnSin>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnSin >::Type_t sin( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnSin>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnSin> > Expr_t; typedef typename UnaryReturn<V1,FnSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnHypSin > { typedef Vector< D, typename UnaryReturn<T,FnHypSin>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnHypSin >::Type_t sinh( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnHypSin>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnHypSin> > Expr_t; typedef typename UnaryReturn<V1,FnHypSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnSqrt > { typedef Vector< D, typename UnaryReturn<T,FnSqrt>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnSqrt >::Type_t sqrt( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnSqrt>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnSqrt> > Expr_t; typedef typename UnaryReturn<V1,FnSqrt>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnTan > { typedef Vector< D, typename UnaryReturn<T,FnTan>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnTan >::Type_t tan( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnTan>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnTan> > Expr_t; typedef typename UnaryReturn<V1,FnTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, FnHypTan > { typedef Vector< D, typename UnaryReturn<T,FnHypTan>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, FnHypTan >::Type_t tanh( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,FnHypTan>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,FnHypTan> > Expr_t; typedef typename UnaryReturn<V1,FnHypTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, OpUnaryMinus > { typedef Vector< D, typename UnaryReturn<T,OpUnaryMinus>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, OpUnaryMinus >::Type_t operator-( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,OpUnaryMinus>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,OpUnaryMinus> > Expr_t; typedef typename UnaryReturn<V1,OpUnaryMinus>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, OpUnaryPlus > { typedef Vector< D, typename UnaryReturn<T,OpUnaryPlus>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, OpUnaryPlus >::Type_t operator+( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,OpUnaryPlus>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,OpUnaryPlus> > Expr_t; typedef typename UnaryReturn<V1,OpUnaryPlus>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Vector<D,T,E>, OpBitwiseNot > { typedef Vector< D, typename UnaryReturn<T,OpBitwiseNot>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Vector<D,T,E>, OpBitwiseNot >::Type_t operator~( const Vector<D,T,E>& v1 ) { typedef Vector<D,T,E> V1; typedef typename UnaryReturn<T,OpBitwiseNot>::Type_t T3; typedef Vector< D, T3, UnaryVectorOp<V1,OpBitwiseNot> > Expr_t; typedef typename UnaryReturn<V1,OpBitwiseNot>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpAdd > { typedef Vector< D, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpAdd >::Type_t operator+( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpAdd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpAdd> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpAdd > { typedef Vector< D, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpAdd > { typedef Vector< D, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > T!
ype_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpAdd >::Type_t operator+( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpAdd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpAdd> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpAdd >::Type_t operator+( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpAdd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpAdd> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpSubtract > { typedef Vector< D, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpSubtract >::Type_t operator-( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpSubtract>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpSubtract> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpSubtract > { typedef Vector< D, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpSubtract > { typedef Vector< D, typename !
BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpSubtract >::Type_t operator-( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpSubtract>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpSubtract> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpSubtract >::Type_t operator-( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpSubtract>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpSubtract> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpMultiply > { typedef Vector< D, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpMultiply >::Type_t operator*( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpMultiply>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpMultiply> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpMultiply > { typedef Vector< D, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpMultiply > { typedef Vector< D, typename !
BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpMultiply >::Type_t operator*( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpMultiply>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpMultiply> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpMultiply >::Type_t operator*( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpMultiply>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpMultiply> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpDivide > { typedef Vector< D, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpDivide >::Type_t operator/( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpDivide>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpDivide> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpDivide > { typedef Vector< D, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpDivide > { typedef Vector< D, typename BinaryReturn<T1,!
T2,OpDivide>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpDivide >::Type_t operator/( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpDivide>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpDivide> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpDivide >::Type_t operator/( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpDivide>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpDivide> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpMod > { typedef Vector< D, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpMod >::Type_t operator%( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpMod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpMod> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpMod > { typedef Vector< D, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpMod > { typedef Vector< D, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > T!
ype_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpMod >::Type_t operator%( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpMod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpMod> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpMod >::Type_t operator%( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpMod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpMod> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpBitwiseAnd > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpBitwiseAnd >::Type_t operator&( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpBitwiseAnd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpBitwiseAnd> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpBitwiseAnd > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpBitwiseAnd > { typedef Vect!
or< D, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpBitwiseAnd >::Type_t operator&( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseAnd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpBitwiseAnd> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpBitwiseAnd >::Type_t operator&( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseAnd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpBitwiseAnd> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpBitwiseOr > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpBitwiseOr >::Type_t operator|( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpBitwiseOr>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpBitwiseOr> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpBitwiseOr > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpBitwiseOr > { typedef Vector< D, t!
ypename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpBitwiseOr >::Type_t operator|( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseOr>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpBitwiseOr> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpBitwiseOr >::Type_t operator|( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseOr>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpBitwiseOr> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, OpBitwiseXor > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, OpBitwiseXor >::Type_t operator^( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,OpBitwiseXor>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,OpBitwiseXor> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, OpBitwiseXor > { typedef Vector< D, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, OpBitwiseXor > { typedef Vect!
or< D, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, OpBitwiseXor >::Type_t operator^( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseXor>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,OpBitwiseXor> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, OpBitwiseXor >::Type_t operator^( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseXor>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,OpBitwiseXor> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, FnLdexp > { typedef Vector< D, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, FnLdexp >::Type_t ldexp( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,FnLdexp>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,FnLdexp> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, FnLdexp > { typedef Vector< D, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, FnLdexp > { typedef Vector< D, typename BinaryReturn<T1,T2,FnLdexp>:!
:Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, FnLdexp >::Type_t ldexp( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnLdexp>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,FnLdexp> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, FnLdexp >::Type_t ldexp( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnLdexp>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,FnLdexp> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, FnPow > { typedef Vector< D, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, FnPow >::Type_t pow( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,FnPow>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,FnPow> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, FnPow > { typedef Vector< D, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, FnPow > { typedef Vector< D, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t;!
}; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, FnPow >::Type_t pow( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnPow>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,FnPow> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, FnPow >::Type_t pow( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnPow>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,FnPow> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, FnFmod > { typedef Vector< D, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, FnFmod >::Type_t fmod( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,FnFmod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,FnFmod> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, FnFmod > { typedef Vector< D, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, FnFmod > { typedef Vector< D, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E!
> Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, FnFmod >::Type_t fmod( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnFmod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,FnFmod> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, FnFmod >::Type_t fmod( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnFmod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,FnFmod> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, Vector<D,T2,E>, FnArcTan2 > { typedef Vector< D, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Vector<D,T1,E1>, Vector<D,T2,E2>, FnArcTan2 >::Type_t atan2( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { typedef Vector<D,T1,E1> V1; typedef Vector<D,T2,E2> V2; typedef typename BinaryReturn<V1,V2,FnArcTan2>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,V2,FnArcTan2> > Expr_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Vector<D,T1,E>, T2, FnArcTan2 > { typedef Vector< D, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Vector<D,T2,E>, FnArcTan2 > { typedef Vector< D, typename BinaryReturn!
<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Vector<D,T1,E>, T2, FnArcTan2 >::Type_t atan2( const Vector<D,T1,E>& v1, const T2& x ) { typedef Vector<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnArcTan2>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<V1,T2,FnArcTan2> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Vector<D,T2,E>, FnArcTan2 >::Type_t atan2( const T1& x, const Vector<D,T2,E>& v2 ) { typedef Vector<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnArcTan2>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Vector< D, T3, BinaryVectorOp<T1,V2,FnArcTan2> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template<class V1, class V2, int B, int L>
+ struct VectorDotVector
+ {
+ typedef typename VectorDotVector<V1,V2,B,L/2>::Type_t Left_t;
+ typedef typename VectorDotVector<V1,V2,B+L/2,L-L/2>::Type_t Right_t;
+ typedef typename BinaryReturn<Left_t,Right_t,OpAdd>::Type_t Type_t;
+ static Type_t get(const V1& x, const V2& y)
+ {
+ return
+ VectorDotVector<V1,V2,B,L/2>::get(x,y) +
+ VectorDotVector<V1,V2,B+L/2,L-L/2>::get(x,y);
+ }
+ };
+ template<class V1, class V2, int B>
+ struct VectorDotVector<V1,V2,B,1>
+ {
+ typedef typename VectorElem<V1,B>::Element_t Left_t;
+ typedef typename VectorElem<V2,B>::Element_t Right_t;
+ typedef typename BinaryReturn<Left_t,Right_t,OpMultiply>::Type_t Type_t;
+ static Type_t get(const V1& x, const V2& y)
+ {
+ return VectorElem<V1,B>::get(x) * VectorElem<V2,B>::get(y);
+ }
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< Vector<D,T1,E1> , Vector<D,T2,E2> , FnDot >
+ {
+ typedef Vector<D,T1,E1> V1;
+ typedef Vector<D,T2,E2> V2;
+ typedef typename VectorDotVector<V1,V2,0,D>::Type_t T0;
+ typedef T0 Type_t;
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ inline typename
+ BinaryReturn< Vector<D,T1,E1>,Vector<D,T2,E2> , FnDot >::Type_t
+ dot( const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 )
+ {
+ return VectorDotVector<Vector<D,T1,E1>,Vector<D,T2,E2>,0,D>::get(v1,v2);
+ }
+ template<int D, class T, class E>
+ struct UnaryReturn< Vector<D,T,E> , FnNorm >
+ {
+ typedef T Type_t;
+ };
+ template<int D, class T, class E>
+ inline T
+ norm(const Vector<D,T,E>& x)
+ {
+ return sqrt(dot(x,x));
+ }
+ template<int D, class T, class E>
+ inline T
+ norm2(const Vector<D,T,E>& x)
+ {
+ return dot(x,x);
+ }
+ template<class V1, class V2, int B, int L>
+ struct VectorEqualsVector
+ {
+ typedef typename VectorEqualsVector<V1,V2,B,L/2>::Type_t Left_t;
+ typedef typename VectorEqualsVector<V1,V2,B+L/2,L-L/2>::Type_t Right_t;
+ typedef bool Type_t;
+ static Type_t get(const V1& x, const V2& y)
+ {
+ return
+ VectorEqualsVector<V1,V2,B,L/2>::get(x,y) &&
+ VectorEqualsVector<V1,V2,B+L/2,L-L/2>::get(x,y);
+ }
+ };
+ template<class V1, class V2, int B>
+ struct VectorEqualsVector<V1,V2,B,1>
+ {
+ typedef typename VectorElem<V1,B>::Element_t Left_t;
+ typedef typename VectorElem<V2,B>::Element_t Right_t;
+ typedef bool Type_t;
+ static Type_t get(const V1& x, const V2& y)
+ {
+ return VectorElem<V1,B>::get(x) == VectorElem<V2,B>::get(y);
+ }
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< Vector<D,T1,E1> , Vector<D,T2,E2> , OpEQ >
+ {
+ typedef bool Type_t;
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< Vector<D,T1,E1> , Vector<D,T2,E2> , OpNE >
+ {
+ typedef bool Type_t;
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ inline typename
+ BinaryReturn< Vector<D,T1,E1>,Vector<D,T2,E2> , OpEQ >::Type_t
+ operator==(const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2)
+ {
+ return VectorEqualsVector<Vector<D,T1,E1>,Vector<D,T2,E2>,0,D>::get(v1,v2);
+ }
+ template<int D, class T1, class T2, class E1, class E2>
+ inline typename
+ BinaryReturn< Vector<D,T1,E1>,Vector<D,T2,E2> , OpNE >::Type_t
+ operator!=(const Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2)
+ {
+ return !(v1 == v2);
+ }
+ template<int D, class T, class E>
+ inline typename
+ BinaryReturn<Vector<D, T, E>, Vector<D, T, E> , OpNE>::Type_t
+ operator!=(const Vector<D, T, E>& v1, const Vector<D, T, E>& v2)
+ {
+ return !(v1 == v2);
+ }
+ template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator+=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpAddAssign,0,D>::apply(v1,v2,OpAddAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator+=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpAddAssign,0,D>::apply(v1,v2,OpAddAssign()); return v1; }
+ template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator-=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpSubtractAssign,0,D>::apply(v1,v2,OpSubtractAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator-=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpSubtractAssign,0,D>::apply(v1,v2,OpSubtractAssign()); return v1; }
+ template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator*=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpMultiplyAssign,0,D>::apply(v1,v2,OpMultiplyAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator*=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpMultiplyAssign,0,D>::apply(v1,v2,OpMultiplyAssign()); return v1; }
+ template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator/=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpDivideAssign,0,D>::apply(v1,v2,OpDivideAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator/=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpDivideAssign,0,D>::apply(v1,v2,OpDivideAssign()); return v1; }
+ template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator%=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpModAssign,0,D>::apply(v1,v2,OpModAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator%=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpModAssign,0,D>::apply(v1,v2,OpModAssign()); return v1; }
+ template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator|=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpBitwiseOrAssign,0,D>::apply(v1,v2,OpBitwiseOrAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator|=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpBitwiseOrAssign,0,D>::apply(v1,v2,OpBitwiseOrAssign()); return v1; }
+ template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator&=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpBitwiseAndAssign,0,D>::apply(v1,v2,OpBitwiseAndAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator&=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpBitwiseAndAssign,0,D>::apply(v1,v2,OpBitwiseAndAssign()); return v1; }
+ template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator^=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpBitwiseXorAssign,0,D>::apply(v1,v2,OpBitwiseXorAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator^=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpBitwiseXorAssign,0,D>::apply(v1,v2,OpBitwiseXorAssign()); return v1; }
+ template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator<<=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpLeftShiftAssign,0,D>::apply(v1,v2,OpLeftShiftAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator<<=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpLeftShiftAssign,0,D>::apply(v1,v2,OpLeftShiftAssign()); return v1; }
+ template <int D, class T1, class T2, class E1, class E2> inline Vector<D,T1,E1>& operator>>=( Vector<D,T1,E1>& v1, const Vector<D,T2,E2>& v2 ) { VectorAssign<Vector<D,T1,E1>,Vector<D,T2,E2>,OpRightShiftAssign,0,D>::apply(v1,v2,OpRightShiftAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Vector<D,T1,E1>& operator>>=( Vector<D,T1,E1>& v1, const T2& v2 ) { VectorAssign<Vector<D,T1,E1>,T2,OpRightShiftAssign,0,D>::apply(v1,v2,OpRightShiftAssign()); return v1; }
+ template<int D, class T, class E> class Vector;
+ template<int D, class T, class E> class VectorEngine;
+ template <class T>
+ void reverseBytes(T&);
+ template<int Dim, class T=double, class EngineTag=Full>
+ class Vector
+ {
+ public:
+ enum { dimensions=1 };
+ enum { d1 = Dim };
+ typedef T Element_t;
+ typedef EngineTag EngineTag_t;
+ typedef VectorEngine<Dim,T,EngineTag> Engine_t;
+ typedef typename Engine_t::ElementRef_t ElementRef_t;
+ typedef typename Engine_t::ConstElementRef_t ConstElementRef_t;
+ typedef Vector<Dim,T,EngineTag> This_t;
+ Vector() {}
+ Vector(const This_t& x) : engine_m(x.engine_m) {}
+ template<int D2, class T2, class EngineTag2>
+ Vector(const Vector<D2, T2, EngineTag2>& x) : engine_m(x) {}
+ template<class X>
+ explicit Vector(const X& x) : engine_m(x) {}
+ template<class X1, class X2>
+ Vector(const X1& x, const X2& y)
+ : engine_m(x,y) {}
+ template<class X1, class X2, class X3>
+ Vector(const X1& x, const X2& y, const X3& z)
+ : engine_m(x,y,z) {}
+ template<class X1, class X2, class X3, class X4>
+ Vector(const X1& x, const X2& y, const X3& z, const X4& a)
+ : engine_m(x,y,z,a) {}
+ template<class X1, class X2, class X3, class X4, class X5>
+ Vector(const X1& x, const X2& y, const X3& z, const X4& a,
+ const X5& b)
+ : engine_m(x,y,z,a,b) {}
+ template<class X1, class X2, class X3, class X4, class X5, class X6>
+ Vector(const X1& x, const X2& y, const X3& z, const X4& a,
+ const X5& b, const X6& c)
+ : engine_m(x,y,z,a,b,c) {}
+ template<class X1, class X2, class X3, class X4, class X5, class X6, class X7>
+ Vector(const X1& x, const X2& y, const X3& z, const X4& a,
+ const X5& b, const X6& c, const X7& d)
+ : engine_m(x,y,z,a,b,c,d) {}
+ template<class X1, class X2, class X3, class X4, class X5, class X6,
+ class X7, class X8, class X9, class X10>
+ Vector(const X1& x, const X2& y, const X3& z, const X4& a,
+ const X5& b, const X6& c, const X7& d, const X8& e,
+ const X9& f, const X10& g)
+ : engine_m(x,y,z,a,b,c,d,e,f,g) {}
+ ~Vector() {}
+ This_t& operator=(const This_t& x)
+ {
+ if ( this != &const_cast<This_t &>(x) )
+ engine() = x.engine();
+ return *this;
+ }
+ template<class V>
+ This_t&
+ operator=(const V& x)
+ {
+ engine() = x;
+ return *this;
+ }
+ ConstElementRef_t operator()(int i) const
+ {
+ return engine()(i);
+ }
+ ElementRef_t operator()(int i)
+ {
+ return engine()(i);
+ }
+ const Engine_t& engine() const { return engine_m; }
+ Engine_t& engine() { return engine_m; }
+ template<class Out>
+ void print(Out &out) const;
+ inline void reverseBytes() { engine_m.reverseBytes(); }
+ private:
+ Engine_t engine_m;
+ };
+ template<int Dim, class T, class EngineTag>
+ template<class Out>
+ void Vector<Dim, T, EngineTag>::print(Out &out) const
+ {
+ std::ios::fmtflags incomingFormatFlags = out.flags();
+ long width = out.width();
+ long precision = out.precision();
+ out.width(0);
+ out << "(";
+ out.flags(incomingFormatFlags);
+ out.width(width);
+ out.precision(precision);
+ out << (*this)(0) ;
+ for (int i = 1; i < Dim; i++) {
+ out << ",";
+ out.flags(incomingFormatFlags);
+ out.width(width);
+ out.precision(precision);
+ out << (*this)(i);
+ }
+ out << ")";
+ }
+ template<int D, class T, class E>
+ std::ostream &operator<<(std::ostream &out, const Vector<D,T,E> &v)
+ {
+ v.print(out);
+ return out;
+ }
+ template <int D, class T, class E>
+ struct ElementProperties< Vector<D,T,E> >
+ : public TrivialElementProperties< Vector<D,T,E> >
+ { };
+ template<int D, class T>
+ class VectorEngine<D,T,Full>
+ {
+ public:
+ enum { dimensions=1 };
+ enum { d1 = D };
+ typedef T Element_t;
+ typedef Full EngineTag_t;
+ typedef T& ElementRef_t;
+ typedef const T& ConstElementRef_t;
+ typedef VectorEngine<D,T,Full> This_t;
+ VectorEngine()
+ {
+ PoomaCTAssert<(ElementProperties<T>::hasTrivialDefaultConstructor && ElementProperties<T>::hasTrivialDestructor && ElementProperties<T>::concrete)>::test();
+ for (int i = 0; i < D; ++i)
+ {
+ ElementProperties<T>::construct(&x_m[i]);
+ }
+ }
+ inline VectorEngine(const VectorEngine<D,T,Full>&);
+ template<class X>
+ inline explicit VectorEngine(const X& x)
+ {
+ VectorAssign< VectorEngine<D,T,Full> , X , OpAssign, 0, D >
+ ::apply(*this,x,OpAssign());
+ }
+ template<class X1, class X2>
+ inline VectorEngine(const X1& x, const X2& y)
+ {
+ PoomaCTAssert<(D == 2)>::test();
+ x_m[0] = x;
+ x_m[1] = y;
+ }
+ template<class X1, class X2, class X3>
+ inline VectorEngine(const X1& x, const X2& y, const X3& z)
+ {
+ PoomaCTAssert<(D == 3)>::test();
+ x_m[0] = x;
+ x_m[1] = y;
+ x_m[2] = z;
+ }
+ template<class X1, class X2, class X3, class X4>
+ inline VectorEngine(const X1& x, const X2& y, const X3& z,
+ const X4& a)
+ {
+ PoomaCTAssert<(D == 4)>::test();
+ x_m[0] = x;
+ x_m[1] = y;
+ x_m[2] = z;
+ x_m[3] = a;
+ }
+ template<class X1, class X2, class X3, class X4, class X5>
+ inline VectorEngine(const X1& x, const X2& y, const X3& z,
+ const X4& a, const X5& b)
+ {
+ PoomaCTAssert<(D == 5)>::test();
+ x_m[0] = x;
+ x_m[1] = y;
+ x_m[2] = z;
+ x_m[3] = a;
+ x_m[4] = b;
+ }
+ template<class X1, class X2, class X3, class X4, class X5, class X6>
+ inline VectorEngine(const X1& x, const X2& y, const X3& z,
+ const X4& a, const X5& b, const X6& c)
+ {
+ PoomaCTAssert<(D == 6)>::test();
+ x_m[0] = x;
+ x_m[1] = y;
+ x_m[2] = z;
+ x_m[3] = a;
+ x_m[4] = b;
+ x_m[5] = c;
+ }
+ template<class X1, class X2, class X3, class X4, class X5, class X6, class X7>
+ inline VectorEngine(const X1& x, const X2& y, const X3& z,
+ const X4& a, const X5& b, const X6& c, const X7& d)
+ {
+ PoomaCTAssert<(D == 7)>::test();
+ x_m[0] = x;
+ x_m[1] = y;
+ x_m[2] = z;
+ x_m[3] = a;
+ x_m[4] = b;
+ x_m[5] = c;
+ x_m[6] = d;
+ }
+ template<class X1, class X2, class X3, class X4, class X5, class X6,
+ class X7, class X8, class X9, class X10>
+ inline VectorEngine(const X1& x, const X2& y, const X3& z,
+ const X4& a, const X5& b, const X6& c,
+ const X7& d, const X8& e, const X9& f,
+ const X10& g)
+ {
+ PoomaCTAssert<(D == 10)>::test();
+ x_m[0] = x;
+ x_m[1] = y;
+ x_m[2] = z;
+ x_m[3] = a;
+ x_m[4] = b;
+ x_m[5] = c;
+ x_m[6] = d;
+ x_m[7] = e;
+ x_m[8] = f;
+ x_m[9] = g;
+ }
+ ~VectorEngine() {}
+ This_t&
+ operator=(const This_t& x)
+ {
+ if ( this != &x )
+ VectorAssign<This_t,This_t,OpAssign,0,D>::apply(*this,x,OpAssign());
+ return *this;
+ }
+ template<class V>
+ This_t&
+ operator=(const V& x)
+ {
+ VectorAssign<This_t,V,OpAssign,0,D>::apply(*this,x,OpAssign());
+ return *this;
+ }
+ ConstElementRef_t operator()(int i) const
+ {
+ ;
+ return x_m[i];
+ }
+ ElementRef_t operator()(int i)
+ {
+ ;
+ return x_m[i];
+ }
+ inline void reverseBytes()
+ {
+ for (int d = 0; d < D; ++d) ::reverseBytes(x_m[d]);
+ }
+ private:
+ T x_m[D];
+ };
+ template<int D, class T, int I>
+ struct VectorElem< VectorEngine<D,T,Full> , I >
+ {
+ typedef VectorEngine<D,T,Full> V;
+ typedef VectorEngineElem<D,T,Full,I> VE;
+ typedef typename VE::Element_t Element_t;
+ typedef typename VE::ConstElementRef_t ConstElementRef_t;
+ typedef typename VE::ElementRef_t ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return VE::get(x); }
+ static ElementRef_t get(V& x) { return VE::get(x); }
+ };
+ template<class T, class Components> struct ComponentAccess;
+ template<int D, class T, class E, int N>
+ struct ComponentAccess< Vector<D, T, E>, Loc<N> >
+ {
+ typedef Vector<D, T, E> V;
+ typedef typename V::Element_t Element_t;
+ typedef typename V::ElementRef_t ElementRef_t;
+ static inline ElementRef_t indexRef(V &v, const Loc<N> &l)
+ {
+ PoomaCTAssert<(N==1)>::test();
+ return v(l[0].first());
+ }
+ static inline Element_t index(const V &v, const Loc<N> &l)
+ {
+ PoomaCTAssert<(N==1)>::test();
+ return v(l[0].first());
+ }
+ };
+ template<int D, class T>
+ inline
+ VectorEngine<D,T,Full>::VectorEngine(const VectorEngine<D,T,Full>& x)
+ {
+ VectorAssign<This_t,This_t,OpAssign,0,D>::apply(*this,x,OpAssign());
+ }
+ template<class T>
+ class RemoteProxy
+ {
+ public:
+ typedef RemoteProxy<T> This_t;
+ RemoteProxy(T &val, int owningContext = 0)
+ {
+ if (Pooma::context() == owningContext)
+ {
+ value_m = &val;
+ }
+ }
+ RemoteProxy(const RemoteProxy<T> &s)
+ {
+ if (s.value_m != &s.storedValue_m)
+ {
+ value_m = s.value_m;
+ }
+ else
+ {
+ storedValue_m = s.value();
+ value_m = &storedValue_m;
+ }
+ }
+ inline
+ operator T() const { return *value_m; }
+ inline
+ T &value() { return *value_m; }
+ inline
+ const T &value() const { return *value_m; }
+ template<class S>
+ inline
+ RemoteProxy<T> &operator=(const S &s)
+ {
+ *value_m = s;
+ return *this;
+ }
+ template<class S>
+ inline
+ RemoteProxy<T> &operator=(const RemoteProxy<S> &s)
+ {
+ *value_m = s.value();
+ return *this;
+ }
+ inline
+ RemoteProxy<T> &operator=(const RemoteProxy<T> &s)
+ {
+ *value_m = s.value();
+ return *this;
+ }
+ inline
+ typename ComponentAccess<T, Loc<1> >::Element_t
+ operator()(int i) const
+ {
+ return ComponentAccess<T, Loc<1> >::index(value(), Loc<1>(i));
+ }
+ inline
+ typename ComponentAccess<T, Loc<1> >::ElementRef_t
+ operator()(int i)
+ {
+ return ComponentAccess<T, Loc<1> >::indexRef(value(), Loc<1>(i));
+ }
+ private:
+ T *value_m;
+ T storedValue_m;
+ };
+ template<class T, class S>
+ inline T
+ operator*(const RemoteProxy<T> &t, const S &s)
+ {
+ return t.value() * s;
+ }
+ template<class T>
+ class ReductionValue
+ {
+ public:
+ ReductionValue(bool valid, const T &val)
+ : valid_m(valid)
+ {
+ if (valid_m)
+ val_m = val;
+ }
+ ReductionValue(const ReductionValue<T> &model)
+ {
+ valid_m = model.valid();
+ if (valid_m)
+ val_m = model.value();
+ }
+ ReductionValue<T> &operator=(const ReductionValue<T> &rhs)
+ {
+ if (&rhs != this)
+ {
+ valid_m = rhs.valid();
+ if (valid_m)
+ val_m = rhs.value();
+ }
+ return *this;
+ }
+ bool valid() const { return valid_m; }
+ const T &value() const { ; return val_m; }
+ T &value() { ; return val_m; }
+ private:
+ bool valid_m;
+ T val_m;
+ };
+ template<class T, class ReductionOp>
+ class ReduceOverContexts
+ {
+ typedef ReduceOverContexts<T, ReductionOp> This_t;
+ public:
+ ReduceOverContexts(const T &val, int = 0, bool valid = true)
+ {
+ ;
+ value_m = val;
+ }
+ void broadcast(T &val)
+ {
+ val = value_m;
+ }
+ inline operator T() const { return value_m; }
+ private:
+ static void receive(This_t *me, ReductionValue<T> &v)
+ {
+ if (v.valid())
+ {
+ if (!me->valid_m)
+ {
+ me->value_m = v.value();
+ me->valid_m = true;
+ }
+ else
+ {
+ ReductionOp()(me->value_m, v.value());
+ }
+ }
+ me->toReceive_m--;
+ }
+ T value_m;
+ bool valid_m;
+ int toReceive_m;
+ int toContext_m;
+ };
+ struct SendReceive
+ {
+ template<class View>
+ static
+ void send(const View &view, int toContext)
+ {
+ ;
+ }
+ };
+ template<class IncomingView>
+ struct Receive
+ {
+ template<class View>
+ static
+ void receive(const View &view, int fromContext)
+ {
+ ;
+ }
+ };
+ template<int Dim>
+ Interval<Dim> &
+ shrinkRightInPlace(Interval<Dim> &dom, const Loc<Dim> &s)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first();
+ int b = dom[d].last() - s[d].first();
+ dom[d] = Interval<1>(a, b);
+ }
+ return dom;
+ }
+ template<int Dim>
+ Interval<Dim> &
+ shrinkRightInPlace(Interval<Dim> &dom, int s)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first();
+ int b = dom[d].last() - s;
+ dom[d] = Interval<1>(a, b);
+ }
+ return dom;
+ }
+ template<int Dim>
+ Interval<Dim> &
+ growRightInPlace(Interval<Dim> &dom, const Loc<Dim> &s)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first();
+ int b = dom[d].last() + s[d].first();
+ dom[d] = Interval<1>(a, b);
+ }
+ return dom;
+ }
+ template<int Dim>
+ Interval<Dim> &
+ growRightInPlace(Interval<Dim> &dom, int s)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first();
+ int b = dom[d].last() + s;
+ dom[d] = Interval<1>(a, b);
+ }
+ return dom;
+ }
+ template<int Dim>
+ Interval<Dim> &
+ shrinkLeftInPlace(Interval<Dim> &dom, const Loc<Dim> &s)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() + s[d].first();
+ int b = dom[d].last();
+ dom[d] = Interval<1>(a, b);
+ }
+ return dom;
+ }
+ template<int Dim>
+ Interval<Dim> &
+ shrinkLeftInPlace(Interval<Dim> &dom, int s)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() + s;
+ int b = dom[d].last();
+ dom[d] = Interval<1>(a, b);
+ }
+ return dom;
+ }
+ template<int Dim>
+ Interval<Dim> &
+ growLeftInPlace(Interval<Dim> &dom, const Loc<Dim> &s)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() - s[d].first();
+ int b = dom[d].last();
+ dom[d] = Interval<1>(a, b);
+ }
+ return dom;
+ }
+ template<int Dim>
+ Interval<Dim> &
+ growLeftInPlace(Interval<Dim> &dom, int s)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() - s;
+ int b = dom[d].last();
+ dom[d] = Interval<1>(a, b);
+ }
+ return dom;
+ }
+ template<int Dim>
+ inline Interval<Dim>
+ shrinkRight(const Interval<Dim> &dom, const Loc<Dim> &s)
+ {
+ Interval<Dim> ret = Pooma::NoInit();
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first();
+ int b = dom[d].last() - s[d].first();
+ ret[d] = Interval<1>(a, b);
+ }
+ return ret;
+ }
+ template<int Dim>
+ inline Interval<Dim>
+ shrinkRight(const Interval<Dim> &dom, int s)
+ {
+ Interval<Dim> ret = Pooma::NoInit();
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first();
+ int b = dom[d].last() - s;
+ ret[d] = Interval<1>(a, b);
+ }
+ return ret;
+ }
+ template<int Dim>
+ inline Interval<Dim>
+ growRight(const Interval<Dim> &dom, const Loc<Dim> &s)
+ {
+ Interval<Dim> ret = Pooma::NoInit();
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first();
+ int b = dom[d].last() + s[d].first();
+ ret[d] = Interval<1>(a, b);
+ }
+ return ret;
+ }
+ template<int Dim>
+ inline Interval<Dim>
+ growRight(const Interval<Dim> &dom, int s)
+ {
+ Interval<Dim> ret = Pooma::NoInit();
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first();
+ int b = dom[d].last() + s;
+ ret[d] = Interval<1>(a, b);
+ }
+ return ret;
+ }
+ template<int Dim>
+ inline Interval<Dim>
+ shrinkLeft(const Interval<Dim> &dom, const Loc<Dim> &s)
+ {
+ Interval<Dim> ret = Pooma::NoInit();
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() + s[d].first();
+ int b = dom[d].last();
+ ret[d] = Interval<1>(a, b);
+ }
+ return ret;
+ }
+ template<int Dim>
+ inline Interval<Dim>
+ shrinkLeft(const Interval<Dim> &dom, int s)
+ {
+ Interval<Dim> ret = Pooma::NoInit();
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() + s;
+ int b = dom[d].last();
+ ret[d] = Interval<1>(a, b);
+ }
+ return ret;
+ }
+ template<int Dim>
+ inline Interval<Dim>
+ growLeft(const Interval<Dim> &dom, const Loc<Dim> &s)
+ {
+ Interval<Dim> ret = Pooma::NoInit();
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() - s[d].first();
+ int b = dom[d].last();
+ ret[d] = Interval<1>(a, b);
+ }
+ return ret;
+ }
+ template<int Dim>
+ inline Interval<Dim>
+ growLeft(const Interval<Dim> &dom, int s)
+ {
+ Interval<Dim> ret = Pooma::NoInit();
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() - s;
+ int b = dom[d].last();
+ ret[d] = Interval<1>(a, b);
+ }
+ return ret;
+ }
+ template<int Dim>
+ inline Interval<Dim>
+ grow(const Interval<Dim> &dom, int s)
+ {
+ Interval<Dim> ret = Pooma::NoInit();
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() - s;
+ int b = dom[d].last() + s;
+ ret[d] = Interval<1>(a, b);
+ }
+ return ret;
+ }
+ template<int Dim>
+ inline Interval<Dim>
+ grow(const Interval<Dim> &dom, const Loc<Dim> &s)
+ {
+ Interval<Dim> ret = Pooma::NoInit();
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() - s[d].first();
+ int b = dom[d].last() + s[d].first();
+ ret[d] = Interval<1>(a, b);
+ }
+ return ret;
+ }
+ template<int Dim>
+ inline Interval<Dim>
+ shrink(const Interval<Dim> &dom, int s)
+ {
+ Interval<Dim> ret = Pooma::NoInit();
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() + s;
+ int b = dom[d].last() - s;
+ ret[d] = Interval<1>(a, b);
+ }
+ return ret;
+ }
+ template<int Dim>
+ inline Interval<Dim>
+ shrink(const Interval<Dim> &dom, const Loc<Dim> &s)
+ {
+ Interval<Dim> ret = Pooma::NoInit();
+ for (int d = 0; d < Dim; ++d)
+ {
+ int a = dom[d].first() + s[d].first();
+ int b = dom[d].last() - s[d].first();
+ ret[d] = Interval<1>(a, b);
+ }
+ return ret;
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
+ Engine()
+ : pDirty_m(0)
+ {
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
+ Engine(const Layout_t &layout)
+ : layout_m(layout),
+ data_m(layout.sizeGlobal()),
+ pDirty_m(new int)
+ {
+ typedef typename Layout_t::Value_t Node_t;
+ setDirty();
+ int sz = data().size();
+ typedef Pooma::CountingSemaphore CountingSemaphore_t;
+ typedef typename Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
+ template PatchAllocator<Node_t,CountingSemaphore_t> PatchAllocator_t;
+ CountingSemaphore_t csem;
+ csem.height(sz);
+ typename Layout_t::const_iterator p = layout_m.beginGlobal();
+ for (int i = 0; i < sz; ++i, ++p)
+ {
+ PatchAllocator_t *spot = new PatchAllocator_t(data()[i], *p, csem);
+ Pooma::addRunnable(spot);
+ }
+ csem.wait();
+ layout_m.attach(*this);
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
+ Engine(const Engine_t &modelEngine)
+ : layout_m(modelEngine.layout_m),
+ data_m(modelEngine.data_m),
+ pDirty_m(modelEngine.pDirty_m)
+ {
+ layout_m.attach(*this);
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
+ ~Engine()
+ {
+ if (initialized())
+ {
+ layout_m.detach(*this);
+ if (!data().isShared())
+ delete pDirty_m;
+ }
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> > &
+ Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
+ operator=(const Engine_t &model)
+ {
+ if (&model == this)
+ return *this;
+ if (!model.initialized())
+ return *this;
+ if (initialized())
+ {
+ if (!data().isShared())
+ delete pDirty_m;
+ layout_m.detach(*this);
+ }
+ data_m = model.data();
+ pDirty_m = model.pDirty_m;
+ layout_m = model.layout_m;
+ layout_m.attach(*this);
+ return *this;
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> > &
+ Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::
+ makeOwnCopy()
+ {
+ if (data_m.isValid() && data_m.isShared()) {
+ data_m.makeOwnCopy();
+ pDirty_m = new int(*pDirty_m);
+ }
+ return *this;
+ }
+ template <int Dim, class T, class Tag>
+ static inline
+ void simpleAssign(const Array<Dim, T, Tag>& lhs,
+ const Array<Dim, T, Tag>& rhs,
+ const Interval<Dim>& domain)
+ {
+ lhs(domain) = rhs(domain);
+ }
+ template <int Dim, class T, class Tag>
+ static inline
+ void simpleAssign(const Array<Dim, T, Remote<Tag> >& lhs,
+ const Array<Dim, T, Remote<Tag> >& rhs,
+ const Interval<Dim>& domain)
+ {
+ if (lhs.engine().owningContext() == rhs.engine().owningContext())
+ lhs(domain) = rhs(domain);
+ else {
+ typedef typename NewEngine<Engine<Dim, T, Tag>, Interval<Dim> >::Type_t ViewEngine_t;
+ if (lhs.engine().engineIsLocal())
+ Receive<ViewEngine_t>::receive(ViewEngine_t(lhs.engine().localEngine(), domain),
+ rhs.engine().owningContext());
+ else if (rhs.engine().engineIsLocal())
+ SendReceive::send(ViewEngine_t(rhs.engine().localEngine(), domain),
+ lhs.engine().owningContext());
+ }
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ void Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::
+ fillGuardsHandler(const GuardLayers<Dim>& g, const WrappedInt<true> &) const
+ {
+ if (!isDirty()) return;
+ int updated = 0;
+ typename Layout_t::FillIterator_t p = layout_m.beginFillList();
+ while (p != layout_m.endFillList())
+ {
+ int src = p->ownedID_m;
+ int dest = p->guardID_m;
+ if (isDirty(p->face_m)) {
+ int d = p->face_m/2;
+ int guardSizeNeeded = p->face_m & 1 ? g.upper(d) : g.lower(d);
+ if (!(p->face_m != -1
+ && guardSizeNeeded == 0)) {
+ Array<Dim, T, PatchTag> lhs(data()[dest]), rhs(data()[src]);
+ lhs(p->domain_m) = rhs(p->domain_m);
+ updated |= 1<<p->face_m;
+ }
+ }
+ ++p;
+ }
+ *pDirty_m &= ~updated;
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ void Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::
+ setGuards(const T &val) const
+ {
+ typename Layout_t::FillIterator_t p = layout_m.beginFillList();
+ while (p != layout_m.endFillList())
+ {
+ int dest = p->guardID_m;
+ Array<Dim, T, PatchTag> lhs(data()[dest]);
+ lhs(p->domain_m) = val;
+ ++p;
+ }
+ setDirty();
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ void Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::
+ accumulateFromGuards() const
+ {
+ typename Layout_t::FillIterator_t p = layout_m.beginFillList();
+ while (p != layout_m.endFillList())
+ {
+ int dest = p->ownedID_m;
+ int src = p->guardID_m;
+ Array<Dim, T, PatchTag> lhs(data()[dest]), rhs(data()[src]);
+ lhs(p->domain_m) += rhs(p->domain_m);
+ ++p;
+ }
+ setDirty();
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ void Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >::
+ dynamicHandler(Observable_t &,
+ const ObserverEvent &event,
+ const WrappedInt<true> &)
+ {
+ switch (event.event())
+ {
+ case DynamicEvents::create:
+ {
+ typedef const CreateEvent &EventRef_t;
+ EventRef_t e = dynamic_cast<EventRef_t>(event);
+ performCreate(e.amount(), e.patch(), e.ID());
+ }
+ break;
+ case DynamicEvents::destroyInterval:
+ {
+ typedef const DestroyEvent< Interval<1> > &EventRef_t;
+ EventRef_t e = dynamic_cast<EventRef_t>(event);
+ switch (e.method())
+ {
+ case DynamicEvents::backfill:
+ performDestroy(e.domain(), e.patch(), BackFill(), e.ID());
+ break;
+ case DynamicEvents::shiftup:
+ performDestroy(e.domain(), e.patch(), ShiftUp(), e.ID());
+ break;
+ default:
+ if (__builtin_expect(!!(false), true)) {} else Pooma::toss_cookies("Unsupported delete method MultiPatchEngine::destroy", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Engine/MultiPatchEngine.cpp", 455);
+ }
+ }
+ break;
+ case DynamicEvents::destroyRange:
+ {
+ typedef const DestroyEvent< Range<1> > &EventRef_t;
+ EventRef_t e = dynamic_cast<EventRef_t>(event);
+ switch (e.method())
+ {
+ case DynamicEvents::backfill:
+ performDestroy(e.domain(), e.patch(), BackFill(), e.ID());
+ break;
+ case DynamicEvents::shiftup:
+ performDestroy(e.domain(), e.patch(), ShiftUp(), e.ID());
+ break;
+ default:
+ if (__builtin_expect(!!(false), true)) {} else Pooma::toss_cookies("Unsupported delete method MultiPatchEngine::destroy", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Engine/MultiPatchEngine.cpp", 476);
+ }
+ }
+ break;
+ case DynamicEvents::destroyList:
+ {
+ typedef const DestroyEvent< IndirectionList<int> > &EventRef_t;
+ EventRef_t e = dynamic_cast<EventRef_t>(event);
+ switch (e.method())
+ {
+ case DynamicEvents::backfill:
+ performDestroy(e.domain(), e.patch(), BackFill(), e.ID());
+ break;
+ case DynamicEvents::shiftup:
+ performDestroy(e.domain(), e.patch(), ShiftUp(), e.ID());
+ break;
+ default:
+ if (__builtin_expect(!!(false), true)) {} else Pooma::toss_cookies("Unsupported delete method MultiPatchEngine::destroy", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Engine/MultiPatchEngine.cpp", 497);
+ }
+ }
+ break;
+ case DynamicEvents::destroyIterList:
+ {
+ using Pooma::IteratorPairDomain;
+ typedef
+ const DestroyEvent< IteratorPairDomain<const int*> > &EventRef_t;
+ EventRef_t e = dynamic_cast<EventRef_t>(event);
+ switch (e.method())
+ {
+ case DynamicEvents::backfill:
+ performDestroy(e.domain(), e.patch(), BackFill(), e.ID());
+ break;
+ case DynamicEvents::shiftup:
+ performDestroy(e.domain(), e.patch(), ShiftUp(), e.ID());
+ break;
+ default:
+ if (__builtin_expect(!!(false), true)) {} else Pooma::toss_cookies("Unsupported delete method MultiPatchEngine::destroy", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Engine/MultiPatchEngine.cpp", 520);
+ }
+ }
+ break;
+ case DynamicEvents::copyInterval:
+ {
+ typedef const CopyEvent< Interval<1> > &EventRef_t;
+ EventRef_t e = dynamic_cast<EventRef_t>(event);
+ performCopy(e.domain(), e.fromPatch(), e.toPatch(), e.ID());
+ }
+ break;
+ case DynamicEvents::copyRange:
+ {
+ typedef const CopyEvent< Range<1> > &EventRef_t;
+ EventRef_t e = dynamic_cast<EventRef_t>(event);
+ performCopy(e.domain(), e.fromPatch(), e.toPatch(), e.ID());
+ }
+ break;
+ case DynamicEvents::copyList:
+ {
+ typedef const CopyEvent< IndirectionList<int> > &EventRef_t;
+ EventRef_t e = dynamic_cast<EventRef_t>(event);
+ performCopy(e.domain(), e.fromPatch(), e.toPatch(), e.ID());
+ }
+ break;
+ case DynamicEvents::copyPatchList:
+ {
+ typedef const CopyPatchEvent &EventRef_t;
+ EventRef_t e = dynamic_cast<EventRef_t>(event);
+ performPatchCopy(e.domainLists(), e.fromPatch(), e.toPatch(),
+ e.create(), e.ID());
+ }
+ break;
+ case DynamicEvents::sync:
+ {
+ for (int i=0; i < layout().sizeGlobal(); ++i)
+ data()[i].sync(layout().nodeListGlobal()[i]->domain());
+ }
+ break;
+ default:
+ if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("Invalid dynamic op???", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Engine/MultiPatchEngine.cpp", 567);
+ }
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ void Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
+ notify(Observable_t &observed, const ObserverEvent &event)
+ {
+ ;
+ if(event.event() == Layout_t::repartitionEvent)
+ {
+ typedef typename Layout_t::Value_t Node_t;
+ int sz = layout().sizeGlobal();
+ PatchContainer_t newData(sz);
+ typedef Pooma::CountingSemaphore CountingSemaphore_t;
+ typedef typename Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
+ template PatchAllocator<Node_t,CountingSemaphore_t> PatchAllocator_t;
+ CountingSemaphore_t csem;
+ csem.height(sz);
+ typename Layout_t::const_iterator p = layout().beginGlobal();
+ for (int i = 0; i < sz; ++i, ++p)
+ {
+ PatchAllocator_t *spot = new PatchAllocator_t(newData[i], *p, csem);
+ Pooma::addRunnable(spot);
+ }
+ csem.wait();
+ data_m = newData;
+ }
+ else
+ {
+ if (DynamicEvents::isDynamic(event.event()))
+ {
+ dynamicHandler(observed, event,
+ WrappedInt<PatchEngine_t::dynamic>());
+ }
+ else
+ {
+ }
+ }
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ void Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
+ performCreate(CreateSize_t num, PatchID_t localPatchID, DynamicID_t did)
+ {
+ ;
+ ;
+ int globalID = layout().nodeListLocal()[localPatchID]->globalID();
+ if (! checkDynamicID(data()[globalID], did))
+ return;
+ data()[globalID].create(num);
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ template <class Dom, class DeleteMethod>
+ void Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
+ performDestroy(const Dom &killlist, PatchID_t localPatchID,
+ const DeleteMethod &method, DynamicID_t did)
+ {
+ ;
+ int globalID = layout().nodeListLocal()[localPatchID]->globalID();
+ if (! checkDynamicID(data()[globalID], did))
+ return;
+ data()[globalID].destroy(killlist, method, true);
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ template <class Dom>
+ void Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
+ performCopy(const Dom ©list, PatchID_t frompatch, PatchID_t topatch,
+ DynamicID_t did)
+ {
+ ;
+ ;
+ ;
+ int from_gID = layout().nodeListLocal()[frompatch]->globalID();
+ int to_gID = layout().nodeListLocal()[topatch]->globalID();
+ bool chk1 = checkDynamicID(data()[from_gID], did);
+ bool chk2 = chk1;
+ if (frompatch != topatch)
+ chk2 = checkDynamicID(data()[to_gID], did);
+ ;
+ if (!chk1 || !chk2)
+ return;
+ ;
+ int offs = data()[from_gID].domain()[0].first();
+ int i = data()[to_gID].domain()[0].last() + 1;
+ int num = copylist.size();
+ data()[to_gID].create(num);
+ for (int n = 0; n < num; ++n, ++i)
+ {
+ localPatchEngine(data()[to_gID])(i) =
+ localPatchEngine(data()[from_gID])(copylist[0](n) + offs);
+ }
+ }
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ void Engine<Dim, T, MultiPatch<LayoutTag, PatchTag> >::
+ performPatchCopy(const IndirectionList< IndirectionList<int> > &domlists,
+ const IndirectionList< int > &fromlist,
+ PatchID_t topatch,
+ bool docreate,
+ DynamicID_t did)
+ {
+ ;
+ ;
+ int to_gID = layout().nodeListLocal()[topatch]->globalID();
+ if (! checkDynamicID(data()[to_gID], did))
+ return;
+ int i, p, fill, created = 0;
+ int np = domlists.size();
+ ;
+ for (p = 0; p < np; ++p)
+ {
+ int frompatch = fromlist(p);
+ int from_gID = layout().nodeListLocal()[frompatch]->globalID();
+ ;
+ ;
+ ;
+ created += domlists(p).size();
+ }
+ if (docreate)
+ {
+ fill = data()[to_gID].domain()[0].last() + 1;
+ data()[to_gID].create(created);
+ }
+ else
+ {
+ ;
+ fill = data()[to_gID].domain()[0].last() + 1 - created;
+ }
+ for (p = 0; p < np; ++p)
+ {
+ int sz = domlists(p).size();
+ int frompatch = fromlist(p);
+ int from_gID = layout().nodeListLocal()[frompatch]->globalID();
+ int offs = data()[from_gID].domain()[0].first();
+ for (i = 0; i < sz; ++i, ++fill)
+ {
+ localPatchEngine(data()[to_gID])(fill) =
+ localPatchEngine(data()[from_gID])(domlists(p)(i) + offs);
+ }
+ }
+ }
+ template<int Dim, class T, class LTag, class PatchTag>
+ long elementsCompressed(const Engine<Dim, T, MultiPatch<LTag, PatchTag> >
+ &engine)
+ {
+ int size = engine.layout().sizeLocal();
+ bool distributed = true;
+ if (size > 0 && engine.layout().beginLocal()->context() == -1)
+ distributed = false;
+ long num = 0L;
+ for (int i = 0 ; i < size ; ++i )
+ num += elementsCompressed(engine.localPatch(i));
+ if (distributed)
+ {
+ ReduceOverContexts<long, OpAddAssign> total(num);
+ total.broadcast(num);
+ }
+ return num;
+ }
+ template<int Dim, class T, class LTag, class PatchTag>
+ bool compressed(const Engine<Dim, T, MultiPatch<LTag, PatchTag> > &engine)
+ {
+ int size = engine.layout().sizeLocal();
+ bool distributed = true;
+ if (size > 0 && engine.layout().beginLocal()->context() == -1)
+ distributed = false;
+ int com = 1;
+ for (int i = 0 ; i < size ; ++i )
+ com &= (compressed(engine.localPatch(i)) ? 1 : 0);
+ if (distributed)
+ {
+ ReduceOverContexts<int, OpBitwiseAndAssign> total(com);
+ total.broadcast(com);
+ }
+ return com ? true : false;
+ }
+ template<int Dim, class T, class LTag, class PatchTag, int Dim2>
+ long elementsCompressed(const
+ Engine<Dim, T, MultiPatchView<LTag, PatchTag, Dim2> > &engine)
+ {
+ typedef Engine<Dim, T, MultiPatchView<LTag, PatchTag, Dim2> > Engine_t;
+ typedef typename Engine_t::Layout_t Layout_t;
+ int size = engine.layout().sizeLocal();
+ bool distributed = true;
+ if (size > 0 && engine.layout().beginLocal()->context() == -1)
+ distributed = false;
+ typename Layout_t::const_iterator i = engine.layout().beginLocal();
+ long num = 0L;
+ while (i != engine.layout().endLocal())
+ {
+ num += elementsCompressed(engine.globalPatch(*i));
+ ++i;
+ }
+ if (distributed)
+ {
+ ReduceOverContexts<long, OpAddAssign> total(num);
+ total.broadcast(num);
+ }
+ return num;
+ }
+ template<int Dim, class T, class LTag, class PatchTag>
+ void compress(Engine<Dim, T, MultiPatch<LTag, PatchTag> > &engine)
+ {
+ for (int i = 0; i < engine.layout().sizeLocal(); ++i)
+ compress(engine.localPatch(i));
+ }
+ template<int Dim, class T, class LTag, class PatchTag>
+ void uncompress(Engine<Dim, T, MultiPatch<LTag, PatchTag> > &engine)
+ {
+ for (int i = 0; i < engine.layout().sizeLocal(); ++i)
+ uncompress(engine.localPatch(i));
+ }
+ template <int Dim> class GridLayoutData;
+ template <int Dim> class GridLayout;
+ template <int Dim, int Dim2> class GridLayoutViewData;
+ template <int Dim, int Dim2> class GridLayoutView;
+ struct GridTag { };
+ template <int Dim>
+ struct MultiPatchLayoutTraits<GridTag,Dim>
+ {
+ typedef GridLayout<Dim> Layout_t;
+ template <int ViewDim>
+ struct View
+ {
+ typedef GridLayoutView<ViewDim,Dim> Layout_t;
+ };
+ };
+ template<int Dim>
+ class GridLayoutData
+ : public LayoutBaseData<Dim>,
+ public RefCounted,
+ public Observable< GridLayoutData<Dim> >
+ {
+ public:
+ typedef GridLayoutData<Dim> This_t;
+ typedef Observable<This_t> Observable_t;
+ typedef Interval<Dim> Domain_t;
+ typedef Interval<Dim> BaseDomain_t;
+ typedef int Context_t;
+ typedef Unique::Value_t ID_t;
+ typedef Node<Domain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ typedef int AxisIndex_t;
+ typedef typename DynamicEvents::PatchID_t PatchID_t;
+ typedef typename DynamicEvents::CreateSize_t CreateSize_t;
+ typedef typename LayoutBaseData<Dim>::GCFillInfo_t GCFillInfo_t;
+ typedef typename std::vector<GCFillInfo_t>::const_iterator FillIterator_t;
+ enum { dimensions = Dim };
+ enum { repartitionEvent = 1 };
+ enum { dynamic = false };
+ GridLayoutData();
+ template <class Partitioner>
+ GridLayoutData(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> & cmap);
+ template <class Partitioner>
+ GridLayoutData(const Grid<Dim> &gdom,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> &cmap);
+ ~GridLayoutData();
+ template <class Partitioner>
+ void initialize(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> &cmap);
+ template <class Partitioner>
+ inline void initialize(const Grid<Dim> &gdom,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> &cmap);
+ void initialize(const Domain_t& idom,
+ const List_t& nodes,
+ const Loc<Dim>& blocks,
+ bool hasIG, bool hasEG,
+ const GuardLayers_t& ig,
+ const GuardLayers_t& eg);
+ inline const Loc<Dim> &blocks() const
+ {
+ return this->blocks_m;
+ }
+ inline bool dirty() const
+ {
+ return dirtyLayout_m;
+ }
+ int globalID(const Loc<Dim> &loc) const;
+ int globalID(int) const;
+ int globalID(int,int) const;
+ int globalID(int,int,int) const;
+ int globalID(int,int,int,int) const;
+ int globalID(int,int,int,int,int) const;
+ int globalID(int,int,int,int,int,int) const;
+ int globalID(int,int,int,int,int,int,int) const;
+ FillIterator_t beginFillList() const
+ {
+ return this->gcFillList_m.begin();
+ }
+ FillIterator_t endFillList() const
+ {
+ return this->gcFillList_m.end();
+ }
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touches(const OtherDomain &fulld, OutIter o,
+ const ConstructTag &ctag) const;
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int touchesAlloc(const OtherDomain &fulld, OutIter o,
+ const ConstructTag &ctag) const;
+ void sync();
+ template<class Out>
+ void print(Out & ostr);
+ private:
+ void calcGCFillList();
+ void calcDomains();
+ void calcMaps() const;
+ void calcAllocMaps() const;
+ inline int blockIndex(const Loc<Dim> &loc) const
+ {
+ int pos = loc[0].first();
+ for (int i=1; i < Dim; ++i)
+ pos += loc[i].first() * blockStrides_m[i];
+ return pos;
+ }
+ bool dirtyLayout_m;
+ int blockStrides_m[Dim];
+ mutable DomainMap<Interval<1>,AxisIndex_t> map_m[Dim];
+ mutable DomainMap<Interval<1>,AxisIndex_t> mapAloc_m[Dim];
+ };
+ template <int Dim>
+ class GridLayout : public LayoutBase<Dim,GridLayoutData<Dim> >,
+ public Observable<GridLayout<Dim> >,
+ public Observer<GridLayoutData<Dim> >
+ {
+ public:
+ typedef GridLayout<Dim> This_t;
+ typedef Observable<This_t> Observable_t;
+ typedef GridLayoutData<Dim> LayoutData_t;
+ typedef typename LayoutData_t::Domain_t Domain_t;
+ typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
+ typedef typename LayoutData_t::Context_t Context_t;
+ typedef typename LayoutData_t::ID_t ID_t;
+ typedef typename LayoutData_t::Value_t Value_t;
+ typedef typename LayoutData_t::List_t List_t;
+ typedef DynamicEvents::PatchID_t PatchID_t;
+ typedef DynamicEvents::CreateSize_t CreateSize_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ typedef DerefIterator<Value_t> iterator;
+ typedef ConstDerefIterator<Value_t> const_iterator;
+ typedef typename LayoutData_t::GCFillInfo_t GCFillInfo_t;
+ typedef typename
+ std::vector<GCFillInfo_t>::const_iterator FillIterator_t;
+ enum { dimensions = Dim };
+ enum { repartitionEvent = 1 };
+ enum { dynamic = true };
+ GridLayout();
+ GridLayout(const Domain_t &,const DistributedTag &);
+ GridLayout(const Domain_t &,const ReplicatedTag &);
+ GridLayout(const Domain_t &,
+ const GuardLayers_t &,const DistributedTag &);
+ GridLayout(const Domain_t &,
+ const GuardLayers_t &,const ReplicatedTag &);
+ GridLayout(const Domain_t &,
+ const Loc<Dim> &,const DistributedTag &);
+ GridLayout(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,const DistributedTag &);
+ GridLayout(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,
+ const GuardLayers_t &,const DistributedTag &);
+ GridLayout(const Domain_t &,
+ const Loc<Dim> &,const ReplicatedTag &);
+ GridLayout(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,const ReplicatedTag &);
+ GridLayout(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,
+ const GuardLayers_t &,const ReplicatedTag &);
+ GridLayout(const Grid<Dim> &,
+ const DistributedTag &);
+ GridLayout(const Grid<Dim> &,
+ const GuardLayers_t &,
+ const DistributedTag &);
+ GridLayout(const Grid<Dim> &,
+ const GuardLayers_t &,
+ const GuardLayers_t &,
+ const DistributedTag &);
+ GridLayout(const Grid<Dim> &,
+ const ReplicatedTag &);
+ GridLayout(const Grid<Dim> &,
+ const GuardLayers_t &,
+ const ReplicatedTag &);
+ GridLayout(const Grid<Dim> &,
+ const GuardLayers_t &,
+ const GuardLayers_t &,
+ const ReplicatedTag &);
+ template <class Partitioner>
+ GridLayout(const Domain_t &,
+ const Partitioner &,
+ const DistributedTag &);
+ template <class Partitioner>
+ GridLayout(const Domain_t &,
+ const Partitioner &,
+ const ReplicatedTag &);
+ template <class Partitioner>
+ GridLayout(const Domain_t &,
+ const Partitioner &,
+ const ContextMapper<Dim> &);
+ GridLayout(const This_t &);
+ This_t &operator=(const This_t &);
+ inline ~GridLayout()
+ {
+ this->pdata_m->detach(*this);
+ }
+ void initialize(const Domain_t &,
+ const DistributedTag &);
+ void initialize(const Domain_t &,
+ const GuardLayers_t &,
+ const DistributedTag &);
+ void initialize(const Domain_t &,
+ const Loc<Dim> &,
+ const DistributedTag &);
+ void initialize(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,
+ const DistributedTag &);
+ void initialize(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,
+ const GuardLayers_t &,
+ const DistributedTag &);
+ void initialize(const Grid<Dim> &,
+ const DistributedTag &);
+ void initialize(const Grid<Dim> &,
+ const GuardLayers_t &,
+ const DistributedTag &);
+ void initialize(const Grid<Dim> &,
+ const GuardLayers_t &,
+ const GuardLayers_t &,
+ const DistributedTag &);
+ template <class Partitioner>
+ void initialize(const Domain_t &,
+ const Partitioner &,
+ const DistributedTag &);
+ void initialize(const Domain_t &,
+ const ReplicatedTag &);
+ void initialize(const Domain_t &,
+ const GuardLayers_t &,
+ const ReplicatedTag &);
+ void initialize(const Domain_t &,
+ const Loc<Dim> &,
+ const ReplicatedTag &);
+ void initialize(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,
+ const ReplicatedTag &);
+ void initialize(const Domain_t &,
+ const Loc<Dim> &,
+ const GuardLayers_t &,
+ const GuardLayers_t &,
+ const ReplicatedTag &);
+ void initialize(const Grid<Dim> &,
+ const ReplicatedTag &);
+ void initialize(const Grid<Dim> &,
+ const GuardLayers_t &,
+ const ReplicatedTag &);
+ void initialize(const Grid<Dim> &,
+ const GuardLayers_t &,
+ const GuardLayers_t &,
+ const ReplicatedTag &);
+ template <class Partitioner>
+ void initialize(const Domain_t &,
+ const Partitioner &,
+ const ReplicatedTag &);
+ template <class Partitioner>
+ void initialize(const Domain_t &,
+ const Partitioner &,
+ const ContextMapper<Dim> &);
+ void initialize(const Domain_t& idom,
+ const List_t& nodes,
+ const Loc<Dim>& blocks,
+ bool hasIG, bool hasEG,
+ const GuardLayers_t& ig,
+ const GuardLayers_t& eg);
+ inline const Loc<Dim> &blocks() const
+ {
+ return this->pdata_m->blocks();
+ }
+ template <class Partitioner>
+ inline bool repartition(const Partitioner &gp,const ContextMapper<Dim> &cm)
+ {
+ this->pdata_m->initialize(this->domain(),gp,cm);
+ this->pdata_m->notify(repartitionEvent);
+ return true;
+ }
+ inline void sync()
+ {
+ this->pdata_m->sync();
+ }
+ virtual void notify(LayoutData_t &d, const ObserverEvent &event)
+ {
+ ;
+ Observable_t::notify(event);
+ }
+ template <class Ostream>
+ void print(Ostream &ostr) const;
+ template <int Dim1, int Dim2>
+ friend class GridLayoutView;
+ friend class GridLayoutData<Dim>;
+ };
+ template <int Dim, int Dim2>
+ class GridLayoutViewData :
+ public LayoutBaseViewData<Dim, Dim2, GridLayout<Dim2> >,
+ public RefCounted
+ {
+ public:
+ typedef GridLayout<Dim2> Layout_t;
+ typedef GridLayoutView<Dim, Dim2> ViewLayout_t;
+ typedef Interval<Dim> Domain_t;
+ typedef Range<Dim2> BaseDomain_t;
+ typedef int Context_t;
+ typedef Unique::Value_t ID_t;
+ typedef typename Layout_t::Domain_t AllocatedDomain_t;
+ typedef ViewIndexer<Dim,Dim2> Indexer_t;
+ typedef Node<Domain_t,AllocatedDomain_t> Value_t;
+ typedef std::vector<Value_t *> List_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ typedef GridLayoutViewData<Dim,Dim2> LayoutData_t;
+ enum { dim = Dim };
+ enum { dim2 = Dim2 };
+ GridLayoutViewData() { }
+ template <class DT>
+ inline GridLayoutViewData(const Layout_t &layout, const Domain<Dim, DT> &dom)
+ : LayoutBaseViewData<Dim,Dim2,GridLayout<Dim2> >(layout,dom)
+ {
+ }
+ template <class DT>
+ inline GridLayoutViewData(const Layout_t &layout,
+ const SliceDomain<DT> &dom)
+ :LayoutBaseViewData<Dim,Dim2,GridLayout<Dim2> >(layout,dom)
+ {
+ }
+ template <class DT>
+ GridLayoutViewData(const ViewLayout_t &layout,
+ const Domain<Dim, DT> &dom)
+ : LayoutBaseViewData<Dim,Dim2,GridLayout<Dim2> >(
+ layout.pdata_m->layout_m,
+ layout,
+ layout.pdata_m->indexer_m,
+ dom,
+ layout.internalGuards(),
+ layout.externalGuards())
+ {
+ }
+ template <int OrigDim, class DT>
+ GridLayoutViewData(const GridLayoutView<OrigDim, Dim2> &layout,
+ const SliceDomain<DT> &dom)
+ : LayoutBaseViewData<Dim,Dim2,GridLayout<Dim2> >(
+ layout.pdata_m->layout_m,
+ layout,
+ Indexer_t(layout.pdata_m->indexer_m,dom),
+ dom)
+ {
+ }
+ ~GridLayoutViewData()
+ {
+ typename List_t::iterator a;
+ for (a = this->all_m.begin(); a != this->all_m.end(); ++a)
+ delete (*a);
+ }
+ };
+ template <int Dim, int Dim2>
+ class GridLayoutView
+ : public LayoutBaseView<Dim, Dim2, GridLayoutViewData<Dim,Dim2> >
+ {
+ public:
+ enum { dimensions = Dim };
+ enum { dim = Dim };
+ enum { dim2 = Dim2 };
+ typedef GridLayoutViewData<Dim, Dim2> LayoutData_t;
+ typedef typename LayoutData_t::Domain_t Domain_t;
+ typedef typename LayoutData_t::BaseDomain_t BaseDomain_t;
+ typedef typename LayoutData_t::Context_t Context_t;
+ typedef typename LayoutData_t::ID_t ID_t;
+ typedef typename LayoutData_t::Layout_t Layout_t;
+ typedef typename LayoutData_t::AllocatedDomain_t AllocatedDomain_t;
+ typedef typename LayoutData_t::Value_t Value_t;
+ typedef typename LayoutData_t::List_t List_t;
+ typedef typename LayoutData_t::Indexer_t Indexer_t;
+ typedef typename LayoutData_t::GuardLayers_t GuardLayers_t;
+ typedef GridLayoutView<Dim, Dim2> This_t;
+ typedef GridLayoutView<Dim, Dim2> ViewLayout_t;
+ typedef LayoutBaseView<Dim, Dim2, LayoutData_t> Base_t;
+ typedef DerefIterator<Value_t> iterator;
+ typedef ConstDerefIterator<Value_t> const_iterator;
+ GridLayoutView()
+ : Base_t(new LayoutData_t())
+ { }
+ template <class DT>
+ GridLayoutView(const Layout_t &layout, const Domain<Dim2, DT> &dom)
+ : LayoutBaseView<Dim,Dim2,GridLayoutViewData<Dim,Dim2> >
+ (new GridLayoutViewData<Dim,Dim2>(layout,dom))
+ { }
+ template <class DT>
+ GridLayoutView(const Layout_t &layout, const SliceDomain<DT> &dom)
+ : LayoutBaseView<Dim,Dim2,GridLayoutViewData<Dim,Dim2> >
+ (new GridLayoutViewData<Dim,Dim2>(layout,dom))
+ { }
+ template <class DT>
+ GridLayoutView(const ViewLayout_t &layout, const Domain<Dim, DT> &dom)
+ : LayoutBaseView<Dim,Dim2,GridLayoutViewData<Dim,Dim2> >
+ (new GridLayoutViewData<Dim,Dim2>(layout,dom))
+ { }
+ template <int OldViewDim, class DT>
+ GridLayoutView(const GridLayoutView<OldViewDim, Dim2> &layout,
+ const SliceDomain<DT> &dom)
+ : LayoutBaseView<Dim,Dim2,GridLayoutViewData<Dim,Dim2> >
+ (new GridLayoutViewData<Dim,Dim2>(layout,dom))
+ { }
+ inline GridLayoutView(const This_t &model)
+ : LayoutBaseView<Dim,Dim2,GridLayoutViewData<Dim,Dim2> >(model.pdata_m)
+ { }
+ inline This_t &operator=(const This_t &model)
+ {
+ if (this != &model)
+ {
+ this->pdata_m = model.pdata_m;
+ }
+ return *this;
+ }
+ inline ~GridLayoutView()
+ { }
+ template <class Ostream>
+ void print(Ostream &ostr) const;
+ template <int OtherDim, int OtherDim2>
+ friend class GridLayoutView;
+ template <int OtherDim, int OtherDim2>
+ friend class GridLayoutViewData;
+ void computeSubdomains() const { this->pdata_m->computeSubdomains(); }
+ };
+ template <int Dim>
+ struct NewDomain1<GridLayout<Dim> >
+ {
+ typedef GridLayout<Dim> &Type_t;
+ inline static Type_t combine(const GridLayout<Dim> &a)
+ {
+ return const_cast<Type_t>(a);
+ }
+ };
+ template <int Dim, int Dim2>
+ struct NewDomain1<GridLayoutView<Dim, Dim2> >
+ {
+ typedef GridLayoutView<Dim, Dim2> &Type_t;
+ inline static Type_t combine(const GridLayoutView<Dim, Dim2> &a)
+ {
+ return const_cast<Type_t>(a);
+ }
+ };
+ template <int Dim>
+ std::ostream &operator<<(std::ostream &ostr,
+ const GridLayout<Dim> &layout)
+ {
+ layout.print(ostr);
+ return ostr;
+ }
+ template <int Dim, int Dim2>
+ std::ostream &operator<<(std::ostream &ostr,
+ const GridLayoutView<Dim, Dim2> &layout)
+ {
+ layout.print(ostr);
+ return ostr;
+ }
+ template<int Dim>
+ GridLayoutData<Dim>::GridLayoutData()
+ : LayoutBaseData<Dim>(false,false,
+ GuardLayers_t(0),GuardLayers_t(0),
+ Interval<Dim>(),Interval<Dim>()),
+ Observable<GridLayoutData>(*this)
+ {
+ for (int d=0; d < Dim; ++d)
+ this->firsti_m[d] = this->firste_m[d] = blockStrides_m[d] = 0;
+ }
+ template<int Dim>
+ template<class Partitioner>
+ GridLayoutData<Dim>::GridLayoutData(const Grid<Dim> &gdom,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> &cmap)
+ : LayoutBaseData<Dim>(false,false,
+ GuardLayers_t(0),GuardLayers_t(0),
+ Interval<Dim>(), Interval<Dim>()),
+ Observable<GridLayoutData>(*this)
+ {
+ initialize(gdom, gpar, cmap);
+ }
+ template<int Dim>
+ template<class Partitioner>
+ GridLayoutData<Dim>::GridLayoutData(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> &cmap)
+ : LayoutBaseData<Dim>(false,false,
+ GuardLayers_t(0),GuardLayers_t(0),
+ gdom,gdom),
+ Observable<GridLayoutData>(*this)
+ {
+ for (int d=0; d < Dim; ++d)
+ this->firsti_m[d] = this->firste_m[d] = blockStrides_m[d] = 0;
+ initialize(gdom, gpar, cmap);
+ }
+ template<int Dim>
+ GridLayoutData<Dim>::~GridLayoutData()
+ {
+ for (typename List_t::iterator a = this->all_m.begin(); a != this->all_m.end(); ++a)
+ delete (*a);
+ }
+ template<int Dim>
+ template <class Partitioner>
+ inline void GridLayoutData<Dim>::initialize(const Grid<Dim> &gdom,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> &cmap)
+ {
+ Domain_t idom = Pooma::NoInit();
+ for (int d=0; d < Dim; ++d)
+ idom[d] = Interval<1>(gdom[d].first(), gdom[d].last() - 1);
+ initialize(idom, gpar, cmap);
+ }
+ template<int Dim>
+ template<class Partitioner>
+ inline void GridLayoutData<Dim>::initialize(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> &cmap)
+ {
+ int i;
+ PoomaCTAssert<(Partitioner::gridded)>::test();
+ if (this->all_m.size() > 0)
+ {
+ for (i=0; i < this->all_m.size(); ++i)
+ delete this->all_m[i];
+ this->all_m.clear();
+ this->local_m.clear();
+ this->remote_m.clear();
+ }
+ dirtyLayout_m = true;
+ this->domain_m = gdom;
+ this->innerdomain_m = gdom;
+ this->hasInternalGuards_m = (gpar.hasInternalGuards() && gpar.maxSize() > 1);
+ if (this->hasInternalGuards_m)
+ {
+ this->internalGuards_m = gpar.internalGuards();
+ }
+ this->hasExternalGuards_m = (gpar.hasExternalGuards() && ! this->domain_m.empty());
+ if (this->hasExternalGuards_m)
+ {
+ this->externalGuards_m = gpar.externalGuards();
+ GuardLayers<Dim>::addGuardLayers(this->domain_m, this->externalGuards_m);
+ }
+ this->blocks_m = gpar.blocks();
+ for (i=0; i < Dim; ++i)
+ {
+ if (!this->domain_m[i].empty())
+ this->firsti_m[i] = this->domain_m[i].first();
+ blockStrides_m[i] = (i == 0 ? 1 :
+ blockStrides_m[i-1] * this->blocks_m[i-1].first());
+ }
+ gpar.partition(this->innerdomain_m, this->all_m, cmap);
+ typename List_t::iterator start = this->all_m.begin();
+ typename List_t::iterator end = this->all_m.end();
+ for ( ; start!=end ;++start )
+ {
+ if( (*start)->context() == Pooma::context()
+ ||(*start)->context() == -1 )
+ this->local_m.push_back(*start);
+ else
+ this->remote_m.push_back(*start);
+ }
+ calcMaps();
+ calcAllocMaps();
+ calcGCFillList();
+ }
+ template<int Dim>
+ void GridLayoutData<Dim>::initialize(const Domain_t& idom,
+ const List_t& nodes,
+ const Loc<Dim>& blocks,
+ bool hasIG, bool hasEG,
+ const GuardLayers_t& ig,
+ const GuardLayers_t& eg)
+ {
+ int i;
+ if (this->all_m.size() > 0)
+ {
+ for (i=0; i < this->all_m.size(); ++i)
+ delete this->all_m[i];
+ this->all_m.clear();
+ this->local_m.clear();
+ this->remote_m.clear();
+ }
+ dirtyLayout_m = true;
+ this->domain_m = idom;
+ this->innerdomain_m = idom;
+ this->hasInternalGuards_m = hasIG;
+ if (this->hasInternalGuards_m)
+ {
+ this->internalGuards_m = ig;
+ }
+ this->hasExternalGuards_m = (hasEG && ! this->domain_m.empty());
+ if (this->hasExternalGuards_m)
+ {
+ this->externalGuards_m = eg;
+ GuardLayers<Dim>::addGuardLayers(this->domain_m, this->externalGuards_m);
+ }
+ this->blocks_m = blocks;
+ for (i=0; i < Dim; ++i)
+ {
+ if (!this->domain_m[i].empty())
+ this->firsti_m[i] = this->domain_m[i].first();
+ blockStrides_m[i] = (i == 0 ? 1 :
+ blockStrides_m[i-1] * this->blocks_m[i-1].first());
+ }
+ this->all_m= nodes;
+ typename List_t::iterator start = this->all_m.begin();
+ typename List_t::iterator end = this->all_m.end();
+ for ( ; start!=end ;++start )
+ {
+ if( (*start)->context() == Pooma::context() ||
+ (*start)->context() == -1 )
+ this->local_m.push_back(*start);
+ else
+ this->remote_m.push_back(*start);
+ }
+ calcMaps();
+ calcAllocMaps();
+ calcGCFillList();
+ }
+ template<int Dim>
+ void GridLayoutData<Dim>::sync()
+ {
+ ;
+ if (!this->initialized() || !dirty())
+ return;
+ calcDomains();
+ calcMaps();
+ this->notify(SyncEvent());
+ }
+ template<int Dim>
+ void GridLayoutData<Dim>::calcGCFillList()
+ {
+ int d;
+ if (!this->initialized() || !this->hasInternalGuards_m)
+ return;
+ this->gcFillList_m.clear();
+ int numPatches = this->all_m.size();
+ this->gcFillList_m.reserve(2*Dim*this->local_m.size());
+ ;
+ Interval<Dim> grid;
+ for (d=0; d < Dim; ++d)
+ grid[d] = Interval<1>(this->blocks_m[d].first() + 1);
+ for (d=0; d < Dim; ++d)
+ {
+ if (this->internalGuards_m.lower(d) > 0)
+ {
+ typename Interval<Dim>::blockIterator start = grid.beginBlock();
+ typename Interval<Dim>::blockIterator end = grid.endBlock();
+ for (; start != end; ++start)
+ {
+ int sourceID = start.index();
+ Loc<Dim> tmp = start.point();
+ tmp[d] += 1;
+ if (!(tmp[d] >= this->blocks_m[d] || tmp[d].first() < 0))
+ {
+ int destID = blockIndex(tmp);
+ if (!(this->all_m[sourceID]->domain().empty() ||
+ this->all_m[destID]->domain().empty()))
+ {
+ ;
+ Domain_t gcdom(this->all_m[sourceID]->allocated());
+ int max = this->all_m[sourceID]->domain()[d].last();
+ int min = max - this->internalGuards_m.lower(d) + 1;
+ gcdom[d] = Interval<1>(min, max);
+ this->gcFillList_m.push_back(GCFillInfo_t(gcdom, sourceID, destID, d*2));
+ }
+ }
+ }
+ }
+ if (this->internalGuards_m.upper(d) > 0)
+ {
+ typename Interval<Dim>::blockIterator start = grid.beginBlock();
+ typename Interval<Dim>::blockIterator end = grid.endBlock();
+ for (; start != end; ++start)
+ {
+ int sourceID = start.index();
+ Loc<Dim> tmp = start.point();
+ tmp[d] -= 1;
+ if (!(tmp[d] >= this->blocks_m[d] || tmp[d].first() < 0))
+ {
+ int destID = blockIndex(tmp);
+ if (!(this->all_m[sourceID]->domain().empty() ||
+ this->all_m[destID]->domain().empty()))
+ {
+ ;
+ Domain_t gcdom(this->all_m[sourceID]->allocated());
+ int min = this->all_m[sourceID]->domain()[d].first();
+ int max = min + this->internalGuards_m.upper(d) - 1;
+ gcdom[d] = Interval<1>(min, max);
+ this->gcFillList_m.push_back(GCFillInfo_t(gcdom, sourceID, destID, d*2+1));
+ }
+ }
+ }
+ }
+ }
+ }
+ template<int Dim>
+ void GridLayoutData<Dim>::calcDomains()
+ {
+ if (!this->initialized() || !dirty())
+ return;
+ ;
+ ;
+ CreateSize_t sizes = this->firsti_m[0];
+ bool allempty = true;
+ for (int i=0; i < this->all_m.size(); ++i)
+ {
+ Domain_t dom = this->all_m[i]->domain();
+ if (!dom[0].empty())
+ {
+ dom[0] = Interval<1>(sizes, sizes + dom[0].length() - 1);
+ sizes += dom[0].length();
+ allempty = false;
+ }
+ this->all_m[i]->setDomain(dom);
+ this->all_m[i]->setAllocated(dom);
+ }
+ if (allempty)
+ this->domain_m = Domain_t();
+ else
+ this->domain_m = Interval<1>(this->firsti_m[0], sizes - 1);
+ this->innerdomain_m = this->domain_m;
+ dirtyLayout_m = false;
+ }
+ template<int Dim>
+ void GridLayoutData<Dim>::calcMaps() const
+ {
+ int i, j;
+ if (!this->initialized() || !dirty())
+ return;
+ for (i=0; i < Dim; ++i)
+ {
+ map_m[i].zap();
+ if (this->domain_m[i].empty())
+ continue;
+ Loc<Dim> blockLoc(0);
+ map_m[i].initialize(Interval<1>(this->domain_m[i].first() -
+ this->externalGuards_m.lower(i),
+ this->domain_m[i].last() +
+ this->externalGuards_m.upper(i)));
+ int b = this->blocks_m[i].first();
+ for (j=0; j < b; ++j)
+ {
+ blockLoc[i] = Loc<1>(j);
+ int k = blockIndex(blockLoc);
+ Interval<1> blockDom = this->all_m[k]->domain()[i];
+ if (!blockDom.empty())
+ {
+ int lo = (j == 0 ? this->externalGuards_m.lower(i) : 0);
+ int hi = (j == (b - 1) ? this->externalGuards_m.upper(i) : 0);
+ Interval<1> mval(blockDom.first() - lo, blockDom.last() + hi);
+ typename DomainMap<Interval<1>,int>::Value_t val(mval, j);
+ map_m[i].insert(val);
+ }
+ }
+ map_m[i].update();
+ }
+ }
+ template<int Dim>
+ void GridLayoutData<Dim>::calcAllocMaps() const
+ {
+ int i, j;
+ if (!this->initialized() || !dirty())
+ return;
+ for (i=0; i < Dim; ++i)
+ {
+ mapAloc_m[i].zap();
+ if (this->domain_m[i].empty())
+ continue;
+ Loc<Dim> blockLoc(0);
+ mapAloc_m[i].initialize(Interval<1>(this->domain_m[i].first() -
+ this->externalGuards_m.lower(i),
+ this->domain_m[i].last() +
+ this->externalGuards_m.upper(i)));
+ int b = this->blocks_m[i].first();
+ for (j=0; j < b; ++j)
+ {
+ blockLoc[i] = Loc<1>(j);
+ int k = blockIndex(blockLoc);
+ Interval<1> blockDom = this->all_m[k]->domain()[i];
+ if (!blockDom.empty())
+ {
+ int lo = (j==0 ?
+ this->externalGuards_m.lower(i) :
+ this->internalGuards_m.lower(i));
+ int hi = (j == (b - 1) ?
+ this->externalGuards_m.upper(i) :
+ this->internalGuards_m.upper(i));
+ Interval<1> ival(blockDom.first() - lo, blockDom.last() + hi);
+ typename DomainMap<Interval<1>,int>::Value_t valAl(ival, j);
+ mapAloc_m[i].insert(valAl);
+ }
+ }
+ mapAloc_m[i].update();
+ }
+ }
+ template<int Dim>
+ int GridLayoutData<Dim>::globalID(const Loc<Dim> &loc) const
+ {
+ ;
+ Loc<Dim> point;
+ for (int i=0; i < Dim; ++i)
+ {
+ DomainMapTouchIterator<Interval<1>,int> dmti =
+ (map_m[i].touch(Interval<1>(loc[i]))).first;
+ DomainMapTouchIterator<Interval<1>,int> baditerator;
+ ;
+ point[i] = *dmti;
+ }
+ return blockIndex(point);
+ }
+ template <int Dim>
+ int GridLayoutData<Dim>::globalID(int i0) const
+ {
+ ;
+ Loc<Dim> loc;
+ loc[0] = i0;
+ return globalID(loc);
+ }
+ template <int Dim>
+ int GridLayoutData<Dim>::globalID(int i0, int i1) const
+ {
+ ;
+ Loc<Dim> loc;
+ loc[0] = i0;
+ loc[1] = i1;
+ return globalID(loc);
+ }
+ template <int Dim>
+ int GridLayoutData<Dim>::globalID(int i0, int i1, int i2) const
+ {
+ ;
+ Loc<Dim> loc;
+ loc[0] = i0;
+ loc[1] = i1;
+ loc[2] = i2;
+ return globalID(loc);
+ }
+ template <int Dim>
+ int GridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3) const
+ {
+ ;
+ Loc<Dim> loc;
+ loc[0] = i0;
+ loc[1] = i1;
+ loc[2] = i2;
+ loc[3] = i3;
+ return globalID(loc);
+ }
+ template <int Dim>
+ int GridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
+ int i4) const
+ {
+ ;
+ Loc<Dim> loc;
+ loc[0] = i0;
+ loc[1] = i1;
+ loc[2] = i2;
+ loc[3] = i3;
+ loc[4] = i4;
+ return globalID(loc);
+ }
+ template <int Dim>
+ int GridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
+ int i4, int i5) const
+ {
+ ;
+ Loc<Dim> loc;
+ loc[0] = i0;
+ loc[1] = i1;
+ loc[2] = i2;
+ loc[3] = i3;
+ loc[4] = i4;
+ loc[5] = i5;
+ return globalID(loc);
+ }
+ template <int Dim>
+ int GridLayoutData<Dim>::globalID(int i0, int i1, int i2, int i3,
+ int i4, int i5, int i6) const
+ {
+ ;
+ Loc<Dim> loc;
+ loc[0] = i0;
+ loc[1] = i1;
+ loc[2] = i2;
+ loc[3] = i3;
+ loc[4] = i4;
+ loc[5] = i5;
+ loc[6] = i6;
+ return globalID(loc);
+ }
+ template <int Dim>
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int GridLayoutData<Dim>::touches(const OtherDomain &fulld, OutIter o,
+ const ConstructTag &ctag) const
+ {
+ int i;
+ ;
+ typedef typename
+ IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
+ OutDomain_t d = intersect(this->domain_m, fulld);
+ if (d.empty())
+ return 0;
+ OutDomain_t outDomain = Pooma::NoInit();
+ typedef Node<OutDomain_t,Domain_t> OutNode_t;
+ int hiAxisIndex[Dim];
+ int loAxisIndex[Dim];
+ Loc<Dim> curnode;
+ for (i=0;i < Dim; ++i)
+ {
+ loAxisIndex[i] =
+ *((map_m[i].touch(Interval<1>(d[i].first(),d[i].first()))).first);
+ ;
+ hiAxisIndex[i] =
+ *((map_m[i].touch(Interval<1>(d[i].last(),d[i].last() ))).first);
+ ;
+ if(loAxisIndex[i]>hiAxisIndex[i])
+ {
+ int tmp = hiAxisIndex[i];
+ hiAxisIndex[i] = loAxisIndex[i];
+ loAxisIndex[i] = tmp;
+ }
+ curnode[i] = loAxisIndex[i];
+ }
+ int count=0;
+ while(1)
+ {
+ int nodeListIndex = blockIndex(curnode);
+ if (!this->all_m[nodeListIndex]->domain().empty())
+ {
+ outDomain = intersect(fulld,this->all_m[nodeListIndex]->domain());
+ ;
+ *o = touchesConstruct(outDomain,
+ this->all_m[nodeListIndex]->allocated(),
+ this->all_m[nodeListIndex]->affinity(),
+ this->all_m[nodeListIndex]->context(),
+ this->all_m[nodeListIndex]->globalID(),
+ this->all_m[nodeListIndex]->localID(),
+ ctag);
+ ++count;
+ }
+ curnode[0] += 1;
+ for (i=0; i < Dim; ++i)
+ {
+ if (curnode[i] == (hiAxisIndex[i]+1))
+ {
+ if (i==(Dim-1))
+ break;
+ curnode[i] = loAxisIndex[i];
+ curnode[i+1] += 1;
+ }
+ }
+ if (curnode[Dim-1] == (hiAxisIndex[Dim-1]+1))
+ break;
+ }
+ return count;
+ }
+ template <int Dim>
+ template <class OtherDomain, class OutIter, class ConstructTag>
+ int GridLayoutData<Dim>::touchesAlloc(const OtherDomain &fulld, OutIter o,
+ const ConstructTag &ctag) const
+ {
+ int i;
+ ;
+ typedef typename
+ IntersectReturnType<Domain_t,OtherDomain>::Type_t OutDomain_t;
+ OutDomain_t d = intersect(this->domain_m, fulld);
+ if (d.empty())
+ return 0;
+ OutDomain_t outDomain = Pooma::NoInit();
+ typedef Node<OutDomain_t,Domain_t> OutNode_t;
+ int hiAxisIndex[Dim];
+ int loAxisIndex[Dim];
+ Loc<Dim> curnode;
+ for (i=0; i < Dim; ++i)
+ {
+ loAxisIndex[i] =
+ *((mapAloc_m[i].touch(Interval<1>(d[i].first(),d[i].first()))).first);
+ ;
+ hiAxisIndex[i] =
+ *((mapAloc_m[i].touch(Interval<1>(d[i].last(),d[i].last()))).first);
+ ;
+ if(loAxisIndex[i]>hiAxisIndex[i])
+ {
+ int tmp = hiAxisIndex[i];
+ hiAxisIndex[i] = loAxisIndex[i];
+ loAxisIndex[i] = tmp;
+ }
+ curnode[i] = loAxisIndex[i];
+ }
+ int count=0;
+ while(1)
+ {
+ int nodeListIndex = blockIndex(curnode);
+ if (!this->all_m[nodeListIndex]->domain().empty())
+ {
+ outDomain = intersect(fulld,this->all_m[nodeListIndex]->allocated());
+ ;
+ *o = touchesConstruct(outDomain,
+ this->all_m[nodeListIndex]->allocated(),
+ this->all_m[nodeListIndex]->affinity(),
+ this->all_m[nodeListIndex]->context(),
+ this->all_m[nodeListIndex]->globalID(),
+ this->all_m[nodeListIndex]->localID(),
+ ctag);
+ ++count;
+ }
+ curnode[0] += 1;
+ for (i=0; i < Dim; ++i)
+ {
+ if (curnode[i] == (hiAxisIndex[i]+1))
+ {
+ if (i == (Dim-1))
+ break;
+ curnode[i] = loAxisIndex[i];
+ curnode[i+1] += 1;
+ }
+ }
+ if (curnode[Dim-1] == (hiAxisIndex[Dim-1]+1))
+ break;
+ }
+ return count;
+ }
+ template<int Dim>
+ template<class Out>
+ void GridLayoutData<Dim>::print(Out & ostr)
+ {
+ int i;
+ ostr << " hasInternalGuards_m, hasExternalGuards_m "
+ << this->hasInternalGuards_m << ' ' << this->hasExternalGuards_m
+ << "\n internalGuards_m ";
+ for (i=0; i<Dim; ++i)
+ ostr << this->internalGuards_m.upper(i) << '-'
+ << this->internalGuards_m.lower(i) << ' ';
+ ostr << "\n externalGuards_m ";
+ for (i=0; i<Dim; ++i)
+ ostr << this->externalGuards_m.upper(i) << '-'
+ << this->externalGuards_m.lower(i) << ' ';
+ ostr << '\n';
+ FillIterator_t gstart = this->gcFillList_m.begin();
+ FillIterator_t gend = this->gcFillList_m.end();
+ ostr << " this->gcFillList_m\n";
+ for(; gstart!=gend; ++gstart)
+ ostr << " "
+ << gstart->domain_m << ' '
+ << gstart->ownedID_m << ' '
+ << gstart->guardID_m << '\n';
+ ostr << std::flush;
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout()
+ : LayoutBase<Dim,GridLayoutData<Dim> >(new LayoutData_t()),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Domain_t &gdom,const DistributedTag & )
+ : LayoutBase<Dim,GridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ GridPartition<Dim>(Loc<Dim>(1)),
+ DistributedMapper<Dim>(GridPartition<Dim>(Loc<Dim>(1))))),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Domain_t &gdom,const ReplicatedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ GridPartition<Dim>(Loc<Dim>(1)),
+ LocalMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Domain_t &gdom,
+ const GuardLayers_t &gcs,
+ const DistributedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ GridPartition<Dim>(Loc<Dim>(1),gcs),
+ DistributedMapper<Dim>(
+ GridPartition<Dim>(Loc<Dim>(1),gcs)))),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Domain_t &gdom,
+ const GuardLayers_t &gcs,
+ const ReplicatedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ GridPartition<Dim>(Loc<Dim>(1),gcs),
+ LocalMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const DistributedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >((LayoutData_t*) 0),
+ Observable<This_t>(*this)
+ {
+ if (!gdom.empty())
+ this->pdata_m =
+ new LayoutData_t( gdom,
+ GridPartition<Dim>(makeRGrid(gdom,blocks)),
+ DistributedMapper<Dim>(GridPartition<Dim>(makeRGrid(gdom,blocks)))
+ );
+ else
+ this->pdata_m = new LayoutData_t( gdom,
+ GridPartition<Dim>(blocks),
+ DistributedMapper<Dim>(GridPartition<Dim>(blocks))
+ );
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const ReplicatedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >((LayoutData_t*) 0),
+ Observable<This_t>(*this)
+ {
+ if (!gdom.empty())
+ this->pdata_m = new LayoutData_t( gdom,
+ GridPartition<Dim>(makeRGrid(gdom,blocks)),
+ LocalMapper<Dim>());
+ else
+ this->pdata_m = new LayoutData_t( gdom,
+ GridPartition<Dim>(blocks),
+ LocalMapper<Dim>());
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &gcs,
+ const DistributedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >((LayoutData_t*) 0),
+ Observable<This_t>(*this)
+ {
+ if (!gdom.empty())
+ this->pdata_m = new LayoutData_t( gdom,
+ GridPartition<Dim>(makeRGrid(gdom,blocks),gcs),
+ DistributedMapper<Dim>(GridPartition<Dim>(makeRGrid(gdom,blocks),gcs)));
+ else
+ this->pdata_m = new LayoutData_t( gdom,
+ GridPartition<Dim>(blocks,gcs),
+ DistributedMapper<Dim>(GridPartition<Dim>(blocks,gcs)));
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &gcs,
+ const ReplicatedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >((LayoutData_t*) 0),
+ Observable<This_t>(*this)
+ {
+ if (!gdom.empty())
+ this->pdata_m = new LayoutData_t(gdom,
+ GridPartition<Dim>(makeRGrid(gdom,blocks),gcs),
+ LocalMapper<Dim>());
+ else
+ this->pdata_m = new LayoutData_t(gdom,
+ GridPartition<Dim>(blocks,gcs),
+ LocalMapper<Dim>());
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &igcs,
+ const GuardLayers_t &egcs,
+ const DistributedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >((LayoutData_t*) 0),
+ Observable<This_t>(*this)
+ {
+ if (!gdom.empty())
+ this->pdata_m = new LayoutData_t( gdom,
+ GridPartition<Dim>(makeRGrid(gdom,blocks),igcs,egcs),
+ DistributedMapper<Dim>(
+ GridPartition<Dim>(makeRGrid(gdom,blocks),igcs,egcs)));
+ else
+ this->pdata_m = new LayoutData_t( gdom,
+ GridPartition<Dim>(blocks,igcs,egcs),
+ DistributedMapper<Dim>(GridPartition<Dim>(blocks,igcs,egcs)));
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &igcs,
+ const GuardLayers_t &egcs,
+ const ReplicatedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >((LayoutData_t*) 0),
+ Observable<This_t>(*this)
+ {
+ if (!gdom.empty())
+ this->pdata_m = new LayoutData_t(
+ gdom,
+ GridPartition<Dim>(makeRGrid(gdom,blocks),igcs,egcs),
+ LocalMapper<Dim>() );
+ else
+ this->pdata_m = new LayoutData_t( gdom,
+ GridPartition<Dim>(blocks,igcs,egcs),
+ LocalMapper<Dim>() );
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Grid<Dim> &grid,
+ const DistributedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >(
+ new LayoutData_t( grid,
+ GridPartition<Dim>(grid),
+ DistributedMapper<Dim>(GridPartition<Dim>(grid)))),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Grid<Dim> &grid,
+ const ReplicatedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >(
+ new LayoutData_t( grid,
+ GridPartition<Dim>(grid),
+ LocalMapper<Dim>())),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Grid<Dim> &grid,
+ const GuardLayers_t &gcs,
+ const DistributedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >
+ ( new LayoutData_t( grid,
+ GridPartition<Dim>(grid,gcs),
+ DistributedMapper<Dim>(GridPartition<Dim>(grid,gcs) )) ),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Grid<Dim> &grid,
+ const GuardLayers_t &gcs,
+ const ReplicatedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >
+ ( new LayoutData_t( grid,
+ GridPartition<Dim>(grid,gcs),
+ LocalMapper<Dim>()) ),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Grid<Dim> &grid,
+ const GuardLayers_t &igcs,
+ const GuardLayers_t &egcs,
+ const DistributedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >
+ (new LayoutData_t(grid,
+ GridPartition<Dim>(grid,igcs,egcs),
+ DistributedMapper<Dim>(GridPartition<Dim>(grid,igcs,egcs)))),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const Grid<Dim> &grid,
+ const GuardLayers_t &igcs,
+ const GuardLayers_t &egcs,
+ const ReplicatedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >
+ (new LayoutData_t( grid,
+ GridPartition<Dim>(grid,igcs,egcs),
+ LocalMapper<Dim>() ) ),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ template <class Partitioner>
+ GridLayout<Dim>::GridLayout(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const DistributedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ gpar,
+ DistributedMapper<Dim>(gpar)) ),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ template <class Partitioner>
+ GridLayout<Dim>::GridLayout(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const ReplicatedTag &)
+ : LayoutBase<Dim,GridLayoutData<Dim> >
+ (new LayoutData_t(gdom,
+ gpar,
+ LocalMapper<Dim>()) ),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ template <class Partitioner>
+ GridLayout<Dim>::GridLayout(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> &cmap)
+ : LayoutBase<Dim,GridLayoutData<Dim> >(new LayoutData_t(gdom, gpar, cmap) ),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim>::GridLayout(const This_t &model)
+ : LayoutBase<Dim,GridLayoutData<Dim> >(model.pdata_m),
+ Observable<This_t>(*this)
+ {
+ this->pdata_m->attach(*this);
+ }
+ template <int Dim>
+ GridLayout<Dim> &GridLayout<Dim>::operator=(const This_t &model)
+ {
+ if (this != &model)
+ {
+ this->pdata_m->detach(*this);
+ this->pdata_m = model.pdata_m;
+ this->pdata_m->attach(*this);
+ }
+ return *this;
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Domain_t &gdom,
+ const DistributedTag &)
+ {
+ this->pdata_m->initialize( gdom,
+ GridPartition<Dim>(),
+ DistributedMapper<Dim>(GridPartition<Dim>()) );
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Domain_t &gdom,
+ const GuardLayers_t &gcs,
+ const DistributedTag &)
+ {
+ this->pdata_m->initialize( gdom,
+ GridPartition<Dim>(gcs),
+ DistributedMapper<Dim>(GridPartition<Dim>(gcs)) );
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const DistributedTag &)
+ {
+ if (!gdom.empty())
+ this->pdata_m->initialize(
+ gdom,
+ GridPartition<Dim>(makeRGrid(gdom,blocks)),
+ DistributedMapper<Dim>(GridPartition<Dim>(makeRGrid(gdom,blocks))));
+ else
+ this->pdata_m->initialize( gdom,
+ GridPartition<Dim>(blocks),
+ DistributedMapper<Dim>(GridPartition<Dim>(blocks)) );
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &gcs,
+ const DistributedTag &)
+ {
+ if (!gdom.empty())
+ this->pdata_m->initialize(
+ gdom,
+ GridPartition<Dim>(makeRGrid(gdom,blocks),gcs),
+ DistributedMapper<Dim>(
+ GridPartition<Dim>(makeRGrid(gdom,blocks),gcs)));
+ else
+ this->pdata_m->initialize(
+ gdom,
+ GridPartition<Dim>(blocks,gcs),
+ DistributedMapper<Dim>(
+ GridPartition<Dim>(blocks,gcs)) );
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &igcs,
+ const GuardLayers_t &egcs,
+ const DistributedTag &)
+ {
+ if (!gdom.empty())
+ this->pdata_m->initialize(
+ gdom,
+ GridPartition<Dim>(makeRGrid(gdom,blocks),igcs,egcs),
+ DistributedMapper<Dim>(
+ GridPartition<Dim>(makeRGrid(gdom,blocks),igcs,egcs)));
+ else
+ this->pdata_m->initialize(
+ gdom,
+ GridPartition<Dim>(blocks,igcs,egcs),
+ DistributedMapper<Dim>(
+ GridPartition<Dim>(blocks,igcs,egcs)));
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Grid<Dim> &grid,
+ const DistributedTag &)
+ {
+ this->pdata_m->initialize( grid,
+ GridPartition<Dim>(grid),
+ DistributedMapper<Dim>(GridPartition<Dim>(grid)));
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Grid<Dim> &grid,
+ const GuardLayers_t &gcs,
+ const DistributedTag &)
+ {
+ this->pdata_m->initialize( grid,
+ GridPartition<Dim>(grid,gcs),
+ DistributedMapper<Dim>(GridPartition<Dim>(grid,gcs)) );
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Grid<Dim> &grid,
+ const GuardLayers_t &igcs,
+ const GuardLayers_t &egcs,
+ const DistributedTag &)
+ {
+ this->pdata_m->initialize(
+ grid,
+ GridPartition<Dim>(grid,igcs,egcs),
+ DistributedMapper<Dim>(
+ GridPartition<Dim>(grid,igcs,egcs)) );
+ }
+ template <int Dim>
+ template <class Partitioner>
+ void GridLayout<Dim>::initialize(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const DistributedTag &)
+ {
+ this->pdata_m->initialize(gdom,
+ gpar,
+ DistributedMapper<Dim>(gpar));
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Domain_t &gdom,
+ const ReplicatedTag &)
+ {
+ this->pdata_m->initialize( gdom, GridPartition<Dim>(),LocalMapper<Dim>() );
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Domain_t &gdom,
+ const GuardLayers_t &gcs,
+ const ReplicatedTag &)
+ {
+ this->pdata_m->initialize( gdom, GridPartition<Dim>(gcs),LocalMapper<Dim>() );
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const ReplicatedTag &)
+ {
+ if (!gdom.empty())
+ this->pdata_m->initialize(
+ gdom,
+ GridPartition<Dim>(makeRGrid(gdom,blocks)),
+ LocalMapper<Dim>() );
+ else
+ this->pdata_m->initialize(
+ gdom,
+ GridPartition<Dim>(blocks),
+ LocalMapper<Dim>() );
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &gcs,
+ const ReplicatedTag &)
+ {
+ if (!gdom.empty())
+ this->pdata_m->initialize( gdom,
+ GridPartition<Dim>(makeRGrid(gdom,blocks),gcs),
+ LocalMapper<Dim>() );
+ else
+ this->pdata_m->initialize( gdom,
+ GridPartition<Dim>(blocks,gcs),
+ LocalMapper<Dim>() );
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Domain_t &gdom,
+ const Loc<Dim> &blocks,
+ const GuardLayers_t &igcs,
+ const GuardLayers_t &egcs,
+ const ReplicatedTag &)
+ {
+ if (!gdom.empty())
+ this->pdata_m->initialize(
+ gdom,
+ GridPartition<Dim>(makeRGrid(gdom,blocks),igcs,egcs),
+ LocalMapper<Dim>() );
+ else
+ this->pdata_m->initialize(
+ gdom,
+ GridPartition<Dim>(blocks,igcs,egcs),
+ LocalMapper<Dim>() );
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Grid<Dim> &grid,
+ const ReplicatedTag &)
+ {
+ this->pdata_m->initialize( grid,
+ GridPartition<Dim>(grid),
+ LocalMapper<Dim>() );
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Grid<Dim> &grid,
+ const GuardLayers_t &gcs,
+ const ReplicatedTag &)
+ {
+ this->pdata_m->initialize(
+ grid,
+ GridPartition<Dim>(grid,gcs),
+ LocalMapper<Dim>() );
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Grid<Dim> &grid,
+ const GuardLayers_t &igcs,
+ const GuardLayers_t &egcs,
+ const ReplicatedTag &)
+ {
+ this->pdata_m->initialize(
+ grid,
+ GridPartition<Dim>(grid,igcs,egcs),
+ LocalMapper<Dim>() );
+ }
+ template <int Dim>
+ template <class Partitioner>
+ void GridLayout<Dim>::initialize(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const ReplicatedTag &)
+ {
+ this->pdata_m->initialize(gdom,
+ gpar,
+ LocalMapper<Dim>());
+ }
+ template <int Dim>
+ void GridLayout<Dim>::initialize(const Domain_t& idom,
+ const List_t& nodes,
+ const Loc<Dim>& blocks,
+ bool hasIG, bool hasEG,
+ const GuardLayers_t& ig,
+ const GuardLayers_t& eg)
+ {
+ this->pdata_m->initialize(idom,nodes,blocks,hasIG,hasEG,ig,eg);
+ }
+ template <int Dim>
+ template <class Partitioner>
+ void GridLayout<Dim>::initialize(const Domain_t &gdom,
+ const Partitioner &gpar,
+ const ContextMapper<Dim> &cmap)
+ {
+ this->pdata_m->initialize(gdom, gpar, cmap);
+ }
+ template <int Dim>
+ template <class Ostream>
+ void GridLayout<Dim>::print(Ostream &ostr) const
+ {
+ ostr << "GridLayout " << this->ID() << " on global domain "
+ << this->domain() << ":" << '\n';
+ ostr << " Total subdomains: " << this->sizeGlobal() << '\n';
+ ostr << " Local subdomains: " << this->sizeLocal() << '\n';
+ ostr << " Remote subdomains: " << this->sizeRemote() << '\n';
+ ostr << " Grid blocks: " << this->blocks() << '\n';
+ typename GridLayout<Dim>::const_iterator a;
+ for (a = this->beginGlobal(); a != this->endGlobal(); ++a)
+ ostr << " Global subdomain = " << *a << '\n';
+ for (a = this->beginLocal(); a != this->endLocal(); ++a)
+ ostr << " Local subdomain = " << *a << '\n';
+ for (a = this->beginRemote(); a != this->endRemote(); ++a)
+ ostr << " Remote subdomain = " << *a << '\n';
+ this->pdata_m->print(ostr);
+ }
+ template<int Dim, int Dim2>
+ template <class Ostream>
+ void GridLayoutView<Dim, Dim2>::print(Ostream &ostr) const
+ {
+ ostr << "GridLayoutView " << this->ID() << " on global domain "
+ << this->domain() << ':' << '\n';
+ ostr << " Base ID: " << this->baseID() << '\n';
+ ostr << " Base domain: " << this->baseDomain() << '\n';
+ ostr << " Total subdomains: " << this->sizeGlobal() << '\n';
+ ostr << " Local subdomains: " << this->sizeLocal() << '\n';
+ ostr << " Remote subdomains: " << this->sizeRemote() << '\n';
+ const_iterator a;
+ for (a = this->beginGlobal(); a != this->endGlobal(); ++a)
+ ostr << " Global subdomain = " << *a << '\n';
+ for (a = this->beginLocal(); a != this->endLocal(); ++a)
+ ostr << " Local subdomain = " << *a << '\n';
+ for (a = this->beginRemote(); a != this->endRemote(); ++a)
+ ostr << " Remote subdomain = " << *a << '\n';
+ }
+ template<int OriginalDim, class ViewedEngineTag>
+ struct ViewEngine
+ {
+ ViewEngine() {};
+ ~ViewEngine() {};
+ };
+ template<int Dim, class T, int OriginalDim, class ViewedEngineTag>
+ class Engine<Dim, T, ViewEngine<OriginalDim, ViewedEngineTag> >
+ {
+ public:
+ typedef ViewEngine<OriginalDim, ViewedEngineTag> Tag_t;
+ typedef Engine<Dim, T, Tag_t> This_t;
+ typedef This_t Engine_t;
+ typedef Engine<OriginalDim, T, ViewedEngineTag> ViewedEngine_t;
+ typedef ViewIndexer<Dim, OriginalDim> Indexer_t;
+ typedef Interval<Dim> Domain_t;
+ typedef DomainLayout<Dim> Layout_t;
+ typedef T Element_t;
+ typedef ErrorType ElementRef_t;
+ enum { dimensions = Dim };
+ enum { hasDataObject = ViewedEngine_t::hasDataObject };
+ enum { dynamic = false };
+ enum { zeroBased = true };
+ enum { multiPatch = ViewedEngine_t::multiPatch };
+ Engine()
+ : eng_m()
+ {
+ }
+ template<class DT>
+ Engine(const Engine<Dim, T, ViewedEngineTag> &e, const Domain<Dim, DT> &dom)
+ : eng_m(e), indexer_m(dom)
+ {
+ PoomaCTAssert<(OriginalDim == Dim)>::test();
+ }
+ template<class DT>
+ Engine(const Engine<OriginalDim, T, ViewedEngineTag> &e,
+ const SliceDomain<DT> &dom)
+ : eng_m(e), indexer_m(dom)
+ {
+ PoomaCTAssert<(DT::sliceDimensions == Dim)>::test();
+ PoomaCTAssert<(DT::dimensions == OriginalDim)>::test();
+ }
+ template<class Domain>
+ Engine(const Engine<Dim, T, ViewedEngineTag> &e, const Node<Domain> &node)
+ : eng_m(e), indexer_m(node.domain())
+ {
+ PoomaCTAssert<(Domain::dimensions == Dim)>::test();
+ }
+ Engine(const Engine<Dim, T, ViewedEngineTag> &e, const INode<Dim> &inode)
+ : eng_m(e), indexer_m(inode.domain())
+ { }
+ template<class DT>
+ Engine(const Engine<Dim, T, ViewEngine<OriginalDim, ViewedEngineTag> > &e,
+ const Domain<Dim, DT> &dom)
+ : eng_m(e.viewedEngine()), indexer_m(e.indexer(), dom)
+ {
+ }
+ template<int OrigDim, class DT>
+ Engine(const Engine<OrigDim, T, ViewEngine<OriginalDim, ViewedEngineTag> > &e,
+ const SliceDomain<DT> &dom)
+ : eng_m(e.viewedEngine()), indexer_m(e.indexer(), dom)
+ {
+ PoomaCTAssert<(DT::sliceDimensions == Dim)>::test();
+ PoomaCTAssert<(DT::dimensions == OrigDim)>::test();
+ }
+ template<class Domain>
+ Engine(const Engine<Dim, T, ViewEngine<OriginalDim, ViewedEngineTag> > &e,
+ const Node<Domain> &node)
+ : eng_m(e.viewedEngine()), indexer_m(e.indexer(), node.domain())
+ {
+ PoomaCTAssert<(Domain::dimensions == Dim)>::test();
+ }
+ Engine(const Engine<Dim, T, ViewEngine<OriginalDim, ViewedEngineTag> > &e,
+ const INode<Dim> &inode)
+ : eng_m(e.viewedEngine()), indexer_m(e.indexer(), inode.domain())
+ { }
+ Engine(const Engine<Dim, T, ViewEngine<OriginalDim, ViewedEngineTag> >
+ &model)
+ : eng_m(model.viewedEngine()), indexer_m(model.indexer())
+ { }
+ This_t &operator=(const This_t &rhs)
+ {
+ eng_m = rhs.viewedEngine();
+ indexer_m = rhs.indexer();
+ return *this;
+ }
+ inline Element_t read(int i0) const
+ {
+ Loc<OriginalDim> oloc;
+ indexer_m.translate(i0, oloc);
+ return eng_m.read(oloc);
+ }
+ inline Element_t read(int i0, int i1) const
+ {
+ Loc<OriginalDim> oloc;
+ indexer_m.translate(i0, i1, oloc);
+ return eng_m.read(oloc);
+ }
+ inline Element_t read(int i0, int i1, int i2) const
+ {
+ Loc<OriginalDim> oloc;
+ indexer_m.translate(i0, i1, i2, oloc);
+ return eng_m.read(oloc);
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3) const
+ {
+ Loc<OriginalDim> oloc;
+ indexer_m.translate(i0, i1, i2, i3, oloc);
+ return eng_m.read(oloc);
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3, int i4) const
+ {
+ Loc<OriginalDim> oloc;
+ indexer_m.translate(i0, i1, i2, i3, i4, oloc);
+ return eng_m.read(oloc);
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3, int i4, int i5) const
+ {
+ Loc<OriginalDim> oloc;
+ indexer_m.translate(i0, i1, i2, i3, i4, i5, oloc);
+ return eng_m.read(oloc);
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3, int i4,
+ int i5, int i6) const
+ {
+ Loc<OriginalDim> oloc;
+ indexer_m.translate(i0, i1, i2, i3, i4, i5, i6, oloc);
+ return eng_m.read(oloc);
+ }
+ inline Element_t read(const Loc<Dim> &loc) const
+ {
+ Loc<OriginalDim> oloc;
+ indexer_m.translate(loc, oloc);
+ return eng_m.read(oloc);
+ }
+ inline const Domain_t &domain() const { return indexer_m.domain(); }
+ inline Layout_t layout() const { return Layout_t(domain()); }
+ inline int first(int i) const
+ {
+ ;
+ return 0;
+ }
+ inline const ViewedEngine_t &viewedEngine() const { return eng_m; }
+ inline const Indexer_t &indexer() const { return indexer_m; }
+ template<class RequestType>
+ inline
+ typename DataObjectRequest<RequestType>::Type_t
+ dataObjectRequest(const DataObjectRequest<RequestType>& f) const
+ {
+ return eng_m.dataObjectRequest(f);
+ }
+ private:
+ ViewedEngine_t eng_m;
+ Indexer_t indexer_m;
+ };
+ template <int Dim, class T, int D2, class ViewedTag>
+ struct NewEngine< Engine<Dim,T,ViewEngine<D2,ViewedTag> >, Interval<Dim> >
+ {
+ typedef Engine<Dim, T, ViewEngine<D2, ViewedTag> > Type_t;
+ };
+ template <int Dim, class T, int D2, class ViewedTag>
+ struct NewEngine< Engine<Dim,T,ViewEngine<D2,ViewedTag> >, Range<Dim> >
+ {
+ typedef Engine<Dim, T, ViewEngine<D2, ViewedTag> > Type_t;
+ };
+ template <int Dim, class T, int D2, class ViewedTag, int SliceDim>
+ struct NewEngine< Engine<Dim, T, ViewEngine<D2, ViewedTag> >,
+ SliceInterval<Dim, SliceDim> >
+ {
+ typedef Engine<SliceDim, T, ViewEngine<D2, ViewedTag> > Type_t;
+ };
+ template <int Dim, class T, int D2, class ViewedTag, int SliceDim>
+ struct NewEngine< Engine<Dim, T, ViewEngine<D2, ViewedTag> >,
+ SliceRange<Dim, SliceDim> >
+ {
+ typedef Engine<SliceDim, T, ViewEngine<D2, ViewedTag> > Type_t;
+ };
+ template <int Dim, class T, int D2, class ViewedTag>
+ struct NewEngine< Engine<Dim, T, ViewEngine<D2, ViewedTag> >, INode<Dim> >
+ {
+ typedef Engine<Dim, T, ViewEngine<D2, ViewedTag> > Engine_t;
+ typedef typename Engine_t::ViewedEngine_t ViewedEngine_t;
+ typedef typename NewEngine<ViewedEngine_t,
+ INode<D2> >::Type_t NewViewedEngine_t;
+ typedef typename NewEngine<NewViewedEngine_t,
+ SliceRange<D2, Dim> >::Type_t Type_t;
+ };
+ template <int Dim, class T, int D2, class ViewedTag>
+ struct NewEngineEngine< Engine<Dim, T, ViewEngine<D2, ViewedTag> >,
+ INode<Dim> >
+ {
+ typedef Engine<Dim, T, ViewEngine<D2, ViewedTag> > Engine_t;
+ typedef typename NewEngine< Engine_t, INode<Dim> >::NewViewedEngine_t Type_t;
+ static inline Type_t
+ apply(const Engine_t &e, const INode<Dim> &inode)
+ {
+ Range<D2> base;
+ e.indexer().localToBase(inode.domain(), base);
+ Interval<D2> baseInt;
+ int i;
+ for (i = 0; i < D2; ++i)
+ {
+ baseInt[i] = Interval<1>(base[i].first(), base[i].last());
+ }
+ INode<D2> viewNode(inode, baseInt);
+ return Type_t(e.viewedEngine(), viewNode);
+ }
+ };
+ template <int Dim, class T, int D2, class ViewedTag>
+ struct NewEngineDomain< Engine<Dim, T, ViewEngine<D2, ViewedTag> >,
+ INode<Dim> >
+ {
+ typedef SliceRange<D2, Dim> Type_t;
+ typedef Engine<Dim, T, ViewEngine<D2, ViewedTag> > Engine_t;
+ static inline Type_t
+ apply(const Engine_t &e, const INode<Dim> &inode)
+ {
+ SliceRange<D2, Dim> base;
+ e.indexer().localToBase(inode.domain(), base);
+ base.totalDomain() -= base.totalDomain().firsts();
+ base.setSliceFromTotal();
+ return base;
+ }
+ };
+ template <int Dim, class T, class ViewedTag>
+ struct NewEngine<Engine<Dim, T, ViewEngine<Dim, ViewedTag> >, INode<Dim> >
+ {
+ typedef Engine<Dim, T, ViewEngine<Dim, ViewedTag> > Engine_t;
+ typedef typename Engine_t::ViewedEngine_t ViewedEngine_t;
+ typedef typename NewEngine<ViewedEngine_t,
+ INode<Dim> >::Type_t NewViewedEngine_t;
+ typedef typename NewEngine<NewViewedEngine_t,
+ Range<Dim> >::Type_t Type_t;
+ };
+ template <int Dim, class T, class ViewedTag>
+ struct NewEngineEngine<Engine<Dim, T, ViewEngine<Dim, ViewedTag> >,
+ INode<Dim> >
+ {
+ typedef Engine<Dim, T, ViewEngine<Dim, ViewedTag> > Engine_t;
+ typedef typename NewEngine<Engine_t, INode<Dim> >::NewViewedEngine_t Type_t;
+ static inline Type_t
+ apply(const Engine_t &e, const INode<Dim> &inode)
+ {
+ Range<Dim> base;
+ e.indexer().localToBase(inode.domain(), base);
+ Interval<Dim> baseInt;
+ int i;
+ for (i = 0; i < Dim; ++i)
+ {
+ baseInt[i] = Interval<1>(base[i].first(), base[i].last());
+ }
+ INode<Dim> viewNode(inode, baseInt);
+ return Type_t(e.viewedEngine(), viewNode);
+ }
+ };
+ template <int Dim, class T, class ViewedTag>
+ struct NewEngineDomain< Engine<Dim, T, ViewEngine<Dim, ViewedTag> >,
+ INode<Dim> >
+ {
+ typedef Range<Dim> Type_t;
+ typedef Engine<Dim, T, ViewEngine<Dim, ViewedTag> > Engine_t;
+ static inline Type_t
+ apply(const Engine_t &e, const INode<Dim> &inode)
+ {
+ Range<Dim> base;
+ e.indexer().localToBase(inode.domain(), base);
+ base -= base.firsts();
+ return base;
+ }
+ };
+ template<int OriginalDim, class ViewedEngineTag>
+ struct EvaluatorEngineTraits<ViewEngine<OriginalDim, ViewedEngineTag> >
+ {
+ typedef typename EvaluatorEngineTraits<ViewedEngineTag>::Evaluator_t
+ Evaluator_t;
+ };
+ template<int Dim, int ViewD1, int ViewD2>
+ class ViewIntersector
+ {
+ public:
+ typedef IntersectorData<Dim> IntersectorData_t;
+ typedef ViewIntersector<Dim, ViewD1, ViewD2> This_t;
+ typedef typename IntersectorData_t::IDContainer_t IDContainer_t;
+ typedef typename IntersectorData_t::BaseDomain_t BaseDomain_t;
+ typedef typename IntersectorData_t::BaseDomainContainer_t
+ BaseDomainContainer_t;
+ typedef typename IntersectorData_t::INode_t INode_t;
+ typedef typename IntersectorData_t::INodeContainer_t INodeContainer_t;
+ typedef typename IntersectorData_t::const_iterator const_iterator;
+ typedef RefCountedPtr<IntersectorData_t> DataPtr_t;
+ typedef ViewIndexer<ViewD1, ViewD2> Indexer_t;
+ enum { dimensions = Dim };
+ ViewIntersector(const ViewIndexer<ViewD1, ViewD2> &indexer,
+ const Intersector<Dim> &model)
+ : pdata_m(model.data()), indexer_m(indexer)
+ {
+ PoomaCTAssert<(Dim == ViewD1)>::test();
+ }
+ This_t &operator=(const This_t &model)
+ {
+ if (this != &model)
+ {
+ indexer_m = model.indexer_m;
+ pdata_m = model.pdata_m;
+ }
+ return *this;
+ }
+ ~ViewIntersector() { }
+ inline DataPtr_t &data() { return pdata_m; }
+ inline const DataPtr_t &data() const { return pdata_m; }
+ inline const_iterator begin() const { return data()->inodes_m.begin(); }
+ inline const_iterator end() const { return data()->inodes_m.end(); }
+ template<class Engine>
+ inline
+ void intersect(const Engine &e)
+ {
+ int n = data()->ids_m.size();
+ typedef INode<ViewD2> INode2_t;
+ typedef std::vector<INode2_t> INode2Container_t;
+ INode2Container_t inodes2;
+ int id = e.layout().ID();
+ if (n == 0)
+ {
+ Range<ViewD2> base = indexer_m.baseDomain();
+ e.layout().touches(base,
+ std::back_inserter(inodes2),
+ TouchesConstructINode<ViewD2>(id, GlobalIDDataBase::
+ nullNodeKey(),
+ &(data()->gidStore_m))
+ );
+ int i;
+ int ni = inodes2.size();
+ for (i = 0; i < ni; i++)
+ {
+ Interval<Dim> ival1;
+ indexer_m.baseToLocalInterval(inodes2[i].domain(), ival1);
+ INode<Dim> inode(inodes2[i], ival1);
+ data()->inodes_m.push_back(inode);
+ }
+ }
+ else
+ {
+ int ni = data()->inodes_m.size();
+ int i;
+ for (i = 0; i < ni; i++)
+ {
+ Range<ViewD2> range;
+ indexer_m.localToBase(data()->inodes_m[i].domain(), range);
+ e.layout().touches(range,
+ std::back_inserter(inodes2),
+ INode<ViewD2>::touchesConstructINode(id,
+ data()->inodes_m[i])
+ );
+ }
+ data()->inodes_m.erase(data()->inodes_m.begin(),
+ data()->inodes_m.begin() + ni);
+ ni = inodes2.size();
+ for (i = 0; i < ni; i++)
+ {
+ Interval<Dim> ival1;
+ indexer_m.baseToLocalInterval(inodes2[i].domain(), ival1);
+ INode<Dim> inode(inodes2[i], ival1);
+ data()->inodes_m.push_back(inode);
+ }
+ }
+ }
+ template<class Engine, int Dim2>
+ inline
+ bool intersect(const Engine &l, const GuardLayers<Dim2> &guard)
+ {
+ return (data()->intersect(l,guard));
+ }
+ private:
+ DataPtr_t pdata_m;
+ Indexer_t indexer_m;
+ };
+ template <int Dim, class T, int D2, class ViewedTag, class Intersect>
+ struct LeafFunctor< Engine<Dim, T, ViewEngine<D2, ViewedTag> >,
+ ExpressionApply<IntersectorTag<Intersect> > >
+ {
+ typedef int Type_t;
+ typedef Engine<Dim, T, ViewEngine<D2, ViewedTag> > Engine_t;
+ static Type_t
+ apply(const Engine_t &,
+ const ExpressionApply<IntersectorTag<Intersect> > &,
+ const WrappedInt<false> &)
+ {
+ return 0;
+ }
+ static Type_t
+ apply(const Engine_t &engine,
+ const ExpressionApply<IntersectorTag<Intersect> > &tag,
+ const WrappedInt<true> &)
+ {
+ enum { d1 = Intersect::dimensions };
+ ViewIntersector<d1, Dim, D2> newIntersector(engine.indexer(),
+ tag.tag().intersector_m);
+ ExpressionApply<IntersectorTag<ViewIntersector<d1, Dim, D2> > >
+ newTag(newIntersector);
+ forEach(engine.viewedEngine(), newTag, NullCombine());
+ return 0;
+ }
+ static Type_t
+ apply(const Engine_t &engine,
+ const ExpressionApply<IntersectorTag<Intersect> > &tag)
+ {
+ enum { multiPatch =
+ Engine<Dim, T, ViewEngine<D2, ViewedTag> >::multiPatch };
+ return apply(engine, tag, WrappedInt<multiPatch>());
+ }
+ };
+ template<class RequestType> class DataObjectRequest;
+ template <int Dim, class T, int D2, class ViewedTag, class RequestType>
+ struct EngineFunctor< Engine<Dim, T, ViewEngine<D2, ViewedTag> >,
+ DataObjectRequest<RequestType> >
+ {
+ typedef typename DataObjectRequest<RequestType>::Type_t Type_t;
+ static Type_t
+ apply(const Engine<Dim, T, ViewEngine<D2, ViewedTag> > &engine,
+ const DataObjectRequest<RequestType> &tag)
+ {
+ return engineFunctor(engine.viewedEngine(), tag);
+ }
+ };
+ template <int D, class T, int D2, class E, class Tag>
+ struct LeafFunctor<Engine<D, T, ViewEngine<D2, E> >, ExpressionApply<Tag> >
+ {
+ typedef Engine<D, T, ViewEngine<D2, E> > Subject_t;
+ typedef typename Subject_t::ViewedEngine_t Engine_t;
+ typedef LeafFunctor<Engine_t, ExpressionApply<Tag> > LeafFunctor_t;
+ typedef int Type_t;
+ static
+ Type_t apply(const Subject_t &engine, const ExpressionApply<Tag> &tag)
+ {
+ return LeafFunctor_t::apply(engine.viewedEngine(), tag);
+ }
+ };
+ template<class Functor>
+ struct IndexFunction
+ {
+ typedef Functor Functor_t;
+ };
+ template<int Dim, class Functor>
+ struct IndexFunctionView
+ { };
+ template<int Dim, class T, class Functor>
+ class Engine<Dim, T, IndexFunction<Functor> >
+ {
+ public:
+ typedef IndexFunction<Functor> Tag_t;
+ typedef Engine<Dim, T, Tag_t> This_t;
+ typedef This_t Engine_t;
+ typedef Interval<Dim> Domain_t;
+ typedef DomainLayout<Dim> Layout_t;
+ typedef T Element_t;
+ typedef ErrorType ElementRef_t;
+ enum { dimensions = Dim };
+ enum { hasDataObject = false };
+ enum { dynamic = false };
+ enum { zeroBased = false };
+ enum { multiPatch = false };
+ Engine() { }
+ explicit Engine(const Domain_t &domain, const Functor &f = Functor())
+ : funct_m(f), domain_m(domain)
+ {
+ }
+ template<class Layout>
+ explicit Engine(const Layout &layout, const Functor &f = Functor())
+ : funct_m(f), domain_m(layout.domain())
+ {
+ }
+ Engine(const This_t &model)
+ : funct_m(model.functor()), domain_m(model.domain())
+ {
+ }
+ This_t &operator=(const This_t &rhs)
+ {
+ domain_m = rhs.domain();
+ funct_m = rhs.functor();
+ return *this;
+ }
+ inline Element_t read(int i0) const
+ {
+ return funct_m(i0);
+ }
+ inline Element_t read(int i0, int i1) const
+ {
+ return funct_m(i0, i1);
+ }
+ inline Element_t read(int i0, int i1, int i2) const
+ {
+ return funct_m(i0, i1, i2);
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3) const
+ {
+ return funct_m(i0, i1, i2, i3);
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3, int i4) const
+ {
+ return funct_m(i0, i1, i2, i3, i4);
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3, int i4,
+ int i5) const
+ {
+ return funct_m(i0, i1, i2, i3, i4, i5);
+ }
+ inline Element_t read(int i0, int i1, int i2, int i3, int i4,
+ int i5, int i6) const
+ {
+ return funct_m(i0, i1, i2, i3, i4, i5, i6);
+ }
+ inline Element_t read(const Loc<1> &loc) const
+ {
+ return funct_m(loc[0].first());
+ }
+ inline Element_t read(const Loc<2> &loc) const
+ {
+ return funct_m(loc[0].first(), loc[1].first());
+ }
+ inline Element_t read(const Loc<3> &loc) const
+ {
+ return funct_m(loc[0].first(), loc[1].first(), loc[2].first());
+ }
+ inline Element_t read(const Loc<4> &loc) const
+ {
+ return funct_m(loc[0].first(), loc[1].first(), loc[2].first(),
+ loc[3].first());
+ }
+ inline Element_t read(const Loc<5> &loc) const
+ {
+ return funct_m(loc[0].first(), loc[1].first(), loc[2].first(),
+ loc[3].first(), loc[4].first());
+ }
+ inline Element_t read(const Loc<6> &loc) const
+ {
+ return funct_m(loc[0].first(), loc[1].first(), loc[2].first(),
+ loc[3].first(), loc[4].first(), loc[5].first());
+ }
+ inline Element_t read(const Loc<7> &loc) const
+ {
+ return funct_m(loc[0].first(), loc[1].first(), loc[2].first(),
+ loc[3].first(), loc[4].first(), loc[5].first(), loc[6].first());
+ }
+ inline const Domain_t &domain() const { return domain_m; }
+ void setDomain(const Domain_t &dom) { domain_m = dom; }
+ inline int first(int i) const
+ {
+ ;
+ return domain_m[i].first();
+ }
+ Layout_t layout() const
+ {
+ return Layout_t(domain_m);
+ }
+ const Functor &functor() const { return funct_m; }
+ void setFunctor(const Functor &f) { funct_m = f; }
+ private:
+ Functor funct_m;
+ Domain_t domain_m;
+ };
+ template <int Dim, class T, class Functor>
+ struct NewEngine<Engine<Dim, T, IndexFunction<Functor> >, Interval<Dim> >
+ {
+ typedef Engine<Dim, T, ViewEngine<Dim, IndexFunction<Functor> > > Type_t;
+ };
+ template <int Dim, class T, class Functor>
+ struct NewEngine<Engine<Dim, T, IndexFunction<Functor> >, Range<Dim> >
+ {
+ typedef Engine<Dim, T, ViewEngine<Dim, IndexFunction<Functor> > > Type_t;
+ };
+ template <int Dim, class T, class Functor, int SliceDim>
+ struct NewEngine<Engine<Dim, T, IndexFunction<Functor> >,
+ SliceInterval<Dim, SliceDim> >
+ {
+ typedef Engine<SliceDim, T, ViewEngine<Dim, IndexFunction<Functor> > > Type_t;
+ };
+ template <int Dim, class T, class Functor, int SliceDim>
+ struct NewEngine<Engine<Dim, T, IndexFunction<Functor> >,
+ SliceRange<Dim, SliceDim> >
+ {
+ typedef Engine<SliceDim, T, ViewEngine<Dim, IndexFunction<Functor> > > Type_t;
+ };
+ template <int Dim, class T, class Functor, class Domain>
+ struct NewEngine<Engine<Dim, T, IndexFunction<Functor> >, Node<Domain> >
+ {
+ typedef Engine<Dim, T, ViewEngine<Dim, IndexFunction<Functor> > > Type_t;
+ };
+ template <int Dim, class T, class Functor>
+ struct NewEngine<Engine<Dim, T, IndexFunction<Functor> >, INode<Dim> >
+ {
+ typedef Engine<Dim, T, ViewEngine<Dim, IndexFunction<Functor> > > Type_t;
+ };
+ class IotaFunctor
+ {
+ public:
+ inline IotaFunctor() { }
+ inline IotaFunctor(const IotaFunctor &) { }
+ inline IotaFunctor &operator=(const IotaFunctor &) { return *this; }
+ inline
+ Vector<1, int> operator()(int i1) const
+ {
+ return Vector<1, int>(i1);
+ }
+ inline
+ Vector<2, int> operator()(int i1, int i2) const
+ {
+ return Vector<2, int>(i1, i2);
+ }
+ inline
+ Vector<3, int> operator()(int i1, int i2, int i3) const
+ {
+ return Vector<3, int>(i1, i2, i3);
+ }
+ };
+ template<int Dim>
+ struct Iota
+ {
+ typedef Array<Dim, Vector<Dim, int>, IndexFunction<IotaFunctor> >
+ Iota_t;
+ typedef typename ComponentView<Loc<1>, Iota_t>::Type_t Index_t;
+ };
+ template<int Dim>
+ inline
+ typename Iota<Dim>::Iota_t
+ iota(const Interval<Dim> &domain)
+ {
+ typedef typename Iota<Dim>::Iota_t Iota_t;
+ return Iota_t(domain);
+ }
+ template<int Dim>
+ inline
+ typename Iota<Dim>::Index_t
+ iotaIndex(const Interval<Dim> &domain, int i)
+ {
+ typedef typename Iota<Dim>::Iota_t Iota_t;
+ return Iota_t(domain).comp(i);
+ }
+ inline
+ Array<1, Vector<1, int>, IndexFunction<IotaFunctor> >
+ iota(int i1);
+ inline
+ Array<1, Vector<1, int>, IndexFunction<IotaFunctor> >
+ iota(int i1)
+ {
+ return Array<1, Vector<1, int>,
+ IndexFunction<IotaFunctor> >(Interval<1>(i1));
+ }
+ inline
+ Array<2, Vector<2, int>, IndexFunction<IotaFunctor> >
+ iota(int i1, int i2);
+ inline
+ Array<2, Vector<2, int>, IndexFunction<IotaFunctor> >
+ iota(int i1, int i2)
+ {
+ return Array<2, Vector<2, int>,
+ IndexFunction<IotaFunctor> >(Interval<2>(i1, i2));
+ }
+ inline
+ Array<3, Vector<3, int>, IndexFunction<IotaFunctor> >
+ iota(int i1, int i2, int i3);
+ inline
+ Array<3, Vector<3, int>, IndexFunction<IotaFunctor> >
+ iota(int i1, int i2, int i3)
+ {
+ return Array<3, Vector<3, int>,
+ IndexFunction<IotaFunctor> >(Interval<3>(i1, i2, i3));
+ }
+ template<class Functor, class ArgumentType>
+ struct FunctorResult
+ {
+ typedef ArgumentType Type_t;
+ };
+ template<int D, class T, class E> class Array;
+ template<class UserFunction, class Expression>
+ struct UserFunctionEngine
+ { };
+ template<int D, class T, class UserFunction, class Expression>
+ class Engine< D, T, UserFunctionEngine<UserFunction,Expression> >
+ {
+ public:
+ typedef UserFunctionEngine<UserFunction,Expression> Tag_t;
+ typedef Engine<D,T,Tag_t> This_t;
+ typedef This_t Engine_t;
+ typedef typename Expression::Domain_t Domain_t;
+ typedef typename Expression::Layout_t Layout_t;
+ typedef T Element_t;
+ typedef ErrorType ElementRef_t;
+ typedef typename Expression::Engine_t ExprEngine_t;
+ enum { dimensions = D };
+ enum { hasDataObject = ExprEngine_t::hasDataObject };
+ enum { dynamic = false };
+ enum { zeroBased = ExprEngine_t::zeroBased };
+ enum { multiPatch = ExprEngine_t::multiPatch };
+ Engine(const UserFunction& s, const Expression& e)
+ : userFunction_m(s), expression_m(e) {}
+ template<class OtherE, class Domain>
+ Engine(const Engine<D,T,UserFunctionEngine<UserFunction,OtherE> >& e,
+ const Domain& d)
+ : userFunction_m(e.userFunction()),
+ expression_m( e.expression(), d ) {}
+ inline Element_t read(const Loc<D> &loc) const
+ {
+ return userFunction_m(expression_m.read(loc));
+ }
+ inline Element_t read(int i) const
+ {
+ return userFunction_m(expression_m.read(i));
+ }
+ inline Element_t read(int i, int j) const
+ {
+ return userFunction_m(expression_m.read(i,j));
+ }
+ inline Element_t read(int i, int j, int k) const
+ {
+ return userFunction_m(expression_m.read(i,j,k));
+ }
+ inline Element_t read(int i, int j, int k, int l) const
+ {
+ return userFunction_m(expression_m.read(i,j,k,l));
+ }
+ inline Element_t read(int i, int j, int k, int l,int m) const
+ {
+ return userFunction_m(expression_m.read(i,j,k,l,m));
+ }
+ inline Element_t read(int i, int j, int k, int l,int m,int n) const
+ {
+ return userFunction_m(expression_m.read(i,j,k,l,m,n));
+ }
+ inline Element_t read(int i, int j, int k, int l,int m,int n,int o) const
+ {
+ return userFunction_m(expression_m.read(i,j,k,l,m,n,o));
+ }
+ inline Element_t operator()(const Loc<D> &loc) const
+ {
+ return userFunction_m(expression_m(loc));
+ }
+ inline Element_t operator()(int i) const
+ {
+ return userFunction_m(expression_m(i));
+ }
+ inline Element_t operator()(int i, int j) const
+ {
+ return userFunction_m(expression_m(i,j));
+ }
+ inline Element_t operator()(int i, int j, int k) const
+ {
+ return userFunction_m(expression_m(i,j,k));
+ }
+ inline Element_t operator()(int i, int j, int k, int l) const
+ {
+ return userFunction_m(expression_m(i,j,k,l));
+ }
+ inline Element_t operator()(int i, int j, int k, int l,int m) const
+ {
+ return userFunction_m(expression_m(i,j,k,l,m));
+ }
+ inline Element_t operator()(int i, int j, int k, int l,int m,int n) const
+ {
+ return userFunction_m(expression_m(i,j,k,l,m,n));
+ }
+ inline Element_t operator()(int i, int j, int k, int l,int m,int n,int o)
+ const
+ {
+ return userFunction_m(expression_m(i,j,k,l,m,n,o));
+ }
+ inline const Domain_t& domain() const { return expression_m.domain(); }
+ inline int first(int d) const
+ {
+ return expression_m.first(d);
+ }
+ const UserFunction& userFunction() const { return userFunction_m; }
+ const Expression& expression() const { return expression_m; }
+ template<class RequestType>
+ inline
+ typename DataObjectRequest<RequestType>::Type_t
+ dataObjectRequest(const DataObjectRequest<RequestType>& f) const
+ {
+ return engineFunctor(expression_m.engine(),f);
+ }
+ private:
+ UserFunction userFunction_m;
+ Expression expression_m;
+ };
+ template<class Func> class UserFunction;
+ template<class Func,int D,class T,class E>
+ struct View1<UserFunction<Func>,Array<D,T,E> >
+ {
+ typedef Array<D,T,E> Expr_t;
+ typedef UserFunctionEngine<Func,Expr_t> NewTag_t;
+ typedef typename FunctorResult<Func,T>::Type_t NewT_t;
+ typedef Engine<D,NewT_t,NewTag_t> NewEngine_t;
+ typedef Array<D,NewT_t,NewTag_t> Type_t;
+ };
+ template<class Func>
+ class UserFunction
+ {
+ public:
+ UserFunction()
+ { }
+ UserFunction(const Func &func)
+ : function_m(func)
+ { }
+ template<class Init>
+ UserFunction(const Init &init)
+ : function_m(init)
+ { }
+ template<class I1, class I2>
+ UserFunction(const I1 &i1, const I2 &i2)
+ : function_m(i1,i2)
+ { }
+ template<class I1, class I2, class I3>
+ UserFunction(const I1 &i1, const I2 &i2, const I3 &i3)
+ : function_m(i1,i2,i3)
+ { }
+ template<class I1, class I2, class I3, class I4>
+ UserFunction(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4)
+ : function_m(i1,i2,i3,i4)
+ { }
+ template<class I1, class I2, class I3, class I4, class I5>
+ UserFunction(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4,
+ const I5 &i5)
+ : function_m(i1,i2,i3,i4,i5)
+ { }
+ template<class I1, class I2, class I3, class I4, class I5, class I6>
+ UserFunction(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4,
+ const I5 &i5, const I6 &i6)
+ : function_m(i1,i2,i3,i4,i5,i6)
+ { }
+ template<class I1, class I2, class I3, class I4, class I5, class I6,
+ class I7>
+ UserFunction(const I1 &i1, const I2 &i2, const I3 &i3, const I4 &i4,
+ const I5 &i5, const I6 &i6, const I7 &i7)
+ : function_m(i1,i2,i3,i4,i5,i6,i7)
+ { }
+ template<int D, class T, class E>
+ typename View1<UserFunction<Func>,Array<D,T,E> >::Type_t
+ operator()(const Array<D,T,E>& expr) const
+ {
+ typedef typename View1<UserFunction<Func>,Array<D,T,E> >::NewEngine_t
+ NewEngine_t;
+ typedef typename View1<UserFunction<Func>,Array<D,T,E> >::Type_t
+ Type_t;
+ return Type_t(NewEngine_t(function(),expr));
+ }
+ inline Func &function() { return function_m; }
+ inline const Func &function() const { return function_m; }
+ private:
+ Func function_m;
+ };
+ template <int Dim, class T, class S, class E, class Domain>
+ struct NewEngine< Engine<Dim,T,UserFunctionEngine<S,E> >, Domain >
+ {
+ typedef typename View1<E,Domain>::Type_t NewExpr_t;
+ typedef UserFunctionEngine<S,NewExpr_t> NewTag_t;
+ typedef typename NewExpr_t::Element_t OldElement_t;
+ typedef typename FunctorResult<S,OldElement_t>::Type_t NewElement_t;
+ typedef Engine<Dim,NewElement_t,NewTag_t> Type_t;
+ };
+ template<class UserFunction,class Expression>
+ struct EvaluatorEngineTraits<UserFunctionEngine<UserFunction,Expression> >
+ {
+ typedef typename Expression::Engine_t Engine_t;
+ typedef typename Engine_t::Tag_t Tag_t;
+ typedef typename EvaluatorEngineTraits<Tag_t>::Evaluator_t Evaluator_t;
+ };
+ template <int Dim, class T, class S, class E, class EFTag>
+ struct EngineFunctor<Engine<Dim, T, UserFunctionEngine<S, E> >, EFTag>
+ {
+ typedef typename EngineFunctor<E, EFTag>::Type_t Type_t;
+ static Type_t
+ apply(const Engine<Dim, T, UserFunctionEngine<S, E> > &engine,
+ const EFTag &tag)
+ {
+ return engineFunctor(engine.expression(), tag);
+ }
+ };
+ template <int D, class T, class Func, class Expr, class Tag>
+ struct LeafFunctor<Engine<D, T, UserFunctionEngine<Func, Expr> >,
+ EngineView<Tag> >
+ {
+ typedef LeafFunctor<Expr, EngineView<Tag> > LeafFunctor_t;
+ typedef typename LeafFunctor_t::Type_t NewViewed_t;
+ typedef Engine<D, T, UserFunctionEngine<Func, NewViewed_t> > Type_t;
+ static
+ Type_t apply(const Engine<D, T, UserFunctionEngine<Func, Expr> > &engine,
+ const EngineView<Tag> &tag)
+ {
+ return Type_t(engine.userFunction(),
+ LeafFunctor_t::apply(engine.expression(), tag));
+ }
+ };
+ template <int D, class T, class Func, class Expr, class Tag>
+ struct LeafFunctor<Engine<D, T, UserFunctionEngine<Func, Expr> >,
+ ExpressionApply<Tag> >
+ {
+ typedef LeafFunctor<Expr, ExpressionApply<Tag> > LeafFunctor_t;
+ typedef int Type_t;
+ static
+ Type_t apply(const Engine<D, T, UserFunctionEngine<Func, Expr> > &engine,
+ const ExpressionApply<Tag> &tag)
+ {
+ return LeafFunctor_t::apply(engine.expression(), tag);
+ }
+ };
+ template<int D, class T, class E> class Array;
+ template<class M, class T, class E> class Field;
+ template<class ST> class Stencil;
+ template<class Function, class Expression>
+ struct StencilEngine
+ {
+ typedef typename Expression::Element_t ViewedElement_t;
+ typedef typename FunctorResult<Function,ViewedElement_t>::Type_t Element_t;
+ };
+ template<class Function, int D>
+ inline
+ Interval<D> insetDomain(const Function &f, const Interval<D> &domain)
+ {
+ Interval<D> ret;
+ int d;
+ for (d = 0; d < D; ++d)
+ {
+ ret[d] = Interval<1>(domain[d].first() + f.lowerExtent(d),
+ domain[d].last() - f.upperExtent(d));
+ }
+ return ret;
+ }
+ template<int D, class T, class Function, class Expression>
+ class Engine<D, T, StencilEngine<Function, Expression> >
+ {
+ public:
+ typedef StencilEngine<Function, Expression> Tag_t;
+ typedef Engine<D, T, Tag_t> This_t;
+ typedef This_t Engine_t;
+ typedef Interval<D> Domain_t;
+ typedef DomainLayout<D> Layout_t;
+ typedef T Element_t;
+ typedef ErrorType ElementRef_t;
+ typedef typename Expression::Engine_t ExprEngine_t;
+ enum { dimensions = D };
+ enum { hasDataObject = ExprEngine_t::hasDataObject };
+ enum { dynamic = false };
+ enum { multiPatch = ExprEngine_t::multiPatch };
+ enum { zeroBased = true };
+ Engine()
+ : function_m(), expression_m(), domain_m(Pooma::NoInit())
+ {
+ }
+ template <class Layout2>
+ explicit Engine(const Layout2 &layout)
+ : function_m(), expression_m(), domain_m(layout.domain())
+ {
+ }
+ Engine(const Function &f, const Expression &e)
+ : function_m(f), expression_m(e), domain_m(Pooma::NoInit())
+ {
+ Interval<D> inset = insetDomain(f, e.domain());
+ int d;
+ for (d = 0; d < D; ++d)
+ {
+ domain_m[d] = Interval<1>(inset[d].length());
+ offset_m[d] = function().lowerExtent(d);
+ }
+ }
+ Engine(const Function &f, const Expression &e, const Interval<D> &domain)
+ : function_m(f), expression_m(e), domain_m(Pooma::NoInit())
+ {
+ int d;
+ for (d = 0; d < D; ++d)
+ {
+ domain_m[d] = Interval<1>(domain[d].length());
+ offset_m[d] = domain[d].first();
+ }
+ }
+ template<class OtherE>
+ Engine(const Engine<D, T, StencilEngine<Function, OtherE> > &e,
+ const INode<D> &node)
+ : function_m(e.function()),
+ expression_m(e.expression()(e.viewDomain(node))),
+ domain_m(Pooma::NoInit())
+ {
+ int d;
+ for (d = 0; d < D; ++d)
+ {
+ domain_m[d] = Interval<1>(node.domain()[d].length());
+ offset_m[d] = function().lowerExtent(d);
+ }
+ }
+ Engine(const Engine_t &e,
+ const Interval<D> &domain)
+ : function_m(e.function()),
+ expression_m(e.expression()),
+ domain_m(Pooma::NoInit())
+ {
+ int d;
+ for (d = 0; d < D; ++d)
+ {
+ domain_m[d] = Interval<1>(domain[d].length());
+ offset_m[d] = e.offset_m[d] + domain[d].first();
+ }
+ }
+ template <int Dim, class Tx, class EngineTag>
+ void initExpressionFromModel(const Array<Dim, Tx, EngineTag>& model)
+ {
+ expression_m.engine() = model.engine();
+ }
+ template <class Mesh, class Tx, class EngineTag>
+ void initExpressionFromModel(const Field<Mesh, Tx, EngineTag>& model)
+ {
+ expression_m.fieldEngine() = model.fieldEngine();
+ }
+ This_t &operator=(const This_t &model)
+ {
+ domain_m = model.domain();
+ function_m = model.function();
+ initExpressionFromModel(model.expression());
+ for (int d = 0; d < D; ++d)
+ {
+ domain_m[d] = model.domain()[d];
+ offset_m[d] = model.offset(d);
+ }
+ return *this;
+ }
+ inline Element_t read(int i) const
+ {
+ return function()(expression_m,
+ i + offset_m[0]);
+ }
+ inline Element_t read(int i, int j) const
+ {
+ return function()(expression_m,
+ i + offset_m[0],
+ j + offset_m[1]);
+ }
+ inline Element_t read(int i, int j, int k) const
+ {
+ return function()(expression_m,
+ i + offset_m[0],
+ j + offset_m[1],
+ k + offset_m[2]);
+ }
+ inline Element_t read(const Loc<1> &loc) const
+ {
+ return function()(expression_m,
+ loc[0].first() + offset_m[0]);
+ }
+ inline Element_t read(const Loc<2> &loc) const
+ {
+ return function()(expression_m,
+ loc[0].first() + offset_m[0],
+ loc[1].first() + offset_m[1]);
+ }
+ inline Element_t read(const Loc<3> &loc) const
+ {
+ return function()(expression_m,
+ loc[0].first() + offset_m[0],
+ loc[1].first() + offset_m[1],
+ loc[2].first() + offset_m[2]);
+ }
+ inline Element_t operator()(int i) const
+ {
+ return read(i);
+ }
+ inline Element_t operator()(int i, int j) const
+ {
+ return read(i, j);
+ }
+ inline Element_t operator()(int i, int j, int k) const
+ {
+ return read(i, j, k);
+ }
+ inline const Domain_t &domain() const { return domain_m; }
+ inline Layout_t layout() const { return Layout_t(domain_m); }
+ inline int first(int i) const
+ {
+ return 0;
+ }
+ inline
+ Interval<D> viewDomain(const Interval<D> &domain) const
+ {
+ Interval<D> ret;
+ int d;
+ for (d = 0; d < D; ++d)
+ {
+ ret[d] =
+ Interval<1>(
+ domain[d].first() + offset_m[d]
+ - function().lowerExtent(d),
+ domain[d].last() + offset_m[d] + function().upperExtent(d)
+ );
+ }
+ return ret;
+ }
+ inline
+ INode<D> viewDomain(const INode<D> &inode) const
+ {
+ return INode<D>(inode, viewDomain(inode.domain()));
+ }
+ inline
+ Interval<D> intersectDomain() const
+ {
+ Interval<D> ret;
+ int d;
+ for (d = 0; d < D; ++d)
+ {
+ ret[d] =
+ Interval<1>(
+ domain_m[d].first() + offset_m[d],
+ domain_m[d].last() + offset_m[d]
+ );
+ }
+ return ret;
+ }
+ inline const Function &function() const { return function_m; }
+ inline const Expression &expression() const { return expression_m; }
+ int offset(int d) const { return offset_m[d]; }
+ private:
+ Function function_m;
+ Expression expression_m;
+ Interval<D> domain_m;
+ int offset_m[D];
+ };
+ template<class Function, int D, class T, class E>
+ struct View1<Stencil<Function>, Array<D, T, E> >
+ {
+ typedef Array<D,T,E> ArrayIn_t;
+ typedef StencilEngine<Function, ArrayIn_t> NewTag_t;
+ typedef typename NewTag_t::Element_t NewT_t;
+ typedef Engine<D, NewT_t, NewTag_t> NewEngine_t;
+ typedef Array<D, NewT_t, NewTag_t> Type_t;
+ static inline
+ Type_t make(const Stencil<Function> &s, const ArrayIn_t &a)
+ {
+ return Type_t(NewEngine_t(s.function(), a,
+ insetDomain(s.function(), a.domain())
+ ));
+ }
+ };
+ template<class Function, class ArrayIn, int Dim>
+ struct View2<Stencil<Function>,ArrayIn,Interval<Dim> >
+ {
+ enum { dim = ArrayIn::dimensions };
+ typedef Interval<Dim> ViewDom_t;
+ typedef typename View1<ArrayIn,ViewDom_t>::Type_t Expression_t;
+ typedef StencilEngine<Function, Expression_t> NewTag_t;
+ typedef typename NewTag_t::Element_t NewT_t;
+ typedef Engine<dim,NewT_t,NewTag_t> NewEngine_t;
+ typedef Array<dim,NewT_t,NewTag_t> Type_t;
+ static inline
+ Type_t make(const Stencil<Function> &s, const ArrayIn &a,
+ const Interval<Dim> &d)
+ {
+ return Type_t(NewEngine_t(s.function(), a(s.inputDomain(d))));
+ }
+ };
+ template<class Function, class ArrayIn, class Dom>
+ struct View2<Stencil<Function>, ArrayIn, Dom>
+ {
+ enum { dim2 = ArrayIn::dimensions };
+ enum { dim = Dom::dimensions };
+ typedef Interval<dim2> ViewDom_t;
+ typedef typename View1<ArrayIn, ViewDom_t>::Type_t Expression_t;
+ typedef StencilEngine<Function, Expression_t> StencilTag_t;
+ typedef typename StencilTag_t::Element_t NewT_t;
+ typedef ViewEngine<dim2, StencilTag_t> NewTag_t;
+ typedef Engine<dim,NewT_t,NewTag_t> NewEngine_t;
+ typedef Array<dim,NewT_t,NewTag_t> Type_t;
+ static inline
+ Type_t make(const Stencil<Function> &s, const ArrayIn &a, const Dom &dom)
+ {
+ ViewDom_t viewDom = s.inputDomain(dom);
+ ViewDom_t insetDom = insetDomain(s.function(), viewDom);
+ ViewIndexer<dim,dim2> indexer(insetDom);
+ Dom stView;
+ indexer.baseToLocal(dom,stView);
+ typedef typename NewEngine_t::ViewedEngine_t ViewedEngine_t;
+ ViewedEngine_t viewed(s.function(),a(viewDom));
+ return Type_t(NewEngine_t(viewed,stView));
+ }
+ };
+ template<class Function>
+ class Stencil
+ {
+ public:
+ Stencil()
+ { }
+ Stencil(const Stencil<Function> &model)
+ : function_m(model.function_m)
+ { }
+ ~Stencil() {}
+ template<class Init>
+ Stencil(const Init &init)
+ : function_m(init)
+ { }
+ template<int D, class T, class E>
+ typename View1<Stencil<Function>,Array<D,T,E> >::Type_t
+ operator()(const Array<D,T,E>& expr) const
+ {
+ typedef View1<Stencil<Function>,Array<D,T,E> > Ret_t;
+ return Ret_t::make(*this,expr);
+ }
+ template<int D, class T, class E,class Dom>
+ typename View2<Stencil<Function>,Array<D,T,E>,Dom>::Type_t
+ operator()(const Array<D,T,E>& expr,const Dom &domain) const
+ {
+ PoomaCTAssert<(D==Dom::dimensions)>::test();
+ typedef View2<Stencil<Function>,Array<D,T,E>,Dom> Ret_t;
+ return Ret_t::make(*this,expr,domain);
+ }
+ template<int D>
+ inline
+ Interval<D> insetDomain(const Interval<D> &domain)
+ {
+ return ::insetDomain(function(), domain);
+ }
+ template<int D, class DT>
+ inline
+ Interval<D> inputDomain(const Domain<D,DT> &domain) const
+ {
+ Interval<D> ret;
+ int d;
+ for (d = 0; d < D; ++d)
+ {
+ ret[d] =
+ Interval<1>(
+ domain[d].first() - function().lowerExtent(d),
+ domain[d].last() + function().upperExtent(d)
+ );
+ }
+ return ret;
+ }
+ inline Function &function() { return function_m; }
+ inline const Function &function() const { return function_m; }
+ private:
+ Function function_m;
+ };
+ template <int Dim, class T, class S, class E>
+ struct NewEngine<Engine<Dim, T, StencilEngine<S, E> >, Interval<Dim> >
+ {
+ typedef Engine<Dim, T, StencilEngine<S, E> > Type_t;
+ };
+ template <int Dim, class T, class S, class E>
+ struct NewEngine<Engine<Dim, T, StencilEngine<S, E> >, INode<Dim> >
+ {
+ typedef typename View1<E, INode<Dim> >::Type_t NewExpr_t;
+ typedef StencilEngine<S, NewExpr_t> NewTag_t;
+ typedef Engine<Dim, T, NewTag_t> Type_t;
+ };
+ template <int Dim, class T, class S, class E>
+ struct NewEngine<Engine<Dim, T, StencilEngine<S, E> >, Range<Dim> >
+ {
+ typedef StencilEngine<S,E> SETag_t;
+ typedef ViewEngine<Dim,SETag_t> NewTag_t;
+ typedef Engine<Dim,T,NewTag_t> Type_t;
+ };
+ template <int Dim, class T, class S, class E, int SliceDim>
+ struct NewEngine< Engine<Dim,T,StencilEngine<S,E> >,
+ SliceInterval<Dim,SliceDim> >
+ {
+ typedef StencilEngine<S,E> SETag_t;
+ typedef ViewEngine<Dim,SETag_t> NewTag_t;
+ typedef Engine<SliceDim,T,NewTag_t> Type_t;
+ };
+ template <int Dim, class T, class S, class E, int SliceDim>
+ struct NewEngine< Engine<Dim,T,StencilEngine<S,E> >,
+ SliceRange<Dim,SliceDim> >
+ {
+ typedef StencilEngine<S,E> SETag_t;
+ typedef ViewEngine<Dim,SETag_t> NewTag_t;
+ typedef Engine<SliceDim,T,NewTag_t> Type_t;
+ };
+ template<class UserFunction,class Expression>
+ struct EvaluatorEngineTraits<StencilEngine<UserFunction,Expression> >
+ {
+ typedef typename Expression::Engine_t Engine_t;
+ typedef typename Engine_t::Tag_t Tag_t;
+ typedef typename EvaluatorEngineTraits<Tag_t>::Evaluator_t Evaluator_t;
+ };
+ template<int Dim, class Intersect>
+ class StencilIntersector
+ {
+ public:
+ typedef typename Intersect::IntersectorData_t IntersectorData_t;
+ typedef StencilIntersector<Dim, Intersect> This_t;
+ typedef typename IntersectorData_t::const_iterator const_iterator;
+ typedef RefCountedPtr<IntersectorData_t> DataPtr_t;
+ enum { dimensions = Intersect::dimensions };
+ StencilIntersector(const This_t &model)
+ : domain_m(model.domain_m),
+ stencilExtent_m(model.stencilExtent_m),
+ intersector_m(model.intersector_m)
+ { }
+ StencilIntersector(const Interval<Dim> &domain, const Intersect &intersect,
+ const GuardLayers<Dim> &stencilExtent)
+ : domain_m(domain),
+ stencilExtent_m(stencilExtent),
+ intersector_m(intersect)
+ { }
+ This_t &operator=(const This_t &model)
+ {
+ if (this != &model)
+ {
+ intersector_m = model.intersector_m;
+ domain_m = model.domain_m;
+ stencilExtent_m = model.stencilExtent_m;
+ }
+ return *this;
+ }
+ ~StencilIntersector() { }
+ inline DataPtr_t &data() { return intersector_m.data(); }
+ inline const DataPtr_t &data() const { return intersector_m.data(); }
+ inline const_iterator begin() const { return data()->inodes_m.begin(); }
+ inline const_iterator end() const { return data()->inodes_m.end(); }
+ template<class Engine>
+ inline
+ void intersect(const Engine &engine)
+ {
+ typedef typename NewEngine<Engine,Interval<Dim> >::Type_t NewEngine_t;
+ NewEngine_t newEngine(engine, domain_m);
+ intersector_m.intersect(newEngine);
+ data()->shared(engine.layout().ID(),newEngine.layout().ID());
+ }
+ template<class Engine, int Dim2>
+ inline
+ bool intersect(const Engine &engine, const GuardLayers<Dim2> &g,
+ GuardLayers<Dim> &usedGuards)
+ {
+ intersect(engine);
+ usedGuards = stencilExtent_m;
+ return true;
+ }
+ private:
+ Interval<Dim> domain_m;
+ GuardLayers<Dim> stencilExtent_m;
+ Intersect intersector_m;
+ };
+ template <int D, class T, class S, class E, class Intersect>
+ struct LeafFunctor<Engine<D,T,StencilEngine<S,E> >,
+ ExpressionApply<IntersectorTag<Intersect> > >
+ {
+ typedef int Type_t;
+ static
+ Type_t apply(const Engine<D,T,StencilEngine<S,E> > &engine,
+ const ExpressionApply<IntersectorTag<Intersect> > &tag)
+ {
+ typedef StencilIntersector<D, Intersect> NewIntersector_t;
+ GuardLayers<D> stencilExtent;
+ for (int i=0; i<D; ++i) {
+ stencilExtent.lower(i) = engine.function().lowerExtent(i);
+ stencilExtent.upper(i) = engine.function().upperExtent(i);
+ }
+ NewIntersector_t newIntersector(engine.intersectDomain(),
+ tag.tag().intersector_m,
+ stencilExtent);
+ expressionApply(engine.expression(),
+ IntersectorTag<NewIntersector_t>(newIntersector));
+ return 0;
+ }
+ };
+ template<class RequestType> class DataObjectRequest;
+ template <int D, class T, class S, class E, class RequestType>
+ struct EngineFunctor<Engine<D, T, StencilEngine<S, E> >,
+ DataObjectRequest<RequestType> >
+ {
+ typedef typename DataObjectRequest<RequestType>::Type_t Type_t;
+ static Type_t
+ apply(const Engine<D, T, StencilEngine<S, E> > &engine,
+ const DataObjectRequest<RequestType> &tag)
+ {
+ return engineFunctor(engine.expression(), tag);
+ }
+ };
+ template <int D, class T, class S, class E, class Tag>
+ struct LeafFunctor<Engine<D, T, StencilEngine<S, E> >, EngineView<Tag> >
+ {
+ typedef LeafFunctor<E, EngineView<Tag> > LeafFunctor_t;
+ typedef typename LeafFunctor_t::Type_t NewViewed_t;
+ typedef Engine<D, T, StencilEngine<S, NewViewed_t> > Type_t;
+ static
+ Type_t apply(const Engine<D, T, StencilEngine<S, E> > &engine,
+ const EngineView<Tag> &tag)
+ {
+ return Type_t(engine.function(),
+ LeafFunctor_t::apply(engine.expression(), tag));
+ }
+ };
+ template <int D, class T, class S, class E, class Tag>
+ struct LeafFunctor<Engine<D, T, StencilEngine<S, E> >, ExpressionApply<Tag> >
+ {
+ typedef LeafFunctor<E, ExpressionApply<Tag> > LeafFunctor_t;
+ typedef int Type_t;
+ static
+ Type_t apply(const Engine<D, T, StencilEngine<S, E> > &engine,
+ const ExpressionApply<Tag> &tag)
+ {
+ return LeafFunctor_t::apply(engine.expression(), tag);
+ }
+ };
+ namespace Pooma {
+ namespace Algorithms {
+ template <bool type>
+ struct IsConcrete
+ {
+ inline IsConcrete() { }; inline IsConcrete(const IsConcrete &) { }; inline IsConcrete &operator=(const IsConcrete &) { return *this; };
+ };
+ template <class It, class It2>
+ inline It2 copy(It begin, It end, It2 dest)
+ {
+ ;
+ ;
+ typedef typename std::iterator_traits<It>::value_type Value_t;
+ typedef ElementProperties<Value_t> EP_t;
+ typedef IsConcrete<EP_t::concrete> ConcreteType_t;
+ return copy_special(begin, end, dest, ConcreteType_t());
+ }
+ template <class It, class It2>
+ inline It2 copy_special(It begin, It end, It2 dest, IsConcrete<true>)
+ {
+ typedef std::iterator_traits<It> DataTraits_t;
+ typedef typename DataTraits_t::difference_type Diff_t;
+ typedef typename DataTraits_t::value_type Value_t;
+ return std::copy(begin, end, dest);
+ }
+ template <class It, class It2>
+ inline It2 copy_special(It begin, It end, It2 dest, IsConcrete<false>)
+ {
+ typedef typename std::iterator_traits<It>::value_type Value_t;
+ while (begin < end)
+ {
+ ElementProperties<Value_t>::construct(dest++, *begin++);
+ }
+ return dest;
+ }
+ template <class DataIterator, class KillIterator>
+ inline
+ typename std::iterator_traits<DataIterator>::difference_type
+ delete_backfill(DataIterator data_begin, DataIterator data_end,
+ const KillIterator kill_begin, const KillIterator kill_end,
+ typename std::iterator_traits<DataIterator>::difference_type offset = 0)
+ {
+ ;
+ ;
+ std::reverse_iterator<KillIterator> rk_pos(kill_end);
+ std::reverse_iterator<KillIterator> rk_end(kill_begin);
+ typedef std::iterator_traits<DataIterator> DataTraits_t;
+ typedef typename DataTraits_t::difference_type Diff_t;
+ Diff_t last = data_end - data_begin - 1;
+ while (!(rk_pos == rk_end))
+ {
+ if ((*rk_pos - offset) != last) break;
+ --last;
+ ++rk_pos;
+ }
+ DataIterator last_pos = data_begin + last;
+ while (!(rk_pos == rk_end))
+ {
+ *(data_begin + (*rk_pos++ - offset)) = *last_pos--;
+ }
+ return kill_end - kill_begin;
+ }
+ template <class DataIterator, class KillIterator>
+ inline
+ typename std::iterator_traits<DataIterator>::difference_type
+ delete_shiftup(DataIterator data_begin, DataIterator data_end,
+ KillIterator kill_begin, KillIterator kill_end,
+ typename std::iterator_traits<DataIterator>::difference_type offset = 0)
+ {
+ DataIterator insert_pos = data_begin + (*kill_begin - offset);
+ KillIterator kill_pos = kill_begin;
+ typedef std::iterator_traits<DataIterator> DataTraits_t;
+ typedef typename DataTraits_t::value_type Value_t;
+ typedef typename DataTraits_t::difference_type Diff_t;
+ while (kill_pos < kill_end)
+ {
+ Diff_t copy_index = *kill_pos + 1;
+ while ( (kill_pos + 1) < kill_end && copy_index == *(kill_pos + 1) )
+ {
+ ++copy_index;
+ ++kill_pos;
+ }
+ DataIterator copy_begin = data_begin + (copy_index - offset);
+ DataIterator copy_end;
+ if (copy_begin < data_end)
+ {
+ if (kill_pos + 1 < kill_end)
+ copy_end = data_begin + (*(kill_pos + 1) - offset);
+ else
+ copy_end = data_end;
+ const Diff_t length = copy_end - copy_begin;
+ Pooma::Algorithms::copy(copy_begin, copy_end, insert_pos);
+ insert_pos += length;
+ }
+ ++kill_pos;
+ }
+ return kill_end - kill_begin;
+ }
+ template<class DataIterator>
+ inline DataIterator
+ find_most_common(DataIterator dataBegin, DataIterator dataEnd)
+ {
+ DataIterator checkValue, mostCommonValue = dataEnd;
+ int checkCount, count = 0;
+ while (dataBegin != dataEnd)
+ {
+ checkValue = dataBegin++;
+ checkCount = 1;
+ while (dataBegin != dataEnd && *dataBegin == *checkValue)
+ {
+ ++checkCount;
+ ++dataBegin;
+ }
+ if (checkCount > count)
+ {
+ mostCommonValue = checkValue;
+ count = checkCount;
+ }
+ }
+ return mostCommonValue;
+ }
+ }
+ }
+ template<class Tag>
+ struct Remote
+ { };
+ template <int Dim, class T, class Tag>
+ class Engine<Dim, T, Remote<Tag> >
+ {
+ public:
+ typedef Engine<Dim, T, Remote<Tag> > This_t;
+ typedef Engine<Dim, T, Remote<Tag> > Engine_t;
+ typedef Engine<Dim, T, Tag> LocalEngine_t;
+ typedef Interval<Dim> Domain_t;
+ typedef T Element_t;
+ typedef RemoteProxy<T> ElementRef_t;
+ typedef Remote<Tag> Tag_t;
+ typedef DomainLayout<Dim> Layout_t;
+ enum { dimensions = Dim };
+ enum { hasDataObject = true };
+ enum { dynamic = false };
+ enum { zeroBased = false };
+ enum { multiPatch = false };
+ typedef Shared<LocalEngine_t> LocalShared_t;
+ typedef RefCountedPtr<LocalShared_t> LocalPtr_t;
+ Engine();
+ explicit
+ Engine(const Domain_t &domain);
+ Engine(int owningContext, const Domain_t &domain);
+ Engine(const Domain_t &domain, const T &elementModel);
+ explicit
+ Engine(const Node<Domain_t> &node);
+ explicit
+ Engine(const Layout_t &layout);
+ Engine(const Engine_t &model);
+ Engine(const Engine_t &, const EngineConstructTag &);
+ template<class OtherEngine, class Domain>
+ Engine(const OtherEngine &otherEngine, const Domain &domain);
+ template<class OtherEngine, int D2>
+ Engine(const OtherEngine &otherEngine,
+ const SliceRange<D2, Dim> &domain);
+ ~Engine();
+ Engine_t &operator=(const Engine_t &model);
+ Element_t read(const Loc<Dim> &) const;
+ ElementRef_t operator()(const Loc<Dim> &) const;
+ Element_t read(int) const;
+ Element_t read(int, int) const;
+ Element_t read(int, int, int) const;
+ Element_t read(int, int, int, int) const;
+ Element_t read(int, int, int, int, int) const;
+ Element_t read(int, int, int, int, int, int) const;
+ Element_t read(int, int, int, int, int, int, int) const;
+ ElementRef_t operator()(int) const;
+ ElementRef_t operator()(int, int) const;
+ ElementRef_t operator()(int, int, int) const;
+ ElementRef_t operator()(int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int, int) const;
+ ElementRef_t operator()(int, int, int, int, int, int, int) const;
+ inline const Domain_t &domain() const
+ {
+ return domain_m;
+ }
+ inline
+ bool engineIsLocal() const
+ {
+ return (Pooma::context() == owningContext_m);
+ }
+ inline
+ int owningContext() const
+ {
+ return owningContext_m;
+ }
+ inline
+ const LocalEngine_t &localEngine() const
+ {
+ ;
+ ;
+ return (*localEnginePtr_m).data();
+ }
+ inline
+ LocalEngine_t &localEngine()
+ {
+ ;
+ ;
+ return (*localEnginePtr_m).data();
+ }
+ inline int first(int i) const
+ {
+ return domain_m[i].first();
+ }
+ inline
+ Engine_t &makeOwnCopy()
+ {
+ if (engineIsLocal() && localEnginePtr_m.isValid())
+ {
+ LocalEngine_t engine(localEngine());
+ engine.makeOwnCopy();
+ localEnginePtr_m = LocalPtr_t(new LocalShared_t(engine));
+ }
+ return *this;
+ }
+ protected:
+ Domain_t domain_m;
+ private:
+ int owningContext_m;
+ LocalPtr_t localEnginePtr_m;
+ };
+ template <int Dim, class T, class Tag>
+ inline T Engine<Dim, T, Remote<Tag> >::
+ read(const Loc<Dim> &loc) const
+ {
+ T value;
+ if (engineIsLocal())
+ {
+ value = localEngine().read(loc);
+ }
+ return ElementRef_t(value, owningContext());
+ }
+ template <int Dim, class T, class Tag>
+ inline T Engine<Dim, T, Remote<Tag> >::
+ read(int i1) const
+ {
+ ;
+ T value;
+ if (engineIsLocal())
+ {
+ value = localEngine().read(i1);
+ }
+ return ElementRef_t(value, owningContext());
+ }
+ template <int Dim, class T, class Tag>
+ inline T Engine<Dim, T, Remote<Tag> >::
+ read(int i1, int i2) const
+ {
+ ;
+ T value;
+ if (engineIsLocal())
+ {
+ value = localEngine().read(i1, i2);
+ }
+ return ElementRef_t(value, owningContext());
+ }
+ template <int Dim, class T, class Tag>
+ inline T Engine<Dim, T, Remote<Tag> >::
+ read(int i1, int i2, int i3) const
+ {
+ ;
+ T value;
+ if (engineIsLocal())
+ {
+ value = localEngine().read(i1, i2, i3);
+ }
+ return ElementRef_t(value, owningContext());
+ }
+ template <int Dim, class T, class Tag>
+ inline T Engine<Dim, T, Remote<Tag> >::
+ read(int i1, int i2, int i3, int i4) const
+ {
+ ;
+ T value;
+ if (engineIsLocal())
+ {
+ value = localEngine().read(i1, i2, i3, i4);
+ }
+ return ElementRef_t(value, owningContext());
+ }
+ template <int Dim, class T, class Tag>
+ inline T Engine<Dim, T, Remote<Tag> >::
+ read(int i1, int i2, int i3, int i4, int i5) const
+ {
+ ;
+ T value;
+ if (engineIsLocal())
+ {
+ value = localEngine().read(i1, i2, i3, i4, i5);
+ }
+ return ElementRef_t(value, owningContext());
+ }
+ template <int Dim, class T, class Tag>
+ inline T Engine<Dim, T, Remote<Tag> >::
+ read(int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ ;
+ T value;
+ if (engineIsLocal())
+ {
+ value = localEngine().read(i1, i2, i3, i4, i5, i6);
+ }
+ return ElementRef_t(value, owningContext());
+ }
+ template <int Dim, class T, class Tag>
+ inline T Engine<Dim, T, Remote<Tag> >::
+ read(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
+ {
+ ;
+ T value;
+ if (engineIsLocal())
+ {
+ value = localEngine().read(i1, i2, i3, i4, i5, i6, i7);
+ }
+ return ElementRef_t(value, owningContext());
+ }
+ template <int Dim, class T, class Tag>
+ inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
+ operator()(const Loc<Dim> &loc) const
+ {
+ if (engineIsLocal())
+ {
+ T &value = localEngine()(loc);
+ return ElementRef_t(value, owningContext());
+ }
+ else
+ {
+ T val;
+ return ElementRef_t(val, owningContext());
+ }
+ }
+ template <int Dim, class T, class Tag>
+ inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
+ operator()(int i1) const
+ {
+ ;
+ if (engineIsLocal())
+ {
+ T &value = localEngine()(i1);
+ return ElementRef_t(value, owningContext());
+ }
+ else
+ {
+ T val;
+ return ElementRef_t(val, owningContext());
+ }
+ }
+ template <int Dim, class T, class Tag>
+ inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
+ operator()(int i1, int i2) const
+ {
+ ;
+ if (engineIsLocal())
+ {
+ T &value = localEngine()(i1, i2);
+ return ElementRef_t(value, owningContext());
+ }
+ else
+ {
+ T val;
+ return ElementRef_t(val, owningContext());
+ }
+ }
+ template <int Dim, class T, class Tag>
+ inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
+ operator()(int i1, int i2, int i3) const
+ {
+ ;
+ if (engineIsLocal())
+ {
+ T &value = localEngine()(i1, i2, i3);
+ return ElementRef_t(value, owningContext());
+ }
+ else
+ {
+ T val;
+ return ElementRef_t(val, owningContext());
+ }
+ }
+ template <int Dim, class T, class Tag>
+ inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
+ operator()(int i1, int i2, int i3, int i4) const
+ {
+ ;
+ if (engineIsLocal())
+ {
+ T &value = localEngine()(i1, i2, i3, i4);
+ return ElementRef_t(value, owningContext());
+ }
+ else
+ {
+ T val;
+ return ElementRef_t(val, owningContext());
+ }
+ }
+ template <int Dim, class T, class Tag>
+ inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
+ operator()(int i1, int i2, int i3, int i4, int i5) const
+ {
+ ;
+ if (engineIsLocal())
+ {
+ T &value = localEngine()(i1, i2, i3, i4, i5);
+ return ElementRef_t(value, owningContext());
+ }
+ else
+ {
+ T val;
+ return ElementRef_t(val, owningContext());
+ }
+ }
+ template <int Dim, class T, class Tag>
+ inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
+ operator()(int i1, int i2, int i3, int i4, int i5, int i6) const
+ {
+ ;
+ if (engineIsLocal())
+ {
+ T &value = localEngine()(i1, i2, i3, i4, i5, i6);
+ return ElementRef_t(value, owningContext());
+ }
+ else
+ {
+ T val;
+ return ElementRef_t(val, owningContext());
+ }
+ }
+ template <int Dim, class T, class Tag>
+ inline RemoteProxy<T> Engine<Dim, T, Remote<Tag> >::
+ operator()(int i1, int i2, int i3, int i4, int i5, int i6, int i7) const
+ {
+ ;
+ if (engineIsLocal())
+ {
+ T &value = localEngine()(i1, i2, i3, i4, i5, i6, i7);
+ return ElementRef_t(value, owningContext());
+ }
+ else
+ {
+ T val;
+ return ElementRef_t(val, owningContext());
+ }
+ }
+ template <int Dim, class T, class Tag>
+ Engine<Dim, T, Remote<Tag> >::Engine()
+ : owningContext_m(0)
+ {
+ ;
+ }
+ template <int Dim, class T, class Tag>
+ Engine<Dim, T, Remote<Tag> >::Engine(const Node<Domain_t> &node)
+ : domain_m(node.allocated()),
+ owningContext_m(node.context())
+ {
+ ;
+ if (engineIsLocal())
+ {
+ localEnginePtr_m = LocalPtr_t(new LocalShared_t(LocalEngine_t(node)));
+ }
+ }
+ template <int Dim, class T, class Tag>
+ Engine<Dim, T, Remote<Tag> >::Engine(const Layout_t &layout)
+ : domain_m(layout.node().allocated()),
+ owningContext_m(0)
+ {
+ ;
+ if (engineIsLocal())
+ {
+ localEnginePtr_m = LocalPtr_t(new LocalShared_t(LocalEngine_t(layout.
+ node())));
+ }
+ }
+ template <int Dim, class T, class Tag>
+ Engine<Dim, T, Remote<Tag> >::Engine(const Domain_t &dom)
+ : domain_m(dom), owningContext_m(0)
+ {
+ if (engineIsLocal())
+ {
+ localEnginePtr_m = LocalPtr_t(new LocalShared_t(LocalEngine_t(domain_m)));
+ }
+ }
+ template <int Dim, class T, class Tag>
+ Engine<Dim, T, Remote<Tag> >::Engine(int owningContext, const Domain_t &dom)
+ : domain_m(dom),
+ owningContext_m(owningContext)
+ {
+ if (engineIsLocal())
+ {
+ localEnginePtr_m = LocalPtr_t(new LocalShared_t(LocalEngine_t(domain_m)));
+ }
+ }
+ template <int Dim, class T, class Tag>
+ Engine<Dim, T, Remote<Tag> >::Engine(const Domain_t &dom, const T& model)
+ : domain_m(dom), owningContext_m(0)
+ {
+ if (engineIsLocal())
+ {
+ localEnginePtr_m =
+ LocalPtr_t(new LocalShared_t(LocalEngine_t(domain_m, model)));
+ }
+ }
+ template <int Dim, class T, class Tag>
+ Engine<Dim, T, Remote<Tag> >::
+ Engine(const Engine<Dim, T, Remote<Tag> > &modelEngine)
+ : domain_m(modelEngine.domain()),
+ owningContext_m(modelEngine.owningContext()),
+ localEnginePtr_m(modelEngine.localEnginePtr_m)
+ {
+ }
+ template <int Dim, class T, class Tag>
+ Engine<Dim, T, Remote<Tag> >::
+ Engine(const Engine<Dim, T, Remote<Tag> > &modelEngine,
+ const EngineConstructTag &)
+ : domain_m(modelEngine.domain()),
+ owningContext_m(modelEngine.owningContext()),
+ localEnginePtr_m(modelEngine.localEnginePtr_m)
+ {
+ }
+ template <int Dim, class T, class Tag>
+ template<class OtherEngine, class Domain>
+ Engine<Dim, T, Remote<Tag> >::
+ Engine(const OtherEngine &otherEngine, const Domain &domain)
+ : owningContext_m(otherEngine.owningContext())
+ {
+ if (engineIsLocal())
+ {
+ localEnginePtr_m =
+ LocalPtr_t(new LocalShared_t(LocalEngine_t(otherEngine.localEngine(),
+ domain)));
+ }
+ int i;
+ for (i = 0; i < Dim; ++i)
+ {
+ domain_m[i] = Interval<1>(domain[i].length());
+ }
+ }
+ template <int Dim, class T, class Tag>
+ template<class OtherEngine, int D2>
+ Engine<Dim, T, Remote<Tag> >::
+ Engine(const OtherEngine &otherEngine, const SliceRange<D2, Dim> &domain)
+ : owningContext_m(otherEngine.owningContext())
+ {
+ if (engineIsLocal())
+ {
+ localEnginePtr_m =
+ LocalPtr_t(new LocalShared_t(LocalEngine_t(otherEngine.localEngine(),
+ domain)));
+ }
+ int i;
+ for (i = 0; i < Dim; ++i)
+ {
+ domain_m[i] = Interval<1>(domain.totalDomain()[i].length());
+ }
+ }
+ template <int Dim, class T, class Tag>
+ Engine<Dim, T, Remote<Tag> > &
+ Engine<Dim, T, Remote<Tag> >::
+ operator=(const Engine<Dim, T, Remote<Tag> > &modelEngine)
+ {
+ if (this == &modelEngine)
+ return *this;
+ owningContext_m = modelEngine.owningContext_m;
+ domain_m = modelEngine.domain_m;
+ localEnginePtr_m = modelEngine.localEnginePtr_m;
+ return *this;
+ }
+ template <int Dim, class T, class Tag>
+ Engine<Dim, T, Remote<Tag> >::~Engine()
+ {
+ }
+ template<int Dim, class T, class Tag, class Domain>
+ struct NewEngine<Engine<Dim, T, Remote<Tag> >, Domain>
+ {
+ typedef typename NewEngine<Engine<Dim, T, Tag>, Domain>::Type_t Local_t;
+ typedef typename Local_t::Tag_t NewTag_t;
+ enum { newDim = Local_t::dimensions };
+ typedef Engine<newDim, T, Remote<NewTag_t> > Type_t;
+ };
+ template<int Dim, class T, class Tag>
+ struct NewEngineDomain<Engine<Dim, T, Remote<Tag> >, INode<Dim> >
+ {
+ typedef const Interval<Dim> &Type_t;
+ static inline const Interval<Dim> &
+ apply(const Engine<Dim, T, Remote<Tag> > &,
+ const INode<Dim> &i)
+ {
+ return i.domain();
+ }
+ };
+ struct RemoteView { };
+ template<>
+ struct EngineView<RemoteView>
+ {
+ typedef TreeCombine Combine_t;
+ };
+ struct RemoteSend
+ {
+ RemoteSend(int n) : toContext_m(n) { }
+ inline int toContext() const { return toContext_m; }
+ int toContext_m;
+ };
+ template<class Engine>
+ struct DefaultExpressionApply<Engine, RemoteSend >
+ {
+ typedef Engine Subject_t;
+ typedef int Type_t;
+ static inline
+ Type_t apply(const Subject_t &engine,
+ const ExpressionApply<RemoteSend> &)
+ {
+ return 0;
+ }
+ };
+ template<class Engine>
+ struct DefaultEngineView<Engine, RemoteView>
+ {
+ typedef Engine Subject_t;
+ typedef Engine Type_t;
+ static inline
+ Type_t apply(const Subject_t &engine,
+ const EngineView<RemoteView> &)
+ {
+ return engine;
+ }
+ };
+ template<int Dim, class T, class Tag>
+ struct LeafFunctor<Engine<Dim, T, Remote<Tag> >, ExpressionApply<RemoteSend> >
+ {
+ typedef Engine<Dim, T, Remote<Tag> > Subject_t;
+ typedef int Type_t;
+ static inline
+ Type_t apply(const Subject_t &engine,
+ const ExpressionApply<RemoteSend> &sendTag)
+ {
+ if (engine.engineIsLocal())
+ {
+ if (sendTag.tag().toContext() == -1)
+ {
+ for (int i = 0; i < Pooma::contexts(); i++)
+ if (i != Pooma::context())
+ SendReceive::send(engine.localEngine(), i);
+ }
+ else
+ {
+ if (Pooma::context() != sendTag.tag().toContext())
+ SendReceive::send(engine.localEngine(), sendTag.tag().toContext());
+ }
+ }
+ return 0;
+ }
+ };
+ template<int Dim, class T, class Tag>
+ struct LeafFunctor<Engine<Dim, T, Remote<Tag> >, EngineView<RemoteView> >
+ {
+ };
+ template<int Dim, class T>
+ struct LeafFunctor<Engine<Dim, T, Remote<Brick> >, EngineView<RemoteView> >
+ {
+ typedef Engine<Dim, T, Remote<Brick> > Subject_t;
+ typedef Engine<Dim, T, Brick> Type_t;
+ static inline
+ Type_t apply(const Subject_t &engine,
+ const EngineView<RemoteView> &)
+ {
+ if (engine.engineIsLocal())
+ {
+ return engine.localEngine();
+ }
+ else
+ {
+ Type_t local(engine.domain());
+ Receive<Type_t>::receive(local, engine.owningContext());
+ return local;
+ }
+ }
+ };
+ template<int Dim, class T>
+ struct LeafFunctor<Engine<Dim, T, Remote<BrickView> >,
+ EngineView<RemoteView> >
+ {
+ typedef Engine<Dim, T, Remote<BrickView> > Subject_t;
+ typedef Engine<Dim, T, Brick> IncomingView_t;
+ typedef Engine<Dim, T, Brick> Brick_t;
+ typedef Engine<Dim, T, BrickView> Type_t;
+ static inline
+ Type_t apply(const Subject_t &engine,
+ const EngineView<RemoteView> &)
+ {
+ if (engine.engineIsLocal())
+ {
+ return engine.localEngine();
+ }
+ else
+ {
+ Interval<Dim> dom = engine.domain();
+ Brick_t local(dom);
+ Type_t view(local, dom);
+ Receive<IncomingView_t>::receive(view, engine.owningContext());
+ return view;
+ }
+ }
+ };
+ template<int Dim, class T>
+ struct LeafFunctor<Engine<Dim, T, Remote<BrickViewU> >,
+ EngineView<RemoteView> >
+ {
+ typedef Engine<Dim, T, Remote<BrickViewU> > Subject_t;
+ typedef Engine<Dim, T, Brick> IncomingView_t;
+ typedef Engine<Dim, T, Brick> Brick_t;
+ typedef Engine<Dim, T, BrickViewU> Type_t;
+ static inline
+ Type_t apply(const Subject_t &engine,
+ const EngineView<RemoteView> &)
+ {
+ if (engine.engineIsLocal())
+ {
+ return engine.localEngine();
+ }
+ else
+ {
+ Interval<Dim> dom = engine.domain();
+ Brick_t local(dom);
+ Type_t view(local, dom);
+ Receive<IncomingView_t>::receive(view, engine.owningContext());
+ return view;
+ }
+ }
+ };
+ template<int Dim, class T>
+ struct LeafFunctor<Engine<Dim, T, Remote<CompressibleBrick> >,
+ EngineView<RemoteView> >
+ {
+ typedef Engine<Dim, T, Remote<CompressibleBrick> > Subject_t;
+ typedef Engine<Dim, T, CompressibleBrick> Type_t;
+ static inline
+ Type_t apply(const Subject_t &engine, const EngineView<RemoteView> &)
+ {
+ if (engine.engineIsLocal())
+ {
+ return engine.localEngine();
+ }
+ else
+ {
+ Type_t local(engine.domain());
+ Receive<Type_t>::receive(local, engine.owningContext());
+ return local;
+ }
+ }
+ };
+ template<int Dim, class T>
+ struct LeafFunctor<Engine<Dim, T, Remote<CompressibleBrickView> >,
+ EngineView<RemoteView> >
+ {
+ typedef Engine<Dim, T, Remote<CompressibleBrickView> > Subject_t;
+ typedef Engine<Dim, T, CompressibleBrick> CompBrick_t;
+ typedef Engine<Dim, T, CompressibleBrickView> Type_t;
+ static inline
+ Type_t apply(const Subject_t &engine, const EngineView<RemoteView> &)
+ {
+ if (engine.engineIsLocal())
+ {
+ return engine.localEngine();
+ }
+ else
+ {
+ Interval<Dim> dom = engine.domain();
+ CompBrick_t local(dom);
+ Type_t view(local, dom);
+ Receive<Type_t>::receive(view, engine.owningContext());
+ return view;
+ }
+ }
+ };
+ struct EngineBlockSerialize
+ {
+ template<class Op, class Eng>
+ inline static /*__attribute__((leafify))*/
+ int apply(Op &op, const Eng &engine)
+ {
+ typedef typename Eng::Domain_t Domain_t;
+ return apply(op, engine, engine.domain(),
+ WrappedInt<Domain_t::dimensions>());
+ }
+ template<class Op, class Eng, class Dom>
+ inline static /*__attribute__((leafify))*/
+ int apply(Op &op, const Eng &engine, const Dom &domain)
+ {
+ return apply(op, engine, domain,
+ WrappedInt<Dom::dimensions>());
+ }
+ template<class Op,class Eng,class Domain>
+ inline static int apply(Op &op,const Eng &engine,
+ const Domain &domain, WrappedInt<1>)
+ {
+ PoomaCTAssert<(Domain::unitStride == 1)>::test();
+ int f0 = domain[0].first();
+ int e0 = domain[0].last();
+ for (int i0 = f0; i0<=e0; ++i0)
+ op(engine(i0));
+ return op.total_m;
+ }
+ template<class Op,class Eng,class Domain>
+ inline static int apply(Op &op,const Eng &engine,
+ const Domain &domain,WrappedInt<2>)
+ {
+ PoomaCTAssert<(Domain::unitStride == 1)>::test();
+ int f0 = domain[0].first();
+ int f1 = domain[1].first();
+ int e0 = domain[0].last();
+ int e1 = domain[1].last();
+ for (int i1 = f1; i1<=e1; ++i1)
+ for (int i0 = f0; i0<=e0; ++i0)
+ op(engine(i0,i1));
+ return op.total_m;
+ }
+ template<class Op,class Eng,class Domain>
+ inline static int apply(Op &op,const Eng &engine,
+ const Domain &domain,WrappedInt<3>)
+ {
+ PoomaCTAssert<(Domain::unitStride == 1)>::test();
+ int f0 = domain[0].first();
+ int f1 = domain[1].first();
+ int f2 = domain[2].first();
+ int e0 = domain[0].last();
+ int e1 = domain[1].last();
+ int e2 = domain[2].last();
+ for (int i2 = f2; i2<=e2; ++i2)
+ for (int i1 = f1; i1<=e1; ++i1)
+ for (int i0 = f0; i0<=e0; ++i0)
+ op(engine(i0,i1,i2));
+ return op.total_m;
+ }
+ template<class Op,class Eng,class Domain>
+ inline static int apply(Op &op,const Eng &engine,
+ const Domain &domain,WrappedInt<4>)
+ {
+ PoomaCTAssert<(Domain::unitStride == 1)>::test();
+ int f0 = domain[0].first();
+ int f1 = domain[1].first();
+ int f2 = domain[2].first();
+ int f3 = domain[3].first();
+ int e0 = domain[0].last();
+ int e1 = domain[1].last();
+ int e2 = domain[2].last();
+ int e3 = domain[3].last();
+ for (int i3 = f3; i3<=e3; ++i3)
+ for (int i2 = f2; i2<=e2; ++i2)
+ for (int i1 = f1; i1<=e1; ++i1)
+ for (int i0 = f0; i0<=e0; ++i0)
+ op(engine(i0,i1,i2,i3));
+ return op.total_m;
+ }
+ template<class Op,class Eng,class Domain>
+ inline static int apply(Op &op,const Eng &engine,
+ const Domain &domain,WrappedInt<5>)
+ {
+ PoomaCTAssert<(Domain::unitStride == 1)>::test();
+ int f0 = domain[0].first();
+ int f1 = domain[1].first();
+ int f2 = domain[2].first();
+ int f3 = domain[3].first();
+ int f4 = domain[4].first();
+ int e0 = domain[0].last();
+ int e1 = domain[1].last();
+ int e2 = domain[2].last();
+ int e3 = domain[3].last();
+ int e4 = domain[4].last();
+ for (int i4 = f4; i4<=e4; ++i4)
+ for (int i3 = f3; i3<=e3; ++i3)
+ for (int i2 = f2; i2<=e2; ++i2)
+ for (int i1 = f1; i1<=e1; ++i1)
+ for (int i0 = f0; i0<=e0; ++i0)
+ op(engine(i0,i1,i2,i3,i4));
+ return op.total_m;
+ }
+ template<class Op,class Eng,class Domain>
+ inline static int apply(Op &op,const Eng &engine,
+ const Domain &domain,WrappedInt<6>)
+ {
+ PoomaCTAssert<(Domain::unitStride == 1)>::test();
+ int f0 = domain[0].first();
+ int f1 = domain[1].first();
+ int f2 = domain[2].first();
+ int f3 = domain[3].first();
+ int f4 = domain[4].first();
+ int f5 = domain[5].first();
+ int e0 = domain[0].last();
+ int e1 = domain[1].last();
+ int e2 = domain[2].last();
+ int e3 = domain[3].last();
+ int e4 = domain[4].last();
+ int e5 = domain[5].last();
+ for (int i5 = f5; i5<=e5; ++i5)
+ for (int i4 = f4; i4<=e4; ++i4)
+ for (int i3 = f3; i3<=e3; ++i3)
+ for (int i2 = f2; i2<=e2; ++i2)
+ for (int i1 = f1; i1<=e1; ++i1)
+ for (int i0 = f0; i0<=e0; ++i0)
+ op(engine(i0,i1,i2,i3,i4,i5));
+ return op.total_m;
+ }
+ template<class Op,class Eng,class Domain>
+ inline static int apply(Op &op,const Eng &engine,
+ const Domain &domain,WrappedInt<7>)
+ {
+ PoomaCTAssert<(Domain::unitStride == 1)>::test();
+ int f0 = domain[0].first();
+ int f1 = domain[1].first();
+ int f2 = domain[2].first();
+ int f3 = domain[3].first();
+ int f4 = domain[4].first();
+ int f5 = domain[5].first();
+ int f6 = domain[6].first();
+ int e0 = domain[0].last();
+ int e1 = domain[1].last();
+ int e2 = domain[2].last();
+ int e3 = domain[3].last();
+ int e4 = domain[4].last();
+ int e5 = domain[5].last();
+ int e6 = domain[6].last();
+ for (int i6 = f6; i6<=e6; ++i6)
+ for (int i5 = f5; i5<=e5; ++i5)
+ for (int i4 = f4; i4<=e4; ++i4)
+ for (int i3 = f3; i3<=e3; ++i3)
+ for (int i2 = f2; i2<=e2; ++i2)
+ for (int i1 = f1; i1<=e1; ++i1)
+ for (int i0 = f0; i0<=e0; ++i0)
+ op(engine(i0,i1,i2,i3,i4,i5,i6));
+ return op.total_m;
+ }
+ private:
+ };
+ template <int Dim, class T, class Tag>
+ long elementsCompressed(const Engine<Dim, T, Remote<Tag> > &engine)
+ {
+ return elementsCompressed(engine.localEngine());
+ }
+ template <int Dim, class T, class Tag>
+ void compress(Engine<Dim, T, Remote<Tag> > &engine)
+ {
+ compress(engine.localEngine());
+ }
+ template <int Dim, class T, class Tag>
+ void uncompress(Engine<Dim, T, Remote<Tag> > &engine)
+ {
+ uncompress(engine.localEngine());
+ }
+ template <int Dim, class T, class Tag>
+ bool compressed(const Engine<Dim, T, Remote<Tag> > &engine)
+ {
+ return compressed(engine.localEngine());
+ }
+ class GatherContexts
+ {
+ private:
+ class GatherContextsData : public RefCounted
+ {
+ public:
+ inline GatherContextsData() {}
+ inline GatherContextsData(const GatherContextsData &model)
+ : contexts_m(model.contexts_m) {}
+ inline ~GatherContextsData() {}
+ void addContext(int c) const
+ {
+ if (c != -1)
+ {
+ if (contexts_m.empty())
+ contexts_m.reserve(4);
+ contexts_m.push_back(c);
+ }
+ }
+ int mostCommonContext() const
+ {
+ if (contexts_m.size() != 0)
+ {
+ std::sort(contexts_m.begin(), contexts_m.end());
+ return
+ *Pooma::Algorithms::find_most_common(contexts_m.begin(),
+ contexts_m.end());
+ }
+ else
+ {
+ return -1;
+ }
+ }
+ private:
+ mutable std::vector<int> contexts_m;
+ };
+ public:
+ typedef NullCombine Combine_t;
+ inline GatherContexts()
+ : data_m(new GatherContextsData) {}
+ inline GatherContexts(const GatherContexts &model)
+ : data_m(model.data_m) { }
+ GatherContexts &operator=(const GatherContexts &rhs)
+ {
+ data_m = rhs.data_m;
+ return *this;
+ }
+ inline ~GatherContexts() {}
+ inline void addContext(int c) const
+ { data_m->addContext(c); }
+ inline int mostCommonContext() const
+ { return data_m->mostCommonContext(); }
+ private:
+ RefCountedPtr<GatherContextsData> data_m;
+ };
+ template<class T>
+ struct EngineFunctorScalar<T, GatherContexts>
+ {
+ typedef int Type_t;
+ static inline
+ Type_t apply(const T &, const GatherContexts &)
+ {
+ return 0;
+ }
+ };
+ template<class Engine>
+ struct EngineFunctorDefault<Engine, GatherContexts>
+ {
+ typedef Engine Subject_t;
+ typedef int Type_t;
+ static inline
+ Type_t apply(const Subject_t &, const GatherContexts &)
+ {
+ return 0;
+ }
+ };
+ template<int Dim, class T, class Tag>
+ struct EngineFunctor<Engine<Dim, T, Remote<Tag> >, GatherContexts>
+ {
+ typedef Engine<Dim, T, Remote<Tag> > Subject_t;
+ typedef int Type_t;
+ static inline
+ Type_t apply(const Subject_t &engine, const GatherContexts &tag)
+ {
+ tag.addContext(engine.owningContext());
+ return 0;
+ }
+ };
+ template <>
+ struct Evaluator<RemoteSinglePatchEvaluatorTag>
+ {
+ Evaluator() { }
+ ~Evaluator() { }
+ template <class LHS, class RHS, class Op>
+ void evaluate(const LHS &lhs, const Op &op, const RHS &rhs) const
+ {
+ GatherContexts gtag;
+ engineFunctor(lhs.engine(), gtag);
+ int lhsContext = gtag.mostCommonContext();
+ expressionApply(rhs, RemoteSend(lhsContext));
+ if (lhsContext == -1 || Pooma::context() == lhsContext)
+ {
+ EngineView<RemoteView> view;
+ Evaluator<SinglePatchEvaluatorTag>().
+ evaluate(forEach(lhs, view, TreeCombine()), op,
+ forEach(rhs, view, TreeCombine()));
+ }
+ else
+ {
+ }
+ }
+ };
+ template <>
+ struct Evaluator<RemoteMultiPatchEvaluatorTag>
+ {
+ Evaluator() { }
+ ~Evaluator() { }
+ template <class LHS, class RHS, class Op>
+ void evaluate(const LHS &lhs, const Op &op, const RHS &rhs) const
+ {
+ typedef Intersector<LHS::dimensions> Inter_t;
+ Inter_t inter;
+ expressionApply(lhs, IntersectorTag<Inter_t>(inter));
+ expressionApply(rhs, IntersectorTag<Inter_t>(inter));
+ typename Inter_t::const_iterator i = inter.begin();
+ while (i != inter.end())
+ {
+ Evaluator<RemoteSinglePatchEvaluatorTag>().
+ evaluate(lhs(*i), op, rhs(*i));
+ ++i;
+ }
+ }
+ };
+ template <>
+ struct Reduction<RemoteSinglePatchEvaluatorTag>
+ {
+ Reduction() { }
+ ~Reduction() { }
+ template<class T, class Op, class Expr>
+ void evaluate(T &ret, const Op &op, const Expr &e) const
+ {
+ GatherContexts gtag;
+ engineFunctor(e.engine(), gtag);
+ int computationContext = gtag.mostCommonContext();
+ Pooma::CountingSemaphore csem;
+ csem.height(1);
+ if (Pooma::context() != computationContext)
+ {
+ expressionApply(e, RemoteSend(computationContext));
+ csem.incr();
+ }
+ else
+ {
+ EngineView<RemoteView> view;
+ Reduction<SinglePatchEvaluatorTag>().
+ evaluate(ret, op,
+ forEach(e, view, TreeCombine()), csem);
+ }
+ csem.wait();
+ Pooma::scheduler().endGeneration();
+ Pooma::blockAndEvaluate();
+ Pooma::scheduler().beginGeneration();
+ RemoteProxy<T> globalRet(ret, computationContext);
+ ret = globalRet;
+ }
+ };
+ template <>
+ struct Reduction<RemoteMultiPatchEvaluatorTag>
+ {
+ Reduction() { }
+ ~Reduction() { }
+ template<class T, class Op, class Expr>
+ void evaluate(T &ret, const Op &op, const Expr &e) const
+ {
+ typedef Intersector<Expr::dimensions> Inter_t;
+ Inter_t inter;
+ expressionApply(e, IntersectorTag<Inter_t>(inter));
+ std::vector<bool> present(inter.size());
+ std::vector<int> computationalContext(inter.size());
+ typename Inter_t::const_iterator i = inter.begin();
+ int j, k, n = 0;
+ for (j = 0; j < inter.size(); j++)
+ {
+ present[j] = i->contextParticipates(Pooma::context());
+ if (present[j])
+ {
+ computationalContext[j] = i->context();
+ if (computationalContext[j] == Pooma::context())
+ ++n;
+ }
+ ++i;
+ }
+ Pooma::CountingSemaphore csem;
+ csem.height(n);
+ T *vals = new T[n];
+ i = inter.begin();
+ k = 0;
+ for (j = 0; j < inter.size(); j++)
+ {
+ if (present[j])
+ {
+ if (computationalContext[j] == Pooma::context())
+ {
+ EngineView<RemoteView> view;
+ Reduction<SinglePatchEvaluatorTag>().
+ evaluate(vals[k++], op,
+ forEach(e(*i).engine(), view, TreeCombine()), csem);
+ }
+ else
+ {
+ expressionApply(e(*i), RemoteSend(computationalContext[j]));
+ }
+ }
+ ++i;
+ }
+ ;
+ csem.wait();
+ Pooma::scheduler().endGeneration();
+ Pooma::blockAndEvaluate();
+ Pooma::scheduler().beginGeneration();
+ if (n > 0)
+ {
+ ret = vals[0];
+ for (j = 1; j < n; j++)
+ op(ret, vals[j]);
+ }
+ delete [] vals;
+ ReduceOverContexts<T, Op> finalReduction(ret, 0, n > 0);
+ if (Pooma::context() == 0)
+ ret = finalReduction;
+ RemoteProxy<T> broadcast(ret, 0);
+ ret = broadcast;
+ }
+ };
+ template <int Dim, class T, class LayoutTag, class Tag>
+ struct EngineFunctor<Engine<Dim, T, MultiPatch<LayoutTag, Remote<Tag> > >,
+ EnginePatch >
+ {
+ typedef Engine<Dim, T, MultiPatch<LayoutTag, Remote<Tag> > > Subject_t;
+ typedef Engine<Dim, T, Tag> Type_t;
+ static inline
+ Type_t apply(const Subject_t &engine, const EnginePatch &tag)
+ {
+ return engine.localPatch(tag.patch_m).localEngine();
+ }
+ };
+ template <int Dim, class T, class Eng>
+ struct ElementProperties<Engine<Dim, T, Remote<Eng> > >
+ : public MakeOwnCopyProperties<Engine<Dim, T, Remote<Eng> > >
+ { };
+ class Full;
+ template<int D1, int D2, class T, class E> class TinyMatrix;
+ template<int D1, int D2, class T, class E> class TinyMatrixEngine;
+ template<class V, int I, int J>
+ struct TinyMatrixElem
+ {
+ typedef V Element_t;
+ typedef const V& ConstElementRef_t;
+ typedef V& ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return x; }
+ static ElementRef_t get( V& x) { return x; }
+ };
+ template<int D1, int D2, class T, class E, int I, int J>
+ struct TinyMatrixEngineElem
+ {
+ typedef TinyMatrixEngine<D1,D2,T,E> V;
+ typedef typename V::Element_t Element_t;
+ typedef typename V::ConstElementRef_t ConstElementRef_t;
+ typedef typename V::ElementRef_t ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return x(I,J); }
+ static ElementRef_t get( V& x) { return x(I,J); }
+ };
+ template<int D1, int D2, class T, class E, int I, int J>
+ struct TinyMatrixElem< TinyMatrix<D1,D2,T,E> , I , J>
+ {
+ typedef TinyMatrix<D1,D2,T,E> V;
+ typedef TinyMatrixEngineElem<D1,D2,T,E,I,J> TE;
+ typedef typename TE::Element_t Element_t;
+ typedef typename TE::ConstElementRef_t ConstElementRef_t;
+ typedef typename TE::ElementRef_t ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return TE::get(x.engine()); }
+ static ElementRef_t get(V& x) { return TE::get(x.engine()); }
+ };
+ template<class T1, class T2, class Op, int B1, int L1, int B2, int L2>
+ struct TinyMatrixAssign
+ {
+ enum { B11=B1 , L11=L1/2 , B12=B1+L1/2 , L12 = L1-L1/2 };
+ enum { B21=B2 , L21=L2/2 , B22=B2+L2/2 , L22 = L2-L2/2 };
+ static void apply(T1& x, const T2& y, Op op=Op())
+ {
+ TinyMatrixAssign<T1,T2,Op,B11,L11,B21,L21>::apply(x,y,op);
+ TinyMatrixAssign<T1,T2,Op,B12,L12,B21,L21>::apply(x,y,op);
+ TinyMatrixAssign<T1,T2,Op,B11,L11,B22,L22>::apply(x,y,op);
+ TinyMatrixAssign<T1,T2,Op,B12,L12,B22,L22>::apply(x,y,op);
+ }
+ };
+ template<class T1, class T2, class Op, int B1, int L1, int B2>
+ struct TinyMatrixAssign<T1,T2,Op,B1,L1,B2,1>
+ {
+ enum { B11=B1 , L11=L1/2 , B12=B1+L1/2 , L12 = L1-L1/2 };
+ static void apply(T1& x, const T2& y, Op op=Op())
+ {
+ TinyMatrixAssign<T1,T2,Op,B11,L11,B2,1>::apply(x,y,op);
+ TinyMatrixAssign<T1,T2,Op,B12,L12,B2,1>::apply(x,y,op);
+ }
+ };
+ template<class T1, class T2, class Op, int B1, int B2, int L2>
+ struct TinyMatrixAssign<T1,T2,Op,B1,1,B2,L2>
+ {
+ enum { B21=B2 , L21=L2/2 , B22=B2+L2/2 , L22 = L2-L2/2 };
+ static void apply(T1& x, const T2& y, Op op=Op())
+ {
+ TinyMatrixAssign<T1,T2,Op,B1,1,B21,L21>::apply(x,y,op);
+ TinyMatrixAssign<T1,T2,Op,B1,1,B22,L22>::apply(x,y,op);
+ }
+ };
+ template<class T1, class T2, class Op, int B1, int B2>
+ struct TinyMatrixAssign<T1,T2,Op,B1,1,B2,1>
+ {
+ static void apply(T1& x, const T2& y,Op op=Op())
+ {
+ op(TinyMatrixElem<T1,B1,B2>::get(x), TinyMatrixElem<T2,B1,B2>::get(y));
+ }
+ };
+ template<class T1, class T2, class Op, int B1, int B2>
+ struct TinyMatrixAssign<T1,T2,Op,B1,2,B2,2>
+ {
+ static void apply(T1& x, const T2& y, Op op=Op())
+ {
+ op(TinyMatrixElem<T1,B1 ,B2 >::get(x), TinyMatrixElem<T2,B1 ,B2 >::get(y));
+ op(TinyMatrixElem<T1,B1+1,B2 >::get(x), TinyMatrixElem<T2,B1+1,B2 >::get(y));
+ op(TinyMatrixElem<T1,B1 ,B2+1>::get(x), TinyMatrixElem<T2,B1 ,B2+1>::get(y));
+ op(TinyMatrixElem<T1,B1+1,B2+1>::get(x), TinyMatrixElem<T2,B1+1,B2+1>::get(y));
+ }
+ };
+ template<class T1, class T2, class Op, int B1, int B2>
+ struct TinyMatrixAssign<T1,T2,Op,B1,3,B2,3>
+ {
+ static void apply(T1& x, const T2& y, Op op=Op())
+ {
+ op(TinyMatrixElem<T1,B1 ,B2 >::get(x), TinyMatrixElem<T2,B1 ,B2 >::get(y));
+ op(TinyMatrixElem<T1,B1+1,B2 >::get(x), TinyMatrixElem<T2,B1+1,B2 >::get(y));
+ op(TinyMatrixElem<T1,B1+2,B2 >::get(x), TinyMatrixElem<T2,B1+2,B2 >::get(y));
+ op(TinyMatrixElem<T1,B1 ,B2+1>::get(x), TinyMatrixElem<T2,B1 ,B2+1>::get(y));
+ op(TinyMatrixElem<T1,B1+1,B2+1>::get(x), TinyMatrixElem<T2,B1+1,B2+1>::get(y));
+ op(TinyMatrixElem<T1,B1+2,B2+1>::get(x), TinyMatrixElem<T2,B1+2,B2+1>::get(y));
+ op(TinyMatrixElem<T1,B1 ,B2+2>::get(x), TinyMatrixElem<T2,B1 ,B2+2>::get(y));
+ op(TinyMatrixElem<T1,B1+1,B2+2>::get(x), TinyMatrixElem<T2,B1+1,B2+2>::get(y));
+ op(TinyMatrixElem<T1,B1+2,B2+2>::get(x), TinyMatrixElem<T2,B1+2,B2+2>::get(y));
+ }
+ };
+ template<class V1, class V2, class Op>
+ class BinaryTinyMatrixOp;
+ template<int D1, int D2, class T, class V1, class V2, class Op>
+ class TinyMatrixEngine<D1,D2,T,BinaryTinyMatrixOp<V1,V2,Op> >
+ {
+ public:
+ enum { dimensions=2 };
+ typedef T Element_t;
+ typedef BinaryTinyMatrixOp<V1,V2,Op> EngineTag_t;
+ typedef T ConstElementRef_t;
+ typedef T ElementRef_t;
+ typedef TinyMatrixEngine<D1,D2,T, BinaryTinyMatrixOp<V1,V2,Op> > This_t;
+ TinyMatrixEngine(const V1& v1, const V2& v2)
+ : v1_m(v1), v2_m(v2) {}
+ Element_t operator()(int i, int j) const
+ {
+ return Op()(v1_m(i,j), v2_m(i,j));
+ }
+ template<int DD1,int DD2, class TT, class EE, int I, int J>
+ friend struct TinyMatrixEngineElem;
+ private:
+ const V1& v1_m;
+ const V2& v2_m;
+ };
+ template<int D1, int D2, class T, class V1, class V2, class Op, int I, int J>
+ struct TinyMatrixEngineElem<D1,D2,T,BinaryTinyMatrixOp<V1,V2,Op>, I, J >
+ {
+ typedef TinyMatrixEngine<D1,D2,T,BinaryTinyMatrixOp<V1,V2,Op> > V;
+ typedef typename TinyMatrixElem<V1,I,J>::Element_t T1;
+ typedef typename TinyMatrixElem<V2,I,J>::Element_t T2;
+ typedef typename BinaryReturn<T1,T2,Op>::Type_t Element_t;
+ typedef Element_t ElementRef_t;
+ typedef Element_t ConstElementRef_t;
+ static Element_t get(const V& x)
+ {
+ return Op()(
+ TinyMatrixElem<V1,I,J>::get(x.v1_m),
+ TinyMatrixElem<V2,I,J>::get(x.v2_m));
+ }
+ };
+ template<class V1, class Op>
+ class UnaryTinyMatrixOp;
+ template<int D1, int D2, class T, class V1, class Op>
+ class TinyMatrixEngine<D1,D2,T,UnaryTinyMatrixOp<V1,Op> >
+ {
+ public:
+ enum { dimensions=2 };
+ typedef T Element_t;
+ typedef UnaryTinyMatrixOp<V1,Op> EngineTag_t;
+ typedef T ConstElementRef_t;
+ typedef T ElementRef_t;
+ typedef TinyMatrixEngine<D1,D2,T, UnaryTinyMatrixOp<V1,Op> > This_t;
+ explicit TinyMatrixEngine(const V1& v1)
+ : v1_m(v1) {}
+ Element_t operator()(int i, int j) const
+ {
+ return Op()(v1_m(i,j));
+ }
+ template<int DD1, int DD2, class TT, class EE, int I, int J>
+ friend struct TinyMatrixEngineElem;
+ private:
+ const V1& v1_m;
+ };
+ template<int D1, int D2, class T, class V1, class Op, int I, int J>
+ struct TinyMatrixEngineElem<D1,D2,T,UnaryTinyMatrixOp<V1,Op>, I, J >
+ {
+ typedef TinyMatrixEngine<D1,D2,T,UnaryTinyMatrixOp<V1,Op> > V;
+ typedef typename TinyMatrixElem<V1,I,J>::Element_t T1;
+ typedef typename UnaryReturn<T1,Op>::Type_t Element_t;
+ typedef Element_t ElementRef_t;
+ typedef Element_t ConstElementRef_t;
+ static Element_t get(const V& x)
+ {
+ return Op()(TinyMatrixElem<V1,I,J>::get(x.v1_m));
+ }
+ };
+ template<int D1, int D2, class T, class E> class TinyMatrix;
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnArcCos > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnArcCos>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnArcCos >::Type_t acos( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnArcCos>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnArcCos> > Expr_t; typedef typename UnaryReturn<V1,FnArcCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnArcSin > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnArcSin>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnArcSin >::Type_t asin( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnArcSin>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnArcSin> > Expr_t; typedef typename UnaryReturn<V1,FnArcSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnArcTan > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnArcTan>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnArcTan >::Type_t atan( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnArcTan>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnArcTan> > Expr_t; typedef typename UnaryReturn<V1,FnArcTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnCeil > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnCeil>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnCeil >::Type_t ceil( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnCeil>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnCeil> > Expr_t; typedef typename UnaryReturn<V1,FnCeil>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnCos > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnCos>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnCos >::Type_t cos( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnCos>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnCos> > Expr_t; typedef typename UnaryReturn<V1,FnCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnHypCos > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnHypCos>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnHypCos >::Type_t cosh( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnHypCos>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnHypCos> > Expr_t; typedef typename UnaryReturn<V1,FnHypCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnExp > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnExp>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnExp >::Type_t exp( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnExp>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnExp> > Expr_t; typedef typename UnaryReturn<V1,FnExp>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnFabs > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnFabs>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnFabs >::Type_t fabs( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnFabs>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnFabs> > Expr_t; typedef typename UnaryReturn<V1,FnFabs>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnFloor > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnFloor>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnFloor >::Type_t floor( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnFloor>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnFloor> > Expr_t; typedef typename UnaryReturn<V1,FnFloor>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnLog > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnLog>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnLog >::Type_t log( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnLog>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnLog> > Expr_t; typedef typename UnaryReturn<V1,FnLog>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnLog10 > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnLog10>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnLog10 >::Type_t log10( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnLog10>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnLog10> > Expr_t; typedef typename UnaryReturn<V1,FnLog10>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnSin > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnSin>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnSin >::Type_t sin( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnSin>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnSin> > Expr_t; typedef typename UnaryReturn<V1,FnSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnHypSin > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnHypSin>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnHypSin >::Type_t sinh( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnHypSin>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnHypSin> > Expr_t; typedef typename UnaryReturn<V1,FnHypSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnSqrt > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnSqrt>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnSqrt >::Type_t sqrt( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnSqrt>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnSqrt> > Expr_t; typedef typename UnaryReturn<V1,FnSqrt>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnTan > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnTan>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnTan >::Type_t tan( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnTan>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnTan> > Expr_t; typedef typename UnaryReturn<V1,FnTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, FnHypTan > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,FnHypTan>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, FnHypTan >::Type_t tanh( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,FnHypTan>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,FnHypTan> > Expr_t; typedef typename UnaryReturn<V1,FnHypTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, OpUnaryMinus > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,OpUnaryMinus>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, OpUnaryMinus >::Type_t operator-( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,OpUnaryMinus>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,OpUnaryMinus> > Expr_t; typedef typename UnaryReturn<V1,OpUnaryMinus>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, OpUnaryPlus > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,OpUnaryPlus>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, OpUnaryPlus >::Type_t operator+( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,OpUnaryPlus>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,OpUnaryPlus> > Expr_t; typedef typename UnaryReturn<V1,OpUnaryPlus>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T, class E> struct UnaryReturn< TinyMatrix<D1,D2,T,E>, OpBitwiseNot > { typedef TinyMatrix< D1, D2, typename UnaryReturn<T,OpBitwiseNot>::Type_t, E > Type_t; }; template <int D1, int D2, class T, class E> inline typename UnaryReturn< TinyMatrix<D1,D2,T,E>, OpBitwiseNot >::Type_t operator~( const TinyMatrix<D1,D2,T,E>& v1 ) { typedef TinyMatrix<D1,D2,T,E> V1; typedef typename UnaryReturn<T,OpBitwiseNot>::Type_t T3; typedef TinyMatrix< D1, D2, T3, UnaryTinyMatrixOp<V1,OpBitwiseNot> > Expr_t; typedef typename UnaryReturn<V1,OpBitwiseNot>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpAdd > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpAdd >::Type_t operator+( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpAdd>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpAdd> > Expr_t; typedef typename BinaryReturn<V1,V2,OpAdd>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpAdd > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D1, int!
D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpAdd > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpAdd >::Type_t operator+( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpAdd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpAdd> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpAdd >::Type_t operator+( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpAdd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMat!
rixOp<T1,V2,OpAdd> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpSubtract > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpSubtract >::Type_t operator-( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpSubtract>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpSubtract> > Expr_t; typedef typename BinaryReturn<V1,V2,OpSubtract>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpSubtract > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpSubtract>::Type!
_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpSubtract > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpSubtract >::Type_t operator-( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpSubtract>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpSubtract> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpSubtract >::Type_t operator-( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpSubtract>::Type_t Return_t; typedef typ!
ename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, !
BinaryTi
nyMatrixOp<T1,V2,OpSubtract> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpMultiply > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpMultiply >::Type_t operator*( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpMultiply> > Expr_t; typedef typename BinaryReturn<V1,V2,OpMultiply>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpMultiply > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpMultiply>::Type!
_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpMultiply > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpMultiply >::Type_t operator*( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpMultiply>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpMultiply> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpMultiply >::Type_t operator*( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpMultiply>::Type_t Return_t; typedef typ!
ename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, !
BinaryTi
nyMatrixOp<T1,V2,OpMultiply> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpDivide > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpDivide >::Type_t operator/( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpDivide>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpDivide> > Expr_t; typedef typename BinaryReturn<V1,V2,OpDivide>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpDivide > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; !
}; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpDivide > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpDivide >::Type_t operator/( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpDivide>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpDivide> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpDivide >::Type_t operator/( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpDivide>::Type_t Return_t; typedef typename Return_t::Element_t T3; !
typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,OpDiv!
ide> > E
xpr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpMod > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpMod >::Type_t operator%( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpMod>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpMod> > Expr_t; typedef typename BinaryReturn<V1,V2,OpMod>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpMod > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D1, int!
D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpMod > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpMod >::Type_t operator%( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpMod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpMod> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpMod >::Type_t operator%( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpMod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMat!
rixOp<T1,V2,OpMod> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpBitwiseAnd > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpBitwiseAnd >::Type_t operator&( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpBitwiseAnd> > Expr_t; typedef typename BinaryReturn<V1,V2,OpBitwiseAnd>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpBitwiseAnd > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpB!
itwiseAnd>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpBitwiseAnd > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpBitwiseAnd >::Type_t operator&( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseAnd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpBitwiseAnd> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpBitwiseAnd >::Type_t operator&( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseAnd>!
::Type_t Return_t; typedef typename Return_t::Element_t T3; ty!
pedef Ti
nyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,OpBitwiseAnd> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpBitwiseOr > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpBitwiseOr >::Type_t operator|( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpBitwiseOr> > Expr_t; typedef typename BinaryReturn<V1,V2,OpBitwiseOr>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpBitwiseOr > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseO!
r>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpBitwiseOr > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpBitwiseOr >::Type_t operator|( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseOr>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpBitwiseOr> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpBitwiseOr >::Type_t operator|( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseOr>::Type_t Return!
_t; typedef typename Return_t::Element_t T3; typedef TinyMatri!
x< D1, D
2, T3, BinaryTinyMatrixOp<T1,V2,OpBitwiseOr> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, OpBitwiseXor > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, OpBitwiseXor >::Type_t operator^( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,OpBitwiseXor> > Expr_t; typedef typename BinaryReturn<V1,V2,OpBitwiseXor>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpBitwiseXor > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpB!
itwiseXor>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpBitwiseXor > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, OpBitwiseXor >::Type_t operator^( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseXor>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,OpBitwiseXor> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, OpBitwiseXor >::Type_t operator^( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseXor>!
::Type_t Return_t; typedef typename Return_t::Element_t T3; ty!
pedef Ti
nyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,OpBitwiseXor> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, FnLdexp > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, FnLdexp >::Type_t ldexp( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnLdexp>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,FnLdexp> > Expr_t; typedef typename BinaryReturn<V1,V2,FnLdexp>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnLdexp > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template !
<int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnLdexp > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnLdexp >::Type_t ldexp( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnLdexp>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,FnLdexp> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnLdexp >::Type_t ldexp( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnLdexp>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2,!
T3, BinaryTinyMatrixOp<T1,V2,FnLdexp> > Expr_t; return Return!
_t( Expr
_t(x,v2) ); }
+ template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, FnPow > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, FnPow >::Type_t pow( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnPow>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,FnPow> > Expr_t; typedef typename BinaryReturn<V1,V2,FnPow>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnPow > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D1, int D2, c!
lass T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnPow > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnPow >::Type_t pow( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnPow>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,FnPow> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnPow >::Type_t pow( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnPow>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,FnPow>!
> Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, FnFmod > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, FnFmod >::Type_t fmod( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnFmod>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,FnFmod> > Expr_t; typedef typename BinaryReturn<V1,V2,FnFmod>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnFmod > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D1, !
int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnFmod > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnFmod >::Type_t fmod( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnFmod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,FnFmod> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnFmod >::Type_t fmod( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnFmod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMat!
rixOp<T1,V2,FnFmod> > Expr_t; return Return_t( Expr_t(x,v2) );!
}
+ template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, TinyMatrix<D1,D2,T2,E>, FnArcTan2 > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class T2, class E1, class E2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>, TinyMatrix<D1,D2,T2,E2>, FnArcTan2 >::Type_t atan2( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> V1; typedef TinyMatrix<D1,D2,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnArcTan2>::Type_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,V2,FnArcTan2> > Expr_t; typedef typename BinaryReturn<V1,V2,FnArcTan2>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnArcTan2 > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type!
_t; }; template <int D1, int D2, class T1, class T2, class E> struct BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnArcTan2 > { typedef TinyMatrix< D1, D2, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D1, int D2, class T1, class E, class T2> inline typename BinaryReturn< TinyMatrix<D1,D2,T1,E>, T2, FnArcTan2 >::Type_t atan2( const TinyMatrix<D1,D2,T1,E>& v1, const T2& x ) { typedef TinyMatrix<D1,D2,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnArcTan2>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<V1,T2,FnArcTan2> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D1, int D2, class T1, class T2, class E> inline typename BinaryReturn< T1, TinyMatrix<D1,D2,T2,E>, FnArcTan2 >::Type_t atan2( const T1& x, const TinyMatrix<D1,D2,T2,E>& v2 ) { typedef TinyMatrix<D1,D2,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnArcTan2>::Type_t Return_t; typedef typename Return_t::Element_t T!
3; typedef TinyMatrix< D1, D2, T3, BinaryTinyMatrixOp<T1,V2,Fn!
ArcTan2>
> Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template<int D1, int D2, class T, class V1, class V2>
+ class TinyMatrixEngine<D1,D2,T,BinaryTinyMatrixOp<V1,V2,FnDot> >
+ {
+ public:
+ enum { dimensions=2 };
+ typedef T Element_t;
+ typedef FnDot Op;
+ typedef BinaryTinyMatrixOp<V1,V2,Op> EngineTag_t;
+ typedef T ConstElementRef_t;
+ typedef T ElementRef_t;
+ typedef TinyMatrixEngine<D1,D2,T, BinaryTinyMatrixOp<V1,V2,Op> > This_t;
+ TinyMatrixEngine(const V1& v1, const V2& v2, Op op)
+ : v1_m(v1), v2_m(v2), op_m(op) {}
+ TinyMatrixEngine(const V1& v1, const V2& v2)
+ : v1_m(v1), v2_m(v2) {}
+ TinyMatrixEngine(const This_t& x)
+ : v1_m(x.v1_m), v2_m(x.v2_m), op_m(x.op_m) {}
+ ~TinyMatrixEngine() {}
+ template<int DD1,int DD2, class TT, class EE, int I, int J>
+ friend struct TinyMatrixEngineElem;
+ private:
+ const V1& v1_m;
+ const V2& v2_m;
+ Op op_m;
+ };
+ template<class T1, class T2, int I, int J, int K, int L>
+ struct TinyMatrixDotTinyMatrix
+ {
+ typedef typename TinyMatrixDotTinyMatrix<T1,T2,I,J,K,L/2>::Type_t Left_t;
+ typedef typename TinyMatrixDotTinyMatrix<T1,T2,I,J,K+L/2,L-L/2>::Type_t Right_t;
+ typedef typename BinaryReturn<Left_t,Right_t,OpAdd>::Type_t Type_t;
+ static Type_t get(const T1& x, const T2& y)
+ {
+ return
+ TinyMatrixDotTinyMatrix<T1,T2,I,J,K,L/2>::get(x,y) +
+ TinyMatrixDotTinyMatrix<T1,T2,I,J,K+L/2,L-L/2>::get(x,y);
+ }
+ };
+ template<class T1, class T2, int I, int J, int K>
+ struct TinyMatrixDotTinyMatrix<T1,T2,I,J,K,1>
+ {
+ typedef typename TinyMatrixElem<T1,I,K>::Element_t Left_t;
+ typedef typename TinyMatrixElem<T2,K,J>::Element_t Right_t;
+ typedef typename BinaryReturn<Left_t,Right_t,OpMultiply>::Type_t Type_t;
+ static Type_t get(const T1& x, const T2& y)
+ {
+ return TinyMatrixElem<T1,I,K>::get(x) * TinyMatrixElem<T2,K,J>::get(y);
+ }
+ };
+ template<int D1, int D2, class T, class T1, class T2, int I, int J>
+ struct TinyMatrixEngineElem<D1,D2,T,BinaryTinyMatrixOp<T1,T2,FnDot>, I, J >
+ {
+ typedef BinaryTinyMatrixOp<T1,T2,FnDot> E;
+ typedef TinyMatrixEngine<D1,D2,T,E> T0;
+ typedef typename TinyMatrixDotTinyMatrix<T1,T2,I,J,0,T1::d1>::Type_t Element_t;
+ typedef Element_t ElementRef_t;
+ typedef Element_t ConstElementRef_t;
+ static Element_t get(const T0& x)
+ {
+ return TinyMatrixDotTinyMatrix<T1,T2,I,J,0,T1::d2>::get(x.v1_m,x.v2_m);
+ }
+ };
+ template<int D1, int D2, int D3, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< TinyMatrix<D1,D2,T1,E1> , TinyMatrix<D2,D3,T2,E2> , FnDot >
+ {
+ typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T0;
+ typedef TinyMatrix<D1,D3,T0,Full> Type_t;
+ };
+ template<int D1, int D2, int D3, class T1, class T2, class E1, class E2>
+ inline
+ typename BinaryReturn< TinyMatrix<D1,D2,T1,E1>,TinyMatrix<D2,D3,T2,E2> , FnDot >::Type_t
+ dot( const TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D2,D3,T2,E2>& v2 )
+ {
+ typedef TinyMatrix<D1,D2,T1,E1> V1;
+ typedef TinyMatrix<D2,D3,T2,E2> V2;
+ typedef typename BinaryReturn<V1,V2,FnDot>::Type_t Return_t;
+ typedef typename Return_t::Element_t T3;
+ typedef TinyMatrix<D1,D3,T3,BinaryTinyMatrixOp<V1,V2,FnDot> > Expr_t;
+ return Return_t( Expr_t(v1,v2) );
+ }
+ template<int D1, int D2, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< TinyMatrix<D1,D2,T1,E1>,TinyMatrix<D1,D2,T2,E2> , OpEQ >
+ {
+ typedef bool Type_t;
+ };
+ template<int D1, int D2, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< TinyMatrix<D1,D2,T1,E1>,TinyMatrix<D1,D2,T2,E2> , OpNE >
+ {
+ typedef bool Type_t;
+ };
+ template<int D1, int D2, class T1, class T2, class E1, class E2>
+ inline typename
+ BinaryReturn< TinyMatrix<D1,D2,T1,E1>,TinyMatrix<D1,D2,T2,E2> , OpEQ >::Type_t
+ operator==(const TinyMatrix<D1,D2,T1,E1>& t1, const TinyMatrix<D1,D2,T2,E2>& t2)
+ {
+ for (int i = 0; i < D1; i++)
+ for (int j = 0; j < D2; j++)
+ if (t1(i,j) != t2(i,j)) return false;
+ return true;
+ }
+ template<int D1, int D2, class T1, class T2, class E1, class E2>
+ inline typename
+ BinaryReturn< TinyMatrix<D1,D2,T1,E1>,TinyMatrix<D1,D2,T2,E2> , OpNE >::Type_t
+ operator!=(const TinyMatrix<D1,D2,T1,E1>& t1, const TinyMatrix<D1,D2,T2,E2>& t2)
+ {
+ return !(t1 == t2);
+ }
+ template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator+=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpAddAssign,0,D1,0,D2>::apply(v1,v2,OpAddAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator+=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpAddAssign,0,D1,0,D2>:: apply(v1,v2,OpAddAssign()); return v1; }
+ template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator-=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpSubtractAssign,0,D1,0,D2>::apply(v1,v2,OpSubtractAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator-=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpSubtractAssign,0,D1,0,D2>:: apply(v1,v2,OpSubtractAssign()); return v1; }
+ template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator*=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpMultiplyAssign,0,D1,0,D2>::apply(v1,v2,OpMultiplyAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator*=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpMultiplyAssign,0,D1,0,D2>:: apply(v1,v2,OpMultiplyAssign()); return v1; }
+ template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator/=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpDivideAssign,0,D1,0,D2>::apply(v1,v2,OpDivideAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator/=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpDivideAssign,0,D1,0,D2>:: apply(v1,v2,OpDivideAssign()); return v1; }
+ template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator%=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpModAssign,0,D1,0,D2>::apply(v1,v2,OpModAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator%=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpModAssign,0,D1,0,D2>:: apply(v1,v2,OpModAssign()); return v1; }
+ template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator|=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpBitwiseOrAssign,0,D1,0,D2>::apply(v1,v2,OpBitwiseOrAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator|=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpBitwiseOrAssign,0,D1,0,D2>:: apply(v1,v2,OpBitwiseOrAssign()); return v1; }
+ template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator&=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpBitwiseAndAssign,0,D1,0,D2>::apply(v1,v2,OpBitwiseAndAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator&=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpBitwiseAndAssign,0,D1,0,D2>:: apply(v1,v2,OpBitwiseAndAssign()); return v1; }
+ template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator^=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpBitwiseXorAssign,0,D1,0,D2>::apply(v1,v2,OpBitwiseXorAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator^=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpBitwiseXorAssign,0,D1,0,D2>:: apply(v1,v2,OpBitwiseXorAssign()); return v1; }
+ template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator<<=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpLeftShiftAssign,0,D1,0,D2>::apply(v1,v2,OpLeftShiftAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator<<=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpLeftShiftAssign,0,D1,0,D2>:: apply(v1,v2,OpLeftShiftAssign()); return v1; }
+ template <int D1, int D2, class T1, class T2, class E1, class E2> inline const TinyMatrix<D1,D2,T1,E1>& operator>>=( TinyMatrix<D1,D2,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 ) { typedef TinyMatrix<D1,D2,T1,E1> Left_t; typedef TinyMatrix<D1,D2,T2,E2> Right_t; TinyMatrixAssign<Left_t,Right_t,OpRightShiftAssign,0,D1,0,D2>::apply(v1,v2,OpRightShiftAssign()); return v1; } template <int D1, int D2, class T1, class T2, class E1> inline const TinyMatrix<D1,D2,T1,E1>& operator>>=( TinyMatrix<D1,D2,T1,E1>& v1, const T2& v2 ) { TinyMatrixAssign<TinyMatrix<D1,D2,T1,E1>,T2,OpRightShiftAssign,0,D1,0,D2>:: apply(v1,v2,OpRightShiftAssign()); return v1; }
+ template<int D1, int D2, class T, class E> class TinyMatrix;
+ template<int D1, int D2, class T, class E> class TinyMatrixEngine;
+ template <class T>
+ void reverseBytes(T&);
+ template<int D1, int D2=D1, class T=double, class EngineTag=Full>
+ class TinyMatrix
+ {
+ public:
+ enum { dimensions=2 };
+ enum { d1=D1, d2=D2 };
+ typedef T Element_t;
+ typedef EngineTag EngineTag_t;
+ typedef TinyMatrixEngine<D1,D2,T,EngineTag> Engine_t;
+ typedef typename Engine_t::ElementRef_t ElementRef_t;
+ typedef typename Engine_t::ConstElementRef_t ConstElementRef_t;
+ typedef TinyMatrix<D1,D2,T,EngineTag> This_t;
+ TinyMatrix() {}
+ TinyMatrix(const This_t& x) : engine_m(x.engine_m) {}
+ template<int D3, int D4, class T2, class EngineTag2>
+ TinyMatrix(const TinyMatrix<D3, D4, T2, EngineTag2>& x) : engine_m(x) {}
+ template<class X>
+ explicit TinyMatrix(const X& x) : engine_m(x) {}
+ template<class X1, class X2>
+ TinyMatrix(const X1& x1, const X2& x2) : engine_m(x1,x2) {}
+ template<class X1, class X2, class X3>
+ TinyMatrix(const X1& x1, const X2& x2, const X3& x3)
+ : engine_m(x1,x2,x3) {}
+ template<class X1, class X2, class X3, class X4>
+ TinyMatrix(const X1& x1, const X2& x2, const X3& x3, const X4& x4)
+ : engine_m(x1,x2,x3,x4) {}
+ template<class X1, class X2, class X3, class X4, class X5>
+ TinyMatrix(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5)
+ : engine_m(x1,x2,x3,x4,x5) {}
+ template<class X1, class X2, class X3, class X4, class X5, class X6>
+ TinyMatrix(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5, const X6& x6)
+ : engine_m(x1,x2,x3,x4,x5,x6) {}
+ template<class X1, class X2, class X3, class X4, class X5, class X6,
+ class X7>
+ TinyMatrix(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5, const X6& x6, const X7& x7)
+ : engine_m(x1,x2,x3,x4,x5,x6,x7) {}
+ template<class X1, class X2, class X3, class X4, class X5, class X6,
+ class X7, class X8>
+ TinyMatrix(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5, const X6& x6, const X7& x7, const X8& x8)
+ : engine_m(x1,x2,x3,x4,x5,x6,x7,x8) {}
+ template<class X1, class X2, class X3, class X4, class X5, class X6,
+ class X7, class X8, class X9>
+ TinyMatrix(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5, const X6& x6, const X7& x7, const X8& x8, const X9& x9)
+ : engine_m(x1,x2,x3,x4,x5,x6,x7,x8,x9) {}
+ ~TinyMatrix() {}
+ This_t& operator=(const This_t& x)
+ {
+ if ( this != &x )
+ engine() = x.engine();
+ return *this;
+ }
+ template<class V>
+ This_t& operator=(const V& x)
+ {
+ engine() = x;
+ return *this;
+ }
+ ConstElementRef_t operator()(int i,int j) const
+ {
+ return engine()(i,j);
+ }
+ ElementRef_t operator()(int i,int j)
+ {
+ return engine()(i,j);
+ }
+ ConstElementRef_t operator()(int i) const { return engine()(i); }
+ ElementRef_t operator()(int i) { return engine()(i); }
+ const Engine_t& engine() const { return engine_m; }
+ Engine_t& engine() { return engine_m; }
+ template<class Out>
+ void print(Out &out) const;
+ inline void reverseBytes() { engine_m.reverseBytes(); }
+ private:
+ Engine_t engine_m;
+ };
+ template<int D1, int D2, class T, class EngineTag>
+ template<class Out>
+ void TinyMatrix<D1, D2, T, EngineTag>::print(Out &out) const
+ {
+ std::ios::fmtflags incomingFormatFlags = out.flags();
+ long width = out.width();
+ long precision = out.precision();
+ out.width(0);
+ out << "(";
+ for (int i = 0; i < D1; i++) {
+ out << "(";
+ out.flags(incomingFormatFlags);
+ out.width(width);
+ out.precision(precision);
+ out << (*this)(i, 0);
+ for (int j = 1; j < D2; j++) {
+ out << " ";
+ out.flags(incomingFormatFlags);
+ out.width(width);
+ out.precision(precision);
+ out << (*this)(i, j);
+ }
+ out << ")";
+ }
+ out << ")";
+ }
+ template<int D1, int D2, class T, class E>
+ std::ostream &operator<<(std::ostream &out, const TinyMatrix<D1,D2,T,E> &t)
+ {
+ t.print(out);
+ return out;
+ }
+ template <int D1, int D2, class T, class E>
+ struct ElementProperties< TinyMatrix<D1,D2,T,E> >
+ : public TrivialElementProperties< TinyMatrix<D1,D2,T,E> >
+ { };
+ template<int D1, int D2, class T>
+ class TinyMatrixEngine<D1,D2,T,Full>
+ {
+ public:
+ enum { dimensions=2 };
+ enum { d1=D1, d2=D2 };
+ typedef T Element_t;
+ typedef Full EngineTag_t;
+ typedef T& ElementRef_t;
+ typedef const T& ConstElementRef_t;
+ typedef TinyMatrixEngine<D1,D2,T,Full> This_t;
+ TinyMatrixEngine()
+ {
+ PoomaCTAssert<(ElementProperties<T>::hasTrivialDefaultConstructor && ElementProperties<T>::hasTrivialDestructor && ElementProperties<T>::concrete)>::test();
+ }
+ TinyMatrixEngine(const TinyMatrixEngine<D1,D2,T,Full>& x)
+ {
+ TinyMatrixAssign<This_t,This_t,OpAssign,0,D1,0,D2>
+ ::apply(*this,x,OpAssign());
+ }
+ template<class X>
+ explicit TinyMatrixEngine(const X& x)
+ {
+ TinyMatrixAssign<This_t,X,OpAssign,0,D1,0,D2>::apply(*this,x,OpAssign());
+ }
+ template<class X1, class X2>
+ TinyMatrixEngine(const X1& x1, const X2& x2)
+ {
+ PoomaCTAssert<(D1*D2 == 2)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ }
+ template<class X1, class X2, class X3>
+ TinyMatrixEngine(const X1& x1, const X2& x2, const X3& x3)
+ {
+ PoomaCTAssert<(D1*D2 == 3)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ }
+ template<class X1, class X2, class X3, class X4>
+ TinyMatrixEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4)
+ {
+ PoomaCTAssert<(D1*D2 == 4)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ (*this)(3) = x4;
+ }
+ template<class X1, class X2, class X3, class X4, class X5>
+ TinyMatrixEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5)
+ {
+ PoomaCTAssert<(D1*D2 == 5)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ (*this)(3) = x4;
+ (*this)(4) = x5;
+ }
+ template<class X1, class X2, class X3, class X4, class X5, class X6>
+ TinyMatrixEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5, const X6& x6)
+ {
+ PoomaCTAssert<(D1*D2 == 6)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ (*this)(3) = x4;
+ (*this)(4) = x5;
+ (*this)(5) = x6;
+ }
+ template<class X1, class X2, class X3, class X4, class X5, class X6,
+ class X7>
+ TinyMatrixEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5, const X6& x6, const X7& x7)
+ {
+ PoomaCTAssert<(D1*D2 == 7)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ (*this)(3) = x4;
+ (*this)(4) = x5;
+ (*this)(5) = x6;
+ (*this)(6) = x7;
+ }
+ template<class X1, class X2, class X3, class X4, class X5, class X6,
+ class X7, class X8>
+ TinyMatrixEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5, const X6& x6, const X7& x7, const X8& x8)
+ {
+ PoomaCTAssert<(D1*D2 == 8)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ (*this)(3) = x4;
+ (*this)(4) = x5;
+ (*this)(5) = x6;
+ (*this)(6) = x7;
+ (*this)(7) = x8;
+ }
+ template<class X1, class X2, class X3, class X4, class X5, class X6,
+ class X7, class X8, class X9>
+ TinyMatrixEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5, const X6& x6, const X7& x7, const X8& x8, const X9& x9)
+ {
+ PoomaCTAssert<(D1*D2 == 9)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ (*this)(3) = x4;
+ (*this)(4) = x5;
+ (*this)(5) = x6;
+ (*this)(6) = x7;
+ (*this)(7) = x8;
+ (*this)(8) = x9;
+ }
+ ~TinyMatrixEngine() {}
+ const This_t&
+ operator=(const This_t& x)
+ {
+ if ( this != &x )
+ TinyMatrixAssign<This_t,This_t,OpAssign,0,D1,0,D2>
+ ::apply(*this,x,OpAssign());
+ return *this;
+ }
+ template<class V>
+ const This_t&
+ operator=(const V& x)
+ {
+ TinyMatrixAssign<This_t,V,OpAssign,0,D1,0,D2>::apply(*this,x,OpAssign());
+ return *this;
+ }
+ ConstElementRef_t operator()(int i,int j) const
+ {
+ ;
+ return x_m[i+D1*j];
+ }
+ ElementRef_t operator()(int i,int j)
+ {
+ ;
+ return x_m[i+D1*j];
+ }
+ ConstElementRef_t operator()(int i) const
+ {
+ ;
+ return x_m[i];
+ }
+ ElementRef_t operator()(int i)
+ {
+ ;
+ return x_m[i];
+ }
+ inline void reverseBytes()
+ {
+ for (int d = 0; d < D1*D2; ++d) ::reverseBytes(x_m[d]);
+ }
+ private:
+ T x_m[D1*D2];
+ };
+ template<class T, class Components> struct ComponentAccess;
+ template<int D1, int D2, class T, class E, int N>
+ struct ComponentAccess< TinyMatrix<D1, D2, T, E>, Loc<N> >
+ {
+ typedef TinyMatrix<D1, D2, T, E> V;
+ typedef typename V::Element_t Element_t;
+ typedef typename V::ElementRef_t ElementRef_t;
+ static inline ElementRef_t indexRef(V &t, const Loc<N> &l)
+ {
+ PoomaCTAssert<(N==2)>::test();
+ return t(l[0].first(), l[1].first());
+ }
+ static inline Element_t index(const V &t, const Loc<N> &l)
+ {
+ PoomaCTAssert<(N==2)>::test();
+ return t(l[0].first(), l[1].first());
+ }
+ };
+ template<int D1, int D2, class T, int I, int J>
+ struct TinyMatrixElem< TinyMatrixEngine<D1,D2,T,Full> , I , J>
+ {
+ typedef TinyMatrixEngine<D1,D2,T,Full> V;
+ typedef TinyMatrixEngineElem<D1,D2,T,Full,I,J> TE;
+ typedef typename TE::Element_t Element_t;
+ typedef typename TE::ConstElementRef_t ConstElementRef_t;
+ typedef typename TE::ElementRef_t ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return TE::get(x); }
+ static ElementRef_t get(V& x) { return TE::get(x); }
+ };
+ template<int D, class T, class E> class Tensor;
+ template<int D, class T, class E> class TensorEngine;
+ class Antisymmetric;
+ class Symmetric;
+ class Diagonal;
+ struct Unwritable
+ {
+ public:
+ template<class T>
+ void operator=(const T&) { }
+ void operator=(const Unwritable&) { }
+ };
+ template<int D, class E, int I, int J>
+ class Writable
+ {
+ public:
+ enum { value = 1 };
+ };
+ template<int D, int I, int J>
+ class Writable<D, Antisymmetric, I, J>
+ {
+ public:
+ enum { value = (I > J) };
+ };
+ template<int D, int I, int J>
+ class Writable<D, Symmetric, I, J>
+ {
+ public:
+ enum { value = (I >= J) };
+ };
+ template<int D, int I, int J>
+ class Writable<D, Diagonal, I, J>
+ {
+ public:
+ enum { value = (I == J) };
+ };
+ template<int D, class T, class E, int I, int J, int B=1>
+ struct TensorEngineElem;
+ template<int D, class T, class E, int I, int J>
+ struct TensorEngineElem<D, T, E, I, J, 1>
+ {
+ typedef TensorEngine<D,T,E> V;
+ typedef typename V::Element_t Element_t;
+ typedef typename V::CTConstElementRef_t ConstElementRef_t;
+ typedef typename V::CTElementRef_t ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return x.template getIJ<I,J>(); }
+ static ElementRef_t get( V& x) { return x.template getIJ<I,J>(); }
+ };
+ template<int D, class T, class E, int I, int J>
+ struct TensorEngineElem<D, T, E, I, J, 0>
+ {
+ typedef TensorEngine<D,T,E> V;
+ typedef typename V::Element_t Element_t;
+ typedef typename V::CTConstElementRef_t ConstElementRef_t;
+ typedef Unwritable ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return x.template getIJ<I,J>(); }
+ static ElementRef_t get( V& x) { return Unwritable(); }
+ };
+ template<class V, int I, int J>
+ struct TensorElem
+ {
+ typedef V Element_t;
+ typedef const V& ConstElementRef_t;
+ typedef V& ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return x; }
+ static ElementRef_t get( V& x) { return x; }
+ };
+ template<int D, class T, class E, int I, int J>
+ struct TensorElem< Tensor<D,T,E> , I , J>
+ {
+ typedef Tensor<D,T,E> V;
+ typedef TensorEngineElem<D,T,E,I,J,Writable<D,E,I,J>::value> TE;
+ typedef typename TE::Element_t Element_t;
+ typedef typename TE::ConstElementRef_t ConstElementRef_t;
+ typedef typename TE::ElementRef_t ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return TE::get(x.engine()); }
+ static ElementRef_t get(V& x) { return TE::get(x.engine()); }
+ };
+ template<int D, class T, class E, int I, int J>
+ struct TensorElem< TensorEngine<D,T,E> , I , J>
+ {
+ };
+ template<class T1, class T2, class Op, int B1, int L1, int B2, int L2>
+ struct TensorAssign
+ {
+ enum { B11=B1 , L11=L1/2 , B12=B1+L1/2 , L12 = L1-L1/2 };
+ enum { B21=B2 , L21=L2/2 , B22=B2+L2/2 , L22 = L2-L2/2 };
+ static void apply(T1& x, const T2& y, Op op=Op())
+ {
+ TensorAssign<T1,T2,Op,B11,L11,B21,L21>::apply(x,y,op);
+ TensorAssign<T1,T2,Op,B12,L12,B21,L21>::apply(x,y,op);
+ TensorAssign<T1,T2,Op,B11,L11,B22,L22>::apply(x,y,op);
+ TensorAssign<T1,T2,Op,B12,L12,B22,L22>::apply(x,y,op);
+ }
+ };
+ template<class T1, class T2, class Op, int B1, int L1, int B2>
+ struct TensorAssign<T1,T2,Op,B1,L1,B2,1>
+ {
+ enum { B11=B1 , L11=L1/2 , B12=B1+L1/2 , L12 = L1-L1/2 };
+ static void apply(T1& x, const T2& y, Op op=Op())
+ {
+ TensorAssign<T1,T2,Op,B11,L11,B2,1>::apply(x,y,op);
+ TensorAssign<T1,T2,Op,B12,L12,B2,1>::apply(x,y,op);
+ }
+ };
+ template<class T1, class T2, class Op, int B1, int B2, int L2>
+ struct TensorAssign<T1,T2,Op,B1,1,B2,L2>
+ {
+ enum { B21=B2 , L21=L2/2 , B22=B2+L2/2 , L22 = L2-L2/2 };
+ static void apply(T1& x, const T2& y, Op op=Op())
+ {
+ TensorAssign<T1,T2,Op,B1,1,B21,L21>::apply(x,y,op);
+ TensorAssign<T1,T2,Op,B1,1,B22,L22>::apply(x,y,op);
+ }
+ };
+ template<class T1, class T2, class Op, int B1, int B2>
+ struct TensorAssign<T1,T2,Op,B1,1,B2,1>
+ {
+ static void apply(T1& x, const T2& y,Op op=Op())
+ {
+ op(TensorElem<T1,B1,B2>::get(x), TensorElem<T2,B1,B2>::get(y));
+ }
+ };
+ template<class T1, class T2, class Op, int B1, int B2>
+ struct TensorAssign<T1,T2,Op,B1,2,B2,2>
+ {
+ static void apply(T1& x, const T2& y, Op op=Op())
+ {
+ op(TensorElem<T1,B1 ,B2 >::get(x), TensorElem<T2,B1 ,B2 >::get(y));
+ op(TensorElem<T1,B1+1,B2 >::get(x), TensorElem<T2,B1+1,B2 >::get(y));
+ op(TensorElem<T1,B1 ,B2+1>::get(x), TensorElem<T2,B1 ,B2+1>::get(y));
+ op(TensorElem<T1,B1+1,B2+1>::get(x), TensorElem<T2,B1+1,B2+1>::get(y));
+ }
+ };
+ template<class T1, class T2, class Op, int B1, int B2>
+ struct TensorAssign<T1,T2,Op,B1,3,B2,3>
+ {
+ static void apply(T1& x, const T2& y, Op op=Op())
+ {
+ op(TensorElem<T1,B1 ,B2 >::get(x), TensorElem<T2,B1 ,B2 >::get(y));
+ op(TensorElem<T1,B1+1,B2 >::get(x), TensorElem<T2,B1+1,B2 >::get(y));
+ op(TensorElem<T1,B1+2,B2 >::get(x), TensorElem<T2,B1+2,B2 >::get(y));
+ op(TensorElem<T1,B1 ,B2+1>::get(x), TensorElem<T2,B1 ,B2+1>::get(y));
+ op(TensorElem<T1,B1+1,B2+1>::get(x), TensorElem<T2,B1+1,B2+1>::get(y));
+ op(TensorElem<T1,B1+2,B2+1>::get(x), TensorElem<T2,B1+2,B2+1>::get(y));
+ op(TensorElem<T1,B1 ,B2+2>::get(x), TensorElem<T2,B1 ,B2+2>::get(y));
+ op(TensorElem<T1,B1+1,B2+2>::get(x), TensorElem<T2,B1+1,B2+2>::get(y));
+ op(TensorElem<T1,B1+2,B2+2>::get(x), TensorElem<T2,B1+2,B2+2>::get(y));
+ }
+ };
+ template<class V1, class V2, class Op>
+ class BinaryTensorOp;
+ template<int D, class T, class V1, class V2, class Op>
+ class TensorEngine<D,T,BinaryTensorOp<V1,V2,Op> >
+ {
+ public:
+ enum { dimensions=2 };
+ typedef T Element_t;
+ typedef BinaryTensorOp<V1,V2,Op> EngineTag_t;
+ typedef T ConstElementRef_t;
+ typedef T ElementRef_t;
+ typedef TensorEngine<D,T, BinaryTensorOp<V1,V2,Op> > This_t;
+ TensorEngine(const V1& v1, const V2& v2)
+ : v1_m(v1), v2_m(v2) {}
+ Element_t operator()(int i, int j) const
+ {
+ return Op()(v1_m(i,j), v2_m(i,j));
+ }
+ template<int DD, class TT, class EE, int I, int J, int BB>
+ friend struct TensorEngineElem;
+ private:
+ const V1& v1_m;
+ const V2& v2_m;
+ };
+ template<int D, class T, class V1, class V2, class Op, int I, int J>
+ struct TensorEngineElem<D,T,BinaryTensorOp<V1,V2,Op>, I, J, 1>
+ {
+ typedef TensorEngine<D,T,BinaryTensorOp<V1,V2,Op> > V;
+ typedef typename TensorElem<V1,I,J>::Element_t T1;
+ typedef typename TensorElem<V2,I,J>::Element_t T2;
+ typedef typename BinaryReturn<T1,T2,Op>::Type_t Element_t;
+ typedef Element_t ElementRef_t;
+ typedef Element_t ConstElementRef_t;
+ static Element_t get(const V& x)
+ {
+ return Op()(
+ TensorElem<V1,I,J>::get(x.v1_m),
+ TensorElem<V2,I,J>::get(x.v2_m));
+ }
+ };
+ template<class V1, class Op>
+ class UnaryTensorOp;
+ template<int D, class T, class V1, class Op>
+ class TensorEngine<D,T,UnaryTensorOp<V1,Op> >
+ {
+ public:
+ enum { dimensions=2 };
+ typedef T Element_t;
+ typedef UnaryTensorOp<V1,Op> EngineTag_t;
+ typedef T ConstElementRef_t;
+ typedef T ElementRef_t;
+ typedef TensorEngine<D,T, UnaryTensorOp<V1,Op> > This_t;
+ explicit TensorEngine(const V1& v1)
+ : v1_m(v1) {}
+ Element_t operator()(int i, int j) const
+ {
+ return Op()(v1_m(i, j));
+ }
+ template<int DD, class TT, class EE, int I, int J, int BB>
+ friend struct TensorEngineElem;
+ private:
+ const V1& v1_m;
+ };
+ template<int D, class T, class V1, class Op, int I, int J>
+ struct TensorEngineElem<D,T,UnaryTensorOp<V1,Op>, I, J, 1>
+ {
+ typedef TensorEngine<D,T,UnaryTensorOp<V1,Op> > V;
+ typedef typename TensorElem<V1,I,J>::Element_t T1;
+ typedef typename UnaryReturn<T1,Op>::Type_t Element_t;
+ typedef Element_t ElementRef_t;
+ typedef Element_t ConstElementRef_t;
+ static Element_t get(const V& x)
+ {
+ return Op()(TensorElem<V1,I,J>::get(x.v1_m));
+ }
+ };
+ template<int D, class T, class E> class Tensor;
+ class Full;
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnArcCos > { typedef Tensor< D, typename UnaryReturn<T,FnArcCos>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnArcCos >::Type_t acos( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnArcCos>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnArcCos> > Expr_t; typedef typename UnaryReturn<V1,FnArcCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnArcSin > { typedef Tensor< D, typename UnaryReturn<T,FnArcSin>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnArcSin >::Type_t asin( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnArcSin>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnArcSin> > Expr_t; typedef typename UnaryReturn<V1,FnArcSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnArcTan > { typedef Tensor< D, typename UnaryReturn<T,FnArcTan>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnArcTan >::Type_t atan( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnArcTan>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnArcTan> > Expr_t; typedef typename UnaryReturn<V1,FnArcTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnCeil > { typedef Tensor< D, typename UnaryReturn<T,FnCeil>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnCeil >::Type_t ceil( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnCeil>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnCeil> > Expr_t; typedef typename UnaryReturn<V1,FnCeil>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnCos > { typedef Tensor< D, typename UnaryReturn<T,FnCos>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnCos >::Type_t cos( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnCos>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnCos> > Expr_t; typedef typename UnaryReturn<V1,FnCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnHypCos > { typedef Tensor< D, typename UnaryReturn<T,FnHypCos>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnHypCos >::Type_t cosh( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnHypCos>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnHypCos> > Expr_t; typedef typename UnaryReturn<V1,FnHypCos>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnExp > { typedef Tensor< D, typename UnaryReturn<T,FnExp>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnExp >::Type_t exp( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnExp>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnExp> > Expr_t; typedef typename UnaryReturn<V1,FnExp>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnFabs > { typedef Tensor< D, typename UnaryReturn<T,FnFabs>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnFabs >::Type_t fabs( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnFabs>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnFabs> > Expr_t; typedef typename UnaryReturn<V1,FnFabs>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnFloor > { typedef Tensor< D, typename UnaryReturn<T,FnFloor>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnFloor >::Type_t floor( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnFloor>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnFloor> > Expr_t; typedef typename UnaryReturn<V1,FnFloor>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnLog > { typedef Tensor< D, typename UnaryReturn<T,FnLog>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnLog >::Type_t log( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnLog>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnLog> > Expr_t; typedef typename UnaryReturn<V1,FnLog>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnLog10 > { typedef Tensor< D, typename UnaryReturn<T,FnLog10>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnLog10 >::Type_t log10( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnLog10>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnLog10> > Expr_t; typedef typename UnaryReturn<V1,FnLog10>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnSin > { typedef Tensor< D, typename UnaryReturn<T,FnSin>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnSin >::Type_t sin( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnSin>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnSin> > Expr_t; typedef typename UnaryReturn<V1,FnSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnHypSin > { typedef Tensor< D, typename UnaryReturn<T,FnHypSin>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnHypSin >::Type_t sinh( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnHypSin>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnHypSin> > Expr_t; typedef typename UnaryReturn<V1,FnHypSin>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnSqrt > { typedef Tensor< D, typename UnaryReturn<T,FnSqrt>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnSqrt >::Type_t sqrt( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnSqrt>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnSqrt> > Expr_t; typedef typename UnaryReturn<V1,FnSqrt>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnTan > { typedef Tensor< D, typename UnaryReturn<T,FnTan>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnTan >::Type_t tan( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnTan>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnTan> > Expr_t; typedef typename UnaryReturn<V1,FnTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, FnHypTan > { typedef Tensor< D, typename UnaryReturn<T,FnHypTan>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, FnHypTan >::Type_t tanh( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,FnHypTan>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,FnHypTan> > Expr_t; typedef typename UnaryReturn<V1,FnHypTan>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, OpUnaryMinus > { typedef Tensor< D, typename UnaryReturn<T,OpUnaryMinus>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, OpUnaryMinus >::Type_t operator-( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,OpUnaryMinus>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,OpUnaryMinus> > Expr_t; typedef typename UnaryReturn<V1,OpUnaryMinus>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, OpUnaryPlus > { typedef Tensor< D, typename UnaryReturn<T,OpUnaryPlus>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, OpUnaryPlus >::Type_t operator+( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,OpUnaryPlus>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,OpUnaryPlus> > Expr_t; typedef typename UnaryReturn<V1,OpUnaryPlus>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T, class E> struct UnaryReturn< Tensor<D,T,E>, OpBitwiseNot > { typedef Tensor< D, typename UnaryReturn<T,OpBitwiseNot>::Type_t, E > Type_t; }; template <int D, class T, class E> inline typename UnaryReturn< Tensor<D,T,E>, OpBitwiseNot >::Type_t operator~( const Tensor<D,T,E>& v1 ) { typedef Tensor<D,T,E> V1; typedef typename UnaryReturn<T,OpBitwiseNot>::Type_t T3; typedef Tensor< D, T3, UnaryTensorOp<V1,OpBitwiseNot> > Expr_t; typedef typename UnaryReturn<V1,OpBitwiseNot>::Type_t Return_t; return Return_t( Expr_t(v1) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpAdd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpAdd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpAdd>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpAdd >::Type_t operator+( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpAdd>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpAdd> > Expr_t; typedef typename BinaryReturn<V1,V2,OpAdd>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, OpAdd > { typedef Tensor< D, typenam!
e BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpAdd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpAdd>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpAdd >::Type_t operator+( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpAdd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpAdd> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpAdd >::Type_t operator+( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpAdd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,OpAdd> > Expr_t; return Return_t(!
Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpSubtract > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpSubtract > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpSubtract >::Type_t operator-( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpSubtract>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpSubtract> > Expr_t; typedef typename BinaryReturn<V1,V2,OpSubtract>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, !
T2, OpSubtract > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpSubtract > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpSubtract>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpSubtract >::Type_t operator-( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpSubtract>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpSubtract> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpSubtract >::Type_t operator-( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpSubtract>::Type_t Return_t; typedef typename Return_t::Elemen!
t_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,OpSubtract!
> > Expr
_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpMultiply > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpMultiply > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpMultiply >::Type_t operator*( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpMultiply> > Expr_t; typedef typename BinaryReturn<V1,V2,OpMultiply>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, !
T2, OpMultiply > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpMultiply > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMultiply>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpMultiply >::Type_t operator*( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpMultiply>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpMultiply> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpMultiply >::Type_t operator*( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpMultiply>::Type_t Return_t; typedef typename Return_t::Elemen!
t_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,OpMultiply!
> > Expr
_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpDivide > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpDivide > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpDivide>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpDivide >::Type_t operator/( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpDivide>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpDivide> > Expr_t; typedef typename BinaryReturn<V1,V2,OpDivide>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, OpDivide > {!
typedef Tensor< D, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpDivide > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpDivide>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpDivide >::Type_t operator/( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpDivide>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpDivide> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpDivide >::Type_t operator/( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpDivide>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, Bin!
aryTensorOp<T1,V2,OpDivide> > Expr_t; return Return_t( Expr_t(!
x,v2) );
}
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpMod > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpMod > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMod>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpMod >::Type_t operator%( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpMod>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpMod> > Expr_t; typedef typename BinaryReturn<V1,V2,OpMod>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, OpMod > { typedef Tensor< D, typenam!
e BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpMod > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpMod>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpMod >::Type_t operator%( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpMod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpMod> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpMod >::Type_t operator%( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpMod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,OpMod> > Expr_t; return Return_t(!
Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpBitwiseAnd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpBitwiseAnd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpBitwiseAnd >::Type_t operator&( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpBitwiseAnd> > Expr_t; typedef typename BinaryReturn<V1,V2,OpBitwiseAnd>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< !
Tensor<D,T1,E>, T2, OpBitwiseAnd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpBitwiseAnd > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseAnd>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpBitwiseAnd >::Type_t operator&( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseAnd>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpBitwiseAnd> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpBitwiseAnd >::Type_t operator&( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseAnd>::Type_t Return_t;!
typedef typename Return_t::Element_t T3; typedef Tensor< D, T!
3, Binar
yTensorOp<T1,V2,OpBitwiseAnd> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpBitwiseOr > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpBitwiseOr > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpBitwiseOr >::Type_t operator|( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpBitwiseOr> > Expr_t; typedef typename BinaryReturn<V1,V2,OpBitwiseOr>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D!
,T1,E>, T2, OpBitwiseOr > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpBitwiseOr > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseOr>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpBitwiseOr >::Type_t operator|( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseOr>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpBitwiseOr> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpBitwiseOr >::Type_t operator|( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseOr>::Type_t Return_t; typedef typename!
Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp!
<T1,V2,O
pBitwiseOr> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, OpBitwiseXor > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpBitwiseXor > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpBitwiseXor >::Type_t operator^( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,OpBitwiseXor> > Expr_t; typedef typename BinaryReturn<V1,V2,OpBitwiseXor>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< !
Tensor<D,T1,E>, T2, OpBitwiseXor > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, OpBitwiseXor > { typedef Tensor< D, typename BinaryReturn<T1,T2,OpBitwiseXor>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, OpBitwiseXor >::Type_t operator^( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,OpBitwiseXor>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,OpBitwiseXor> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, OpBitwiseXor >::Type_t operator^( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,OpBitwiseXor>::Type_t Return_t;!
typedef typename Return_t::Element_t T3; typedef Tensor< D, T!
3, Binar
yTensorOp<T1,V2,OpBitwiseXor> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, FnLdexp > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnLdexp > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnLdexp >::Type_t ldexp( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnLdexp>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,FnLdexp> > Expr_t; typedef typename BinaryReturn<V1,V2,FnLdexp>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, FnLdexp > { typedef Tens!
or< D, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, FnLdexp > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnLdexp>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, FnLdexp >::Type_t ldexp( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnLdexp>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,FnLdexp> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, FnLdexp >::Type_t ldexp( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnLdexp>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,FnLdexp> > !
Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, FnPow > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnPow > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnPow>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnPow >::Type_t pow( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnPow>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,FnPow> > Expr_t; typedef typename BinaryReturn<V1,V2,FnPow>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, FnPow > { typedef Tensor< D, typename Bina!
ryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, FnPow > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnPow>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, FnPow >::Type_t pow( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnPow>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,FnPow> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, FnPow >::Type_t pow( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnPow>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,FnPow> > Expr_t; return Return_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, FnFmod > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnFmod > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnFmod>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnFmod >::Type_t fmod( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnFmod>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,FnFmod> > Expr_t; typedef typename BinaryReturn<V1,V2,FnFmod>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, FnFmod > { typedef Tensor< D, typ!
ename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, FnFmod > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnFmod>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, FnFmod >::Type_t fmod( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnFmod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,FnFmod> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, FnFmod >::Type_t fmod( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnFmod>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<T1,V2,FnFmod> > Expr_t; return Return!
_t( Expr_t(x,v2) ); }
+ template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, Tensor<D,T2,E>, FnArcTan2 > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E1, class E2> struct BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnArcTan2 > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, Full > Type_t; }; template <int D, class T1, class T2, class E1, class E2> inline typename BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, FnArcTan2 >::Type_t atan2( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 ) { typedef Tensor<D,T1,E1> V1; typedef Tensor<D,T2,E2> V2; typedef typename BinaryReturn<T1,T2,FnArcTan2>::Type_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,V2,FnArcTan2> > Expr_t; typedef typename BinaryReturn<V1,V2,FnArcTan2>::Type_t Return_t; return Return_t( Expr_t(v1,v2) ); } template <int D, class T1, class T2, class E> struct BinaryReturn< Tensor<D,T1,E>, T2, FnArcTan!
2 > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D, class T1, class T2, class E> struct BinaryReturn< T1, Tensor<D,T2,E>, FnArcTan2 > { typedef Tensor< D, typename BinaryReturn<T1,T2,FnArcTan2>::Type_t, E > Type_t; }; template <int D, class T1, class E, class T2> inline typename BinaryReturn< Tensor<D,T1,E>, T2, FnArcTan2 >::Type_t atan2( const Tensor<D,T1,E>& v1, const T2& x ) { typedef Tensor<D,T1,E> V1; typedef typename BinaryReturn<V1,T2,FnArcTan2>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3, BinaryTensorOp<V1,T2,FnArcTan2> > Expr_t; return Return_t( Expr_t(v1,x) ); } template <int D, class T1, class T2, class E> inline typename BinaryReturn< T1, Tensor<D,T2,E>, FnArcTan2 >::Type_t atan2( const T1& x, const Tensor<D,T2,E>& v2 ) { typedef Tensor<D,T2,E> V2; typedef typename BinaryReturn<T1,V2,FnArcTan2>::Type_t Return_t; typedef typename Return_t::Element_t T3; typedef Tensor< D, T3!
, BinaryTensorOp<T1,V2,FnArcTan2> > Expr_t; return Return_t( E!
xpr_t(x,
v2) ); }
+ template<class T1, class T2, int I, int J, int K, int L>
+ struct TensorDotTensor
+ {
+ typedef typename TensorDotTensor<T1,T2,I,J,K,L/2>::Type_t Left_t;
+ typedef typename TensorDotTensor<T1,T2,I,J,K+L/2,L-L/2>::Type_t Right_t;
+ typedef typename BinaryReturn<Left_t,Right_t,OpAdd>::Type_t Type_t;
+ static Type_t get(const T1& x, const T2& y)
+ {
+ return
+ TensorDotTensor<T1,T2,I,J,K,L/2>::get(x,y) +
+ TensorDotTensor<T1,T2,I,J,K+L/2,L-L/2>::get(x,y);
+ }
+ };
+ template<class T1, class T2, int I, int J, int K>
+ struct TensorDotTensor<T1,T2,I,J,K,1>
+ {
+ typedef typename TensorElem<T1,I,K>::Element_t Left_t;
+ typedef typename TensorElem<T2,K,J>::Element_t Right_t;
+ typedef typename BinaryReturn<Left_t,Right_t,OpMultiply>::Type_t Type_t;
+ static Type_t get(const T1& x, const T2& y)
+ {
+ return TensorElem<T1,I,K>::get(x) * TensorElem<T2,K,J>::get(y);
+ }
+ };
+ template<int D, class T, class T1, class T2, int I, int J>
+ struct TensorEngineElem<D,T,BinaryTensorOp<T1,T2,FnDot>, I, J,
+ 1>
+ {
+ typedef BinaryTensorOp<T1,T2,FnDot> E;
+ typedef TensorEngine<D,T,E> T0;
+ typedef typename TensorDotTensor<T1,T2,I,J,0,T1::d>::Type_t Element_t;
+ typedef Element_t ElementRef_t;
+ typedef Element_t ConstElementRef_t;
+ static Element_t get(const T0& x)
+ {
+ return TensorDotTensor<T1,T2,I,J,0,T1::d>::get(x.v1_m,x.v2_m);
+ }
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< Tensor<D,T1,E1> , Tensor<D,T2,E2> , FnDot >
+ {
+ typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T0;
+ typedef Tensor<D,T0,Full> Type_t;
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ inline
+ typename BinaryReturn< Tensor<D,T1,E1>,Tensor<D,T2,E2> , FnDot >::Type_t
+ dot( const Tensor<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 )
+ {
+ typedef Tensor<D,T1,E1> V1;
+ typedef Tensor<D,T2,E2> V2;
+ typedef typename BinaryReturn<V1,V2,FnDot>::Type_t Return_t;
+ typedef typename Return_t::Element_t T3;
+ typedef Tensor<D,T3,BinaryTensorOp<V1,V2,FnDot> > Expr_t;
+ return Return_t( Expr_t(v1,v2) );
+ }
+ template<int D, class T, class E>
+ struct UnaryReturn< Tensor<D,T,E> , FnTrace >
+ {
+ typedef T Type_t;
+ };
+ template<int D, class T, class E>
+ inline T
+ trace(const Tensor<D,T,E>& t)
+ {
+ T result(0.0);
+ for (int d = 0; d < D; d++) {
+ result += t(d,d);
+ }
+ return result;
+ }
+ template<int D, class T>
+ inline T
+ trace(const Tensor<D,T,Diagonal>& t)
+ {
+ T result(0.0);
+ for (int d = 0; d < D; d++) {
+ result += t(d);
+ }
+ return result;
+ }
+ template<int D, class T>
+ inline T
+ trace(const Tensor<D,T,Antisymmetric>& t)
+ {
+ return T(0.0);
+ }
+ template<int D, class T, class E>
+ struct UnaryReturn< Tensor<D,T,E> , FnDet >
+ {
+ typedef T Type_t;
+ };
+ template<int D, class T, class E>
+ inline T
+ det(const Tensor<D,T,E>& t)
+ {
+ if (__builtin_expect(!!(D<4), true)) {} else Pooma::toss_cookies("Tensor det() function not implemented for D>3!", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Tiny/TensorOperators.h", 405);
+ return T(-999999.999999);
+ }
+ template<class T, class E>
+ inline T
+ det(const Tensor<3,T,E>& t)
+ {
+ T result;
+ result =
+ t(0,0)*(t(1,1)*t(2,2) - t(1,2)*t(2,1)) +
+ t(0,1)*(t(1,2)*t(2,0) - t(1,0)*t(2,2)) +
+ t(0,2)*(t(1,0)*t(2,1) - t(1,1)*t(2,0));
+ return result;
+ }
+ template<class T, class E>
+ inline T
+ det(const Tensor<2,T,E>& t)
+ {
+ T result;
+ result = t(0,0)*t(1,1) - t(0,1)*t(1,0);
+ return result;
+ }
+ template<class T, class E>
+ inline T
+ det(const Tensor<1,T,E>& t)
+ {
+ T result = t(0,0);
+ return result;
+ }
+ template<class T>
+ inline T
+ det(const Tensor<3,T,Diagonal>& t)
+ {
+ T result;
+ result = t(0)*t(1)*t(2);
+ return result;
+ }
+ template<class T>
+ inline T
+ det(const Tensor<2,T,Diagonal>& t)
+ {
+ T result;
+ result = t(0)*t(1);
+ return result;
+ }
+ template<class T>
+ inline T
+ det(const Tensor<1,T,Diagonal>& t)
+ {
+ T result = t(0);
+ return result;
+ }
+ template<class T>
+ inline T
+ det(const Tensor<3,T,Antisymmetric>& t)
+ {
+ return T(0.0);
+ }
+ template<class T>
+ inline T
+ det(const Tensor<2,T,Antisymmetric>& t)
+ {
+ T result;
+ result = t(0)*t(0);
+ return result;
+ }
+ template<class T>
+ inline T
+ det(const Tensor<1,T,Antisymmetric>& t)
+ {
+ return T(0.0);
+ }
+ template<int D, class T, class E>
+ struct UnaryReturn< Tensor<D,T,E> , FnTranspose >
+ {
+ typedef Tensor<D,T,E> Type_t;
+ };
+ template<int D, class T, class E>
+ inline Tensor<D,T,E>
+ transpose(const Tensor<D,T,E>& t)
+ {
+ Tensor<D,T,E> result;
+ for (int i = 0; i < D; i++) {
+ for (int j = 0; j < D; j++) {
+ result(i,j) = t(j,i);
+ }
+ }
+ return result;
+ }
+ template<int D, class T>
+ inline Tensor<D,T,Symmetric>
+ transpose(const Tensor<D,T,Symmetric>& t)
+ {
+ Tensor<D,T,Symmetric> result;
+ result = t;
+ return result;
+ }
+ template<int D, class T>
+ inline Tensor<D,T,Antisymmetric>
+ transpose(const Tensor<D,T,Antisymmetric>& t)
+ {
+ Tensor<D,T,Antisymmetric> result;
+ result = -t;
+ return result;
+ }
+ template<int D, class T>
+ inline Tensor<D,T,Diagonal>
+ transpose(const Tensor<D,T,Diagonal>& t)
+ {
+ Tensor<D,T,Diagonal> result;
+ result = t;
+ return result;
+ }
+ template<int D, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< Tensor<D,T1,E1>,Tensor<D,T2,E2> , OpEQ >
+ {
+ typedef bool Type_t;
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< Tensor<D,T1,E1>,Tensor<D,T2,E2> , OpNE >
+ {
+ typedef bool Type_t;
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ inline typename
+ BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpEQ >::Type_t
+ operator==(const Tensor<D,T1,E1>& t1, const Tensor<D,T2,E2>& t2)
+ {
+ for (int i = 0; i < D; i++)
+ for (int j = 0; j < D; j++)
+ if (t1(i,j) != t2(i,j)) return false;
+ return true;
+ }
+ template<int D, class T1, class T2, class E1, class E2>
+ inline typename
+ BinaryReturn< Tensor<D,T1,E1>, Tensor<D,T2,E2>, OpNE >::Type_t
+ operator!=(const Tensor<D,T1,E1>& t1, const Tensor<D,T2,E2>& t2)
+ {
+ return !(t1 == t2);
+ }
+ template <int D, class T1, class T2, class E1> inline Tensor<D,T1,E1>& operator+=( Tensor<D,T1,E1>& v1, const Tensor<D,T2,E1>& v2 ) { typedef typename Tensor<D,T1,E1>::Engine_t Left_t; typedef typename Tensor<D,T2,E1>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Symmetric>& operator+=( Tensor<D,T1,Symmetric>& v1, const Tensor<D,T2,Symmetric>& v2 ) { typedef typename Tensor<D,T1,Symmetric>::Engine_t Left_t; typedef typename Tensor<D,T2,Symmetric>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Antisymmetric>& operator+=( Tensor<D,T1,Antisymmetric>& v1, const Tensor<D,T2,Antisymmetric>& v2 ) { typedef typename Tensor<D,T1,Antisymmetric>::Engine_t Left_t; typedef typename Tensor<D,T2,Antisymmetric>::Engi!
ne_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Diagonal>& operator+=( Tensor<D,T1,Diagonal>& v1, const Tensor<D,T2,Diagonal>& v2 ) { typedef typename Tensor<D,T1,Diagonal>::Engine_t Left_t; typedef typename Tensor<D,T2,Diagonal>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Tensor<D,T1,E1>& operator+=( Tensor<D,T1,E1>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,E1>::Engine_t Left_t; typedef typename T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Symmetric>& operator+=( Tensor<D,T1,Symmetric>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,Symmetric>::Engine_t L!
eft_t; typedef typename T2::Engine_t Right_t; TensorAssign<Lef!
t_t,Righ
t_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Antisymmetric>& operator+=( Tensor<D,T1,Antisymmetric>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,Antisymmetric>::Engine_t Left_t; typedef typename T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Diagonal>& operator+=( Tensor<D,T1,Diagonal>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,Diagonal>::Engine_t Left_t; typedef typename T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpAddAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpAddAssign()); return v1; }
+ template <int D, class T1, class T2, class E1> inline Tensor<D,T1,E1>& operator-=( Tensor<D,T1,E1>& v1, const Tensor<D,T2,E1>& v2 ) { typedef typename Tensor<D,T1,E1>::Engine_t Left_t; typedef typename Tensor<D,T2,E1>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Symmetric>& operator-=( Tensor<D,T1,Symmetric>& v1, const Tensor<D,T2,Symmetric>& v2 ) { typedef typename Tensor<D,T1,Symmetric>::Engine_t Left_t; typedef typename Tensor<D,T2,Symmetric>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Antisymmetric>& operator-=( Tensor<D,T1,Antisymmetric>& v1, const Tensor<D,T2,Antisymmetric>& v2 ) { typedef typename Tensor<D,T1,Antisymmetric>::Engine_t Left_t; typedef typename Tensor<D,T2,!
Antisymmetric>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Diagonal>& operator-=( Tensor<D,T1,Diagonal>& v1, const Tensor<D,T2,Diagonal>& v2 ) { typedef typename Tensor<D,T1,Diagonal>::Engine_t Left_t; typedef typename Tensor<D,T2,Diagonal>::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; } template <int D, class T1, class T2, class E1> inline Tensor<D,T1,E1>& operator-=( Tensor<D,T1,E1>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,E1>::Engine_t Left_t; typedef typename T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Symmetric>& operator-=( Tensor<D,T1,Symmetric>& v1, const T2& v2 ) { t!
ypedef typename Tensor<D,T1,Symmetric>::Engine_t Left_t; typed!
ef typen
ame T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Antisymmetric>& operator-=( Tensor<D,T1,Antisymmetric>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,Antisymmetric>::Engine_t Left_t; typedef typename T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; } template <int D, class T1, class T2> inline Tensor<D,T1,Diagonal>& operator-=( Tensor<D,T1,Diagonal>& v1, const T2& v2 ) { typedef typename Tensor<D,T1,Diagonal>::Engine_t Left_t; typedef typename T2::Engine_t Right_t; TensorAssign<Left_t,Right_t,OpSubtractAssign,0,D,0,D>:: apply(v1.engine(),v2.engine(),OpSubtractAssign()); return v1; }
+ template<int D, class T, class EngineTag> class Tensor;
+ template<int D, class T, class EngineTag> class TensorEngine;
+ template <class T>
+ void reverseBytes(T&);
+ class Full;
+ class Antisymmetric;
+ class Symmetric;
+ class Diagonal;
+ template<int D, class EngineTag>
+ class TensorStorageSize {};
+ template<int D>
+ class TensorStorageSize<D, Full>
+ {
+ public:
+ enum { Size = D*D };
+ };
+ template<int D>
+ class TensorStorageSize<D, Antisymmetric>
+ {
+ public:
+ enum { Size = (D*D - D)/2 + 1/D };
+ };
+ template<int D>
+ class TensorStorageSize<D, Symmetric>
+ {
+ public:
+ enum { Size = (D*D - D)/2 + D };
+ };
+ template<int D>
+ class TensorStorageSize<D, Diagonal>
+ {
+ public:
+ enum { Size = D };
+ };
+ template<int D, class T=double, class EngineTag=Full>
+ class Tensor
+ {
+ public:
+ enum { dimensions=2 };
+ enum { d=D };
+ typedef T Element_t;
+ typedef EngineTag EngineTag_t;
+ typedef TensorEngine<D,T,EngineTag> Engine_t;
+ typedef typename Engine_t::ElementRef_t ElementRef_t;
+ typedef typename Engine_t::ConstElementRef_t ConstElementRef_t;
+ typedef Tensor<D,T,EngineTag> This_t;
+ Tensor() {}
+ Tensor(const This_t& x) : engine_m(x.engine_m) {}
+ template<int D2, class T2, class EngineTag2>
+ Tensor(const Tensor<D2, T2, EngineTag2>& x) : engine_m(x) {}
+ template<class X>
+ explicit Tensor(const X& x) : engine_m(x) {}
+ template<class X1, class X2>
+ Tensor(const X1& x, const X2& y) : engine_m(x,y) {}
+ template<class X1, class X2, class X3>
+ Tensor(const X1& x, const X2& y, const X3& z) : engine_m(x,y,z) {}
+ template<class X1, class X2, class X3, class X4>
+ Tensor(const X1& x1, const X2& x2, const X3& x3, const X4& x4)
+ : engine_m(x1,x2,x3,x4) {}
+ template<class X1, class X2, class X3, class X4, class X5>
+ Tensor(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5)
+ : engine_m(x1,x2,x3,x4,x5) {}
+ template<class X1, class X2, class X3, class X4, class X5, class X6>
+ Tensor(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5, const X6& x6)
+ : engine_m(x1,x2,x3,x4,x5,x6) {}
+ template<class X1, class X2, class X3, class X4, class X5, class X6,
+ class X7>
+ Tensor(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5, const X6& x6, const X7& x7)
+ : engine_m(x1,x2,x3,x4,x5,x6,x7) {}
+ template<class X1, class X2, class X3, class X4, class X5, class X6,
+ class X7, class X8>
+ Tensor(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5, const X6& x6, const X7& x7, const X8& x8)
+ : engine_m(x1,x2,x3,x4,x5,x6,x7,x8) {}
+ template<class X1, class X2, class X3, class X4, class X5, class X6,
+ class X7, class X8, class X9>
+ Tensor(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5, const X6& x6, const X7& x7, const X8& x8, const X9& x9)
+ : engine_m(x1,x2,x3,x4,x5,x6,x7,x8,x9) {}
+ ~Tensor() {}
+ This_t& operator=(const This_t& x)
+ {
+ if ( this != &x )
+ engine() = x.engine();
+ return *this;
+ }
+ template<class T1, class EngineTag1>
+ This_t& operator=(const Tensor<d,T1,EngineTag1> &x)
+ {
+ engine() = x.engine();
+ return *this;
+ }
+ template<class V>
+ This_t&
+ operator=(const V& x)
+ {
+ engine() = x;
+ return *this;
+ }
+ ConstElementRef_t operator()(int i, int j) const
+ {
+ return engine()(i,j);
+ }
+ ElementRef_t operator()(int i, int j)
+ {
+ return engine()(i,j);
+ }
+ ConstElementRef_t operator()(int i) const { return engine()(i); }
+ ElementRef_t operator()(int i) { return engine()(i); }
+ const Engine_t& engine() const { return engine_m; }
+ Engine_t& engine() { return engine_m; }
+ template<class Out>
+ void print(Out &out) const;
+ inline void reverseBytes() { engine_m.reverseBytes(); }
+ private:
+ Engine_t engine_m;
+ };
+ template<int D, class T, class EngineTag>
+ template<class Out>
+ void Tensor<D, T, EngineTag>::print(Out &out) const
+ {
+ std::ios::fmtflags incomingFormatFlags = out.flags();
+ long width = out.width();
+ long precision = out.precision();
+ out.width(0);
+ out << "(";
+ for (int i = 0; i < D; i++) {
+ out << "(";
+ out.flags(incomingFormatFlags);
+ out.width(width);
+ out.precision(precision);
+ out << (*this)(i,0);
+ for (int j = 1; j < D; j++) {
+ out << " ";
+ out.flags(incomingFormatFlags);
+ out.width(width);
+ out.precision(precision);
+ out << (*this)(i,j);
+ }
+ out << ")";
+ }
+ out << ")";
+ }
+ template<int D, class T, class E>
+ std::ostream &operator<<(std::ostream &out, const Tensor<D,T,E> &t)
+ {
+ t.print(out);
+ return out;
+ }
+ template <int D, class T, class E>
+ struct ElementProperties< Tensor<D,T,E> >
+ : public TrivialElementProperties< Tensor<D,T,E> >
+ { };
+ template<int D, class T>
+ class TensorEngine<D, T, Full>
+ {
+ public:
+ enum { dimensions=2 };
+ enum { d=D };
+ typedef T Element_t;
+ typedef Full EngineTag_t;
+ typedef T& ElementRef_t;
+ typedef const T& ConstElementRef_t;
+ typedef T& CTElementRef_t;
+ typedef const T& CTConstElementRef_t;
+ typedef TensorEngine<D,T,Full> This_t;
+ TensorEngine()
+ {
+ PoomaCTAssert<(ElementProperties<T>::hasTrivialDefaultConstructor && ElementProperties<T>::hasTrivialDestructor && ElementProperties<T>::concrete)>::test();
+ }
+ TensorEngine(const TensorEngine<D,T,Full>& x)
+ {
+ TensorAssign<This_t,This_t,OpAssign,0,D,0,D>
+ ::apply(*this,x,OpAssign());
+ }
+ template<class X>
+ explicit TensorEngine(const X& x)
+ {
+ TensorAssign<This_t,X,OpAssign,0,D,0,D>::apply(*this,x,OpAssign());
+ }
+ explicit TensorEngine(const T& x)
+ {
+ for (int i = 0 ; i < D*D ; i++) {
+ (*this)(i) = x;
+ }
+ }
+ template<class X1, class X2, class X3, class X4>
+ TensorEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4)
+ {
+ PoomaCTAssert<(D == 2)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ (*this)(3) = x4;
+ }
+ template<class X1, class X2, class X3, class X4, class X5, class X6,
+ class X7, class X8, class X9>
+ TensorEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5, const X6& x6, const X7& x7, const X8& x8,
+ const X9& x9)
+ {
+ PoomaCTAssert<(D == 3)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ (*this)(3) = x4;
+ (*this)(4) = x5;
+ (*this)(5) = x6;
+ (*this)(6) = x7;
+ (*this)(7) = x8;
+ (*this)(8) = x9;
+ }
+ ~TensorEngine() {}
+ This_t&
+ operator=(const This_t& x)
+ {
+ if (this != &x) {
+ TensorAssign<This_t,This_t,OpAssign,0,D,0,D>::apply(*this,x,OpAssign());
+ }
+ return *this;
+ }
+ template<class V>
+ This_t&
+ operator=(const V& x)
+ {
+ TensorAssign<This_t,V,OpAssign,0,D,0,D>::apply(*this,x,OpAssign());
+ return *this;
+ }
+ template<int I, int J>
+ CTConstElementRef_t getIJ() const
+ {
+ PoomaCTAssert<((I >= 0) && (I < D) && (J >= 0) && (J < D))>::test();
+ return x_m[I + D*J];
+ }
+ template<int I, int J>
+ CTElementRef_t getIJ()
+ {
+ PoomaCTAssert<((I >= 0) && (I < D) && (J >= 0) && (J < D))>::test();
+ return x_m[I + D*J];
+ }
+ ConstElementRef_t operator()(int i,int j) const
+ {
+ ;
+ return x_m[i + D*j];
+ }
+ ElementRef_t operator()(int i,int j)
+ {
+ ;
+ return x_m[i + D*j];
+ }
+ ConstElementRef_t operator()(int i) const
+ {
+ ;
+ return x_m[i];
+ }
+ ElementRef_t operator()(int i)
+ {
+ ;
+ return x_m[i];
+ }
+ const T* data() const{
+ return (const T*) &x_m[0];
+ }
+ T* data(){
+ return (T*) &x_m[0];
+ }
+ inline void reverseBytes()
+ {
+ const int sz = TensorStorageSize<d, EngineTag_t>::Size;
+ for (int i = 0; i < sz; ++i)
+ ::reverseBytes(x_m[i]);
+ }
+ private:
+ T x_m[TensorStorageSize<d, EngineTag_t>::Size];
+ };
+ template<int D, class T>
+ class TensorEngine<D, T, Antisymmetric>
+ {
+ public:
+ enum { dimensions=2 };
+ enum { d=D };
+ typedef T Element_t;
+ typedef Antisymmetric EngineTag_t;
+ class AssignProxy {
+ public:
+ AssignProxy(Element_t &elem, int where)
+ : elem_m(elem), where_m(where) { }
+ AssignProxy(const AssignProxy &model)
+ : elem_m(model.elem_m), where_m(where_m) { }
+ AssignProxy &operator=(const AssignProxy &a) const
+ {
+ ;
+ elem_m = where_m < 0 ? -a.elem_m : a.elem_m;
+ return const_cast<AssignProxy &>(*this);
+ }
+ AssignProxy &operator=(const Element_t &e) const
+ {
+ ;
+ elem_m = where_m < 0 ? -e : e;
+ return const_cast<AssignProxy &>(*this);
+ }
+ operator Element_t() const
+ {
+ return (where_m < 0 ? -elem_m : elem_m);
+ }
+ private:
+ mutable Element_t &elem_m;
+ mutable int where_m;
+ };
+ typedef AssignProxy ElementRef_t;
+ typedef T ConstElementRef_t;
+ typedef T& CTElementRef_t;
+ typedef T CTConstElementRef_t;
+ typedef TensorEngine<d,T,Antisymmetric> This_t;
+ TensorEngine()
+ {
+ PoomaCTAssert<(ElementProperties<T>::hasTrivialDefaultConstructor && ElementProperties<T>::hasTrivialDestructor && ElementProperties<T>::concrete)>::test();
+ }
+ TensorEngine(const TensorEngine<d,T,Antisymmetric> &x)
+ {
+ TensorAssign<This_t,This_t,OpAssign,0,d,0,d>::
+ apply(*this,x,OpAssign());
+ }
+ template<class X>
+ explicit TensorEngine(const X& x)
+ {
+ TensorAssign<This_t,X,OpAssign,0,d,0,d>::
+ apply(*this,x,OpAssign());
+ }
+ explicit TensorEngine(const T &x) {
+ for (int i = 0; i < TensorStorageSize<d, EngineTag_t>::Size; i++) {
+ x_m[i] = x;
+ }
+ }
+ template<class X1, class X2, class X3>
+ TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3)
+ {
+ PoomaCTAssert<(D == 3)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ }
+ template<class X1, class X2, class X3, class X4, class X5, class X6>
+ TensorEngine(const X1& x1, const X2& x2, const X3& x3, const X4& x4,
+ const X5& x5, const X6& x6)
+ {
+ PoomaCTAssert<(D == 4)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ (*this)(3) = x4;
+ (*this)(4) = x5;
+ (*this)(5) = x6;
+ }
+ ~TensorEngine() {}
+ This_t&
+ operator=(const This_t& x)
+ {
+ if (this != &x) {
+ TensorAssign<This_t,This_t,OpAssign,0,d,0,d>::
+ apply(*this,x,OpAssign());
+ }
+ return *this;
+ }
+ template<class V>
+ This_t&
+ operator=(const V& x)
+ {
+ TensorAssign<This_t,V,OpAssign,0,d,0,d>::
+ apply(*this,x,OpAssign());
+ return *this;
+ }
+ template<int I, int J>
+ CTConstElementRef_t getIJ() const
+ {
+ PoomaCTAssert<((I >= 0) && (I < d) && (J >= 0) && (J < d))>::test();
+ if (I == J) {
+ return This_t::Zero;
+ } else {
+ int lo = I < J ? I : J;
+ int hi = I > J ? I : J;
+ int symmetrySign = I < J ? -1 : 1;
+ return symmetrySign * x_m[((hi - 1)*hi/2) + lo];
+ }
+ }
+ template<int I, int J>
+ CTElementRef_t getIJ()
+ {
+ PoomaCTAssert<((I >= 0) && (I < d) && (J >= 0) && (J < d) && (I > J))>::test();
+ return x_m[((I - 1)*I/2) + J];
+ }
+ ConstElementRef_t operator()(int i,int j) const
+ {
+ ;
+ if (i == j) {
+ return This_t::Zero;
+ } else if (i < j) {
+ return -x_m[((j - 1)*j/2) + i];
+ } else {
+ return x_m[((i - 1)*i/2) + j];
+ }
+ }
+ ElementRef_t operator()(int i,int j)
+ {
+ ;
+ if (i == j) {
+ return AssignProxy(This_t::Zero, 0);
+ } else {
+ int lo = i < j ? i : j;
+ int hi = i > j ? i : j;
+ return AssignProxy(x_m[((hi-1)*hi/2) + lo], i - j);
+ }
+ }
+ ConstElementRef_t operator()(int i) const
+ {
+ ;
+ return x_m[i];
+ }
+ ElementRef_t operator()(int i)
+ {
+ ;
+ return AssignProxy(x_m[i], 1);
+ }
+ const T* data() const{
+ return (const T*) &x_m[0];
+ }
+ T* data(){
+ return (T*) &x_m[0];
+ }
+ inline void reverseBytes()
+ {
+ const int sz = TensorStorageSize<d, EngineTag_t>::Size;
+ for (int i = 0; i < sz; ++i)
+ ::reverseBytes(x_m[i]);
+ }
+ private:
+ T x_m[TensorStorageSize<d, EngineTag_t>::Size];
+ static T Zero;
+ };
+ template<int D, class T>
+ T TensorEngine<D,T,Antisymmetric>::Zero = 0.0;
+ template<class T, class T2, class Op>
+ struct TensorAssign<TensorEngine<1,T,Antisymmetric>,T2,Op,0,1,0,1>
+ {
+ static void apply(TensorEngine<1,T,Antisymmetric> &x, const T2 &y,
+ Op op=Op())
+ { }
+ };
+ template<class T, class T2, class Op>
+ struct TensorAssign<TensorEngine<2,T,Antisymmetric>,T2,Op,0,2,0,2>
+ {
+ static void apply(TensorEngine<2,T,Antisymmetric> &x, const T2 &y,
+ Op op=Op())
+ {
+ TensorAssign<TensorEngine<2,T,Antisymmetric>,T2,Op,1,1,0,1>::apply(x,y,op);
+ }
+ };
+ template<class T, class T2, class Op>
+ struct TensorAssign<TensorEngine<3,T,Antisymmetric>,T2,Op,0,3,0,3>
+ {
+ static void apply(TensorEngine<3,T,Antisymmetric> &x, const T2 &y,
+ Op op=Op())
+ {
+ TensorAssign<TensorEngine<3,T,Antisymmetric>,T2,Op,1,1,0,1>::apply(x,y,op);
+ TensorAssign<TensorEngine<3,T,Antisymmetric>,T2,Op,2,1,0,2>::apply(x,y,op);
+ }
+ };
+ template<int D, class T>
+ class TensorEngine<D, T, Symmetric>
+ {
+ public:
+ enum { dimensions=2 };
+ enum { d=D };
+ typedef T Element_t;
+ typedef Symmetric EngineTag_t;
+ typedef T& ElementRef_t;
+ typedef const T& ConstElementRef_t;
+ typedef T& CTElementRef_t;
+ typedef const T& CTConstElementRef_t;
+ typedef TensorEngine<D,T,Symmetric> This_t;
+ TensorEngine()
+ {
+ PoomaCTAssert<(ElementProperties<T>::hasTrivialDefaultConstructor && ElementProperties<T>::hasTrivialDestructor && ElementProperties<T>::concrete)>::test();
+ }
+ TensorEngine(const TensorEngine<D,T,Symmetric> &x)
+ {
+ TensorAssign<This_t,This_t,OpAssign,0,d,0,d>::
+ apply(*this,x,OpAssign());
+ }
+ template<class X>
+ explicit TensorEngine(const X &x)
+ {
+ *this = x;
+ }
+ explicit TensorEngine(const T &x) {
+ for (int i = 0; i < TensorStorageSize<d, EngineTag_t>::Size; i++) {
+ x_m[i] = x;
+ }
+ }
+ template<class X1, class X2, class X3>
+ TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3)
+ {
+ PoomaCTAssert<(D == 2)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ }
+ template<class X1, class X2, class X3, class X4, class X5, class X6>
+ TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3, const X4 &x4,
+ const X5 &x5, const X6 &x6)
+ {
+ PoomaCTAssert<(D == 3)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ (*this)(3) = x4;
+ (*this)(4) = x5;
+ (*this)(5) = x6;
+ }
+ ~TensorEngine() {}
+ This_t&
+ operator=(const This_t &x)
+ {
+ if (this != &x) {
+ TensorAssign<This_t,This_t,OpAssign,0,d,0,d>::
+ apply(*this,x,OpAssign());
+ }
+ return *this;
+ }
+ template<class V>
+ This_t&
+ operator=(const V &x)
+ {
+ TensorAssign<This_t,V,OpAssign,0,d,0,d>::
+ apply(*this,x,OpAssign());
+ return *this;
+ }
+ template<int I, int J>
+ CTConstElementRef_t getIJ() const
+ {
+ PoomaCTAssert<((I >= 0) && (I < D) && (J >= 0) && (J < D))>::test();
+ int lo = I < J ? I : J;
+ int hi = I > J ? I : J;
+ return x_m[((hi + 1)*hi/2) + lo];
+ }
+ template<int I, int J>
+ CTElementRef_t getIJ()
+ {
+ PoomaCTAssert<((I >= 0) && (I < D) && (J >= 0) && (J < D))>::test();
+ int lo = I < J ? I : J;
+ int hi = I > J ? I : J;
+ return x_m[((hi + 1)*hi/2) + lo];
+ }
+ ConstElementRef_t operator()(int i,int j) const
+ {
+ ;
+ int lo = i < j ? i : j;
+ int hi = i > j ? i : j;
+ return x_m[((hi + 1)*hi/2) + lo];
+ }
+ ElementRef_t operator()(int i,int j)
+ {
+ ;
+ int lo = i < j ? i : j;
+ int hi = i > j ? i : j;
+ return x_m[((hi + 1)*hi/2) + lo];
+ }
+ ConstElementRef_t operator()(int i) const
+ {
+ ;
+ return x_m[i];
+ }
+ ElementRef_t operator()(int i)
+ {
+ ;
+ return x_m[i];
+ }
+ const T* data() const{
+ return (const T*) &x_m[0];
+ }
+ T* data(){
+ return (T*) &x_m[0];
+ }
+ inline void reverseBytes()
+ {
+ const int sz = TensorStorageSize<d, EngineTag_t>::Size;
+ for (int i = 0; i < sz; ++i)
+ ::reverseBytes(x_m[i]);
+ }
+ private:
+ T x_m[TensorStorageSize<d, EngineTag_t>::Size];
+ };
+ template<class T, class T2, class Op>
+ struct TensorAssign<TensorEngine<2,T,Symmetric>,T2,Op,0,2,0,2>
+ {
+ static void apply(TensorEngine<2,T,Symmetric> &x, const T2 &y,
+ Op op=Op())
+ {
+ TensorAssign<TensorEngine<2,T,Symmetric>,T2,Op,0,1,0,1>::apply(x,y,op);
+ TensorAssign<TensorEngine<2,T,Symmetric>,T2,Op,1,1,0,2>::apply(x,y,op);
+ }
+ };
+ template<class T, class T2, class Op>
+ struct TensorAssign<TensorEngine<3,T,Symmetric>,T2,Op,0,3,0,3>
+ {
+ static void apply(TensorEngine<3,T,Symmetric> &x, const T2 &y,
+ Op op=Op())
+ {
+ TensorAssign<TensorEngine<3,T,Symmetric>,T2,Op,0,1,0,1>::apply(x,y,op);
+ TensorAssign<TensorEngine<3,T,Symmetric>,T2,Op,1,1,0,2>::apply(x,y,op);
+ TensorAssign<TensorEngine<3,T,Symmetric>,T2,Op,2,1,0,3>::apply(x,y,op);
+ }
+ };
+ template<int D, class T>
+ class TensorEngine<D, T, Diagonal>
+ {
+ public:
+ enum { dimensions=2 };
+ enum { d=D };
+ typedef T Element_t;
+ typedef Diagonal EngineTag_t;
+ class AssignProxy {
+ public:
+ AssignProxy(Element_t &elem, int where)
+ : elem_m(elem), where_m(where) { }
+ AssignProxy(const AssignProxy &model)
+ : elem_m(model.elem_m), where_m(where_m) { }
+ AssignProxy &operator=(const AssignProxy &a) const
+ {
+ ;
+ elem_m = a.elem_m;
+ return const_cast<AssignProxy &>(*this);
+ }
+ AssignProxy &operator=(const Element_t &e) const
+ {
+ ;
+ elem_m = e;
+ return const_cast<AssignProxy &>(*this);
+ }
+ operator Element_t() const
+ {
+ return (elem_m);
+ }
+ private:
+ mutable Element_t &elem_m;
+ mutable int where_m;
+ };
+ typedef AssignProxy ElementRef_t;
+ typedef T ConstElementRef_t;
+ typedef T& CTElementRef_t;
+ typedef T CTConstElementRef_t;
+ typedef TensorEngine<D,T,Diagonal> This_t;
+ TensorEngine()
+ {
+ PoomaCTAssert<(ElementProperties<T>::hasTrivialDefaultConstructor && ElementProperties<T>::hasTrivialDestructor && ElementProperties<T>::concrete)>::test();
+ }
+ TensorEngine(const TensorEngine<D,T,Diagonal> &x)
+ {
+ TensorAssign<This_t,This_t,OpAssign,0,d,0,d>::
+ apply(*this,x,OpAssign());
+ }
+ template<class X>
+ explicit TensorEngine(const X &x)
+ {
+ *this = x;
+ }
+ explicit TensorEngine(const T &x) {
+ for (int i = 0; i < TensorStorageSize<d, EngineTag_t>::Size; i++) {
+ x_m[i] = x;
+ }
+ }
+ template<class X1, class X2>
+ TensorEngine(const X1 &x1, const X2 &x2)
+ {
+ PoomaCTAssert<(D == 2)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ }
+ template<class X1, class X2, class X3>
+ TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3)
+ {
+ PoomaCTAssert<(D == 3)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ }
+ template<class X1, class X2, class X3, class X4>
+ TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3, const X4 &x4)
+ {
+ PoomaCTAssert<(D == 4)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ (*this)(3) = x4;
+ }
+ template<class X1, class X2, class X3, class X4, class X5>
+ TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3, const X4 &x4,
+ const X5 &x5)
+ {
+ PoomaCTAssert<(D == 5)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ (*this)(3) = x4;
+ (*this)(4) = x5;
+ }
+ template<class X1, class X2, class X3, class X4, class X5, class X6>
+ TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3, const X4 &x4,
+ const X5 &x5, const X6 &x6)
+ {
+ PoomaCTAssert<(D == 6)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ (*this)(3) = x4;
+ (*this)(4) = x5;
+ (*this)(5) = x6;
+ }
+ template<class X1, class X2, class X3, class X4, class X5, class X6,
+ class X7>
+ TensorEngine(const X1 &x1, const X2 &x2, const X3 &x3, const X4 &x4,
+ const X5 &x5, const X6 &x6, const X7 &x7)
+ {
+ PoomaCTAssert<(D == 7)>::test();
+ (*this)(0) = x1;
+ (*this)(1) = x2;
+ (*this)(2) = x3;
+ (*this)(3) = x4;
+ (*this)(4) = x5;
+ (*this)(5) = x6;
+ (*this)(6) = x7;
+ }
+ ~TensorEngine() {}
+ This_t&
+ operator=(const This_t &x)
+ {
+ if (this != &x) {
+ TensorAssign<This_t,This_t,OpAssign,0,d,0,d>::
+ apply(*this,x,OpAssign());
+ }
+ return *this;
+ }
+ template<class V>
+ This_t&
+ operator=(const V &x)
+ {
+ TensorAssign<This_t,V,OpAssign,0,d,0,d>::
+ apply(*this,x,OpAssign());
+ return *this;
+ }
+ template<int I, int J>
+ CTConstElementRef_t getIJ() const
+ {
+ PoomaCTAssert<((I >= 0) && (I < d) && (J >= 0) && (J < d))>::test();
+ if (I != J) {
+ return This_t::Zero;
+ } else {
+ return x_m[I];
+ }
+ }
+ template<int I, int J>
+ CTElementRef_t getIJ()
+ {
+ PoomaCTAssert<((I >= 0) && (I < d) && (J >= 0) && (J < d))>::test();
+ PoomaCTAssert<(I == J)>::test();
+ return x_m[I];
+ }
+ ConstElementRef_t operator()(int i, int j) const
+ {
+ ;
+ if (i != j) {
+ return This_t::Zero;
+ } else {
+ return x_m[i];
+ }
+ }
+ ElementRef_t operator()(int i, int j)
+ {
+ ;
+ if (i != j) {
+ return AssignProxy(This_t::Zero, 0);
+ } else {
+ return AssignProxy(x_m[i], 1);
+ }
+ }
+ ConstElementRef_t operator()(int i) const
+ {
+ ;
+ return x_m[i];
+ }
+ ElementRef_t operator()(int i)
+ {
+ ;
+ return AssignProxy(x_m[i], 1);
+ }
+ const T* data() const{
+ return (const T*) &x_m[0];
+ }
+ T* data(){
+ return (T*) &x_m[0];
+ }
+ inline void reverseBytes()
+ {
+ const int sz = TensorStorageSize<d, EngineTag_t>::Size;
+ for (int i = 0; i < sz; ++i)
+ ::reverseBytes(x_m[i]);
+ }
+ private:
+ T x_m[TensorStorageSize<d, EngineTag_t>::Size];
+ static T Zero;
+ };
+ template<int D, class T>
+ T TensorEngine<D,T,Diagonal>::Zero = 0.0;
+ template<class T, class T2, class Op>
+ struct TensorAssign<TensorEngine<2,T,Diagonal>,T2,Op,0,2,0,2>
+ {
+ static void apply(TensorEngine<2,T,Diagonal> &x, const T2 &y, Op op=Op())
+ {
+ TensorAssign<TensorEngine<2,T,Diagonal>,T2,Op,0,1,0,1>::apply(x,y,op);
+ TensorAssign<TensorEngine<2,T,Diagonal>,T2,Op,1,1,1,1>::apply(x,y,op);
+ }
+ };
+ template<class T, class T2, class Op>
+ struct TensorAssign<TensorEngine<3,T,Diagonal>,T2,Op,0,3,0,3>
+ {
+ static void apply(TensorEngine<3,T,Diagonal> &x, const T2 &y, Op op=Op())
+ {
+ TensorAssign<TensorEngine<3,T,Diagonal>,T2,Op,0,1,0,1>::apply(x,y,op);
+ TensorAssign<TensorEngine<3,T,Diagonal>,T2,Op,1,1,1,1>::apply(x,y,op);
+ TensorAssign<TensorEngine<3,T,Diagonal>,T2,Op,2,1,2,1>::apply(x,y,op);
+ }
+ };
+ template<class T, class Components> struct ComponentAccess;
+ template<int D, class T, class E, int N>
+ struct ComponentAccess< Tensor<D, T, E>, Loc<N> >
+ {
+ typedef Tensor<D, T, E> V;
+ typedef typename V::Element_t Element_t;
+ typedef typename V::ElementRef_t ElementRef_t;
+ static inline ElementRef_t indexRef(V &t, const Loc<N> &l)
+ {
+ PoomaCTAssert<(N==2)>::test();
+ return t(l[0].first(), l[1].first());
+ }
+ static inline Element_t index(const V &t, const Loc<N> &l)
+ {
+ PoomaCTAssert<(N==2)>::test();
+ return t(l[0].first(), l[1].first());
+ }
+ };
+ template<int D, class T, int I, int J>
+ struct TensorElem< TensorEngine<D,T,Full> , I , J>
+ {
+ typedef TensorEngine<D,T,Full> V;
+ typedef TensorEngineElem<D,T,Full,I,J,
+ Writable<D,Full,I,J>::value> TE;
+ typedef typename TE::Element_t Element_t;
+ typedef typename TE::ConstElementRef_t ConstElementRef_t;
+ typedef typename TE::ElementRef_t ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return TE::get(x); }
+ static ElementRef_t get(V& x) { return TE::get(x); }
+ };
+ template<int D, class T, int I, int J>
+ struct TensorElem< TensorEngine<D,T,Antisymmetric> , I , J>
+ {
+ typedef TensorEngine<D,T,Antisymmetric> V;
+ typedef TensorEngineElem<D,T,Antisymmetric,I,J,
+ Writable<D,Antisymmetric,I,J>::value> TE;
+ typedef typename TE::Element_t Element_t;
+ typedef typename TE::ConstElementRef_t ConstElementRef_t;
+ typedef typename TE::ElementRef_t ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return TE::get(x); }
+ static ElementRef_t get(V& x) { return TE::get(x); }
+ };
+ template<int D, class T, int I, int J>
+ struct TensorElem< TensorEngine<D,T,Symmetric> , I , J>
+ {
+ typedef TensorEngine<D,T,Symmetric> V;
+ typedef TensorEngineElem<D,T,Symmetric,I,J,
+ Writable<D,Symmetric,I,J>::value> TE;
+ typedef typename TE::Element_t Element_t;
+ typedef typename TE::ConstElementRef_t ConstElementRef_t;
+ typedef typename TE::ElementRef_t ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return TE::get(x); }
+ static ElementRef_t get(V& x) { return TE::get(x); }
+ };
+ template<int D, class T, int I, int J>
+ struct TensorElem< TensorEngine<D,T,Diagonal> , I , J>
+ {
+ typedef TensorEngine<D,T,Diagonal> V;
+ typedef TensorEngineElem<D,T,Diagonal,I,J,
+ Writable<D,Diagonal,I,J>::value> TE;
+ typedef typename TE::Element_t Element_t;
+ typedef typename TE::ConstElementRef_t ConstElementRef_t;
+ typedef typename TE::ElementRef_t ElementRef_t;
+ static ConstElementRef_t get(const V& x) { return TE::get(x); }
+ static ElementRef_t get(V& x) { return TE::get(x); }
+ };
+ template<class OutputEngineTag, int D, class T, class EngineTag>
+ class Symmetrize;
+ template<class OutputEngineTag, int D, class T, class EngineTag>
+ Tensor<D, T, OutputEngineTag>
+ symmetrize(const Tensor<D, T, EngineTag> &x)
+ {
+ Symmetrize<OutputEngineTag, D, T, EngineTag> s;
+ return s.apply(x);
+ }
+ template<class OutputEngineTag, int D, class T, class E>
+ struct UnaryReturn< Tensor<D,T,E> , FnSymmetrize<OutputEngineTag> >
+ {
+ typedef Tensor<D,T,OutputEngineTag> Type_t;
+ };
+ template<class OutputEngineTag, int D, class T, class EngineTag>
+ class Symmetrize
+ {
+ public:
+ Symmetrize() {};
+ Tensor<D, T, OutputEngineTag>
+ apply(const Tensor<D, T, EngineTag> &x) {
+ Tensor<D, T, OutputEngineTag> y(-99.99);
+ return y;
+ }
+ };
+ template<int D, class T, class EngineTag>
+ class Symmetrize<Symmetric, D, T, EngineTag>
+ {
+ public:
+ Tensor<D, T, Symmetric>
+ apply(const Tensor<D, T, EngineTag> &x)
+ {
+ Tensor<D, T, Symmetric> y;
+ for (int i = 0; i < D; i++) {
+ y(i,i) = x(i,i);
+ for (int j = i + 1; j < D; j++) {
+ y(i,j) = (x(i,j) + x(j,i))*0.5;
+ }
+ }
+ return y;
+ }
+ };
+ template<int D, class T>
+ class Symmetrize<Symmetric, D, T, Antisymmetric>
+ {
+ public:
+ Tensor<D, T, Symmetric>
+ apply(const Tensor<D, T, Antisymmetric> &x)
+ {
+ Tensor<D, T, Symmetric> y(0.0);
+ return y;
+ }
+ };
+ template<int D, class T>
+ class Symmetrize<Symmetric, D, T, Diagonal>
+ {
+ public:
+ Tensor<D, T, Symmetric>
+ apply(const Tensor<D, T, Diagonal> &x)
+ {
+ Tensor<D, T, Symmetric> y(0.0);
+ for (int i = 0; i < D; i++) {
+ y(i,i) = x(i,i);
+ }
+ return y;
+ }
+ };
+ template<int D, class T, class EngineTag>
+ class Symmetrize<Antisymmetric, D, T, EngineTag>
+ {
+ public:
+ Tensor<D, T, Antisymmetric>
+ apply(const Tensor<D, T, EngineTag> &x)
+ {
+ Tensor<D, T, Antisymmetric> y;
+ for (int i = 1; i < D; i++) {
+ for (int j = 0; j < i; j++) {
+ y(((i - 1)*i/2)+j) = (x(i,j) - x(j,i))*0.5;
+ }
+ }
+ return y;
+ }
+ };
+ template<int D, class T>
+ class Symmetrize<Antisymmetric, D, T, Symmetric>
+ {
+ public:
+ Tensor<D, T, Antisymmetric>
+ apply(const Tensor<D, T, Symmetric> &x)
+ {
+ Tensor<D, T, Antisymmetric> y(0.0);
+ return y;
+ }
+ };
+ template<int D, class T>
+ class Symmetrize<Antisymmetric, D, T, Diagonal>
+ {
+ public:
+ Tensor<D, T, Antisymmetric>
+ apply(const Tensor<D, T, Diagonal> &x)
+ {
+ Tensor<D, T, Antisymmetric> y(0.0);
+ return y;
+ }
+ };
+ template<int D, class T, class EngineTag>
+ class Symmetrize<Diagonal, D, T, EngineTag>
+ {
+ public:
+ Tensor<D, T, Diagonal>
+ apply(const Tensor<D, T, EngineTag> &x)
+ {
+ Tensor<D, T, Diagonal> y;
+ for (int i = 0; i < D; i++) {
+ y(i) = x(i,i);
+ }
+ return y;
+ }
+ };
+ template<int D, class T>
+ class Symmetrize<Diagonal, D, T, Antisymmetric>
+ {
+ public:
+ Tensor<D, T, Diagonal>
+ apply(const Tensor<D, T, Antisymmetric> &x)
+ {
+ Tensor<D, T, Diagonal> y(0.0);
+ return y;
+ }
+ };
+ template<int D, class T>
+ class Symmetrize<Diagonal, D, T, Symmetric>
+ {
+ public:
+ Tensor<D, T, Diagonal>
+ apply(const Tensor<D, T, Symmetric> &x)
+ {
+ Tensor<D, T, Diagonal> y(0.0);
+ for (int i = 0; i < D; i++) {
+ y(i) = x(i,i);
+ }
+ return y;
+ }
+ };
+ template<int D, class T, class EngineTag>
+ class Symmetrize<Full, D, T, EngineTag>
+ {
+ public:
+ Tensor<D, T, Full>
+ apply(const Tensor<D, T, EngineTag> &x)
+ {
+ Tensor<D, T, Full> y;
+ for (int i = 0; i < D; i++) {
+ for (int j = 0; j < D; j++) {
+ y(i,j) = x(i,j);
+ }
+ }
+ return y;
+ }
+ };
+ template<int D, class T, class E> class Tensor;
+ template<int D, class T, class E> class TensorEngine;
+ template<int D, class T, class E> class Vector;
+ template<int D, class T, class E> class VectorEngine;
+ template<class V1, class T2, int I, int B, int L>
+ struct VectorDotTensor
+ {
+ typedef typename VectorDotTensor<V1,T2,I,B,L/2>::Type_t E1;
+ typedef typename VectorDotTensor<V1,T2,I,B+L/2,L-L/2>::Type_t E2;
+ typedef typename BinaryReturn<E1,E2,OpAdd>::Type_t Type_t;
+ static Type_t get(const V1& v1, const T2& t2)
+ {
+ return
+ VectorDotTensor<V1,T2,I,B,L/2>::get(v1,t2) +
+ VectorDotTensor<V1,T2,I,B+L/2,L-L/2>::get(v1,t2);
+ }
+ };
+ template<class V1, class T2, int I, int B>
+ struct VectorDotTensor<V1,T2,I,B,1>
+ {
+ typedef typename VectorElem<V1,B>::Element_t E1;
+ typedef typename TensorElem<T2,B,I>::Element_t E2;
+ typedef typename BinaryReturn<E1,E2,OpMultiply>::Type_t Type_t;
+ static Type_t get(const V1& v1, const T2& t2)
+ {
+ return VectorElem<V1,B>::get(v1) * TensorElem<T2,B,I>::get(t2);
+ }
+ };
+ template<int D, class T1, class T2, class T3, class E1, class E2, int I>
+ struct VectorEngineElem<D,T3,
+ BinaryVectorOp<Vector<D,T1,E1>,Tensor<D,T2,E2>,FnDot>,I>
+ {
+ typedef Vector<D,T1,E1> V1;
+ typedef Tensor<D,T2,E2> V2;
+ typedef VectorEngine<D,T3,BinaryVectorOp<V1,V2,FnDot> > V;
+ typedef typename VectorDotTensor<V1,V2,I,0,D>::Type_t T0;
+ typedef T0 Element_t;
+ typedef T0 ConstElementRef_t;
+ typedef T0 ElementRef_t;
+ static T0 get(const V& x)
+ {
+ return VectorDotTensor<V1,V2,I,0,D>::get(x.v1_m,x.v2_m);
+ }
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< Vector<D,T1,E1> , Tensor<D,T2,E2> , FnDot >
+ {
+ typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T0;
+ typedef Vector<D,T0,Full> Type_t;
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ inline
+ typename BinaryReturn< Vector<D,T1,E1>,Tensor<D,T2,E2> , FnDot >::Type_t
+ dot( const Vector<D,T1,E1>& v1, const Tensor<D,T2,E2>& v2 )
+ {
+ typedef Vector<D,T1,E1> V1;
+ typedef Tensor<D,T2,E2> V2;
+ typedef typename BinaryReturn<V1,V2,FnDot>::Type_t Return_t;
+ typedef typename Return_t::Element_t T3;
+ typedef Vector<D,T3,BinaryVectorOp<V1,V2,FnDot> > Expr_t;
+ return Return_t( Expr_t(v1,v2) );
+ }
+ template<class T1, class V2, int I, int B, int L>
+ struct TensorDotVector
+ {
+ typedef typename TensorDotVector<T1,V2,I,B,L/2>::Type_t E1;
+ typedef typename TensorDotVector<T1,V2,I,B+L/2,L-L/2>::Type_t E2;
+ typedef typename BinaryReturn<E1,E2,OpAdd>::Type_t Type_t;
+ static Type_t get(const T1& t1, const V2& v2)
+ {
+ return
+ TensorDotVector<T1,V2,I,B,L/2>::get(t1,v2) +
+ TensorDotVector<T1,V2,I,B+L/2,L-L/2>::get(t1,v2);
+ }
+ };
+ template<class T1, class V2, int I, int B>
+ struct TensorDotVector<T1,V2,I,B,1>
+ {
+ typedef typename TensorElem<T1,I,B>::Element_t E1;
+ typedef typename VectorElem<V2,B>::Element_t E2;
+ typedef typename BinaryReturn<E1,E2,OpMultiply>::Type_t Type_t;
+ static Type_t get(const T1& t1, const V2& v2)
+ {
+ return TensorElem<T1,I,B>::get(t1) * VectorElem<V2,B>::get(v2);
+ }
+ };
+ template<int D, class T1, class T2, class T3, class E1, class E2, int I>
+ struct VectorEngineElem<D,T3,
+ BinaryVectorOp<Tensor<D,T1,E1>,Vector<D,T2,E2>,FnDot>,I>
+ {
+ typedef Tensor<D,T1,E1> V1;
+ typedef Vector<D,T2,E2> V2;
+ typedef VectorEngine<D,T3,BinaryVectorOp<V1,V2,FnDot> > V;
+ typedef typename TensorDotVector<V1,V2,I,0,D>::Type_t T0;
+ typedef T0 Element_t;
+ typedef T0 ConstElementRef_t;
+ typedef T0 ElementRef_t;
+ static T0 get(const V& x)
+ {
+ return TensorDotVector<V1,V2,I,0,D>::get(x.v1_m,x.v2_m);
+ }
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< Tensor<D,T1,E1> , Vector<D,T2,E2> , FnDot >
+ {
+ typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T0;
+ typedef Vector<D,T0,Full> Type_t;
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ inline
+ typename BinaryReturn< Tensor<D,T1,E1> , Vector<D,T2,E2>, FnDot >::Type_t
+ dot( const Tensor<D,T1,E1>& v1 , const Vector<D,T2,E2>& v2 )
+ {
+ typedef Tensor<D,T1,E1> V1;
+ typedef Vector<D,T2,E2> V2;
+ typedef typename BinaryReturn<V1,V2,FnDot>::Type_t Return_t;
+ typedef typename Return_t::Element_t T3;
+ typedef Vector<D,T3,BinaryVectorOp<V1,V2,FnDot> > Expr_t;
+ return Return_t( Expr_t(v1,v2) );
+ }
+ template<int D, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< Vector<D,T1,E1> , Vector<D,T2,E2>, FnOuterProduct >
+ {
+ typedef typename BinaryReturn<T1, T2, OpMultiply>::Type_t T0;
+ typedef Tensor<D, T0> Type_t;
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ inline
+ typename BinaryReturn<Vector<D,T1,E1>, Vector<D,T2,E2>, FnOuterProduct>::Type_t
+ outerProduct(const Vector<D,T1,E1> &v1, const Vector<D,T2,E2> &v2 )
+ {
+ typedef typename
+ BinaryReturn<Vector<D,T1,E1>, Vector<D,T2,E2>, FnOuterProduct>::Type_t
+ Return_t;
+ Return_t ret;
+ for (int i = 0; i < D; ++i)
+ for (int j = 0; j < D; ++j)
+ ret(i, j) = v1(i) * v2(j);
+ return ret;
+ }
+ template<int D1, int D2, class T, class E> class TinyMatrix;
+ template<int D1, int D2, class T, class E> class TinyMatrixEngine;
+ template<int D, class T, class E> class Vector;
+ template<int D, class T, class E> class VectorEngine;
+ template<class V1, class T2, int I, int B, int L>
+ struct VectorDotTinyMatrix
+ {
+ typedef typename VectorDotTinyMatrix<V1,T2,I,B,L/2>::Type_t E1;
+ typedef typename VectorDotTinyMatrix<V1,T2,I,B+L/2,L-L/2>::Type_t E2;
+ typedef typename BinaryReturn<E1,E2,OpAdd>::Type_t Type_t;
+ static Type_t get(const V1& v1, const T2& t2)
+ {
+ return
+ VectorDotTinyMatrix<V1,T2,I,B,L/2>::get(v1,t2) +
+ VectorDotTinyMatrix<V1,T2,I,B+L/2,L-L/2>::get(v1,t2);
+ }
+ };
+ template<class V1, class T2, int I, int B>
+ struct VectorDotTinyMatrix<V1,T2,I,B,1>
+ {
+ typedef typename VectorElem<V1,B>::Element_t E1;
+ typedef typename TinyMatrixElem<T2,B,I>::Element_t E2;
+ typedef typename BinaryReturn<E1,E2,OpMultiply>::Type_t Type_t;
+ static Type_t get(const V1& v1, const T2& t2)
+ {
+ return VectorElem<V1,B>::get(v1) * TinyMatrixElem<T2,B,I>::get(t2);
+ }
+ };
+ template<int D1, int D2, class T1, class T2, class T3, class E1, class E2, int I>
+ struct VectorEngineElem<D2,T3,
+ BinaryVectorOp<Vector<D1,T1,E1>,TinyMatrix<D1,D2,T2,E2>,FnDot>,I>
+ {
+ typedef Vector<D1,T1,E1> V1;
+ typedef TinyMatrix<D1,D2,T2,E2> V2;
+ typedef VectorEngine<D2,T3,BinaryVectorOp<V1,V2,FnDot> > V;
+ typedef typename VectorDotTinyMatrix<V1,V2,I,0,D1>::Type_t T0;
+ typedef T0 Element_t;
+ typedef T0 ConstElementRef_t;
+ typedef T0 ElementRef_t;
+ static T0 get(const V& x)
+ {
+ return VectorDotTinyMatrix<V1,V2,I,0,D1>::get(x.v1_m,x.v2_m);
+ }
+ };
+ template<int D1, int D2, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< Vector<D1,T1,E1> , TinyMatrix<D1,D2,T2,E2> , FnDot >
+ {
+ typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T0;
+ typedef Vector<D2,T0,Full> Type_t;
+ };
+ template<int D1, int D2, class T1, class T2, class E1, class E2>
+ inline
+ typename BinaryReturn< Vector<D1,T1,E1>,TinyMatrix<D1,D2,T2,E2> , FnDot >::Type_t
+ dot( const Vector<D1,T1,E1>& v1, const TinyMatrix<D1,D2,T2,E2>& v2 )
+ {
+ typedef Vector<D1,T1,E1> V1;
+ typedef TinyMatrix<D1,D2,T2,E2> V2;
+ typedef typename BinaryReturn<V1,V2,FnDot>::Type_t Return_t;
+ typedef typename Return_t::Element_t T3;
+ typedef Vector<D2,T3,BinaryVectorOp<V1,V2,FnDot> > Expr_t;
+ return Return_t( Expr_t(v1,v2) );
+ }
+ template<class T1, class V2, int I, int B, int L>
+ struct TinyMatrixDotVector
+ {
+ typedef typename TinyMatrixDotVector<T1,V2,I,B,L/2>::Type_t E1;
+ typedef typename TinyMatrixDotVector<T1,V2,I,B+L/2,L-L/2>::Type_t E2;
+ typedef typename BinaryReturn<E1,E2,OpAdd>::Type_t Type_t;
+ static Type_t get(const T1& t1, const V2& v2)
+ {
+ return
+ TinyMatrixDotVector<T1,V2,I,B,L/2>::get(t1,v2) +
+ TinyMatrixDotVector<T1,V2,I,B+L/2,L-L/2>::get(t1,v2);
+ }
+ };
+ template<class T1, class V2, int I, int B>
+ struct TinyMatrixDotVector<T1,V2,I,B,1>
+ {
+ typedef typename TinyMatrixElem<T1,I,B>::Element_t E1;
+ typedef typename VectorElem<V2,B>::Element_t E2;
+ typedef typename BinaryReturn<E1,E2,OpMultiply>::Type_t Type_t;
+ static Type_t get(const T1& t1, const V2& v2)
+ {
+ return TinyMatrixElem<T1,I,B>::get(t1) * VectorElem<V2,B>::get(v2);
+ }
+ };
+ template<int D1, int D2, class T1, class T2, class T3, class E1, class E2, int I>
+ struct VectorEngineElem<D1,T3,
+ BinaryVectorOp<TinyMatrix<D1,D2,T1,E1>,Vector<D2,T2,E2>,FnDot>,I>
+ {
+ typedef TinyMatrix<D1,D2,T1,E1> V1;
+ typedef Vector<D2,T2,E2> V2;
+ typedef VectorEngine<D1,T3,BinaryVectorOp<V1,V2,FnDot> > V;
+ typedef typename TinyMatrixDotVector<V1,V2,I,0,D2>::Type_t T0;
+ typedef T0 Element_t;
+ typedef T0 ConstElementRef_t;
+ typedef T0 ElementRef_t;
+ static T0 get(const V& x)
+ {
+ return TinyMatrixDotVector<V1,V2,I,0,D2>::get(x.v1_m,x.v2_m);
+ }
+ };
+ template<int D1, int D2, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< TinyMatrix<D1,D2,T1,E1> , Vector<D2,T2,E2> , FnDot >
+ {
+ typedef typename BinaryReturn<T1,T2,OpMultiply>::Type_t T0;
+ typedef Vector<D1,T0,Full> Type_t;
+ };
+ template<int D1, int D2, class T1, class T2, class E1, class E2>
+ inline
+ typename BinaryReturn< TinyMatrix<D1,D2,T1,E1> , Vector<D2,T2,E2>, FnDot >::Type_t
+ dot( const TinyMatrix<D1,D2,T1,E1>& v1 , const Vector<D2,T2,E2>& v2 )
+ {
+ typedef TinyMatrix<D1,D2,T1,E1> V1;
+ typedef Vector<D2,T2,E2> V2;
+ typedef typename BinaryReturn<V1,V2,FnDot>::Type_t Return_t;
+ typedef typename Return_t::Element_t T3;
+ typedef Vector<D1,T3,BinaryVectorOp<V1,V2,FnDot> > Expr_t;
+ return Return_t( Expr_t(v1,v2) );
+ }
+ template<int D, class T1, class T2, class E1, class E2>
+ struct BinaryReturn< Vector<D,T1,E1> , Vector<D,T2,E2>, FnOuterProductAsTinyMatrix >
+ {
+ typedef typename BinaryReturn<T1, T2, OpMultiply>::Type_t T0;
+ typedef TinyMatrix<D, D, T0> Type_t;
+ };
+ template<int D, class T1, class T2, class E1, class E2>
+ inline
+ typename BinaryReturn<Vector<D,T1,E1>, Vector<D,T2,E2>, FnOuterProductAsTinyMatrix>::Type_t
+ outerProductAsTinyMatrix(const Vector<D,T1,E1> &v1, const Vector<D,T2,E2> &v2 )
+ {
+ typedef typename
+ BinaryReturn<Vector<D,T1,E1>, Vector<D,T2,E2>, FnOuterProduct>::Type_t
+ Return_t;
+ Return_t ret;
+ for (int i = 0; i < D; ++i)
+ for (int j = 0; j < D; ++j)
+ ret(i, j) = v1(i) * v2(j);
+ return ret;
+ }
+ template<int Dim, class T, class EngineTag, class Op>
+ inline T globalReduction(const Vector<Dim, T, EngineTag> &v,
+ const Op &op)
+ {
+ T val = v(0);
+ for (int i = 1; i < Dim; i++)
+ op(val, v(i));
+ return val;
+ }
+ template<int Dim, class T, class EngineTag, class Op>
+ inline T globalReduction(const Tensor<Dim, T, EngineTag> &t,
+ const Op &op)
+ {
+ T val = t(0, 0);
+ for (int k = 1; k < Dim; k++)
+ op(val, t(k, 0));
+ for (int j = 1; j < Dim; j++)
+ for (int i = 0; i < Dim; i++)
+ op(val, t(i, j));
+ return val;
+ }
+ template<int Dim, class T, class Op>
+ inline T globalReduction(const Tensor<Dim, T, Full> &t,
+ const Op &op)
+ {
+ T val = t(0, 0);
+ for (int i = 1; i < TensorStorageSize<Dim, Full>::Size; i++)
+ op(val, t(i));
+ return val;
+ }
+ template<int Dim, class T, class Op>
+ inline T globalReduction(const Tensor<Dim, T, Antisymmetric> &t,
+ const Op &op)
+ {
+ T val = t(0,0);
+ for (int i = 0; i < TensorStorageSize<Dim, Antisymmetric>::Size - 1 / Dim; i++)
+ {
+ op(val, t(i));
+ op(val, -t(i));
+ }
+ return val;
+ }
+ template<int Dim, class T, class Op>
+ inline T globalReduction(const Tensor<Dim, T, Diagonal> &t,
+ const Op &op)
+ {
+ T val = t(0);
+ for (int i = 1; i < TensorStorageSize<Dim, Diagonal>::Size; i++)
+ op(val, t(i));
+ if (Dim > 1)
+ op(val, T(0));
+ return val;
+ }
+ template<int Dim1, int Dim2, class T, class EngineTag, class Op>
+ inline T globalReduction(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m,
+ const Op &op)
+ {
+ T val = m(0, 0);
+ for (int k = 1; k < Dim1; k++)
+ op(val, m(k, 0));
+ for (int j = 1; j < Dim2; j++)
+ for (int i = 0; i < Dim1; i++)
+ op(val, m(i, j));
+ return val;
+ }
+ template<int Dim1, int Dim2, class T, class Op>
+ inline T globalReduction(const TinyMatrix<Dim1, Dim2, T, Full> &m,
+ const Op &op)
+ {
+ T val = m(0, 0);
+ for (int i = 1; i < Dim1 * Dim2; i++)
+ op(val, m(i));
+ return val;
+ }
+ template<int Dim, class T, class EngineTag>
+ T sum(const Vector<Dim, T, EngineTag> &v)
+ {
+ return globalReduction(v, OpAddAssign());
+ }
+ template<int Dim, class T, class EngineTag>
+ T prod(const Vector<Dim, T, EngineTag> &v)
+ {
+ return globalReduction(v, OpMultiplyAssign());
+ }
+ template<int Dim, class T, class EngineTag>
+ T min(const Vector<Dim, T, EngineTag> &v)
+ {
+ return globalReduction(v, FnMinAssign());
+ }
+ template<int Dim, class T, class EngineTag>
+ T max(const Vector<Dim, T, EngineTag> &v)
+ {
+ return globalReduction(v, FnMaxAssign());
+ }
+ template<int Dim, class T, class EngineTag>
+ bool all(const Vector<Dim, T, EngineTag> &v)
+ {
+ for (int i = 0; i < Dim; i++)
+ if (!v(i))
+ return false;
+ return true;
+ }
+ template<int Dim, class T, class EngineTag>
+ bool any(const Vector<Dim, T, EngineTag> &v)
+ {
+ for (int i = 0; i < Dim; i++)
+ if (v(i))
+ return true;
+ return false;
+ }
+ template<int Dim, class T, class EngineTag>
+ T bitOr(const Vector<Dim, T, EngineTag> &v)
+ {
+ return globalReduction(v, OpBitwiseOrAssign());
+ }
+ template<int Dim, class T, class EngineTag>
+ T bitAnd(const Vector<Dim, T, EngineTag> &v)
+ {
+ return globalReduction(v, OpBitwiseAndAssign());
+ }
+ template<int Dim, class T, class EngineTag>
+ T sum(const Tensor<Dim, T, EngineTag> &t)
+ {
+ return globalReduction(t, OpAddAssign());
+ }
+ template<int Dim, class T>
+ T sum(const Tensor<Dim, T, Antisymmetric> &t)
+ {
+ return T(0);
+ }
+ template<int Dim, class T, class EngineTag>
+ T prod(const Tensor<Dim, T, EngineTag> &t)
+ {
+ return globalReduction(t, OpMultiplyAssign());
+ }
+ template<int Dim, class T>
+ T prod(const Tensor<Dim, T, Antisymmetric> &t)
+ {
+ return T(0);
+ }
+ template<int Dim, class T, class EngineTag>
+ T min(const Tensor<Dim, T, EngineTag> &t)
+ {
+ return globalReduction(t, FnMinAssign());
+ }
+ template<int Dim, class T, class EngineTag>
+ T max(const Tensor<Dim, T, EngineTag> &t)
+ {
+ return globalReduction(t, FnMaxAssign());
+ }
+ template<int Dim, class T, class EngineTag>
+ bool all(const Tensor<Dim, T, EngineTag> &t)
+ {
+ for (int j = 0; j < Dim; j++)
+ for (int i = 0; i < Dim; i++)
+ if (!t(i, j))
+ return false;
+ return true;
+ }
+ template<int Dim, class T>
+ bool all(const Tensor<Dim, T, Antisymmetric> &t)
+ {
+ return false;
+ }
+ template<int Dim, class T, class EngineTag>
+ bool any(const Tensor<Dim, T, EngineTag> &t)
+ {
+ for (int j = 0; j < Dim; j++)
+ for (int i = 0; i < Dim; i++)
+ if (t(i, j))
+ return true;
+ return false;
+ }
+ template<int Dim, class T, class EngineTag>
+ T bitOr(const Tensor<Dim, T, EngineTag> &t)
+ {
+ return globalReduction(t, OpBitwiseOrAssign());
+ }
+ template<int Dim, class T, class EngineTag>
+ T bitAnd(const Tensor<Dim, T, EngineTag> &t)
+ {
+ return globalReduction(t, OpBitwiseAndAssign());
+ }
+ template<int Dim1, int Dim2, class T, class EngineTag>
+ T sum(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
+ {
+ return globalReduction(m, OpAddAssign());
+ }
+ template<int Dim1, int Dim2, class T, class EngineTag>
+ T prod(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
+ {
+ return globalReduction(m, OpMultiplyAssign());
+ }
+ template<int Dim1, int Dim2, class T, class EngineTag>
+ T min(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
+ {
+ return globalReduction(m, FnMinAssign());
+ }
+ template<int Dim1, int Dim2, class T, class EngineTag>
+ T max(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
+ {
+ return globalReduction(m, FnMaxAssign());
+ }
+ template<int Dim1, int Dim2, class T, class EngineTag>
+ bool all(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
+ {
+ for (int j = 0; j < Dim2; j++)
+ for (int i = 0; i < Dim1; i++)
+ if (!m(i, j))
+ return false;
+ return true;
+ }
+ template<int Dim1, int Dim2, class T, class EngineTag>
+ bool any(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
+ {
+ for (int j = 0; j < Dim2; j++)
+ for (int i = 0; i < Dim1; i++)
+ if (m(i, j))
+ return true;
+ return false;
+ }
+ template<int Dim1, int Dim2, class T, class EngineTag>
+ T bitOr(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
+ {
+ return globalReduction(m, OpBitwiseOrAssign());
+ }
+ template<int Dim1, int Dim2, class T, class EngineTag>
+ T bitAnd(const TinyMatrix<Dim1, Dim2, T, EngineTag> &m)
+ {
+ return globalReduction(m, OpBitwiseAndAssign());
+ }
+ template<class T>
+ struct Zero
+ {
+ operator T() const { return T(0); }
+ bool operator==(const Zero<T>&) const { return true; }
+ Zero() {}
+ Zero(const Zero<T>&) {}
+ Zero<T>& operator=(const Zero<T>&) { return *this; }
+ };
+ template<class T, class Op> struct UnaryReturn;
+ template<class T1, class T2, class Op> struct BinaryReturn;
+ template<class T>
+ inline Zero<T> operator*(Zero<T>, const T&) { return Zero<T>(); }
+ template<class T>
+ inline Zero<T> operator*(const T&, Zero<T>) { return Zero<T>(); }
+ template<class T>
+ inline Zero<T> operator*(Zero<T>, Zero<T>) { return Zero<T>(); }
+ template<class T>
+ inline Zero<T> operator/(Zero<T>, const T&) { return Zero<T>(); }
+ template<class T>
+ struct BinaryReturn< Zero<T> , T , OpMultiply >
+ {
+ typedef Zero<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< T, Zero<T> , OpMultiply >
+ {
+ typedef Zero<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< Zero<T>, Zero<T> , OpMultiply >
+ {
+ typedef Zero<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< Zero<T> , T , OpDivide >
+ {
+ typedef Zero<T> Type_t;
+ };
+ template<class T>
+ inline const T& operator+(Zero<T>, const T& x) { return x; }
+ template<class T>
+ inline const T& operator+(const T& x, Zero<T>) { return x; }
+ template<class T>
+ inline Zero<T> operator+(Zero<T>, Zero<T>) { return Zero<T>(); }
+ template<class T>
+ inline T operator-(Zero<T>, const T& x) { return -x; }
+ template<class T>
+ inline const T& operator-(const T& x, Zero<T>) { return x; }
+ template<class T>
+ inline Zero<T> operator-(Zero<T>, Zero<T>) { return Zero<T>(); }
+ template<class T>
+ struct BinaryReturn< Zero<T> , T , OpAdd >
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< T, Zero<T> , OpAdd >
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< Zero<T>, Zero<T> , OpAdd >
+ {
+ typedef Zero<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< Zero<T> , T , OpSubtract >
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< T, Zero<T> , OpSubtract >
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< Zero<T>, Zero<T> , OpSubtract >
+ {
+ typedef Zero<T> Type_t;
+ };
+ template<class T>
+ inline Zero<T> operator-(Zero<T>) { return Zero<T>(); }
+ template<class T>
+ struct UnaryReturn< Zero<T> , OpUnaryMinus >
+ {
+ typedef Zero<T> Type_t;
+ };
+ template<class T>
+ inline Zero<T> operator+(Zero<T>) { return Zero<T>(); }
+ template<class T>
+ struct UnaryReturn< Zero<T> , OpUnaryPlus >
+ {
+ typedef Zero<T> Type_t;
+ };
+ template<class T1, class T2, class Op>
+ struct BinaryReturn< Zero<T1> , Zero<T2>, Op >
+ {
+ typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
+ };
+ template<class T1, class T2>
+ struct BinaryReturn< Zero<T1> , Zero<T2>, OpEQ >
+ {
+ typedef typename BinaryReturn<T1,T2,OpEQ>::Type_t Type_t;
+ };
+ template<class T> struct Zero;
+ template<class T, class Op> struct UnaryReturn;
+ template<class T1, class T2, class Op> struct BinaryReturn;
+ template<class T>
+ struct One
+ {
+ operator T() const { return T(1); }
+ bool operator==(const One<T>&) const { return true; }
+ One() {}
+ One(const One<T>&) {}
+ One<T>& operator=(const One<T>&) { return *this; }
+ };
+ template<class T>
+ struct MinusOne
+ {
+ operator T() const { return T(-1); }
+ bool operator==(const MinusOne<T>&) const { return true; }
+ MinusOne() {}
+ MinusOne(const One<T>&) {}
+ MinusOne<T>& operator=(const MinusOne<T>&) { return *this; }
+ };
+ template<class T>
+ inline MinusOne<T> operator-(One<T>) { return MinusOne<T>(); }
+ template<class T>
+ inline One<T> operator-(MinusOne<T>) { return One<T>(); }
+ template<class T>
+ inline T operator*(One<T>, const T& val) { return val; }
+ template<class T>
+ inline T operator*(const T& val, One<T>) { return val; }
+ template<class T>
+ inline One<T> operator*(One<T>, One<T>) { return One<T>(); }
+ template<class T>
+ inline One<T> operator/(One<T>, One<T>) { return One<T>(); }
+ template<class T>
+ inline T operator/(const T& val, One<T>) { return val; }
+ template<class T>
+ inline T operator*(MinusOne<T>, const T& val) { return -val; }
+ template<class T>
+ inline T operator*(const T& val, MinusOne<T>) { return -val; }
+ template<class T>
+ inline One<T> operator*(MinusOne<T>, MinusOne<T>) { return One<T>(); }
+ template<class T>
+ inline One<T> operator/(MinusOne<T>, MinusOne<T>) { return One<T>(); }
+ template<class T>
+ inline T operator/(const T& val, MinusOne<T>) { return -val; }
+ template<class T>
+ inline MinusOne<T> operator*(MinusOne<T>, One<T>) { return MinusOne<T>(); }
+ template<class T>
+ inline MinusOne<T> operator*(One<T>, MinusOne<T>) { return MinusOne<T>(); }
+ template<class T>
+ inline MinusOne<T> operator/(MinusOne<T>, One<T>) { return MinusOne<T>(); }
+ template<class T>
+ inline MinusOne<T> operator/(One<T>, MinusOne<T>) { return MinusOne<T>(); }
+ template<class T>
+ inline Zero<T> operator-(One<T>, One<T>) { return Zero<T>(); }
+ template<class T>
+ inline Zero<T> operator-(MinusOne<T>, MinusOne<T>) { return Zero<T>(); }
+ template<class T>
+ inline Zero<T> operator+(One<T>, MinusOne<T>) { return Zero<T>(); }
+ template<class T>
+ inline Zero<T> operator+(MinusOne<T>, One<T>) { return Zero<T>(); }
+ template<class T>
+ inline MinusOne<T> operator-(Zero<T>, One<T>) { return MinusOne<T>(); }
+ template<class T>
+ inline One<T> operator-(Zero<T>, MinusOne<T>) { return One<T>(); }
+ template<class T>
+ struct UnaryReturn< One<T> , OpUnaryMinus >
+ {
+ typedef MinusOne<T> Type_t;
+ };
+ template<class T>
+ struct UnaryReturn< MinusOne<T> , OpUnaryMinus >
+ {
+ typedef One<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< One<T> , T , OpMultiply >
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< T, One<T> , OpMultiply >
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< One<T>, One<T> , OpMultiply >
+ {
+ typedef One<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< MinusOne<T> , T , OpMultiply >
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< T, MinusOne<T> , OpMultiply >
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< MinusOne<T>, MinusOne<T> , OpMultiply >
+ {
+ typedef One<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< MinusOne<T>, One<T> , OpMultiply >
+ {
+ typedef MinusOne<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< One<T>, MinusOne<T> , OpMultiply >
+ {
+ typedef MinusOne<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< T, One<T> , OpDivide >
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< T, MinusOne<T> , OpDivide >
+ {
+ typedef T Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< MinusOne<T>, One<T> , OpDivide >
+ {
+ typedef MinusOne<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< One<T>, MinusOne<T> , OpDivide >
+ {
+ typedef MinusOne<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< One<T>, One<T> , OpSubtract >
+ {
+ typedef Zero<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< MinusOne<T>, MinusOne<T> , OpSubtract >
+ {
+ typedef Zero<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< Zero<T>, One<T>, OpSubtract >
+ {
+ typedef MinusOne<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< Zero<T>, MinusOne<T>, OpSubtract >
+ {
+ typedef One<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< One<T>, MinusOne<T> , OpAdd >
+ {
+ typedef Zero<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< MinusOne<T>, One<T> , OpAdd >
+ {
+ typedef Zero<T> Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< MinusOne<T>, MinusOne<T>, OpEQ>
+ {
+ typedef bool Type_t;
+ };
+ template<class T>
+ struct BinaryReturn< One<T>, One<T>, OpEQ>
+ {
+ typedef bool Type_t;
+ };
+ template<class T1, class T2, class Op>
+ struct BinaryReturn< One<T1> , One<T2>, Op >
+ {
+ typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
+ };
+ template<class T1, class T2, class Op>
+ struct BinaryReturn< MinusOne<T1> , MinusOne<T2>, Op >
+ {
+ typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
+ };
+ template<class T1, class T2, class Op>
+ struct BinaryReturn< One<T1>, Zero<T2>, Op >
+ {
+ typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
+ };
+ template<class T1, class T2, class Op>
+ struct BinaryReturn< Zero<T1>, One<T2>, Op >
+ {
+ typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
+ };
+ template<class T1, class T2, class Op>
+ struct BinaryReturn< MinusOne<T1>, Zero<T2>, Op >
+ {
+ typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
+ };
+ template<class T1, class T2, class Op>
+ struct BinaryReturn< Zero<T1>, MinusOne<T2>, Op >
+ {
+ typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
+ };
+ template<class T1, class T2, class Op>
+ struct BinaryReturn< One<T1>, MinusOne<T2>, Op >
+ {
+ typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
+ };
+ template<class T1, class T2, class Op>
+ struct BinaryReturn< MinusOne<T1>, One<T2>, Op >
+ {
+ typedef typename BinaryReturn<T1,T2,Op>::Type_t Type_t;
+ };
+ template<class A1> struct MultiArg1;
+ template<class A1, class A2> struct MultiArg2;
+ template<class A1, class A2, class A3> struct MultiArg3;
+ template<class A1, class A2, class A3, class A4> struct MultiArg4;
+ template<class A1, class A2, class A3, class A4, class A5> struct MultiArg5;
+ template<class A1, class A2, class A3, class A4, class A5, class A6> struct MultiArg6;
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> struct MultiArg7;
+ template<class A1, class Dom>
+ struct MultiArgView1
+ {
+ typedef typename View1<A1, Dom>::Type_t A1_t;
+ typedef MultiArg1<A1_t> Type_t;
+ };
+ template<class A1, class A2, class Dom>
+ struct MultiArgView2
+ {
+ typedef typename View1<A1, Dom>::Type_t A1_t;
+ typedef typename View1<A2, Dom>::Type_t A2_t;
+ typedef MultiArg2<A1_t, A2_t> Type_t;
+ };
+ template<class A1, class A2, class A3, class Dom>
+ struct MultiArgView3
+ {
+ typedef typename View1<A1, Dom>::Type_t A1_t;
+ typedef typename View1<A2, Dom>::Type_t A2_t;
+ typedef typename View1<A3, Dom>::Type_t A3_t;
+ typedef MultiArg3<A1_t, A2_t, A3_t> Type_t;
+ };
+ template<class A1, class A2, class A3, class A4, class Dom>
+ struct MultiArgView4
+ {
+ typedef typename View1<A1, Dom>::Type_t A1_t;
+ typedef typename View1<A2, Dom>::Type_t A2_t;
+ typedef typename View1<A3, Dom>::Type_t A3_t;
+ typedef typename View1<A4, Dom>::Type_t A4_t;
+ typedef MultiArg4<A1_t, A2_t, A3_t, A4_t> Type_t;
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class Dom>
+ struct MultiArgView5
+ {
+ typedef typename View1<A1, Dom>::Type_t A1_t;
+ typedef typename View1<A2, Dom>::Type_t A2_t;
+ typedef typename View1<A3, Dom>::Type_t A3_t;
+ typedef typename View1<A4, Dom>::Type_t A4_t;
+ typedef typename View1<A5, Dom>::Type_t A5_t;
+ typedef MultiArg5<A1_t, A2_t, A3_t, A4_t, A5_t> Type_t;
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class Dom>
+ struct MultiArgView6
+ {
+ typedef typename View1<A1, Dom>::Type_t A1_t;
+ typedef typename View1<A2, Dom>::Type_t A2_t;
+ typedef typename View1<A3, Dom>::Type_t A3_t;
+ typedef typename View1<A4, Dom>::Type_t A4_t;
+ typedef typename View1<A5, Dom>::Type_t A5_t;
+ typedef typename View1<A6, Dom>::Type_t A6_t;
+ typedef MultiArg6<A1_t, A2_t, A3_t, A4_t, A5_t, A6_t> Type_t;
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class Dom>
+ struct MultiArgView7
+ {
+ typedef typename View1<A1, Dom>::Type_t A1_t;
+ typedef typename View1<A2, Dom>::Type_t A2_t;
+ typedef typename View1<A3, Dom>::Type_t A3_t;
+ typedef typename View1<A4, Dom>::Type_t A4_t;
+ typedef typename View1<A5, Dom>::Type_t A5_t;
+ typedef typename View1<A6, Dom>::Type_t A6_t;
+ typedef typename View1<A7, Dom>::Type_t A7_t;
+ typedef MultiArg7<A1_t, A2_t, A3_t, A4_t, A5_t, A6_t, A7_t> Type_t;
+ };
+ template<class A1, class Dom>
+ struct View1<MultiArg1<A1>, Dom>
+ {
+ typedef typename MultiArgView1<A1, Dom>::Type_t Type_t;
+ };
+ template<class A1, class A2, class Dom>
+ struct View1<MultiArg2<A1, A2>, Dom>
+ {
+ typedef typename MultiArgView2<A1, A2, Dom>::Type_t Type_t;
+ };
+ template<class A1, class A2, class A3, class Dom>
+ struct View1<MultiArg3<A1, A2, A3>, Dom>
+ {
+ typedef typename MultiArgView3<A1, A2, A3, Dom>::Type_t Type_t;
+ };
+ template<class A1, class A2, class A3, class A4, class Dom>
+ struct View1<MultiArg4<A1, A2, A3, A4>, Dom>
+ {
+ typedef typename MultiArgView4<A1, A2, A3, A4, Dom>::Type_t Type_t;
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class Dom>
+ struct View1<MultiArg5<A1, A2, A3, A4, A5>, Dom>
+ {
+ typedef typename MultiArgView5<A1, A2, A3, A4, A5, Dom>::Type_t Type_t;
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class Dom>
+ struct View1<MultiArg6<A1, A2, A3, A4, A5, A6>, Dom>
+ {
+ typedef typename MultiArgView6<A1, A2, A3, A4, A5, A6, Dom>::Type_t Type_t;
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class Dom>
+ struct View1<MultiArg7<A1, A2, A3, A4, A5, A6, A7>, Dom>
+ {
+ typedef typename MultiArgView7<A1, A2, A3, A4, A5, A6, A7, Dom>::Type_t Type_t;
+ };
+ template<class A1>
+ struct MultiArg1
+ {
+ enum { size = 1 };
+ MultiArg1(const A1 &a1)
+ : a1_m(a1)
+ {
+ }
+ template<class Dom>
+ typename View1<MultiArg1<A1>, Dom>::Type_t
+ operator()(const Dom &dom) const
+ {
+ typedef typename View1<MultiArg1<A1>, Dom>::Type_t Ret_t;
+ return Ret_t(a1_m(dom));
+ }
+ A1 a1_m;
+ };
+ template<class A1, class A2>
+ struct MultiArg2
+ {
+ enum { size = 2 };
+ MultiArg2(const A1 &a1, const A2 &a2)
+ : a1_m(a1), a2_m(a2)
+ {
+ }
+ template<class Dom>
+ typename View1<MultiArg2<A1, A2>, Dom>::Type_t
+ operator()(const Dom &dom) const
+ {
+ typedef typename View1<MultiArg2<A1, A2>, Dom>::Type_t Ret_t;
+ return Ret_t(a1_m(dom), a2_m(dom));
+ }
+ A1 a1_m;
+ A2 a2_m;
+ };
+ template<class A1, class A2, class A3>
+ struct MultiArg3
+ {
+ enum { size = 3 };
+ MultiArg3(const A1 &a1, const A2 &a2, const A3 &a3)
+ : a1_m(a1), a2_m(a2), a3_m(a3)
+ {
+ }
+ template<class Dom>
+ typename View1<MultiArg3<A1, A2, A3>, Dom>::Type_t
+ operator()(const Dom &dom) const
+ {
+ typedef typename View1<MultiArg3<A1, A2, A3>, Dom>::Type_t Ret_t;
+ return Ret_t(a1_m(dom), a2_m(dom), a3_m(dom));
+ }
+ A1 a1_m;
+ A2 a2_m;
+ A3 a3_m;
+ };
+ template<class A1, class A2, class A3, class A4>
+ struct MultiArg4
+ {
+ enum { size = 4 };
+ MultiArg4(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4)
+ : a1_m(a1), a2_m(a2), a3_m(a3), a4_m(a4)
+ {
+ }
+ template<class Dom>
+ typename View1<MultiArg4<A1, A2, A3, A4>, Dom>::Type_t
+ operator()(const Dom &dom) const
+ {
+ typedef typename View1<MultiArg4<A1, A2, A3, A4>, Dom>::Type_t Ret_t;
+ return Ret_t(a1_m(dom), a2_m(dom), a3_m(dom), a4_m(dom));
+ }
+ A1 a1_m;
+ A2 a2_m;
+ A3 a3_m;
+ A4 a4_m;
+ };
+ template<class A1, class A2, class A3, class A4, class A5>
+ struct MultiArg5
+ {
+ enum { size = 5 };
+ MultiArg5(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5)
+ : a1_m(a1), a2_m(a2), a3_m(a3), a4_m(a4), a5_m(a5)
+ {
+ }
+ template<class Dom>
+ typename View1<MultiArg5<A1, A2, A3, A4, A5>, Dom>::Type_t
+ operator()(const Dom &dom) const
+ {
+ typedef typename View1<MultiArg5<A1, A2, A3, A4, A5>, Dom>::Type_t Ret_t;
+ return Ret_t(a1_m(dom), a2_m(dom), a3_m(dom), a4_m(dom), a5_m(dom));
+ }
+ A1 a1_m;
+ A2 a2_m;
+ A3 a3_m;
+ A4 a4_m;
+ A5 a5_m;
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class A6>
+ struct MultiArg6
+ {
+ enum { size = 6 };
+ MultiArg6(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6)
+ : a1_m(a1), a2_m(a2), a3_m(a3), a4_m(a4), a5_m(a5), a6_m(a6)
+ {
+ }
+ template<class Dom>
+ typename View1<MultiArg6<A1, A2, A3, A4, A5, A6>, Dom>::Type_t
+ operator()(const Dom &dom) const
+ {
+ typedef typename View1<MultiArg6<A1, A2, A3, A4, A5, A6>, Dom>::Type_t Ret_t;
+ return Ret_t(a1_m(dom), a2_m(dom), a3_m(dom), a4_m(dom), a5_m(dom), a6_m(dom));
+ }
+ A1 a1_m;
+ A2 a2_m;
+ A3 a3_m;
+ A4 a4_m;
+ A5 a5_m;
+ A6 a6_m;
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+ struct MultiArg7
+ {
+ enum { size = 7 };
+ MultiArg7(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7)
+ : a1_m(a1), a2_m(a2), a3_m(a3), a4_m(a4), a5_m(a5), a6_m(a6), a7_m(a7)
+ {
+ }
+ template<class Dom>
+ typename View1<MultiArg7<A1, A2, A3, A4, A5, A6, A7>, Dom>::Type_t
+ operator()(const Dom &dom) const
+ {
+ typedef typename View1<MultiArg7<A1, A2, A3, A4, A5, A6, A7>, Dom>::Type_t Ret_t;
+ return Ret_t(a1_m(dom), a2_m(dom), a3_m(dom), a4_m(dom), a5_m(dom), a6_m(dom), a7_m(dom));
+ }
+ A1 a1_m;
+ A2 a2_m;
+ A3 a3_m;
+ A4 a4_m;
+ A5 a5_m;
+ A6 a6_m;
+ A7 a7_m;
+ };
+ template<class A1, class Function>
+ void applyMultiArg(const MultiArg1<A1> &node,
+ const Function &f,
+ const std::vector<bool> &condition)
+ {
+ f(node.a1_m, condition[0]);
+ }
+ template<class A1, class A2, class Function>
+ void applyMultiArg(const MultiArg2<A1, A2> &node,
+ const Function &f,
+ const std::vector<bool> &condition)
+ {
+ f(node.a1_m, condition[0]);
+ f(node.a2_m, condition[1]);
+ }
+ template<class A1, class A2, class A3, class Function>
+ void applyMultiArg(const MultiArg3<A1, A2, A3> &node,
+ const Function &f,
+ const std::vector<bool> &condition)
+ {
+ f(node.a1_m, condition[0]);
+ f(node.a2_m, condition[1]);
+ f(node.a3_m, condition[2]);
+ }
+ template<class A1, class A2, class A3, class A4, class Function>
+ void applyMultiArg(const MultiArg4<A1, A2, A3, A4> &node,
+ const Function &f,
+ const std::vector<bool> &condition)
+ {
+ f(node.a1_m, condition[0]);
+ f(node.a2_m, condition[1]);
+ f(node.a3_m, condition[2]);
+ f(node.a4_m, condition[3]);
+ }
+ template<class A1, class A2, class A3, class A4, class A5, class Function>
+ void applyMultiArg(const MultiArg5<A1, A2, A3, A4, A5> &node,
+ const Function &f,
+ const std::vector<bool> &condition)
+ {
+ f(node.a1_m, condition[0]);
+ f(node.a2_m, condition[1]);
+ f(node.a3_m, condition[2]);
+ f(node.a4_m, condition[3]);
+ f(node.a5_m, condition[4]);
+ }
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class Function>
+ void applyMultiArg(const MultiArg6<A1, A2, A3, A4, A5, A6> &node,
+ const Function &f,
+ const std::vector<bool> &condition)
+ {
+ f(node.a1_m, condition[0]);
+ f(node.a2_m, condition[1]);
+ f(node.a3_m, condition[2]);
+ f(node.a4_m, condition[3]);
+ f(node.a5_m, condition[4]);
+ f(node.a6_m, condition[5]);
+ }
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class Function>
+ void applyMultiArg(const MultiArg7<A1, A2, A3, A4, A5, A6, A7> &node,
+ const Function &f,
+ const std::vector<bool> &condition)
+ {
+ f(node.a1_m, condition[0]);
+ f(node.a2_m, condition[1]);
+ f(node.a3_m, condition[2]);
+ f(node.a4_m, condition[3]);
+ f(node.a5_m, condition[4]);
+ f(node.a6_m, condition[5]);
+ f(node.a7_m, condition[6]);
+ }
+ template<class A1, class Function>
+ void applyMultiArg(const MultiArg1<A1> &node,
+ const Function &f)
+ {
+ f(node.a1_m);
+ }
+ template<class A1, class A2, class Function>
+ void applyMultiArg(const MultiArg2<A1, A2> &node,
+ const Function &f)
+ {
+ f(node.a1_m);
+ f(node.a2_m);
+ }
+ template<class A1, class A2, class A3, class Function>
+ void applyMultiArg(const MultiArg3<A1, A2, A3> &node,
+ const Function &f)
+ {
+ f(node.a1_m);
+ f(node.a2_m);
+ f(node.a3_m);
+ }
+ template<class A1, class A2, class A3, class A4, class Function>
+ void applyMultiArg(const MultiArg4<A1, A2, A3, A4> &node,
+ const Function &f)
+ {
+ f(node.a1_m);
+ f(node.a2_m);
+ f(node.a3_m);
+ f(node.a4_m);
+ }
+ template<class A1, class A2, class A3, class A4, class A5, class Function>
+ void applyMultiArg(const MultiArg5<A1, A2, A3, A4, A5> &node,
+ const Function &f)
+ {
+ f(node.a1_m);
+ f(node.a2_m);
+ f(node.a3_m);
+ f(node.a4_m);
+ f(node.a5_m);
+ }
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class Function>
+ void applyMultiArg(const MultiArg6<A1, A2, A3, A4, A5, A6> &node,
+ const Function &f)
+ {
+ f(node.a1_m);
+ f(node.a2_m);
+ f(node.a3_m);
+ f(node.a4_m);
+ f(node.a5_m);
+ f(node.a6_m);
+ }
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class Function>
+ void applyMultiArg(const MultiArg7<A1, A2, A3, A4, A5, A6, A7> &node,
+ const Function &f)
+ {
+ f(node.a1_m);
+ f(node.a2_m);
+ f(node.a3_m);
+ f(node.a4_m);
+ f(node.a5_m);
+ f(node.a6_m);
+ f(node.a7_m);
+ }
+ template<class A1, class Function>
+ void applyMultiArgIf(const MultiArg1<A1> &node,
+ const Function &f,
+ const std::vector<bool> &condition)
+ {
+ if (condition[0])
+ f(node.a1_m);
+ }
+ template<class A1, class A2, class Function>
+ void applyMultiArgIf(const MultiArg2<A1, A2> &node,
+ const Function &f,
+ const std::vector<bool> &condition)
+ {
+ if (condition[0])
+ f(node.a1_m);
+ if (condition[1])
+ f(node.a2_m);
+ }
+ template<class A1, class A2, class A3, class Function>
+ void applyMultiArgIf(const MultiArg3<A1, A2, A3> &node,
+ const Function &f,
+ const std::vector<bool> &condition)
+ {
+ if (condition[0])
+ f(node.a1_m);
+ if (condition[1])
+ f(node.a2_m);
+ if (condition[2])
+ f(node.a3_m);
+ }
+ template<class A1, class A2, class A3, class A4, class Function>
+ void applyMultiArgIf(const MultiArg4<A1, A2, A3, A4> &node,
+ const Function &f,
+ const std::vector<bool> &condition)
+ {
+ if (condition[0])
+ f(node.a1_m);
+ if (condition[1])
+ f(node.a2_m);
+ if (condition[2])
+ f(node.a3_m);
+ if (condition[3])
+ f(node.a4_m);
+ }
+ template<class A1, class A2, class A3, class A4, class A5, class Function>
+ void applyMultiArgIf(const MultiArg5<A1, A2, A3, A4, A5> &node,
+ const Function &f,
+ const std::vector<bool> &condition)
+ {
+ if (condition[0])
+ f(node.a1_m);
+ if (condition[1])
+ f(node.a2_m);
+ if (condition[2])
+ f(node.a3_m);
+ if (condition[3])
+ f(node.a4_m);
+ if (condition[4])
+ f(node.a5_m);
+ }
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class Function>
+ void applyMultiArgIf(const MultiArg6<A1, A2, A3, A4, A5, A6> &node,
+ const Function &f,
+ const std::vector<bool> &condition)
+ {
+ if (condition[0])
+ f(node.a1_m);
+ if (condition[1])
+ f(node.a2_m);
+ if (condition[2])
+ f(node.a3_m);
+ if (condition[3])
+ f(node.a4_m);
+ if (condition[4])
+ f(node.a5_m);
+ if (condition[5])
+ f(node.a6_m);
+ }
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class Function>
+ void applyMultiArgIf(const MultiArg7<A1, A2, A3, A4, A5, A6, A7> &node,
+ const Function &f,
+ const std::vector<bool> &condition)
+ {
+ if (condition[0])
+ f(node.a1_m);
+ if (condition[1])
+ f(node.a2_m);
+ if (condition[2])
+ f(node.a3_m);
+ if (condition[3])
+ f(node.a4_m);
+ if (condition[4])
+ f(node.a5_m);
+ if (condition[5])
+ f(node.a6_m);
+ if (condition[6])
+ f(node.a7_m);
+ }
+ struct LoopApplyEvaluator
+ {
+ template<class Op, class Dom>
+ static /*__attribute__((leafify))*/
+ void evaluate(const Op &op, const Dom &domain)
+ {
+ PoomaCTAssert<(Dom::unitStride)>::test();
+ evaluate(op, domain, WrappedInt<Dom::dimensions>());
+ }
+ template<class Op, class Domain>
+ inline static void evaluate(const Op &op, const Domain &domain, WrappedInt<1>)
+ {
+ Op localOp(op);
+ int f0 = domain[0].first();
+ int e0 = domain[0].last();
+ ;
+ #pragma omp parallel for if (e0-f0 > 512)
+ for (int i0 = f0; i0 <= e0; ++i0)
+ localOp(i0);
+ }
+ template<class Op, class Domain>
+ inline static void evaluate(const Op &op, const Domain &domain, WrappedInt<2>)
+ {
+ Op localOp(op);
+ int f0 = domain[0].first();
+ int f1 = domain[1].first();
+ int e0 = domain[0].last();
+ int e1 = domain[1].last();
+ #pragma omp parallel for
+ for (int i1 = f1; i1 <= e1; ++i1) {
+ ;
+ for (int i0 = f0; i0 <= e0; ++i0)
+ localOp(i0, i1);
+ }
+ }
+ template<class Op, class Domain>
+ inline static void evaluate(const Op &op, const Domain &domain, WrappedInt<3>)
+ {
+ Op localOp(op);
+ int f0 = domain[0].first();
+ int f1 = domain[1].first();
+ int f2 = domain[2].first();
+ int e0 = domain[0].last();
+ int e1 = domain[1].last();
+ int e2 = domain[2].last();
+ #pragma omp parallel for
+ for (int i2 = f2; i2 <= e2; ++i2)
+ for (int i1 = f1; i1 <= e1; ++i1) {
+ ;
+ for (int i0 = f0; i0 <= e0; ++i0)
+ localOp(i0,i1,i2);
+ }
+ }
+ template<class Op, class Domain>
+ inline static void evaluate(const Op &op, const Domain &domain, WrappedInt<4>)
+ {
+ Op localOp(op);
+ int f0 = domain[0].first();
+ int f1 = domain[1].first();
+ int f2 = domain[2].first();
+ int f3 = domain[3].first();
+ int e0 = domain[0].last();
+ int e1 = domain[1].last();
+ int e2 = domain[2].last();
+ int e3 = domain[3].last();
+ #pragma omp parallel for
+ for (int i3 = f3; i3 <= e3; ++i3)
+ for (int i2 = f2; i2 <= e2; ++i2)
+ for (int i1 = f1; i1 <= e1; ++i1) {
+ ;
+ for (int i0 = f0; i0 <= e0; ++i0)
+ localOp(i0,i1,i2,i3);
+ }
+ }
+ template<class Op, class Domain>
+ inline static void evaluate(const Op &op, const Domain &domain, WrappedInt<5>)
+ {
+ Op localOp(op);
+ int f0 = domain[0].first();
+ int f1 = domain[1].first();
+ int f2 = domain[2].first();
+ int f3 = domain[3].first();
+ int f4 = domain[4].first();
+ int e0 = domain[0].last();
+ int e1 = domain[1].last();
+ int e2 = domain[2].last();
+ int e3 = domain[3].last();
+ int e4 = domain[4].last();
+ #pragma omp parallel for
+ for (int i4 = f4; i4 <= e4; ++i4)
+ for (int i3 = f3; i3 <= e3; ++i3)
+ for (int i2 = f2; i2 <= e2; ++i2)
+ for (int i1 = f1; i1 <= e1; ++i1) {
+ ;
+ for (int i0 = f0; i0 <= e0; ++i0)
+ localOp(i0,i1,i2,i3,i4);
+ }
+ }
+ template<class Op, class Domain>
+ inline static void evaluate(const Op &op, const Domain &domain, WrappedInt<6>)
+ {
+ Op localOp(op);
+ int f0 = domain[0].first();
+ int f1 = domain[1].first();
+ int f2 = domain[2].first();
+ int f3 = domain[3].first();
+ int f4 = domain[4].first();
+ int f5 = domain[5].first();
+ int e0 = domain[0].last();
+ int e1 = domain[1].last();
+ int e2 = domain[2].last();
+ int e3 = domain[3].last();
+ int e4 = domain[4].last();
+ int e5 = domain[5].last();
+ #pragma omp parallel for
+ for (int i5 = f5; i5 <= e5; ++i5)
+ for (int i4 = f4; i4 <= e4; ++i4)
+ for (int i3 = f3; i3 <= e3; ++i3)
+ for (int i2 = f2; i2 <= e2; ++i2)
+ for (int i1 = f1; i1 <= e1; ++i1) {
+ ;
+ for (int i0 = f0; i0 <= e0; ++i0)
+ localOp(i0,i1,i2,i3,i4,i5);
+ }
+ }
+ template<class Op, class Domain>
+ inline static void evaluate(const Op &op, const Domain &domain, WrappedInt<7>)
+ {
+ Op localOp(op);
+ int f0 = domain[0].first();
+ int f1 = domain[1].first();
+ int f2 = domain[2].first();
+ int f3 = domain[3].first();
+ int f4 = domain[4].first();
+ int f5 = domain[5].first();
+ int f6 = domain[6].first();
+ int e0 = domain[0].last();
+ int e1 = domain[1].last();
+ int e2 = domain[2].last();
+ int e3 = domain[3].last();
+ int e4 = domain[4].last();
+ int e5 = domain[5].last();
+ int e6 = domain[6].last();
+ #pragma omp parallel for
+ for (int i6 = f6; i6 <= e6; ++i6)
+ for (int i5 = f5; i5 <= e5; ++i5)
+ for (int i4 = f4; i4 <= e4; ++i4)
+ for (int i3 = f3; i3 <= e3; ++i3)
+ for (int i2 = f2; i2 <= e2; ++i2)
+ for (int i1 = f1; i1 <= e1; ++i1) {
+ ;
+ for (int i0 = f0; i0 <= e0; ++i0)
+ localOp(i0,i1,i2,i3,i4,i5,i6);
+ }
+ }
+ };
+ template<class MultiArg, class Function>
+ class MultiArgKernel
+ : public Pooma::Iterate_t
+ {
+ public:
+ MultiArgKernel(const MultiArg &multiArg,
+ const Function &function,
+ std::vector<bool> &write,
+ std::vector<bool> &read)
+ : Pooma::Iterate_t(Pooma::scheduler()),
+ multiArg_m(multiArg), function_m(function),
+ write_m(write), read_m(read)
+ {
+ DataObjectRequest<BlockAffinity> getAffinity;
+ hintAffinity(engineFunctor(multiArg.a1_m.engine(), getAffinity));
+ typedef DataObjectRequest<WriteRequest> WriteRequest_t;
+ typedef DataObjectRequest<ReadRequest> ReadRequest_t;
+ WriteRequest_t writeReq(*this);
+ applyMultiArgIf(multiArg, ExpressionApply<WriteRequest_t>(writeReq),
+ write_m);
+ ReadRequest_t readReq(writeReq);
+ applyMultiArgIf(multiArg, ExpressionApply<ReadRequest_t>(readReq),
+ read_m);
+ }
+ virtual ~MultiArgKernel()
+ {
+ typedef DataObjectRequest<WriteRelease> WriteRequest_t;
+ typedef DataObjectRequest<ReadRelease> ReadRequest_t;
+ WriteRequest_t writeReq;
+ applyMultiArgIf(multiArg_m, ExpressionApply<WriteRequest_t>(writeReq),
+ write_m);
+ ReadRequest_t readReq(writeReq);
+ applyMultiArgIf(multiArg_m, ExpressionApply<ReadRequest_t>(readReq),
+ read_m);
+ }
+ virtual void /*__attribute__((leafify))*/ run()
+ {
+ function_m(multiArg_m);
+ }
+ private:
+ MultiArg multiArg_m;
+ Function function_m;
+ std::vector<bool> write_m;
+ std::vector<bool> read_m;
+ };
+ template<int Dim>
+ class SimpleIntersectorData
+ : public RefCounted
+ {
+ public:
+ typedef SimpleIntersectorData<Dim> This_t;
+ typedef INode<Dim> INode_t;
+ typedef std::vector<INode_t> INodeContainer_t;
+ typedef typename INodeContainer_t::const_iterator const_iterator;
+ typedef Unique::Value_t LayoutID_t;
+ enum { dimensions = Dim };
+ inline SimpleIntersectorData(const Interval<Dim> &domain, const GuardLayers<Dim> &extent)
+ : seenFirst_m(false), domain_m(domain), extent_m(extent)
+ {
+ }
+ inline ~SimpleIntersectorData() { }
+ template<class Engine>
+ void intersect(const Engine &engine, bool useGuards)
+ {
+ typedef typename Engine::Layout_t Layout_t;
+ typedef typename NewEngine<Engine, Interval<Dim> >::Type_t NewEngine_t;
+ const Layout_t &layout(engine.layout());
+ if (!seenFirst_m)
+ {
+ firstID_m = layout.ID();
+ seenFirst_m = true;
+ int key = GlobalIDDataBase::nullNodeKey();
+ layout.touches(domain_m, std::back_inserter(inodes_m),
+ TouchesConstructINode<Dim>(firstID_m, key, &gidStore_m));
+ }
+ else
+ {
+ shared(layout.ID(), firstID_m);
+ }
+ if (useGuards) {
+ expressionApply(NewEngine_t(engine, grow(domain_m, extent_m)),
+ IntersectorTag<Intersector<Dim> >(lhsi_m));
+ } else {
+ expressionApply(NewEngine_t(engine, domain_m),
+ IntersectorTag<Intersector<Dim> >(lhsi_m));
+ }
+ }
+ inline
+ void shared(LayoutID_t id1, LayoutID_t id2)
+ {
+ gidStore_m.shared(id1,id2);
+ }
+ SimpleIntersectorData(const This_t &);
+ This_t &operator=(const This_t &);
+ LayoutID_t firstID_m;
+ bool seenFirst_m;
+ INodeContainer_t inodes_m;
+ GlobalIDDataBase gidStore_m;
+ Interval<Dim> domain_m;
+ GuardLayers<Dim> extent_m;
+ Intersector<Dim> lhsi_m;
+ };
+ template<int Dim>
+ class SimpleIntersector
+ {
+ public:
+ typedef SimpleIntersectorData<Dim> SimpleIntersectorData_t;
+ typedef SimpleIntersector<Dim> This_t;
+ typedef typename SimpleIntersectorData_t::INode_t INode_t;
+ typedef typename SimpleIntersectorData_t::INodeContainer_t INodeContainer_t;
+ typedef typename SimpleIntersectorData_t::const_iterator const_iterator;
+ typedef RefCountedPtr<SimpleIntersectorData_t> DataPtr_t;
+ typedef NullCombine Combine_t;
+ enum { dimensions = Dim };
+ SimpleIntersector(const Interval<Dim> &domain, const GuardLayers<Dim> &extent)
+ : pdata_m(new SimpleIntersectorData_t(domain, extent)), useGuards_m(true)
+ { }
+ SimpleIntersector(const This_t &model)
+ : pdata_m(model.pdata_m), useGuards_m(model.useGuards())
+ { }
+ This_t &operator=(const This_t &model)
+ {
+ if (this != &model) {
+ pdata_m = model.pdata_m;
+ useGuards_m = model.useGuards_m;
+ }
+ return *this;
+ }
+ ~SimpleIntersector() { }
+ inline DataPtr_t &data() { return pdata_m; }
+ inline const DataPtr_t &data() const { return pdata_m; }
+ inline const_iterator begin() const { return data()->inodes_m.begin(); }
+ inline const_iterator end() const { return data()->inodes_m.end(); }
+ inline int size() const { return data()->inodes_m.size(); }
+ template<class Engine>
+ inline
+ void intersect(const Engine &l) const
+ {
+ data()->intersect(l, useGuards());
+ }
+ inline
+ bool useGuards() const
+ {
+ return useGuards_m;
+ }
+ inline
+ void useGuards(bool f) const
+ {
+ useGuards_m = f;
+ }
+ template<class A>
+ void operator()(const A &a, bool f) const
+ {
+ useGuards(f);
+ expressionApply(a, *this);
+ }
+ private:
+ DataPtr_t pdata_m;
+ mutable bool useGuards_m;
+ };
+ template<class Eng, int Dim>
+ struct DefaultExpressionApply<Eng, SimpleIntersector<Dim> >
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const Eng &,
+ const ExpressionApply<SimpleIntersector<Dim> > &)
+ {
+ PoomaCTAssert<(!(Eng::multiPatch))>::test();
+ return true;
+ }
+ };
+ template<class LT, class PT>
+ struct MultiPatch;
+ template <int Dim, class T, class LayoutTag, class PatchTag>
+ struct LeafFunctor<Engine<Dim, T, MultiPatch<LayoutTag,PatchTag> >,
+ ExpressionApply<SimpleIntersector<Dim> > >
+ {
+ typedef int Type_t;
+ static Type_t
+ apply(const Engine<Dim,T,MultiPatch<LayoutTag,PatchTag> > &engine,
+ const ExpressionApply<SimpleIntersector<Dim> > &apply)
+ {
+ apply.tag().intersect(engine);
+ if (apply.tag().useGuards())
+ engine.fillGuards(apply.tag().data()->extent_m);
+ return 0;
+ }
+ };
+ template <int Dim, class T, class LT, class PatchTag, int BD>
+ struct LeafFunctor<Engine<Dim, T, MultiPatchView<LT,PatchTag,BD> >,
+ ExpressionApply<SimpleIntersector<Dim> > >
+ {
+ typedef int Type_t;
+ static Type_t
+ apply(const Engine<Dim,T,MultiPatchView<LT,PatchTag,BD> > &engine,
+ const ExpressionApply<SimpleIntersector<Dim> > &apply)
+ {
+ apply.tag().intersect(engine);
+ if (apply.tag().useGuards())
+ engine.fillGuards(apply.tag().data()->extent_m);
+ return 0;
+ }
+ };
+ template <int Dim, int size>
+ class ScalarCodeInfo
+ {
+ public:
+ enum { dimensions = Dim };
+ enum { arguments = size };
+ typedef std::vector<bool> BoolVector_t;
+ ScalarCodeInfo()
+ : extent_m(GuardLayers<Dim>(0)),
+ useGuards_m(arguments, true),
+ writers_m(arguments, false),
+ readers_m(arguments, true)
+ {
+ useGuards_m[0] = false;
+ writers_m[0] = true;
+ readers_m[0] = true;
+ }
+ void extent(const GuardLayers<Dim> &g)
+ {
+ extent_m = g;
+ }
+ GuardLayers<Dim>& extent()
+ {
+ return extent_m;
+ }
+ const GuardLayers<Dim>& extent() const
+ {
+ return extent_m;
+ }
+ void write(int i, bool f, bool r = true)
+ {
+ writers_m[i] = f;
+ readers_m[i] = r;
+ }
+ BoolVector_t &writers()
+ {
+ return writers_m;
+ }
+ BoolVector_t &readers()
+ {
+ return readers_m;
+ }
+ void useGuards(int i, bool f)
+ {
+ useGuards_m[i] = f;
+ }
+ BoolVector_t &useGuards()
+ {
+ return useGuards_m;
+ }
+ inline Interval<Dim> extendDomain(const Interval<Dim> &domain) const
+ {
+ return grow(domain, extent_m);
+ }
+ inline Interval<Dim> evaluationDomain(const Interval<Dim> &domain) const
+ {
+ Interval<Dim> ret;
+ for (int d = 0; d < Dim; ++d)
+ {
+ ret[d] = Interval<1>(extent_m.lower(d),
+ domain[d].last() - domain[d].first()
+ + extent_m.lower(d));
+ }
+ return ret;
+ }
+ inline INode<Dim> extendDomain(const INode<Dim> &inode) const
+ {
+ return INode<Dim>(inode, extendDomain(inode.domain()));
+ }
+ private:
+ GuardLayers<Dim> extent_m;
+ BoolVector_t useGuards_m;
+ BoolVector_t writers_m;
+ BoolVector_t readers_m;
+ };
+ template<class MultiArg> struct MultiArgEvaluatorTag;
+ template<class MeshTag, class T, class EngineTag> class Field;
+ template<int Dim, class T, class EngineTag> class Array;
+ template<class EvalTag>
+ struct MultiArgEvaluator
+ {
+ };
+ struct EngineWriteNotifier
+ {
+ EngineWriteNotifier()
+ {
+ }
+ template<class A>
+ inline void dirtyRelations(const A &a, const WrappedInt<true>&) const
+ {
+ a.notifyPostWrite();
+ }
+ template<class A>
+ inline void dirtyRelations(const A &, const WrappedInt<false>&) const
+ {
+ }
+ template<class A>
+ void operator()(const A &a) const
+ {
+ notifyEngineWrite(a.engine());
+ dirtyRelations(a, WrappedInt<A::hasRelations>());
+ }
+ template<class MeshTag, class T, class Expr>
+ void operator()(const Field<MeshTag, T, ExpressionTag<Expr> >&) const
+ {
+ if (__builtin_expect(!!(false), true)) {} else Pooma::toss_cookies("writing to expression engine?", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Evaluator/MultiArgEvaluator.h", 124);
+ }
+ template<int Dim, class T, class Expr>
+ void operator()(const Array<Dim, T, ExpressionTag<Expr> >&) const
+ {
+ if (__builtin_expect(!!(false), true)) {} else Pooma::toss_cookies("writing to expression engine?", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Evaluator/MultiArgEvaluator.h", 130);
+ }
+ };
+ struct UpdateNotifier
+ {
+ UpdateNotifier()
+ {
+ }
+ template<class A>
+ void operator()(const A &a) const
+ {
+ forEach(a, PerformUpdateTag(), NullCombine());
+ }
+ };
+ template <int Dim>
+ struct CheckDomain
+ {
+ CheckDomain(const Interval<Dim>&d) : d_m(d) {}
+ template <class A>
+ void operator()(const A &a) const
+ {
+ a(d_m);
+ }
+ Interval<Dim> d_m;
+ };
+ template<>
+ struct MultiArgEvaluator<MainEvaluatorTag>
+ {
+ public:
+ MultiArgEvaluator() {}
+ ~MultiArgEvaluator() {}
+ template<class MultiArg, class Function, int Dim, class Kernel>
+ static void
+ evaluate(const MultiArg &multiArg,
+ const Function &function,
+ const Interval<Dim> &domain,
+ const Kernel &kernel)
+ {
+ typedef typename MultiArgEvaluatorTag<MultiArg>::Evaluator_t Evaluator_t;
+ ScalarCodeInfo<Dim, MultiArg::size> info;
+ function.scalarCodeInfo(info);
+ Pooma::beginExpression();
+ applyMultiArgIf(multiArg, UpdateNotifier(), info.readers());
+ MultiArgEvaluator<Evaluator_t>::evaluate(multiArg, function,
+ domain, info, kernel);
+ applyMultiArgIf(multiArg, EngineWriteNotifier(), info.writers());
+ Pooma::endExpression();
+ }
+ template<class A1, class Function, int Dim, class Kernel>
+ static void
+ createIterate(const A1& a1,
+ const Function& function,
+ const Interval<Dim> &domain,
+ ScalarCodeInfo<Dim, A1::size> &info,
+ const Kernel &)
+ {
+ Kernel kernelf(function, domain);
+ Pooma::Iterate_t *iterate =
+ new MultiArgKernel<A1, Kernel>(a1, kernelf,
+ info.writers(), info.readers());
+ Pooma::scheduler().handOff(iterate);
+ }
+ };
+ template<>
+ struct MultiArgEvaluator<SinglePatchEvaluatorTag>
+ {
+ public:
+ MultiArgEvaluator() {}
+ ~MultiArgEvaluator() {}
+ template<class MultiArg, class Function, int Dim, class Kernel>
+ static void
+ evaluate(const MultiArg& multiArg,
+ const Function& function,
+ Interval<Dim> domain,
+ ScalarCodeInfo<Dim, MultiArg::size> &info,
+ const Kernel &kernel)
+ {
+ Interval<Dim> newDom = info.extendDomain(domain);
+ Interval<Dim> evalDom = info.evaluationDomain(domain);
+ MultiArgEvaluator<MainEvaluatorTag>::createIterate(multiArg(newDom),
+ function,
+ evalDom, info,
+ kernel);
+ }
+ };
+ template<>
+ struct MultiArgEvaluator<MultiPatchEvaluatorTag>
+ {
+ public:
+ MultiArgEvaluator() {}
+ ~MultiArgEvaluator() {}
+ template<class MultiArg, class Function, int Dim, class Kernel>
+ static void
+ evaluate(const MultiArg &multiArg,
+ const Function &function,
+ const Interval<Dim> &domain,
+ ScalarCodeInfo<Dim, MultiArg::size> &info,
+ const Kernel &kernel)
+ {
+ typedef SimpleIntersector<Dim> Inter_t;
+ Inter_t inter(domain, info.extent());
+ applyMultiArg(multiArg, inter, info.useGuards());
+ typename Inter_t::const_iterator i = inter.begin();
+ while (i != inter.end())
+ {
+ INode<Dim> inode = info.extendDomain(*i);
+ Interval<Dim> evalDom = info.evaluationDomain((*i).domain());
+ MultiArgEvaluator<MainEvaluatorTag>::createIterate(multiArg(inode),
+ function,
+ evalDom, info,
+ kernel);
+ ++i;
+ }
+ }
+ };
+ template <>
+ struct MultiArgEvaluator<RemoteSinglePatchEvaluatorTag>
+ {
+ MultiArgEvaluator() { }
+ ~MultiArgEvaluator() { }
+ template<class MultiArg, class Function, int Dim, class Kernel>
+ static void
+ evaluate(const MultiArg &multiArg,
+ const Function &function,
+ const Interval<Dim> &domain,
+ ScalarCodeInfo<Dim, MultiArg::size> &info,
+ const Kernel &kernel)
+ {
+ GatherContexts gtag;
+ engineFunctor(multiArg.a1_m.engine(), gtag);
+ int lhsContext = gtag.mostCommonContext();
+ expressionApply(multiArg, RemoteSend(lhsContext));
+ EngineView<RemoteView> view;
+ if (lhsContext == -1 || Pooma::context() == lhsContext)
+ {
+ MultiArgEvaluator<SinglePatchEvaluatorTag> speval;
+ speval.evaluate(
+ forEach(multiArg, view, TreeCombine()),
+ function, domain, info, kernel
+ );
+ }
+ }
+ };
+ template <>
+ struct MultiArgEvaluator<RemoteMultiPatchEvaluatorTag>
+ {
+ MultiArgEvaluator() { }
+ ~MultiArgEvaluator() { }
+ template<class MultiArg, class Function, int Dim, class Kernel>
+ static void
+ evaluate(const MultiArg &multiArg,
+ const Function &function,
+ const Interval<Dim> &domain,
+ ScalarCodeInfo<Dim, MultiArg::size> &info,
+ const Kernel &kernel)
+ {
+ typedef SimpleIntersector<Dim> Inter_t;
+ Inter_t inter(domain, info.extent());
+ applyMultiArg(multiArg, inter, info.useGuards());
+ typename Inter_t::const_iterator i = inter.begin();
+ while (i != inter.end())
+ {
+ INode<Dim> inode = info.extendDomain(*i);
+ Interval<Dim> evalDom = info.evaluationDomain((*i).domain());
+ MultiArgEvaluator<RemoteSinglePatchEvaluatorTag>().
+ evaluate(multiArg(inode),
+ function, evalDom, info, kernel);
+ ++i;
+ }
+ }
+ };
+ template<class A1>
+ struct MultiArgEvaluatorTag<MultiArg1<A1> >
+ {
+ typedef typename EvaluatorTag1<A1>::Evaluator_t Evaluator_t;
+ };
+ template<class A1, class A2>
+ struct MultiArgEvaluatorTag<MultiArg2<A1, A2> >
+ {
+ typedef typename EvaluatorTag1<A1>::Evaluator_t Eval1_t;
+ typedef typename EvaluatorTag1<A2>::Evaluator_t Eval2_t;
+ typedef typename EvaluatorCombine<Eval1_t, Eval2_t>::Evaluator_t Evaluator_t;
+ };
+ template<class A1, class A2, class A3>
+ struct MultiArgEvaluatorTag<MultiArg3<A1, A2, A3> >
+ {
+ typedef typename EvaluatorTag1<A1>::Evaluator_t Eval1_t;
+ typedef typename EvaluatorTag1<A2>::Evaluator_t Eval2_t;
+ typedef typename EvaluatorTag1<A3>::Evaluator_t Eval3_t;
+ typedef typename EvaluatorCombine<Eval1_t, Eval2_t>::Evaluator_t Eval12_t;
+ typedef typename EvaluatorCombine<Eval3_t, Eval12_t>::Evaluator_t
+ Evaluator_t;
+ };
+ template<class A1, class A2, class A3, class A4>
+ struct MultiArgEvaluatorTag<MultiArg4<A1, A2, A3, A4> >
+ {
+ typedef typename EvaluatorTag1<A1>::Evaluator_t Eval1_t;
+ typedef typename EvaluatorTag1<A2>::Evaluator_t Eval2_t;
+ typedef typename EvaluatorTag1<A3>::Evaluator_t Eval3_t;
+ typedef typename EvaluatorTag1<A4>::Evaluator_t Eval4_t;
+ typedef typename EvaluatorCombine<Eval1_t, Eval2_t>::Evaluator_t Eval12_t;
+ typedef typename EvaluatorCombine<Eval3_t, Eval4_t>::Evaluator_t Eval34_t;
+ typedef typename EvaluatorCombine<Eval12_t, Eval34_t>::Evaluator_t Evaluator_t;
+ };
+ template<class A1, class A2, class A3, class A4, class A5>
+ struct MultiArgEvaluatorTag<MultiArg5<A1, A2, A3, A4, A5> >
+ {
+ typedef typename EvaluatorTag1<A1>::Evaluator_t Eval1_t;
+ typedef typename EvaluatorTag1<A2>::Evaluator_t Eval2_t;
+ typedef typename EvaluatorTag1<A3>::Evaluator_t Eval3_t;
+ typedef typename EvaluatorTag1<A4>::Evaluator_t Eval4_t;
+ typedef typename EvaluatorTag1<A5>::Evaluator_t Eval5_t;
+ typedef typename EvaluatorCombine<Eval1_t, Eval2_t>::Evaluator_t Eval12_t;
+ typedef typename EvaluatorCombine<Eval3_t, Eval4_t>::Evaluator_t Eval34_t;
+ typedef typename EvaluatorCombine<Eval12_t, Eval34_t>::Evaluator_t Eval1234_t;
+ typedef typename EvaluatorCombine<Eval1234_t, Eval5_t>::Evaluator_t Evaluator_t;
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class A6>
+ struct MultiArgEvaluatorTag<MultiArg6<A1, A2, A3, A4, A5, A6> >
+ {
+ typedef typename EvaluatorTag1<A1>::Evaluator_t Eval1_t;
+ typedef typename EvaluatorTag1<A2>::Evaluator_t Eval2_t;
+ typedef typename EvaluatorTag1<A3>::Evaluator_t Eval3_t;
+ typedef typename EvaluatorTag1<A4>::Evaluator_t Eval4_t;
+ typedef typename EvaluatorTag1<A5>::Evaluator_t Eval5_t;
+ typedef typename EvaluatorTag1<A6>::Evaluator_t Eval6_t;
+ typedef typename EvaluatorCombine<Eval1_t, Eval2_t>::Evaluator_t Eval12_t;
+ typedef typename EvaluatorCombine<Eval3_t, Eval4_t>::Evaluator_t Eval34_t;
+ typedef typename EvaluatorCombine<Eval5_t, Eval6_t>::Evaluator_t Eval56_t;
+ typedef typename EvaluatorCombine<Eval12_t, Eval34_t>::Evaluator_t Eval1234_t;
+ typedef typename EvaluatorCombine<Eval1234_t, Eval56_t>::Evaluator_t Evaluator_t;
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+ struct MultiArgEvaluatorTag<MultiArg7<A1, A2, A3, A4, A5, A6, A7> >
+ {
+ typedef typename EvaluatorTag1<A1>::Evaluator_t Eval1_t;
+ typedef typename EvaluatorTag1<A2>::Evaluator_t Eval2_t;
+ typedef typename EvaluatorTag1<A3>::Evaluator_t Eval3_t;
+ typedef typename EvaluatorTag1<A4>::Evaluator_t Eval4_t;
+ typedef typename EvaluatorTag1<A5>::Evaluator_t Eval5_t;
+ typedef typename EvaluatorTag1<A6>::Evaluator_t Eval6_t;
+ typedef typename EvaluatorTag1<A7>::Evaluator_t Eval7_t;
+ typedef typename EvaluatorCombine<Eval1_t, Eval2_t>::Evaluator_t Eval12_t;
+ typedef typename EvaluatorCombine<Eval3_t, Eval12_t>::Evaluator_t Eval123_t;
+ typedef typename EvaluatorCombine<Eval4_t, Eval123_t>::Evaluator_t Eval1234_t;
+ typedef typename EvaluatorCombine<Eval5_t, Eval1234_t>::Evaluator_t Eval12345_t;
+ typedef typename EvaluatorCombine<Eval6_t, Eval12345_t>::Evaluator_t Eval123456_t;
+ typedef typename EvaluatorCombine<Eval7_t, Eval123456_t>::Evaluator_t
+ Evaluator_t;
+ };
+ template<class A1, class Tag>
+ struct LeafFunctor<MultiArg1<A1>, ExpressionApply<Tag> >
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const MultiArg1<A1> &multiarg,
+ const ExpressionApply<Tag> &tag)
+ {
+ leafFunctor(multiarg.a1_m, tag);
+ return 0;
+ }
+ };
+ template<class A1, class Tag>
+ struct LeafFunctor<MultiArg1<A1>, EngineView<Tag> >
+ {
+ typedef typename LeafFunctor<A1, EngineView<Tag> >::Type_t Type1_t;
+ typedef MultiArg1<Type1_t> Type_t;
+ inline static
+ Type_t apply(const MultiArg1<A1> &multiarg,
+ const EngineView<Tag> &tag)
+ {
+ return Type_t(
+ leafFunctor(multiarg.a1_m, tag)
+ );
+ }
+ };
+ template<class A1, class A2, class Tag>
+ struct LeafFunctor<MultiArg2<A1, A2>, ExpressionApply<Tag> >
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const MultiArg2<A1, A2> &multiarg,
+ const ExpressionApply<Tag> &tag)
+ {
+ leafFunctor(multiarg.a1_m, tag);
+ leafFunctor(multiarg.a2_m, tag);
+ return 0;
+ }
+ };
+ template<class A1, class A2, class Tag>
+ struct LeafFunctor<MultiArg2<A1, A2>, EngineView<Tag> >
+ {
+ typedef typename LeafFunctor<A1, EngineView<Tag> >::Type_t Type1_t;
+ typedef typename LeafFunctor<A2, EngineView<Tag> >::Type_t Type2_t;
+ typedef MultiArg2<Type1_t, Type2_t> Type_t;
+ inline static
+ Type_t apply(const MultiArg2<A1, A2> &multiarg,
+ const EngineView<Tag> &tag)
+ {
+ return Type_t(
+ leafFunctor(multiarg.a1_m, tag),
+ leafFunctor(multiarg.a2_m, tag)
+ );
+ }
+ };
+ template<class A1, class A2, class A3, class Tag>
+ struct LeafFunctor<MultiArg3<A1, A2, A3>,
+ ExpressionApply<Tag> >
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const MultiArg3<A1, A2, A3> &multiarg,
+ const ExpressionApply<Tag> &tag)
+ {
+ leafFunctor(multiarg.a1_m, tag);
+ leafFunctor(multiarg.a2_m, tag);
+ leafFunctor(multiarg.a3_m, tag);
+ return 0;
+ }
+ };
+ template<class A1, class A2, class A3, class Tag>
+ struct LeafFunctor<MultiArg3<A1, A2, A3>, EngineView<Tag> >
+ {
+ typedef typename LeafFunctor<A1, EngineView<Tag> >::Type_t Type1_t;
+ typedef typename LeafFunctor<A2, EngineView<Tag> >::Type_t Type2_t;
+ typedef typename LeafFunctor<A3, EngineView<Tag> >::Type_t Type3_t;
+ typedef MultiArg3<Type1_t, Type2_t, Type3_t> Type_t;
+ inline static
+ Type_t apply(const MultiArg3<A1, A2, A3> &multiarg,
+ const EngineView<Tag> &tag)
+ {
+ return Type_t(
+ leafFunctor(multiarg.a1_m, tag),
+ leafFunctor(multiarg.a2_m, tag),
+ leafFunctor(multiarg.a3_m, tag)
+ );
+ }
+ };
+ template<class A1, class A2, class A3, class A4, class Tag>
+ struct LeafFunctor<MultiArg4<A1, A2, A3, A4>,
+ ExpressionApply<Tag> >
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const MultiArg4<A1, A2, A3, A4> &multiarg,
+ const ExpressionApply<Tag> &tag)
+ {
+ leafFunctor(multiarg.a1_m, tag);
+ leafFunctor(multiarg.a2_m, tag);
+ leafFunctor(multiarg.a3_m, tag);
+ leafFunctor(multiarg.a4_m, tag);
+ return 0;
+ }
+ };
+ template<class A1, class A2, class A3, class A4, class Tag>
+ struct LeafFunctor<MultiArg4<A1, A2, A3, A4>, EngineView<Tag> >
+ {
+ typedef typename LeafFunctor<A1, EngineView<Tag> >::Type_t Type1_t;
+ typedef typename LeafFunctor<A2, EngineView<Tag> >::Type_t Type2_t;
+ typedef typename LeafFunctor<A3, EngineView<Tag> >::Type_t Type3_t;
+ typedef typename LeafFunctor<A4, EngineView<Tag> >::Type_t Type4_t;
+ typedef MultiArg4<Type1_t, Type2_t, Type3_t, Type4_t> Type_t;
+ inline static
+ Type_t apply(const MultiArg4<A1, A2, A3, A4> &multiarg,
+ const EngineView<Tag> &tag)
+ {
+ return Type_t(
+ leafFunctor(multiarg.a1_m, tag),
+ leafFunctor(multiarg.a2_m, tag),
+ leafFunctor(multiarg.a3_m, tag),
+ leafFunctor(multiarg.a4_m, tag)
+ );
+ }
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class Tag>
+ struct LeafFunctor<MultiArg5<A1, A2, A3, A4, A5>,
+ ExpressionApply<Tag> >
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const MultiArg5<A1, A2, A3, A4, A5> &multiarg,
+ const ExpressionApply<Tag> &tag)
+ {
+ leafFunctor(multiarg.a1_m, tag);
+ leafFunctor(multiarg.a2_m, tag);
+ leafFunctor(multiarg.a3_m, tag);
+ leafFunctor(multiarg.a4_m, tag);
+ leafFunctor(multiarg.a5_m, tag);
+ return 0;
+ }
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class Tag>
+ struct LeafFunctor<MultiArg5<A1, A2, A3, A4, A5>, EngineView<Tag> >
+ {
+ typedef typename LeafFunctor<A1, EngineView<Tag> >::Type_t Type1_t;
+ typedef typename LeafFunctor<A2, EngineView<Tag> >::Type_t Type2_t;
+ typedef typename LeafFunctor<A3, EngineView<Tag> >::Type_t Type3_t;
+ typedef typename LeafFunctor<A4, EngineView<Tag> >::Type_t Type4_t;
+ typedef typename LeafFunctor<A5, EngineView<Tag> >::Type_t Type5_t;
+ typedef MultiArg5<Type1_t, Type2_t, Type3_t, Type4_t, Type5_t> Type_t;
+ inline static
+ Type_t apply(const MultiArg5<A1, A2, A3, A4, A5> &multiarg,
+ const EngineView<Tag> &tag)
+ {
+ return Type_t(
+ leafFunctor(multiarg.a1_m, tag),
+ leafFunctor(multiarg.a2_m, tag),
+ leafFunctor(multiarg.a3_m, tag),
+ leafFunctor(multiarg.a4_m, tag),
+ leafFunctor(multiarg.a5_m, tag)
+ );
+ }
+ };
+ template<class A1, class A2, class A3, class A4, class A5,
+ class A6, class Tag>
+ struct LeafFunctor<MultiArg6<A1, A2, A3, A4, A5, A6>,
+ ExpressionApply<Tag> >
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const MultiArg6<A1, A2, A3, A4, A5, A6> &multiarg,
+ const ExpressionApply<Tag> &tag)
+ {
+ leafFunctor(multiarg.a1_m, tag);
+ leafFunctor(multiarg.a2_m, tag);
+ leafFunctor(multiarg.a3_m, tag);
+ leafFunctor(multiarg.a4_m, tag);
+ leafFunctor(multiarg.a5_m, tag);
+ leafFunctor(multiarg.a6_m, tag);
+ return 0;
+ }
+ };
+ template<class A1, class A2, class A3, class A4, class A5,
+ class A6, class Tag>
+ struct LeafFunctor<MultiArg6<A1, A2, A3, A4, A5, A6>, EngineView<Tag> >
+ {
+ typedef typename LeafFunctor<A1, EngineView<Tag> >::Type_t Type1_t;
+ typedef typename LeafFunctor<A2, EngineView<Tag> >::Type_t Type2_t;
+ typedef typename LeafFunctor<A3, EngineView<Tag> >::Type_t Type3_t;
+ typedef typename LeafFunctor<A4, EngineView<Tag> >::Type_t Type4_t;
+ typedef typename LeafFunctor<A5, EngineView<Tag> >::Type_t Type5_t;
+ typedef typename LeafFunctor<A6, EngineView<Tag> >::Type_t Type6_t;
+ typedef MultiArg6<Type1_t, Type2_t, Type3_t, Type4_t, Type5_t,
+ Type6_t> Type_t;
+ inline static
+ Type_t apply(const MultiArg6<A1, A2, A3, A4, A5, A6> &multiarg,
+ const EngineView<Tag> &tag)
+ {
+ return Type_t(
+ leafFunctor(multiarg.a1_m, tag),
+ leafFunctor(multiarg.a2_m, tag),
+ leafFunctor(multiarg.a3_m, tag),
+ leafFunctor(multiarg.a4_m, tag),
+ leafFunctor(multiarg.a5_m, tag),
+ leafFunctor(multiarg.a6_m, tag)
+ );
+ }
+ };
+ template<class A1, class A2, class A3, class A4, class A5,
+ class A6, class A7, class Tag>
+ struct LeafFunctor<MultiArg7<A1, A2, A3, A4, A5, A6, A7>,
+ ExpressionApply<Tag> >
+ {
+ typedef int Type_t;
+ inline static
+ Type_t apply(const MultiArg7<A1, A2, A3, A4, A5, A6, A7> &multiarg,
+ const ExpressionApply<Tag> &tag)
+ {
+ leafFunctor(multiarg.a1_m, tag);
+ leafFunctor(multiarg.a2_m, tag);
+ leafFunctor(multiarg.a3_m, tag);
+ leafFunctor(multiarg.a4_m, tag);
+ leafFunctor(multiarg.a5_m, tag);
+ leafFunctor(multiarg.a6_m, tag);
+ leafFunctor(multiarg.a7_m, tag);
+ return 0;
+ }
+ };
+ template<class A1, class A2, class A3, class A4, class A5,
+ class A6, class A7, class Tag>
+ struct LeafFunctor<MultiArg7<A1, A2, A3, A4, A5, A6, A7>, EngineView<Tag> >
+ {
+ typedef typename LeafFunctor<A1, EngineView<Tag> >::Type_t Type1_t;
+ typedef typename LeafFunctor<A2, EngineView<Tag> >::Type_t Type2_t;
+ typedef typename LeafFunctor<A3, EngineView<Tag> >::Type_t Type3_t;
+ typedef typename LeafFunctor<A4, EngineView<Tag> >::Type_t Type4_t;
+ typedef typename LeafFunctor<A5, EngineView<Tag> >::Type_t Type5_t;
+ typedef typename LeafFunctor<A6, EngineView<Tag> >::Type_t Type6_t;
+ typedef typename LeafFunctor<A7, EngineView<Tag> >::Type_t Type7_t;
+ typedef MultiArg7<Type1_t, Type2_t, Type3_t, Type4_t, Type5_t,
+ Type6_t, Type7_t> Type_t;
+ inline static
+ Type_t apply(const MultiArg7<A1, A2, A3, A4, A5, A6, A7> &multiarg,
+ const EngineView<Tag> &tag)
+ {
+ return Type_t(
+ leafFunctor(multiarg.a1_m, tag),
+ leafFunctor(multiarg.a2_m, tag),
+ leafFunctor(multiarg.a3_m, tag),
+ leafFunctor(multiarg.a4_m, tag),
+ leafFunctor(multiarg.a5_m, tag),
+ leafFunctor(multiarg.a6_m, tag),
+ leafFunctor(multiarg.a7_m, tag)
+ );
+ }
+ };
+ template<class MA, class Function>
+ struct ApplyMultiArgLoc;
+ template<class A1, class Function>
+ struct ApplyMultiArgLoc<MultiArg1<A1>, Function>
+ {
+ ApplyMultiArgLoc(const MultiArg1<A1> &multiArg, const Function &function)
+ : multiArg_m(multiArg), function_m(function)
+ {
+ }
+ void operator()(int i0) const
+ {
+ function_m(multiArg_m.a1_m, Loc<1>(i0));
+ }
+ void operator()(int i0, int i1) const
+ {
+ function_m(multiArg_m.a1_m, Loc<2>(i0, i1));
+ }
+ void operator()(int i0, int i1, int i2) const
+ {
+ function_m(multiArg_m.a1_m, Loc<3>(i0, i1, i2));
+ }
+ void operator()(int i0, int i1, int i2, int i3) const
+ {
+ function_m(multiArg_m.a1_m, Loc<4>(i0, i1, i2, i3));
+ }
+ const MultiArg1<A1> &multiArg_m;
+ const Function &function_m;
+ };
+ template<class A1, class A2, class Function>
+ struct ApplyMultiArgLoc<MultiArg2<A1, A2>, Function>
+ {
+ ApplyMultiArgLoc(const MultiArg2<A1, A2> &multiArg,const Function &function)
+ : multiArg_m(multiArg), function_m(function)
+ {
+ }
+ void operator()(int i0) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, Loc<1>(i0));
+ }
+ void operator()(int i0, int i1) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, Loc<2>(i0, i1));
+ }
+ void operator()(int i0, int i1, int i2) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, Loc<3>(i0, i1, i2));
+ }
+ void operator()(int i0, int i1, int i2, int i3) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, Loc<4>(i0, i1, i2, i3));
+ }
+ const MultiArg2<A1, A2> &multiArg_m;
+ const Function &function_m;
+ };
+ template<class A1, class A2, class A3, class Function>
+ struct ApplyMultiArgLoc<MultiArg3<A1, A2, A3>, Function>
+ {
+ ApplyMultiArgLoc(const MultiArg3<A1, A2, A3> &multiArg,
+ const Function &function)
+ : multiArg_m(multiArg), function_m(function)
+ {
+ }
+ void operator()(int i0) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ Loc<1>(i0));
+ }
+ void operator()(int i0, int i1) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ Loc<2>(i0, i1));
+ }
+ void operator()(int i0, int i1, int i2) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ Loc<3>(i0, i1, i2));
+ }
+ void operator()(int i0, int i1, int i2, int i3) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ Loc<4>(i0, i1, i2, i3));
+ }
+ const MultiArg3<A1, A2, A3> &multiArg_m;
+ const Function &function_m;
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class Function>
+ struct ApplyMultiArgLoc<MultiArg7<A1, A2, A3, A4, A5, A6, A7>, Function>
+ {
+ ApplyMultiArgLoc(const MultiArg7<A1, A2, A3, A4, A5, A6, A7> &multiArg,
+ const Function &function)
+ : multiArg_m(multiArg), function_m(function)
+ {
+ }
+ void operator()(int i0) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
+ multiArg_m.a7_m, Loc<1>(i0));
+ }
+ void operator()(int i0, int i1) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
+ multiArg_m.a7_m, Loc<2>(i0, i1));
+ }
+ void operator()(int i0, int i1, int i2) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
+ multiArg_m.a7_m, Loc<3>(i0, i1, i2));
+ }
+ void operator()(int i0, int i1, int i2, int i3) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
+ multiArg_m.a7_m, Loc<4>(i0, i1, i2, i3));
+ }
+ const MultiArg7<A1, A2, A3, A4, A5, A6, A7> &multiArg_m;
+ const Function &function_m;
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class A6, class Function>
+ struct ApplyMultiArgLoc<MultiArg6<A1, A2, A3, A4, A5, A6>, Function>
+ {
+ ApplyMultiArgLoc(const MultiArg6<A1, A2, A3, A4, A5, A6> &multiArg,
+ const Function &function)
+ : multiArg_m(multiArg), function_m(function)
+ {
+ }
+ void operator()(int i0) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
+ Loc<1>(i0));
+ }
+ void operator()(int i0, int i1) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
+ Loc<2>(i0, i1));
+ }
+ void operator()(int i0, int i1, int i2) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
+ Loc<3>(i0, i1, i2));
+ }
+ void operator()(int i0, int i1, int i2, int i3) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m, multiArg_m.a5_m, multiArg_m.a6_m,
+ Loc<4>(i0, i1, i2, i3));
+ }
+ const MultiArg6<A1, A2, A3, A4, A5, A6> &multiArg_m;
+ const Function &function_m;
+ };
+ template<class A1, class A2, class A3, class A4, class Function>
+ struct ApplyMultiArgLoc<MultiArg4<A1, A2, A3, A4>, Function>
+ {
+ ApplyMultiArgLoc(const MultiArg4<A1, A2, A3, A4> &multiArg,
+ const Function &function)
+ : multiArg_m(multiArg), function_m(function)
+ {
+ }
+ void operator()(int i0) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m,
+ Loc<1>(i0));
+ }
+ void operator()(int i0, int i1) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m,
+ Loc<2>(i0, i1));
+ }
+ void operator()(int i0, int i1, int i2) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m,
+ Loc<3>(i0, i1, i2));
+ }
+ void operator()(int i0, int i1, int i2, int i3) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m,
+ Loc<4>(i0, i1, i2, i3));
+ }
+ const MultiArg4<A1, A2, A3, A4> &multiArg_m;
+ const Function &function_m;
+ };
+ template<class A1, class A2, class A3, class A4, class A5, class Function>
+ struct ApplyMultiArgLoc<MultiArg5<A1, A2, A3, A4, A5>, Function>
+ {
+ ApplyMultiArgLoc(const MultiArg5<A1, A2, A3, A4, A5> &multiArg,
+ const Function &function)
+ : multiArg_m(multiArg), function_m(function)
+ {
+ }
+ void operator()(int i0) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m, multiArg_m.a5_m,
+ Loc<1>(i0));
+ }
+ void operator()(int i0, int i1) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m, multiArg_m.a5_m,
+ Loc<2>(i0, i1));
+ }
+ void operator()(int i0, int i1, int i2) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m, multiArg_m.a5_m,
+ Loc<3>(i0, i1, i2));
+ }
+ void operator()(int i0, int i1, int i2, int i3) const
+ {
+ function_m(multiArg_m.a1_m, multiArg_m.a2_m, multiArg_m.a3_m,
+ multiArg_m.a4_m, multiArg_m.a5_m,
+ Loc<4>(i0, i1, i2, i3));
+ }
+ const MultiArg5<A1, A2, A3, A4, A5> &multiArg_m;
+ const Function &function_m;
+ };
+ template<class Function, int Dim>
+ struct EvaluateLocLoop
+ {
+ EvaluateLocLoop()
+ {
+ }
+ EvaluateLocLoop(const Function &function, const Interval<Dim> &domain)
+ : function_m(function), domain_m(domain)
+ {
+ }
+ template<class MultiArg>
+ void operator()(MultiArg &multiArg) const
+ {
+ ApplyMultiArgLoc<MultiArg, Function> op(multiArg, function_m);
+ LoopApplyEvaluator::evaluate(op, domain_m);
+ }
+ Function function_m;
+ Interval<Dim> domain_m;
+ };
+ template<class Function>
+ struct ScalarCode
+ {
+ ScalarCode()
+ {
+ }
+ ScalarCode(const Function &function)
+ : function_m(function)
+ {
+ }
+ template <class LHS>
+ ScalarCode(const ScalarCode<Function>& sc, const LHS&)
+ : function_m(sc.function_m)
+ {
+ }
+ template<class F>
+ static inline bool checkValidity(const F& f, WrappedInt<false>)
+ {
+ return true;
+ }
+ template<class F>
+ static inline bool checkValidity(const F& f, WrappedInt<true>)
+ {
+ return f.centeringSize() == 1 && f.numMaterials() == 1;
+ }
+ template<class F1>
+ void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom) const
+ {
+ ;
+ MultiArg1<F1> multiArg(f1);
+ EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
+ MultiArgEvaluator<MainEvaluatorTag>::
+ evaluate(multiArg, function_m, evalDom, kernel);
+ }
+ template<class F1>
+ inline void operator()(const F1 &f1) const
+ {
+ (*this)(f1, f1.physicalDomain());
+ }
+ template<class F1, class F2>
+ void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
+ const F2 &f2) const
+ {
+ ;
+ MultiArg2<F1, F2> multiArg(f1, f2);
+ EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
+ MultiArgEvaluator<MainEvaluatorTag>::
+ evaluate(multiArg, function_m, evalDom, kernel);
+ }
+ template<class F1, class F2>
+ inline void operator()(const F1 &f1, const F2 &f2) const
+ {
+ (*this)(f1, f1.physicalDomain(), f2);
+ }
+ template<class F1, class F2, class F3>
+ void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
+ const F2 &f2, const F3 &f3) const
+ {
+ ;
+ MultiArg3<F1, F2, F3> multiArg(f1, f2, f3);
+ EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
+ MultiArgEvaluator<MainEvaluatorTag>::
+ evaluate(multiArg, function_m, evalDom, kernel);
+ }
+ template<class F1, class F2, class F3>
+ inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3) const
+ {
+ (*this)(f1, f1.physicalDomain(), f2, f3);
+ }
+ template<class F1, class F2, class F3, class F4>
+ void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
+ const F2 &f2, const F3 &f3, const F4 &f4) const
+ {
+ ;
+ MultiArg4<F1, F2, F3, F4> multiArg(f1, f2, f3, f4);
+ EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
+ MultiArgEvaluator<MainEvaluatorTag>::
+ evaluate(multiArg, function_m, evalDom, kernel);
+ }
+ template<class F1, class F2, class F3, class F4>
+ inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4) const
+ {
+ (*this)(f1, f1.physicalDomain(), f2, f3, f4);
+ }
+ template<class F1, class F2, class F3, class F4, class F5>
+ void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
+ const F2 &f2, const F3 &f3, const F4 &f4, const F5 &f5) const
+ {
+ ;
+ MultiArg5<F1, F2, F3, F4, F5> multiArg(f1, f2, f3, f4, f5);
+ EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
+ MultiArgEvaluator<MainEvaluatorTag>::
+ evaluate(multiArg, function_m, evalDom, kernel);
+ }
+ template<class F1, class F2, class F3, class F4, class F5>
+ inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4,
+ const F5 &f5) const
+ {
+ (*this)(f1, f1.physicalDomain(), f2, f3, f4, f5);
+ }
+ template<class F1, class F2, class F3, class F4, class F5, class F6>
+ void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
+ const F2 &f2, const F3 &f3, const F4 &f4, const F5 &f5,
+ const F6 &f6) const
+ {
+ ;
+ MultiArg6<F1, F2, F3, F4, F5, F6> multiArg(f1, f2, f3, f4, f5, f6);
+ EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
+ MultiArgEvaluator<MainEvaluatorTag>::
+ evaluate(multiArg, function_m, evalDom, kernel);
+ }
+ template<class F1, class F2, class F3, class F4, class F5, class F6>
+ inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4,
+ const F5 &f5, const F6 &f6) const
+ {
+ (*this)(f1, f1.physicalDomain(), f2, f3, f4, f5, f6);
+ }
+ template<class F1, class F2, class F3, class F4, class F5, class F6, class F7>
+ void operator()(const F1 &f1, const Interval<F1::dimensions> &evalDom,
+ const F2 &f2, const F3 &f3, const F4 &f4,
+ const F5 &f5, const F6 &f6, const F7 &f7) const
+ {
+ ;
+ MultiArg7<F1, F2, F3, F4, F5, F6, F7> multiArg(f1, f2, f3, f4, f5, f6, f7);
+ EvaluateLocLoop<Function, F1::dimensions> kernel(function_m, evalDom);
+ MultiArgEvaluator<MainEvaluatorTag>::
+ evaluate(multiArg, function_m, evalDom, kernel);
+ }
+ template<class F1, class F2, class F3, class F4, class F5, class F6, class F7>
+ inline void operator()(const F1 &f1, const F2 &f2, const F3 &f3, const F4 &f4,
+ const F5 &f5, const F6 &f6, const F7 &f7) const
+ {
+ (*this)(f1, f1.physicalDomain(), f2, f3, f4, f5, f6, f7);
+ }
+ Function function_m;
+ };
+ template<class InputField>
+ struct PackLocalPatches
+ {
+ typedef typename InputField::Element_t Element_t;
+ PackLocalPatches(RefCountedBlockPtr<Element_t> block)
+ : block_m(block)
+ {
+ }
+ inline void operator()(const Element_t &t)
+ {
+ *block_m = t;
+ ++block_m;
+ }
+ RefCountedBlockPtr<Element_t> block_m;
+ int total_m;
+ };
+ template<class InputField>
+ RefCountedBlockPtr<typename InputField::Element_t>
+ pack(const InputField &field)
+ {
+ Pooma::blockAndEvaluate();
+ typedef typename InputField::Element_t Element_t;
+ int size, i;
+ size = 0;
+ for (i = 0; i < field.numPatchesLocal(); ++i)
+ {
+ size += field.patchLocal(i).domain().size();
+ }
+ RefCountedBlockPtr<Element_t> ret(size);
+ RefCountedBlockPtr<Element_t> current = ret;
+ for (i = 0; i < field.numPatchesLocal(); ++i)
+ {
+ typedef typename Patch<InputField>::Type_t PatchField_t;
+ PatchField_t patch = field.patchLocal(i);
+ PackLocalPatches<PatchField_t> packFunctor(current);
+ EngineBlockSerialize::apply(packFunctor, patch, patch.domain());
+ current += patch.domain().size();
+ }
+ return ret;
+ }
+ template<class InputField>
+ struct UnPackLocalPatches
+ {
+ typedef typename InputField::Element_t Element_t;
+ UnPackLocalPatches(RefCountedBlockPtr<Element_t> block)
+ : block_m(block)
+ {
+ }
+ inline void operator()(Element_t &t)
+ {
+ t = *block_m;
+ ++block_m;
+ }
+ RefCountedBlockPtr<Element_t> block_m;
+ int total_m;
+ };
+ template<class InputField, class T>
+ void
+ unpack(const InputField &field, RefCountedBlockPtr<T> block)
+ {
+ Pooma::blockAndEvaluate();
+ int i;
+ RefCountedBlockPtr<T> current = block;
+ for (i = 0; i < field.numPatchesLocal(); ++i)
+ {
+ typedef typename Patch<InputField>::Type_t PatchField_t;
+ PatchField_t patch = field.patchLocal(i);
+ UnPackLocalPatches<PatchField_t> unpackFunctor(current);
+ EngineBlockSerialize::apply(unpackFunctor, patch, patch.physicalDomain());
+ current += patch.physicalDomain().size();
+ }
+ }
+ struct FarLeftTag;
+ template<class G, class T, class E> class Field;
+ template<class Expr>
+ struct MakeFieldReturn;
+ template<class Op, class Leaf>
+ struct MakeFieldReturn<UnaryNode<Op, Leaf> >
+ {
+ typedef UnaryNode<Op, Leaf> Tree_t;
+ typedef typename
+ ForEach<Tree_t, DomainFunctorTag, DomainFunctorTag>::Type_t Domain_t;
+ enum { dim = Domain_t::dimensions };
+ typedef typename ForEach<Tree_t, EvalLeaf<dim>, OpCombine>::Type_t T_t;
+ typedef Engine<dim, T_t, ExpressionTag<Tree_t> > Engine_t;
+ typedef typename ForEach<Tree_t, FarLeftTag, FarLeftTag>::
+ Type_t::MeshTag_t MeshTag_t;
+ typedef Field<MeshTag_t, T_t, ExpressionTag<Tree_t> > Expression_t;
+ inline static
+ Expression_t make(const Tree_t &tree)
+ {
+ return Expression_t(Engine_t(tree));
+ }
+ };
+ template<class Op, class Left, class Right>
+ struct MakeFieldReturn<BinaryNode<Op, Left, Right> >
+ {
+ typedef BinaryNode<Op, Left, Right> Tree_t;
+ typedef typename
+ ForEach<Tree_t, DomainFunctorTag, DomainFunctorTag>::Type_t Domain_t;
+ enum { dim = Domain_t::dimensions };
+ typedef typename ForEach<Tree_t, EvalLeaf<dim>, OpCombine>::Type_t T_t;
+ typedef Engine<dim, T_t, ExpressionTag<Tree_t> > Engine_t;
+ typedef typename ForEach<Tree_t, FarLeftTag, FarLeftTag>::
+ Type_t::MeshTag_t MeshTag_t;
+ typedef Field<MeshTag_t, T_t, ExpressionTag<Tree_t> >
+ Expression_t;
+ inline static
+ Expression_t make(const Tree_t &tree)
+ {
+ return Expression_t(Engine_t(tree));
+ }
+ };
+ template<class Op, class Left, class Middle, class Right>
+ struct MakeFieldReturn<TrinaryNode<Op, Left, Middle, Right> >
+ {
+ typedef TrinaryNode<Op, Left, Middle, Right> Tree_t;
+ typedef typename
+ ForEach<Tree_t, DomainFunctorTag, DomainFunctorTag>::Type_t Domain_t;
+ enum { dim = Domain_t::dimensions };
+ typedef typename ForEach<Tree_t, EvalLeaf<dim>, OpCombine>::Type_t T_t;
+ typedef Engine<dim, T_t, ExpressionTag<Tree_t> > Engine_t;
+ typedef typename ForEach<Tree_t, FarLeftTag, FarLeftTag>::
+ Type_t::MeshTag_t MeshTag_t;
+ typedef Field<MeshTag_t, T_t, ExpressionTag<Tree_t> > Expression_t;
+ inline static
+ Expression_t make(const Tree_t &tree)
+ {
+ return Expression_t(Engine_t(tree));
+ }
+ };
+ template<class G, class T, class E> class Field;
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnArcCos,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ acos(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnArcCos,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnArcSin,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ asin(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnArcSin,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnArcTan,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ atan(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnArcTan,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnCeil,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ ceil(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnCeil,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnCos,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ cos(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnCos,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnHypCos,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ cosh(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnHypCos,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnExp,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ exp(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnExp,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnFabs,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ fabs(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnFabs,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnFloor,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ floor(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnFloor,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnLog,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ log(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnLog,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnLog10,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ log10(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnLog10,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnSin,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ sin(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnSin,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnHypSin,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ sinh(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnHypSin,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnSqrt,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ sqrt(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnSqrt,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnTan,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ tan(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnTan,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnHypTan,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ tanh(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnHypTan,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<OpUnaryMinus,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ operator-(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<OpUnaryMinus,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<OpUnaryPlus,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ operator+(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<OpUnaryPlus,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<OpBitwiseNot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ operator~(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<OpBitwiseNot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<OpIdentity,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ PETE_identity(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<OpIdentity,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<OpNot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ operator!(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<OpNot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<UnaryNode<OpCast<T1>,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ peteCast(const T1&, const Field<G2,T2,E2> & l)
+ {
+ typedef UnaryNode<OpCast<T1>,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G2,T2,E2> >::make(l)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLT,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLT,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<=(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGT,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGT,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>=(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&&(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator||(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLeftShift,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<<(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLeftShift,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpRightShift,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>>(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpRightShift,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator+(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator-(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator*(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator/(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator%(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator&(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator|(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator^(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ ldexp(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ pow(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ fmod(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ atan2(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLT,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLT,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpLT,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator<(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpLT,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<=(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpLE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator<=(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpLE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGT,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGT,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpGT,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator>(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpGT,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>=(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpGE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator>=(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpGE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator==(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator!=(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&&(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator&&(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator||(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator||(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLeftShift,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<<(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLeftShift,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpLeftShift,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator<<(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpLeftShift,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpRightShift,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>>(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpRightShift,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpRightShift,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ operator>>(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpRightShift,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMod,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnPow,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLT,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLT,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLT,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLT,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<=(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLE,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator<=(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLE,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGT,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGT,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGT,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGT,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>=(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGE,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator>=(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGE,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&&(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAnd,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpAnd,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&&(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAnd,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator||(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpOr,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpOr,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator||(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpOr,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2,class T3>
+ inline typename MakeFieldReturn<TrinaryNode<FnWhere,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t,
+ typename CreateLeaf<T3 >::Leaf_t> >::Expression_t
+ where(const Field<G1,T1,E1> & c,const T2 & t,const T3 & f)
+ {
+ typedef TrinaryNode<FnWhere,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t,
+ typename CreateLeaf<T3 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(c),
+ CreateLeaf<T2 >::make(t),
+ CreateLeaf<T3 >::make(f)));
+ }
+ template<int D, class T, class EngineTag> class Tensor;
+ template<class OutputEngineTag, int D, class T, class EngineTag>
+ Tensor<D, T, OutputEngineTag>
+ symmetrize(const Tensor<D, T, EngineTag> &x);
+ template<class G, class T, class E> class Field;
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnReal,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ real(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnReal,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnImag,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ imag(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnImag,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnAbs,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ abs(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnAbs,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnArg,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ arg(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnArg,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnNorm,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ norm(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnNorm,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnConj,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ conj(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnConj,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnPow2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ pow2(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnPow2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnPow3,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ pow3(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnPow3,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnPow4,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ pow4(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnPow4,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnMagnitude,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ magnitude(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnMagnitude,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnTrace,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ trace(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnTrace,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnDet,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ det(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnDet,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnTranspose,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ transpose(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnTranspose,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class OutputSymmetry,class G1,class T1,class E1>
+ inline typename MakeFieldReturn<UnaryNode<FnSymmetrize<OutputSymmetry>,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> >::Expression_t
+ symmetrize(const Field<G1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnSymmetrize<OutputSymmetry>,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnPolar,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ polar(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPolar,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnOuterProduct,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ outerProduct(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnOuterProduct,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ outerProductAsTinyMatrix(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnDotDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ dotdot(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDotDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnMin,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ min(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnMin,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnMax,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ max(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnMax,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLT2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ LT(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLT2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ LE(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGT2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ GT(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGT2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ GE(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ EQ(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ NE(const Field<G1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ dot(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnPolar,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ polar(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPolar,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<FnPolar,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ polar(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnPolar,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnOuterProduct,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ outerProduct(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnOuterProduct,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<FnOuterProduct,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ outerProduct(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnOuterProduct,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ outerProductAsTinyMatrix(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ outerProductAsTinyMatrix(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnDotDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ dotdot(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDotDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<FnDotDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ dotdot(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnDotDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnMin,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ min(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnMin,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<FnMin,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ min(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnMin,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnMax,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ max(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnMax,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<FnMax,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ max(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<FnMax,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLT2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ LT(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLT2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpLT2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ LT(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpLT2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ LE(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpLE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ LE(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpLE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGT2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ GT(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGT2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpGT2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ GT(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpGT2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ GE(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpGE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ GE(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpGE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ EQ(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ EQ(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpEQ2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> >::Expression_t
+ NE(const Field<G1,T1,E1> & l,const Array<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Array<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Array<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,class T2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> >::Expression_t
+ NE(const Field<G1,T1,E1> & l,const T2 & r)
+ {
+ typedef BinaryNode<OpNE2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<T2 >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<T2 >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnDot,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnPolar,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ polar(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPolar,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnPolar,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ polar(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPolar,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnOuterProduct,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ outerProduct(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnOuterProduct,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnOuterProduct,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ outerProduct(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnOuterProduct,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ outerProductAsTinyMatrix(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ outerProductAsTinyMatrix(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnOuterProductAsTinyMatrix,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnDotDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ dotdot(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDotDot,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnDotDot,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ dotdot(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDotDot,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnMin,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ min(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnMin,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnMin,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ min(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnMin,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnMax,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ max(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnMax,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnMax,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ max(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnMax,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLT2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ LT(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLT2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLT2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ LT(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLT2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ LE(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpLE2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ LE(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpLE2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGT2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ GT(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGT2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGT2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ GT(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGT2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ GE(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpGE2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ GE(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpGE2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ EQ(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ EQ(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ NE(const Array<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE2,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class T1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ NE(const T1 & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE2,
+ typename CreateLeaf<T1 >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<T1 >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<class G, class T, class E> class Field;
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const Field<G1,T1,E1> & l,const Vector<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Vector<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Vector<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int D2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const Field<G1,T1,E1> & l,const Tensor<D2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Tensor<D2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<Tensor<D2,T2,E2> >::make(r)));
+ }
+ template<class G1,class T1,class E1,int DR2,int DC2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const Field<G1,T1,E1> & l,const TinyMatrix<DR2,DC2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Field<G1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<G1,T1,E1> >::make(l),
+ CreateLeaf<TinyMatrix<DR2,DC2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpAdd,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator+(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpAdd,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpSubtract,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator-(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpSubtract,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMultiply,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator*(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMultiply,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpDivide,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator/(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpDivide,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMod,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpMod,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator%(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpMod,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator&(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseAnd,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator|(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseOr,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator^(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpBitwiseXor,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnDot,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnDot,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ dot(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnDot,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnLdexp,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ ldexp(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnLdexp,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnPow,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnPow,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ pow(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnPow,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnFmod,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ fmod(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnFmod,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<FnArcTan2,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ atan2(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<FnArcTan2,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpEQ,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator==(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpEQ,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const Vector<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Vector<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Vector<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int D1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const Tensor<D1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<Tensor<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Tensor<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ template<int DR1,int DC1,class T1,class E1,class G2,class T2,class E2>
+ inline typename MakeFieldReturn<BinaryNode<OpNE,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> >::Expression_t
+ operator!=(const TinyMatrix<DR1,DC1,T1,E1> & l,const Field<G2,T2,E2> & r)
+ {
+ typedef BinaryNode<OpNE,
+ typename CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<G2,T2,E2> >::Leaf_t> Tree_t;
+ return MakeFieldReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<TinyMatrix<DR1,DC1,T1,E1> >::make(l),
+ CreateLeaf<Field<G2,T2,E2> >::make(r)));
+ }
+ struct FarLeftTag;
+ template<class G, class T, class E> class Field;
+ template<class GeometryTag, class T, class Expr>
+ struct CreateLeaf<Field<GeometryTag, T, ExpressionTag<Expr> > >
+ {
+ typedef Field<GeometryTag, T, ExpressionTag<Expr> > Input_t;
+ typedef Expr Leaf_t;
+ typedef const Leaf_t &Return_t;
+ inline static
+ Return_t make(const Input_t &f)
+ {
+ return f.engine().expression();
+ }
+ };
+ template<class GeometryTag, class T, class EngineTag>
+ struct CreateLeaf<Field<GeometryTag, T, EngineTag> >
+ {
+ typedef Field<GeometryTag, T, EngineTag> Input_t;
+ typedef Reference<Input_t> Leaf_t;
+ typedef Leaf_t Return_t;
+ inline static
+ Return_t make(const Input_t &f)
+ {
+ return Leaf_t(f);
+ }
+ };
+ template<class GeometryTag, class T, class EngineTag>
+ struct CreateLeaf<Scalar<Field<GeometryTag, T, EngineTag> > >
+ {
+ typedef Scalar<Field<GeometryTag, T, EngineTag> > Input_t;
+ typedef Scalar<ErrorType> Leaf_t;
+ typedef Leaf_t Return_t;
+ inline static
+ Return_t make(const Input_t &)
+ {
+ return ErrorType();
+ }
+ };
+ template <int Dim>
+ class Centering;
+ template <int Dim>
+ class CanonicalCentering;
+ enum CenteringType {
+ VertexType,
+ EdgeType,
+ FaceType,
+ CellType
+ };
+ enum ContinuityType {
+ Continuous = 0,
+ Discontinuous
+ };
+ enum {
+ XDim = 1,
+ YDim = XDim << 1,
+ ZDim = YDim << 1,
+ AllDim = XDim | YDim | ZDim
+ };
+ template <int Dim>
+ class Centering
+ {
+ public:
+ typedef Loc<Dim> Orientation;
+ typedef Vector<Dim> Position;
+ typedef std::vector<Orientation> Orientations;
+ typedef std::vector<Position> Positions;
+ Centering(CenteringType cent = CellType, ContinuityType cont = Continuous)
+ : centering_type_m(cent), discontinuous_m(cont),
+ orientations_m(0), positions_m(0)
+ { }
+ Centering(CenteringType cent, ContinuityType cont,
+ const Orientations &orientations, const Positions &positions)
+ : centering_type_m(cent), discontinuous_m(cont),
+ orientations_m(orientations), positions_m(positions)
+ {
+ return;
+ }
+ Centering(const Centering<Dim>& model, int c)
+ : centering_type_m(model.centering_type_m),
+ discontinuous_m(model.discontinuous_m),
+ orientations_m(1, model.orientations_m[c]),
+ positions_m(1, model.positions_m[c])
+ { }
+ Centering<Dim> operator[](int iSubField) const
+ {
+ return Centering<Dim>(*this, iSubField);
+ }
+ ~Centering() { }
+ inline CenteringType centeringType() const
+ {
+ return centering_type_m;
+ }
+ inline ContinuityType continuityType() const
+ {
+ return discontinuous_m;
+ }
+ inline bool discontinuous() const
+ {
+ return discontinuous_m == Discontinuous;
+ }
+ inline bool continuous() const
+ {
+ return discontinuous_m == Continuous;
+ }
+ inline const Orientations &orientations() const
+ {
+ return orientations_m;
+ }
+ inline const Positions &positions() const
+ {
+ return positions_m;
+ }
+ inline const Orientation &orientation(int i) const
+ {
+ return orientations_m[i];
+ }
+ inline const Position &position(int i) const
+ {
+ return positions_m[i];
+ }
+ inline int size() const
+ {
+ return orientations_m.size();
+ }
+ inline void
+ addValue(const Orientation &orientation,
+ const Position &position)
+ {
+ orientations_m.push_back(orientation);
+ positions_m.push_back(position);
+ return;
+ }
+ private:
+ CenteringType centering_type_m;
+ ContinuityType discontinuous_m;
+ Orientations orientations_m;
+ Positions positions_m;
+ };
+ template <int Dim>
+ class CanonicalCentering {
+ public:
+ CanonicalCentering();
+ ~CanonicalCentering () {
+ if (--class_count_m == 0) {
+ for (int i = 0; i <= CellType; ++i) {
+ for (int j = 0; j < 2; ++j)
+ delete [] centering_table_m[i][j];
+ delete [] centering_table_m[i];
+ }
+ delete [] centering_table_m;
+ }
+ }
+ inline Centering<Dim> operator()
+ (const enum CenteringType type,
+ const enum ContinuityType discontinuous,
+ int dimension = 0) const
+ {
+ if (dimension == 0)
+ dimension = AllDim;
+ dimension %= (1<<Dim);
+ return centering_table_m[type][discontinuous][dimension];
+ }
+ private:
+ inline static void addValue(typename Centering<Dim>::Orientations &os,
+ typename Centering<Dim>::Positions &pos,
+ const typename Centering<Dim>::Orientation &o,
+ const typename Centering<Dim>::Position &p)
+ {
+ os.push_back(o);
+ pos.push_back(p);
+ return;
+ }
+ template <class T>
+ inline static
+ T combine(const T &op1, const T &op2)
+ {
+ T answer(op1);
+ answer.insert(answer.end(), op2.begin(), op2.end());
+ return answer;
+ }
+ static int class_count_m;
+ static Centering<Dim>*** centering_table_m;
+ };
+ template <int Dim>
+ std::ostream &operator<<(std::ostream &o,
+ const Centering<Dim> ¢ering)
+ {
+ switch (centering.centeringType())
+ {
+ case VertexType:
+ o << "Vertex";
+ break;
+ case EdgeType:
+ o << "Edge";
+ break;
+ case FaceType:
+ o << "Face";
+ break;
+ case CellType:
+ o << "Cell";
+ break;
+ }
+ o << "," << (centering.continuous() ? "Continuous" : "Discontinuous")
+ << ",{";
+ for (int i = 0; i < centering.size();)
+ {
+ o << "[" << centering.orientation(i)
+ << "," << centering.position(i) << "]";
+ ++i;
+ if (i < centering.size())
+ o << ",";
+ }
+ o << "}";
+ return o;
+ }
+ template <int Dim>
+ bool operator==(const Centering<Dim> ¢ering1, const Centering<Dim> ¢ering2)
+ {
+ return
+ centering1.centeringType() == centering2.centeringType() &&
+ centering1.discontinuous() == centering2.discontinuous() &&
+ centering1.orientations() == centering2.orientations() &&
+ centering1.positions() == centering2.positions();
+ }
+ template <int Dim>
+ bool operator!=(const Centering<Dim> ¢ering1, const Centering<Dim> ¢ering2)
+ {
+ return !(centering1 == centering2);
+ }
+ template <int Dim>
+ int CanonicalCentering<Dim>::class_count_m = 0;
+ template <int Dim>
+ Centering<Dim>*** CanonicalCentering<Dim>::centering_table_m = 0;
+ extern const CanonicalCentering<1> canonicalCenteringOne_g;
+ extern const CanonicalCentering<2> canonicalCenteringTwo_g;
+ extern const CanonicalCentering<3> canonicalCenteringThree_g;
+ template <int Dim>
+ const Centering<Dim> canonicalCentering
+ (const enum CenteringType type,
+ const enum ContinuityType discontinuous,
+ const int dimension = 0);
+ template <>
+ const Centering<1> canonicalCentering<1>
+ (const enum CenteringType type,
+ const enum ContinuityType discontinuous,
+ const int dimension);
+ template <>
+ const Centering<2> canonicalCentering<2>
+ (const enum CenteringType type,
+ const enum ContinuityType discontinuous,
+ const int dimension);
+ template <>
+ const Centering<3> canonicalCentering<3>
+ (const enum CenteringType type,
+ const enum ContinuityType discontinuous,
+ const int dimension);
+ template<int Dim>
+ inline Interval<Dim>
+ cellDomainToCenteringDomain(const Interval<Dim> &cellDom,
+ const Centering<Dim> ¢ering, int i)
+ {
+ if (centering.discontinuous())
+ {
+ return cellDom;
+ }
+ else
+ {
+ return shrinkRight(growRight(cellDom, 1), centering.orientation(i));
+ }
+ }
+ template<int Dim>
+ inline Interval<Dim>
+ centeringDomainToCellDomain(const Interval<Dim> &cDom,
+ const Centering<Dim> ¢ering, int i)
+ {
+ if (centering.discontinuous())
+ {
+ return cDom;
+ }
+ else
+ {
+ return shrinkRight(growRight(cDom, centering.orientation(i)), 1);
+ }
+ }
+ template <int Dim>
+ class FieldOffset;
+ template <int Dim>
+ class FieldOffsetList;
+ template <int Dim>
+ class FieldOffset {
+ public:
+ FieldOffset(const Loc<Dim> &loc, const int subFieldNumber = 0)
+ : cell_offset_m(loc), subfield_number_m(subFieldNumber)
+ {
+ return;
+ }
+ FieldOffset()
+ : cell_offset_m(Loc<Dim>()), subfield_number_m(0)
+ {}
+ inline void setSubFieldNumber(int subFieldNumber)
+ {
+ subfield_number_m = subFieldNumber;
+ return;
+ }
+ inline Loc<Dim> &modifyCellOffset()
+ {
+ return cell_offset_m;
+ }
+ inline const Loc<Dim> &cellOffset() const
+ {
+ return cell_offset_m;
+ }
+ inline int subFieldNumber() const
+ {
+ return subfield_number_m;
+ }
+ private:
+ Loc<Dim> cell_offset_m;
+ int subfield_number_m;
+ };
+ template <int Dim>
+ std::ostream &operator<<(std::ostream &o,
+ const FieldOffset<Dim> &fieldOffset)
+ {
+ return o << "FieldOffset: (" << fieldOffset.cellOffset()
+ << ", " << fieldOffset.subFieldNumber() << ")";
+ }
+ template <int Dim>
+ inline bool
+ operator==(const FieldOffset<Dim> &fieldOffset1,
+ const FieldOffset<Dim> &fieldOffset2)
+ {
+ return
+ fieldOffset1.cellOffset() == fieldOffset2.cellOffset() &&
+ fieldOffset1.subFieldNumber() == fieldOffset2.subFieldNumber();
+ }
+ template <int Dim>
+ inline bool
+ operator!=(const FieldOffset<Dim> &fieldOffset1,
+ const FieldOffset<Dim> &fieldOffset2)
+ {
+ return !(fieldOffset1 == fieldOffset2);
+ }
+ template <int Dim>
+ class FieldOffsetList
+ {
+ public:
+ typedef size_t size_type;
+ typedef FieldOffset<Dim>& reference;
+ typedef const FieldOffset<Dim>& const_reference;
+ size_type size() const
+ {
+ return v_m.size();
+ }
+ const_reference operator[](const size_type n) const
+ {
+ return v_m[n];
+ }
+ FieldOffsetList() {}
+ FieldOffsetList(const size_type sz)
+ {
+ v_m.reserve(sz);
+ }
+ FieldOffsetList(const std::vector<FieldOffset<Dim> > &v) {
+ v_m.resize(v.size());
+ std::copy(v.begin(), v.end(), v_m.begin());
+ }
+ FieldOffsetList &operator=(const std::vector<FieldOffset<Dim> > &v)
+ {
+ v_m.resize(v.size());
+ std::copy(v.begin(), v.end(), v_m.begin());
+ return *this;
+ }
+ reference operator[](const size_type n)
+ {
+ return v_m[n];
+ }
+ private:
+ std::vector<FieldOffset<Dim> > v_m;
+ };
+ template <int Dim>
+ std::ostream &operator<<(std::ostream &o,
+ const FieldOffsetList<Dim> &fieldOffsetList)
+ {
+ o << "FieldOffsetList:\n";
+ for (int index = 0; index < fieldOffsetList.size(); ++index)
+ o << fieldOffsetList[index] << std::endl;
+ return o;
+ }
+ template<class GeometryTag, class T, class Expr, int Dim,
+ class BinaryFunction>
+ inline
+ T
+ accumulate(BinaryFunction binary_op,
+ const Field<GeometryTag, T, Expr>& field,
+ const FieldOffsetList<Dim> &lst,
+ const Loc<Dim> &loc)
+ {
+ typedef typename Field<GeometryTag, T, Expr>::T_t T_t;
+ typedef typename FieldOffsetList<Dim>::size_type size_type;
+ PoomaCTAssert<((Field<GeometryTag, T, Expr>::dimensions == Dim))>::test();
+ const size_type lstLength = lst.size();
+ if (__builtin_expect(!!(lstLength > 0), true)) {} else Pooma::toss_cookies("accumulate must be given a nonempty list.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/FieldOffset.h", 334);
+ T_t init = field(lst[0], loc);
+ for (size_type i = 1; i < lstLength ; ++i)
+ init = binary_op(init, field(lst[i], loc));
+ return init;
+ }
+ template<class GeometryTag, class T, class Expr, int Dim>
+ inline
+ T
+ sum(const Field<GeometryTag, T, Expr>& field,
+ const FieldOffsetList<Dim> &lst,
+ const Loc<Dim> &loc)
+ {
+ typedef typename Field<GeometryTag, T, Expr>::T_t T_t;
+ PoomaCTAssert<((Field<GeometryTag, T, Expr>::dimensions == Dim))>::test();
+ return accumulate(std::plus<T_t>(), field, lst, loc);
+ }
+ template<class GeometryTag, class T, class Expr, int Dim>
+ inline
+ T
+ av(const Field<GeometryTag, T, Expr>& field,
+ const FieldOffsetList<Dim> &lst,
+ const Loc<Dim> &loc)
+ {
+ typedef typename Field<GeometryTag, T, Expr>::T_t T_t;
+ PoomaCTAssert<((Field<GeometryTag, T, Expr>::dimensions == Dim))>::test();
+ return sum(field, lst, loc) / lst.size();
+ }
+ template <class T>
+ struct fomin : public std::binary_function<T, T, T>
+ {
+ T operator()(const T &op1, const T &op2) const {
+ return std::min(op1, op2);
+ }
+ };
+ template<class GeometryTag, class T, class Expr, int Dim>
+ inline
+ T
+ min(const Field<GeometryTag, T, Expr>& field,
+ const FieldOffsetList<Dim> &lst,
+ const Loc<Dim> &loc)
+ {
+ typedef typename Field<GeometryTag, T, Expr>::T_t T_t;
+ PoomaCTAssert<((Field<GeometryTag, T, Expr>::dimensions == Dim))>::test();
+ return accumulate(fomin<T_t>(), field, lst, loc);
+ }
+ template <class T>
+ struct fomax : public std::binary_function<T, T, T>
+ {
+ T operator()(const T &op1, const T &op2) const {
+ return std::max(op1, op2);
+ }
+ };
+ template<class GeometryTag, class T, class Expr, int Dim>
+ inline
+ T
+ max(const Field<GeometryTag, T, Expr>& field,
+ const FieldOffsetList<Dim> &lst,
+ const Loc<Dim> &loc)
+ {
+ typedef typename Field<GeometryTag, T, Expr>::T_t T_t;
+ PoomaCTAssert<((Field<GeometryTag, T, Expr>::dimensions == Dim))>::test();
+ return accumulate(fomax<T_t>(), field, lst, loc);
+ }
+ template <class GeometryTag, class T, class Expr, int Dim>
+ inline
+ typename
+ View2<Field<GeometryTag, T, Expr>, std::vector<FieldOffset<Dim> >,
+ Centering<Dim> >::Type_t
+ replicate(const Field<GeometryTag, T, Expr>& field,
+ const std::vector<FieldOffsetList<Dim> > &vec,
+ const Centering<Dim> ¢ering)
+ {
+ PoomaCTAssert<((Field<GeometryTag, T, Expr>::dimensions == Dim))>::test();
+ typedef typename std::vector<FieldOffsetList<Dim> >::size_type vsize_type;
+ if (__builtin_expect(!!(vec.size() > 0), true)) {} else Pooma::toss_cookies("Cannot replicate no values.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/FieldOffset.h", 445);
+ if (__builtin_expect(!!(vec.size() == centering.size()), true)) {} else Pooma::toss_cookies("Vector and output centering sizes must match.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/FieldOffset.h", 447);
+ std::vector<FieldOffset<Dim> > vecFO(vec.size());
+ for (vsize_type i = 0; i < vec.size(); ++i) {
+ if (__builtin_expect(!!(vec[i].size() == 1), true)) {} else Pooma::toss_cookies("Can replicate only one value.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/FieldOffset.h", 451);
+ vecFO[i] = vec[i][0];
+ }
+ return field(vecFO, centering);
+ }
+ #include <numeric>
+ template <int Dim, bool IntraCellOnly = false>
+ class NearestNeighborClass {
+ public:
+ typedef FieldOffset<Dim> FieldOffset_t;
+ typedef FieldOffsetList<Dim> FieldOffsetList_t;
+ typedef std::vector<FieldOffset_t> FieldOffset_vt;
+ typedef std::vector<FieldOffsetList_t> Answer_t;
+ typedef Centering<Dim> Center;
+ typedef typename Center::Positions Positions;
+ typedef typename Center::Position Position;
+ typedef std::pair<int, Position> MinimumPair;
+ typedef std::vector<MinimumPair> MinimumSet;
+ NearestNeighborClass() {}
+ inline Answer_t
+ operator()(const Center &inputCentering, const Center &outputCentering)
+ {
+ if (__builtin_expect(!!(inputCentering.size() > 0), true)) {} else Pooma::toss_cookies("The input centering must be non-empty.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/NearestNeighbors.h", 95);
+ Answer_t answer;
+ answer.resize(outputCentering.size());
+ const Positions inputPositions = inputCentering.positions();
+ const Positions outputPositions = outputCentering.positions();
+ for (typename Answer_t::size_type outputIndex = 0;
+ outputIndex < outputCentering.size();
+ ++outputIndex)
+ answer[outputIndex] = nearestNeighbors(inputPositions,
+ outputPositions[outputIndex]);
+ return answer;
+ }
+ inline FieldOffsetList_t
+ operator()(const Center &inputCentering,
+ const FieldOffset_t &fieldOffset,
+ const Center &outputCentering)
+ {
+ if (__builtin_expect(!!(inputCentering.size() > 0), true)) {} else Pooma::toss_cookies("The input centering must be non-empty.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/NearestNeighbors.h", 122);
+ if (__builtin_expect(!!(fieldOffset.subFieldNumber() < outputCentering.size()), true)) {} else Pooma::toss_cookies("The field offset must correspond to the output centering.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/NearestNeighbors.h", 124);
+ return nearestNeighbors(inputCentering.positions(),
+ outputCentering.position(fieldOffset.subFieldNumber()));
+ }
+ inline std::vector<FieldOffsetList_t>
+ operator()(const Center &inputCentering,
+ const FieldOffsetList_t &fieldOffsetList,
+ const Center &outputCentering)
+ {
+ if (__builtin_expect(!!(inputCentering.size() > 0), true)) {} else Pooma::toss_cookies("The input centering must be non-empty.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/NearestNeighbors.h", 140);
+ Answer_t answer;
+ answer.resize(fieldOffsetList.size());
+ const Positions inputPositions = inputCentering.positions();
+ for (typename FieldOffsetList_t::size_type folIndex = 0;
+ folIndex < outputCentering.size();
+ ++folIndex) {
+ if (__builtin_expect(!!(fieldOffsetList[folIndex].subFieldNumber() < outputCentering.size()), true)) {} else Pooma::toss_cookies("The field offset must correspond to the output centering.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/NearestNeighbors.h", 152);
+ answer[folIndex] =
+ nearestNeighbors(inputPositions,
+ outputCentering.position(fieldOffsetList[folIndex].subFieldNumber()));
+ }
+ return answer;
+ }
+ private:
+ inline FieldOffsetList_t
+ nearestNeighbors(const Positions &inputPositions,
+ const Position outputValue)
+ {
+ MinimumSet minimumSet;
+ typename Positions::size_type inputIndex = 0;
+ Position positionDifference = inputPositions[inputIndex] - outputValue;
+ double minimumDistance =
+ (IntraCellOnly ?
+ manhattanDistance<Manhattan>(positionDifference) :
+ manhattanDistance<ManhattanGrid>(positionDifference));
+ minimumSet.push_back(std::make_pair(inputIndex, positionDifference));
+ for (++inputIndex;
+ inputIndex < inputPositions.size();
+ ++inputIndex) {
+ positionDifference = inputPositions[inputIndex] - outputValue;
+ const double distance =
+ (IntraCellOnly ?
+ manhattanDistance<Manhattan>(positionDifference) :
+ manhattanDistance<ManhattanGrid>(positionDifference));
+ if (distance < minimumDistance + epsilon) {
+ if (distance < minimumDistance) {
+ minimumSet.clear();
+ minimumDistance = distance;
+ }
+ minimumSet.push_back(std::make_pair(inputIndex,
+ positionDifference));
+ }
+ }
+ FieldOffset_vt answerHolder;
+ if (IntraCellOnly) {
+ for (typename MinimumSet::size_type minIndex = 0;
+ minIndex < minimumSet.size();
+ ++minIndex)
+ answerHolder.push_back(FieldOffset_t(Loc<Dim>(0),
+ minimumSet[minIndex].first));
+ }
+ else {
+ FieldOffset_vt partialAnswer;
+ for (typename MinimumSet::size_type minIndex = 0;
+ minIndex < minimumSet.size();
+ ++minIndex)
+ {
+ partialAnswer = computeCellOffsets(minimumSet[minIndex].first,
+ minimumSet[minIndex].second);
+ answerHolder.insert(answerHolder.end(),
+ partialAnswer.begin(), partialAnswer.end());
+ }
+ std::sort(answerHolder.begin(), answerHolder.end(),
+ CompareFieldOffset());
+ answerHolder.erase(std::unique(answerHolder.begin(),
+ answerHolder.end(),
+ EqualFieldOffset()),
+ answerHolder.end());
+ }
+ return answerHolder;
+ }
+ struct ManhattanGrid : public std::binary_function<double, double, double>
+ {
+ double operator()(const double totalSoFar, double coordinate) const {
+ const double absCoordinate = std::abs(coordinate);
+ return totalSoFar + std::min(absCoordinate, 1-absCoordinate);
+ }
+ };
+ struct Manhattan : public std::binary_function<double, double, double>
+ {
+ double operator()(const double totalSoFar, double coordinate) const {
+ return totalSoFar + std::abs(coordinate);
+ }
+ };
+ template <class Distance>
+ inline static
+ double manhattanDistance(const Position &difference)
+ {
+ double answer = 0.0;;
+ for (int coordinate = Dim-1; coordinate >= 0; --coordinate)
+ answer = Distance()(answer, difference(coordinate));
+ return answer;
+ }
+ inline static const FieldOffset_vt
+ computeCellOffsets(const int inputValueIndex, const Position &difference)
+ {
+ FieldOffset_vt answer(1);
+ int numTuples = 1;
+ int cellOffsetCoordinates[2];
+ int numOffsets;
+ for (int dimension = 0; dimension < Dim; ++dimension) {
+ numOffsets =
+ convertDifferenceToCellOffsets(difference(dimension),
+ cellOffsetCoordinates);
+ if (__builtin_expect(!!(numOffsets >= 1 && numOffsets <= 2), true)) {} else Pooma::toss_cookies("Incorrect number of cell offsets", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/NearestNeighbors.h", 309);
+ if (numOffsets == 2)
+ answer.insert(answer.end(), answer.begin(), answer.end());
+ for (int coc = 0; coc < numOffsets; ++coc)
+ for (int tuple = 0; tuple < numTuples; ++tuple)
+ answer[numTuples * coc + tuple].modifyCellOffset()[dimension] =
+ cellOffsetCoordinates[coc];
+ numTuples *= numOffsets;
+ }
+ for (int i = numTuples-1; i >= 0; --i)
+ answer[i].setSubFieldNumber(inputValueIndex);
+ return answer;
+ }
+ inline static
+ int convertDifferenceToCellOffsets(const double difference,
+ int cellOffsetCoordinate[])
+ {
+ if (difference < -0.5 - epsilon) {
+ cellOffsetCoordinate[0] = +1;
+ return 1;
+ }
+ else if (std::abs(difference + 0.5) < epsilon) {
+ cellOffsetCoordinate[0] = +1;
+ cellOffsetCoordinate[1] = 0;
+ return 2;
+ }
+ else if (difference <= 0.5 - epsilon) {
+ cellOffsetCoordinate[0] = 0;
+ return 1;
+ }
+ else if (std::abs(difference - 0.5) < epsilon) {
+ cellOffsetCoordinate[0] = 0;
+ cellOffsetCoordinate[1] = -1;
+ return 2;
+ }
+ else if (difference < 1.0 + epsilon) {
+ cellOffsetCoordinate[0] = -1;
+ return 1;
+ }
+ else {
+ if (__builtin_expect(!!(0), true)) {} else Pooma::toss_cookies("Out of range difference", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/NearestNeighbors.h", 361);
+ return 0;
+ }
+ }
+ struct CompareFieldOffset :
+ public std::binary_function<FieldOffset_t, FieldOffset_t, bool> {
+ bool operator()(const FieldOffset_t &op1, const FieldOffset_t &op2) {
+ return (op1.cellOffset() < op2.cellOffset()) ||
+ (op1.cellOffset() == op2.cellOffset() &&
+ op1.subFieldNumber() < op2.subFieldNumber());
+ }
+ };
+ struct EqualFieldOffset :
+ public std::binary_function<FieldOffset_t, FieldOffset_t, bool> {
+ bool operator()(const FieldOffset_t &op1, const FieldOffset_t &op2) {
+ return op1.cellOffset() == op2.cellOffset() &&
+ op1.subFieldNumber() == op2.subFieldNumber();
+ }
+ };
+ static const double epsilon;
+ };
+ template <int Dim, bool IntraCellOnly>
+ const double
+ NearestNeighborClass<Dim, IntraCellOnly>::epsilon = 1.0e-08;
+ template <int Dim>
+ inline
+ std::vector<FieldOffsetList<Dim> >
+ nearestNeighbors(const Centering<Dim> &inputCentering,
+ const Centering<Dim> &outputCentering)
+ {
+ return NearestNeighborClass<Dim>()(inputCentering, outputCentering);
+ }
+ template <int Dim>
+ inline
+ std::vector<FieldOffsetList<Dim> >
+ nearestNeighbors(const Centering<Dim> &inputCentering,
+ const Centering<Dim> &outputCentering,
+ const bool)
+ {
+ return NearestNeighborClass<Dim, true>()(inputCentering, outputCentering);
+ }
+ template <int Dim>
+ inline
+ std::vector<FieldOffsetList<Dim> >
+ nearestNeighbors(const Centering<Dim> &inputCentering,
+ const FieldOffsetList<Dim> &fOL,
+ const Centering<Dim> &outputCentering)
+ {
+ return NearestNeighborClass<Dim>()(inputCentering, fOL, outputCentering);
+ }
+ template <int Dim>
+ inline
+ std::vector<FieldOffsetList<Dim> >
+ nearestNeighbors(const Centering<Dim> &inputCentering,
+ const FieldOffsetList<Dim> &fOL,
+ const Centering<Dim> &outputCentering,
+ const bool)
+ {
+ return NearestNeighborClass<Dim, true>()
+ (inputCentering, fOL, outputCentering);
+ }
+ template <int Dim>
+ inline
+ FieldOffsetList<Dim>
+ nearestNeighbors(const Centering<Dim> &inputCentering,
+ const FieldOffset<Dim> &fieldOffset,
+ const Centering<Dim> &outputCentering)
+ {
+ return NearestNeighborClass<Dim>()
+ (inputCentering, fieldOffset, outputCentering);
+ }
+ template <int Dim>
+ inline
+ FieldOffsetList<Dim>
+ nearestNeighbors(const Centering<Dim> &inputCentering,
+ const FieldOffset<Dim> &fieldOffset,
+ const Centering<Dim> &outputCentering,
+ const bool)
+ {
+ return NearestNeighborClass<Dim, true>()
+ (inputCentering, fieldOffset, outputCentering);
+ }
+ template<int Dim>
+ inline Vector<Dim, double>
+ inputPosition(const Centering<Dim> &inputCentering,
+ const FieldOffset<Dim> &fieldOffset)
+ {
+ Vector<Dim, double> ret =
+ inputCentering.position(fieldOffset.subFieldNumber());
+ for (int i = 0; i < Dim; ++i)
+ ret(i) += fieldOffset.cellOffset()[i].first();
+ return ret;
+ }
+ class PrintField;
+ template<int Dim>
+ struct PerformPrintField
+ {
+ template <class S, class A>
+ static void print(const PrintField &, S &, const A &);
+ };
+ template<>
+ struct PerformPrintField<1>
+ {
+ template<class S, class A>
+ static void print(const PrintField &, S &, const A &);
+ };
+ class PrintField
+ {
+ public:
+ PrintField(int domainWidth = 3, int dataWidth = 10,
+ int dataPrecision = 4, int carReturn = -1,
+ bool scientific = false, int spacing = 1)
+ : domainwidth_m(domainWidth), datawidth_m(dataWidth),
+ dataprecision_m(dataPrecision), carreturn_m(carReturn),
+ spacing_m(spacing), scientific_m(scientific)
+ {
+ ;
+ ;
+ ;
+ ;
+ }
+ PrintField(const PrintField &a)
+ : domainwidth_m(a.domainwidth_m), datawidth_m(a.datawidth_m),
+ dataprecision_m(a.dataprecision_m), carreturn_m(a.carreturn_m),
+ scientific_m(a.scientific_m)
+ {
+ }
+ ~PrintField()
+ {
+ }
+ template<class S, class A>
+ void print(S &s, const A &a) const
+ {
+ forEach(a, PerformUpdateTag(), NullCombine());
+ Pooma::blockAndEvaluate();
+ for (int m = 0; m < a.numMaterials(); m++)
+ for (int c = 0; c < a.centeringSize(); c++)
+ {
+ s << "Material #" << m << ", Centering #" << c << " " << a.centering(c)
+ << "\n"<< "-------------\n";
+ PerformPrintField<A::dimensions>::print(*this, s, a.subField(m, c));
+ }
+ }
+ int domainWidth() const
+ {
+ return domainwidth_m;
+ }
+ void setDomainWidth(int val)
+ {
+ domainwidth_m = val;
+ ;
+ }
+ int dataWidth() const
+ {
+ return datawidth_m;
+ }
+ void setDataWidth(int val)
+ {
+ datawidth_m = val;
+ ;
+ }
+ int dataPrecision() const
+ {
+ return dataprecision_m;
+ }
+ void setDataPrecision(int val)
+ {
+ dataprecision_m = val;
+ ;
+ }
+ int carReturn() const
+ {
+ return carreturn_m;
+ }
+ void setCarReturn(int val)
+ {
+ carreturn_m = val;
+ }
+ bool scientific() const
+ {
+ return scientific_m;
+ }
+ void setScientific(bool val)
+ {
+ scientific_m = val;
+ }
+ int spacing() const
+ {
+ return spacing_m;
+ }
+ void setSpacing(int val)
+ {
+ spacing_m = val;
+ ;
+ }
+ private:
+ int domainwidth_m;
+ int datawidth_m;
+ int dataprecision_m;
+ int carreturn_m;
+ int spacing_m;
+ bool scientific_m;
+ };
+ template<class S, class A>
+ void
+ PerformPrintField<1>::print(const PrintField &p, S &s, const A &a)
+ {
+ PoomaCTAssert<(A::dimensions == 1)>::test();
+ typedef typename A::Domain_t Domain_t;
+ typedef typename Domain_t::const_iterator Iterator_t;
+ Iterator_t griditer = a.domain().begin();
+ Iterator_t enditer = a.domain().end();
+ s << "[";
+ if (a.domain()[0].first() < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << a.domain()[0].first() << ":";
+ if (a.domain()[0].last() < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << a.domain()[0].last() << "] = ";
+ s.fill(' ');
+ int i, printed = 0;
+ while (griditer != enditer)
+ {
+ int spacing = 0;
+ if (printed > 0)
+ {
+ spacing = p.spacing();
+ if (p.carReturn() >= 0 && printed >= p.carReturn())
+ {
+ s << "\n";
+ spacing = 2*p.domainWidth() + 6;
+ printed = 0;
+ }
+ }
+ for (i=0; i < spacing; ++i)
+ s << " ";
+ if (p.scientific())
+ s.setf(std::ios::scientific);
+ s.precision(p.dataPrecision());
+ s.width(p.dataWidth());
+ s << a.read(*griditer);
+ ++griditer;
+ ++printed;
+ }
+ s << "\n";
+ }
+ template<int Dim>
+ template<class S, class A>
+ void
+ PerformPrintField<Dim>::print(const PrintField &p, S &s, const A &a)
+ {
+ int i, j, k;
+ PoomaCTAssert<(A::dimensions == Dim && Dim > 1)>::test();
+ typedef typename A::Domain_t Domain_t;
+ typedef typename Domain_t::Element_t Element_t;
+ typedef typename Domain_t::const_iterator Iterator_t;
+ Iterator_t griditer = a.domain().begin();
+ Iterator_t enditer = a.domain().end();
+ Element_t x0 = a.domain()[0].first();
+ Element_t x1 = a.domain()[0].last();
+ Element_t xs = a.domain()[0].stride();
+ Element_t y0 = a.domain()[1].first();
+ Element_t y1 = a.domain()[1].last();
+ Element_t ys = a.domain()[1].stride();
+ while (griditer != enditer)
+ {
+ if (Dim > 2)
+ {
+ s << '\n' << a.domain()[0] << a.domain()[1];
+ for (i=2; i < Dim; ++i)
+ s << "[" << (*griditer)[i].first() << "]";
+ s << ":" << '\n';
+ s << "----------------------------------------------------\n";
+ }
+ for (j=y0; j <= y1; j += ys)
+ {
+ s << "[";
+ if (x0 < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << x0 << ":";
+ if (x1 < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << x1 << "]";
+ for (i=1; i < Dim; ++i)
+ {
+ s << "[";
+ if ((*griditer)[i].first() < 0)
+ s.fill(' ');
+ else
+ s.fill('0');
+ s.width(p.domainWidth());
+ s << (*griditer)[i].first() << "]";
+ }
+ s.fill(' ');
+ s << " = ";
+ int printed = 0;
+ for (i=x0; i <= x1; i += xs)
+ {
+ int spacing = 0;
+ if (printed > 0)
+ {
+ spacing = p.spacing();
+ if (p.carReturn() >= 0 && printed >= p.carReturn())
+ {
+ s << '\n';
+ spacing = (Dim + 1)*(p.domainWidth() + 2) + 4;
+ printed = 0;
+ }
+ }
+ for (k=0; k < spacing; ++k)
+ s << ' ';
+ if (p.scientific())
+ s.setf(std::ios::scientific);
+ s.precision(p.dataPrecision());
+ s.width(p.dataWidth());
+ s << a.read(*griditer);
+ ++griditer;
+ ++printed;
+ }
+ s << '\n';
+ }
+ }
+ }
+ template<int Dim>
+ struct FieldEnginePatch
+ {
+ FieldEnginePatch(int patch, Interval<Dim> domain)
+ : patch_m(patch), domain_m(domain)
+ { }
+ int patch_m;
+ Interval<Dim> domain_m;
+ };
+ namespace Pooma {
+ unsigned int activeRelationGroups();
+ bool isRelationGroupActive(unsigned int groups);
+ void activateRelationGroup(unsigned int group);
+ void deactivateRelationGroup(unsigned int group);
+ unsigned int newRelationGroup();
+ }
+ class RelationListItem {
+ public:
+ RelationListItem()
+ : priority_m(0),
+ groups_m(Pooma::activeRelationGroups()),
+ dirty_m(true)
+ { }
+ RelationListItem(const RelationListItem &model)
+ : priority_m(model.priority_m),
+ groups_m(model.groups_m),
+ dirty_m(model.dirty_m)
+ { }
+ virtual ~RelationListItem() { }
+ virtual void apply() = 0;
+ virtual void notifyPreRead()
+ {
+ if (Pooma::isRelationGroupActive(groups_m) && dirty_m)
+ {
+ apply();
+ clearDirty();
+ }
+ }
+ virtual void notifyPostWrite()
+ {
+ setDirty();
+ }
+ inline bool dirty() const { return dirty_m; }
+ inline unsigned int priority() const { return priority_m; }
+ virtual void setDirty()
+ {
+ dirty_m = true;
+ }
+ virtual void clearDirty()
+ {
+ dirty_m = false;
+ }
+ inline void setPriority(unsigned int p)
+ {
+ priority_m = p;
+ }
+ private:
+ unsigned int priority_m;
+ unsigned int groups_m;
+ bool dirty_m;
+ };
+ namespace Pooma {
+ struct DontCopyRelations { };
+ }
+ template<class Target>
+ class RelationRetargetBase : public RelationListItem {
+ public:
+ RelationRetargetBase(const Target &target)
+ : target_m(target, Pooma::DontCopyRelations())
+ { }
+ RelationRetargetBase(const RelationRetargetBase<Target> &model)
+ : RelationListItem(model),
+ target_m(model.target_m)
+ { }
+ virtual ~RelationRetargetBase() { }
+ Target &target() { return target_m; }
+ const Target &target() const { return target_m; }
+ virtual RelationListItem *retarget(const Target &target) const = 0;
+ protected:
+ Target target_m;
+ };
+ template<class Target, class Functor>
+ class RelationBase : public RelationRetargetBase<Target> {
+ public:
+ RelationBase(const Target &t, const Functor &f)
+ : RelationRetargetBase<Target>(t),
+ functor_m(f, t)
+ { }
+ RelationBase(const RelationBase<Target, Functor> &model)
+ : RelationRetargetBase<Target>(model),
+ functor_m(model.functor_m)
+ { }
+ virtual ~RelationBase() { }
+ Functor &functor() { return functor_m; }
+ const Functor &functor() const { return functor_m; }
+ protected:
+ Functor functor_m;
+ };
+ class RelationListData : public RefCounted
+ {
+ public:
+ RelationListData()
+ { }
+ RelationListData(const RelationListData &model)
+ : data_m(model.data_m)
+ { }
+ RelationListData &operator=(const RelationListData &rhs)
+ {
+ data_m = rhs.data_m;
+ return *this;
+ }
+ ~RelationListData()
+ {
+ typedef List_t::size_type size_type;
+ for (size_type i = 0; i < data_m.size(); i++)
+ delete data_m[i];
+ }
+ inline int size() const
+ {
+ return data_m.size();
+ }
+ inline RelationListItem *elem(int i) const
+ {
+ return data_m[i];
+ }
+ inline RelationListItem* &elem(int i)
+ {
+ return data_m[i];
+ }
+ void add(RelationListItem *item)
+ {
+ data_m.push_back(item);
+ int i = size() - 1;
+ while (i > 0)
+ {
+ if (data_m[i]->priority() <= data_m[i]->priority())
+ break;
+ data_m[i] = data_m[i - 1];
+ data_m[i - 1] = item;
+ --i;
+ }
+ }
+ private:
+ typedef std::vector<RelationListItem *> List_t;
+ List_t data_m;
+ };
+ class RelationList {
+ public:
+ RelationList()
+ : list_m(new RelationListData)
+ { }
+ RelationList(const RelationList &model)
+ : list_m(model.list_m)
+ { }
+ ~RelationList() { }
+ template<class Target>
+ void makeOwnCopy(const Target &t)
+ {
+ list_m = new RelationListData(*list_m);
+ for (int i = 0; i < list_m->size(); i++)
+ {
+ RelationRetargetBase<Target> *u =
+ dynamic_cast<RelationRetargetBase<Target> *>(list_m->elem(i));
+ if (u != NULL)
+ list_m->elem(i) = u->retarget(t);
+ }
+ }
+ inline void erase()
+ {
+ list_m = new RelationListData;
+ }
+ void addRelation(RelationListItem *item)
+ {
+ list_m->add(item);
+ }
+ void notifyPreRead() const
+ {
+ for (int i = 0; i < list_m->size(); ++i)
+ list_m->elem(i)->notifyPreRead();
+ }
+ void notifyPostWrite() const
+ {
+ for (int i = 0; i < list_m->size(); ++i)
+ list_m->elem(i)->notifyPostWrite();
+ }
+ void setDirty() const
+ {
+ for (int i = 0; i < list_m->size(); ++i)
+ list_m->elem(i)->setDirty();
+ }
+ void clearDirty() const
+ {
+ for (int i = 0; i < list_m->size(); ++i)
+ list_m->elem(i)->clearDirty();
+ }
+ bool dirty() const
+ {
+ for (int i = 0; i < list_m->size(); ++i)
+ if (list_m->elem(i)->dirty())
+ return true;
+ return false;
+ }
+ inline RelationListItem *operator()(int i) const
+ {
+ return list_m->elem(i);
+ }
+ inline RelationListItem *operator()(int i)
+ {
+ return list_m->elem(i);
+ }
+ inline int size() const { return list_m->size(); }
+ private:
+ RefCountedPtr<RelationListData> list_m;
+ };
+ template<int Dim, class T, class EngineTag> class Engine;
+ template<class Components> class ComponentWrapper;
+ namespace Pooma {
+ struct MaterialViewTag {};
+ struct CenteringViewTag {};
+ }
+ template <int Dim, class T, class EngineTag>
+ class FieldEngineBaseData
+ {
+ public:
+ FieldEngineBaseData()
+ : engine_m()
+ { }
+ template<class Initializer>
+ FieldEngineBaseData(const Initializer &init)
+ : engine_m(init)
+ { }
+ FieldEngineBaseData(const Pooma::NoInit &)
+ : engine_m()
+ { }
+ template<class Initializer>
+ FieldEngineBaseData(const Initializer &init, const RelationList &l)
+ : engine_m(init),
+ relations_m(l)
+ { }
+ template<class Engine, class Domain>
+ FieldEngineBaseData(const Engine &e,
+ const Domain &d, const RelationList &l)
+ : engine_m(NewEngineEngine<Engine, Domain>::apply(e, d),
+ NewEngineDomain<Engine, Domain>::apply(e, d)),
+ relations_m(l)
+ {
+ }
+ const Engine<Dim, T, EngineTag> &engine() const { return engine_m; }
+ Engine<Dim, T, EngineTag> &engine() { return engine_m; }
+ RelationList &relations() const { return relations_m; }
+ private:
+ Engine<Dim, T, EngineTag> engine_m;
+ mutable RelationList relations_m;
+ };
+ template<class Mesh, class T, class EngineTag>
+ class FieldEngine
+ {
+ public:
+ enum { dimensions = Mesh::dimensions };
+ enum { Dim = dimensions };
+ typedef FieldEngine<Mesh, T, EngineTag> This_t;
+ typedef FieldEngineBaseData<Dim, T, EngineTag> Data_t;
+ typedef Engine<Dim, T, EngineTag> Engine_t;
+ typedef typename Engine_t::Domain_t Domain_t;
+ typedef typename Engine_t::Layout_t Layout_t;
+ typedef typename Engine_t::Element_t Element_t;
+ typedef typename Engine_t::ElementRef_t ElementRef_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ FieldEngine()
+ : num_materials_m(0),
+ physicalCellDomain_m(Pooma::NoInit()),
+ guards_m(0)
+ { }
+ template<class Layout2>
+ FieldEngine(const Centering<Dim> ¢ering, const Layout2 &layout,
+ const Mesh &mesh, int materials = 1)
+ : num_materials_m(materials),
+ centering_m(centering),
+ stride_m(centering.size()),
+ physicalCellDomain_m(layout.domain()),
+ guards_m(layout.externalGuards()),
+ mesh_m(mesh)
+ {
+ physicalCellDomain_m = shrinkRight(shrink(physicalCellDomain_m, guards_m), 1);
+ addSubFields();
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ for (int c = 0; c < centering.size(); ++ c)
+ {
+ data(m, c) = Data_t(layout);
+ }
+ }
+ }
+ FieldEngine(const This_t &model)
+ : num_materials_m(model.num_materials_m),
+ centering_m(model.centering_m),
+ stride_m(model.stride_m),
+ data_m(model.data_m),
+ physicalCellDomain_m(model.physicalCellDomain_m),
+ guards_m(model.guards_m),
+ mesh_m(model.mesh_m)
+ {
+ }
+ FieldEngine(const This_t &model, int subField)
+ : num_materials_m(1),
+ centering_m(model.centering_m, subField % model.centeringSize()),
+ stride_m(model.stride_m),
+ data_m(model.data_m + subField),
+ physicalCellDomain_m(model.physicalCellDomain_m),
+ guards_m(model.guards_m),
+ mesh_m(model.mesh_m)
+ {
+ }
+ FieldEngine(const This_t &model, int m, int c)
+ : num_materials_m(1),
+ centering_m(model.centering_m, c),
+ stride_m(model.stride_m),
+ data_m(model.data_m + model.stride_m * m + c),
+ physicalCellDomain_m(model.physicalCellDomain_m),
+ guards_m(model.guards_m),
+ mesh_m(model.mesh_m)
+ {
+ }
+ FieldEngine(const This_t &model, int c, const Pooma::CenteringViewTag&)
+ : num_materials_m(model.num_materials_m),
+ centering_m(model.centering_m, c),
+ stride_m(model.stride_m),
+ data_m(model.data_m + c),
+ physicalCellDomain_m(model.physicalCellDomain_m),
+ guards_m(model.guards_m),
+ mesh_m(model.mesh_m)
+ {
+ }
+ FieldEngine(const This_t &model, int m, const Pooma::MaterialViewTag&)
+ : num_materials_m(1),
+ centering_m(model.centering_m),
+ stride_m(model.stride_m),
+ data_m(model.data_m + m * model.stride_m),
+ physicalCellDomain_m(model.physicalCellDomain_m),
+ guards_m(model.guards_m),
+ mesh_m(model.mesh_m)
+ {
+ }
+ template<class T2, class EngineTag2>
+ FieldEngine(const FieldEngine<Mesh, T2, EngineTag2> &model,
+ const Domain_t &d)
+ : num_materials_m(model.numMaterials()),
+ centering_m(model.centering()),
+ stride_m(model.centeringSize()),
+ guards_m(0),
+ mesh_m(model.mesh(), inputDomainToVertexDomain(d))
+ {
+ addSubFields();
+ physicalCellDomain_m = d;
+ if (centeringSize() == 1)
+ {
+ physicalCellDomain_m =
+ centeringDomainToCellDomain(physicalCellDomain_m, centering_m, 0);
+ }
+ for (int c = 0; c < centeringSize(); ++c)
+ {
+ Domain_t dc(cellDomainToCenteringDomain(physicalCellDomain_m, centering_m, c));
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ data(m, c) = Data_t(model.data(m, c).engine(), dc, model.data(m, c).relations());
+ }
+ }
+ physicalCellDomain_m -= d.firsts();
+ }
+ template<class Mesh2, class T2, class EngineTag2, class Domain>
+ FieldEngine(const FieldEngine<Mesh2, T2, EngineTag2> &model,
+ const Domain &d)
+ : num_materials_m(model.numMaterials()),
+ centering_m(model.centering()),
+ stride_m(model.centeringSize()),
+ guards_m(0)
+ {
+ addSubFields();
+ ;
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ data(m, 0) = Data_t(model.data(m, 0).engine(), d,
+ model.data(m, 0).relations());
+ }
+ mesh_m = Mesh(DomainLayout<Dim>(inputDomainToVertexDomain(data(0,0).engine().domain())));
+ physicalCellDomain_m = mesh_m.physicalCellDomain();
+ }
+ template<class Mesh2, class EngineTag2>
+ FieldEngine(const FieldEngine<Mesh2, T, EngineTag2> &model,
+ const SliceInterval<Mesh2::dimensions, Dim> &d)
+ {
+ initSlice(model, d);
+ }
+ template<class Mesh2, class EngineTag2>
+ FieldEngine(const FieldEngine<Mesh2, T, EngineTag2> &model,
+ const SliceRange<Mesh2::dimensions, Dim> &d)
+ {
+ initSlice(model, d);
+ }
+ template<class Mesh2, class EngineTag2>
+ FieldEngine(const FieldEngine<Mesh2, T, EngineTag2> &model,
+ const SliceInterval<Dim, Mesh2::dimensions> &d,
+ const Interval<Dim>& totalDomain)
+ {
+ initSlice(model, d, totalDomain);
+ }
+ template<class T2, class EngineTag2>
+ FieldEngine(const FieldEngine<Mesh, T2, EngineTag2> &model,
+ const INode<Dim> &i)
+ : num_materials_m(model.numMaterials()),
+ centering_m(model.centering()),
+ stride_m(model.centeringSize()),
+ guards_m(0),
+ mesh_m(model.mesh(),
+ inputDomainToVertexDomain(i.domain()))
+ {
+ addSubFields();
+ physicalCellDomain_m = i.domain();
+ if (centeringSize() == 1)
+ {
+ physicalCellDomain_m =
+ centeringDomainToCellDomain(physicalCellDomain_m, centering_m, 0);
+ }
+ for (int c = 0; c < centeringSize(); ++ c)
+ {
+ INode<Dim> ic(i, cellDomainToCenteringDomain(physicalCellDomain_m, centering_m, c));
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ data(m, c) = Data_t(model.data(m, c).engine(), ic, model.data(m, c).relations());
+ }
+ }
+ physicalCellDomain_m -= i.domain().firsts();
+ }
+ template<class Mesh2, class T2, class EngineTag2, class Tag>
+ FieldEngine(const FieldEngine<Mesh2, T2, EngineTag2> &model,
+ const EngineView<Tag> &ev)
+ : num_materials_m(model.numMaterials()),
+ centering_m(model.centering()),
+ stride_m(model.centeringSize()),
+ physicalCellDomain_m(model.physicalCellDomain()),
+ guards_m(model.guardLayers()),
+ mesh_m(model.mesh())
+ {
+ typedef typename FieldEngine<Mesh2, T2, EngineTag2>::Engine_t EngIn_t;
+ typedef LeafFunctor<EngIn_t, EngineView<Tag> > Functor_t;
+ addSubFields();
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ for (int c = 0; c < centeringSize(); ++c)
+ {
+ data(m, c)
+ = Data_t(Functor_t::apply(model.data(m, c).engine(), ev),
+ model.data(m, c).relations());
+ }
+ }
+ }
+ template<class EngineTag2>
+ FieldEngine(const FieldEngine<Mesh, T, EngineTag2> &model,
+ const FieldEnginePatch<Dim> &p)
+ : num_materials_m(model.numMaterials()),
+ centering_m(model.centering()),
+ stride_m(model.centeringSize()),
+ guards_m(model.guardLayers()),
+ mesh_m(model.mesh())
+ {
+ ;
+ addSubFields();
+ data(0, 0) = Data_t(engineFunctor(model.engine(), EnginePatch(p.patch_m)));
+ physicalCellDomain_m =
+ centeringDomainToCellDomain(p.domain_m, centering_m, 0);
+ }
+ template<class Mesh2, class T2, class EngineTag2, class Components>
+ FieldEngine(const FieldEngine<Mesh2, T2, EngineTag2> &model,
+ const ComponentWrapper<Components> &cw)
+ : num_materials_m(model.numMaterials()),
+ centering_m(model.centering()),
+ stride_m(model.centeringSize()),
+ physicalCellDomain_m(model.physicalCellDomain()),
+ guards_m(model.guardLayers()),
+ mesh_m(model.mesh())
+ {
+ addSubFields();
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ for (int c = 0; c < centeringSize(); ++ c)
+ {
+ data(m, c) =
+ Data_t(Engine_t(model.data(m, c).engine(), cw.components()),
+ model.data(m, c).relations());
+ }
+ }
+ }
+ FieldEngine(const This_t &model,
+ const Pooma::DontCopyRelations &d)
+ : num_materials_m(model.numMaterials()),
+ centering_m(model.centering()),
+ stride_m(model.centeringSize()),
+ physicalCellDomain_m(model.physicalCellDomain_m),
+ guards_m(model.guardLayers()),
+ mesh_m(model.mesh())
+ {
+ addSubFields();
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ for (int c = 0; c < centeringSize(); ++ c)
+ {
+ data(m, c) = Data_t(model.data(m, c).engine());
+ }
+ }
+ }
+ void initialize(const This_t &model)
+ {
+ num_materials_m = model.num_materials_m;
+ stride_m = model.stride_m;
+ centering_m = model.centering_m;
+ data_m = model.data_m;
+ physicalCellDomain_m = model.physicalCellDomain_m;
+ guards_m = model.guards_m;
+ mesh_m = model.mesh_m;
+ }
+ void addSubFields()
+ {
+ ;
+ int size = numMaterials() * centeringSize();
+ data_m.reserve(size);
+ data_m.resize(size);
+ }
+ int numSubFields() const
+ {
+ return numMaterials() * centeringSize();
+ }
+ Engine_t &engine()
+ {
+ ;
+ return data_m->engine();
+ }
+ const Engine_t &engine() const
+ {
+ ;
+ return data_m->engine();
+ }
+ Engine_t &engine(int m, int c)
+ {
+ ;
+ return data(m,c).engine();
+ }
+ const Engine_t &engine(int m, int c) const
+ {
+ ;
+ return data(m,c).engine();
+ }
+ RelationList &relations() const
+ {
+ ;
+ return data_m->relations();
+ }
+ RelationList &relations(int m, int c) const
+ {
+ ;
+ return data(m, c).relations();
+ }
+ const GuardLayers_t &guardLayers() const
+ {
+ return guards_m;
+ }
+ GuardLayers_t &guardLayers()
+ {
+ return guards_m;
+ }
+ int numMaterials() const
+ {
+ return num_materials_m;
+ }
+ Domain_t &physicalCellDomain()
+ {
+ return physicalCellDomain_m;
+ }
+ const Domain_t &physicalCellDomain() const
+ {
+ return physicalCellDomain_m;
+ }
+ Domain_t totalCellDomain() const
+ {
+ return grow(physicalCellDomain_m, guards_m);
+ }
+ Domain_t physicalDomain() const
+ {
+ if (centeringSize() == 1)
+ return cellDomainToCenteringDomain(physicalCellDomain_m, centering_m, 0);
+ else
+ return physicalCellDomain_m;
+ }
+ Domain_t physicalDomain(int i) const
+ {
+ return cellDomainToCenteringDomain(physicalCellDomain_m, centering_m, i);
+ }
+ Domain_t totalDomain() const
+ {
+ if (centeringSize() == 1)
+ return cellDomainToCenteringDomain(totalCellDomain(), centering_m, 0);
+ else
+ return totalCellDomain();
+ }
+ Domain_t totalDomain(int i) const
+ {
+ return cellDomainToCenteringDomain(totalCellDomain(), centering_m, i);
+ }
+ const Centering<Dim> ¢ering() const
+ {
+ return centering_m;
+ }
+ int centeringSize() const
+ {
+ return centering_m.size();
+ }
+ Mesh &mesh()
+ {
+ return mesh_m;
+ }
+ const Mesh &mesh() const
+ {
+ return mesh_m;
+ }
+ template<class Subject>
+ void makeOwnCopy(const Subject &s)
+ {
+ ;
+ RefCountedBlockPtr<Data_t> model = data_m;
+ data_m = RefCountedBlockPtr<Data_t>();
+ stride_m = centeringSize();
+ addSubFields();
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ for (int c = 0; c < centeringSize(); ++ c)
+ {
+ data(m, c) = model[m*stride_m + c];
+ data(m, c).engine().makeOwnCopy();
+ data(m, c).relations().makeOwnCopy(s.subField(m, c));
+ }
+ }
+ }
+ Domain_t
+ inputDomainToVertexDomain(const Domain_t &d) const
+ {
+ if (centeringSize() == 1)
+ return growRight(centeringDomainToCellDomain(d, centering(), 0), 1);
+ else
+ return growRight(d, 1);
+ }
+ inline Data_t &
+ data(int material, int centering)
+ {
+ ;
+ return data_m[material * stride_m + centering];
+ }
+ inline const Data_t &
+ data(int material, int centering) const
+ {
+ ;
+ return data_m[material * stride_m + centering];
+ }
+ private:
+ template <class FE, class Domain>
+ void initSlice(const FE& model, const Domain& d)
+ {
+ ;
+ num_materials_m = model.numMaterials();
+ stride_m = 1;
+ typename Centering<Dim>::Orientation orientation;
+ typename Centering<Dim>::Position position;
+ int j=0;
+ for (int i=0; i<FE::dimensions; ++i)
+ {
+ if (d.ignorable(i))
+ continue;
+ orientation[j] = model.centering().orientation(0)[i];
+ position(j) = model.centering().position(0)(i);
+ guards_m.lower(j) = model.guardLayers().lower(i);
+ guards_m.upper(j) = model.guardLayers().upper(i);
+ physicalCellDomain_m[j] = model.physicalCellDomain()[i];
+ ++j;
+ }
+ centering_m.addValue(orientation, position);
+ addSubFields();
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ data(m, 0) = Data_t(model.data(m, 0).engine(), d,
+ model.data(m, 0).relations());
+ }
+ mesh_m = Mesh(DomainLayout<Dim>(growRight(physicalCellDomain(), 1),
+ guardLayers()));
+ }
+ template <class FE>
+ void initSlice(const FE& model,
+ const SliceInterval<Dim, FE::dimensions>& d,
+ const Interval<Dim>& totalDomain)
+ {
+ ;
+ num_materials_m = model.numMaterials();
+ stride_m = 1;
+ typename Centering<Dim>::Orientation orientation;
+ typename Centering<Dim>::Position position;
+ int j=0;
+ for (int i=0; i<Dim; ++i)
+ {
+ if (d.ignorable(i)) {
+ if (model.centering().centeringType() == CellType) {
+ orientation[i] = 1;
+ position(i) = 0.5;
+ } else {
+ orientation[i] = 0;
+ position(i) = 0.0;
+ }
+ guards_m.lower(i) = 0;
+ guards_m.upper(i) = 0;
+ physicalCellDomain_m[i] = totalDomain[i];
+ } else {
+ orientation[i] = model.centering().orientation(0)[j];
+ position(i) = model.centering().position(0)(j);
+ guards_m.lower(i) = model.guardLayers().lower(j);
+ guards_m.upper(i) = model.guardLayers().upper(j);
+ physicalCellDomain_m[i] = model.physicalCellDomain()[j];
+ ++j;
+ }
+ }
+ centering_m.addValue(orientation, position);
+ addSubFields();
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ typedef typename NewEngine<typename FE::Engine_t, SliceInterval<Dim, FE::dimensions> >::Type_t NewEngine_t;
+ data(m, 0) = Data_t(NewEngine_t(model.data(m, 0).engine(), d, totalDomain),
+ model.data(m, 0).relations());
+ }
+ mesh_m = Mesh(DomainLayout<Dim>(growRight(physicalCellDomain(), 1),
+ guardLayers()));
+ }
+ unsigned int num_materials_m;
+ Centering<Dim> centering_m;
+ int stride_m;
+ RefCountedBlockPtr<Data_t> data_m;
+ Domain_t physicalCellDomain_m;
+ GuardLayers_t guards_m;
+ Mesh mesh_m;
+ };
+ template<class Mesh, class T, class EngineTag, class Tag>
+ struct LeafFunctor<FieldEngine<Mesh, T, EngineTag>,
+ ExpressionApply<Tag> >
+ {
+ typedef FieldEngine<Mesh, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Engine_t Engine_t;
+ typedef LeafFunctor<Engine_t, ExpressionApply<Tag> > LeafFunctor_t;
+ typedef int Type_t;
+ inline static
+ Type_t apply(const Subject_t &fieldEngineBase,
+ const ExpressionApply<Tag> &tag)
+ {
+ for (int m = 0; m < fieldEngineBase.numMaterials(); ++m)
+ {
+ for (int c = 0; c < fieldEngineBase.centeringSize(); ++ c)
+ {
+ LeafFunctor_t::apply(fieldEngineBase.data(m, c).engine(), tag);
+ }
+ }
+ return 0;
+ }
+ };
+ struct CompressibleBrick;
+ template<class Mesh, class T, class EngineTag>
+ class Field;
+ template<class LTag, class EngineTag>
+ struct MultiPatch;
+ template<int Dim> struct NoMesh;
+ struct Brick;
+ template<class Subject> class SubFieldView;
+ template<class Subject, class Domain, bool SV>
+ struct View1Implementation;
+ template <class Subject, class Domain>
+ struct ReverseSliceView;
+ class RelationListItem;
+ template <int Dim>
+ class FieldOffset;
+ template <int Dim>
+ class FieldOffsetList;
+ template<class Mesh, class T, class EngineTag,
+ class MeshTag2, class T2, class EngineTag2, class Op>
+ const Field<Mesh, T, EngineTag> &
+ assign(const Field<Mesh, T, EngineTag> &lhs,
+ const Field<MeshTag2, T2, EngineTag2> &rhs,
+ const Op &op);
+ template<class Mesh, class T, class EngineTag,
+ int Dim2, class T2, class EngineTag2, class Op>
+ const Field<Mesh, T, EngineTag> &
+ assign(const Field<Mesh, T, EngineTag> &lhs,
+ const Array<Dim2, T2, EngineTag2> &rhs, const Op &op);
+ template<class Mesh, class T, class EngineTag, class T1, class Op>
+ const Field<Mesh, T, EngineTag> &
+ assign(const Field<Mesh, T, EngineTag> &lhs,
+ const T1 &rhs, const Op &op);
+ template<class Mesh, class T, class EngineTag,
+ int Dim2, class T2, class EngineTag2, class Op>
+ const Array<Dim2, T2, EngineTag2> &
+ 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);
+ struct SubFieldViewFunctorTag;
+ template<class Mesh, class T, class EngineTag>
+ class SubFieldView<Field<Mesh, T, EngineTag> > {
+ public:
+ typedef Field<Mesh, T, EngineTag> Type_t;
+ inline static Type_t make(const Type_t &s, int iSubField)
+ {
+ ;
+ return Type_t(s, iSubField);
+ }
+ inline static Type_t make(const Type_t &s, int m, int c)
+ {
+ ;
+ return Type_t(s, m, c);
+ }
+ inline static Type_t make(const Type_t &s, int c, const Pooma::CenteringViewTag &tag)
+ {
+ ;
+ return Type_t(s, c, tag);
+ }
+ inline static Type_t make(const Type_t &s, int m, const Pooma::MaterialViewTag &tag)
+ {
+ ;
+ return Type_t(s, m, tag);
+ }
+ };
+ template<class Mesh, class T, class Expr>
+ class SubFieldView<Field<Mesh, T, ExpressionTag<Expr> > > {
+ public:
+ typedef Field<Mesh, T, ExpressionTag<Expr> > Subject_t;
+ typedef
+ typename ForEach<Expr, SubFieldViewFunctorTag, TreeCombine>::Type_t
+ Expr_t;
+ typedef Field<Mesh, T, ExpressionTag<Expr_t> > Type_t;
+ inline static Type_t make(const Subject_t &s, int iSubField)
+ {
+ ;
+ return Type_t(s, iSubField);
+ }
+ inline static Type_t make(const Subject_t &s, int m, int c)
+ {
+ ;
+ return Type_t(s, m, c);
+ }
+ inline static Type_t make(const Subject_t &s, int c, const Pooma::CenteringViewTag &tag)
+ {
+ ;
+ return Type_t(s, c, tag);
+ }
+ inline static Type_t make(const Subject_t &s, int m, const Pooma::MaterialViewTag &tag)
+ {
+ ;
+ return Type_t(s, m, tag);
+ }
+ };
+ template<class Mesh, class T, class EngineTag, class Domain>
+ struct View1Implementation<Field<Mesh, T, EngineTag>, Domain, true>
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ template<class S1, class Combine>
+ inline static
+ Type_t make(const Subject_t &f, const S1 &s1,
+ const Combine &)
+ {
+ ;
+ Domain s(Combine::make(f, s1));
+ ;
+ return f.engine()(s);
+ }
+ template<class S1, class S2, class Combine>
+ inline static
+ Type_t make(const Subject_t &f,
+ const S1 &s1, const S2 &s2,
+ const Combine &)
+ {
+ ;
+ Domain s(Combine::make(f, s1, s2));
+ ;
+ return f.engine()(s);
+ }
+ template<class S1, class S2, class S3,
+ class Combine>
+ inline static
+ Type_t make(const Subject_t &f,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const Combine &)
+ {
+ ;
+ Domain s(Combine::make(f, s1, s2, s3));
+ ;
+ return f.engine()(s);
+ }
+ template<class S1, class Combine>
+ inline static
+ ReadType_t makeRead(const Subject_t &f, const S1 &s1,
+ const Combine &)
+ {
+ ;
+ Domain s(Combine::make(f, s1));
+ ;
+ return f.engine().read(s);
+ }
+ template<class S1, class S2, class Combine>
+ inline static
+ ReadType_t makeRead(const Subject_t &f,
+ const S1 &s1, const S2 &s2,
+ const Combine &)
+ {
+ ;
+ Domain s(Combine::make(f, s1, s2));
+ ;
+ return f.engine().read(s);
+ }
+ template<class S1, class S2, class S3,
+ class Combine>
+ inline static
+ ReadType_t makeRead(const Subject_t &f,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const Combine &)
+ {
+ ;
+ Domain s(Combine::make(f, s1, s2, s3));
+ ;
+ return f.engine().read(s);
+ }
+ };
+ template<int Dim, class Mesh, class Domain>
+ struct NewMeshTag
+ {
+ typedef NoMesh<Dim> Type_t;
+ };
+ template<int Dim, class Mesh>
+ struct NewMeshTag<Dim, Mesh, Interval<Dim> >
+ {
+ typedef Mesh Type_t;
+ };
+ template<int Dim, class Mesh>
+ struct NewMeshTag<Dim, Mesh, INode<Dim> >
+ {
+ typedef Mesh Type_t;
+ };
+ template<class Mesh, class T, class EngineTag, class Domain>
+ struct View1Implementation<Field<Mesh, T, EngineTag>, Domain, false>
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Engine_t Engine_t;
+ typedef typename NewEngine<Engine_t, Domain>::Type_t NewEngine_t;
+ typedef typename NewEngine_t::Element_t NewT_t;
+ typedef typename NewEngine_t::Tag_t NewEngineTag_t;
+ typedef typename
+ NewMeshTag<NewEngine_t::dimensions, Mesh, Domain>::Type_t
+ NewMeshTag_t;
+ typedef Field<NewMeshTag_t, NewT_t, NewEngineTag_t> ReadType_t;
+ typedef Field<NewMeshTag_t, NewT_t, NewEngineTag_t> Type_t;
+ template<class S1, class Combine>
+ static
+ Type_t make(const Subject_t &f, const S1 &s1,
+ const Combine &)
+ {
+ Domain s(Combine::make(f, s1));
+ ;
+ return Type_t(f, s);
+ }
+ template<class S1, class S2, class Combine>
+ static
+ Type_t make(const Subject_t &f, const S1 &s1,
+ const S2 &s2, const Combine &)
+ {
+ Domain s(Combine::make(f, s1, s2));
+ ;
+ return Type_t(f, s);
+ }
+ template<class S1, class S2, class S3,
+ class Combine>
+ static
+ Type_t make(const Subject_t &f,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const Combine &)
+ {
+ Domain s(Combine::make(f, s1, s2, s3));
+ ;
+ return Type_t(f, s);
+ }
+ template<class S1, class Combine>
+ inline static
+ Type_t makeRead(const Subject_t &f, const S1 &s1,
+ const Combine &c)
+ {
+ return make(f, s1, c);
+ }
+ template<class S1, class S2, class Combine>
+ inline static
+ Type_t makeRead(const Subject_t &f, const S1 &s1,
+ const S2 &s2, const Combine &c)
+ {
+ return make(f, s1, s2, c);
+ }
+ template<class S1, class S2, class S3,
+ class Combine>
+ inline static
+ Type_t makeRead(const Subject_t &f,
+ const S1 &s1, const S2 &s2, const S3 &s3,
+ const Combine &c)
+ {
+ return make(f, s1, s2, s3, c);
+ }
+ };
+ template<class Mesh, class T, class EngineTag, class Sub1>
+ struct View1<Field<Mesh, T, EngineTag>, Sub1>
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Domain_t Domain_t;
+ typedef TemporaryNewDomain1<Domain_t, Sub1> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SDomain_t;
+ enum { sv = DomainTraits<SDomain_t>::singleValued };
+ typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
+ typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
+ typedef typename Dispatch_t::ReadType_t ReadType_t;
+ typedef typename Dispatch_t::Type_t Type_t;
+ inline static
+ Type_t make(const Subject_t &f, const Sub1 &s1)
+ {
+ return Dispatch_t::make(f, s1, Combine_t());
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &f, const Sub1 &s1)
+ {
+ return Dispatch_t::makeRead(f, s1, Combine_t());
+ }
+ };
+ template<class Mesh, class T, class EngineTag>
+ struct View1<Field<Mesh, T, EngineTag>, int>
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ inline static
+ Type_t make(const Subject_t &f, int s1)
+ {
+ ;
+ ;
+ return f.engine()(s1);
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &f, int s1)
+ {
+ ;
+ ;
+ return f.engine().read(s1);
+ }
+ };
+ template<class Mesh, class T, class EngineTag>
+ struct View1<Field<Mesh, T, EngineTag>, Loc<Mesh::dimensions> >
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ inline static
+ Type_t make(const Subject_t &f, const Loc<Mesh::dimensions>& s1)
+ {
+ ;
+ return f.engine()(s1);
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &f, const Loc<Mesh::dimensions>& s1)
+ {
+ ;
+ return f.engine().read(s1);
+ }
+ };
+ template<class Mesh, class T, class EngineTag,
+ class Sub1, class Sub2>
+ struct View2<Field<Mesh, T, EngineTag>, Sub1, Sub2>
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Domain_t Domain_t;
+ typedef NewDomain2<Sub1, Sub2> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SDomain_t;
+ enum { sv = DomainTraits<SDomain_t>::singleValued };
+ typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
+ typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
+ typedef typename Dispatch_t::ReadType_t ReadType_t;
+ typedef typename Dispatch_t::Type_t Type_t;
+ inline static
+ Type_t make(const Subject_t &f, const Sub1 &s1, const Sub2 &s2)
+ {
+ return Dispatch_t::make(f, s1, s2, Combine_t());
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &f, const Sub1 &s1, const Sub2 &s2)
+ {
+ return Dispatch_t::makeRead(f, s1, s2, Combine_t());
+ }
+ };
+ template<class Mesh, class T, class EngineTag>
+ struct View2<Field<Mesh, T, EngineTag>, int, int>
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ inline static
+ Type_t make(const Subject_t &f, int s1, int s2)
+ {
+ ;
+ ;
+ return f.engine()(s1, s2);
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &f, int s1, int s2)
+ {
+ ;
+ ;
+ return f.engine().read(s1, s2);
+ }
+ };
+ template<class Mesh, class T, class EngineTag, int Dim>
+ struct View2<Field<Mesh, T, EngineTag>,
+ FieldOffset<Dim>,
+ Loc<Dim> >
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ enum { dimensions = Subject_t::dimensions };
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ inline static
+ Type_t make(const Subject_t &f,
+ const FieldOffset<dimensions> &fo,
+ const Loc<dimensions> &loc)
+ {
+ PoomaCTAssert<(dimensions == Dim)>::test();
+ if (f.numSubFields() > 1) {
+ ;
+ return f[fo.subFieldNumber()].engine()(loc + fo.cellOffset());
+ }
+ else {
+ ;
+ return f.engine()(loc + fo.cellOffset());
+ }
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &f,
+ const FieldOffset<dimensions> &fo,
+ const Loc<dimensions> &loc)
+ {
+ if (f.numSubFields() > 1) {
+ ;
+ return f[fo.subFieldNumber()].engine().read(loc + fo.cellOffset());
+ }
+ else {
+ ;
+ return f.engine().read(loc + fo.cellOffset());
+ }
+ }
+ };
+ template<class Mesh, class T, class EngineTag,
+ class Sub1, class Sub2, class Sub3>
+ struct View3<Field<Mesh, T, EngineTag>, Sub1, Sub2, Sub3>
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Domain_t Domain_t;
+ typedef NewDomain3<Sub1, Sub2, Sub3> NewDomain_t;
+ typedef typename NewDomain_t::SliceType_t SDomain_t;
+ enum { sv = DomainTraits<SDomain_t>::singleValued };
+ typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
+ typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
+ typedef typename Dispatch_t::ReadType_t ReadType_t;
+ typedef typename Dispatch_t::Type_t Type_t;
+ inline static
+ Type_t make(const Subject_t &f, const Sub1 &s1, const Sub2 &s2,
+ const Sub3 &s3)
+ {
+ return Dispatch_t::make(f, s1, s2, s3, Combine_t());
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &f, const Sub1 &s1, const Sub2 &s2,
+ const Sub3 &s3)
+ {
+ return Dispatch_t::makeRead(f, s1, s2, s3, Combine_t());
+ }
+ };
+ template<class Mesh, class T, class EngineTag>
+ struct View3<Field<Mesh, T, EngineTag>, int, int, int>
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Element_t ReadType_t;
+ typedef typename Subject_t::ElementRef_t Type_t;
+ inline static
+ Type_t make(const Subject_t &f, int s1, int s2, int s3)
+ {
+ ;
+ ;
+ return f.engine()(s1, s2, s3);
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &f, int s1, int s2, int s3)
+ {
+ ;
+ ;
+ return f.engine().read(s1, s2, s3);
+ }
+ };
+ template <int SliceDim, class Mesh, class T, class EngineTag, int Dim>
+ struct ReverseSliceView<Field<Mesh, T, EngineTag>, SliceInterval<Dim, SliceDim> >
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef SliceInterval<Dim, SliceDim> Domain_t;
+ typedef typename NewEngine<typename Subject_t::Engine_t, Domain_t>::Type_t NewEngine_t;
+ typedef Field<NoMesh<Dim>, T, typename NewEngine_t::Tag_t> Type_t;
+ inline static
+ Type_t make(const Subject_t &a, const SliceInterval<Dim, SliceDim>& dom,
+ const Interval<Dim>& totalDom)
+ {
+ PoomaCTAssert<(Mesh::dimensions == SliceDim)>::test();
+ ;
+ return Type_t(typename Type_t::FieldEngine_t(a.fieldEngine(), dom, totalDom));
+ }
+ };
+ template<class Subject> struct Patch;
+ template<class Mesh, class T, class EngineTag>
+ struct Patch<Field<Mesh, T, EngineTag> >
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Engine_t OldEngine_t;
+ typedef typename EngineFunctor<OldEngine_t, EnginePatch>::Type_t Engine_t;
+ typedef Field<Mesh, T, typename Engine_t::Tag_t> Type_t;
+ enum { dim = OldEngine_t::dimensions };
+ inline static
+ Type_t make(const Subject_t &f, int i)
+ {
+ ;
+ return Type_t(f, FieldEnginePatch<dim>(i, f.physicalDomain()));
+ }
+ };
+ template<class Mesh, class T, class LTag, class EngineTag>
+ struct Patch<Field<Mesh, T, MultiPatch<LTag, EngineTag> > >
+ {
+ typedef Field<Mesh, T, MultiPatch<LTag, EngineTag> > Subject_t;
+ typedef typename Subject_t::Engine_t OldEngine_t;
+ typedef typename EngineFunctor<OldEngine_t, EnginePatch>::Type_t Engine_t;
+ typedef Field<Mesh, T, typename Engine_t::Tag_t> Type_t;
+ enum { dim = OldEngine_t::dimensions };
+ typedef typename OldEngine_t::Layout_t Layout_t;
+ typedef typename Layout_t::Value_t Node_t;
+ inline static
+ Type_t make(const Subject_t &f, int i)
+ {
+ ;
+ Node_t *node = f.engine().layout().nodeListLocal()[i];
+ return Type_t(f, FieldEnginePatch<dim>(i, intersect(f.physicalDomain(),
+ node->domain())));
+ }
+ };
+ template<class Components, class Subject> struct ComponentView;
+ template<class Components, class Mesh, class T, class EngineTag>
+ struct ComponentView<Components, Field<Mesh, T, EngineTag> >
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef Engine<Mesh::dimensions, T, EngineTag> Engine_t;
+ typedef typename Engine_t::Element_t Element_t;
+ typedef typename ComponentAccess<Element_t, Components>::Element_t NewT_t;
+ typedef CompFwd<Engine_t, Components> NewEngineTag_t;
+ typedef Field<Mesh, NewT_t, NewEngineTag_t> Type_t;
+ inline static
+ Type_t make(const Subject_t &f, const Components &c)
+ {
+ return Type_t(f, ComponentWrapper<Components>(c));
+ }
+ };
+ template<class Mesh,
+ class T = double,
+ class EngineTag = Brick>
+ class Field {
+ public:
+ typedef Mesh MeshTag_t;
+ typedef Mesh Mesh_t;
+ typedef T T_t;
+ typedef EngineTag EngineTag_t;
+ typedef Field<Mesh, T, EngineTag> This_t;
+ typedef FieldEngine<Mesh, T, EngineTag> FieldEngine_t;
+ enum { dimensions = FieldEngine_t::dimensions };
+ enum { coordinateDimensions = MeshTag_t::coordinateDimensions };
+ typedef Engine<dimensions, T, EngineTag> Engine_t;
+ typedef typename Engine_t::Element_t Element_t;
+ typedef typename Engine_t::ElementRef_t ElementRef_t;
+ typedef typename Engine_t::Layout_t Layout_t;
+ typedef typename Engine_t::Domain_t Domain_t;
+ typedef Centering<dimensions> Centering_t;
+ enum { hasRelations = true };
+ Field()
+ : fieldEngine_m()
+ { }
+ template<class I1>
+ explicit Field(const I1 &i1)
+ : fieldEngine_m(i1)
+ { }
+ template<class Layout2>
+ Field(const Centering_t ¢ering, const Layout2 &layout, const Mesh_t &mesh)
+ : fieldEngine_m(centering, layout, mesh)
+ { }
+ template<class Layout2>
+ Field(int materials, const Centering_t ¢ering, const Layout2 &layout, const Mesh_t &mesh)
+ : fieldEngine_m(centering, layout, mesh, materials)
+ { }
+ template<class I1, class I2>
+ Field(const Centering_t ¢ering, const Layout_t &layout, const I1 &i1, const I2 &i2)
+ : fieldEngine_m(centering, layout, Mesh_t(layout, i1, i2))
+ { }
+ Field(const Centering_t ¢ering, const Layout_t &layout)
+ : fieldEngine_m(centering, layout, Mesh_t(layout))
+ { }
+ template<class I1, class I2>
+ Field(int materials, const Centering_t ¢ering, const Layout_t &layout,
+ const I1 &i1, const I2 &i2)
+ : fieldEngine_m(centering, layout, Mesh_t(layout, i1, i2), materials)
+ { }
+ Field(const This_t &model)
+ : fieldEngine_m(model.fieldEngine())
+ { }
+ void initialize(const This_t &model)
+ {
+ fieldEngine_m = model.fieldEngine();
+ }
+ template<class Layout2>
+ void
+ initialize(const Centering_t ¢ering, const Layout2 &layout,
+ const Mesh_t &mesh)
+ {
+ fieldEngine_m = FieldEngine_t(centering, layout, mesh);
+ }
+ template<class Layout2>
+ void
+ initialize(int materials, const Centering_t ¢ering,
+ const Layout2 &layout, const Mesh_t &mesh)
+ {
+ fieldEngine_m = FieldEngine_t(centering, layout, mesh, materials);
+ }
+ void
+ initialize(const Centering_t ¢ering, const Layout_t &layout)
+ {
+ fieldEngine_m = FieldEngine_t(centering, layout, Mesh_t(layout));
+ }
+ template<class GT2, class T2, class ET2, class Initializer>
+ Field(const Field<GT2, T2, ET2> &model, const Initializer &i)
+ : fieldEngine_m(model.fieldEngine(), i)
+ { }
+ template<class ET2>
+ Field(const Field<Mesh, T, ET2> &model, int m, int c)
+ : fieldEngine_m(model.fieldEngine(), m, c)
+ { }
+ template<class ET2>
+ Field(const Field<Mesh, T, ET2> &model, int c, const Pooma::CenteringViewTag &tag)
+ : fieldEngine_m(model.fieldEngine(), c, tag)
+ { }
+ template<class ET2>
+ Field(const Field<Mesh, T, ET2> &model, int m, const Pooma::MaterialViewTag &tag)
+ : fieldEngine_m(model.fieldEngine(), m, tag)
+ { }
+ ~Field() { }
+ inline const Engine_t &engine() const
+ {
+ return fieldEngine_m.engine();
+ }
+ inline Engine_t &engine()
+ {
+ return fieldEngine_m.engine();
+ }
+ inline const FieldEngine_t &fieldEngine() const
+ {
+ return fieldEngine_m;
+ }
+ inline FieldEngine_t &fieldEngine()
+ {
+ return fieldEngine_m;
+ }
+ inline int numSubFields() const
+ {
+ return fieldEngine_m.numSubFields();
+ }
+ const Centering<dimensions> ¢ering() const
+ {
+ return fieldEngine().centering();
+ }
+ const Centering<dimensions> centering(int c) const
+ {
+ return fieldEngine().centering()[c];
+ }
+ inline int centeringSize() const
+ {
+ return fieldEngine().centeringSize();
+ }
+ inline int numMaterials() const
+ {
+ return fieldEngine().numMaterials();
+ }
+ inline const Domain_t& physicalCellDomain() const
+ {
+ return fieldEngine_m.physicalCellDomain();
+ }
+ inline Domain_t totalCellDomain() const
+ {
+ return fieldEngine_m.totalCellDomain();
+ }
+ Domain_t physicalDomain(int iSubfield) const
+ {
+ return fieldEngine_m.physicalDomain(iSubfield);
+ }
+ Domain_t totalDomain(int iSubfield) const
+ {
+ return fieldEngine_m.totalDomain(iSubfield);
+ }
+ Domain_t physicalDomain() const
+ {
+ return fieldEngine_m.physicalDomain();
+ }
+ Domain_t totalDomain() const
+ {
+ return fieldEngine_m.totalDomain();
+ }
+ Domain_t domain() const
+ {
+ return fieldEngine_m.physicalDomain();
+ }
+ inline
+ const Mesh_t &mesh() const
+ {
+ return fieldEngine_m.mesh();
+ }
+ inline Layout_t layout() const
+ {
+ return fieldEngine_m.engine(0, 0).layout();
+ }
+ void makeOwnCopy()
+ {
+ fieldEngine_m.makeOwnCopy(*this);
+ }
+ inline typename SubFieldView<This_t>::Type_t
+ operator[](int iSubfield) const
+ {
+ typedef SubFieldView<This_t> Ret_t;
+ return Ret_t::make(*this, iSubfield);
+ }
+ inline typename SubFieldView<This_t>::Type_t
+ subField(int m, int c) const
+ {
+ typedef SubFieldView<This_t> Ret_t;
+ return Ret_t::make(*this, m, c);
+ }
+ inline typename SubFieldView<This_t>::Type_t
+ center(int c) const
+ {
+ typedef SubFieldView<This_t> Ret_t;
+ return Ret_t::make(*this, c, Pooma::CenteringViewTag());
+ }
+ inline typename SubFieldView<This_t>::Type_t
+ material(int m) const
+ {
+ ;
+ typedef SubFieldView<This_t> Ret_t;
+ return Ret_t::make(*this, m, Pooma::MaterialViewTag());
+ }
+ inline typename View1<This_t, Domain_t>::ReadType_t
+ read() const
+ {
+ typedef View1<This_t, Domain_t> Ret_t;
+ return Ret_t::makeRead(*this, physicalDomain());
+ }
+ inline typename View1<This_t, Domain_t>::ReadType_t
+ readAll() const
+ {
+ typedef View1<This_t, Domain_t> Ret_t;
+ return Ret_t::makeRead(*this, totalDomain());
+ }
+ template<class Sub1>
+ inline typename View1<This_t, Sub1>::ReadType_t
+ read(const Sub1 &s1) const
+ {
+ typedef View1<This_t, Sub1> Ret_t;
+ return Ret_t::makeRead(*this, s1);
+ }
+ template<class Sub1, class Sub2>
+ inline typename View2<This_t, Sub1, Sub2>::ReadType_t
+ read(const Sub1 &s1, const Sub2 &s2) const
+ {
+ typedef View2<This_t, Sub1, Sub2> Ret_t;
+ return Ret_t::makeRead(*this, s1, s2);
+ }
+ template<class Sub1, class Sub2, class Sub3>
+ inline typename View3<This_t, Sub1, Sub2, Sub3>::ReadType_t
+ read(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3) const
+ {
+ typedef View3<This_t, Sub1, Sub2, Sub3> Ret_t;
+ return Ret_t::makeRead(*this, s1, s2, s3);
+ }
+ inline typename View1<This_t, Domain_t>::Type_t
+ operator()() const
+ {
+ typedef View1<This_t, Domain_t> Ret_t;
+ return Ret_t::make(*this, physicalDomain());
+ }
+ inline typename View1<This_t, Domain_t>::Type_t
+ all() const
+ {
+ typedef View1<This_t, Domain_t> Ret_t;
+ return Ret_t::make(*this, totalDomain());
+ }
+ template<class Sub1>
+ inline typename View1<This_t, Sub1>::Type_t
+ operator()(const Sub1 &s1) const
+ {
+ typedef View1<This_t, Sub1> Ret_t;
+ return Ret_t::make(*this, s1);
+ }
+ template<class Sub1, class Sub2>
+ inline typename View2<This_t, Sub1, Sub2>::Type_t
+ operator()(const Sub1 &s1, const Sub2 &s2) const
+ {
+ typedef View2<This_t, Sub1, Sub2> Ret_t;
+ return Ret_t::make(*this, s1, s2);
+ }
+ template<class Sub1, class Sub2, class Sub3>
+ inline typename View3<This_t, Sub1, Sub2, Sub3>::Type_t
+ operator()(const Sub1 &s1, const Sub2 &s2, const Sub3 &s3) const
+ {
+ typedef View3<This_t, Sub1, Sub2, Sub3> Ret_t;
+ return Ret_t::make(*this, s1, s2, s3);
+ }
+ inline typename ComponentView<Loc<1>, This_t>::Type_t
+ comp(int i1) const
+ {
+ return ComponentView<Loc<1>, This_t>::make(*this, Loc<1>(i1));
+ }
+ inline typename ComponentView<Loc<2>, This_t>::Type_t
+ comp(int i1, int i2) const
+ {
+ return ComponentView<Loc<2>, This_t>::make(*this, Loc<2>(i1, i2));
+ }
+ template<class Components>
+ inline typename ComponentView<Components, This_t>::Type_t
+ comp(const Components &loc) const
+ {
+ return ComponentView<Components, This_t>::make(*this, loc);
+ }
+ inline typename Patch<This_t>::Type_t
+ patchLocal(EnginePatch::PatchID_t i) const
+ {
+ return Patch<This_t>::make(*this, i);
+ }
+ inline int
+ numPatchesLocal() const
+ {
+ return engineFunctor(engine(), EngineNumPatches());
+ }
+ This_t &operator=(const This_t &rhs)
+ {
+ assign(*this, rhs, OpAssign());
+ return *this;
+ }
+ const This_t &operator=(const This_t &rhs) const
+ {
+ return assign(*this, rhs, OpAssign());
+ }
+ template<class T1>
+ const This_t &operator=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpAssign());
+ }
+ template<class T1>
+ const This_t &operator+=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpAddAssign());
+ }
+ template<class T1>
+ const This_t &operator-=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpSubtractAssign());
+ }
+ template<class T1>
+ const This_t &operator*=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpMultiplyAssign());
+ }
+ template<class T1>
+ const This_t &operator/=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpDivideAssign());
+ }
+ template<class T1>
+ const This_t &operator%=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpModAssign());
+ }
+ template<class T1>
+ const This_t &operator|=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpBitwiseOrAssign());
+ }
+ template<class T1>
+ const This_t &operator&=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpBitwiseAndAssign());
+ }
+ template<class T1>
+ const This_t &operator^=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpBitwiseXorAssign());
+ }
+ template<class T1>
+ const This_t &operator<<=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpLeftShiftAssign());
+ }
+ template<class T1>
+ const This_t &operator>>=(const T1 &rhs) const
+ {
+ return assign(*this, rhs, OpRightShiftAssign());
+ }
+ void addRelation(RelationListItem *item) const
+ {
+ ;
+ fieldEngine_m.relations().addRelation(item);
+ }
+ void removeRelations()
+ {
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ for (int c = 0; c < centering().size(); ++ c)
+ {
+ fieldEngine_m.data(m, c).relations().erase();
+ }
+ }
+ }
+ void applyRelations(bool makeDirty = false) const
+ {
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ for (int c = 0; c < centering().size(); ++ c)
+ {
+ if (makeDirty)
+ fieldEngine_m.data(m, c).relations().setDirty();
+ fieldEngine_m.data(m, c).relations().notifyPreRead();
+ }
+ }
+ }
+ void notifyPreRead() const
+ {
+ for (int m = 0; m < numMaterials(); ++m)
+ for (int c = 0; c < centering().size(); ++c)
+ fieldEngine_m.data(m, c).relations().notifyPreRead();
+ }
+ void notifyPostWrite() const
+ {
+ for (int m = 0; m < numMaterials(); ++m)
+ for (int c = 0; c < centering().size(); ++c)
+ fieldEngine_m.data(m, c).relations().notifyPostWrite();
+ }
+ void setDirty() const
+ {
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ for (int c = 0; c < centering().size(); ++ c)
+ {
+ fieldEngine_m.data(m, c).relations().setDirty();
+ }
+ }
+ }
+ void clearDirty() const
+ {
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ for (int c = 0; c < centering().size(); ++ c)
+ {
+ fieldEngine_m.data(m, c).relations().clearDirty();
+ }
+ }
+ }
+ bool isDirty() const
+ {
+ for (int m = 0; m < numMaterials(); ++m)
+ {
+ for (int c = 0; c < centering().size(); ++ c)
+ {
+ if (fieldEngine_m.data(m, c).relations().dirty())
+ return true;
+ }
+ }
+ return false;
+ }
+ private:
+ FieldEngine_t fieldEngine_m;
+ };
+ template<class Op>
+ struct AssignOpReadWriteTraits
+ {
+ enum { readLHS = true };
+ };
+ template<>
+ struct AssignOpReadWriteTraits<OpAssign>
+ {
+ enum { readLHS = false };
+ };
+ template<class Mesh, class T, class EngineTag, int Dim>
+ struct LeafFunctor<Field<Mesh, T, EngineTag>, ConformTag<Dim> >
+ {
+ typedef bool Type_t;
+ static Type_t apply1(const Interval<Dim> &d,
+ const ConformTag<Dim> &ct)
+ {
+ return conforms(d, ct);
+ }
+ template<int Dim2>
+ static Type_t apply1(const Interval<Dim2> &d,
+ const ConformTag<Dim> &ct)
+ {
+ return false;
+ }
+ static Type_t apply(const Field<Mesh, T, EngineTag> &f,
+ const ConformTag<Dim> &ct)
+ {
+ return apply1(f.physicalDomain(), ct);
+ }
+ };
+ template<class Mesh, class T, class EngineTag, class RequestType>
+ struct LeafFunctor<Field<Mesh, T, EngineTag>,
+ DataObjectRequest<RequestType> >
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef typename Subject_t::FieldEngine_t FieldEngine_t;
+ typedef LeafFunctor<FieldEngine_t, DataObjectRequest<RequestType> >
+ LeafFunctor_t;
+ typedef typename LeafFunctor_t::Type_t Type_t;
+ enum { dataObject = LeafFunctor_t::dataObject };
+ inline static
+ Type_t apply(const Subject_t &f,
+ const DataObjectRequest<RequestType> &functor)
+ {
+ return LeafFunctor_t::apply(f.fieldEngine(), functor);
+ }
+ };
+ template<class Mesh, class T, class EngineTag, class RequestType>
+ struct LeafFunctor<FieldEngine<Mesh, T, EngineTag>,
+ DataObjectRequest<RequestType> >
+ {
+ typedef typename FieldEngine<Mesh, T, EngineTag>::Engine_t
+ Engine_t;
+ enum { dataObject = Engine_t::dataObject };
+ typedef typename DataObjectRequest<RequestType>::Type_t Type_t;
+ inline static
+ Type_t apply(const FieldEngine<Mesh, T, EngineTag> &f,
+ const DataObjectRequest<RequestType> &functor)
+ {
+ return DataObjectApply<dataObject>::apply(f.engine(), functor);
+ }
+ };
+ template<class Mesh, class T, class EngineTag>
+ struct LeafFunctor<Field<Mesh, T, EngineTag>, DomainFunctorTag>
+ {
+ typedef typename Field<Mesh, T, EngineTag>::Domain_t Type_t;
+ inline static Type_t apply(const Field<Mesh, T, EngineTag> &f,
+ const DomainFunctorTag &)
+ {
+ return f.physicalDomain() - f.physicalDomain().firsts();
+ }
+ };
+ template<class Mesh, class T, class EngineTag, class Tag>
+ struct LeafFunctor<Field<Mesh, T, EngineTag>, ExpressionApply<Tag> >
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef typename Subject_t::FieldEngine_t FieldEngine_t;
+ typedef LeafFunctor<FieldEngine_t, ExpressionApply<Tag> > LeafFunctor_t;
+ typedef int Type_t;
+ inline static
+ Type_t apply(const Subject_t &field,
+ const ExpressionApply<Tag> &tag)
+ {
+ return LeafFunctor_t::apply(field.fieldEngine(), tag);
+ }
+ };
+ template<class Mesh, class T, class EngineTag, class Tag>
+ struct LeafFunctor<Field<Mesh, T, EngineTag>, EngineView<Tag> >
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Engine_t Engine_t;
+ typedef typename LeafFunctor<Engine_t, EngineView<Tag> >::Type_t NewEngine_t;
+ typedef typename NewEngine_t::Tag_t NewEngineTag_t;
+ typedef Field<Mesh, T, NewEngineTag_t> Type_t;
+ inline static
+ Type_t apply(const Subject_t &field,
+ const EngineView<Tag> &tag)
+ {
+ return Type_t(field, tag);
+ }
+ };
+ template<class Mesh, class T, class EngineTag, class Tag>
+ struct LeafFunctor<Field<Mesh, T, EngineTag>, EngineFunctorTag<Tag> >
+ {
+ typedef typename Field<Mesh,T,EngineTag>::Engine_t Engine_t;
+ typedef typename EngineFunctor<Engine_t,Tag>::Type_t Type_t;
+ inline static
+ Type_t apply(const Field<Mesh, T, EngineTag> &field,
+ const EngineFunctorTag<Tag> &tag)
+ {
+ return EngineFunctor<Engine_t,Tag>::apply(field.engine(), tag.tag());
+ }
+ };
+ template<class Mesh, class T, class EngineTag, class Tag>
+ struct EngineFunctor<Field<Mesh, T, EngineTag>, Tag>
+ {
+ typedef typename Field<Mesh, T, EngineTag>::Engine_t Engine_t;
+ typedef typename EngineFunctor<Engine_t, Tag>::Type_t Type_t;
+ inline static
+ Type_t apply(const Field<Mesh, T, EngineTag> &field,
+ const Tag &tag)
+ {
+ return engineFunctor(field.engine(), tag);
+ }
+ };
+ template<class Mesh, class T, class EngineTag, int Dim>
+ struct LeafFunctor<Field<Mesh, T, EngineTag>, EvalLeaf<Dim> >
+ {
+ typedef typename Field<Mesh, T, EngineTag>::Element_t Type_t;
+ inline static
+ Type_t apply(const Field<Mesh, T, EngineTag> &f,
+ const EvalLeaf<Dim> &t)
+ {
+ return t.eval(f.engine());
+ }
+ };
+ template<class Mesh, class T, class EngineTag>
+ struct LeafFunctor<Field<Mesh, T, EngineTag>,
+ PerformUpdateTag>
+ {
+ typedef Field<Mesh, T, EngineTag> Subject_t;
+ typedef int Type_t;
+ inline static
+ Type_t apply(const Subject_t &f, const PerformUpdateTag &)
+ {
+ f.notifyPreRead();
+ return 0;
+ }
+ };
+ template<class Mesh, class T, class Expr>
+ struct LeafFunctor<Field<Mesh, T, ExpressionTag<Expr> >,
+ PerformUpdateTag>
+ {
+ typedef Field<Mesh, T, ExpressionTag<Expr> > Subject_t;
+ typedef int Type_t;
+ inline static
+ Type_t apply(const Subject_t &f, const PerformUpdateTag &tag)
+ {
+ forEach(f.engine().expression(), tag, NullCombine());
+ return 0;
+ }
+ };
+ template<class Mesh, class T, class EngineTag>
+ struct LeafFunctor<Field<Mesh, T, EngineTag>, SubFieldViewFunctorTag>
+ {
+ typedef Field<Mesh, T, EngineTag> Type_t;
+ };
+ template<int Dim, class T, class EngineTag>
+ struct LeafFunctor<Array<Dim, T, EngineTag>, SubFieldViewFunctorTag>
+ {
+ typedef Array<Dim, T, EngineTag> Type_t;
+ };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, SubFieldViewFunctorTag>
+ {
+ typedef Scalar<T> Type_t;
+ };
+ template<class Mesh, class T, class EngineTag, class Domain>
+ struct LeafFunctor<Field<Mesh, T, EngineTag>, ViewFunctorTag<Domain> >
+ {
+ typedef typename View1<Field<Mesh, T, EngineTag>, Domain>::Type_t
+ Type_t;
+ };
+ template <class Mesh, class T, class EngineTag>
+ std::ostream &operator<<(std::ostream &o,
+ const Field<Mesh, T, EngineTag> &cf)
+ {
+ Pooma::blockAndEvaluate();
+ PrintField().print(o, cf);
+ return o;
+ }
+ template <class Mesh, class T, class EngineTag>
+ std::fstream &operator<<(std::fstream &f,
+ const Field<Mesh, T, EngineTag> &cf)
+ {
+ Pooma::blockAndEvaluate();
+ PrintField().print(f, cf);
+ return f;
+ }
+ 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;
+ };
+ template<class Mesh, class T, class EngineTag,
+ int Dim2, class T2, class EngineTag2, class Op>
+ const Field<Mesh, T, EngineTag> &
+ assign(const Field<Mesh, T, EngineTag> &lhs,
+ const Array<Dim2, T2, EngineTag2> &rhs, const Op &op)
+ {
+ for (int m = 0; m < lhs.numMaterials(); ++m)
+ {
+ for (int c = 0; c < lhs.centeringSize(); ++c)
+ {
+ const Field<Mesh, T, EngineTag> &l = lhs.subField(m, c);
+ if (AssignOpReadWriteTraits<Op>::readLHS)
+ l.notifyPreRead();
+ Evaluator<MainEvaluatorTag>().evaluate(l, op, rhs);
+ l.notifyPostWrite();
+ }
+ }
+ return lhs;
+ }
+ template<class Mesh, class T, class EngineTag,
+ class Mesh2, class T2, class EngineTag2, class Op>
+ const Field<Mesh, T, EngineTag> &
+ assign(const Field<Mesh, T, EngineTag> &lhs,
+ const Field<Mesh2, T2, EngineTag2> &rhs,
+ const Op &op)
+ {
+ ;
+ for (int m = 0; m < lhs.numMaterials(); ++m)
+ {
+ for (int c = 0; c < lhs.centeringSize(); ++c)
+ {
+ const Field<Mesh, T, EngineTag> &l = lhs.subField(m, c);
+ const typename SubFieldView<Field<Mesh2, T2, EngineTag2> >::Type_t &r =
+ rhs.subField(m, c);
+ forEach(r, PerformUpdateTag(), NullCombine());
+ if (AssignOpReadWriteTraits<Op>::readLHS)
+ l.notifyPreRead();
+ Evaluator<MainEvaluatorTag>().evaluate(l, op, r);
+ l.notifyPostWrite();
+ }
+ }
+ return lhs;
+ }
+ template<class Mesh, class T, class EngineTag, class T1, class Op>
+ const Field<Mesh, T, EngineTag> &
+ assign(const Field<Mesh, T, EngineTag> &lhs, const T1 &rhs,
+ const Op &op)
+ {
+ for (int m = 0; m < lhs.numMaterials(); ++m)
+ {
+ for (int c = 0; c < lhs.centeringSize(); ++c)
+ {
+ const Field<Mesh, T, EngineTag> &l = lhs.subField(m, c);
+ if (AssignOpReadWriteTraits<Op>::readLHS)
+ l.notifyPreRead();
+ typedef Field<Mesh, T, EngineTag> LHS_t;
+ Array<LHS_t::dimensions, T1, ConstantFunction> rhsExpr(l.physicalDomain());
+ rhsExpr.engine().setConstant(rhs);
+ Evaluator<MainEvaluatorTag>().evaluate(l, op, rhsExpr);
+ l.notifyPostWrite();
+ }
+ }
+ return lhs;
+ }
+ template<class Mesh, class T, class EngineTag,
+ int Dim2, class T2, class EngineTag2, class Op>
+ const Array<Dim2, T2, EngineTag2> &
+ assign(const Array<Dim2, T2, EngineTag2> &lhs,
+ const Field<Mesh, T, EngineTag> &rhs, const Op &op)
+ {
+ ;
+ forEach(rhs, PerformUpdateTag(), NullCombine());
+ Evaluator<MainEvaluatorTag>().evaluate(lhs, op, rhs);
+ return lhs;
+ }
+ 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;
+ }
+ template<class Mesh, class T, class EngineTag>
+ inline bool compressed(const Field<Mesh, T, EngineTag> &f)
+ {
+ ;
+ return compressed(f.engine());
+ }
+ template<class Mesh, class T, class EngineTag>
+ inline long elementsCompressed(const Field<Mesh, T, EngineTag> &f)
+ {
+ ;
+ return elementsCompressed(f.engine());
+ }
+ template<class Mesh, class T, class LTag>
+ void
+ compress(Field<Mesh, T, MultiPatch<LTag,CompressibleBrick> > &f)
+ {
+ for (int m = 0; m < f.numMaterials(); ++m)
+ {
+ for (int c = 0; c < f.centeringSize(); ++c)
+ {
+ compress(f.fieldEngine().data(m, c).engine());
+ }
+ }
+ }
+ template<class Mesh, class T, class LTag>
+ void
+ uncompress(Field<Mesh, T, MultiPatch<LTag,CompressibleBrick> > &f)
+ {
+ for (int m = 0; m < f.numMaterials(); ++m)
+ {
+ for (int c = 0; c < f.centeringSize(); ++c)
+ {
+ uncompress(f.fieldEngine().data(m, c).engine());
+ }
+ }
+ }
+ template<int Dim, class T, class EngineTag>
+ inline int numMaterials(const Array<Dim, T, EngineTag> &a)
+ {
+ return 1;
+ }
+ template<class Mesh, class T, class EngineTag>
+ inline int numMaterials(const Field<Mesh, T, EngineTag> &f)
+ {
+ return f.numMaterials();
+ }
+ template<int Dim, class T, class EngineTag>
+ inline int centeringSize(const Array<Dim, T, EngineTag> &a)
+ {
+ return 1;
+ }
+ template<class Mesh, class T, class EngineTag>
+ inline int centeringSize(const Field<Mesh, T, EngineTag> &f)
+ {
+ return f.centeringSize();
+ }
+ template<int Dim, class T, class EngineTag>
+ inline Array<Dim, T, EngineTag> &subField(Array<Dim, T, EngineTag> &a, int, int)
+ {
+ return a;
+ }
+ template<class Mesh, class T, class EngineTag>
+ inline typename SubFieldView<Field<Mesh, T, EngineTag> >::Type_t
+ subField(Field<Mesh, T, EngineTag> &f, int m, int c)
+ {
+ return f.subField(m, c);
+ }
+ template<class Mesh, class T, class EngineTag> class Field;
+ struct FarLeftTag
+ {
+
+ };
+ template<class G1, class T1, class E1, class Op>
+ struct Combine1<Field<G1, T1, E1>, Op, FarLeftTag>
+ {
+ typedef Field<G1, T1, E1> Type_t;
+ inline static
+ const Type_t &combine(const Field<G1, T1, E1> &a,
+ const FarLeftTag &)
+ {
+ return a;
+ }
+ };
+ template<class G1, class T1, class E1, class G2, class T2, class E2,
+ class Op>
+ struct Combine2<Field<G1, T1, E1>, Field<G2, T2, E2>, Op, FarLeftTag>
+ {
+ typedef Field<G1, T1, E1> Type_t;
+ inline static
+ const Type_t &combine(const Field<G1, T1, E1> &a,
+ const Field<G2, T2, E2> &, FarLeftTag)
+ {
+ return a;
+ }
+ };
+ template<class T, class G2, class T2, class E2, class Op>
+ struct Combine2<T, Field<G2, T2, E2>, Op, FarLeftTag>
+ {
+ typedef Field<G2, T2, E2> Type_t;
+ inline static
+ const Type_t &combine(const T &,
+ const Field<G2, T2, E2> &b, FarLeftTag)
+ {
+ return b;
+ }
+ };
+ template<class G1, class T1, class E1, class T, class Op>
+ struct Combine2<Field<G1, T1, E1>, T, Op, FarLeftTag>
+ {
+ typedef Field<G1, T1, E1> Type_t;
+ inline static
+ const Type_t &combine(const Field<G1, T1, E1> &a,
+ const T &, FarLeftTag)
+ {
+ return a;
+ }
+ };
+ template<class T, class Op>
+ struct Combine2<ErrorType, T, Op, FarLeftTag>
+ {
+ typedef T Type_t;
+ inline static
+ const Type_t &combine(const ErrorType& e, const T& t,
+ FarLeftTag)
+ {
+ return t;
+ }
+ };
+ template<class T, class Op>
+ struct Combine2<T, ErrorType, Op, FarLeftTag>
+ {
+ typedef T Type_t;
+ inline static
+ const Type_t &combine(const T& t, const ErrorType& e,
+ FarLeftTag)
+ {
+ return t;
+ }
+ };
+ template<class A,class B,class C,class Op>
+ struct Combine3<A, B, C, Op, FarLeftTag>
+ {
+ typedef typename Combine2<A, B, Op, FarLeftTag>::Type_t Type1_t;
+ typedef typename Combine2<Type1_t, C, Op, FarLeftTag>::Type_t Type_t;
+ inline static
+ const Type_t &combine(const A& a, const B& b, const C& c,
+ const FarLeftTag& t)
+ {
+ return
+ Combine2<Type1_t, C,
+ Op, FarLeftTag>::combine(Combine2<A, B, Op,
+ FarLeftTag>::combine(a, b, t), c, t);
+ }
+ };
+ template<class GeometryTag, class T, class EngineTag>
+ struct LeafFunctor<Field<GeometryTag, T, EngineTag>, FarLeftTag>
+ {
+ typedef Field<GeometryTag, T, EngineTag> Type_t;
+ inline static
+ const Type_t &apply(const Field<GeometryTag, T, EngineTag> &f,
+ const FarLeftTag &)
+ {
+ return f;
+ }
+ };
+ template<int Dim, class T, class EngineTag>
+ struct LeafFunctor<Array<Dim, T, EngineTag>, FarLeftTag>
+ {
+ typedef ErrorType Type_t;
+ inline static
+ const Type_t &apply(const Array<Dim, T, EngineTag> &a,
+ const FarLeftTag &)
+ {
+ return Type_t();
+ }
+ };
+ template<class T>
+ struct LeafFunctor<Scalar<T>, FarLeftTag>
+ {
+ typedef Scalar<T> Type_t;
+ inline static
+ const Type_t &apply(const Scalar<T> &s, const FarLeftTag &)
+ {
+ return s;
+ }
+ };
+ template<class Mesh, class T, class Expr>
+ class FieldEngine<Mesh, T, ExpressionTag<Expr> >
+ {
+ public:
+ enum { dimensions = Mesh::dimensions };
+ enum { Dim = dimensions };
+ typedef ExpressionTag<Expr> EngineTag_t;
+ typedef FieldEngine<Mesh, T, EngineTag_t> This_t;
+ typedef Engine<Dim, T, EngineTag_t> Engine_t;
+ typedef typename Engine_t::Domain_t Domain_t;
+ typedef typename Engine_t::Layout_t Layout_t;
+ typedef typename Engine_t::Element_t Element_t;
+ typedef typename Engine_t::ElementRef_t ElementRef_t;
+ typedef GuardLayers<Dim> GuardLayers_t;
+ typedef typename ForEach<Expr, FarLeftTag, FarLeftTag>::Type_t
+ ReferenceField_t;
+ FieldEngine(const Engine_t &e)
+ : engine_m(e),
+ referenceField_m(
+ forEachRef(engine_m.expression(), FarLeftTag(), FarLeftTag()))
+ { }
+ template<class Expr2, class Domain>
+ FieldEngine(const FieldEngine<Mesh, T, ExpressionTag<Expr2> > &model,
+ const Domain &d)
+ : engine_m(NewEngineEngine<Engine<Dim, T, ExpressionTag<Expr2> >, Domain>::apply(model.engine(), d),
+ NewEngineDomain<Engine<Dim, T, ExpressionTag<Expr2> >, Domain>::apply(model.engine(), d)
+ ),
+ referenceField_m(
+ forEachRef(engine_m.expression(), FarLeftTag(), FarLeftTag()))
+ { }
+ template<class Expr2>
+ FieldEngine(const FieldEngine<Mesh, T, ExpressionTag<Expr2> > &model, int m, int c)
+ : engine_m(Expr(model.engine().expression(), m, c)),
+ referenceField_m(forEachRef(engine_m.expression(),
+ FarLeftTag(), FarLeftTag()))
+ { }
+ template<class Expr2>
+ FieldEngine(const FieldEngine<Mesh, T, ExpressionTag<Expr2> > &model, int m,
+ const Pooma::MaterialViewTag& tag)
+ : engine_m(Expr(model.engine().expression(), m, tag)),
+ referenceField_m(forEachRef(engine_m.expression(),
+ FarLeftTag(), FarLeftTag()))
+ { }
+ template<class Expr2>
+ FieldEngine(const FieldEngine<Mesh, T, ExpressionTag<Expr2> > &model, int c,
+ const Pooma::CenteringViewTag& tag)
+ : engine_m(Expr(model.engine().expression(), c, tag)),
+ referenceField_m(forEachRef(engine_m.expression(),
+ FarLeftTag(), FarLeftTag()))
+ { }
+ template<class Expr2>
+ FieldEngine(const FieldEngine<Mesh, T, ExpressionTag<Expr2> > &model, int iSubField)
+ : engine_m(Expr(model.engine().expression, iSubField)),
+ referenceField_m(forEachRef(engine_m.expression(),
+ FarLeftTag(), FarLeftTag()))
+ { }
+ FieldEngine(const FieldEngine<Mesh, T, ExpressionTag<Expr> > &other)
+ : engine_m(other.engine()),
+ referenceField_m(forEachRef(engine_m.expression(),
+ FarLeftTag(), FarLeftTag()))
+ { }
+ int numSubFields() const
+ {
+ return referenceField().numSubFields();
+ }
+ const Engine_t &engine() const
+ {
+ return engine_m;
+ }
+ Engine_t &engine()
+ {
+ return engine_m;
+ }
+ const ReferenceField_t &referenceField() const
+ {
+ return referenceField_m;
+ }
+ const Domain_t &physicalCellDomain() const
+ {
+ return referenceField().physicalCellDomain();
+ }
+ Domain_t totalCellDomain() const
+ {
+ return referenceField().totalCellDomain();
+ }
+ Domain_t physicalDomain() const
+ {
+ return referenceField().physicalDomain();
+ }
+ Domain_t totalDomain() const
+ {
+ return referenceField().totalDomain();
+ }
+ Domain_t physicalDomain(int iSubField) const
+ {
+ return referenceField().physicalDomain(iSubField);
+ }
+ Domain_t totalDomain(int iSubField) const
+ {
+ return referenceField().totalDomain(iSubField);
+ }
+ const Centering<Dim> ¢ering() const
+ {
+ return referenceField().centering();
+ }
+ int centeringSize() const
+ {
+ return referenceField().centeringSize();
+ }
+ int numMaterials() const
+ {
+ return referenceField().numMaterials();
+ }
+ Mesh &mesh()
+ {
+ return referenceField().mesh();
+ }
+ const Mesh &mesh() const
+ {
+ return referenceField().mesh();
+ }
+ private:
+ This_t &operator=(const This_t &other);
+ Engine_t engine_m;
+ const ReferenceField_t &referenceField_m;
+ };
+ template<class Mesh, class T, class Expr, class Tag>
+ struct LeafFunctor<FieldEngine<Mesh, T, ExpressionTag<Expr> >,
+ ExpressionApply<Tag> >
+ {
+ typedef FieldEngine<Mesh, T, ExpressionTag<Expr> > Subject_t;
+ typedef typename Subject_t::Engine_t Engine_t;
+ typedef LeafFunctor<Engine_t, ExpressionApply<Tag> > LeafFunctor_t;
+ typedef int Type_t;
+ inline static
+ Type_t apply(const Subject_t &fieldEngineBase,
+ const ExpressionApply<Tag> &tag)
+ {
+ LeafFunctor_t::apply(fieldEngineBase.engine(), tag);
+ return 0;
+ }
+ };
+ struct RectilinearTag {};
+ struct UniformRectilinearTag {};
+ struct CartesianTag {
+ enum { x = 0, y = 1, z = 2 };
+ };
+ struct CylindricalTag {
+ enum { r = 0, z = 1, phi = 2 };
+ };
+ struct SphericalTag {
+ enum { r = 0, theta = 1, phi = 2};
+ };
+ template<class MeshTraits> struct CartesianRM;
+ template<class MeshTraits> struct CartesianURM;
+ template<class MeshTraits> struct CylindricalRM;
+ template<class MeshTraits> struct CylindricalURM;
+ template<class MeshTraits> struct SphericalRM;
+ template<class MeshTraits> struct SphericalURM;
+ template<class MeshTraits> class RectilinearMeshData;
+ template<class MeshTraits> class RectilinearMesh;
+ template<class MeshTraits> class UniformRectilinearMeshData;
+ template<class MeshTraits> class UniformRectilinearMesh;
+ template <int Dim, typename T = double, class MeshTag = UniformRectilinearTag, class CoordinateSystemTag = CartesianTag, int CDim = Dim>
+ struct MeshTraits;
+ template <int Dim, typename T, class MeshTag, class CoordinateSystemTag, int CDim>
+ struct MeshTraitsBase
+ {
+ typedef MeshTraits<Dim, T, MeshTag, CoordinateSystemTag, CDim> MeshTraits_t;
+ typedef MeshTag MeshTag_t;
+ typedef CoordinateSystemTag CoordinateSystemTag_t;
+ typedef T T_t;
+ enum { dimensions = Dim };
+ enum { coordinateDimensions = CDim };
+ typedef T Scalar_t;
+ typedef Loc<Dim> Loc_t;
+ typedef Interval<Dim> Domain_t;
+ typedef Vector<CDim, T> PointType_t;
+ typedef Vector<CDim, T> VectorType_t;
+ typedef Vector<CDim, int> CIndexType_t;
+ };
+ template <int Dim, typename T, int CDim>
+ struct MeshTraits<Dim, T, RectilinearTag, CartesianTag, CDim>
+ : MeshTraitsBase<Dim, T, RectilinearTag, CartesianTag, CDim>
+ {
+ typedef typename MeshTraitsBase<Dim, T, RectilinearTag, CartesianTag, CDim>::MeshTraits_t MeshTraits_t;
+ typedef CartesianRM<MeshTraits_t> CoordinateSystem_t;
+ typedef RectilinearMeshData<MeshTraits_t> MeshData_t;
+ typedef RectilinearMesh<MeshTraits_t> Mesh_t;
+ typedef Array<1, T, Brick> SpacingsType_t[CDim];
+ typedef Array<1, T, Brick> PositionsType_t[CDim];
+ };
+ template <int Dim, typename T, int CDim>
+ struct MeshTraits<Dim, T, UniformRectilinearTag, CartesianTag, CDim>
+ : public MeshTraitsBase<Dim, T, UniformRectilinearTag, CartesianTag, CDim>
+ {
+ typedef typename MeshTraitsBase<Dim, T, UniformRectilinearTag, CartesianTag, CDim>::MeshTraits_t MeshTraits_t;
+ typedef CartesianURM<MeshTraits_t> CoordinateSystem_t;
+ typedef UniformRectilinearMeshData<MeshTraits_t> MeshData_t;
+ typedef UniformRectilinearMesh<MeshTraits_t> Mesh_t;
+ typedef Vector<CDim, T> SpacingsType_t;
+ typedef Vector<CDim, T> PositionsType_t;
+ };
+ template <int Dim, typename T, int CDim>
+ struct MeshTraits<Dim, T, RectilinearTag, CylindricalTag, CDim>
+ : public MeshTraitsBase<Dim, T, RectilinearTag, CylindricalTag, CDim>
+ {
+ typedef typename MeshTraitsBase<Dim, T, RectilinearTag, CylindricalTag, CDim>::MeshTraits_t MeshTraits_t;
+ typedef CylindricalRM<MeshTraits_t> CoordinateSystem_t;
+ typedef RectilinearMeshData<MeshTraits_t> MeshData_t;
+ typedef RectilinearMesh<MeshTraits_t> Mesh_t;
+ typedef Array<1, T, Brick> SpacingsType_t[CDim];
+ typedef Array<1, T, Brick> PositionsType_t[CDim];
+ };
+ template <int Dim, typename T, int CDim>
+ struct MeshTraits<Dim, T, UniformRectilinearTag, CylindricalTag, CDim>
+ : public MeshTraitsBase<Dim, T, UniformRectilinearTag, CylindricalTag, CDim>
+ {
+ typedef typename MeshTraitsBase<Dim, T, UniformRectilinearTag, CylindricalTag, CDim>::MeshTraits_t MeshTraits_t;
+ typedef CylindricalURM<MeshTraits_t> CoordinateSystem_t;
+ typedef UniformRectilinearMeshData<MeshTraits_t> MeshData_t;
+ typedef UniformRectilinearMesh<MeshTraits_t> Mesh_t;
+ typedef Vector<CDim, T> SpacingsType_t;
+ typedef Vector<CDim, T> PositionsType_t;
+ };
+ template <int Dim, typename T, int CDim>
+ struct MeshTraits<Dim, T, RectilinearTag, SphericalTag, CDim>
+ : MeshTraitsBase<Dim, T, RectilinearTag, SphericalTag, CDim>
+ {
+ typedef typename MeshTraitsBase<Dim, T, RectilinearTag, SphericalTag, CDim>::MeshTraits_t MeshTraits_t;
+ typedef SphericalRM<MeshTraits_t> CoordinateSystem_t;
+ typedef RectilinearMeshData<MeshTraits_t> MeshData_t;
+ typedef RectilinearMesh<MeshTraits_t> Mesh_t;
+ typedef Array<1, T, Brick> SpacingsType_t[CDim];
+ typedef Array<1, T, Brick> PositionsType_t[CDim];
+ };
+ template <int Dim, typename T, int CDim>
+ struct MeshTraits<Dim, T, UniformRectilinearTag, SphericalTag, CDim>
+ : MeshTraitsBase<Dim, T, UniformRectilinearTag, SphericalTag, CDim>
+ {
+ typedef typename MeshTraitsBase<Dim, T, UniformRectilinearTag, SphericalTag, CDim>::MeshTraits_t MeshTraits_t;
+ typedef SphericalURM<MeshTraits_t> CoordinateSystem_t;
+ typedef UniformRectilinearMeshData<MeshTraits_t> MeshData_t;
+ typedef UniformRectilinearMesh<MeshTraits_t> Mesh_t;
+ typedef Vector<CDim, T> SpacingsType_t;
+ typedef Vector<CDim, T> PositionsType_t;
+ };
+ template <int Dim>
+ class NoMeshData : public RefCounted
+ {
+ public:
+ NoMeshData()
+ {
+ }
+ template<class Layout>
+ explicit NoMeshData(const Layout &layout)
+ : physicalVertexDomain_m(layout.innerDomain()),
+ physicalCellDomain_m(shrinkRight(physicalVertexDomain_m, 1)),
+ totalVertexDomain_m(layout.domain()),
+ totalCellDomain_m(shrinkRight(totalVertexDomain_m, 1))
+ {
+ }
+ NoMeshData(const NoMeshData<Dim> &model)
+ : physicalVertexDomain_m(model.physicalVertexDomain_m),
+ physicalCellDomain_m(model.physicalCellDomain_m),
+ totalVertexDomain_m(model.totalVertexDomain_m),
+ totalCellDomain_m(model.totalCellDomain_m)
+ {
+ }
+ NoMeshData(const Interval<Dim> &d)
+ : physicalVertexDomain_m(d - d.firsts()),
+ physicalCellDomain_m(shrinkRight(physicalVertexDomain_m, 1)),
+ totalVertexDomain_m(d - d.firsts()),
+ totalCellDomain_m(shrinkRight(totalVertexDomain_m, 1))
+ {
+ }
+ NoMeshData(const NoMeshData<Dim> &model, const FieldEnginePatch<Dim> &p)
+ : physicalVertexDomain_m(p.domain_m),
+ physicalCellDomain_m(shrinkRight(physicalVertexDomain_m, 1)),
+ totalVertexDomain_m(p.domain_m),
+ totalCellDomain_m(shrinkRight(totalVertexDomain_m, 1))
+ {
+ }
+ NoMeshData<Dim> &operator=(const NoMeshData<Dim> &rhs)
+ {
+ if (this != &rhs)
+ {
+ physicalVertexDomain_m = rhs.physicalVertexDomain_m;
+ physicalCellDomain_m = rhs.physicalCellDomain_m;
+ totalVertexDomain_m = rhs.totalVertexDomain_m;
+ totalCellDomain_m = rhs.totalCellDomain_m;
+ }
+ return *this;
+ }
+ ~NoMeshData()
+ {
+ }
+ inline const Interval<Dim> &physicalVertexDomain() const
+ {
+ return physicalVertexDomain_m;
+ }
+ inline const Interval<Dim> &physicalCellDomain() const
+ {
+ return physicalCellDomain_m;
+ }
+ inline const Interval<Dim> &totalVertexDomain() const
+ {
+ return totalVertexDomain_m;
+ }
+ inline const Interval<Dim> &totalCellDomain() const
+ {
+ return totalCellDomain_m;
+ }
+ private:
+ Interval<Dim> physicalVertexDomain_m, physicalCellDomain_m;
+ Interval<Dim> totalVertexDomain_m, totalCellDomain_m;
+ };
+ template<int Dim>
+ class NoMesh
+ {
+ public:
+ enum { dimensions = Dim };
+ enum { coordinateDimensions = Dim };
+ inline NoMesh()
+ : data_m(new NoMeshData<Dim>)
+ {
+ }
+ template<class Layout>
+ inline explicit NoMesh(const Layout &layout)
+ : data_m(new NoMeshData<Dim>(layout))
+ {
+ }
+ inline explicit NoMesh(const NoMeshData<Dim> &data)
+ : data_m(new NoMeshData<Dim>(data))
+ {
+ }
+ inline NoMesh(const NoMesh<Dim> &model)
+ : data_m(model.data_m)
+ {
+ }
+ inline NoMesh(const NoMesh<Dim> &model, const Interval<Dim> &d)
+ : data_m(new NoMeshData<Dim>(d))
+ {
+ }
+ NoMesh(const NoMesh<Dim> &model, const INode<Dim> &i)
+ : data_m(new NoMeshData<Dim>(i.domain()))
+ {
+ }
+ inline NoMesh(const NoMesh<Dim> &model, const FieldEnginePatch<Dim> &p)
+ : data_m(new NoMeshData<Dim>(*model.data_m, p))
+ {
+ }
+ template<class Mesh, class Domain>
+ inline NoMesh(const Mesh &, const Domain &d)
+ {
+ Interval<Dim> dom;
+ for (int i = 0; i < Dim; i++)
+ dom[i] = d[i].size();
+ data_m = new NoMeshData<Dim>(dom);
+ }
+ ~NoMesh() { }
+ const NoMeshData<Dim>& data() const
+ {
+ return *data_m;
+ }
+ NoMesh<Dim> &
+ operator=(const NoMesh<Dim> &rhs)
+ {
+ if (&rhs != this)
+ {
+ data_m = rhs.data_m;
+ }
+ return *this;
+ }
+ inline const Interval<Dim> &physicalVertexDomain() const
+ {
+ return data_m->physicalVertexDomain();
+ }
+ inline const Interval<Dim> &physicalCellDomain() const
+ {
+ return data_m->physicalCellDomain();
+ }
+ inline const Interval<Dim> &totalVertexDomain() const
+ {
+ return data_m->totalVertexDomain();
+ }
+ inline const Interval<Dim> &totalCellDomain() const
+ {
+ return data_m->totalCellDomain();
+ }
+ private:
+ RefCountedPtr<NoMeshData<Dim> > data_m;
+ };
+ template <class MeshTraits>
+ class UniformRectilinearMeshData : public NoMeshData<MeshTraits::dimensions>
+ {
+ public:
+ typedef typename MeshTraits::MeshData_t MeshData_t;
+ typedef typename MeshTraits::Domain_t Domain_t;
+ typedef typename MeshTraits::Scalar_t Scalar_t;
+ typedef typename MeshTraits::PointType_t PointType_t;
+ typedef typename MeshTraits::VectorType_t VectorType_t;
+ typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
+ typedef typename MeshTraits::PositionsType_t PositionsType_t;
+ enum { dimensions = MeshTraits::dimensions };
+ UniformRectilinearMeshData()
+ {
+ }
+ template<class Layout>
+ UniformRectilinearMeshData(
+ const Layout &layout,
+ const PointType_t &origin,
+ const SpacingsType_t &spacings)
+ : NoMeshData<dimensions>(layout),
+ origin_m(origin),
+ spacings_m(spacings)
+ {
+ }
+ UniformRectilinearMeshData(const MeshData_t &model)
+ : NoMeshData<dimensions>(model),
+ origin_m(model.origin_m),
+ spacings_m(model.spacings_m)
+ {
+ }
+ UniformRectilinearMeshData(const MeshData_t &model,
+ const Domain_t &d)
+ : NoMeshData<dimensions>(d),
+ origin_m(model.origin_m),
+ spacings_m(model.spacings_m)
+ {
+ for (int i = 0; i < dimensions; i++)
+ origin_m(i) +=
+ spacings_m(i) *
+ (d[i].first() - model.physicalCellDomain()[i].first());
+ }
+ MeshData_t &
+ operator=(const MeshData_t &rhs)
+ {
+ if (this != &rhs)
+ {
+ NoMeshData<dimensions>::operator=(rhs);
+ origin_m = rhs.origin_m;
+ spacings_m = rhs.spacings_m;
+ }
+ return *this;
+ }
+ ~UniformRectilinearMeshData() { }
+ inline const SpacingsType_t &spacings() const
+ {
+ return spacings_m;
+ }
+ inline const PointType_t &origin() const
+ {
+ return origin_m;
+ }
+ private:
+ PointType_t origin_m;
+ SpacingsType_t spacings_m;
+ };
+ template<class MeshTraits>
+ class UniformRectilinearMesh : public MeshTraits::CoordinateSystem_t
+ {
+ public:
+ typedef MeshTraits MeshTraits_t;
+ typedef typename MeshTraits::CoordinateSystem_t CoordinateSystem_t;
+ typedef typename MeshTraits::Mesh_t Mesh_t;
+ typedef typename MeshTraits::MeshData_t MeshData_t;
+ typedef typename MeshTraits::Loc_t Loc_t;
+ typedef typename MeshTraits::Domain_t Domain_t;
+ typedef typename MeshTraits::Scalar_t Scalar_t;
+ typedef typename MeshTraits::PointType_t PointType_t;
+ typedef typename MeshTraits::VectorType_t VectorType_t;
+ typedef typename MeshTraits::PositionsType_t PositionsType_t;
+ typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
+ typedef typename MeshTraits::T_t T_t;
+ enum { dimensions = MeshTraits::dimensions };
+ enum { coordinateDimensions = MeshTraits::coordinateDimensions };
+ UniformRectilinearMesh()
+ : data_m(new MeshData_t())
+ {
+ }
+ template<class Layout>
+ inline UniformRectilinearMesh(const Layout &layout,
+ const PointType_t &origin,
+ const SpacingsType_t &spacings)
+ : data_m(new MeshData_t(layout, origin, spacings))
+ {
+ }
+ template<class Layout>
+ inline explicit UniformRectilinearMesh(const Layout &layout)
+ : data_m(new MeshData_t(layout,
+ PointType_t(0),
+ SpacingsType_t(1)))
+ {
+ }
+ inline UniformRectilinearMesh(const Mesh_t &model)
+ : data_m(model.data_m)
+ {
+ }
+ inline UniformRectilinearMesh(const Mesh_t &model,
+ const Domain_t &d)
+ : data_m(new MeshData_t(*model.data_m, d))
+ {
+ }
+ inline UniformRectilinearMesh(const Mesh_t &model,
+ const INode<dimensions> &i)
+ : data_m(new MeshData_t(*model.data_m, i.domain()))
+ {
+ }
+ inline Mesh_t &
+ operator=(const Mesh_t &rhs)
+ {
+ if (&rhs != this)
+ {
+ data_m = rhs.data_m;
+ }
+ return *this;
+ }
+ ~UniformRectilinearMesh()
+ {
+ }
+ const MeshData_t& data() const
+ {
+ return *data_m;
+ }
+ inline const Domain_t &physicalVertexDomain() const
+ {
+ return data_m->physicalVertexDomain();
+ }
+ inline const Domain_t &physicalCellDomain() const
+ {
+ return data_m->physicalCellDomain();
+ }
+ inline const Domain_t &totalVertexDomain() const
+ {
+ return data_m->totalVertexDomain();
+ }
+ inline const Domain_t &totalCellDomain() const
+ {
+ return data_m->totalCellDomain();
+ }
+ inline const PointType_t &origin() const
+ {
+ return data_m->origin();
+ }
+ inline const SpacingsType_t &spacings() const
+ {
+ return data_m->spacings();
+ }
+ inline Loc_t cellContaining(const PointType_t &point) const
+ {
+ Loc_t loc((Pooma::NoInit()));
+ for (int i = 0; i < dimensions; i++)
+ loc[i] =
+ Loc<1>(static_cast<int>((point(i) - origin()(i)) / spacings()(i)));
+ return loc;
+ }
+ inline PointType_t vertexPosition(const Loc_t &loc) const
+ {
+ PointType_t point;
+ for (int i = 0; i < dimensions; i++)
+ point(i) = origin()(i) + spacings()(i) *
+ (loc[i].first() - physicalCellDomain()[i].first());
+ return point;
+ }
+ inline Scalar_t vertexPosition(int dim, int i) const
+ {
+ return origin()(dim) + spacings()(dim)
+ * (i - physicalCellDomain()[dim].first());
+ }
+ inline PointType_t cellPosition(const Loc_t &loc) const
+ {
+ PointType_t point;
+ for (int i=0; i<dimensions; i++)
+ point(i) = origin()(i) + spacings()(i)
+ * (loc[i].first() - physicalCellDomain()[i].first() + 0.5);
+ return point;
+ }
+ inline Scalar_t cellPosition(int dim, int i) const
+ {
+ return origin()(dim) + spacings()(dim)
+ * (i - physicalCellDomain()[dim].first() + 0.5);
+ }
+ inline VectorType_t vertexSpacing(const Loc_t &loc) const
+ {
+ return spacings();
+ }
+ inline Scalar_t vertexSpacing(int dim, int = 0) const
+ {
+ return spacings()(dim);
+ }
+ inline VectorType_t cellSpacing(const Loc_t &loc) const
+ {
+ return spacings();
+ }
+ inline Scalar_t cellSpacing(int dim, int = 0) const
+ {
+ return spacings()(dim);
+ }
+ private:
+ RefCountedPtr<MeshData_t > data_m;
+ };
+ template <class MeshTraits>
+ struct GenericURM {
+ typedef typename MeshTraits::T_t T_t;
+ typedef typename MeshTraits::Mesh_t Mesh_t;
+ typedef typename MeshTraits::PointType_t PointType_t;
+ typedef typename MeshTraits::VectorType_t VectorType_t;
+ typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
+ typedef typename MeshTraits::Loc_t Loc_t;
+ typedef typename MeshTraits::CIndexType_t CIndexType_t;
+ enum { dimensions = MeshTraits::dimensions };
+ enum { coordinateDimensions = MeshTraits::coordinateDimensions };
+ class PositionsFunctor {
+ public:
+ PositionsFunctor() { }
+ PositionsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : origin_m(m.origin()), spacings_m(m.spacings())
+ {
+ for (int i = 0; i < dimensions; i++)
+ origin_m(i) += spacings_m(i) *
+ (c.position(0)(i) - m.physicalCellDomain()[i].first());
+ }
+ inline PointType_t operator()(int i0) const
+ {
+ CIndexType_t i(0);
+ i(0) = i0;
+ return origin_m + i * spacings_m;
+ }
+ inline PointType_t operator()(int i0, int i1) const
+ {
+ CIndexType_t i(0);
+ i(0) = i0;
+ i(1) = i1;
+ return origin_m + i * spacings_m;
+ }
+ inline PointType_t operator()(int i0, int i1, int i2) const
+ {
+ CIndexType_t i(0);
+ i(0) = i0;
+ i(1) = i1;
+ i(2) = i2;
+ return origin_m + i * spacings_m;
+ }
+ private:
+ PointType_t origin_m;
+ SpacingsType_t spacings_m;
+ };
+ typedef IndexFunction<PositionsFunctor> PositionsEngineTag_t;
+ template <class PositionsEngineTag>
+ void initializePositions(
+ Engine<dimensions, PointType_t, PositionsEngineTag> &e,
+ const Centering<dimensions> &c) const
+ {
+ e.setFunctor(typename PositionsEngineTag::Functor_t(static_cast<const Mesh_t&>(*this), c));
+ }
+ typedef ConstantFunction SpacingsEngineTag_t;
+ void initializeSpacings(
+ Engine<dimensions, VectorType_t, SpacingsEngineTag_t> &e,
+ const Centering<dimensions> &) const
+ {
+ e.setConstant(static_cast<const Mesh_t&>(*this).spacings());
+ }
+ typedef ConstantFunction NormalsEngineTag_t;
+ void initializeNormals(
+ Engine<dimensions, VectorType_t, NormalsEngineTag_t> &e,
+ const Centering<dimensions> &c,
+ bool outward = true) const
+ {
+ ;
+ ;
+ VectorType_t normal;
+ for (int i = 0; i < dimensions; i++)
+ {
+ normal(i) = static_cast<T_t>(1 - c.orientation(0)[i].first());
+ if (outward && c.position(0)(i) == 0.0)
+ normal(i) *= static_cast<T_t>(-1);
+ }
+ e.setConstant(normal);
+ }
+ inline T_t DDX0(int) const { return 0.5; }
+ inline T_t DDX0(const Loc_t&) const { return 0.5; }
+ inline T_t DDX1(int) const { return 0.5; }
+ inline T_t DDX1(const Loc_t&) const { return 0.5; }
+ inline T_t DDY0(int) const { return 0.5; }
+ inline T_t DDY0(const Loc_t&) const { return 0.5; }
+ inline T_t DDY1(int) const { return 0.5; }
+ inline T_t DDY1(const Loc_t&) const { return 0.5; }
+ inline T_t DDZ0(int) const { return 0.5; }
+ inline T_t DDZ0(const Loc_t&) const { return 0.5; }
+ inline T_t DDZ1(int) const { return 0.5; }
+ inline T_t DDZ1(const Loc_t&) const { return 0.5; }
+ };
+ template <class MeshTraits>
+ class RectilinearMeshData : public NoMeshData<MeshTraits::dimensions>
+ {
+ public:
+ typedef typename MeshTraits::Domain_t Domain_t;
+ typedef typename MeshTraits::MeshData_t MeshData_t;
+ typedef typename MeshTraits::Scalar_t Scalar_t;
+ typedef typename MeshTraits::PointType_t PointType_t;
+ typedef typename MeshTraits::VectorType_t VectorType_t;
+ typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
+ typedef typename MeshTraits::PositionsType_t PositionsType_t;
+ enum { dimensions = MeshTraits::dimensions };
+ RectilinearMeshData()
+ {
+ }
+ template<class Layout>
+ RectilinearMeshData(
+ const Layout &layout,
+ const PointType_t &origin,
+ const SpacingsType_t &spacings)
+ : NoMeshData<dimensions>(layout),
+ origin_m(origin)
+ {
+ typedef Engine<1, Scalar_t, Brick> Engine_t;
+ for (int i=0; i<dimensions; i++) {
+ Interval<1> dom(layout.domain()[i]), idom(layout.innerDomain()[i]);
+ spacings_m[i].engine() = Engine_t(dom);
+ spacings_m[i] = spacings[i];
+ Pooma::blockAndEvaluate();
+ positions_m[i].engine() = Engine_t(dom);
+ positions_m[i](idom.min()) = origin_m(i);
+ for (int j=idom.min()-1; j>=dom.min(); j--)
+ positions_m[i](j) = positions_m[i].read(j+1) - spacings_m[i].read(j);
+ for (int j=idom.min()+1; j<=dom.max(); j++)
+ positions_m[i](j) = positions_m[i].read(j-1) + spacings_m[i].read(j-1);
+ }
+ }
+ template<class Layout>
+ RectilinearMeshData(
+ const Layout &layout,
+ const PointType_t &origin,
+ const VectorType_t &spacings)
+ : NoMeshData<dimensions>(layout),
+ origin_m(origin)
+ {
+ for (int i=0; i<dimensions; i++) {
+ Interval<1> dom(layout.domain()[i]), idom(layout.innerDomain()[i]);
+ spacings_m[i].engine() = Engine<1, Scalar_t, Brick>(dom, spacings(i));
+ positions_m[i].engine() = Engine<1, Scalar_t, Brick>(dom);
+ positions_m[i](idom.min()) = origin_m(i);
+ for (int j=idom.min()-1; j>=dom.min(); j--)
+ positions_m[i](j) = positions_m[i].read(j+1) - spacings_m[i].read(j);
+ for (int j=idom.min()+1; j<=dom.max(); j++)
+ positions_m[i](j) = positions_m[i].read(j-1) + spacings_m[i].read(j-1);
+ }
+ }
+ RectilinearMeshData(const MeshData_t &model)
+ : NoMeshData<dimensions>(model),
+ origin_m(model.origin_m)
+ {
+ for (int i=0; i<dimensions; i++) {
+ spacings_m[i].engine() = model.spacings_m[i].engine();
+ positions_m[i].engine() = model.positions_m[i].engine();
+ }
+ }
+ RectilinearMeshData(const MeshData_t &model,
+ const Interval<dimensions> &d)
+ : NoMeshData<dimensions>(d)
+ {
+ typedef Engine<1, Scalar_t, Brick> Engine_t;
+ for (int i = 0; i < dimensions; i++) {
+ Interval<1> dom(d[i]);
+ Interval<1> viewdom(dom.size());
+ spacings_m[i].engine() = Engine_t(&model.spacings_m[i](dom)(0),
+ viewdom);
+ positions_m[i].engine() = Engine_t(&model.positions_m[i](dom)(0),
+ viewdom);
+ origin_m(i) = model.positions_m[i].read(dom.min());
+ }
+ }
+ MeshData_t &
+ operator=(const MeshData_t &rhs)
+ {
+ if (this != &rhs)
+ {
+ NoMeshData<dimensions>::operator=(rhs);
+ origin_m = rhs.origin_m;
+ for (int i=0; i<dimensions; i++) {
+ spacings_m[i].engine() = rhs.spacings_m[i].engine();
+ positions_m[i].engine() = rhs.positions_m[i].engine();
+ }
+ }
+ return *this;
+ }
+ ~RectilinearMeshData() { }
+ inline const SpacingsType_t &spacings() const
+ {
+ return spacings_m;
+ }
+ inline const PositionsType_t &positions() const
+ {
+ return positions_m;
+ }
+ inline const PointType_t &origin() const
+ {
+ return origin_m;
+ }
+ private:
+ PointType_t origin_m;
+ SpacingsType_t spacings_m;
+ PositionsType_t positions_m;
+ };
+ template<class MeshTraits>
+ class RectilinearMesh : public MeshTraits::CoordinateSystem_t
+ {
+ public:
+ typedef MeshTraits MeshTraits_t;
+ typedef typename MeshTraits::Mesh_t Mesh_t;
+ typedef typename MeshTraits::MeshData_t MeshData_t;
+ typedef typename MeshTraits::CoordinateSystem_t CoordinateSystem_t;
+ typedef typename MeshTraits::Domain_t Domain_t;
+ typedef typename MeshTraits::Loc_t Loc_t;
+ typedef typename MeshTraits::T_t T_t;
+ typedef typename MeshTraits::Scalar_t Scalar_t;
+ typedef typename MeshTraits::PointType_t PointType_t;
+ typedef typename MeshTraits::VectorType_t VectorType_t;
+ typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
+ typedef typename MeshTraits::PositionsType_t PositionsType_t;
+ enum { dimensions = MeshTraits::dimensions };
+ enum { coordinateDimensions = MeshTraits::coordinateDimensions };
+ RectilinearMesh()
+ : data_m(new MeshData_t)
+ {
+ }
+ template<class Layout>
+ inline RectilinearMesh(const Layout &layout,
+ const PointType_t &origin,
+ const SpacingsType_t &spacings)
+ : data_m(new MeshData_t(layout, origin, spacings))
+ {
+ }
+ template<class Layout>
+ inline RectilinearMesh(const Layout &layout,
+ const PointType_t &origin,
+ const PointType_t &spacings)
+ : data_m(new MeshData_t(layout, origin, spacings))
+ {
+ }
+ template<class Layout>
+ inline explicit RectilinearMesh(const Layout &layout)
+ : data_m(new MeshData_t(layout,
+ PointType_t(0),
+ PointType_t(1)))
+ {
+ }
+ inline RectilinearMesh(const Mesh_t &model)
+ : data_m(model.data_m)
+ {
+ }
+ inline RectilinearMesh(const Mesh_t &model,
+ const Domain_t &d)
+ : data_m(new MeshData_t(*model.data_m, d))
+ {
+ }
+ inline RectilinearMesh(const Mesh_t &model,
+ const INode<dimensions> &i)
+ : data_m(new MeshData_t(*model.data_m, i.domain()))
+ {
+ }
+ inline Mesh_t &
+ operator=(const Mesh_t &rhs)
+ {
+ if (&rhs != this)
+ {
+ data_m = rhs.data_m;
+ }
+ return *this;
+ }
+ ~RectilinearMesh()
+ {
+ }
+ const MeshData_t& data() const
+ {
+ return *data_m;
+ }
+ inline const Domain_t &physicalVertexDomain() const
+ {
+ return data_m->physicalVertexDomain();
+ }
+ inline const Domain_t &physicalCellDomain() const
+ {
+ return data_m->physicalCellDomain();
+ }
+ inline const Domain_t &totalVertexDomain() const
+ {
+ return data_m->totalVertexDomain();
+ }
+ inline const Domain_t &totalCellDomain() const
+ {
+ return data_m->totalCellDomain();
+ }
+ inline const PointType_t &origin() const
+ {
+ return data_m->origin();
+ }
+ inline const SpacingsType_t &spacings() const
+ {
+ return data_m->spacings();
+ }
+ inline const PositionsType_t &positions() const
+ {
+ return data_m->positions();
+ }
+ inline Loc_t cellContaining(const PointType_t &point) const
+ {
+ Loc_t loc((Pooma::NoInit()));
+ for (int i = 0; i < dimensions; i++)
+ {
+ const T_t *start = &positions()[i](0);
+ const T_t *finish = start + positions()[i].physicalDomain()[i].length();
+ const T_t *p = std::lower_bound(start, finish, point(i));
+ int j = static_cast<int>(std::distance(start, p));
+ if (*p == point(i))
+ loc[i] = j;
+ else
+ loc[i] = j-1;
+ }
+ return loc;
+ }
+ inline PointType_t vertexPosition(const Loc_t &loc) const
+ {
+ PointType_t point;
+ for (int i = 0; i < dimensions; i++)
+ point(i) = positions()[i](loc[i]);
+ return point;
+ }
+ inline Scalar_t vertexPosition(int dim, int i) const
+ {
+ return positions()[dim](i);
+ }
+ inline PointType_t cellPosition(const Loc_t &loc) const
+ {
+ PointType_t point;
+ for (int i=0; i<dimensions; i++)
+ point(i) = positions()[i](loc[i]) + 0.5*spacings()[i](loc[i]);
+ return point;
+ }
+ inline Scalar_t cellPosition(int dim, int i) const
+ {
+ return positions()[dim](i) + 0.5*spacings()[dim](i);
+ }
+ inline VectorType_t vertexSpacing(const Loc_t &loc) const
+ {
+ VectorType_t delta;
+ for (int i=0; i<dimensions; i++)
+ delta(i) = spacings()[i](loc[i]);
+ return delta;
+ }
+ inline Scalar_t vertexSpacing(int dim, int i) const
+ {
+ return spacings()[dim](i);
+ }
+ inline VectorType_t cellSpacing(const Loc_t &loc) const
+ {
+ VectorType_t delta;
+ for (int i=0; i<dimensions; i++)
+ delta(i) = 0.5 * (spacings()[i](loc[i]) + spacings()[i](loc[i]+1));
+ return delta;
+ }
+ inline Scalar_t cellSpacing(int dim, int i) const
+ {
+ return 0.5*(spacings()[dim](i) + spacings()[dim](i+1));
+ }
+ private:
+ RefCountedPtr<MeshData_t> data_m;
+ };
+ template <class MeshTraits>
+ struct GenericRM {
+ typedef typename MeshTraits::T_t T_t;
+ typedef typename MeshTraits::Mesh_t Mesh_t;
+ typedef typename MeshTraits::PointType_t PointType_t;
+ typedef typename MeshTraits::VectorType_t VectorType_t;
+ typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
+ typedef typename MeshTraits::PositionsType_t PositionsType_t;
+ typedef typename MeshTraits::Loc_t Loc_t;
+ enum { dimensions = MeshTraits::dimensions };
+ enum { coordinateDimensions = MeshTraits::coordinateDimensions };
+ class PositionsFunctor {
+ public:
+ PositionsFunctor() { }
+ PositionsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : centering_m(c.position(0))
+ {
+ for (int i=0; i<dimensions; i++) {
+ positions_m[i].engine() = m.positions()[i].engine();
+ spacings_m[i].engine() = m.spacings()[i].engine();
+ }
+ }
+ PositionsFunctor(const PositionsFunctor &m)
+ : centering_m(m.centering_m)
+ {
+ for (int i=0; i<dimensions; i++) {
+ positions_m[i].engine() = m.positions_m[i].engine();
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ }
+ }
+ PositionsFunctor& operator=(const PositionsFunctor &m)
+ {
+ centering_m = m.centering_m;
+ for (int i=0; i<dimensions; i++) {
+ positions_m[i].engine() = m.positions_m[i].engine();
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ }
+ return *this;
+ }
+ inline PointType_t operator()(int i0) const
+ {
+ return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0));
+ }
+ inline PointType_t operator()(int i0, int i1) const
+ {
+ return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
+ positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1));
+ }
+ inline PointType_t operator()(int i0, int i1, int i2) const
+ {
+ return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
+ positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1),
+ positions_m[2].read(i2) + spacings_m[2].read(i2)*centering_m(2));
+ }
+ private:
+ PositionsType_t positions_m;
+ SpacingsType_t spacings_m;
+ typename Centering<dimensions>::Position centering_m;
+ };
+ typedef IndexFunction<PositionsFunctor> PositionsEngineTag_t;
+ template <class PositionsEngineTag>
+ void initializePositions(
+ Engine<dimensions, PointType_t, PositionsEngineTag> &e,
+ const Centering<dimensions> &c) const
+ {
+ e.setFunctor(typename PositionsEngineTag::Functor_t(static_cast<const Mesh_t&>(*this), c));
+ }
+ class SpacingsFunctor {
+ public:
+ SpacingsFunctor() { }
+ SpacingsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : centering_m(c.position(0))
+ {
+ for (int i=0; i<dimensions; i++)
+ spacings_m[i].engine() = m.spacings()[i].engine();
+ }
+ SpacingsFunctor(const SpacingsFunctor &m)
+ : centering_m(m.centering_m)
+ {
+ for (int i=0; i<dimensions; i++)
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ }
+ SpacingsFunctor& operator=(const SpacingsFunctor &m)
+ {
+ centering_m = m.centering_m;
+ for (int i=0; i<dimensions; i++)
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ return *this;
+ }
+ inline VectorType_t operator()(int i0) const
+ {
+ return VectorType_t(spacings_m[0].read(i0)
+ + (spacings_m[0].read(i0+1)-spacings_m[0].read(i0))*centering_m(0));
+ }
+ inline VectorType_t operator()(int i0, int i1) const
+ {
+ return VectorType_t(spacings_m[0].read(i0)
+ + (spacings_m[0].read(i0+1)-spacings_m[0].read(i0))*centering_m(0),
+ spacings_m[1].read(i1)
+ + (spacings_m[1].read(i1+1)-spacings_m[1].read(i1))*centering_m(1));
+ }
+ inline VectorType_t operator()(int i0, int i1, int i2) const
+ {
+ return VectorType_t(spacings_m[0].read(i0)
+ + (spacings_m[0].read(i0+1)-spacings_m[0].read(i0))*centering_m(0),
+ spacings_m[1].read(i1)
+ + (spacings_m[1].read(i1+1)-spacings_m[1].read(i1))*centering_m(1),
+ spacings_m[2].read(i2)
+ + (spacings_m[2].read(i2+1)-spacings_m[2].read(i2))*centering_m(2));
+ }
+ private:
+ SpacingsType_t spacings_m;
+ typename Centering<dimensions>::Position centering_m;
+ };
+ typedef IndexFunction<SpacingsFunctor> SpacingsEngineTag_t;
+ void initializeSpacings(
+ Engine<dimensions, PointType_t, SpacingsEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ e.setFunctor(SpacingsFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ typedef ConstantFunction NormalsEngineTag_t;
+ void initializeNormals(
+ Engine<dimensions, VectorType_t, NormalsEngineTag_t> &e,
+ const Centering<dimensions> &c,
+ bool outward = true) const
+ {
+ ;
+ ;
+ VectorType_t normal;
+ for (int i = 0; i < dimensions; i++)
+ {
+ normal(i) = static_cast<T_t>(1 - c.orientation(0)[i].first());
+ if (outward && c.position(0)(i) == 0.0)
+ normal(i) *= static_cast<T_t>(-1);
+ }
+ e.setConstant(normal);
+ }
+ inline T_t DDX0(int i) const
+ {
+ return (static_cast<const Mesh_t&>(*this).cellPosition( 0, i)
+ - static_cast<const Mesh_t&>(*this).vertexPosition( 0, i))
+ / static_cast<const Mesh_t&>(*this).cellSpacing( 0, i-1);
+ }
+ inline T_t DDX0(const Loc_t& l) const { return DDX0(l[0].first()); }
+ inline T_t DDX1(int i) const
+ {
+ return (static_cast<const Mesh_t&>(*this).vertexPosition( 0, i)
+ - static_cast<const Mesh_t&>(*this).cellPosition( 0, i-1))
+ / static_cast<const Mesh_t&>(*this).cellSpacing( 0, i-1);
+ }
+ inline T_t DDX1(const Loc_t& l) const { return DDX0(l[0].first()); }
+ inline T_t DDY0(int j) const
+ {
+ return (static_cast<const Mesh_t&>(*this).cellPosition( 1, j)
+ - static_cast<const Mesh_t&>(*this).vertexPosition( 1, j))
+ / static_cast<const Mesh_t&>(*this).cellSpacing( 1, j-1);
+ }
+ inline T_t DDY0(const Loc_t& l) const { return DDX0(l[0].first()); }
+ inline T_t DDY1(int j) const
+ {
+ return (static_cast<const Mesh_t&>(*this).vertexPosition( 1, j)
+ - static_cast<const Mesh_t&>(*this).cellPosition( 1, j-1))
+ / static_cast<const Mesh_t&>(*this).cellSpacing( 1, j-1);
+ }
+ inline T_t DDY1(const Loc_t& l) const { return DDX0(l[0].first()); }
+ inline T_t DDZ0(int k) const
+ {
+ return (static_cast<const Mesh_t&>(*this).cellPosition( 2, k)
+ - static_cast<const Mesh_t&>(*this).vertexPosition( 2, k))
+ / static_cast<const Mesh_t&>(*this).cellSpacing( 2, k-1);
+ }
+ inline T_t DDZ0(const Loc_t& l) const { return DDX0(l[0].first()); }
+ inline T_t DDZ1(int k) const
+ {
+ return (static_cast<const Mesh_t&>(*this).vertexPosition( 1, k)
+ - static_cast<const Mesh_t&>(*this).cellPosition( 1, k-1))
+ / static_cast<const Mesh_t&>(*this).cellSpacing( 1, k-1);
+ }
+ inline T_t DDZ1(const Loc_t& l) const { return DDX0(l[0].first()); }
+ };
+ template <class MeshTraits>
+ struct CartesianRM : public GenericRM<MeshTraits> {
+ typedef typename MeshTraits::T_t T_t;
+ typedef typename MeshTraits::Mesh_t Mesh_t;
+ typedef typename MeshTraits::PointType_t PointType_t;
+ typedef typename MeshTraits::VectorType_t VectorType_t;
+ typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
+ typedef typename MeshTraits::PositionsType_t PositionsType_t;
+ enum { dimensions = MeshTraits::dimensions };
+ enum { coordinateDimensions = MeshTraits::coordinateDimensions };
+ class GeneralVolumesFunctor {
+ public:
+ GeneralVolumesFunctor() { }
+ GeneralVolumesFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : orientation_m(c.orientation(0))
+ {
+ for (int i=0; i<dimensions; i++)
+ spacings_m[i].engine() = m.spacings()[i].engine();
+ }
+ GeneralVolumesFunctor(const GeneralVolumesFunctor &m)
+ : orientation_m(m.orientation_m)
+ {
+ for (int i=0; i<dimensions; i++)
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ }
+ GeneralVolumesFunctor& operator=(const GeneralVolumesFunctor &m)
+ {
+ orientation_m = m.orientation_m;
+ for (int i=0; i<dimensions; i++)
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ return *this;
+ }
+ inline T_t operator()(int i0) const
+ {
+ return spacings_m[0].read(i0);
+ }
+ inline T_t operator()(int i0, int i1) const
+ {
+ if (orientation_m[0].first() == 0)
+ return spacings_m[1].read(i1);
+ else if (orientation_m[1].first() == 0)
+ return spacings_m[0].read(i0);
+ else
+ return spacings_m[0].read(i0) * spacings_m[1].read(i1);
+ }
+ inline T_t operator()(int i0, int i1, int i2) const
+ {
+ T_t volume = static_cast<T_t>(1);
+ if (orientation_m[0].first() != 0)
+ volume *= spacings_m[0].read(i0);
+ if (orientation_m[1].first() != 0)
+ volume *= spacings_m[1].read(i1);
+ if (orientation_m[2].first() != 0)
+ volume *= spacings_m[2].read(i2);
+ return volume;
+ }
+ private:
+ SpacingsType_t spacings_m;
+ typename Centering<dimensions>::Orientation orientation_m;
+ };
+ typedef IndexFunction<GeneralVolumesFunctor> CellVolumesEngineTag_t;
+ void initializeCellVolumes(
+ Engine<dimensions, T_t, CellVolumesEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ typedef IndexFunction<GeneralVolumesFunctor> FaceAreasEngineTag_t;
+ void initializeFaceAreas(
+ Engine<dimensions, T_t, FaceAreasEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ typedef IndexFunction<GeneralVolumesFunctor> EdgeLengthsEngineTag_t;
+ void initializeEdgeLengths(
+ Engine<dimensions, T_t, EdgeLengthsEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ class SphericalPositionsFunctor {
+ public:
+ SphericalPositionsFunctor() {}
+ SphericalPositionsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : centering_m(c.position(0))
+ {
+ for (int i = 0; i < dimensions; i++) {
+ positions_m[i].engine() = m.positions()[i].engine();
+ spacings_m[i].engine() = m.spacings()[i].engine();
+ }
+ }
+ SphericalPositionsFunctor& operator=(const SphericalPositionsFunctor& m)
+ {
+ centering_m = m.centering_m;
+ for (int i = 0; i < dimensions; i++) {
+ positions_m[i].engine() = m.positions_m[i].engine();
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ }
+ return *this;
+ }
+ inline PointType_t operator()(int i0) const
+ {
+ return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0));
+ }
+ inline PointType_t operator()(int i0, int i1) const
+ {
+ PointType_t x(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
+ positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1));
+ return PointType_t(norm(x),
+ atan2(x(0), x(1)));
+ }
+ inline PointType_t operator()(int i0, int i1, int i2) const
+ {
+ PointType_t x(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
+ positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1),
+ positions_m[2].read(i2) + spacings_m[2].read(i2)*centering_m(2));
+ T_t r = norm(x);
+ return PointType_t(r,
+ acos(x(2)/r),
+ atan2(x(1), x(0)));
+ }
+ private:
+ PositionsType_t positions_m;
+ SpacingsType_t spacings_m;
+ typename Centering<dimensions>::Position centering_m;
+ };
+ class CylindricalPositionsFunctor {
+ public:
+ CylindricalPositionsFunctor() {}
+ CylindricalPositionsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : centering_m(c.position(0))
+ {
+ for (int i = 0; i < dimensions; i++) {
+ positions_m[i].engine() = m.positions()[i].engine();
+ spacings_m[i].engine() = m.spacings()[i].engine();
+ }
+ }
+ CylindricalPositionsFunctor& operator=(const CylindricalPositionsFunctor& m)
+ {
+ centering_m = m.centering_m;
+ for (int i = 0; i < dimensions; i++) {
+ positions_m[i].engine() = m.positions_m[i].engine();
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ }
+ return *this;
+ }
+ inline PointType_t operator()(int i0) const
+ {
+ return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0));
+ }
+ inline PointType_t operator()(int i0, int i1) const
+ {
+ return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
+ positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1));
+ }
+ inline PointType_t operator()(int i0, int i1, int i2) const
+ {
+ PointType_t x(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
+ positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1),
+ positions_m[2].read(i2) + spacings_m[2].read(i2)*centering_m(2));
+ return PointType_t(norm(Vector<2, T_t>(x(0), x(1))),
+ x(2),
+ atan2(x(1), x(0)));
+ }
+ private:
+ PositionsType_t positions_m;
+ SpacingsType_t spacings_m;
+ typename Centering<dimensions>::Position centering_m;
+ };
+ typedef IndexFunction<typename GenericRM<MeshTraits>::PositionsFunctor> CartesianPositionsEngineTag_t;
+ typedef IndexFunction<CylindricalPositionsFunctor> CylindricalPositionsEngineTag_t;
+ typedef IndexFunction<SphericalPositionsFunctor> SphericalPositionsEngineTag_t;
+ inline T_t VOLXA(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellSpacing( 0, i);
+ }
+ inline T_t VOLXA(const Loc<dimensions>& l) const { return VOLXA(l[0].first()); }
+ inline T_t VOLYA(int j) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellSpacing( 1, j);
+ }
+ inline T_t VOLYA(const Loc<dimensions>& l) const { return VOLYA(l[1].first()); }
+ inline T_t VOLZA(int k) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellSpacing( 2, k);
+ }
+ inline T_t VOLZA(const Loc<dimensions>& l) const { return VOLZA(l[2].first()); }
+ inline T_t VOLXB(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexSpacing( 0, i);
+ }
+ inline T_t VOLXB(const Loc<dimensions>& l) const { return VOLXB(l[0].first()); }
+ inline T_t VOLYB(int j) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexSpacing( 1, j);
+ }
+ inline T_t VOLYB(const Loc<dimensions>& l) const { return VOLYB(l[1].first()); }
+ inline T_t VOLZB(int k) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexSpacing( 2, k);
+ }
+ inline T_t VOLZB(const Loc<dimensions>& l) const { return VOLZB(l[2].first()); }
+ inline One<T_t> SURXA(int) const { return One<T_t>(); }
+ inline One<T_t> SURXA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> SURYA(int) const { return One<T_t>(); }
+ inline One<T_t> SURYA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> SURZA(int) const { return One<T_t>(); }
+ inline One<T_t> SURZA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> SURXB(int) const { return One<T_t>(); }
+ inline One<T_t> SURXB(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> SURYB(int) const { return One<T_t>(); }
+ inline One<T_t> SURYB(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> SURZB(int) const { return One<T_t>(); }
+ inline One<T_t> SURZB(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline Zero<T_t> CCXA(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCXA(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCYA(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCYA(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZA(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZA(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCXB(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCXB(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCYB(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCYB(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZB(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZB(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline One<T_t> GEOXG(int) const { return One<T_t>(); }
+ inline One<T_t> GEOXG(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> GEOXH(int) const { return One<T_t>(); }
+ inline One<T_t> GEOXH(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> GEOYH(int) const { return One<T_t>(); }
+ inline One<T_t> GEOYH(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> GEOXGA(int) const { return One<T_t>(); }
+ inline One<T_t> GEOXGA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> GEOXHA(int) const { return One<T_t>(); }
+ inline One<T_t> GEOXHA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> GEOYHA(int) const { return One<T_t>(); }
+ inline One<T_t> GEOYHA(const Loc<dimensions>&) const { return One<T_t>(); }
+ };
+ template <class MeshTraits>
+ struct CartesianURM : public GenericURM<MeshTraits> {
+ typedef typename MeshTraits::T_t T_t;
+ typedef typename MeshTraits::Mesh_t Mesh_t;
+ typedef typename MeshTraits::PointType_t PointType_t;
+ typedef typename MeshTraits::VectorType_t VectorType_t;
+ typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
+ enum { dimensions = MeshTraits::dimensions };
+ enum { coordinateDimensions = MeshTraits::coordinateDimensions };
+ inline void initializeGeneralVolume(
+ Engine<dimensions, T_t, ConstantFunction> &e,
+ const Centering<dimensions> &c) const
+ {
+ T_t volume = static_cast<T_t>(1);
+ for (int i = 0; i < dimensions; i++)
+ {
+ if (c.orientation(0)[i].first() != 0)
+ volume *= static_cast<const Mesh_t&>(*this).spacings()(i);
+ }
+ e.setConstant(volume);
+ }
+ typedef ConstantFunction CellVolumesEngineTag_t;
+ void initializeCellVolumes(
+ Engine<dimensions, T_t, CellVolumesEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ initializeGeneralVolume(e, c);
+ }
+ typedef ConstantFunction FaceAreasEngineTag_t;
+ void initializeFaceAreas(
+ Engine<dimensions, T_t, FaceAreasEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ initializeGeneralVolume(e, c);
+ }
+ typedef ConstantFunction EdgeLengthsEngineTag_t;
+ void initializeEdgeLengths(
+ Engine<dimensions, T_t, EdgeLengthsEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ initializeGeneralVolume(e, c);
+ }
+ class SphericalPositionsFunctor {
+ public:
+ SphericalPositionsFunctor() {}
+ SphericalPositionsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : origin_m(m.origin()), spacings_m(m.spacings())
+ {
+ for (int i = 0; i < dimensions; i++)
+ origin_m(i) += spacings_m(i) *
+ (c.position(0)(i) - m.physicalCellDomain()[i].first());
+ }
+ inline PointType_t operator()(int i0) const
+ {
+ return origin_m + PointType_t(i0) * spacings_m;
+ }
+ inline PointType_t operator()(int i0, int i1) const
+ {
+ PointType_t x(origin_m + PointType_t(i0, i1) * spacings_m);
+ return PointType_t(norm(x),
+ atan2(x(0), x(1)));
+ }
+ inline PointType_t operator()(int i0, int i1, int i2) const
+ {
+ PointType_t x(origin_m + PointType_t(i0, i1, i2) * spacings_m);
+ T_t r = norm(x);
+ return PointType_t(r,
+ acos(x(2)/r),
+ atan2(x(1), x(0)));
+ }
+ private:
+ PointType_t origin_m;
+ SpacingsType_t spacings_m;
+ };
+ class CylindricalPositionsFunctor {
+ public:
+ CylindricalPositionsFunctor() {}
+ CylindricalPositionsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : origin_m(m.origin()), spacings_m(m.spacings())
+ {
+ for (int i = 0; i < dimensions; i++)
+ origin_m(i) += spacings_m(i) *
+ (c.position(0)(i) - m.physicalCellDomain()[i].first());
+ }
+ inline PointType_t operator()(int i0) const
+ {
+ return origin_m + PointType_t(i0) * spacings_m;
+ }
+ inline PointType_t operator()(int i0, int i1) const
+ {
+ return origin_m + PointType_t(i0, i1) * spacings_m;
+ }
+ inline PointType_t operator()(int i0, int i1, int i2) const
+ {
+ PointType_t x(origin_m + PointType_t(i0, i1, i2) * spacings_m);
+ return PointType_t(norm(Vector<2, T_t>(x(0), x(1))),
+ x(2),
+ atan2(x(1), x(0)));
+ }
+ private:
+ PointType_t origin_m;
+ SpacingsType_t spacings_m;
+ };
+ typedef IndexFunction<typename GenericURM<MeshTraits>::PositionsFunctor> CartesianPositionsEngineTag_t;
+ typedef IndexFunction<CylindricalPositionsFunctor> CylindricalPositionsEngineTag_t;
+ typedef IndexFunction<SphericalPositionsFunctor> SphericalPositionsEngineTag_t;
+ inline T_t VOLXA(int) const
+ {
+ return static_cast<const Mesh_t&>(*this).spacings()(0);
+ }
+ inline T_t VOLXA(const Loc<dimensions>&) const { return VOLXA(0); }
+ inline T_t VOLYA(int) const
+ {
+ return static_cast<const Mesh_t&>(*this).spacings()(1);
+ }
+ inline T_t VOLYA(const Loc<dimensions>&) const { return VOLYA(0); }
+ inline T_t VOLZA(int) const
+ {
+ return static_cast<const Mesh_t&>(*this).spacings()(2);
+ }
+ inline T_t VOLZA(const Loc<dimensions>&) const { return VOLZA(0); }
+ inline T_t VOLXB(int) const
+ {
+ return static_cast<const Mesh_t&>(*this).spacings()(0);
+ }
+ inline T_t VOLXB(const Loc<dimensions>&) const { return VOLXB(0); }
+ inline T_t VOLYB(int) const
+ {
+ return static_cast<const Mesh_t&>(*this).spacings()(1);
+ }
+ inline T_t VOLYB(const Loc<dimensions>&) const { return VOLYB(0); }
+ inline T_t VOLZB(int) const
+ {
+ return static_cast<const Mesh_t&>(*this).spacings()(2);
+ }
+ inline T_t VOLZB(const Loc<dimensions>&) const { return VOLZB(0); }
+ inline One<T_t> SURXA(int) const { return One<T_t>(); }
+ inline One<T_t> SURXA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> SURYA(int) const { return One<T_t>(); }
+ inline One<T_t> SURYA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> SURZA(int) const { return One<T_t>(); }
+ inline One<T_t> SURZA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> SURXB(int) const { return One<T_t>(); }
+ inline One<T_t> SURXB(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> SURYB(int) const { return One<T_t>(); }
+ inline One<T_t> SURYB(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> SURZB(int) const { return One<T_t>(); }
+ inline One<T_t> SURZB(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline Zero<T_t> CCXA(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCXA(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCYA(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCYA(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZA(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZA(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCXB(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCXB(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCYB(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCYB(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZB(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZB(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline One<T_t> GEOXG(int) const { return One<T_t>(); }
+ inline One<T_t> GEOXG(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> GEOXH(int) const { return One<T_t>(); }
+ inline One<T_t> GEOXH(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> GEOYH(int) const { return One<T_t>(); }
+ inline One<T_t> GEOYH(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> GEOXGA(int) const { return One<T_t>(); }
+ inline One<T_t> GEOXGA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> GEOXHA(int) const { return One<T_t>(); }
+ inline One<T_t> GEOXHA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> GEOYHA(int) const { return One<T_t>(); }
+ inline One<T_t> GEOYHA(const Loc<dimensions>&) const { return One<T_t>(); }
+ };
+ template <class MeshTraits>
+ struct CylindricalRM : public GenericRM<MeshTraits> {
+ typedef typename MeshTraits::T_t T_t;
+ typedef typename MeshTraits::Mesh_t Mesh_t;
+ typedef typename MeshTraits::PointType_t PointType_t;
+ typedef typename MeshTraits::VectorType_t VectorType_t;
+ typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
+ typedef typename MeshTraits::PositionsType_t PositionsType_t;
+ enum { dimensions = MeshTraits::dimensions };
+ enum { coordinateDimensions = MeshTraits::coordinateDimensions };
+ class GeneralVolumesFunctor {
+ public:
+ GeneralVolumesFunctor() { }
+ GeneralVolumesFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : orientation_m(c.orientation(0))
+ {
+ for (int i=0; i<dimensions; i++) {
+ spacings_m[i].engine() = m.spacings()[i].engine();
+ positions_m[i].engine() = m.positions()[i].engine();
+ }
+ }
+ GeneralVolumesFunctor(const GeneralVolumesFunctor &m)
+ : orientation_m(m.orientation_m)
+ {
+ for (int i=0; i<dimensions; i++) {
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ positions_m[i].engine() = m.positions_m[i].engine();
+ }
+ }
+ GeneralVolumesFunctor& operator=(const GeneralVolumesFunctor &m)
+ {
+ orientation_m = m.orientation_m;
+ for (int i=0; i<dimensions; i++) {
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ positions_m[i].engine() = m.positions_m[i].engine();
+ }
+ return *this;
+ }
+ inline T_t r(int i0) const
+ {
+ return positions_m[0].read(i0);
+ }
+ inline T_t operator()(int i0) const
+ {
+ return spacings_m[0].read(i0);
+ }
+ inline T_t operator()(int i0, int i1) const
+ {
+ if (orientation_m[0].first() == 0)
+ return spacings_m[1].read(i1);
+ else if (orientation_m[1].first() == 0)
+ return spacings_m[0].read(i0);
+ else
+ return spacings_m[0].read(i0) * spacings_m[1].read(i1);
+ }
+ inline T_t operator()(int i0, int i1, int i2) const
+ {
+ if (orientation_m[0].first() != 0
+ && orientation_m[1].first() != 0
+ && orientation_m[2].first() != 0) {
+ T_t r1 = r(i0);
+ T_t r2 = r(i0+1);
+ return 0.5*(r2*r2 - r1*r1) * spacings_m[1].read(i1) * spacings_m[2].read(i2);
+ } else if (orientation_m[0].first() != 0
+ && orientation_m[1].first() != 0)
+ return spacings_m[0].read(i0)*spacings_m[1].read(i1);
+ else if (orientation_m[0].first() != 0
+ && orientation_m[2].first() != 0) {
+ T_t r1 = r(i0);
+ T_t r2 = r(i0+1);
+ return 0.5*(r2*r2 - r1*r1) * spacings_m[2].read(i2);
+ } else if (orientation_m[1].first() != 0
+ && orientation_m[2].first() != 0)
+ return r(i0)*spacings_m[1].read(i1)*spacings_m[2].read(i2);
+ else if (orientation_m[0].first() != 0)
+ return spacings_m[0].read(i0);
+ else if (orientation_m[1].first() != 0)
+ return spacings_m[1].read(i1);
+ else if (orientation_m[2].first() != 0)
+ return r(i0)*spacings_m[2].read(i2);
+ }
+ private:
+ SpacingsType_t spacings_m;
+ PositionsType_t positions_m;
+ typename Centering<dimensions>::Orientation orientation_m;
+ };
+ typedef IndexFunction<GeneralVolumesFunctor> CellVolumesEngineTag_t;
+ void initializeCellVolumes(
+ Engine<dimensions, T_t, CellVolumesEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ typedef IndexFunction<GeneralVolumesFunctor> FaceAreasEngineTag_t;
+ void initializeFaceAreas(
+ Engine<dimensions, T_t, FaceAreasEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ typedef IndexFunction<GeneralVolumesFunctor> EdgeLengthsEngineTag_t;
+ void initializeEdgeLengths(
+ Engine<dimensions, T_t, EdgeLengthsEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ class CartesianPositionsFunctor {
+ public:
+ CartesianPositionsFunctor() {}
+ CartesianPositionsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : centering_m(c.position(0))
+ {
+ for (int i = 0; i < dimensions; i++) {
+ positions_m[i].engine() = m.positions()[i].engine();
+ spacings_m[i].engine() = m.spacings()[i].engine();
+ }
+ }
+ CartesianPositionsFunctor& operator=(const CartesianPositionsFunctor& m)
+ {
+ centering_m = m.centering_m;
+ for (int i = 0; i < dimensions; i++) {
+ positions_m[i].engine() = m.positions_m[i].engine();
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ }
+ return *this;
+ }
+ inline PointType_t operator()(int i0) const
+ {
+ return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0));
+ }
+ inline PointType_t operator()(int i0, int i1) const
+ {
+ return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
+ positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1));
+ }
+ inline PointType_t operator()(int i0, int i1, int i2) const
+ {
+ PointType_t r(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
+ positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1),
+ positions_m[2].read(i2) + spacings_m[2].read(i2)*centering_m(2));
+ return PointType_t(r(0)*cos(r(2)),
+ r(0)*sin(r(2)),
+ r(1));
+ }
+ private:
+ PositionsType_t positions_m;
+ SpacingsType_t spacings_m;
+ typename Centering<dimensions>::Position centering_m;
+ };
+ class SphericalPositionsFunctor {
+ public:
+ SphericalPositionsFunctor() {}
+ SphericalPositionsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : centering_m(c.position(0))
+ {
+ for (int i = 0; i < dimensions; i++) {
+ positions_m[i].engine() = m.positions()[i].engine();
+ spacings_m[i].engine() = m.spacings()[i].engine();
+ }
+ }
+ SphericalPositionsFunctor& operator=(const SphericalPositionsFunctor& m)
+ {
+ centering_m = m.centering_m;
+ for (int i = 0; i < dimensions; i++) {
+ positions_m[i].engine() = m.positions_m[i].engine();
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ }
+ return *this;
+ }
+ inline PointType_t operator()(int i0) const
+ {
+ return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0));
+ }
+ inline PointType_t operator()(int i0, int i1) const
+ {
+ PointType_t r(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
+ positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1));
+ T_t R = hypot(r(0), r(1));
+ return PointType_t(R,
+ acos(r(1)/R));
+ }
+ inline PointType_t operator()(int i0, int i1, int i2) const
+ {
+ PointType_t r(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
+ positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1),
+ positions_m[2].read(i2) + spacings_m[2].read(i2)*centering_m(2));
+ T_t R = hypot(r(0), r(1));
+ return PointType_t(R,
+ acos(r(1)/R),
+ r(2));
+ }
+ private:
+ PositionsType_t positions_m;
+ SpacingsType_t spacings_m;
+ typename Centering<dimensions>::Position centering_m;
+ };
+ typedef IndexFunction<CartesianPositionsFunctor> CartesianPositionsEngineTag_t;
+ typedef IndexFunction<typename GenericRM<MeshTraits>::PositionsFunctor> CylindricalPositionsEngineTag_t;
+ typedef IndexFunction<SphericalPositionsFunctor> SphericalPositionsEngineTag_t;
+ inline T_t VOLXA(int i) const
+ {
+ return 0.5*(std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i), 2)
+ - std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i-1), 2));
+ }
+ inline T_t VOLXA(const Loc<dimensions>& l) const { return VOLXA(l[0].first()); }
+ inline T_t VOLYA(int j) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellSpacing( 1, j);
+ }
+ inline T_t VOLYA(const Loc<dimensions>& l) const { return VOLYA(l[1].first()); }
+ inline T_t VOLZA(int k) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellSpacing( 2, k);
+ }
+ inline T_t VOLZA(const Loc<dimensions>& l) const { return VOLZA(l[2].first()); }
+ inline T_t VOLXB(int i) const
+ {
+ return 0.5*(std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i+1), 2)
+ - std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i), 2));
+ }
+ inline T_t VOLXB(const Loc<dimensions>& l) const { return VOLXB(l[0].first()); }
+ inline T_t VOLYB(int j) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexSpacing( 1, j);
+ }
+ inline T_t VOLYB(const Loc<dimensions>& l) const { return VOLYB(l[1].first()); }
+ inline T_t VOLZB(int k) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexSpacing( 2, k);
+ }
+ inline T_t VOLZB(const Loc<dimensions>& l) const { return VOLZB(l[2].first()); }
+ inline T_t SURXA(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
+ }
+ inline T_t SURXA(const Loc<dimensions>& l) const { return SURXA(l[0].first()); }
+ inline One<T_t> SURYA(int) const { return One<T_t>(); }
+ inline One<T_t> SURYA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> SURZA(int) const { return One<T_t>(); }
+ inline One<T_t> SURZA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline T_t SURXB(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
+ }
+ inline T_t SURXB(const Loc<dimensions>& l) const { return SURXB(l[0].first()); }
+ inline One<T_t> SURYB(int) const { return One<T_t>(); }
+ inline One<T_t> SURYB(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> SURZB(int) const { return One<T_t>(); }
+ inline One<T_t> SURZB(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> CCXA(int) const { return One<T_t>(); }
+ inline One<T_t> CCXA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline Zero<T_t> CCYA(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCYA(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZA(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZA(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline One<T_t> CCXB(int) const { return One<T_t>(); }
+ inline One<T_t> CCXB(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline Zero<T_t> CCYB(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCYB(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZB(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZB(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline One<T_t> GEOXG(int) const { return One<T_t>(); }
+ inline One<T_t> GEOXG(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline T_t GEOXH(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
+ }
+ inline T_t GEOXH(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
+ inline One<T_t> GEOYH(int) const { return One<T_t>(); }
+ inline One<T_t> GEOYH(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> GEOXGA(int) const { return One<T_t>(); }
+ inline One<T_t> GEOXGA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline T_t GEOXHA(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
+ }
+ inline T_t GEOXHA(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
+ inline One<T_t> GEOYHA(int) const { return One<T_t>(); }
+ inline One<T_t> GEOYHA(const Loc<dimensions>&) const { return One<T_t>(); }
+ };
+ template <class MeshTraits>
+ struct CylindricalURM : public GenericURM<MeshTraits> {
+ typedef typename MeshTraits::T_t T_t;
+ typedef typename MeshTraits::Mesh_t Mesh_t;
+ typedef typename MeshTraits::PointType_t PointType_t;
+ typedef typename MeshTraits::VectorType_t VectorType_t;
+ typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
+ enum { dimensions = MeshTraits::dimensions };
+ enum { coordinateDimensions = MeshTraits::coordinateDimensions };
+ class GeneralVolumesFunctor {
+ public:
+ GeneralVolumesFunctor() { }
+ GeneralVolumesFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : spacings_m(m.spacings()),
+ orientation_m(c.orientation(0)),
+ origin_m(m.origin())
+ {
+ }
+ inline T_t r(int i0) const
+ {
+ return origin_m(0)+i0*spacings_m(0);
+ }
+ inline T_t operator()(int i0) const
+ {
+ return spacings_m(0);
+ }
+ inline T_t operator()(int i0, int i1) const
+ {
+ if (orientation_m[0].first() == 0)
+ return spacings_m(1);
+ else if (orientation_m[1].first() == 0)
+ return spacings_m(0);
+ else
+ return spacings_m(0) * spacings_m(1);
+ }
+ inline T_t operator()(int i0, int i1, int i2) const
+ {
+ if (orientation_m[0].first() != 0
+ && orientation_m[1].first() != 0
+ && orientation_m[2].first() != 0) {
+ T_t r1 = r(i0);
+ T_t r2 = r(i0+1);
+ return 0.5*(r2*r2 - r1*r1) * spacings_m(1) * spacings_m(2);
+ } else if (orientation_m[0].first() != 0
+ && orientation_m[1].first() != 0)
+ return spacings_m(0) * spacings_m(1);
+ else if (orientation_m[0].first() != 0
+ && orientation_m[2].first() != 0) {
+ T_t r1 = r(i0);
+ T_t r2 = r(i0+1);
+ return 0.5*(r2*r2 - r1*r1) * spacings_m(2);
+ } else if (orientation_m[1].first() != 0
+ && orientation_m[2].first() != 0)
+ return r(i0)*spacings_m(1) * spacings_m(2);
+ else if (orientation_m[0].first() != 0)
+ return spacings_m(0);
+ else if (orientation_m[1].first() != 0)
+ return spacings_m(1);
+ else if (orientation_m[2].first() != 0)
+ return r(i0)*spacings_m(2);
+ }
+ private:
+ SpacingsType_t spacings_m;
+ typename Centering<dimensions>::Orientation orientation_m;
+ PointType_t origin_m;
+ };
+ typedef IndexFunction<GeneralVolumesFunctor> CellVolumesEngineTag_t;
+ void initializeCellVolumes(
+ Engine<dimensions, T_t, CellVolumesEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ typedef IndexFunction<GeneralVolumesFunctor> FaceAreasEngineTag_t;
+ void initializeFaceAreas(
+ Engine<dimensions, T_t, FaceAreasEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ typedef IndexFunction<GeneralVolumesFunctor> EdgeLengthsEngineTag_t;
+ void initializeEdgeLengths(
+ Engine<dimensions, T_t, EdgeLengthsEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ class CartesianPositionsFunctor {
+ public:
+ CartesianPositionsFunctor() {}
+ CartesianPositionsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : origin_m(m.origin()), spacings_m(m.spacings())
+ {
+ for (int i = 0; i < dimensions; i++)
+ origin_m(i) += spacings_m(i) *
+ (c.position(0)(i) - m.physicalCellDomain()[i].first());
+ }
+ inline PointType_t operator()(int i0) const
+ {
+ return origin_m + PointType_t(i0) * spacings_m;
+ }
+ inline PointType_t operator()(int i0, int i1) const
+ {
+ return origin_m + PointType_t(i0, i1) * spacings_m;
+ }
+ inline PointType_t operator()(int i0, int i1, int i2) const
+ {
+ PointType_t r(origin_m + PointType_t(i0, i1, i2) * spacings_m);
+ return PointType_t(r(0)*cos(r(2)),
+ r(0)*sin(r(2)),
+ r(1));
+ }
+ private:
+ PointType_t origin_m;
+ SpacingsType_t spacings_m;
+ };
+ class SphericalPositionsFunctor {
+ public:
+ SphericalPositionsFunctor() {}
+ SphericalPositionsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : origin_m(m.origin()), spacings_m(m.spacings())
+ {
+ for (int i = 0; i < dimensions; i++)
+ origin_m(i) += spacings_m(i) *
+ (c.position(0)(i) - m.physicalCellDomain()[i].first());
+ }
+ inline PointType_t operator()(int i0) const
+ {
+ return origin_m + PointType_t(i0) * spacings_m;
+ }
+ inline PointType_t operator()(int i0, int i1) const
+ {
+ PointType_t r(origin_m + PointType_t(i0, i1) * spacings_m);
+ T_t R = hypot(r(0), r(1));
+ return PointType_t(R,
+ acos(r(1)/R));
+ }
+ inline PointType_t operator()(int i0, int i1, int i2) const
+ {
+ PointType_t r(origin_m + PointType_t(i0, i1, i2) * spacings_m);
+ T_t R = hypot(r(0), r(1));
+ return PointType_t(R,
+ acos(r(1)/R),
+ r(2));
+ }
+ private:
+ PointType_t origin_m;
+ SpacingsType_t spacings_m;
+ };
+ typedef IndexFunction<CartesianPositionsFunctor> CartesianPositionsEngineTag_t;
+ typedef IndexFunction<typename GenericURM<MeshTraits>::PositionsFunctor> CylindricalPositionsEngineTag_t;
+ typedef IndexFunction<SphericalPositionsFunctor> SphericalPositionsEngineTag_t;
+ inline T_t VOLXA(int i) const
+ {
+ return 0.5*(std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i), 2)
+ - std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i-1), 2));
+ }
+ inline T_t VOLXA(const Loc<dimensions>& l) const { return VOLXA(l[0].first()); }
+ inline T_t VOLYA(int) const
+ {
+ return static_cast<const Mesh_t&>(*this).spacings()(1);
+ }
+ inline T_t VOLYA(const Loc<dimensions>&) const { return VOLYA(0); }
+ inline T_t VOLZA(int) const
+ {
+ return static_cast<const Mesh_t&>(*this).spacings()(2);
+ }
+ inline T_t VOLZA(const Loc<dimensions>&) const { return VOLZA(0); }
+ inline T_t VOLXB(int i) const
+ {
+ return 0.5*(std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i+1), 2)
+ - std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i), 2));
+ }
+ inline T_t VOLXB(const Loc<dimensions>& l) const { return VOLXB(l[0].first()); }
+ inline T_t VOLYB(int) const
+ {
+ return static_cast<const Mesh_t&>(*this).spacings()(1);
+ }
+ inline T_t VOLYB(const Loc<dimensions>&) const { return VOLYB(0); }
+ inline T_t VOLZB(int) const
+ {
+ return static_cast<const Mesh_t&>(*this).spacings()(2);
+ }
+ inline T_t VOLZB(const Loc<dimensions>&) const { return VOLZB(0); }
+ inline T_t SURXA(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
+ }
+ inline T_t SURXA(const Loc<dimensions>& l) const { return SURXA(l[0].first()); }
+ inline One<T_t> SURYA(int) const { return One<T_t>(); }
+ inline One<T_t> SURYA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> SURZA(int) const { return One<T_t>(); }
+ inline One<T_t> SURZA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline T_t SURXB(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
+ }
+ inline T_t SURXB(const Loc<dimensions>& l) const { return SURXB(l[0].first()); }
+ inline One<T_t> SURYB(int) const { return One<T_t>(); }
+ inline One<T_t> SURYB(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> SURZB(int) const { return One<T_t>(); }
+ inline One<T_t> SURZB(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> CCXA(int) const { return One<T_t>(); }
+ inline One<T_t> CCXA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline Zero<T_t> CCYA(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCYA(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZA(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZA(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline One<T_t> CCXB(int) const { return One<T_t>(); }
+ inline One<T_t> CCXB(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline Zero<T_t> CCYB(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCYB(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZB(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZB(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline One<T_t> GEOXG(int) const { return One<T_t>(); }
+ inline One<T_t> GEOXG(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline T_t GEOXH(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
+ }
+ inline T_t GEOXH(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
+ inline One<T_t> GEOYH(int) const { return One<T_t>(); }
+ inline One<T_t> GEOYH(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline One<T_t> GEOXGA(int) const { return One<T_t>(); }
+ inline One<T_t> GEOXGA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline T_t GEOXHA(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
+ }
+ inline T_t GEOXHA(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
+ inline One<T_t> GEOYHA(int) const { return One<T_t>(); }
+ inline One<T_t> GEOYHA(const Loc<dimensions>&) const { return One<T_t>(); }
+ };
+ template <class MeshTraits>
+ struct SphericalRM : public GenericRM<MeshTraits> {
+ typedef typename MeshTraits::T_t T_t;
+ typedef typename MeshTraits::Mesh_t Mesh_t;
+ typedef typename MeshTraits::PointType_t PointType_t;
+ typedef typename MeshTraits::VectorType_t VectorType_t;
+ typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
+ typedef typename MeshTraits::PositionsType_t PositionsType_t;
+ enum { dimensions = MeshTraits::dimensions };
+ class GeneralVolumesFunctor {
+ public:
+ GeneralVolumesFunctor() { }
+ GeneralVolumesFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : orientation_m(c.orientation(0))
+ {
+ for (int i=0; i<dimensions; i++) {
+ spacings_m[i].engine() = m.spacings()[i].engine();
+ positions_m[i].engine() = m.positions()[i].engine();
+ }
+ }
+ GeneralVolumesFunctor(const GeneralVolumesFunctor &m)
+ : orientation_m(m.orientation_m)
+ {
+ for (int i=0; i<dimensions; i++) {
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ positions_m[i].engine() = m.positions_m[i].engine();
+ }
+ }
+ GeneralVolumesFunctor& operator=(const GeneralVolumesFunctor &m)
+ {
+ orientation_m = m.orientation_m;
+ for (int i=0; i<dimensions; i++) {
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ positions_m[i].engine() = m.positions_m[i].engine();
+ }
+ return *this;
+ }
+ inline T_t r(int i0) const
+ {
+ return positions_m[0].read(i0);
+ }
+ inline T_t theta(int i1) const
+ {
+ return positions_m[1].read(i1);
+ }
+ inline T_t phi(int i2) const
+ {
+ return positions_m[2].read(i2);
+ }
+ inline T_t operator()(int i0) const
+ {
+ return spacings_m[0].read(i0);
+ }
+ inline T_t operator()(int i0, int i1) const
+ {
+ if (orientation_m[0].first() == 0)
+ return r(i0)*spacings_m[1].read(i1);
+ else if (orientation_m[1].first() == 0)
+ return spacings_m[0].read(i0);
+ else {
+ T_t r1 = r(i0);
+ T_t r2 = r(i0+1);
+ return 0.5*(r2*r2 - r1*r1) * spacings_m[1].read(i1);
+ }
+ }
+ inline T_t operator()(int i0, int i1, int i2) const
+ {
+ if (orientation_m[0].first() != 0
+ && orientation_m[1].first() != 0
+ && orientation_m[2].first() != 0) {
+ T_t r1 = r(i0);
+ T_t r2 = r(i0+1);
+ return (r2*r2*r2 - r1*r1*r1)/3.0
+ * (cos(theta(i1)) - cos(theta(i1+1)))
+ * spacings_m[2].read(i2);
+ } else if (orientation_m[0].first() != 0
+ && orientation_m[1].first() != 0) {
+ T_t r1 = r(i0);
+ T_t r2 = r(i0+1);
+ return 0.5*(r2*r2 - r1*r1) * spacings_m[1].read(i1);
+ } else if (orientation_m[0].first() != 0
+ && orientation_m[2].first() != 0) {
+ T_t r1 = r(i0);
+ T_t r2 = r(i0+1);
+ return 0.5*(r2*r2 - r1*r1)*sin(theta(i1)) * spacings_m[2].read(i2);
+ } else if (orientation_m[1].first() != 0
+ && orientation_m[2].first() != 0) {
+ T_t r1 = r(i0);
+ return - r1*r1 * spacings_m[2].read(i2) * (cos(theta(i1+1)) - cos(theta(i1)));
+ } else if (orientation_m[0].first() != 0)
+ return spacings_m[0].read(i0);
+ else if (orientation_m[1].first() != 0)
+ return r(i0)*spacings_m[1].read(i1);
+ else if (orientation_m[2].first() != 0)
+ return r(i0)*sin(theta(i1)) * spacings_m[2].read(i2);
+ }
+ private:
+ SpacingsType_t spacings_m;
+ SpacingsType_t positions_m;
+ typename Centering<dimensions>::Orientation orientation_m;
+ };
+ typedef IndexFunction<GeneralVolumesFunctor> CellVolumesEngineTag_t;
+ void initializeCellVolumes(
+ Engine<dimensions, T_t, CellVolumesEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ typedef IndexFunction<GeneralVolumesFunctor> FaceAreasEngineTag_t;
+ void initializeFaceAreas(
+ Engine<dimensions, T_t, FaceAreasEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ typedef IndexFunction<GeneralVolumesFunctor> EdgeLengthsEngineTag_t;
+ void initializeEdgeLengths(
+ Engine<dimensions, T_t, EdgeLengthsEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ class CartesianPositionsFunctor {
+ public:
+ CartesianPositionsFunctor() {}
+ CartesianPositionsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : centering_m(c.position(0))
+ {
+ for (int i = 0; i < dimensions; i++) {
+ positions_m[i].engine() = m.positions()[i].engine();
+ spacings_m[i].engine() = m.spacings()[i].engine();
+ }
+ }
+ CartesianPositionsFunctor& operator=(const CartesianPositionsFunctor& m)
+ {
+ centering_m = m.centering_m;
+ for (int i = 0; i < dimensions; i++) {
+ positions_m[i].engine() = m.positions_m[i].engine();
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ }
+ return *this;
+ }
+ inline PointType_t operator()(int i0) const
+ {
+ return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0));
+ }
+ inline PointType_t operator()(int i0, int i1) const
+ {
+ PointType_t r(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
+ positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1));
+ return PointType_t(r(0)*sin(r(1)),
+ r(0)*cos(r(1)));
+ }
+ inline PointType_t operator()(int i0, int i1, int i2) const
+ {
+ PointType_t r(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
+ positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1),
+ positions_m[2].read(i2) + spacings_m[2].read(i2)*centering_m(2));
+ return PointType_t(r(0)*sin(r(1))*cos(r(2)),
+ r(0)*sin(r(1))*sin(r(2)),
+ r(0)*cos(r(1)));
+ }
+ private:
+ PositionsType_t positions_m;
+ SpacingsType_t spacings_m;
+ typename Centering<dimensions>::Position centering_m;
+ };
+ class CylindricalPositionsFunctor {
+ public:
+ CylindricalPositionsFunctor() {}
+ CylindricalPositionsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : centering_m(c.position(0))
+ {
+ for (int i = 0; i < dimensions; i++) {
+ positions_m[i].engine() = m.positions()[i].engine();
+ spacings_m[i].engine() = m.spacings()[i].engine();
+ }
+ }
+ CylindricalPositionsFunctor& operator=(const CylindricalPositionsFunctor& m)
+ {
+ centering_m = m.centering_m;
+ for (int i = 0; i < dimensions; i++) {
+ positions_m[i].engine() = m.positions_m[i].engine();
+ spacings_m[i].engine() = m.spacings_m[i].engine();
+ }
+ return *this;
+ }
+ inline PointType_t operator()(int i0) const
+ {
+ return PointType_t(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0));
+ }
+ inline PointType_t operator()(int i0, int i1) const
+ {
+ PointType_t r(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
+ positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1));
+ return PointType_t(r(0)*sin(r(1)),
+ r(0)*cos(r(1)));
+ }
+ inline PointType_t operator()(int i0, int i1, int i2) const
+ {
+ PointType_t r(positions_m[0].read(i0) + spacings_m[0].read(i0)*centering_m(0),
+ positions_m[1].read(i1) + spacings_m[1].read(i1)*centering_m(1),
+ positions_m[2].read(i2) + spacings_m[2].read(i2)*centering_m(2));
+ return PointType_t(r(0)*sin(r(1)),
+ r(0)*cos(r(1)),
+ r(2));
+ }
+ private:
+ PositionsType_t positions_m;
+ SpacingsType_t spacings_m;
+ typename Centering<dimensions>::Position centering_m;
+ };
+ typedef IndexFunction<CartesianPositionsFunctor> CartesianPositionsEngineTag_t;
+ typedef IndexFunction<CylindricalPositionsFunctor> CylindricalPositionsEngineTag_t;
+ typedef IndexFunction<typename GenericRM<MeshTraits>::PositionsFunctor> SphericalPositionsEngineTag_t;
+ inline T_t VOLXA(int i) const
+ {
+ return (1.0/3.0)*(std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i), 3)
+ - std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i-1), 3));
+ }
+ inline T_t VOLXA(const Loc<dimensions>& l) const { return VOLXA(l[0].first()); }
+ inline T_t VOLYA(int j) const
+ {
+ return std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j-1))
+ - std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
+ }
+ inline T_t VOLYA(const Loc<dimensions>& l) const { return VOLYA(l[1].first()); }
+ inline T_t VOLZA(int k) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellSpacing( 2, k-1);
+ }
+ inline T_t VOLZA(const Loc<dimensions>& l) const { return VOLZA(l[2].first()); }
+ inline T_t VOLXB(int i) const
+ {
+ return (1.0/3.0)*(std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i+1), 3)
+ - std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i), 3));
+ }
+ inline T_t VOLXB(const Loc<dimensions>& l) const { return VOLXB(l[0].first()); }
+ inline T_t VOLYB(int j) const
+ {
+ return std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j))
+ - std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j+1));
+ }
+ inline T_t VOLYB(const Loc<dimensions>& l) const { return VOLYB(l[1].first()); }
+ inline T_t VOLZB(int k) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexSpacing( 2, k);
+ }
+ inline T_t VOLZB(const Loc<dimensions>& l) const { return VOLZB(l[2].first()); }
+ inline T_t SURXA(int i) const
+ {
+ return std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i), 2);
+ }
+ inline T_t SURXA(const Loc<dimensions>& l) const { return SURXA(l[0].first()); }
+ inline T_t SURYA(int j) const
+ {
+ return std::sin(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j));
+ }
+ inline T_t SURYA(const Loc<dimensions>& l) const { return SURYA(l[1].first()); }
+ inline One<T_t> SURZA(int) const { return One<T_t>(); }
+ inline One<T_t> SURZA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline T_t SURXB(int i) const
+ {
+ return std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i), 2);
+ }
+ inline T_t SURXB(const Loc<dimensions>& l) const { return SURXB(l[0].first()); }
+ inline T_t SURYB(int j) const
+ {
+ return std::sin(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
+ }
+ inline T_t SURYB(const Loc<dimensions>& l) const { return SURYB(l[1].first()); }
+ inline One<T_t> SURZB(int) const { return One<T_t>(); }
+ inline One<T_t> SURZB(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline T_t CCXA(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
+ }
+ inline T_t CCXA(const Loc<dimensions>& l) const { return CCXA(l[0].first()); }
+ inline T_t CCYA(int j) const
+ {
+ return 0.5*std::cos(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j));
+ }
+ inline T_t CCYA(const Loc<dimensions>& l) const { return CCYA(l[1].first()); }
+ inline Zero<T_t> CCZA(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZA(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline T_t CCXB(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
+ }
+ inline T_t CCXB(const Loc<dimensions>& l) const { return CCXB(l[0].first()); }
+ inline T_t CCYB(int j) const
+ {
+ return 0.5*std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
+ }
+ inline T_t CCYB(const Loc<dimensions>& l) const { return CCYB(l[1].first()); }
+ inline Zero<T_t> CCZB(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZB(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline T_t GEOXG(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
+ }
+ inline T_t GEOXG(const Loc<dimensions>& l) const { return GEOXG(l[0].first()); }
+ inline T_t GEOXH(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
+ }
+ inline T_t GEOXH(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
+ inline T_t GEOYH(int j) const
+ {
+ return std::sin(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
+ }
+ inline T_t GEOYH(const Loc<dimensions>& l) const { return GEOYH(l[1].first()); }
+ inline T_t GEOXGA(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
+ }
+ inline T_t GEOXGA(const Loc<dimensions>& l) const { return GEOXG(l[0].first()); }
+ inline T_t GEOXHA(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
+ }
+ inline T_t GEOXHA(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
+ inline T_t GEOYHA(int j) const
+ {
+ return std::sin(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j));
+ }
+ inline T_t GEOYHA(const Loc<dimensions>& l) const { return GEOYH(l[1].first()); }
+ };
+ template <class MeshTraits>
+ struct SphericalURM : public GenericURM<MeshTraits> {
+ typedef typename MeshTraits::T_t T_t;
+ typedef typename MeshTraits::Mesh_t Mesh_t;
+ typedef typename MeshTraits::PointType_t PointType_t;
+ typedef typename MeshTraits::VectorType_t VectorType_t;
+ typedef typename MeshTraits::SpacingsType_t SpacingsType_t;
+ enum { dimensions = MeshTraits::dimensions };
+ class GeneralVolumesFunctor {
+ public:
+ GeneralVolumesFunctor() { }
+ GeneralVolumesFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : spacings_m(m.spacings()),
+ orientation_m(c.orientation(0)),
+ origin_m(m.origin())
+ {
+ }
+ inline T_t r(int i0) const
+ {
+ return origin_m(0)+i0*spacings_m(0);
+ }
+ inline T_t theta(int i1) const
+ {
+ return origin_m(1)+i1*spacings_m(1);
+ }
+ inline T_t operator()(int i0) const
+ {
+ return spacings_m(0);
+ }
+ inline T_t operator()(int i0, int i1) const
+ {
+ if (orientation_m[0].first() == 0)
+ return r(i0)*spacings_m(1);
+ else if (orientation_m[1].first() == 0)
+ return spacings_m(0);
+ else {
+ T_t r1 = r(i0);
+ T_t r2 = r(i0+1);
+ return 0.5*(r2*r2 - r1*r1) * spacings_m(1);
+ }
+ }
+ inline T_t operator()(int i0, int i1, int i2) const
+ {
+ if (orientation_m[0].first() != 0
+ && orientation_m[1].first() != 0
+ && orientation_m[2].first() != 0) {
+ T_t r1 = r(i0);
+ T_t r2 = r1 + spacings_m(0);
+ return (r2*r2*r2 - r1*r1*r1)/3.0
+ * (cos(theta(i1)) - cos(theta(i1+1)))
+ * spacings_m(2);
+ } else if (orientation_m[0].first() != 0
+ && orientation_m[1].first() != 0) {
+ T_t r1 = r(i0);
+ T_t r2 = r1 + spacings_m(0);
+ return 0.5*(r2*r2 - r1*r1) * spacings_m(1);
+ } else if (orientation_m[0].first() != 0
+ && orientation_m[2].first() != 0) {
+ T_t r1 = r(i0);
+ T_t r2 = r(i0+1);
+ return 0.5*(r2*r2 - r1*r1)*sin(theta(i1)) * spacings_m(2);
+ } else if (orientation_m[1].first() != 0
+ && orientation_m[2].first() != 0) {
+ T_t r1 = r(i0);
+ return - r1*r1 * spacings_m(2) * (cos(theta(i1+1)) - cos(theta(i1)));
+ } else if (orientation_m[0].first() != 0)
+ return spacings_m(0);
+ else if (orientation_m[1].first() != 0)
+ return r(i0)*spacings_m(1);
+ else if (orientation_m[2].first() != 0)
+ return r(i0)*sin(theta(i1)) * spacings_m(2);
+ }
+ private:
+ SpacingsType_t spacings_m;
+ typename Centering<dimensions>::Orientation orientation_m;
+ PointType_t origin_m;
+ };
+ typedef IndexFunction<GeneralVolumesFunctor> CellVolumesEngineTag_t;
+ void initializeCellVolumes(
+ Engine<dimensions, T_t, CellVolumesEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ typedef IndexFunction<GeneralVolumesFunctor> FaceAreasEngineTag_t;
+ void initializeFaceAreas(
+ Engine<dimensions, T_t, FaceAreasEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ typedef IndexFunction<GeneralVolumesFunctor> EdgeLengthsEngineTag_t;
+ void initializeEdgeLengths(
+ Engine<dimensions, T_t, EdgeLengthsEngineTag_t> &e,
+ const Centering<dimensions> &c) const
+ {
+ ;
+ ;
+ e.setFunctor(GeneralVolumesFunctor(static_cast<const Mesh_t&>(*this), c));
+ }
+ class CartesianPositionsFunctor {
+ public:
+ CartesianPositionsFunctor() {}
+ CartesianPositionsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : origin_m(m.origin()), spacings_m(m.spacings())
+ {
+ for (int i = 0; i < dimensions; i++)
+ origin_m(i) += spacings_m(i) *
+ (c.position(0)(i) - m.physicalCellDomain()[i].first());
+ }
+ inline PointType_t operator()(int i0) const
+ {
+ return origin_m + PointType_t(i0) * spacings_m;
+ }
+ inline PointType_t operator()(int i0, int i1) const
+ {
+ PointType_t r(origin_m + PointType_t(i0, i1) * spacings_m);
+ return PointType_t(r(0)*sin(r(1)),
+ r(0)*cos(r(1)));
+ }
+ inline PointType_t operator()(int i0, int i1, int i2) const
+ {
+ PointType_t r(origin_m + PointType_t(i0, i1, i2) * spacings_m);
+ return PointType_t(r(0)*sin(r(1))*cos(r(2)),
+ r(0)*sin(r(1))*sin(r(2)),
+ r(0)*cos(r(1)));
+ }
+ private:
+ PointType_t origin_m;
+ SpacingsType_t spacings_m;
+ };
+ class CylindricalPositionsFunctor {
+ public:
+ CylindricalPositionsFunctor() {}
+ CylindricalPositionsFunctor(const Mesh_t &m,
+ const Centering<dimensions> &c)
+ : origin_m(m.origin()), spacings_m(m.spacings())
+ {
+ for (int i = 0; i < dimensions; i++)
+ origin_m(i) += spacings_m(i) *
+ (c.position(0)(i) - m.physicalCellDomain()[i].first());
+ }
+ inline PointType_t operator()(int i0) const
+ {
+ return origin_m + PointType_t(i0) * spacings_m;
+ }
+ inline PointType_t operator()(int i0, int i1) const
+ {
+ PointType_t r(origin_m + PointType_t(i0, i1) * spacings_m);
+ return PointType_t(r(0)*sin(r(1)),
+ r(0)*cos(r(1)));
+ }
+ inline PointType_t operator()(int i0, int i1, int i2) const
+ {
+ PointType_t r(origin_m + PointType_t(i0, i1, i2) * spacings_m);
+ return PointType_t(r(0)*sin(r(1)),
+ r(0)*cos(r(1)),
+ r(2));
+ }
+ private:
+ PointType_t origin_m;
+ SpacingsType_t spacings_m;
+ };
+ typedef IndexFunction<CartesianPositionsFunctor> CartesianPositionsEngineTag_t;
+ typedef IndexFunction<CylindricalPositionsFunctor> CylindricalPositionsEngineTag_t;
+ typedef IndexFunction<typename GenericURM<MeshTraits>::PositionsFunctor> SphericalPositionsEngineTag_t;
+ inline T_t VOLXA(int i) const
+ {
+ return (std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i), 3)
+ - std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i-1), 3))
+ / 3.0;
+ }
+ inline T_t VOLXA(const Loc<dimensions>& l) const { return VOLXA(l[0].first()); }
+ inline T_t VOLYA(int j) const
+ {
+ return std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j-1))
+ - std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
+ }
+ inline T_t VOLYA(const Loc<dimensions>& l) const { return VOLYA(l[1].first()); }
+ inline T_t VOLZA(int) const
+ {
+ return static_cast<const Mesh_t&>(*this).spacings()(2);
+ }
+ inline T_t VOLZA(const Loc<dimensions>&) const { return VOLZA(0); }
+ inline T_t VOLXB(int i) const
+ {
+ return (std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i+1), 3)
+ - std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i), 3))
+ / 3.0;
+ }
+ inline T_t VOLXB(const Loc<dimensions>& l) const { return VOLXB(l[0].first()); }
+ inline T_t VOLYB(int j) const
+ {
+ return std::cos(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j))
+ - std::cos(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j+1));
+ }
+ inline T_t VOLYB(const Loc<dimensions>& l) const { return VOLYB(l[1].first()); }
+ inline T_t VOLZB(int) const
+ {
+ return static_cast<const Mesh_t&>(*this).spacings()(2);
+ }
+ inline T_t VOLZB(const Loc<dimensions>&) const { return VOLZB(0); }
+ inline T_t SURXA(int i) const
+ {
+ return std::pow(static_cast<const Mesh_t&>(*this).vertexPosition( 0, i), 2);
+ }
+ inline T_t SURXA(const Loc<dimensions>& l) const { return SURXA(l[0].first()); }
+ inline T_t SURYA(int j) const
+ {
+ return std::sin(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j));
+ }
+ inline T_t SURYA(const Loc<dimensions>& l) const { return SURYA(l[1].first()); }
+ inline One<T_t> SURZA(int) const { return One<T_t>(); }
+ inline One<T_t> SURZA(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline T_t SURXB(int i) const
+ {
+ return std::pow(static_cast<const Mesh_t&>(*this).cellPosition( 0, i), 2);
+ }
+ inline T_t SURXB(const Loc<dimensions>& l) const { return SURXB(l[0].first()); }
+ inline T_t SURYB(int j) const
+ {
+ return std::sin(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
+ }
+ inline T_t SURYB(const Loc<dimensions>& l) const { return SURYB(l[1].first()); }
+ inline One<T_t> SURZB(int) const { return One<T_t>(); }
+ inline One<T_t> SURZB(const Loc<dimensions>&) const { return One<T_t>(); }
+ inline T_t CCXA(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
+ }
+ inline T_t CCXA(const Loc<dimensions>& l) const { return CCXA(l[0].first()); }
+ inline T_t CCYA(int j) const
+ {
+ return 0.5*std::cos(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j));
+ }
+ inline T_t CCYA(const Loc<dimensions>& l) const { return CCYA(l[1].first()); }
+ inline Zero<T_t> CCZA(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZA(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline T_t CCXB(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
+ }
+ inline T_t CCXB(const Loc<dimensions>& l) const { return CCXB(l[0].first()); }
+ inline T_t CCYB(int j) const
+ {
+ return 0.5*std::cos(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
+ }
+ inline T_t CCYB(const Loc<dimensions>& l) const { return CCYB(l[1].first()); }
+ inline Zero<T_t> CCZB(int) const { return Zero<T_t>(); }
+ inline Zero<T_t> CCZB(const Loc<dimensions>&) const { return Zero<T_t>(); }
+ inline T_t GEOXG(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
+ }
+ inline T_t GEOXG(const Loc<dimensions>& l) const { return GEOXG(l[0].first()); }
+ inline T_t GEOXH(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).cellPosition( 0, i);
+ }
+ inline T_t GEOXH(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
+ inline T_t GEOYH(int j) const
+ {
+ return std::sin(static_cast<const Mesh_t&>(*this).cellPosition( 1, j));
+ }
+ inline T_t GEOYH(const Loc<dimensions>& l) const { return GEOYH(l[1].first()); }
+ inline T_t GEOXGA(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
+ }
+ inline T_t GEOXGA(const Loc<dimensions>& l) const { return GEOXG(l[0].first()); }
+ inline T_t GEOXHA(int i) const
+ {
+ return static_cast<const Mesh_t&>(*this).vertexPosition( 0, i);
+ }
+ inline T_t GEOXHA(const Loc<dimensions>& l) const { return GEOXH(l[0].first()); }
+ inline T_t GEOYHA(int j) const
+ {
+ return std::sin(static_cast<const Mesh_t&>(*this).vertexPosition( 1, j));
+ }
+ inline T_t GEOYHA(const Loc<dimensions>& l) const { return GEOYH(l[1].first()); }
+ };
+ template<class Mesh, class T, class EngineTag> class Field;
+ namespace Pooma {
+ template<class Mesh>
+ struct PositionsTraits {
+ typedef Field<NoMesh<Mesh::dimensions>,
+ typename Mesh::PointType_t,
+ typename Mesh::PositionsEngineTag_t> Type_t;
+ typedef Field<NoMesh<Mesh::dimensions>,
+ typename Mesh::PointType_t,
+ typename Mesh::CartesianPositionsEngineTag_t> CartesianType_t;
+ typedef Field<NoMesh<Mesh::dimensions>,
+ typename Mesh::PointType_t,
+ typename Mesh::CylindricalPositionsEngineTag_t> CylindricalType_t;
+ typedef Field<NoMesh<Mesh::dimensions>,
+ typename Mesh::PointType_t,
+ typename Mesh::SphericalPositionsEngineTag_t> SphericalType_t;
+ };
+ template<class Mesh, class T, class EngineTag>
+ typename PositionsTraits<Mesh>::Type_t
+ positions(const Field<Mesh, T, EngineTag> &f)
+ {
+ NoMesh<Mesh::dimensions> m(f.layout());
+ typename PositionsTraits<Mesh>::Type_t
+ of(f.numMaterials(), f.centering(), f.layout(), m);
+ for (int i = 0; i < of.numMaterials(); i++)
+ for (int j = 0; j < of.centeringSize(); j++)
+ f.mesh().initializePositions(of.subField(i, j).engine(), of.centering(j));
+ return of;
+ }
+ template<class Mesh, int Dim>
+ typename PositionsTraits<Mesh>::Type_t
+ positions(const Mesh &mesh, Centering<Dim> c)
+ {
+ GuardLayers<Mesh::dimensions> g;
+ for (int i = 0; i < Mesh::dimensions; ++i) {
+ g.lower(i) = mesh.physicalVertexDomain()[i].min() - mesh.totalVertexDomain()[i].min();
+ g.upper(i) = mesh.totalVertexDomain()[i].max() - mesh.physicalVertexDomain()[i].max();
+ }
+ DomainLayout<Mesh::dimensions> layout(mesh.physicalVertexDomain(), g);
+ NoMesh<Mesh::dimensions> m(layout);
+ typename PositionsTraits<Mesh>::Type_t
+ of(1, c, layout, m);
+ for (int j = 0; j < of.centeringSize(); j++)
+ mesh.initializePositions(of.subField(0, j).engine(), of.centering(j));
+ return of;
+ }
+ template<class Mesh, class T, class EngineTag>
+ typename PositionsTraits<Mesh>::CartesianType_t
+ cartesianPositions(const Field<Mesh, T, EngineTag> &f)
+ {
+ NoMesh<Mesh::dimensions> m(f.layout());
+ typename PositionsTraits<Mesh>::CartesianType_t
+ of(f.numMaterials(), f.centering(), f.layout(), m);
+ for (int i = 0; i < of.numMaterials(); i++)
+ for (int j = 0; j < of.centeringSize(); j++)
+ f.mesh().initializePositions(of.subField(i, j).engine(), of.centering(j));
+ return of;
+ }
+ template<class Mesh, class T, class EngineTag>
+ typename PositionsTraits<Mesh>::CylindricalType_t
+ cylindricalPositions(const Field<Mesh, T, EngineTag> &f)
+ {
+ NoMesh<Mesh::dimensions> m(f.layout());
+ typename PositionsTraits<Mesh>::CylindricalType_t
+ of(f.numMaterials(), f.centering(), f.layout(), m);
+ for (int i = 0; i < of.numMaterials(); i++)
+ for (int j = 0; j < of.centeringSize(); j++)
+ f.mesh().initializePositions(of.subField(i, j).engine(), of.centering(j));
+ return of;
+ }
+ template<class Mesh, class T, class EngineTag>
+ typename PositionsTraits<Mesh>::SphericalType_t
+ sphericalPositions(const Field<Mesh, T, EngineTag> &f)
+ {
+ NoMesh<Mesh::dimensions> m(f.layout());
+ typename PositionsTraits<Mesh>::SphericalType_t
+ of(f.numMaterials(), f.centering(), f.layout(), m);
+ for (int i = 0; i < of.numMaterials(); i++)
+ for (int j = 0; j < of.centeringSize(); j++)
+ f.mesh().initializePositions(of.subField(i, j).engine(), of.centering(j));
+ return of;
+ }
+ template<class Mesh>
+ struct SpacingsTraits {
+ typedef Field<NoMesh<Mesh::dimensions>,
+ typename Mesh::VectorType_t,
+ typename Mesh::SpacingsEngineTag_t> Type_t;
+ };
+ template<class Mesh, class T, class EngineTag>
+ typename SpacingsTraits<Mesh>::Type_t
+ spacings(const Field<Mesh, T, EngineTag> &f)
+ {
+ NoMesh<Mesh::dimensions> m(f.layout());
+ typename SpacingsTraits<Mesh>::Type_t
+ of(f.numMaterials(), f.centering(), f.layout(), m);
+ for (int i = 0; i < of.numMaterials(); i++)
+ for (int j = 0; j < of.centeringSize(); j++)
+ f.mesh().initializeSpacings(of.subField(i, j).engine(), of.centering(j));
+ return of;
+ }
+ template<class Mesh, int Dim>
+ typename SpacingsTraits<Mesh>::Type_t
+ spacings(const Mesh &mesh, Centering<Dim> c)
+ {
+ GuardLayers<Mesh::dimensions> g;
+ for (int i = 0; i < Mesh::dimensions; ++i) {
+ g.lower(i) = mesh.physicalVertexDomain()[i].min() - mesh.totalVertexDomain()[i].min();
+ g.upper(i) = mesh.totalVertexDomain()[i].max() - mesh.physicalVertexDomain()[i].max();
+ }
+ DomainLayout<Mesh::dimensions> layout(mesh.physicalVertexDomain(), g);
+ NoMesh<Mesh::dimensions> m(layout);
+ typename SpacingsTraits<Mesh>::Type_t
+ of(1, c, layout, m);
+ for (int j = 0; j < of.centeringSize(); j++)
+ mesh.initializeSpacings(of.subField(0, j).engine(), of.centering(j));
+ return of;
+ }
+ template<class Mesh>
+ struct NormalsTraits {
+ typedef Field<NoMesh<Mesh::dimensions>,
+ typename Mesh::VectorType_t,
+ typename Mesh::NormalsEngineTag_t> Type_t;
+ };
+ template<class Mesh, class T, class EngineTag>
+ typename NormalsTraits<Mesh>::Type_t
+ outwardNormals(const Field<Mesh, T, EngineTag> &f)
+ {
+ NoMesh<Mesh::dimensions> m(f.layout());
+ Centering<Mesh::dimensions> c =
+ canonicalCentering<Mesh::dimensions>(FaceType, Discontinuous);
+ typename NormalsTraits<Mesh>::Type_t
+ of(f.numMaterials(), c, f.layout(), m);
+ for (int i = 0; i < of.numMaterials(); i++)
+ for (int j = 0; j < of.centeringSize(); j++)
+ f.mesh().initializeNormals(of.subField(i, j).engine(), of.centering(j), true);
+ return of;
+ }
+ template<class Mesh, class T, class EngineTag>
+ typename NormalsTraits<Mesh>::Type_t
+ coordinateNormals(const Field<Mesh, T, EngineTag> &f)
+ {
+ NoMesh<Mesh::dimensions> m(f.layout());
+ Centering<Mesh::dimensions> c =
+ canonicalCentering<Mesh::dimensions>(FaceType, Continuous);
+ typename NormalsTraits<Mesh>::Type_t
+ of(f.numMaterials(), c, f.layout(), m);
+ for (int i = 0; i < of.numMaterials(); i++)
+ for (int j = 0; j < of.centeringSize(); j++)
+ f.mesh().initializeNormals(of.subField(i, j).engine(), of.centering(j), false);
+ return of;
+ }
+ template<class Mesh>
+ struct CellVolumesTraits {
+ typedef Field<NoMesh<Mesh::dimensions>,
+ typename Mesh::Scalar_t,
+ typename Mesh::CellVolumesEngineTag_t> Type_t;
+ };
+ template<class Mesh, class T, class EngineTag>
+ typename CellVolumesTraits<Mesh>::Type_t
+ cellVolumes(const Field<Mesh, T, EngineTag> &f)
+ {
+ NoMesh<Mesh::dimensions> m(f.layout());
+ Centering<Mesh::dimensions> c =
+ canonicalCentering<Mesh::dimensions>(CellType, Continuous);
+ typename CellVolumesTraits<Mesh>::Type_t
+ of(f.numMaterials(), c, f.layout(), m);
+ for (int i = 0; i < of.numMaterials(); i++)
+ f.mesh().initializeCellVolumes(of.subField(i, 0).engine(), of.centering(0));
+ return of;
+ }
+ template<class Mesh>
+ struct FaceAreasTraits {
+ typedef Field<NoMesh<Mesh::dimensions>,
+ typename Mesh::Scalar_t,
+ typename Mesh::FaceAreasEngineTag_t> Type_t;
+ };
+ template<class Mesh, class T, class EngineTag>
+ typename FaceAreasTraits<Mesh>::Type_t
+ faceAreas(const Field<Mesh, T, EngineTag> &f)
+ {
+ NoMesh<Mesh::dimensions> m(f.layout());
+ Centering<Mesh::dimensions> c =
+ canonicalCentering<Mesh::dimensions>(FaceType, Continuous);
+ typename FaceAreasTraits<Mesh>::Type_t
+ of(f.numMaterials(), c, f.layout(), m);
+ for (int i = 0; i < of.numMaterials(); i++)
+ for (int j = 0; j < of.centeringSize(); j++)
+ f.mesh().initializeFaceAreas(of.subField(i, j).engine(), of.centering(j));
+ return of;
+ }
+ template<class Mesh>
+ struct EdgeLengthsTraits {
+ typedef Field<NoMesh<Mesh::dimensions>,
+ typename Mesh::Scalar_t,
+ typename Mesh::EdgeLengthsEngineTag_t> Type_t;
+ };
+ template<class Mesh, class T, class EngineTag>
+ typename EdgeLengthsTraits<Mesh>::Type_t
+ edgeLengths(const Field<Mesh, T, EngineTag> &f)
+ {
+ NoMesh<Mesh::dimensions> m(f.layout());
+ Centering<Mesh::dimensions> c =
+ canonicalCentering<Mesh::dimensions>(EdgeType, Continuous);
+ typename EdgeLengthsTraits<Mesh>::Type_t
+ of(f.numMaterials(), c, f.layout(), m);
+ for (int i = 0; i < of.numMaterials(); i++)
+ for (int j = 0; j < of.centeringSize(); j++)
+ f.mesh().initializeEdgeLengths(of.subField(i, j).engine(), of.centering(j));
+ return of;
+ }
+ }
+ using Pooma::PositionsTraits;
+ using Pooma::positions;
+ using Pooma::NormalsTraits;
+ using Pooma::outwardNormals;
+ using Pooma::coordinateNormals;
+ using Pooma::CellVolumesTraits;
+ using Pooma::cellVolumes;
+ using Pooma::FaceAreasTraits;
+ using Pooma::faceAreas;
+ using Pooma::EdgeLengthsTraits;
+ using Pooma::edgeLengths;
+ class InfluenceRelation : public RelationListItem
+ {
+ public:
+ template<class Target>
+ InfluenceRelation(const Target &t)
+ : RelationListItem(),
+ list_m(const_cast<RelationList*>(&t.fieldEngine().relations()))
+ {
+ setPriority(100u);
+ }
+ InfluenceRelation(const InfluenceRelation &model)
+ : RelationListItem(model), list_m(model.list_m)
+ { }
+ InfluenceRelation() { }
+ void setDirty()
+ {
+ if (!dirty())
+ {
+ RelationListItem::setDirty();
+ list_m->setDirty();
+ }
+ }
+ void apply() { }
+ private:
+ RelationList *list_m;
+ };
+ template<class Target, class RelationFunctor>
+ class Relation0: public RelationBase<Target, RelationFunctor>
+ {
+ public:
+ Relation0(const Target &t, const RelationFunctor &f)
+ : RelationBase<Target, RelationFunctor>(t, f)
+ { }
+ ~Relation0()
+ { }
+ void apply()
+ {
+ this->functor_m(this->target_m);
+ }
+ virtual RelationListItem *retarget(const Target &target) const
+ {
+ return new Relation0<Target, RelationFunctor>(target, this->functor_m);
+ }
+ };
+ template<class Target, class R1, class RelationFunctor>
+ class Relation1: public RelationBase<Target, RelationFunctor>
+ {
+ public:
+ Relation1(const Target &t, const R1 &r,
+ const RelationFunctor &f)
+ : RelationBase<Target, RelationFunctor>(t, f), r1_m(r)
+ { }
+ ~Relation1()
+ { }
+ void apply()
+ {
+ this->functor_m(this->target_m, r1_m);
+ }
+ virtual RelationListItem *retarget(const Target &target) const
+ {
+ r1_m.addRelation(new InfluenceRelation(target));
+ return new Relation1<Target, R1, RelationFunctor>
+ (target, r1_m, this->functor_m);
+ }
+ protected:
+ R1 r1_m;
+ };
+ template<class Target, class R1, class R2, class RelationFunctor>
+ class Relation2: public RelationBase<Target, RelationFunctor>
+ {
+ public:
+ Relation2(const Target &t, const R1 &r1, const R2 &r2,
+ const RelationFunctor &f)
+ : RelationBase<Target, RelationFunctor>(t, f), r1_m(r1), r2_m(r2)
+ { }
+ ~Relation2()
+ { }
+ void apply()
+ {
+ this->functor_m(this->target_m, r1_m, r2_m);
+ }
+ virtual RelationListItem *retarget(const Target &target) const
+ {
+ r1_m.addRelation(new InfluenceRelation(target));
+ r2_m.addRelation(new InfluenceRelation(target));
+ return new Relation2<Target, R1, R2, RelationFunctor>
+ (target, r1_m, r2_m, this->functor_m);
+ }
+ protected:
+ R1 r1_m;
+ R2 r2_m;
+ };
+ template<class Target, class R1, class R2, class R3, class RelationFunctor>
+ class Relation3: public RelationBase<Target, RelationFunctor>
+ {
+ public:
+ Relation3(const Target &t, const R1 &r1, const R2 &r2, const R3 &r3,
+ const RelationFunctor &f)
+ : RelationBase<Target, RelationFunctor>(t, f),
+ r1_m(r1),
+ r2_m(r2),
+ r3_m(r3)
+ { }
+ ~Relation3()
+ { }
+ void apply()
+ {
+ this->functor_m(this->target_m, r1_m, r2_m, r3_m);
+ }
+ virtual RelationListItem *retarget(const Target &target) const
+ {
+ r1_m.addRelation(new InfluenceRelation(target));
+ r2_m.addRelation(new InfluenceRelation(target));
+ r3_m.addRelation(new InfluenceRelation(target));
+ return new Relation3<Target, R1, R2, R3, RelationFunctor>
+ (target, r1_m, r2_m, r3_m, this->functor_m);
+ }
+ protected:
+ R1 r1_m;
+ R2 r2_m;
+ R3 r3_m;
+ };
+ template<class Target, class R1, class R2, class R3, class R4,
+ class RelationFunctor>
+ class Relation4: public RelationBase<Target, RelationFunctor>
+ {
+ public:
+ Relation4(const Target &t, const R1 &r1, const R2 &r2, const R3 &r3,
+ const R4 &r4, const RelationFunctor &f)
+ : RelationBase<Target, RelationFunctor>(t, f),
+ r1_m(r1),
+ r2_m(r2),
+ r3_m(r3),
+ r4_m(r4)
+ { }
+ ~Relation4()
+ { }
+ void apply()
+ {
+ this->functor_m(this->target_m, r1_m, r2_m, r3_m, r4_m);
+ }
+ virtual RelationListItem *retarget(const Target &target) const
+ {
+ r1_m.addRelation(new InfluenceRelation(target));
+ r2_m.addRelation(new InfluenceRelation(target));
+ r3_m.addRelation(new InfluenceRelation(target));
+ r4_m.addRelation(new InfluenceRelation(target));
+ return new Relation4<Target, R1, R2, R3, R4, RelationFunctor>
+ (target, r1_m, r2_m, r3_m, r4_m, this->functor_m);
+ }
+ protected:
+ R1 r1_m;
+ R2 r2_m;
+ R3 r3_m;
+ R4 r4_m;
+ };
+ template<class Target, class R1, class R2, class R3, class R4, class R5,
+ class RelationFunctor>
+ class Relation5: public RelationBase<Target, RelationFunctor>
+ {
+ public:
+ Relation5(const Target &t, const R1 &r1, const R2 &r2, const R3 &r3,
+ const R4 &r4, const R5 &r5, const RelationFunctor &f)
+ : RelationBase<Target, RelationFunctor>(t, f),
+ r1_m(r1),
+ r2_m(r2),
+ r3_m(r3),
+ r4_m(r4),
+ r5_m(r5)
+ { }
+ ~Relation5()
+ { }
+ void apply()
+ {
+ this->functor_m(this->target_m, r1_m, r2_m, r3_m, r4_m, r5_m);
+ }
+ virtual RelationListItem *retarget(const Target &target) const
+ {
+ r1_m.addRelation(new InfluenceRelation(target));
+ r2_m.addRelation(new InfluenceRelation(target));
+ r3_m.addRelation(new InfluenceRelation(target));
+ r4_m.addRelation(new InfluenceRelation(target));
+ r5_m.addRelation(new InfluenceRelation(target));
+ return new Relation5<Target, R1, R2, R3, R4, R5, RelationFunctor>
+ (target, r1_m, r2_m, r3_m, r4_m, r5_m, this->functor_m);
+ }
+ protected:
+ R1 r1_m;
+ R2 r2_m;
+ R3 r3_m;
+ R4 r4_m;
+ R5 r5_m;
+ };
+ template<class Target, class R1, class R2, class R3, class R4, class R5,
+ class R6, class RelationFunctor>
+ class Relation6: public RelationBase<Target, RelationFunctor>
+ {
+ public:
+ Relation6(const Target &t, const R1 &r1, const R2 &r2, const R3 &r3,
+ const R4 &r4, const R5 &r5, const R6 &r6, const RelationFunctor &f)
+ : RelationBase<Target, RelationFunctor>(t, f),
+ r1_m(r1),
+ r2_m(r2),
+ r3_m(r3),
+ r4_m(r4),
+ r5_m(r5),
+ r6_m(r6)
+ { }
+ ~Relation6()
+ { }
+ void apply()
+ {
+ this->functor_m(this->target_m, r1_m, r2_m, r3_m, r4_m, r5_m, r6_m);
+ }
+ virtual RelationListItem *retarget(const Target &target) const
+ {
+ r1_m.addRelation(new InfluenceRelation(target));
+ r2_m.addRelation(new InfluenceRelation(target));
+ r3_m.addRelation(new InfluenceRelation(target));
+ r4_m.addRelation(new InfluenceRelation(target));
+ r5_m.addRelation(new InfluenceRelation(target));
+ r6_m.addRelation(new InfluenceRelation(target));
+ return new Relation6<Target, R1, R2, R3, R4, R5, R6, RelationFunctor>
+ (target, r1_m, r2_m, r3_m, r4_m, r5_m, r6_m, this->functor_m);
+ }
+ protected:
+ R1 r1_m;
+ R2 r2_m;
+ R3 r3_m;
+ R4 r4_m;
+ R5 r5_m;
+ R6 r6_m;
+ };
+ template<class L>
+ class RelationFunctionPtr0 {
+ public:
+ RelationFunctionPtr0(void (*f)(const L &))
+ : f_m(f)
+ { }
+ RelationFunctionPtr0(const RelationFunctionPtr0<L> &init, const L &)
+ : f_m(init.f_m)
+ { }
+ inline void operator()(const L &l)
+ {
+ f_m(l);
+ }
+ private:
+ void (*f_m)(const L &);
+ };
+ template<class L, class R1>
+ class RelationFunctionPtr1 {
+ public:
+ RelationFunctionPtr1(void (*f)(const L &, const R1 &))
+ : f_m(f)
+ { }
+ RelationFunctionPtr1(const RelationFunctionPtr1<L, R1> &init, const L &)
+ : f_m(init.f_m)
+ { }
+ inline void operator()(const L &l, const R1 &r1)
+ {
+ f_m(l, r1);
+ }
+ private:
+ void (*f_m)(const L &, const R1 &);
+ };
+ template<class L, class R1, class R2>
+ class RelationFunctionPtr2 {
+ public:
+ RelationFunctionPtr2(void (*f)(const L &, const R1 &, const R2 &))
+ : f_m(f)
+ { }
+ RelationFunctionPtr2(const RelationFunctionPtr2<L, R1, R2> &init, const L &)
+ : f_m(init.f_m)
+ { }
+ inline void operator()(const L &l, const R1 &r1, const R2 &r2)
+ {
+ f_m(l, r1, r2);
+ }
+ private:
+ void (*f_m)(const L &, const R1 &, const R2 &);
+ };
+ template<class L, class R1, class R2, class R3>
+ class RelationFunctionPtr3 {
+ public:
+ RelationFunctionPtr3(void (*f)(const L &,
+ const R1 &, const R2 &, const R3 &))
+ : f_m(f)
+ { }
+ RelationFunctionPtr3(
+ const RelationFunctionPtr3<L, R1, R2, R3> &model)
+ : f_m(model.f_m)
+ { }
+ RelationFunctionPtr3(
+ const RelationFunctionPtr3<L, R1, R2, R3> &init, const L &)
+ : f_m(init.f_m)
+ { }
+ inline void operator()(const L &l, const R1 &r1, const R2 &r2,
+ const R3 &r3)
+ {
+ f_m(l, r1, r2, r3);
+ }
+ private:
+ void (*f_m)(const L &, const R1 &, const R2 &, const R3 &);
+ };
+ template<class L, class R1, class R2, class R3, class R4>
+ class RelationFunctionPtr4 {
+ public:
+ RelationFunctionPtr4(void (*f)(const L &,
+ const R1 &, const R2 &, const R3 &, const R4 &))
+ : f_m(f)
+ { }
+ RelationFunctionPtr4(
+ const RelationFunctionPtr4<L, R1, R2, R3, R4> &model)
+ : f_m(model.f_m)
+ { }
+ RelationFunctionPtr4(
+ const RelationFunctionPtr4<L, R1, R2, R3, R4> &init, const L &)
+ : f_m(init.f_m)
+ { }
+ inline void operator()(const L &l, const R1 &r1, const R2 &r2,
+ const R3 &r3, const R4 &r4)
+ {
+ f_m(l, r1, r2, r3, r4);
+ }
+ private:
+ void (*f_m)(const L &, const R1 &, const R2 &,
+ const R3 &, const R4 &);
+ };
+ template<class L,
+ class R1, class R2, class R3, class R4, class R5>
+ class RelationFunctionPtr5 {
+ public:
+ RelationFunctionPtr5(void (*f)(const L &,
+ const R1 &, const R2 &, const R3 &, const R4 &, const R5 &))
+ : f_m(f)
+ { }
+ RelationFunctionPtr5(
+ const RelationFunctionPtr5<L, R1, R2, R3, R4, R5> &model)
+ : f_m(model.f_m)
+ { }
+ RelationFunctionPtr5(
+ const RelationFunctionPtr5<L, R1, R2, R3, R4, R5> &init, const L &)
+ : f_m(init.f_m)
+ { }
+ inline void operator()(const L &l, const R1 &r1, const R2 &r2,
+ const R3 &r3, const R4 &r4, const R5 &r5)
+ {
+ f_m(l, r1, r2, r3, r4, r5);
+ }
+ private:
+ void (*f_m)(const L &, const R1 &, const R2 &,
+ const R3 &, const R4 &, const R5 &);
+ };
+ template<class L,
+ class R1, class R2, class R3, class R4, class R5, class R6>
+ class RelationFunctionPtr6 {
+ public:
+ RelationFunctionPtr6(void (*f)(const L &,
+ const R1 &, const R2 &, const R3 &, const R4 &, const R5 &, const R6 &))
+ : f_m(f)
+ { }
+ RelationFunctionPtr6(
+ const RelationFunctionPtr6<L, R1, R2, R3, R4, R5, R6> &model)
+ : f_m(model.f_m)
+ { }
+ RelationFunctionPtr6(
+ const RelationFunctionPtr6<L, R1, R2, R3, R4, R5, R6> &init, const L &)
+ : f_m(init.f_m)
+ { }
+ inline void operator()(const L &l, const R1 &r1, const R2 &r2,
+ const R3 &r3, const R4 &r4, const R5 &r5, const R6 &r6)
+ {
+ f_m(l, r1, r2, r3, r4, r5, r6);
+ }
+ private:
+ void (*f_m)(const L &, const R1 &, const R2 &,
+ const R3 &, const R4 &, const R5 &, const R6 &);
+ };
+ template<class C, class L>
+ class RelationMemberPtr0 {
+ public:
+ RelationMemberPtr0(const C &obj, void (C::*f)(const L &))
+ : obj_m(obj), f_m(f)
+ { }
+ RelationMemberPtr0(const RelationMemberPtr0<C, L> &model)
+ : obj_m(model.obj_m), f_m(model.f_m)
+ { }
+ RelationMemberPtr0(const RelationMemberPtr0<C, L> &init, const L &)
+ : obj_m(init.obj_m), f_m(init.f_m)
+ { }
+ inline void operator()(const L &l)
+ {
+ (obj_m.*f_m)(l);
+ }
+ private:
+ C obj_m;
+ void (C::*f_m)(const L &);
+ };
+ template<class C, class L, class R1>
+ class RelationMemberPtr1 {
+ public:
+ RelationMemberPtr1(const C &obj, void (C::*f)(const L &,
+ const R1 &))
+ : obj_m(obj), f_m(f)
+ { }
+ RelationMemberPtr1(const RelationMemberPtr1<C, L, R1> &model)
+ : obj_m(model.obj_m), f_m(model.f_m)
+ { }
+ RelationMemberPtr1(const RelationMemberPtr1<C, L, R1> &init, const L &)
+ : obj_m(init.obj_m), f_m(init.f_m)
+ { }
+ inline void operator()(const L &l, const R1 &r1)
+ {
+ (obj_m.*f_m)(l, r1);
+ }
+ private:
+ C obj_m;
+ void (C::*f_m)(const L &, const R1 &);
+ };
+ template<class C, class L, class R1, class R2>
+ class RelationMemberPtr2 {
+ public:
+ RelationMemberPtr2(const C &obj, void (C::*f)(const L &,
+ const R1 &, const R2 &))
+ : obj_m(obj), f_m(f)
+ { }
+ RelationMemberPtr2(const RelationMemberPtr2<C, L, R1, R2> &model)
+ : obj_m(model.obj_m), f_m(model.f_m)
+ { }
+ RelationMemberPtr2(const RelationMemberPtr2<C, L, R1, R2> &init, const L &)
+ : obj_m(init.obj_m), f_m(init.f_m)
+ { }
+ inline void operator()(const L &l, const R1 &r1, const R2 &r2)
+ {
+ (obj_m.*f_m)(l, r1, r2);
+ }
+ private:
+ C obj_m;
+ void (C::*f_m)(const L &, const R1 &, const R2 &);
+ };
+ template<class C, class L, class R1, class R2, class R3>
+ class RelationMemberPtr3 {
+ public:
+ RelationMemberPtr3(const C &obj, void (C::*f)(const L &,
+ const R1 &, const R2 &, const R3 &))
+ : obj_m(obj), f_m(f)
+ { }
+ RelationMemberPtr3(
+ const RelationMemberPtr3<C, L, R1, R2, R3> &model)
+ : obj_m(model.obj_m), f_m(model.f_m)
+ { }
+ RelationMemberPtr3(
+ const RelationMemberPtr3<C, L, R1, R2, R3> &init, const L &)
+ : obj_m(init.obj_m), f_m(init.f_m)
+ { }
+ inline void operator()(const L &l, const R1 &r1, const R2 &r2,
+ const R3 &r3)
+ {
+ (obj_m.*f_m)(l, r1, r2, r3);
+ }
+ private:
+ C obj_m;
+ void (C::*f_m)(const L &, const R1 &, const R2 &, const R3 &);
+ };
+ template<class C, class L, class R1, class R2, class R3, class R4>
+ class RelationMemberPtr4 {
+ public:
+ RelationMemberPtr4(const C &obj, void (C::*f)(const L &,
+ const R1 &, const R2 &, const R3 &, const R4 &))
+ : obj_m(obj), f_m(f)
+ { }
+ RelationMemberPtr4(
+ const RelationMemberPtr4<C, L, R1, R2, R3, R4> &model)
+ : obj_m(model.obj_m), f_m(model.f_m)
+ { }
+ RelationMemberPtr4(
+ const RelationMemberPtr4<C, L, R1, R2, R3, R4> &init, const L &)
+ : obj_m(init.obj_m), f_m(init.f_m)
+ { }
+ inline void operator()(const L &l, const R1 &r1, const R2 &r2,
+ const R3 &r3, const R4 &r4)
+ {
+ (obj_m.*f_m)(l, r1, r2, r3, r4);
+ }
+ private:
+ C obj_m;
+ void (C::*f_m)(const L &, const R1 &, const R2 &,
+ const R3 &, const R4 &);
+ };
+ template<class C, class L,
+ class R1, class R2, class R3, class R4, class R5>
+ class RelationMemberPtr5 {
+ public:
+ RelationMemberPtr5(const C &obj, void (C::*f)(const L &,
+ const R1 &, const R2 &, const R3 &, const R4 &, const R5 &))
+ : obj_m(obj), f_m(f)
+ { }
+ RelationMemberPtr5(
+ const RelationMemberPtr5<C, L, R1, R2, R3, R4, R5> &model)
+ : obj_m(model.obj_m), f_m(model.f_m)
+ { }
+ RelationMemberPtr5(
+ const RelationMemberPtr5<C, L, R1, R2, R3, R4, R5> &init, const L &)
+ : obj_m(init.obj_m), f_m(init.f_m)
+ { }
+ inline void operator()(const L &l, const R1 &r1, const R2 &r2,
+ const R3 &r3, const R4 &r4, const R5 &r5)
+ {
+ (obj_m.*f_m)(l, r1, r2, r3, r4, r5);
+ }
+ private:
+ C obj_m;
+ void (C::*f_m)(const L &, const R1 &, const R2 &,
+ const R3 &, const R4 &, const R5 &);
+ };
+ template<class C, class L,
+ class R1, class R2, class R3, class R4, class R5, class R6>
+ class RelationMemberPtr6 {
+ public:
+ RelationMemberPtr6(const C &obj, void (C::*f)(const L &,
+ const R1 &, const R2 &, const R3 &, const R4 &, const R5 &, const R6 &))
+ : obj_m(obj), f_m(f)
+ { }
+ RelationMemberPtr6(
+ const RelationMemberPtr6<C, L, R1, R2, R3, R4, R5, R6> &model)
+ : obj_m(model.obj_m), f_m(model.f_m)
+ { }
+ RelationMemberPtr6(
+ const RelationMemberPtr6<C, L, R1, R2, R3, R4, R5, R6> &init, const L &)
+ : obj_m(init.obj_m), f_m(init.f_m)
+ { }
+ inline void operator()(const L &l, const R1 &r1, const R2 &r2,
+ const R3 &r3, const R4 &r4, const R5 &r5, const R6 &r6)
+ {
+ (obj_m.*f_m)(l, r1, r2, r3, r4, r5, r6);
+ }
+ private:
+ C obj_m;
+ void (C::*f_m)(const L &, const R1 &, const R2 &,
+ const R3 &, const R4 &, const R5 &, const R6 &);
+ };
+ template<class RelationFunctor>
+ struct RelationFunctorTraits {
+ enum { defaultPriority = 0 };
+ };
+ namespace Pooma {
+ template<class RelationFunctor, class L>
+ void newRelation(const RelationFunctor &f, const L &l)
+ {
+ for (int m = 0; m < l.numMaterials(); ++m)
+ {
+ for (int c = 0; c < l.centeringSize(); ++c)
+ {
+ const L &lsub = l.subField(m, c);
+ RelationListItem *r = new Relation0<L, RelationFunctor>(lsub, f);
+ r->setPriority(RelationFunctorTraits<RelationFunctor>::defaultPriority);
+ lsub.addRelation(r);
+ }
+ }
+ }
+ template<class RelationFunctor, class L, class R1>
+ void newRelation(const RelationFunctor &f, const L &l,
+ const R1 &r1)
+ {
+ for (int m = 0; m < l.numMaterials(); ++m)
+ {
+ for (int c = 0; c < l.centeringSize(); ++c)
+ {
+ const L &lsub = l.subField(m, c);
+ const R1 &r1sub = r1.subField(m, c);
+ r1sub.addRelation(new InfluenceRelation(lsub));
+ RelationListItem *r = new
+ Relation1<L, R1, RelationFunctor>
+ (lsub, r1sub, f);
+ lsub.addRelation(r);
+ }
+ }
+ }
+ template<class RelationFunctor, class L, class R1, class R2>
+ void newRelation(const RelationFunctor &f, const L &l,
+ const R1 &r1, const R2 &r2)
+ {
+ for (int m = 0; m < l.numMaterials(); ++m)
+ {
+ for (int c = 0; c < l.centeringSize(); ++c)
+ {
+ const L &lsub = l.subField(m, c);
+ const R1 &r1sub = r1.subField(m, c);
+ const R2 &r2sub = r2.subField(m, c);
+ r1sub.addRelation(new InfluenceRelation(lsub));
+ r2sub.addRelation(new InfluenceRelation(lsub));
+ RelationListItem *r =
+ new Relation2<L, R1, R2, RelationFunctor>(lsub, r1sub, r2sub, f);
+ lsub.addRelation(r);
+ }
+ }
+ }
+ template<class RelationFunctor, class L, class R1, class R2, class R3>
+ void newRelation(const RelationFunctor &f, const L &l,
+ const R1 &r1, const R2 &r2, const R3 &r3)
+ {
+ for (int m = 0; m < l.numMaterials(); ++m)
+ {
+ for (int c = 0; c < l.centeringSize(); ++c)
+ {
+ const L &lsub = l.subField(m, c);
+ const R1 &r1sub = r1.subField(m, c);
+ const R2 &r2sub = r2.subField(m, c);
+ const R3 &r3sub = r3.subField(m, c);
+ r1sub.addRelation(new InfluenceRelation(lsub));
+ r2sub.addRelation(new InfluenceRelation(lsub));
+ r3sub.addRelation(new InfluenceRelation(lsub));
+ RelationListItem *r = new
+ Relation3<L, R1, R2, R3, RelationFunctor>
+ (lsub, r1sub, r2sub, r3sub, f);
+ lsub.addRelation(r);
+ }
+ }
+ }
+ template<class RelationFunctor, class L, class R1, class R2, class R3,
+ class R4>
+ void newRelation(const RelationFunctor &f, const L &l,
+ const R1 &r1, const R2 &r2,
+ const R3 &r3, const R4 &r4)
+ {
+ for (int m = 0; m < l.numMaterials(); ++m)
+ {
+ for (int c = 0; c < l.centeringSize(); ++c)
+ {
+ const L &lsub = l.subField(m, c);
+ const R1 &r1sub = r1.subField(m, c);
+ const R2 &r2sub = r2.subField(m, c);
+ const R3 &r3sub = r3.subField(m, c);
+ const R4 &r4sub = r4.subField(m, c);
+ r1sub.addRelation(new InfluenceRelation(lsub));
+ r2sub.addRelation(new InfluenceRelation(lsub));
+ r3sub.addRelation(new InfluenceRelation(lsub));
+ r4sub.addRelation(new InfluenceRelation(lsub));
+ RelationListItem *r = new
+ Relation4<L, R1, R2, R3, R4, RelationFunctor>
+ (lsub, r1sub, r2sub, r3sub, r4sub, f);
+ lsub.addRelation(r);
+ }
+ }
+ }
+ template<class RelationFunctor, class L, class R1, class R2, class R3,
+ class R4, class R5>
+ void newRelation(const RelationFunctor &f, const L &l,
+ const R1 &r1, const R2 &r2,
+ const R3 &r3, const R4 &r4, const R5 &r5)
+ {
+ for (int m = 0; m < l.numMaterials(); ++m)
+ {
+ for (int c = 0; c < l.centeringSize(); ++c)
+ {
+ const L &lsub = l.subField(m, c);
+ const R1 &r1sub = r1.subField(m, c);
+ const R2 &r2sub = r2.subField(m, c);
+ const R3 &r3sub = r3.subField(m, c);
+ const R4 &r4sub = r4.subField(m, c);
+ const R5 &r5sub = r5.subField(m, c);
+ r1sub.addRelation(new InfluenceRelation(lsub));
+ r2sub.addRelation(new InfluenceRelation(lsub));
+ r3sub.addRelation(new InfluenceRelation(lsub));
+ r4sub.addRelation(new InfluenceRelation(lsub));
+ r5sub.addRelation(new InfluenceRelation(lsub));
+ RelationListItem *r = new
+ Relation5<L, R1, R2, R3, R4, R5, RelationFunctor>
+ (lsub, r1sub, r2sub, r3sub, r4sub, r5sub, f);
+ lsub.addRelation(r);
+ }
+ }
+ }
+ template<class RelationFunctor, class L, class R1, class R2, class R3,
+ class R4, class R5, class R6>
+ void newRelation(const RelationFunctor &f, const L &l,
+ const R1 &r1, const R2 &r2,
+ const R3 &r3, const R4 &r4, const R5 &r5, const R6 &r6)
+ {
+ for (int m = 0; m < l.numMaterials(); ++m)
+ {
+ for (int c = 0; c < l.centeringSize(); ++c)
+ {
+ const L &lsub = l.subField(m, c);
+ const R1 &r1sub = r1.subField(m, c);
+ const R2 &r2sub = r2.subField(m, c);
+ const R3 &r3sub = r3.subField(m, c);
+ const R4 &r4sub = r4.subField(m, c);
+ const R5 &r5sub = r5.subField(m, c);
+ const R6 &r6sub = r6.subField(m, c);
+ r1sub.addRelation(new InfluenceRelation(lsub));
+ r2sub.addRelation(new InfluenceRelation(lsub));
+ r3sub.addRelation(new InfluenceRelation(lsub));
+ r4sub.addRelation(new InfluenceRelation(lsub));
+ r5sub.addRelation(new InfluenceRelation(lsub));
+ r6sub.addRelation(new InfluenceRelation(lsub));
+ RelationListItem *r = new
+ Relation6<L, R1, R2, R3, R4, R5, R6, RelationFunctor>
+ (lsub, r1sub, r2sub, r3sub, r4sub, r5sub, r6sub, f);
+ lsub.addRelation(r);
+ }
+ }
+ }
+ template<class L>
+ RelationFunctionPtr0<L>
+ functionPtr(void (*f)(const L &))
+ {
+ return RelationFunctionPtr0<L>(f);
+ }
+ template<class L, class R1>
+ RelationFunctionPtr1<L, R1>
+ functionPtr(void (*f)(const L &, const R1 &))
+ {
+ return RelationFunctionPtr1<L, R1>(f);
+ }
+ template<class L, class R1, class R2>
+ RelationFunctionPtr2<L, R1, R2>
+ functionPtr(void (*f)(const L &, const R1 &, const R2 &))
+ {
+ return RelationFunctionPtr2<L, R1, R2>(f);
+ }
+ template<class L, class R1, class R2, class R3>
+ RelationFunctionPtr3<L, R1, R2, R3>
+ functionPtr(void (*f)(const L &, const R1 &, const R2 &, const R3 &))
+ {
+ return RelationFunctionPtr3<L, R1, R2, R3>(f);
+ }
+ template<class L, class R1, class R2, class R3, class R4>
+ RelationFunctionPtr4<L, R1, R2, R3, R4>
+ functionPtr(void (*f)(const L &, const R1 &, const R2 &, const R3 &,
+ const R4 &r4))
+ {
+ return RelationFunctionPtr4<L, R1, R2, R3, R4>(f);
+ }
+ template<class L, class R1, class R2, class R3,
+ class R4, class R5>
+ RelationFunctionPtr5<L, R1, R2, R3, R4, R5>
+ functionPtr(void (*f)(const L &, const R1 &, const R2 &, const R3 &,
+ const R4 &r4, const R5 &r5))
+ {
+ return RelationFunctionPtr5<L, R1, R2, R3, R4, R5>(f);
+ }
+ template<class L, class R1, class R2, class R3,
+ class R4, class R5, class R6>
+ RelationFunctionPtr6<L, R1, R2, R3, R4, R5, R6>
+ functionPtr(void (*f)(const L &, const R1 &, const R2 &, const R3 &,
+ const R4 &r4, const R5 &r5, const R6 &r6))
+ {
+ return RelationFunctionPtr6<L, R1, R2, R3, R4, R5, R6>(f);
+ }
+ template<class C, class L>
+ RelationMemberPtr0<C, L>
+ memberPtr(const C &obj, void (C::*f)(const L &))
+ {
+ return RelationMemberPtr0<C, L>(obj, f);
+ }
+ template<class C, class L, class R1>
+ RelationMemberPtr1<C, L, R1>
+ memberPtr(const C &obj, void (C::*f)(const L &, const R1 &))
+ {
+ return RelationMemberPtr1<C, L, R1>(obj, f);
+ }
+ template<class C, class L, class R1, class R2>
+ RelationMemberPtr2<C, L, R1, R2>
+ memberPtr(const C &obj, void (C::*f)(const L &, const R1 &, const R2 &))
+ {
+ return RelationMemberPtr2<C, L, R1, R2>(obj, f);
+ }
+ template<class C, class L, class R1, class R2, class R3>
+ RelationMemberPtr3<C, L, R1, R2, R3>
+ memberPtr(const C &obj,
+ void (C::*f)(const L &, const R1 &, const R2 &, const R3 &))
+ {
+ return RelationMemberPtr3<C, L, R1, R2, R3>(obj, f);
+ }
+ template<class C, class L, class R1, class R2, class R3,
+ class R4>
+ RelationMemberPtr4<C, L, R1, R2, R3, R4>
+ memberPtr(const C &obj,
+ void (C::*f)(const L &, const R1 &, const R2 &, const R3 &,
+ const R4 &r4))
+ {
+ return RelationMemberPtr4<C, L, R1, R2, R3, R4>(obj, f);
+ }
+ template<class C, class L, class R1, class R2, class R3,
+ class R4, class R5>
+ RelationMemberPtr5<C, L, R1, R2, R3, R4, R5>
+ memberPtr(const C &obj,
+ void (C::*f)(const L &, const R1 &, const R2 &, const R3 &,
+ const R4 &r4, const R5 &r5))
+ {
+ return RelationMemberPtr5<C, L, R1, R2, R3, R4, R5>(obj, f);
+ }
+ template<class C, class L, class R1, class R2, class R3,
+ class R4, class R5, class R6>
+ RelationMemberPtr6<C, L, R1, R2, R3, R4, R5, R6>
+ memberPtr(const C &obj,
+ void (C::*f)(const L &, const R1 &, const R2 &, const R3 &,
+ const R4 &r4, const R5 &r5, const R6 &r6))
+ {
+ return RelationMemberPtr6<C, L, R1, R2, R3, R4, R5, R6>(obj, f);
+ }
+ }
+ template<int Dim, class T>
+ class ConstantFaceBC
+ {
+ public:
+ ConstantFaceBC(int face, const T &constant,
+ bool enforceConstantBoundary = false)
+ : domain_m(Pooma::NoInit()),
+ face_m(face),
+ constant_m(constant),
+ enforceConstantBoundary_m(enforceConstantBoundary)
+ { }
+ ConstantFaceBC(const ConstantFaceBC<Dim, T> &model)
+ : domain_m(model.domain_m),
+ face_m(model.face_m),
+ constant_m(model.constant_m),
+ enforceConstantBoundary_m(model.enforceConstantBoundary_m)
+ { }
+ template<class Target>
+ ConstantFaceBC(const ConstantFaceBC<Dim, T> &init, const Target &t)
+ : domain_m(t.totalDomain()),
+ face_m(init.face_m),
+ constant_m(init.constant_m),
+ enforceConstantBoundary_m(init.enforceConstantBoundary_m)
+ {
+ ;
+ int d = face_m / 2;
+ int adjust;
+ if (enforceConstantBoundary_m &&
+ t.centering().orientation(0)[d].min() == 0)
+ adjust = 0;
+ else
+ adjust = 1;
+ if (face_m & 1)
+ {
+ int nGuards = t.fieldEngine().guardLayers().upper(d);
+ domain_m[d] = Interval<1>(domain_m[d].max() - nGuards + adjust,
+ domain_m[d].max());
+ }
+ else
+ {
+ int nGuards = t.fieldEngine().guardLayers().lower(d);
+ domain_m[d] = Interval<1>(domain_m[d].min(),
+ domain_m[d].min() + nGuards - adjust);
+ }
+ }
+ ConstantFaceBC<Dim, T> &operator=(const ConstantFaceBC<Dim, T> &rhs)
+ {
+ domain_m = rhs.domain_m;
+ face_m = rhs.face_m;
+ constant_m = rhs.constant_m;
+ enforceConstantBoundary_m = rhs.enforceConstantBoundary_m;
+ return *this;
+ }
+ T constant() const { return constant_m; }
+ void setConstant(T newConstant) { constant_m = newConstant; }
+ int face() const { return face_m; }
+ template<class Target>
+ void operator()(const Target &t) const
+ {
+ t(domain_m) = constant_m;
+ }
+ private:
+ Interval<Dim> domain_m;
+ int face_m;
+ T constant_m;
+ bool enforceConstantBoundary_m;
+ };
+ template<int Dim, class T>
+ struct RelationFunctorTraits<ConstantFaceBC<Dim, T> > {
+ enum { defaultPriority = 100 };
+ };
+ namespace Pooma {
+ template<class Target, class T>
+ void addConstantFaceBC(const Target &f, int face, const T &constant,
+ bool enforceConstantBoundary = false)
+ {
+ newRelation(ConstantFaceBC<Target::dimensions, T>
+ (face, constant, enforceConstantBoundary), f);
+ }
+ template<class Target, class T>
+ void addAllConstantFaceBC(const Target &f, const T &constant,
+ bool enforceConstantBoundary = false)
+ {
+ for (int i = 0; i < 2 * Target::dimensions; i++)
+ {
+ addConstantFaceBC(f, i, constant, enforceConstantBoundary);
+ }
+ }
+ }
+ template<int Dim>
+ class ReflectFaceBase
+ {
+ public:
+ ReflectFaceBase(int face, bool enforceZeroBoundary = false)
+ : domain_m(Pooma::NoInit()),
+ vertFaceDomain_m(Pooma::NoInit()),
+ srcRange_m(Pooma::NoInit()),
+ face_m(face),
+ enforceZeroBoundary_m(enforceZeroBoundary)
+ { }
+ ReflectFaceBase(const ReflectFaceBase<Dim> &model)
+ : domain_m(model.domain_m),
+ vertFaceDomain_m(model.vertFaceDomain_m),
+ srcRange_m(model.srcRange_m),
+ face_m(model.face_m),
+ enforceZeroBoundary_m(model.enforceZeroBoundary_m)
+ { }
+ template<class Target>
+ ReflectFaceBase(const ReflectFaceBase<Dim> &init, const Target &t)
+ : domain_m(t.totalDomain()),
+ vertFaceDomain_m(t.totalDomain()),
+ srcRange_m(Pooma::NoInit()),
+ face_m(init.face_m),
+ enforceZeroBoundary_m(init.enforceZeroBoundary_m)
+ {
+ ;
+ for (int dd = 0; dd < Dim; ++dd)
+ {
+ srcRange_m[dd] =
+ Range<1>(domain_m[dd].min(), domain_m[dd].max(), 1);
+ }
+ int d = face_m / 2;
+ int adjust = 1 - t.centering().orientation(0)[d].min();
+ if (face_m & 1)
+ {
+ int nGuards = t.fieldEngine().guardLayers().upper(d);
+ if (adjust == 1)
+ {
+ vertFaceDomain_m[d] =
+ Interval<1>(t.physicalDomain()[d].max(),
+ t.physicalDomain()[d].max());
+ }
+ srcRange_m[d] =
+ Range<1>(t.physicalDomain()[d].max() - adjust,
+ t.physicalDomain()[d].max() - adjust - (nGuards - 1),
+ -1);
+ domain_m[d] = Interval<1>(domain_m[d].max() - (nGuards - 1),
+ domain_m[d].max());
+ }
+ else
+ {
+ int nGuards = t.fieldEngine().guardLayers().lower(d);
+ if (adjust == 1)
+ {
+ vertFaceDomain_m[d] =
+ Interval<1>(t.physicalDomain()[d].min(),
+ t.physicalDomain()[d].min());
+ }
+ srcRange_m[d] =
+ Range<1>(t.physicalDomain()[d].min() + adjust +
+ (nGuards - 1),
+ t.physicalDomain()[d].min() + adjust, -1);
+ domain_m[d] = Interval<1>(domain_m[d].min(),
+ domain_m[d].min() + (nGuards - 1));
+ }
+ }
+ ReflectFaceBase<Dim> &operator=(const ReflectFaceBase<Dim> &rhs)
+ {
+ domain_m = rhs.domain_m;
+ vertFaceDomain_m = rhs.vertFaceDomain_m;
+ srcRange_m = rhs.srcRange_m;
+ face_m = rhs.face_m;
+ enforceZeroBoundary_m = rhs.enforceZeroBoundary_m;
+ return *this;
+ }
+ int face() const { return face_m; }
+ bool enforceZeroBoundary() const { return enforceZeroBoundary_m; }
+ protected:
+ Interval<Dim> domain_m, vertFaceDomain_m;
+ Range<Dim> srcRange_m;
+ int face_m;
+ bool enforceZeroBoundary_m;
+ };
+ template<int Dim>
+ class PosReflectFaceBC : public ReflectFaceBase<Dim>
+ {
+ public:
+ PosReflectFaceBC(int face, bool enforceZeroBoundary = false)
+ : ReflectFaceBase<Dim>(face, enforceZeroBoundary)
+ {}
+ template<class Target>
+ PosReflectFaceBC(const PosReflectFaceBC<Dim>& init, const Target &t)
+ : ReflectFaceBase<Dim>(init, t)
+ {}
+ template<class Target>
+ void operator()(const Target &t) const
+ {
+ t(this->domain_m) = t(this->srcRange_m);
+ if (this->enforceZeroBoundary_m &&
+ t.centering().orientation(0)[this->face_m / 2].min() == 0)
+ {
+ typedef typename Target::Element_t T;
+ t(this->vertFaceDomain_m) = T(0.0);
+ }
+ }
+ };
+ template<int Dim>
+ class NegReflectFaceBC : public ReflectFaceBase<Dim>
+ {
+ public:
+ NegReflectFaceBC(int face, bool enforceZeroBoundary = false)
+ : ReflectFaceBase<Dim>(face, enforceZeroBoundary)
+ {}
+ template<class Target>
+ NegReflectFaceBC(const NegReflectFaceBC<Dim>& init, const Target &t)
+ : ReflectFaceBase<Dim>(init, t)
+ {}
+ template<class Target>
+ void operator()(const Target &t) const
+ {
+ t(this->domain_m) = -t(this->srcRange_m);
+ if (this->enforceZeroBoundary_m &&
+ t.centering().orientation(0)[this->face_m / 2].min() == 0)
+ {
+ typedef typename Target::Element_t T;
+ t(this->vertFaceDomain_m) = T(0.0);
+ }
+ }
+ };
+ template<int Dim>
+ struct RelationFunctorTraits<PosReflectFaceBC<Dim> > {
+ enum { defaultPriority = 100 };
+ };
+ template<int Dim>
+ struct RelationFunctorTraits<NegReflectFaceBC<Dim> > {
+ enum { defaultPriority = 100 };
+ };
+ namespace Pooma {
+ template<class Target>
+ void addPosReflectFaceBC(const Target &f, int face,
+ bool enforceZeroBoundary = false)
+ {
+ newRelation(PosReflectFaceBC<Target::dimensions>
+ (face, enforceZeroBoundary), f);
+ }
+ template<class Target>
+ void addAllPosReflectFaceBC(const Target &f, bool enforceZeroBoundary = false)
+ {
+ for (int i = 0; i < 2 * Target::dimensions; i++)
+ {
+ addPosReflectFaceBC(f, i, enforceZeroBoundary);
+ }
+ }
+ template<class Target>
+ void addNegReflectFaceBC(const Target &f, int face,
+ bool enforceZeroBoundary = false)
+ {
+ newRelation(NegReflectFaceBC<Target::dimensions>
+ (face, enforceZeroBoundary), f);
+ }
+ template<class Target>
+ void addAllNegReflectFaceBC(const Target &f, bool enforceZeroBoundary = false)
+ {
+ for (int i = 0; i < 2 * Target::dimensions; i++)
+ {
+ addNegReflectFaceBC(f, i, enforceZeroBoundary);
+ }
+ }
+ }
+ template<int Dim>
+ class PeriodicFaceBC
+ {
+ public:
+ PeriodicFaceBC(int face)
+ : domain_m(Pooma::NoInit()),
+ srcDomain_m(Pooma::NoInit()),
+ face_m(face)
+ { }
+ PeriodicFaceBC(const PeriodicFaceBC<Dim> &model)
+ : domain_m(model.domain_m),
+ srcDomain_m(model.srcDomain_m),
+ face_m(model.face_m)
+ { }
+ template<class Target>
+ PeriodicFaceBC(const PeriodicFaceBC<Dim> &init, const Target &t)
+ : domain_m(t.totalDomain()),
+ srcDomain_m(t.totalDomain()),
+ face_m(init.face_m)
+ {
+ ;
+ int d = face_m / 2;
+ int adjust = 1 - t.centering().orientation(0)[d].min();
+ if (face_m & 1)
+ {
+ int nGuards = t.fieldEngine().guardLayers().upper(d);
+ domain_m[d] =
+ Interval<1>(domain_m[d].max() - nGuards,
+ domain_m[d].max());
+ srcDomain_m[d] =
+ Interval<1>(domain_m[d].min() -
+ (t.physicalDomain()[d].length() - 1 - adjust),
+ domain_m[d].max() -
+ (t.physicalDomain()[d].length() - 1 - adjust));
+ }
+ else
+ {
+ int nGuards = t.fieldEngine().guardLayers().lower(d);
+ domain_m[d] = Interval<1>(domain_m[d].min(),
+ domain_m[d].min() + (nGuards - 1) + adjust);
+ srcDomain_m[d] =
+ Interval<1>(domain_m[d].min() +
+ (t.physicalDomain()[d].length() - 1 - adjust),
+ domain_m[d].max() +
+ (t.physicalDomain()[d].length() - 1 - adjust));
+ }
+ }
+ PeriodicFaceBC<Dim> &operator=(const PeriodicFaceBC<Dim> &rhs)
+ {
+ if (&rhs != this)
+ {
+ domain_m = rhs.domain_m;
+ srcDomain_m = rhs.srcDomain_m;
+ face_m = rhs.face_m;
+ }
+ return *this;
+ }
+ int face() const { return face_m; }
+ template<class Target>
+ void operator()(const Target &t) const
+ {
+ t(domain_m) = t(srcDomain_m);
+ }
+ private:
+ Interval<Dim> domain_m, srcDomain_m;
+ int face_m;
+ };
+ template<int Dim>
+ struct RelationFunctorTraits<PeriodicFaceBC<Dim> > {
+ enum { defaultPriority = 100 };
+ };
+ namespace Pooma {
+ template<class Target>
+ void addPeriodicFaceBC(const Target &f, int face)
+ {
+ newRelation(PeriodicFaceBC<Target::dimensions>(face), f);
+ }
+ template<class Target>
+ void addAllPeriodicFaceBC(const Target &f)
+ {
+ for (int i = 0; i < 2 * Target::dimensions; i++)
+ {
+ addPeriodicFaceBC(f, i);
+ }
+ }
+ }
+ template<int Dim>
+ class ZeroGradientFaceBC
+ {
+ public:
+ ZeroGradientFaceBC(int face)
+ : srcDomain_m(Pooma::NoInit()),
+ face_m(face)
+ { }
+ ZeroGradientFaceBC(const ZeroGradientFaceBC<Dim> &model)
+ : srcDomain_m(model.srcDomain_m),
+ domains_m(model.domains_m),
+ face_m(model.face_m)
+ { }
+ template<class Target>
+ ZeroGradientFaceBC(const ZeroGradientFaceBC<Dim> &init, const Target &t)
+ : srcDomain_m(t.totalDomain()),
+ face_m(init.face_m)
+ {
+ ;
+ int d = face_m / 2;
+ int adjust = 1 - t.centering().orientation(0)[d].min();
+ if (face_m & 1)
+ {
+ int nGuards = t.fieldEngine().guardLayers().upper(d);
+ domains_m.resize(nGuards+adjust, t.totalDomain());
+ srcDomain_m[d] =
+ Interval<1>(t.physicalDomain()[d].max() - adjust,
+ t.physicalDomain()[d].max() - adjust);
+ for (int i=0; i<nGuards+adjust; i++)
+ domains_m[i][d] =
+ Interval<1>(t.physicalDomain()[d].max() -adjust + i + 1,
+ t.physicalDomain()[d].max() -adjust + i + 1);
+ }
+ else
+ {
+ int nGuards = t.fieldEngine().guardLayers().lower(d);
+ domains_m.resize(nGuards+adjust, t.totalDomain());
+ srcDomain_m[d] = Interval<1>(t.physicalDomain()[d].min()+adjust,
+ t.physicalDomain()[d].min()+adjust);
+ for (int i=0; i<nGuards+adjust; i++)
+ domains_m[i][d] =
+ Interval<1>(t.physicalDomain()[d].min() +adjust - i - 1,
+ t.physicalDomain()[d].min() +adjust - i - 1);
+ }
+ }
+ ZeroGradientFaceBC<Dim> &operator=(const ZeroGradientFaceBC<Dim> &rhs)
+ {
+ if (&rhs != this)
+ {
+ domains_m = rhs.domains_m;
+ srcDomain_m = rhs.srcDomain_m;
+ face_m = rhs.face_m;
+ }
+ return *this;
+ }
+ int face() const { return face_m; }
+ template<class Target>
+ void operator()(const Target &t) const
+ {
+ for (int i=0; i<domains_m.size(); i++) {
+ t(domains_m[i]) = t(srcDomain_m);
+ }
+ }
+ private:
+ Interval<Dim> srcDomain_m;
+ std::vector<Interval<Dim> > domains_m;
+ int face_m;
+ };
+ template<int Dim>
+ struct RelationFunctorTraits<ZeroGradientFaceBC<Dim> > {
+ enum { defaultPriority = 100 };
+ };
+ namespace Pooma {
+ template<class Target>
+ void addZeroGradientFaceBC(const Target &f, int face)
+ {
+ newRelation(ZeroGradientFaceBC<Target::dimensions>(face), f);
+ }
+ template<class Target>
+ void addAllZeroGradientFaceBC(const Target &f)
+ {
+ for (int i = 0; i < 2 * Target::dimensions; i++)
+ {
+ addZeroGradientFaceBC(f, i);
+ }
+ }
+ }
+ template<class Functor, class Expression>
+ struct FieldStencilSimple
+ {
+ typedef typename Expression::MeshTag_t MeshTag_t;
+ enum { outputDim = Expression::dimensions };
+ typedef typename Functor::OutputElement_t OutputElement_t;
+ typedef StencilEngine<Functor, Expression> OutputEngineTag_t;
+ typedef Field<MeshTag_t, OutputElement_t, OutputEngineTag_t> Type_t;
+ typedef Engine<outputDim, OutputElement_t, OutputEngineTag_t> SEngine_t;
+ static inline
+ Type_t make(const Functor &stencil, const Expression &f)
+ {
+ return make(stencil, f, f.physicalDomain());
+ }
+ static inline
+ Type_t make(const Functor &stencil, const Expression &f, const Interval<outputDim> &domain)
+ {
+ Type_t h(stencil.outputCentering(), f.layout(), f.mesh());
+ h.fieldEngine().engine() = SEngine_t(stencil, f, domain);
+ return h;
+ }
+ template<class Accumulate>
+ static inline
+ Type_t make(const Expression &f,
+ const std::vector<FieldOffsetList<outputDim> > &nn,
+ const Centering<outputDim> &outputCentering,
+ Accumulate accumulate = Accumulate())
+ {
+ ;
+ Type_t h(outputCentering, f.layout(), f.mesh());
+ h.fieldEngine().physicalCellDomain() = f.fieldEngine().physicalCellDomain();
+ h.fieldEngine().guardLayers() = f.fieldEngine().guardLayers();
+ if (outputCentering.size() == 1)
+ {
+ h.fieldEngine().engine()
+ = SEngine_t(Functor(nn[0], outputCentering, f.centering(),
+ accumulate),
+ f, h.physicalDomain());
+ }
+ else
+ {
+ int oc;
+ for (oc = 0; oc < nn.size(); ++oc)
+ {
+ h[oc].fieldEngine().guardLayers() = f.fieldEngine().guardLayers();
+ h[oc].fieldEngine().engine()
+ = SEngine_t(Functor(nn[oc], outputCentering[oc], f.centering(),
+ accumulate),
+ f, h[oc].physicalDomain());
+ }
+ }
+ return h;
+ }
+ };
+ template<class T2, class Mesh>
+ class DivVertToCell;
+ template<class T2, int Dim, class TM>
+ class DivVertToCell<Vector<Dim, T2>, UniformRectilinearMesh<MeshTraits<Dim, TM, UniformRectilinearTag, CartesianTag> > >
+ {
+ public:
+ typedef T2 OutputElement_t;
+ Centering<Dim> outputCentering() const
+ {
+ return canonicalCentering<Dim>(CellType, Continuous, AllDim);
+ }
+ Centering<Dim> inputCentering() const
+ {
+ return canonicalCentering<Dim>(VertexType, Continuous, AllDim);
+ }
+ DivVertToCell()
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ fact_m(d) = 1.0;
+ }
+ }
+ template<class FE>
+ DivVertToCell(const FE &fieldEngine)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ fact_m(d) = 1 / fieldEngine.mesh().spacings()(d);
+ }
+ }
+ int lowerExtent(int d) const { return 0; }
+ int upperExtent(int d) const { return 1; }
+ template<class F>
+ inline OutputElement_t
+ operator()(const F &f, int i1) const
+ {
+ return OutputElement_t
+ (fact_m(0)*(f.read(i1+1)(0) - f.read(i1)(0)));
+ }
+ template<class F>
+ inline OutputElement_t
+ operator()(const F &f, int i1, int i2) const
+ {
+ return OutputElement_t
+ (0.5*(fact_m(0)*(f.read(i1+1,i2)(0) - f.read(i1,i2)(0)
+ + f.read(i1+1,i2+1)(0) - f.read(i1,i2+1)(0))
+ + fact_m(1)*(f.read(i1, i2+1)(1) - f.read(i1, i2)(1)
+ + f.read(i1+1,i2+1)(1) - f.read(i1+1,i2)(1))));
+ }
+ template<class F>
+ inline OutputElement_t
+ operator()(const F &f, int i1, int i2, int i3) const
+ {
+ return OutputElement_t
+ (0.25*(fact_m(0)*(f.read(i1+1,i2, i3)(0) - f.read(i1,i2, i3)(0)
+ + f.read(i1+1,i2+1,i3)(0) - f.read(i1,i2+1,i3)(0)
+ + f.read(i1+1,i2, i3+1)(0) - f.read(i1,i2, i3+1)(0)
+ + f.read(i1+1,i2+1,i3+1)(0) - f.read(i1,i2+1,i3+1)(0))
+ + fact_m(1)*(f.read(i1, i2+1,i3)(1) - f.read(i1, i2,i3)(1)
+ + f.read(i1+1,i2+1,i3)(1) - f.read(i1+1,i2,i3)(1)
+ + f.read(i1, i2+1,i3+1)(1) - f.read(i1, i2,i3+1)(1)
+ + f.read(i1+1,i2+1,i3+1)(1) - f.read(i1+1,i2,i3+1)(1))
+ + fact_m(2)*(f.read(i1, i2, i3+1)(2) - f.read(i1, i2, i3)(2)
+ + f.read(i1+1,i2, i3+1)(2) - f.read(i1+1,i2, i3)(2)
+ + f.read(i1, i2+1,i3+1)(2) - f.read(i1, i2+1,i3)(2)
+ + f.read(i1+1,i2+1,i3+1)(2) - f.read(i1+1,i2+1,i3)(2))));
+ }
+ private:
+ Vector<Dim, TM> fact_m;
+ };
+ template<class T2, class Mesh>
+ class DivCellToVert;
+ template<class T2, int Dim, class TM>
+ class DivCellToVert<Vector<Dim, T2>, UniformRectilinearMesh<MeshTraits<Dim, TM> > >
+ {
+ public:
+ typedef T2 OutputElement_t;
+ Centering<Dim> outputCentering() const
+ {
+ return canonicalCentering<Dim>(CellType, Continuous, AllDim);
+ }
+ Centering<Dim> inputCentering() const
+ {
+ return canonicalCentering<Dim>(VertexType, Continuous, AllDim);
+ }
+ DivCellToVert()
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ fact_m(d) = 1.0;
+ }
+ }
+ template<class FE>
+ DivCellToVert(const FE &fieldEngine)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ fact_m(d) = 1 / fieldEngine.mesh().spacings()(d);
+ }
+ }
+ int lowerExtent(int d) const { return 0; }
+ int upperExtent(int d) const { return 1; }
+ template<class F>
+ inline OutputElement_t
+ operator()(const F &f, int i1) const
+ {
+ return OutputElement_t
+ (fact_m(0)*(f.read(i1)(0) - f.read(i1-1)(0)));
+ }
+ template<class F>
+ inline OutputElement_t
+ operator()(const F &f, int i1, int i2) const
+ {
+ return OutputElement_t
+ (0.5*(fact_m(0)*(f.read(i1,i2-1)(0) - f.read(i1-1,i2-1)(0)
+ + f.read(i1,i2)(0) - f.read(i1-1,i2)(0))
+ + fact_m(1)*(f.read(i1-1,i2)(1) - f.read(i1-1,i2-1)(1)
+ + f.read(i1, i2)(1) - f.read(i1, i2-1)(1))));
+ }
+ template<class F>
+ inline OutputElement_t
+ operator()(const F &f, int i1, int i2, int i3) const
+ {
+ return OutputElement_t
+ (0.25*(fact_m(0)*(f.read(i1,i2-1,i3-1)(0) - f.read(i1-1,i2-1,i3-1)(0)
+ + f.read(i1,i2, i3-1)(0) - f.read(i1-1,i2, i3-1)(0)
+ + f.read(i1,i2-1,i3)(0) - f.read(i1-1,i2-1,i3)(0)
+ + f.read(i1,i2, i3)(0) - f.read(i1-1,i2, i3)(0))
+ + fact_m(1)*(f.read(i1-1,i2,i3-1)(1) - f.read(i1-1,i2-1,i3-1)(1)
+ + f.read(i1, i2,i3-1)(1) - f.read(i1, i2-1,i3-1)(1)
+ + f.read(i1-1,i2,i3)(1) - f.read(i1-1,i2-1,i3)(1)
+ + f.read(i1, i2,i3)(1) - f.read(i1, i2-1,i3)(1))
+ + fact_m(2)*(f.read(i1-1,i2-1,i3)(2) - f.read(i1-1,i2-1,i3-1)(2)
+ + f.read(i1, i2-1,i3)(2) - f.read(i1, i2-1,i3-1)(2)
+ + f.read(i1-1,i2, i3)(2) - f.read(i1-1,i2, i3-1)(2)
+ + f.read(i1, i2, i3)(2) - f.read(i1, i2, i3-1)(2))));
+ }
+ private:
+ Vector<Dim, TM> fact_m;
+ };
+ template<class T2, class Mesh, CenteringType OC>
+ class DivSameToSame;
+ template<class T2, int Dim, class TM, CenteringType OC>
+ class DivSameToSame<Vector<Dim, T2>, UniformRectilinearMesh<MeshTraits<Dim, TM, UniformRectilinearTag, CartesianTag> >, OC>
+ {
+ public:
+ typedef T2 OutputElement_t;
+ Centering<Dim> outputCentering() const
+ {
+ return canonicalCentering<Dim>(OC, Continuous);
+ }
+ Centering<Dim> inputCentering() const
+ {
+ return canonicalCentering<Dim>(OC, Continuous);
+ }
+ DivSameToSame()
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ fact_m(d) = 0.5;
+ }
+ }
+ template<class FE>
+ DivSameToSame(const FE &fieldEngine)
+ {
+ for (int d = 0; d < Dim; ++d)
+ {
+ fact_m(d) = 0.5 / fieldEngine.mesh().spacings()(d);
+ }
+ }
+ int lowerExtent(int d) const { return 1; }
+ int upperExtent(int d) const { return 1; }
+ template<class F>
+ inline OutputElement_t
+ operator()(const F &f, int i1) const
+ {
+ return OutputElement_t
+ (fact_m(0)*(f.read(i1+1)(0) - f.read(i1-1)(0)));
+ }
+ template<class F>
+ inline OutputElement_t
+ operator()(const F &f, int i1, int i2) const
+ {
+ return OutputElement_t
+ (fact_m(0)*(f.read(i1+1,i2)(0) - f.read(i1-1,i2)(0))
+ + fact_m(1)*(f.read(i1, i2+1)(1) - f.read(i1, i2-1)(1)));
+ }
+ template<class F>
+ inline OutputElement_t
+ operator()(const F &f, int i1, int i2, int i3) const
+ {
+ return OutputElement_t
+ (fact_m(0)*(f.read(i1+1,i2, i3)(0) - f.read(i1-1,i2, i3)(0))
+ + fact_m(1)*(f.read(i1, i2+1,i3)(1) - f.read(i1, i2-1,i3)(1))
+ + fact_m(2)*(f.read(i1, i2, i3+1)(2) - f.read(i1, i2, i3-1)(2)));
+ }
+ private:
+ Vector<Dim, TM> fact_m;
+ };
+ template<class T2, class Mesh>
+ class DivCellToVert;
+ template<class T2, class Mesh>
+ class DivVertToCell;
+ template<class T2, class Mesh, CenteringType OC>
+ class DivSameToSame;
+ template<class Mesh, class T, class EngineTag>
+ typename
+ FieldStencilSimple<DivSameToSame<T, Mesh, CellType>,
+ Field<Mesh, T, EngineTag> >::Type_t
+ divCellToCell(const Field<Mesh, T, EngineTag> &f)
+ {
+ typedef DivSameToSame<T, Mesh, CellType> Div_t;
+ typedef FieldStencilSimple<Div_t, Field<Mesh, T, EngineTag> > Ret_t;
+ return Ret_t::make(Div_t(f.fieldEngine()), f);
+ }
+ template<class Mesh, class T, class EngineTag>
+ typename
+ FieldStencilSimple<DivVertToCell<T, Mesh>,
+ Field<Mesh, T, EngineTag> >::Type_t
+ divVertToCell(const Field<Mesh, T, EngineTag> &f)
+ {
+ typedef DivVertToCell<T, Mesh> Div_t;
+ typedef FieldStencilSimple<Div_t, Field<Mesh, T, EngineTag> > Ret_t;
+ return Ret_t::make(Div_t(f.fieldEngine()), f);
+ }
+ template<class Mesh, class T, class EngineTag>
+ typename
+ FieldStencilSimple<DivCellToVert<T, Mesh>,
+ Field<Mesh, T, EngineTag> >::Type_t
+ divCellToVert(const Field<Mesh, T, EngineTag> &f)
+ {
+ typedef DivCellToVert<T, Mesh> Div_t;
+ typedef FieldStencilSimple<Div_t, Field<Mesh, T, EngineTag> > Ret_t;
+ return Ret_t::make(Div_t(f.fieldEngine()), f);
+ }
+ template<class Mesh, class T, class EngineTag>
+ typename
+ FieldStencilSimple<DivSameToSame<T, Mesh, VertexType>,
+ Field<Mesh, T, EngineTag> >::Type_t
+ divVertToVert(const Field<Mesh, T, EngineTag> &f)
+ {
+ typedef DivSameToSame<T, Mesh, VertexType> Div_t;
+ typedef FieldStencilSimple<Div_t, Field<Mesh, T, EngineTag> > Ret_t;
+ return Ret_t::make(Div_t(f.fieldEngine()), f);
+ }
+ template<class D1,class T1,class E1>
+ inline typename MakeReturn<BinaryNode<FnMin,
+ typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t> >::Expression_t
+ min(const Field<D1,T1,E1> & l,const Field<D1,T1,E1> & r)
+ {
+ typedef BinaryNode<FnMin,
+ typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<D1,T1,E1> >::make(r)));
+ }
+ template<class D1,class T1,class E1>
+ inline typename MakeReturn<BinaryNode<FnMax,
+ typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t> >::Expression_t
+ max(const Field<D1,T1,E1> & l,const Field<D1,T1,E1> & r)
+ {
+ typedef BinaryNode<FnMax,
+ typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t,
+ typename CreateLeaf<Field<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<D1,T1,E1> >::make(l),
+ CreateLeaf<Field<D1,T1,E1> >::make(r)));
+ }
+ template <int Dim>
+ class DomainLayout;
+ template<class Functor> class FieldShift;
+ template <class Expression>
+ struct FieldShift;
+ template<int Dim, class T, class Expression>
+ class Engine<Dim, T, FieldShift<Expression> >
+ {
+ public:
+ typedef FieldShift<Expression> Tag_t;
+ typedef Expression Expression_t;
+ typedef Engine<Dim, T, Tag_t> This_t;
+ typedef This_t Engine_t;
+ typedef Interval<Dim> Domain_t;
+ typedef T Element_t;
+ typedef ErrorType ElementRef_t;
+ typedef typename Expression_t::Engine_t ExprEngine_t;
+ typedef DomainLayout<Dim> Layout_t;
+ enum { dimensions = Dim };
+ enum { hasDataObject = ExprEngine_t::hasDataObject };
+ enum { dynamic = false };
+ enum { zeroBased = false };
+ enum { multiPatch = ExprEngine_t::multiPatch };
+ Engine()
+ : domain_m(Pooma::NoInit()), exprEngine_m()
+ {
+ }
+ template<class Layout>
+ explicit Engine(const Layout &layout)
+ : domain_m(layout.domain()), exprEngine_m()
+ {
+ }
+ Engine(const Expression_t &f, const Loc<Dim> &offset, Domain_t domain)
+ : domain_m(domain),
+ offset_m(offset),
+ exprEngine_m(f)
+ {
+ }
+ Engine(const This_t &model)
+ : domain_m(model.domain()),
+ offset_m(model.offset_m),
+ exprEngine_m(model.exprEngine())
+ {
+ }
+ This_t &operator=(const This_t &model)
+ {
+ domain_m = model.domain();
+ offset_m = model.offset_m;
+ exprEngine_m = model.exprEngine();
+ return *this;
+ }
+ inline Element_t read(int i) const
+ {
+ return exprEngine()(i + offset_m[0].first());
+ }
+ inline Element_t read(int i, int j) const
+ {
+ return exprEngine()(i + offset_m[0].first(),
+ j + offset_m[1].first());
+ }
+ inline Element_t read(int i, int j, int k) const
+ {
+ return exprEngine()(i + offset_m[0].first(),
+ j + offset_m[1].first(),
+ k + offset_m[2].first());
+ }
+ inline Element_t read(const Loc<Dim> &loc) const
+ {
+ return exprEngine()(loc + offset_m);
+ }
+ inline Element_t operator()(int i) const
+ {
+ return read(i);
+ }
+ inline Element_t operator()(int i, int j) const
+ {
+ return read(i, j);
+ }
+ inline Element_t operator()(int i, int j, int k) const
+ {
+ return read(i, j, k);
+ }
+ inline Element_t operator()(const Loc<Dim> &loc) const
+ {
+ return read(loc);
+ }
+ inline const Domain_t &domain() const { return domain_m; }
+ inline Loc<Dim> offset() const
+ {
+ return offset_m;
+ }
+ inline const Expression_t &exprEngine() const { return exprEngine_m; }
+ template<class RequestType>
+ inline
+ typename DataObjectRequest<RequestType>::Type_t
+ dataObjectRequest(const DataObjectRequest<RequestType> &req) const
+ {
+ return exprEngine().engine().dataObjectRequest(req);
+ }
+ inline
+ Interval<Dim> viewDomain(const Interval<Dim> &domain) const
+ {
+ Interval<Dim> ret;
+ int d;
+ for (d = 0; d < Dim; ++d)
+ {
+ ret[d] =
+ Interval<1>(
+ domain[d].first() + offset_m[d].first(),
+ domain[d].last() + offset_m[d].first()
+ );
+ }
+ return ret;
+ }
+ inline
+ INode<Dim> viewDomain(const INode<Dim> &inode) const
+ {
+ return INode<Dim>(inode, viewDomain(inode.domain()));
+ }
+ inline
+ Interval<Dim> intersectDomain() const
+ {
+ Interval<Dim> ret;
+ int d;
+ for (d = 0; d < Dim; ++d)
+ {
+ ret[d] =
+ Interval<1>(
+ domain_m[d].first() + offset_m[d].first(),
+ domain_m[d].last() + offset_m[d].first()
+ );
+ }
+ return ret;
+ }
+ private:
+ Interval<Dim> domain_m;
+ Loc<Dim> offset_m;
+ Expression_t exprEngine_m;
+ };
+ template <int Dim, class T, class E>
+ struct NewEngine<Engine<Dim, T, FieldShift<E> >, Interval<Dim> >
+ {
+ typedef typename NewEngine<E, Interval<Dim> >::Type_t Type_t;
+ };
+ template <int Dim, class T, class E>
+ struct NewEngineEngine<Engine<Dim, T, FieldShift<E> >, Interval<Dim> >
+ {
+ typedef typename NewEngineEngine<E, Interval<Dim> >::Type_t Type_t;
+ static inline
+ Type_t apply(const Engine<Dim, T, FieldShift<E> > &e, const Interval<Dim> &d)
+ {
+ return NewEngineEngine<E, Interval<Dim> >::apply(e.exprEngine(),
+ e.viewDomain(d));
+ }
+ };
+ template <int Dim, class T, class E>
+ struct NewEngineDomain<Engine<Dim, T, FieldShift<E> >, Interval<Dim> >
+ {
+ typedef typename NewEngineDomain<E, Interval<Dim> >::Type_t Type_t;
+ static inline
+ Type_t apply(const Engine<Dim, T, FieldShift<E> > &e, const Interval<Dim> &d)
+ {
+ return NewEngineDomain<E, Interval<Dim> >::apply(e.exprEngine(),
+ e.viewDomain(d));
+ }
+ };
+ template <int Dim, class T, class E>
+ struct NewEngine<Engine<Dim, T, FieldShift<E> >, INode<Dim> >
+ {
+ typedef typename NewEngine<E, INode<Dim> >::Type_t Type_t;
+ };
+ template <int Dim, class T, class E>
+ struct NewEngineEngine<Engine<Dim, T, FieldShift<E> >, INode<Dim> >
+ {
+ typedef typename NewEngineEngine<E, INode<Dim> >::Type_t Type_t;
+ static inline
+ Type_t apply(const Engine<Dim, T, FieldShift<E> > &e, const INode<Dim> &d)
+ {
+ return NewEngineEngine<E, INode<Dim> >::apply(e.exprEngine(),
+ e.viewDomain(d));
+ }
+ };
+ template <int Dim, class T, class E>
+ struct NewEngineDomain<Engine<Dim, T, FieldShift<E> >, INode<Dim> >
+ {
+ typedef typename NewEngineDomain<E, INode<Dim> >::Type_t Type_t;
+ static inline
+ Type_t apply(const Engine<Dim, T, FieldShift<E> > &e, const INode<Dim> &d)
+ {
+ return NewEngineDomain<E, INode<Dim> >::apply(e.exprEngine(),
+ e.viewDomain(d));
+ }
+ };
+ template<class Expression>
+ struct FieldShiftSimple
+ {
+ typedef typename Expression::MeshTag_t MeshTag_t;
+ typedef typename Expression::Element_t OutputElement_t;
+ enum { outputDim = Expression::dimensions };
+ typedef typename Expression::Engine_t InputEngine_t;
+ typedef FieldShift<InputEngine_t> OutputEngineTag_t;
+ typedef Field<MeshTag_t, OutputElement_t, OutputEngineTag_t> Type_t;
+ typedef Engine<outputDim, OutputElement_t, OutputEngineTag_t> SEngine_t;
+ static inline
+ Type_t make(const Expression &f,
+ const FieldOffset<outputDim> &s1,
+ const Centering<outputDim> ¢ering)
+ {
+ Type_t h(centering, f.layout(), f.mesh());
+ h.fieldEngine().physicalCellDomain() = f.fieldEngine().physicalCellDomain();
+ Expression fld =
+ (f.numSubFields() > 1) ? f[s1.subFieldNumber()] : f;
+ const Loc<outputDim> &offset = s1.cellOffset();
+ GuardLayers<outputDim> og(fld.fieldEngine().guardLayers());
+ for (int d = 0; d < outputDim; d++)
+ {
+ og.lower(d) += offset[d].first();
+ og.upper(d) -= offset[d].first();
+ }
+ h.fieldEngine().guardLayers() = og;
+ h.fieldEngine().engine() = SEngine_t(fld.engine(), offset, fld.domain());
+ return h;
+ }
+ static inline
+ Type_t make(const Expression &f,
+ const std::vector<FieldOffset<outputDim> > &vs1,
+ const Centering<outputDim> ¢ering)
+ {
+ typedef typename std::vector<FieldOffset<outputDim> >::size_type size_type;
+ Type_t h(centering, f.layout(), f.mesh());
+ h.fieldEngine().physicalCellDomain() = f.fieldEngine().physicalCellDomain();
+ if (__builtin_expect(!!(vs1.size() == centering.size()), true)) {} else Pooma::toss_cookies("The FieldOffset vector's length must match the centering's size.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/DiffOps/FieldShiftEngine.h", 433);
+ for (size_type s1Index = 0; s1Index < vs1.size(); ++s1Index) {
+ const FieldOffset<outputDim> s1 = vs1[s1Index];
+ Type_t hField = (h.numSubFields() > 1) ? h[s1Index] : h;
+ Expression fld =
+ (f.numSubFields() > 1) ? f[s1.subFieldNumber()] : f;
+ const Loc<outputDim> &offset = s1.cellOffset();
+ GuardLayers<outputDim> og(fld.fieldEngine().guardLayers());
+ for (int d = 0; d < outputDim; d++)
+ {
+ og.lower(d) += offset[d].first();
+ og.upper(d) -= offset[d].first();
+ }
+ hField.fieldEngine().guardLayers() = og;
+ hField.fieldEngine().engine() =
+ SEngine_t(fld.engine(), offset, fld.domain());
+ }
+ return h;
+ }
+ };
+ template<class Expression>
+ struct EvaluatorEngineTraits<FieldShift<Expression> >
+ {
+ typedef typename CreateLeaf<Expression>::Leaf_t Expr_t;
+ typedef typename
+ ForEach<Expr_t, EvaluatorTypeTag, EvaluatorCombineTag>::Type_t
+ Evaluator_t;
+ };
+ template<int Dim, class Intersect>
+ class FieldShiftIntersector
+ {
+ public:
+ typedef typename Intersect::IntersectorData_t IntersectorData_t;
+ typedef FieldShiftIntersector<Dim, Intersect> This_t;
+ typedef typename IntersectorData_t::const_iterator const_iterator;
+ typedef RefCountedPtr<IntersectorData_t> DataPtr_t;
+ typedef Interval<Dim> Domain_t;
+ enum { dimensions = Intersect::dimensions };
+ FieldShiftIntersector(const This_t &model)
+ : domain_m(model.domain_m), intersector_m(model.intersector_m)
+ { }
+ FieldShiftIntersector(const Domain_t &dom, const Intersect &intersect)
+ : domain_m(dom), intersector_m(intersect)
+ { }
+ This_t &operator=(const This_t &model)
+ {
+ if (this != &model)
+ {
+ domain_m = model.domain_m;
+ intersector_m = model.intersector_m;
+ }
+ return *this;
+ }
+ ~FieldShiftIntersector() { }
+ inline DataPtr_t &data() { return intersector_m.data(); }
+ inline const DataPtr_t &data() const { return intersector_m.data(); }
+ inline const_iterator begin() const { return data()->inodes_m.begin(); }
+ inline const_iterator end() const { return data()->inodes_m.end(); }
+ template<class Engine>
+ inline void intersect(const Engine &engine)
+ {
+ typedef typename NewEngine<Engine, Interval<Dim> >::Type_t NewEngine_t;
+ NewEngine_t newEngine(engine, domain_m);
+ intersector_m.intersect(newEngine);
+ data()->shared(engine.layout().ID(), newEngine.layout().ID());
+ }
+ template<class Engine, int Dim2>
+ inline bool intersect(const Engine &engine, const GuardLayers<Dim2> &)
+ {
+ intersect(engine);
+ return true;
+ }
+ private:
+ Interval<Dim> domain_m;
+ Intersect intersector_m;
+ };
+ template <int Dim, class T, class Expression, class Intersect>
+ struct LeafFunctor<Engine<Dim, T, FieldShift<Expression> >,
+ ExpressionApply<IntersectorTag<Intersect> > >
+ {
+ typedef int Type_t;
+ static
+ int apply(const Engine<Dim, T, FieldShift<Expression> >
+ &engine, const ExpressionApply<IntersectorTag<Intersect> > &tag)
+ {
+ typedef FieldShiftIntersector<Dim, Intersect> NewIntersector_t;
+ NewIntersector_t newIntersector(engine.intersectDomain(),
+ tag.tag().intersector_m);
+ expressionApply(engine.field(),
+ IntersectorTag<NewIntersector_t>(newIntersector));
+ return 0;
+ }
+ };
+ template<class RequestType> class DataObjectRequest;
+ template <int Dim, class T, class Expression, class RequestType>
+ struct EngineFunctor<Engine<Dim, T, FieldShift<Expression> >,
+ DataObjectRequest<RequestType> >
+ {
+ typedef typename DataObjectRequest<RequestType>::Type_t Type_t;
+ static Type_t
+ apply(const Engine<Dim, T, FieldShift<Expression> > &engine,
+ const DataObjectRequest<RequestType> &tag)
+ {
+ return engineFunctor(engine.field().engine(), tag);
+ }
+ };
+ template <int Dim, class T, class Expression, class Tag>
+ struct LeafFunctor<Engine<Dim, T, FieldShift<Expression> >,
+ EngineView<Tag> >
+ {
+ typedef LeafFunctor<Expression, EngineView<Tag> > LeafFunctor_t;
+ typedef typename LeafFunctor_t::Type_t NewViewed_t;
+ typedef Engine<Dim, T, FieldShift<NewViewed_t> > Type_t;
+ static
+ Type_t apply(const Engine<Dim, T,
+ FieldShift<Expression> > &engine,
+ const EngineView<Tag> &tag)
+ {
+ return Type_t(LeafFunctor_t::apply(engine.field(), tag), engine);
+ }
+ };
+ template <int Dim, class T, class Expression, class Tag>
+ struct LeafFunctor<Engine<Dim, T, FieldShift<Expression> >,
+ ExpressionApply<Tag> >
+ {
+ typedef LeafFunctor<Expression, ExpressionApply<Tag> > LeafFunctor_t;
+ typedef int Type_t;
+ static
+ Type_t apply(const Engine<Dim, T,
+ FieldShift<Expression> > &engine,
+ const ExpressionApply<Tag> &tag)
+ {
+ return LeafFunctor_t::apply(engine.field(), tag);
+ }
+ };
+ template<class MeshTag, class T, class EngineTag, int Dim>
+ struct View2<Field<MeshTag, T, EngineTag>, FieldOffset<Dim>,
+ Centering<Dim> >
+ {
+ typedef Field<MeshTag, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Engine_t Engine_t;
+ typedef Field<MeshTag, T, FieldShift<Engine_t> > ReadType_t;
+ typedef Field<MeshTag, T, FieldShift<Engine_t> > Type_t;
+ inline static
+ Type_t make(const Subject_t &f, const FieldOffset<Dim> &s1,
+ const Centering<Dim> &c)
+ {
+ PoomaCTAssert<(Dim == Subject_t::dimensions)>::test();
+ return FieldShiftSimple<Subject_t>::make(f, s1, c);
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &f, const FieldOffset<Dim> &s1,
+ const Centering<Dim> &c)
+ {
+ PoomaCTAssert<(Dim == Subject_t::dimensions)>::test();
+ return FieldShiftSimple<Subject_t>::make(f, s1, c);
+ }
+ };
+ template<class MeshTag, class T, class EngineTag, int Dim>
+ struct View2<Field<MeshTag, T, EngineTag>, std::vector<FieldOffset<Dim> >,
+ Centering<Dim> >
+ {
+ typedef Field<MeshTag, T, EngineTag> Subject_t;
+ typedef typename Subject_t::Engine_t Engine_t;
+ typedef Field<MeshTag, T, FieldShift<Engine_t> > ReadType_t;
+ typedef Field<MeshTag, T, FieldShift<Engine_t> > Type_t;
+ inline static
+ Type_t make(const Subject_t &f,
+ const std::vector<FieldOffset<Dim> > &s1,
+ const Centering<Dim> &c)
+ {
+ PoomaCTAssert<(Dim == Subject_t::dimensions)>::test();
+ return FieldShiftSimple<Subject_t>::make(f, s1, c);
+ }
+ inline static
+ ReadType_t makeRead(const Subject_t &f,
+ const std::vector<FieldOffset<Dim> > &s1,
+ const Centering<Dim> &c)
+ {
+ PoomaCTAssert<(Dim == Subject_t::dimensions)>::test();
+ return FieldShiftSimple<Subject_t>::make(f, s1, c);
+ }
+ };
+ template<class T, int Dim, class Accumulate>
+ class FieldOffsetReduction
+ {
+ public:
+ typedef T OutputElement_t;
+ const Centering<Dim> &outputCentering() const
+ {
+ return outputCentering_m;
+ }
+ const Centering<Dim> &inputCentering() const
+ {
+ return inputCentering_m;
+ }
+ int lowerExtent(int d) const { return lower_m[d]; }
+ int upperExtent(int d) const { return upper_m[d]; }
+ FieldOffsetReduction()
+ {
+ }
+ FieldOffsetReduction(const FieldOffsetList<Dim> &neighbors,
+ const Centering<Dim> &outputCentering,
+ const Centering<Dim> &inputCentering,
+ Accumulate accumulate = Accumulate())
+ : neighbors_m(neighbors),
+ outputCentering_m(outputCentering),
+ inputCentering_m(inputCentering),
+ accumulate_m(accumulate)
+ {
+ if (__builtin_expect(!!(neighbors.size() > 0), true)) {} else Pooma::toss_cookies("no support for empty accumulation", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Field/DiffOps/FieldOffsetReduction.h", 115);
+ ;
+ int d, i;
+ for (d = 0; d < Dim; ++d)
+ {
+ upper_m[d] = 0;
+ lower_m[d] = 0;
+ }
+ for (i = 0; i < neighbors_m.size(); ++i)
+ {
+ for (d = 0; d < Dim; ++d)
+ {
+ if (-neighbors_m[i].cellOffset()[d].first() > lower_m[d])
+ {
+ lower_m[d] = -neighbors_m[i].cellOffset()[d].first();
+ }
+ if (neighbors_m[i].cellOffset()[d].first() > upper_m[d])
+ {
+ upper_m[d] = neighbors_m[i].cellOffset()[d].first();
+ }
+ }
+ }
+ }
+ template<class F>
+ inline OutputElement_t
+ operator()(const F &f, int i1) const
+ {
+ T ret = f(neighbors_m[0], Loc<1>(i1));
+ for (int i = 1; i < neighbors_m.size(); ++i)
+ {
+ ret = accumulate_m(ret, f(neighbors_m[i], Loc<1>(i1)));
+ }
+ return ret;
+ }
+ template<class F>
+ inline OutputElement_t
+ operator()(const F &f, int i1, int i2) const
+ {
+ T ret = f(neighbors_m[0], Loc<2>(i1, i2));
+ for (int i = 1; i < neighbors_m.size(); ++i)
+ {
+ ret = accumulate_m(ret, f(neighbors_m[i], Loc<2>(i1, i2)));
+ }
+ return ret;
+ }
+ template<class F>
+ inline OutputElement_t
+ operator()(const F &f, int i1, int i2, int i3) const
+ {
+ T ret = f(neighbors_m[0], Loc<3>(i1, i2, i3));
+ for (int i = 1; i < neighbors_m.size(); ++i)
+ {
+ ret = accumulate_m(ret, f(neighbors_m[i], Loc<3>(i1, i2, i3)));
+ }
+ return ret;
+ }
+ private:
+ FieldOffsetList<Dim> neighbors_m;
+ Centering<Dim> outputCentering_m;
+ Centering<Dim> inputCentering_m;
+ Accumulate accumulate_m;
+ int lower_m[Dim];
+ int upper_m[Dim];
+ };
+ template<class GeometryTag, class T, class EngineTag, int Dim>
+ typename FieldStencilSimple<FieldOffsetReduction<T, Dim, OpAdd>,
+ Field<GeometryTag, T, EngineTag> >::Type_t
+ sum(const Field<GeometryTag, T, EngineTag> &f,
+ const std::vector<FieldOffsetList<Dim> > &nn,
+ const Centering<Dim> &outputCentering)
+ {
+ typedef FieldOffsetReduction<T, Dim, OpAdd> Functor_t;
+ typedef Field<GeometryTag, T, EngineTag> Field_t;
+ return FieldStencilSimple<Functor_t, Field_t>::make(f, nn, outputCentering,
+ OpAdd());
+ }
+ template <int Dim>
+ struct Deltas
+ {
+ static const DomainDelta<Dim, 0> dX;
+ static const DomainDelta<Dim, 1> dY;
+ static const DomainDelta<Dim, 2> dZ;
+ };
+ template <int Dim>
+ const DomainDelta<Dim, 0> Deltas<Dim>::dX;
+ template <int Dim>
+ const DomainDelta<Dim, 1> Deltas<Dim>::dY;
+ template <int Dim>
+ const DomainDelta<Dim, 2> Deltas<Dim>::dZ;
+ static const DomainDelta<3, 0> dX;
+ static const DomainDelta<3, 1> dY;
+ static const DomainDelta<3, 2> dZ;
+ template <int dim, class MeshTag = UniformRectilinearTag, class CoordinateSystemTag = CartesianTag>
+ struct SerialTraits {
+ typedef MeshTag MeshTag_t;
+ typedef CoordinateSystemTag CoordinateSystemTag_t;
+ enum { Dim = dim };
+ typedef DomainLayout<dim> Layout_t;
+ typedef MeshTraits<dim, double, MeshTag, CoordinateSystemTag> MeshTraits_t;
+ typedef typename MeshTraits_t::Mesh_t Mesh_t;
+ typedef Brick Engine_t;
+ typedef CompressibleBrick CompressibleEngine_t;
+ static void createLayout(DomainLayout<Dim>& l,
+ const Grid<Dim>&, const Interval<Dim>& domain,
+ const GuardLayers<Dim>&, const GuardLayers<Dim>& egc)
+ {
+ l = DomainLayout<Dim>(domain, egc);
+ }
+ };
+ template <int dim, class MeshTag = UniformRectilinearTag, class CoordinateSystemTag = CartesianTag>
+ struct ParallelTraits {
+ typedef MeshTag MeshTag_t;
+ typedef CoordinateSystemTag CoordinateSystemTag_t;
+ enum { Dim = dim };
+ typedef GridLayout<dim> Layout_t;
+ typedef MeshTraits<dim, double, MeshTag, CoordinateSystemTag> MeshTraits_t;
+ typedef typename MeshTraits_t::Mesh_t Mesh_t;
+ typedef MultiPatch<GridTag, Remote<Brick> > Engine_t;
+ typedef MultiPatch<GridTag, Remote<CompressibleBrick> > CompressibleEngine_t;
+ static void createLayout(GridLayout<Dim>& l,
+ const Grid<Dim>& grid, const Interval<Dim>&,
+ const GuardLayers<Dim>& igc, const GuardLayers<Dim>& egc)
+ {
+ l = GridLayout<Dim>(grid, igc, egc, DistributedTag());
+ }
+ };
+ template <int dim, class MeshTag = UniformRectilinearTag, class CoordinateSystemTag = CartesianTag>
+ struct SerialMPTraits {
+ typedef MeshTag MeshTag_t;
+ typedef CoordinateSystemTag CoordinateSystemTag_t;
+ enum { Dim = dim };
+ typedef GridLayout<dim> Layout_t;
+ typedef MeshTraits<dim, double, MeshTag, CoordinateSystemTag> MeshTraits_t;
+ typedef typename MeshTraits_t::Mesh_t Mesh_t;
+ typedef MultiPatch<GridTag, Brick> Engine_t;
+ typedef MultiPatch<GridTag, CompressibleBrick> CompressibleEngine_t;
+ static void createLayout(GridLayout<Dim>& l,
+ const Grid<Dim>& grid, const Interval<Dim>&,
+ const GuardLayers<Dim>& igc, const GuardLayers<Dim>& egc)
+ {
+ l = GridLayout<Dim>(grid, igc, egc, DistributedTag());
+ }
+ };
+ template <class ComputeTraits>
+ struct RhalkTraits : public ComputeTraits {
+ typedef ComputeTraits ComputeTraits_t;
+ typedef typename ComputeTraits::Layout_t Layout_t;
+ typedef typename ComputeTraits::Mesh_t Mesh_t;
+ typedef typename ComputeTraits::Engine_t Engine_t;
+ typedef typename ComputeTraits::CompressibleEngine_t CompressibleEngine_t;
+ enum { Dim = ComputeTraits::Dim };
+ typedef Centering<Dim> Centering_t;
+ typedef typename Mesh_t::PositionsType_t Positions_t;
+ typedef typename Mesh_t::SpacingsType_t Spacings_t;
+ typedef Interval<Dim> Domain_t;
+ typedef Loc<Dim> Loc_t;
+ typedef Field<Mesh_t, double, Engine_t> Scalar_t;
+ typedef Field<Mesh_t, Vector<Dim, double>, Engine_t> Vector_t;
+ };
+ enum { Dim = 3 };
+ typedef RhalkTraits<ParallelTraits<Dim, UniformRectilinearTag, CartesianTag> > Traits_t;
+ extern GuardLayers<Dim> corr_v[Dim];
+ extern bool a_dump_debug_f;
+ inline void enable_fp_exceptions(void)
+ {
+ fexcept_t f;
+ fegetexceptflag(&f, FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW);
+ fesetexceptflag(&f, FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW);
+ }
+ inline void disable_fp_exceptions(void)
+ {
+ feclearexcept((FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID));
+ }
+ #include <fstream>
+ namespace Pooma {
+ Inform pinfo("Pooma");
+ Inform pwarn("Warning", std::cerr, Inform::allContexts);
+ Inform perr("Error", std::cerr, Inform::allContexts);
+ Inform pdebug("** Debug **", std::cerr, Inform::allContexts);
+ Context_t myContext_g = 0;
+ int numContexts_g = 1;
+ int expression_g = 0;
+ namespace {
+ bool initialized_s = false;
+ bool weInitializedRTS_s = false, weInitializedArch_s = false;
+ Options options_s;
+ Scheduler_t mainScheduler_s;
+ Statistics statistics_s;
+ std::ofstream *logstream_s = 0;
+ Inform::ID_t pinfoLogID_s;
+ Inform::ID_t pwarnLogID_s;
+ Inform::ID_t perrLogID_s;
+ Inform::ID_t pdebugLogID_s;
+ void defAbortHandler_s()
+ {
+ std::cerr << "In default abort handler." << std::endl;
+ }
+ AbortHandler_t currentAbortHandler_s = defAbortHandler_s;
+ long reductionFilter_s(long val)
+ {
+ ReduceOverContexts<long, OpAddAssign> reduce(val, 0);
+ return reduce;
+ }
+ void cleanup_s()
+ {
+ if (printStats())
+ statistics_s.print(pinfo, reductionFilter_s);
+ logMessages(0);
+ infoMessages(false);
+ warnMessages(false);
+ errorMessages(false);
+ debugLevel(Inform::off);
+ }
+ }
+ namespace { Pooma::StatisticsData *statNumExpressions_s = statistics_s.add("Number of expressions evaluated"); } void incrementNumExpressions(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumExpressions_s->increment(val); mutex.unlock(); }
+ namespace { Pooma::StatisticsData *statNumZBExpressions_s = statistics_s.add("Number of zero-based expressions evaluated"); } void incrementNumZBExpressions(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumZBExpressions_s->increment(val); mutex.unlock(); }
+ namespace { Pooma::StatisticsData *statNumMultiPatchExpressions_s = statistics_s.add("Number of multi-patch expressions evaluated"); } void incrementNumMultiPatchExpressions(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumMultiPatchExpressions_s->increment(val); mutex.unlock(); }
+ namespace { Pooma::StatisticsData *statNumCompressedAssigns_s = statistics_s.add("Number of fully compressed assignments"); } void incrementNumCompressedAssigns(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumCompressedAssigns_s->increment(val); mutex.unlock(); }
+ namespace { Pooma::StatisticsData *statNumAssignsRequiringUnCompression_s = statistics_s.add("Number of assignments requiring uncompression"); } void incrementNumAssignsRequiringUnCompression(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumAssignsRequiringUnCompression_s->increment(val); mutex.unlock(); }
+ namespace { Pooma::StatisticsData *statNumInlineEvaluations_s = statistics_s.add("Number of assignments using the inline evaluator"); } void incrementNumInlineEvaluations(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumInlineEvaluations_s->increment(val); mutex.unlock(); }
+ namespace { Pooma::StatisticsData *statNumLocalPatchesEvaluated_s = statistics_s.add("Number of local patches evaluated"); } void incrementNumLocalPatchesEvaluated(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumLocalPatchesEvaluated_s->increment(val); mutex.unlock(); }
+ namespace { Pooma::StatisticsData *statNumReductions_s = statistics_s.add("Number of reductions performed"); } void incrementNumReductions(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumReductions_s->increment(val); mutex.unlock(); }
+ namespace { Pooma::StatisticsData *statNumUnCompresses_s = statistics_s.add("Number of times a compressible block uncompresses"); } void incrementNumUnCompresses(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumUnCompresses_s->increment(val); mutex.unlock(); }
+ namespace { Pooma::StatisticsData *statNumUnsuccessfulTryCompresses_s = statistics_s.add("Number of times a compression attempt fails"); } void incrementNumUnsuccessfulTryCompresses(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumUnsuccessfulTryCompresses_s->increment(val); mutex.unlock(); }
+ namespace { Pooma::StatisticsData *statNumSuccessfulTryCompresses_s = statistics_s.add("Number of times a compression attempt succeeds"); } void incrementNumSuccessfulTryCompresses(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumSuccessfulTryCompresses_s->increment(val); mutex.unlock(); }
+ namespace { Pooma::StatisticsData *statNumPolls_s = statistics_s.add("Number of calls to Pooma::poll()"); } void incrementNumPolls(long val) { static Pooma::Mutex_t mutex; mutex.lock(); statNumPolls_s->increment(val); mutex.unlock(); }
+ bool initialize(int &argc, char ** &argv, bool initRTS, bool getCLArgsArch,
+ bool initArch)
+ {
+ if (getCLArgsArch)
+ Pooma::Arch::getCommandLineArguments(argc, argv);
+ Options opts(argc, argv);
+ return initialize(opts, initRTS, initArch);
+ }
+ bool initialize(Options &opts, bool initRTS, bool initArch)
+ {
+ if (__builtin_expect(!!(!initialized_s), true)) {} else Pooma::toss_cookies("You can only call Pooma::initialize once.", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Pooma/Pooma.cmpl.cpp", 306);
+ initialized_s = true;
+ weInitializedRTS_s = initRTS;
+ weInitializedArch_s = initArch;
+ if (initArch)
+ Pooma::Arch::initialize();
+ debugLevel(opts.debug());
+ options_s = opts;
+ if (initRTS)
+ {
+ Smarts::concurrency(opts.concurrency());
+ }
+ myContext_g = 0;
+ numContexts_g = 1;
+ logstream_s = 0;
+ logMessages(opts.logfile().c_str());
+ infoMessages(opts.printInfo());
+ warnMessages(opts.printWarnings());
+ errorMessages(opts.printErrors());
+ Inform::setContext(myContext_g);
+ Inform::setNumContexts(numContexts_g);
+ return true;
+ }
+ bool finalize()
+ {
+ return finalize(weInitializedRTS_s, weInitializedArch_s);
+ }
+ bool finalize(bool quitRTS, bool quitArch)
+ {
+ Pooma::blockAndEvaluate();
+ if (initialized_s)
+ {
+ Smarts::wait();
+ cleanup_s();
+ if (quitRTS)
+ {
+ }
+ }
+ if (quitArch)
+ Pooma::Arch::finalize();
+ return true;
+ }
+ void pAbort(int errorcode)
+ {
+ pAbort("Pooma::pAbort called.", errorcode);
+ }
+ void pAbort(const char *msg, int)
+ {
+ if (msg != 0)
+ std::cerr << msg << std::endl;
+ currentAbortHandler_s();
+ if (initialized_s)
+ {
+ cleanup_s();
+ }
+ ::abort();
+ }
+ AbortHandler_t abortHandler()
+ {
+ return currentAbortHandler_s;
+ }
+ AbortHandler_t abortHandler(AbortHandler_t ah)
+ {
+ AbortHandler_t oldah = currentAbortHandler_s;
+ currentAbortHandler_s = ah;
+ return oldah;
+ }
+ AbortHandler_t resetAbortHandler()
+ {
+ return abortHandler(defAbortHandler_s);
+ }
+ const char *version()
+ {
+ ;
+ return "FreePOOMA 2.4.devel";
+ }
+ int majorVersion()
+ {
+ ;
+ return 2;
+ }
+ int minorVersion()
+ {
+ ;
+ return 4;
+ }
+ const char *buildDate()
+ {
+ ;
+ return "Wed Mar 23 16:19:43 CET 2005";
+ }
+ bool printStats()
+ {
+ ;
+ return options_s.printStats();
+ }
+ void printStats(bool on)
+ {
+ ;
+ options_s.printStats(on);
+ }
+ bool infoMessages()
+ {
+ ;
+ return (pinfo.outputLevel() >= 0);
+ }
+ void infoMessages(bool on)
+ {
+ ;
+ pinfo.setOutputLevel(on ? Inform::on : Inform::off);
+ }
+ bool warnMessages()
+ {
+ ;
+ return (pwarn.outputLevel() >= 0);
+ }
+ void warnMessages(bool on)
+ {
+ ;
+ pwarn.setOutputLevel(on ? Inform::on : Inform::off);
+ }
+ bool errorMessages()
+ {
+ ;
+ return (perr.outputLevel() >= 0);
+ }
+ void errorMessages(bool on)
+ {
+ ;
+ perr.setOutputLevel(on ? Inform::on : Inform::off);
+ }
+ void logMessages(const char *filename)
+ {
+ ;
+ if (logstream_s != 0)
+ {
+ pinfo.close(pinfoLogID_s);
+ pwarn.close(pwarnLogID_s);
+ perr.close(perrLogID_s);
+ pdebug.close(pdebugLogID_s);
+ delete logstream_s;
+ logstream_s = 0;
+ }
+ if (filename != 0 && *filename != 0)
+ {
+ logstream_s = new std::ofstream(filename, std::ios::out);
+ pinfoLogID_s = pinfo.open(*logstream_s);
+ pwarnLogID_s = pwarn.open(*logstream_s);
+ perrLogID_s = perr.open(*logstream_s);
+ pdebugLogID_s = pdebug.open(*logstream_s);
+ pinfo.setOutputLevel(pinfo.outputLevel());
+ pwarn.setOutputLevel(pwarn.outputLevel());
+ perr.setOutputLevel(perr.outputLevel());
+ pdebug.setOutputLevel(pdebug.outputLevel());
+ }
+ }
+ int debugLevel()
+ {
+ ;
+ return pdebug.outputLevel();
+ }
+ void debugLevel(int level)
+ {
+ ;
+ pdebug.setOutputLevel(level);
+ }
+ bool neverCompress()
+ {
+ ;
+ return options_s.neverCompress();
+ }
+ void neverCompress(bool p)
+ {
+ ;
+ options_s.neverCompress(p);
+ }
+ bool deferredGuardFills()
+ {
+ ;
+ return options_s.deferredGuardFills();
+ }
+ void deferredGuardFills(bool p)
+ {
+ ;
+ options_s.deferredGuardFills(p);
+ }
+ Scheduler_t &scheduler()
+ {
+ ;
+ return mainScheduler_s;
+ }
+ void blockAndEvaluate()
+ {
+ ;
+ mainScheduler_s.blockingEvaluate();
+ }
+ bool hardInit()
+ {
+ ;
+ return options_s.hardInit();
+ }
+ void hardInit(bool on)
+ {
+ ;
+ options_s.hardInit(on);
+ }
+ bool hardRun()
+ {
+ ;
+ return options_s.hardRun();
+ }
+ void hardRun(bool on)
+ {
+ ;
+ options_s.hardRun(on);
+ }
+ bool lockThreads()
+ {
+ ;
+ return options_s.lockThreads();
+ }
+ void lockThreads(bool on)
+ {
+ ;
+ options_s.lockThreads(on);
+ }
+ bool blockingExpressions()
+ {
+ ;
+ return options_s.blockingExpressions();
+ }
+ void blockingExpressions(bool on)
+ {
+ ;
+ options_s.blockingExpressions(on);
+ }
+ }
+ extern "C" void pooma_stop_here();
+ void Pooma::stopHere()
+ {
+ ::pooma_stop_here();
+ }
+ extern "C" void pooma_stop_here()
+ {
+ }
+ namespace Pooma {
+ class PatchSizeSyncer
+ {
+ public:
+ typedef Grid<1> Grid_t;
+ PatchSizeSyncer(int contextKey, Grid_t &localGrid);
+ ~PatchSizeSyncer();
+ void calcGlobalGrid(Grid_t &globalGrid);
+ private:
+ int myContext_m;
+ int numContexts_m;
+ int localKey_m;
+ Grid_t localGrid_m;
+ typedef std::pair<int,Grid_t *> Elem_t;
+ std::vector<Elem_t> gridList_m;
+ PatchSizeSyncer(const PatchSizeSyncer &);
+ PatchSizeSyncer &operator=(const PatchSizeSyncer &);
+ static int tag_s;
+ };
+ }
+ template<class T>
+ class CollectFromContexts
+ {
+ public:
+ CollectFromContexts(const T &val, int context = 0, bool valid = true)
+ {
+ ;
+ ;
+ value_m = val;
+ }
+ T &operator[](int i)
+ {
+ ;
+ return value_m;
+ }
+ T operator[](int i) const
+ {
+ ;
+ return value_m;
+ }
+ private:
+ T value_m;
+ };
+ namespace Pooma {
+ PatchSizeSyncer::PatchSizeSyncer(int contextKey, Grid_t &localGrid)
+ : myContext_m(Pooma::context()),
+ numContexts_m(Pooma::contexts()),
+ localKey_m(contextKey),
+ localGrid_m(localGrid)
+ {
+ if (myContext_m == 0) gridList_m.reserve(numContexts_m);
+ }
+ PatchSizeSyncer::~PatchSizeSyncer()
+ {
+ ;
+ for (int i = 0; i < gridList_m.size(); ++i)
+ delete gridList_m[i].second;
+ }
+ namespace {
+ struct ElemCompare
+ {
+ typedef std::pair<int,Grid<1>*> Elem_t;
+ inline bool operator()(const Elem_t &l, const Elem_t &r)
+ {
+ return l.first < r.first;
+ }
+ };
+ }
+ void PatchSizeSyncer::calcGlobalGrid(Grid_t &globalGrid)
+ {
+ globalGrid = localGrid_m;
+ }
+ }
+ TagGenerator tagGenerator_g;
+ namespace Pooma {
+ int expectedMessages_g = 0;
+ void initializeCheetahHelpers(int contexts)
+ {
+ tagGenerator_g = TagGenerator(contexts);
+ expectedMessages_g = 0;
+ }
+ void finalizeCheetahHelpers()
+ {
+ ;
+ }
+ int sendTag(int context)
+ {
+ return tagGenerator_g.send(context);
+ }
+ int receiveTag(int context)
+ {
+ return tagGenerator_g.receive(context);
+ }
+ }
+ const unsigned int Inform::bufSize = 32000;
+ Pooma::Mutex_t Inform::outputMutex_s;
+ Inform::Context_t Inform::context_s = 0;
+ Inform::Context_t Inform::nContexts_s = 1;
+ class InformStream
+ {
+ public:
+ InformStream(std::ostream *s, Inform::Context_t oc)
+ : stream_m(s), close_m(false), outputContext_m(oc), level_m(0)
+ {
+ ;
+ }
+ InformStream(const char *fname, int mode, Inform::Context_t oc)
+ : stream_m(0), close_m(true), outputContext_m(oc), level_m(0)
+ {
+ ;
+ ;
+ if (oc < 0 || oc == Inform::context()) {
+ if (mode == Inform::out)
+ stream_m = new std::ofstream(fname, std::ios::out);
+ else
+ stream_m = new std::ofstream(fname, std::ios::app);
+ }
+ }
+ ~InformStream()
+ {
+ if (close_m && stream_m != 0)
+ delete stream_m;
+ }
+ Inform::Context_t outputContext() const
+ {
+ return outputContext_m;
+ }
+ void setOutputContext(Inform::Context_t val)
+ {
+ outputContext_m = val;
+ }
+ Inform::Level_t outputLevel() const
+ {
+ return level_m;
+ }
+ void setOutputLevel(Inform::Level_t val)
+ {
+ level_m = val;
+ }
+ void print(Inform::Level_t l, const std::string &prefix, const char *msg)
+ {
+ if (shouldPrint(l))
+ {
+ if (prefix.length() > 0)
+ {
+ *stream_m << prefix;
+ if (Inform::numContexts() > 1)
+ {
+ if ((outputContext_m == Inform::allContexts) ||
+ (outputContext_m == Inform::context()))
+ {
+ *stream_m << "{" << Inform::context() << "}";
+ }
+ }
+ *stream_m << "> ";
+ }
+ *stream_m << msg << "\n";
+ stream_m->flush();
+ }
+ }
+ private:
+ std::ostream *stream_m;
+ bool close_m;
+ Inform::Context_t outputContext_m;
+ Inform::Level_t level_m;
+ bool shouldPrint(Inform::Level_t level)
+ {
+ ;
+ if (stream_m == 0)
+ return false;
+ return (level <= level_m &&
+ (outputContext_m == Inform::context() ||
+ outputContext_m == Inform::allContexts));
+ }
+ };
+ namespace std {
+ Inform &endl(Inform &inf)
+ {
+ inf.flush();
+ return inf;
+ }
+ Inform &flush(Inform &inf)
+ {
+ inf.flush();
+ return inf;
+ }
+ Inform &lock(Inform &inf)
+ {
+ inf.lock();
+ return inf;
+ }
+ Inform &unlock(Inform &inf)
+ {
+ inf.unlock();
+ return inf;
+ }
+ }
+ Inform::Inform(const char *prefix, Context_t outputContext)
+ : prefix_m(""), outputContext_m(outputContext), level_m(0),
+ message_m(0), buffer_m(0), nextID_m(0)
+ {
+ open(outputContext);
+ setup(prefix);
+ }
+ Inform::Inform(const char *prefix, const char *fname, int writemode,
+ Context_t outputContext)
+ : prefix_m(""), outputContext_m(outputContext), level_m(0),
+ message_m(0), buffer_m(0), nextID_m(0)
+ {
+ open(fname, writemode, outputContext);
+ setup(prefix);
+ }
+ Inform::Inform(const char *prefix, std::ostream &outstream,
+ Context_t outputContext)
+ : prefix_m(""), outputContext_m(outputContext), level_m(0),
+ message_m(0), buffer_m(0), nextID_m(0)
+ {
+ open(outstream, outputContext);
+ setup(prefix);
+ }
+ Inform::~Inform()
+ {
+ close();
+ delete message_m;
+ if (buffer_m != 0)
+ delete [] buffer_m;
+ }
+ Inform::ID_t Inform::open(Context_t oc)
+ {
+ streams_m.insert(Value_t(nextID_m, new InformStream(&std::cout, oc)));
+ return nextID_m++;
+ }
+ Inform::ID_t Inform::open(const char *fname, int mode, Context_t oc)
+ {
+ streams_m.insert(Value_t(nextID_m, new InformStream(fname, mode, oc)));
+ return nextID_m++;
+ }
+ Inform::ID_t Inform::open(std::ostream &outstream, Context_t oc)
+ {
+ streams_m.insert(Value_t(nextID_m, new InformStream(&outstream, oc)));
+ return nextID_m++;
+ }
+ void Inform::close(ID_t id)
+ {
+ iterator s = streams_m.find(id);
+ ;
+ delete ((*s).second);
+ streams_m.erase(s);
+ }
+ void Inform::close()
+ {
+ for (iterator a = streams_m.begin(); a != streams_m.end(); ++a)
+ delete ((*a).second);
+ streams_m.erase(streams_m.begin(), streams_m.end());
+ }
+ Inform::Level_t Inform::outputLevel(ID_t id) const
+ {
+ InformStream *s = findStream(id);
+ ;
+ return s->outputLevel();
+ }
+ void Inform::setOutputLevel(Level_t newval, ID_t id)
+ {
+ InformStream *s = findStream(id);
+ ;
+ s->setOutputLevel(newval);
+ }
+ void Inform::setOutputLevel(Level_t newval)
+ {
+ for (iterator a = streams_m.begin(); a != streams_m.end(); ++a)
+ (*a).second->setOutputLevel(newval);
+ }
+ Inform::Context_t Inform::outputContext(ID_t id) const
+ {
+ InformStream *s = findStream(id);
+ ;
+ return s->outputContext();
+ }
+ void Inform::setOutputContext(Context_t outputContext, ID_t id)
+ {
+ InformStream *s = findStream(id);
+ ;
+ s->setOutputContext(outputContext);
+ }
+ void Inform::setOutputContext(Context_t outputContext)
+ {
+ for (iterator a = streams_m.begin(); a != streams_m.end(); ++a)
+ (*a).second->setOutputContext(outputContext);
+ }
+ void Inform::flush()
+ {
+ *message_m << std::ends;
+ outputMutex_s.lock();
+ std::string formatstr = message_m->str();
+ char *outputbuf = new char[formatstr.length() + 2];
+ char *endbuf = outputbuf;
+ char *begbuf = outputbuf;
+ const char *formatbuf = formatstr.c_str();
+ do {
+ while (*formatbuf != '\n' && *formatbuf != '\0')
+ *endbuf++ = *formatbuf++;
+ *endbuf = '\0';
+ if (*formatbuf == '\n')
+ ++formatbuf;
+ for (iterator a = streams_m.begin(); a != streams_m.end(); ++a)
+ (*a).second->print(level_m, prefix_m, begbuf);
+ begbuf = endbuf;
+ } while (*formatbuf != '\0');
+ message_m->str( std::string() );
+ delete [] outputbuf;
+ outputMutex_s.unlock();
+ }
+ InformStream *Inform::findStream(ID_t id) const
+ {
+ const_iterator s = streams_m.find(id);
+ if (s != streams_m.end())
+ return (*s).second;
+ else
+ return 0;
+ }
+ void Inform::setup(const char *prefix)
+ {
+ setPrefix(prefix);
+ buffer_m = 0;
+ message_m = new std::ostringstream(std::ios::out);
+ }
+ void Inform::setPrefix(const char *prefix)
+ {
+ if (prefix == 0 || *prefix == '\0')
+ prefix_m = "";
+ else
+ prefix_m = prefix;
+ }
+ Pool::Pool(size_t sz)
+ :
+ head_m(0),
+ outstandingAllocs_m(0),
+ bsize_m(roundToAlign(sz)),
+ nblock_m(blocksInPage(bsize_m))
+ {
+ }
+ Pool::Pool()
+ :
+ head_m(0),
+ outstandingAllocs_m(0),
+ bsize_m(0),
+ nblock_m(0)
+ {
+ }
+ Pool::~Pool()
+ {
+ if (__builtin_expect(!!(outstandingAllocs_m==0), true)) {} else Pooma::toss_cookies("Not all of the pooled memory was freed!", "/home/rguenth/ix86/pooma/tat-serial/pooma/linux/src/Utilities/Pool.cmpl.cpp", 73);
+ for (std::vector<char*>::iterator p=chunks_m.begin(); p!=chunks_m.end(); ++p)
+ delete [] *p;
+ }
+ void Pool::grow()
+ {
+ size_t alloc_this;
+ if ( bsize_m>page )
+ alloc_this = bsize_m;
+ else
+ alloc_this = page;
+ char *start = new char[alloc_this];
+ chunks_m.push_back(start);
+ char *last = start + (nblock_m-1)*bsize_m;
+ for (char *p=start; p!=last; p+=bsize_m)
+ ((Link*)p)->next_m = (Link*)(p+bsize_m);
+ ((Link*)last)->next_m = head_m;
+ head_m = (Link*)start;
+ }
+ //#include <execinfo.h>
+ namespace Pooma {
+ Assertion::Assertion(const char *msg, const char *file, int line)
+ {
+ msg_m = new char[strlen(msg) + 1];
+ strcpy(msg_m, msg);
+ file_m = new char[strlen(file) + 1];
+ strcpy(file_m, file);
+ line_m = line;
+ }
+ Assertion::Assertion(const Assertion &a)
+ {
+ msg_m = new char[strlen(a.what())+1];
+ strcpy(msg_m, a.what());
+ file_m = new char[strlen(a.file())+1];
+ strcpy(file_m, a.file());
+ line_m = a.line();
+ }
+ Assertion &Assertion::operator=(const Assertion &a)
+ {
+ msg_m = new char[strlen(a.what())+1];
+ strcpy(msg_m, a.what());
+ file_m = new char[strlen(a.file())+1];
+ strcpy(file_m, a.file());
+ line_m = a.line();
+ return *this;
+ }
+ void toss_cookies(const char *msg, const char *file, int line ...)
+ {
+ va_list ap;
+ va_start(ap,line);
+ char buf[256];
+ vsprintf(buf, msg, ap);
+ va_end(ap);
+ Assertion a(buf, file, line);
+ Pooma::stopHere();
+ fprintf(stderr, "### POOMA Assertion Failure on context %i ###\n", Pooma::context());
+ fprintf(stderr, "### %s\n", a.what());
+ fprintf(stderr, "### File %s; Line %d.\n", a.file(), a.line());
+ Pooma::pAbort();
+ }
+ }
+ Unique::Value_t Unique::next_s = 0;
+ Pooma::Mutex_t Unique::mutex_s;
+ bool findLeftCommonEndpoint(int a0, int a1, int s, int b0, int b1, int t,
+ int &endpoint)
+ {
+ ;
+ if (s < 0) s = -s;
+ if (t < 0) t = -t;
+ if (a0 > b0) {
+ int tmp;
+ tmp = a0; a0 = b0; b0 = tmp;
+ tmp = a1; a1 = b1; b1 = tmp;
+ tmp = s; s = t; t = tmp;
+ }
+ int i1 = b0 - ((b0 - a0) % s);
+ int i2 = b0;
+ int maxdiff = 0;
+ int minright = a1;
+ if (b1 < a1)
+ minright = b1;
+ while (i1 <= minright && i2 <= minright) {
+ while (i1 < i2)
+ i1 += s;
+ int newdiff = i1 - i2;
+ if (i1 == i2 || newdiff == maxdiff) {
+ break;
+ } else if (newdiff > maxdiff) {
+ maxdiff = newdiff;
+ }
+ i2 += t;
+ }
+ if (i1 == i2 && i1 <= minright) {
+ endpoint = i1;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ int findLCM(int s, int t)
+ {
+ ;
+ int i1 = s, i2 = t;
+ if (s > t) {
+ s = t;
+ t = i1;
+ i1 = s;
+ i2 = t;
+ }
+ while (i1 != i2) {
+ while (i1 < i2)
+ i1 += s;
+ if (i1 > i2)
+ i2 += t;
+ }
+ return i1;
+ }
+ bool findIntersectionEndpoints(int a0, int a1, int s, int b0, int b1, int t,
+ int &left, int &right, int &stride)
+ {
+ ;
+ if (s < 0) s = -s;
+ if (t < 0) t = -t;
+ if (!findLeftCommonEndpoint(a0, a1, s, b0, b1, t, left))
+ return false;
+ stride = findLCM(s, t);
+ int m = a1;
+ if (b1 < a1)
+ m = b1;
+ right = m - ((m - left) % stride);
+ return true;
+ }
+ GlobalIDDataBase::NodeKey_t
+ GlobalIDDataBase::push(LayoutID_t layoutID, int context, GlobalID_t globalID)
+ {
+ int ret = data_m.size();
+ data_m.push_back(Pack(layoutID, context, globalID, nullNodeKey()));
+ return ret;
+ }
+ GlobalIDDataBase::NodeKey_t
+ GlobalIDDataBase::push(LayoutID_t layoutID,
+ int context,
+ GlobalID_t globalID,
+ NodeKey_t parentNode)
+ {
+ int ret = data_m.size();
+ data_m.push_back(Pack(layoutID, context, globalID, parentNode));
+ return ret;
+ }
+ void
+ GlobalIDDataBase::shared(LayoutID_t idNew, LayoutID_t idOld)
+ {
+ Shared_t::const_iterator p = shared_m.find(idOld);
+ if (p != shared_m.end())
+ {
+ idOld = p->second;
+ }
+ Shared_t::value_type i(idNew, idOld);
+ shared_m.insert(i);
+ }
+ GlobalIDDataBase::GlobalID_t
+ GlobalIDDataBase::globalID(LayoutID_t layoutID, NodeKey_t key) const
+ {
+ Shared_t::const_iterator p = shared_m.find(layoutID);
+ if (p != shared_m.end())
+ {
+ layoutID = p->second;
+ }
+ while( key != nullNodeKey() )
+ {
+ if (data_m[key].layoutID() == layoutID)
+ {
+ return data_m[key].globalID();
+ }
+ else
+ {
+ key = data_m[key].parent();
+ }
+ }
+ ;
+ return -1;
+ }
+ int
+ GlobalIDDataBase::context(LayoutID_t layoutID, NodeKey_t key) const
+ {
+ Shared_t::const_iterator p = shared_m.find(layoutID);
+ if (p != shared_m.end())
+ {
+ layoutID = p->second;
+ }
+ while( key != nullNodeKey() )
+ {
+ if (data_m[key].layoutID() == layoutID)
+ {
+ return data_m[key].context();
+ }
+ else
+ {
+ key = data_m[key].parent();
+ }
+ }
+ ;
+ return -1;
+ }
+ int
+ GlobalIDDataBase::context(NodeKey_t key) const
+ {
+ ;
+ return data_m[key].context();
+ }
+ bool
+ GlobalIDDataBase::contextParticipates(int context, NodeKey_t key) const
+ {
+ while( key != nullNodeKey() )
+ {
+ if (data_m[key].context() == context)
+ {
+ return true;
+ }
+ else
+ {
+ key = data_m[key].parent();
+ }
+ }
+ return false;
+ }
+ namespace Pooma {
+ namespace {
+ unsigned int activeGroups_g = 1;
+ unsigned int numGroups_g = 1;
+ }
+ unsigned int activeRelationGroups()
+ {
+ return activeGroups_g;
+ }
+ bool isRelationGroupActive(unsigned int groups)
+ {
+ return (groups & activeGroups_g) != 0;
+ }
+ void activateRelationGroup(unsigned int group)
+ {
+ blockAndEvaluate();
+ activeGroups_g |= group;
+ }
+ void deactivateRelationGroup(unsigned int group)
+ {
+ blockAndEvaluate();
+ activeGroups_g &= ~group;
+ }
+ unsigned int newRelationGroup()
+ {
+ unsigned int n = (1 << numGroups_g++);
+ activateRelationGroup(n);
+ return n;
+ }
+ }
+ template <int Dim>
+ CanonicalCentering<Dim>::CanonicalCentering()
+ {
+ Centering<Dim> centering;
+ typename Centering<Dim>::Orientation orientation;
+ typename Centering<Dim>::Position position;
+ typename Centering<Dim>::Orientations orientations[Dim][2];
+ typename Centering<Dim>::Positions positions[Dim][2];
+ enum { x = 0, y, z };
+ if (class_count_m == 0) {
+ centering_table_m = new Centering<Dim>**[CellType+1];
+ for (int i = 0; i <= CellType; ++i) {
+ centering_table_m[i] = new Centering<Dim>*[2];
+ for (int j = 0; j < 2; ++j)
+ centering_table_m[i][j] = new Centering<Dim>[1<<Dim];
+ }
+ }
+ ++class_count_m;
+ centering = Centering<Dim>(CellType, Continuous);
+ orientation = 1;
+ position = 0.5;
+ centering.addValue(orientation, position);
+ centering_table_m[CellType][Continuous][AllDim%(1<<Dim)] = centering;
+ orientation = 0; orientation[0] = 1;
+ position = 0.0; position(0) = 0.5;
+ addValue(orientations[x][Continuous],
+ positions[x][Continuous],
+ orientation, position);
+ orientations[x][Discontinuous] =
+ orientations[x][Continuous];
+ positions[x][Discontinuous] =
+ positions[x][Continuous];
+ if (Dim > 1) {
+ position(1) = 1.0;
+ addValue(orientations[x][Discontinuous],
+ positions[x][Discontinuous],
+ orientation, position);
+ if (Dim > 2) {
+ position(2) = 1.0;
+ addValue(orientations[x][Discontinuous],
+ positions[x][Discontinuous],
+ orientation, position);
+ position(1) = 0.0;
+ addValue(orientations[x][Discontinuous],
+ positions[x][Discontinuous],
+ orientation, position);
+ }
+ }
+ if (Dim > 1) {
+ orientation = 0; orientation[1] = 1;
+ position = 0.0; position(1) = 0.5;
+ addValue(orientations[y][Continuous],
+ positions[y][Continuous],
+ orientation, position);
+ orientations[y][Discontinuous] =
+ orientations[y][Continuous];
+ positions[y][Discontinuous] =
+ positions[y][Continuous];
+ position(0) = 1.0;
+ addValue(orientations[y][Discontinuous],
+ positions[y][Discontinuous],
+ orientation, position);
+ if (Dim > 2) {
+ position(2) = 1.0;
+ addValue(orientations[y][Discontinuous],
+ positions[y][Discontinuous],
+ orientation, position);
+ position(0) = 0.0;
+ addValue(orientations[y][Discontinuous],
+ positions[y][Discontinuous],
+ orientation, position);
+ }
+ }
+ if (Dim > 2) {
+ orientation = 0; orientation[2] = 1;
+ position = 0.0; position(2) = 0.5;
+ addValue(orientations[z][Continuous],
+ positions[z][Continuous],
+ orientation, position);
+ orientations[z][Discontinuous] =
+ orientations[z][Continuous];
+ positions[z][Discontinuous] =
+ positions[z][Continuous];
+ position(0) = 1.0;
+ addValue(orientations[z][Discontinuous],
+ positions[z][Discontinuous],
+ orientation, position);
+ position(1) = 1.0;
+ addValue(orientations[z][Discontinuous],
+ positions[z][Discontinuous],
+ orientation, position);
+ position(0) = 0.0;
+ addValue(orientations[z][Discontinuous],
+ positions[z][Discontinuous],
+ orientation, position);
+ }
+ for (int cont = 0; cont < 2; ++cont) {
+ centering_table_m[EdgeType][cont][XDim] =
+ Centering<Dim>(EdgeType, static_cast<enum ContinuityType>(cont),
+ orientations[x][cont], positions[x][cont]);
+ if (Dim > 1) {
+ centering_table_m[EdgeType][cont][YDim] =
+ Centering<Dim>(EdgeType, static_cast<enum ContinuityType>(cont),
+ orientations[y][cont], positions[y][cont]);
+ centering_table_m[EdgeType][cont][XDim|YDim] =
+ Centering<Dim>(EdgeType, static_cast<enum ContinuityType>(cont),
+ combine(orientations[x][cont],orientations[y][cont]),
+ combine(positions[x][cont], positions[y][cont]));
+ }
+ if (Dim > 2) {
+ centering_table_m[EdgeType][cont][ZDim] =
+ Centering<Dim>(EdgeType, static_cast<enum ContinuityType>(cont),
+ orientations[z][cont], positions[z][cont]);
+ centering_table_m[EdgeType][cont][XDim|ZDim] =
+ Centering<Dim>(EdgeType, static_cast<enum ContinuityType>(cont),
+ combine(orientations[x][cont],orientations[z][cont]),
+ combine(positions[x][cont], positions[z][cont]));
+ centering_table_m[EdgeType][cont][YDim|ZDim] =
+ Centering<Dim>(EdgeType, static_cast<enum ContinuityType>(cont),
+ combine(orientations[y][cont],orientations[z][cont]),
+ combine(positions[y][cont], positions[z][cont]));
+ centering_table_m[EdgeType][cont][XDim|YDim|ZDim] =
+ Centering<Dim>(EdgeType, static_cast<enum ContinuityType>(cont),
+ combine(orientations[x][cont],
+ combine(orientations[y][cont],orientations[z][cont])),
+ combine(positions[x][cont],
+ combine(positions[y][cont], positions[z][cont])));
+ }
+ }
+ for (int dim = 0; dim < Dim; ++dim)
+ for (int cont = 0; cont < 2; ++cont)
+ {
+ orientations[dim][cont].clear();
+ positions[dim][cont].clear();
+ }
+ orientation = 1; orientation[0] = 0;
+ position = 0.5; position(0) = 0.0;
+ addValue(orientations[x][Continuous],
+ positions[x][Continuous],
+ orientation, position);
+ orientations[x][Discontinuous] =
+ orientations[x][Continuous];
+ positions[x][Discontinuous] =
+ positions[x][Continuous];
+ position(0) = 1.0;
+ addValue(orientations[x][Discontinuous],
+ positions[x][Discontinuous],
+ orientation, position);
+ if (Dim > 1) {
+ orientation = 1; orientation[1] = 0;
+ position = 0.5; position(1) = 0.0;
+ addValue(orientations[y][Continuous],
+ positions[y][Continuous],
+ orientation, position);
+ orientations[y][Discontinuous] =
+ orientations[y][Continuous];
+ positions[y][Discontinuous] =
+ positions[y][Continuous];
+ position(1) = 1.0;
+ addValue(orientations[y][Discontinuous],
+ positions[y][Discontinuous],
+ orientation, position);
+ }
+ if (Dim > 2) {
+ orientation = 1; orientation[2] = 0;
+ position = 0.5; position(2) = 0.0;
+ addValue(orientations[z][Continuous],
+ positions[z][Continuous],
+ orientation, position);
+ orientations[z][Discontinuous] =
+ orientations[z][Continuous];
+ positions[z][Discontinuous] =
+ positions[z][Continuous];
+ position(2) = 1.0;
+ addValue(orientations[z][Discontinuous],
+ positions[z][Discontinuous],
+ orientation, position);
+ }
+ for (int cont = 0; cont < 2; ++cont) {
+ centering_table_m[FaceType][cont][XDim] =
+ Centering<Dim>(FaceType, static_cast<enum ContinuityType>(cont),
+ orientations[x][cont], positions[x][cont]);
+ if (Dim > 1) {
+ centering_table_m[FaceType][cont][XDim|YDim] =
+ Centering<Dim>(FaceType, static_cast<enum ContinuityType>(cont),
+ combine(orientations[x][cont],orientations[y][cont]),
+ combine(positions[x][cont], positions[y][cont]));
+ centering_table_m[FaceType][cont][YDim] =
+ Centering<Dim>(FaceType, static_cast<enum ContinuityType>(cont),
+ orientations[y][cont], positions[y][cont]);
+ }
+ if (Dim > 2) {
+ centering_table_m[FaceType][cont][ZDim] =
+ Centering<Dim>(FaceType, static_cast<enum ContinuityType>(cont),
+ orientations[z][cont], positions[z][cont]);
+ centering_table_m[FaceType][cont][XDim|ZDim] =
+ Centering<Dim>(FaceType, static_cast<enum ContinuityType>(cont),
+ combine(orientations[x][cont],orientations[z][cont]),
+ combine(positions[x][cont], positions[z][cont]));
+ centering_table_m[FaceType][cont][YDim|ZDim] =
+ Centering<Dim>(FaceType, static_cast<enum ContinuityType>(cont),
+ combine(orientations[y][cont],orientations[z][cont]),
+ combine(positions[y][cont], positions[z][cont]));
+ centering_table_m[FaceType][cont][XDim|YDim|ZDim] =
+ Centering<Dim>(FaceType, static_cast<enum ContinuityType>(cont),
+ combine(orientations[x][cont],
+ combine(orientations[y][cont],orientations[z][cont])),
+ combine(positions[x][cont],
+ combine(positions[y][cont], positions[z][cont])));
+ }
+ }
+ for (int dim = 0; dim < Dim; ++dim)
+ for (int cont = 0; cont < 2; ++cont)
+ {
+ orientations[dim][cont].clear();
+ positions[dim][cont].clear();
+ }
+ centering = Centering<Dim>(VertexType, Continuous);
+ orientation = 0;
+ position = 0.0;
+ centering.addValue(orientation, position);
+ centering_table_m[VertexType][Continuous][AllDim%(1<<Dim)] =
+ centering;
+ centering = Centering<Dim>(VertexType, Discontinuous);
+ orientation = 0;
+ position = 0.0;
+ centering.addValue(orientation, position);
+ position(0) = 1.0; centering.addValue(orientation, position);
+ if (Dim > 1) {
+ position(1) = 1.0; centering.addValue(orientation, position);
+ position(0) = 0.0; centering.addValue(orientation, position);
+ if (Dim > 2) {
+ position(2) = 1.0; centering.addValue(orientation, position);
+ position(0) = 1.0; centering.addValue(orientation, position);
+ position(1) = 0.0; centering.addValue(orientation, position);
+ position(0) = 0.0; centering.addValue(orientation, position);
+ }
+ }
+ centering_table_m[VertexType][Discontinuous][AllDim%(1<<Dim)] =
+ centering;
+ return;
+ }
+ const CanonicalCentering<1> canonicalCenteringOne_g;
+ const CanonicalCentering<2> canonicalCenteringTwo_g;
+ const CanonicalCentering<3> canonicalCenteringThree_g;
+ template <int Dim>
+ const Centering<Dim> canonicalCentering
+ (const enum CenteringType type,
+ const enum ContinuityType discontinuous,
+ const int dimension);
+ template <>
+ const Centering<1> canonicalCentering<1>
+ (const enum CenteringType type,
+ const enum ContinuityType discontinuous,
+ const int dimension)
+ {
+ return canonicalCenteringOne_g(type, discontinuous, dimension);
+ }
+ template <>
+ const Centering<2> canonicalCentering<2>
+ (const enum CenteringType type,
+ const enum ContinuityType discontinuous,
+ const int dimension)
+ {
+ return canonicalCenteringTwo_g(type, discontinuous, dimension);
+ }
+ template <>
+ const Centering<3> canonicalCentering<3>
+ (const enum CenteringType type,
+ const enum ContinuityType discontinuous,
+ const int dimension)
+ {
+ return canonicalCenteringThree_g(type, discontinuous, dimension);
+ }
+ template class CanonicalCentering<1>;
+ template class CanonicalCentering<2>;
+ template class CanonicalCentering<3>;
+ void UniformMapper::map(const List_t& templist) const
+ {
+ int contexts = Pooma::contexts();
+ int npc = blocks_m.first() / contexts;
+ int remainder = blocks_m.first() % contexts;
+ int index = 0;
+ for (int c=0; c<contexts; ++c)
+ {
+ for (int i=0; i<npc; ++i)
+ templist[index++]->context() = c;
+ if (c < remainder)
+ templist[index++]->context() = c;
+ }
+ setAffinity(templist);
+ }
+ namespace Pooma {
+ Options::Options()
+ {
+ reset();
+ }
+ Options::Options(int &argc, char ** argv)
+ {
+ reset();
+ parse(argc, argv);
+ }
+ Options::Options(const Options &opts)
+ {
+ *this = opts;
+ }
+ Options &Options::operator=(const Options &opts)
+ {
+ concurrency_m = opts.concurrency();
+ info_m = opts.printInfo();
+ warn_m = opts.printWarnings();
+ err_m = opts.printErrors();
+ logfile_m = opts.logfile();
+ stats_m = opts.printStats();
+ debug_m = opts.debug();
+ neverCompress_m = opts.neverCompress();
+ deferredFills_m = opts.deferredGuardFills();
+ hardinit_m = opts.hardInit();
+ hardrun_m = opts.hardRun();
+ lockthreads_m = opts.lockThreads();
+ blockingExpressions_m = opts.blockingExpressions();
+ return *this;
+ }
+ Options::~Options()
+ {
+ }
+ void Options::usage()
+ {
+ Inform msg("POOMA Usage", std::cerr);
+ msg << ">>>-----------------------------------<<<\n";
+ msg << ">>> POOMA command-line option summary <<<\n";
+ msg << ">>>-----------------------------------<<<\n";
+ msg << "Standard options:\n";
+ msg << "--pooma-threads <N> ......... set concurrency level (N >= 1)\n";
+ msg << "--pooma-info ................ turn on output of info messages\n";
+ msg << "--pooma-warn ................ turn on output of warning messages\n";
+ msg << "--pooma-err ................. turn on output of error messages\n";
+ msg << "--pooma-log <file> .......... turn on logging of output to <file>\n";
+ msg << "--pooma-stats ............... turn on output of stats at end\n";
+ msg << "--pooma-nocompress .......... disable compression of\n";
+ msg << " compressible brick-engines\n";
+ msg << "--pooma-help ................ print out this summary\n";
+ msg << "Developer options:\n";
+ msg << "--pooma-debug <N> ........... set debug output level to <N>\n";
+ msg << "--pooma-smarts-hardinit\n";
+ msg << "--pooma-smarts-hardrun\n";
+ msg << "--pooma-smarts-lockthreads\n";
+ msg << "--pooma-blocking-expressions\n";
+ msg << "All options exist as \"yes\" and \"no\" pairs.\n";
+ msg << "For example --pooma-info and --pooma-noinfo.\n";
+ msg << "The \"no\" versions listed above imply that \"yes\" is the default.";
+ msg << std::endl;
+ }
+ void Options::reset()
+ {
+ concurrency_m = 1;
+ info_m = true;
+ warn_m = true;
+ err_m = true;
+ logfile_m = "";
+ stats_m = false;
+ debug_m = Inform::off;
+ neverCompress_m = false;
+ deferredFills_m = true;
+ hardinit_m = true;
+ hardrun_m = false;
+ lockthreads_m = false;
+ blockingExpressions_m = false;
+ }
+ void Options::parse(int &argc, char ** &argv)
+ {
+ if (argc < 2)
+ return;
+ int retargc = 1;
+ char **retargv = new char *[argc];
+ retargv[0] = argv[0];
+ int i = 1;
+ while (i < argc)
+ {
+ bool argok = true;
+ bool argvalerr = false;
+ std::string word(argv[i]);
+ if (word == "--pooma-threads")
+ {
+ argok = intArgument(argc, argv, i+1, concurrency_m);
+ argvalerr = (concurrency_m < 1);
+ ++i;
+ }
+ else if (word == "--pooma-nothreads")
+ {
+ concurrency_m = 1;
+ }
+ else if (word == "--pooma-info" || word == "--pooma-noinfo")
+ {
+ info_m = (word == "--pooma-info");
+ }
+ else if (word == "--pooma-nocompress" || word == "--pooma-compress")
+ {
+ neverCompress_m = (word == "--pooma-nocompress");
+ }
+ else if (word == "--pooma-nodeferred-guardfills" ||
+ word == "--pooma-deferred-guardfills")
+ {
+ deferredFills_m = (word == "--pooma-deferred-guardfills");
+ }
+ else if (word == "--pooma-warn" || word == "--pooma-nowarn")
+ {
+ warn_m = (word == "--pooma-warn");
+ }
+ else if (word == "--pooma-err" || word == "--pooma-noerr")
+ {
+ err_m = (word == "--pooma-err");
+ }
+ else if (word == "--pooma-stats" || word == "--pooma-nostats")
+ {
+ stats_m = (word == "--pooma-stats");
+ }
+ else if (word == "--pooma-log")
+ {
+ argok = stringArgument(argc, argv, i+1, logfile_m);
+ ++i;
+ }
+ else if (word == "--pooma-debug")
+ {
+ argok = intArgument(argc, argv, i+1, debug_m);
+ ++i;
+ }
+ else if (word == "--pooma-nodebug")
+ {
+ debug_m = Inform::off;
+ }
+ else if (word == "--pooma-smarts-hardinit")
+ {
+ hardinit_m = true;
+ }
+ else if (word == "--pooma-smarts-nohardinit")
+ {
+ hardinit_m = false;
+ }
+ else if (word == "--pooma-smarts-hardrun")
+ {
+ hardrun_m = true;
+ }
+ else if (word == "--pooma-smarts-nohardrun")
+ {
+ hardrun_m = false;
+ }
+ else if (word == "--pooma-smarts-lockthreads")
+ {
+ lockthreads_m = true;
+ }
+ else if (word == "--pooma-smarts-nolockthreads")
+ {
+ lockthreads_m = false;
+ }
+ else if (word == "--pooma-blocking-expressions")
+ {
+ blockingExpressions_m = true;
+ }
+ else if (word == "--pooma-noblocking-expressions")
+ {
+ blockingExpressions_m = false;
+ }
+ else if (word == "--pooma-help")
+ {
+ usage();
+ exit(0);
+ }
+ else
+ {
+ retargv[retargc++] = argv[i];
+ }
+ if (!argok)
+ {
+ std::cerr << "\nERROR: Bad format for POOMA command-line option '";
+ std::cerr << word.c_str() << "'.\n" << std::endl;
+ usage();
+ exit(0);
+ }
+ if (argvalerr)
+ {
+ std::cerr << "\n";
+ std::cerr << "ERROR: Illegal value for POOMA command-line option '";
+ std::cerr << word.c_str() << "'.\n" << std::endl;
+ usage();
+ exit(0);
+ }
+ ++i;
+ }
+ argc = retargc;
+ for (i = 0; i < retargc; ++i) argv[i] = retargv[i];
+ delete [] retargv;
+ }
+ bool intArgument(int argc, char **argv, int pos, int &val)
+ {
+ if (pos >= argc)
+ return false;
+ char firstchar = argv[pos][0];
+ if (firstchar < '0' || firstchar > '9')
+ {
+ if ((firstchar != '-' && firstchar != '+') || argv[pos][1] == 0 ||
+ (argv[pos][1] < '0' || argv[pos][1] > '9'))
+ return false;
+ }
+ val = atoi(argv[pos]);
+ return true;
+ }
+ bool stringArgument(int argc, char **argv, int pos, std::string &val)
+ {
+ if (pos >= argc)
+ return false;
+ val = argv[pos];
+ return true;
+ }
+ bool doubleArgument(int argc, char **argv, int pos, double &val)
+ {
+ if (pos >= argc)
+ return false;
+ val = atof(argv[pos]);
+ return true;
+ }
+ }
+ namespace Pooma {
+ Statistics::Statistics()
+ {
+ }
+ Statistics::~Statistics()
+ {
+ for (int i = 0; i < statList_m.size(); ++i)
+ {
+ delete statList_m[i];
+ }
+ }
+ long Statistics::defaultFilter(long val)
+ {
+ return val;
+ }
+ void Statistics::print(Inform &o, long (*filter)(long))
+ {
+ int i, j;
+ if (statList_m.size() == 0)
+ return;
+ o << "Runtime statistics summary:" << std::endl;
+ for (i = 0; i < statList_m.size(); ++i)
+ {
+ o << statList_m[i]->description() << " ";
+ int numperiods = 53 - strlen(statList_m[i]->description().c_str());
+ if (numperiods < 2)
+ numperiods = 2;
+ for (j = 0; j < numperiods; ++j)
+ o << ".";
+ o << " " << std::setw(12) << filter(statList_m[i]->value()) << std::endl;
+ }
+ }
+ }
+ namespace EOS {
+ typedef enum {
+ IdealAdiabatic = 0,
+ Last = 4
+ } Eos_t;
+ struct pg_ig
+ {
+ pg_ig() {}
+ template <class F1>
+ pg_ig(const pg_ig& f, const F1&) {}
+ template <class F1, class F2, class F3, class F4>
+ void operator()(const F1& pg, const F2& T, const F3& rh, const F4& xmue) const
+ {
+ Interval<F1::dimensions> I = pg.totalDomain();
+ pg(I) = (T*rh/xmue)(I);
+ }
+ };
+ struct cs_adiabatic
+ {
+ cs_adiabatic() {}
+ cs_adiabatic(double gamma) : gamma_m(gamma) {}
+ template <class F>
+ cs_adiabatic(const cs_adiabatic& f, const F&)
+ : gamma_m(f.gamma_m) {}
+ template <class F1, class F2, class F3>
+ void operator()(const F1& cs, const F2& pg, const F3& rh) const
+ {
+ Interval<F1::dimensions> I = cs.totalDomain();
+ cs(I) = (sqrt(gamma_m * pg/rh))(I);
+ }
+ double gamma_m;
+ };
+ }
+ namespace Hacks {
+ struct limit_rh
+ {
+ limit_rh() {}
+ limit_rh(double rhomin) : rhomin_m(rhomin) {}
+ template <class F>
+ limit_rh(const limit_rh& l, const F&) : rhomin_m(l.rhomin_m) {}
+ template <class F>
+ void operator()(const F& rh);
+ double rhomin_m;
+ };
+ template <class F>
+ void checkRegularity(const F& f);
+ };
+ namespace Hacks {
+ template <class F>
+ void limit_rh::operator()(const F& rh)
+ {
+ Interval<F::dimensions> I = rh.physicalDomain();
+ rh(I) = where(rh(I) < rhomin_m, rhomin_m);
+ }
+ template <int Dim>
+ struct CheckRegularity {
+ CheckRegularity() {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 1> &i) const
+ {
+ i.write(0, false);
+ i.useGuards(0, false);
+ }
+ template <class F1>
+ inline void operator()(const F1 &f, const Loc<Dim>& I) const
+ {
+ if (std::isnan(f(I)))
+ Pooma::pAbort("NaN detected");
+ if (std::isinf(f(I)))
+ Pooma::pAbort("Inf detected");
+ }
+ };
+ template <class F>
+ void checkRegularity(const F& f)
+ {
+ ScalarCode<CheckRegularity<F::dimensions> >()(f);
+ }
+ };
+ namespace CFL {
+ template <int Dim>
+ struct CflFunctor : public Deltas<Dim> {
+ CflFunctor(double omrot, bool vis) : omrot_m(omrot), vis_m(vis) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
+ {
+ for (int d=0; d<Dim; ++d)
+ i.extent().upper(d) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.useGuards(1, false);
+ i.useGuards(2, false);
+ i.useGuards(3, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4>
+ inline void operator()(const F1 &dt, const F2 &cs, const F3 &nue, const F4 &v,
+ const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = dt.mesh();
+ double dtmin = m.vertexSpacing(0, I[0].first()+1)
+ / (std::max(fabs(v.fieldEngine().engine(0, 0).read(I)), fabs(v.fieldEngine().engine(0, 0).read(I+dX)))
+ + cs.read(I));
+ if (Dim > 1)
+ dtmin = std::min(dtmin,
+ m.vertexSpacing(1, I[1].first()+1)
+ / (std::max(fabs(v.fieldEngine().engine(0, 1).read(I)), fabs(v.fieldEngine().engine(0, 1).read(I+dY)))
+ + cs.read(I)/m.GEOXG(I)));
+ if (Dim > 2)
+ dtmin = std::min(dtmin,
+ m.vertexSpacing(2, I[2].first()+1)
+ / (std::max(fabs(v.fieldEngine().engine(0, 2).read(I))+omrot_m, fabs(v.fieldEngine().engine(0, 2).read(I+dZ))+omrot_m)
+ + cs.read(I)/(m.GEOXH(I)*m.GEOYH(I))));
+ dt(I) = dtmin;
+ }
+ const double omrot_m;
+ const bool vis_m;
+ };
+ template <int Dim, class F1, class F2, class F3, class F4>
+ double schritt(const F1 &v, const F2 &cs, const F3 &nue,
+ const F4 &scratch, double omrot, bool vis_f)
+ {
+ Interval<Dim> I(cs.physicalDomain());
+ ScalarCode<CflFunctor<Dim> >(CflFunctor<Dim>(omrot, vis_f))(scratch, I, cs, nue, v);
+ return min(scratch(I));
+ }
+ }
+ GuardLayers<Dim> corr_v[Dim];
+ Interval<Dim> vertexDomain;
+ Vector<Dim> origin;
+ Traits_t::Spacings_t spacings;
+ double gamma_, K, cartvis_nr, cartvis_av;
+ Vector<2> smooth;
+ std::string commandline;
+ Vector<Dim, int> periodicity;
+ std::vector<Loc<Dim> > dump_points;
+ EOS::Eos_t eos;
+ bool a_nr_f = false;
+ int a_nr = std::numeric_limits<int>::max();
+ bool a_end_t_f = false;
+ double a_end_t = std::numeric_limits<double>::max();
+ bool a_blocks_f = false;
+ Loc<Dim> a_blocks;
+ bool a_cfl_f = false;
+ double a_cfl = 0.5;
+ bool a_constant_timestep_f = false;
+ double dt;
+ bool a_min_dt_f = false;
+ double a_min_dt = 0.0;
+ bool a_max_dt_f = false;
+ double a_max_dt = std::numeric_limits<double>::max();
+ bool a_cartvis_f = false;
+ bool a_eos_f = false;
+ EOS::Eos_t a_eos;
+ bool a_rhomin_f = false;
+ double a_rhomin = 1e-6;
+ namespace Adv5 {
+ template<class F1, class F2, class F3, class F4, class F5, class F6, class F7, class F8, class F9>
+ void advect(double dt,
+ const F1 &rh, const F2 &v, double omrot_, const F3 &T,
+ const F4 &flm, const F5 &fle, const F6 &flvv,
+ const F7 &flvc, const F8 &cv, const F9 &ekin,
+ bool eeq, bool ietot);
+ }
+ namespace Adv5 {
+ template <int Dim>
+ struct Ekin : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
+ {
+ i.extent(GuardLayers<Dim>(Loc<Dim>(0), Loc<Dim>(1)));
+ i.write(0, true);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2>
+ inline void operator()(const F1 &ekin, const F2 &v, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = ekin.mesh();
+ double ek = (v.fieldEngine().engine(0, 0).read(I)+v.fieldEngine().engine(0, 0).read(I+dX)) * (v.fieldEngine().engine(0, 0).read(I)+v.fieldEngine().engine(0, 0).read(I+dX));
+ if (Dim > 1)
+ ek += (v.fieldEngine().engine(0, 1).read(I)+v.fieldEngine().engine(0, 1).read(I+dY)) * (v.fieldEngine().engine(0, 1).read(I)+v.fieldEngine().engine(0, 1).read(I+dY)) * std::pow(m.GEOXG(I), 2);
+ if (Dim > 2)
+ ek += (v.fieldEngine().engine(0, 2).read(I)+v.fieldEngine().engine(0, 2).read(I+dZ)) * (v.fieldEngine().engine(0, 2).read(I)+v.fieldEngine().engine(0, 2).read(I+dZ)) * std::pow(m.GEOXH(I)*m.GEOYH(I), 2);
+ ekin(I) = ek / 8.0;
+ }
+ };
+ template <int Dim>
+ struct VelupdX : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
+ {
+ i.extent().lower(0) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2>
+ inline void operator()(const F1 &vx, const F2 &rh, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vx(I) = vx(I)
+ / (m.DDX1(I)*rh(I)+m.DDX0(I)*rh(I-dX));
+ }
+ };
+ template <int Dim>
+ struct VelupdY : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
+ {
+ i.extent().lower(1) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2>
+ inline void operator()(const F1 &vy, const F2 &rh, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vy(I) = vy(I)
+ / ((m.DDY1(I)*rh(I)+m.DDY0(I)*rh(I-dY))
+ * std::pow(m.GEOXG(I), 2));
+ }
+ };
+ template <int Dim>
+ struct VelupdZ : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
+ {
+ i.extent().lower(2) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2>
+ inline void operator()(const F1 &vz, const F2 &rh, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vz(I) = vz(I)
+ / ((m.DDZ1(I)*rh(I)+m.DDZ0(I)*rh(I-dZ))
+ * std::pow(m.GEOXH(I),2) * std::pow(m.GEOYH(I),2));
+ }
+ };
+ namespace X {
+ template <int Dim>
+ struct Massflow : public Deltas<Dim> {
+ Massflow(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().lower(0) = 2;
+ i.extent().upper(0) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, false);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &flmx, const F2 &rh, const F3 &vx, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ double s = vx(I)*dt;
+ Loc<Dim> IND = s > 0.0 ? I-dX : I;
+ double grad1 = (rh(IND)-rh(IND-dX)) * (rh(IND+dX)-rh(IND));
+ double grad = grad1 > 0.0
+ ? 2.0*grad1 / ((rh(IND)-rh(IND-dX))*m.cellSpacing(IND+dX)(0)
+ + (rh(IND+dX)-rh(IND))*m.cellSpacing(IND)(0))
+ : 0.0;
+ flmx(I) = (m.SURXA(I)-m.CCXA(I)*s) * s
+ * (rh(IND)
+ + (m.vertexPosition(I)(0) - m.cellPosition(IND)(0) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct Energyflux : public Deltas<Dim> {
+ Energyflux(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
+ {
+ i.extent().lower(0) = 2;
+ i.extent().upper(0) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, false);
+ i.useGuards(3, false);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4>
+ inline void operator()(const F1 &flex, const F2 &T, const F3 &vx, const F4 &flmx,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = T.mesh();
+ Loc<Dim> IND = Pooma::NoInit();
+ double s, ddm1, dd, ddp1, grad1, grad;
+ s = vx(I)*dt;
+ IND = s > 0.0 ? I-dX : I;
+ ddm1 = T(IND-dX);
+ dd = T(IND);
+ ddp1 = T(IND+dX);
+ grad1 = (dd-ddm1)*(ddp1-dd);
+ grad = grad1 > 0.0
+ ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(0)
+ + (dd-ddm1)*m.cellSpacing(IND+dX)(0))
+ : 0.0;
+ flex(I) = flmx(I)
+ * (dd + (m.vertexPosition(I)(0) - m.cellPosition(IND)(0) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct MomentumfluxX : public Deltas<Dim> {
+ MomentumfluxX(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().lower(0) = 1;
+ i.extent().upper(0) = 2;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &flx, const F2 &vx, const F3 &flmx,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = flx.mesh();
+ Loc<Dim> IND = Pooma::NoInit();
+ double s, ddm1, dd, ddp1, grad1, grad;
+ s = (vx(I) + vx(I+dX)) * 0.5*dt;
+ IND = s > 0.0 ? I : I+dX;
+ ddm1 = vx(IND-dX);
+ dd = vx(IND);
+ ddp1 = vx(IND+dX);
+ grad1 = (dd-ddm1)*(ddp1-dd);
+ grad = grad1 > 0.0
+ ? 2.0*grad1 / ((ddp1-dd)*m.vertexSpacing(IND)(0)
+ + (dd-ddm1)*m.vertexSpacing(IND+dX)(0))
+ : 0.0;
+ flx(I) = 0.5*(flmx(I) + flmx(I+dX))
+ * (dd + (m.cellPosition(I)(0) - m.vertexPosition(IND)(0) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct MomentumfluxY : public Deltas<Dim> {
+ MomentumfluxY(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
+ {
+ i.extent().lower(0) = 2;
+ i.extent().upper(0) = 1;
+ i.extent().lower(1) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ i.useGuards(3, true);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4>
+ inline void operator()(const F1 &flx, const F2 &vx, const F3 &vy, const F4 &flmx,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = flx.mesh();
+ Loc<Dim> IND = Pooma::NoInit();
+ double s, ddm1, dd, ddp1, grad1, grad;
+ s = (m.DDY1(I)*vx(I) + m.DDY0(I)*vx(I-dY)) * dt;
+ IND = s > 0.0 ? I-dX : I;
+ ddm1 = vy(IND-dX) * std::pow(m.GEOXG(IND-dX), 2);
+ dd = vy(IND) * std::pow(m.GEOXG(IND), 2);
+ ddp1 = vy(IND+dX) * std::pow(m.GEOXG(IND+dX), 2);
+ grad1 = (dd-ddm1)*(ddp1-dd);
+ grad = grad1 > 0.0
+ ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(0)
+ + (dd-ddm1)*m.cellSpacing(IND+dX)(0))
+ : 0.0;
+ flx(I) = (m.DDY1(I)*flmx(I) + m.DDY0(I)*flmx(I-dY))
+ * (dd + (m.vertexPosition(I)(0) - m.cellPosition(IND)(0) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct MomentumfluxZ : public Deltas<Dim> {
+ MomentumfluxZ(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
+ {
+ i.extent().lower(0) = 2;
+ i.extent().upper(0) = 1;
+ i.extent().lower(2) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ i.useGuards(3, true);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4>
+ inline void operator()(const F1 &flx, const F2 &vx, const F3 &vz, const F4 &flmx,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = flx.mesh();
+ Loc<Dim> IND = Pooma::NoInit();
+ double s, ddm1, dd, ddp1, grad1, grad;
+ s = (m.DDZ1(I)*vx(I)
+ + m.DDZ0(I)*vx(I-dZ)) * dt;
+ IND = s > 0.0 ? I-dX : I;
+ ddm1 = vz.read(IND-dX)
+ * std::pow(m.GEOXH(IND-dX), 2) * std::pow(m.GEOYH(I), 2);
+ dd = vz.read(IND)
+ * std::pow(m.GEOXH(IND), 2) * std::pow(m.GEOYH(I), 2);
+ ddp1 = vz.read(IND+dX)
+ * std::pow(m.GEOXH(IND+dX), 2) * std::pow(m.GEOYH(I), 2);
+ grad1 = (dd-ddm1)*(ddp1-dd);
+ grad = grad1 > 0.0
+ ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(0)
+ + (dd-ddm1)*m.cellSpacing(IND+dX)(0))
+ : 0.0;
+ flx(I) = (m.DDZ1(I)*flmx(I) + m.DDZ0(I)*flmx(I-dZ))
+ * (dd + (m.vertexPosition(I)(0) - m.cellPosition(IND)(0) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct Energyflux2 : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().upper(0) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, false);
+ i.useGuards(2, true);
+ }
+ using Deltas<Dim>::dX;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &T, const F2 &rh, const F3 &flex,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = T.mesh();
+ T(I) = T(I)*rh(I)
+ - (flex(I+dX) - flex(I)) / m.VOLXB(I);
+ }
+ };
+ template <int Dim>
+ struct Momentumflux2X : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().lower(0) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &vx, const F2 &rh, const F3 &flx,
+ const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vx(I) = vx(I)
+ * (m.DDX1(I)*rh(I)+m.DDX0(I)*rh(I-dX))
+ - (flx(I) - flx(I-dX)) / m.VOLXA(I);
+ }
+ };
+ template <int Dim>
+ struct Momentumflux2Y : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().upper(0) = 1;
+ i.extent().lower(1) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &vy, const F2 &rh, const F3 &flx,
+ const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vy(I) = vy(I) * std::pow(m.GEOXG(I), 2)
+ * (m.DDY1(I)*rh(I)+m.DDY0(I)*rh(I-dY))
+ - (flx(I+dX) - flx(I)) / m.VOLXB(I);
+ }
+ };
+ template <int Dim>
+ struct Momentumflux2Z : public Deltas<Dim> {
+ Momentumflux2Z(double omrot) : omrot_m(omrot) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().upper(0) = 1;
+ i.extent().lower(2) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &vz, const F2 &rh, const F3 &flx,
+ const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vz(I) = (vz(I) + omrot_m) * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(I), 2)
+ * (m.DDZ1(I)*rh(I)+m.DDZ0(I)*rh(I-dZ))
+ - (flx(I+dX) - flx(I)) / m.VOLXB(I);
+ }
+ const double omrot_m;
+ };
+ template <int Dim>
+ struct Densupd : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
+ {
+ i.extent().upper(0) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ }
+ using Deltas<Dim>::dX;
+ template <class F1, class F2>
+ inline void operator()(const F1 &rh, const F2 &flmx, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ rh(I) = rh(I) - (flmx(I+dX)-flmx(I))/m.VOLXB(I);
+ }
+ };
+ template<int Dim, class F1, class F2, class F3, class F4, class F5, class F6, class F7, class F8, class F9>
+ inline
+ void advect(double dt,
+ const F1 &rh, const F2 &v, const F3 &T,
+ const F4 &flm, const F5 &fle, const F6 &flvv, const F7 &flvc,
+ const F8 &cv, const F9 &ekin,
+ double omrot, bool eeq, bool ietot)
+ {
+ (ScalarCode<Massflow<Dim> >(dt))(flm.center(0),
+ rh, v.center(0));
+ if (eeq) {
+ if (ietot) {
+ Interval<Dim> I(T.physicalDomain());
+ ScalarCode<Ekin<Dim> >()(ekin, v);
+ T(I) = (cv*T + ekin)(I);
+ }
+ (ScalarCode<Energyflux<Dim> >(dt))(fle.center(0),
+ T, v.center(0), flm.center(0));
+ ScalarCode<Energyflux2<Dim> >()(T, T.physicalDomain(),
+ rh, fle.center(0));
+ }
+ (ScalarCode<MomentumfluxX<Dim> >(dt))(flvc,
+ v.center(0), flm.center(0));
+ if (Dim > 1)
+ (ScalarCode<MomentumfluxY<Dim> >(dt))(flvv.comp(1), shrink(flvv.physicalDomain(), corr_v[1]),
+ v.center(0), v.center(1), flm.center(0));
+ if (Dim > 2)
+ (ScalarCode<MomentumfluxZ<Dim> >(dt))(flvv.comp(2), shrink(flvv.physicalDomain(), corr_v[2]),
+ v.center(0), v.center(2)+omrot, flm.center(0));
+ ScalarCode<Momentumflux2X<Dim> >()(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]),
+ rh, flvc);
+ if (Dim > 1)
+ ScalarCode<Momentumflux2Y<Dim> >()(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]),
+ rh, flvv.comp(1));
+ if (Dim > 2)
+ (ScalarCode<Momentumflux2Z<Dim> >(omrot))(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]),
+ rh, flvv.comp(2));
+ ScalarCode<Densupd<Dim> >()(rh, rh.physicalDomain(), flm.center(0));
+ ScalarCode<VelupdX<Dim> >()(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]), rh);
+ if (Dim > 1)
+ ScalarCode<VelupdY<Dim> >()(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]), rh);
+ if (Dim > 2) {
+ ScalarCode<VelupdZ<Dim> >()(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]), rh);
+ if (omrot != 0.0)
+ v.center(2)(shrink(v.center(2).physicalDomain(), corr_v[2])) -= omrot;
+ }
+ if (eeq) {
+ Interval<Dim> I(T.physicalDomain());
+ if (!ietot)
+ T(I) = (T / rh)(I);
+ else {
+ ScalarCode<Ekin<Dim> >()(ekin, v);
+ T(I) = ((T / rh - ekin)/cv)(I);
+ }
+ }
+ }
+ };
+ namespace Y {
+ template <int Dim>
+ struct Massflow : public Deltas<Dim> {
+ Massflow(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().lower(1) = 2;
+ i.extent().upper(1) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, false);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &flmx, const F2 &rh, const F3 &vy, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ double s = vy(I)*dt;
+ Loc<Dim> IND = s > 0.0 ? I-dY : I;
+ double grad1 = (rh(IND)-rh(IND-dY)) * (rh(IND+dY)-rh(IND));
+ double grad = grad1 > 0.0
+ ? 2.0*grad1 / ((rh(IND)-rh(IND-dY))*m.cellSpacing(IND+dY)(1)
+ + (rh(IND+dY)-rh(IND))*m.cellSpacing(IND)(1))
+ : 0.0;
+ flmx(I) = (m.SURYA(I)+m.CCYA(I)*s) * s
+ * (rh(IND)
+ + (m.vertexPosition(I)(1) - m.cellPosition(IND)(1) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct Energyflux : public Deltas<Dim> {
+ Energyflux(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
+ {
+ i.extent().lower(1) = 2;
+ i.extent().upper(1) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, false);
+ i.useGuards(3, false);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4>
+ inline void operator()(const F1 &flex, const F2 &T, const F3 &vy, const F4 &flmx,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = T.mesh();
+ Loc<Dim> IND = Pooma::NoInit();
+ double s, ddm1, dd, ddp1, grad1, grad;
+ s = vy(I)*dt;
+ IND = s > 0.0 ? I-dY : I;
+ ddm1 = T(IND-dY);
+ dd = T(IND);
+ ddp1 = T(IND+dY);
+ grad1 = (dd-ddm1)*(ddp1-dd);
+ grad = grad1 > 0.0
+ ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(1)
+ + (dd-ddm1)*m.cellSpacing(IND+dY)(1))
+ : 0.0;
+ flex(I) = flmx(I)
+ * (dd + (m.vertexPosition(I)(1) - m.cellPosition(IND)(1) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct MomentumfluxX : public Deltas<Dim> {
+ MomentumfluxX(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
+ {
+ i.extent().lower(0) = 1;
+ i.extent().lower(1) = 2;
+ i.extent().upper(1) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ i.useGuards(3, true);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4>
+ inline void operator()(const F1 &flx, const F2 &vy, const F3 &vx, const F4 &flmx,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = flx.mesh();
+ Loc<Dim> IND = Pooma::NoInit();
+ double s, ddm1, dd, ddp1, grad1, grad;
+ s = (m.DDX1(I)*vy(I) + m.DDX0(I)*vy(I-dX)) * dt;
+ IND = s > 0.0 ? I-dY : I;
+ ddm1 = vx(IND-dY);
+ dd = vx(IND);
+ ddp1 = vx(IND+dY);
+ grad1 = (dd-ddm1)*(ddp1-dd);
+ grad = grad1 > 0.0
+ ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(1)
+ + (dd-ddm1)*m.cellSpacing(IND+dY)(1))
+ : 0.0;
+ flx(I) = (m.DDX1(I)*flmx(I) + m.DDX0(I)*flmx(I-dX))
+ * (dd + (m.vertexPosition(I)(1) - m.cellPosition(IND)(1) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct MomentumfluxY : public Deltas<Dim> {
+ MomentumfluxY(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().lower(1) = 1;
+ i.extent().upper(1) = 2;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &flx, const F2 &vy, const F3 &flmx,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = flx.mesh();
+ Loc<Dim> IND = Pooma::NoInit();
+ double s, ddm1, dd, ddp1, grad1, grad;
+ s = (vy(I) + vy(I+dY)) * 0.5 * dt;
+ IND = s > 0.0 ? I : I+dY;
+ ddm1 = vy(IND-dY) * std::pow(m.GEOXG(I), 2);
+ dd = vy(IND) * std::pow(m.GEOXG(I), 2);
+ ddp1 = vy(IND+dY) * std::pow(m.GEOXG(I), 2);
+ grad1 = (dd-ddm1)*(ddp1-dd);
+ grad = grad1 > 0.0
+ ? 2.0*grad1 / ((ddp1-dd)*m.vertexSpacing(IND)(1)
+ + (dd-ddm1)*m.vertexSpacing(IND+dY)(1))
+ : 0.0;
+ flx(I) = 0.5*(flmx(I) + flmx(I+dY))
+ * (dd + (m.cellPosition(I)(1) - m.vertexPosition(IND)(1) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct MomentumfluxZ : public Deltas<Dim> {
+ MomentumfluxZ(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
+ {
+ i.extent().lower(1) = 2;
+ i.extent().upper(1) = 1;
+ i.extent().lower(2) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ i.useGuards(3, true);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4>
+ inline void operator()(const F1 &flx, const F2 &vy, const F3 &vz, const F4 &flmx,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = flx.mesh();
+ Loc<Dim> IND = Pooma::NoInit();
+ double s, ddm1, dd, ddp1, grad1, grad;
+ s = (m.DDZ1(I)*vy(I)
+ + m.DDZ0(I)*vy(I-dZ)) * dt;
+ IND = s > 0.0 ? I-dY : I;
+ ddm1 = vz.read(IND-dY)
+ * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(IND-dY), 2);
+ dd = vz.read(IND)
+ * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(IND), 2);
+ ddp1 = vz.read(IND+dY)
+ * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(IND+dY), 2);
+ grad1 = (dd-ddm1)*(ddp1-dd);
+ grad = grad1 > 0.0
+ ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(1)
+ + (dd-ddm1)*m.cellSpacing(IND+dY)(1))
+ : 0.0;
+ flx(I) = (m.DDZ1(I)*flmx(I) + m.DDZ0(I)*flmx(I-dZ))
+ * (dd + (m.vertexPosition(I)(1) - m.cellPosition(IND)(1) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct Energyflux2 : public Deltas<Dim> {
+ Energyflux2() {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().upper(1) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, false);
+ i.useGuards(2, true);
+ }
+ using Deltas<Dim>::dY;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &T, const F2 &rh, const F3 &flex,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = T.mesh();
+ T(I) = T(I)*rh(I)
+ - (flex(I+dY) - flex(I)) / m.VOLYB(I);
+ }
+ };
+ template <int Dim>
+ struct Momentumflux2X : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().lower(0) = 1;
+ i.extent().upper(1) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &vx, const F2 &rh, const F3 &flx,
+ const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vx(I) = vx(I)
+ * (m.DDX1(I)*rh(I)+m.DDX0(I)*rh(I-dX))
+ - (flx(I+dY) - flx(I)) / m.VOLYB(I);
+ }
+ };
+ template <int Dim>
+ struct Momentumflux2Y : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().lower(1) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &vy, const F2 &rh, const F3 &flx,
+ const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vy(I) = vy(I) * std::pow(m.GEOXG(I), 2)
+ * (m.DDY1(I)*rh(I)+m.DDY0(I)*rh(I-dY))
+ - (flx(I) - flx(I-dY)) / m.VOLYA(I);
+ }
+ };
+ template <int Dim>
+ struct Momentumflux2Z : public Deltas<Dim> {
+ Momentumflux2Z(double omrot) : omrot_m(omrot) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().upper(1) = 1;
+ i.extent().lower(2) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &vz, const F2 &rh, const F3 &flx,
+ const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vz(I) = (vz(I)+omrot_m) * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(I), 2)
+ * (m.DDZ1(I)*rh(I)+m.DDZ0(I)*rh(I-dZ))
+ - (flx(I+dY) - flx(I)) / m.VOLYB(I);
+ }
+ const double omrot_m;
+ };
+ template <int Dim>
+ struct Densupd : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
+ {
+ i.extent().upper(1) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ }
+ using Deltas<Dim>::dY;
+ template <class F1, class F2>
+ inline void operator()(const F1 &rh, const F2 &flmx, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ rh(I) = rh(I) - (flmx(I+dY)-flmx(I))/m.VOLYB(I);
+ }
+ };
+ template<int Dim, class F1, class F2, class F3, class F4, class F5, class F6, class F7, class F8, class F9>
+ inline
+ void advect(double dt,
+ const F1 &rh, const F2 &v, const F3 &T,
+ const F4 &flm, const F5 &fle, const F6 &flvv, const F7 &flvc,
+ const F8 &cv, const F9 &ekin,
+ double omrot, bool eeq, bool ietot)
+ {
+ (ScalarCode<Massflow<Dim> >(dt))(flm.center(1),
+ rh, v.center(1));
+ if (eeq) {
+ if (ietot) {
+ Interval<Dim> I(T.physicalDomain());
+ ScalarCode<Ekin<Dim> >()(ekin, v);
+ T(I) = (cv*T + ekin)(I);
+ }
+ (ScalarCode<Energyflux<Dim> >(dt))(fle.center(1),
+ T, v.center(1), flm.center(1));
+ ScalarCode<Energyflux2<Dim> >()(T, T.physicalDomain(),
+ rh, fle.center(1));
+ }
+ (ScalarCode<MomentumfluxX<Dim> >(dt))(flvv.comp(0), shrink(flvv.physicalDomain(), corr_v[0]),
+ v.center(1), v.center(0), flm.center(1));
+ if (Dim > 1)
+ (ScalarCode<MomentumfluxY<Dim> >(dt))(flvc,
+ v.center(1), flm.center(1));
+ if (Dim > 2)
+ (ScalarCode<MomentumfluxZ<Dim> >(dt))(flvv.comp(2), shrink(flvv.physicalDomain(), corr_v[2]),
+ v.center(1), v.center(2)+omrot, flm.center(1));
+ ScalarCode<Momentumflux2X<Dim> >()(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]),
+ rh, flvv.comp(0));
+ if (Dim > 1)
+ ScalarCode<Momentumflux2Y<Dim> >()(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]),
+ rh, flvc);
+ if (Dim > 2)
+ (ScalarCode<Momentumflux2Z<Dim> >(omrot))(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]),
+ rh, flvv.comp(2));
+ ScalarCode<Densupd<Dim> >()(rh, rh.physicalDomain(), flm.center(1));
+ ScalarCode<VelupdX<Dim> >()(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]), rh);
+ if (Dim > 1)
+ ScalarCode<VelupdY<Dim> >()(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]), rh);
+ if (Dim > 2) {
+ ScalarCode<VelupdZ<Dim> >()(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]), rh);
+ if (omrot != 0.0)
+ v.center(2)(shrink(v.center(2).physicalDomain(), corr_v[2])) -= omrot;
+ }
+ if (eeq) {
+ Interval<Dim> I(T.physicalDomain());
+ if (!ietot)
+ T(I) = (T / rh)(I);
+ else {
+ ScalarCode<Ekin<Dim> >()(ekin, v);
+ T(I) = ((T / rh - ekin)/cv)(I);
+ }
+ }
+ }
+ };
+ namespace Z {
+ template <int Dim>
+ struct Massflow : public Deltas<Dim> {
+ Massflow(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().lower(2) = 2;
+ i.extent().upper(2) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, false);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &flmx, const F2 &rh, const F3 &vz, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ double s = vz(I)*dt;
+ Loc<Dim> IND = s > 0.0 ? I-dZ : I;
+ double grad1 = (rh(IND)-rh(IND-dZ)) * (rh(IND+dZ)-rh(IND));
+ double grad = grad1 > 0.0
+ ? 2.0*grad1 / ((rh(IND)-rh(IND-dZ))*m.cellSpacing(IND+dZ)(2)
+ + (rh(IND+dZ)-rh(IND))*m.cellSpacing(IND)(2))
+ : 0.0;
+ flmx(I) = (m.SURZA(I)-m.CCZA(I)*s) * s
+ * (rh(IND)
+ + (m.vertexPosition(I)(2) - m.cellPosition(IND)(2) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct Energyflux : public Deltas<Dim> {
+ Energyflux(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
+ {
+ i.extent().lower(2) = 2;
+ i.extent().upper(2) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, false);
+ i.useGuards(3, false);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4>
+ inline void operator()(const F1 &flex, const F2 &T, const F3 &vz, const F4 &flmx,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = T.mesh();
+ Loc<Dim> IND = Pooma::NoInit();
+ double s, ddm1, dd, ddp1, grad1, grad;
+ s = vz(I)*dt;
+ IND = s > 0.0 ? I-dZ : I;
+ ddm1 = T(IND-dZ);
+ dd = T(IND);
+ ddp1 = T(IND+dZ);
+ grad1 = (dd-ddm1)*(ddp1-dd);
+ grad = grad1 > 0.0
+ ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(2)
+ + (dd-ddm1)*m.cellSpacing(IND+dZ)(2))
+ : 0.0;
+ flex(I) = flmx(I)
+ * (dd + (m.vertexPosition(I)(2) - m.cellPosition(IND)(2) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct MomentumfluxX : public Deltas<Dim> {
+ MomentumfluxX(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
+ {
+ i.extent().lower(0) = 1;
+ i.extent().lower(2) = 2;
+ i.extent().upper(2) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ i.useGuards(3, true);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4>
+ inline void operator()(const F1 &flx, const F2 &vz, const F3 &vx, const F4 &flmx,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = flx.mesh();
+ Loc<Dim> IND = Pooma::NoInit();
+ double s, ddm1, dd, ddp1, grad1, grad;
+ s = (m.DDX1(I)*vz(I) + m.DDX0(I)*vz(I-dX)) * dt;
+ IND = s > 0.0 ? I-dZ : I;
+ ddm1 = vx(IND-dZ);
+ dd = vx(IND);
+ ddp1 = vx(IND+dZ);
+ grad1 = (dd-ddm1)*(ddp1-dd);
+ grad = grad1 > 0.0
+ ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(2)
+ + (dd-ddm1)*m.cellSpacing(IND+dZ)(2))
+ : 0.0;
+ flx(I) = (m.DDX1(I)*flmx(I) + m.DDX0(I)*flmx(I-dX))
+ * (dd + (m.vertexPosition(I)(2) - m.cellPosition(IND)(2) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct MomentumfluxY : public Deltas<Dim> {
+ MomentumfluxY(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
+ {
+ i.extent().lower(1) = 1;
+ i.extent().lower(2) = 2;
+ i.extent().upper(2) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ i.useGuards(3, true);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4>
+ inline void operator()(const F1 &flx, const F2 &vz, const F3 &vy, const F4 &flmx,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = flx.mesh();
+ Loc<Dim> IND = Pooma::NoInit();
+ double s, ddm1, dd, ddp1, grad1, grad;
+ s = (m.DDY1(I)*vz(I)
+ + m.DDY0(I)*vz(I-dY)) * dt;
+ IND = s > 0.0 ? I-dZ : I;
+ ddm1 = vy(IND-dZ) * std::pow(m.GEOXG(I), 2);
+ dd = vy(IND) * std::pow(m.GEOXG(I), 2);
+ ddp1 = vy(IND+dZ) * std::pow(m.GEOXG(I), 2);
+ grad1 = (dd-ddm1)*(ddp1-dd);
+ grad = grad1 > 0.0
+ ? 2.0*grad1 / ((ddp1-dd)*m.cellSpacing(IND)(2)
+ + (dd-ddm1)*m.cellSpacing(IND+dZ)(2))
+ : 0.0;
+ flx(I) = (m.DDY1(I)*flmx(I) + m.DDY0(I)*flmx(I-dY))
+ * (dd + (m.vertexPosition(I)(2) - m.cellPosition(IND)(2) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct MomentumfluxZ : public Deltas<Dim> {
+ MomentumfluxZ(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().lower(2) = 1;
+ i.extent().upper(2) = 2;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &flx, const F2 &vz, const F3 &flmx,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = flx.mesh();
+ Loc<Dim> IND = Pooma::NoInit();
+ double s, ddm1, dd, ddp1, grad1, grad;
+ s = (vz(I) + vz(I+dZ)) * 0.5*dt;
+ IND = s > 0.0 ? I : I+dZ;
+ ddm1 = vz(IND-dZ)
+ * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(I), 2);
+ dd = vz(IND)
+ * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(I), 2);
+ ddp1 = vz(IND+dZ)
+ * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(I), 2);
+ grad1 = (dd-ddm1)*(ddp1-dd);
+ grad = grad1 > 0.0
+ ? 2.0*grad1 / ((ddp1-dd)*m.vertexSpacing(IND)(2)
+ + (dd-ddm1)*m.vertexSpacing(IND+dZ)(2))
+ : 0.0;
+ flx(I) = 0.5*(flmx(I) + flmx(I+dZ))
+ * (dd + (m.cellPosition(I)(2) - m.vertexPosition(IND)(2) - 0.5*s) * grad);
+ }
+ };
+ template <int Dim>
+ struct Energyflux2 : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().upper(2) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, false);
+ i.useGuards(2, true);
+ }
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &T, const F2 &rh, const F3 &flex,
+ const Loc<Dim>& I) const
+ {
+ const typename F3::Mesh_t &m = T.mesh();
+ T(I) = T(I)*rh(I)
+ - (flex(I+dZ) - flex(I)) / m.VOLZB(I);
+ }
+ };
+ template <int Dim>
+ struct Momentumflux2X : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().lower(0) = 1;
+ i.extent().upper(2) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &vx, const F2 &rh, const F3 &flx,
+ const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vx(I) = vx(I)
+ * (m.DDX1(I)*rh(I)+m.DDX0(I)*rh(I-dX))
+ - (flx(I+dZ) - flx(I)) / m.VOLZA(I);
+ }
+ };
+ template <int Dim>
+ struct Momentumflux2Y : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().lower(1) = 1;
+ i.extent().upper(2) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &vy, const F2 &rh, const F3 &flx,
+ const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vy(I) = vy(I) * std::pow(m.GEOXG(I), 2)
+ * (m.DDY1(I)*rh(I)+m.DDY0(I)*rh(I-dY))
+ - (flx(I+dZ) - flx(I)) / m.VOLZB(I);
+ }
+ };
+ template <int Dim>
+ struct Momentumflux2Z : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 3> &i) const
+ {
+ i.extent().lower(2) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &vz, const F2 &rh, const F3 &flx,
+ const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vz(I) = vz(I) * std::pow(m.GEOXH(I), 2) * std::pow(m.GEOYH(I), 2)
+ * (m.DDZ1(I)*rh(I)+m.DDZ0(I)*rh(I-dZ))
+ - (flx(I) - flx(I-dZ)) / m.VOLZB(I);
+ }
+ };
+ template <int Dim>
+ struct Densupd : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
+ {
+ i.extent().upper(2) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ }
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2>
+ inline void operator()(const F1 &rh, const F2 &flmx, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ rh(I) = rh(I) - (flmx(I+dZ)-flmx(I))/m.VOLZB(I);
+ }
+ };
+ template<int Dim, class F1, class F2, class F3, class F4, class F5, class F6, class F7, class F8, class F9>
+ inline
+ void advect(double dt,
+ const F1 &rh, const F2 &v, const F3 &T,
+ const F4 &flm, const F5 &fle, const F6 &flvv, const F7 &flvc,
+ const F8 &cv, const F9 &ekin,
+ bool eeq, bool ietot)
+ {
+ (ScalarCode<Massflow<Dim> >(dt))(flm.center(2),
+ rh, v.center(2));
+ if (eeq) {
+ if (ietot) {
+ Interval<Dim> I(T.physicalDomain());
+ ScalarCode<Ekin<Dim> >()(ekin, v);
+ T(I) = (cv*T + ekin)(I);
+ }
+ (ScalarCode<Energyflux<Dim> >(dt))(fle.center(2),
+ T, v.center(2), flm.center(2));
+ ScalarCode<Energyflux2<Dim> >()(T, T.physicalDomain(), rh, fle.center(2));
+ }
+ (ScalarCode<MomentumfluxX<Dim> >(dt))(flvv.comp(0), shrink(flvv.physicalDomain(), corr_v[0]),
+ v.center(2), v.center(0), flm.center(2));
+ if (Dim > 1)
+ (ScalarCode<MomentumfluxY<Dim> >(dt))(flvv.comp(1), shrink(flvv.physicalDomain(), corr_v[1]),
+ v.center(2), v.center(1), flm.center(2));
+ if (Dim > 2)
+ (ScalarCode<MomentumfluxZ<Dim> >(dt))(flvc,
+ v.center(2), flm.center(2));
+ ScalarCode<Momentumflux2X<Dim> >()(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]),
+ rh, flvv.comp(0));
+ if (Dim > 1)
+ ScalarCode<Momentumflux2Y<Dim> >()(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]),
+ rh, flvv.comp(1));
+ if (Dim > 2)
+ ScalarCode<Momentumflux2Z<Dim> >()(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]),
+ rh, flvc);
+ ScalarCode<Densupd<Dim> >()(rh, rh.physicalDomain(), flm.center(2));
+ ScalarCode<VelupdX<Dim> >()(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]), rh);
+ if (Dim > 1)
+ ScalarCode<VelupdY<Dim> >()(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]), rh);
+ if (Dim > 2)
+ ScalarCode<VelupdZ<Dim> >()(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]), rh);
+ if (eeq) {
+ Interval<Dim> I(T.physicalDomain());
+ if (!ietot)
+ T(I) = (T / rh)(I);
+ else {
+ ScalarCode<Ekin<Dim> >()(ekin, v);
+ T(I) = ((T / rh - ekin)/cv)(I);
+ }
+ }
+ }
+ };
+ template <class CoordinateSystemTag>
+ double omrotForAdvect(double omrot) { return omrot; }
+ template <>
+ double omrotForAdvect<CartesianTag>(double omrot) { return 0.0; }
+ template<class F1, class F2, class F3, class F4, class F5, class F6, class F7, class F8, class F9>
+ void advect(double dt,
+ const F1 &rh, const F2 &v, double omrot_, const F3 &T,
+ const F4 &flm, const F5 &fle, const F6 &flvv,
+ const F7 &flvc, const F8 &cv, const F9 &ekin,
+ bool eeq, bool ietot)
+ {
+ static int it = 0;
+ enum { Dim = F1::dimensions };
+ double omrot = omrotForAdvect<typename F1::Mesh_t::MeshTraits_t::CoordinateSystemTag_t>(omrot_);
+ if (it++ % 2 == 0) {
+ X::advect<Dim>(dt, rh, v, T, flm, fle, flvv, flvc, cv, ekin, omrot, eeq, ietot);
+ Y::advect<Dim>(dt, rh, v, T, flm, fle, flvv, flvc, cv, ekin, omrot, eeq, ietot);
+ Z::advect<Dim>(dt, rh, v, T, flm, fle, flvv, flvc, cv, ekin, eeq, ietot);
+ } else {
+ Z::advect<Dim>(dt, rh, v, T, flm, fle, flvv, flvc, cv, ekin, eeq, ietot);
+ Y::advect<Dim>(dt, rh, v, T, flm, fle, flvv, flvc, cv, ekin, omrot, eeq, ietot);
+ X::advect<Dim>(dt, rh, v, T, flm, fle, flvv, flvc, cv, ekin, omrot, eeq, ietot);
+ }
+ }
+ };
+ namespace Forgas {
+ template <class F1, class F2, class F3, class F4, class F5,
+ class F6, class F7, class F8, class F9, class F10,
+ class F11, class F12, class F13,
+ class F14, class F15, class F16, class F17>
+ void force(double dt, const F1 &rh, F2 &T, F3 &v, double omrot, F4 &pg, const F5 &ph,
+ const F11& cs, const F6 &cv, const F7 &dlmdlt, const F8 &xmue,
+ const F9 &vint, F10 ¢, const F12 &a_pg, const F13 &gradv,
+ const F14 &Tii, const F15 &Tij, const F16 &fvis, const F17 &eta, bool vis,
+ double c_nr, bool cartvis_f, bool eeq);
+ template <class F1, class F2, class F3, class F4, class F5,
+ class F6, class F7, class F8, class F9, class F10, class F11,
+ class F12, class F13, class F14, class F15>
+ void force(double dt, const F1 &rh, const F2 &T, const F3 &v, double omrot, F4 &pg, const F5 &ph,
+ const F11 &cs, const F6 &cv, const F7 &dlmdlt, const F8 &xmue,
+ const F9 &vint, const F10 ¢,
+ const F12 &Tii, const F13 &Tij, const F14 &fvis, const F15 &eta, bool vis,
+ double c_nr, double c_av, bool cartvis_f, bool eeq);
+ }
+ namespace Forgas {
+ template <class F>
+ struct IsSpherical {
+ enum { result = false };
+ };
+ template <template <class> class Mesh, int Dim, class MeshTag, class T, class E>
+ struct IsSpherical<Field<Mesh<MeshTraits<Dim, T, MeshTag, SphericalTag> >, T, E> > {
+ enum { result = true };
+ };
+ template <class F>
+ static bool isSpherical()
+ {
+ return IsSpherical<F>::result;
+ }
+ template <class F>
+ struct IsNotCartesian {
+ enum { result = true };
+ };
+ template <template <class> class Mesh, int Dim, class MeshTag, class T, class E>
+ struct IsNotCartesian<Field<Mesh<MeshTraits<Dim, T, MeshTag, CartesianTag> >, T, E> > {
+ enum { result = false };
+ };
+ template <class F>
+ static bool isNotCartesian()
+ {
+ return IsNotCartesian<F>::result;
+ }
+ template <class CAV>
+ struct ViscTii : public Deltas<3> {
+ ViscTii(const CAV& av) : c_av(av) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<3, 4> &i) const
+ {
+ i.extent(GuardLayers<3>(Loc<3>(0), Loc<3>(1)));
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, false);
+ i.useGuards(3, false);
+ }
+ using Deltas<3>::dX;
+ using Deltas<3>::dY;
+ using Deltas<3>::dZ;
+ template <class F1, class F2, class F3, class F4>
+ inline void operator()(const F1 &T, const F2 &v, const F4 &rh, const F3 &eta,
+ const Loc<3>& I) const
+ {
+ const typename F1::Mesh_t &m = T.mesh();
+ double divu = ((m.SURXA(I+dX)*v.fieldEngine().engine(0, 0).read(I+dX) - m.SURXA(I)*v.fieldEngine().engine(0, 0).read(I))/m.VOLXB(I)
+ + (m.SURYA(I+dY)*v.fieldEngine().engine(0, 1).read(I+dY) - m.SURYA(I)*v.fieldEngine().engine(0, 1).read(I))/m.VOLYB(I)
+ + (m.SURZA(I+dZ)*v.fieldEngine().engine(0, 2).read(I+dZ) - m.SURZA(I)*v.fieldEngine().engine(0, 2).read(I))/m.VOLZB(I));
+ T(I)(0) = 2.0 * eta.read(I) * rh.read(I)
+ * ((v.fieldEngine().engine(0, 0).read(I+dX) - v.fieldEngine().engine(0, 0).read(I))/m.vertexSpacing(I+dX)(0)
+ - 1.0/3.0 * divu)
+ - rh.read(I)*c_av*std::pow(std::min(divu, 0.0)*m.vertexSpacing(I)(0), 2);
+ T(I)(1) = 2.0 * eta.read(I) * rh.read(I)
+ * ((v.fieldEngine().engine(0, 1).read(I+dY) - v.fieldEngine().engine(0, 1).read(I))/m.vertexSpacing(I+dY)(1)
+ + (isSpherical<F1>() ? (v.fieldEngine().engine(0, 0).read(I) + v.fieldEngine().engine(0, 0).read(I+dX))/(2.0*m.cellPosition(I)(0)) : 0.0)
+ - 1.0/3.0 * divu)
+ - rh.read(I)*c_av*std::pow(std::min(divu, 0.0)*m.vertexSpacing(I)(0), 2);
+ T(I)(2) = 2.0 * eta.read(I) * rh.read(I)
+ * ((v.fieldEngine().engine(0, 2).read(I+dZ) - v.fieldEngine().engine(0, 2).read(I))/m.vertexSpacing(I+dZ)(2)
+ + (isNotCartesian<F1>() ? 0.5 * (v.fieldEngine().engine(0, 0).read(I) + v.fieldEngine().engine(0, 0).read(I+dX))/m.cellPosition(I)(0) : 0.0)
+ - (isSpherical<F1>() ? 0.5 * (v.fieldEngine().engine(0, 1).read(I) + v.fieldEngine().engine(0, 1).read(I+dY))/tan(m.cellPosition(I)(1)) : 0.0)
+ - 1.0/3.0 * divu)
+ - rh.read(I)*c_av*std::pow(std::min(divu, 0.0)*m.vertexSpacing(I)(0), 2);
+ }
+ CAV c_av;
+ };
+ struct Txy : public Deltas<3> {
+ Txy() {}
+ inline void scalarCodeInfo(ScalarCodeInfo<3, 2> &i) const
+ {
+ i.extent().lower(0) = 1;
+ i.extent().lower(1) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ }
+ using Deltas<3>::dX;
+ using Deltas<3>::dY;
+ using Deltas<3>::dZ;
+ template <class F1, class F2>
+ inline void operator()(const F1 &T, const F2 &v,
+ const Loc<3>& I) const
+ {
+ const typename F1::Mesh_t &m = T.mesh();
+ T(I) = (v.fieldEngine().engine(0, 1).read(I) - v.fieldEngine().engine(0, 1).read(I-dX)) * m.GEOXGA(I) / m.cellSpacing(I)(0)
+ + (v.fieldEngine().engine(0, 0).read(I) - v.fieldEngine().engine(0, 0).read(I-dY)) / (m.GEOXGA(I) * m.cellSpacing(I)(1));
+ }
+ };
+ struct Txz : public Deltas<3> {
+ Txz() {}
+ inline void scalarCodeInfo(ScalarCodeInfo<3, 2> &i) const
+ {
+ i.extent().lower(0) = 1;
+ i.extent().lower(2) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ }
+ using Deltas<3>::dX;
+ using Deltas<3>::dY;
+ using Deltas<3>::dZ;
+ template <class F1, class F2>
+ inline void operator()(const F1 &T, const F2 &v,
+ const Loc<3>& I) const
+ {
+ const typename F1::Mesh_t &m = T.mesh();
+ T(I) = (v.fieldEngine().engine(0, 2).read(I) - v.fieldEngine().engine(0, 2).read(I-dX)) * m.GEOXH(I) * m.GEOYH(I) / m.cellSpacing(I)(0)
+ + (v.fieldEngine().engine(0, 0).read(I) - v.fieldEngine().engine(0, 0).read(I-dZ)) / (m.GEOXH(I) * m.GEOYH(I) * m.cellSpacing(I)(2));
+ }
+ };
+ struct Tyz : public Deltas<3> {
+ Tyz() {}
+ inline void scalarCodeInfo(ScalarCodeInfo<3, 2> &i) const
+ {
+ i.extent().lower(1) = 1;
+ i.extent().lower(2) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ }
+ using Deltas<3>::dX;
+ using Deltas<3>::dY;
+ using Deltas<3>::dZ;
+ template <class F1, class F2>
+ inline void operator()(const F1 &T, const F2 &v,
+ const Loc<3>& I) const
+ {
+ const typename F1::Mesh_t &m = T.mesh();
+ T(I) = (v.fieldEngine().engine(0, 2).read(I) - v.fieldEngine().engine(0, 2).read(I-dY)) * m.GEOYHA(I) / m.cellSpacing(I)(1)
+ + (v.fieldEngine().engine(0, 1).read(I) - v.fieldEngine().engine(0, 1).read(I-dZ)) / (m.GEOYHA(I) * m.cellSpacing(I)(2));
+ }
+ };
+ struct ViscForceX : public Deltas<3> {
+ ViscForceX() {}
+ inline void scalarCodeInfo(ScalarCodeInfo<3, 3> &i) const
+ {
+ i.extent().lower(0) = 1;
+ i.extent().upper(1) = 1;
+ i.extent().upper(2) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ using Deltas<3>::dX;
+ using Deltas<3>::dY;
+ using Deltas<3>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &f, const F2 &Tii, const F3 &Tij,
+ const Loc<3>& I) const
+ {
+ const typename F1::Mesh_t &m = f.mesh();
+ f(I) = (Tii(I)(0) * m.SURXB(I) - Tii(I-dX)(0) * m.SURXB(I-dX)) / m.VOLXA(I-dX)
+ + (Tij.fieldEngine().engine(0, 0).read(I+dY) * m.SURYA(I+dY) - Tij.fieldEngine().engine(0, 0).read(I) * m.SURYA(I)) / (m.VOLYB(I)*m.GEOXHA(I))
+ + (Tij.fieldEngine().engine(0, 1).read(I+dZ) * m.SURZA(I+dZ) - Tij.fieldEngine().engine(0, 1).read(I) * m.SURZA(I)) / (m.VOLZB(I)*m.GEOXHA(I)*m.GEOYH(I))
+ - (isNotCartesian<F1>() ? ((isSpherical<F1>() ? Tii(I-dX)(1) + Tii(I)(1) : 0.0)
+ + Tii(I-dX)(2) + Tii(I)(2)) / (2.0*m.vertexPosition(I)(0))
+ : 0.0);
+ }
+ };
+ struct ViscForceY : public Deltas<3> {
+ ViscForceY() {}
+ inline void scalarCodeInfo(ScalarCodeInfo<3, 3> &i) const
+ {
+ i.extent().lower(1) = 1;
+ i.extent().upper(0) = 1;
+ i.extent().upper(2) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ using Deltas<3>::dX;
+ using Deltas<3>::dY;
+ using Deltas<3>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &f, const F2 &Tii, const F3 &Tij,
+ const Loc<3>& I) const
+ {
+ const typename F1::Mesh_t &m = f.mesh();
+ f(I) = (Tij.fieldEngine().engine(0, 0).read(I+dX) * m.SURXA(I+dX) - Tij.fieldEngine().engine(0, 0).read(I) * m.SURXA(I)) / m.VOLXB(I)
+ + (Tii(I)(1) * m.SURYB(I) - Tii(I-dY)(1) * m.SURYB(I-dY)) / (m.VOLYA(I-dY)*m.GEOXG(I))
+ + (Tij.fieldEngine().engine(0, 2).read(I+dZ) * m.SURZA(I+dZ) - Tij.fieldEngine().engine(0, 2).read(I) * m.SURZA(I)) / (m.VOLZB(I)*m.GEOXH(I)*m.GEOYHA(I))
+ + (isSpherical<F1>() ? (Tij.fieldEngine().engine(0, 0).read(I) + Tij.fieldEngine().engine(0, 0).read(I+dX)
+ + (Tii(I-dY)(2) + Tii(I)(2)) / tan(m.cellPosition(I)(1))) / (2.0*m.cellPosition(I)(0))
+ : 0.0);
+ }
+ };
+ struct ViscForceZ : public Deltas<3> {
+ ViscForceZ() {}
+ inline void scalarCodeInfo(ScalarCodeInfo<3, 3> &i) const
+ {
+ i.extent().lower(2) = 1;
+ i.extent().upper(0) = 1;
+ i.extent().upper(1) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ }
+ using Deltas<3>::dX;
+ using Deltas<3>::dY;
+ using Deltas<3>::dZ;
+ template <class F1, class F2, class F3>
+ inline void operator()(const F1 &f, const F2 &Tii, const F3 &Tij,
+ const Loc<3>& I) const
+ {
+ const typename F1::Mesh_t &m = f.mesh();
+ f(I) = (Tij.fieldEngine().engine(0, 1).read(I+dX) * m.SURXA(I+dX) - Tij.fieldEngine().engine(0, 1).read(I) * m.SURXA(I)) / m.VOLXB(I)
+ + (Tij.fieldEngine().engine(0, 2).read(I+dY) * m.SURYA(I+dY) - Tij.fieldEngine().engine(0, 2).read(I) * m.SURYA(I)) / (m.VOLYB(I)*m.GEOXG(I))
+ + (Tii(I)(2) * m.SURZB(I) - Tii(I-dZ)(2) * m.SURZB(I-dZ)) / (m.VOLZA(I)*m.GEOXH(I)*m.GEOYH(I))
+ + (isNotCartesian<F1>() ? ((Tij.fieldEngine().engine(0, 1).read(I) + Tij.fieldEngine().engine(0, 1).read(I+dX)
+ - (isSpherical<F1>() ? (Tij.fieldEngine().engine(0, 2).read(I) + Tij.fieldEngine().engine(0, 2).read(I+dY))
+ / tan(m.cellPosition(I)(1))
+ : 0.0))
+ / (2.0*m.cellPosition(I)(0)))
+ : 0.0);
+ }
+ };
+ template <int Dim>
+ struct TGuess : public Deltas<Dim> {
+ TGuess(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 7> &i) const
+ {
+ i.extent(GuardLayers<Dim>(Loc<Dim>(0), Loc<Dim>(1)));
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.write(4, false);
+ i.write(5, false);
+ i.write(6, false);
+ i.useGuards(0, false);
+ i.useGuards(1, false);
+ i.useGuards(2, false);
+ i.useGuards(3, true);
+ i.useGuards(4, false);
+ i.useGuards(5, false);
+ i.useGuards(6, false);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4, class F5, class F6, class F7>
+ inline void operator()(const F1 &pg, const F2 &T, const F3 &rh, const F4 &v,
+ const F5 &cv, const F6 &dlmdlt, const F7 &xmue, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = pg.mesh();
+ double g = (m.SURXA(I+dX)*v.fieldEngine().engine(0, 0).read(I+dX)
+ - m.SURXA(I)*v.fieldEngine().engine(0, 0).read(I)) / m.VOLXB(I);
+ if (Dim > 1)
+ g += (m.SURYA(I+dY)*v.fieldEngine().engine(0, 1).read(I+dY)
+ - m.SURYA(I)*v.fieldEngine().engine(0, 1).read(I)) / m.VOLYB(I);
+ if (Dim > 2)
+ g += (m.SURZA(I+dZ)*v.fieldEngine().engine(0, 2).read(I+dZ)
+ - m.SURZA(I)*v.fieldEngine().engine(0, 2).read(I)) / m.VOLZB(I);
+ double tguess = T(I)
+ - (dt
+ * pg(I) / rh(I) / cv.read(I)
+ * (1.0 - dlmdlt.read(I))
+ * g);
+ pg(I) = tguess * rh(I) / xmue.read(I);
+ }
+ };
+ template <int Dim>
+ struct CentX : public Deltas<Dim> {
+ CentX(double omrot) : omrot_m(omrot) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
+ {
+ i.extent().lower(0) = 1;
+ i.extent().upper(1) = 1;
+ if (Dim > 2)
+ i.extent().upper(2) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.useGuards(0, false);
+ i.useGuards(1, false);
+ i.useGuards(2, true);
+ if (Dim > 2)
+ i.useGuards(3, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <template <class> class Mesh, class MeshTag, class T, class EngineTag,
+ class F2, class F3, class F4>
+ inline void operator()(const Field<Mesh<MeshTraits<Dim, T, MeshTag, CartesianTag> >,
+ T, EngineTag> ¢x,
+ const F4 &vx, const F2 &vy, const F3 &vz,
+ const Loc<Dim>& I) const
+ {
+ const typename MeshTraits<Dim, T, MeshTag, CartesianTag>::Mesh_t &m = centx.mesh();
+ centx(I) = omrot_m*omrot_m*m.vertexPosition(I)(0);
+ }
+ template <template <class> class Mesh, class MeshTag, class T, class EngineTag,
+ class F2, class F3, class F4>
+ inline void operator()(const Field<Mesh<MeshTraits<Dim, T, MeshTag, CylindricalTag> >,
+ T, EngineTag> ¢x,
+ const F4 &vx, const F2 &vy, const F3 &vz,
+ const Loc<Dim>& I) const
+ {
+ const typename MeshTraits<Dim, T, MeshTag, CylindricalTag>::Mesh_t &m = centx.mesh();
+ double hq = 0.5*(m.DDX0(I)*(vz(I-dX) + vz(I-dX+dZ))
+ + m.DDX1(I)*(vz(I) + vz(I+dZ))) + omrot_m;
+ centx(I) = m.vertexPosition(I)(0) * std::pow(hq, 2);
+ }
+ template <template <class> class Mesh, class MeshTag, class T, class EngineTag,
+ class F2, class F3, class F4>
+ inline void operator()(const Field<Mesh<MeshTraits<Dim, T, MeshTag, SphericalTag> >,
+ T, EngineTag> ¢x,
+ const F4 &vx, const F2 &vy, const F3 &vz,
+ const Loc<Dim>& I) const
+ {
+ const typename MeshTraits<Dim, T, MeshTag, SphericalTag>::Mesh_t &m = centx.mesh();
+ double hq = 0.5*(m.DDX0(I)*(vz(I-dX) + vz(I-dX+dZ))
+ + m.DDX1(I)*(vz(I) + vz(I+dZ))) + omrot_m;
+ double gq = 0.5*(m.DDX0(I)*(vy(I-dX+dY) + vy(I-dX))
+ + m.DDX1(I)*(vy(I+dY) + vy(I)));
+ centx(I) = m.vertexPosition(I)(0)
+ * (std::pow(gq, 2) + std::pow(hq*sin(m.cellPosition(I)(1)), 2));
+ }
+ const double omrot_m;
+ };
+ template <int Dim>
+ struct CentY : public Deltas<Dim> {
+ CentY(double omrot) : omrot_m(omrot) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
+ {
+ i.extent().upper(0) = 1;
+ i.extent().lower(1) = 1;
+ if (Dim > 2)
+ i.extent().upper(2) = 1;
+ i.write(0, true, false);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, false);
+ if (Dim > 2)
+ i.useGuards(3, true);
+ }
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <template <class> class Mesh, class MeshTag, class T, class EngineTag,
+ class F2, class F3, class F4>
+ inline void operator()(const Field<Mesh<MeshTraits<Dim, T, MeshTag, CartesianTag> >,
+ T, EngineTag> ¢y,
+ const F4 &vx, const F2 &vy, const F3 &vz,
+ const Loc<Dim>& I) const
+ {
+ const typename MeshTraits<Dim, T, MeshTag, CartesianTag>::Mesh_t &m = centy.mesh();
+ centy(I) = - omrot_m*omrot_m*m.vertexPosition(I)(1);
+ }
+ template <template <class> class Mesh, class MeshTag, class T, class EngineTag,
+ class F2, class F3, class F4>
+ inline void operator()(const Field<Mesh<MeshTraits<Dim, T, MeshTag, CylindricalTag> >,
+ T, EngineTag> ¢y,
+ const F4 &vx, const F2 &vy, const F3 &vz,
+ const Loc<Dim>& I) const
+ {
+ centy(I) = 0.0;
+ }
+ template <template <class> class Mesh, class MeshTag, class T, class EngineTag,
+ class F2, class F3, class F4>
+ inline void operator()(const Field<Mesh<MeshTraits<Dim, T, MeshTag, SphericalTag> >,
+ T, EngineTag> ¢y,
+ const F4 &vx, const F2 &vy, const F3 &vz,
+ const Loc<Dim>& I) const
+ {
+ const typename MeshTraits<Dim, T, MeshTag, SphericalTag>::Mesh_t &m = centy.mesh();
+ double hq = 0.5*(m.DDY0(I)*(vz(I-dY) + vz(I-dY+dZ))
+ + m.DDY1(I)*(vz(I) + vz(I+dZ))) + omrot_m;
+ centy(I) = -cos(m.vertexPosition(I)(1)) * sin(m.vertexPosition(I)(1)) * std::pow(hq, 2)
+ * m.cellPosition(I)(0);
+ }
+ const double omrot_m;
+ };
+ template <int Dim>
+ struct VXUpd : public Deltas<Dim> {
+ VXUpd(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 6> &i) const
+ {
+ i.extent().lower(0) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.write(4, false);
+ i.write(5, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ i.useGuards(3, true);
+ i.useGuards(4, false);
+ i.useGuards(5, false);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4, class F5, class F6>
+ inline void operator()(const F1 &vx, const F2 &rh, const F3 &pg, const F4 &ph,
+ const F5 ¢x, const F6 &fvisx, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vx(I) = vx(I)
+ + dt * ((-(pg.read(I)-pg.read(I-dX)) / m.cellSpacing(I)(0)
+ + fvisx(I))
+ / (m.DDX1(I)*rh(I)+m.DDX0(I)*rh(I-dX))
+ - (ph(I)-ph(I-dX)) / m.cellSpacing(I)(0)
+ + centx(I));
+ }
+ };
+ template <int Dim>
+ struct VYUpd : public Deltas<Dim> {
+ VYUpd(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 6> &i) const
+ {
+ i.extent().lower(1) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.write(4, false);
+ i.write(5, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ i.useGuards(3, true);
+ i.useGuards(4, false);
+ i.useGuards(5, false);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4, class F5, class F6>
+ inline void operator()(const F1 &vy, const F2 &rh, const F3 &pg, const F4 &ph,
+ const F5 ¢y, const F6 &fvisy, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vy(I) = vy(I)
+ + (dt * ((-(pg.read(I)-pg.read(I-dY)) / (m.cellSpacing(I)(1) * m.GEOXG(I))
+ + fvisy(I))
+ / (m.DDY1(I)*rh(I)+m.DDY0(I)*rh(I-dY))
+ -((ph(I)-ph(I-dY))
+ / (m.cellSpacing(I)(1) * m.GEOXG(I)))
+ - centy(I))
+ / m.GEOXG(I));
+ }
+ };
+ template <int Dim>
+ struct VZUpd : public Deltas<Dim> {
+ VZUpd(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 5> &i) const
+ {
+ i.extent().lower(2) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.write(4, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ i.useGuards(2, true);
+ i.useGuards(3, true);
+ i.useGuards(4, true);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4, class F5>
+ inline void operator()(const F1 &vz, const F2 &rh, const F3 &pg, const F4 &ph,
+ const F5 &fvisz, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = rh.mesh();
+ vz(I) = vz(I)
+ + (dt * ((-(pg.read(I)-pg.read(I-dZ)) / (m.cellSpacing(I)(2)*m.GEOXH(I)*m.GEOYH(I))
+ + fvisz(I))
+ / (m.DDZ1(I)*rh(I)+m.DDZ0(I)*rh(I-dZ))
+ -((ph(I)-ph(I-dZ))
+ / (m.cellSpacing(I)(2)*m.GEOXH(I)*m.GEOYH(I)))
+ )
+ / (m.GEOXH(I)*m.GEOYH(I)));
+ }
+ };
+ template <int Dim>
+ struct TUpd : public Deltas<Dim> {
+ TUpd(double dt_) : dt(dt_) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 6> &i) const
+ {
+ i.extent(GuardLayers<Dim>(Loc<Dim>(0), Loc<Dim>(1)));
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.write(4, false);
+ i.write(5, false);
+ i.useGuards(0, false);
+ i.useGuards(1, false);
+ i.useGuards(2, true);
+ i.useGuards(3, false);
+ i.useGuards(4, false);
+ i.useGuards(5, false);
+ }
+ double dt;
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4, class F5, class F6>
+ inline void operator()(const F1 &T, const F2 &rh, const F3 &v, const F4 &pg,
+ const F5 &cv, const F6 &dlmdlt, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = T.mesh();
+ double g = (m.SURXA(I+dX)*v.fieldEngine().engine(0, 0).read(I+dX)
+ - m.SURXA(I)*v.fieldEngine().engine(0, 0).read(I)) / m.VOLXB(I);
+ if (Dim > 1)
+ g += (m.SURYA(I+dY)*v.fieldEngine().engine(0, 1).read(I+dY)
+ - m.SURYA(I)*v.fieldEngine().engine(0, 1).read(I)) / m.VOLYB(I);
+ if (Dim > 2)
+ g += (m.SURZA(I+dZ)*v.fieldEngine().engine(0, 2).read(I+dZ)
+ - m.SURZA(I)*v.fieldEngine().engine(0, 2).read(I)) / m.VOLZB(I);
+ T(I) = T(I)
+ - (dt
+ * pg.read(I) / rh(I) / cv.read(I)
+ * (1.0 - dlmdlt.read(I))
+ * g);
+ }
+ };
+ template <int Dim>
+ struct GradV : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
+ {
+ i.extent(GuardLayers<Dim>(Loc<Dim>(0), Loc<Dim>(1)));
+ i.write(0, true, false);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2>
+ inline void operator()(const F1 &grad_v, const F2 &v, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = grad_v.mesh();
+ grad_v(I)(0) = (m.SURXA(I+dX)*v.fieldEngine().engine(0, 0).read(I+dX)
+ - m.SURXA(I)*v.fieldEngine().engine(0, 0).read(I))/m.VOLXB(I);
+ if (Dim > 1)
+ grad_v(I)(1) = (m.SURYA(I+dY)*v.fieldEngine().engine(0, 1).read(I+dY)
+ - m.SURYA(I)*v.fieldEngine().engine(0, 1).read(I))/m.VOLYB(I);
+ if (Dim > 2)
+ grad_v(I)(2) = (m.SURZA(I+dZ)*v.fieldEngine().engine(0, 2).read(I+dZ)
+ - m.SURZA(I)*v.fieldEngine().engine(0, 2).read(I))/m.VOLZB(I);
+ }
+ };
+ template <int Dim>
+ struct GradVdX : public Deltas<Dim> {
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
+ {
+ i.extent(GuardLayers<Dim>(Loc<Dim>(0), Loc<Dim>(1)));
+ i.write(0, true, false);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2>
+ inline void operator()(const F1 &grad_v, const F2 &v, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = grad_v.mesh();
+ grad_v(I)(0) = (m.SURXA(I+dX)*v.fieldEngine().engine(0, 0).read(I+dX)
+ - m.SURXA(I)*v.fieldEngine().engine(0, 0).read(I));
+ if (Dim > 1)
+ grad_v(I)(1) = (m.SURYA(I+dY)*v.fieldEngine().engine(0, 1).read(I+dY)
+ - m.SURYA(I)*v.fieldEngine().engine(0, 1).read(I));
+ if (Dim > 2)
+ grad_v(I)(2) = (m.SURZA(I+dZ)*v.fieldEngine().engine(0, 2).read(I+dZ)
+ - m.SURZA(I)*v.fieldEngine().engine(0, 2).read(I));
+ }
+ };
+ template <int Dim>
+ struct APressure : public Deltas<Dim> {
+ APressure(double cnr, double cav) : c_nr(cnr), c_av(cav) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 4> &i) const
+ {
+ i.extent(GuardLayers<Dim>(Loc<Dim>(0), Loc<Dim>(1)));
+ i.write(0, true);
+ i.write(1, false);
+ i.write(2, false);
+ i.write(3, false);
+ i.useGuards(0, false);
+ i.useGuards(1, false);
+ i.useGuards(2, true);
+ i.useGuards(3, false);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ using Deltas<Dim>::dZ;
+ template <class F1, class F2, class F3, class F4>
+ inline void operator()(const F1 &pg, const F2 &rh, const F3 &v, const F4 &cs,
+ const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = pg.mesh();
+ double q = (m.SURXA(I+dX)*v.fieldEngine().engine(0, 0).read(I+dX)
+ - m.SURXA(I)*v.fieldEngine().engine(0, 0).read(I))/m.VOLXB(I);
+ if (Dim > 1)
+ q += (m.SURYA(I+dY)*v.fieldEngine().engine(0, 1).read(I+dY)
+ - m.SURYA(I)*v.fieldEngine().engine(0, 1).read(I))/m.VOLYB(I);
+ if (Dim > 2)
+ q += (m.SURZA(I+dZ)*v.fieldEngine().engine(0, 2).read(I+dZ)
+ - m.SURZA(I)*v.fieldEngine().engine(0, 2).read(I))/m.VOLZB(I);
+ if (q >= 0.0)
+ return;
+ q *= m.vertexSpacing(I)(0);
+ pg(I) += c_nr * q * q * rh(I);
+ pg(I) -= c_av * rh(I) * cs(I) * q;
+ }
+ private:
+ const double c_nr, c_av;
+ };
+ template <class CoordinateSystemTag>
+ struct ApplyCoriolis
+ {
+ template <class F1, class F2>
+ static void applyCoriolis(const F1&, const F2&, double) {}
+ };
+ template <int Dim>
+ struct CoriolisX : public Deltas<Dim> {
+ CoriolisX(double dphi) : sin2o_m(sin(2*dphi)), cos2o_m(cos(2*dphi)) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
+ {
+ i.extent().lower(0) = 1;
+ i.extent().upper(1) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ template <class F1, class F2>
+ inline void operator()(const F1 &vx, const F2 &v, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = v.mesh();
+ double vyx = 0.5*(m.DDX0(I)*(v.fieldEngine().engine(0, 1).read(I-dX)
+ + v.fieldEngine().engine(0, 1).read(I-dX+dY))
+ + m.DDX1(I)*(v.fieldEngine().engine(0, 1).read(I)
+ + v.fieldEngine().engine(0, 1).read(I+dY)));
+ vx(I) = v.fieldEngine().engine(0, 0).read(I)*cos2o_m + vyx*sin2o_m;
+ }
+ private:
+ const double sin2o_m, cos2o_m;
+ };
+ template <int Dim>
+ struct CoriolisY : public Deltas<Dim> {
+ CoriolisY(double dphi) : sin2o_m(sin(2*dphi)), cos2o_m(cos(2*dphi)) {}
+ inline void scalarCodeInfo(ScalarCodeInfo<Dim, 2> &i) const
+ {
+ i.extent().lower(1) = 1;
+ i.extent().upper(0) = 1;
+ i.write(0, true);
+ i.write(1, false);
+ i.useGuards(0, false);
+ i.useGuards(1, true);
+ }
+ using Deltas<Dim>::dX;
+ using Deltas<Dim>::dY;
+ template <class F1, class F2>
+ inline void operator()(const F1 &vy, const F2 &v, const Loc<Dim>& I) const
+ {
+ const typename F1::Mesh_t &m = v.mesh();
+ double vxy = 0.5*(m.DDY1(I)*(v.fieldEngine().engine(0, 0).read(I)
+ + v.fieldEngine().engine(0, 0).read(I+dX))
+ + m.DDY0(I)*(v.fieldEngine().engine(0, 0).read(I-dY)
+ + v.fieldEngine().engine(0, 0).read(I-dY+dX)));
+ vy(I) = -vxy*sin2o_m + v.fieldEngine().engine(0, 1).read(I)*cos2o_m;
+ }
+ private:
+ const double sin2o_m, cos2o_m;
+ };
+ template <>
+ struct ApplyCoriolis<CartesianTag>
+ {
+ template <class F1, class F2>
+ static void applyCoriolis(const F1& v, const F2& scratchv, double dphi)
+ {
+ (ScalarCode<CoriolisX<Dim> >(dphi))(scratchv.center(0), v);
+ (ScalarCode<CoriolisY<Dim> >(dphi))(scratchv.center(1), v);
+ v.center(0) = scratchv.center(0);
+ v.center(1) = scratchv.center(1);
+ }
+ };
+ template <class F1, class F2>
+ void applyCoriolis(const F1& v, const F2& scratchv, double omrot, double dt)
+ {
+ ApplyCoriolis<typename F1::Mesh_t::MeshTraits_t::CoordinateSystemTag_t>
+ ::applyCoriolis(v, scratchv, omrot*dt);
+ }
+ template <class Tag, class T>
+ struct FnSave
+ {
+ inline T
+ operator()(const T &a) const
+ {
+ val = a;
+ return a;
+ }
+ static T val;
+ };
+ template <class Tag, class T>
+ T FnSave<Tag, T>::val;
+ template<class Tag, int D1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnSave<Tag, T1>,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> >::Expression_t
+ save(const Array<D1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnSave<Tag, T1>,
+ typename CreateLeaf<Array<D1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Array<D1,T1,E1> >::make(l)));
+ }
+ template<class Tag, class M1,class T1,class E1>
+ inline typename MakeReturn<UnaryNode<FnSave<Tag, T1>,
+ typename CreateLeaf<Field<M1,T1,E1> >::Leaf_t> >::Expression_t
+ save(const Field<M1,T1,E1> & l)
+ {
+ typedef UnaryNode<FnSave<Tag, T1>,
+ typename CreateLeaf<Field<M1,T1,E1> >::Leaf_t> Tree_t;
+ return MakeReturn<Tree_t>::make(Tree_t(
+ CreateLeaf<Field<M1,T1,E1> >::make(l)));
+ }
+ template <class Tag, class T>
+ struct SaveRef
+ {
+ SaveRef() {}
+ inline
+ operator T() const
+ {
+ return FnSave<Tag, T>::val;
+ }
+ };
+ template<class Tag, class T>
+ inline Expression<Scalar<SaveRef<Tag, T> > >
+ ref()
+ {
+ return Expression<Scalar<SaveRef<Tag, T> > >(SaveRef<Tag, T>());
+ }
+ struct DivV {};
+ template <class F1, class F2, class F3, class F4, class F5,
+ class F6, class F7, class F8, class F9, class F10,
+ class F11, class F12, class F13,
+ class F14, class F15, class F16, class F17>
+ void force(double dt, const F1 &rh, F2 &T, F3 &v, double omrot, F4 &pg, const F5 &ph,
+ const F11& cs, const F6 &cv, const F7 &dlmdlt, const F8 &xmue,
+ const F9 &vint, F10 ¢, const F12 &a_pg, const F13 &gradv,
+ const F14 &Tii, const F15 &Tij, const F16 &fvis, const F17 &eta, bool vis,
+ double c_nr, bool cartvis_f, bool eeq)
+ {
+ enum { Dim = F1::dimensions };
+ if (Dim == 3) {
+ (ScalarCode<CentX<Dim> >(omrot))(cent.center(0), shrink(cent.center(0).physicalDomain(), corr_v[0]),
+ v.center(0), v.center(1), v.center(2));
+ (ScalarCode<CentY<Dim> >(omrot))(cent.center(1), shrink(cent.center(1).physicalDomain(), corr_v[1]),
+ v.center(0), v.center(1), v.center(2));
+ } else if (Dim == 2) {
+ (ScalarCode<CentX<Dim> >(omrot))(cent.center(0), shrink(cent.center(0).physicalDomain(), corr_v[0]),
+ v.center(0), v.center(1), v.center(0));
+ (ScalarCode<CentY<Dim> >(omrot))(cent.center(1), shrink(cent.center(1).physicalDomain(), corr_v[1]),
+ v.center(0), v.center(1), v.center(0));
+ }
+ if ((cartvis_f && !vis) || eeq) {
+ Interval<Dim> I(grow(a_pg.physicalDomain(), GuardLayers<Dim>(1)));
+ ScalarCode<GradV<Dim> >()(gradv, I, v);
+ }
+ if (cartvis_f && !vis) {
+ Interval<Dim> I(grow(a_pg.physicalDomain(), GuardLayers<Dim>(1)));
+ a_pg(I) = where(save<DivV>(dot(gradv, Vector<Dim>(1))(I)) < 0.0,
+ (c_nr * rh * pow2(Pooma::spacings(rh).comp(0)) * ref<DivV, double>())(I),
+ 0.0);
+ }
+ if (eeq) {
+ Interval<Dim> I(grow(a_pg.physicalDomain(), GuardLayers<Dim>(1)));
+ pg(I) = (T(I) - (0.5*dt * pg(I)
+ / rh(I) / cv.read(I)
+ * (1.0 - dlmdlt.read(I)) * dot(gradv(I), Vector<Dim>(1)))) * rh(I) / xmue.read(I);
+ pg.clearDirty();
+ }
+ if (eeq) {
+ vint.all() = v.all();
+ }
+ fvis.all() = 0.0;
+ if (cartvis_f && !vis) {
+ (ScalarCode<VXUpd<Dim> >(dt))(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]),
+ rh,
+ pg + a_pg * min(gradv.comp(0), 0.0),
+ ph, cent.center(0), fvis.center(0));
+ if (Dim > 1)
+ (ScalarCode<VYUpd<Dim> >(dt))(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]),
+ rh,
+ pg + a_pg * min(gradv.comp(1), 0.0),
+ ph, cent.center(1), fvis.center(1));
+ if (Dim > 2)
+ (ScalarCode<VZUpd<Dim> >(dt))(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]),
+ rh,
+ pg + a_pg * min(gradv.comp(2), 0.0),
+ ph, fvis.center(2));
+ } else {
+ (ScalarCode<VXUpd<Dim> >(dt))(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]),
+ rh, pg, ph, cent.center(0), fvis.center(0));
+ if (Dim > 1)
+ (ScalarCode<VYUpd<Dim> >(dt))(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]),
+ rh, pg, ph, cent.center(1), fvis.center(1));
+ if (Dim > 2)
+ (ScalarCode<VZUpd<Dim> >(dt))(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]),
+ rh, pg, ph, fvis.center(2));
+ }
+ if (omrot != 0.0)
+ applyCoriolis(v, cent, omrot, dt);
+ if (eeq) {
+ for (int i=0; i<Dim; ++i)
+ vint.center(i).all() = 0.5*(vint.center(i).all() + v.center(i).all());
+ if (cartvis_f && !vis)
+ (ScalarCode<TUpd<Dim> >(dt))(T, T.physicalDomain(), rh, vint,
+ pg + a_pg * dot(gradv, Vector<Dim>(1)), cv, dlmdlt);
+ else
+ (ScalarCode<TUpd<Dim> >(dt))(T, T.physicalDomain(), rh, vint, pg, cv, dlmdlt);
+ }
+ }
+ template <class F1, class F2, class F3, class F4, class F5,
+ class F6, class F7, class F8, class F9, class F10, class F11,
+ class F12, class F13, class F14, class F15>
+ void force(double dt, const F1 &rh, const F2 &T, const F3 &v, double omrot, F4 &pg, const F5 &ph,
+ const F11 &cs, const F6 &cv, const F7 &dlmdlt, const F8 &xmue,
+ const F9 &vint, const F10 ¢,
+ const F12 &Tii, const F13 &Tij, const F14 &fvis, const F15 &eta, bool vis,
+ double c_nr, double c_av, bool cartvis_f, bool eeq)
+ {
+ enum { Dim = F1::dimensions };
+ if (Dim == 3) {
+ (ScalarCode<CentX<Dim> >(omrot))(cent.center(0), shrink(cent.center(0).physicalDomain(), corr_v[0]),
+ v.center(0), v.center(1), v.center(2));
+ (ScalarCode<CentY<Dim> >(omrot))(cent.center(1), shrink(cent.center(1).physicalDomain(), corr_v[1]),
+ v.center(0), v.center(1), v.center(2));
+ } else if (Dim == 2) {
+ (ScalarCode<CentX<Dim> >(omrot))(cent.center(0), shrink(cent.center(0).physicalDomain(), corr_v[0]),
+ v.center(0), v.center(1), v.center(0));
+ (ScalarCode<CentY<Dim> >(omrot))(cent.center(1), shrink(cent.center(1).physicalDomain(), corr_v[1]),
+ v.center(0), v.center(1), v.center(0));
+ }
+ if (eeq) {
+ (ScalarCode<TGuess<Dim> >(0.5*dt))(pg, pg.physicalDomain(),
+ T, rh, v, cv, dlmdlt, xmue);
+ pg.clearDirty();
+ vint.all() = v.all();
+ }
+ if (cartvis_f && !vis) {
+ (ScalarCode<APressure<Dim> >(APressure<Dim>(c_nr, c_av)))(pg, pg.physicalDomain(), rh, v, cs);
+ pg.clearDirty();
+ }
+ fvis.all() = 0.0;
+ (ScalarCode<VXUpd<Dim> >(dt))(v.center(0), shrink(v.center(0).physicalDomain(), corr_v[0]),
+ rh, pg, ph, cent.center(0), fvis.center(0));
+ if (Dim > 1)
+ (ScalarCode<VYUpd<Dim> >(dt))(v.center(1), shrink(v.center(1).physicalDomain(), corr_v[1]),
+ rh, pg, ph, cent.center(1), fvis.center(1));
+ if (Dim > 2)
+ (ScalarCode<VZUpd<Dim> >(dt))(v.center(2), shrink(v.center(2).physicalDomain(), corr_v[2]),
+ rh, pg, ph, fvis.center(2));
+ if (omrot != 0.0)
+ applyCoriolis(v, cent, omrot, dt);
+ if (eeq) {
+ for (int i=0; i<Dim; ++i)
+ vint.center(i).all() = 0.5*(vint.center(i).all() + v.center(i).all());
+ (ScalarCode<TUpd<Dim> >(dt))(T, T.physicalDomain(), rh, vint, pg, cv, dlmdlt);
+ }
+ }
+ };
+ Loc<Dim> vdom(64, 64, 64);
+ void usage(int ret)
+ {
+ std::cerr
+ << "Usage: tramp3d-v4\n"
+ << " --help|-h|-? show this command line help\n"
+ << " --num-iter|-n number of iterations to perform [Inf]\n"
+ << " --end-t|-t time to stop simulation [Inf]\n"
+ << " --cfl cfl number [0.6]\n"
+ << " --dt constant timestep, used with cfl number [off]\n"
+ << " --min-dt minimum timestep allowed\n"
+ << " --max-dt maximum timestep allowed\n"
+ << " --blocks nx ny nz processor setup [automatic]\n"
+ << " --cartvis nr av artificial viscosity NR AV [off]\n"
+ << " --eos n choose eos\n"
+ << " --rhomin rho density floor [off]\n"
+ << " --blocking-expressions set blocking expressions [off]\n"
+ << " --domain x y z computational vertex domain [64x64x64]\n\n"
+ << "A particularly benchmarky and checky command-line includes\n"
+ << "both artificial viscosity and density minimum via f.i.\n"
+ << " ./tramp3d-v4 --cartvis 1.0 0.0 --rhomin 1e-8\n"
+ << std::flush;
+ Pooma::finalize();
+ exit(ret);
+ }
+ void handle_cmd_args(int argc, char** argv)
+ {
+ int i = 1;
+ while (i < argc) {
+ if (strcmp(argv[i], "--help") == 0
+ || strcmp(argv[i], "-h") == 0
+ || strcmp(argv[i], "-?") == 0) {
+ usage(0);
+ } else if (argc > i+1
+ && (strcmp(argv[i], "--num-iter") == 0
+ || strcmp(argv[i], "-n") == 0)) {
+ a_nr_f = true;
+ a_nr = atoi(argv[i+1]);
+ i += 1;
+ } else if (argc > i+1
+ && (strcmp(argv[i], "--end-t") == 0
+ || strcmp(argv[i], "-t") == 0)) {
+ a_end_t_f = true;
+ a_end_t = atof(argv[i+1]);
+ i += 1;
+ } else if (argc > i+Dim
+ && strcmp(argv[i], "--blocks") == 0) {
+ a_blocks_f = true;
+ a_blocks[0] = Loc<1>(atoi(argv[i+1]));
+ if (Dim > 1)
+ a_blocks[1] = Loc<1>(atoi(argv[i+2]));
+ if (Dim > 2)
+ a_blocks[2] = Loc<1>(atoi(argv[i+3]));
+ i += 3;
+ } else if (argc > i+Dim
+ && strcmp(argv[i], "--domain") == 0) {
+ vdom[0] = Loc<1>(atoi(argv[i+1]));
+ if (Dim > 1)
+ vdom[1] = Loc<1>(atoi(argv[i+2]));
+ if (Dim > 2)
+ vdom[2] = Loc<1>(atoi(argv[i+3]));
+ i += 3;
+ } else if (argc > i+1
+ && strcmp(argv[i], "--cfl") == 0) {
+ a_cfl_f = true;
+ a_cfl = atof(argv[i+1]);
+ i += 1;
+ } else if (argc > i+1
+ && strcmp(argv[i], "--dt") == 0) {
+ a_constant_timestep_f = true;
+ dt = atof(argv[i+1]);
+ i += 1;
+ } else if (argc > i+1
+ && strcmp(argv[i], "--min-dt") == 0) {
+ a_min_dt_f = true;
+ a_min_dt = atof(argv[i+1]);
+ i += 1;
+ } else if (argc > i+1
+ && strcmp(argv[i], "--max-dt") == 0) {
+ a_max_dt_f = true;
+ a_max_dt = atof(argv[i+1]);
+ i += 1;
+ } else if (argc > i+2
+ && strcmp(argv[i], "--cartvis") == 0) {
+ a_cartvis_f = true;
+ cartvis_nr = atof(argv[i+1]);
+ cartvis_av = atof(argv[i+2]);
+ i += 2;
+ } else if (argc > i+1
+ && strcmp(argv[i], "--rhomin") == 0) {
+ a_rhomin_f = true;
+ a_rhomin = atof(argv[i+1]);
+ i += 1;
+ } else if (strcmp(argv[i], "--blocking-expressions") == 0) {
+ Pooma::blockingExpressions(true);
+ } else {
+ std::cerr << "Unknown option " << argv[i] << ".\n\n";
+ usage(1);
+ }
+ ++i;
+ }
+ commandline.append(argv[0]);
+ for (int i=1; i<argc; ++i) {
+ commandline.append(" ");
+ commandline.append(argv[i]);
+ }
+ }
+ static void initSpacings(Array<1, double, Brick> s[Dim], const Interval<Dim>& dom)
+ {
+ for (int i=0; i<Dim; ++i)
+ s[i].engine() = Engine<1, double, Brick>(grow(dom[i], 2));
+ }
+ static void initSpacings(Vector<Dim>& s, const Interval<Dim>&)
+ {
+ }
+ int main(int argc, char** argv)
+ {
+ Pooma::initialize(argc,argv);
+ Pooma::blockingExpressions(false);
+ Inform out;
+ if (argc == 1)
+ usage(1);
+ handle_cmd_args(argc, argv);
+ origin = Vector<Dim>(-1.0);
+ for (int i=0; i<Dim; ++i) {
+ vertexDomain[i] = Interval<1>(vdom[i].min());
+ spacings(i) = 2.0/(vertexDomain[i].size()-1);
+ }
+ periodicity = Vector<Dim, int>(1);
+ if (a_blocks[0].min() == 0)
+ a_blocks = makeRBlocks(vertexDomain, Pooma::contexts());
+ Grid<Dim> grid = makeRGrid(vertexDomain, a_blocks);
+ for (int i=0; i<Dim; ++i) {
+ corr_v[i] = GuardLayers<Dim>(0);
+ corr_v[i].lower(i) = 1;
+ corr_v[i].upper(i) = 1;
+ }
+ Traits_t::Layout_t layout;
+ Traits_t::createLayout(layout, grid, vertexDomain,
+ GuardLayers<Dim>(2),
+ GuardLayers<Dim>(2));
+ Traits_t::Mesh_t mesh(layout, origin, spacings);
+ Traits_t::Layout_t layout1;
+ Traits_t::createLayout(layout1, grid, vertexDomain,
+ GuardLayers<Dim>(1),
+ GuardLayers<Dim>(1));
+ Traits_t::Mesh_t mesh1(layout1, origin, spacings);
+ Traits_t::Layout_t layout0;
+ Traits_t::createLayout(layout0, grid, vertexDomain,
+ GuardLayers<Dim>(0),
+ GuardLayers<Dim>(0));
+ Traits_t::Mesh_t mesh0(layout0, origin, spacings);
+ Traits_t::Centering_t cell = canonicalCentering<Traits_t::Dim>(CellType, Continuous);
+ Traits_t::Centering_t face = canonicalCentering<Traits_t::Dim>(FaceType, Continuous);
+ Traits_t::Centering_t edge = canonicalCentering<Traits_t::Dim>(EdgeType, Continuous);
+ Traits_t::Centering_t vertex = canonicalCentering<Traits_t::Dim>(VertexType, Continuous);
+ Traits_t::Scalar_t rh(cell, layout, mesh);
+ Traits_t::Scalar_t v(face, layout, mesh);
+ Traits_t::Scalar_t T;
+ Traits_t::Scalar_t pg(cell, layout, mesh);
+ Traits_t::Scalar_t ph(cell, layout, mesh);
+ Traits_t::Scalar_t cs(cell, layout, mesh);
+ rh.all() = std::numeric_limits<double>::signaling_NaN();
+ for (int i=0; i<Dim; ++i)
+ v.center(i).all() = std::numeric_limits<double>::signaling_NaN();
+ pg.all() = std::numeric_limits<double>::signaling_NaN();
+ ph.all() = std::numeric_limits<double>::signaling_NaN();
+ cs.all() = std::numeric_limits<double>::signaling_NaN();
+ double t;
+ Traits_t::Scalar_t scratchv(vertex, layout, mesh);
+ Traits_t::Scalar_t scratchc(cell, layout, mesh);
+ Traits_t::Vector_t scratchc_v(cell, layout, mesh);
+ Traits_t::Vector_t scratchc_v2;
+ Traits_t::Scalar_t flm(face, layout1, mesh1);
+ Traits_t::Scalar_t fle;
+ Traits_t::Vector_t flvv(vertex, layout0, mesh0);
+ Traits_t::Scalar_t flvc(cell, layout0, mesh0);
+ Traits_t::Scalar_t Tij;
+ scratchv.all() = std::numeric_limits<double>::signaling_NaN();
+ scratchc.all() = std::numeric_limits<double>::signaling_NaN();
+ scratchc_v.all() = Vector<Dim>(std::numeric_limits<double>::signaling_NaN());
+ for (int i=0; i<Dim; ++i)
+ flm.center(i).all() = std::numeric_limits<double>::signaling_NaN();
+ flvc.all() = std::numeric_limits<double>::signaling_NaN();
+ flvv.all() = Vector<Dim>(std::numeric_limits<double>::signaling_NaN());
+ Field<Traits_t::Mesh_t, double, ConstantFunction> cv(cell, layout, mesh);
+ Field<Traits_t::Mesh_t, Zero<double>, ConstantFunction> dlmdlt(cell, layout, mesh);
+ Field<Traits_t::Mesh_t, double, ConstantFunction> xmue(cell, layout, mesh);
+ Field<Traits_t::Mesh_t, double, ConstantFunction> nue(cell, layout, mesh);
+ int it;
+ it = 0;
+ it++;
+ t = 0.0;
+ T.initialize(cell, layout, mesh);
+ bool eeq = true;
+ if (eeq) {
+ fle.initialize(face, layout0, mesh0);
+ for (int i=0; i<Dim; ++i)
+ fle.center(i).all() = std::numeric_limits<double>::signaling_NaN();
+ }
+ bool ietot = true;
+ gamma_ = 1.33;
+ K = 4.0*3.14159265358979323846/(1.0/(gamma_-1.0)+1.0);
+ if (! a_cartvis_f) {
+ cartvis_nr = 0.0;
+ cartvis_av = 0.0;
+ }
+ xmue.engine().setConstant(2.3);
+ cv.engine().setConstant(1.0/(xmue.engine().constant()*(gamma_-1.0)));
+ nue.engine().setConstant(0.0);
+ {
+ Interval<Dim> I(rh.physicalDomain());
+ rh(I) = 0.1;
+ v.all() = 0.0;
+ T(I) = 99.0/exp(100.0*pow(norm(positions(T)(I)-Vector<Dim>(0.25)), 2.0))+1.0;
+ Pooma::addAllPeriodicFaceBC(rh);
+ Pooma::addAllPeriodicFaceBC(T);
+ Pooma::addAllPeriodicFaceBC(v);
+ }
+ Traits_t::Scalar_t vint(v);
+ vint.makeOwnCopy();
+ vint.all() = std::numeric_limits<double>::signaling_NaN();
+ Traits_t::Scalar_t cent(face, layout0, mesh0);
+ cent.all() = 0.0;
+ ph.initialize(rh);
+ ph.makeOwnCopy();
+ ph.all() = 0.0;
+ eos = EOS::IdealAdiabatic;
+ double rh0 = sum(rh);
+ double T0 = sum(rh*T);
+ out << "Using\n"
+ << " using " << a_blocks << " block setup for computation on domain " << vertexDomain << "\n"
+ << " " << (eeq ? "" : "not ") << "solving eeq\n";
+ if (a_constant_timestep_f)
+ out << " time increments fixed at " << dt << ", cfl " << a_cfl << "\n";
+ else
+ out << " time increments from [" << a_min_dt << ", " << a_max_dt << "], cfl " << a_cfl << "\n";
+ out << " starting at t = " << t << ", i = " << it << "\n"
+ << " cell physical/total domain " << rh.physicalDomain() << ", " << rh.totalDomain() << "\n"
+ << " face physical/total domain " << v.physicalDomain() << ", " << v.totalDomain() << "\n";
+ if (periodicity(0)
+ || (Dim > 1 && periodicity(1))
+ || (Dim > 2 && periodicity(2))) {
+ out << " periodic boundaries in";
+ if (periodicity(0))
+ out << " X";
+ if (Dim > 1 && periodicity(1))
+ out << " Y";
+ if (Dim > 2 && periodicity(2))
+ out << " Z";
+ out << "\n";
+ }
+ out << std::flush;
+ struct timeval end_time, start_time;
+ gettimeofday(&start_time, NULL);
+ if (a_rhomin_f)
+ Pooma::newRelation(Hacks::limit_rh(a_rhomin), rh);
+ switch (eos) {
+ case EOS::IdealAdiabatic:
+ Pooma::newRelation(EOS::pg_ig(), pg, T, rh, xmue);
+ Pooma::newRelation(EOS::cs_adiabatic(gamma_), cs, pg, rh);
+ break;
+ }
+ double iteration_time = 0.0;
+ for (; it<=a_nr && t<=a_end_t; it++) {
+ if (!a_constant_timestep_f) {
+ double dt_ = CFL::schritt<Dim>(v, cs, nue,
+ scratchc,
+ 0.0, false);
+ if (dt_ <= 0.0 || std::isnan(dt_) || std::isinf(dt_)) {
+ out << "dt is " << dt_ << std::endl;
+ Pooma::pAbort("Blowup.");
+ }
+ dt = std::min(a_max_dt, std::max(a_min_dt, a_cfl*dt_));
+ }
+ t += dt;
+ gettimeofday(&end_time, NULL);
+ out << "i = " << it << "\t t = " << t << "\t dt = " << dt
+ << " (" << end_time.tv_sec + end_time.tv_usec/1000000.0 - start_time.tv_sec - start_time.tv_usec/1000000.0 << "s/it)" << std::endl;
+ iteration_time += end_time.tv_sec + end_time.tv_usec/1000000.0 - start_time.tv_sec - start_time.tv_usec/1000000.0;
+ start_time = end_time;
+ Adv5::advect(dt, rh, v, 0.0, T, flm, fle, flvv, flvc, cv, scratchc, eeq, ietot);
+ Forgas::force(dt,
+ rh, T, v, 0.0, pg, ph,
+ cs, cv, dlmdlt, xmue, vint, cent,
+ scratchc_v , Tij, flm , nue*rh, false,
+ cartvis_nr, cartvis_av, a_cartvis_f,
+ eeq);
+ Hacks::checkRegularity(rh);
+ Hacks::checkRegularity(v.center(0));
+ if (Dim > 1)
+ Hacks::checkRegularity(v.center(1));
+ if (Dim > 2)
+ Hacks::checkRegularity(v.center(2));
+ }
+ out << "Time spent in iteration: " << iteration_time << std::endl;
+ out << "Correctness:"
+ << "\n\tsum(rh) difference = " << sum(rh)-rh0
+ << "\n\tsum(vx) = " << sum(v.center(0))
+ << "\n\tsum(vy) = " << sum(v.center(1))
+ << "\n\tsum(vz) = " << sum(v.center(2))
+ << "\n\tsum(rh*T) difference = " << sum(rh*T)-T0 << std::endl;
+ Pooma::finalize();
+ return 0;
+ }
More information about the llvm-commits
mailing list