/******************************************************************************* * For each run, the input filename and restart information (if needed) must * * be given on the command line. For non-restarted case, command line is: * * * * executable <input file name> * * * * For restarted run, command line is: * * * * executable <input file name> <restart directory> <restart number> * * * *******************************************************************************/ int main(int argc, char* argv[]) { // Initialize PETSc, MPI, and SAMRAI. PetscInitialize(&argc, &argv, NULL, NULL); SAMRAI_MPI::setCommunicator(PETSC_COMM_WORLD); SAMRAI_MPI::setCallAbortInSerialInsteadOfExit(); SAMRAIManager::startup(); { // cleanup dynamically allocated objects prior to shutdown // Parse command line options, set some standard options from the input // file, initialize the restart database (if this is a restarted run), // and enable file logging. Pointer<AppInitializer> app_initializer = new AppInitializer(argc, argv, "IB.log"); Pointer<Database> input_db = app_initializer->getInputDatabase(); // Get various standard options set in the input file. const bool dump_viz_data = app_initializer->dumpVizData(); const int viz_dump_interval = app_initializer->getVizDumpInterval(); const bool uses_visit = dump_viz_data && app_initializer->getVisItDataWriter(); const bool dump_restart_data = app_initializer->dumpRestartData(); const int restart_dump_interval = app_initializer->getRestartDumpInterval(); const string restart_dump_dirname = app_initializer->getRestartDumpDirectory(); const bool dump_postproc_data = app_initializer->dumpPostProcessingData(); const int postproc_data_dump_interval = app_initializer->getPostProcessingDataDumpInterval(); const string postproc_data_dump_dirname = app_initializer->getPostProcessingDataDumpDirectory(); if (dump_postproc_data && (postproc_data_dump_interval > 0) && !postproc_data_dump_dirname.empty()) { Utilities::recursiveMkdir(postproc_data_dump_dirname); } const bool dump_timer_data = app_initializer->dumpTimerData(); const int timer_dump_interval = app_initializer->getTimerDumpInterval(); // Create major algorithm and data objects that comprise the // application. These objects are configured from the input database // and, if this is a restarted run, from the restart database. Pointer<INSHierarchyIntegrator> navier_stokes_integrator; const string solver_type = app_initializer->getComponentDatabase("Main")->getStringWithDefault("solver_type", "STAGGERED"); if (solver_type == "STAGGERED") { navier_stokes_integrator = new INSStaggeredHierarchyIntegrator( "INSStaggeredHierarchyIntegrator", app_initializer->getComponentDatabase("INSStaggeredHierarchyIntegrator")); } else if (solver_type == "COLLOCATED") { navier_stokes_integrator = new INSCollocatedHierarchyIntegrator( "INSCollocatedHierarchyIntegrator", app_initializer->getComponentDatabase("INSCollocatedHierarchyIntegrator")); } else { TBOX_ERROR("Unsupported solver type: " << solver_type << "\n" << "Valid options are: COLLOCATED, STAGGERED"); } Pointer<IBMethod> ib_method_ops = new IBMethod("IBMethod", app_initializer->getComponentDatabase("IBMethod")); Pointer<IBHierarchyIntegrator> time_integrator = new IBExplicitHierarchyIntegrator( "IBHierarchyIntegrator", app_initializer->getComponentDatabase("IBHierarchyIntegrator"), ib_method_ops, navier_stokes_integrator); Pointer<CartesianGridGeometry<NDIM> > grid_geometry = new CartesianGridGeometry<NDIM>( "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); Pointer<PatchHierarchy<NDIM> > patch_hierarchy = new PatchHierarchy<NDIM>("PatchHierarchy", grid_geometry); Pointer<StandardTagAndInitialize<NDIM> > error_detector = new StandardTagAndInitialize<NDIM>("StandardTagAndInitialize", time_integrator, app_initializer->getComponentDatabase("StandardTagAndInitialize")); Pointer<BergerRigoutsos<NDIM> > box_generator = new BergerRigoutsos<NDIM>(); Pointer<LoadBalancer<NDIM> > load_balancer = new LoadBalancer<NDIM>("LoadBalancer", app_initializer->getComponentDatabase("LoadBalancer")); Pointer<GriddingAlgorithm<NDIM> > gridding_algorithm = new GriddingAlgorithm<NDIM>("GriddingAlgorithm", app_initializer->getComponentDatabase("GriddingAlgorithm"), error_detector, box_generator, load_balancer); // Configure the IB solver. Pointer<IBStandardInitializer> ib_initializer = new IBStandardInitializer( "IBStandardInitializer", app_initializer->getComponentDatabase("IBStandardInitializer")); ib_method_ops->registerLInitStrategy(ib_initializer); Pointer<IBStandardForceGen> ib_force_fcn = new IBStandardForceGen(); ib_method_ops->registerIBLagrangianForceFunction(ib_force_fcn); // Create Eulerian initial condition specification objects. These // objects also are used to specify exact solution values for error // analysis. Pointer<CartGridFunction> u_init = new muParserCartGridFunction( "u_init", app_initializer->getComponentDatabase("VelocityInitialConditions"), grid_geometry); navier_stokes_integrator->registerVelocityInitialConditions(u_init); Pointer<CartGridFunction> p_init = new muParserCartGridFunction( "p_init", app_initializer->getComponentDatabase("PressureInitialConditions"), grid_geometry); navier_stokes_integrator->registerPressureInitialConditions(p_init); // Create Eulerian boundary condition specification objects (when necessary). const IntVector<NDIM>& periodic_shift = grid_geometry->getPeriodicShift(); vector<RobinBcCoefStrategy<NDIM>*> u_bc_coefs(NDIM); if (periodic_shift.min() > 0) { for (unsigned int d = 0; d < NDIM; ++d) { u_bc_coefs[d] = NULL; } } else { for (unsigned int d = 0; d < NDIM; ++d) { ostringstream bc_coefs_name_stream; bc_coefs_name_stream << "u_bc_coefs_" << d; const string bc_coefs_name = bc_coefs_name_stream.str(); ostringstream bc_coefs_db_name_stream; bc_coefs_db_name_stream << "VelocityBcCoefs_" << d; const string bc_coefs_db_name = bc_coefs_db_name_stream.str(); u_bc_coefs[d] = new muParserRobinBcCoefs( bc_coefs_name, app_initializer->getComponentDatabase(bc_coefs_db_name), grid_geometry); } navier_stokes_integrator->registerPhysicalBoundaryConditions(u_bc_coefs); } // Create Eulerian body force function specification objects. if (input_db->keyExists("ForcingFunction")) { Pointer<CartGridFunction> f_fcn = new muParserCartGridFunction( "f_fcn", app_initializer->getComponentDatabase("ForcingFunction"), grid_geometry); time_integrator->registerBodyForceFunction(f_fcn); } // Set up visualization plot file writers. Pointer<VisItDataWriter<NDIM> > visit_data_writer = app_initializer->getVisItDataWriter(); Pointer<LSiloDataWriter> silo_data_writer = app_initializer->getLSiloDataWriter(); if (uses_visit) { ib_initializer->registerLSiloDataWriter(silo_data_writer); time_integrator->registerVisItDataWriter(visit_data_writer); ib_method_ops->registerLSiloDataWriter(silo_data_writer); } // Initialize hierarchy configuration and data on all patches. time_integrator->initializePatchHierarchy(patch_hierarchy, gridding_algorithm); // Deallocate initialization objects. ib_method_ops->freeLInitStrategy(); ib_initializer.setNull(); app_initializer.setNull(); // Print the input database contents to the log file. plog << "Input database:\n"; input_db->printClassData(plog); // Setup data used to determine the accuracy of the computed solution. VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase(); const Pointer<Variable<NDIM> > u_var = navier_stokes_integrator->getVelocityVariable(); const Pointer<VariableContext> u_ctx = navier_stokes_integrator->getCurrentContext(); const int u_idx = var_db->mapVariableAndContextToIndex(u_var, u_ctx); const int u_cloned_idx = var_db->registerClonedPatchDataIndex(u_var, u_idx); const Pointer<Variable<NDIM> > p_var = navier_stokes_integrator->getPressureVariable(); const Pointer<VariableContext> p_ctx = navier_stokes_integrator->getCurrentContext(); const int p_idx = var_db->mapVariableAndContextToIndex(p_var, p_ctx); const int p_cloned_idx = var_db->registerClonedPatchDataIndex(p_var, p_idx); visit_data_writer->registerPlotQuantity("P error", "SCALAR", p_cloned_idx); const int coarsest_ln = 0; const int finest_ln = patch_hierarchy->getFinestLevelNumber(); for (int ln = coarsest_ln; ln <= finest_ln; ++ln) { patch_hierarchy->getPatchLevel(ln)->allocatePatchData(u_cloned_idx); patch_hierarchy->getPatchLevel(ln)->allocatePatchData(p_cloned_idx); } // Write out initial visualization data. int iteration_num = time_integrator->getIntegratorStep(); double loop_time = time_integrator->getIntegratorTime(); if (dump_viz_data && uses_visit) { pout << "\n\nWriting visualization files...\n\n"; time_integrator->setupPlotData(); visit_data_writer->writePlotData(patch_hierarchy, iteration_num, loop_time); silo_data_writer->writePlotData(iteration_num, loop_time); } // Main time step loop. double loop_time_end = time_integrator->getEndTime(); double dt = 0.0; while (!MathUtilities<double>::equalEps(loop_time, loop_time_end) && time_integrator->stepsRemaining()) { iteration_num = time_integrator->getIntegratorStep(); loop_time = time_integrator->getIntegratorTime(); pout << "\n"; pout << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n"; pout << "At beginning of timestep # " << iteration_num << "\n"; pout << "Simulation time is " << loop_time << "\n"; dt = time_integrator->getMaximumTimeStepSize(); time_integrator->advanceHierarchy(dt); loop_time += dt; pout << "\n"; pout << "At end of timestep # " << iteration_num << "\n"; pout << "Simulation time is " << loop_time << "\n"; pout << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n"; pout << "\n"; // At specified intervals, write visualization and restart files, // print out timer data, and store hierarchy data for post // processing. iteration_num += 1; const bool last_step = !time_integrator->stepsRemaining(); if (dump_viz_data && uses_visit && (iteration_num % viz_dump_interval == 0 || last_step)) { pout << "\nWriting visualization files...\n\n"; time_integrator->setupPlotData(); visit_data_writer->writePlotData(patch_hierarchy, iteration_num, loop_time); silo_data_writer->writePlotData(iteration_num, loop_time); } if (dump_restart_data && (iteration_num % restart_dump_interval == 0 || last_step)) { pout << "\nWriting restart files...\n\n"; RestartManager::getManager()->writeRestartFile(restart_dump_dirname, iteration_num); } if (dump_timer_data && (iteration_num % timer_dump_interval == 0 || last_step)) { pout << "\nWriting timer data...\n\n"; TimerManager::getManager()->print(plog); } if (dump_postproc_data && (iteration_num % postproc_data_dump_interval == 0 || last_step)) { output_data(patch_hierarchy, navier_stokes_integrator, ib_method_ops->getLDataManager(), iteration_num, loop_time, postproc_data_dump_dirname); } // Compute velocity and pressure error norms. const int coarsest_ln = 0; const int finest_ln = patch_hierarchy->getFinestLevelNumber(); for (int ln = coarsest_ln; ln <= finest_ln; ++ln) { Pointer<PatchLevel<NDIM> > level = patch_hierarchy->getPatchLevel(ln); if (!level->checkAllocated(u_cloned_idx)) level->allocatePatchData(u_cloned_idx); if (!level->checkAllocated(p_cloned_idx)) level->allocatePatchData(p_cloned_idx); } pout << "\n" << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n" << "Computing error norms.\n\n"; u_init->setDataOnPatchHierarchy(u_cloned_idx, u_var, patch_hierarchy, loop_time); p_init->setDataOnPatchHierarchy(p_cloned_idx, p_var, patch_hierarchy, loop_time - 0.5 * dt); HierarchyMathOps hier_math_ops("HierarchyMathOps", patch_hierarchy); hier_math_ops.setPatchHierarchy(patch_hierarchy); hier_math_ops.resetLevels(coarsest_ln, finest_ln); const int wgt_cc_idx = hier_math_ops.getCellWeightPatchDescriptorIndex(); const int wgt_sc_idx = hier_math_ops.getSideWeightPatchDescriptorIndex(); Pointer<CellVariable<NDIM, double> > u_cc_var = u_var; if (u_cc_var) { HierarchyCellDataOpsReal<NDIM, double> hier_cc_data_ops(patch_hierarchy, coarsest_ln, finest_ln); hier_cc_data_ops.subtract(u_cloned_idx, u_idx, u_cloned_idx); pout << "Error in u at time " << loop_time << ":\n" << " L1-norm: " << hier_cc_data_ops.L1Norm(u_cloned_idx, wgt_cc_idx) << "\n" << " L2-norm: " << hier_cc_data_ops.L2Norm(u_cloned_idx, wgt_cc_idx) << "\n" << " max-norm: " << hier_cc_data_ops.maxNorm(u_cloned_idx, wgt_cc_idx) << "\n"; } Pointer<SideVariable<NDIM, double> > u_sc_var = u_var; if (u_sc_var) { HierarchySideDataOpsReal<NDIM, double> hier_sc_data_ops(patch_hierarchy, coarsest_ln, finest_ln); hier_sc_data_ops.subtract(u_cloned_idx, u_idx, u_cloned_idx); pout << "Error in u at time " << loop_time << ":\n" << " L1-norm: " << hier_sc_data_ops.L1Norm(u_cloned_idx, wgt_sc_idx) << "\n" << " L2-norm: " << hier_sc_data_ops.L2Norm(u_cloned_idx, wgt_sc_idx) << "\n" << " max-norm: " << hier_sc_data_ops.maxNorm(u_cloned_idx, wgt_sc_idx) << "\n"; } HierarchyCellDataOpsReal<NDIM, double> hier_cc_data_ops(patch_hierarchy, coarsest_ln, finest_ln); hier_cc_data_ops.subtract(p_cloned_idx, p_idx, p_cloned_idx); pout << "Error in p at time " << loop_time - 0.5 * dt << ":\n" << " L1-norm: " << hier_cc_data_ops.L1Norm(p_cloned_idx, wgt_cc_idx) << "\n" << " L2-norm: " << hier_cc_data_ops.L2Norm(p_cloned_idx, wgt_cc_idx) << "\n" << " max-norm: " << hier_cc_data_ops.maxNorm(p_cloned_idx, wgt_cc_idx) << "\n" << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n"; } // Cleanup Eulerian boundary condition specification objects (when // necessary). for (unsigned int d = 0; d < NDIM; ++d) delete u_bc_coefs[d]; } // cleanup dynamically allocated objects prior to shutdown SAMRAIManager::shutdown(); PetscFinalize(); return 0; } // main
/******************************************************************************* * For each run, the input filename and restart information (if needed) must * * be given on the command line. For non-restarted case, command line is: * * * * executable <input file name> * * * * For restarted run, command line is: * * * * executable <input file name> <restart directory> <restart number> * * * *******************************************************************************/ int main( int argc, char* argv[]) { // Initialize PETSc, MPI, and SAMRAI. PetscInitialize(&argc,&argv,NULL,NULL); SAMRAI_MPI::setCommunicator(PETSC_COMM_WORLD); SAMRAI_MPI::setCallAbortInSerialInsteadOfExit(); SAMRAIManager::startup(); {// cleanup dynamically allocated objects prior to shutdown // Parse command line options, set some standard options from the input // file, initialize the restart database (if this is a restarted run), // and enable file logging. Pointer<AppInitializer> app_initializer = new AppInitializer(argc, argv, "adv_diff.log"); Pointer<Database> input_db = app_initializer->getInputDatabase(); // Get various standard options set in the input file. const bool dump_viz_data = app_initializer->dumpVizData(); const int viz_dump_interval = app_initializer->getVizDumpInterval(); const bool uses_visit = dump_viz_data && app_initializer->getVisItDataWriter(); const bool dump_restart_data = app_initializer->dumpRestartData(); const int restart_dump_interval = app_initializer->getRestartDumpInterval(); const string restart_dump_dirname = app_initializer->getRestartDumpDirectory(); const bool dump_timer_data = app_initializer->dumpTimerData(); const int timer_dump_interval = app_initializer->getTimerDumpInterval(); Pointer<Database> main_db = app_initializer->getComponentDatabase("Main"); // Create major algorithm and data objects that comprise the // application. These objects are configured from the input database // and, if this is a restarted run, from the restart database. Pointer<AdvDiffHierarchyIntegrator> time_integrator; const string solver_type = main_db->getStringWithDefault("solver_type", "GODUNOV"); if (solver_type == "GODUNOV") { Pointer<AdvectorExplicitPredictorPatchOps> predictor = new AdvectorExplicitPredictorPatchOps("AdvectorExplicitPredictorPatchOps", app_initializer->getComponentDatabase("AdvectorExplicitPredictorPatchOps")); time_integrator = new AdvDiffPredictorCorrectorHierarchyIntegrator("AdvDiffPredictorCorrectorHierarchyIntegrator", app_initializer->getComponentDatabase("AdvDiffPredictorCorrectorHierarchyIntegrator"), predictor); } else if (solver_type == "SEMI_IMPLICIT") { time_integrator = new AdvDiffSemiImplicitHierarchyIntegrator("AdvDiffSemiImplicitHierarchyIntegrator", app_initializer->getComponentDatabase("AdvDiffSemiImplicitHierarchyIntegrator")); } else { TBOX_ERROR("Unsupported solver type: " << solver_type << "\n" << "Valid options are: GODUNOV, SEMI_IMPLICIT"); } Pointer<CartesianGridGeometry<NDIM> > grid_geometry = new CartesianGridGeometry<NDIM>("CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); Pointer<PatchHierarchy<NDIM> > patch_hierarchy = new PatchHierarchy<NDIM>("PatchHierarchy", grid_geometry); Pointer<StandardTagAndInitialize<NDIM> > error_detector = new StandardTagAndInitialize<NDIM>("StandardTagAndInitialize", time_integrator, app_initializer->getComponentDatabase("StandardTagAndInitialize")); Pointer<BergerRigoutsos<NDIM> > box_generator = new BergerRigoutsos<NDIM>(); Pointer<LoadBalancer<NDIM> > load_balancer = new LoadBalancer<NDIM>("LoadBalancer", app_initializer->getComponentDatabase("LoadBalancer")); Pointer<GriddingAlgorithm<NDIM> > gridding_algorithm = new GriddingAlgorithm<NDIM>("GriddingAlgorithm", app_initializer->getComponentDatabase("GriddingAlgorithm"), error_detector, box_generator, load_balancer); // Create an initial condition specification object. Pointer<CartGridFunction> u_init = new muParserCartGridFunction("u_init", app_initializer->getComponentDatabase("VelocityInitialConditions"), grid_geometry); // Create boundary condition specification objects (when necessary). const IntVector<NDIM>& periodic_shift = grid_geometry->getPeriodicShift(); vector<RobinBcCoefStrategy<NDIM>*> u_bc_coefs(NDIM); if (periodic_shift.min() > 0) { for (unsigned int d = 0; d < NDIM; ++d) { u_bc_coefs[d] = NULL; } } else { for (unsigned int d = 0; d < NDIM; ++d) { ostringstream bc_coefs_name_stream; bc_coefs_name_stream << "u_bc_coefs_" << d; const string bc_coefs_name = bc_coefs_name_stream.str(); ostringstream bc_coefs_db_name_stream; bc_coefs_db_name_stream << "VelocityBcCoefs_" << d; const string bc_coefs_db_name = bc_coefs_db_name_stream.str(); u_bc_coefs[d] = new muParserRobinBcCoefs(bc_coefs_name, app_initializer->getComponentDatabase(bc_coefs_db_name), grid_geometry); } } // Set up the advected and diffused quantity. Pointer<CellVariable<NDIM,double> > U_var = new CellVariable<NDIM,double>("U",NDIM); time_integrator->registerTransportedQuantity(U_var); time_integrator->setDiffusionCoefficient(U_var, input_db->getDouble("MU")/input_db->getDouble("RHO")); time_integrator->setInitialConditions(U_var, u_init); time_integrator->setPhysicalBcCoefs(U_var, u_bc_coefs); Pointer<FaceVariable<NDIM,double> > u_adv_var = new FaceVariable<NDIM,double>("u_adv"); time_integrator->registerAdvectionVelocity(u_adv_var); time_integrator->setAdvectionVelocityFunction(u_adv_var, u_init); time_integrator->setAdvectionVelocity(U_var, u_adv_var); if (input_db->keyExists("ForcingFunction")) { Pointer<CellVariable<NDIM,double> > F_var = new CellVariable<NDIM,double>("F",NDIM); Pointer<CartGridFunction> F_fcn = new muParserCartGridFunction("F_fcn", app_initializer->getComponentDatabase("ForcingFunction"), grid_geometry); time_integrator->registerSourceTerm(F_var); time_integrator->setSourceTermFunction(F_var, F_fcn); time_integrator->setSourceTerm(U_var, F_var); } // Set up visualization plot file writers. Pointer<VisItDataWriter<NDIM> > visit_data_writer = app_initializer->getVisItDataWriter(); if (uses_visit) { time_integrator->registerVisItDataWriter(visit_data_writer); } // Initialize hierarchy configuration and data on all patches. time_integrator->initializePatchHierarchy(patch_hierarchy, gridding_algorithm); // Deallocate initialization objects. app_initializer.setNull(); // Print the input database contents to the log file. plog << "Input database:\n"; input_db->printClassData(plog); // Write out initial visualization data. int iteration_num = time_integrator->getIntegratorStep(); double loop_time = time_integrator->getIntegratorTime(); if (dump_viz_data && uses_visit) { pout << "\n\nWriting visualization files...\n\n"; time_integrator->setupPlotData(); visit_data_writer->writePlotData(patch_hierarchy, iteration_num, loop_time); } // Main time step loop. double loop_time_end = time_integrator->getEndTime(); double dt = 0.0; while (!MathUtilities<double>::equalEps(loop_time,loop_time_end) && time_integrator->stepsRemaining()) { iteration_num = time_integrator->getIntegratorStep(); loop_time = time_integrator->getIntegratorTime(); pout << "\n"; pout << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n"; pout << "At beginning of timestep # " << iteration_num << "\n"; pout << "Simulation time is " << loop_time << "\n"; dt = time_integrator->getMaximumTimeStepSize(); time_integrator->advanceHierarchy(dt); loop_time += dt; pout << "\n"; pout << "At end of timestep # " << iteration_num << "\n"; pout << "Simulation time is " << loop_time << "\n"; pout << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n"; pout << "\n"; // At specified intervals, write visualization and restart files, // print out timer data, and store hierarchy data for post // processing. iteration_num += 1; const bool last_step = !time_integrator->stepsRemaining(); if (dump_viz_data && uses_visit && (iteration_num%viz_dump_interval == 0 || last_step)) { pout << "\nWriting visualization files...\n\n"; time_integrator->setupPlotData(); visit_data_writer->writePlotData(patch_hierarchy, iteration_num, loop_time); } if (dump_restart_data && (iteration_num%restart_dump_interval == 0 || last_step)) { pout << "\nWriting restart files...\n\n"; RestartManager::getManager()->writeRestartFile(restart_dump_dirname, iteration_num); } if (dump_timer_data && (iteration_num%timer_dump_interval == 0 || last_step)) { pout << "\nWriting timer data...\n\n"; TimerManager::getManager()->print(plog); } } // Determine the accuracy of the computed solution. pout << "\n" << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n" << "Computing error norms.\n\n"; VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase(); const Pointer<VariableContext> U_ctx = time_integrator->getCurrentContext(); const int U_idx = var_db->mapVariableAndContextToIndex(U_var, U_ctx); const int U_cloned_idx = var_db->registerClonedPatchDataIndex(U_var, U_idx); const int coarsest_ln = 0; const int finest_ln = patch_hierarchy->getFinestLevelNumber(); for (int ln = coarsest_ln; ln <= finest_ln; ++ln) { patch_hierarchy->getPatchLevel(ln)->allocatePatchData(U_cloned_idx, loop_time); } u_init->setDataOnPatchHierarchy(U_cloned_idx, U_var, patch_hierarchy, loop_time); HierarchyMathOps hier_math_ops("HierarchyMathOps", patch_hierarchy); hier_math_ops.setPatchHierarchy(patch_hierarchy); hier_math_ops.resetLevels(coarsest_ln, finest_ln); const int wgt_cc_idx = hier_math_ops.getCellWeightPatchDescriptorIndex(); HierarchyCellDataOpsReal<NDIM,double> hier_cc_data_ops(patch_hierarchy, coarsest_ln, finest_ln); hier_cc_data_ops.subtract(U_idx, U_idx, U_cloned_idx); pout << "Error in U at time " << loop_time << ":\n" << " L1-norm: " << hier_cc_data_ops. L1Norm(U_idx,wgt_cc_idx) << "\n" << " L2-norm: " << hier_cc_data_ops. L2Norm(U_idx,wgt_cc_idx) << "\n" << " max-norm: " << hier_cc_data_ops.maxNorm(U_idx,wgt_cc_idx) << "\n"; if (dump_viz_data && uses_visit) { time_integrator->setupPlotData(); visit_data_writer->writePlotData(patch_hierarchy, iteration_num+1, loop_time); } // Cleanup boundary condition specification objects (when necessary). for (unsigned int d = 0; d < NDIM; ++d) delete u_bc_coefs[d]; }// cleanup dynamically allocated objects prior to shutdown SAMRAIManager::shutdown(); PetscFinalize(); return 0; }// main
/******************************************************************************* * For each run, the input filename and restart information (if needed) must * * be given on the command line. For non-restarted case, command line is: * * * * executable <input file name> * * * * For restarted run, command line is: * * * * executable <input file name> <restart directory> <restart number> * * * *******************************************************************************/ int main( int argc, char *argv[]) { // Initialize MPI and SAMRAI. SAMRAI_MPI::init(&argc, &argv); SAMRAI_MPI::setCallAbortInSerialInsteadOfExit(); SAMRAIManager::startup(); {// cleanup dynamically allocated objects prior to shutdown // Parse command line options, set some standard options from the input // file, initialize the restart database (if this is a restarted run), // and enable file logging. Pointer<AppInitializer> app_initializer = new AppInitializer(argc, argv, "advect.log"); Pointer<Database> input_db = app_initializer->getInputDatabase(); Pointer<Database> main_db = app_initializer->getComponentDatabase("Main"); // Get various standard options set in the input file. const bool dump_viz_data = app_initializer->dumpVizData(); const int viz_dump_interval = app_initializer->getVizDumpInterval(); const bool uses_visit = dump_viz_data && app_initializer->getVisItDataWriter(); const bool dump_restart_data = app_initializer->dumpRestartData(); const int restart_dump_interval = app_initializer->getRestartDumpInterval(); const string restart_dump_dirname = app_initializer->getRestartDumpDirectory(); const bool dump_timer_data = app_initializer->dumpTimerData(); const int timer_dump_interval = app_initializer->getTimerDumpInterval(); // Get solver configuration options. bool using_refined_timestepping = false; if (main_db->keyExists("timestepping")) { string timestepping_method = main_db->getString("timestepping"); if (timestepping_method == "SYNCHRONIZED") { using_refined_timestepping = false; } else { using_refined_timestepping = true; } } if (using_refined_timestepping) { pout << "using subcycled timestepping.\n"; } else { pout << "NOT using subcycled timestepping.\n"; } // Create major algorithm and data objects that comprise the // application. These objects are configured from the input database // and, if this is a restarted run, from the restart database. Pointer<AdvectorExplicitPredictorStrategy> explicit_predictor = new AdvectorExplicitPredictorStrategy( "AdvectorExplicitPredictorStrategy", app_initializer->getComponentDatabase("AdvectorExplicitPredictorStrategy")); Pointer<CartesianGridGeometry<NDIM> > grid_geometry = new CartesianGridGeometry<NDIM>( "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); Pointer<AdvectorPredictorCorrectorHyperbolicPatchOps> hyp_patch_ops = new AdvectorPredictorCorrectorHyperbolicPatchOps( "AdvectorPredictorCorrectorHyperbolicPatchOps", app_initializer->getComponentDatabase("AdvectorPredictorCorrectorHyperbolicPatchOps"), explicit_predictor, grid_geometry); Pointer<HyperbolicLevelIntegrator<NDIM> > hyp_level_integrator = new HyperbolicLevelIntegrator<NDIM>( "HyperbolicLevelIntegrator", app_initializer->getComponentDatabase("HyperbolicLevelIntegrator"), hyp_patch_ops, true, using_refined_timestepping); Pointer<PatchHierarchy<NDIM> > patch_hierarchy = new PatchHierarchy<NDIM>( "PatchHierarchy", grid_geometry); Pointer<StandardTagAndInitialize<NDIM> > error_detector = new StandardTagAndInitialize<NDIM>( "StandardTagAndInitialize", hyp_level_integrator, app_initializer->getComponentDatabase("StandardTagAndInitialize")); Pointer<BergerRigoutsos<NDIM> > box_generator = new BergerRigoutsos<NDIM>(); Pointer<LoadBalancer<NDIM> > load_balancer = new LoadBalancer<NDIM>( "LoadBalancer", app_initializer->getComponentDatabase("LoadBalancer")); Pointer<GriddingAlgorithm<NDIM> > gridding_algorithm = new GriddingAlgorithm<NDIM>( "GriddingAlgorithm", app_initializer->getComponentDatabase("GriddingAlgorithm"), error_detector, box_generator, load_balancer); Pointer<TimeRefinementIntegrator<NDIM> > time_integrator = new TimeRefinementIntegrator<NDIM>( "TimeRefinementIntegrator", app_initializer->getComponentDatabase("TimeRefinementIntegrator"), patch_hierarchy, hyp_level_integrator, gridding_algorithm); // Setup the advection velocity. const bool u_is_div_free = main_db->getBoolWithDefault("u_is_div_free", false); if (u_is_div_free) { pout << "advection velocity u is discretely divergence free.\n"; } else { pout << "advection velocity u is NOT discretely divergence free.\n"; } Pointer<FaceVariable<NDIM,double> > u_var = new FaceVariable<NDIM,double>("u"); UFunction u_fcn("UFunction", grid_geometry, app_initializer->getComponentDatabase("UFunction")); hyp_patch_ops->registerAdvectionVelocity(u_var); hyp_patch_ops->setAdvectionVelocityIsDivergenceFree(u_var, u_is_div_free); hyp_patch_ops->setAdvectionVelocityFunction(u_var, Pointer<CartGridFunction>(&u_fcn,false)); // Setup the advected quantity. const ConvectiveDifferencingType difference_form = IBAMR::string_to_enum<ConvectiveDifferencingType>( main_db->getStringWithDefault( "difference_form", IBAMR::enum_to_string<ConvectiveDifferencingType>(ADVECTIVE))); pout << "solving the advection equation in " << enum_to_string<ConvectiveDifferencingType>(difference_form) << " form.\n"; Pointer<CellVariable<NDIM,double> > Q_var = new CellVariable<NDIM,double>("Q"); QInit Q_init("QInit", grid_geometry, app_initializer->getComponentDatabase("QInit")); LocationIndexRobinBcCoefs<NDIM> physical_bc_coef( "physical_bc_coef", app_initializer->getComponentDatabase("LocationIndexRobinBcCoefs")); hyp_patch_ops->registerTransportedQuantity(Q_var); hyp_patch_ops->setAdvectionVelocity(Q_var, u_var); hyp_patch_ops->setConvectiveDifferencingType(Q_var, difference_form); hyp_patch_ops->setInitialConditions(Q_var, Pointer<CartGridFunction>(&Q_init,false)); hyp_patch_ops->setPhysicalBcCoefs(Q_var, &physical_bc_coef); // Set up visualization plot file writer. Pointer<VisItDataWriter<NDIM> > visit_data_writer = app_initializer->getVisItDataWriter(); if (uses_visit) hyp_patch_ops->registerVisItDataWriter(visit_data_writer); // Initialize hierarchy configuration and data on all patches. double dt_now = time_integrator->initializeHierarchy(); // Deallocate initialization objects. app_initializer.setNull(); // Print the input database contents to the log file. plog << "Input database:\n"; input_db->printClassData(plog); // Write out initial visualization data. int iteration_num = time_integrator->getIntegratorStep(); double loop_time = time_integrator->getIntegratorTime(); if (dump_viz_data && uses_visit) { pout << "\n\nWriting visualization files...\n\n"; visit_data_writer->writePlotData(patch_hierarchy, iteration_num, loop_time); } // Main time step loop. double loop_time_end = time_integrator->getEndTime(); while (!MathUtilities<double>::equalEps(loop_time,loop_time_end) && time_integrator->stepsRemaining()) { iteration_num = time_integrator->getIntegratorStep(); loop_time = time_integrator->getIntegratorTime(); pout << "\n"; pout << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n"; pout << "At beginning of timestep # " << iteration_num << "\n"; pout << "Simulation time is " << loop_time << "\n"; double dt_new = time_integrator->advanceHierarchy(dt_now); loop_time += dt_now; dt_now = dt_new; pout << "\n"; pout << "At end of timestep # " << iteration_num << "\n"; pout << "Simulation time is " << loop_time << "\n"; pout << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n"; pout << "\n"; // At specified intervals, write visualization and restart files, // and print out timer data. iteration_num += 1; const bool last_step = !time_integrator->stepsRemaining(); if (dump_viz_data && uses_visit && (iteration_num%viz_dump_interval == 0 || last_step)) { pout << "\nWriting visualization files...\n\n"; visit_data_writer->writePlotData(patch_hierarchy, iteration_num, loop_time); } if (dump_restart_data && (iteration_num%restart_dump_interval == 0 || last_step)) { pout << "\nWriting restart files...\n\nn"; RestartManager::getManager()->writeRestartFile(restart_dump_dirname, iteration_num); } if (dump_timer_data && (iteration_num%timer_dump_interval == 0 || last_step)) { pout << "\nWriting timer data...\n\n"; TimerManager::getManager()->print(plog); } } // Determine the accuracy of the computed solution. pout << "\n" << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n" << "Computing error norms.\n\n"; VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase(); const Pointer<VariableContext> Q_ctx = hyp_level_integrator->getCurrentContext(); const int Q_idx = var_db->mapVariableAndContextToIndex(Q_var, Q_ctx); const int Q_cloned_idx = var_db->registerClonedPatchDataIndex(Q_var, Q_idx); const int coarsest_ln = 0; const int finest_ln = patch_hierarchy->getFinestLevelNumber(); for (int ln = coarsest_ln; ln <= finest_ln; ++ln) { patch_hierarchy->getPatchLevel(ln)->allocatePatchData(Q_cloned_idx, loop_time); } Q_init.setDataOnPatchHierarchy(Q_cloned_idx, Q_var, patch_hierarchy, loop_time); HierarchyMathOps hier_math_ops("HierarchyMathOps", patch_hierarchy); hier_math_ops.setPatchHierarchy(patch_hierarchy); hier_math_ops.resetLevels(coarsest_ln, finest_ln); const int wgt_idx = hier_math_ops.getCellWeightPatchDescriptorIndex(); HierarchyCellDataOpsReal<NDIM,double> hier_cc_data_ops(patch_hierarchy, coarsest_ln, finest_ln); hier_cc_data_ops.subtract(Q_idx, Q_idx, Q_cloned_idx); pout << "Error in " << Q_var->getName() << " at time " << loop_time << ":\n" << " L1-norm: " << hier_cc_data_ops.L1Norm(Q_idx,wgt_idx) << "\n" << " L2-norm: " << hier_cc_data_ops.L2Norm(Q_idx,wgt_idx) << "\n" << " max-norm: " << hier_cc_data_ops.maxNorm(Q_idx,wgt_idx) << "\n" << "+++++++++++++++++++++++++++++++++++++++++++++++++++\n"; if (dump_viz_data && uses_visit) { visit_data_writer->writePlotData(patch_hierarchy, iteration_num+1, loop_time); } }// cleanup dynamically allocated objects prior to shutdown SAMRAIManager::shutdown(); SAMRAI_MPI::finalize(); return 0; }// main
void LSLocateFluidInterface::setLevelSetPatchData(int D_idx, Pointer<HierarchyMathOps> hier_math_ops, double /*time*/, bool initial_time) { Pointer<PatchHierarchy<NDIM> > patch_hierarchy = hier_math_ops->getPatchHierarchy(); const int coarsest_ln = 0; const int finest_ln = patch_hierarchy->getFinestLevelNumber(); // If not the intial time, set the level set to the current value maintained by the integrator if (!initial_time) { VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase(); const int ls_current_idx = var_db->mapVariableAndContextToIndex(d_ls_var, d_adv_diff_solver->getCurrentContext()); HierarchyCellDataOpsReal<NDIM, double> hier_cc_data_ops(patch_hierarchy, coarsest_ln, finest_ln); hier_cc_data_ops.copyData(D_idx, ls_current_idx); return; } // Set the initial condition for locating the interface const double& R = d_init_circle.R; const IBTK::Vector& X0 = d_init_circle.X0; const double& film_height = d_init_film.height; const int height_dim = NDIM - 1; for (int ln = coarsest_ln; ln <= finest_ln; ++ln) { Pointer<PatchLevel<NDIM> > level = patch_hierarchy->getPatchLevel(ln); for (PatchLevel<NDIM>::Iterator p(level); p; p++) { Pointer<Patch<NDIM> > patch = level->getPatch(p()); const Box<NDIM>& patch_box = patch->getBox(); Pointer<CellData<NDIM, double> > D_data = patch->getPatchData(D_idx); for (Box<NDIM>::Iterator it(patch_box); it; it++) { CellIndex<NDIM> ci(it()); // Get physical coordinates IBTK::Vector coord = IBTK::Vector::Zero(); Pointer<CartesianPatchGeometry<NDIM> > patch_geom = patch->getPatchGeometry(); const double* patch_X_lower = patch_geom->getXLower(); const hier::Index<NDIM>& patch_lower_idx = patch_box.lower(); const double* const patch_dx = patch_geom->getDx(); for (int d = 0; d < NDIM; ++d) { coord[d] = patch_X_lower[d] + patch_dx[d] * (static_cast<double>(ci(d) - patch_lower_idx(d)) + 0.5); } // Distance from the bubble const double distance_bubble = std::sqrt(std::pow((coord[0] - X0(0)), 2.0) + std::pow((coord[1] - X0(1)), 2.0) #if (NDIM == 3) + std::pow((coord[2] - X0(2)), 2.0) #endif ) - R; // Distance from the film const double distance_film = coord[height_dim] - film_height; if (distance_film <= 0) { // If within the film, set LS as the negative distance away (*D_data)(ci) = distance_film; } else if (distance_bubble <= 0) { // If within the bubble, again set the LS as the negative distance away (*D_data)(ci) = distance_bubble; } else { // Otherwise, set the distance as the minimum between the two (*D_data)(ci) = std::min(distance_bubble, distance_film); } } } } return; } // setLevelSetPatchData