blob: 25d307de93749c2a9610a7bc2b19352714df9fd2 [file] [log] [blame]
//#####################################################################
// Copyright 2004-2006, Zhaosheng Bao, Ron Fedkiw, Geoffrey Irving, Sergey Koltakov, Andrew Selle, Eftychios Sifakis, Joseph Teran.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
// Class DEFORMABLE_OBJECT_3D
//#####################################################################
#include "DEFORMABLE_OBJECT_3D.h"
#include "../Forces_And_Torques/BODY_FORCES_3D.h"
#include "../Forces_And_Torques/DIAGONALIZED_FINITE_VOLUME_3D.h"
#include "../Constitutive_Models/CONSTITUTIVE_MODEL_3D.h"
#include "../Constitutive_Models/DIAGONALIZED_FACE_3D.h"
#include "../Constitutive_Models/STRAIN_MEASURE_3D.h"
#include "../Collisions_And_Interactions/COLLISION_PENALTY_FORCES.h"
#include "../Utilities/LOG.h"
#include "../Arrays/ARRAY_PARALLEL_OPERATIONS.h"
using namespace PhysBAM;
extern bool PHYSBAM_THREADED_RUN;
//#####################################################################
// Function Delete_Forces
//#####################################################################
template<class T> void DEFORMABLE_OBJECT_3D<T>::
Delete_Forces()
{
solids_forces.Clean_Up_Memory();
body_forces.Delete_Pointers_And_Clean_Memory();
diagonalized_finite_volume_3d.Delete_Pointers_And_Clean_Memory();
strain_measure_3d.Delete_Pointers_And_Clean_Memory();
constitutive_model_3d.Delete_Pointers_And_Clean_Memory();
diagonalized_constitutive_model_3d.Delete_Pointers_And_Clean_Memory();
}
//#####################################################################
// Function Update_Collision_Penalty_Forces_And_Derivatives
//#####################################################################
template<class T> void DEFORMABLE_OBJECT_3D<T>::
Update_Collision_Penalty_Forces_And_Derivatives()
{
LOG::Time ("UCPF", "UCPF");
for (int i = 1; i <= collision_penalty_forces.m; i++) collision_penalty_forces (i)->Update_Forces_And_Derivatives();
LOG::Stop_Time();
}
//#####################################################################
// Function Advance_One_Time_Step
//#####################################################################
template<class T> void DEFORMABLE_OBJECT_3D<T>::
Advance_One_Time_Step (const T time, const T dt, const T cg_tolerance, const int cg_iterations, const bool perform_collision_body_collisions, const bool verbose)
{
NOT_IMPLEMENTED();
}
//#####################################################################
// Function Advance_One_Time_Step_Semi_Implicit
//#####################################################################
template<class T> void DEFORMABLE_OBJECT_3D<T>::
Advance_One_Time_Step_Semi_Implicit (const T time, const T dt, const bool perform_collision_body_collisions, const bool verbose)
{
NOT_IMPLEMENTED();
}
//#####################################################################
// Function Advance_One_Time_Step_Using_Quasistatics
//#####################################################################
template<class T> void DEFORMABLE_OBJECT_3D<T>::
Advance_One_Time_Step_Quasistatic (const T time, const T dt, const T cg_tolerance, const int cg_iterations, const T newton_tolerance, const int newton_iterations,
const bool use_partially_converged_result, const bool verbose)
{
LOG::Push_Scope ("AOTSQ", "AOTSQ");
// prepare for force computation
LOG::Time ("AOTSQ - Initialize");
Enforce_Definiteness (true);
external_forces_and_velocities->Update_Time_Varying_Material_Properties (time + dt, id_number);
// Iterate to steady state
double supnorm = 0;
int iteration;
dX_full.Resize_Array (particles.number, false, false), R_full.Resize_Array (particles.number, false, false);
LOG::Stop_Time();
LOG::Push_Scope ("AOTSQ - NR loop", "AOTSQ - NR loop");
for (iteration = 0; iteration < newton_iterations; iteration++)
{
LOG::Time ("AOTSQ - NR loop - Initialize");
#ifndef NEW_SERIAL_IMPLEMENTATIOM
if (PHYSBAM_THREADED_RUN)
{
#endif
ARRAY_PARALLEL_OPERATIONS<VECTOR_3D<T>, T, VECTOR_3D<T> >::Clear_Parallel (dX_full, *particles.particle_ranges);
ARRAY_PARALLEL_OPERATIONS<VECTOR_3D<T>, T, VECTOR_3D<T> >::Clear_Parallel (R_full, *particles.particle_ranges);
#ifndef NEW_SERIAL_IMPLEMENTATIOM
}
else
{
ARRAY<VECTOR_3D<T> >::copy (VECTOR_3D<T>(), dX_full);
ARRAY<VECTOR_3D<T> >::copy (VECTOR_3D<T>(), R_full);
}
#endif
LOG::Stop_Time();
Update_Collision_Penalty_Forces_And_Derivatives();
if (One_Newton_Step_Toward_Steady_State (cg_tolerance, cg_iterations, time + dt, dX_full, false, 0, iteration == 0) || use_partially_converged_result)
if (PHYSBAM_THREADED_RUN) ARRAY_PARALLEL_OPERATIONS<VECTOR_3D<T>, T, VECTOR_3D<T> >::Add_Scaled_Array_Parallel (dX_full, (T) 1, particles.X.array, *particles.particle_ranges);
#ifndef NEW_SERIAL_IMPLEMENTATIOM
else particles.X.array += dX_full;
#else
else ARRAY_PARALLEL_OPERATIONS<VECTOR_3D<T>, T, VECTOR_3D<T> >::Add_Scaled_Array_Parallel (dX_full, (T) 1, particles.X.array, *particles.particle_ranges);
#endif
Update_Position_Based_State();
Update_Collision_Penalty_Forces_And_Derivatives();
Add_Velocity_Independent_Forces (R_full);
LOG::Time ("AOTSQ - NR loop - Boundary conditions");
external_forces_and_velocities->Add_External_Forces (R_full, time, id_number);
external_forces_and_velocities->Zero_Out_Enslaved_Position_Nodes (R_full, time, id_number);
LOG::Stop_Time();
LOG::Time ("AOTSQ - NR loop - Compute residual");
supnorm = (T) 0;
if (PHYSBAM_THREADED_RUN) supnorm = ARRAY_PARALLEL_OPERATIONS<VECTOR_3D<T>, T, VECTOR_3D<T> >::Maximum_Magnitude_Squared_Parallel (R_full, *particles.particle_ranges);
#ifndef NEW_SERIAL_IMPLEMENTATIOM
else for (int i = 1; i <= particles.number; i++)
{
double s2 = R_full (i).Magnitude_Squared();
supnorm = max (supnorm, s2);
}
#else
else supnorm = ARRAY_PARALLEL_OPERATIONS<VECTOR_3D<T>, T, VECTOR_3D<T> >::Maximum_Magnitude_Squared_Parallel (R_full, *particles.particle_ranges);
#endif
supnorm = sqrt (supnorm);
if (print_residuals) LOG::cout << "Newton iteration residual after " << iteration + 1 << " iterations = " << supnorm << std::endl;
if (supnorm <= newton_tolerance)
{
LOG::cout << "Newton converged in " << iteration + 1 << " steps for object " << id_number << std::endl;
break;
}
LOG::Stop_Time();
}
LOG::Pop_Scope(); // from AOTSQ - NR loop
if (iteration >= newton_iterations && print_diagnostics)
{
LOG::cout << "Newton iteration did not converge in " << newton_iterations << " for object " << id_number << std::endl;
LOG::cout << "\tError = " << supnorm << ", Newton tolerance = " << newton_tolerance << std::endl;
}
LOG::Pop_Scope(); // from AOTSQ
}
//#####################################################################
// Function Add_Quasistatic_Neo_Hookean_Elasticity
//#####################################################################
template<class T> int DEFORMABLE_OBJECT_3D<T>::
Add_Quasistatic_Neo_Hookean_Elasticity (TETRAHEDRALIZED_VOLUME<T>& tetrahedralized_volume, const T youngs_modulus, const T poissons_ratio, const bool verbose)
{
NOT_IMPLEMENTED();
}
//#####################################################################
// Function Add_Diagonalized_Linear_Finite_Volume
//#####################################################################
template<class T> int DEFORMABLE_OBJECT_3D<T>::
Add_Quasistatic_Diagonalized_Linear_Finite_Volume (TETRAHEDRALIZED_VOLUME<T>& tetrahedralized_volume, const T youngs_modulus, const T poissons_ratio, const bool verbose, const bool precompute_stiffness_matrix)
{
NOT_IMPLEMENTED();
}
//#####################################################################
// Function Add_Quasistatic_Diagonalized_Neo_Hookean_Elasticity
//#####################################################################
template<class T> int DEFORMABLE_OBJECT_3D<T>::
Add_Quasistatic_Diagonalized_Neo_Hookean_Elasticity (TETRAHEDRALIZED_VOLUME<T>& tetrahedralized_volume, const T youngs_modulus, const T poissons_ratio, const T failure_threshold,
const bool verbose, const bool precompute_stiffness_matrix)
{
NOT_IMPLEMENTED();
}
//#####################################################################
// Function Add_Quasistatic_Diagonalized_Linear_Elasticity
//#####################################################################
template<class T> int DEFORMABLE_OBJECT_3D<T>::
Add_Quasistatic_Diagonalized_Linear_Elasticity (TETRAHEDRALIZED_VOLUME<T>& tetrahedralized_volume, const T youngs_modulus, const T poissons_ratio, const bool verbose)
{
NOT_IMPLEMENTED();
}
//#####################################################################
// Function Add_Diagonalized_Mooney_Rivlin
//#####################################################################
template<class T> int DEFORMABLE_OBJECT_3D<T>::
Add_Diagonalized_Mooney_Rivlin (TETRAHEDRALIZED_VOLUME<T>& tetrahedralized_volume, const T mu_10, const T mu_01, const T kappa, const T Rayleigh_coefficient, const T failure_threshold,
const bool limit_time_step_by_strain_rate, const T max_strain_per_time_step, const bool use_rest_state_for_strain_rate, const bool verbose)
{
NOT_IMPLEMENTED();
}
//#####################################################################
// Function Add_Quasistatic_Diagonalized_Mooney_Rivlin
//#####################################################################
template<class T> int DEFORMABLE_OBJECT_3D<T>::
Add_Quasistatic_Diagonalized_Mooney_Rivlin (TETRAHEDRALIZED_VOLUME<T>& tetrahedralized_volume, const T mu_10, const T mu_01, const T kappa, const T failure_threshold, const bool verbose,
const bool precompute_stiffness_matrix)
{
NOT_IMPLEMENTED();
}
//#####################################################################
// Function Add_Diagonalized_Face
//#####################################################################
template<class T> int DEFORMABLE_OBJECT_3D<T>::
Add_Diagonalized_Face (TETRAHEDRALIZED_VOLUME<T>& tetrahedralized_volume, const LIST_ARRAY<LIST_ARRAY<int> >& muscle_tets, const LIST_ARRAY<LIST_ARRAY<VECTOR_3D<T> > >& muscle_fibers,
const LIST_ARRAY<LIST_ARRAY<T> >& muscle_densities, LIST_ARRAY<T>& muscle_activations, const LIST_ARRAY<T>* peak_isometric_stress, const T mu_10, const T mu_01,
const T kappa, const T Rayleigh_coefficient, const T failure_threshold, const bool limit_time_step_by_strain_rate, const T max_strain_per_time_step,
const bool use_rest_state_for_strain_rate, const bool verbose)
{
NOT_IMPLEMENTED();
}
//#####################################################################
// Function Add_Quasistatic_Diagonalized_Face
//#####################################################################
template<class T> int DEFORMABLE_OBJECT_3D<T>::
Add_Quasistatic_Diagonalized_Face (TETRAHEDRALIZED_VOLUME<T>& tetrahedralized_volume, const LIST_ARRAY<LIST_ARRAY<int> >& muscle_tets, const LIST_ARRAY<LIST_ARRAY<VECTOR_3D<T> > >& muscle_fibers,
const LIST_ARRAY<LIST_ARRAY<T> >& muscle_densities, LIST_ARRAY<T>& muscle_activations, int *single_activation_used_for_force_derivative, const LIST_ARRAY<T>* peak_isometric_stress,
DIAGONALIZED_CONSTITUTIVE_MODEL_3D<T> **face_constitutive_model, const T mu_10, const T mu_01, const T kappa, const T failure_threshold, const bool verbose)
{
STRAIN_MEASURE_3D<T> *strain_measure = new STRAIN_MEASURE_3D<T> (tetrahedralized_volume);
strain_measure_3d.Append_Element (strain_measure);
DIAGONALIZED_FACE_3D<T>* constitutive_model = new DIAGONALIZED_FACE_3D<T> (mu_10, mu_01, kappa, 0, muscle_activations, single_activation_used_for_force_derivative, peak_isometric_stress, failure_threshold);
constitutive_model->Initialize_Fiber_Data (*strain_measure, muscle_tets, muscle_fibers, muscle_densities);
diagonalized_constitutive_model_3d.Append_Element (constitutive_model);
if (face_constitutive_model) *face_constitutive_model = constitutive_model;
DIAGONALIZED_FINITE_VOLUME_3D<T>* fvm = new DIAGONALIZED_FINITE_VOLUME_3D<T> (*strain_measure, *constitutive_model);
fvm->Use_Quasistatics();
fvm->Use_Stiffness_Matrix();
diagonalized_finite_volume_3d.Append_Element (fvm);
solids_forces.Append_Element (fvm);
return solids_forces.m;
}
//#####################################################################
template class DEFORMABLE_OBJECT_3D<float>;
template class DEFORMABLE_OBJECT_3D<double>;