📄 ivp_controller_buoyancy.cxx
字号:
//weighted_new_input->set_time_stamp(current_time);
//solution_values->set_time_stamp(current_time);
if(!(temp_buoyancy->insert_extrapol_only)) {
ai->mi->add_new_input_solution_combination_stochastic(weighted_new_input, solution_values);
}
//extrapolate into the future
IVP_RETURN_TYPE success = calculate_future_extrapolation(&ai->last_io_vectors,
weighted_new_input,
solution_values,
d_time,
current_time,
future_input,
future_solution);
if (success) {
future_input->set_time_stamp(current_time);
future_solution->set_time_stamp(current_time);
ai->mi->add_new_input_solution_combination_stochastic(future_input, future_solution);
}
}
break;
}
case IVP_FALSE: {
//weighted_new_input->set_time_stamp(current_time);
//solution_values->set_time_stamp(current_time);
if(!(temp_buoyancy->insert_extrapol_only)) {
ai->mi->add_new_input_solution_combination_conventional(weighted_new_input, solution_values);
}
//extrapolate into the future
IVP_RETURN_TYPE success = calculate_future_extrapolation(&ai->last_io_vectors,
weighted_new_input,
solution_values,
d_time,
current_time,
future_input,
future_solution);
if (success) {
future_input->set_time_stamp(current_time);
future_solution->set_time_stamp(current_time);
ai->mi->add_new_input_solution_combination_conventional(future_input, future_solution);
}
break;
}
} //end switch statement
#if 0
if (ai->mi->get_nr_occupied() < ai->mi->get_nr_of_vectors()) {
//the array of input vectors in the multidim. interpolator is not yet fully occupied
ai->mi->add_new_input_solution_combination_conventional(new_input, solution_values);
} else {
//array of input vectors is already fully occupied, so a member has to be replaced by a new one
ai->mi->add_new_input_solution_combination_stochastic(new_input, solution_values);
}
#endif
}
/********************************************************************
* Name: do_simulation_controller(...)
* Description: Simulates the fluid dynamics in the current PSI step
* for the core in its class variable 'core'
* Note: do_simulation_controller is called by the internal
* simulation unit of the physics engine
********************************************************************/
void IVP_Controller_Buoyancy::do_simulation_controller(IVP_Event_Sim *es,IVP_U_Vector<IVP_Core> *) {
IVP_Environment *environment = es->environment;
IVP_U_Float_Hesse surface_hesse_ws;
IVP_U_Float_Point abs_speed_of_current_ws;
//calc the surface of the medium the current core (perhaps) lies in
attacher_buoyancy->liquid_surface_descriptor->calc_liquid_surface( environment, core, &surface_hesse_ws, &abs_speed_of_current_ws );
// if area is increased, reduce mean velocity of water
if (core_visible_surface_content_under > core_visible_surface_content_under_old) {
relative_speed_of_current_in_objects_vicinity_old.mult(core_visible_surface_content_under_old / core_visible_surface_content_under);
}
//update core_visible_surface_content_under(_old)
core_visible_surface_content_under_old = core_visible_surface_content_under;
core_visible_surface_content_under = 0.0f;
//calc resulting_speed_of_current
IVP_U_Float_Point resulting_speed_of_current_ws;
#ifdef DAMPENING_WITH_PARTICLE_ACCELERATION
resulting_speed_of_current_ws.set(&abs_speed_of_current_ws);
resulting_speed_of_current_ws.add(&relative_speed_of_current_in_objects_vicinity_old);
#else
resulting_speed_of_current_ws.set(&abs_speed_of_current_ws);
#endif
IVP_U_Float_Point rel_speed_of_current_ws;
rel_speed_of_current_ws.subtract(&resulting_speed_of_current_ws, &core->speed);
IVP_Template_Buoyancy *temp_buoyancy = attacher_buoyancy->get_parameters_per_core( core);
/*** calc buoyancy and dampening for every object in the core ***/
int nr_of_objects = core->objects.len();
for(int i=0; i<nr_of_objects; i++) {
IVP_U_Float_Point rel_speed_of_current_os;
IVP_U_Float_Hesse surface_os; //surface in object's coordinate system
{
//calc surface_os
//translate resulting_speed_of_current_ws into object coordinate system
IVP_Cache_Object *cache_object = attacher_interpolator[i].object->get_cache_object_no_lock();
cache_object->transform_vector_to_object_coords(&rel_speed_of_current_ws, &rel_speed_of_current_os);
cache_object->transform_vector_to_object_coords(&surface_hesse_ws, &surface_os);
IVP_U_Matrix m_world_f_object;
attacher_interpolator[i].object->get_m_world_f_object_AT(&m_world_f_object);
IVP_DOUBLE dist = m_world_f_object.get_position()->dot_product(&surface_hesse_ws);
surface_os.hesse_val = surface_hesse_ws.hesse_val + dist;
}
//create new input vector without using weights, needed for the buoyancy solver
IVP_Buoyancy_Input b_input;
//IVP_MI_Vector *new_input = (IVP_MI_Vector *)&b_input;
b_input.rel_speed_of_current_os.set(&rel_speed_of_current_os);
b_input.surface_os.set(&surface_os);
b_input.surface_os.hesse_val = surface_os.hesse_val;
b_input.rot_speed.set(&core->rot_speed);
//create new input vector and use the provided weights
IVP_Buoyancy_Input weighted_b_input;
IVP_MI_Vector *weighted_new_input = (IVP_MI_Vector *)&weighted_b_input;
weighted_b_input.rel_speed_of_current_os.set_multiple(&rel_speed_of_current_os, temp_buoyancy->mi_weights.weight_current_speed);
weighted_b_input.surface_os.set_multiple(&surface_os, temp_buoyancy->mi_weights.weight_surface);
weighted_b_input.surface_os.hesse_val = surface_os.hesse_val * temp_buoyancy->mi_weights.weight_surface;
weighted_b_input.rot_speed.set_multiple(&core->rot_speed, temp_buoyancy->mi_weights.weight_rot_speed);
//reserve memory on the stack for the new solutions
IVP_Buoyancy_Output b_output;
IVP_MI_Vector *solution_values = (IVP_MI_Vector *)&b_output;
#if !defined(IVP_NO_MD_INTERPOLATION)
//check if interpolation should be used or not
if (temp_buoyancy->use_interpolation) { //use interpolation
IVP_RETURN_TYPE result;
//force a new buoyancy solver run if the interpolation_counter has reached the maximum value allowed
if (interpolation_counter++ >= temp_buoyancy->max_interpolation_tries) {
result = IVP_FAULT; //force new buoyancy_solver run
interpolation_counter = 0; //reinitialize counter
} else {
result = attacher_interpolator[i].mi->check_interpolation(weighted_new_input,
temp_buoyancy->max_tries_nr_of_vectors_involved,
temp_buoyancy->max_res,
solution_values);
}
if (result) {
//interpolation was successful
//fetch new solution values
#ifdef WITH_DEBUG_OUTPUT
printf("Interpolated!\n");
ivp_debug_show_real_values(&b_input,
temp_buoyancy,
core,
attacher_interpolator->object,
&resulting_speed_of_current_ws);
attacher_interpolator[i].nr_interpolated++;
#endif
} else {
//interpolation failed
//call the buoyancy solver
#ifdef WITH_DEBUG_OUTPUT
printf("Not Interpolated!\n");
attacher_interpolator[i].nr_not_interpolated++;
#endif
IVP_BOOL in_water = use_buoyancy_solver(&b_input, temp_buoyancy, &b_output, &resulting_speed_of_current_ws, i);
if (in_water) {
//if the buoyancy solver did compute values (if object is in water) then copy the new
//input/solution-combination into the interpolator
provide_new_input_solution_combination(&attacher_interpolator[i],
temp_buoyancy,
weighted_new_input,
solution_values,
es->delta_time,
environment->get_current_time());
}
#ifdef WITH_DEBUG_OUTPUT
else {
printf("Not yet in water!\n");
}
#endif
}
#ifdef WITH_DEBUG_OUTPUT
printf("times_interpolated : times_calculated = %d : %d\n", attacher_interpolator[i].nr_interpolated, attacher_interpolator[i].nr_not_interpolated);
printf("# of one vector already sufficient = %d\n", attacher_interpolator[i].mi->nr_one_vector_sufficient);
for (int q=0; q<attacher_interpolator[i].mi->get_nr_of_vectors(); q++) {
printf("%d vectors involved: # of res over limit = %d ", q+1, attacher_interpolator[i].mi->nr_res_over_limit[q]);
printf("# of interpol. weigh over limit = %d ", attacher_interpolator[i].mi->nr_int_weight_over_limit[q]);
printf("# of times LINFIT failed = %d ", attacher_interpolator[i].mi->nr_of_linfit_failure[q]);
printf("# of interpolation successes = %d\n", attacher_interpolator[i].mi->nr_of_success[q]);
}
printf("\n\n");
#endif
//update last_input structure, is needed in 'calculate_future_extrapolation'
attacher_interpolator[i].last_io_vectors.last_input_vector->set(weighted_new_input);
attacher_interpolator[i].last_io_vectors.last_solution_vector->set(solution_values);
// attacher_interpolator[i].last_io_vectors.last_psi_time = environment->get_current_time();
attacher_interpolator[i].last_io_vectors.last_psi_time = environment->get_current_time().get_time();
} else {
#endif /* if !defined(IVP_NO_MD_INTERPOLATION) */
//don't use interpolation
use_buoyancy_solver(&b_input, temp_buoyancy, &b_output, &resulting_speed_of_current_ws, i);
#ifdef WITH_DEBUG_OUTPUT
printf("nr_not_interpolated = %d\n", ++nr_not_interpolated);
#endif
#if !defined(IVP_NO_MD_INTERPOLATION)
}
#endif
//apply the calculated impulses to the current object
apply_buoyancy_impulse( attacher_interpolator[i].object,
temp_buoyancy,
es->delta_time,
b_output.volume_under,
&b_output.volume_center_under );
apply_dampening( attacher_interpolator[i].object,
IVP_Inline_Math::fabsd(b_output.object_visible_surface_content_under),
es->delta_time,
&b_output.sum_impulse_x_movevector,
&b_output.sum_impulse_x_point,
&b_output.sum_impulse);
//add 'object_visible_surface_content_under' to 'core_visible_surface_content_under'
//'fabs' is taken in case the interpolation's result was negative
core_visible_surface_content_under += IVP_Inline_Math::fabsd(b_output.object_visible_surface_content_under);
}
#ifdef DAMPENING_WITH_PARTICLE_ACCELERATION
IVP_FLOAT inverse_viscosity = 1.0f - (temp_buoyancy->viscosity_factor * es->delta_time);
IVP_U_Float_Point speed_of_object_relative_to_medium_ws;
speed_of_object_relative_to_medium_ws.set(&core->speed);
speed_of_object_relative_to_medium_ws.subtract(&resulting_speed_of_current_ws);
relative_speed_of_current_in_objects_vicinity_old.mult(inverse_viscosity);
relative_speed_of_current_in_objects_vicinity_old.add_multiple(&speed_of_object_relative_to_medium_ws, temp_buoyancy->viscosity_input_factor*es->delta_time);
#endif
}
/*********************
* Constructor
*********************/
IVP_Controller_Buoyancy::IVP_Controller_Buoyancy(IVP_Attacher_To_Cores<IVP_Controller_Buoyancy> *attacher_buoyancy_, IVP_Core *core_) {
attacher_buoyancy = (IVP_Attacher_To_Cores_Buoyancy *)attacher_buoyancy_;
core = core_;
core->environment->get_controller_manager()->add_controller_to_core(this,core);
relative_speed_of_current_in_objects_vicinity_old.set(0.0f, 0.0f, 0.0f);
core_visible_surface_content_under_old = 0.0f;
core_visible_surface_content_under = 0.0f;
//initialize vector which applies a multidimensional interpolator to every object in the core
int nr_of_objects = core->objects.len();
attacher_interpolator = new Attacher_Interpolator[nr_of_objects];
for(int i=0; i<nr_of_objects; i++) {
attacher_interpolator[i].object = core->objects.element_at(i);
#if !defined( IVP_NO_MD_INTERPOLATION )
attacher_interpolator[i].mi = new IVP_Multidimensional_Interpolator(5, INPUT_VECTOR_LENGTH, SOLUTION_VECTOR_LENGTH);
attacher_interpolator[i].last_io_vectors.last_input_vector = IVP_MI_Vector::malloc_mi_vector(INPUT_VECTOR_LENGTH);
attacher_interpolator[i].last_io_vectors.last_solution_vector = IVP_MI_Vector::malloc_mi_vector(SOLUTION_VECTOR_LENGTH);
#endif
attacher_interpolator[i].last_io_vectors.last_psi_time = 0;
attacher_interpolator[i].nr_interpolated = 0;
attacher_interpolator[i].nr_not_interpolated = 0;
}
interpolation_counter = 0; //initialize the counter
//for debugging
nr_not_interpolated = 0;
}
/*********************
* Destructor
*********************/
IVP_Controller_Buoyancy::~IVP_Controller_Buoyancy() {
int nr_of_objects = core->objects.len();
if ( attacher_interpolator){
for(int i=0; i<nr_of_objects; i++) {
#if !defined( IVP_NO_MD_INTERPOLATION )
P_DELETE(attacher_interpolator[i].mi);
//#if !defined(__MWERKS__) || !defined(__POWERPC__)
#pragma message ("this code should not be called")
P_DELETE_ARRAY(attacher_interpolator[i].last_io_vectors.last_input_vector);
P_DELETE_ARRAY(attacher_interpolator[i].last_io_vectors.last_solution_vector);
//#endif
#endif
}
P_DELETE_ARRAY(attacher_interpolator); //@@CB was a P_DELETE, which was bad
}
attacher_buoyancy->attachment_is_going_to_be_deleted(this,core);
core->environment->get_controller_manager()->remove_controller_from_core(this,core);
}
IVP_Attacher_To_Cores_Buoyancy::IVP_Attacher_To_Cores_Buoyancy(IVP_Template_Buoyancy &templ, IVP_U_Set_Active<IVP_Core> *set_of_cores_, IVP_Liquid_Surface_Descriptor *liquid_surface_descriptor_)
: IVP_Attacher_To_Cores<IVP_Controller_Buoyancy>(set_of_cores_)
{
template_buoyancy = templ;
set_of_cores = set_of_cores_;
liquid_surface_descriptor = liquid_surface_descriptor_;
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -