|
Fluid Dynamics Library
|
00001 00027 #include <boost/program_options.hpp> 00028 #include <boost/thread.hpp> 00029 #include <boost/signal.hpp> 00030 #include <boost/bind.hpp> 00031 #include <boost/format.hpp> 00032 namespace po = boost::program_options; 00033 00034 #include <vlCore/VisualizationLibrary.hpp> 00035 #include <vlGLUT/GLUTWindow.hpp> 00036 #include <vlCore/VLSettings.hpp> 00037 00038 #include "logger/logger.h" 00039 #include "logger/stdiowriter.h" 00040 #include "logger/syslogwriter.h" 00041 00042 #include "core/common.h" 00043 #include "core/fields.hpp" 00044 #include "core/scalars.hpp" 00045 #include "core/macsmoke.hpp" 00046 #include "core/inssmoke.hpp" 00047 #include "core/pointrender.hpp" 00048 #include "core/volumerender.hpp" 00049 #include "render/glutapp.h" 00050 #include "render/drawable.h" 00051 #include "io/xmlparser.h" 00052 00053 #ifndef TARGET_VERSION_MAJOR 00054 #define TARGET_VERSION_MAJOR 99 00055 #endif 00056 00057 #ifndef TARGET_VERSION_MINOR 00058 #define TARGET_VERSION_MINOR 99 00059 #endif 00060 00061 static fdl::MACSmoke<float>* grid = NULL; 00062 static fdl::INSSmoke<float>* solver = NULL; 00063 fdl::Constant<float>* gravityField = NULL; 00064 // static fdl::FieldBase<float>* advectField = NULL; 00065 static fdl::ScalarBase<float>* smokeSrc = NULL; 00066 static fdl::ScalarBase<float>* tempSrc = NULL; 00067 static vl::ref<fdl::VolumeRenderer> applet; 00068 00072 template<class T> 00073 std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) 00074 { 00075 std::copy(v.begin(), v.end(), std::ostream_iterator<T>(std::cout, " ")); 00076 return os; 00077 } 00078 00079 void simulateSmoke() 00080 { 00081 for (int t = 0; t < 200; ++t) { 00082 00083 INFO() << boost::format("T= %g, S= %g, p= %g, u= %g, v= %g, w= %g") \ 00084 % grid->supP() % grid->supT() % grid->supS() % grid->supU() % grid->supV() % grid->supW(); 00085 00086 INFO() << "Advection step"; 00087 solver->advect(); 00088 00089 INFO() << "Adding external force"; 00090 solver->addfield(); 00091 00092 INFO() << "Adding source terms"; 00093 solver->addsources(); 00094 00095 INFO() << "Pressure update step"; 00096 solver->project(); 00097 } 00098 } 00099 00104 int main(int argc, char **argv) 00105 { 00106 fdl::Logger out; 00107 // figure out how to automate this output... 00108 std::cout << "FDL version " << TARGET_VERSION_MAJOR << "." << TARGET_VERSION_MINOR << " of " << __DATE__ << " at " << __TIME__ << std::endl; 00109 00110 fdl::SyslogWriter* syslogger = new fdl::SyslogWriter(); 00111 fdl::StdOutWriter* stdlogger = new fdl::StdOutWriter(); 00112 stdlogger->setFormat("%H:%M:%S"); 00113 fdl::Logger::setIdentity("FDL"); 00114 // fdl::Logger::RegisterWriter(syslogger); 00115 fdl::Logger::registerWriter(stdlogger); 00116 fdl::Logger::setLevel(fdl::Logger::WARN | fdl::Logger::ERROR); 00117 00118 std::string output_prefix = "density_export_"; 00119 00120 int window_width, window_height; 00121 int use_glut_window = 1; 00122 std::string render_exporter = ""; 00123 std::string levelLabel = ""; 00124 std::string inputfile = ""; 00125 int level = 0; 00126 00127 float dx = 0.1; 00128 float dt = 0.1; 00129 float rho = 1.0; 00130 std::vector<int> grid_dims(3, 50); 00131 float solidTemp = 0.0; 00132 float smokeSrcTemp = 2.0; 00133 00134 float gvec[3] = {0.0, 0.0, -1.0}; // gravitational field (constant) 00135 00136 float cg_tol = fdl::EPSILON; 00137 unsigned cg_maxiter = 200; 00138 float ode_tol = 1e-2; 00139 00140 try { 00141 po::options_description desc("Allowed options"); 00142 desc.add_options() 00143 ("help,H", "produce help message") 00144 ("input-file,C", po::value<std::string>(&inputfile), "input configuration file") 00145 ("output-format,O", po::value<std::string>(), "output format") 00146 ("output-name,N", po::value<std::string>(&output_prefix), "output file name PREFIX") 00147 ("win-width,W", po::value<int>(&window_width)->default_value(512), "Glut window width") 00148 ("win-height,E", po::value<int>(&window_height)->default_value(512), "Glut window height") 00149 ("use-glut,L", po::value<int>(&use_glut_window)->default_value(1), "Use Glut rendering window") 00150 ("verbose,V", po::value<int>(&level), "logging level"); 00151 00152 po::variables_map vm; 00153 po::store(po::command_line_parser(argc, argv).options(desc).style(po::command_line_style::default_style 00154 | po::command_line_style::allow_slash_for_short 00155 | po::command_line_style::allow_long_disguise).run(), vm); 00156 00157 po::notify(vm); 00158 00159 if (vm.count("help")) { 00160 std::cout << "Usage: options_description [options]" << std::endl; 00161 std::cout << desc << std::endl; 00162 return 0; 00163 } 00164 00165 if (vm.count("output-name")) { 00166 std::cout << "Output name is: " << vm["output-name"].as<std::string>() << std::endl; 00167 } 00168 00169 if (vm.count("output-format")) { 00170 std::cout << "Output format is: " << vm["output-format"].as<std::string>() << std::endl; 00171 } 00172 00173 if(level >= 0){ 00174 levelLabel = fdl::Logger::loggerLevelAsString(fdl::Logger::INFO); 00175 fdl::Logger::pushLevel(fdl::Logger::INFO); 00176 } 00177 if(level >= 1){ 00178 levelLabel = fdl::Logger::loggerLevelAsString(fdl::Logger::DEV); 00179 fdl::Logger::pushLevel(fdl::Logger::DEV); 00180 } 00181 if(level >= 2){ 00182 levelLabel = fdl::Logger::loggerLevelAsString(fdl::Logger::DEBUG); 00183 fdl::Logger::pushLevel(fdl::Logger::DEBUG); 00184 } 00185 00186 if (vm.count("renderer")) { 00187 std::cout << "Output name is: " << vm["output-name"].as<std::string>() << std::endl; 00188 } 00189 00190 gravityField = new fdl::Constant<float>(3, gvec); 00191 00192 float x_rel = 0.5, y_rel = 0.5; 00193 float sph_R0[3] = {grid_dims[0] * dx * x_rel, grid_dims[1] * dx * y_rel, dx}; 00194 float sph_r = dx * 3; 00195 00196 float cyl_XY[2] = {grid_dims[0] * dx * x_rel, grid_dims[1] * dx * y_rel}; 00197 float cyl_z[2] = {dx, 3 * dx}; 00198 float cyl_r = dx * 4; 00199 00200 smokeSrc = new fdl::Cylindrical<float>(3, cyl_XY, cyl_r, cyl_z[0], cyl_z[1], 0.1 ); 00201 tempSrc = new fdl::Gaussian<float>(3, sph_R0, sph_r, smokeSrcTemp); 00202 00203 grid = new fdl::MACSmoke<float>(grid_dims[0], grid_dims[1], grid_dims[2], dx, solidTemp); 00204 // solver = new fdl::INSSmoke<float>(grid, gravityField, rho, dt, tempScalar, smokeSrc); 00205 00206 00207 INFO() << "Initializing for fluid at rest in solid container "; 00208 00209 float X_tmp[3]; 00210 for (int x = 1; x <= grid->xdim(); ++x) { 00211 for (int y = 1; y <= grid->ydim(); ++y) { 00212 for (int z = 1; z <= grid->zdim(); ++z) 00213 { 00214 // at the boundary... 00215 if (x == 1 || x == grid->xdim() || 00216 y == 1 || y == grid->ydim() || 00217 z == 1 || z == grid->zdim()) 00218 { 00219 grid->operator()(x, y, z) = fdl::SOLID; 00220 grid->p(x, y, z) = 0.0; 00221 grid->u(x, y, z) = 0.0; 00222 grid->u(x+1, y, z) = 0.0; 00223 grid->v(x, y, z) = 0.0; 00224 grid->v(x, y+1, z) = 0.0; 00225 grid->w(x, y, z) = 0.0; 00226 grid->w(x, y, z+1) = 0.0; 00227 grid->T(x, y, z) = 1.0; // this is a hack 00228 grid->s(x, y, z) = 0.0; 00229 } else { 00230 grid->operator()(x, y, z) = fdl::FLUID; 00231 grid->p(x, y, z) = 1.0; 00232 grid->u(x, y, z) = 0.0; 00233 grid->v(x, y, z) = 0.0; 00234 grid->w(x, y, z) = 0.0; 00235 grid->coordsP(x, y, z, X_tmp); 00236 grid->T(x, y, z) = (*tempSrc)(0.0, X_tmp); 00237 // grid->T(x, y, z) = 0.0; 00238 grid->s(x, y, z) = (*smokeSrc)(0.0, X_tmp); 00239 } 00240 } 00241 } 00242 } 00243 00244 solver = new fdl::INSSmoke<float>(grid, gravityField, rho, dt, tempSrc, smokeSrc); 00245 solver->setStepTolerance(ode_tol); 00246 solver->setStepRule(fdl::RK2); 00247 00248 INFO() << "Logging level is " << levelLabel << " (" << level << ")"; 00249 INFO() << "Grid dimensions are: " << grid->xdim() << " x " << grid->ydim() << " x " << grid->zdim(); 00250 INFO() << "Cell width is: " << grid->dx(); 00251 INFO() << "Time step is: " << solver->dt(); 00252 INFO() << "CG solver tolerance is: " << solver->getCGTolerance(); 00253 INFO() << "CG solver max iterations is: " << solver->getCGMaxIter(); 00254 INFO() << "Fluid density coeff. is: " << solver->rho(); 00255 00256 if(use_glut_window>0){ 00257 boost::thread t(simulateSmoke); 00258 00259 int pargc = argc; 00260 glutInit( &pargc, argv ); 00261 00262 // init Visualization Library 00263 vl::VisualizationLibrary::init(); 00264 vl::globalSettings()->setDataPath(vl::String(".")); 00265 00266 // setup the OpenGL context format 00267 vl::OpenGLContextFormat format; 00268 format.setDoubleBuffer(true); 00269 format.setRGBABits( 8,8,8,8 ); 00270 format.setDepthBufferBits(24); 00271 format.setStencilBufferBits(8); 00272 format.setFullscreen(false); 00273 format.setMultisampleSamples(8); 00274 format.setMultisample(true); 00275 00276 // create the applet to be run 00277 //applet = new fdl::PointRenderer(); 00278 applet = new fdl::VolumeRenderer(); 00279 applet->initialize(); 00280 applet->setGrid(grid); 00281 //applet->setSolver(solver); 00282 // create a native GLUT window 00283 vl::ref<vlGLUT::GLUTWindow> glut_window = new vlGLUT::GLUTWindow; 00284 // bind the applet so it receives all the GUI events related to the OpenGLContext 00285 glut_window->addEventListener(applet.get()); 00286 // target the window so we can render on it 00287 applet->rendering()->as<Rendering>()->renderer()->setRenderTarget( glut_window->renderTarget() ); 00288 // black background 00289 applet->rendering()->as<Rendering>()->camera()->viewport()->setClearColor( vl::black ); 00290 // define the camera position and orientation 00291 vl::vec3 eye = vl::vec3(0,30,0); // camera position 00292 vl::vec3 target = vl::vec3(0,0,0); // point the camera is looking at 00293 vl::vec3 up = vl::vec3(0,1,0); // up direction 00294 00295 // --- trackball manipulator --- 00296 vl::ref<vl::TrackballManipulator> trackball = new vl::TrackballManipulator; 00297 // bind the camera to be manipulated 00298 trackball->setCamera( applet->rendering()->as<Rendering>()->camera() ); 00299 // manipulate the camera's transform 00300 trackball->setTransform(NULL); 00301 // rotation pivot coordinates 00302 trackball->setPivot( vl::vec3(0,0,0) ); 00303 // install the trackball 00304 glut_window->addEventListener(trackball.get()); 00305 00306 AABB volume_box( vec3( 0,0,0 ), vec3( 1,1,1 ) ); 00307 trackball->adjustView(volume_box, vl::vec3(10,10,10), up); 00308 00309 // Initialize the OpenGL context and window properties 00310 glut_window->initGLUTWindow( "FDL", format, 0, 0, window_width, window_height ); 00311 00312 glutMainLoop(); 00313 } 00314 else{ 00315 simulateSmoke(); 00316 } 00317 00318 } 00319 catch(std::exception& e) { 00320 ERROR() << " * error: " << e.what(); 00321 return 1; 00322 } 00323 catch(...) { 00324 ERROR() << "Exception of unknown type!"; 00325 } 00326 00327 /* 00328 Idea: move this stuff into the class constructors 00329 00330 std::cout << "Grid dimensions are: " << grid_dims[0] << " x " << grid_dims[1] << " x " << grid_dims[2] << std::endl; 00331 std::cout << "Cell width is: " << dx << std::endl; 00332 // and so on... 00333 */ 00334 00335 delete solver; 00336 delete grid; 00337 00338 return 0; 00339 }
1.7.4