Skip to content
Snippets Groups Projects
Commit 651def34 authored by Amaury Johnen's avatar Amaury Johnen
Browse files

cleanup inequalities

parent 9f512f96
No related branches found
No related tags found
No related merge requests found
......@@ -14,14 +14,26 @@
namespace {
double cubicCardanoRoot(double p, double q)
{
double sq = std::sqrt(q*q/4 + p*p*p/27);
double A = q*q/4 + p*p*p/27;
if (A > 0) {
double sq = std::sqrt(A);
return std::pow(-q/2+sq, 1/3.) + std::pow(-q/2-sq, 1/3.);
}
else {
double module = std::sqrt(-p*p*p/27);
double ang = std::acos(-q/2/module);
return 2 * std::pow(module, 1/3.) * std::cos(ang/3);
}
}
int nChoosek(int n, int k)
{
if (n < k || k < 0) {
Msg::Error("Wrong argument for combination. n %d k %d", n, k);
int a[2];
int e = 0;
for (int i = 0; i < 10000000; ++i) e+=a[i];
Msg::Info("%d",e);
return 1;
}
......@@ -105,162 +117,153 @@ MetricCoefficient::MetricCoefficient(MElement *el) : _element(el)
void MetricCoefficient::_fillInequalities(int metricOrder)
{
std::map<int, int> result2vect;
std::vector<std::pair<int,int> > v;
int dimSimplex = _bezier->_dimSimplex;
int dim = _bezier->getDim();
fullMatrix<double> exp = _bezier->_exponents;
fullMatrix<int> exp(_bezier->_exponents.size1(), _bezier->_exponents.size2());
for (int i = 0; i < _bezier->_exponents.size1(); ++i) {
for (int j = 0; j < _bezier->_exponents.size2(); ++j) {
exp(i, j) = static_cast<int>(_bezier->_exponents(i, j) + .5);
}
}
int ncoeff = _coefficientsLag.size1();
Msg::Info("ncoeff %d", ncoeff);
int countP3 = 0, countJ2 = 0;
double tol = .99;
int countP3 = 0, countJ2 = 0, countA = 0;
double tol = .1;
for (int i = 0; i < ncoeff; i++) {
for (int j = i; j < ncoeff; j++) {
double A = 1, B = 1;
double num = 1, den = 1;
{
int compl1 = metricOrder;
int compl2 = metricOrder;
int compl3 = 2*metricOrder;
int compltot = 2*metricOrder;
for (int k = 0; k < dimSimplex; k++) {
A *= nChoosek(compl1, (int) exp(i, k))
* nChoosek(compl2, (int) exp(j, k));
B *= nChoosek(compl3, (int) exp(i, k) + (int) exp(j, k));
compl1 -= (int) exp(i, k);
compl2 -= (int) exp(j, k);
compl3 -= (int) exp(i, k) + (int) exp(j, k);
}
num *= nChoosek(compl1, exp(i, k))
* nChoosek(compl2, exp(j, k));
den *= nChoosek(compltot, exp(i, k) + exp(j, k));
compl1 -= exp(i, k);
compl2 -= exp(j, k);
compltot -= exp(i, k) + exp(j, k);
}
for (int k = dimSimplex; k < dim; k++) {
A *= nChoosek(metricOrder, (int) exp(i, k))
* nChoosek(metricOrder, (int) exp(j, k));
B *= nChoosek(2*metricOrder, (int) exp(i, k) + (int) exp(j, k));
num *= nChoosek(metricOrder, exp(i, k))
* nChoosek(metricOrder, exp(j, k));
den *= nChoosek(2*metricOrder, exp(i, k) + exp(j, k));
}
}
if (i != j) A *= 2;
if (i != j) num *= 2;
if (A > tol*B) {
v.push_back(std::make_pair(i, j));
int ind;
++countA;
int hash = 0;
for (int k = 0; k < dim; k++) {
hash += (int) (exp(i, k)+exp(j, k)) * pow_int(2*metricOrder+1, k);
}
std::map<int, int>::iterator it;
if ((it = result2vect.find(hash)) != result2vect.end()) {
ind = it->second;
}
else {
ind = _ineq2.size();
_ineq2.push_back(std::map<std::pair<int, int>, double>());
result2vect[hash] = ind;
}
_ineq2[ind][std::make_pair(i, j)] = A/B;
for (int l = 0; l < dim; l++) {
hash += (exp(i, l)+exp(j, l)) * pow_int(2*metricOrder+1, l);
}
_ineqA[hash].push_back(IneqData(num/den, i, j));
for (int k = j; k < ncoeff; ++k) {
double A = 1, B = 1;
double num = 1, den = 1;
{
int compl1 = metricOrder;
int compl2 = metricOrder;
int compl3 = metricOrder;
int compltot = 3*metricOrder;
for (int l = 0; l < dimSimplex; l++) {
A *= nChoosek(compl1, (int) exp(i, l))
* nChoosek(compl2, (int) exp(j, l))
* nChoosek(compl3, (int) exp(k, l));
B *= nChoosek(compltot, (int) exp(i, l) + (int) exp(j, l) + (int) exp(k, l));
compl1 -= (int) exp(i, l);
compl2 -= (int) exp(j, l);
compl3 -= (int) exp(k, l);
compltot -= (int) exp(i, l) + (int) exp(j, l) + (int) exp(k, l);
}
num *= nChoosek(compl1, exp(i, l))
* nChoosek(compl2, exp(j, l))
* nChoosek(compl3, exp(k, l));
den *= nChoosek(compltot, exp(i, l) + exp(j, l) + exp(k, l));
compl1 -= exp(i, l);
compl2 -= exp(j, l);
compl3 -= exp(k, l);
compltot -= exp(i, l) + exp(j, l) + exp(k, l);
}
for (int l = dimSimplex; l < dim; l++) {
A *= nChoosek(metricOrder, (int) exp(i, l))
* nChoosek(metricOrder, (int) exp(j, l))
* nChoosek(metricOrder, (int) exp(k, l));
B *= nChoosek(3*metricOrder, (int) exp(i, l) + (int) exp(j, l) + (int) exp(k, l));
num *= nChoosek(metricOrder, exp(i, l))
* nChoosek(metricOrder, exp(j, l))
* nChoosek(metricOrder, exp(k, l));
den *= nChoosek(3*metricOrder, exp(i, l) + exp(j, l) + exp(k, l));
}
}
if (i == j) {
if (j != k) A *= 3;
if (j != k) num *= 3;
}
else {
if (j == k || i == k) A *= 3;
else A *= 6;
if (j == k || i == k) num *= 3;
else num *= 6;
}
++countP3;
int hash = 0;
for (int l = 0; l < dim; l++) {
hash += (int) (exp(i, l)+exp(j, l)+exp(k, l)) * pow_int(3*metricOrder+1, l);
}
_ineqP3[hash].push_back(IneqData(A/B, i, j, k));
//Msg::Info(" %d", _ineqP3[hash].back().k);
hash += (exp(i, l)+exp(j, l)+exp(k, l)) * pow_int(3*metricOrder+1, l);
}
_ineqP3[hash].push_back(IneqData(num/den, i, j, k));
}
}
_inequations.resize(v.size(), 2);
exp = _jacobian->bezier->_exponents;
for (unsigned int k = 0; k < v.size(); ++k) {
//Msg::Info("%d %d", v[k].first, v[k].second);
_inequations(k, 0) = v[k].first;
_inequations(k, 1) = v[k].second;
}
exp.resize(_jacobian->bezier->_exponents.size1(),
_jacobian->bezier->_exponents.size2());
for (int i = 0; i < _jacobian->bezier->_exponents.size1(); ++i) {
for (int j = 0; j < _jacobian->bezier->_exponents.size2(); ++j) {
exp(i, j) = static_cast<int>(_jacobian->bezier->_exponents(i, j) + .5);
}
}
int njac = _jacobian->getNumJacNodes();
for (int i = 0; i < njac; i++) {
for (int j = i; j < njac; j++) {
int order = metricOrder/2*3;
double A = 1, B = 1;
double num = 1, den = 1;
{
int compl1 = order;
int compl2 = order;
int compltot = 2*order;
for (int k = 0; k < dimSimplex; k++) {
A *= nChoosek(compl1, (int) exp(i, k))
* nChoosek(compl2, (int) exp(j, k));
B *= nChoosek(compltot, (int) exp(i, k) + (int) exp(j, k));
compl1 -= (int) exp(i, k);
compl2 -= (int) exp(j, k);
compltot -= (int) exp(i, k) + (int) exp(j, k);
num *= nChoosek(compl1, exp(i, k))
* nChoosek(compl2, exp(j, k));
den *= nChoosek(compltot, exp(i, k) + exp(j, k));
compl1 -= exp(i, k);
compl2 -= exp(j, k);
compltot -= exp(i, k) + exp(j, k);
}
}
for (int k = dimSimplex; k < dim; k++) {
A *= nChoosek(order, (int) exp(i, k))
* nChoosek(order, (int) exp(j, k));
B *= nChoosek(2*order, (int) exp(i, k) + (int) exp(j, k));
num *= nChoosek(order, exp(i, k))
* nChoosek(order, exp(j, k));
den *= nChoosek(2*order, exp(i, k) + exp(j, k));
}
if (i != j) A *= 2;
if (i != j) num *= 2;
++countJ2;
int hash = 0;
for (int k = 0; k < dim; k++) {
hash += (int) (exp(i, k)+exp(j, k)) * pow_int(2*order+1, k);
hash += (exp(i, k)+exp(j, k)) * pow_int(2*order+1, k);
}
_ineqJ2[hash].push_back(IneqData(A/B, i, j));
_ineqJ2[hash].push_back(IneqData(num/den, i, j));
}
}
_lightenInequalities(tol, countJ2, countP3);
_lightenInequalities(tol, countJ2, countP3, countA);
Msg::Info("A : %d / %d", v.size(), ncoeff*(ncoeff+1)/2);
Msg::Info("A : %d / %d", countA, ncoeff*(ncoeff+1)/2);
Msg::Info("J2 : %d / %d", countJ2, njac*(njac+1)/2);
Msg::Info("P3 : %d / %d", countP3, ncoeff*(ncoeff+1)*(ncoeff+2)/6);
}
void MetricCoefficient::_lightenInequalities(double tol, int &countj, int &countp)
void MetricCoefficient::_lightenInequalities(double tol, int &countj, int &countp, int &counta)
{
std::map<int, std::vector<IneqData> >::iterator it, itbeg[3], itend[3];
int cnt[3] = {0,0,0};
itbeg[0] = _ineqJ2.begin();
itbeg[1] = _ineqP3.begin();
//itbeg[2] = _ineqJ2.begin();
itbeg[2] = _ineqA.begin();
itend[0] = _ineqJ2.end();
itend[1] = _ineqP3.end();
//itend[2] = _ineqJ2.end();
for (int k = 0; k < 2; ++k) {
itend[2] = _ineqA.end();
for (int k = 0; k < 3; ++k) {
it = itbeg[k];
while (it != itend[k]) {
std::sort(it->second.begin(), it->second.end(), gterIneq());
......@@ -280,6 +283,7 @@ void MetricCoefficient::_lightenInequalities(double tol, int &countj, int &count
}
countj -= cnt[0];
countp -= cnt[1];
counta -= cnt[2];
}
void MetricCoefficient::getCoefficients(fullMatrix<double> &coeff, bool bezier)
......@@ -846,9 +850,6 @@ double MetricCoefficient::_subdivideForRmin(
++((MetricCoefficient*)this)->__numSub[depth];
((MetricCoefficient*)this)->__maxdepth = std::max(__maxdepth, depth+1);
if (depth == 0) {
Msg::Info("Begin 1");
}
for (int i = 0; i < numSub; ++i) {
coeff = new fullMatrix<double>(numMetPnts, numCoeff);
coeff->copy(*subcoeffs, i * numMetPnts, numMetPnts, 0, numCoeff, 0, 0);
......@@ -865,9 +866,6 @@ double MetricCoefficient::_subdivideForRmin(
subdomains.push(metData);
vect.push_back(metData);
}
if (depth == 0) {
Msg::Info("End 1");
}
trash.push_back(subjac);
delete subcoeffs;
......@@ -962,37 +960,31 @@ void MetricCoefficient::_minMaxA2(
{
min = 1e10;
max = 0;
std::map<std::pair<int, int>, double>::const_iterator it;
for (unsigned int k = 0; k < _ineq2.size(); ++k) {
double tmpNum = 0;
double tmpDen = 0;
//Msg::Info("%d/%d: %d", k, _ineq2.size(), _ineq2[k].size());
//Msg::Info(" ");
for (it = _ineq2[k].begin(); it != _ineq2[k].end(); ++it) {
const int i = it->first.first;
const int j = it->first.second;
double tmp2 = 0;
std::map<int, std::vector<IneqData> >::const_iterator it = _ineqA.begin();
while (it != _ineqA.end()) {
double num = 0;
double den = 0;
for (unsigned int k = 0; k < it->second.size(); ++k) {
const int i = it->second[k].i;
const int j = it->second[k].j;
double tmp = 0;
for (int l = 1; l < 7; ++l) {
tmp2 += coeff(i, l) * coeff(j, l);
tmp += coeff(i, l) * coeff(j, l);
}
tmpNum += it->second * tmp2;
tmpDen += it->second * coeff(i, 0) * coeff(j, 0);
}
double val = tmpNum/tmpDen;
//Msg::Info("%g/%g = %g", tmpNum, tmpDen, val);
den += it->second[k].val * tmp;
num += it->second[k].val * coeff(i, 0) * coeff(j, 0);
double val = num/den;
min = std::min(val, min);
max = std::max(val, max);
}
++it;
}
if (min < 0)
Msg::Fatal("minA ne devrait pas etre negatif");
min = std::sqrt(min);
max = std::sqrt(max);
double tmp = min;
min = 1./max;
max = 1./tmp;
}
void MetricCoefficient::_minMaxJacobianSqr(
......
......@@ -54,9 +54,7 @@ private:
const GradientBasis *_gradients;
const bezierBasis *_bezier;
fullMatrix<double> _coefficientsLag, _coefficientsBez;
fullMatrix<double> _inequations;
std::vector<std::map<std::pair<int, int>, double> > _ineq2; //TODO : pas top
std::map<int, std::vector<IneqData> > _ineqJ2, _ineqP3;
std::map<int, std::vector<IneqData> > _ineqJ2, _ineqP3, _ineqA;
int __maxdepth, __numSubdivision;
std::vector<int> __numSub;
......@@ -72,7 +70,7 @@ private:
private:
void _computeBezCoeff();
void _fillInequalities(int order);
void _lightenInequalities(double, int&, int&); //TODO change
void _lightenInequalities(double, int&, int&, int&); //TODO change
void _interpolateBezierPyramid(const double *uvw, double *minmaxQ);
void _computeRmin1(fullMatrix<double>&, fullVector<double>&,
double &RminLag, double &RminBez, int) const;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment