diff --git a/apps/tutorials/pe/01_ConfinedGas.cpp b/apps/tutorials/pe/01_ConfinedGas.cpp index 52795b4d3cd65e81a3d9139c8677413925d409c3..8a95fee6066e0009464fb970402a7bba6acb5033 100644 --- a/apps/tutorials/pe/01_ConfinedGas.cpp +++ b/apps/tutorials/pe/01_ConfinedGas.cpp @@ -26,16 +26,7 @@ #include <core/grid_generator/SCIterator.h> #include <core/logging/Logging.h> -#include "gui/Gui.h" -#include "timeloop/SweepTimeloop.h" - -#include <pe/vtk/SphereVtkOutput.h> -#include "vtk/VTKOutput.h" - #include <pe/raytracing/Raytracer.h> - -#include <core/mpi/all.h> - //! [Includes] using namespace walberla; @@ -43,65 +34,23 @@ using namespace walberla::pe; using namespace walberla::pe::raytracing; //! [BodyTypeTuple] -typedef boost::tuple<Sphere, Plane, Box> BodyTypeTuple ; +typedef boost::tuple<Sphere, Plane> BodyTypeTuple ; //! [BodyTypeTuple] -void testRayTracing () { - shared_ptr<BodyStorage> globalBodyStorage = make_shared<BodyStorage>(); - shared_ptr<BlockForest> forest = createBlockForest(AABB(0,-5,-5,10,5,5), Vec3(1,1,1), Vec3(false, false, false)); - auto storageID = forest->addBlockData(createStorageDataHandling<BodyTypeTuple>(), "Storage"); - SetBodyTypeIDs<BodyTypeTuple>::execute(); - createSphere(*globalBodyStorage, *forest, storageID, 2, Vec3(6,4.5,4.5), real_t(0.5)); - createSphere(*globalBodyStorage, *forest, storageID, 3, Vec3(3.5,-2,0), real_t(1)); - //createSphere(*globalBodyStorage, *forest, storageID, 6, Vec3(3,2,0), real_t(1)); - BoxID box = createBox(*globalBodyStorage, *forest, storageID, 7, Vec3(5,0,0), Vec3(2,4,3)); - box->rotate(0,math::M_PI/4,math::M_PI/4); - createBox(*globalBodyStorage, *forest, storageID, 7, Vec3(5,-4,3), Vec3(2,2,2)); - //createSphere(*globalBodyStorage, *forest, storageID, 5, Vec3(1,0,0), real_t(0.1)); - - //Raytracer raytracer(forest, storageID, uint8_t(640), uint8_t(480), 49.13, Vec3(-5,0,0), Vec3(-1,0,0), Vec3(0,0,1)); - //raytracer.generateImage<BodyTypeTuple>(0); -} - int main( int argc, char ** argv ) { //! [Parameters] Environment env(argc, argv); WALBERLA_UNUSED(env); - + math::seedRandomGenerator( static_cast<unsigned int>(1337 * mpi::MPIManager::instance()->worldRank()) ); - - //testRayTracing(); - //return 0; - + real_t spacing = real_c(1.0); real_t radius = real_c(0.4); real_t vMax = real_c(1.0); - size_t simulationSteps = 10; - size_t raytraceSkippedSteps = 10; + int simulationSteps = 100; + int raytracerSkippedSteps = 5; real_t dt = real_c(0.01); - - uint_t blocks_x = 2, blocks_y = 2, blocks_z = 2; - - auto cfg = env.config(); - if (cfg != NULL) { - const Config::BlockHandle confBlock = cfg->getBlock("gas"); - - spacing = confBlock.getParameter<real_t>("spacing", spacing); - radius = confBlock.getParameter<real_t>("radius", radius); - simulationSteps = confBlock.getParameter<size_t>("simulationSteps", simulationSteps); - raytraceSkippedSteps = confBlock.getParameter<size_t>("raytraceSkippedSteps", raytraceSkippedSteps); - blocks_x = confBlock.getParameter<uint_t>("blocks_x", blocks_x); - blocks_y = confBlock.getParameter<uint_t>("blocks_y", blocks_y); - blocks_z = confBlock.getParameter<uint_t>("blocks_z", blocks_z); - - WALBERLA_LOG_INFO_ON_ROOT("spacing: " << spacing); - WALBERLA_LOG_INFO_ON_ROOT("radius: " << radius); - WALBERLA_LOG_INFO_ON_ROOT("blocks_x: " << blocks_x); - WALBERLA_LOG_INFO_ON_ROOT("blocks_y: " << blocks_y); - WALBERLA_LOG_INFO_ON_ROOT("blocks_z: " << blocks_z); - } - //! [Parameters] WALBERLA_LOG_INFO_ON_ROOT("*** GLOBALBODYSTORAGE ***"); @@ -113,10 +62,9 @@ int main( int argc, char ** argv ) // create forest //! [BlockForest] shared_ptr< BlockForest > forest = createBlockForest( AABB(0,0,0,20,20,20), // simulation domain - Vector3<uint_t>(blocks_x,blocks_y,blocks_z), // blocks in each direction + Vector3<uint_t>(2,2,2), // blocks in each direction Vector3<bool>(false, false, false) // periodicity ); - //! [BlockForest] if (!forest) { @@ -133,12 +81,6 @@ int main( int argc, char ** argv ) auto ccdID = forest->addBlockData(ccd::createHashGridsDataHandling( globalBodyStorage, storageID ), "CCD"); auto fcdID = forest->addBlockData(fcd::createGenericFCDDataHandling<BodyTypeTuple, fcd::AnalyticCollideFunctor>(), "FCD"); //! [AdditionalBlockData] - - WALBERLA_LOG_INFO_ON_ROOT("*** RAYTRACER ***"); - if (cfg == NULL) { - WALBERLA_ABORT("raytracer needs a working config"); - } - Raytracer raytracer(forest, storageID, globalBodyStorage, ccdID, cfg->getBlock("raytracing")); WALBERLA_LOG_INFO_ON_ROOT("*** INTEGRATOR ***"); //! [Integrator] @@ -154,6 +96,19 @@ int main( int argc, char ** argv ) //! [SetBodyTypeIDs] SetBodyTypeIDs<BodyTypeTuple>::execute(); //! [SetBodyTypeIDs] + + WALBERLA_LOG_INFO_ON_ROOT("*** RAYTRACER ***"); + Lighting lighting(Vec3(-12, 12, 12), + Color(1, 1, 1), + Color(1, 1, 1), + Color(0.4, 0.4, 0.4)); + Raytracer raytracer(forest, storageID, globalBodyStorage, ccdID, + 640, 480, + real_t(49.13), + Vec3(-25, 10, 10), Vec3(-5, 10, 10), Vec3(0, 0, 1), + lighting, + Color(0.1, 0.1, 0.1), + radius); WALBERLA_LOG_INFO_ON_ROOT("*** SETUP - START ***"); //! [Material] @@ -172,7 +127,7 @@ int main( int argc, char ** argv ) createPlane(*globalBodyStorage, 0, Vec3(0,0,1), simulationDomain.minCorner(), material ); createPlane(*globalBodyStorage, 0, Vec3(0,0,-1), simulationDomain.maxCorner(), material ); //! [Planes] - + //! [Gas] uint_t numParticles = uint_c(0); for (auto blkIt = forest->begin(); blkIt != forest->end(); ++blkIt) @@ -194,7 +149,7 @@ int main( int argc, char ** argv ) WALBERLA_LOG_INFO_ON_ROOT("*** SIMULATION - START ***"); //! [GameLoop] - for (size_t i=0; i < simulationSteps; ++i) + for (int i=0; i < simulationSteps; ++i) { if( i % 10 == 0 ) { @@ -202,12 +157,13 @@ int main( int argc, char ** argv ) } cr.timestep( real_c(dt) ); - syncNextNeighbors<BodyTypeTuple>(*forest, storageID); - - if (i%raytraceSkippedSteps == 0) { - raytracer.generateImage<BodyTypeTuple>(i); + if (i % raytracerSkippedSteps == 0) { + raytracer.generateImage<BodyTypeTuple>(uint_c(i)); } + syncNextNeighbors<BodyTypeTuple>(*forest, storageID); + } + //! [GameLoop] WALBERLA_LOG_INFO_ON_ROOT("*** SIMULATION - END ***"); @@ -224,18 +180,6 @@ int main( int argc, char ** argv ) meanVelocity /= numParticles; WALBERLA_LOG_INFO( "mean velocity: " << meanVelocity ); //! [PostProcessing] - - //WALBERLA_LOG_INFO_ON_ROOT("*** RAYTRACING - START ***"); - //raytracer.generateImage<BodyTypeTuple>(0); - //WALBERLA_LOG_INFO_ON_ROOT("*** RAYTRACING - END ***"); - // für einzelne sphere vtks: -> SphereVtkOutput.cpp - - auto vtkDomainOutput = vtk::createVTKOutput_DomainDecomposition( forest, "domain_decomposition", 1, "vtk_out", "simulation_step" ); - auto vtkSphereHelper = make_shared<SphereVtkOutput>(storageID, *forest) ; - auto vtkSphereOutput = vtk::createVTKOutput_PointData(vtkSphereHelper, "Bodies", 1, "vtk_out", "simulation_step", false, false); - vtkDomainOutput->write(); - vtkSphereOutput->write(); - return EXIT_SUCCESS; } diff --git a/apps/tutorials/pe/02_ConfinedGasExtended.cpp b/apps/tutorials/pe/02_ConfinedGasExtended.cpp index feca8150acc31c19c7132c2ba575ed9c2b0275e9..eb2e964d514cdc3de009a7216dbcc3c184d337fb 100644 --- a/apps/tutorials/pe/02_ConfinedGasExtended.cpp +++ b/apps/tutorials/pe/02_ConfinedGasExtended.cpp @@ -146,10 +146,22 @@ int main( int argc, char ** argv ) auto fcdID = forest->addBlockData(fcd::createGenericFCDDataHandling<BodyTuple, fcd::AnalyticCollideFunctor>(), "FCD"); WALBERLA_LOG_INFO_ON_ROOT("*** RAYTRACER ***"); - if (cfg == NULL) { - WALBERLA_ABORT("raytracer needs a working config"); - } - Raytracer raytracer(forest, storageID, globalBodyStorage, ccdID, cfg->getBlock("Raytracing")); + //if (cfg == NULL) { + // WALBERLA_ABORT("raytracer needs a working config"); + //} + //Raytracer raytracer(forest, storageID, globalBodyStorage, ccdID, + // cfg->getBlock("Raytracing")); + Lighting lighting(Vec3(-12, 12, 12), + Color(1, 1, 1), + Color(1, 1, 1), + Color(0.4, 0.4, 0.4)); + Raytracer raytracer(forest, storageID, globalBodyStorage, ccdID, + 640, 480, + real_t(49.13), + Vec3(-25, 10, 10), Vec3(-5, 10, 10), Vec3(0, 0, 1), + lighting, + Color(0.1, 0.1, 0.1), + radius); WALBERLA_LOG_INFO_ON_ROOT("*** INTEGRATOR ***"); cr::HCSITS cr(globalBodyStorage, forest, storageID, ccdID, fcdID); diff --git a/src/pe/raytracing/Ray.h b/src/pe/raytracing/Ray.h index a95948053c415c28e25c320f6efe80ca78b1fbdd..04de8cdfd058a3def15f8df6fcd9b6c0819ebbf3 100644 --- a/src/pe/raytracing/Ray.h +++ b/src/pe/raytracing/Ray.h @@ -109,7 +109,7 @@ public: /*!\brief Returns the inverse of the direction vector of the ray for a given axis. */ inline real_t getInvDirection (size_t axis) const { - WALBERLA_ASSERT(axis >= 0 && axis <= 2, "No valid axis index passed."); + WALBERLA_ASSERT(axis <= 2, "No valid axis index passed."); return inv_direction_[axis]; } diff --git a/src/pe/raytracing/Raytracer.cpp b/src/pe/raytracing/Raytracer.cpp index 5b9be64b635d02f3a1887a59ab9372ce4c6aac2c..7f95db2fb83d3a3d116a69b528d5eff3acdc10c0 100644 --- a/src/pe/raytracing/Raytracer.cpp +++ b/src/pe/raytracing/Raytracer.cpp @@ -32,6 +32,7 @@ namespace pe { namespace raytracing { void BodyIntersectionInfo_Comparator_MPI_OP( BodyIntersectionInfo *in, BodyIntersectionInfo *inout, int *len, MPI_Datatype *dptr) { + WALBERLA_UNUSED(dptr); for (int i = 0; i < *len; ++i) { if (in->bodySystemID != 0 && inout->bodySystemID != 0) { WALBERLA_ASSERT(in->imageX == inout->imageX && in->imageY == inout->imageY, "coordinates of infos do not match: " << in->imageX << "/" << in->imageY << " and " << inout->imageX << "/" << inout->imageY); @@ -86,8 +87,10 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, const BlockDataID st backgroundColor_(backgroundColor), blockAABBIntersectionPadding_(blockAABBIntersectionPadding), tBufferOutputEnabled_(false), - imageOutputEnabled_(false), + tBufferOutputDirectory_("."), + imageOutputEnabled_(true), localImageOutputEnabled_(false), + imageOutputDirectory_("."), filenameTimestepWidth_(5), bodyToShadingParamsFunction_(bodyToShadingParamsFunction), raytracingAlgorithm_(RAYTRACE_HASHGRIDS), @@ -129,7 +132,7 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, const BlockDataID st if (config.isDefined("tbuffer_output_directory")) { setTBufferOutputEnabled(true); - setTBufferOutputDirectory(config.getParameter<std::string>("tbuffer_output_directory")); + setTBufferOutputDirectory(config.getParameter<std::string>("tbuffer_output_directory", ".")); WALBERLA_LOG_INFO_ON_ROOT("t buffers will be written to " << getTBufferOutputDirectory() << "."); } else { setTBufferOutputEnabled(false); @@ -139,7 +142,7 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, const BlockDataID st if (config.isDefined("image_output_directory")) { setImageOutputEnabled(true); - setImageOutputDirectory(config.getParameter<std::string>("image_output_directory")); + setImageOutputDirectory(config.getParameter<std::string>("image_output_directory", ".")); WALBERLA_LOG_INFO_ON_ROOT("Images will be written to " << getImageOutputDirectory() << "."); } else if (getLocalImageOutputEnabled()) { WALBERLA_ABORT("Cannot enable local image output without image_output_directory parameter being set."); diff --git a/src/pe/raytracing/Raytracer.h b/src/pe/raytracing/Raytracer.h index 9b5008e1774ca8c1a23bdbdb686cb882a9f6f964..d6a3c31a99b1295ebc1d70e1cb609697aef8bf3f 100644 --- a/src/pe/raytracing/Raytracer.h +++ b/src/pe/raytracing/Raytracer.h @@ -60,7 +60,7 @@ struct BodyIntersectionInfo { double b; //!< Blue value for the pixel. -> MPI_DOUBLE }; -class Raytracer { +class Raytracer { public: enum ReductionMethod { MPI_REDUCE, MPI_GATHER }; enum Algorithm { RAYTRACE_HASHGRIDS, RAYTRACE_NAIVE, RAYTRACE_COMPARE_BOTH }; @@ -532,8 +532,7 @@ void Raytracer::generateImage(const size_t timestep, WcTimingTree* tt) { bool isErrorneousPixel = false; uint_t pixelErrors = 0; #if defined(RAYTRACER_VERBOSE_COMPARISONS) - std::unordered_set<BodyID> incorrectHashgridsBodyIDs; - std::unordered_set<BodyID> correctBodyIDs; + std::map<BodyID, std::unordered_set<BodyID>> correctToIncorrectBodyIDsMap; #endif if (tt != NULL) tt->start("Intersection Testing"); @@ -543,6 +542,9 @@ void Raytracer::generateImage(const size_t timestep, WcTimingTree* tt) { Vec3 direction = (pixelLocation - cameraPosition_).getNormalized(); ray.setDirection(direction); + //if (x != 110) continue; + //if (y != 80 && y != 150) continue; + n.reset(); t_closest = inf; body_closest = NULL; @@ -561,8 +563,7 @@ void Raytracer::generateImage(const size_t timestep, WcTimingTree* tt) { if (body_closest != hashgrids_body_closest) { #if defined(RAYTRACER_VERBOSE_COMPARISONS) - correctBodyIDs.insert(body_closest); - incorrectHashgridsBodyIDs.insert(hashgrids_body_closest); + correctToIncorrectBodyIDsMap[body_closest].insert(hashgrids_body_closest); #endif isErrorneousPixel = true; ++pixelErrors; @@ -603,24 +604,28 @@ void Raytracer::generateImage(const size_t timestep, WcTimingTree* tt) { #if defined(RAYTRACER_VERBOSE_COMPARISONS) std::stringstream ss; - for (auto body: correctBodyIDs) { - if (body != NULL) { - ss << body->getID() << "(" << body->getHash() << ") "; + for (auto it: correctToIncorrectBodyIDsMap) { + const BodyID correctBody = it.first; + if (it.first != NULL) { + ss << " correct body: " << correctBody->getID() << "(" << correctBody->getHash() << ")"; } else { - ss << "NULL" << " "; + ss << " no body naively found"; } - }; - ss << "("; - for (auto body: incorrectHashgridsBodyIDs) { - if (body != NULL) { - ss << body->getID() << "(" << body->getHash() << ") "; - } else { - ss << "NULL" << " "; + ss << ", hashgrids found:"; + for (auto incorrectBody: it.second) { + ss << " "; + if (incorrectBody != NULL) { + ss << incorrectBody->getID() << "(" << incorrectBody->getHash(); + } else { + ss << "NULL"; + } } - }; - ss << ")"; + ss << std::endl; + ss << " minCorner: " << correctBody->getAABB().minCorner() << ", maxCorner: " << correctBody->getAABB().maxCorner(); + ss << std::endl; + } - WALBERLA_LOG_WARNING(" problematic bodies: " << ss.str()); + WALBERLA_LOG_WARNING("Problematic bodies: " << std::endl << ss.str()); #endif } @@ -686,7 +691,7 @@ inline Color Raytracer::getColor(const BodyID body, const Ray& ray, real_t t, co real_t specular = real_t(0); - if (lambertian > 0) { + if (lambertian > 0 || realIsEqual(lambertian, real_t(0))) { // Blinn-Phong Vec3 viewDirection = -ray.getDirection(); Vec3 halfDirection = (lightDirection + viewDirection).getNormalized(); diff --git a/tests/pe/Raytracing.cpp b/tests/pe/Raytracing.cpp index 09c616b37ce96d05b49a6ae682051027588c89e1..a6b0ca082a107b94dae7100f2888ac733675b5f3 100644 --- a/tests/pe/Raytracing.cpp +++ b/tests/pe/Raytracing.cpp @@ -850,7 +850,7 @@ int main( int argc, char** argv ) math::seedRandomGenerator( static_cast<unsigned int>(1337 * mpi::MPIManager::instance()->worldRank()) ); Raytracer::Algorithm algorithm = Raytracer::RAYTRACE_COMPARE_BOTH; - bool outputToFoldersEnabled = false; + bool outputToFoldersEnabled = true; std::string outputFolder = "."; if (outputToFoldersEnabled) { @@ -872,8 +872,9 @@ int main( int argc, char** argv ) //BoxIntersectsTest(); //AABBIntersectsTest(); //CapsuleIntersectsTest(); - //RaytracerTest(algorithm, outputFolder); - //RaytracerSpheresTest(algorithm, outputFolder); + RaytracerTest(algorithm, outputFolder); + return; + RaytracerSpheresTest(algorithm, outputFolder); HashGridsTestScene(algorithm, outputFolder);