00001
00025 #ifndef AVI_ABSTRACT_MAIN_H_
00026 #define AVI_ABSTRACT_MAIN_H_
00027
00028 #include <vector>
00029 #include <string>
00030 #include <exception>
00031 #include <iostream>
00032 #include <sstream>
00033 #include <vector>
00034 #include <string>
00035 #include <queue>
00036
00037 #include <cassert>
00038 #include <cstdlib>
00039 #include <cstdio>
00040
00041
00042 #include "AVI.h"
00043 #include "MeshInit.h"
00044 #include "GlobalVec.h"
00045 #include "LocalVec.h"
00046
00047
00048
00049 #include "Galois/Statistic.h"
00050 #include "Galois/Graphs/Graph.h"
00051 #include "Galois/Galois.h"
00052
00053 #include "Lonestar/Banner.h"
00054 #include "Lonestar/CommandLine.h"
00055
00056 static const char* fileNameOpt = "-f";
00057 static const char* spDimOpt = "-d";
00058 static const char* ndivOpt = "-n";
00059 static const char* simEndTimeOpt = "-e";
00060
00061
00062 static const char* name = "Asynchronous Variational Integrators";
00063 static const char* description = "Elasto-dynamic simulation of a mesh with minimal number of simulation updates";
00064 static const char* url = "asynchronous_variational_integrators";
00065
00069 class AVIabstractMain {
00070 private:
00071
00072 struct InputConfig {
00073
00074 std::string fileName;
00075 int spDim;
00076 int ndiv;
00077 double simEndTime;
00078 std::string verifile;
00079
00080 InputConfig (const std::string& fileName, int spDim, int ndiv, double simEndTime, const std::string& verifile)
00081 :fileName (fileName), spDim (spDim), ndiv (ndiv), simEndTime (simEndTime), verifile (verifile) {
00082 }
00083 };
00084
00085 private:
00086 static const std::string getUsage ();
00087
00088 static void printUsage ();
00089
00090 static InputConfig readCmdLine (std::vector<const char*> args);
00091
00092 static MeshInit* initMesh (const InputConfig& input);
00093
00094 static void initGlobalVec (const MeshInit& meshInit, GlobalVec& g);
00095
00096 protected:
00097
00098
00100 virtual const std::string getVersion () const = 0;
00101
00109 virtual void initRemaining (const MeshInit& meshInit, const GlobalVec& g) = 0;
00110
00111
00112 public:
00113
00120 virtual void runLoop (MeshInit& meshInit, GlobalVec& g, bool createSyncFiles) = 0;
00121
00127 void run (int argc, const char* argv[]);
00128
00129 void verify (const InputConfig& input, const MeshInit& meshInit, const GlobalVec& g) const;
00130
00141 inline static void simulate (AVI* avi, MeshInit& meshInit,
00142 GlobalVec& g, LocalVec& l, bool createSyncFiles);
00143 };
00144
00148 class AVIorderedSerial: public AVIabstractMain {
00149
00150 protected:
00151 virtual const std::string getVersion () const {
00152 return std::string ("Serial");
00153 }
00154
00155 virtual void initRemaining (const MeshInit& meshInit, const GlobalVec& g) {
00156
00157 }
00158
00159 public:
00160
00161 virtual void runLoop (MeshInit& meshInit, GlobalVec& g, bool createSyncFiles);
00162 };
00163
00164 const std::string AVIabstractMain::getUsage () {
00165 std::stringstream ss;
00166 ss << fileNameOpt << " fileName.neu " << spDimOpt << " spDim " << ndivOpt << " ndiv "
00167 << simEndTimeOpt << " simEndTime" << std::endl;
00168 return ss.str ();
00169
00170 }
00171
00172 void AVIabstractMain::printUsage () {
00173 fprintf (stderr, "%s\n", getUsage ().c_str ());
00174 abort ();
00175 }
00176
00177 AVIabstractMain::InputConfig AVIabstractMain::readCmdLine (std::vector<const char*> args) {
00178 const char* fileName = NULL;
00179 int spDim = 2;
00180 int ndiv = 0;
00181 double simEndTime = 1.0;
00182
00183 if (args.size() == 0) {
00184 printUsage ();
00185 }
00186
00187 for (std::vector<const char*>::const_iterator i = args.begin (), e = args.end (); i != e; ++i) {
00188
00189 if (std::string (*i) == fileNameOpt) {
00190 ++i;
00191 fileName = *i;
00192
00193 } else if (std::string (*i) == spDimOpt) {
00194 ++i;
00195 spDim = atoi (*i);
00196
00197 } else if (std::string (*i) == ndivOpt) {
00198 ++i;
00199 ndiv = atoi (*i);
00200
00201 } else if (std::string (*i) == simEndTimeOpt) {
00202 ++i;
00203 simEndTime = atof (*i);
00204 } else {
00205 fprintf (stderr, "Unkown option: %s\n Exiting ...\n", *i);
00206 printUsage ();
00207 }
00208 }
00209
00210
00211
00212 return InputConfig (fileName, spDim, ndiv, simEndTime, "");
00213 }
00214
00215 MeshInit* AVIabstractMain::initMesh (const AVIabstractMain::InputConfig& input) {
00216 MeshInit* meshInit = NULL;
00217
00218 if (input.spDim == 2) {
00219 meshInit = new TriMeshInit (input.simEndTime);
00220 }
00221 else if (input.spDim == 3) {
00222 meshInit = new TetMeshInit (input.simEndTime);
00223 }
00224 else {
00225 printUsage ();
00226 }
00227
00228
00229 meshInit->initializeMesh (input.fileName, input.ndiv);
00230
00231 return meshInit;
00232 }
00233
00234 void AVIabstractMain::initGlobalVec (const MeshInit& meshInit, GlobalVec& g) {
00235 if (meshInit.isWave ()) {
00236 meshInit.setupVelocities (g.vecV);
00237 meshInit.setupVelocities (g.vecV_b);
00238 }
00239 else {
00240 meshInit.setupDisplacements (g.vecQ);
00241 }
00242 }
00243
00244 void AVIabstractMain::run (int argc, const char* argv[]) {
00245
00246 std::vector<const char*> args = parse_command_line (argc, argv, getUsage ().c_str ());
00247
00248 printBanner(std::cout, name, description, url);
00249
00250
00251 InputConfig input = readCmdLine (args);
00252
00253 MeshInit* meshInit = initMesh (input);
00254
00255 GlobalVec g(meshInit->getTotalNumDof ());
00256
00257 const std::vector<AVI*>& aviList = meshInit->getAVIVec ();
00258 for (size_t i = 0; i < aviList.size (); ++i) {
00259 assert (aviList[i]->getOperation ().getFields ().size () == meshInit->getSpatialDim());
00260 }
00261
00262
00263 initGlobalVec (*meshInit, g);
00264
00265
00266
00267 initRemaining (*meshInit, g);
00268
00269
00270
00271 printf ("PAVI %s version\n", getVersion ().c_str ());
00272 printf ("input mesh: %d elements, %d nodes\n", meshInit->getNumElements (), meshInit->getNumNodes ());
00273
00274
00275 Galois::StatTimer t;
00276 t.start ();
00277
00278
00279 runLoop (*meshInit, g, false);
00280
00281 t.stop ();
00282
00283 if (!skipVerify) {
00284 verify (input, *meshInit, g);
00285 }
00286
00287 delete meshInit;
00288
00289 }
00290
00291
00292 void AVIabstractMain::verify (const InputConfig& input, const MeshInit& meshInit, const GlobalVec& g) const {
00293
00294 if (input.verifile == ("")) {
00295 AVIorderedSerial* serial = new AVIorderedSerial ();
00296
00297 MeshInit* serialMesh = initMesh (input);
00298
00299 GlobalVec sg(serialMesh->getTotalNumDof ());
00300
00301 initGlobalVec (*serialMesh, sg);
00302
00303
00304 serial->runLoop (*serialMesh, sg, true);
00305
00306
00307 bool gvecCmp = g.cmpState (sg);
00308
00309
00310 bool aviCmp = meshInit.cmpState (*serialMesh);
00311
00312 if (!gvecCmp || !aviCmp) {
00313 g.printDiff (sg);
00314
00315 meshInit.printDiff (*serialMesh);
00316
00317 std::cerr << "BAD: results don't match against Serial" << std::endl;
00318 abort ();
00319 }
00320
00321 std::cout << ">>> OK: result verified against serial" << std::endl;
00322
00323 delete serialMesh;
00324 delete serial;
00325
00326 }
00327 else {
00328 std::cerr << "TODO: cmp against file data needs implementation" << std::endl;
00329 abort ();
00330 }
00331 }
00332
00333
00334 void AVIabstractMain::simulate (AVI* avi, MeshInit& meshInit,
00335 GlobalVec& g, LocalVec& l, bool createSyncFiles) {
00336
00337 if (createSyncFiles) {
00338 meshInit.writeSync (*avi, g.vecQ, g.vecV_b, g.vecT);
00339 }
00340
00341 const LocalToGlobalMap& l2gMap = meshInit.getLocalToGlobalMap();
00342
00343 avi->gather (l2gMap, g.vecQ, g.vecV, g.vecV_b, g.vecT,
00344 l.q, l.v, l.vb, l.ti);
00345
00346 avi->computeLocalTvec (l.tnew);
00347
00348 if (avi->getTimeStamp () == 0.0) {
00349 avi->vbInit (l.q, l.v, l.vb, l.ti, l.tnew,
00350 l.qnew, l.vbinit,
00351 l.forcefield, l.funcval, l.deltaV);
00352 avi->update (l.q, l.v, l.vbinit, l.ti, l.tnew,
00353 l.qnew, l.vnew, l.vbnew,
00354 l.forcefield, l.funcval, l.deltaV);
00355 }
00356 else {
00357 avi->update (l.q, l.v, l.vb, l.ti, l.tnew,
00358 l.qnew, l.vnew, l.vbnew,
00359 l.forcefield, l.funcval, l.deltaV);
00360 }
00361
00362 avi->incTimeStamp ();
00363
00364 avi->assemble (l2gMap, l.qnew, l.vnew, l.vbnew, l.tnew, g.vecQ, g.vecV, g.vecV_b, g.vecT, g.vecLUpdate);
00365 }
00366
00367 void AVIorderedSerial::runLoop (MeshInit& meshInit, GlobalVec& g, bool createSyncFiles) {
00368
00369 int nrows = meshInit.getSpatialDim ();
00370 int ncols = meshInit.getNodesPerElem ();
00371
00372 LocalVec l(nrows, ncols);
00373
00374 const std::vector<AVI*>& aviList = meshInit.getAVIVec ();
00375
00376 for (size_t i = 0; i < aviList.size (); ++i) {
00377 assert (aviList[i]->getOperation ().getFields ().size () == meshInit.getSpatialDim());
00378 }
00379
00380
00381 std::priority_queue<AVI*, std::vector<AVI*>, AVIReverseComparator> pq;
00382 for (std::vector<AVI*>::const_iterator i = aviList.begin (), e = aviList.end (); i != e; ++i) {
00383 pq.push (*i);
00384 }
00385
00386
00387 int iter = 0;
00388 while (!pq.empty ()) {
00389
00390 AVI* avi = pq.top ();
00391 pq.pop ();
00392
00393 assert (avi != NULL);
00394
00395 AVIabstractMain::simulate (avi, meshInit, g, l, createSyncFiles);
00396
00397
00398 if (avi->getNextTimeStamp () <= meshInit.getSimEndTime ()) {
00399 pq.push (avi);
00400 }
00401
00402 ++iter;
00403 }
00404
00405
00406
00407 printf ("iterations = %d\n", iter);
00408
00409 }
00410 #endif // AVI_ABSTRACT_MAIN_H_