Commit 7a0f27b4 authored by vijaysm's avatar vijaysm
Browse files

Merged in vijaysm/add-eigen-support (pull request #248)

Add support for Eigen library for Dense matrix/vector algebra in MOAB
parents ad2dc476 ec0236b5

Too many changes to show.

To preserve performance only 184 of 184+ files are displayed.
...@@ -1449,7 +1449,7 @@ bool VolMap::solve_inverse( const CartVect& x, CartVect& xi, double tol ) const ...@@ -1449,7 +1449,7 @@ bool VolMap::solve_inverse( const CartVect& x, CartVect& xi, double tol ) const
det = J.determinant(); det = J.determinant();
if (det < std::numeric_limits<double>::epsilon()) if (det < std::numeric_limits<double>::epsilon())
return false; return false;
xi -= J.inverse(1.0/det) * delta; xi -= J.inverse() * delta;
delta = evaluate( xi ) - x; delta = evaluate( xi ) - x;
} }
return true; return true;
......
...@@ -61,7 +61,7 @@ namespace moab { ...@@ -61,7 +61,7 @@ namespace moab {
} }
// new params tries to eliminate residual // new params tries to eliminate residual
*cvparams -= J.inverse(1.0/det) * res; *cvparams -= J.inverse() * res;
// get the new forward-evaluated position, and its difference from the target pt // get the new forward-evaluated position, and its difference from the target pt
rval = (*eval)(params, verts, ndim, rval = (*eval)(params, verts, ndim,
......
...@@ -35,7 +35,7 @@ namespace moab ...@@ -35,7 +35,7 @@ namespace moab
} }
ErrorCode LinearTet::evalFcn(const double *params, const double *field, const int /*ndim*/, const int num_tuples, ErrorCode LinearTet::evalFcn(const double *params, const double *field, const int /*ndim*/, const int num_tuples,
double */*work*/, double *result) { double* /*work*/, double *result) {
assert(params && field && num_tuples > 0); assert(params && field && num_tuples > 0);
std::vector<double> f0(num_tuples); std::vector<double> f0(num_tuples);
std::copy(field, field+num_tuples, f0.begin()); std::copy(field, field+num_tuples, f0.begin());
...@@ -50,7 +50,7 @@ namespace moab ...@@ -50,7 +50,7 @@ namespace moab
return MB_SUCCESS; return MB_SUCCESS;
} }
ErrorCode LinearTet::integrateFcn(const double *field, const double */*verts*/, const int nverts, const int /*ndim*/, const int num_tuples, ErrorCode LinearTet::integrateFcn(const double *field, const double* /*verts*/, const int nverts, const int /*ndim*/, const int num_tuples,
double *work, double *result) double *work, double *result)
{ {
assert(field && num_tuples > 0); assert(field && num_tuples > 0);
...@@ -122,9 +122,11 @@ namespace moab ...@@ -122,9 +122,11 @@ namespace moab
CartVect res = new_pos - *cvposn; CartVect res = new_pos - *cvposn;
Matrix3 J; Matrix3 J;
rval = (*jacob)(cvparams->array(), verts, nverts, ndim, work, J[0]); rval = (*jacob)(cvparams->array(), verts, nverts, ndim, work, J[0]);
#ifndef NDEBUG
double det = J.determinant(); double det = J.determinant();
assert(det > std::numeric_limits<double>::epsilon()); assert(det > std::numeric_limits<double>::epsilon());
Matrix3 Ji = J.inverse(1.0/det); #endif
Matrix3 Ji = J.inverse();
int iters=0; int iters=0;
// while |res| larger than tol // while |res| larger than tol
......
...@@ -119,9 +119,11 @@ namespace moab ...@@ -119,9 +119,11 @@ namespace moab
CartVect res = new_pos - *cvposn; CartVect res = new_pos - *cvposn;
Matrix3 J; Matrix3 J;
rval = (*jacob)(cvparams->array(), verts, nverts, ndim, work, J[0]); rval = (*jacob)(cvparams->array(), verts, nverts, ndim, work, J[0]);
#ifndef NDEBUG
double det = J.determinant(); double det = J.determinant();
assert(det > std::numeric_limits<double>::epsilon()); assert(det > std::numeric_limits<double>::epsilon());
Matrix3 Ji = J.inverse(1.0/det); #endif
Matrix3 Ji = J.inverse();
int iters=0; int iters=0;
// while |res| larger than tol // while |res| larger than tol
......
...@@ -14,6 +14,8 @@ if PARALLEL ...@@ -14,6 +14,8 @@ if PARALLEL
AM_CPPFLAGS += -I$(srcdir)/parallel AM_CPPFLAGS += -I$(srcdir)/parallel
endif endif
include moab/EigenHeaders
SUBDIRS += io LocalDiscretization verdict RefineMesh . SUBDIRS += io LocalDiscretization verdict RefineMesh .
libMOAB_la_LIBADD += io/libmoabio.la LocalDiscretization/libLocalDiscretization.la verdict/libmoabverdict.la RefineMesh/libRefineMesh.la libMOAB_la_LIBADD += io/libmoabio.la LocalDiscretization/libLocalDiscretization.la verdict/libmoabverdict.la RefineMesh/libRefineMesh.la
...@@ -219,6 +221,7 @@ nobase_libMOAB_la_include_HEADERS = \ ...@@ -219,6 +221,7 @@ nobase_libMOAB_la_include_HEADERS = \
moab/Util.hpp \ moab/Util.hpp \
moab/WriteUtilIface.hpp \ moab/WriteUtilIface.hpp \
moab/WriterIface.hpp \ moab/WriterIface.hpp \
$(EIGEN_INST_HDRS) \
MBEntityType.h \ MBEntityType.h \
MBCN.h \ MBCN.h \
MBCN_protos.h \ MBCN_protos.h \
......
...@@ -35,8 +35,6 @@ ...@@ -35,8 +35,6 @@
#include "moab/CN.hpp" #include "moab/CN.hpp"
#include "moab/OrientedBox.hpp" #include "moab/OrientedBox.hpp"
#include "moab/Range.hpp" #include "moab/Range.hpp"
#include "moab/Matrix3.hpp"
#include "moab/Util.hpp"
#include <ostream> #include <ostream>
#include <assert.h> #include <assert.h>
#include <limits> #include <limits>
...@@ -47,17 +45,17 @@ std::ostream& operator<<( std::ostream& s, const OrientedBox& b ) ...@@ -47,17 +45,17 @@ std::ostream& operator<<( std::ostream& s, const OrientedBox& b )
{ {
return s << b.center return s << b.center
<< " + " << " + "
<< b.axis[0] << b.axes.col(0)
#if MB_ORIENTED_BOX_UNIT_VECTORS #if MB_ORIENTED_BOX_UNIT_VECTORS
<< ":" << b.length[0] << ":" << b.length[0]
#endif #endif
<< " x " << " x "
<< b.axis[1] << b.axes.col(1)
#if MB_ORIENTED_BOX_UNIT_VECTORS #if MB_ORIENTED_BOX_UNIT_VECTORS
<< ":" << b.length[1] << ":" << b.length[1]
#endif #endif
<< " x " << " x "
<< b.axis[2] << b.axes.col(2)
#if MB_ORIENTED_BOX_UNIT_VECTORS #if MB_ORIENTED_BOX_UNIT_VECTORS
<< ":" << b.length[2] << ":" << b.length[2]
#endif #endif
...@@ -86,47 +84,59 @@ static double point_perp( const CartVect& p, // closest to this point ...@@ -86,47 +84,59 @@ static double point_perp( const CartVect& p, // closest to this point
#endif #endif
return Util::is_finite(t) ? t : 0.0; return Util::is_finite(t) ? t : 0.0;
} }
OrientedBox::OrientedBox( const CartVect axes[3], const CartVect& mid )
: center(mid)
{
// re-order axes by length
CartVect len( axes[0].length(), axes[1].length(), axes[2].length() );
axis[0] = axes[0];
axis[1] = axes[1];
axis[2] = axes[2];
void OrientedBox::order_axes_by_length(double ax1_len, double ax2_len, double ax3_len)
{
CartVect len( ax1_len, ax2_len, ax3_len );
if (len[2] < len[1]) if (len[2] < len[1])
{ {
if (len[2] < len[0]) { if (len[2] < len[0]) {
std::swap( len[0], len[2] ); std::swap( len[0], len[2] );
std::swap( axis[0], axis[2] ); axes.swapcol( 0, 2 );
}
} }
}
else if (len[1] < len[0]) { else if (len[1] < len[0]) {
std::swap( len[0], len[1] ); std::swap( len[0], len[1] );
std::swap( axis[0], axis[1] ); axes.swapcol( 0, 1 );
} }
if (len[1] > len[2]) { if (len[1] > len[2]) {
std::swap( len[1], len[2] ); std::swap( len[1], len[2] );
std::swap( axis[1], axis[2] ); axes.swapcol( 1, 2 );
} }
#if MB_ORIENTED_BOX_UNIT_VECTORS #if MB_ORIENTED_BOX_UNIT_VECTORS
this->length = len; length = len;
if (len[0] > 0.0) if (len[0] > 0.0)
axis[0] /= len[0]; axes.colscale(0, 1.0/len[0]);
if (len[1] > 0.0) if (len[1] > 0.0)
axis[1] /= len[1]; axes.colscale(1, 1.0/len[1]);
if (len[2] > 0.0) if (len[2] > 0.0)
axis[2] /= len[2]; axes.colscale(2 ,1.0/len[2]);
#endif #endif
#if MB_ORIENTED_BOX_OUTER_RADIUS #if MB_ORIENTED_BOX_OUTER_RADIUS
radius = len.length(); radius = len.length();
#endif #endif
} }
OrientedBox::OrientedBox( const CartVect axes_in[3], const CartVect& mid )
: center(mid)
{
axes = Matrix3( axes_in[0], axes_in[1], axes_in[2], false );
order_axes_by_length( axes_in[0].length(),axes_in[1].length(),axes_in[2].length() );
}
OrientedBox::OrientedBox( const Matrix3& axes_mat, const CartVect& mid )
: center(mid), axes(axes_mat)
{
order_axes_by_length( axes.col(0).length(), axes.col(1).length(), axes.col(2).length() );
}
ErrorCode OrientedBox::tag_handle( Tag& handle_out, ErrorCode OrientedBox::tag_handle( Tag& handle_out,
Interface* instance, Interface* instance,
const char* name) const char* name)
...@@ -174,13 +184,11 @@ static ErrorCode box_from_axes( OrientedBox& result, ...@@ -174,13 +184,11 @@ static ErrorCode box_from_axes( OrientedBox& result,
for (Range::iterator i = points.begin(); i != points.end(); ++i) for (Range::iterator i = points.begin(); i != points.end(); ++i)
{ {
CartVect coords; CartVect coords;
rval = instance->get_coords( &*i, 1, coords.array() ); rval = instance->get_coords( &*i, 1, coords.array() );MB_CHK_ERR(rval);
if (MB_SUCCESS != rval)
return rval;
for (int d = 0; d < 3; ++d) for (int d = 0; d < 3; ++d)
{ {
double t = point_perp( coords, result.center, result.axis[d] ); const double t = point_perp( coords, result.center, result.axes.col(d) );
if (t < min[d]) if (t < min[d])
min[d] = t; min[d] = t;
if (t > max[d]) if (t > max[d])
...@@ -190,14 +198,14 @@ static ErrorCode box_from_axes( OrientedBox& result, ...@@ -190,14 +198,14 @@ static ErrorCode box_from_axes( OrientedBox& result,
// We now have a box defined by three orthogonal line segments // We now have a box defined by three orthogonal line segments
// that intersect at the center of the box. Each line segment // that intersect at the center of the box. Each line segment
// is defined as result.center + t * result.axis[i], where the // is defined as result.center + t * result.axes[i], where the
// range of t is [min[i], max[i]]. // range of t is [min[i], max[i]].
// Calculate new center // Calculate new center
CartVect mid = 0.5 * (min + max); const CartVect mid = 0.5 * (min + max);
result.center += mid[0] * result.axis[0] + result.center += mid[0] * result.axes.col(0) +
mid[1] * result.axis[1] + mid[1] * result.axes.col(1) +
mid[2] * result.axis[2]; mid[2] * result.axes.col(2);
// reorder axes by length // reorder axes by length
CartVect range = 0.5 * (max - min); CartVect range = 0.5 * (max - min);
...@@ -205,25 +213,25 @@ static ErrorCode box_from_axes( OrientedBox& result, ...@@ -205,25 +213,25 @@ static ErrorCode box_from_axes( OrientedBox& result,
{ {
if (range[2] < range[0]) { if (range[2] < range[0]) {
std::swap( range[0], range[2] ); std::swap( range[0], range[2] );
std::swap( result.axis[0], result.axis[2] ); result.axes.swapcol( 0, 2 );
} }
} }
else if (range[1] < range[0]) { else if (range[1] < range[0]) {
std::swap( range[0], range[1] ); std::swap( range[0], range[1] );
std::swap( result.axis[0], result.axis[1] ); result.axes.swapcol( 0, 1 );
} }
if (range[1] > range[2]) { if (range[1] > range[2]) {
std::swap( range[1], range[2] ); std::swap( range[1], range[2] );
std::swap( result.axis[1], result.axis[2] ); result.axes.swapcol( 1, 2 );
} }
// scale axis to encompass all points, divide in half // scale axis to encompass all points, divide in half
#if MB_ORIENTED_BOX_UNIT_VECTORS #if MB_ORIENTED_BOX_UNIT_VECTORS
result.length = range; result.length = range;
#else #else
result.axis[0] *= range[0]; result.axes.colscale(0, range[0]);
result.axis[1] *= range[1]; result.axes.colscale(1, range[1]);
result.axis[2] *= range[2]; result.axes.colscale(2, range[2]);
#endif #endif
#if MB_ORIENTED_BOX_OUTER_RADIUS #if MB_ORIENTED_BOX_OUTER_RADIUS
...@@ -269,8 +277,10 @@ ErrorCode OrientedBox::compute_from_vertices( OrientedBox& result, ...@@ -269,8 +277,10 @@ ErrorCode OrientedBox::compute_from_vertices( OrientedBox& result,
a /= count; a /= count;
// Get axes (Eigenvectors) from covariance matrix // Get axes (Eigenvectors) from covariance matrix
double lambda[3]; CartVect lambda;
moab::Matrix::EigenDecomp( a, lambda, result.axis ); a.eigen_decomposition(lambda, result.axes);
// moab::Matrix::EigenDecomp( a, lambda, result.axes );
// Calculate center and extents of box given orientation defined by axes // Calculate center and extents of box given orientation defined by axes
return box_from_axes( result, instance, vertices ); return box_from_axes( result, instance, vertices );
...@@ -351,8 +361,8 @@ ErrorCode OrientedBox::compute_from_covariance_data( ...@@ -351,8 +361,8 @@ ErrorCode OrientedBox::compute_from_covariance_data(
const Range& vertices ) const Range& vertices )
{ {
if (data.area <= 0.0) { if (data.area <= 0.0) {
CartVect axis[3] = { CartVect(0.), CartVect(0.), CartVect(0.) }; Matrix3 empty_axes (0.0);
result = OrientedBox( axis, CartVect(0.) ); result = OrientedBox( empty_axes, CartVect(0.) );
return MB_SUCCESS; return MB_SUCCESS;
} }
...@@ -364,8 +374,8 @@ ErrorCode OrientedBox::compute_from_covariance_data( ...@@ -364,8 +374,8 @@ ErrorCode OrientedBox::compute_from_covariance_data(
data.matrix -= outer_product( result.center, result.center ); data.matrix -= outer_product( result.center, result.center );
// get axes (Eigenvectors) from covariance matrix // get axes (Eigenvectors) from covariance matrix
double lamda[3]; CartVect lambda;
moab::Matrix::EigenDecomp( data.matrix, lamda, result.axis ); data.matrix.eigen_decomposition(lambda, result.axes);
// We now have only the axes. Calculate proper center // We now have only the axes. Calculate proper center
// and extents for enclosed points. // and extents for enclosed points.
...@@ -376,13 +386,13 @@ bool OrientedBox::contained( const CartVect& point, double tol ) const ...@@ -376,13 +386,13 @@ bool OrientedBox::contained( const CartVect& point, double tol ) const
{ {
CartVect from_center = point - center; CartVect from_center = point - center;
#if MB_ORIENTED_BOX_UNIT_VECTORS #if MB_ORIENTED_BOX_UNIT_VECTORS
return fabs(from_center % axis[0]) - length[0] <= tol && return fabs(from_center % axes.col(0)) - length[0] <= tol &&
fabs(from_center % axis[1]) - length[1] <= tol && fabs(from_center % axes.col(1)) - length[1] <= tol &&
fabs(from_center % axis[2]) - length[2] <= tol ; fabs(from_center % axes.col(2)) - length[2] <= tol ;
#else #else
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
double length = axis[i].length(); double length = axes.col(i).length();
if (fabs(from_center % axis[i]) - length*length > length*tol) if (fabs(from_center % axes.col(i)) - length*length > length*tol)
return false; return false;
} }
return true; return true;
...@@ -418,13 +428,13 @@ ErrorCode OrientedBox::compute_from_covariance_data( OrientedBox& result, ...@@ -418,13 +428,13 @@ ErrorCode OrientedBox::compute_from_covariance_data( OrientedBox& result,
// { // {
// CartVect corner( center ); // CartVect corner( center );
//#ifdef MB_ORIENTED_BOX_UNIT_VECTORS //#ifdef MB_ORIENTED_BOX_UNIT_VECTORS
// corner += i * box.length[0] * box.axis[0]; // corner += i * box.length[0] * box.axis.col(0);
// corner += j * box.length[1] * box.axis[1]; // corner += j * box.length[1] * box.axis.col(1);
// corner += k * box.length[2] * box.axis[2]; // corner += k * box.length[2] * box.axis.col(2);
//#else //#else
// corner += i * box.axis[0]; // corner += i * box.axis.col(0);
// corner += j * box.axis[1]; // corner += j * box.axis.col(1);
// corner += k * box.axis[2]; // corner += k * box.axis.col(2);
//#endif //#endif
// if (!contained( corner, tol )) // if (!contained( corner, tol ))
// return false; // return false;
...@@ -552,26 +562,17 @@ bool OrientedBox::intersect_ray( const CartVect& ray_origin, ...@@ -552,26 +562,17 @@ bool OrientedBox::intersect_ray( const CartVect& ray_origin,
} }
} }
// get transpose of axes // get transpose of axes
// Note: if axes were stored as a matrix, could skip Matrix3 B = Matrix::transpose(axes);
// transpose and just switch order of operands in
// matrix-vector multiplies below. - J.K.
//Matrix3 B( axis[0][0], axis[1][0], axis[2][0],
// axis[0][1], axis[1][1], axis[2][1],
// axis[0][2], axis[1][2], axis[2][2] );
Matrix3 B( axis[0][0], axis[0][1], axis[0][2],
axis[1][0], axis[1][1], axis[1][2],
axis[2][0], axis[2][1], axis[2][2] );
//CartVect T = B * -center;
// transform ray to box coordintae system // transform ray to box coordintae system
//CartVect par_pos = T + B * b;
CartVect par_pos = B * (ray_origin - center); CartVect par_pos = B * (ray_origin - center);
CartVect par_dir = B * ray_direction; CartVect par_dir = B * ray_direction;
// Fast Rejection Test: Ray will not intersect if it is going away from the box. // Fast Rejection Test: Ray will not intersect if it is going away from the box.
// This will not work for rays with neg_ray_len. length[0] is half of box width // This will not work for rays with neg_ray_len. length[0] is half of box width
// along axis[0]. // along axes.col(0).
const double half_x = length[0] + reps; const double half_x = length[0] + reps;
const double half_y = length[1] + reps; const double half_y = length[1] + reps;
const double half_z = length[2] + reps; const double half_z = length[2] + reps;
...@@ -658,9 +659,9 @@ ErrorCode OrientedBox::make_hex( EntityHandle& hex, Interface* instance ) ...@@ -658,9 +659,9 @@ ErrorCode OrientedBox::make_hex( EntityHandle& hex, Interface* instance )
CartVect coords(center); CartVect coords(center);
for (int j = 0; j < 3; ++j){ for (int j = 0; j < 3; ++j){
#if MB_ORIENTED_BOX_UNIT_VECTORS #if MB_ORIENTED_BOX_UNIT_VECTORS
coords += signs[i][j] * (axis[j]*length[j]); coords += signs[i][j] * (axes.col(j)*length[j]);
#else #else
coords += signs[i][j] * axis[j]; coords += signs[i][j] * axes.col(j);
#endif #endif
} }
EntityHandle handle; EntityHandle handle;
...@@ -689,9 +690,9 @@ void OrientedBox::closest_location_in_box( ...@@ -689,9 +690,9 @@ void OrientedBox::closest_location_in_box(
const CartVect from_center = input_position - center; const CartVect from_center = input_position - center;
#if MB_ORIENTED_BOX_UNIT_VECTORS #if MB_ORIENTED_BOX_UNIT_VECTORS
CartVect local( from_center % axis[0], CartVect local( from_center % axes.col(0),
from_center % axis[1], from_center % axes.col(1),
from_center % axis[2] ); from_center % axes.col(2) );
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
if (local[i] < -length[i]) if (local[i] < -length[i])
...@@ -700,9 +701,9 @@ void OrientedBox::closest_location_in_box( ...@@ -700,9 +701,9 @@ void OrientedBox::closest_location_in_box(
local[i] = length[i]; local[i] = length[i];
} }
#else #else
CartVect local( (from_center % axis[0]) / (axis[0] % axis[0]), CartVect local( (from_center % axes.col(0)) / (axes.col(0) % axes.col(0)),
(from_center % axis[1]) / (axis[1] % axis[1]), (from_center % axes.col(1)) / (axes.col(1) % axes.col(1)),
(from_center % axis[2]) / (axis[2] % axis[2]) ); (from_center % axes.col(2)) / (axes.col(2) % axes.col(2)) );
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
if (local[i] < -1.0) if (local[i] < -1.0)
...@@ -713,9 +714,9 @@ void OrientedBox::closest_location_in_box( ...@@ -713,9 +714,9 @@ void OrientedBox::closest_location_in_box(
#endif #endif
output_position = center output_position = center
+ local[0] * axis[0] + local[0] * axes.col(0)
+ local[1] * axis[1] + local[1] * axes.col(1)
+ local[2] * axis[2]; + local[2] * axes.col(2);
} }
} // namespace moab } // namespace moab
...@@ -361,7 +361,7 @@ static ErrorCode split_box( Interface* instance, ...@@ -361,7 +361,7 @@ static ErrorCode split_box( Interface* instance,
centroid += coords[j]; centroid += coords[j];