blob: 04a65540617afcfca21524d400e55eb04969e232 [file] [log] [blame]
//#####################################################################
// Copyright 2004-2005, Eftychios Sifakis.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
// Class FACE_CONTROL_PARAMETERS
//#####################################################################
#ifndef __FACE_CONTROL_PARAMETERS__
#define __FACE_CONTROL_PARAMETERS__
#include "FACE_CONTROL_SET.h"
#include "../../Public_Library/Matrices_And_Vectors/MATRIX_NXN.h"
namespace PhysBAM
{
template <class T>
class FACE_CONTROL_PARAMETERS
{
public:
LIST_ARRAY<FACE_CONTROL_SET<T>*> list;
FACE_CONTROL_PARAMETERS()
{}
int Size() const
{
int n = 0;
for (int s = 1; s <= list.m; s++) n += list (s)->Size();
return n;
}
int Active_Size() const
{
int n = 0;
for (int s = 1; s <= list.m; s++) for (int c = 1; c <= list (s)->Size(); c++) if (list (s)->Control_Active (c)) n++;
return n;
}
int Active_Kinematic_Size() const
{
int n = 0;
for (int s = 1; s <= list.m; s++) for (int c = 1; c <= list (s)->Size(); c++) if (list (s)->Control_Active (c) && list (s)->Positions_Determined_Kinematically (c)) n++;
return n;
}
int Active_Nonkinematic_Size() const
{
int n = 0;
for (int s = 1; s <= list.m; s++) for (int c = 1; c <= list (s)->Size(); c++) if (list (s)->Control_Active (c) && !list (s)->Positions_Determined_Kinematically (c)) n++;
return n;
}
void Seek (const int control_index, int& set_subindex, int& control_subindex) const
{
assert (1 <= control_index && control_index <= Size());
control_subindex = control_index;
for (set_subindex = 1; control_subindex > list (set_subindex)->Size(); set_subindex++) control_subindex -= list (set_subindex)->Size();
}
T& operator() (const int control_index)
{
int s, c;
Seek (control_index, s, c);
return (*list (s)) (c);
}
T operator() (const int control_index) const
{
int s, c;
Seek (control_index, s, c);
return (*list (s)) (c);
}
bool& Active (const int control_index)
{
int s, c;
Seek (control_index, s, c);
return list (s)->Control_Active (c);
}
bool Active (const int control_index) const
{
int s, c;
Seek (control_index, s, c);
return list (s)->Control_Active (c);
}
bool Kinematic (const int control_index) const
{
int s, c;
Seek (control_index, s, c);
return list (s)->Positions_Determined_Kinematically (c);
}
bool Active_Kinematic (const int control_index) const
{
int s, c;
Seek (control_index, s, c);
return list (s)->Control_Active (c) && list (s)->Positions_Determined_Kinematically (c);
}
bool Active_Nonkinematic (const int control_index) const
{
int s, c;
Seek (control_index, s, c);
return list (s)->Control_Active (c) && !list (s)->Positions_Determined_Kinematically (c);
}
ARRAY<int> Active_Subset() const
{
ARRAY<int> result (Active_Size());
int n = 0;
for (int i = 1; i <= Size(); i++) if (Active (i)) result (++n) = i;
return result;
}
ARRAY<int> Active_Kinematic_Subset() const
{
ARRAY<int> result (Active_Kinematic_Size());
int n = 0;
for (int i = 1; i <= Size(); i++) if (Active_Kinematic (i)) result (++n) = i;
return result;
}
ARRAY<int> Active_Nonkinematic_Subset() const
{
ARRAY<int> result (Active_Nonkinematic_Size());
int n = 0;
for (int i = 1; i <= Size(); i++) if (Active_Nonkinematic (i)) result (++n) = i;
return result;
}
void Get (VECTOR_ND<T>& values) const
{
values = VECTOR_ND<T> (Size());
for (int i = 1; i <= Size(); i++) values (i) = (*this) (i);
}
void Get (VECTOR_ND<T>& values, const ARRAY<int>& subset) const
{
values = VECTOR_ND<T> (subset.m);
for (int i = 1; i <= subset.m; i++) values (i) = (*this) (subset (i));
}
void Get_Active (ARRAY<bool>& active) const
{
active.Resize_Array (Size());
for (int i = 1; i <= Size(); i++) active (i) = Active (i);
}
void Get_Active (ARRAY<bool>& active, const ARRAY<int>& subset) const
{
active.Resize_Array (subset.m);
for (int i = 1; i <= subset.m; i++) active (i) = Active (subset (i));
}
void Set (const VECTOR_ND<T>& values)
{
assert (values.n == Size());
for (int i = 1; i <= Size(); i++) (*this) (i) = values (i);
}
void Set (const VECTOR_ND<T>& values, const ARRAY<int>& subset)
{
assert (values.n == subset.m);
for (int i = 1; i <= subset.m; i++) (*this) (subset (i)) = values (i);
}
void Set (const T value_input, const ARRAY<int>& subset)
{
for (int i = 1; i <= subset.m; i++) (*this) (subset (i)) = value_input;
}
void Set_Active (const ARRAY<bool>& active)
{
assert (active.m == Size());
for (int i = 1; i <= Size(); i++) Active (i) = active (i);
}
void Set_Active (const ARRAY<bool>& active, const ARRAY<int>& subset)
{
assert (active.m == subset.m);
for (int i = 1; i <= subset.m; i++) Active (subset (i)) = active (i);
}
void Set_Active (const bool active_input, const ARRAY<int>& subset)
{
for (int i = 1; i <= subset.m; i++) Active (subset (i)) = active_input;
}
T Penalty() const
{
T result = 0;
for (int s = 1; s <= list.m; s++) result += list (s)->Penalty();
return result;
}
VECTOR_ND<T> Penalty_Gradient() const
{
ARRAY<int> subset (Active_Subset());
VECTOR_ND<T> result (subset.m);
for (int i = 1; i <= subset.m; i++)
{
int s, c;
Seek (subset (i), s, c);
result (i) = list (s)->Penalty_Gradient (c);
}
return result;
}
MATRIX_NXN<T> Penalty_Hessian() const
{
ARRAY<int> subset (Active_Subset());
MATRIX_NXN<T> result (subset.m);
for (int i1 = 1; i1 <= subset.m; i1++) for (int i2 = 1; i2 <= subset.m; i2++)
{
int s1, c1, s2, c2;
Seek (subset (i1), s1, c1);
Seek (subset (i2), s2, c2);
if (s1 == s2) result (i1, i2) = list (s1)->Penalty_Hessian (c1, c2);
}
return result;
}
void Save_Controls()
{
for (int s = 1; s <= list.m; s++) list (s)->Save_Controls();
}
void Print_Diagnostics (std::ostream& output = std::cout) const
{
for (int s = 1; s <= list.m; s++) list (s)->Print_Diagnostics (output);
}
void Kinematically_Update_Positions (ARRAY<VECTOR_3D<T> >&X) const
{
for (int s = 1; s <= list.m; s++) list (s)->Kinematically_Update_Positions (X);
}
void Kinematically_Update_Jacobian (ARRAY<VECTOR_3D<T> >&dX) const
{
for (int s = 1; s <= list.m; s++) list (s)->Kinematically_Update_Jacobian (dX);
}
void Force_Derivative (ARRAY<VECTOR_3D<T> >& dFdl, const int control_index) const
{
int s, c;
Seek (control_index, s, c);
list (s)->Force_Derivative (dFdl, c);
}
void Position_Derivative (ARRAY<VECTOR_3D<T> >& dXdl, const int control_index) const
{
int s, c;
Seek (control_index, s, c);
list (s)->Position_Derivative (dXdl, c);
}
void Project_Parameters_To_Allowable_Range (const bool active_controls_only = false)
{
for (int s = 1; s <= list.m; s++) list (s)->Project_Parameters_To_Allowable_Range (active_controls_only);
}
void Interpolate (const T interpolation_fraction)
{
for (int s = 1; s <= list.m; s++) list (s)->Interpolate (interpolation_fraction);
}
template <class RW>
void Read (std::istream& input_stream)
{
VECTOR_ND<T> values;
ARRAY<bool> active;
values.template Read<RW> (input_stream);
active.template Read<RW> (input_stream);
assert (values.n == Size() && active.m == Size());
Set (values);
Set_Active (active);
}
template <class RW>
void Write (std::ostream& output_stream) const
{
VECTOR_ND<T> values;
ARRAY<bool> active;
Get (values);
Get_Active (active);
values.template Write<RW> (output_stream);
active.template Write<RW> (output_stream);
}
//#####################################################################
};
}
#endif