//----------------------------------------------------------------------
// Define body relation map.
// The contact map gives the topological connections between the bodies.
// Basically the the range of bodies to build neighbor particle lists.
// Generally, we first define all the inner relations, then the contact relations.
//----------------------------------------------------------------------
InnerRelation water_block_inner(water_block);
ContactRelation water_wall_contact(water_block, {&wall_boundary});
ContactRelation fluid_observer_contact(fluid_observer, {&water_block});
// Combined relations built from basic relations
// which is only used for update configuration.
//----------------------------------------------------------------------
ComplexRelation water_wall_complex(water_block_inner, water_wall_contact);
//----------------------------------------------------------------------
// Define the numerical methods used in the simulation.
// Note that there may be data dependence on the sequence of constructions.
// Generally, the geometric models or simple objects without data dependencies,
// such as gravity, should be initiated first.
// Then the major physical particle dynamics model should be introduced.
// Finally, the auxiliary models such as time step estimator, initial condition,
// boundary condition and other constraints should be defined.
//----------------------------------------------------------------------
Gravity gravity(Vecd(0.0, -gravity_g));
SimpleDynamics<GravityForce<Gravity>> constant_gravity(water_block, gravity);
SimpleDynamics<NormalDirectionFromBodyShape> wall_boundary_normal_direction(wall_boundary);
// Define the configuration related particles dynamics.
//----------------------------------------------------------------------
ParticleSorting particle_sorting(water_block);
// Define the methods for I/O operations, observations
// and regression tests of the simulation.
//----------------------------------------------------------------------
BodyStatesRecordingToVtp body_states_recording(sph_system);
body_states_recording.addToWrite<Vecd>(wall_boundary, "NormalDirection");
RestartIO restart_io(sph_system);
RegressionTestDynamicTimeWarping<ReducedQuantityRecording<TotalMechanicalEnergy>> write_water_mechanical_energy(water_block, gravity);
RegressionTestDynamicTimeWarping<ObservedQuantityRecording<Real>> write_recorded_water_pressure("Pressure", fluid_observer_contact);
// Load restart file if necessary.
//----------------------------------------------------------------------
Real &physical_time = *sph_system.getSystemVariableDataByName<Real>("PhysicalTime");
if (sph_system.RestartStep() != 0)
{
physical_time = restart_io.readRestartFiles(sph_system.RestartStep());
water_block.updateCellLinkedList();
water_wall_complex.updateConfiguration();
fluid_observer_contact.updateConfiguration();
}
//----------------------------------------------------------------------
// Setup for time-stepping control
//----------------------------------------------------------------------
size_t number_of_iterations = sph_system.RestartStep();
int screen_output_interval = 100;
int observation_sample_interval = screen_output_interval * 2;
int restart_output_interval = screen_output_interval * 10;
Real end_time = 20;
Real output_interval = 0.1;
//----------------------------------------------------------------------
// Statistics for CPU time
//----------------------------------------------------------------------
TickCount t1 = TickCount::now();
TimeInterval interval;
TimeInterval interval_computing_time_step;
TimeInterval interval_computing_fluid_pressure_relaxation;
TimeInterval interval_updating_configuration;
TickCount time_instance;
//----------------------------------------------------------------------
// First output before the main loop.
//----------------------------------------------------------------------
body_states_recording.writeToFile();
write_water_mechanical_energy.writeToFile(number_of_iterations);
write_recorded_water_pressure.writeToFile(number_of_iterations);
while (physical_time < end_time)
{
Real integration_time = 0.0;
/** Integrate time (loop) until the next output time. */
while (integration_time < output_interval)
{
// middle loop
/** outer loop for dual-time criteria time-stepping. */
...
}
body_states_recording.writeToFile();
TickCount t2 = TickCount::now();
TickCount t3 = TickCount::now();
interval += t3 - t2;
}
TickCount t2 = TickCount::now();
body_states_recording.writeToFile();
TickCount t3 = TickCount::now();
while (integration_time < output_interval)
{
/** outer loop for dual-time criteria time-stepping. */
time_instance = TickCount::now();
Real advection_dt = fluid_advection_time_step.exec();
fluid_density_by_summation.exec();
interval_computing_time_step += TickCount::now() - time_instance;
time_instance = TickCount::now();
Real relaxation_time = 0.0;
Real acoustic_dt = 0.0;
while (relaxation_time < advection_dt)
{
/** inner loop for dual-time criteria time-stepping. */
...
}
interval_computing_fluid_pressure_relaxation += TickCount::now() - time_instance;