blender/intern/elbeem/intern/attributes.cpp
Nils Thuerey 818bfcca63 - Added OpenMP code, it is enabled by defining PARALLEL=1 for the elbeem
compilation.  Currently, it is not yet active by default, but 
  Genscher wanted to do some tests. 
  It can be used to distribute the computation load onto multiple shared-
  memory CPUs by splitting the domain along the y-axis (assuming a 
  gravity force along z). However, there is no load balancing: so
  if there's fluid only in one of the y-axis halves you will not get 
  a speedup for 2 CPUs.  

- Added a fix for the memory allocation bugs #7120 and #6775. In 
  solver_init.cpp there are now several variables max___MemChunk 
  (line 692+), that set upper limits for various systems. The same
  problem existed for mac & linux, but the limit is higher, so 
  it probably went by undetected. The windows limit is currently 1GB,
  if the strange 700MB limit problems mentioned in the bug regports the 
  bugs persist, this could be further reduced. For 64bit compilations 
  this problem shouldn't exist anyway.
  What's still missing is a display of how much the resolution was 
  reduced to fit into memory...

- And some minor solver code cleanup.
2007-11-21 22:12:16 +00:00

360 lines
11 KiB
C++

/******************************************************************************
*
* El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
* Copyright 2003-2006 Nils Thuerey
*
* DEPRECATED - replaced by elbeem API, only channels are still used
*
*****************************************************************************/
#include "attributes.h"
#include "ntl_matrices.h"
#include "elbeem.h"
/******************************************************************************
* attribute conversion functions
*****************************************************************************/
bool Attribute::initChannel(int elemSize) {
elemSize=0; // remove warning
return false;
}
string Attribute::getAsString(bool debug) {
debug=false; // remove warning
return string("");
}
int Attribute::getAsInt() {
return 0;
}
bool Attribute::getAsBool() {
return false;
}
double Attribute::getAsFloat() {
return 0.;
}
ntlVec3d Attribute::getAsVec3d() {
return ntlVec3d(0.);
}
void Attribute::getAsMat4Gfx(ntlMat4Gfx *mat) {
mat=NULL; // remove warning
}
string Attribute::getCompleteString() {
return string("");
}
/******************************************************************************
* channel returns
*****************************************************************************/
AnimChannel<double> Attribute::getChannelFloat() {
return AnimChannel<double>();
}
AnimChannel<int> Attribute::getChannelInt() {
return AnimChannel<int>();
}
AnimChannel<ntlVec3d> Attribute::getChannelVec3d() {
return AnimChannel<ntlVec3d>();
}
AnimChannel<ntlSetVec3f>
Attribute::getChannelSetVec3f() {
return AnimChannel<ntlSetVec3f>();
}
/******************************************************************************
* check if there were unknown params
*****************************************************************************/
bool AttributeList::checkUnusedParams() {
return false;
}
void AttributeList::setAllUsed() {
}
/******************************************************************************
* Attribute list read functions
*****************************************************************************/
int AttributeList::readInt(string name, int defaultValue, string source,string target, bool needed) {
name=source=target=string(""); needed=false; // remove warning
return defaultValue;
}
bool AttributeList::readBool(string name, bool defaultValue, string source,string target, bool needed) {
name=source=target=string(""); needed=false; // remove warning
return defaultValue;
}
double AttributeList::readFloat(string name, double defaultValue, string source,string target, bool needed) {
name=source=target=string(""); needed=false; // remove warning
return defaultValue;
}
string AttributeList::readString(string name, string defaultValue, string source,string target, bool needed) {
name=source=target=string(""); needed=false; // remove warning
return defaultValue;
}
ntlVec3d AttributeList::readVec3d(string name, ntlVec3d defaultValue, string source,string target, bool needed) {
name=source=target=string(""); needed=false; // remove warning
return defaultValue;
}
void AttributeList::readMat4Gfx(string name, ntlMat4Gfx defaultValue, string source,string target, bool needed, ntlMat4Gfx *mat) {
*mat = defaultValue;
name=source=target=string(""); needed=false; mat=NULL; // remove warning
}
// set that a parameter can be given, and will be ignored...
bool AttributeList::ignoreParameter(string name, string source) {
name = source = ("");
return false;
}
// read channels
AnimChannel<int> AttributeList::readChannelInt(string name, int defaultValue, string source, string target, bool needed) {
name=source=target=string(""); needed=false; // remove warning
return AnimChannel<int>(defaultValue);
}
AnimChannel<double> AttributeList::readChannelFloat(string name, double defaultValue, string source, string target, bool needed ) {
name=source=target=string(""); needed=false; // remove warning
return AnimChannel<double>(defaultValue);
}
AnimChannel<ntlVec3d> AttributeList::readChannelVec3d(string name, ntlVec3d defaultValue, string source, string target, bool needed ) {
name=source=target=string(""); needed=false; // remove warning
return AnimChannel<ntlVec3d>(defaultValue);
}
AnimChannel<ntlSetVec3f> AttributeList::readChannelSetVec3f(string name, ntlSetVec3f defaultValue, string source, string target, bool needed) {
name=source=target=string(""); needed=false; // remove warning
return AnimChannel<ntlSetVec3f>(defaultValue);
}
AnimChannel<float> AttributeList::readChannelSinglePrecFloat(string name, float defaultValue, string source, string target, bool needed ) {
name=source=target=string(""); needed=false; // remove warning
return AnimChannel<float>(defaultValue);
}
AnimChannel<ntlVec3f> AttributeList::readChannelVec3f(string name, ntlVec3f defaultValue, string source, string target, bool needed) {
name=source=target=string(""); needed=false; // remove warning
return AnimChannel<ntlVec3f>(defaultValue);
}
/******************************************************************************
* destructor
*****************************************************************************/
AttributeList::~AttributeList() {
};
/******************************************************************************
* debugging
*****************************************************************************/
//! debug function, prints value
void Attribute::print() {
}
//! debug function, prints all attribs
void AttributeList::print() {
}
/******************************************************************************
* import attributes from other attribute list
*****************************************************************************/
void AttributeList::import(AttributeList *oal) {
oal=NULL; // remove warning
}
/******************************************************************************
* channel max finding
*****************************************************************************/
ntlVec3f channelFindMaxVf (AnimChannel<ntlVec3f> channel) {
ntlVec3f ret(0.0);
float maxLen = 0.0;
for(size_t i=0; i<channel.accessValues().size(); i++) {
float nlen = normNoSqrt(channel.accessValues()[i]);
if(nlen>maxLen) { ret=channel.accessValues()[i]; maxLen=nlen; }
}
return ret;
}
ntlVec3d channelFindMaxVd (AnimChannel<ntlVec3d> channel) {
ntlVec3d ret(0.0);
float maxLen = 0.0;
for(size_t i=0; i<channel.accessValues().size(); i++) {
float nlen = normNoSqrt(channel.accessValues()[i]);
if(nlen>maxLen) { ret=channel.accessValues()[i]; maxLen=nlen; }
}
return ret;
}
int channelFindMaxi (AnimChannel<float > channel) {
int ret = 0;
float maxLen = 0.0;
for(size_t i=0; i<channel.accessValues().size(); i++) {
float nlen = ABS(channel.accessValues()[i]);
if(nlen>maxLen) { ret= (int)channel.accessValues()[i]; maxLen=nlen; }
}
return ret;
}
float channelFindMaxf (AnimChannel<float > channel) {
float ret = 0.0;
float maxLen = 0.0;
for(size_t i=0; i<channel.accessValues().size(); i++) {
float nlen = ABS(channel.accessValues()[i]);
if(nlen>maxLen) { ret=channel.accessValues()[i]; maxLen=nlen; }
}
return ret;
}
double channelFindMaxd (AnimChannel<double > channel) {
double ret = 0.0;
float maxLen = 0.0;
for(size_t i=0; i<channel.accessValues().size(); i++) {
float nlen = ABS(channel.accessValues()[i]);
if(nlen>maxLen) { ret=channel.accessValues()[i]; maxLen=nlen; }
}
return ret;
}
/******************************************************************************
// unoptimized channel simplification functions, use elbeem.cpp functions
// warning - currently only with single precision
*****************************************************************************/
template<class SCALAR>
static bool channelSimplifyScalarT(AnimChannel<SCALAR> &channel) {
int size = channel.getSize();
if(size<=1) return false;
float *nchannel = new float[2*size];
// convert to array
for(size_t i=0; i<channel.accessValues().size(); i++) {
nchannel[i*2 + 0] = (float)channel.accessValues()[i];
nchannel[i*2 + 1] = (float)channel.accessTimes()[i];
}
bool ret = elbeemSimplifyChannelFloat(nchannel, &size);
if(ret) {
vector<SCALAR> vals;
vector<double> times;
for(int i=0; i<size; i++) {
vals.push_back( (SCALAR)(nchannel[i*2 + 0]) );
times.push_back( (double)(nchannel[i*2 + 1]) );
}
channel = AnimChannel<SCALAR>(vals, times);
}
delete [] nchannel;
return ret;
}
bool channelSimplifyi (AnimChannel<int > &channel) { return channelSimplifyScalarT<int>(channel); }
bool channelSimplifyf (AnimChannel<float> &channel) { return channelSimplifyScalarT<float>(channel); }
bool channelSimplifyd (AnimChannel<double > &channel) { return channelSimplifyScalarT<double>(channel); }
template<class VEC>
static bool channelSimplifyVecT(AnimChannel<VEC> &channel) {
int size = channel.getSize();
if(size<=1) return false;
float *nchannel = new float[4*size];
// convert to array
for(size_t i=0; i<channel.accessValues().size(); i++) {
nchannel[i*4 + 0] = (float)channel.accessValues()[i][0];
nchannel[i*4 + 1] = (float)channel.accessValues()[i][1];
nchannel[i*4 + 2] = (float)channel.accessValues()[i][2];
nchannel[i*4 + 3] = (float)channel.accessTimes()[i];
}
bool ret = elbeemSimplifyChannelVec3(nchannel, &size);
if(ret) {
vector<VEC> vals;
vector<double> times;
for(int i=0; i<size; i++) {
vals.push_back( VEC(nchannel[i*4 + 0], nchannel[i*4 + 1], nchannel[i*4 + 2] ) );
times.push_back( (double)(nchannel[i*4 + 3]) );
}
channel = AnimChannel<VEC>(vals, times);
}
delete [] nchannel;
return ret;
}
bool channelSimplifyVf (AnimChannel<ntlVec3f> &channel) {
return channelSimplifyVecT<ntlVec3f>(channel);
}
bool channelSimplifyVd (AnimChannel<ntlVec3d> &channel) {
return channelSimplifyVecT<ntlVec3d>(channel);
}
//! debug function, prints channel as string
template<class Scalar>
string AnimChannel<Scalar>::printChannel() {
std::ostringstream ostr;
ostr << " CHANNEL #"<< mValue.size() <<" = { ";
for(size_t i=0;i<mValue.size();i++) {
ostr <<"'"<< mValue[i]<<"' ";
ostr << "@"<<mTimes[i]<<"; ";
}
ostr << " } ";
return ostr.str();
} // */
// is now in header file: debugPrintChannel()
// hack to force instantiation
void __forceAnimChannelInstantiation() {
AnimChannel< float > tmp1;
AnimChannel< double > tmp2;
AnimChannel< string > tmp3;
AnimChannel< ntlVector3Dim<float> > tmp4;
AnimChannel< ntlVector3Dim<double> > tmp5;
tmp1.debugPrintChannel();
tmp2.debugPrintChannel();
tmp3.debugPrintChannel();
tmp4.debugPrintChannel();
tmp5.debugPrintChannel();
}
ntlSetVec3f::ntlSetVec3f(double v ) {
mVerts.clear();
mVerts.push_back( ntlVec3f(v) );
}
const ntlSetVec3f&
ntlSetVec3f::operator=(double v ) {
mVerts.clear();
mVerts.push_back( ntlVec3f(v) );
return *this;
}
std::ostream& operator<<( std::ostream& os, const ntlSetVec3f& vs ) {
os<< "{";
for(int j=0;j<(int)vs.mVerts.size();j++) os<<vs.mVerts[j];
os<< "}";
return os;
}
ntlSetVec3f&
ntlSetVec3f::operator+=( double v )
{
for(int j=0;j<(int)(mVerts.size()) ;j++) {
mVerts[j] += v;
}
return *this;
}
ntlSetVec3f&
ntlSetVec3f::operator+=( const ntlSetVec3f &v )
{
for(int j=0;j<(int)MIN(mVerts.size(),v.mVerts.size()) ;j++) {
mVerts[j] += v.mVerts[j];
}
return *this;
}
ntlSetVec3f&
ntlSetVec3f::operator*=( double v )
{
for(int j=0;j<(int)(mVerts.size()) ;j++) {
mVerts[j] *= v;
}
return *this;
}
ntlSetVec3f&
ntlSetVec3f::operator*=( const ntlSetVec3f &v )
{
for(int j=0;j<(int)MIN(mVerts.size(),v.mVerts.size()) ;j++) {
mVerts[j] *= v.mVerts[j];
}
return *this;
}