diff --git a/examples/IB/explicit/ex0/example.cpp b/examples/IB/explicit/ex0/example.cpp index b2b012402b..bd8acdd60b 100644 --- a/examples/IB/explicit/ex0/example.cpp +++ b/examples/IB/explicit/ex0/example.cpp @@ -25,6 +25,7 @@ // Headers for application-specific algorithm/data structure objects #include +#include #include #include #include @@ -297,12 +298,27 @@ main(int argc, char* argv[]) TBOX_ERROR("Unsupported solver type: " << solver_type << "\n" << "Valid options are: COLLOCATED, STAGGERED"); } + Pointer ib_method_ops = new IBMethod("IBMethod", app_initializer->getComponentDatabase("IBMethod")); - Pointer time_integrator = - new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", - app_initializer->getComponentDatabase("IBHierarchyIntegrator"), - ib_method_ops, - navier_stokes_integrator); + Pointer time_integrator; + const string ib_time_stepping_type = + app_initializer->getComponentDatabase("Main")->getStringWithDefault("ib_time_stepping_type", "EXPLICIT"); + if (ib_time_stepping_type == "EXPLICIT") + { + time_integrator = + new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } + else + { + time_integrator = + new IBImplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } Pointer > grid_geometry = new CartesianGridGeometry( "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); Pointer > patch_hierarchy = new PatchHierarchy("PatchHierarchy", grid_geometry); diff --git a/examples/IB/explicit/ex1/example.cpp b/examples/IB/explicit/ex1/example.cpp index 72630d3a97..9528f7aa99 100644 --- a/examples/IB/explicit/ex1/example.cpp +++ b/examples/IB/explicit/ex1/example.cpp @@ -24,7 +24,9 @@ #include // Headers for application-specific algorithm/data structure objects +#include "ibamr/IBHierarchyIntegrator.h" #include +#include #include #include #include @@ -120,11 +122,25 @@ main(int argc, char* argv[]) << "Valid options are: COLLOCATED, STAGGERED"); } Pointer ib_method_ops = new IBMethod("IBMethod", app_initializer->getComponentDatabase("IBMethod")); - Pointer time_integrator = - new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", - app_initializer->getComponentDatabase("IBHierarchyIntegrator"), - ib_method_ops, - navier_stokes_integrator); + Pointer time_integrator; + const string ib_time_stepping_type = + app_initializer->getComponentDatabase("Main")->getStringWithDefault("ib_time_stepping_type", "EXPLICIT"); + if (ib_time_stepping_type == "EXPLICIT") + { + time_integrator = + new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } + else + { + time_integrator = + new IBImplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } Pointer > grid_geometry = new CartesianGridGeometry( "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); Pointer > patch_hierarchy = new PatchHierarchy("PatchHierarchy", grid_geometry); diff --git a/examples/IB/explicit/ex2/example.cpp b/examples/IB/explicit/ex2/example.cpp index 83669d315f..0c19c1db2d 100644 --- a/examples/IB/explicit/ex2/example.cpp +++ b/examples/IB/explicit/ex2/example.cpp @@ -25,6 +25,7 @@ // Headers for application-specific algorithm/data structure objects #include +#include #include #include #include @@ -111,11 +112,25 @@ main(int argc, char* argv[]) << "Valid options are: COLLOCATED, STAGGERED"); } Pointer ib_method_ops = new IBMethod("IBMethod", app_initializer->getComponentDatabase("IBMethod")); - Pointer time_integrator = - new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", - app_initializer->getComponentDatabase("IBHierarchyIntegrator"), - ib_method_ops, - navier_stokes_integrator); + Pointer time_integrator; + const string ib_time_stepping_type = + app_initializer->getComponentDatabase("Main")->getStringWithDefault("ib_time_stepping_type", "EXPLICIT"); + if (ib_time_stepping_type == "EXPLICIT") + { + time_integrator = + new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } + else + { + time_integrator = + new IBImplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } Pointer > grid_geometry = new CartesianGridGeometry( "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); Pointer > patch_hierarchy = new PatchHierarchy("PatchHierarchy", grid_geometry); diff --git a/examples/IB/explicit/ex5/example.cpp b/examples/IB/explicit/ex5/example.cpp index 668c680704..8ebc6ca832 100644 --- a/examples/IB/explicit/ex5/example.cpp +++ b/examples/IB/explicit/ex5/example.cpp @@ -25,6 +25,7 @@ // Headers for application-specific algorithm/data structure objects #include +#include #include #include #include @@ -105,11 +106,25 @@ main(int argc, char* argv[]) "INSStaggeredHierarchyIntegrator", app_initializer->getComponentDatabase("INSStaggeredHierarchyIntegrator")); Pointer ib_method_ops = new IBMethod("IBMethod", app_initializer->getComponentDatabase("IBMethod")); - Pointer time_integrator = - new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", - app_initializer->getComponentDatabase("IBHierarchyIntegrator"), - ib_method_ops, - navier_stokes_integrator); + Pointer time_integrator; + const string ib_time_stepping_type = + app_initializer->getComponentDatabase("Main")->getStringWithDefault("ib_time_stepping_type", "EXPLICIT"); + if (ib_time_stepping_type == "EXPLICIT") + { + time_integrator = + new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } + else + { + time_integrator = + new IBImplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } Pointer > grid_geometry = new CartesianGridGeometry( "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); Pointer > patch_hierarchy = new PatchHierarchy("PatchHierarchy", grid_geometry); diff --git a/examples/IBFE/explicit/ex0/example.cpp b/examples/IBFE/explicit/ex0/example.cpp index 7042901177..4e53440159 100644 --- a/examples/IBFE/explicit/ex0/example.cpp +++ b/examples/IBFE/explicit/ex0/example.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -219,11 +220,25 @@ main(int argc, char* argv[]) /*register_for_restart*/ true, restart_read_dirname, restart_restore_num); - Pointer time_integrator = - new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", - app_initializer->getComponentDatabase("IBHierarchyIntegrator"), - ib_method_ops, - navier_stokes_integrator); + Pointer time_integrator; + const string ib_time_stepping_type = + app_initializer->getComponentDatabase("Main")->getStringWithDefault("ib_time_stepping_type", "EXPLICIT"); + if (ib_time_stepping_type == "EXPLICIT") + { + time_integrator = + new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } + else + { + time_integrator = + new IBImplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } Pointer > grid_geometry = new CartesianGridGeometry( "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); Pointer > patch_hierarchy = new PatchHierarchy("PatchHierarchy", grid_geometry); diff --git a/examples/IBFE/explicit/ex1/example.cpp b/examples/IBFE/explicit/ex1/example.cpp index 5b13387c36..012ede1a14 100644 --- a/examples/IBFE/explicit/ex1/example.cpp +++ b/examples/IBFE/explicit/ex1/example.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -216,11 +217,25 @@ main(int argc, char* argv[]) /*register_for_restart*/ true, restart_read_dirname, restart_restore_num); - Pointer time_integrator = - new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", - app_initializer->getComponentDatabase("IBHierarchyIntegrator"), - ib_method_ops, - navier_stokes_integrator); + Pointer time_integrator; + const string ib_time_stepping_type = + app_initializer->getComponentDatabase("Main")->getStringWithDefault("ib_time_stepping_type", "EXPLICIT"); + if (ib_time_stepping_type == "EXPLICIT") + { + time_integrator = + new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } + else + { + time_integrator = + new IBImplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } Pointer > grid_geometry = new CartesianGridGeometry( "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); Pointer > patch_hierarchy = new PatchHierarchy("PatchHierarchy", grid_geometry); diff --git a/examples/IBFE/explicit/ex2/example.cpp b/examples/IBFE/explicit/ex2/example.cpp index 072f7ab788..42251b7778 100644 --- a/examples/IBFE/explicit/ex2/example.cpp +++ b/examples/IBFE/explicit/ex2/example.cpp @@ -34,6 +34,7 @@ // Headers for application-specific algorithm/data structure objects #include #include +#include #include #include @@ -244,11 +245,25 @@ main(int argc, char* argv[]) /*register_for_restart*/ true, restart_read_dirname, restart_restore_num); - Pointer time_integrator = - new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", - app_initializer->getComponentDatabase("IBHierarchyIntegrator"), - ib_method_ops, - navier_stokes_integrator); + Pointer time_integrator; + const string ib_time_stepping_type = + app_initializer->getComponentDatabase("Main")->getStringWithDefault("ib_time_stepping_type", "EXPLICIT"); + if (ib_time_stepping_type == "EXPLICIT") + { + time_integrator = + new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } + else + { + time_integrator = + new IBImplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } Pointer > grid_geometry = new CartesianGridGeometry( "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); Pointer > patch_hierarchy = new PatchHierarchy("PatchHierarchy", grid_geometry); diff --git a/examples/IBFE/explicit/ex3/example.cpp b/examples/IBFE/explicit/ex3/example.cpp index 3c1ce8ce48..b2eb4612a6 100644 --- a/examples/IBFE/explicit/ex3/example.cpp +++ b/examples/IBFE/explicit/ex3/example.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -227,11 +228,25 @@ main(int argc, char* argv[]) /*register_for_restart*/ true, restart_read_dirname, restart_restore_num); - Pointer time_integrator = - new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", - app_initializer->getComponentDatabase("IBHierarchyIntegrator"), - ib_method_ops, - navier_stokes_integrator); + Pointer time_integrator; + const string ib_time_stepping_type = + app_initializer->getComponentDatabase("Main")->getStringWithDefault("ib_time_stepping_type", "EXPLICIT"); + if (ib_time_stepping_type == "EXPLICIT") + { + time_integrator = + new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } + else + { + time_integrator = + new IBImplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } Pointer > grid_geometry = new CartesianGridGeometry( "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); Pointer > patch_hierarchy = new PatchHierarchy("PatchHierarchy", grid_geometry); diff --git a/examples/IBFE/explicit/ex4/example.cpp b/examples/IBFE/explicit/ex4/example.cpp index dec9553240..1f4b016d6f 100644 --- a/examples/IBFE/explicit/ex4/example.cpp +++ b/examples/IBFE/explicit/ex4/example.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -70,6 +71,7 @@ coordinate_mapping_function(libMesh::Point& X, const libMesh::Point& s, void* /* static double c1_s = 0.05; static double p0_s = 0.0; static double beta_s = 0.0; + void PK1_dev_stress_function(TensorValue& PP, const TensorValue& FF, @@ -81,7 +83,10 @@ PK1_dev_stress_function(TensorValue& PP, double /*time*/, void* /*ctx*/) { - PP = 2.0 * c1_s * FF; + const auto CC = FF.transpose() * FF; + const auto I1 = CC.tr(); + const auto dI1_bar_dFF = pow(FF.det(), -2.0 / 3.0) * (FF - I1 / 3.0 * tensor_inverse_transpose(FF, NDIM)); + PP = 2.0 * c1_s * dI1_bar_dFF; return; } // PK1_dev_stress_function @@ -96,7 +101,9 @@ PK1_dil_stress_function(TensorValue& PP, double /*time*/, void* /*ctx*/) { - PP = 2.0 * (-p0_s + beta_s * log(FF.det())) * tensor_inverse_transpose(FF, NDIM); + const auto FF_inv_trans = tensor_inverse_transpose(FF, NDIM); + const auto J = FF.det(); + PP = beta_s * J * log(J) * FF_inv_trans; return; } // PK1_dil_stress_function } // namespace ModelData @@ -267,13 +274,26 @@ main(int argc, char* argv[]) /*register_for_restart*/ true, restart_read_dirname, restart_restore_num); - Pointer time_integrator = - new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", - app_initializer->getComponentDatabase("IBHierarchyIntegrator"), - ib_method_ops, - navier_stokes_integrator); + Pointer time_integrator; + const string ib_time_stepping_type = + app_initializer->getComponentDatabase("Main")->getStringWithDefault("ib_time_stepping_type", "EXPLICIT"); + if (ib_time_stepping_type == "EXPLICIT") + { + time_integrator = + new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } + else + { + time_integrator = + new IBImplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_method_ops, + navier_stokes_integrator); + } time_integrator->registerLoadBalancer(load_balancer); - Pointer > error_detector = new StandardTagAndInitialize("StandardTagAndInitialize", time_integrator, @@ -435,7 +455,11 @@ main(int argc, char* argv[]) #endif } } - time_integrator->setMarkers(positions); + if (ib_time_stepping_type == "EXPLICIT") + { + Pointer explicit_time_integrator = time_integrator; + explicit_time_integrator->setMarkers(positions); + } } // Write out initial visualization data. @@ -450,9 +474,10 @@ main(int argc, char* argv[]) equation_systems->get_system(ib_method_ops->getCurrentCoordinatesSystemName()); time_integrator->setupPlotData(); visit_data_writer->writePlotData(patch_hierarchy, iteration_num, loop_time); - if (use_markers) + if (use_markers && ib_time_stepping_type == "EXPLICIT") { - time_integrator->writeMarkerPlotData(iteration_num, loop_time); + Pointer explicit_time_integrator = time_integrator; + explicit_time_integrator->writeMarkerPlotData(iteration_num, loop_time); } if (NDIM < 3 && input_db->getBoolWithDefault("save_extra_partitioning", false)) { @@ -491,8 +516,8 @@ main(int argc, char* argv[]) pout << "At beginning of timestep # " << iteration_num << "\n"; pout << "Simulation time is " << loop_time << "\n"; - dt = time_integrator->getMaximumTimeStepSize(); - time_integrator->advanceHierarchy(dt); + const auto dt_max = time_integrator->getMaximumTimeStepSize(); + dt = time_integrator->advanceHierarchy(dt_max); loop_time += dt; pout << "\n"; @@ -515,9 +540,10 @@ main(int argc, char* argv[]) equation_systems->get_system(ib_method_ops->getCurrentCoordinatesSystemName()); time_integrator->setupPlotData(); visit_data_writer->writePlotData(patch_hierarchy, iteration_num, loop_time); - if (use_markers) + if (use_markers && ib_time_stepping_type == "EXPLICIT") { - time_integrator->writeMarkerPlotData(iteration_num, loop_time); + Pointer explicit_time_integrator = time_integrator; + explicit_time_integrator->writeMarkerPlotData(iteration_num, loop_time); } if (NDIM < 3 && input_db->getBoolWithDefault("save_extra_partitioning", false)) { diff --git a/examples/IBFE/explicit/ex4/input2d.implicit b/examples/IBFE/explicit/ex4/input2d.implicit new file mode 100644 index 0000000000..2ce2a42464 --- /dev/null +++ b/examples/IBFE/explicit/ex4/input2d.implicit @@ -0,0 +1,229 @@ +// physical parameters +MU = 0.01 +RHO = 1.0 +L = 1.0 + +// grid spacing parameters +MAX_LEVELS = 1 // maximum number of levels in locally refined grid +REF_RATIO = 2 // refinement ratio between levels +N = 64 // actual number of grid cells on coarsest grid level +NFINEST = (REF_RATIO^(MAX_LEVELS - 1))*N // effective number of grid cells on finest grid level +DX0 = L/N // mesh width on coarsest grid level +DX = L/NFINEST // mesh width on finest grid level +MFAC = 2.0 // ratio of Lagrangian mesh width to Cartesian mesh width +ELEM_TYPE = "TRI6" // type of element to use for structure discretization +PK1_DEV_QUAD_ORDER = "FIFTH" +PK1_DIL_QUAD_ORDER = "THIRD" + +// model parameters +U_MAX = 2.0 +C1_S = 100.0*0.625*5000.0 +P0_S = C1_S +BETA_S = 1.0*(NFINEST/64.0) + +// solver parameters +IB_DELTA_FUNCTION = "IB_4" // the type of smoothed delta function to use for Lagrangian-Eulerian interaction +SPLIT_FORCES = FALSE // whether to split interior and boundary forces +USE_JUMP_CONDITIONS = FALSE // whether to impose pressure jumps at fluid-structure interfaces +USE_CONSISTENT_MASS_MATRIX = TRUE // whether to use a consistent or lumped mass matrix +IB_POINT_DENSITY = 3.0 // approximate density of IB quadrature points for Lagrangian-Eulerian interaction +SOLVER_TYPE = "STAGGERED" // the fluid solver to use (STAGGERED or COLLOCATED) +CFL_MAX = 0.1 // maximum CFL number +DT = 10.0*.25*CFL_MAX*DX/U_MAX // maximum timestep size +START_TIME = 0.0e0 // initial simulation time +END_TIME = 100.0 // final simulation time +GROW_DT = 2.0e0 // growth factor for timesteps +NUM_CYCLES = 1 // number of cycles of fixed-point iteration +CONVECTIVE_TS_TYPE = "ADAMS_BASHFORTH" // convective time stepping type +CONVECTIVE_OP_TYPE = "PPM" // convective differencing discretization type +CONVECTIVE_FORM = "ADVECTIVE" // how to compute the convective terms +NORMALIZE_PRESSURE = FALSE // whether to explicitly force the pressure to have mean zero +ERROR_ON_DT_CHANGE = FALSE // whether to emit an error message if the time step size changes +VORTICITY_TAGGING = TRUE // whether to tag cells for refinement based on vorticity thresholds +TAG_BUFFER = 1 // size of tag buffer used by grid generation algorithm +REGRID_CFL_INTERVAL = 0.5 // regrid whenever any material point could have moved 0.5 meshwidths since previous regrid +OUTPUT_U = TRUE +OUTPUT_P = TRUE +OUTPUT_F = TRUE +OUTPUT_OMEGA = TRUE +OUTPUT_DIV_U = TRUE +ENABLE_LOGGING = TRUE + +// collocated solver parameters +PROJECTION_METHOD_TYPE = "PRESSURE_UPDATE" +SECOND_ORDER_PRESSURE_UPDATE = TRUE + +VelocityBcCoefs_0 { + acoef_function_0 = "1.0" + acoef_function_1 = "1.0" + acoef_function_2 = "1.0" + acoef_function_3 = "1.0" + + bcoef_function_0 = "0.0" + bcoef_function_1 = "0.0" + bcoef_function_2 = "0.0" + bcoef_function_3 = "0.0" + + gcoef_function_0 = "0.0" + gcoef_function_1 = "0.0" + gcoef_function_2 = "0.0" + gcoef_function_3 = "1.0" +} + +VelocityBcCoefs_1 { + acoef_function_0 = "1.0" + acoef_function_1 = "1.0" + acoef_function_2 = "1.0" + acoef_function_3 = "1.0" + + bcoef_function_0 = "0.0" + bcoef_function_1 = "0.0" + bcoef_function_2 = "0.0" + bcoef_function_3 = "0.0" + + gcoef_function_0 = "0.0" + gcoef_function_1 = "0.0" + gcoef_function_2 = "0.0" + gcoef_function_3 = "0.0" +} + +IBHierarchyIntegrator { + start_time = START_TIME + end_time = END_TIME + grow_dt = GROW_DT + num_cycles = NUM_CYCLES + regrid_cfl_interval = REGRID_CFL_INTERVAL + dt_init = 0.001*DT + dt_max = 100.0*DT + dt_min = DT/1000.0 + error_on_dt_change = ERROR_ON_DT_CHANGE + enable_logging = ENABLE_LOGGING + + //time_stepping_type = "BACKWARD_EULER" + solve_for_position = TRUE + //eta = 100.0 * RHO / DT +} + +IBFEMethod { + IB_delta_fcn = IB_DELTA_FUNCTION + split_forces = SPLIT_FORCES + use_jump_conditions = USE_JUMP_CONDITIONS + use_consistent_mass_matrix = USE_CONSISTENT_MASS_MATRIX + IB_point_density = IB_POINT_DENSITY +} + +INSCollocatedHierarchyIntegrator { + mu = MU + rho = RHO + start_time = START_TIME + end_time = END_TIME + grow_dt = GROW_DT + convective_time_stepping_type = CONVECTIVE_TS_TYPE + convective_op_type = CONVECTIVE_OP_TYPE + convective_difference_form = CONVECTIVE_FORM + normalize_pressure = NORMALIZE_PRESSURE + cfl = CFL_MAX + dt_max = DT + using_vorticity_tagging = VORTICITY_TAGGING + vorticity_rel_thresh = 0.01 + tag_buffer = TAG_BUFFER + output_U = OUTPUT_U + output_P = OUTPUT_P + output_F = OUTPUT_F + output_Omega = OUTPUT_OMEGA + output_Div_U = OUTPUT_DIV_U + enable_logging = ENABLE_LOGGING + projection_method_type = PROJECTION_METHOD_TYPE + use_2nd_order_pressure_update = SECOND_ORDER_PRESSURE_UPDATE +} + +INSStaggeredHierarchyIntegrator { + mu = MU + rho = RHO + start_time = START_TIME + end_time = END_TIME + grow_dt = GROW_DT + convective_time_stepping_type = CONVECTIVE_TS_TYPE + convective_op_type = CONVECTIVE_OP_TYPE + convective_difference_form = CONVECTIVE_FORM + normalize_pressure = NORMALIZE_PRESSURE + cfl = CFL_MAX + dt_max = DT + using_vorticity_tagging = VORTICITY_TAGGING + vorticity_rel_thresh = 0.01 + tag_buffer = TAG_BUFFER + output_U = OUTPUT_U + output_P = OUTPUT_P + output_F = OUTPUT_F + output_Omega = OUTPUT_OMEGA + output_Div_U = OUTPUT_DIV_U + enable_logging = ENABLE_LOGGING +} + +Main { + solver_type = SOLVER_TYPE + ib_time_stepping_type = "IMPLICIT" + +// log file parameters + log_file_name = "IB2d.log" + log_all_nodes = FALSE + +// visualization dump parameters + viz_writer = "VisIt","ExodusII" + viz_dump_interval = int(0.125/DT) + viz_dump_dirname = "viz_IB2d" + visit_number_procs_per_file = 1 + +// restart dump parameters + restart_dump_interval = 0 + restart_dump_dirname = "restart_IB2d" + +// hierarchy data dump parameters + data_dump_interval = 0 + data_dump_dirname = "hier_data_IB2d" + +// timer dump parameters + timer_dump_interval = 0 +} + +CartesianGeometry { + domain_boxes = [ (0,0),(N - 1,N - 1) ] + x_lo = 0,0 + x_up = L,L + periodic_dimension = 0,0 +} + +GriddingAlgorithm { + max_levels = MAX_LEVELS + ratio_to_coarser { + level_1 = REF_RATIO,REF_RATIO + level_2 = REF_RATIO,REF_RATIO + level_3 = REF_RATIO,REF_RATIO + level_4 = REF_RATIO,REF_RATIO + level_5 = REF_RATIO,REF_RATIO + } + largest_patch_size { + level_0 = 512,512 // all finer levels will use same values as level_0 + } + smallest_patch_size { + level_0 = 8, 8 // all finer levels will use same values as level_0 + } + efficiency_tolerance = 0.85e0 // min % of tag cells in new patch level + combine_efficiency = 0.85e0 // chop box if sum of volumes of smaller boxes < efficiency * vol of large box +} + +StandardTagAndInitialize { + tagging_method = "GRADIENT_DETECTOR" +} + +LoadBalancer { + bin_pack_method = "SPATIAL" + max_workload_factor = 1 +} + +TimerManager{ + print_exclusive = FALSE + print_total = TRUE + print_threshold = 0.1 + timer_list = "IBAMR::*::*","IBTK::*::*","*::*::*" +} diff --git a/examples/IBFE/explicit/ex5/example.cpp b/examples/IBFE/explicit/ex5/example.cpp index f8fc17e066..bc047dd4ea 100644 --- a/examples/IBFE/explicit/ex5/example.cpp +++ b/examples/IBFE/explicit/ex5/example.cpp @@ -35,7 +35,7 @@ // Headers for application-specific algorithm/data structure objects #include #include -#include +#include #include #include @@ -311,18 +311,13 @@ main(int argc, char* argv[]) } } solid_mesh.prepare_for_use(); - - BoundaryMesh boundary_mesh(solid_mesh.comm(), solid_mesh.mesh_dimension() - 1); - BoundaryInfo& boundary_info = solid_mesh.get_boundary_info(); - boundary_info.sync(boundary_mesh); - boundary_mesh.prepare_for_use(); - - bool use_boundary_mesh = input_db->getBoolWithDefault("USE_BOUNDARY_MESH", false); - Mesh& mesh = use_boundary_mesh ? boundary_mesh : solid_mesh; + Mesh& mesh = solid_mesh; // 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 > grid_geometry = new CartesianGridGeometry( + "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); Pointer navier_stokes_integrator; const string solver_type = app_initializer->getComponentDatabase("Main")->getString("solver_type"); if (solver_type == "STAGGERED") @@ -342,36 +337,34 @@ main(int argc, char* argv[]) TBOX_ERROR("Unsupported solver type: " << solver_type << "\n" << "Valid options are: COLLOCATED, STAGGERED"); } - Pointer ib_ops; - if (use_boundary_mesh) + Pointer ib_ops = + new IBFEMethod("IBFEMethod", + app_initializer->getComponentDatabase("IBFEMethod"), + &mesh, + app_initializer->getComponentDatabase("GriddingAlgorithm")->getInteger("max_levels"), + /*register_for_restart*/ true, + restart_read_dirname, + restart_restore_num); + Pointer time_integrator; + const string ib_time_stepping_type = + app_initializer->getComponentDatabase("Main")->getStringWithDefault("ib_time_stepping_type", "EXPLICIT"); + if (ib_time_stepping_type == "EXPLICIT") { - ib_ops = new IBFESurfaceMethod( - "IBFEMethod", - app_initializer->getComponentDatabase("IBFEMethod"), - &mesh, - app_initializer->getComponentDatabase("GriddingAlgorithm")->getInteger("max_levels"), - /*register_for_restart*/ true, - restart_read_dirname, - restart_restore_num); + time_integrator = + new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_ops, + navier_stokes_integrator); } else { - ib_ops = - new IBFEMethod("IBFEMethod", - app_initializer->getComponentDatabase("IBFEMethod"), - &mesh, - app_initializer->getComponentDatabase("GriddingAlgorithm")->getInteger("max_levels"), - /*register_for_restart*/ true, - restart_read_dirname, - restart_restore_num); + time_integrator = + new IBImplicitHierarchyIntegrator("IBHierarchyIntegrator", + app_initializer->getComponentDatabase("IBHierarchyIntegrator"), + ib_ops, + navier_stokes_integrator); } - Pointer time_integrator = - new IBExplicitHierarchyIntegrator("IBHierarchyIntegrator", - app_initializer->getComponentDatabase("IBHierarchyIntegrator"), - ib_ops, - navier_stokes_integrator); - Pointer > grid_geometry = new CartesianGridGeometry( - "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry")); + Pointer > patch_hierarchy = new PatchHierarchy("PatchHierarchy", grid_geometry); Pointer > error_detector = new StandardTagAndInitialize("StandardTagAndInitialize", @@ -394,42 +387,26 @@ main(int argc, char* argv[]) std::string coords_system_name, velocity_system_name; std::vector vars(NDIM); for (unsigned int d = 0; d < NDIM; ++d) vars[d] = d; - if (use_boundary_mesh) + ib_ops->initializeFEEquationSystems(); + equation_systems = ib_ops->getFEDataManager()->getEquationSystems(); + coords_system_name = ib_ops->getCurrentCoordinatesSystemName(); + velocity_system_name = ib_ops->getVelocitySystemName(); + vector sys_data(1, SystemData(velocity_system_name, vars)); + IBFEMethod::PK1StressFcnData PK1_stress_data( + PK1_stress_function, std::vector(), tether_data_ptr); + PK1_stress_data.quad_order = + Utility::string_to_enum(input_db->getStringWithDefault("PK1_QUAD_ORDER", "THIRD")); + ib_ops->registerPK1StressFunction(PK1_stress_data); + + IBFEMethod::LagBodyForceFcnData body_fcn_data(tether_force_function, sys_data, tether_data_ptr); + ib_ops->registerLagBodyForceFunction(body_fcn_data); + + IBFEMethod::LagSurfaceForceFcnData surface_fcn_data(tether_force_function, sys_data, tether_data_ptr); + ib_ops->registerLagSurfaceForceFunction(surface_fcn_data); + + if (input_db->getBoolWithDefault("ELIMINATE_PRESSURE_JUMPS", false)) { - Pointer ibfe_ops = ib_ops; - ibfe_ops->initializeFEEquationSystems(); - equation_systems = ibfe_ops->getFEDataManager()->getEquationSystems(); - coords_system_name = IBFESurfaceMethod::COORDS_SYSTEM_NAME; - velocity_system_name = IBFESurfaceMethod::VELOCITY_SYSTEM_NAME; - vector sys_data(1, SystemData(velocity_system_name, vars)); - IBFESurfaceMethod::LagSurfaceForceFcnData surface_fcn_data( - tether_force_function, sys_data, tether_data_ptr); - ibfe_ops->registerLagSurfaceForceFunction(surface_fcn_data); - } - else - { - Pointer ibfe_ops = ib_ops; - ibfe_ops->initializeFEEquationSystems(); - equation_systems = ibfe_ops->getFEDataManager()->getEquationSystems(); - coords_system_name = ibfe_ops->getCurrentCoordinatesSystemName(); - velocity_system_name = ibfe_ops->getVelocitySystemName(); - vector sys_data(1, SystemData(velocity_system_name, vars)); - IBFEMethod::PK1StressFcnData PK1_stress_data( - PK1_stress_function, std::vector(), tether_data_ptr); - PK1_stress_data.quad_order = - Utility::string_to_enum(input_db->getStringWithDefault("PK1_QUAD_ORDER", "THIRD")); - ibfe_ops->registerPK1StressFunction(PK1_stress_data); - - IBFEMethod::LagBodyForceFcnData body_fcn_data(tether_force_function, sys_data, tether_data_ptr); - ibfe_ops->registerLagBodyForceFunction(body_fcn_data); - - IBFEMethod::LagSurfaceForceFcnData surface_fcn_data(tether_force_function, sys_data, tether_data_ptr); - ibfe_ops->registerLagSurfaceForceFunction(surface_fcn_data); - - if (input_db->getBoolWithDefault("ELIMINATE_PRESSURE_JUMPS", false)) - { - ibfe_ops->registerStressNormalizationPart(); - } + ib_ops->registerStressNormalizationPart(); } // Create Eulerian initial condition specification objects. @@ -495,16 +472,7 @@ main(int argc, char* argv[]) } // Initialize hierarchy configuration and data on all patches. - if (use_boundary_mesh) - { - Pointer ibfe_ops = ib_ops; - ibfe_ops->initializeFEData(); - } - else - { - Pointer ibfe_ops = ib_ops; - ibfe_ops->initializeFEData(); - } + ib_ops->initializeFEData(); time_integrator->initializePatchHierarchy(patch_hierarchy, gridding_algorithm); // Deallocate initialization objects. @@ -595,15 +563,7 @@ main(int argc, char* argv[]) { pout << "\nWriting restart files...\n\n"; RestartManager::getManager()->writeRestartFile(restart_dump_dirname, iteration_num); - if (use_boundary_mesh) - { - dynamic_cast(*ib_ops).writeFEDataToRestartFile(restart_dump_dirname, - iteration_num); - } - else - { - dynamic_cast(*ib_ops).writeFEDataToRestartFile(restart_dump_dirname, iteration_num); - } + ib_ops->writeFEDataToRestartFile(restart_dump_dirname, iteration_num); } if (dump_timer_data && (iteration_num % timer_dump_interval == 0 || last_step)) { diff --git a/examples/IBFE/explicit/ex5/input2d.implicit b/examples/IBFE/explicit/ex5/input2d.implicit new file mode 100644 index 0000000000..c439ef1db0 --- /dev/null +++ b/examples/IBFE/explicit/ex5/input2d.implicit @@ -0,0 +1,239 @@ +// physical parameters +Re = 200.0 +MU = 1.0/Re +RHO = 1.0 + +// grid spacing parameters +L = 16.0 // width of computational domain +MAX_LEVELS = 5 // maximum number of levels in locally refined grid +REF_RATIO = 2 // refinement ratio between levels +N = 16 // actual number of grid cells on coarsest grid level +NFINEST = (REF_RATIO^(MAX_LEVELS - 1))*N // effective number of grid cells on finest grid level +DX0 = L/N // mesh width on coarsest grid level +DX = L/NFINEST // mesh width on finest grid level +MFAC = 2.0 // ratio of Lagrangian mesh width to Cartesian mesh width +ELEM_TYPE = "TRI3" // type of element to use for structure discretization +PK1_DEV_QUAD_ORDER = "SEVENTH" +PK1_DIL_QUAD_ORDER = "FIFTH" +USE_BOUNDARY_MESH = TRUE + +// solver parameters +IB_DELTA_FUNCTION = "IB_4" // the type of smoothed delta function to use for Lagrangian-Eulerian interaction +SPLIT_FORCES = FALSE // whether to split interior and boundary forces +USE_JUMP_CONDITIONS = FALSE // whether to impose pressure jumps at fluid-structure interfaces +USE_CONSISTENT_MASS_MATRIX = TRUE // whether to use a consistent or lumped mass matrix +IB_POINT_DENSITY = 4.0 // approximate density of IB quadrature points for Lagrangian-Eulerian interaction +SOLVER_TYPE = "STAGGERED" // the fluid solver to use (STAGGERED or COLLOCATED) +CFL_MAX = 0.9 // maximum CFL number +DT = 0.25*CFL_MAX*DX // maximum timestep size +START_TIME = 0.0e0 // initial simulation time +END_TIME = 100.0 // final simulation time +GROW_DT = 2.0e0 // growth factor for timesteps +CONVECTIVE_TS_TYPE = "ADAMS_BASHFORTH" // convective time stepping type +CONVECTIVE_OP_TYPE = "PPM" // convective differencing discretization type +CONVECTIVE_FORM = "ADVECTIVE" // how to compute the convective terms +NORMALIZE_PRESSURE = FALSE // whether to explicitly force the pressure to have mean zero +ERROR_ON_DT_CHANGE = TRUE // whether to emit an error message if the time step size changes +VORTICITY_TAGGING = TRUE // whether to tag cells for refinement based on vorticity thresholds +TAG_BUFFER = 1 // size of tag buffer used by grid generation algorithm +REGRID_CFL_INTERVAL = 0.5 // regrid whenever any material point could have moved 0.5 meshwidths since previous regrid +OUTPUT_U = TRUE +OUTPUT_P = TRUE +OUTPUT_F = TRUE +OUTPUT_OMEGA = TRUE +OUTPUT_DIV_U = TRUE +ENABLE_LOGGING = TRUE + +// model parameters +KAPPA_S = 2.5*DX/DT^2 +ETA_S = 1.5*DX/DT + +// tether penalty data +C1_S = 1.0e5 +KAPPA_S_BODY = 1.0e6 +ETA_S_BODY = 0.0 +KAPPA_S_SURFACE = 1.0e6 +ETA_S_SURFACE = 0.0 + +// collocated solver parameters +PROJECTION_METHOD_TYPE = "PRESSURE_UPDATE" +SECOND_ORDER_PRESSURE_UPDATE = TRUE + +VelocityBcCoefs_0 { + t_half = 0.5 + tau = 0.125 + + acoef_function_0 = "1.0" + acoef_function_1 = "0.0" + acoef_function_2 = "0.0" + acoef_function_3 = "0.0" + + bcoef_function_0 = "0.0" + bcoef_function_1 = "1.0" + bcoef_function_2 = "1.0" + bcoef_function_3 = "1.0" + + gcoef_function_0 = "(tanh((t-t_half)/tau)+tanh(t_half/tau))/(1+tanh(t_half/tau))" + gcoef_function_1 = "0.0" + gcoef_function_2 = "0.0" + gcoef_function_3 = "0.0" +} + +VelocityBcCoefs_1 { + acoef_function_0 = "1.0" + acoef_function_1 = "0.0" + acoef_function_2 = "1.0" + acoef_function_3 = "1.0" + + bcoef_function_0 = "0.0" + bcoef_function_1 = "1.0" + bcoef_function_2 = "0.0" + bcoef_function_3 = "0.0" + + gcoef_function_0 = "cos(pi*X_1/16.0)*exp(-2.0*t)" + gcoef_function_1 = "0.0" + gcoef_function_2 = "0.0" + gcoef_function_3 = "0.0" +} + +IBHierarchyIntegrator { + start_time = START_TIME + end_time = END_TIME + grow_dt = GROW_DT + regrid_cfl_interval = REGRID_CFL_INTERVAL + dt_max = DT + error_on_dt_change = ERROR_ON_DT_CHANGE + enable_logging = ENABLE_LOGGING + + time_stepping_type = "BACKWARD_EULER" + solve_for_position = FALSE + eta = 100.0 * RHO / DT +} + +IBFEMethod { + IB_delta_fcn = IB_DELTA_FUNCTION + split_forces = SPLIT_FORCES + use_jump_conditions = USE_JUMP_CONDITIONS + use_consistent_mass_matrix = USE_CONSISTENT_MASS_MATRIX + IB_point_density = IB_POINT_DENSITY +} + +INSCollocatedHierarchyIntegrator { + mu = MU + rho = RHO + start_time = START_TIME + end_time = END_TIME + grow_dt = GROW_DT + convective_time_stepping_type = CONVECTIVE_TS_TYPE + convective_op_type = CONVECTIVE_OP_TYPE + convective_difference_form = CONVECTIVE_FORM + normalize_pressure = NORMALIZE_PRESSURE + cfl = CFL_MAX + dt_max = DT + using_vorticity_tagging = VORTICITY_TAGGING + vorticity_abs_thresh = 0.125,0.25,0.5,1,2 + tag_buffer = TAG_BUFFER + output_U = OUTPUT_U + output_P = OUTPUT_P + output_F = OUTPUT_F + output_Omega = OUTPUT_OMEGA + output_Div_U = OUTPUT_DIV_U + enable_logging = ENABLE_LOGGING + projection_method_type = PROJECTION_METHOD_TYPE + use_2nd_order_pressure_update = SECOND_ORDER_PRESSURE_UPDATE +} + +INSStaggeredHierarchyIntegrator { + creeping_flow = FALSE + mu = MU + rho = RHO + start_time = START_TIME + end_time = END_TIME + grow_dt = GROW_DT + convective_time_stepping_type = CONVECTIVE_TS_TYPE + convective_op_type = CONVECTIVE_OP_TYPE + convective_difference_form = CONVECTIVE_FORM + normalize_pressure = NORMALIZE_PRESSURE + cfl = CFL_MAX + dt_max = DT + using_vorticity_tagging = VORTICITY_TAGGING + vorticity_abs_thresh = 0.125,0.25,0.5,1,2 + tag_buffer = TAG_BUFFER + output_U = OUTPUT_U + output_P = OUTPUT_P + output_F = OUTPUT_F + output_Omega = OUTPUT_OMEGA + output_Div_U = OUTPUT_DIV_U + enable_logging = ENABLE_LOGGING +} + +Main { + solver_type = SOLVER_TYPE + ib_time_stepping_type = "IMPLICIT" + +// log file parameters + log_file_name = "IB2d.log" + log_all_nodes = FALSE + +// visualization dump parameters + viz_writer = "VisIt","ExodusII" + viz_dump_interval = int(0.1/DT) + viz_dump_dirname = "viz_IB2d" + visit_number_procs_per_file = 1 + +// restart dump parameters + restart_dump_interval = 0 + restart_dump_dirname = "restart_IB2d" + +// hierarchy data dump parameters + data_dump_interval = 1 + data_dump_dirname = "hier_data_IB2d" + +// timer dump parameters + timer_dump_interval = 0 +} + +CartesianGeometry { + domain_boxes = [ (0,0),(2*N - 1,N - 1) ] + x_lo = -0.5*L,-0.5*L + x_up = 1.5*L, 0.5*L + periodic_dimension = 0,0 +} + +GriddingAlgorithm { + max_levels = MAX_LEVELS + ratio_to_coarser { + level_1 = REF_RATIO,REF_RATIO + level_2 = REF_RATIO,REF_RATIO + level_3 = REF_RATIO,REF_RATIO + level_4 = REF_RATIO,REF_RATIO + level_5 = REF_RATIO,REF_RATIO + level_6 = REF_RATIO,REF_RATIO + level_7 = REF_RATIO,REF_RATIO + } + largest_patch_size { + level_0 = 512,512 // all finer levels will use same values as level_0 + } + smallest_patch_size { + level_0 = 8, 8 // all finer levels will use same values as level_0 + } + efficiency_tolerance = 0.80e0 // min % of tag cells in new patch level + combine_efficiency = 0.80e0 // chop box if sum of volumes of smaller boxes < efficiency * vol of large box +} + +StandardTagAndInitialize { + tagging_method = "GRADIENT_DETECTOR" +} + +LoadBalancer { + bin_pack_method = "SPATIAL" + max_workload_factor = 1 +} + +TimerManager{ + print_exclusive = FALSE + print_total = TRUE + print_threshold = 0.1 + + timer_list = "IBAMR::*::*","IBTK::*::*","*::*::*" +} diff --git a/ibtk/include/ibtk/HierarchyIntegrator.h b/ibtk/include/ibtk/HierarchyIntegrator.h index bf7ccad090..8b26b978e3 100644 --- a/ibtk/include/ibtk/HierarchyIntegrator.h +++ b/ibtk/include/ibtk/HierarchyIntegrator.h @@ -141,9 +141,11 @@ class HierarchyIntegrator : public SAMRAI::mesh::StandardTagAndInitStrategy::quiet_NaN(), d_start_time = 0.0, d_end_time = std::numeric_limits::max(); double d_dt_init = std::numeric_limits::max(), d_dt_min = 0.0, - d_dt_max = std::numeric_limits::max(), d_dt_growth_factor = 2.0; + d_dt_max = std::numeric_limits::max(), d_dt_growth_factor = 2.0, d_dt_shrink_factor = 0.5; int d_integrator_step = 0, d_max_integrator_steps = std::numeric_limits::max(); std::deque d_dt_previous; @@ -1088,6 +1096,8 @@ class HierarchyIntegrator : public SAMRAI::mesh::StandardTagAndInitStrategy::quiet_NaN(); + bool d_skip_enforce_num_cycles = false; + bool d_redo_time_step = false; /* * The number of integration steps taken between invocations of the diff --git a/ibtk/src/utilities/HierarchyIntegrator.cpp b/ibtk/src/utilities/HierarchyIntegrator.cpp index 04125f3435..5a2c7324ec 100644 --- a/ibtk/src/utilities/HierarchyIntegrator.cpp +++ b/ibtk/src/utilities/HierarchyIntegrator.cpp @@ -230,7 +230,7 @@ HierarchyIntegrator::initializePatchHierarchy(Pointer > hie return; } // initializePatchHierarchy -void +double HierarchyIntegrator::advanceHierarchy(double dt) { IBTK_TIMER_START(t_advance_hierarchy); @@ -284,7 +284,8 @@ HierarchyIntegrator::advanceHierarchy(double dt) // Determine the number of cycles and the time step size. d_current_num_cycles = getNumberOfCycles(); - d_current_dt = new_time - current_time; + auto dt_actual = new_time - current_time; + d_current_dt = dt_actual; // Execute the preprocessing method of the parent integrator, and // recursively execute all preprocessing callbacks registered with the @@ -302,7 +303,16 @@ HierarchyIntegrator::advanceHierarchy(double dt) plog << d_object_name << "::advanceHierarchy(): executing cycle " << cycle_num + 1 << " of " << d_current_num_cycles << "\n"; } + d_redo_time_step = false; integrateHierarchy(current_time, new_time, cycle_num); + if (d_redo_time_step) + { + const auto dt = d_current_dt; + const auto dt_reduced = d_dt_shrink_factor * dt; + resetIntegratorToPreadvanceState(); + pout << "redoing time step at reduced time step size: " << dt_reduced << "\n"; + return advanceHierarchy(dt_reduced); + } } // Execute the postprocessing method of the parent integrator, and @@ -336,7 +346,7 @@ HierarchyIntegrator::advanceHierarchy(double dt) // Reset the regrid indicator. d_at_regrid_time_step = false; IBTK_TIMER_STOP(t_advance_hierarchy); - return; + return dt_actual; } // advanceHierarchy double @@ -643,6 +653,12 @@ HierarchyIntegrator::getCurrentTimeStepSize() const return d_current_dt; } // getCurrentTimeStepSize +void +HierarchyIntegrator::setSkipEnforceNumCycles(const bool skip_enforce_num_cycles) +{ + d_skip_enforce_num_cycles = skip_enforce_num_cycles; +} + void HierarchyIntegrator::preprocessIntegrateHierarchy(const double current_time, const double new_time, @@ -664,8 +680,12 @@ HierarchyIntegrator::integrateHierarchy(const double current_time, const double ++d_current_cycle_num; #if !defined(NDEBUG) TBOX_ASSERT(IBTK::abs_equal_eps(d_current_dt, new_time - current_time)); - TBOX_ASSERT(d_current_cycle_num == cycle_num); - TBOX_ASSERT(d_current_cycle_num < d_current_num_cycles); + TBOX_ASSERT(d_skip_enforce_num_cycles || d_current_cycle_num == cycle_num); + TBOX_ASSERT(d_skip_enforce_num_cycles || d_current_cycle_num < d_current_num_cycles); +#else + NULL_USE(current_time); + NULL_USE(new_time); + NULL_USE(cycle_num); #endif integrateHierarchySpecialized(current_time, new_time, cycle_num); @@ -680,8 +700,8 @@ HierarchyIntegrator::skipCycle(const double current_time, const double new_time, ++d_current_cycle_num; #if !defined(NDEBUG) TBOX_ASSERT(IBTK::abs_equal_eps(d_current_dt, new_time - current_time)); - TBOX_ASSERT(d_current_cycle_num == cycle_num); - TBOX_ASSERT(d_current_cycle_num < d_current_num_cycles); + TBOX_ASSERT(d_skip_enforce_num_cycles || d_current_cycle_num == cycle_num); + TBOX_ASSERT(d_skip_enforce_num_cycles || d_current_cycle_num < d_current_num_cycles); #else NULL_USE(current_time); NULL_USE(new_time); @@ -698,8 +718,8 @@ HierarchyIntegrator::postprocessIntegrateHierarchy(const double current_time, { #if !defined(NDEBUG) TBOX_ASSERT(IBTK::abs_equal_eps(d_current_dt, new_time - current_time)); - TBOX_ASSERT(num_cycles == d_current_num_cycles); - TBOX_ASSERT(d_current_cycle_num + 1 == d_current_num_cycles); + TBOX_ASSERT(d_skip_enforce_num_cycles || num_cycles == d_current_num_cycles); + TBOX_ASSERT(d_skip_enforce_num_cycles || d_current_cycle_num + 1 == d_current_num_cycles); #else NULL_USE(current_time); NULL_USE(new_time); @@ -1197,6 +1217,7 @@ HierarchyIntegrator::putToDatabase(Pointer db) db->putDouble("d_dt_min", d_dt_min); db->putDouble("d_dt_max", d_dt_max); db->putDouble("d_dt_growth_factor", d_dt_growth_factor); + db->putDouble("d_dt_shrink_factor", d_dt_shrink_factor); db->putInteger("d_integrator_step", d_integrator_step); db->putInteger("d_max_integrator_steps", d_max_integrator_steps); db->putInteger("d_num_cycles", d_num_cycles); @@ -1665,6 +1686,8 @@ HierarchyIntegrator::getFromInput(Pointer db, bool is_from_restart) if (db->keyExists("dt_max")) d_dt_max = db->getDouble("dt_max"); if (db->keyExists("grow_dt")) d_dt_growth_factor = db->getDouble("grow_dt"); + if (db->keyExists("shrink_dt")) + d_dt_shrink_factor = db->getDouble("shrink_dt"); else if (db->keyExists("dt_growth_factor")) d_dt_growth_factor = db->getDouble("dt_growth_factor"); if (db->keyExists("max_integrator_steps")) d_max_integrator_steps = db->getInteger("max_integrator_steps"); diff --git a/include/ibamr/IBFEMethod.h b/include/ibamr/IBFEMethod.h index bccbf22f6d..549e5ec447 100644 --- a/include/ibamr/IBFEMethod.h +++ b/include/ibamr/IBFEMethod.h @@ -24,7 +24,7 @@ #include "ibamr/FEMechanicsBase.h" #include "ibamr/IBFEDirectForcingKinematics.h" -#include "ibamr/IBStrategy.h" +#include "ibamr/IBImplicitStrategy.h" #include "ibamr/ibamr_enums.h" #include "ibtk/FEDataManager.h" @@ -434,7 +434,7 @@ class IBFEDirectForcingKinematics; * is handled by the SAMRAI::tbox::RestartManager automatically to reinitiate * the IBFEMethod. */ -class IBFEMethod : public FEMechanicsBase, public IBStrategy +class IBFEMethod : public FEMechanicsBase, public IBImplicitStrategy { public: IBTK_DEPRECATED("Use IBFEMethod::getSourceSystemName() to access the source system name.") @@ -632,8 +632,8 @@ class IBFEMethod : public FEMechanicsBase, public IBStrategy void forwardEulerStep(double current_time, double new_time) override; /*! - * Advance the positions of the Lagrangian structure using the (explicit) - * backward Euler method. + * Advance the positions of the Lagrangian structure using the backward Euler + * method. */ void backwardEulerStep(double current_time, double new_time) override; @@ -686,6 +686,67 @@ class IBFEMethod : public FEMechanicsBase, public IBStrategy const std::vector > >& q_prolongation_scheds, double data_time) override; + /*! + * Create solution data. + */ + void createSolutionVec(Vec* X_vec) override; + + /*! + * Create solution and rhs data. + */ + void createSolverVecs(Vec* X_vec, Vec* F_vec, Vec* R_vec) override; + + /*! + * Setup solution and rhs data. + */ + void setupSolverVecs(Vec& X_vec, Vec& F_vec, Vec& R_vec) override; + + /*! + * Set the value of the updated position vector. + */ + void setUpdatedPosition(Vec& X_new_vec) override; + + /*! + * Set the value of the updated force vector. + */ + void setUpdatedForce(Vec& F_new_vec) override; + + /*! + * Get the value of the updated position vector. + */ + void getUpdatedPosition(Vec& X_new_vec) override; + + /*! + * Get the value of the updated velocity vector. + */ + void getUpdatedVelocity(Vec& U_new_vec) override; + + /*! + * Get the value of the updated force vector. + */ + void getUpdatedForce(Vec& F_new_vec) override; + + /*! + * Compute the nonlinear residual for backward Euler time stepping. + */ + void computeResidualBackwardEuler(Vec& R_vec) override; + + /*! + * Compute the nonlinear residual for midpoint rule time stepping. + */ + void computeResidualMidpointRule(Vec& R_vec) override; + + /*! + * Compute the nonlinear residual for trapezoidal rule time stepping. + */ + void computeResidualTrapezoidalRule(Vec& R_vec) override; + + /*! + * Update the positions used for the "fixed" interpolation and spreading + * operators. + */ + void updateFixedLEOperators() override; + /*! * Get the default interpolation spec object used by the class. */ @@ -1113,6 +1174,12 @@ class IBFEMethod : public FEMechanicsBase, public IBStrategy * scratch hierarchy). */ void reinitElementMappings(); + + /** + * Cached data for implicit solver. + */ + std::vector > > d_implicit_X_vecs, d_implicit_F_vecs, + d_implicit_R_vecs; }; } // namespace IBAMR diff --git a/include/ibamr/IBImplicitHierarchyIntegrator.h b/include/ibamr/IBImplicitHierarchyIntegrator.h new file mode 100644 index 0000000000..21a3253739 --- /dev/null +++ b/include/ibamr/IBImplicitHierarchyIntegrator.h @@ -0,0 +1,160 @@ +// --------------------------------------------------------------------- +// +// Copyright (c) 2014 - 2019 by the IBAMR developers +// All rights reserved. +// +// This file is part of IBAMR. +// +// IBAMR is free software and is distributed under the 3-clause BSD +// license. The full text of the license can be found in the file +// COPYRIGHT at the top level directory of IBAMR. +// +// --------------------------------------------------------------------- + +#ifndef included_IBAMR_IBImplicitHierarchyIntegrator +#define included_IBAMR_IBImplicitHierarchyIntegrator + +/////////////////////////////// INCLUDES ///////////////////////////////////// + +#include "ibamr/IBHierarchyIntegrator.h" +#include "ibamr/IBImplicitStrategy.h" + +#include "petscsnes.h" + +/////////////////////////////// CLASS DEFINITION ///////////////////////////// + +namespace IBAMR +{ +/*! + * \brief Class IBImplicitHierarchyIntegrator is an implementation of a + * formally second-order accurate, nonlinearly-implicit version of the immersed + * boundary method. + */ +class IBImplicitHierarchyIntegrator : public IBHierarchyIntegrator +{ +public: + /*! + * The constructor for class IBImplicitHierarchyIntegrator sets + * some default values, reads in configuration information from input and + * restart databases, and registers the integrator object with the restart + * manager when requested. + */ + IBImplicitHierarchyIntegrator(const std::string& object_name, + SAMRAI::tbox::Pointer input_db, + SAMRAI::tbox::Pointer ib_method_ops, + SAMRAI::tbox::Pointer ins_hier_integrator, + bool register_for_restart = true); + + /*! + * The destructor for class IBImplicitHierarchyIntegrator + * unregisters the integrator object with the restart manager when the + * object is so registered. + */ + ~IBImplicitHierarchyIntegrator() = default; + + /*! + * Prepare to advance the data from current_time to new_time. + */ + void preprocessIntegrateHierarchy(double current_time, double new_time, int num_cycles = 1) override; + +protected: + /*! + * Synchronously advance each level in the hierarchy over the given time + * increment. + */ + void integrateHierarchySpecialized(double current_time, double new_time, int cycle_num = 0) override; + +public: + /*! + * Clean up data following call(s) to integrateHierarchy(). + */ + void postprocessIntegrateHierarchy(double current_time, + double new_time, + bool skip_synchronize_new_state_data, + int num_cycles = 1) override; + + /*! + * Initialize the variables, basic communications algorithms, solvers, and + * other data structures used by this time integrator object. + * + * This method is called automatically by initializePatchHierarchy() prior + * to the construction of the patch hierarchy. It is also possible for + * users to make an explicit call to initializeHierarchyIntegrator() prior + * to calling initializePatchHierarchy(). + */ + void + initializeHierarchyIntegrator(SAMRAI::tbox::Pointer > hierarchy, + SAMRAI::tbox::Pointer > gridding_alg) override; + + /*! + * Returns the number of cycles to perform for the present time step. + */ + int getNumberOfCycles() const override; + +protected: + /*! + * Determine the maximum time step size. + */ + double getMaximumTimeStepSizeSpecialized() override; + + /*! + * Write out specialized object state to the given database. + */ + void putToDatabaseSpecialized(SAMRAI::tbox::Pointer db) override; + + SAMRAI::tbox::Pointer d_ib_implicit_ops; + + // Whether to use "frozen" LE operators. + bool d_use_fixed_LE_operators = false; + + // Penalty factor used in direct forcing. + double d_eta = std::numeric_limits::quiet_NaN(); + +private: + /*! + * \brief Copy constructor. + * + * \note This constructor is not implemented and should not be used. + * + * \param from The value to copy to this object. + */ + IBImplicitHierarchyIntegrator(const IBImplicitHierarchyIntegrator& from) = delete; + + /*! + * \brief Assignment operator. + * + * \note This operator is not implemented and should not be used. + * + * \param that The value to assign to this object. + * + * \return A reference to this object. + */ + IBImplicitHierarchyIntegrator& operator=(const IBImplicitHierarchyIntegrator& that) = delete; + + /*! + * Read object state from the restart file and initialize class data + * members. + */ + void getFromRestart(); + + /// Solver state data. + int d_cycle_num, d_ins_cycle_num; + int d_snes_f_evals, d_snes_f_evals_previous, d_snes_f_evals_target_min = 5, d_snes_f_evals_target_max = 10; + double d_current_time, d_new_time, d_cfl_max_tol = 1.2; + bool d_skip_final_update_solution = false; + + /*! + * Update the solution (e.g. for fixed-point iteration) based on the current value of Y and compute the residual. + */ + void updateSolution(Vec X, Vec R); + + /*! + * Static function for implicit formulation. + */ + static PetscErrorCode IBFunction(SNES snes, Vec X, Vec R, void* ctx); +}; +} // namespace IBAMR + +////////////////////////////////////////////////////////////////////////////// + +#endif // #ifndef included_IBAMR_IBImplicitHierarchyIntegrator diff --git a/include/ibamr/IBImplicitStrategy.h b/include/ibamr/IBImplicitStrategy.h index 2a51efa1c8..f2c16189f6 100644 --- a/include/ibamr/IBImplicitStrategy.h +++ b/include/ibamr/IBImplicitStrategy.h @@ -68,15 +68,20 @@ class IBImplicitStrategy : public IBStrategy */ virtual ~IBImplicitStrategy() = default; + /*! + * Create solution data. + */ + virtual void createSolutionVec(Vec* X_vec) = 0; + /*! * Create solution and rhs data. */ - virtual void createSolverVecs(Vec* X_vec, Vec* F_vec) = 0; + virtual void createSolverVecs(Vec* X_vec, Vec* F_vec, Vec* R_vec) = 0; /*! * Setup solution and rhs data. */ - virtual void setupSolverVecs(Vec* X_vec, Vec* F_vec) = 0; + virtual void setupSolverVecs(Vec& X_vec, Vec& F_vec, Vec& R_vec) = 0; /*! * Set the value of the updated position vector. @@ -84,63 +89,39 @@ class IBImplicitStrategy : public IBStrategy virtual void setUpdatedPosition(Vec& X_new_vec) = 0; /*! - * Set the value of the intermediate position vector used in evaluating the - * linearized problem. - */ - virtual void setLinearizedPosition(Vec& X_vec, double data_time) = 0; - - /*! - * Compute the nonlinear residual. + * Set the value of the updated position vector. */ - virtual void computeResidual(Vec& R_vec) = 0; + virtual void setUpdatedForce(Vec& F_new_vec) = 0; /*! - * Compute the linearized residual for the given intermediate position - * vector. + * Get the value of the updated position vector. */ - virtual void computeLinearizedResidual(Vec& X_vec, Vec& R_vec) = 0; + virtual void getUpdatedPosition(Vec& X_new_vec) = 0; /*! - * Interpolate the Eulerian velocity to the curvilinear mesh at the - * specified time within the current time interval for use in evaluating the - * residual of the linearized problem. + * Get the value of the updated velocity vector. */ - virtual void interpolateLinearizedVelocity( - int u_data_idx, - const std::vector > >& u_synch_scheds, - const std::vector > >& u_ghost_fill_scheds, - double data_time) = 0; + virtual void getUpdatedVelocity(Vec& U_new_vec) = 0; /*! - * Compute the Lagrangian force of the linearized problem for the specified - * configuration of the updated position vector. + * Get the value of the updated force vector. */ - virtual void computeLinearizedLagrangianForce(Vec& X_vec, double data_time) = 0; + virtual void getUpdatedForce(Vec& F_new_vec) = 0; /*! - * Construct the linearized Lagrangian force Jacobian. + * Compute the nonlinear residual for backward Euler time stepping. */ - virtual void constructLagrangianForceJacobian(Mat& A, MatType mat_type, double data_time) = 0; + virtual void computeResidualBackwardEuler(Vec& R_vec) = 0; /*! - * Spread the Lagrangian force of the linearized problem to the Cartesian - * grid at the specified time within the current time interval. + * Compute the nonlinear residual for midpoint rule time stepping. */ - virtual void spreadLinearizedForce( - int f_data_idx, - IBTK::RobinPhysBdryPatchStrategy* f_phys_bdry_op, - const std::vector > >& f_prolongation_scheds, - double data_time) = 0; + virtual void computeResidualMidpointRule(Vec& R_vec) = 0; /*! - * Construct the IB interpolation operator. + * Compute the nonlinear residual for trapezoidal rule time stepping. */ - virtual void constructInterpOp(Mat& J, - void (*spread_fnc)(const double, double*), - int stencil_width, - const std::vector& num_dofs_per_proc, - int dof_index_idx, - double data_time) = 0; + virtual void computeResidualTrapezoidalRule(Vec& R_vec) = 0; protected: private: diff --git a/include/ibamr/IBMethod.h b/include/ibamr/IBMethod.h index 356f09d9b6..c12a3e7d90 100644 --- a/include/ibamr/IBMethod.h +++ b/include/ibamr/IBMethod.h @@ -186,17 +186,23 @@ class IBMethod : public IBImplicitStrategy */ void postprocessIntegrateData(double current_time, double new_time, int num_cycles) override; + /*! + * Create solution data on the specified level of the patch + * hierarchy. + */ + void createSolutionVec(Vec* X_vec) override; + /*! * Create solution and rhs data on the specified level of the patch * hierarchy. */ - void createSolverVecs(Vec* X_vec, Vec* F_vec) override; + void createSolverVecs(Vec* X_vec, Vec* F_vec, Vec* R_vec) override; /*! * Setup solution and rhs data on the specified level of the patch * hierarchy. */ - void setupSolverVecs(Vec* X_vec, Vec* F_vec) override; + void setupSolverVecs(Vec& X_vec, Vec& F_vec, Vec& R_vec) override; /*! * Set the value of the updated position vector. @@ -204,21 +210,39 @@ class IBMethod : public IBImplicitStrategy void setUpdatedPosition(Vec& X_new_vec) override; /*! - * Set the value of the intermediate position vector used in evaluating the - * linearized problem. + * Set the value of the updated force vector. + */ + void setUpdatedForce(Vec& F_new_vec) override; + + /*! + * Get the value of the updated position vector. + */ + void getUpdatedPosition(Vec& X_new_vec) override; + + /*! + * Get the value of the updated velocity vector. + */ + void getUpdatedVelocity(Vec& U_new_vec) override; + + /*! + * Get the value of the updated force vector. */ - void setLinearizedPosition(Vec& X_vec, double data_time) override; + void getUpdatedForce(Vec& F_new_vec) override; /*! - * Compute the residual on the specified level of the patch hierarchy. + * Compute the nonlinear residual for backward Euler time stepping. */ - void computeResidual(Vec& R_vec) override; + void computeResidualBackwardEuler(Vec& R_vec) override; /*! - * Compute the linearized residual for the given intermediate position - * vector. + * Compute the nonlinear residual for midpoint rule time stepping. */ - void computeLinearizedResidual(Vec& X_vec, Vec& R_vec) override; + void computeResidualMidpointRule(Vec& R_vec) override; + + /*! + * Compute the nonlinear residual for trapezoidal rule time stepping. + */ + void computeResidualTrapezoidalRule(Vec& R_vec) override; /*! * Update the positions used for the "fixed" interpolation and spreading @@ -236,17 +260,6 @@ class IBMethod : public IBImplicitStrategy const std::vector > >& u_ghost_fill_scheds, double data_time) override; - /*! - * Interpolate the Eulerian velocity to the curvilinear mesh at the - * specified time within the current time interval for use in evaluating the - * residual of the linearized problem. - */ - void interpolateLinearizedVelocity( - int u_data_idx, - const std::vector > >& u_synch_scheds, - const std::vector > >& u_ghost_fill_scheds, - double data_time) override; - /*! * Advance the positions of the Lagrangian structure using the forward Euler * method. @@ -276,17 +289,6 @@ class IBMethod : public IBImplicitStrategy */ void computeLagrangianForce(double data_time) override; - /*! - * Compute the Lagrangian force of the linearized problem for the specified - * configuration of the updated position vector. - */ - void computeLinearizedLagrangianForce(Vec& X_vec, double data_time) override; - - /*! - * Construct the linearized Lagrangian force Jacobian. - */ - void constructLagrangianForceJacobian(Mat& A, MatType mat_type, double data_time) override; - /*! * Spread the Lagrangian force to the Cartesian grid at the specified time * within the current time interval. @@ -297,16 +299,6 @@ class IBMethod : public IBImplicitStrategy const std::vector > >& f_prolongation_scheds, double data_time) override; - /*! - * Spread the Lagrangian force of the linearized problem to the Cartesian - * grid at the specified time within the current time interval. - */ - void spreadLinearizedForce( - int f_data_idx, - IBTK::RobinPhysBdryPatchStrategy* f_phys_bdry_op, - const std::vector > >& f_prolongation_scheds, - double data_time) override; - /*! * Construct the IB interpolation operator. */ @@ -315,7 +307,7 @@ class IBMethod : public IBImplicitStrategy int stencil_width, const std::vector& num_dofs_per_proc, int dof_index_idx, - double data_time) override; + double data_time); /*! * Indicate whether there are any internal fluid sources/sinks. @@ -452,12 +444,6 @@ class IBMethod : public IBImplicitStrategy bool** X_needs_ghost_fill, double data_time); - /*! - * Get the linearized structure position data. - */ - void getLinearizedPositionData(std::vector >** X_data, - bool** X_needs_ghost_fill); - /*! * Get the current interpolation/spreading position data. */ @@ -470,11 +456,6 @@ class IBMethod : public IBImplicitStrategy */ void getVelocityData(std::vector >** U_data, double data_time); - /*! - * Get the linearized structure velocity data. - */ - void getLinearizedVelocityData(std::vector >** U_data); - /*! * Get the current structure force data. */ @@ -482,11 +463,6 @@ class IBMethod : public IBImplicitStrategy bool** F_needs_ghost_fill, double data_time); - /*! - * Get the linearized structure force data. - */ - void getLinearizedForceData(std::vector >** F_data, bool** F_needs_ghost_fill); - /*! * Interpolate the current and new data to obtain values at the midpoint of * the time interval. @@ -502,13 +478,6 @@ class IBMethod : public IBImplicitStrategy void resetAnchorPointValues(std::vector > U_data, int coarsest_ln, int finest_ln); - /* - * PETSc function for evaluating Lagrangian force. - */ - static PetscErrorCode computeForce_SAMRAI(void* ctx, Vec X, Vec F); - - PetscErrorCode computeForce(Vec X, Vec F); - /* * Indicates whether the integrator should output logging messages. */ @@ -533,9 +502,8 @@ class IBMethod : public IBImplicitStrategy * reinitialized. */ bool d_X_current_needs_ghost_fill = true, d_X_new_needs_ghost_fill = true, d_X_half_needs_ghost_fill = true, - d_X_jac_needs_ghost_fill = true, d_X_LE_new_needs_ghost_fill = true, d_X_LE_half_needs_ghost_fill = true; - bool d_F_current_needs_ghost_fill = true, d_F_new_needs_ghost_fill = true, d_F_half_needs_ghost_fill = true, - d_F_jac_needs_ghost_fill = true; + d_X_LE_new_needs_ghost_fill = true, d_X_LE_half_needs_ghost_fill = true; + bool d_F_current_needs_ghost_fill = true, d_F_new_needs_ghost_fill = true, d_F_half_needs_ghost_fill = true; /* * The LDataManager is used to coordinate the distribution of Lagrangian @@ -549,10 +517,10 @@ class IBMethod : public IBImplicitStrategy /* * Lagrangian variables. */ - std::vector > d_X_current_data, d_X_new_data, d_X_half_data, d_X_jac_data, - d_X_LE_new_data, d_X_LE_half_data; - std::vector > d_U_current_data, d_U_new_data, d_U_half_data, d_U_jac_data; - std::vector > d_F_current_data, d_F_new_data, d_F_half_data, d_F_jac_data; + std::vector > d_X_current_data, d_X_new_data, d_X_half_data, d_X_LE_new_data, + d_X_LE_half_data; + std::vector > d_U_current_data, d_U_new_data, d_U_half_data; + std::vector > d_F_current_data, d_F_new_data, d_F_half_data; /* * List of local indices of local anchor points. @@ -673,13 +641,6 @@ class IBMethod : public IBImplicitStrategy * members. */ void getFromRestart(); - - /*! - * Jacobian data. - */ - bool d_force_jac_mffd = false; - Mat d_force_jac = nullptr; - double d_force_jac_data_time; }; } // namespace IBAMR diff --git a/include/ibamr/INSHierarchyIntegrator.h b/include/ibamr/INSHierarchyIntegrator.h index 3eeb3a301b..05c6f0f9b3 100644 --- a/include/ibamr/INSHierarchyIntegrator.h +++ b/include/ibamr/INSHierarchyIntegrator.h @@ -77,6 +77,12 @@ class INSHierarchyIntegrator : public IBTK::HierarchyIntegrator */ ~INSHierarchyIntegrator(); + /*! + * Compute the current CFL number for the given velocity field and time step size. + */ + static double + compute_CFL_number(const int data_idx, const double dt, const SAMRAI::hier::PatchHierarchy* patch_hierarchy); + /*! * Set the type of viscous time integration scheme being employed by the * incompressible flow solver. @@ -371,6 +377,11 @@ class INSHierarchyIntegrator : public IBTK::HierarchyIntegrator */ int getNumberOfCycles() const override; + /*! + * Returns the maximum CFL number. + */ + double getMaximumCFLNumber() const { return d_cfl_max; } + /*! * Finish postprocessing the hierarchy by computing the current CFL number. */ diff --git a/lib/Makefile.am b/lib/Makefile.am index c393918584..7da31a66ee 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -69,7 +69,7 @@ DIM_INDEPENDENT_SOURCES = \ ../src/IB/IBExplicitHierarchyIntegrator.cpp \ ../src/IB/IBHierarchyIntegrator.cpp \ ../src/IB/IBHydrodynamicForceEvaluator.cpp \ -../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp \ +../src/IB/IBImplicitHierarchyIntegrator.cpp \ ../src/IB/IBInstrumentPanel.cpp \ ../src/IB/IBInstrumentationSpec.cpp \ ../src/IB/IBInstrumentationSpecFactory.cpp \ @@ -250,7 +250,7 @@ pkg_include_HEADERS += \ ../include/ibamr/IBExplicitHierarchyIntegrator.h \ ../include/ibamr/IBHierarchyIntegrator.h \ ../include/ibamr/IBHydrodynamicForceEvaluator.h \ -../include/ibamr/IBImplicitStaggeredHierarchyIntegrator.h \ +../include/ibamr/IBImplicitHierarchyIntegrator.h \ ../include/ibamr/IBImplicitStrategy.h \ ../include/ibamr/IBInstrumentPanel.h \ ../include/ibamr/IBInstrumentationSpec.h \ diff --git a/lib/Makefile.in b/lib/Makefile.in index 812b0f7f09..f13561fe7e 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -216,7 +216,7 @@ am__libIBAMR2d_a_SOURCES_DIST = ../src/IB/BrinkmanAdvDiffBcHelper.cpp \ ../src/IB/IBExplicitHierarchyIntegrator.cpp \ ../src/IB/IBHierarchyIntegrator.cpp \ ../src/IB/IBHydrodynamicForceEvaluator.cpp \ - ../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp \ + ../src/IB/IBImplicitHierarchyIntegrator.cpp \ ../src/IB/IBInstrumentPanel.cpp \ ../src/IB/IBInstrumentationSpec.cpp \ ../src/IB/IBInstrumentationSpecFactory.cpp \ @@ -402,7 +402,7 @@ am__objects_2 = \ ../src/IB/libIBAMR2d_a-IBExplicitHierarchyIntegrator.$(OBJEXT) \ ../src/IB/libIBAMR2d_a-IBHierarchyIntegrator.$(OBJEXT) \ ../src/IB/libIBAMR2d_a-IBHydrodynamicForceEvaluator.$(OBJEXT) \ - ../src/IB/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.$(OBJEXT) \ + ../src/IB/libIBAMR2d_a-IBImplicitHierarchyIntegrator.$(OBJEXT) \ ../src/IB/libIBAMR2d_a-IBInstrumentPanel.$(OBJEXT) \ ../src/IB/libIBAMR2d_a-IBInstrumentationSpec.$(OBJEXT) \ ../src/IB/libIBAMR2d_a-IBInstrumentationSpecFactory.$(OBJEXT) \ @@ -570,7 +570,7 @@ am__libIBAMR3d_a_SOURCES_DIST = ../src/IB/BrinkmanAdvDiffBcHelper.cpp \ ../src/IB/IBExplicitHierarchyIntegrator.cpp \ ../src/IB/IBHierarchyIntegrator.cpp \ ../src/IB/IBHydrodynamicForceEvaluator.cpp \ - ../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp \ + ../src/IB/IBImplicitHierarchyIntegrator.cpp \ ../src/IB/IBInstrumentPanel.cpp \ ../src/IB/IBInstrumentationSpec.cpp \ ../src/IB/IBInstrumentationSpecFactory.cpp \ @@ -756,7 +756,7 @@ am__objects_4 = \ ../src/IB/libIBAMR3d_a-IBExplicitHierarchyIntegrator.$(OBJEXT) \ ../src/IB/libIBAMR3d_a-IBHierarchyIntegrator.$(OBJEXT) \ ../src/IB/libIBAMR3d_a-IBHydrodynamicForceEvaluator.$(OBJEXT) \ - ../src/IB/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.$(OBJEXT) \ + ../src/IB/libIBAMR3d_a-IBImplicitHierarchyIntegrator.$(OBJEXT) \ ../src/IB/libIBAMR3d_a-IBInstrumentPanel.$(OBJEXT) \ ../src/IB/libIBAMR3d_a-IBInstrumentationSpec.$(OBJEXT) \ ../src/IB/libIBAMR3d_a-IBInstrumentationSpecFactory.$(OBJEXT) \ @@ -949,7 +949,7 @@ am__depfiles_remade = ../src/$(DEPDIR)/dummy.Po \ ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBHierarchyIntegrator.Po \ ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBHydrodynamicForceEvaluator.Po \ ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBHydrodynamicSurfaceForceEvaluator.Po \ - ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.Po \ + ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitHierarchyIntegrator.Po \ ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBInstrumentPanel.Po \ ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBInstrumentationSpec.Po \ ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBInstrumentationSpecFactory.Po \ @@ -1019,7 +1019,7 @@ am__depfiles_remade = ../src/$(DEPDIR)/dummy.Po \ ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBHierarchyIntegrator.Po \ ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBHydrodynamicForceEvaluator.Po \ ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBHydrodynamicSurfaceForceEvaluator.Po \ - ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.Po \ + ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitHierarchyIntegrator.Po \ ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBInstrumentPanel.Po \ ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBInstrumentationSpec.Po \ ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBInstrumentationSpecFactory.Po \ @@ -1344,7 +1344,7 @@ am__pkg_include_HEADERS_DIST = ../include/ibamr/app_namespaces.h \ ../include/ibamr/IBExplicitHierarchyIntegrator.h \ ../include/ibamr/IBHierarchyIntegrator.h \ ../include/ibamr/IBHydrodynamicForceEvaluator.h \ - ../include/ibamr/IBImplicitStaggeredHierarchyIntegrator.h \ + ../include/ibamr/IBImplicitHierarchyIntegrator.h \ ../include/ibamr/IBImplicitStrategy.h \ ../include/ibamr/IBInstrumentPanel.h \ ../include/ibamr/IBInstrumentationSpec.h \ @@ -1772,7 +1772,7 @@ pkg_include_HEADERS = ../include/ibamr/app_namespaces.h \ ../include/ibamr/IBExplicitHierarchyIntegrator.h \ ../include/ibamr/IBHierarchyIntegrator.h \ ../include/ibamr/IBHydrodynamicForceEvaluator.h \ - ../include/ibamr/IBImplicitStaggeredHierarchyIntegrator.h \ + ../include/ibamr/IBImplicitHierarchyIntegrator.h \ ../include/ibamr/IBImplicitStrategy.h \ ../include/ibamr/IBInstrumentPanel.h \ ../include/ibamr/IBInstrumentationSpec.h \ @@ -1885,7 +1885,7 @@ DIM_INDEPENDENT_SOURCES = ../src/IB/BrinkmanAdvDiffBcHelper.cpp \ ../src/IB/IBExplicitHierarchyIntegrator.cpp \ ../src/IB/IBHierarchyIntegrator.cpp \ ../src/IB/IBHydrodynamicForceEvaluator.cpp \ - ../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp \ + ../src/IB/IBImplicitHierarchyIntegrator.cpp \ ../src/IB/IBInstrumentPanel.cpp \ ../src/IB/IBInstrumentationSpec.cpp \ ../src/IB/IBInstrumentationSpecFactory.cpp \ @@ -2180,7 +2180,7 @@ libIBAMR.a: $(libIBAMR_a_OBJECTS) $(libIBAMR_a_DEPENDENCIES) $(EXTRA_libIBAMR_a_ ../src/IB/$(am__dirstamp) ../src/IB/$(DEPDIR)/$(am__dirstamp) ../src/IB/libIBAMR2d_a-IBHydrodynamicForceEvaluator.$(OBJEXT): \ ../src/IB/$(am__dirstamp) ../src/IB/$(DEPDIR)/$(am__dirstamp) -../src/IB/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.$(OBJEXT): \ +../src/IB/libIBAMR2d_a-IBImplicitHierarchyIntegrator.$(OBJEXT): \ ../src/IB/$(am__dirstamp) ../src/IB/$(DEPDIR)/$(am__dirstamp) ../src/IB/libIBAMR2d_a-IBInstrumentPanel.$(OBJEXT): \ ../src/IB/$(am__dirstamp) ../src/IB/$(DEPDIR)/$(am__dirstamp) @@ -2727,7 +2727,7 @@ libIBAMR2d.a: $(libIBAMR2d_a_OBJECTS) $(libIBAMR2d_a_DEPENDENCIES) $(EXTRA_libIB ../src/IB/$(am__dirstamp) ../src/IB/$(DEPDIR)/$(am__dirstamp) ../src/IB/libIBAMR3d_a-IBHydrodynamicForceEvaluator.$(OBJEXT): \ ../src/IB/$(am__dirstamp) ../src/IB/$(DEPDIR)/$(am__dirstamp) -../src/IB/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.$(OBJEXT): \ +../src/IB/libIBAMR3d_a-IBImplicitHierarchyIntegrator.$(OBJEXT): \ ../src/IB/$(am__dirstamp) ../src/IB/$(DEPDIR)/$(am__dirstamp) ../src/IB/libIBAMR3d_a-IBInstrumentPanel.$(OBJEXT): \ ../src/IB/$(am__dirstamp) ../src/IB/$(DEPDIR)/$(am__dirstamp) @@ -3211,7 +3211,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR2d_a-IBHierarchyIntegrator.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR2d_a-IBHydrodynamicForceEvaluator.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR2d_a-IBHydrodynamicSurfaceForceEvaluator.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitHierarchyIntegrator.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR2d_a-IBInstrumentPanel.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR2d_a-IBInstrumentationSpec.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR2d_a-IBInstrumentationSpecFactory.Po@am__quote@ # am--include-marker @@ -3281,7 +3281,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR3d_a-IBHierarchyIntegrator.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR3d_a-IBHydrodynamicForceEvaluator.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR3d_a-IBHydrodynamicSurfaceForceEvaluator.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitHierarchyIntegrator.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR3d_a-IBInstrumentPanel.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR3d_a-IBInstrumentationSpec.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../src/IB/$(DEPDIR)/libIBAMR3d_a-IBInstrumentationSpecFactory.Po@am__quote@ # am--include-marker @@ -3839,19 +3839,19 @@ am--depfiles: $(am__depfiles_remade) @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR2d_a_CXXFLAGS) $(CXXFLAGS) -c -o ../src/IB/libIBAMR2d_a-IBHydrodynamicForceEvaluator.obj `if test -f '../src/IB/IBHydrodynamicForceEvaluator.cpp'; then $(CYGPATH_W) '../src/IB/IBHydrodynamicForceEvaluator.cpp'; else $(CYGPATH_W) '$(srcdir)/../src/IB/IBHydrodynamicForceEvaluator.cpp'; fi` -../src/IB/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.o: ../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR2d_a_CXXFLAGS) $(CXXFLAGS) -MT ../src/IB/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.o -MD -MP -MF ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.Tpo -c -o ../src/IB/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.o `test -f '../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp' || echo '$(srcdir)/'`../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.Tpo ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp' object='../src/IB/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.o' libtool=no @AMDEPBACKSLASH@ +../src/IB/libIBAMR2d_a-IBImplicitHierarchyIntegrator.o: ../src/IB/IBImplicitHierarchyIntegrator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR2d_a_CXXFLAGS) $(CXXFLAGS) -MT ../src/IB/libIBAMR2d_a-IBImplicitHierarchyIntegrator.o -MD -MP -MF ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitHierarchyIntegrator.Tpo -c -o ../src/IB/libIBAMR2d_a-IBImplicitHierarchyIntegrator.o `test -f '../src/IB/IBImplicitHierarchyIntegrator.cpp' || echo '$(srcdir)/'`../src/IB/IBImplicitHierarchyIntegrator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitHierarchyIntegrator.Tpo ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitHierarchyIntegrator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../src/IB/IBImplicitHierarchyIntegrator.cpp' object='../src/IB/libIBAMR2d_a-IBImplicitHierarchyIntegrator.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR2d_a_CXXFLAGS) $(CXXFLAGS) -c -o ../src/IB/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.o `test -f '../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp' || echo '$(srcdir)/'`../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR2d_a_CXXFLAGS) $(CXXFLAGS) -c -o ../src/IB/libIBAMR2d_a-IBImplicitHierarchyIntegrator.o `test -f '../src/IB/IBImplicitHierarchyIntegrator.cpp' || echo '$(srcdir)/'`../src/IB/IBImplicitHierarchyIntegrator.cpp -../src/IB/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.obj: ../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR2d_a_CXXFLAGS) $(CXXFLAGS) -MT ../src/IB/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.obj -MD -MP -MF ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.Tpo -c -o ../src/IB/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.obj `if test -f '../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp'; then $(CYGPATH_W) '../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp'; else $(CYGPATH_W) '$(srcdir)/../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.Tpo ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp' object='../src/IB/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.obj' libtool=no @AMDEPBACKSLASH@ +../src/IB/libIBAMR2d_a-IBImplicitHierarchyIntegrator.obj: ../src/IB/IBImplicitHierarchyIntegrator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR2d_a_CXXFLAGS) $(CXXFLAGS) -MT ../src/IB/libIBAMR2d_a-IBImplicitHierarchyIntegrator.obj -MD -MP -MF ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitHierarchyIntegrator.Tpo -c -o ../src/IB/libIBAMR2d_a-IBImplicitHierarchyIntegrator.obj `if test -f '../src/IB/IBImplicitHierarchyIntegrator.cpp'; then $(CYGPATH_W) '../src/IB/IBImplicitHierarchyIntegrator.cpp'; else $(CYGPATH_W) '$(srcdir)/../src/IB/IBImplicitHierarchyIntegrator.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitHierarchyIntegrator.Tpo ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitHierarchyIntegrator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../src/IB/IBImplicitHierarchyIntegrator.cpp' object='../src/IB/libIBAMR2d_a-IBImplicitHierarchyIntegrator.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR2d_a_CXXFLAGS) $(CXXFLAGS) -c -o ../src/IB/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.obj `if test -f '../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp'; then $(CYGPATH_W) '../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp'; else $(CYGPATH_W) '$(srcdir)/../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR2d_a_CXXFLAGS) $(CXXFLAGS) -c -o ../src/IB/libIBAMR2d_a-IBImplicitHierarchyIntegrator.obj `if test -f '../src/IB/IBImplicitHierarchyIntegrator.cpp'; then $(CYGPATH_W) '../src/IB/IBImplicitHierarchyIntegrator.cpp'; else $(CYGPATH_W) '$(srcdir)/../src/IB/IBImplicitHierarchyIntegrator.cpp'; fi` ../src/IB/libIBAMR2d_a-IBInstrumentPanel.o: ../src/IB/IBInstrumentPanel.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR2d_a_CXXFLAGS) $(CXXFLAGS) -MT ../src/IB/libIBAMR2d_a-IBInstrumentPanel.o -MD -MP -MF ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBInstrumentPanel.Tpo -c -o ../src/IB/libIBAMR2d_a-IBInstrumentPanel.o `test -f '../src/IB/IBInstrumentPanel.cpp' || echo '$(srcdir)/'`../src/IB/IBInstrumentPanel.cpp @@ -6079,19 +6079,19 @@ am--depfiles: $(am__depfiles_remade) @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR3d_a_CXXFLAGS) $(CXXFLAGS) -c -o ../src/IB/libIBAMR3d_a-IBHydrodynamicForceEvaluator.obj `if test -f '../src/IB/IBHydrodynamicForceEvaluator.cpp'; then $(CYGPATH_W) '../src/IB/IBHydrodynamicForceEvaluator.cpp'; else $(CYGPATH_W) '$(srcdir)/../src/IB/IBHydrodynamicForceEvaluator.cpp'; fi` -../src/IB/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.o: ../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR3d_a_CXXFLAGS) $(CXXFLAGS) -MT ../src/IB/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.o -MD -MP -MF ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.Tpo -c -o ../src/IB/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.o `test -f '../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp' || echo '$(srcdir)/'`../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.Tpo ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp' object='../src/IB/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.o' libtool=no @AMDEPBACKSLASH@ +../src/IB/libIBAMR3d_a-IBImplicitHierarchyIntegrator.o: ../src/IB/IBImplicitHierarchyIntegrator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR3d_a_CXXFLAGS) $(CXXFLAGS) -MT ../src/IB/libIBAMR3d_a-IBImplicitHierarchyIntegrator.o -MD -MP -MF ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitHierarchyIntegrator.Tpo -c -o ../src/IB/libIBAMR3d_a-IBImplicitHierarchyIntegrator.o `test -f '../src/IB/IBImplicitHierarchyIntegrator.cpp' || echo '$(srcdir)/'`../src/IB/IBImplicitHierarchyIntegrator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitHierarchyIntegrator.Tpo ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitHierarchyIntegrator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../src/IB/IBImplicitHierarchyIntegrator.cpp' object='../src/IB/libIBAMR3d_a-IBImplicitHierarchyIntegrator.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR3d_a_CXXFLAGS) $(CXXFLAGS) -c -o ../src/IB/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.o `test -f '../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp' || echo '$(srcdir)/'`../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR3d_a_CXXFLAGS) $(CXXFLAGS) -c -o ../src/IB/libIBAMR3d_a-IBImplicitHierarchyIntegrator.o `test -f '../src/IB/IBImplicitHierarchyIntegrator.cpp' || echo '$(srcdir)/'`../src/IB/IBImplicitHierarchyIntegrator.cpp -../src/IB/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.obj: ../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR3d_a_CXXFLAGS) $(CXXFLAGS) -MT ../src/IB/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.obj -MD -MP -MF ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.Tpo -c -o ../src/IB/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.obj `if test -f '../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp'; then $(CYGPATH_W) '../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp'; else $(CYGPATH_W) '$(srcdir)/../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.Tpo ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp' object='../src/IB/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.obj' libtool=no @AMDEPBACKSLASH@ +../src/IB/libIBAMR3d_a-IBImplicitHierarchyIntegrator.obj: ../src/IB/IBImplicitHierarchyIntegrator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR3d_a_CXXFLAGS) $(CXXFLAGS) -MT ../src/IB/libIBAMR3d_a-IBImplicitHierarchyIntegrator.obj -MD -MP -MF ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitHierarchyIntegrator.Tpo -c -o ../src/IB/libIBAMR3d_a-IBImplicitHierarchyIntegrator.obj `if test -f '../src/IB/IBImplicitHierarchyIntegrator.cpp'; then $(CYGPATH_W) '../src/IB/IBImplicitHierarchyIntegrator.cpp'; else $(CYGPATH_W) '$(srcdir)/../src/IB/IBImplicitHierarchyIntegrator.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitHierarchyIntegrator.Tpo ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitHierarchyIntegrator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../src/IB/IBImplicitHierarchyIntegrator.cpp' object='../src/IB/libIBAMR3d_a-IBImplicitHierarchyIntegrator.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR3d_a_CXXFLAGS) $(CXXFLAGS) -c -o ../src/IB/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.obj `if test -f '../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp'; then $(CYGPATH_W) '../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp'; else $(CYGPATH_W) '$(srcdir)/../src/IB/IBImplicitStaggeredHierarchyIntegrator.cpp'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR3d_a_CXXFLAGS) $(CXXFLAGS) -c -o ../src/IB/libIBAMR3d_a-IBImplicitHierarchyIntegrator.obj `if test -f '../src/IB/IBImplicitHierarchyIntegrator.cpp'; then $(CYGPATH_W) '../src/IB/IBImplicitHierarchyIntegrator.cpp'; else $(CYGPATH_W) '$(srcdir)/../src/IB/IBImplicitHierarchyIntegrator.cpp'; fi` ../src/IB/libIBAMR3d_a-IBInstrumentPanel.o: ../src/IB/IBInstrumentPanel.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libIBAMR3d_a_CXXFLAGS) $(CXXFLAGS) -MT ../src/IB/libIBAMR3d_a-IBInstrumentPanel.o -MD -MP -MF ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBInstrumentPanel.Tpo -c -o ../src/IB/libIBAMR3d_a-IBInstrumentPanel.o `test -f '../src/IB/IBInstrumentPanel.cpp' || echo '$(srcdir)/'`../src/IB/IBInstrumentPanel.cpp @@ -8236,7 +8236,7 @@ distclean: distclean-am -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBHierarchyIntegrator.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBHydrodynamicForceEvaluator.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBHydrodynamicSurfaceForceEvaluator.Po - -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.Po + -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitHierarchyIntegrator.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBInstrumentPanel.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBInstrumentationSpec.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBInstrumentationSpecFactory.Po @@ -8306,7 +8306,7 @@ distclean: distclean-am -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBHierarchyIntegrator.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBHydrodynamicForceEvaluator.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBHydrodynamicSurfaceForceEvaluator.Po - -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.Po + -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitHierarchyIntegrator.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBInstrumentPanel.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBInstrumentationSpec.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBInstrumentationSpecFactory.Po @@ -8602,7 +8602,7 @@ maintainer-clean: maintainer-clean-am -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBHierarchyIntegrator.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBHydrodynamicForceEvaluator.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBHydrodynamicSurfaceForceEvaluator.Po - -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitStaggeredHierarchyIntegrator.Po + -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBImplicitHierarchyIntegrator.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBInstrumentPanel.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBInstrumentationSpec.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR2d_a-IBInstrumentationSpecFactory.Po @@ -8672,7 +8672,7 @@ maintainer-clean: maintainer-clean-am -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBHierarchyIntegrator.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBHydrodynamicForceEvaluator.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBHydrodynamicSurfaceForceEvaluator.Po - -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitStaggeredHierarchyIntegrator.Po + -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBImplicitHierarchyIntegrator.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBInstrumentPanel.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBInstrumentationSpec.Po -rm -f ../src/IB/$(DEPDIR)/libIBAMR3d_a-IBInstrumentationSpecFactory.Po diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f902bf8377..dd020c4339 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -150,7 +150,7 @@ SET(CXX_SRC IB/CIBStaggeredStokesSolver.cpp IB/IBKirchhoffRodForceGen.cpp IB/IBAnchorPointSpec.cpp - IB/IBImplicitStaggeredHierarchyIntegrator.cpp + IB/IBImplicitHierarchyIntegrator.cpp IB/IBRedundantInitializer.cpp IB/IBAnchorPointSpecFactory.cpp IB/CIBStrategy.cpp diff --git a/src/IB/IBExplicitHierarchyIntegrator.cpp b/src/IB/IBExplicitHierarchyIntegrator.cpp index 3c27a100e9..3e12d68296 100644 --- a/src/IB/IBExplicitHierarchyIntegrator.cpp +++ b/src/IB/IBExplicitHierarchyIntegrator.cpp @@ -216,6 +216,8 @@ IBExplicitHierarchyIntegrator::integrateHierarchySpecialized(const double curren // Compute the Lagrangian source/sink strengths and spread them to the // Eulerian grid. + // + // TODO: Should this be "half_time" or "new_time"? if (d_ib_method_ops->hasFluidSources()) { if (d_enable_logging) diff --git a/src/IB/IBFEMethod.cpp b/src/IB/IBFEMethod.cpp index 974d9a3c9e..95091e125a 100644 --- a/src/IB/IBFEMethod.cpp +++ b/src/IB/IBFEMethod.cpp @@ -689,10 +689,16 @@ IBFEMethod::interpolateVelocity(const int u_data_idx, } std::vector*> U_vecs = d_U_vecs->get(data_time_str); - std::vector*> X_vecs = d_X_vecs->get(data_time_str); std::vector*> U_rhs_vecs = d_U_IB_vecs->getIBGhosted("tmp"); std::vector*> X_IB_ghost_vecs = d_X_IB_vecs->getIBGhosted("tmp"); - batch_vec_copy(X_vecs, X_IB_ghost_vecs); + if (d_use_fixed_coupling_ops) + { + batch_vec_copy(d_X_IB_vecs->get(data_time_str), X_IB_ghost_vecs); + } + else + { + batch_vec_copy(d_X_vecs->get(data_time_str), X_IB_ghost_vecs); + } batch_vec_ghost_update(X_IB_ghost_vecs, INSERT_VALUES, SCATTER_FORWARD); // Build the right-hand-sides to compute the interpolated data. @@ -945,8 +951,16 @@ IBFEMethod::spreadForce(const int f_data_idx, // Communicate ghost data. std::vector*> X_IB_ghost_vecs = d_X_IB_vecs->getIBGhosted("tmp"); std::vector*> F_IB_ghost_vecs = d_F_IB_vecs->getIBGhosted("tmp"); - batch_vec_copy({ d_X_vecs->get(data_time_str), d_F_vecs->get(data_time_str) }, - { X_IB_ghost_vecs, F_IB_ghost_vecs }); + if (d_use_fixed_coupling_ops) + { + batch_vec_copy({ d_X_IB_vecs->get(data_time_str), d_F_vecs->get(data_time_str) }, + { X_IB_ghost_vecs, F_IB_ghost_vecs }); + } + else + { + batch_vec_copy({ d_X_vecs->get(data_time_str), d_F_vecs->get(data_time_str) }, + { X_IB_ghost_vecs, F_IB_ghost_vecs }); + } batch_vec_ghost_update({ X_IB_ghost_vecs, F_IB_ghost_vecs }, INSERT_VALUES, SCATTER_FORWARD); // set up a new data index for computing forces on the active hierarchy. @@ -1200,7 +1214,14 @@ IBFEMethod::spreadFluidSource(const int q_data_idx, std::vector*> X_IB_ghost_vecs = d_X_IB_vecs->getIBGhosted("tmp"); std::vector*> Q_IB_ghost_vecs = d_Q_IB_vecs->getIBGhosted("tmp"); TBOX_ASSERT(IBTK::rel_equal_eps(data_time, d_half_time)); - batch_vec_copy({ d_X_vecs->get("half"), d_Q_vecs->get("half") }, { X_IB_ghost_vecs, Q_IB_ghost_vecs }); + if (d_use_fixed_coupling_ops) + { + batch_vec_copy({ d_X_IB_vecs->get("half"), d_Q_vecs->get("half") }, { X_IB_ghost_vecs, Q_IB_ghost_vecs }); + } + else + { + batch_vec_copy({ d_X_vecs->get("half"), d_Q_vecs->get("half") }, { X_IB_ghost_vecs, Q_IB_ghost_vecs }); + } batch_vec_ghost_update({ X_IB_ghost_vecs, Q_IB_ghost_vecs }, INSERT_VALUES, SCATTER_FORWARD); if (d_use_scratch_hierarchy) @@ -1235,6 +1256,252 @@ IBFEMethod::spreadFluidSource(const int q_data_idx, return; } // spreadFluidSource +void +IBFEMethod::createSolutionVec(Vec* X_vec) +{ + // TODO: Don't rebuild these vectors each time. + d_implicit_X_vecs.clear(); + std::vector X_vecs; + for (unsigned int part = 0; part < d_meshes.size(); ++part) + { + d_implicit_X_vecs.push_back(std::unique_ptr >( + dynamic_cast*>(d_X_vecs->get("new", part).clone().release()))); + X_vecs.push_back(d_implicit_X_vecs[part]->vec()); + } + PetscErrorCode ierr; + ierr = VecCreateNest(PETSC_COMM_WORLD, d_meshes.size(), nullptr, X_vecs.data(), X_vec); + IBTK_CHKERRQ(ierr); +} + +void +IBFEMethod::createSolverVecs(Vec* X_vec, Vec* F_vec, Vec* R_vec) +{ + // TODO: Don't rebuild these vectors each time. + d_implicit_X_vecs.clear(); + d_implicit_F_vecs.clear(); + d_implicit_R_vecs.clear(); + std::vector X_vecs, F_vecs, R_vecs; + for (unsigned int part = 0; part < d_meshes.size(); ++part) + { + d_implicit_X_vecs.push_back(std::unique_ptr >( + dynamic_cast*>(d_X_vecs->get("new", part).clone().release()))); + X_vecs.push_back(d_implicit_X_vecs[part]->vec()); + + d_implicit_F_vecs.push_back(std::unique_ptr >( + dynamic_cast*>(d_F_vecs->get("new", part).clone().release()))); + F_vecs.push_back(d_implicit_F_vecs[part]->vec()); + + d_implicit_R_vecs.push_back(std::unique_ptr >( + dynamic_cast*>(d_X_vecs->get("RHS Vector", part).clone().release()))); + R_vecs.push_back(d_implicit_R_vecs[part]->vec()); + } + PetscErrorCode ierr; + ierr = VecCreateNest(PETSC_COMM_WORLD, d_meshes.size(), nullptr, X_vecs.data(), X_vec); + IBTK_CHKERRQ(ierr); + ierr = VecCreateNest(PETSC_COMM_WORLD, d_meshes.size(), nullptr, F_vecs.data(), F_vec); + IBTK_CHKERRQ(ierr); + ierr = VecCreateNest(PETSC_COMM_WORLD, d_meshes.size(), nullptr, R_vecs.data(), R_vec); + IBTK_CHKERRQ(ierr); +} + +void +IBFEMethod::setupSolverVecs(Vec& X_vec, Vec& F_vec, Vec& R_vec) +{ + PetscErrorCode ierr; + PetscInt N; + Vec *X_sub_vecs, *F_sub_vecs, *R_sub_vecs; + ierr = VecNestGetSubVecs(X_vec, &N, &X_sub_vecs); + IBTK_CHKERRQ(ierr); + TBOX_ASSERT(static_cast(N) == d_meshes.size()); + ierr = VecNestGetSubVecs(F_vec, &N, &F_sub_vecs); + IBTK_CHKERRQ(ierr); + TBOX_ASSERT(static_cast(N) == d_meshes.size()); + ierr = VecNestGetSubVecs(R_vec, &N, &R_sub_vecs); + IBTK_CHKERRQ(ierr); + TBOX_ASSERT(static_cast(N) == d_meshes.size()); + for (unsigned int part = 0; part < d_meshes.size(); ++part) + { + auto& X_new_petsc_vec = d_X_vecs->get("new", part); + ierr = VecCopy(X_new_petsc_vec.vec(), X_sub_vecs[part]); + auto& F_new_petsc_vec = d_F_vecs->get("new", part); + ierr = VecCopy(F_new_petsc_vec.vec(), F_sub_vecs[part]); + IBTK_CHKERRQ(ierr); + ierr = VecZeroEntries(R_sub_vecs[part]); + IBTK_CHKERRQ(ierr); + } +} + +void +IBFEMethod::setUpdatedPosition(Vec& X_new_vec) +{ + PetscErrorCode ierr; + PetscInt N; + Vec* X_new_sub_vecs; + ierr = VecNestGetSubVecs(X_new_vec, &N, &X_new_sub_vecs); + IBTK_CHKERRQ(ierr); + TBOX_ASSERT(static_cast(N) == d_meshes.size()); + for (unsigned int part = 0; part < d_meshes.size(); ++part) + { + ierr = VecCopy(X_new_sub_vecs[part], d_X_vecs->get("new", part).vec()); + IBTK_CHKERRQ(ierr); + ierr = VecAXPBYPCZ(d_X_vecs->get("half", part).vec(), + 0.5, + 0.5, + 0.0, + d_X_vecs->get("current", part).vec(), + d_X_vecs->get("new", part).vec()); + IBTK_CHKERRQ(ierr); + } + return; +} // setUpdatedPosition + +void +IBFEMethod::setUpdatedForce(Vec& F_new_vec) +{ + PetscErrorCode ierr; + PetscInt N; + Vec* F_new_sub_vecs; + ierr = VecNestGetSubVecs(F_new_vec, &N, &F_new_sub_vecs); + IBTK_CHKERRQ(ierr); + TBOX_ASSERT(static_cast(N) == d_meshes.size()); + for (unsigned int part = 0; part < d_meshes.size(); ++part) + { + ierr = VecCopy(F_new_sub_vecs[part], d_F_vecs->get("new", part).vec()); + IBTK_CHKERRQ(ierr); + ierr = VecAXPBYPCZ(d_F_vecs->get("half", part).vec(), + 0.5, + 0.5, + 0.0, + d_F_vecs->get("current", part).vec(), + d_F_vecs->get("new", part).vec()); + IBTK_CHKERRQ(ierr); + } + return; +} // setUpdatedForce + +void +IBFEMethod::getUpdatedPosition(Vec& X_new_vec) +{ + PetscErrorCode ierr; + PetscInt N; + Vec* X_new_sub_vecs; + ierr = VecNestGetSubVecs(X_new_vec, &N, &X_new_sub_vecs); + IBTK_CHKERRQ(ierr); + TBOX_ASSERT(static_cast(N) == d_meshes.size()); + for (unsigned int part = 0; part < d_meshes.size(); ++part) + { + ierr = VecCopy(d_X_vecs->get("new", part).vec(), X_new_sub_vecs[part]); + IBTK_CHKERRQ(ierr); + } + return; +} // getUpdatedPosition + +void +IBFEMethod::getUpdatedVelocity(Vec& U_new_vec) +{ + PetscErrorCode ierr; + PetscInt N; + Vec* U_new_sub_vecs; + ierr = VecNestGetSubVecs(U_new_vec, &N, &U_new_sub_vecs); + IBTK_CHKERRQ(ierr); + TBOX_ASSERT(static_cast(N) == d_meshes.size()); + for (unsigned int part = 0; part < d_meshes.size(); ++part) + { + ierr = VecCopy(d_U_vecs->get("new", part).vec(), U_new_sub_vecs[part]); + IBTK_CHKERRQ(ierr); + } + return; +} // getUpdatedVelocity + +void +IBFEMethod::getUpdatedForce(Vec& F_new_vec) +{ + PetscErrorCode ierr; + PetscInt N; + Vec* F_new_sub_vecs; + ierr = VecNestGetSubVecs(F_new_vec, &N, &F_new_sub_vecs); + IBTK_CHKERRQ(ierr); + TBOX_ASSERT(static_cast(N) == d_meshes.size()); + for (unsigned int part = 0; part < d_meshes.size(); ++part) + { + ierr = VecCopy(d_F_vecs->get("new", part).vec(), F_new_sub_vecs[part]); + IBTK_CHKERRQ(ierr); + } + return; +} // getUpdatedForce + +void +IBFEMethod::computeResidualBackwardEuler(Vec& R_vec) +{ + PetscErrorCode ierr; + PetscInt N; + Vec* R_sub_vecs; + ierr = VecNestGetSubVecs(R_vec, &N, &R_sub_vecs); + IBTK_CHKERRQ(ierr); + TBOX_ASSERT(static_cast(N) == d_meshes.size()); + for (unsigned int part = 0; part < d_meshes.size(); ++part) + { + const double dt = d_new_time - d_current_time; + ierr = VecWAXPY(R_sub_vecs[part], -dt, d_U_vecs->get("new", part).vec(), d_X_vecs->get("new", part).vec()); + IBTK_CHKERRQ(ierr); + ierr = VecAXPY(R_sub_vecs[part], -1.0, d_X_vecs->get("current", part).vec()); + IBTK_CHKERRQ(ierr); + } + return; +} // computeResidualBackwardEuler + +void +IBFEMethod::computeResidualMidpointRule(Vec& R_vec) +{ + PetscErrorCode ierr; + PetscInt N; + Vec* R_sub_vecs; + ierr = VecNestGetSubVecs(R_vec, &N, &R_sub_vecs); + IBTK_CHKERRQ(ierr); + TBOX_ASSERT(static_cast(N) == d_meshes.size()); + for (unsigned int part = 0; part < d_meshes.size(); ++part) + { + const double dt = d_new_time - d_current_time; + ierr = VecWAXPY(R_sub_vecs[part], -dt, d_U_vecs->get("half", part).vec(), d_X_vecs->get("new", part).vec()); + IBTK_CHKERRQ(ierr); + ierr = VecAXPY(R_sub_vecs[part], -1.0, d_X_vecs->get("current", part).vec()); + IBTK_CHKERRQ(ierr); + } + return; +} // computeResidualMidpointRule + +void +IBFEMethod::computeResidualTrapezoidalRule(Vec& R_vec) +{ + PetscErrorCode ierr; + PetscInt N; + Vec* R_sub_vecs; + ierr = VecNestGetSubVecs(R_vec, &N, &R_sub_vecs); + IBTK_CHKERRQ(ierr); + TBOX_ASSERT(static_cast(N) == d_meshes.size()); + for (unsigned int part = 0; part < d_meshes.size(); ++part) + { + const double dt = d_new_time - d_current_time; + ierr = VecWAXPY( + R_sub_vecs[part], -0.5 * dt, d_U_vecs->get("current", part).vec(), d_X_vecs->get("new", part).vec()); + IBTK_CHKERRQ(ierr); + ierr = VecAXPY(R_sub_vecs[part], -0.5 * dt, d_U_vecs->get("new", part).vec()); + IBTK_CHKERRQ(ierr); + ierr = VecAXPY(R_sub_vecs[part], -1.0, d_X_vecs->get("current", part).vec()); + IBTK_CHKERRQ(ierr); + } + return; +} // computeResidualTrapezoidalRule + +void +IBFEMethod::updateFixedLEOperators() +{ + if (!d_use_fixed_coupling_ops) return; + batch_vec_copy({ d_X_vecs->get("current"), d_X_vecs->get("half"), d_X_vecs->get("new") }, + { d_X_IB_vecs->get("current"), d_X_IB_vecs->get("half"), d_X_IB_vecs->get("new") }); + return; +} + FEDataManager::InterpSpec IBFEMethod::getDefaultInterpSpec() const { diff --git a/src/IB/IBImplicitHierarchyIntegrator.cpp b/src/IB/IBImplicitHierarchyIntegrator.cpp new file mode 100644 index 0000000000..e3f08339bf --- /dev/null +++ b/src/IB/IBImplicitHierarchyIntegrator.cpp @@ -0,0 +1,614 @@ +// --------------------------------------------------------------------- +// +// Copyright (c) 2014 - 2019 by the IBAMR developers +// All rights reserved. +// +// This file is part of IBAMR. +// +// IBAMR is free software and is distributed under the 3-clause BSD +// license. The full text of the license can be found in the file +// COPYRIGHT at the top level directory of IBAMR. +// +// --------------------------------------------------------------------- + +#include "ibamr/IBImplicitHierarchyIntegrator.h" + +/////////////////////////////// INCLUDES ///////////////////////////////////// + +#include "ibtk/IBTK_CHKERRQ.h" +#include "ibtk/IBTK_MPI.h" + +#include "petscksp.h" +#include "petscmat.h" +#include "petscpctypes.h" +#include "petscsnes.h" +#include "petscvec.h" + +#include "ibamr/namespaces.h" // IWYU pragma: keep + +/////////////////////////////// NAMESPACE //////////////////////////////////// + +namespace IBAMR +{ +/////////////////////////////// STATIC /////////////////////////////////////// + +namespace +{ +// Version of IBImplicitHierarchyIntegrator restart file data. +static const int IB_IMPLICIT_HIERARCHY_INTEGRATOR_VERSION = 1; +} // namespace + +/////////////////////////////// PUBLIC /////////////////////////////////////// + +IBImplicitHierarchyIntegrator::IBImplicitHierarchyIntegrator(const std::string& object_name, + Pointer input_db, + Pointer ib_implicit_ops, + Pointer ins_hier_integrator, + bool register_for_restart) + : IBHierarchyIntegrator(object_name, input_db, ib_implicit_ops, ins_hier_integrator, register_for_restart), + d_ib_implicit_ops(ib_implicit_ops) +{ + // Set default configuration options. + d_use_structure_predictor = false; + d_use_fixed_LE_operators = false; + d_eta = std::numeric_limits::quiet_NaN(); + + // Set options from input. + if (input_db) + { + if (input_db->keyExists("use_structure_predictor")) + d_use_structure_predictor = input_db->getBool("use_structure_predictor"); + if (input_db->keyExists("use_fixed_LE_operators")) + d_use_fixed_LE_operators = input_db->getBool("use_fixed_LE_operators"); + if (input_db->keyExists("eta")) d_eta = input_db->getDouble("eta"); + if (input_db->keyExists("f_evals_target_min")) + d_snes_f_evals_target_min = input_db->getInteger("f_evals_target_min"); + if (input_db->keyExists("f_evals_target_max")) + d_snes_f_evals_target_max = input_db->getInteger("f_evals_target_max"); + if (input_db->keyExists("skip_final_update_solution")) + d_skip_final_update_solution = input_db->getBool("skip_final_update_solution"); + } + d_ib_implicit_ops->setUseFixedLEOperators(d_use_fixed_LE_operators); + + // Initialize object with data read from the input and restart databases. + bool from_restart = RestartManager::getManager()->isFromRestart(); + if (from_restart) getFromRestart(); + return; +} // IBImplicitHierarchyIntegrator + +void +IBImplicitHierarchyIntegrator::preprocessIntegrateHierarchy(const double current_time, + const double new_time, + const int num_cycles) +{ + IBHierarchyIntegrator::preprocessIntegrateHierarchy(current_time, new_time, num_cycles); + + switch (d_time_stepping_type) + { + case BACKWARD_EULER: + case TRAPEZOIDAL_RULE: + case MIDPOINT_RULE: + break; + default: + TBOX_ERROR("IBImplicitHierarchyIntegrator::preprocessIntegrateHierarchy(): time_stepping_type = " + << enum_to_string(d_time_stepping_type) << "\n" + << " only supported time_stepping_types are:\n" + << " " << enum_to_string(BACKWARD_EULER) << "\n" + << " " << enum_to_string(TRAPEZOIDAL_RULE) << "\n" + << " " << enum_to_string(MIDPOINT_RULE) << "\n"); + } + + // Initialize IB data. + d_ib_implicit_ops->preprocessIntegrateData(current_time, new_time, num_cycles); + + // Initialize the fluid solver. + d_ins_hier_integrator->setSkipEnforceNumCycles(); + + // Compute the Lagrangian forces and spread them to the Eulerian grid. + switch (d_time_stepping_type) + { + case TRAPEZOIDAL_RULE: + if (d_enable_logging) plog << d_object_name << "::preprocessIntegrateHierarchy(): computing Lagrangian force\n"; + d_ib_method_ops->computeLagrangianForce(current_time); + if (d_enable_logging) + plog << d_object_name + << "::preprocessIntegrateHierarchy(): spreading Lagrangian force " + "to the Eulerian grid\n"; + d_hier_velocity_data_ops->setToScalar(d_f_idx, 0.0); + d_u_phys_bdry_op->setPatchDataIndex(d_f_idx); + d_u_phys_bdry_op->setHomogeneousBc(true); + d_ib_method_ops->spreadForce( + d_f_idx, d_u_phys_bdry_op, getProlongRefineSchedules(d_object_name + "::f"), current_time); + d_u_phys_bdry_op->setHomogeneousBc(false); + d_hier_velocity_data_ops->copyData(d_f_current_idx, d_f_idx); + break; + case BACKWARD_EULER: + case MIDPOINT_RULE: + // intentionally blank + break; + default: + TBOX_ERROR( + d_object_name << "::preprocessIntegrateHierarchy():\n" + << " unsupported time stepping type: " + << enum_to_string(d_time_stepping_type) << "\n" + << " supported time stepping types are: BACKWARD_EULER, MIDPOINT_RULE, TRAPEZOIDAL_RULE\n"); + } + + // Compute an initial prediction of the updated positions of the Lagrangian + // structure. + // + // NOTE: The velocity should already have been interpolated to the + // curvilinear mesh and should not need to be re-interpolated. + if (d_use_structure_predictor) + { + if (d_enable_logging) + plog << d_object_name << "::preprocessIntegrateHierarchy(): performing Lagrangian forward Euler step\n"; + d_ib_implicit_ops->forwardEulerStep(current_time, new_time); + } + + // Zero out the function evaluation counter. + d_snes_f_evals = 0; + + // Execute any registered callbacks. + executePreprocessIntegrateHierarchyCallbackFcns(current_time, new_time, num_cycles); + return; +} // preprocessIntegrateHierarchy + +void +IBImplicitHierarchyIntegrator::integrateHierarchySpecialized(const double current_time, + const double new_time, + const int cycle_num) +{ + d_current_time = current_time; + d_new_time = new_time; + d_cycle_num = cycle_num; + + if (d_use_fixed_LE_operators) d_ib_implicit_ops->updateFixedLEOperators(); + + // Setup Lagrangian vectors used in solving the implicit IB equations. + PetscErrorCode ierr; + Vec X, F, R, R_work; + d_ib_implicit_ops->createSolverVecs(&X, &F, &R); + d_ib_implicit_ops->setupSolverVecs(X, F, R); + ierr = VecDuplicate(R, &R_work); + IBTK_CHKERRQ(ierr); + + // Solve the implicit IB equations. + d_ins_cycle_num = 0; + + SNES snes; + ierr = SNESCreate(PETSC_COMM_WORLD, &snes); + IBTK_CHKERRQ(ierr); + ierr = SNESSetFunction(snes, R_work, IBFunction, this); + IBTK_CHKERRQ(ierr); + ierr = SNESSetOptionsPrefix(snes, "ib_"); + IBTK_CHKERRQ(ierr); + ierr = SNESSetFromOptions(snes); + IBTK_CHKERRQ(ierr); + + ierr = SNESSolve(snes, R, X); + IBTK_CHKERRQ(ierr); + SNESConvergedReason converged_reason; + ierr = SNESGetConvergedReason(snes, &converged_reason); + IBTK_CHKERRQ(ierr); + const bool snes_diverged = converged_reason <= 0; + int f_evals; + ierr = SNESGetNumberFunctionEvals(snes, &f_evals); + d_snes_f_evals += f_evals; + IBTK_CHKERRQ(ierr); + ierr = SNESDestroy(&snes); + IBTK_CHKERRQ(ierr); + + // Check to see if we need to re-do this time step. + auto* var_db = VariableDatabase::getDatabase(); + const auto u_new_idx = var_db->mapVariableAndContextToIndex(d_ins_hier_integrator->getVelocityVariable(), + d_ins_hier_integrator->getNewContext()); + const double dt = new_time - current_time; + const auto cfl = INSHierarchyIntegrator::compute_CFL_number(u_new_idx, dt, d_hierarchy); + const auto cfl_max = d_ins_hier_integrator->getMaximumCFLNumber(); + const bool exceeded_cfl_number = cfl > d_cfl_max_tol * cfl_max; + d_redo_time_step = snes_diverged || exceeded_cfl_number; + + // Ensure that the state variables are consistent with the solution. + if (!d_redo_time_step && !d_skip_final_update_solution) updateSolution(X, nullptr); + + // Deallocate temporary data. + ierr = VecDestroy(&X); + IBTK_CHKERRQ(ierr); + ierr = VecDestroy(&F); + IBTK_CHKERRQ(ierr); + ierr = VecDestroy(&R); + IBTK_CHKERRQ(ierr); + ierr = VecDestroy(&R_work); + IBTK_CHKERRQ(ierr); + + executeIntegrateHierarchyCallbackFcns(current_time, new_time, cycle_num); +} // integrateHierarchy + +void +IBImplicitHierarchyIntegrator::postprocessIntegrateHierarchy(const double current_time, + const double new_time, + const bool skip_synchronize_new_state_data, + const int num_cycles) +{ + const int coarsest_ln = 0; + const int finest_ln = d_hierarchy->getFinestLevelNumber(); + const double dt = new_time - current_time; + VariableDatabase* var_db = VariableDatabase::getDatabase(); + const int u_new_idx = var_db->mapVariableAndContextToIndex(d_ins_hier_integrator->getVelocityVariable(), + d_ins_hier_integrator->getNewContext()); + + // Interpolate the Eulerian velocity to the curvilinear mesh. + d_hier_velocity_data_ops->copyData(d_u_idx, u_new_idx); + if (d_enable_logging) + plog << d_object_name + << "::postprocessIntegrateHierarchy(): interpolating Eulerian " + "velocity to the Lagrangian mesh\n"; + d_u_phys_bdry_op->setPatchDataIndex(d_u_idx); + d_u_phys_bdry_op->setHomogeneousBc(false); + d_ib_implicit_ops->interpolateVelocity(d_u_idx, + getCoarsenSchedules(d_object_name + "::u::CONSERVATIVE_COARSEN"), + getGhostfillRefineSchedules(d_object_name + "::u"), + new_time); + + // Synchronize new state data. + if (!skip_synchronize_new_state_data) + { + if (d_enable_logging) + plog << d_object_name << "::postprocessIntegrateHierarchy(): synchronizing updated data\n"; + synchronizeHierarchyData(NEW_DATA); + } + + // postprocess the objects this class manages... + d_ib_implicit_ops->postprocessIntegrateData(current_time, new_time, num_cycles); + + const int ins_num_cycles = d_ins_hier_integrator->getNumberOfCycles(); + d_ins_hier_integrator->postprocessIntegrateHierarchy( + current_time, new_time, skip_synchronize_new_state_data, ins_num_cycles); + + // ... and postprocess ourself. + HierarchyIntegrator::postprocessIntegrateHierarchy( + current_time, new_time, skip_synchronize_new_state_data, num_cycles); + + // Determine the CFL number. + const auto cfl = INSHierarchyIntegrator::compute_CFL_number(u_new_idx, dt, d_hierarchy); + d_regrid_fluid_cfl_estimate += cfl; + + // Not all IBStrategy objects implement this so make it optional (-1.0 is + // the default value) + if (d_regrid_structure_cfl_interval != -1.0) + d_regrid_structure_cfl_estimate = d_ib_method_ops->getMaxPointDisplacement(); + + if (d_enable_logging) + { + plog << d_object_name << "::postprocessIntegrateHierarchy(): CFL number = " << cfl << "\n"; + plog << d_object_name + << "::postprocessIntegrateHierarchy(): Eulerian estimate of " + "upper bound on IB point displacement since last regrid = " + << d_regrid_fluid_cfl_estimate << "\n"; + + if (d_regrid_structure_cfl_interval != -1.0) + { + plog << d_object_name + << "::postprocessIntegrateHierarchy(): Lagrangian estimate of " + "upper bound on IB point displacement since last regrid = " + << d_regrid_structure_cfl_estimate << "\n"; + } + } + + // Keep track of the number of function evaluations. + d_snes_f_evals_previous = d_snes_f_evals; + + // Deallocate Eulerian scratch data. + for (int ln = coarsest_ln; ln <= finest_ln; ++ln) + { + Pointer > level = d_hierarchy->getPatchLevel(ln); + level->deallocatePatchData(d_u_idx); + level->deallocatePatchData(d_f_idx); + if (d_f_current_idx != -1) level->deallocatePatchData(d_f_current_idx); + } + + // Execute any registered callbacks. + executePostprocessIntegrateHierarchyCallbackFcns( + current_time, new_time, skip_synchronize_new_state_data, num_cycles); + return; +} // postprocessIntegrateHierarchy + +void +IBImplicitHierarchyIntegrator::initializeHierarchyIntegrator(Pointer > hierarchy, + Pointer > gridding_alg) +{ + if (d_integrator_is_initialized) return; + + // Register body force function with INSHierarchyIntegrator + d_ins_hier_integrator->registerBodyForceFunction(new IBEulerianForceFunction(this)); + + // Finish initializing the hierarchy integrator. + IBHierarchyIntegrator::initializeHierarchyIntegrator(hierarchy, gridding_alg); + return; +} // initializeHierarchyIntegrator + +int +IBImplicitHierarchyIntegrator::getNumberOfCycles() const +{ + return d_ins_hier_integrator->getNumberOfCycles(); +} // getNumberOfCycles + +/////////////////////////////// PROTECTED //////////////////////////////////// + +double +IBImplicitHierarchyIntegrator::getMaximumTimeStepSizeSpecialized() +{ + auto dt_max = IBHierarchyIntegrator::getMaximumTimeStepSizeSpecialized(); + const bool initial_time = IBTK::rel_equal_eps(d_integrator_time, d_start_time); + if (initial_time) return dt_max; + if (d_snes_f_evals_previous < d_snes_f_evals_target_min) + { + dt_max = std::min(dt_max, std::max(1.0, d_dt_growth_factor) * d_dt_previous[0]); + } + else if (d_snes_f_evals_previous > d_snes_f_evals_target_max) + { + dt_max = std::min(dt_max, std::min(1.0, d_dt_shrink_factor) * d_dt_previous[0]); + } + else + { + dt_max = std::min(dt_max, d_dt_previous[0]); + } + return dt_max; +} // getMaximumTimeStepSizeSpecialized + +void +IBImplicitHierarchyIntegrator::putToDatabaseSpecialized(Pointer db) +{ + IBHierarchyIntegrator::putToDatabaseSpecialized(db); + db->putInteger("IB_IMPLICIT_HIERARCHY_INTEGRATOR_VERSION", IB_IMPLICIT_HIERARCHY_INTEGRATOR_VERSION); + return; +} // putToDatabaseSpecialized + +/////////////////////////////// PRIVATE ////////////////////////////////////// + +void +IBImplicitHierarchyIntegrator::getFromRestart() +{ + Pointer restart_db = RestartManager::getManager()->getRootDatabase(); + Pointer db; + if (restart_db->isDatabase(d_object_name)) + { + db = restart_db->getDatabase(d_object_name); + } + else + { + TBOX_ERROR(d_object_name << ": Restart database corresponding to " << d_object_name + << " not found in restart file." << std::endl); + } + int ver = db->getInteger("IB_IMPLICIT_HIERARCHY_INTEGRATOR_VERSION"); + if (ver != IB_IMPLICIT_HIERARCHY_INTEGRATOR_VERSION) + { + TBOX_ERROR(d_object_name << ": Restart file version different than class version." << std::endl); + } + return; +} // getFromRestart + +void +IBImplicitHierarchyIntegrator::updateSolution(Vec X, Vec R) +{ + const double current_time = d_current_time; + const double new_time = d_new_time; + const double half_time = current_time + 0.5 * (new_time - current_time); + const int cycle_num = d_cycle_num; + + VariableDatabase* var_db = VariableDatabase::getDatabase(); + const int u_current_idx = var_db->mapVariableAndContextToIndex(d_ins_hier_integrator->getVelocityVariable(), + d_ins_hier_integrator->getCurrentContext()); + const int u_new_idx = var_db->mapVariableAndContextToIndex(d_ins_hier_integrator->getVelocityVariable(), + d_ins_hier_integrator->getNewContext()); + const int p_new_idx = var_db->mapVariableAndContextToIndex(d_ins_hier_integrator->getPressureVariable(), + d_ins_hier_integrator->getNewContext()); + + // Set the current position data. + d_ib_implicit_ops->setUpdatedPosition(X); + + // Compute the Lagrangian forces and spread them to the Eulerian grid. + switch (d_time_stepping_type) + { + case BACKWARD_EULER: + if (d_enable_logging) plog << d_object_name << "::integrateHierarchy(): computing Lagrangian force\n"; + d_ib_method_ops->computeLagrangianForce(d_new_time); + if (d_enable_logging) + plog << d_object_name << "::integrateHierarchy(): spreading Lagrangian force to the Eulerian grid\n"; + d_hier_velocity_data_ops->setToScalar(d_f_idx, 0.0); + d_u_phys_bdry_op->setPatchDataIndex(d_f_idx); + d_u_phys_bdry_op->setHomogeneousBc(true); + d_ib_method_ops->spreadForce( + d_f_idx, d_u_phys_bdry_op, getProlongRefineSchedules(d_object_name + "::f"), new_time); + d_u_phys_bdry_op->setHomogeneousBc(false); + break; + case MIDPOINT_RULE: + if (d_enable_logging) plog << d_object_name << "::integrateHierarchy(): computing Lagrangian force\n"; + d_ib_method_ops->computeLagrangianForce(half_time); + if (d_enable_logging) + plog << d_object_name << "::integrateHierarchy(): spreading Lagrangian force to the Eulerian grid\n"; + d_hier_velocity_data_ops->setToScalar(d_f_idx, 0.0); + d_u_phys_bdry_op->setPatchDataIndex(d_f_idx); + d_u_phys_bdry_op->setHomogeneousBc(true); + d_ib_method_ops->spreadForce( + d_f_idx, d_u_phys_bdry_op, getProlongRefineSchedules(d_object_name + "::f"), half_time); + d_u_phys_bdry_op->setHomogeneousBc(false); + break; + case TRAPEZOIDAL_RULE: + if (d_enable_logging) plog << d_object_name << "::integrateHierarchy(): computing Lagrangian force\n"; + d_ib_method_ops->computeLagrangianForce(new_time); + if (d_enable_logging) + plog << d_object_name << "::integrateHierarchy(): spreading Lagrangian force to the Eulerian grid\n"; + d_hier_velocity_data_ops->setToScalar(d_f_idx, 0.0); + d_u_phys_bdry_op->setPatchDataIndex(d_f_idx); + d_u_phys_bdry_op->setHomogeneousBc(true); + d_ib_method_ops->spreadForce( + d_f_idx, d_u_phys_bdry_op, getProlongRefineSchedules(d_object_name + "::f"), new_time); + d_u_phys_bdry_op->setHomogeneousBc(false); + d_hier_velocity_data_ops->linearSum(d_f_idx, 0.5, d_f_current_idx, 0.5, d_f_idx); + break; + default: + TBOX_ERROR( + d_object_name << "::integrateHierarchy():\n" + << " unsupported time stepping type: " + << enum_to_string(d_time_stepping_type) << "\n" + << " supported time stepping types are: BACKWARD_EULER, MIDPOINT_RULE, TRAPEZOIDAL_RULE\n"); + } + + // Compute the Lagrangian source/sink strengths and spread them to the + // Eulerian grid. + // + // TODO: Should this be "half_time" or "new_time"? + if (d_ib_method_ops->hasFluidSources()) + { + if (d_enable_logging) + plog << d_object_name << "::integrateHierarchy(): computing Lagrangian fluid source strength\n"; + d_ib_method_ops->computeLagrangianFluidSource(half_time); + if (d_enable_logging) + plog << d_object_name + << "::integrateHierarchy(): spreading Lagrangian fluid source " + "strength to the Eulerian grid\n"; + d_hier_pressure_data_ops->setToScalar(d_q_idx, 0.0); + // NOTE: This does not correctly treat the case in which the structure + // is close to the physical boundary. + d_ib_method_ops->spreadFluidSource( + d_q_idx, nullptr, getProlongRefineSchedules(d_object_name + "::q"), half_time); + } + + // Solve the incompressible Navier-Stokes equations. + if (d_enable_logging) + plog << d_object_name << "::integrateHierarchy(): solving the incompressible Navier-Stokes equations\n"; + d_ib_method_ops->preprocessSolveFluidEquations(current_time, new_time, cycle_num); + d_ins_hier_integrator->integrateHierarchy(current_time, new_time, d_ins_cycle_num); + d_ins_cycle_num++; + d_ib_method_ops->postprocessSolveFluidEquations(current_time, new_time, cycle_num); + + // Interpolate the Eulerian velocity to the curvilinear mesh. + switch (d_time_stepping_type) + { + case BACKWARD_EULER: + case TRAPEZOIDAL_RULE: + d_hier_velocity_data_ops->copyData(d_u_idx, u_new_idx); + if (d_enable_logging) + plog << d_object_name + << "::integrateHierarchy(): interpolating Eulerian velocity to " + "the Lagrangian mesh\n"; + d_u_phys_bdry_op->setPatchDataIndex(d_u_idx); + d_u_phys_bdry_op->setHomogeneousBc(false); + d_ib_method_ops->interpolateVelocity(d_u_idx, + getCoarsenSchedules(d_object_name + "::u::CONSERVATIVE_COARSEN"), + getGhostfillRefineSchedules(d_object_name + "::u"), + new_time); + break; + case MIDPOINT_RULE: + d_hier_velocity_data_ops->linearSum(d_u_idx, 0.5, u_current_idx, 0.5, u_new_idx); + if (d_enable_logging) + plog << d_object_name + << "::integrateHierarchy(): interpolating Eulerian velocity to " + "the Lagrangian mesh\n"; + d_u_phys_bdry_op->setPatchDataIndex(d_u_idx); + d_u_phys_bdry_op->setHomogeneousBc(false); + d_ib_method_ops->interpolateVelocity(d_u_idx, + getCoarsenSchedules(d_object_name + "::u::CONSERVATIVE_COARSEN"), + getGhostfillRefineSchedules(d_object_name + "::u"), + half_time); + break; + default: + TBOX_ERROR( + d_object_name << "::integrateHierarchy():\n" + << " unsupported time stepping type: " + << enum_to_string(d_time_stepping_type) << "\n" + << " supported time stepping types are: BACKWARD_EULER, MIDPOINT_RULE, TRAPEZOIDAL_RULE\n"); + } + + // Compute the time stepping-based residual before updating the IB variables. + // + // (Once the IB variables are updated, we can no longer get the residual from the IB ops object.) + if (R != nullptr) + { + switch (d_time_stepping_type) + { + case BACKWARD_EULER: + { + d_ib_implicit_ops->computeResidualBackwardEuler(R); + break; + } + case MIDPOINT_RULE: + { + d_ib_implicit_ops->computeResidualMidpointRule(R); + break; + } + case TRAPEZOIDAL_RULE: + { + d_ib_implicit_ops->computeResidualTrapezoidalRule(R); + break; + } + default: + TBOX_ERROR(d_object_name << "::integrateHierarchy():\n" + << " unsupported time stepping type: " + << enum_to_string(d_time_stepping_type) << "\n" + << " supported time stepping types are: BACKWARD_EULER, " + "MIDPOINT_RULE, TRAPEZOIDAL_RULE\n"); + } + } + + // Update the IB variables. + switch (d_time_stepping_type) + { + case BACKWARD_EULER: + { + d_ib_implicit_ops->backwardEulerStep(current_time, new_time); + break; + } + case MIDPOINT_RULE: + { + d_ib_implicit_ops->midpointStep(current_time, new_time); + break; + } + case TRAPEZOIDAL_RULE: + { + d_ib_implicit_ops->trapezoidalStep(current_time, new_time); + break; + } + default: + TBOX_ERROR(d_object_name << "::integrateHierarchy():\n" + << " unsupported time stepping type: " + << enum_to_string(d_time_stepping_type) << "\n" + << " supported time stepping types are: BACKWARD_EULER, " + "MIDPOINT_RULE, TRAPEZOIDAL_RULE\n"); + } + + // Compute the pressure at the updated locations of any distributed internal + // fluid sources or sinks. + if (d_ib_method_ops->hasFluidSources()) + { + if (d_enable_logging) + plog << d_object_name + << "::integrateHierarchy(): interpolating Eulerian fluid " + "pressure to the Lagrangian mesh\n"; + d_hier_pressure_data_ops->copyData(d_p_idx, p_new_idx); + d_p_phys_bdry_op->setPatchDataIndex(d_p_idx); + d_p_phys_bdry_op->setHomogeneousBc(false); + d_ib_method_ops->interpolatePressure(d_p_idx, + getCoarsenSchedules(d_object_name + "::p::CONSERVATIVE_COARSEN"), + getGhostfillRefineSchedules(d_object_name + "::p"), + half_time); + } + + return; +} + +PetscErrorCode +IBImplicitHierarchyIntegrator::IBFunction(SNES /*snes*/, Vec X, Vec R, void* ctx) +{ + auto integrator = static_cast(ctx); + integrator->updateSolution(X, R); + return 0; +} + +/////////////////////////////// NAMESPACE //////////////////////////////////// + +} // namespace IBAMR + +////////////////////////////////////////////////////////////////////////////// diff --git a/src/IB/IBMethod.cpp b/src/IB/IBMethod.cpp index a08c7a7845..ae876f5a02 100644 --- a/src/IB/IBMethod.cpp +++ b/src/IB/IBMethod.cpp @@ -184,12 +184,6 @@ IBMethod::~IBMethod() RestartManager::getManager()->unregisterRestartItem(d_object_name); d_registered_for_restart = false; } - if (d_force_jac) - { - PetscErrorCode ierr; - ierr = MatDestroy(&d_force_jac); - IBTK_CHKERRQ(ierr); - } return; } // ~IBMethod @@ -353,15 +347,12 @@ IBMethod::preprocessIntegrateData(double current_time, double new_time, int /*nu d_X_current_data.resize(finest_ln + 1); d_X_new_data.resize(finest_ln + 1); d_X_half_data.resize(finest_ln + 1); - d_X_jac_data.resize(finest_ln + 1); d_U_current_data.resize(finest_ln + 1); d_U_new_data.resize(finest_ln + 1); d_U_half_data.resize(finest_ln + 1); - d_U_jac_data.resize(finest_ln + 1); d_F_current_data.resize(finest_ln + 1); d_F_new_data.resize(finest_ln + 1); d_F_half_data.resize(finest_ln + 1); - d_F_jac_data.resize(finest_ln + 1); if (d_use_fixed_coupling_ops) { d_X_LE_new_data.resize(finest_ln + 1); @@ -462,17 +453,14 @@ IBMethod::postprocessIntegrateData(double current_time, double new_time, int /*n d_X_current_data.clear(); d_X_new_data.clear(); d_X_half_data.clear(); - d_X_jac_data.clear(); d_X_LE_new_data.clear(); d_X_LE_half_data.clear(); d_U_current_data.clear(); d_U_new_data.clear(); d_U_half_data.clear(); - d_U_jac_data.clear(); d_F_current_data.clear(); d_F_new_data.clear(); d_F_half_data.clear(); - d_F_jac_data.clear(); // Reset the current time step interval. d_current_time = std::numeric_limits::quiet_NaN(); @@ -482,7 +470,20 @@ IBMethod::postprocessIntegrateData(double current_time, double new_time, int /*n } // postprocessIntegrateData void -IBMethod::createSolverVecs(Vec* X_vec, Vec* F_vec) +IBMethod::createSolutionVec(Vec* X_vec) +{ + PetscErrorCode ierr; + const int level_num = d_hierarchy->getFinestLevelNumber(); + if (X_vec != nullptr) + { + ierr = VecDuplicate(d_X_current_data[level_num]->getVec(), X_vec); + IBTK_CHKERRQ(ierr); + } + return; +} // createSolutionVec + +void +IBMethod::createSolverVecs(Vec* X_vec, Vec* F_vec, Vec* R_vec) { PetscErrorCode ierr; const int level_num = d_hierarchy->getFinestLevelNumber(); @@ -493,25 +494,35 @@ IBMethod::createSolverVecs(Vec* X_vec, Vec* F_vec) } if (F_vec != nullptr) { - ierr = VecDuplicate(d_X_current_data[level_num]->getVec(), F_vec); + ierr = VecDuplicate(d_F_current_data[level_num]->getVec(), F_vec); + IBTK_CHKERRQ(ierr); + } + if (R_vec != nullptr) + { + ierr = VecDuplicate(d_X_current_data[level_num]->getVec(), R_vec); IBTK_CHKERRQ(ierr); } return; } // createSolverVecs void -IBMethod::setupSolverVecs(Vec* X_vec, Vec* F_vec) +IBMethod::setupSolverVecs(Vec& X_vec, Vec& F_vec, Vec& R_vec) { PetscErrorCode ierr; const int level_num = d_hierarchy->getFinestLevelNumber(); if (X_vec != nullptr) { - ierr = VecCopy(d_X_current_data[level_num]->getVec(), *X_vec); + ierr = VecCopy(d_X_current_data[level_num]->getVec(), X_vec); IBTK_CHKERRQ(ierr); } if (F_vec != nullptr) { - ierr = VecSet(*F_vec, 0.0); + ierr = VecCopy(d_F_current_data[level_num]->getVec(), F_vec); + IBTK_CHKERRQ(ierr); + } + if (R_vec != nullptr) + { + ierr = VecZeroEntries(R_vec); IBTK_CHKERRQ(ierr); } return; @@ -537,90 +548,69 @@ IBMethod::setUpdatedPosition(Vec& X_new_vec) } // setUpdatedPosition void -IBMethod::setLinearizedPosition(Vec& X_vec, const double data_time) +IBMethod::setUpdatedForce(Vec& F_new_vec) { PetscErrorCode ierr; const int level_num = d_hierarchy->getFinestLevelNumber(); - std::vector >* X_jac_data; - bool* X_jac_needs_ghost_fill; - getLinearizedPositionData(&X_jac_data, &X_jac_needs_ghost_fill); - ierr = VecCopy(X_vec, (*X_jac_data)[level_num]->getVec()); + ierr = VecCopy(F_new_vec, d_F_new_data[level_num]->getVec()); IBTK_CHKERRQ(ierr); - *X_jac_needs_ghost_fill = true; + d_F_new_needs_ghost_fill = true; - if (d_force_jac) - { - ierr = MatDestroy(&d_force_jac); - IBTK_CHKERRQ(ierr); - d_force_jac = nullptr; - } - d_force_jac_data_time = data_time; - int n_local, n_global; - ierr = VecGetLocalSize(X_vec, &n_local); + std::vector >* F_half_data; + bool* F_half_needs_ghost_fill = nullptr; + getForceData(&F_half_data, &F_half_needs_ghost_fill, d_half_time); + reinitMidpointData(d_F_current_data, d_F_new_data, *F_half_data); + TBOX_ASSERT(F_half_needs_ghost_fill); + *F_half_needs_ghost_fill = true; + + return; +} // setUpdatedForce + +void +IBMethod::getUpdatedPosition(Vec& X_new_vec) +{ + PetscErrorCode ierr; + const int level_num = d_hierarchy->getFinestLevelNumber(); + ierr = VecCopy(d_X_new_data[level_num]->getVec(), X_new_vec); IBTK_CHKERRQ(ierr); - ierr = VecGetSize(X_vec, &n_global); + return; +} // getUpdatedPosition + +void +IBMethod::getUpdatedVelocity(Vec& U_new_vec) +{ + PetscErrorCode ierr; + const int level_num = d_hierarchy->getFinestLevelNumber(); + ierr = VecCopy(d_U_new_data[level_num]->getVec(), U_new_vec); IBTK_CHKERRQ(ierr); + return; +} // getUpdatedVelocity - if (d_force_jac_mffd) - { - ierr = MatCreateMFFD(PETSC_COMM_WORLD, n_local, n_local, n_global, n_global, &d_force_jac); - IBTK_CHKERRQ(ierr); - ierr = MatMFFDSetFunction(d_force_jac, computeForce_SAMRAI, this); - IBTK_CHKERRQ(ierr); - ierr = MatSetOptionsPrefix(d_force_jac, "ib_jac_"); - IBTK_CHKERRQ(ierr); - ierr = MatSetFromOptions(d_force_jac); - IBTK_CHKERRQ(ierr); - ierr = MatMFFDSetBase(d_force_jac, (*X_jac_data)[level_num]->getVec(), nullptr); - IBTK_CHKERRQ(ierr); - ierr = MatAssemblyBegin(d_force_jac, MAT_FINAL_ASSEMBLY); - IBTK_CHKERRQ(ierr); - ierr = MatAssemblyEnd(d_force_jac, MAT_FINAL_ASSEMBLY); - IBTK_CHKERRQ(ierr); - } - else - { - std::vector d_nnz, o_nnz; - d_ib_force_fcn->computeLagrangianForceJacobianNonzeroStructure( - d_nnz, o_nnz, d_hierarchy, level_num, d_l_data_manager); - std::vector d_nnz_unblocked(NDIM * d_nnz.size()), o_nnz_unblocked(NDIM * o_nnz.size()); - for (unsigned int k = 0; k < d_nnz.size(); ++k) - { - for (unsigned int d = 0; d < NDIM; ++d) - { - d_nnz_unblocked[NDIM * k + d] = NDIM * d_nnz[k]; - o_nnz_unblocked[NDIM * k + d] = NDIM * o_nnz[k]; - } - } - ierr = MatCreateAIJ(PETSC_COMM_WORLD, - n_local, - n_local, - n_global, - n_global, - 0, - n_local ? &d_nnz_unblocked[0] : nullptr, - 0, - n_local ? &o_nnz_unblocked[0] : nullptr, - &d_force_jac); - IBTK_CHKERRQ(ierr); - ierr = MatSetBlockSize(d_force_jac, NDIM); - IBTK_CHKERRQ(ierr); - d_ib_force_fcn->computeLagrangianForceJacobian(d_force_jac, - MAT_FINAL_ASSEMBLY, - 1.0, - (*X_jac_data)[level_num], - 0.0, - Pointer(nullptr), - d_hierarchy, - level_num, - data_time, - d_l_data_manager); - } +void +IBMethod::getUpdatedForce(Vec& F_new_vec) +{ + PetscErrorCode ierr; + const int level_num = d_hierarchy->getFinestLevelNumber(); + ierr = VecCopy(d_F_new_data[level_num]->getVec(), F_new_vec); + IBTK_CHKERRQ(ierr); + return; +} // getUpdatedVelocity + +void +IBMethod::computeResidualBackwardEuler(Vec& R_vec) +{ + PetscErrorCode ierr; + const int level_num = d_hierarchy->getFinestLevelNumber(); + const double dt = d_new_time - d_current_time; + ierr = VecWAXPY(R_vec, -dt, d_U_new_data[level_num]->getVec(), d_X_new_data[level_num]->getVec()); + IBTK_CHKERRQ(ierr); + ierr = VecAXPY(R_vec, -1.0, d_X_current_data[level_num]->getVec()); + IBTK_CHKERRQ(ierr); return; -} // setLinearizedPosition +} // computeResidualBackwardEuler void -IBMethod::computeResidual(Vec& R_vec) +IBMethod::computeResidualMidpointRule(Vec& R_vec) { PetscErrorCode ierr; const int level_num = d_hierarchy->getFinestLevelNumber(); @@ -630,18 +620,22 @@ IBMethod::computeResidual(Vec& R_vec) ierr = VecAXPY(R_vec, -1.0, d_X_current_data[level_num]->getVec()); IBTK_CHKERRQ(ierr); return; -} // computeResidual +} // computeResidualMidpointRule void -IBMethod::computeLinearizedResidual(Vec& X_vec, Vec& R_vec) +IBMethod::computeResidualTrapezoidalRule(Vec& R_vec) { PetscErrorCode ierr; const int level_num = d_hierarchy->getFinestLevelNumber(); const double dt = d_new_time - d_current_time; - ierr = VecWAXPY(R_vec, -dt, d_U_jac_data[level_num]->getVec(), X_vec); + ierr = VecWAXPY(R_vec, -0.5 * dt, d_U_current_data[level_num]->getVec(), d_X_new_data[level_num]->getVec()); + IBTK_CHKERRQ(ierr); + ierr = VecAXPY(R_vec, -0.5 * dt, d_U_new_data[level_num]->getVec()); + IBTK_CHKERRQ(ierr); + ierr = VecAXPY(R_vec, -1.0, d_X_current_data[level_num]->getVec()); IBTK_CHKERRQ(ierr); return; -} // computeLinearizedResidual +} // computeResidualTrapezoidalRule void IBMethod::updateFixedLEOperators() @@ -692,23 +686,6 @@ IBMethod::interpolateVelocity(const int u_data_idx, return; } // interpolateVelocity -void -IBMethod::interpolateLinearizedVelocity(const int u_data_idx, - const std::vector > >& u_synch_scheds, - const std::vector > >& u_ghost_fill_scheds, - const double data_time) -{ - std::vector >*U_jac_data, *X_LE_data; - bool* X_LE_needs_ghost_fill; - getLinearizedVelocityData(&U_jac_data); - getLECouplingPositionData(&X_LE_data, &X_LE_needs_ghost_fill, data_time); - d_l_data_manager->interp(u_data_idx, *U_jac_data, *X_LE_data, u_synch_scheds, u_ghost_fill_scheds, data_time); - resetAnchorPointValues(*U_jac_data, - /*coarsest_ln*/ 0, - /*finest_ln*/ d_hierarchy->getFinestLevelNumber()); - return; -} // interpolateLinearizedVelocity - void IBMethod::forwardEulerStep(const double current_time, const double new_time) { @@ -843,7 +820,7 @@ IBMethod::computeLagrangianForce(const double data_time) for (int ln = coarsest_ln; ln <= finest_ln; ++ln) { if (!d_l_data_manager->levelContainsLagrangianData(ln)) continue; - ierr = VecSet((*F_data)[ln]->getVec(), 0.0); + ierr = VecZeroEntries((*F_data)[ln]->getVec()); IBTK_CHKERRQ(ierr); if (d_ib_force_fcn) { @@ -855,118 +832,6 @@ IBMethod::computeLagrangianForce(const double data_time) return; } // computeLagrangianForce -void -IBMethod::computeLinearizedLagrangianForce(Vec& X_vec, const double /*data_time*/) -{ - PetscErrorCode ierr; - const int level_num = d_hierarchy->getFinestLevelNumber(); - std::vector >* F_jac_data; - bool* F_jac_needs_ghost_fill; - getLinearizedForceData(&F_jac_data, &F_jac_needs_ghost_fill); - Vec F_vec = (*F_jac_data)[level_num]->getVec(); - ierr = MatMult(d_force_jac, X_vec, F_vec); - IBTK_CHKERRQ(ierr); - *F_jac_needs_ghost_fill = true; - IBTK_CHKERRQ(ierr); - return; -} // computeLinearizedLagrangianForce - -void -IBMethod::constructLagrangianForceJacobian(Mat& A, MatType mat_type, const double data_time) -{ - const int finest_ln = d_hierarchy->getFinestLevelNumber(); - - if (!std::strcmp(mat_type, MATMFFD) || !std::strcmp(mat_type, MATSHELL)) - { - if (!d_force_jac) - { - Vec X_current = d_X_current_data[finest_ln]->getVec(); - setLinearizedPosition(X_current, data_time); - } - A = d_force_jac; - } - else - { - int ierr; - if (A) - { - ierr = MatDestroy(&A); - IBTK_CHKERRQ(ierr); - } - - // Get the "frozen" position for Lagrangian structure. - std::vector >* X_LE_data; - bool* X_LE_needs_ghost_fill; - getLECouplingPositionData(&X_LE_data, &X_LE_needs_ghost_fill, data_time); - - TBOX_ASSERT(d_ib_force_fcn); - - // Build the Jacobian matrix. - const int num_local_nodes = d_l_data_manager->getNumberOfLocalNodes(finest_ln); - std::vector d_nnz, o_nnz; - d_ib_force_fcn->computeLagrangianForceJacobianNonzeroStructure( - d_nnz, o_nnz, d_hierarchy, finest_ln, d_l_data_manager); - if (!std::strcmp(mat_type, MATBAIJ) || !std::strcmp(mat_type, MATMPIBAIJ)) - { - ierr = MatCreateBAIJ(PETSC_COMM_WORLD, - NDIM, - NDIM * num_local_nodes, - NDIM * num_local_nodes, - PETSC_DETERMINE, - PETSC_DETERMINE, - 0, - num_local_nodes ? &d_nnz[0] : nullptr, - 0, - num_local_nodes ? &o_nnz[0] : nullptr, - &A); - IBTK_CHKERRQ(ierr); - } - else if (!std::strcmp(mat_type, MATAIJ) || !std::strcmp(mat_type, MATMPIAIJ)) - { - std::vector d_nnz_unblocked(NDIM * d_nnz.size()), o_nnz_unblocked(NDIM * o_nnz.size()); - for (unsigned int k = 0; k < d_nnz.size(); ++k) - { - for (unsigned int d = 0; d < NDIM; ++d) - { - d_nnz_unblocked[NDIM * k + d] = NDIM * d_nnz[k]; - o_nnz_unblocked[NDIM * k + d] = NDIM * o_nnz[k]; - } - } - ierr = MatCreateAIJ(PETSC_COMM_WORLD, - NDIM * num_local_nodes, - NDIM * num_local_nodes, - PETSC_DETERMINE, - PETSC_DETERMINE, - 0, - num_local_nodes ? &d_nnz_unblocked[0] : nullptr, - 0, - num_local_nodes ? &o_nnz_unblocked[0] : nullptr, - &A); - IBTK_CHKERRQ(ierr); - } - else - { - TBOX_ERROR(d_object_name + "::getLagrangianForceJacobian()." - << "Matrix of the type " << mat_type << " given. Supported types are " << MATSHELL << "/" - << MATMFFD << " , " << MATBAIJ << "/" << MATMPIBAIJ << " , " << MATAIJ << "/" << MATMPIAIJ - << std::endl); - } - ierr = MatSetBlockSize(A, NDIM); - IBTK_CHKERRQ(ierr); - d_ib_force_fcn->computeLagrangianForceJacobian(A, - MAT_FINAL_ASSEMBLY, - 1.0, - (*X_LE_data)[finest_ln], - 0.0, - Pointer(nullptr), - d_hierarchy, - finest_ln, - data_time, - d_l_data_manager); - } - return; -} // getLagrangianForceJacobian - void IBMethod::spreadForce(const int f_data_idx, RobinPhysBdryPatchStrategy* f_phys_bdry_op, @@ -993,32 +858,6 @@ IBMethod::spreadForce(const int f_data_idx, return; } // spreadForce -void -IBMethod::spreadLinearizedForce(const int f_data_idx, - RobinPhysBdryPatchStrategy* f_phys_bdry_op, - const std::vector > >& f_prolongation_scheds, - const double data_time) -{ - std::vector >*F_jac_data, *X_LE_data; - bool *F_jac_needs_ghost_fill, *X_LE_needs_ghost_fill; - getLinearizedForceData(&F_jac_data, &F_jac_needs_ghost_fill); - getLECouplingPositionData(&X_LE_data, &X_LE_needs_ghost_fill, data_time); - resetAnchorPointValues(*F_jac_data, - /*coarsest_ln*/ 0, - /*finest_ln*/ d_hierarchy->getFinestLevelNumber()); - d_l_data_manager->spread(f_data_idx, - *F_jac_data, - *X_LE_data, - f_phys_bdry_op, - f_prolongation_scheds, - data_time, - *F_jac_needs_ghost_fill, - *X_LE_needs_ghost_fill); - *F_jac_needs_ghost_fill = false; - *X_LE_needs_ghost_fill = false; - return; -} // spreadLinearizedForce - void IBMethod::constructInterpOp(Mat& J, void (*spread_fnc)(const double, double*), @@ -1456,14 +1295,6 @@ IBMethod::initializePatchHierarchy(Pointer > hierarchy, // Indicate that the force and source strategies need to be re-initialized. d_ib_force_fcn_needs_init = true; d_ib_source_fcn_needs_init = true; - - // Deallocate any previously allocated Jacobian data structures. - if (d_force_jac) - { - PetscErrorCode ierr; - ierr = MatDestroy(&d_force_jac); - IBTK_CHKERRQ(ierr); - } return; } // initializePatchHierarchy @@ -1724,25 +1555,6 @@ IBMethod::getPositionData(std::vector >** X_data, bool** X_needs_ return; } // getPositionData -void -IBMethod::getLinearizedPositionData(std::vector >** X_jac_data, bool** X_jac_needs_ghost_fill) -{ - const int coarsest_ln = 0; - const int finest_ln = d_hierarchy->getFinestLevelNumber(); - for (int ln = coarsest_ln; ln <= finest_ln; ++ln) - { - if (!d_l_data_manager->levelContainsLagrangianData(ln)) continue; - if (!d_X_jac_data[ln]) - { - d_X_jac_data[ln] = d_l_data_manager->createLData("X_jac", ln, NDIM); - d_X_jac_needs_ghost_fill = true; - } - } - *X_jac_data = &d_X_jac_data; - *X_jac_needs_ghost_fill = &d_X_jac_needs_ghost_fill; - return; -} // getLinearizedPositionData - void IBMethod::getLECouplingPositionData(std::vector >** X_LE_data, bool** X_LE_needs_ghost_fill, @@ -1769,6 +1581,10 @@ IBMethod::getLECouplingPositionData(std::vector >** X_LE_data, *X_LE_data = &d_X_LE_new_data; *X_LE_needs_ghost_fill = &d_X_LE_new_needs_ghost_fill; } + else + { + *X_LE_data = nullptr; + } return; } // getLECouplingPositionData @@ -1787,25 +1603,12 @@ IBMethod::getVelocityData(std::vector >** U_data, double data_tim { *U_data = &d_U_new_data; } - return; -} // getVelocityData - -void -IBMethod::getLinearizedVelocityData(std::vector >** U_jac_data) -{ - const int coarsest_ln = 0; - const int finest_ln = d_hierarchy->getFinestLevelNumber(); - for (int ln = coarsest_ln; ln <= finest_ln; ++ln) + else { - if (!d_l_data_manager->levelContainsLagrangianData(ln)) continue; - if (!d_U_jac_data[ln]) - { - d_U_jac_data[ln] = d_l_data_manager->createLData("U_jac", ln, NDIM); - } + *U_data = nullptr; } - *U_jac_data = &d_U_jac_data; return; -} // getLinearizedVelocityData +} // getVelocityData void IBMethod::getForceData(std::vector >** F_data, bool** F_needs_ghost_fill, double data_time) @@ -1832,27 +1635,12 @@ IBMethod::getForceData(std::vector >** F_data, bool** F_needs_gho *F_data = &d_F_new_data; *F_needs_ghost_fill = &d_F_new_needs_ghost_fill; } - return; -} // getForceData - -void -IBMethod::getLinearizedForceData(std::vector >** F_jac_data, bool** F_jac_needs_ghost_fill) -{ - const int coarsest_ln = 0; - const int finest_ln = d_hierarchy->getFinestLevelNumber(); - for (int ln = coarsest_ln; ln <= finest_ln; ++ln) + else { - if (!d_l_data_manager->levelContainsLagrangianData(ln)) continue; - if (!d_F_jac_data[ln]) - { - d_F_jac_data[ln] = d_l_data_manager->createLData("F_jac", ln, NDIM); - d_F_jac_needs_ghost_fill = true; - } + *F_data = nullptr; } - *F_jac_data = &d_F_jac_data; - *F_jac_needs_ghost_fill = &d_F_jac_needs_ghost_fill; return; -} // getLinearizedForceData +} // getForceData void IBMethod::reinitMidpointData(const std::vector >& current_data, @@ -2025,7 +1813,6 @@ IBMethod::getFromInput(Pointer db, bool is_from_restart) TBOX_ASSERT(LEInteractor::isKnownKernel(d_spread_kernel_fcn)); if (db->keyExists("error_if_points_leave_domain")) d_error_if_points_leave_domain = db->getBool("error_if_points_leave_domain"); - if (db->keyExists("force_jac_mffd")) d_force_jac_mffd = db->getBool("force_jac_mffd"); if (db->keyExists("do_log")) d_do_log = db->getBool("do_log"); else if (db->keyExists("enable_logging")) @@ -2103,37 +1890,6 @@ IBMethod::getFromRestart() return; } // getFromRestart -PetscErrorCode -IBMethod::computeForce_SAMRAI(void* ctx, Vec X, Vec F) -{ - PetscErrorCode ierr; - auto ib_method_ops = static_cast(ctx); - ierr = ib_method_ops->computeForce(X, F); - CHKERRQ(ierr); - return ierr; -} // computeForce_SAMRAI - -PetscErrorCode -IBMethod::computeForce(Vec X, Vec F) -{ - PetscErrorCode ierr; - std::vector >*F_data, *X_data; - bool *F_needs_ghost_fill, *X_needs_ghost_fill; - getForceData(&F_data, &F_needs_ghost_fill, d_force_jac_data_time); - getPositionData(&X_data, &X_needs_ghost_fill, d_force_jac_data_time); - const int level_num = d_hierarchy->getFinestLevelNumber(); - ierr = VecSwap(X, (*X_data)[level_num]->getVec()); - CHKERRQ(ierr); - ierr = VecSwap(F, (*F_data)[level_num]->getVec()); - CHKERRQ(ierr); - computeLagrangianForce(d_force_jac_data_time); - ierr = VecSwap(X, (*X_data)[level_num]->getVec()); - CHKERRQ(ierr); - ierr = VecSwap(F, (*F_data)[level_num]->getVec()); - CHKERRQ(ierr); - return ierr; -} // computeForce - /////////////////////////////// NAMESPACE //////////////////////////////////// } // namespace IBAMR diff --git a/src/navier_stokes/INSHierarchyIntegrator.cpp b/src/navier_stokes/INSHierarchyIntegrator.cpp index eeeb6e1751..cc1228005a 100644 --- a/src/navier_stokes/INSHierarchyIntegrator.cpp +++ b/src/navier_stokes/INSHierarchyIntegrator.cpp @@ -68,6 +68,36 @@ namespace static const int INS_HIERARCHY_INTEGRATOR_VERSION = 3; } // namespace +double +INSHierarchyIntegrator::compute_CFL_number(const int data_idx, const double dt, const PatchHierarchy* patch_hierarchy) +{ + double cfl_max = 0.0; + PatchCellDataOpsReal patch_cc_ops; + PatchSideDataOpsReal patch_sc_ops; + for (int ln = 0; ln <= patch_hierarchy->getFinestLevelNumber(); ++ln) + { + Pointer > level = patch_hierarchy->getPatchLevel(ln); + for (PatchLevel::Iterator p(level); p; p++) + { + Pointer > patch = level->getPatch(p()); + const Box& patch_box = patch->getBox(); + const Pointer > pgeom = patch->getPatchGeometry(); + const double* const dx = pgeom->getDx(); + const double dx_min = *(std::min_element(dx, dx + NDIM)); + Pointer > u_cc_new_data = patch->getPatchData(data_idx); + Pointer > u_sc_new_data = patch->getPatchData(data_idx); +#ifndef NDEBUG + TBOX_ASSERT(u_cc_new_data || u_sc_new_data); +#endif + double u_max = 0.0; + if (u_cc_new_data) u_max = patch_cc_ops.maxNorm(u_cc_new_data, patch_box); + if (u_sc_new_data) u_max = patch_sc_ops.maxNorm(u_sc_new_data, patch_box); + cfl_max = std::max(cfl_max, u_max * dt / dx_min); + } + } + return IBTK_MPI::maxReduction(cfl_max); +} + /////////////////////////////// PUBLIC /////////////////////////////////////// INSHierarchyIntegrator::~INSHierarchyIntegrator() @@ -536,32 +566,7 @@ INSHierarchyIntegrator::INSHierarchyIntegrator(std::string object_name, void INSHierarchyIntegrator::updateCurrentCFLNumber(const int data_idx, const double dt) { - double cfl_max = 0.0; - PatchCellDataOpsReal patch_cc_ops; - PatchSideDataOpsReal patch_sc_ops; - for (int ln = 0; ln <= d_hierarchy->getFinestLevelNumber(); ++ln) - { - Pointer > level = d_hierarchy->getPatchLevel(ln); - for (PatchLevel::Iterator p(level); p; p++) - { - Pointer > patch = level->getPatch(p()); - const Box& patch_box = patch->getBox(); - const Pointer > pgeom = patch->getPatchGeometry(); - const double* const dx = pgeom->getDx(); - const double dx_min = *(std::min_element(dx, dx + NDIM)); - Pointer > u_cc_new_data = patch->getPatchData(data_idx); - Pointer > u_sc_new_data = patch->getPatchData(data_idx); -#ifndef NDEBUG - TBOX_ASSERT(u_cc_new_data || u_sc_new_data); -#endif - double u_max = 0.0; - if (u_cc_new_data) u_max = patch_cc_ops.maxNorm(u_cc_new_data, patch_box); - if (u_sc_new_data) u_max = patch_sc_ops.maxNorm(u_sc_new_data, patch_box); - cfl_max = std::max(cfl_max, u_max * dt / dx_min); - } - } - - d_cfl_current = IBTK_MPI::maxReduction(cfl_max); + d_cfl_current = compute_CFL_number(data_idx, dt, d_hierarchy); } // updateCurrentCFLNumber double diff --git a/src/navier_stokes/INSStaggeredHierarchyIntegrator.cpp b/src/navier_stokes/INSStaggeredHierarchyIntegrator.cpp index 7d85a88a4d..398dfec26b 100644 --- a/src/navier_stokes/INSStaggeredHierarchyIntegrator.cpp +++ b/src/navier_stokes/INSStaggeredHierarchyIntegrator.cpp @@ -1408,45 +1408,49 @@ INSStaggeredHierarchyIntegrator::setupSolverVectors(const PointergetComponentDescriptorIndex(0); const TimeSteppingType convective_time_stepping_type = getConvectiveTimeSteppingType(cycle_num); - if (cycle_num > 0) + if (cycle_num == 0 && convective_time_stepping_type == ADAMS_BASHFORTH) + { + TBOX_ASSERT(cycle_num == 0); + const double omega = dt / d_dt_previous[0]; + d_hier_sc_data_ops->linearSum(N_idx, 1.0 + 0.5 * omega, N_idx, -0.5 * omega, d_N_old_current_idx); + } + else if (cycle_num > 0) { const int U_adv_idx = d_U_adv_vec->getComponentDescriptorIndex(0); double apply_time = std::numeric_limits::quiet_NaN(); + bool update_convective_term = false; if (convective_time_stepping_type == MIDPOINT_RULE) { + update_convective_term = true; d_hier_sc_data_ops->linearSum(U_adv_idx, 0.5, d_U_current_idx, 0.5, d_U_new_idx); apply_time = half_time; } else if (convective_time_stepping_type == TRAPEZOIDAL_RULE) { + update_convective_term = true; d_hier_sc_data_ops->copyData(U_adv_idx, d_U_new_idx); apply_time = new_time; } - for (int ln = finest_ln; ln > coarsest_ln; --ln) + if (update_convective_term) { - Pointer > coarsen_alg = new CoarsenAlgorithm(); - Pointer > grid_geom = d_hierarchy->getGridGeometry(); - Pointer > coarsen_op = - grid_geom->lookupCoarsenOperator(d_U_var, d_U_coarsen_type); - coarsen_alg->registerCoarsen(U_adv_idx, U_adv_idx, coarsen_op); - coarsen_alg->resetSchedule(getCoarsenSchedules(d_object_name + "::CONVECTIVE_OP")[ln]); - getCoarsenSchedules(d_object_name + "::CONVECTIVE_OP")[ln]->coarsenData(); - getCoarsenAlgorithm(d_object_name + "::CONVECTIVE_OP") - ->resetSchedule(getCoarsenSchedules(d_object_name + "::CONVECTIVE_OP")[ln]); + for (int ln = finest_ln; ln > coarsest_ln; --ln) + { + Pointer > coarsen_alg = new CoarsenAlgorithm(); + Pointer > grid_geom = d_hierarchy->getGridGeometry(); + Pointer > coarsen_op = + grid_geom->lookupCoarsenOperator(d_U_var, d_U_coarsen_type); + coarsen_alg->registerCoarsen(U_adv_idx, U_adv_idx, coarsen_op); + coarsen_alg->resetSchedule(getCoarsenSchedules(d_object_name + "::CONVECTIVE_OP")[ln]); + getCoarsenSchedules(d_object_name + "::CONVECTIVE_OP")[ln]->coarsenData(); + getCoarsenAlgorithm(d_object_name + "::CONVECTIVE_OP") + ->resetSchedule(getCoarsenSchedules(d_object_name + "::CONVECTIVE_OP")[ln]); + } + d_convective_op->setAdvectionVelocity(d_U_adv_vec->getComponentDescriptorIndex(0)); + d_convective_op->setSolutionTime(apply_time); + d_convective_op->apply(*d_U_adv_vec, *d_N_vec); } - d_convective_op->setAdvectionVelocity(d_U_adv_vec->getComponentDescriptorIndex(0)); - d_convective_op->setSolutionTime(apply_time); - d_convective_op->apply(*d_U_adv_vec, *d_N_vec); - } - const int N_idx = d_N_vec->getComponentDescriptorIndex(0); - if (convective_time_stepping_type == ADAMS_BASHFORTH) - { -#if !defined(NDEBUG) - TBOX_ASSERT(cycle_num == 0); -#endif - const double omega = dt / d_dt_previous[0]; - d_hier_sc_data_ops->linearSum(N_idx, 1.0 + 0.5 * omega, N_idx, -0.5 * omega, d_N_old_current_idx); } if (convective_time_stepping_type == ADAMS_BASHFORTH || convective_time_stepping_type == MIDPOINT_RULE) { @@ -2764,32 +2768,16 @@ INSStaggeredHierarchyIntegrator::computeDivSourceTerm(const int F_idx, const int } // computeDivSourceTerm TimeSteppingType -INSStaggeredHierarchyIntegrator::getConvectiveTimeSteppingType(const int cycle_num) +INSStaggeredHierarchyIntegrator::getConvectiveTimeSteppingType(const int /*cycle_num*/) { TimeSteppingType convective_time_stepping_type = d_convective_time_stepping_type; if (is_multistep_time_stepping_type(convective_time_stepping_type)) { -#if !defined(NDEBUG) TBOX_ASSERT(convective_time_stepping_type == ADAMS_BASHFORTH); -#endif if (getIntegratorStep() == 0) { convective_time_stepping_type = d_init_convective_time_stepping_type; } - else if (cycle_num > 0) - { - convective_time_stepping_type = MIDPOINT_RULE; - IBAMR_DO_ONCE({ - pout << "INSStaggeredHierarchyIntegrator::integrateHierarchy():\n" - << " WARNING: convective_time_stepping_type = " - << enum_to_string(d_convective_time_stepping_type) - << " but num_cycles = " << d_current_num_cycles << " > 1.\n" - << " using " << enum_to_string(d_convective_time_stepping_type) - << " only for the first cycle in each time step;\n" - << " using " << enum_to_string(convective_time_stepping_type) - << " for subsequent cycles.\n"; - }); - } } return convective_time_stepping_type; } // getConvectiveTimeSteppingType