#include <iostream>
void refineMode(int rf, int lvl, unsigned meshSize,
unsigned extent, std::vector<index_t> & boxes);
int main(int argc, char *argv[])
{
bool plot = false;
gsCmdLine cmd(
"Create standard refined TH>B meshes.");
cmd.addInt("l","levels",
"Number of refinement levels", refLevels);
cmd.addInt("m","mode",
"Refinement mode (0, 1, 2 3 4)", refmode);
cmd.addInt("p","degree",
"Spline degree", degree);
cmd.addSwitch("plot", "Plot result in ParaView format", plot);
try { cmd.getValues(argc,argv); } catch (int rv) { return rv; }
gsInfo<<
"Coarsest level: "<< tp <<
"\n";
std::vector<index_t> boxes;
refineMode(refmode, refLevels, numknots+1, degree, boxes);
gsInfo<<
"THB-spline basis: "<< thb <<
"\n";
gsInfo <<
"Nested grid dimensions: ";
unsigned kcount = 0;
for( unsigned l = 0; l <= thb.maxLevel(); ++l)
{
kcount += thb.tensorLevel(l).knots(0).uSize()
+ thb.tensorLevel(l).knots(1).uSize();
gsInfo<< thb.tensorLevel(l).size() <<
", ";
}
const int numTr = thb.numTruncated();
trcount.setZero(thb.maxLevel()+1);
if (numTr < 1000)
gsInfo <<
"\nCoefficient count for each truncated function: \n";
unsigned ccount = 0;
typedef std::map<index_t, gsSparseVector<> >::const_iterator trIter;
for( trIter it = thb.truncatedBegin(); it != thb.truncatedEnd(); ++it)
{
const int lvl = thb.levelOf(it->first);
if (numTr < 1000)
gsInfo << it->second.nonZeros() <<
", ";
trcount[lvl]++;
ccount += it->second.nonZeros();
}
gsInfo <<
"Truncated functions: "<< numTr <<
"\n";
gsInfo <<
" per level: "<< trcount.transpose() <<
"\n";
gsInfo <<
"Total coeffs stored: "<< ccount
<<" ("<< (sizeof(real_t)*ccount >> 20) <<"MB)\n";
gsInfo <<
"Total knots stored : "<< kcount
<<
" ("<< ( (
sizeof(real_t)+
sizeof(
index_t))*kcount >> 20) <<
"MB)\n";
if ( plot )
gsWriteParaview( thb , "thb_refined", 1000, true);
else
gsInfo <<
"Done. No output created, re-run with --plot to get a ParaView "
"file containing the solution.\n";
return 0;
}
void refineMode(int rf, int lvl, unsigned meshSize,
unsigned extent, std::vector<index_t> & boxes)
{
boxes.clear();
const unsigned nb = meshSize*(1<<lvl);
const unsigned mid = nb / 2;
const unsigned bpd = 5*nb;
switch( rf )
{
case 0:
boxes.resize(5);
boxes[0] = lvl;
boxes[1] = boxes[2] = 0;
boxes[3] = boxes[4] = 1;
gsInfo <<
"Corner refinement.\n";
break;
case 1:
boxes.resize(5*nb);
for ( unsigned i = 0; i!= nb; ++i)
{
boxes[5*i ] = lvl;
boxes[5*i+1] = boxes[5*i+2] = i-extent/2;
boxes[5*i+3] = boxes[5*i+4] = i+extent/2;
}
gsInfo <<
"Diagonal refinement.\n";
break;
case 2:
boxes.resize(2 * bpd);
for ( unsigned i = 0; i!= nb; ++i)
{
for ( unsigned k = 0; k!= 2; ++k)
{
boxes[k*bpd+5*i ] = lvl;
boxes[k*bpd+5*i+1] = boxes[k*bpd+5*i+2] = i-extent/2;
boxes[k*bpd+5*i+3] = boxes[k*bpd+5*i+4] = i+extent/2;
boxes[k*bpd+5*i+1+k] = mid-1;
boxes[k*bpd+5*i+3+k] = mid+1;
}
}
gsInfo <<
"Cross refinement.\n";
break;
case 3:
boxes.resize(5);
boxes[0] = lvl;
boxes[1] = boxes[2] = mid - extent/2;
boxes[3] = boxes[4] = mid + extent/2;
gsInfo <<
"Central refinement.\n";
break;
case 4:
boxes.resize(5*lvl);
for ( int i = 0; i<lvl; ++i)
{
boxes[5*i ] = i+1;
boxes[5*i+1] = boxes[5*i+2] = 0 ;
boxes[5*i+3] = ( meshSize <<(i+1) );
boxes[5*i+4] = meshSize;
}
gsInfo <<
"Stripes refinement.\n";
break;
default:
break;
}
}
Class for command-line argument parsing.
Definition gsCmdLine.h:57
Class for representing a knot vector.
Definition gsKnotVector.h:80
Truncated hierarchical B-spline basis.
Definition gsTHBSplineBasis.h:36
A tensor product B-spline basis.
Definition gsTensorBSplineBasis.h:37
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
Main header to be included by clients using the G+Smo library.
#define index_t
Definition gsConfig.h:32
#define gsInfo
Definition gsDebug.h:43
The G+Smo namespace, containing all definitions for the library.